/ Hex Artifact Content
Login

Artifact a3fe31b17e841ec70beee72a2c960e9c787a8857:


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 30 2c 20 30  _PAGECACHE, 0, 0
0cf0: 2c 20 4e 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 4e  , N)..**.** If N
0d00: 20 69 73 20 70 6f 73 69 74 69 76 65 2c 20 74 68   is positive, th
0d10: 65 6e 20 4e 20 70 61 67 65 73 20 77 6f 72 74 68  en N pages worth
0d20: 20 6f 66 20 6d 65 6d 6f 72 79 20 61 72 65 20 61   of memory are a
0d30: 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e 67 20 61  llocated using a
0d40: 20 73 69 6e 67 6c 65 0a 2a 2a 20 73 71 6c 69 74   single.** sqlit
0d50: 65 33 4d 61 6c 6c 6f 63 28 29 20 63 61 6c 6c 20  e3Malloc() call 
0d60: 61 6e 64 20 74 68 61 74 20 6d 65 6d 6f 72 79 20  and that memory 
0d70: 69 73 20 75 73 65 64 20 66 6f 72 20 74 68 65 20  is used for the 
0d80: 66 69 72 73 74 20 4e 20 70 61 67 65 73 20 61 6c  first N pages al
0d90: 6c 6f 63 61 74 65 64 2e 0a 2a 2a 20 4f 72 20 69  located..** Or i
0da0: 66 20 4e 20 69 73 20 6e 65 67 61 74 69 76 65 2c  f N is negative,
0db0: 20 74 68 65 6e 20 2d 31 30 32 34 2a 4e 20 62 79   then -1024*N by
0dc0: 74 65 73 20 6f 66 20 6d 65 6d 6f 72 79 20 61 72  tes of memory ar
0dd0: 65 20 61 6c 6c 6f 63 61 74 65 64 20 61 6e 64 20  e allocated and 
0de0: 75 73 65 64 0a 2a 2a 20 66 6f 72 20 61 73 20 6d  used.** for as m
0df0: 61 6e 79 20 70 61 67 65 73 20 61 73 20 63 61 6e  any pages as can
0e00: 20 62 65 20 61 63 63 6f 6d 6f 64 61 74 65 64 2e   be accomodated.
0e10: 0a 2a 2a 0a 2a 2a 20 4f 6e 6c 79 20 6f 6e 65 20  .**.** Only one 
0e20: 6f 66 20 28 32 29 20 6f 72 20 28 33 29 20 63 61  of (2) or (3) ca
0e30: 6e 20 62 65 20 75 73 65 64 2e 20 20 4f 6e 63 65  n be used.  Once
0e40: 20 74 68 65 20 6d 65 6d 6f 72 79 20 61 76 61 69   the memory avai
0e50: 6c 61 62 6c 65 20 74 6f 20 28 32 29 20 6f 72 0a  lable to (2) or.
0e60: 2a 2a 20 28 33 29 20 69 73 20 65 78 68 61 75 73  ** (3) is exhaus
0e70: 74 65 64 2c 20 73 75 62 73 65 71 75 65 6e 74 20  ted, subsequent 
0e80: 61 6c 6c 6f 63 61 74 69 6f 6e 73 20 66 61 69 6c  allocations fail
0e90: 20 6f 76 65 72 20 74 6f 20 74 68 65 20 67 65 6e   over to the gen
0ea0: 65 72 61 6c 2d 70 75 72 70 6f 73 65 0a 2a 2a 20  eral-purpose.** 
0eb0: 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 6f 72  memory allocator
0ec0: 20 28 31 29 2e 0a 2a 2a 0a 2a 2a 20 45 61 72 6c   (1)..**.** Earl
0ed0: 69 65 72 20 76 65 72 73 69 6f 6e 73 20 6f 66 20  ier versions of 
0ee0: 53 51 4c 69 74 65 20 75 73 65 64 20 6f 6e 6c 79  SQLite used only
0ef0: 20 6d 65 74 68 6f 64 73 20 28 31 29 20 61 6e 64   methods (1) and
0f00: 20 28 32 29 2e 20 20 42 75 74 20 65 78 70 65 72   (2).  But exper
0f10: 69 6d 65 6e 74 73 0a 2a 2a 20 73 68 6f 77 20 74  iments.** show t
0f20: 68 61 74 20 6d 65 74 68 6f 64 20 28 33 29 20 77  hat method (3) w
0f30: 69 74 68 20 4e 3d 3d 31 30 30 20 70 72 6f 76 69  ith N==100 provi
0f40: 64 65 73 20 61 62 6f 75 74 20 61 20 35 25 20 70  des about a 5% p
0f50: 65 72 66 6f 72 6d 61 6e 63 65 20 62 6f 6f 73 74  erformance boost
0f60: 20 66 6f 72 0a 2a 2a 20 63 6f 6d 6d 6f 6e 20 77   for.** common w
0f70: 6f 72 6b 6c 6f 61 64 73 2e 0a 2a 2f 0a 23 69 6e  orkloads..*/.#in
0f80: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 49 6e 74  clude "sqliteInt
0f90: 2e 68 22 0a 0a 74 79 70 65 64 65 66 20 73 74 72  .h"..typedef str
0fa0: 75 63 74 20 50 43 61 63 68 65 31 20 50 43 61 63  uct PCache1 PCac
0fb0: 68 65 31 3b 0a 74 79 70 65 64 65 66 20 73 74 72  he1;.typedef str
0fc0: 75 63 74 20 50 67 48 64 72 31 20 50 67 48 64 72  uct PgHdr1 PgHdr
0fd0: 31 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  1;.typedef struc
0fe0: 74 20 50 67 46 72 65 65 73 6c 6f 74 20 50 67 46  t PgFreeslot PgF
0ff0: 72 65 65 73 6c 6f 74 3b 0a 74 79 70 65 64 65 66  reeslot;.typedef
1000: 20 73 74 72 75 63 74 20 50 47 72 6f 75 70 20 50   struct PGroup P
1010: 47 72 6f 75 70 3b 0a 0a 2f 2a 20 45 61 63 68 20  Group;../* Each 
1020: 70 61 67 65 20 63 61 63 68 65 20 28 6f 72 20 50  page cache (or P
1030: 43 61 63 68 65 29 20 62 65 6c 6f 6e 67 73 20 74  Cache) belongs t
1040: 6f 20 61 20 50 47 72 6f 75 70 2e 20 20 41 20 50  o a PGroup.  A P
1050: 47 72 6f 75 70 20 69 73 20 61 20 73 65 74 20 0a  Group is a set .
1060: 2a 2a 20 6f 66 20 6f 6e 65 20 6f 72 20 6d 6f 72  ** of one or mor
1070: 65 20 50 43 61 63 68 65 73 20 74 68 61 74 20 61  e PCaches that a
1080: 72 65 20 61 62 6c 65 20 74 6f 20 72 65 63 79 63  re able to recyc
1090: 6c 65 20 65 61 63 68 20 6f 74 68 65 72 27 73 20  le each other's 
10a0: 75 6e 70 69 6e 6e 65 64 0a 2a 2a 20 70 61 67 65  unpinned.** page
10b0: 73 20 77 68 65 6e 20 74 68 65 79 20 61 72 65 20  s when they are 
10c0: 75 6e 64 65 72 20 6d 65 6d 6f 72 79 20 70 72 65  under memory pre
10d0: 73 73 75 72 65 2e 20 20 41 20 50 47 72 6f 75 70  ssure.  A PGroup
10e0: 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   is an instance 
10f0: 6f 66 0a 2a 2a 20 74 68 65 20 66 6f 6c 6c 6f 77  of.** the follow
1100: 69 6e 67 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a  ing object..**.*
1110: 2a 20 54 68 69 73 20 70 61 67 65 20 63 61 63 68  * This page cach
1120: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
1130: 20 77 6f 72 6b 73 20 69 6e 20 6f 6e 65 20 6f 66   works in one of
1140: 20 74 77 6f 20 6d 6f 64 65 73 3a 0a 2a 2a 0a 2a   two modes:.**.*
1150: 2a 20 20 20 28 31 29 20 20 45 76 65 72 79 20 50  *   (1)  Every P
1160: 43 61 63 68 65 20 69 73 20 74 68 65 20 73 6f 6c  Cache is the sol
1170: 65 20 6d 65 6d 62 65 72 20 6f 66 20 69 74 73 20  e member of its 
1180: 6f 77 6e 20 50 47 72 6f 75 70 2e 20 20 54 68 65  own PGroup.  The
1190: 72 65 20 69 73 0a 2a 2a 20 20 20 20 20 20 20 20  re is.**        
11a0: 6f 6e 65 20 50 47 72 6f 75 70 20 70 65 72 20 50  one PGroup per P
11b0: 43 61 63 68 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 28  Cache..**.**   (
11c0: 32 29 20 20 54 68 65 72 65 20 69 73 20 61 20 73  2)  There is a s
11d0: 69 6e 67 6c 65 20 67 6c 6f 62 61 6c 20 50 47 72  ingle global PGr
11e0: 6f 75 70 20 74 68 61 74 20 61 6c 6c 20 50 43 61  oup that all PCa
11f0: 63 68 65 73 20 61 72 65 20 61 20 6d 65 6d 62 65  ches are a membe
1200: 72 0a 2a 2a 20 20 20 20 20 20 20 20 6f 66 2e 0a  r.**        of..
1210: 2a 2a 0a 2a 2a 20 4d 6f 64 65 20 31 20 75 73 65  **.** Mode 1 use
1220: 73 20 6d 6f 72 65 20 6d 65 6d 6f 72 79 20 28 73  s more memory (s
1230: 69 6e 63 65 20 50 43 61 63 68 65 20 69 6e 73 74  ince PCache inst
1240: 61 6e 63 65 73 20 61 72 65 20 6e 6f 74 20 61 62  ances are not ab
1250: 6c 65 20 74 6f 20 72 6f 62 0a 2a 2a 20 75 6e 75  le to rob.** unu
1260: 73 65 64 20 70 61 67 65 73 20 66 72 6f 6d 20 6f  sed pages from o
1270: 74 68 65 72 20 50 43 61 63 68 65 73 29 20 62 75  ther PCaches) bu
1280: 74 20 69 74 20 61 6c 73 6f 20 6f 70 65 72 61 74  t it also operat
1290: 65 73 20 77 69 74 68 6f 75 74 20 61 20 6d 75 74  es without a mut
12a0: 65 78 2c 0a 2a 2a 20 61 6e 64 20 69 73 20 74 68  ex,.** and is th
12b0: 65 72 65 66 6f 72 65 20 6f 66 74 65 6e 20 66 61  erefore often fa
12c0: 73 74 65 72 2e 20 20 4d 6f 64 65 20 32 20 72 65  ster.  Mode 2 re
12d0: 71 75 69 72 65 73 20 61 20 6d 75 74 65 78 20 69  quires a mutex i
12e0: 6e 20 6f 72 64 65 72 20 74 6f 20 62 65 0a 2a 2a  n order to be.**
12f0: 20 74 68 72 65 61 64 73 61 66 65 2c 20 62 75 74   threadsafe, but
1300: 20 72 65 63 79 63 6c 65 73 20 70 61 67 65 73 20   recycles pages 
1310: 6d 6f 72 65 20 65 66 66 69 63 69 65 6e 74 6c 79  more efficiently
1320: 2e 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 6d 6f 64 65  ..**.** For mode
1330: 20 28 31 29 2c 20 50 47 72 6f 75 70 2e 6d 75 74   (1), PGroup.mut
1340: 65 78 20 69 73 20 4e 55 4c 4c 2e 20 20 46 6f 72  ex is NULL.  For
1350: 20 6d 6f 64 65 20 28 32 29 20 74 68 65 72 65 20   mode (2) there 
1360: 69 73 20 6f 6e 6c 79 20 61 20 73 69 6e 67 6c 65  is only a single
1370: 0a 2a 2a 20 50 47 72 6f 75 70 20 77 68 69 63 68  .** PGroup which
1380: 20 69 73 20 74 68 65 20 70 63 61 63 68 65 31 2e   is the pcache1.
1390: 67 72 70 20 67 6c 6f 62 61 6c 20 76 61 72 69 61  grp global varia
13a0: 62 6c 65 20 61 6e 64 20 69 74 73 20 6d 75 74 65  ble and its mute
13b0: 78 20 69 73 0a 2a 2a 20 53 51 4c 49 54 45 5f 4d  x is.** SQLITE_M
13c0: 55 54 45 58 5f 53 54 41 54 49 43 5f 4c 52 55 2e  UTEX_STATIC_LRU.
13d0: 0a 2a 2f 0a 73 74 72 75 63 74 20 50 47 72 6f 75  .*/.struct PGrou
13e0: 70 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75  p {.  sqlite3_mu
13f0: 74 65 78 20 2a 6d 75 74 65 78 3b 20 20 20 20 20  tex *mutex;     
1400: 20 20 20 20 20 2f 2a 20 4d 55 54 45 58 5f 53 54       /* MUTEX_ST
1410: 41 54 49 43 5f 4c 52 55 20 6f 72 20 4e 55 4c 4c  ATIC_LRU or NULL
1420: 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69   */.  unsigned i
1430: 6e 74 20 6e 4d 61 78 50 61 67 65 3b 20 20 20 20  nt nMaxPage;    
1440: 20 20 20 20 20 2f 2a 20 53 75 6d 20 6f 66 20 6e       /* Sum of n
1450: 4d 61 78 20 66 6f 72 20 70 75 72 67 65 61 62 6c  Max for purgeabl
1460: 65 20 63 61 63 68 65 73 20 2a 2f 0a 20 20 75 6e  e caches */.  un
1470: 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e 50  signed int nMinP
1480: 61 67 65 3b 20 20 20 20 20 20 20 20 20 2f 2a 20  age;         /* 
1490: 53 75 6d 20 6f 66 20 6e 4d 69 6e 20 66 6f 72 20  Sum of nMin for 
14a0: 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73  purgeable caches
14b0: 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69   */.  unsigned i
14c0: 6e 74 20 6d 78 50 69 6e 6e 65 64 3b 20 20 20 20  nt mxPinned;    
14d0: 20 20 20 20 20 2f 2a 20 6e 4d 61 78 70 61 67 65       /* nMaxpage
14e0: 20 2b 20 31 30 20 2d 20 6e 4d 69 6e 50 61 67 65   + 10 - nMinPage
14f0: 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69   */.  unsigned i
1500: 6e 74 20 6e 43 75 72 72 65 6e 74 50 61 67 65 3b  nt nCurrentPage;
1510: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
1520: 66 20 70 75 72 67 65 61 62 6c 65 20 70 61 67 65  f purgeable page
1530: 73 20 61 6c 6c 6f 63 61 74 65 64 20 2a 2f 0a 20  s allocated */. 
1540: 20 50 67 48 64 72 31 20 2a 70 4c 72 75 48 65 61   PgHdr1 *pLruHea
1550: 64 2c 20 2a 70 4c 72 75 54 61 69 6c 3b 20 20 20  d, *pLruTail;   
1560: 2f 2a 20 4c 52 55 20 6c 69 73 74 20 6f 66 20 75  /* LRU list of u
1570: 6e 70 69 6e 6e 65 64 20 70 61 67 65 73 20 2a 2f  npinned pages */
1580: 0a 7d 3b 0a 0a 2f 2a 20 45 61 63 68 20 70 61 67  .};../* Each pag
1590: 65 20 63 61 63 68 65 20 69 73 20 61 6e 20 69 6e  e cache is an in
15a0: 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f  stance of the fo
15b0: 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 2e 20  llowing object. 
15c0: 20 45 76 65 72 79 0a 2a 2a 20 6f 70 65 6e 20 64   Every.** open d
15d0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 28 69 6e  atabase file (in
15e0: 63 6c 75 64 69 6e 67 20 65 61 63 68 20 69 6e 2d  cluding each in-
15f0: 6d 65 6d 6f 72 79 20 64 61 74 61 62 61 73 65 20  memory database 
1600: 61 6e 64 20 65 61 63 68 0a 2a 2a 20 74 65 6d 70  and each.** temp
1610: 6f 72 61 72 79 20 6f 72 20 74 72 61 6e 73 69 65  orary or transie
1620: 6e 74 20 64 61 74 61 62 61 73 65 29 20 68 61 73  nt database) has
1630: 20 61 20 73 69 6e 67 6c 65 20 70 61 67 65 20 63   a single page c
1640: 61 63 68 65 20 77 68 69 63 68 0a 2a 2a 20 69 73  ache which.** is
1650: 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   an instance of 
1660: 74 68 69 73 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a  this object..**.
1670: 2a 2a 20 50 6f 69 6e 74 65 72 73 20 74 6f 20 73  ** Pointers to s
1680: 74 72 75 63 74 75 72 65 73 20 6f 66 20 74 68 69  tructures of thi
1690: 73 20 74 79 70 65 20 61 72 65 20 63 61 73 74 20  s type are cast 
16a0: 61 6e 64 20 72 65 74 75 72 6e 65 64 20 61 73 20  and returned as 
16b0: 0a 2a 2a 20 6f 70 61 71 75 65 20 73 71 6c 69 74  .** opaque sqlit
16c0: 65 33 5f 70 63 61 63 68 65 2a 20 68 61 6e 64 6c  e3_pcache* handl
16d0: 65 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 50 43  es..*/.struct PC
16e0: 61 63 68 65 31 20 7b 0a 20 20 2f 2a 20 43 61 63  ache1 {.  /* Cac
16f0: 68 65 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e  he configuration
1700: 20 70 61 72 61 6d 65 74 65 72 73 2e 20 50 61 67   parameters. Pag
1710: 65 20 73 69 7a 65 20 28 73 7a 50 61 67 65 29 20  e size (szPage) 
1720: 61 6e 64 20 74 68 65 20 70 75 72 67 65 61 62 6c  and the purgeabl
1730: 65 0a 20 20 2a 2a 20 66 6c 61 67 20 28 62 50 75  e.  ** flag (bPu
1740: 72 67 65 61 62 6c 65 29 20 61 72 65 20 73 65 74  rgeable) are set
1750: 20 77 68 65 6e 20 74 68 65 20 63 61 63 68 65 20   when the cache 
1760: 69 73 20 63 72 65 61 74 65 64 2e 20 6e 4d 61 78  is created. nMax
1770: 20 6d 61 79 20 62 65 20 0a 20 20 2a 2a 20 6d 6f   may be .  ** mo
1780: 64 69 66 69 65 64 20 61 74 20 61 6e 79 20 74 69  dified at any ti
1790: 6d 65 20 62 79 20 61 20 63 61 6c 6c 20 74 6f 20  me by a call to 
17a0: 74 68 65 20 70 63 61 63 68 65 31 43 61 63 68 65  the pcache1Cache
17b0: 73 69 7a 65 28 29 20 6d 65 74 68 6f 64 2e 0a 20  size() method.. 
17c0: 20 2a 2a 20 54 68 65 20 50 47 72 6f 75 70 20 6d   ** The PGroup m
17d0: 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c  utex must be hel
17e0: 64 20 77 68 65 6e 20 61 63 63 65 73 73 69 6e 67  d when accessing
17f0: 20 6e 4d 61 78 2e 0a 20 20 2a 2f 0a 20 20 50 47   nMax..  */.  PG
1800: 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20 20 20  roup *pGroup;   
1810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1820: 20 20 2f 2a 20 50 47 72 6f 75 70 20 74 68 69 73    /* PGroup this
1830: 20 63 61 63 68 65 20 62 65 6c 6f 6e 67 73 20 74   cache belongs t
1840: 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67  o */.  int szPag
1850: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
1860: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
1870: 7a 65 20 6f 66 20 64 61 74 61 62 61 73 65 20 63  ze of database c
1880: 6f 6e 74 65 6e 74 20 73 65 63 74 69 6f 6e 20 2a  ontent section *
1890: 2f 0a 20 20 69 6e 74 20 73 7a 45 78 74 72 61 3b  /.  int szExtra;
18a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18b0: 20 20 20 20 20 20 20 20 2f 2a 20 73 69 7a 65 6f          /* sizeo
18c0: 66 28 4d 65 6d 50 61 67 65 29 2b 73 69 7a 65 6f  f(MemPage)+sizeo
18d0: 66 28 50 67 48 64 72 29 20 2a 2f 0a 20 20 69 6e  f(PgHdr) */.  in
18e0: 74 20 73 7a 41 6c 6c 6f 63 3b 20 20 20 20 20 20  t szAlloc;      
18f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1900: 20 20 2f 2a 20 54 6f 74 61 6c 20 73 69 7a 65 20    /* Total size 
1910: 6f 66 20 6f 6e 65 20 70 63 61 63 68 65 20 6c 69  of one pcache li
1920: 6e 65 20 2a 2f 0a 20 20 69 6e 74 20 62 50 75 72  ne */.  int bPur
1930: 67 65 61 62 6c 65 3b 20 20 20 20 20 20 20 20 20  geable;         
1940: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1950: 72 75 65 20 69 66 20 63 61 63 68 65 20 69 73 20  rue if cache is 
1960: 70 75 72 67 65 61 62 6c 65 20 2a 2f 0a 20 20 75  purgeable */.  u
1970: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4d 69 6e  nsigned int nMin
1980: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1990: 20 20 20 2f 2a 20 4d 69 6e 69 6d 75 6d 20 6e 75     /* Minimum nu
19a0: 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20 72 65  mber of pages re
19b0: 73 65 72 76 65 64 20 2a 2f 0a 20 20 75 6e 73 69  served */.  unsi
19c0: 67 6e 65 64 20 69 6e 74 20 6e 4d 61 78 3b 20 20  gned int nMax;  
19d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19e0: 2f 2a 20 43 6f 6e 66 69 67 75 72 65 64 20 22 63  /* Configured "c
19f0: 61 63 68 65 5f 73 69 7a 65 22 20 76 61 6c 75 65  ache_size" value
1a00: 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69   */.  unsigned i
1a10: 6e 74 20 6e 39 30 70 63 74 3b 20 20 20 20 20 20  nt n90pct;      
1a20: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 4d 61            /* nMa
1a30: 78 2a 39 2f 31 30 20 2a 2f 0a 20 20 75 6e 73 69  x*9/10 */.  unsi
1a40: 67 6e 65 64 20 69 6e 74 20 69 4d 61 78 4b 65 79  gned int iMaxKey
1a50: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1a60: 2f 2a 20 4c 61 72 67 65 73 74 20 6b 65 79 20 73  /* Largest key s
1a70: 65 65 6e 20 73 69 6e 63 65 20 78 54 72 75 6e 63  een since xTrunc
1a80: 61 74 65 28 29 20 2a 2f 0a 0a 20 20 2f 2a 20 48  ate() */..  /* H
1a90: 61 73 68 20 74 61 62 6c 65 20 6f 66 20 61 6c 6c  ash table of all
1aa0: 20 70 61 67 65 73 2e 20 54 68 65 20 66 6f 6c 6c   pages. The foll
1ab0: 6f 77 69 6e 67 20 76 61 72 69 61 62 6c 65 73 20  owing variables 
1ac0: 6d 61 79 20 6f 6e 6c 79 20 62 65 20 61 63 63 65  may only be acce
1ad0: 73 73 65 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74  ssed.  ** when t
1ae0: 68 65 20 61 63 63 65 73 73 6f 72 20 69 73 20 68  he accessor is h
1af0: 6f 6c 64 69 6e 67 20 74 68 65 20 50 47 72 6f 75  olding the PGrou
1b00: 70 20 6d 75 74 65 78 2e 0a 20 20 2a 2f 0a 20 20  p mutex..  */.  
1b10: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 52 65  unsigned int nRe
1b20: 63 79 63 6c 61 62 6c 65 3b 20 20 20 20 20 20 20  cyclable;       
1b30: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
1b40: 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 4c 52   pages in the LR
1b50: 55 20 6c 69 73 74 20 2a 2f 0a 20 20 75 6e 73 69  U list */.  unsi
1b60: 67 6e 65 64 20 69 6e 74 20 6e 50 61 67 65 3b 20  gned int nPage; 
1b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b80: 2f 2a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20  /* Total number 
1b90: 6f 66 20 70 61 67 65 73 20 69 6e 20 61 70 48 61  of pages in apHa
1ba0: 73 68 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  sh */.  unsigned
1bb0: 20 69 6e 74 20 6e 48 61 73 68 3b 20 20 20 20 20   int nHash;     
1bc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
1bd0: 75 6d 62 65 72 20 6f 66 20 73 6c 6f 74 73 20 69  umber of slots i
1be0: 6e 20 61 70 48 61 73 68 5b 5d 20 2a 2f 0a 20 20  n apHash[] */.  
1bf0: 50 67 48 64 72 31 20 2a 2a 61 70 48 61 73 68 3b  PgHdr1 **apHash;
1c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c10: 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c      /* Hash tabl
1c20: 65 20 66 6f 72 20 66 61 73 74 20 6c 6f 6f 6b 75  e for fast looku
1c30: 70 20 62 79 20 6b 65 79 20 2a 2f 0a 20 20 50 67  p by key */.  Pg
1c40: 48 64 72 31 20 2a 70 46 72 65 65 3b 20 20 20 20  Hdr1 *pFree;    
1c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c60: 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20 75 6e 75    /* List of unu
1c70: 73 65 64 20 70 63 61 63 68 65 2d 6c 6f 63 61 6c  sed pcache-local
1c80: 20 70 61 67 65 73 20 2a 2f 0a 20 20 76 6f 69 64   pages */.  void
1c90: 20 2a 70 42 75 6c 6b 3b 20 20 20 20 20 20 20 20   *pBulk;        
1ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cb0: 2f 2a 20 42 75 6c 6b 20 6d 65 6d 6f 72 79 20 75  /* Bulk memory u
1cc0: 73 65 64 20 62 79 20 70 63 61 63 68 65 2d 6c 6f  sed by pcache-lo
1cd0: 63 61 6c 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  cal */.};../*.**
1ce0: 20 45 61 63 68 20 63 61 63 68 65 20 65 6e 74 72   Each cache entr
1cf0: 79 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64  y is represented
1d00: 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   by an instance 
1d10: 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
1d20: 20 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 2e 20   .** structure. 
1d30: 55 6e 6c 65 73 73 20 53 51 4c 49 54 45 5f 50 43  Unless SQLITE_PC
1d40: 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f 48 45  ACHE_SEPARATE_HE
1d50: 41 44 45 52 20 69 73 20 64 65 66 69 6e 65 64 2c  ADER is defined,
1d60: 20 61 20 62 75 66 66 65 72 20 6f 66 0a 2a 2a 20   a buffer of.** 
1d70: 50 67 48 64 72 31 2e 70 43 61 63 68 65 2d 3e 73  PgHdr1.pCache->s
1d80: 7a 50 61 67 65 20 62 79 74 65 73 20 69 73 20 61  zPage bytes is a
1d90: 6c 6c 6f 63 61 74 65 64 20 64 69 72 65 63 74 6c  llocated directl
1da0: 79 20 62 65 66 6f 72 65 20 74 68 69 73 20 73 74  y before this st
1db0: 72 75 63 74 75 72 65 20 0a 2a 2a 20 69 6e 20 6d  ructure .** in m
1dc0: 65 6d 6f 72 79 2e 0a 2a 2f 0a 73 74 72 75 63 74  emory..*/.struct
1dd0: 20 50 67 48 64 72 31 20 7b 0a 20 20 73 71 6c 69   PgHdr1 {.  sqli
1de0: 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20  te3_pcache_page 
1df0: 70 61 67 65 3b 0a 20 20 75 6e 73 69 67 6e 65 64  page;.  unsigned
1e00: 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20 20   int iKey;      
1e10: 20 20 20 20 20 20 20 2f 2a 20 4b 65 79 20 76 61         /* Key va
1e20: 6c 75 65 20 28 70 61 67 65 20 6e 75 6d 62 65 72  lue (page number
1e30: 29 20 2a 2f 0a 20 20 75 38 20 69 73 50 69 6e 6e  ) */.  u8 isPinn
1e40: 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ed;             
1e50: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 69 6e        /* Page in
1e60: 20 75 73 65 2c 20 6e 6f 74 20 6f 6e 20 74 68 65   use, not on the
1e70: 20 4c 52 55 20 6c 69 73 74 20 2a 2f 0a 20 20 75   LRU list */.  u
1e80: 38 20 69 73 42 75 6c 6b 4c 6f 63 61 6c 3b 20 20  8 isBulkLocal;  
1e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1ea0: 20 54 68 69 73 20 70 61 67 65 20 66 72 6f 6d 20   This page from 
1eb0: 62 75 6c 6b 20 6c 6f 63 61 6c 20 73 74 6f 72 61  bulk local stora
1ec0: 67 65 20 2a 2f 0a 20 20 50 67 48 64 72 31 20 2a  ge */.  PgHdr1 *
1ed0: 70 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20  pNext;          
1ee0: 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 69         /* Next i
1ef0: 6e 20 68 61 73 68 20 74 61 62 6c 65 20 63 68 61  n hash table cha
1f00: 69 6e 20 2a 2f 0a 20 20 50 43 61 63 68 65 31 20  in */.  PCache1 
1f10: 2a 70 43 61 63 68 65 3b 20 20 20 20 20 20 20 20  *pCache;        
1f20: 20 20 20 20 20 20 20 2f 2a 20 43 61 63 68 65 20         /* Cache 
1f30: 74 68 61 74 20 63 75 72 72 65 6e 74 6c 79 20 6f  that currently o
1f40: 77 6e 73 20 74 68 69 73 20 70 61 67 65 20 2a 2f  wns this page */
1f50: 0a 20 20 50 67 48 64 72 31 20 2a 70 4c 72 75 4e  .  PgHdr1 *pLruN
1f60: 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ext;            
1f70: 20 20 2f 2a 20 4e 65 78 74 20 69 6e 20 4c 52 55    /* Next in LRU
1f80: 20 6c 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65   list of unpinne
1f90: 64 20 70 61 67 65 73 20 2a 2f 0a 20 20 50 67 48  d pages */.  PgH
1fa0: 64 72 31 20 2a 70 4c 72 75 50 72 65 76 3b 20 20  dr1 *pLruPrev;  
1fb0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
1fc0: 72 65 76 69 6f 75 73 20 69 6e 20 4c 52 55 20 6c  revious in LRU l
1fd0: 69 73 74 20 6f 66 20 75 6e 70 69 6e 6e 65 64 20  ist of unpinned 
1fe0: 70 61 67 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  pages */.};../*.
1ff0: 2a 2a 20 46 72 65 65 20 73 6c 6f 74 73 20 69 6e  ** Free slots in
2000: 20 74 68 65 20 61 6c 6c 6f 63 61 74 6f 72 20 75   the allocator u
2010: 73 65 64 20 74 6f 20 64 69 76 69 64 65 20 75 70  sed to divide up
2020: 20 74 68 65 20 67 6c 6f 62 61 6c 20 70 61 67 65   the global page
2030: 20 63 61 63 68 65 0a 2a 2a 20 62 75 66 66 65 72   cache.** buffer
2040: 20 70 72 6f 76 69 64 65 64 20 75 73 69 6e 67 20   provided using 
2050: 74 68 65 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49  the SQLITE_CONFI
2060: 47 5f 50 41 47 45 43 41 43 48 45 20 6d 65 63 68  G_PAGECACHE mech
2070: 61 6e 69 73 6d 2e 0a 2a 2f 0a 73 74 72 75 63 74  anism..*/.struct
2080: 20 50 67 46 72 65 65 73 6c 6f 74 20 7b 0a 20 20   PgFreeslot {.  
2090: 50 67 46 72 65 65 73 6c 6f 74 20 2a 70 4e 65 78  PgFreeslot *pNex
20a0: 74 3b 20 20 2f 2a 20 4e 65 78 74 20 66 72 65 65  t;  /* Next free
20b0: 20 73 6c 6f 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a   slot */.};../*.
20c0: 2a 2a 20 47 6c 6f 62 61 6c 20 64 61 74 61 20 75  ** Global data u
20d0: 73 65 64 20 62 79 20 74 68 69 73 20 63 61 63 68  sed by this cach
20e0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 53 51 4c  e..*/.static SQL
20f0: 49 54 45 5f 57 53 44 20 73 74 72 75 63 74 20 50  ITE_WSD struct P
2100: 43 61 63 68 65 47 6c 6f 62 61 6c 20 7b 0a 20 20  CacheGlobal {.  
2110: 50 47 72 6f 75 70 20 67 72 70 3b 20 20 20 20 20  PGroup grp;     
2120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2130: 2a 20 54 68 65 20 67 6c 6f 62 61 6c 20 50 47 72  * The global PGr
2140: 6f 75 70 20 66 6f 72 20 6d 6f 64 65 20 28 32 29  oup for mode (2)
2150: 20 2a 2f 0a 0a 20 20 2f 2a 20 56 61 72 69 61 62   */..  /* Variab
2160: 6c 65 73 20 72 65 6c 61 74 65 64 20 74 6f 20 53  les related to S
2170: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
2180: 45 43 41 43 48 45 20 73 65 74 74 69 6e 67 73 2e  ECACHE settings.
2190: 20 20 54 68 65 0a 20 20 2a 2a 20 73 7a 53 6c 6f    The.  ** szSlo
21a0: 74 2c 20 6e 53 6c 6f 74 2c 20 70 53 74 61 72 74  t, nSlot, pStart
21b0: 2c 20 70 45 6e 64 2c 20 6e 52 65 73 65 72 76 65  , pEnd, nReserve
21c0: 2c 20 61 6e 64 20 69 73 49 6e 69 74 20 76 61 6c  , and isInit val
21d0: 75 65 73 20 61 72 65 20 61 6c 6c 0a 20 20 2a 2a  ues are all.  **
21e0: 20 66 69 78 65 64 20 61 74 20 73 71 6c 69 74 65   fixed at sqlite
21f0: 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 20 74  3_initialize() t
2200: 69 6d 65 20 61 6e 64 20 64 6f 20 6e 6f 74 20 72  ime and do not r
2210: 65 71 75 69 72 65 20 6d 75 74 65 78 20 70 72 6f  equire mutex pro
2220: 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2a 20 54 68  tection..  ** Th
2230: 65 20 6e 46 72 65 65 53 6c 6f 74 20 61 6e 64 20  e nFreeSlot and 
2240: 70 46 72 65 65 20 76 61 6c 75 65 73 20 64 6f 20  pFree values do 
2250: 72 65 71 75 69 72 65 20 6d 75 74 65 78 20 70 72  require mutex pr
2260: 6f 74 65 63 74 69 6f 6e 2e 0a 20 20 2a 2f 0a 20  otection..  */. 
2270: 20 69 6e 74 20 69 73 49 6e 69 74 3b 20 20 20 20   int isInit;    
2280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2290: 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 69 74 69  /* True if initi
22a0: 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 69 6e 74 20  alized */.  int 
22b0: 73 65 70 61 72 61 74 65 43 61 63 68 65 3b 20 20  separateCache;  
22c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
22d0: 65 20 61 20 6e 65 77 20 50 47 72 6f 75 70 20 66  e a new PGroup f
22e0: 6f 72 20 65 61 63 68 20 50 43 61 63 68 65 20 2a  or each PCache *
22f0: 2f 0a 20 20 69 6e 74 20 6e 49 6e 69 74 50 61 67  /.  int nInitPag
2300: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
2310: 20 20 20 2f 2a 20 49 6e 69 74 69 61 6c 20 62 75     /* Initial bu
2320: 6c 6b 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 73 69  lk allocation si
2330: 7a 65 20 2a 2f 20 20 20 0a 20 20 69 6e 74 20 73  ze */   .  int s
2340: 7a 53 6c 6f 74 3b 20 20 20 20 20 20 20 20 20 20  zSlot;          
2350: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
2360: 65 20 6f 66 20 65 61 63 68 20 66 72 65 65 20 73  e of each free s
2370: 6c 6f 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 6c  lot */.  int nSl
2380: 6f 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ot;             
2390: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6e          /* The n
23a0: 75 6d 62 65 72 20 6f 66 20 70 63 61 63 68 65 20  umber of pcache 
23b0: 73 6c 6f 74 73 20 2a 2f 0a 20 20 69 6e 74 20 6e  slots */.  int n
23c0: 52 65 73 65 72 76 65 3b 20 20 20 20 20 20 20 20  Reserve;        
23d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 79            /* Try
23e0: 20 74 6f 20 6b 65 65 70 20 6e 46 72 65 65 53 6c   to keep nFreeSl
23f0: 6f 74 20 61 62 6f 76 65 20 74 68 69 73 20 2a 2f  ot above this */
2400: 0a 20 20 76 6f 69 64 20 2a 70 53 74 61 72 74 2c  .  void *pStart,
2410: 20 2a 70 45 6e 64 3b 20 20 20 20 20 20 20 20 20   *pEnd;         
2420: 20 20 2f 2a 20 42 6f 75 6e 64 73 20 6f 66 20 67    /* Bounds of g
2430: 6c 6f 62 61 6c 20 70 61 67 65 20 63 61 63 68 65  lobal page cache
2440: 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 2f 2a 20   memory */.  /* 
2450: 41 62 6f 76 65 20 72 65 71 75 69 72 65 73 20 6e  Above requires n
2460: 6f 20 6d 75 74 65 78 2e 20 20 55 73 65 20 6d 75  o mutex.  Use mu
2470: 74 65 78 20 62 65 6c 6f 77 20 66 6f 72 20 76 61  tex below for va
2480: 72 69 61 62 6c 65 20 74 68 61 74 20 66 6f 6c 6c  riable that foll
2490: 6f 77 2e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ow. */.  sqlite3
24a0: 5f 6d 75 74 65 78 20 2a 6d 75 74 65 78 3b 20 20  _mutex *mutex;  
24b0: 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 74 65 78          /* Mutex
24c0: 20 66 6f 72 20 61 63 63 65 73 73 69 6e 67 20 74   for accessing t
24d0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 3a 20 2a 2f  he following: */
24e0: 0a 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70  .  PgFreeslot *p
24f0: 46 72 65 65 3b 20 20 20 20 20 20 20 20 20 20 20  Free;           
2500: 20 20 2f 2a 20 46 72 65 65 20 70 61 67 65 20 62    /* Free page b
2510: 6c 6f 63 6b 73 20 2a 2f 0a 20 20 69 6e 74 20 6e  locks */.  int n
2520: 46 72 65 65 53 6c 6f 74 3b 20 20 20 20 20 20 20  FreeSlot;       
2530: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
2540: 62 65 72 20 6f 66 20 75 6e 75 73 65 64 20 70 63  ber of unused pc
2550: 61 63 68 65 20 73 6c 6f 74 73 20 2a 2f 0a 20 20  ache slots */.  
2560: 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  /* The following
2570: 20 76 61 6c 75 65 20 72 65 71 75 69 72 65 73 20   value requires 
2580: 61 20 6d 75 74 65 78 20 74 6f 20 63 68 61 6e 67  a mutex to chang
2590: 65 2e 20 20 57 65 20 73 6b 69 70 20 74 68 65 20  e.  We skip the 
25a0: 6d 75 74 65 78 20 6f 6e 0a 20 20 2a 2a 20 72 65  mutex on.  ** re
25b0: 61 64 69 6e 67 20 62 65 63 61 75 73 65 20 28 31  ading because (1
25c0: 29 20 6d 6f 73 74 20 70 6c 61 74 66 6f 72 6d 73  ) most platforms
25d0: 20 72 65 61 64 20 61 20 33 32 2d 62 69 74 20 69   read a 32-bit i
25e0: 6e 74 65 67 65 72 20 61 74 6f 6d 69 63 61 6c 6c  nteger atomicall
25f0: 79 20 61 6e 64 0a 20 20 2a 2a 20 28 32 29 20 65  y and.  ** (2) e
2600: 76 65 6e 20 69 66 20 61 6e 20 69 6e 63 6f 72 72  ven if an incorr
2610: 65 63 74 20 76 61 6c 75 65 20 69 73 20 72 65 61  ect value is rea
2620: 64 2c 20 6e 6f 20 67 72 65 61 74 20 68 61 72 6d  d, no great harm
2630: 20 69 73 20 64 6f 6e 65 20 73 69 6e 63 65 20 74   is done since t
2640: 68 69 73 0a 20 20 2a 2a 20 69 73 20 72 65 61 6c  his.  ** is real
2650: 6c 79 20 6a 75 73 74 20 61 6e 20 6f 70 74 69 6d  ly just an optim
2660: 69 7a 61 74 69 6f 6e 2e 20 2a 2f 0a 20 20 69 6e  ization. */.  in
2670: 74 20 62 55 6e 64 65 72 50 72 65 73 73 75 72 65  t bUnderPressure
2680: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
2690: 54 72 75 65 20 69 66 20 6c 6f 77 20 6f 6e 20 50  True if low on P
26a0: 41 47 45 43 41 43 48 45 20 6d 65 6d 6f 72 79 20  AGECACHE memory 
26b0: 2a 2f 0a 7d 20 70 63 61 63 68 65 31 5f 67 3b 0a  */.} pcache1_g;.
26c0: 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 63 6f 64 65 20  ./*.** All code 
26d0: 69 6e 20 74 68 69 73 20 66 69 6c 65 20 73 68 6f  in this file sho
26e0: 75 6c 64 20 61 63 63 65 73 73 20 74 68 65 20 67  uld access the g
26f0: 6c 6f 62 61 6c 20 73 74 72 75 63 74 75 72 65 20  lobal structure 
2700: 61 62 6f 76 65 20 76 69 61 20 74 68 65 0a 2a 2a  above via the.**
2710: 20 61 6c 69 61 73 20 22 70 63 61 63 68 65 31 22   alias "pcache1"
2720: 2e 20 54 68 69 73 20 65 6e 73 75 72 65 73 20 74  . This ensures t
2730: 68 61 74 20 74 68 65 20 57 53 44 20 65 6d 75 6c  hat the WSD emul
2740: 61 74 69 6f 6e 20 69 73 20 75 73 65 64 20 77 68  ation is used wh
2750: 65 6e 0a 2a 2a 20 63 6f 6d 70 69 6c 69 6e 67 20  en.** compiling 
2760: 66 6f 72 20 73 79 73 74 65 6d 73 20 74 68 61 74  for systems that
2770: 20 64 6f 20 6e 6f 74 20 73 75 70 70 6f 72 74 20   do not support 
2780: 72 65 61 6c 20 57 53 44 2e 0a 2a 2f 0a 23 64 65  real WSD..*/.#de
2790: 66 69 6e 65 20 70 63 61 63 68 65 31 20 28 47 4c  fine pcache1 (GL
27a0: 4f 42 41 4c 28 73 74 72 75 63 74 20 50 43 61 63  OBAL(struct PCac
27b0: 68 65 47 6c 6f 62 61 6c 2c 20 70 63 61 63 68 65  heGlobal, pcache
27c0: 31 5f 67 29 29 0a 0a 2f 2a 0a 2a 2a 20 4d 61 63  1_g))../*.** Mac
27d0: 72 6f 73 20 74 6f 20 65 6e 74 65 72 20 61 6e 64  ros to enter and
27e0: 20 6c 65 61 76 65 20 74 68 65 20 50 43 61 63 68   leave the PCach
27f0: 65 20 4c 52 55 20 6d 75 74 65 78 2e 0a 2a 2f 0a  e LRU mutex..*/.
2800: 23 69 66 20 21 64 65 66 69 6e 65 64 28 53 51 4c  #if !defined(SQL
2810: 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52  ITE_ENABLE_MEMOR
2820: 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 29 20 7c 7c  Y_MANAGEMENT) ||
2830: 20 53 51 4c 49 54 45 5f 54 48 52 45 41 44 53 41   SQLITE_THREADSA
2840: 46 45 3d 3d 30 0a 23 20 64 65 66 69 6e 65 20 70  FE==0.# define p
2850: 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78  cache1EnterMutex
2860: 28 58 29 20 20 61 73 73 65 72 74 28 28 58 29 2d  (X)  assert((X)-
2870: 3e 6d 75 74 65 78 3d 3d 30 29 0a 23 20 64 65 66  >mutex==0).# def
2880: 69 6e 65 20 70 63 61 63 68 65 31 4c 65 61 76 65  ine pcache1Leave
2890: 4d 75 74 65 78 28 58 29 20 20 61 73 73 65 72 74  Mutex(X)  assert
28a0: 28 28 58 29 2d 3e 6d 75 74 65 78 3d 3d 30 29 0a  ((X)->mutex==0).
28b0: 23 20 64 65 66 69 6e 65 20 50 43 41 43 48 45 31  # define PCACHE1
28c0: 5f 4d 49 47 48 54 5f 55 53 45 5f 47 52 4f 55 50  _MIGHT_USE_GROUP
28d0: 5f 4d 55 54 45 58 20 30 0a 23 65 6c 73 65 0a 23  _MUTEX 0.#else.#
28e0: 20 64 65 66 69 6e 65 20 70 63 61 63 68 65 31 45   define pcache1E
28f0: 6e 74 65 72 4d 75 74 65 78 28 58 29 20 73 71 6c  nterMutex(X) sql
2900: 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72  ite3_mutex_enter
2910: 28 28 58 29 2d 3e 6d 75 74 65 78 29 0a 23 20 64  ((X)->mutex).# d
2920: 65 66 69 6e 65 20 70 63 61 63 68 65 31 4c 65 61  efine pcache1Lea
2930: 76 65 4d 75 74 65 78 28 58 29 20 73 71 6c 69 74  veMutex(X) sqlit
2940: 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 28  e3_mutex_leave((
2950: 58 29 2d 3e 6d 75 74 65 78 29 0a 23 20 64 65 66  X)->mutex).# def
2960: 69 6e 65 20 50 43 41 43 48 45 31 5f 4d 49 47 48  ine PCACHE1_MIGH
2970: 54 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55 54 45  T_USE_GROUP_MUTE
2980: 58 20 31 0a 23 65 6e 64 69 66 0a 0a 2f 2a 2a 2a  X 1.#endif../***
2990: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 2a  ***********/./**
29e0: 2a 2a 2a 2a 2a 2a 20 50 61 67 65 20 41 6c 6c 6f  ****** Page Allo
29f0: 63 61 74 69 6f 6e 2f 53 51 4c 49 54 45 5f 43 4f  cation/SQLITE_CO
2a00: 4e 46 49 47 5f 50 43 41 43 48 45 20 52 65 6c 61  NFIG_PCACHE Rela
2a10: 74 65 64 20 46 75 6e 63 74 69 6f 6e 73 20 2a 2a  ted Functions **
2a20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f  ************/../
2a30: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
2a40: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 64 75 72  on is called dur
2a50: 69 6e 67 20 69 6e 69 74 69 61 6c 69 7a 61 74 69  ing initializati
2a60: 6f 6e 20 69 66 20 61 20 73 74 61 74 69 63 20 62  on if a static b
2a70: 75 66 66 65 72 20 69 73 20 0a 2a 2a 20 73 75 70  uffer is .** sup
2a80: 70 6c 69 65 64 20 74 6f 20 75 73 65 20 66 6f 72  plied to use for
2a90: 20 74 68 65 20 70 61 67 65 2d 63 61 63 68 65 20   the page-cache 
2aa0: 62 79 20 70 61 73 73 69 6e 67 20 74 68 65 20 53  by passing the S
2ab0: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
2ac0: 45 43 41 43 48 45 0a 2a 2a 20 76 65 72 62 20 74  ECACHE.** verb t
2ad0: 6f 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  o sqlite3_config
2ae0: 28 29 2e 20 50 61 72 61 6d 65 74 65 72 20 70 42  (). Parameter pB
2af0: 75 66 20 70 6f 69 6e 74 73 20 74 6f 20 61 6e 20  uf points to an 
2b00: 61 6c 6c 6f 63 61 74 69 6f 6e 20 6c 61 72 67 65  allocation large
2b10: 0a 2a 2a 20 65 6e 6f 75 67 68 20 74 6f 20 63 6f  .** enough to co
2b20: 6e 74 61 69 6e 20 27 6e 27 20 62 75 66 66 65 72  ntain 'n' buffer
2b30: 73 20 6f 66 20 27 73 7a 27 20 62 79 74 65 73 20  s of 'sz' bytes 
2b40: 65 61 63 68 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  each..**.** This
2b50: 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c   routine is call
2b60: 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 5f  ed from sqlite3_
2b70: 69 6e 69 74 69 61 6c 69 7a 65 28 29 20 61 6e 64  initialize() and
2b80: 20 73 6f 20 69 74 20 69 73 20 67 75 61 72 61 6e   so it is guaran
2b90: 74 65 65 64 0a 2a 2a 20 74 6f 20 62 65 20 73 65  teed.** to be se
2ba0: 72 69 61 6c 69 7a 65 64 20 61 6c 72 65 61 64 79  rialized already
2bb0: 2e 20 20 54 68 65 72 65 20 69 73 20 6e 6f 20 6e  .  There is no n
2bc0: 65 65 64 20 66 6f 72 20 66 75 72 74 68 65 72 20  eed for further 
2bd0: 6d 75 74 65 78 69 6e 67 2e 0a 2a 2f 0a 76 6f 69  mutexing..*/.voi
2be0: 64 20 73 71 6c 69 74 65 33 50 43 61 63 68 65 42  d sqlite3PCacheB
2bf0: 75 66 66 65 72 53 65 74 75 70 28 76 6f 69 64 20  ufferSetup(void 
2c00: 2a 70 42 75 66 2c 20 69 6e 74 20 73 7a 2c 20 69  *pBuf, int sz, i
2c10: 6e 74 20 6e 29 7b 0a 20 20 69 66 28 20 70 63 61  nt n){.  if( pca
2c20: 63 68 65 31 2e 69 73 49 6e 69 74 20 29 7b 0a 20  che1.isInit ){. 
2c30: 20 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a 70     PgFreeslot *p
2c40: 3b 0a 20 20 20 20 69 66 28 20 70 42 75 66 3d 3d  ;.    if( pBuf==
2c50: 30 20 29 20 73 7a 20 3d 20 6e 20 3d 20 30 3b 0a  0 ) sz = n = 0;.
2c60: 20 20 20 20 73 7a 20 3d 20 52 4f 55 4e 44 44 4f      sz = ROUNDDO
2c70: 57 4e 38 28 73 7a 29 3b 0a 20 20 20 20 70 63 61  WN8(sz);.    pca
2c80: 63 68 65 31 2e 73 7a 53 6c 6f 74 20 3d 20 73 7a  che1.szSlot = sz
2c90: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 2e 6e 53  ;.    pcache1.nS
2ca0: 6c 6f 74 20 3d 20 70 63 61 63 68 65 31 2e 6e 46  lot = pcache1.nF
2cb0: 72 65 65 53 6c 6f 74 20 3d 20 6e 3b 0a 20 20 20  reeSlot = n;.   
2cc0: 20 70 63 61 63 68 65 31 2e 6e 52 65 73 65 72 76   pcache1.nReserv
2cd0: 65 20 3d 20 6e 3e 39 30 20 3f 20 31 30 20 3a 20  e = n>90 ? 10 : 
2ce0: 28 6e 2f 31 30 20 2b 20 31 29 3b 0a 20 20 20 20  (n/10 + 1);.    
2cf0: 70 63 61 63 68 65 31 2e 70 53 74 61 72 74 20 3d  pcache1.pStart =
2d00: 20 70 42 75 66 3b 0a 20 20 20 20 70 63 61 63 68   pBuf;.    pcach
2d10: 65 31 2e 70 46 72 65 65 20 3d 20 30 3b 0a 20 20  e1.pFree = 0;.  
2d20: 20 20 70 63 61 63 68 65 31 2e 62 55 6e 64 65 72    pcache1.bUnder
2d30: 50 72 65 73 73 75 72 65 20 3d 20 30 3b 0a 20 20  Pressure = 0;.  
2d40: 20 20 77 68 69 6c 65 28 20 6e 2d 2d 20 29 7b 0a    while( n-- ){.
2d50: 20 20 20 20 20 20 70 20 3d 20 28 50 67 46 72 65        p = (PgFre
2d60: 65 73 6c 6f 74 2a 29 70 42 75 66 3b 0a 20 20 20  eslot*)pBuf;.   
2d70: 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 70 63     p->pNext = pc
2d80: 61 63 68 65 31 2e 70 46 72 65 65 3b 0a 20 20 20  ache1.pFree;.   
2d90: 20 20 20 70 63 61 63 68 65 31 2e 70 46 72 65 65     pcache1.pFree
2da0: 20 3d 20 70 3b 0a 20 20 20 20 20 20 70 42 75 66   = p;.      pBuf
2db0: 20 3d 20 28 76 6f 69 64 2a 29 26 28 28 63 68 61   = (void*)&((cha
2dc0: 72 2a 29 70 42 75 66 29 5b 73 7a 5d 3b 0a 20 20  r*)pBuf)[sz];.  
2dd0: 20 20 7d 0a 20 20 20 20 70 63 61 63 68 65 31 2e    }.    pcache1.
2de0: 70 45 6e 64 20 3d 20 70 42 75 66 3b 0a 20 20 7d  pEnd = pBuf;.  }
2df0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74 6f  .}../*.** Try to
2e00: 20 69 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20   initialize the 
2e10: 70 43 61 63 68 65 2d 3e 70 46 72 65 65 20 61 6e  pCache->pFree an
2e20: 64 20 70 43 61 63 68 65 2d 3e 70 42 75 6c 6b 20  d pCache->pBulk 
2e30: 66 69 65 6c 64 73 2e 20 20 52 65 74 75 72 6e 0a  fields.  Return.
2e40: 2a 2a 20 74 72 75 65 20 69 66 20 70 43 61 63 68  ** true if pCach
2e50: 65 2d 3e 70 46 72 65 65 20 65 6e 64 73 20 75 70  e->pFree ends up
2e60: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 6f 6e 65 20   containing one 
2e70: 6f 72 20 6d 6f 72 65 20 66 72 65 65 20 70 61 67  or more free pag
2e80: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  es..*/.static in
2e90: 74 20 70 63 61 63 68 65 31 49 6e 69 74 42 75 6c  t pcache1InitBul
2ea0: 6b 28 50 43 61 63 68 65 31 20 2a 70 43 61 63 68  k(PCache1 *pCach
2eb0: 65 29 7b 0a 20 20 69 36 34 20 73 7a 42 75 6c 6b  e){.  i64 szBulk
2ec0: 3b 0a 20 20 63 68 61 72 20 2a 7a 42 75 6c 6b 3b  ;.  char *zBulk;
2ed0: 0a 20 20 69 66 28 20 70 63 61 63 68 65 31 2e 6e  .  if( pcache1.n
2ee0: 49 6e 69 74 50 61 67 65 3d 3d 30 20 29 20 72 65  InitPage==0 ) re
2ef0: 74 75 72 6e 20 30 3b 0a 20 20 2f 2a 20 44 6f 20  turn 0;.  /* Do 
2f00: 6e 6f 74 20 62 6f 74 68 65 72 20 77 69 74 68 20  not bother with 
2f10: 61 20 62 75 6c 6b 20 61 6c 6c 6f 63 61 74 69 6f  a bulk allocatio
2f20: 6e 20 69 66 20 74 68 65 20 63 61 63 68 65 20 73  n if the cache s
2f30: 69 7a 65 20 76 65 72 79 20 73 6d 61 6c 6c 20 2a  ize very small *
2f40: 2f 0a 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e  /.  if( pCache->
2f50: 6e 4d 61 78 3c 33 20 29 20 72 65 74 75 72 6e 20  nMax<3 ) return 
2f60: 30 3b 0a 20 20 73 71 6c 69 74 65 33 42 65 67 69  0;.  sqlite3Begi
2f70: 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  nBenignMalloc();
2f80: 0a 20 20 69 66 28 20 70 63 61 63 68 65 31 2e 6e  .  if( pcache1.n
2f90: 49 6e 69 74 50 61 67 65 3e 30 20 29 7b 0a 20 20  InitPage>0 ){.  
2fa0: 20 20 73 7a 42 75 6c 6b 20 3d 20 70 43 61 63 68    szBulk = pCach
2fb0: 65 2d 3e 73 7a 41 6c 6c 6f 63 20 2a 20 28 69 36  e->szAlloc * (i6
2fc0: 34 29 70 63 61 63 68 65 31 2e 6e 49 6e 69 74 50  4)pcache1.nInitP
2fd0: 61 67 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  age;.  }else{.  
2fe0: 20 20 73 7a 42 75 6c 6b 20 3d 20 2d 31 30 32 34    szBulk = -1024
2ff0: 20 2a 20 28 69 36 34 29 70 63 61 63 68 65 31 2e   * (i64)pcache1.
3000: 6e 49 6e 69 74 50 61 67 65 3b 0a 20 20 7d 0a 20  nInitPage;.  }. 
3010: 20 69 66 28 20 73 7a 42 75 6c 6b 20 3e 20 70 43   if( szBulk > pC
3020: 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 2a 28 69  ache->szAlloc*(i
3030: 36 34 29 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20  64)pCache->nMax 
3040: 29 7b 0a 20 20 20 20 73 7a 42 75 6c 6b 20 3d 20  ){.    szBulk = 
3050: 70 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 2a  pCache->szAlloc*
3060: 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20  pCache->nMax;.  
3070: 7d 0a 20 20 7a 42 75 6c 6b 20 3d 20 70 43 61 63  }.  zBulk = pCac
3080: 68 65 2d 3e 70 42 75 6c 6b 20 3d 20 73 71 6c 69  he->pBulk = sqli
3090: 74 65 33 4d 61 6c 6c 6f 63 28 20 73 7a 42 75 6c  te3Malloc( szBul
30a0: 6b 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 45 6e  k );.  sqlite3En
30b0: 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  dBenignMalloc();
30c0: 0a 20 20 69 66 28 20 7a 42 75 6c 6b 20 29 7b 0a  .  if( zBulk ){.
30d0: 20 20 20 20 69 6e 74 20 6e 42 75 6c 6b 20 3d 20      int nBulk = 
30e0: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a  sqlite3MallocSiz
30f0: 65 28 7a 42 75 6c 6b 29 2f 70 43 61 63 68 65 2d  e(zBulk)/pCache-
3100: 3e 73 7a 41 6c 6c 6f 63 3b 0a 20 20 20 20 69 6e  >szAlloc;.    in
3110: 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  t i;.    for(i=0
3120: 3b 20 69 3c 6e 42 75 6c 6b 3b 20 69 2b 2b 29 7b  ; i<nBulk; i++){
3130: 0a 20 20 20 20 20 20 50 67 48 64 72 31 20 2a 70  .      PgHdr1 *p
3140: 58 20 3d 20 28 50 67 48 64 72 31 2a 29 26 7a 42  X = (PgHdr1*)&zB
3150: 75 6c 6b 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61  ulk[pCache->szPa
3160: 67 65 5d 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70  ge];.      pX->p
3170: 61 67 65 2e 70 42 75 66 20 3d 20 7a 42 75 6c 6b  age.pBuf = zBulk
3180: 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70 61 67 65  ;.      pX->page
3190: 2e 70 45 78 74 72 61 20 3d 20 26 70 58 5b 31 5d  .pExtra = &pX[1]
31a0: 3b 0a 20 20 20 20 20 20 70 58 2d 3e 69 73 42 75  ;.      pX->isBu
31b0: 6c 6b 4c 6f 63 61 6c 20 3d 20 31 3b 0a 20 20 20  lkLocal = 1;.   
31c0: 20 20 20 70 58 2d 3e 70 4e 65 78 74 20 3d 20 70     pX->pNext = p
31d0: 43 61 63 68 65 2d 3e 70 46 72 65 65 3b 0a 20 20  Cache->pFree;.  
31e0: 20 20 20 20 70 43 61 63 68 65 2d 3e 70 46 72 65      pCache->pFre
31f0: 65 20 3d 20 70 58 3b 0a 20 20 20 20 20 20 7a 42  e = pX;.      zB
3200: 75 6c 6b 20 2b 3d 20 70 43 61 63 68 65 2d 3e 73  ulk += pCache->s
3210: 7a 41 6c 6c 6f 63 3b 0a 20 20 20 20 7d 0a 20 20  zAlloc;.    }.  
3220: 7d 0a 20 20 72 65 74 75 72 6e 20 70 43 61 63 68  }.  return pCach
3230: 65 2d 3e 70 46 72 65 65 21 3d 30 3b 0a 7d 0a 0a  e->pFree!=0;.}..
3240: 2f 2a 0a 2a 2a 20 4d 61 6c 6c 6f 63 20 66 75 6e  /*.** Malloc fun
3250: 63 74 69 6f 6e 20 75 73 65 64 20 77 69 74 68 69  ction used withi
3260: 6e 20 74 68 69 73 20 66 69 6c 65 20 74 6f 20 61  n this file to a
3270: 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66 72  llocate space fr
3280: 6f 6d 20 74 68 65 20 62 75 66 66 65 72 0a 2a 2a  om the buffer.**
3290: 20 63 6f 6e 66 69 67 75 72 65 64 20 75 73 69 6e   configured usin
32a0: 67 20 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67  g sqlite3_config
32b0: 28 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50  (SQLITE_CONFIG_P
32c0: 41 47 45 43 41 43 48 45 29 20 6f 70 74 69 6f 6e  AGECACHE) option
32d0: 2e 20 49 66 20 6e 6f 20 0a 2a 2a 20 73 75 63 68  . If no .** such
32e0: 20 62 75 66 66 65 72 20 65 78 69 73 74 73 20 6f   buffer exists o
32f0: 72 20 74 68 65 72 65 20 69 73 20 6e 6f 20 73 70  r there is no sp
3300: 61 63 65 20 6c 65 66 74 20 69 6e 20 69 74 2c 20  ace left in it, 
3310: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 61  this function fa
3320: 6c 6c 73 20 0a 2a 2a 20 62 61 63 6b 20 74 6f 20  lls .** back to 
3330: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 28 29 2e  sqlite3Malloc().
3340: 0a 2a 2a 0a 2a 2a 20 4d 75 6c 74 69 70 6c 65 20  .**.** Multiple 
3350: 74 68 72 65 61 64 73 20 63 61 6e 20 72 75 6e 20  threads can run 
3360: 74 68 69 73 20 72 6f 75 74 69 6e 65 20 61 74 20  this routine at 
3370: 74 68 65 20 73 61 6d 65 20 74 69 6d 65 2e 20 20  the same time.  
3380: 47 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73  Global variables
3390: 0a 2a 2a 20 69 6e 20 70 63 61 63 68 65 31 20 6e  .** in pcache1 n
33a0: 65 65 64 20 74 6f 20 62 65 20 70 72 6f 74 65 63  eed to be protec
33b0: 74 65 64 20 76 69 61 20 6d 75 74 65 78 2e 0a 2a  ted via mutex..*
33c0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a 70  /.static void *p
33d0: 63 61 63 68 65 31 41 6c 6c 6f 63 28 69 6e 74 20  cache1Alloc(int 
33e0: 6e 42 79 74 65 29 7b 0a 20 20 76 6f 69 64 20 2a  nByte){.  void *
33f0: 70 20 3d 20 30 3b 0a 20 20 61 73 73 65 72 74 28  p = 0;.  assert(
3400: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6e   sqlite3_mutex_n
3410: 6f 74 68 65 6c 64 28 70 63 61 63 68 65 31 2e 67  otheld(pcache1.g
3420: 72 70 2e 6d 75 74 65 78 29 20 29 3b 0a 20 20 69  rp.mutex) );.  i
3430: 66 28 20 6e 42 79 74 65 3c 3d 70 63 61 63 68 65  f( nByte<=pcache
3440: 31 2e 73 7a 53 6c 6f 74 20 29 7b 0a 20 20 20 20  1.szSlot ){.    
3450: 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e  sqlite3_mutex_en
3460: 74 65 72 28 70 63 61 63 68 65 31 2e 6d 75 74 65  ter(pcache1.mute
3470: 78 29 3b 0a 20 20 20 20 70 20 3d 20 28 50 67 48  x);.    p = (PgH
3480: 64 72 31 20 2a 29 70 63 61 63 68 65 31 2e 70 46  dr1 *)pcache1.pF
3490: 72 65 65 3b 0a 20 20 20 20 69 66 28 20 70 20 29  ree;.    if( p )
34a0: 7b 0a 20 20 20 20 20 20 70 63 61 63 68 65 31 2e  {.      pcache1.
34b0: 70 46 72 65 65 20 3d 20 70 63 61 63 68 65 31 2e  pFree = pcache1.
34c0: 70 46 72 65 65 2d 3e 70 4e 65 78 74 3b 0a 20 20  pFree->pNext;.  
34d0: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65      pcache1.nFre
34e0: 65 53 6c 6f 74 2d 2d 3b 0a 20 20 20 20 20 20 70  eSlot--;.      p
34f0: 63 61 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65  cache1.bUnderPre
3500: 73 73 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e  ssure = pcache1.
3510: 6e 46 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65  nFreeSlot<pcache
3520: 31 2e 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20  1.nReserve;.    
3530: 20 20 61 73 73 65 72 74 28 20 70 63 61 63 68 65    assert( pcache
3540: 31 2e 6e 46 72 65 65 53 6c 6f 74 3e 3d 30 20 29  1.nFreeSlot>=0 )
3550: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 53  ;.      sqlite3S
3560: 74 61 74 75 73 53 65 74 28 53 51 4c 49 54 45 5f  tatusSet(SQLITE_
3570: 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48 45  STATUS_PAGECACHE
3580: 5f 53 49 5a 45 2c 20 6e 42 79 74 65 29 3b 0a 20  _SIZE, nByte);. 
3590: 20 20 20 20 20 73 71 6c 69 74 65 33 53 74 61 74       sqlite3Stat
35a0: 75 73 55 70 28 53 51 4c 49 54 45 5f 53 54 41 54  usUp(SQLITE_STAT
35b0: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45  US_PAGECACHE_USE
35c0: 44 2c 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20 20  D, 1);.    }.   
35d0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c   sqlite3_mutex_l
35e0: 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74  eave(pcache1.mut
35f0: 65 78 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70  ex);.  }.  if( p
3600: 3d 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20 4d 65  ==0 ){.    /* Me
3610: 6d 6f 72 79 20 69 73 20 6e 6f 74 20 61 76 61 69  mory is not avai
3620: 6c 61 62 6c 65 20 69 6e 20 74 68 65 20 53 51 4c  lable in the SQL
3630: 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43  ITE_CONFIG_PAGEC
3640: 41 43 48 45 20 70 6f 6f 6c 2e 20 20 47 65 74 0a  ACHE pool.  Get.
3650: 20 20 20 20 2a 2a 20 69 74 20 66 72 6f 6d 20 73      ** it from s
3660: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 20 69 6e 73  qlite3Malloc ins
3670: 74 65 61 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  tead..    */.   
3680: 20 70 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c   p = sqlite3Mall
3690: 6f 63 28 6e 42 79 74 65 29 3b 0a 23 69 66 6e 64  oc(nByte);.#ifnd
36a0: 65 66 20 53 51 4c 49 54 45 5f 44 49 53 41 42 4c  ef SQLITE_DISABL
36b0: 45 5f 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52  E_PAGECACHE_OVER
36c0: 46 4c 4f 57 5f 53 54 41 54 53 0a 20 20 20 20 69  FLOW_STATS.    i
36d0: 66 28 20 70 20 29 7b 0a 20 20 20 20 20 20 69 6e  f( p ){.      in
36e0: 74 20 73 7a 20 3d 20 73 71 6c 69 74 65 33 4d 61  t sz = sqlite3Ma
36f0: 6c 6c 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20  llocSize(p);.   
3700: 20 20 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78     sqlite3_mutex
3710: 5f 65 6e 74 65 72 28 70 63 61 63 68 65 31 2e 6d  _enter(pcache1.m
3720: 75 74 65 78 29 3b 0a 20 20 20 20 20 20 73 71 6c  utex);.      sql
3730: 69 74 65 33 53 74 61 74 75 73 53 65 74 28 53 51  ite3StatusSet(SQ
3740: 4c 49 54 45 5f 53 54 41 54 55 53 5f 50 41 47 45  LITE_STATUS_PAGE
3750: 43 41 43 48 45 5f 53 49 5a 45 2c 20 6e 42 79 74  CACHE_SIZE, nByt
3760: 65 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  e);.      sqlite
3770: 33 53 74 61 74 75 73 55 70 28 53 51 4c 49 54 45  3StatusUp(SQLITE
3780: 5f 53 54 41 54 55 53 5f 50 41 47 45 43 41 43 48  _STATUS_PAGECACH
3790: 45 5f 4f 56 45 52 46 4c 4f 57 2c 20 73 7a 29 3b  E_OVERFLOW, sz);
37a0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d  .      sqlite3_m
37b0: 75 74 65 78 5f 6c 65 61 76 65 28 70 63 61 63 68  utex_leave(pcach
37c0: 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20 7d  e1.mutex);.    }
37d0: 0a 23 65 6e 64 69 66 0a 20 20 20 20 73 71 6c 69  .#endif.    sqli
37e0: 74 65 33 4d 65 6d 64 65 62 75 67 53 65 74 54 79  te3MemdebugSetTy
37f0: 70 65 28 70 2c 20 4d 45 4d 54 59 50 45 5f 50 43  pe(p, MEMTYPE_PC
3800: 41 43 48 45 29 3b 0a 20 20 7d 0a 20 20 72 65 74  ACHE);.  }.  ret
3810: 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn p;.}../*.** 
3820: 46 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61 74 65  Free an allocate
3830: 64 20 62 75 66 66 65 72 20 6f 62 74 61 69 6e 65  d buffer obtaine
3840: 64 20 66 72 6f 6d 20 70 63 61 63 68 65 31 41 6c  d from pcache1Al
3850: 6c 6f 63 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  loc()..*/.static
3860: 20 76 6f 69 64 20 70 63 61 63 68 65 31 46 72 65   void pcache1Fre
3870: 65 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 69 6e  e(void *p){.  in
3880: 74 20 6e 46 72 65 65 64 20 3d 20 30 3b 0a 20 20  t nFreed = 0;.  
3890: 69 66 28 20 70 3d 3d 30 20 29 20 72 65 74 75 72  if( p==0 ) retur
38a0: 6e 3b 0a 20 20 69 66 28 20 70 3e 3d 70 63 61 63  n;.  if( p>=pcac
38b0: 68 65 31 2e 70 53 74 61 72 74 20 26 26 20 70 3c  he1.pStart && p<
38c0: 70 63 61 63 68 65 31 2e 70 45 6e 64 20 29 7b 0a  pcache1.pEnd ){.
38d0: 20 20 20 20 50 67 46 72 65 65 73 6c 6f 74 20 2a      PgFreeslot *
38e0: 70 53 6c 6f 74 3b 0a 20 20 20 20 73 71 6c 69 74  pSlot;.    sqlit
38f0: 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 70  e3_mutex_enter(p
3900: 63 61 63 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20  cache1.mutex);. 
3910: 20 20 20 73 71 6c 69 74 65 33 53 74 61 74 75 73     sqlite3Status
3920: 44 6f 77 6e 28 53 51 4c 49 54 45 5f 53 54 41 54  Down(SQLITE_STAT
3930: 55 53 5f 50 41 47 45 43 41 43 48 45 5f 55 53 45  US_PAGECACHE_USE
3940: 44 2c 20 31 29 3b 0a 20 20 20 20 70 53 6c 6f 74  D, 1);.    pSlot
3950: 20 3d 20 28 50 67 46 72 65 65 73 6c 6f 74 2a 29   = (PgFreeslot*)
3960: 70 3b 0a 20 20 20 20 70 53 6c 6f 74 2d 3e 70 4e  p;.    pSlot->pN
3970: 65 78 74 20 3d 20 70 63 61 63 68 65 31 2e 70 46  ext = pcache1.pF
3980: 72 65 65 3b 0a 20 20 20 20 70 63 61 63 68 65 31  ree;.    pcache1
3990: 2e 70 46 72 65 65 20 3d 20 70 53 6c 6f 74 3b 0a  .pFree = pSlot;.
39a0: 20 20 20 20 70 63 61 63 68 65 31 2e 6e 46 72 65      pcache1.nFre
39b0: 65 53 6c 6f 74 2b 2b 3b 0a 20 20 20 20 70 63 61  eSlot++;.    pca
39c0: 63 68 65 31 2e 62 55 6e 64 65 72 50 72 65 73 73  che1.bUnderPress
39d0: 75 72 65 20 3d 20 70 63 61 63 68 65 31 2e 6e 46  ure = pcache1.nF
39e0: 72 65 65 53 6c 6f 74 3c 70 63 61 63 68 65 31 2e  reeSlot<pcache1.
39f0: 6e 52 65 73 65 72 76 65 3b 0a 20 20 20 20 61 73  nReserve;.    as
3a00: 73 65 72 74 28 20 70 63 61 63 68 65 31 2e 6e 46  sert( pcache1.nF
3a10: 72 65 65 53 6c 6f 74 3c 3d 70 63 61 63 68 65 31  reeSlot<=pcache1
3a20: 2e 6e 53 6c 6f 74 20 29 3b 0a 20 20 20 20 73 71  .nSlot );.    sq
3a30: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61 76  lite3_mutex_leav
3a40: 65 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  e(pcache1.mutex)
3a50: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61  ;.  }else{.    a
3a60: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 4d 65  ssert( sqlite3Me
3a70: 6d 64 65 62 75 67 48 61 73 54 79 70 65 28 70 2c  mdebugHasType(p,
3a80: 20 4d 45 4d 54 59 50 45 5f 50 43 41 43 48 45 29   MEMTYPE_PCACHE)
3a90: 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4d   );.    sqlite3M
3aa0: 65 6d 64 65 62 75 67 53 65 74 54 79 70 65 28 70  emdebugSetType(p
3ab0: 2c 20 4d 45 4d 54 59 50 45 5f 48 45 41 50 29 3b  , MEMTYPE_HEAP);
3ac0: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
3ad0: 44 49 53 41 42 4c 45 5f 50 41 47 45 43 41 43 48  DISABLE_PAGECACH
3ae0: 45 5f 4f 56 45 52 46 4c 4f 57 5f 53 54 41 54 53  E_OVERFLOW_STATS
3af0: 0a 20 20 20 20 6e 46 72 65 65 64 20 3d 20 73 71  .    nFreed = sq
3b00: 6c 69 74 65 33 4d 61 6c 6c 6f 63 53 69 7a 65 28  lite3MallocSize(
3b10: 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  p);.    sqlite3_
3b20: 6d 75 74 65 78 5f 65 6e 74 65 72 28 70 63 61 63  mutex_enter(pcac
3b30: 68 65 31 2e 6d 75 74 65 78 29 3b 0a 20 20 20 20  he1.mutex);.    
3b40: 73 71 6c 69 74 65 33 53 74 61 74 75 73 44 6f 77  sqlite3StatusDow
3b50: 6e 28 53 51 4c 49 54 45 5f 53 54 41 54 55 53 5f  n(SQLITE_STATUS_
3b60: 50 41 47 45 43 41 43 48 45 5f 4f 56 45 52 46 4c  PAGECACHE_OVERFL
3b70: 4f 57 2c 20 6e 46 72 65 65 64 29 3b 0a 20 20 20  OW, nFreed);.   
3b80: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c   sqlite3_mutex_l
3b90: 65 61 76 65 28 70 63 61 63 68 65 31 2e 6d 75 74  eave(pcache1.mut
3ba0: 65 78 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20  ex);.#endif.    
3bb0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b  sqlite3_free(p);
3bc0: 0a 20 20 7d 0a 7d 0a 0a 23 69 66 64 65 66 20 53  .  }.}..#ifdef S
3bd0: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d  QLITE_ENABLE_MEM
3be0: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f  ORY_MANAGEMENT./
3bf0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
3c00: 73 69 7a 65 20 6f 66 20 61 20 70 63 61 63 68 65  size of a pcache
3c10: 20 61 6c 6c 6f 63 61 74 69 6f 6e 0a 2a 2f 0a 73   allocation.*/.s
3c20: 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65  tatic int pcache
3c30: 31 4d 65 6d 53 69 7a 65 28 76 6f 69 64 20 2a 70  1MemSize(void *p
3c40: 29 7b 0a 20 20 69 66 28 20 70 3e 3d 70 63 61 63  ){.  if( p>=pcac
3c50: 68 65 31 2e 70 53 74 61 72 74 20 26 26 20 70 3c  he1.pStart && p<
3c60: 70 63 61 63 68 65 31 2e 70 45 6e 64 20 29 7b 0a  pcache1.pEnd ){.
3c70: 20 20 20 20 72 65 74 75 72 6e 20 70 63 61 63 68      return pcach
3c80: 65 31 2e 73 7a 53 6c 6f 74 3b 0a 20 20 7d 65 6c  e1.szSlot;.  }el
3c90: 73 65 7b 0a 20 20 20 20 69 6e 74 20 69 53 69 7a  se{.    int iSiz
3ca0: 65 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 73  e;.    assert( s
3cb0: 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 48 61  qlite3MemdebugHa
3cc0: 73 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50 45  sType(p, MEMTYPE
3cd0: 5f 50 43 41 43 48 45 29 20 29 3b 0a 20 20 20 20  _PCACHE) );.    
3ce0: 73 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 53  sqlite3MemdebugS
3cf0: 65 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50  etType(p, MEMTYP
3d00: 45 5f 48 45 41 50 29 3b 0a 20 20 20 20 69 53 69  E_HEAP);.    iSi
3d10: 7a 65 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c  ze = sqlite3Mall
3d20: 6f 63 53 69 7a 65 28 70 29 3b 0a 20 20 20 20 73  ocSize(p);.    s
3d30: 71 6c 69 74 65 33 4d 65 6d 64 65 62 75 67 53 65  qlite3MemdebugSe
3d40: 74 54 79 70 65 28 70 2c 20 4d 45 4d 54 59 50 45  tType(p, MEMTYPE
3d50: 5f 50 43 41 43 48 45 29 3b 0a 20 20 20 20 72 65  _PCACHE);.    re
3d60: 74 75 72 6e 20 69 53 69 7a 65 3b 0a 20 20 7d 0a  turn iSize;.  }.
3d70: 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  }.#endif /* SQLI
3d80: 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59  TE_ENABLE_MEMORY
3d90: 5f 4d 41 4e 41 47 45 4d 45 4e 54 20 2a 2f 0a 0a  _MANAGEMENT */..
3da0: 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61  /*.** Allocate a
3db0: 20 6e 65 77 20 70 61 67 65 20 6f 62 6a 65 63 74   new page object
3dc0: 20 69 6e 69 74 69 61 6c 6c 79 20 61 73 73 6f 63   initially assoc
3dd0: 69 61 74 65 64 20 77 69 74 68 20 63 61 63 68 65  iated with cache
3de0: 20 70 43 61 63 68 65 2e 0a 2a 2f 0a 73 74 61 74   pCache..*/.stat
3df0: 69 63 20 50 67 48 64 72 31 20 2a 70 63 61 63 68  ic PgHdr1 *pcach
3e00: 65 31 41 6c 6c 6f 63 50 61 67 65 28 50 43 61 63  e1AllocPage(PCac
3e10: 68 65 31 20 2a 70 43 61 63 68 65 29 7b 0a 20 20  he1 *pCache){.  
3e20: 50 67 48 64 72 31 20 2a 70 20 3d 20 30 3b 0a 20  PgHdr1 *p = 0;. 
3e30: 20 76 6f 69 64 20 2a 70 50 67 3b 0a 0a 20 20 61   void *pPg;..  a
3e40: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
3e50: 75 74 65 78 5f 68 65 6c 64 28 70 43 61 63 68 65  utex_held(pCache
3e60: 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78 29  ->pGroup->mutex)
3e70: 20 29 3b 0a 20 20 69 66 28 20 70 43 61 63 68 65   );.  if( pCache
3e80: 2d 3e 70 46 72 65 65 20 7c 7c 20 28 70 43 61 63  ->pFree || (pCac
3e90: 68 65 2d 3e 6e 50 61 67 65 3d 3d 30 20 26 26 20  he->nPage==0 && 
3ea0: 70 63 61 63 68 65 31 49 6e 69 74 42 75 6c 6b 28  pcache1InitBulk(
3eb0: 70 43 61 63 68 65 29 29 20 29 7b 0a 20 20 20 20  pCache)) ){.    
3ec0: 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 46 72 65  p = pCache->pFre
3ed0: 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 70  e;.    pCache->p
3ee0: 46 72 65 65 20 3d 20 70 2d 3e 70 4e 65 78 74 3b  Free = p->pNext;
3ef0: 0a 20 20 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20  .    p->pNext = 
3f00: 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a 23 69 66 64  0;.  }else{.#ifd
3f10: 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45  ef SQLITE_ENABLE
3f20: 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45  _MEMORY_MANAGEME
3f30: 4e 54 0a 20 20 20 20 2f 2a 20 54 68 65 20 67 72  NT.    /* The gr
3f40: 6f 75 70 20 6d 75 74 65 78 20 6d 75 73 74 20 62  oup mutex must b
3f50: 65 20 72 65 6c 65 61 73 65 64 20 62 65 66 6f 72  e released befor
3f60: 65 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 29  e pcache1Alloc()
3f70: 20 69 73 20 63 61 6c 6c 65 64 2e 20 54 68 69 73   is called. This
3f80: 0a 20 20 20 20 2a 2a 20 69 73 20 62 65 63 61 75  .    ** is becau
3f90: 73 65 20 69 74 20 6d 69 67 68 74 20 63 61 6c 6c  se it might call
3fa0: 20 73 71 6c 69 74 65 33 5f 72 65 6c 65 61 73 65   sqlite3_release
3fb0: 5f 6d 65 6d 6f 72 79 28 29 2c 20 77 68 69 63 68  _memory(), which
3fc0: 20 61 73 73 75 6d 65 73 20 74 68 61 74 20 0a 20   assumes that . 
3fd0: 20 20 20 2a 2a 20 74 68 69 73 20 6d 75 74 65 78     ** this mutex
3fe0: 20 69 73 20 6e 6f 74 20 68 65 6c 64 2e 20 2a 2f   is not held. */
3ff0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 63 61  .    assert( pca
4000: 63 68 65 31 2e 73 65 70 61 72 61 74 65 43 61 63  che1.separateCac
4010: 68 65 3d 3d 30 20 29 3b 0a 20 20 20 20 61 73 73  he==0 );.    ass
4020: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 70 47 72  ert( pCache->pGr
4030: 6f 75 70 3d 3d 26 70 63 61 63 68 65 31 2e 67 72  oup==&pcache1.gr
4040: 70 20 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31  p );.    pcache1
4050: 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68  LeaveMutex(pCach
4060: 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 23 65 6e 64  e->pGroup);.#end
4070: 69 66 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  if.#ifdef SQLITE
4080: 5f 50 43 41 43 48 45 5f 53 45 50 41 52 41 54 45  _PCACHE_SEPARATE
4090: 5f 48 45 41 44 45 52 0a 20 20 20 20 70 50 67 20  _HEADER.    pPg 
40a0: 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28 70  = pcache1Alloc(p
40b0: 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 29 3b 0a  Cache->szPage);.
40c0: 20 20 20 20 70 20 3d 20 73 71 6c 69 74 65 33 4d      p = sqlite3M
40d0: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 50 67 48  alloc(sizeof(PgH
40e0: 64 72 31 29 20 2b 20 70 43 61 63 68 65 2d 3e 73  dr1) + pCache->s
40f0: 7a 45 78 74 72 61 29 3b 0a 20 20 20 20 69 66 28  zExtra);.    if(
4100: 20 21 70 50 67 20 7c 7c 20 21 70 20 29 7b 0a 20   !pPg || !p ){. 
4110: 20 20 20 20 20 70 63 61 63 68 65 31 46 72 65 65       pcache1Free
4120: 28 70 50 67 29 3b 0a 20 20 20 20 20 20 73 71 6c  (pPg);.      sql
4130: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20  ite3_free(p);.  
4140: 20 20 20 20 70 50 67 20 3d 20 30 3b 0a 20 20 20      pPg = 0;.   
4150: 20 7d 0a 23 65 6c 73 65 0a 20 20 20 20 70 50 67   }.#else.    pPg
4160: 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 28   = pcache1Alloc(
4170: 70 43 61 63 68 65 2d 3e 73 7a 41 6c 6c 6f 63 29  pCache->szAlloc)
4180: 3b 0a 20 20 20 20 70 20 3d 20 28 50 67 48 64 72  ;.    p = (PgHdr
4190: 31 20 2a 29 26 28 28 75 38 20 2a 29 70 50 67 29  1 *)&((u8 *)pPg)
41a0: 5b 70 43 61 63 68 65 2d 3e 73 7a 50 61 67 65 5d  [pCache->szPage]
41b0: 3b 0a 23 65 6e 64 69 66 0a 23 69 66 64 65 66 20  ;.#endif.#ifdef 
41c0: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45  SQLITE_ENABLE_ME
41d0: 4d 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a  MORY_MANAGEMENT.
41e0: 20 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72      pcache1Enter
41f0: 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70 47  Mutex(pCache->pG
4200: 72 6f 75 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20  roup);.#endif.  
4210: 20 20 69 66 28 20 70 50 67 3d 3d 30 20 29 20 72    if( pPg==0 ) r
4220: 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 70 2d 3e  eturn 0;.    p->
4230: 70 61 67 65 2e 70 42 75 66 20 3d 20 70 50 67 3b  page.pBuf = pPg;
4240: 0a 20 20 20 20 70 2d 3e 70 61 67 65 2e 70 45 78  .    p->page.pEx
4250: 74 72 61 20 3d 20 26 70 5b 31 5d 3b 0a 20 20 20  tra = &p[1];.   
4260: 20 70 2d 3e 69 73 42 75 6c 6b 4c 6f 63 61 6c 20   p->isBulkLocal 
4270: 3d 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70  = 0;.  }.  if( p
4280: 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61 62 6c  Cache->bPurgeabl
4290: 65 20 29 7b 0a 20 20 20 20 70 43 61 63 68 65 2d  e ){.    pCache-
42a0: 3e 70 47 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e  >pGroup->nCurren
42b0: 74 50 61 67 65 2b 2b 3b 0a 20 20 7d 0a 20 20 72  tPage++;.  }.  r
42c0: 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn p;.}../*.*
42d0: 2a 20 46 72 65 65 20 61 20 70 61 67 65 20 6f 62  * Free a page ob
42e0: 6a 65 63 74 20 61 6c 6c 6f 63 61 74 65 64 20 62  ject allocated b
42f0: 79 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50 61  y pcache1AllocPa
4300: 67 65 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ge()..*/.static 
4310: 76 6f 69 64 20 70 63 61 63 68 65 31 46 72 65 65  void pcache1Free
4320: 50 61 67 65 28 50 67 48 64 72 31 20 2a 70 29 7b  Page(PgHdr1 *p){
4330: 0a 20 20 50 43 61 63 68 65 31 20 2a 70 43 61 63  .  PCache1 *pCac
4340: 68 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 21  he;.  assert( p!
4350: 3d 30 20 29 3b 0a 20 20 70 43 61 63 68 65 20 3d  =0 );.  pCache =
4360: 20 70 2d 3e 70 43 61 63 68 65 3b 0a 20 20 61 73   p->pCache;.  as
4370: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
4380: 74 65 78 5f 68 65 6c 64 28 70 2d 3e 70 43 61 63  tex_held(p->pCac
4390: 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65  he->pGroup->mute
43a0: 78 29 20 29 3b 0a 20 20 69 66 28 20 70 2d 3e 69  x) );.  if( p->i
43b0: 73 42 75 6c 6b 4c 6f 63 61 6c 20 29 7b 0a 20 20  sBulkLocal ){.  
43c0: 20 20 70 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61    p->pNext = pCa
43d0: 63 68 65 2d 3e 70 46 72 65 65 3b 0a 20 20 20 20  che->pFree;.    
43e0: 70 43 61 63 68 65 2d 3e 70 46 72 65 65 20 3d 20  pCache->pFree = 
43f0: 70 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  p;.  }else{.    
4400: 70 63 61 63 68 65 31 46 72 65 65 28 70 2d 3e 70  pcache1Free(p->p
4410: 61 67 65 2e 70 42 75 66 29 3b 0a 23 69 66 64 65  age.pBuf);.#ifde
4420: 66 20 53 51 4c 49 54 45 5f 50 43 41 43 48 45 5f  f SQLITE_PCACHE_
4430: 53 45 50 41 52 41 54 45 5f 48 45 41 44 45 52 0a  SEPARATE_HEADER.
4440: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
4450: 28 70 29 3b 0a 23 65 6e 64 69 66 0a 20 20 7d 0a  (p);.#endif.  }.
4460: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50    if( pCache->bP
4470: 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20  urgeable ){.    
4480: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e  pCache->pGroup->
4490: 6e 43 75 72 72 65 6e 74 50 61 67 65 2d 2d 3b 0a  nCurrentPage--;.
44a0: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6c    }.}../*.** Mal
44b0: 6c 6f 63 20 66 75 6e 63 74 69 6f 6e 20 75 73 65  loc function use
44c0: 64 20 62 79 20 53 51 4c 69 74 65 20 74 6f 20 6f  d by SQLite to o
44d0: 62 74 61 69 6e 20 73 70 61 63 65 20 66 72 6f 6d  btain space from
44e0: 20 74 68 65 20 62 75 66 66 65 72 20 63 6f 6e 66   the buffer conf
44f0: 69 67 75 72 65 64 0a 2a 2a 20 75 73 69 6e 67 20  igured.** using 
4500: 73 71 6c 69 74 65 33 5f 63 6f 6e 66 69 67 28 53  sqlite3_config(S
4510: 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47  QLITE_CONFIG_PAG
4520: 45 43 41 43 48 45 29 20 6f 70 74 69 6f 6e 2e 20  ECACHE) option. 
4530: 49 66 20 6e 6f 20 73 75 63 68 20 62 75 66 66 65  If no such buffe
4540: 72 0a 2a 2a 20 65 78 69 73 74 73 2c 20 74 68 69  r.** exists, thi
4550: 73 20 66 75 6e 63 74 69 6f 6e 20 66 61 6c 6c 73  s function falls
4560: 20 62 61 63 6b 20 74 6f 20 73 71 6c 69 74 65 33   back to sqlite3
4570: 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 76 6f 69  Malloc()..*/.voi
4580: 64 20 2a 73 71 6c 69 74 65 33 50 61 67 65 4d 61  d *sqlite3PageMa
4590: 6c 6c 6f 63 28 69 6e 74 20 73 7a 29 7b 0a 20 20  lloc(int sz){.  
45a0: 72 65 74 75 72 6e 20 70 63 61 63 68 65 31 41 6c  return pcache1Al
45b0: 6c 6f 63 28 73 7a 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  loc(sz);.}../*.*
45c0: 2a 20 46 72 65 65 20 61 6e 20 61 6c 6c 6f 63 61  * Free an alloca
45d0: 74 65 64 20 62 75 66 66 65 72 20 6f 62 74 61 69  ted buffer obtai
45e0: 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33  ned from sqlite3
45f0: 50 61 67 65 4d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f  PageMalloc()..*/
4600: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50 61 67  .void sqlite3Pag
4610: 65 46 72 65 65 28 76 6f 69 64 20 2a 70 29 7b 0a  eFree(void *p){.
4620: 20 20 70 63 61 63 68 65 31 46 72 65 65 28 70 29    pcache1Free(p)
4630: 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  ;.}.../*.** Retu
4640: 72 6e 20 74 72 75 65 20 69 66 20 69 74 20 64 65  rn true if it de
4650: 73 69 72 61 62 6c 65 20 74 6f 20 61 76 6f 69 64  sirable to avoid
4660: 20 61 6c 6c 6f 63 61 74 69 6e 67 20 61 20 6e 65   allocating a ne
4670: 77 20 70 61 67 65 20 63 61 63 68 65 0a 2a 2a 20  w page cache.** 
4680: 65 6e 74 72 79 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  entry..**.** If 
4690: 6d 65 6d 6f 72 79 20 77 61 73 20 61 6c 6c 6f 63  memory was alloc
46a0: 61 74 65 64 20 73 70 65 63 69 66 69 63 61 6c 6c  ated specificall
46b0: 79 20 74 6f 20 74 68 65 20 70 61 67 65 20 63 61  y to the page ca
46c0: 63 68 65 20 75 73 69 6e 67 0a 2a 2a 20 53 51 4c  che using.** SQL
46d0: 49 54 45 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43  ITE_CONFIG_PAGEC
46e0: 41 43 48 45 20 62 75 74 20 74 68 61 74 20 6d 65  ACHE but that me
46f0: 6d 6f 72 79 20 68 61 73 20 61 6c 6c 20 62 65 65  mory has all bee
4700: 6e 20 75 73 65 64 2c 20 74 68 65 6e 0a 2a 2a 20  n used, then.** 
4710: 69 74 20 69 73 20 64 65 73 69 72 61 62 6c 65 20  it is desirable 
4720: 74 6f 20 61 76 6f 69 64 20 61 6c 6c 6f 63 61 74  to avoid allocat
4730: 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65 20 63  ing a new page c
4740: 61 63 68 65 20 65 6e 74 72 79 20 62 65 63 61 75  ache entry becau
4750: 73 65 0a 2a 2a 20 70 72 65 73 75 6d 61 62 6c 79  se.** presumably
4760: 20 53 51 4c 49 54 45 5f 43 4f 4e 46 49 47 5f 50   SQLITE_CONFIG_P
4770: 41 47 45 43 41 43 48 45 20 77 61 73 20 73 75 70  AGECACHE was sup
4780: 70 6f 73 65 20 74 6f 20 62 65 20 73 75 66 66 69  pose to be suffi
4790: 63 69 65 6e 74 0a 2a 2a 20 66 6f 72 20 61 6c 6c  cient.** for all
47a0: 20 70 61 67 65 20 63 61 63 68 65 20 6e 65 65 64   page cache need
47b0: 73 20 61 6e 64 20 77 65 20 73 68 6f 75 6c 64 20  s and we should 
47c0: 6e 6f 74 20 6e 65 65 64 20 74 6f 20 73 70 69 6c  not need to spil
47d0: 6c 20 74 68 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74  l the.** allocat
47e0: 69 6f 6e 20 6f 6e 74 6f 20 74 68 65 20 68 65 61  ion onto the hea
47f0: 70 2e 0a 2a 2a 0a 2a 2a 20 4f 72 2c 20 74 68 65  p..**.** Or, the
4800: 20 68 65 61 70 20 69 73 20 75 73 65 64 20 66 6f   heap is used fo
4810: 72 20 61 6c 6c 20 70 61 67 65 20 63 61 63 68 65  r all page cache
4820: 20 6d 65 6d 6f 72 79 20 62 75 74 20 74 68 65 20   memory but the 
4830: 68 65 61 70 20 69 73 0a 2a 2a 20 75 6e 64 65 72  heap is.** under
4840: 20 6d 65 6d 6f 72 79 20 70 72 65 73 73 75 72 65   memory pressure
4850: 2c 20 74 68 65 6e 20 61 67 61 69 6e 20 69 74 20  , then again it 
4860: 69 73 20 64 65 73 69 72 61 62 6c 65 20 74 6f 20  is desirable to 
4870: 61 76 6f 69 64 0a 2a 2a 20 61 6c 6c 6f 63 61 74  avoid.** allocat
4880: 69 6e 67 20 61 20 6e 65 77 20 70 61 67 65 20 63  ing a new page c
4890: 61 63 68 65 20 65 6e 74 72 79 20 69 6e 20 6f 72  ache entry in or
48a0: 64 65 72 20 74 6f 20 61 76 6f 69 64 20 73 74 72  der to avoid str
48b0: 65 73 73 69 6e 67 0a 2a 2a 20 74 68 65 20 68 65  essing.** the he
48c0: 61 70 20 65 76 65 6e 20 66 75 72 74 68 65 72 2e  ap even further.
48d0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 70  .*/.static int p
48e0: 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f 72  cache1UnderMemor
48f0: 79 50 72 65 73 73 75 72 65 28 50 43 61 63 68 65  yPressure(PCache
4900: 31 20 2a 70 43 61 63 68 65 29 7b 0a 20 20 69 66  1 *pCache){.  if
4910: 28 20 70 63 61 63 68 65 31 2e 6e 53 6c 6f 74 20  ( pcache1.nSlot 
4920: 26 26 20 28 70 43 61 63 68 65 2d 3e 73 7a 50 61  && (pCache->szPa
4930: 67 65 2b 70 43 61 63 68 65 2d 3e 73 7a 45 78 74  ge+pCache->szExt
4940: 72 61 29 3c 3d 70 63 61 63 68 65 31 2e 73 7a 53  ra)<=pcache1.szS
4950: 6c 6f 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72  lot ){.    retur
4960: 6e 20 70 63 61 63 68 65 31 2e 62 55 6e 64 65 72  n pcache1.bUnder
4970: 50 72 65 73 73 75 72 65 3b 0a 20 20 7d 65 6c 73  Pressure;.  }els
4980: 65 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 73 71  e{.    return sq
4990: 6c 69 74 65 33 48 65 61 70 4e 65 61 72 6c 79 46  lite3HeapNearlyF
49a0: 75 6c 6c 28 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  ull();.  }.}../*
49b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
49c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
49d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
49e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
49f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f  *************/./
4a00: 2a 2a 2a 2a 2a 2a 2a 2a 20 47 65 6e 65 72 61 6c  ******** General
4a10: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
4a20: 46 75 6e 63 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a  Functions ******
4a30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4a40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
4a50: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
4a60: 74 69 6f 6e 20 69 73 20 75 73 65 64 20 74 6f 20  tion is used to 
4a70: 72 65 73 69 7a 65 20 74 68 65 20 68 61 73 68 20  resize the hash 
4a80: 74 61 62 6c 65 20 75 73 65 64 20 62 79 20 74 68  table used by th
4a90: 65 20 63 61 63 68 65 20 70 61 73 73 65 64 0a 2a  e cache passed.*
4aa0: 2a 20 61 73 20 74 68 65 20 66 69 72 73 74 20 61  * as the first a
4ab0: 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54  rgument..**.** T
4ac0: 68 65 20 50 43 61 63 68 65 20 6d 75 74 65 78 20  he PCache mutex 
4ad0: 6d 75 73 74 20 62 65 20 68 65 6c 64 20 77 68 65  must be held whe
4ae0: 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
4af0: 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74  is called..*/.st
4b00: 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65  atic void pcache
4b10: 31 52 65 73 69 7a 65 48 61 73 68 28 50 43 61 63  1ResizeHash(PCac
4b20: 68 65 31 20 2a 70 29 7b 0a 20 20 50 67 48 64 72  he1 *p){.  PgHdr
4b30: 31 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 75 6e 73  1 **apNew;.  uns
4b40: 69 67 6e 65 64 20 69 6e 74 20 6e 4e 65 77 3b 0a  igned int nNew;.
4b50: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
4b60: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  ;..  assert( sql
4b70: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
4b80: 70 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65 78  p->pGroup->mutex
4b90: 29 20 29 3b 0a 0a 20 20 6e 4e 65 77 20 3d 20 70  ) );..  nNew = p
4ba0: 2d 3e 6e 48 61 73 68 2a 32 3b 0a 20 20 69 66 28  ->nHash*2;.  if(
4bb0: 20 6e 4e 65 77 3c 32 35 36 20 29 7b 0a 20 20 20   nNew<256 ){.   
4bc0: 20 6e 4e 65 77 20 3d 20 32 35 36 3b 0a 20 20 7d   nNew = 256;.  }
4bd0: 0a 0a 20 20 70 63 61 63 68 65 31 4c 65 61 76 65  ..  pcache1Leave
4be0: 4d 75 74 65 78 28 70 2d 3e 70 47 72 6f 75 70 29  Mutex(p->pGroup)
4bf0: 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61 73 68  ;.  if( p->nHash
4c00: 20 29 7b 20 73 71 6c 69 74 65 33 42 65 67 69 6e   ){ sqlite3Begin
4c10: 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20  BenignMalloc(); 
4c20: 7d 0a 20 20 61 70 4e 65 77 20 3d 20 28 50 67 48  }.  apNew = (PgH
4c30: 64 72 31 20 2a 2a 29 73 71 6c 69 74 65 33 4d 61  dr1 **)sqlite3Ma
4c40: 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28  llocZero(sizeof(
4c50: 50 67 48 64 72 31 20 2a 29 2a 6e 4e 65 77 29 3b  PgHdr1 *)*nNew);
4c60: 0a 20 20 69 66 28 20 70 2d 3e 6e 48 61 73 68 20  .  if( p->nHash 
4c70: 29 7b 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e  ){ sqlite3EndBen
4c80: 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20 7d 0a 20  ignMalloc(); }. 
4c90: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
4ca0: 65 78 28 70 2d 3e 70 47 72 6f 75 70 29 3b 0a 20  ex(p->pGroup);. 
4cb0: 20 69 66 28 20 61 70 4e 65 77 20 29 7b 0a 20 20   if( apNew ){.  
4cc0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 2d 3e    for(i=0; i<p->
4cd0: 6e 48 61 73 68 3b 20 69 2b 2b 29 7b 0a 20 20 20  nHash; i++){.   
4ce0: 20 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65     PgHdr1 *pPage
4cf0: 3b 0a 20 20 20 20 20 20 50 67 48 64 72 31 20 2a  ;.      PgHdr1 *
4d00: 70 4e 65 78 74 20 3d 20 70 2d 3e 61 70 48 61 73  pNext = p->apHas
4d10: 68 5b 69 5d 3b 0a 20 20 20 20 20 20 77 68 69 6c  h[i];.      whil
4d20: 65 28 20 28 70 50 61 67 65 20 3d 20 70 4e 65 78  e( (pPage = pNex
4d30: 74 29 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  t)!=0 ){.       
4d40: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 20   unsigned int h 
4d50: 3d 20 70 50 61 67 65 2d 3e 69 4b 65 79 20 25 20  = pPage->iKey % 
4d60: 6e 4e 65 77 3b 0a 20 20 20 20 20 20 20 20 70 4e  nNew;.        pN
4d70: 65 78 74 20 3d 20 70 50 61 67 65 2d 3e 70 4e 65  ext = pPage->pNe
4d80: 78 74 3b 0a 20 20 20 20 20 20 20 20 70 50 61 67  xt;.        pPag
4d90: 65 2d 3e 70 4e 65 78 74 20 3d 20 61 70 4e 65 77  e->pNext = apNew
4da0: 5b 68 5d 3b 0a 20 20 20 20 20 20 20 20 61 70 4e  [h];.        apN
4db0: 65 77 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a 20  ew[h] = pPage;. 
4dc0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
4dd0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d   sqlite3_free(p-
4de0: 3e 61 70 48 61 73 68 29 3b 0a 20 20 20 20 70 2d  >apHash);.    p-
4df0: 3e 61 70 48 61 73 68 20 3d 20 61 70 4e 65 77 3b  >apHash = apNew;
4e00: 0a 20 20 20 20 70 2d 3e 6e 48 61 73 68 20 3d 20  .    p->nHash = 
4e10: 6e 4e 65 77 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  nNew;.  }.}../*.
4e20: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
4e30: 20 69 73 20 75 73 65 64 20 69 6e 74 65 72 6e 61   is used interna
4e40: 6c 6c 79 20 74 6f 20 72 65 6d 6f 76 65 20 74 68  lly to remove th
4e50: 65 20 70 61 67 65 20 70 50 61 67 65 20 66 72 6f  e page pPage fro
4e60: 6d 20 74 68 65 20 0a 2a 2a 20 50 47 72 6f 75 70  m the .** PGroup
4e70: 20 4c 52 55 20 6c 69 73 74 2c 20 69 66 20 69 73   LRU list, if is
4e80: 20 70 61 72 74 20 6f 66 20 69 74 2e 20 49 66 20   part of it. If 
4e90: 70 50 61 67 65 20 69 73 20 6e 6f 74 20 70 61 72  pPage is not par
4ea0: 74 20 6f 66 20 74 68 65 20 50 47 72 6f 75 70 0a  t of the PGroup.
4eb0: 2a 2a 20 4c 52 55 20 6c 69 73 74 2c 20 74 68 65  ** LRU list, the
4ec0: 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  n this function 
4ed0: 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a  is a no-op..**.*
4ee0: 2a 20 54 68 65 20 50 47 72 6f 75 70 20 6d 75 74  * The PGroup mut
4ef0: 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c 64 20  ex must be held 
4f00: 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69  when this functi
4f10: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f  on is called..*/
4f20: 0a 73 74 61 74 69 63 20 50 67 48 64 72 31 20 2a  .static PgHdr1 *
4f30: 70 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 50  pcache1PinPage(P
4f40: 67 48 64 72 31 20 2a 70 50 61 67 65 29 7b 0a 20  gHdr1 *pPage){. 
4f50: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
4f60: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 50 61  ;..  assert( pPa
4f70: 67 65 21 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  ge!=0 );.  asser
4f80: 74 28 20 70 50 61 67 65 2d 3e 69 73 50 69 6e 6e  t( pPage->isPinn
4f90: 65 64 3d 3d 30 20 29 3b 0a 20 20 70 43 61 63 68  ed==0 );.  pCach
4fa0: 65 20 3d 20 70 50 61 67 65 2d 3e 70 43 61 63 68  e = pPage->pCach
4fb0: 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 50 61  e;.  assert( pPa
4fc0: 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 7c 7c 20  ge->pLruNext || 
4fd0: 70 50 61 67 65 3d 3d 70 43 61 63 68 65 2d 3e 70  pPage==pCache->p
4fe0: 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20  Group->pLruTail 
4ff0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 50 61  );.  assert( pPa
5000: 67 65 2d 3e 70 4c 72 75 50 72 65 76 20 7c 7c 20  ge->pLruPrev || 
5010: 70 50 61 67 65 3d 3d 70 43 61 63 68 65 2d 3e 70  pPage==pCache->p
5020: 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64 20  Group->pLruHead 
5030: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  );.  assert( sql
5040: 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28  ite3_mutex_held(
5050: 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e  pCache->pGroup->
5060: 6d 75 74 65 78 29 20 29 3b 0a 20 20 69 66 28 20  mutex) );.  if( 
5070: 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76 20  pPage->pLruPrev 
5080: 29 7b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70 4c  ){.    pPage->pL
5090: 72 75 50 72 65 76 2d 3e 70 4c 72 75 4e 65 78 74  ruPrev->pLruNext
50a0: 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65   = pPage->pLruNe
50b0: 78 74 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  xt;.  }else{.   
50c0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 2d   pCache->pGroup-
50d0: 3e 70 4c 72 75 48 65 61 64 20 3d 20 70 50 61 67  >pLruHead = pPag
50e0: 65 2d 3e 70 4c 72 75 4e 65 78 74 3b 0a 20 20 7d  e->pLruNext;.  }
50f0: 0a 20 20 69 66 28 20 70 50 61 67 65 2d 3e 70 4c  .  if( pPage->pL
5100: 72 75 4e 65 78 74 20 29 7b 0a 20 20 20 20 70 50  ruNext ){.    pP
5110: 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 2d 3e 70  age->pLruNext->p
5120: 4c 72 75 50 72 65 76 20 3d 20 70 50 61 67 65 2d  LruPrev = pPage-
5130: 3e 70 4c 72 75 50 72 65 76 3b 0a 20 20 7d 65 6c  >pLruPrev;.  }el
5140: 73 65 7b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e  se{.    pCache->
5150: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c  pGroup->pLruTail
5160: 20 3d 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72   = pPage->pLruPr
5170: 65 76 3b 0a 20 20 7d 0a 20 20 70 50 61 67 65 2d  ev;.  }.  pPage-
5180: 3e 70 4c 72 75 4e 65 78 74 20 3d 20 30 3b 0a 20  >pLruNext = 0;. 
5190: 20 70 50 61 67 65 2d 3e 70 4c 72 75 50 72 65 76   pPage->pLruPrev
51a0: 20 3d 20 30 3b 0a 20 20 70 50 61 67 65 2d 3e 69   = 0;.  pPage->i
51b0: 73 50 69 6e 6e 65 64 20 3d 20 31 3b 0a 20 20 70  sPinned = 1;.  p
51c0: 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62  Cache->nRecyclab
51d0: 6c 65 2d 2d 3b 0a 20 20 72 65 74 75 72 6e 20 70  le--;.  return p
51e0: 50 61 67 65 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  Page;.}.../*.** 
51f0: 52 65 6d 6f 76 65 20 74 68 65 20 70 61 67 65 20  Remove the page 
5200: 73 75 70 70 6c 69 65 64 20 61 73 20 61 6e 20 61  supplied as an a
5210: 72 67 75 6d 65 6e 74 20 66 72 6f 6d 20 74 68 65  rgument from the
5220: 20 68 61 73 68 20 74 61 62 6c 65 20 0a 2a 2a 20   hash table .** 
5230: 28 50 43 61 63 68 65 31 2e 61 70 48 61 73 68 20  (PCache1.apHash 
5240: 73 74 72 75 63 74 75 72 65 29 20 74 68 61 74 20  structure) that 
5250: 69 74 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20  it is currently 
5260: 73 74 6f 72 65 64 20 69 6e 2e 0a 2a 2a 20 41 6c  stored in..** Al
5270: 73 6f 20 66 72 65 65 20 74 68 65 20 70 61 67 65  so free the page
5280: 20 69 66 20 66 72 65 65 50 61 67 65 20 69 73 20   if freePage is 
5290: 74 72 75 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  true..**.** The 
52a0: 50 47 72 6f 75 70 20 6d 75 74 65 78 20 6d 75 73  PGroup mutex mus
52b0: 74 20 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74  t be held when t
52c0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
52d0: 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  called..*/.stati
52e0: 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 52 65  c void pcache1Re
52f0: 6d 6f 76 65 46 72 6f 6d 48 61 73 68 28 50 67 48  moveFromHash(PgH
5300: 64 72 31 20 2a 70 50 61 67 65 2c 20 69 6e 74 20  dr1 *pPage, int 
5310: 66 72 65 65 46 6c 61 67 29 7b 0a 20 20 75 6e 73  freeFlag){.  uns
5320: 69 67 6e 65 64 20 69 6e 74 20 68 3b 0a 20 20 50  igned int h;.  P
5330: 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d  Cache1 *pCache =
5340: 20 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3b 0a   pPage->pCache;.
5350: 20 20 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a 0a    PgHdr1 **pp;..
5360: 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65    assert( sqlite
5370: 33 5f 6d 75 74 65 78 5f 68 65 6c 64 28 70 43 61  3_mutex_held(pCa
5380: 63 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74  che->pGroup->mut
5390: 65 78 29 20 29 3b 0a 20 20 68 20 3d 20 70 50 61  ex) );.  h = pPa
53a0: 67 65 2d 3e 69 4b 65 79 20 25 20 70 43 61 63 68  ge->iKey % pCach
53b0: 65 2d 3e 6e 48 61 73 68 3b 0a 20 20 66 6f 72 28  e->nHash;.  for(
53c0: 70 70 3d 26 70 43 61 63 68 65 2d 3e 61 70 48 61  pp=&pCache->apHa
53d0: 73 68 5b 68 5d 3b 20 28 2a 70 70 29 21 3d 70 50  sh[h]; (*pp)!=pP
53e0: 61 67 65 3b 20 70 70 3d 26 28 2a 70 70 29 2d 3e  age; pp=&(*pp)->
53f0: 70 4e 65 78 74 29 3b 0a 20 20 2a 70 70 20 3d 20  pNext);.  *pp = 
5400: 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 0a 20  (*pp)->pNext;.. 
5410: 20 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d   pCache->nPage--
5420: 3b 0a 20 20 69 66 28 20 66 72 65 65 46 6c 61 67  ;.  if( freeFlag
5430: 20 29 20 70 63 61 63 68 65 31 46 72 65 65 50 61   ) pcache1FreePa
5440: 67 65 28 70 50 61 67 65 29 3b 0a 7d 0a 0a 2f 2a  ge(pPage);.}../*
5450: 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 61 72 65  .** If there are
5460: 20 63 75 72 72 65 6e 74 6c 79 20 6d 6f 72 65 20   currently more 
5470: 74 68 61 6e 20 6e 4d 61 78 50 61 67 65 20 70 61  than nMaxPage pa
5480: 67 65 73 20 61 6c 6c 6f 63 61 74 65 64 2c 20 74  ges allocated, t
5490: 72 79 0a 2a 2a 20 74 6f 20 72 65 63 79 63 6c 65  ry.** to recycle
54a0: 20 70 61 67 65 73 20 74 6f 20 72 65 64 75 63 65   pages to reduce
54b0: 20 74 68 65 20 6e 75 6d 62 65 72 20 61 6c 6c 6f   the number allo
54c0: 63 61 74 65 64 20 74 6f 20 6e 4d 61 78 50 61 67  cated to nMaxPag
54d0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  e..*/.static voi
54e0: 64 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63 65  d pcache1Enforce
54f0: 4d 61 78 50 61 67 65 28 50 43 61 63 68 65 31 20  MaxPage(PCache1 
5500: 2a 70 43 61 63 68 65 29 7b 0a 20 20 50 47 72 6f  *pCache){.  PGro
5510: 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 43 61  up *pGroup = pCa
5520: 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 61  che->pGroup;.  a
5530: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d  ssert( sqlite3_m
5540: 75 74 65 78 5f 68 65 6c 64 28 70 47 72 6f 75 70  utex_held(pGroup
5550: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 77 68  ->mutex) );.  wh
5560: 69 6c 65 28 20 70 47 72 6f 75 70 2d 3e 6e 43 75  ile( pGroup->nCu
5570: 72 72 65 6e 74 50 61 67 65 3e 70 47 72 6f 75 70  rrentPage>pGroup
5580: 2d 3e 6e 4d 61 78 50 61 67 65 20 26 26 20 70 47  ->nMaxPage && pG
5590: 72 6f 75 70 2d 3e 70 4c 72 75 54 61 69 6c 20 29  roup->pLruTail )
55a0: 7b 0a 20 20 20 20 50 67 48 64 72 31 20 2a 70 20  {.    PgHdr1 *p 
55b0: 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 54 61  = pGroup->pLruTa
55c0: 69 6c 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  il;.    assert( 
55d0: 70 2d 3e 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  p->pCache->pGrou
55e0: 70 3d 3d 70 47 72 6f 75 70 20 29 3b 0a 20 20 20  p==pGroup );.   
55f0: 20 61 73 73 65 72 74 28 20 70 2d 3e 69 73 50 69   assert( p->isPi
5600: 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 20 20 70  nned==0 );.    p
5610: 63 61 63 68 65 31 50 69 6e 50 61 67 65 28 70 29  cache1PinPage(p)
5620: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 6d  ;.    pcache1Rem
5630: 6f 76 65 46 72 6f 6d 48 61 73 68 28 70 2c 20 31  oveFromHash(p, 1
5640: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 43 61  );.  }.  if( pCa
5650: 63 68 65 2d 3e 6e 50 61 67 65 3d 3d 30 20 26 26  che->nPage==0 &&
5660: 20 70 43 61 63 68 65 2d 3e 70 42 75 6c 6b 20 29   pCache->pBulk )
5670: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  {.    sqlite3_fr
5680: 65 65 28 70 43 61 63 68 65 2d 3e 70 42 75 6c 6b  ee(pCache->pBulk
5690: 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 70  );.    pCache->p
56a0: 42 75 6c 6b 20 3d 20 70 43 61 63 68 65 2d 3e 70  Bulk = pCache->p
56b0: 46 72 65 65 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a  Free = 0;.  }.}.
56c0: 0a 2f 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61  ./*.** Discard a
56d0: 6c 6c 20 70 61 67 65 73 20 66 72 6f 6d 20 63 61  ll pages from ca
56e0: 63 68 65 20 70 43 61 63 68 65 20 77 69 74 68 20  che pCache with 
56f0: 61 20 70 61 67 65 20 6e 75 6d 62 65 72 20 28 6b  a page number (k
5700: 65 79 20 76 61 6c 75 65 29 20 0a 2a 2a 20 67 72  ey value) .** gr
5710: 65 61 74 65 72 20 74 68 61 6e 20 6f 72 20 65 71  eater than or eq
5720: 75 61 6c 20 74 6f 20 69 4c 69 6d 69 74 2e 20 41  ual to iLimit. A
5730: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
5740: 74 68 61 74 20 6d 65 65 74 20 74 68 69 73 20 0a  that meet this .
5750: 2a 2a 20 63 72 69 74 65 72 69 61 20 61 72 65 20  ** criteria are 
5760: 75 6e 70 69 6e 6e 65 64 20 62 65 66 6f 72 65 20  unpinned before 
5770: 74 68 65 79 20 61 72 65 20 64 69 73 63 61 72 64  they are discard
5780: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 50 43  ed..**.** The PC
5790: 61 63 68 65 20 6d 75 74 65 78 20 6d 75 73 74 20  ache mutex must 
57a0: 62 65 20 68 65 6c 64 20 77 68 65 6e 20 74 68 69  be held when thi
57b0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
57c0: 6c 6c 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  lled..*/.static 
57d0: 76 6f 69 64 20 70 63 61 63 68 65 31 54 72 75 6e  void pcache1Trun
57e0: 63 61 74 65 55 6e 73 61 66 65 28 0a 20 20 50 43  cateUnsafe(.  PC
57f0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20 20  ache1 *pCache,  
5800: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
5810: 65 20 63 61 63 68 65 20 74 6f 20 74 72 75 6e 63  e cache to trunc
5820: 61 74 65 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65  ate */.  unsigne
5830: 64 20 69 6e 74 20 69 4c 69 6d 69 74 20 20 20 20  d int iLimit    
5840: 20 20 20 20 20 20 2f 2a 20 44 72 6f 70 20 70 61        /* Drop pa
5850: 67 65 73 20 77 69 74 68 20 74 68 69 73 20 70 67  ges with this pg
5860: 6e 6f 20 6f 72 20 6c 61 72 67 65 72 20 2a 2f 0a  no or larger */.
5870: 29 7b 0a 20 20 54 45 53 54 4f 4e 4c 59 28 20 75  ){.  TESTONLY( u
5880: 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 50 61 67  nsigned int nPag
5890: 65 20 3d 20 30 3b 20 29 20 20 2f 2a 20 54 6f 20  e = 0; )  /* To 
58a0: 61 73 73 65 72 74 20 70 43 61 63 68 65 2d 3e 6e  assert pCache->n
58b0: 50 61 67 65 20 69 73 20 63 6f 72 72 65 63 74 20  Page is correct 
58c0: 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e  */.  unsigned in
58d0: 74 20 68 3b 0a 20 20 61 73 73 65 72 74 28 20 73  t h;.  assert( s
58e0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 68 65 6c  qlite3_mutex_hel
58f0: 64 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  d(pCache->pGroup
5900: 2d 3e 6d 75 74 65 78 29 20 29 3b 0a 20 20 66 6f  ->mutex) );.  fo
5910: 72 28 68 3d 30 3b 20 68 3c 70 43 61 63 68 65 2d  r(h=0; h<pCache-
5920: 3e 6e 48 61 73 68 3b 20 68 2b 2b 29 7b 0a 20 20  >nHash; h++){.  
5930: 20 20 50 67 48 64 72 31 20 2a 2a 70 70 20 3d 20    PgHdr1 **pp = 
5940: 26 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b  &pCache->apHash[
5950: 68 5d 3b 20 0a 20 20 20 20 50 67 48 64 72 31 20  h]; .    PgHdr1 
5960: 2a 70 50 61 67 65 3b 0a 20 20 20 20 77 68 69 6c  *pPage;.    whil
5970: 65 28 20 28 70 50 61 67 65 20 3d 20 2a 70 70 29  e( (pPage = *pp)
5980: 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28  !=0 ){.      if(
5990: 20 70 50 61 67 65 2d 3e 69 4b 65 79 3e 3d 69 4c   pPage->iKey>=iL
59a0: 69 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 20 20  imit ){.        
59b0: 70 43 61 63 68 65 2d 3e 6e 50 61 67 65 2d 2d 3b  pCache->nPage--;
59c0: 0a 20 20 20 20 20 20 20 20 2a 70 70 20 3d 20 70  .        *pp = p
59d0: 50 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  Page->pNext;.   
59e0: 20 20 20 20 20 69 66 28 20 21 70 50 61 67 65 2d       if( !pPage-
59f0: 3e 69 73 50 69 6e 6e 65 64 20 29 20 70 63 61 63  >isPinned ) pcac
5a00: 68 65 31 50 69 6e 50 61 67 65 28 70 50 61 67 65  he1PinPage(pPage
5a10: 29 3b 0a 20 20 20 20 20 20 20 20 70 63 61 63 68  );.        pcach
5a20: 65 31 46 72 65 65 50 61 67 65 28 70 50 61 67 65  e1FreePage(pPage
5a30: 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  );.      }else{.
5a40: 20 20 20 20 20 20 20 20 70 70 20 3d 20 26 70 50          pp = &pP
5a50: 61 67 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  age->pNext;.    
5a60: 20 20 20 20 54 45 53 54 4f 4e 4c 59 28 20 6e 50      TESTONLY( nP
5a70: 61 67 65 2b 2b 3b 20 29 0a 20 20 20 20 20 20 7d  age++; ).      }
5a80: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73  .    }.  }.  ass
5a90: 65 72 74 28 20 70 43 61 63 68 65 2d 3e 6e 50 61  ert( pCache->nPa
5aa0: 67 65 3d 3d 6e 50 61 67 65 20 29 3b 0a 7d 0a 0a  ge==nPage );.}..
5ab0: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
5ac0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5ad0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5ae0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5af0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f  ***************/
5b00: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 20 73 71 6c 69 74  ./******** sqlit
5b10: 65 33 5f 70 63 61 63 68 65 20 4d 65 74 68 6f 64  e3_pcache Method
5b20: 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  s **************
5b30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5b40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5b50: 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  /../*.** Impleme
5b60: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
5b70: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 49  qlite3_pcache.xI
5b80: 6e 69 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  nit method..*/.s
5b90: 74 61 74 69 63 20 69 6e 74 20 70 63 61 63 68 65  tatic int pcache
5ba0: 31 49 6e 69 74 28 76 6f 69 64 20 2a 4e 6f 74 55  1Init(void *NotU
5bb0: 73 65 64 29 7b 0a 20 20 55 4e 55 53 45 44 5f 50  sed){.  UNUSED_P
5bc0: 41 52 41 4d 45 54 45 52 28 4e 6f 74 55 73 65 64  ARAMETER(NotUsed
5bd0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 63 61  );.  assert( pca
5be0: 63 68 65 31 2e 69 73 49 6e 69 74 3d 3d 30 20 29  che1.isInit==0 )
5bf0: 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 63 61 63  ;.  memset(&pcac
5c00: 68 65 31 2c 20 30 2c 20 73 69 7a 65 6f 66 28 70  he1, 0, sizeof(p
5c10: 63 61 63 68 65 31 29 29 3b 0a 0a 0a 20 20 2f 2a  cache1));...  /*
5c20: 0a 20 20 2a 2a 20 54 68 65 20 70 63 61 63 68 65  .  ** The pcache
5c30: 31 2e 73 65 70 61 72 61 74 65 43 61 63 68 65 20  1.separateCache 
5c40: 76 61 72 69 61 62 6c 65 20 69 73 20 74 72 75 65  variable is true
5c50: 20 69 66 20 65 61 63 68 20 50 43 61 63 68 65 20   if each PCache 
5c60: 68 61 73 20 69 74 73 20 6f 77 6e 0a 20 20 2a 2a  has its own.  **
5c70: 20 70 72 69 76 61 74 65 20 50 47 72 6f 75 70 20   private PGroup 
5c80: 28 6d 6f 64 65 2d 31 29 2e 20 20 70 63 61 63 68  (mode-1).  pcach
5c90: 65 31 2e 73 65 70 61 72 61 74 65 43 61 63 68 65  e1.separateCache
5ca0: 20 69 73 20 66 61 6c 73 65 20 69 66 20 74 68 65   is false if the
5cb0: 20 73 69 6e 67 6c 65 0a 20 20 2a 2a 20 50 47 72   single.  ** PGr
5cc0: 6f 75 70 20 69 6e 20 70 63 61 63 68 65 31 2e 67  oup in pcache1.g
5cd0: 72 70 20 69 73 20 75 73 65 64 20 66 6f 72 20 61  rp is used for a
5ce0: 6c 6c 20 70 61 67 65 20 63 61 63 68 65 73 20 28  ll page caches (
5cf0: 6d 6f 64 65 2d 32 29 2e 0a 20 20 2a 2a 0a 20 20  mode-2)..  **.  
5d00: 2a 2a 20 20 20 2a 20 20 41 6c 77 61 79 73 20 75  **   *  Always u
5d10: 73 65 20 61 20 75 6e 69 66 69 65 64 20 63 61 63  se a unified cac
5d20: 68 65 20 28 6d 6f 64 65 2d 32 29 20 69 66 20 45  he (mode-2) if E
5d30: 4e 41 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e  NABLE_MEMORY_MAN
5d40: 41 47 45 4d 45 4e 54 0a 20 20 2a 2a 0a 20 20 2a  AGEMENT.  **.  *
5d50: 2a 20 20 20 2a 20 20 55 73 65 20 61 20 75 6e 69  *   *  Use a uni
5d60: 66 69 65 64 20 63 61 63 68 65 20 69 6e 20 73 69  fied cache in si
5d70: 6e 67 6c 65 2d 74 68 72 65 61 64 65 64 20 61 70  ngle-threaded ap
5d80: 70 6c 69 63 61 74 69 6f 6e 73 20 74 68 61 74 20  plications that 
5d90: 68 61 76 65 0a 20 20 2a 2a 20 20 20 20 20 20 63  have.  **      c
5da0: 6f 6e 66 69 67 75 72 65 64 20 61 20 73 74 61 72  onfigured a star
5db0: 74 2d 74 69 6d 65 20 62 75 66 66 65 72 20 66 6f  t-time buffer fo
5dc0: 72 20 75 73 65 20 61 73 20 70 61 67 65 2d 63 61  r use as page-ca
5dd0: 63 68 65 20 6d 65 6d 6f 72 79 20 75 73 69 6e 67  che memory using
5de0: 0a 20 20 2a 2a 20 20 20 20 20 20 73 71 6c 69 74  .  **      sqlit
5df0: 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45  e3_config(SQLITE
5e00: 5f 43 4f 4e 46 49 47 5f 50 41 47 45 43 41 43 48  _CONFIG_PAGECACH
5e10: 45 2c 20 70 42 75 66 2c 20 73 7a 2c 20 4e 29 20  E, pBuf, sz, N) 
5e20: 77 69 74 68 20 6e 6f 6e 2d 4e 55 4c 4c 20 0a 20  with non-NULL . 
5e30: 20 2a 2a 20 20 20 20 20 20 70 42 75 66 20 61 72   **      pBuf ar
5e40: 67 75 6d 65 6e 74 2e 0a 20 20 2a 2a 0a 20 20 2a  gument..  **.  *
5e50: 2a 20 20 20 2a 20 20 4f 74 68 65 72 77 69 73 65  *   *  Otherwise
5e60: 20 75 73 65 20 73 65 70 61 72 61 74 65 20 63 61   use separate ca
5e70: 63 68 65 73 20 28 6d 6f 64 65 2d 31 29 0a 20 20  ches (mode-1).  
5e80: 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53  */.#if defined(S
5e90: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d  QLITE_ENABLE_MEM
5ea0: 4f 52 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 29 0a  ORY_MANAGEMENT).
5eb0: 20 20 70 63 61 63 68 65 31 2e 73 65 70 61 72 61    pcache1.separa
5ec0: 74 65 43 61 63 68 65 20 3d 20 30 3b 0a 23 65 6c  teCache = 0;.#el
5ed0: 69 66 20 53 51 4c 49 54 45 5f 54 48 52 45 41 44  if SQLITE_THREAD
5ee0: 53 41 46 45 0a 20 20 70 63 61 63 68 65 31 2e 73  SAFE.  pcache1.s
5ef0: 65 70 61 72 61 74 65 43 61 63 68 65 20 3d 20 73  eparateCache = s
5f00: 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66  qlite3GlobalConf
5f10: 69 67 2e 70 50 61 67 65 3d 3d 30 0a 20 20 20 20  ig.pPage==0.    
5f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5f30: 20 20 20 20 20 20 7c 7c 20 73 71 6c 69 74 65 33        || sqlite3
5f40: 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 62 43 6f  GlobalConfig.bCo
5f50: 72 65 4d 75 74 65 78 3e 30 3b 0a 23 65 6c 73 65  reMutex>0;.#else
5f60: 0a 20 20 70 63 61 63 68 65 31 2e 73 65 70 61 72  .  pcache1.separ
5f70: 61 74 65 43 61 63 68 65 20 3d 20 73 71 6c 69 74  ateCache = sqlit
5f80: 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70  e3GlobalConfig.p
5f90: 50 61 67 65 3d 3d 30 3b 0a 23 65 6e 64 69 66 0a  Page==0;.#endif.
5fa0: 0a 23 69 66 20 53 51 4c 49 54 45 5f 54 48 52 45  .#if SQLITE_THRE
5fb0: 41 44 53 41 46 45 0a 20 20 69 66 28 20 73 71 6c  ADSAFE.  if( sql
5fc0: 69 74 65 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67  ite3GlobalConfig
5fd0: 2e 62 43 6f 72 65 4d 75 74 65 78 20 29 7b 0a 20  .bCoreMutex ){. 
5fe0: 20 20 20 70 63 61 63 68 65 31 2e 67 72 70 2e 6d     pcache1.grp.m
5ff0: 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33 5f 6d  utex = sqlite3_m
6000: 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49 54  utex_alloc(SQLIT
6010: 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43 5f 4c  E_MUTEX_STATIC_L
6020: 52 55 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31  RU);.    pcache1
6030: 2e 6d 75 74 65 78 20 3d 20 73 71 6c 69 74 65 33  .mutex = sqlite3
6040: 5f 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51 4c  _mutex_alloc(SQL
6050: 49 54 45 5f 4d 55 54 45 58 5f 53 54 41 54 49 43  ITE_MUTEX_STATIC
6060: 5f 50 4d 45 4d 29 3b 0a 20 20 7d 0a 23 65 6e 64  _PMEM);.  }.#end
6070: 69 66 0a 20 20 69 66 28 20 70 63 61 63 68 65 31  if.  if( pcache1
6080: 2e 73 65 70 61 72 61 74 65 43 61 63 68 65 0a 20  .separateCache. 
6090: 20 20 26 26 20 73 71 6c 69 74 65 33 47 6c 6f 62    && sqlite3Glob
60a0: 61 6c 43 6f 6e 66 69 67 2e 6e 50 61 67 65 21 3d  alConfig.nPage!=
60b0: 30 0a 20 20 20 26 26 20 73 71 6c 69 74 65 33 47  0.   && sqlite3G
60c0: 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 70 50 61 67  lobalConfig.pPag
60d0: 65 3d 3d 30 0a 20 20 29 7b 0a 20 20 20 20 70 63  e==0.  ){.    pc
60e0: 61 63 68 65 31 2e 6e 49 6e 69 74 50 61 67 65 20  ache1.nInitPage 
60f0: 3d 20 73 71 6c 69 74 65 33 47 6c 6f 62 61 6c 43  = sqlite3GlobalC
6100: 6f 6e 66 69 67 2e 6e 50 61 67 65 3b 0a 20 20 7d  onfig.nPage;.  }
6110: 65 6c 73 65 7b 0a 20 20 20 20 70 63 61 63 68 65  else{.    pcache
6120: 31 2e 6e 49 6e 69 74 50 61 67 65 20 3d 20 30 3b  1.nInitPage = 0;
6130: 0a 20 20 7d 0a 20 20 70 63 61 63 68 65 31 2e 67  .  }.  pcache1.g
6140: 72 70 2e 6d 78 50 69 6e 6e 65 64 20 3d 20 31 30  rp.mxPinned = 10
6150: 3b 0a 20 20 70 63 61 63 68 65 31 2e 69 73 49 6e  ;.  pcache1.isIn
6160: 69 74 20 3d 20 31 3b 0a 20 20 72 65 74 75 72 6e  it = 1;.  return
6170: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
6180: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
6190: 69 6f 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74  ion of the sqlit
61a0: 65 33 5f 70 63 61 63 68 65 2e 78 53 68 75 74 64  e3_pcache.xShutd
61b0: 6f 77 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2a 20 4e  own method..** N
61c0: 6f 74 65 20 74 68 61 74 20 74 68 65 20 73 74 61  ote that the sta
61d0: 74 69 63 20 6d 75 74 65 78 20 61 6c 6c 6f 63 61  tic mutex alloca
61e0: 74 65 64 20 69 6e 20 78 49 6e 69 74 20 64 6f 65  ted in xInit doe
61f0: 73 20 0a 2a 2a 20 6e 6f 74 20 6e 65 65 64 20 74  s .** not need t
6200: 6f 20 62 65 20 66 72 65 65 64 2e 0a 2a 2f 0a 73  o be freed..*/.s
6210: 74 61 74 69 63 20 76 6f 69 64 20 70 63 61 63 68  tatic void pcach
6220: 65 31 53 68 75 74 64 6f 77 6e 28 76 6f 69 64 20  e1Shutdown(void 
6230: 2a 4e 6f 74 55 73 65 64 29 7b 0a 20 20 55 4e 55  *NotUsed){.  UNU
6240: 53 45 44 5f 50 41 52 41 4d 45 54 45 52 28 4e 6f  SED_PARAMETER(No
6250: 74 55 73 65 64 29 3b 0a 20 20 61 73 73 65 72 74  tUsed);.  assert
6260: 28 20 70 63 61 63 68 65 31 2e 69 73 49 6e 69 74  ( pcache1.isInit
6270: 21 3d 30 20 29 3b 0a 20 20 6d 65 6d 73 65 74 28  !=0 );.  memset(
6280: 26 70 63 61 63 68 65 31 2c 20 30 2c 20 73 69 7a  &pcache1, 0, siz
6290: 65 6f 66 28 70 63 61 63 68 65 31 29 29 3b 0a 7d  eof(pcache1));.}
62a0: 0a 0a 2f 2a 20 66 6f 72 77 61 72 64 20 64 65 63  ../* forward dec
62b0: 6c 61 72 61 74 69 6f 6e 20 2a 2f 0a 73 74 61 74  laration */.stat
62c0: 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31 44  ic void pcache1D
62d0: 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f 70  estroy(sqlite3_p
62e0: 63 61 63 68 65 20 2a 70 29 3b 0a 0a 2f 2a 0a 2a  cache *p);../*.*
62f0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
6300: 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f   of the sqlite3_
6310: 70 63 61 63 68 65 2e 78 43 72 65 61 74 65 20 6d  pcache.xCreate m
6320: 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c  ethod..**.** All
6330: 6f 63 61 74 65 20 61 20 6e 65 77 20 63 61 63 68  ocate a new cach
6340: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c  e..*/.static sql
6350: 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 63 61  ite3_pcache *pca
6360: 63 68 65 31 43 72 65 61 74 65 28 69 6e 74 20 73  che1Create(int s
6370: 7a 50 61 67 65 2c 20 69 6e 74 20 73 7a 45 78 74  zPage, int szExt
6380: 72 61 2c 20 69 6e 74 20 62 50 75 72 67 65 61 62  ra, int bPurgeab
6390: 6c 65 29 7b 0a 20 20 50 43 61 63 68 65 31 20 2a  le){.  PCache1 *
63a0: 70 43 61 63 68 65 3b 20 20 20 20 20 20 2f 2a 20  pCache;      /* 
63b0: 54 68 65 20 6e 65 77 6c 79 20 63 72 65 61 74 65  The newly create
63c0: 64 20 70 61 67 65 20 63 61 63 68 65 20 2a 2f 0a  d page cache */.
63d0: 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70    PGroup *pGroup
63e0: 3b 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 67  ;       /* The g
63f0: 72 6f 75 70 20 74 68 65 20 6e 65 77 20 70 61 67  roup the new pag
6400: 65 20 63 61 63 68 65 20 77 69 6c 6c 20 62 65 6c  e cache will bel
6410: 6f 6e 67 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20  ong to */.  int 
6420: 73 7a 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  sz;             
6430: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 6d 65    /* Bytes of me
6440: 6d 6f 72 79 20 72 65 71 75 69 72 65 64 20 74 6f  mory required to
6450: 20 61 6c 6c 6f 63 61 74 65 20 74 68 65 20 6e 65   allocate the ne
6460: 77 20 63 61 63 68 65 20 2a 2f 0a 0a 20 20 61 73  w cache */..  as
6470: 73 65 72 74 28 20 28 73 7a 50 61 67 65 20 26 20  sert( (szPage & 
6480: 28 73 7a 50 61 67 65 2d 31 29 29 3d 3d 30 20 26  (szPage-1))==0 &
6490: 26 20 73 7a 50 61 67 65 3e 3d 35 31 32 20 26 26  & szPage>=512 &&
64a0: 20 73 7a 50 61 67 65 3c 3d 36 35 35 33 36 20 29   szPage<=65536 )
64b0: 3b 0a 20 20 61 73 73 65 72 74 28 20 73 7a 45 78  ;.  assert( szEx
64c0: 74 72 61 20 3c 20 33 30 30 20 29 3b 0a 0a 20 20  tra < 300 );..  
64d0: 73 7a 20 3d 20 73 69 7a 65 6f 66 28 50 43 61 63  sz = sizeof(PCac
64e0: 68 65 31 29 20 2b 20 73 69 7a 65 6f 66 28 50 47  he1) + sizeof(PG
64f0: 72 6f 75 70 29 2a 70 63 61 63 68 65 31 2e 73 65  roup)*pcache1.se
6500: 70 61 72 61 74 65 43 61 63 68 65 3b 0a 20 20 70  parateCache;.  p
6510: 43 61 63 68 65 20 3d 20 28 50 43 61 63 68 65 31  Cache = (PCache1
6520: 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   *)sqlite3Malloc
6530: 5a 65 72 6f 28 73 7a 29 3b 0a 20 20 69 66 28 20  Zero(sz);.  if( 
6540: 70 43 61 63 68 65 20 29 7b 0a 20 20 20 20 69 66  pCache ){.    if
6550: 28 20 70 63 61 63 68 65 31 2e 73 65 70 61 72 61  ( pcache1.separa
6560: 74 65 43 61 63 68 65 20 29 7b 0a 20 20 20 20 20  teCache ){.     
6570: 20 70 47 72 6f 75 70 20 3d 20 28 50 47 72 6f 75   pGroup = (PGrou
6580: 70 2a 29 26 70 43 61 63 68 65 5b 31 5d 3b 0a 20  p*)&pCache[1];. 
6590: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6d 78 50       pGroup->mxP
65a0: 69 6e 6e 65 64 20 3d 20 31 30 3b 0a 20 20 20 20  inned = 10;.    
65b0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 70 47 72  }else{.      pGr
65c0: 6f 75 70 20 3d 20 26 70 63 61 63 68 65 31 2e 67  oup = &pcache1.g
65d0: 72 70 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43  rp;.    }.    pC
65e0: 61 63 68 65 2d 3e 70 47 72 6f 75 70 20 3d 20 70  ache->pGroup = p
65f0: 47 72 6f 75 70 3b 0a 20 20 20 20 70 43 61 63 68  Group;.    pCach
6600: 65 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61  e->szPage = szPa
6610: 67 65 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e  ge;.    pCache->
6620: 73 7a 45 78 74 72 61 20 3d 20 73 7a 45 78 74 72  szExtra = szExtr
6630: 61 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 73  a;.    pCache->s
6640: 7a 41 6c 6c 6f 63 20 3d 20 73 7a 50 61 67 65 20  zAlloc = szPage 
6650: 2b 20 73 7a 45 78 74 72 61 20 2b 20 52 4f 55 4e  + szExtra + ROUN
6660: 44 38 28 73 69 7a 65 6f 66 28 50 67 48 64 72 31  D8(sizeof(PgHdr1
6670: 29 29 3b 0a 20 20 20 20 70 43 61 63 68 65 2d 3e  ));.    pCache->
6680: 62 50 75 72 67 65 61 62 6c 65 20 3d 20 28 62 50  bPurgeable = (bP
6690: 75 72 67 65 61 62 6c 65 20 3f 20 31 20 3a 20 30  urgeable ? 1 : 0
66a0: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 45 6e  );.    pcache1En
66b0: 74 65 72 4d 75 74 65 78 28 70 47 72 6f 75 70 29  terMutex(pGroup)
66c0: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 52 65 73  ;.    pcache1Res
66d0: 69 7a 65 48 61 73 68 28 70 43 61 63 68 65 29 3b  izeHash(pCache);
66e0: 0a 20 20 20 20 69 66 28 20 62 50 75 72 67 65 61  .    if( bPurgea
66f0: 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 70 43 61  ble ){.      pCa
6700: 63 68 65 2d 3e 6e 4d 69 6e 20 3d 20 31 30 3b 0a  che->nMin = 10;.
6710: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 6e 4d        pGroup->nM
6720: 69 6e 50 61 67 65 20 2b 3d 20 70 43 61 63 68 65  inPage += pCache
6730: 2d 3e 6e 4d 69 6e 3b 0a 20 20 20 20 20 20 70 47  ->nMin;.      pG
6740: 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d  roup->mxPinned =
6750: 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67   pGroup->nMaxPag
6760: 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70 2d  e + 10 - pGroup-
6770: 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 20 20 7d  >nMinPage;.    }
6780: 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61 76  .    pcache1Leav
6790: 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a  eMutex(pGroup);.
67a0: 20 20 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e      if( pCache->
67b0: 6e 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20  nHash==0 ){.    
67c0: 20 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79    pcache1Destroy
67d0: 28 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  ((sqlite3_pcache
67e0: 2a 29 70 43 61 63 68 65 29 3b 0a 20 20 20 20 20  *)pCache);.     
67f0: 20 70 43 61 63 68 65 20 3d 20 30 3b 0a 20 20 20   pCache = 0;.   
6800: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
6810: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
6820: 2a 29 70 43 61 63 68 65 3b 0a 7d 0a 0a 2f 2a 0a  *)pCache;.}../*.
6830: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
6840: 6e 20 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33  n of the sqlite3
6850: 5f 70 63 61 63 68 65 2e 78 43 61 63 68 65 73 69  _pcache.xCachesi
6860: 7a 65 20 6d 65 74 68 6f 64 2e 20 0a 2a 2a 0a 2a  ze method. .**.*
6870: 2a 20 43 6f 6e 66 69 67 75 72 65 20 74 68 65 20  * Configure the 
6880: 63 61 63 68 65 5f 73 69 7a 65 20 6c 69 6d 69 74  cache_size limit
6890: 20 66 6f 72 20 61 20 63 61 63 68 65 2e 0a 2a 2f   for a cache..*/
68a0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
68b0: 63 68 65 31 43 61 63 68 65 73 69 7a 65 28 73 71  che1Cachesize(sq
68c0: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
68d0: 20 69 6e 74 20 6e 4d 61 78 29 7b 0a 20 20 50 43   int nMax){.  PC
68e0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
68f0: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
6900: 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  if( pCache->bPur
6910: 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20 50 47  geable ){.    PG
6920: 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70  roup *pGroup = p
6930: 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b 0a 20  Cache->pGroup;. 
6940: 20 20 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d     pcache1EnterM
6950: 75 74 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20  utex(pGroup);.  
6960: 20 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61    pGroup->nMaxPa
6970: 67 65 20 2b 3d 20 28 6e 4d 61 78 20 2d 20 70 43  ge += (nMax - pC
6980: 61 63 68 65 2d 3e 6e 4d 61 78 29 3b 0a 20 20 20  ache->nMax);.   
6990: 20 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65   pGroup->mxPinne
69a0: 64 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78  d = pGroup->nMax
69b0: 50 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f  Page + 10 - pGro
69c0: 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20  up->nMinPage;.  
69d0: 20 20 70 43 61 63 68 65 2d 3e 6e 4d 61 78 20 3d    pCache->nMax =
69e0: 20 6e 4d 61 78 3b 0a 20 20 20 20 70 43 61 63 68   nMax;.    pCach
69f0: 65 2d 3e 6e 39 30 70 63 74 20 3d 20 70 43 61 63  e->n90pct = pCac
6a00: 68 65 2d 3e 6e 4d 61 78 2a 39 2f 31 30 3b 0a 20  he->nMax*9/10;. 
6a10: 20 20 20 70 63 61 63 68 65 31 45 6e 66 6f 72 63     pcache1Enforc
6a20: 65 4d 61 78 50 61 67 65 28 70 43 61 63 68 65 29  eMaxPage(pCache)
6a30: 3b 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61  ;.    pcache1Lea
6a40: 76 65 4d 75 74 65 78 28 70 47 72 6f 75 70 29 3b  veMutex(pGroup);
6a50: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d  .  }.}../*.** Im
6a60: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
6a70: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
6a80: 68 65 2e 78 53 68 72 69 6e 6b 20 6d 65 74 68 6f  he.xShrink metho
6a90: 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 72 65 65 20 75  d. .**.** Free u
6aa0: 70 20 61 73 20 6d 75 63 68 20 6d 65 6d 6f 72 79  p as much memory
6ab0: 20 61 73 20 70 6f 73 73 69 62 6c 65 2e 0a 2a 2f   as possible..*/
6ac0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63 61  .static void pca
6ad0: 63 68 65 31 53 68 72 69 6e 6b 28 73 71 6c 69 74  che1Shrink(sqlit
6ae0: 65 33 5f 70 63 61 63 68 65 20 2a 70 29 7b 0a 20  e3_pcache *p){. 
6af0: 20 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65   PCache1 *pCache
6b00: 20 3d 20 28 50 43 61 63 68 65 31 2a 29 70 3b 0a   = (PCache1*)p;.
6b10: 20 20 69 66 28 20 70 43 61 63 68 65 2d 3e 62 50    if( pCache->bP
6b20: 75 72 67 65 61 62 6c 65 20 29 7b 0a 20 20 20 20  urgeable ){.    
6b30: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d  PGroup *pGroup =
6b40: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
6b50: 0a 20 20 20 20 69 6e 74 20 73 61 76 65 64 4d 61  .    int savedMa
6b60: 78 50 61 67 65 3b 0a 20 20 20 20 70 63 61 63 68  xPage;.    pcach
6b70: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72  e1EnterMutex(pGr
6b80: 6f 75 70 29 3b 0a 20 20 20 20 73 61 76 65 64 4d  oup);.    savedM
6b90: 61 78 50 61 67 65 20 3d 20 70 47 72 6f 75 70 2d  axPage = pGroup-
6ba0: 3e 6e 4d 61 78 50 61 67 65 3b 0a 20 20 20 20 70  >nMaxPage;.    p
6bb0: 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20  Group->nMaxPage 
6bc0: 3d 20 30 3b 0a 20 20 20 20 70 63 61 63 68 65 31  = 0;.    pcache1
6bd0: 45 6e 66 6f 72 63 65 4d 61 78 50 61 67 65 28 70  EnforceMaxPage(p
6be0: 43 61 63 68 65 29 3b 0a 20 20 20 20 70 47 72 6f  Cache);.    pGro
6bf0: 75 70 2d 3e 6e 4d 61 78 50 61 67 65 20 3d 20 73  up->nMaxPage = s
6c00: 61 76 65 64 4d 61 78 50 61 67 65 3b 0a 20 20 20  avedMaxPage;.   
6c10: 20 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74   pcache1LeaveMut
6c20: 65 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d 0a  ex(pGroup);.  }.
6c30: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
6c40: 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73  ntation of the s
6c50: 71 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 50  qlite3_pcache.xP
6c60: 61 67 65 63 6f 75 6e 74 20 6d 65 74 68 6f 64 2e  agecount method.
6c70: 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20   .*/.static int 
6c80: 70 63 61 63 68 65 31 50 61 67 65 63 6f 75 6e 74  pcache1Pagecount
6c90: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20  (sqlite3_pcache 
6ca0: 2a 70 29 7b 0a 20 20 69 6e 74 20 6e 3b 0a 20 20  *p){.  int n;.  
6cb0: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
6cc0: 3d 20 28 50 43 61 63 68 65 31 2a 29 70 3b 0a 20  = (PCache1*)p;. 
6cd0: 20 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74   pcache1EnterMut
6ce0: 65 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75  ex(pCache->pGrou
6cf0: 70 29 3b 0a 20 20 6e 20 3d 20 70 43 61 63 68 65  p);.  n = pCache
6d00: 2d 3e 6e 50 61 67 65 3b 0a 20 20 70 63 61 63 68  ->nPage;.  pcach
6d10: 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43 61  e1LeaveMutex(pCa
6d20: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  che->pGroup);.  
6d30: 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a 0a 2f 2a  return n;.}.../*
6d40: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 20 73 74  .** Implement st
6d50: 65 70 73 20 33 2c 20 34 2c 20 61 6e 64 20 35 20  eps 3, 4, and 5 
6d60: 6f 66 20 74 68 65 20 70 63 61 63 68 65 31 46 65  of the pcache1Fe
6d70: 74 63 68 28 29 20 61 6c 67 6f 72 69 74 68 6d 20  tch() algorithm 
6d80: 64 65 73 63 72 69 62 65 64 0a 2a 2a 20 69 6e 20  described.** in 
6d90: 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 74 68  the header of th
6da0: 65 20 70 63 61 63 68 65 31 46 65 74 63 68 28 29  e pcache1Fetch()
6db0: 20 70 72 6f 63 65 64 75 72 65 2e 0a 2a 2a 0a 2a   procedure..**.*
6dc0: 2a 20 54 68 69 73 20 73 74 65 70 73 20 61 72 65  * This steps are
6dd0: 20 62 72 6f 6b 65 6e 20 6f 75 74 20 69 6e 74 6f   broken out into
6de0: 20 61 20 73 65 70 61 72 61 74 65 20 70 72 6f 63   a separate proc
6df0: 65 64 75 72 65 20 62 65 63 61 75 73 65 20 74 68  edure because th
6e00: 65 79 20 61 72 65 0a 2a 2a 20 75 73 75 61 6c 6c  ey are.** usuall
6e10: 79 20 6e 6f 74 20 6e 65 65 64 65 64 2c 20 61 6e  y not needed, an
6e20: 64 20 62 79 20 61 76 6f 69 64 69 6e 67 20 74 68  d by avoiding th
6e30: 65 20 73 74 61 63 6b 20 69 6e 69 74 69 61 6c 69  e stack initiali
6e40: 7a 61 74 69 6f 6e 20 72 65 71 75 69 72 65 64 0a  zation required.
6e50: 2a 2a 20 66 6f 72 20 74 68 65 73 65 20 73 74 65  ** for these ste
6e60: 70 73 2c 20 74 68 65 20 6d 61 69 6e 20 70 63 61  ps, the main pca
6e70: 63 68 65 31 46 65 74 63 68 28 29 20 70 72 6f 63  che1Fetch() proc
6e80: 65 64 75 72 65 20 63 61 6e 20 72 75 6e 20 66 61  edure can run fa
6e90: 73 74 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ster..*/.static 
6ea0: 53 51 4c 49 54 45 5f 4e 4f 49 4e 4c 49 4e 45 20  SQLITE_NOINLINE 
6eb0: 50 67 48 64 72 31 20 2a 70 63 61 63 68 65 31 46  PgHdr1 *pcache1F
6ec0: 65 74 63 68 53 74 61 67 65 32 28 0a 20 20 50 43  etchStage2(.  PC
6ed0: 61 63 68 65 31 20 2a 70 43 61 63 68 65 2c 20 0a  ache1 *pCache, .
6ee0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
6ef0: 4b 65 79 2c 20 0a 20 20 69 6e 74 20 63 72 65 61  Key, .  int crea
6f00: 74 65 46 6c 61 67 0a 29 7b 0a 20 20 75 6e 73 69  teFlag.){.  unsi
6f10: 67 6e 65 64 20 69 6e 74 20 6e 50 69 6e 6e 65 64  gned int nPinned
6f20: 3b 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f  ;.  PGroup *pGro
6f30: 75 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72  up = pCache->pGr
6f40: 6f 75 70 3b 0a 20 20 50 67 48 64 72 31 20 2a 70  oup;.  PgHdr1 *p
6f50: 50 61 67 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20  Page = 0;..  /* 
6f60: 53 74 65 70 20 33 3a 20 41 62 6f 72 74 20 69 66  Step 3: Abort if
6f70: 20 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 31   createFlag is 1
6f80: 20 62 75 74 20 74 68 65 20 63 61 63 68 65 20 69   but the cache i
6f90: 73 20 6e 65 61 72 6c 79 20 66 75 6c 6c 20 2a 2f  s nearly full */
6fa0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
6fb0: 65 2d 3e 6e 50 61 67 65 20 3e 3d 20 70 43 61 63  e->nPage >= pCac
6fc0: 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62 6c 65 20  he->nRecyclable 
6fd0: 29 3b 0a 20 20 6e 50 69 6e 6e 65 64 20 3d 20 70  );.  nPinned = p
6fe0: 43 61 63 68 65 2d 3e 6e 50 61 67 65 20 2d 20 70  Cache->nPage - p
6ff0: 43 61 63 68 65 2d 3e 6e 52 65 63 79 63 6c 61 62  Cache->nRecyclab
7000: 6c 65 3b 0a 20 20 61 73 73 65 72 74 28 20 70 47  le;.  assert( pG
7010: 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64 20 3d  roup->mxPinned =
7020: 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50 61  = pGroup->nMaxPa
7030: 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75 70  ge + 10 - pGroup
7040: 2d 3e 6e 4d 69 6e 50 61 67 65 20 29 3b 0a 20 20  ->nMinPage );.  
7050: 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e  assert( pCache->
7060: 6e 39 30 70 63 74 20 3d 3d 20 70 43 61 63 68 65  n90pct == pCache
7070: 2d 3e 6e 4d 61 78 2a 39 2f 31 30 20 29 3b 0a 20  ->nMax*9/10 );. 
7080: 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d   if( createFlag=
7090: 3d 31 20 26 26 20 28 0a 20 20 20 20 20 20 20 20  =1 && (.        
70a0: 6e 50 69 6e 6e 65 64 3e 3d 70 47 72 6f 75 70 2d  nPinned>=pGroup-
70b0: 3e 6d 78 50 69 6e 6e 65 64 0a 20 20 20 20 20 7c  >mxPinned.     |
70c0: 7c 20 6e 50 69 6e 6e 65 64 3e 3d 70 43 61 63 68  | nPinned>=pCach
70d0: 65 2d 3e 6e 39 30 70 63 74 0a 20 20 20 20 20 7c  e->n90pct.     |
70e0: 7c 20 28 70 63 61 63 68 65 31 55 6e 64 65 72 4d  | (pcache1UnderM
70f0: 65 6d 6f 72 79 50 72 65 73 73 75 72 65 28 70 43  emoryPressure(pC
7100: 61 63 68 65 29 20 26 26 20 70 43 61 63 68 65 2d  ache) && pCache-
7110: 3e 6e 52 65 63 79 63 6c 61 62 6c 65 3c 6e 50 69  >nRecyclable<nPi
7120: 6e 6e 65 64 29 0a 20 20 29 29 7b 0a 20 20 20 20  nned).  )){.    
7130: 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20  return 0;.  }.. 
7140: 20 69 66 28 20 70 43 61 63 68 65 2d 3e 6e 50 61   if( pCache->nPa
7150: 67 65 3e 3d 70 43 61 63 68 65 2d 3e 6e 48 61 73  ge>=pCache->nHas
7160: 68 20 29 20 70 63 61 63 68 65 31 52 65 73 69 7a  h ) pcache1Resiz
7170: 65 48 61 73 68 28 70 43 61 63 68 65 29 3b 0a 20  eHash(pCache);. 
7180: 20 61 73 73 65 72 74 28 20 70 43 61 63 68 65 2d   assert( pCache-
7190: 3e 6e 48 61 73 68 3e 30 20 26 26 20 70 43 61 63  >nHash>0 && pCac
71a0: 68 65 2d 3e 61 70 48 61 73 68 20 29 3b 0a 0a 20  he->apHash );.. 
71b0: 20 2f 2a 20 53 74 65 70 20 34 2e 20 54 72 79 20   /* Step 4. Try 
71c0: 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61 67  to recycle a pag
71d0: 65 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 61 63  e. */.  if( pCac
71e0: 68 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 0a 20  he->bPurgeable. 
71f0: 20 20 26 26 20 70 47 72 6f 75 70 2d 3e 70 4c 72    && pGroup->pLr
7200: 75 54 61 69 6c 0a 20 20 20 26 26 20 28 28 70 43  uTail.   && ((pC
7210: 61 63 68 65 2d 3e 6e 50 61 67 65 2b 31 3e 3d 70  ache->nPage+1>=p
7220: 43 61 63 68 65 2d 3e 6e 4d 61 78 29 20 7c 7c 20  Cache->nMax) || 
7230: 70 63 61 63 68 65 31 55 6e 64 65 72 4d 65 6d 6f  pcache1UnderMemo
7240: 72 79 50 72 65 73 73 75 72 65 28 70 43 61 63 68  ryPressure(pCach
7250: 65 29 29 0a 20 20 29 7b 0a 20 20 20 20 50 43 61  e)).  ){.    PCa
7260: 63 68 65 31 20 2a 70 4f 74 68 65 72 3b 0a 20 20  che1 *pOther;.  
7270: 20 20 70 50 61 67 65 20 3d 20 70 47 72 6f 75 70    pPage = pGroup
7280: 2d 3e 70 4c 72 75 54 61 69 6c 3b 0a 20 20 20 20  ->pLruTail;.    
7290: 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e 69  assert( pPage->i
72a0: 73 50 69 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20 20  sPinned==0 );.  
72b0: 20 20 70 63 61 63 68 65 31 52 65 6d 6f 76 65 46    pcache1RemoveF
72c0: 72 6f 6d 48 61 73 68 28 70 50 61 67 65 2c 20 30  romHash(pPage, 0
72d0: 29 3b 0a 20 20 20 20 70 63 61 63 68 65 31 50 69  );.    pcache1Pi
72e0: 6e 50 61 67 65 28 70 50 61 67 65 29 3b 0a 20 20  nPage(pPage);.  
72f0: 20 20 70 4f 74 68 65 72 20 3d 20 70 50 61 67 65    pOther = pPage
7300: 2d 3e 70 43 61 63 68 65 3b 0a 20 20 20 20 69 66  ->pCache;.    if
7310: 28 20 70 4f 74 68 65 72 2d 3e 73 7a 41 6c 6c 6f  ( pOther->szAllo
7320: 63 20 21 3d 20 70 43 61 63 68 65 2d 3e 73 7a 41  c != pCache->szA
7330: 6c 6c 6f 63 20 29 7b 0a 20 20 20 20 20 20 70 63  lloc ){.      pc
7340: 61 63 68 65 31 46 72 65 65 50 61 67 65 28 70 50  ache1FreePage(pP
7350: 61 67 65 29 3b 0a 20 20 20 20 20 20 70 50 61 67  age);.      pPag
7360: 65 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65  e = 0;.    }else
7370: 7b 0a 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e  {.      pGroup->
7380: 6e 43 75 72 72 65 6e 74 50 61 67 65 20 2d 3d 20  nCurrentPage -= 
7390: 28 70 4f 74 68 65 72 2d 3e 62 50 75 72 67 65 61  (pOther->bPurgea
73a0: 62 6c 65 20 2d 20 70 43 61 63 68 65 2d 3e 62 50  ble - pCache->bP
73b0: 75 72 67 65 61 62 6c 65 29 3b 0a 20 20 20 20 7d  urgeable);.    }
73c0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 74 65 70 20  .  }..  /* Step 
73d0: 35 2e 20 49 66 20 61 20 75 73 61 62 6c 65 20 70  5. If a usable p
73e0: 61 67 65 20 62 75 66 66 65 72 20 68 61 73 20 73  age buffer has s
73f0: 74 69 6c 6c 20 6e 6f 74 20 62 65 65 6e 20 66 6f  till not been fo
7400: 75 6e 64 2c 20 0a 20 20 2a 2a 20 61 74 74 65 6d  und, .  ** attem
7410: 70 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61  pt to allocate a
7420: 20 6e 65 77 20 6f 6e 65 2e 20 0a 20 20 2a 2f 0a   new one. .  */.
7430: 20 20 69 66 28 20 21 70 50 61 67 65 20 29 7b 0a    if( !pPage ){.
7440: 20 20 20 20 69 66 28 20 63 72 65 61 74 65 46 6c      if( createFl
7450: 61 67 3d 3d 31 20 29 7b 20 73 71 6c 69 74 65 33  ag==1 ){ sqlite3
7460: 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f  BeginBenignMallo
7470: 63 28 29 3b 20 7d 0a 20 20 20 20 70 50 61 67 65  c(); }.    pPage
7480: 20 3d 20 70 63 61 63 68 65 31 41 6c 6c 6f 63 50   = pcache1AllocP
7490: 61 67 65 28 70 43 61 63 68 65 29 3b 0a 20 20 20  age(pCache);.   
74a0: 20 69 66 28 20 63 72 65 61 74 65 46 6c 61 67 3d   if( createFlag=
74b0: 3d 31 20 29 7b 20 73 71 6c 69 74 65 33 45 6e 64  =1 ){ sqlite3End
74c0: 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 20  BenignMalloc(); 
74d0: 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 50 61  }.  }..  if( pPa
74e0: 67 65 20 29 7b 0a 20 20 20 20 75 6e 73 69 67 6e  ge ){.    unsign
74f0: 65 64 20 69 6e 74 20 68 20 3d 20 69 4b 65 79 20  ed int h = iKey 
7500: 25 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3b  % pCache->nHash;
7510: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 6e 50 61  .    pCache->nPa
7520: 67 65 2b 2b 3b 0a 20 20 20 20 70 50 61 67 65 2d  ge++;.    pPage-
7530: 3e 69 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20  >iKey = iKey;.  
7540: 20 20 70 50 61 67 65 2d 3e 70 4e 65 78 74 20 3d    pPage->pNext =
7550: 20 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b   pCache->apHash[
7560: 68 5d 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 70  h];.    pPage->p
7570: 43 61 63 68 65 20 3d 20 70 43 61 63 68 65 3b 0a  Cache = pCache;.
7580: 20 20 20 20 70 50 61 67 65 2d 3e 70 4c 72 75 50      pPage->pLruP
7590: 72 65 76 20 3d 20 30 3b 0a 20 20 20 20 70 50 61  rev = 0;.    pPa
75a0: 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20 3d 20 30  ge->pLruNext = 0
75b0: 3b 0a 20 20 20 20 70 50 61 67 65 2d 3e 69 73 50  ;.    pPage->isP
75c0: 69 6e 6e 65 64 20 3d 20 31 3b 0a 20 20 20 20 2a  inned = 1;.    *
75d0: 28 76 6f 69 64 20 2a 2a 29 70 50 61 67 65 2d 3e  (void **)pPage->
75e0: 70 61 67 65 2e 70 45 78 74 72 61 20 3d 20 30 3b  page.pExtra = 0;
75f0: 0a 20 20 20 20 70 43 61 63 68 65 2d 3e 61 70 48  .    pCache->apH
7600: 61 73 68 5b 68 5d 20 3d 20 70 50 61 67 65 3b 0a  ash[h] = pPage;.
7610: 20 20 20 20 69 66 28 20 69 4b 65 79 3e 70 43 61      if( iKey>pCa
7620: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a  che->iMaxKey ){.
7630: 20 20 20 20 20 20 70 43 61 63 68 65 2d 3e 69 4d        pCache->iM
7640: 61 78 4b 65 79 20 3d 20 69 4b 65 79 3b 0a 20 20  axKey = iKey;.  
7650: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
7660: 20 70 50 61 67 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   pPage;.}../*.**
7670: 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   Implementation 
7680: 6f 66 20 74 68 65 20 73 71 6c 69 74 65 33 5f 70  of the sqlite3_p
7690: 63 61 63 68 65 2e 78 46 65 74 63 68 20 6d 65 74  cache.xFetch met
76a0: 68 6f 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 65 74 63  hod. .**.** Fetc
76b0: 68 20 61 20 70 61 67 65 20 62 79 20 6b 65 79 20  h a page by key 
76c0: 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 57 68 65  value..**.** Whe
76d0: 74 68 65 72 20 6f 72 20 6e 6f 74 20 61 20 6e 65  ther or not a ne
76e0: 77 20 70 61 67 65 20 6d 61 79 20 62 65 20 61 6c  w page may be al
76f0: 6c 6f 63 61 74 65 64 20 62 79 20 74 68 69 73 20  located by this 
7700: 66 75 6e 63 74 69 6f 6e 20 64 65 70 65 6e 64 73  function depends
7710: 20 6f 6e 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65   on.** the value
7720: 20 6f 66 20 74 68 65 20 63 72 65 61 74 65 46 6c   of the createFl
7730: 61 67 20 61 72 67 75 6d 65 6e 74 2e 20 20 30 20  ag argument.  0 
7740: 6d 65 61 6e 73 20 64 6f 20 6e 6f 74 20 61 6c 6c  means do not all
7750: 6f 63 61 74 65 20 61 20 6e 65 77 0a 2a 2a 20 70  ocate a new.** p
7760: 61 67 65 2e 20 20 31 20 6d 65 61 6e 73 20 61 6c  age.  1 means al
7770: 6c 6f 63 61 74 65 20 61 20 6e 65 77 20 70 61 67  locate a new pag
7780: 65 20 69 66 20 73 70 61 63 65 20 69 73 20 65 61  e if space is ea
7790: 73 69 6c 79 20 61 76 61 69 6c 61 62 6c 65 2e 20  sily available. 
77a0: 20 32 20 0a 2a 2a 20 6d 65 61 6e 73 20 74 6f 20   2 .** means to 
77b0: 74 72 79 20 72 65 61 6c 6c 79 20 68 61 72 64 20  try really hard 
77c0: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 20 6e 65  to allocate a ne
77d0: 77 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 46 6f  w page..**.** Fo
77e0: 72 20 61 20 6e 6f 6e 2d 70 75 72 67 65 61 62 6c  r a non-purgeabl
77f0: 65 20 63 61 63 68 65 20 28 61 20 63 61 63 68 65  e cache (a cache
7800: 20 75 73 65 64 20 61 73 20 74 68 65 20 73 74 6f   used as the sto
7810: 72 61 67 65 20 66 6f 72 20 61 6e 20 69 6e 2d 6d  rage for an in-m
7820: 65 6d 6f 72 79 0a 2a 2a 20 64 61 74 61 62 61 73  emory.** databas
7830: 65 29 20 74 68 65 72 65 20 69 73 20 72 65 61 6c  e) there is real
7840: 6c 79 20 6e 6f 20 64 69 66 66 65 72 65 6e 63 65  ly no difference
7850: 20 62 65 74 77 65 65 6e 20 63 72 65 61 74 65 46   between createF
7860: 6c 61 67 20 31 20 61 6e 64 20 32 2e 20 20 53 6f  lag 1 and 2.  So
7870: 0a 2a 2a 20 74 68 65 20 63 61 6c 6c 69 6e 67 20  .** the calling 
7880: 66 75 6e 63 74 69 6f 6e 20 28 70 63 61 63 68 65  function (pcache
7890: 2e 63 29 20 77 69 6c 6c 20 6e 65 76 65 72 20 68  .c) will never h
78a0: 61 76 65 20 61 20 63 72 65 61 74 65 46 6c 61 67  ave a createFlag
78b0: 20 6f 66 20 31 20 6f 6e 0a 2a 2a 20 61 20 6e 6f   of 1 on.** a no
78c0: 6e 2d 70 75 72 67 65 61 62 6c 65 20 63 61 63 68  n-purgeable cach
78d0: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 61  e..**.** There a
78e0: 72 65 20 74 68 72 65 65 20 64 69 66 66 65 72 65  re three differe
78f0: 6e 74 20 61 70 70 72 6f 61 63 68 65 73 20 74 6f  nt approaches to
7900: 20 6f 62 74 61 69 6e 69 6e 67 20 73 70 61 63 65   obtaining space
7910: 20 66 6f 72 20 61 20 70 61 67 65 2c 0a 2a 2a 20   for a page,.** 
7920: 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65  depending on the
7930: 20 76 61 6c 75 65 20 6f 66 20 70 61 72 61 6d 65   value of parame
7940: 74 65 72 20 63 72 65 61 74 65 46 6c 61 67 20 28  ter createFlag (
7950: 77 68 69 63 68 20 6d 61 79 20 62 65 20 30 2c 20  which may be 0, 
7960: 31 20 6f 72 20 32 29 2e 0a 2a 2a 0a 2a 2a 20 20  1 or 2)..**.**  
7970: 20 31 2e 20 52 65 67 61 72 64 6c 65 73 73 20 6f   1. Regardless o
7980: 66 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 63  f the value of c
7990: 72 65 61 74 65 46 6c 61 67 2c 20 74 68 65 20 63  reateFlag, the c
79a0: 61 63 68 65 20 69 73 20 73 65 61 72 63 68 65 64  ache is searched
79b0: 20 66 6f 72 20 61 20 0a 2a 2a 20 20 20 20 20 20   for a .**      
79c0: 63 6f 70 79 20 6f 66 20 74 68 65 20 72 65 71 75  copy of the requ
79d0: 65 73 74 65 64 20 70 61 67 65 2e 20 49 66 20 6f  ested page. If o
79e0: 6e 65 20 69 73 20 66 6f 75 6e 64 2c 20 69 74 20  ne is found, it 
79f0: 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a  is returned..**.
7a00: 2a 2a 20 20 20 32 2e 20 49 66 20 63 72 65 61 74  **   2. If creat
7a10: 65 46 6c 61 67 3d 3d 30 20 61 6e 64 20 74 68 65  eFlag==0 and the
7a20: 20 70 61 67 65 20 69 73 20 6e 6f 74 20 61 6c 72   page is not alr
7a30: 65 61 64 79 20 69 6e 20 74 68 65 20 63 61 63 68  eady in the cach
7a40: 65 2c 20 4e 55 4c 4c 20 69 73 0a 2a 2a 20 20 20  e, NULL is.**   
7a50: 20 20 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a     returned..**.
7a60: 2a 2a 20 20 20 33 2e 20 49 66 20 63 72 65 61 74  **   3. If creat
7a70: 65 46 6c 61 67 20 69 73 20 31 2c 20 61 6e 64 20  eFlag is 1, and 
7a80: 74 68 65 20 70 61 67 65 20 69 73 20 6e 6f 74 20  the page is not 
7a90: 61 6c 72 65 61 64 79 20 69 6e 20 74 68 65 20 63  already in the c
7aa0: 61 63 68 65 2c 20 74 68 65 6e 0a 2a 2a 20 20 20  ache, then.**   
7ab0: 20 20 20 72 65 74 75 72 6e 20 4e 55 4c 4c 20 28     return NULL (
7ac0: 64 6f 20 6e 6f 74 20 61 6c 6c 6f 63 61 74 65 20  do not allocate 
7ad0: 61 20 6e 65 77 20 70 61 67 65 29 20 69 66 20 61  a new page) if a
7ae0: 6e 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77  ny of the follow
7af0: 69 6e 67 0a 2a 2a 20 20 20 20 20 20 63 6f 6e 64  ing.**      cond
7b00: 69 74 69 6f 6e 73 20 61 72 65 20 74 72 75 65 3a  itions are true:
7b10: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 28 61 29  .**.**       (a)
7b20: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70   the number of p
7b30: 61 67 65 73 20 70 69 6e 6e 65 64 20 62 79 20 74  ages pinned by t
7b40: 68 65 20 63 61 63 68 65 20 69 73 20 67 72 65 61  he cache is grea
7b50: 74 65 72 20 74 68 61 6e 0a 2a 2a 20 20 20 20 20  ter than.**     
7b60: 20 20 20 20 20 20 50 43 61 63 68 65 31 2e 6e 4d        PCache1.nM
7b70: 61 78 2c 20 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 20  ax, or.**.**    
7b80: 20 20 20 28 62 29 20 74 68 65 20 6e 75 6d 62 65     (b) the numbe
7b90: 72 20 6f 66 20 70 61 67 65 73 20 70 69 6e 6e 65  r of pages pinne
7ba0: 64 20 62 79 20 74 68 65 20 63 61 63 68 65 20 69  d by the cache i
7bb0: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a  s greater than.*
7bc0: 2a 20 20 20 20 20 20 20 20 20 20 20 74 68 65 20  *           the 
7bd0: 73 75 6d 20 6f 66 20 6e 4d 61 78 20 66 6f 72 20  sum of nMax for 
7be0: 61 6c 6c 20 70 75 72 67 65 61 62 6c 65 20 63 61  all purgeable ca
7bf0: 63 68 65 73 2c 20 6c 65 73 73 20 74 68 65 20 73  ches, less the s
7c00: 75 6d 20 6f 66 20 0a 2a 2a 20 20 20 20 20 20 20  um of .**       
7c10: 20 20 20 20 6e 4d 69 6e 20 66 6f 72 20 61 6c 6c      nMin for all
7c20: 20 6f 74 68 65 72 20 70 75 72 67 65 61 62 6c 65   other purgeable
7c30: 20 63 61 63 68 65 73 2c 20 6f 72 0a 2a 2a 0a 2a   caches, or.**.*
7c40: 2a 20 20 20 34 2e 20 49 66 20 6e 6f 6e 65 20 6f  *   4. If none o
7c50: 66 20 74 68 65 20 66 69 72 73 74 20 74 68 72 65  f the first thre
7c60: 65 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 70 70  e conditions app
7c70: 6c 79 20 61 6e 64 20 74 68 65 20 63 61 63 68 65  ly and the cache
7c80: 20 69 73 20 6d 61 72 6b 65 64 0a 2a 2a 20 20 20   is marked.**   
7c90: 20 20 20 61 73 20 70 75 72 67 65 61 62 6c 65 2c     as purgeable,
7ca0: 20 61 6e 64 20 69 66 20 6f 6e 65 20 6f 66 20 74   and if one of t
7cb0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20  he following is 
7cc0: 74 72 75 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  true:.**.**     
7cd0: 20 20 28 61 29 20 54 68 65 20 6e 75 6d 62 65 72    (a) The number
7ce0: 20 6f 66 20 70 61 67 65 73 20 61 6c 6c 6f 63 61   of pages alloca
7cf0: 74 65 64 20 66 6f 72 20 74 68 65 20 63 61 63 68  ted for the cach
7d00: 65 20 69 73 20 61 6c 72 65 61 64 79 20 0a 2a 2a  e is already .**
7d10: 20 20 20 20 20 20 20 20 20 20 20 50 43 61 63 68             PCach
7d20: 65 31 2e 6e 4d 61 78 2c 20 6f 72 0a 2a 2a 0a 2a  e1.nMax, or.**.*
7d30: 2a 20 20 20 20 20 20 20 28 62 29 20 54 68 65 20  *       (b) The 
7d40: 6e 75 6d 62 65 72 20 6f 66 20 70 61 67 65 73 20  number of pages 
7d50: 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61 6c  allocated for al
7d60: 6c 20 70 75 72 67 65 61 62 6c 65 20 63 61 63 68  l purgeable cach
7d70: 65 73 20 69 73 0a 2a 2a 20 20 20 20 20 20 20 20  es is.**        
7d80: 20 20 20 61 6c 72 65 61 64 79 20 65 71 75 61 6c     already equal
7d90: 20 74 6f 20 6f 72 20 67 72 65 61 74 65 72 20 74   to or greater t
7da0: 68 61 6e 20 74 68 65 20 73 75 6d 20 6f 66 20 6e  han the sum of n
7db0: 4d 61 78 20 66 6f 72 20 61 6c 6c 0a 2a 2a 20 20  Max for all.**  
7dc0: 20 20 20 20 20 20 20 20 20 70 75 72 67 65 61 62           purgeab
7dd0: 6c 65 20 63 61 63 68 65 73 2c 0a 2a 2a 0a 2a 2a  le caches,.**.**
7de0: 20 20 20 20 20 20 20 28 63 29 20 54 68 65 20 73         (c) The s
7df0: 79 73 74 65 6d 20 69 73 20 75 6e 64 65 72 20 6d  ystem is under m
7e00: 65 6d 6f 72 79 20 70 72 65 73 73 75 72 65 20 61  emory pressure a
7e10: 6e 64 20 77 61 6e 74 73 20 74 6f 20 61 76 6f 69  nd wants to avoi
7e20: 64 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 75  d.**           u
7e30: 6e 6e 65 63 65 73 73 61 72 79 20 70 61 67 65 73  nnecessary pages
7e40: 20 63 61 63 68 65 20 65 6e 74 72 79 20 61 6c 6c   cache entry all
7e50: 6f 63 61 74 69 6f 6e 73 0a 2a 2a 0a 2a 2a 20 20  ocations.**.**  
7e60: 20 20 20 20 74 68 65 6e 20 61 74 74 65 6d 70 74      then attempt
7e70: 20 74 6f 20 72 65 63 79 63 6c 65 20 61 20 70 61   to recycle a pa
7e80: 67 65 20 66 72 6f 6d 20 74 68 65 20 4c 52 55 20  ge from the LRU 
7e90: 6c 69 73 74 2e 20 49 66 20 69 74 20 69 73 20 74  list. If it is t
7ea0: 68 65 20 72 69 67 68 74 0a 2a 2a 20 20 20 20 20  he right.**     
7eb0: 20 73 69 7a 65 2c 20 72 65 74 75 72 6e 20 74 68   size, return th
7ec0: 65 20 72 65 63 79 63 6c 65 64 20 62 75 66 66 65  e recycled buffe
7ed0: 72 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 66 72  r. Otherwise, fr
7ee0: 65 65 20 74 68 65 20 62 75 66 66 65 72 20 61 6e  ee the buffer an
7ef0: 64 0a 2a 2a 20 20 20 20 20 20 70 72 6f 63 65 65  d.**      procee
7f00: 64 20 74 6f 20 73 74 65 70 20 35 2e 20 0a 2a 2a  d to step 5. .**
7f10: 0a 2a 2a 20 20 20 35 2e 20 4f 74 68 65 72 77 69  .**   5. Otherwi
7f20: 73 65 2c 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64  se, allocate and
7f30: 20 72 65 74 75 72 6e 20 61 20 6e 65 77 20 70 61   return a new pa
7f40: 67 65 20 62 75 66 66 65 72 2e 0a 2a 2a 0a 2a 2a  ge buffer..**.**
7f50: 20 54 68 65 72 65 20 61 72 65 20 74 77 6f 20 76   There are two v
7f60: 65 72 73 69 6f 6e 73 20 6f 66 20 74 68 69 73 20  ersions of this 
7f70: 72 6f 75 74 69 6e 65 2e 20 20 70 63 61 63 68 65  routine.  pcache
7f80: 31 46 65 74 63 68 57 69 74 68 4d 75 74 65 78 28  1FetchWithMutex(
7f90: 29 20 69 73 0a 2a 2a 20 74 68 65 20 67 65 6e 65  ) is.** the gene
7fa0: 72 61 6c 20 63 61 73 65 2e 20 20 70 63 61 63 68  ral case.  pcach
7fb0: 65 31 46 65 74 63 68 4e 6f 4d 75 74 65 78 28 29  e1FetchNoMutex()
7fc0: 20 69 73 20 61 20 66 61 73 74 65 72 20 69 6d 70   is a faster imp
7fd0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 66 6f 72 0a  lementation for.
7fe0: 2a 2a 20 74 68 65 20 63 6f 6d 6d 6f 6e 20 63 61  ** the common ca
7ff0: 73 65 20 77 68 65 72 65 20 70 47 72 6f 75 70 2d  se where pGroup-
8000: 3e 6d 75 74 65 78 20 69 73 20 4e 55 4c 4c 2e 20  >mutex is NULL. 
8010: 20 54 68 65 20 70 63 61 63 68 65 31 46 65 74 63   The pcache1Fetc
8020: 68 28 29 20 77 72 61 70 70 65 72 0a 2a 2a 20 69  h() wrapper.** i
8030: 6e 76 6f 6b 65 73 20 74 68 65 20 61 70 70 72 6f  nvokes the appro
8040: 70 72 69 61 74 65 20 72 6f 75 74 69 6e 65 2e 0a  priate routine..
8050: 2a 2f 0a 73 74 61 74 69 63 20 50 67 48 64 72 31  */.static PgHdr1
8060: 20 2a 70 63 61 63 68 65 31 46 65 74 63 68 4e 6f   *pcache1FetchNo
8070: 4d 75 74 65 78 28 0a 20 20 73 71 6c 69 74 65 33  Mutex(.  sqlite3
8080: 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a 20 20 75  _pcache *p, .  u
8090: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4b 65 79  nsigned int iKey
80a0: 2c 20 0a 20 20 69 6e 74 20 63 72 65 61 74 65 46  , .  int createF
80b0: 6c 61 67 0a 29 7b 0a 20 20 50 43 61 63 68 65 31  lag.){.  PCache1
80c0: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
80d0: 68 65 31 20 2a 29 70 3b 0a 20 20 50 67 48 64 72  he1 *)p;.  PgHdr
80e0: 31 20 2a 70 50 61 67 65 20 3d 20 30 3b 0a 0a 20  1 *pPage = 0;.. 
80f0: 20 2f 2a 20 53 74 65 70 20 31 3a 20 53 65 61 72   /* Step 1: Sear
8100: 63 68 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ch the hash tabl
8110: 65 20 66 6f 72 20 61 6e 20 65 78 69 73 74 69 6e  e for an existin
8120: 67 20 65 6e 74 72 79 2e 20 2a 2f 0a 20 20 70 50  g entry. */.  pP
8130: 61 67 65 20 3d 20 70 43 61 63 68 65 2d 3e 61 70  age = pCache->ap
8140: 48 61 73 68 5b 69 4b 65 79 20 25 20 70 43 61 63  Hash[iKey % pCac
8150: 68 65 2d 3e 6e 48 61 73 68 5d 3b 0a 20 20 77 68  he->nHash];.  wh
8160: 69 6c 65 28 20 70 50 61 67 65 20 26 26 20 70 50  ile( pPage && pP
8170: 61 67 65 2d 3e 69 4b 65 79 21 3d 69 4b 65 79 20  age->iKey!=iKey 
8180: 29 7b 20 70 50 61 67 65 20 3d 20 70 50 61 67 65  ){ pPage = pPage
8190: 2d 3e 70 4e 65 78 74 3b 20 7d 0a 0a 20 20 2f 2a  ->pNext; }..  /*
81a0: 20 53 74 65 70 20 32 3a 20 41 62 6f 72 74 20 69   Step 2: Abort i
81b0: 66 20 6e 6f 20 65 78 69 73 74 69 6e 67 20 70 61  f no existing pa
81c0: 67 65 20 69 73 20 66 6f 75 6e 64 20 61 6e 64 20  ge is found and 
81d0: 63 72 65 61 74 65 46 6c 61 67 20 69 73 20 30 20  createFlag is 0 
81e0: 2a 2f 0a 20 20 69 66 28 20 70 50 61 67 65 20 29  */.  if( pPage )
81f0: 7b 0a 20 20 20 20 69 66 28 20 21 70 50 61 67 65  {.    if( !pPage
8200: 2d 3e 69 73 50 69 6e 6e 65 64 20 29 7b 0a 20 20  ->isPinned ){.  
8210: 20 20 20 20 72 65 74 75 72 6e 20 70 63 61 63 68      return pcach
8220: 65 31 50 69 6e 50 61 67 65 28 70 50 61 67 65 29  e1PinPage(pPage)
8230: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
8240: 20 20 20 72 65 74 75 72 6e 20 70 50 61 67 65 3b     return pPage;
8250: 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69  .    }.  }else i
8260: 66 28 20 63 72 65 61 74 65 46 6c 61 67 20 29 7b  f( createFlag ){
8270: 0a 20 20 20 20 2f 2a 20 53 74 65 70 73 20 33 2c  .    /* Steps 3,
8280: 20 34 2c 20 61 6e 64 20 35 20 69 6d 70 6c 65 6d   4, and 5 implem
8290: 65 6e 74 65 64 20 62 79 20 74 68 69 73 20 73 75  ented by this su
82a0: 62 72 6f 75 74 69 6e 65 20 2a 2f 0a 20 20 20 20  broutine */.    
82b0: 72 65 74 75 72 6e 20 70 63 61 63 68 65 31 46 65  return pcache1Fe
82c0: 74 63 68 53 74 61 67 65 32 28 70 43 61 63 68 65  tchStage2(pCache
82d0: 2c 20 69 4b 65 79 2c 20 63 72 65 61 74 65 46 6c  , iKey, createFl
82e0: 61 67 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  ag);.  }else{.  
82f0: 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a    return 0;.  }.
8300: 7d 0a 23 69 66 20 50 43 41 43 48 45 31 5f 4d 49  }.#if PCACHE1_MI
8310: 47 48 54 5f 55 53 45 5f 47 52 4f 55 50 5f 4d 55  GHT_USE_GROUP_MU
8320: 54 45 58 0a 73 74 61 74 69 63 20 50 67 48 64 72  TEX.static PgHdr
8330: 31 20 2a 70 63 61 63 68 65 31 46 65 74 63 68 57  1 *pcache1FetchW
8340: 69 74 68 4d 75 74 65 78 28 0a 20 20 73 71 6c 69  ithMutex(.  sqli
8350: 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c 20 0a  te3_pcache *p, .
8360: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69    unsigned int i
8370: 4b 65 79 2c 20 0a 20 20 69 6e 74 20 63 72 65 61  Key, .  int crea
8380: 74 65 46 6c 61 67 0a 29 7b 0a 20 20 50 43 61 63  teFlag.){.  PCac
8390: 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50  he1 *pCache = (P
83a0: 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50 67  Cache1 *)p;.  Pg
83b0: 48 64 72 31 20 2a 70 50 61 67 65 3b 0a 0a 20 20  Hdr1 *pPage;..  
83c0: 70 63 61 63 68 65 31 45 6e 74 65 72 4d 75 74 65  pcache1EnterMute
83d0: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
83e0: 29 3b 0a 20 20 70 50 61 67 65 20 3d 20 70 63 61  );.  pPage = pca
83f0: 63 68 65 31 46 65 74 63 68 4e 6f 4d 75 74 65 78  che1FetchNoMutex
8400: 28 70 2c 20 69 4b 65 79 2c 20 63 72 65 61 74 65  (p, iKey, create
8410: 46 6c 61 67 29 3b 0a 20 20 61 73 73 65 72 74 28  Flag);.  assert(
8420: 20 70 50 61 67 65 3d 3d 30 20 7c 7c 20 70 43 61   pPage==0 || pCa
8430: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 3e 3d 69 4b  che->iMaxKey>=iK
8440: 65 79 20 29 3b 0a 20 20 70 63 61 63 68 65 31 4c  ey );.  pcache1L
8450: 65 61 76 65 4d 75 74 65 78 28 70 43 61 63 68 65  eaveMutex(pCache
8460: 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20 72 65 74  ->pGroup);.  ret
8470: 75 72 6e 20 70 50 61 67 65 3b 0a 7d 0a 23 65 6e  urn pPage;.}.#en
8480: 64 69 66 0a 73 74 61 74 69 63 20 73 71 6c 69 74  dif.static sqlit
8490: 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20 2a  e3_pcache_page *
84a0: 70 63 61 63 68 65 31 46 65 74 63 68 28 0a 20 20  pcache1Fetch(.  
84b0: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
84c0: 70 2c 20 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  p, .  unsigned i
84d0: 6e 74 20 69 4b 65 79 2c 20 0a 20 20 69 6e 74 20  nt iKey, .  int 
84e0: 63 72 65 61 74 65 46 6c 61 67 0a 29 7b 0a 23 69  createFlag.){.#i
84f0: 66 20 50 43 41 43 48 45 31 5f 4d 49 47 48 54 5f  f PCACHE1_MIGHT_
8500: 55 53 45 5f 47 52 4f 55 50 5f 4d 55 54 45 58 20  USE_GROUP_MUTEX 
8510: 7c 7c 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  || defined(SQLIT
8520: 45 5f 44 45 42 55 47 29 0a 20 20 50 43 61 63 68  E_DEBUG).  PCach
8530: 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43  e1 *pCache = (PC
8540: 61 63 68 65 31 20 2a 29 70 3b 0a 23 65 6e 64 69  ache1 *)p;.#endi
8550: 66 0a 0a 20 20 61 73 73 65 72 74 28 20 6f 66 66  f..  assert( off
8560: 73 65 74 6f 66 28 50 67 48 64 72 31 2c 70 61 67  setof(PgHdr1,pag
8570: 65 29 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  e)==0 );.  asser
8580: 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67  t( pCache->bPurg
8590: 65 61 62 6c 65 20 7c 7c 20 63 72 65 61 74 65 46  eable || createF
85a0: 6c 61 67 21 3d 31 20 29 3b 0a 20 20 61 73 73 65  lag!=1 );.  asse
85b0: 72 74 28 20 70 43 61 63 68 65 2d 3e 62 50 75 72  rt( pCache->bPur
85c0: 67 65 61 62 6c 65 20 7c 7c 20 70 43 61 63 68 65  geable || pCache
85d0: 2d 3e 6e 4d 69 6e 3d 3d 30 20 29 3b 0a 20 20 61  ->nMin==0 );.  a
85e0: 73 73 65 72 74 28 20 70 43 61 63 68 65 2d 3e 62  ssert( pCache->b
85f0: 50 75 72 67 65 61 62 6c 65 3d 3d 30 20 7c 7c 20  Purgeable==0 || 
8600: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 31 30  pCache->nMin==10
8610: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43   );.  assert( pC
8620: 61 63 68 65 2d 3e 6e 4d 69 6e 3d 3d 30 20 7c 7c  ache->nMin==0 ||
8630: 20 70 43 61 63 68 65 2d 3e 62 50 75 72 67 65 61   pCache->bPurgea
8640: 62 6c 65 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ble );.  assert(
8650: 20 70 43 61 63 68 65 2d 3e 6e 48 61 73 68 3e 30   pCache->nHash>0
8660: 20 29 3b 0a 23 69 66 20 50 43 41 43 48 45 31 5f   );.#if PCACHE1_
8670: 4d 49 47 48 54 5f 55 53 45 5f 47 52 4f 55 50 5f  MIGHT_USE_GROUP_
8680: 4d 55 54 45 58 0a 20 20 69 66 28 20 70 43 61 63  MUTEX.  if( pCac
8690: 68 65 2d 3e 70 47 72 6f 75 70 2d 3e 6d 75 74 65  he->pGroup->mute
86a0: 78 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  x ){.    return 
86b0: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f  (sqlite3_pcache_
86c0: 70 61 67 65 2a 29 70 63 61 63 68 65 31 46 65 74  page*)pcache1Fet
86d0: 63 68 57 69 74 68 4d 75 74 65 78 28 70 2c 20 69  chWithMutex(p, i
86e0: 4b 65 79 2c 20 63 72 65 61 74 65 46 6c 61 67 29  Key, createFlag)
86f0: 3b 0a 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66  ;.  }else.#endif
8700: 0a 20 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  .  {.    return 
8710: 28 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 5f  (sqlite3_pcache_
8720: 70 61 67 65 2a 29 70 63 61 63 68 65 31 46 65 74  page*)pcache1Fet
8730: 63 68 4e 6f 4d 75 74 65 78 28 70 2c 20 69 4b 65  chNoMutex(p, iKe
8740: 79 2c 20 63 72 65 61 74 65 46 6c 61 67 29 3b 0a  y, createFlag);.
8750: 20 20 7d 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6d    }.}.../*.** Im
8760: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
8770: 74 68 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63  the sqlite3_pcac
8780: 68 65 2e 78 55 6e 70 69 6e 20 6d 65 74 68 6f 64  he.xUnpin method
8790: 2e 0a 2a 2a 0a 2a 2a 20 4d 61 72 6b 20 61 20 70  ..**.** Mark a p
87a0: 61 67 65 20 61 73 20 75 6e 70 69 6e 6e 65 64 20  age as unpinned 
87b0: 28 65 6c 69 67 69 62 6c 65 20 66 6f 72 20 61 73  (eligible for as
87c0: 79 6e 63 68 72 6f 6e 6f 75 73 20 72 65 63 79 63  ynchronous recyc
87d0: 6c 69 6e 67 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  ling)..*/.static
87e0: 20 76 6f 69 64 20 70 63 61 63 68 65 31 55 6e 70   void pcache1Unp
87f0: 69 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 70 63  in(.  sqlite3_pc
8800: 61 63 68 65 20 2a 70 2c 20 0a 20 20 73 71 6c 69  ache *p, .  sqli
8810: 74 65 33 5f 70 63 61 63 68 65 5f 70 61 67 65 20  te3_pcache_page 
8820: 2a 70 50 67 2c 20 0a 20 20 69 6e 74 20 72 65 75  *pPg, .  int reu
8830: 73 65 55 6e 6c 69 6b 65 6c 79 0a 29 7b 0a 20 20  seUnlikely.){.  
8840: 50 43 61 63 68 65 31 20 2a 70 43 61 63 68 65 20  PCache1 *pCache 
8850: 3d 20 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a  = (PCache1 *)p;.
8860: 20 20 50 67 48 64 72 31 20 2a 70 50 61 67 65 20    PgHdr1 *pPage 
8870: 3d 20 28 50 67 48 64 72 31 20 2a 29 70 50 67 3b  = (PgHdr1 *)pPg;
8880: 0a 20 20 50 47 72 6f 75 70 20 2a 70 47 72 6f 75  .  PGroup *pGrou
8890: 70 20 3d 20 70 43 61 63 68 65 2d 3e 70 47 72 6f  p = pCache->pGro
88a0: 75 70 3b 0a 20 0a 20 20 61 73 73 65 72 74 28 20  up;. .  assert( 
88b0: 70 50 61 67 65 2d 3e 70 43 61 63 68 65 3d 3d 70  pPage->pCache==p
88c0: 43 61 63 68 65 20 29 3b 0a 20 20 70 63 61 63 68  Cache );.  pcach
88d0: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72  e1EnterMutex(pGr
88e0: 6f 75 70 29 3b 0a 0a 20 20 2f 2a 20 49 74 20 69  oup);..  /* It i
88f0: 73 20 61 6e 20 65 72 72 6f 72 20 74 6f 20 63 61  s an error to ca
8900: 6c 6c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  ll this function
8910: 20 69 66 20 74 68 65 20 70 61 67 65 20 69 73 20   if the page is 
8920: 61 6c 72 65 61 64 79 20 0a 20 20 2a 2a 20 70 61  already .  ** pa
8930: 72 74 20 6f 66 20 74 68 65 20 50 47 72 6f 75 70  rt of the PGroup
8940: 20 4c 52 55 20 6c 69 73 74 2e 0a 20 20 2a 2f 0a   LRU list..  */.
8950: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
8960: 3e 70 4c 72 75 50 72 65 76 3d 3d 30 20 26 26 20  >pLruPrev==0 && 
8970: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 3d  pPage->pLruNext=
8980: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
8990: 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65 61 64  pGroup->pLruHead
89a0: 21 3d 70 50 61 67 65 20 26 26 20 70 47 72 6f 75  !=pPage && pGrou
89b0: 70 2d 3e 70 4c 72 75 54 61 69 6c 21 3d 70 50 61  p->pLruTail!=pPa
89c0: 67 65 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  ge );.  assert( 
89d0: 70 50 61 67 65 2d 3e 69 73 50 69 6e 6e 65 64 3d  pPage->isPinned=
89e0: 3d 31 20 29 3b 0a 0a 20 20 69 66 28 20 72 65 75  =1 );..  if( reu
89f0: 73 65 55 6e 6c 69 6b 65 6c 79 20 7c 7c 20 70 47  seUnlikely || pG
8a00: 72 6f 75 70 2d 3e 6e 43 75 72 72 65 6e 74 50 61  roup->nCurrentPa
8a10: 67 65 3e 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50  ge>pGroup->nMaxP
8a20: 61 67 65 20 29 7b 0a 20 20 20 20 70 63 61 63 68  age ){.    pcach
8a30: 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48 61 73 68  e1RemoveFromHash
8a40: 28 70 50 61 67 65 2c 20 31 29 3b 0a 20 20 7d 65  (pPage, 1);.  }e
8a50: 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41 64 64 20  lse{.    /* Add 
8a60: 74 68 65 20 70 61 67 65 20 74 6f 20 74 68 65 20  the page to the 
8a70: 50 47 72 6f 75 70 20 4c 52 55 20 6c 69 73 74 2e  PGroup LRU list.
8a80: 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 47 72 6f   */.    if( pGro
8a90: 75 70 2d 3e 70 4c 72 75 48 65 61 64 20 29 7b 0a  up->pLruHead ){.
8aa0: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c        pGroup->pL
8ab0: 72 75 48 65 61 64 2d 3e 70 4c 72 75 50 72 65 76  ruHead->pLruPrev
8ac0: 20 3d 20 70 50 61 67 65 3b 0a 20 20 20 20 20 20   = pPage;.      
8ad0: 70 50 61 67 65 2d 3e 70 4c 72 75 4e 65 78 74 20  pPage->pLruNext 
8ae0: 3d 20 70 47 72 6f 75 70 2d 3e 70 4c 72 75 48 65  = pGroup->pLruHe
8af0: 61 64 3b 0a 20 20 20 20 20 20 70 47 72 6f 75 70  ad;.      pGroup
8b00: 2d 3e 70 4c 72 75 48 65 61 64 20 3d 20 70 50 61  ->pLruHead = pPa
8b10: 67 65 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ge;.    }else{. 
8b20: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72       pGroup->pLr
8b30: 75 54 61 69 6c 20 3d 20 70 50 61 67 65 3b 0a 20  uTail = pPage;. 
8b40: 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4c 72       pGroup->pLr
8b50: 75 48 65 61 64 20 3d 20 70 50 61 67 65 3b 0a 20  uHead = pPage;. 
8b60: 20 20 20 7d 0a 20 20 20 20 70 43 61 63 68 65 2d     }.    pCache-
8b70: 3e 6e 52 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a  >nRecyclable++;.
8b80: 20 20 20 20 70 50 61 67 65 2d 3e 69 73 50 69 6e      pPage->isPin
8b90: 6e 65 64 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20  ned = 0;.  }..  
8ba0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
8bb0: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
8bc0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
8bd0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
8be0: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
8bf0: 2e 78 52 65 6b 65 79 20 6d 65 74 68 6f 64 2e 20  .xRekey method. 
8c00: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
8c10: 70 63 61 63 68 65 31 52 65 6b 65 79 28 0a 20 20  pcache1Rekey(.  
8c20: 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a  sqlite3_pcache *
8c30: 70 2c 0a 20 20 73 71 6c 69 74 65 33 5f 70 63 61  p,.  sqlite3_pca
8c40: 63 68 65 5f 70 61 67 65 20 2a 70 50 67 2c 0a 20  che_page *pPg,. 
8c50: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4f   unsigned int iO
8c60: 6c 64 2c 0a 20 20 75 6e 73 69 67 6e 65 64 20 69  ld,.  unsigned i
8c70: 6e 74 20 69 4e 65 77 0a 29 7b 0a 20 20 50 43 61  nt iNew.){.  PCa
8c80: 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20 28  che1 *pCache = (
8c90: 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20 50  PCache1 *)p;.  P
8ca0: 67 48 64 72 31 20 2a 70 50 61 67 65 20 3d 20 28  gHdr1 *pPage = (
8cb0: 50 67 48 64 72 31 20 2a 29 70 50 67 3b 0a 20 20  PgHdr1 *)pPg;.  
8cc0: 50 67 48 64 72 31 20 2a 2a 70 70 3b 0a 20 20 75  PgHdr1 **pp;.  u
8cd0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 20 0a  nsigned int h; .
8ce0: 20 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d    assert( pPage-
8cf0: 3e 69 4b 65 79 3d 3d 69 4f 6c 64 20 29 3b 0a 20  >iKey==iOld );. 
8d00: 20 61 73 73 65 72 74 28 20 70 50 61 67 65 2d 3e   assert( pPage->
8d10: 70 43 61 63 68 65 3d 3d 70 43 61 63 68 65 20 29  pCache==pCache )
8d20: 3b 0a 0a 20 20 70 63 61 63 68 65 31 45 6e 74 65  ;..  pcache1Ente
8d30: 72 4d 75 74 65 78 28 70 43 61 63 68 65 2d 3e 70  rMutex(pCache->p
8d40: 47 72 6f 75 70 29 3b 0a 0a 20 20 68 20 3d 20 69  Group);..  h = i
8d50: 4f 6c 64 25 70 43 61 63 68 65 2d 3e 6e 48 61 73  Old%pCache->nHas
8d60: 68 3b 0a 20 20 70 70 20 3d 20 26 70 43 61 63 68  h;.  pp = &pCach
8d70: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
8d80: 77 68 69 6c 65 28 20 28 2a 70 70 29 21 3d 70 50  while( (*pp)!=pP
8d90: 61 67 65 20 29 7b 0a 20 20 20 20 70 70 20 3d 20  age ){.    pp = 
8da0: 26 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20  &(*pp)->pNext;. 
8db0: 20 7d 0a 20 20 2a 70 70 20 3d 20 70 50 61 67 65   }.  *pp = pPage
8dc0: 2d 3e 70 4e 65 78 74 3b 0a 0a 20 20 68 20 3d 20  ->pNext;..  h = 
8dd0: 69 4e 65 77 25 70 43 61 63 68 65 2d 3e 6e 48 61  iNew%pCache->nHa
8de0: 73 68 3b 0a 20 20 70 50 61 67 65 2d 3e 69 4b 65  sh;.  pPage->iKe
8df0: 79 20 3d 20 69 4e 65 77 3b 0a 20 20 70 50 61 67  y = iNew;.  pPag
8e00: 65 2d 3e 70 4e 65 78 74 20 3d 20 70 43 61 63 68  e->pNext = pCach
8e10: 65 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  e->apHash[h];.  
8e20: 70 43 61 63 68 65 2d 3e 61 70 48 61 73 68 5b 68  pCache->apHash[h
8e30: 5d 20 3d 20 70 50 61 67 65 3b 0a 20 20 69 66 28  ] = pPage;.  if(
8e40: 20 69 4e 65 77 3e 70 43 61 63 68 65 2d 3e 69 4d   iNew>pCache->iM
8e50: 61 78 4b 65 79 20 29 7b 0a 20 20 20 20 70 43 61  axKey ){.    pCa
8e60: 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20 69  che->iMaxKey = i
8e70: 4e 65 77 3b 0a 20 20 7d 0a 0a 20 20 70 63 61 63  New;.  }..  pcac
8e80: 68 65 31 4c 65 61 76 65 4d 75 74 65 78 28 70 43  he1LeaveMutex(pC
8e90: 61 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 7d  ache->pGroup);.}
8ea0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
8eb0: 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 73 71  tation of the sq
8ec0: 6c 69 74 65 33 5f 70 63 61 63 68 65 2e 78 54 72  lite3_pcache.xTr
8ed0: 75 6e 63 61 74 65 20 6d 65 74 68 6f 64 2e 20 0a  uncate method. .
8ee0: 2a 2a 0a 2a 2a 20 44 69 73 63 61 72 64 20 61 6c  **.** Discard al
8ef0: 6c 20 75 6e 70 69 6e 6e 65 64 20 70 61 67 65 73  l unpinned pages
8f00: 20 69 6e 20 74 68 65 20 63 61 63 68 65 20 77 69   in the cache wi
8f10: 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72  th a page number
8f20: 20 65 71 75 61 6c 20 74 6f 0a 2a 2a 20 6f 72 20   equal to.** or 
8f30: 67 72 65 61 74 65 72 20 74 68 61 6e 20 70 61 72  greater than par
8f40: 61 6d 65 74 65 72 20 69 4c 69 6d 69 74 2e 20 41  ameter iLimit. A
8f50: 6e 79 20 70 69 6e 6e 65 64 20 70 61 67 65 73 20  ny pinned pages 
8f60: 77 69 74 68 20 61 20 70 61 67 65 20 6e 75 6d 62  with a page numb
8f70: 65 72 0a 2a 2a 20 65 71 75 61 6c 20 74 6f 20 6f  er.** equal to o
8f80: 72 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 69  r greater than i
8f90: 4c 69 6d 69 74 20 61 72 65 20 69 6d 70 6c 69 63  Limit are implic
8fa0: 69 74 6c 79 20 75 6e 70 69 6e 6e 65 64 2e 0a 2a  itly unpinned..*
8fb0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 63  /.static void pc
8fc0: 61 63 68 65 31 54 72 75 6e 63 61 74 65 28 73 71  ache1Truncate(sq
8fd0: 6c 69 74 65 33 5f 70 63 61 63 68 65 20 2a 70 2c  lite3_pcache *p,
8fe0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 4c   unsigned int iL
8ff0: 69 6d 69 74 29 7b 0a 20 20 50 43 61 63 68 65 31  imit){.  PCache1
9000: 20 2a 70 43 61 63 68 65 20 3d 20 28 50 43 61 63   *pCache = (PCac
9010: 68 65 31 20 2a 29 70 3b 0a 20 20 70 63 61 63 68  he1 *)p;.  pcach
9020: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 43 61  e1EnterMutex(pCa
9030: 63 68 65 2d 3e 70 47 72 6f 75 70 29 3b 0a 20 20  che->pGroup);.  
9040: 69 66 28 20 69 4c 69 6d 69 74 3c 3d 70 43 61 63  if( iLimit<=pCac
9050: 68 65 2d 3e 69 4d 61 78 4b 65 79 20 29 7b 0a 20  he->iMaxKey ){. 
9060: 20 20 20 70 63 61 63 68 65 31 54 72 75 6e 63 61     pcache1Trunca
9070: 74 65 55 6e 73 61 66 65 28 70 43 61 63 68 65 2c  teUnsafe(pCache,
9080: 20 69 4c 69 6d 69 74 29 3b 0a 20 20 20 20 70 43   iLimit);.    pC
9090: 61 63 68 65 2d 3e 69 4d 61 78 4b 65 79 20 3d 20  ache->iMaxKey = 
90a0: 69 4c 69 6d 69 74 2d 31 3b 0a 20 20 7d 0a 20 20  iLimit-1;.  }.  
90b0: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
90c0: 78 28 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70  x(pCache->pGroup
90d0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  );.}../*.** Impl
90e0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68  ementation of th
90f0: 65 20 73 71 6c 69 74 65 33 5f 70 63 61 63 68 65  e sqlite3_pcache
9100: 2e 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64  .xDestroy method
9110: 2e 20 0a 2a 2a 0a 2a 2a 20 44 65 73 74 72 6f 79  . .**.** Destroy
9120: 20 61 20 63 61 63 68 65 20 61 6c 6c 6f 63 61 74   a cache allocat
9130: 65 64 20 75 73 69 6e 67 20 70 63 61 63 68 65 31  ed using pcache1
9140: 43 72 65 61 74 65 28 29 2e 0a 2a 2f 0a 73 74 61  Create()..*/.sta
9150: 74 69 63 20 76 6f 69 64 20 70 63 61 63 68 65 31  tic void pcache1
9160: 44 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f  Destroy(sqlite3_
9170: 70 63 61 63 68 65 20 2a 70 29 7b 0a 20 20 50 43  pcache *p){.  PC
9180: 61 63 68 65 31 20 2a 70 43 61 63 68 65 20 3d 20  ache1 *pCache = 
9190: 28 50 43 61 63 68 65 31 20 2a 29 70 3b 0a 20 20  (PCache1 *)p;.  
91a0: 50 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d  PGroup *pGroup =
91b0: 20 70 43 61 63 68 65 2d 3e 70 47 72 6f 75 70 3b   pCache->pGroup;
91c0: 0a 20 20 61 73 73 65 72 74 28 20 70 43 61 63 68  .  assert( pCach
91d0: 65 2d 3e 62 50 75 72 67 65 61 62 6c 65 20 7c 7c  e->bPurgeable ||
91e0: 20 28 70 43 61 63 68 65 2d 3e 6e 4d 61 78 3d 3d   (pCache->nMax==
91f0: 30 20 26 26 20 70 43 61 63 68 65 2d 3e 6e 4d 69  0 && pCache->nMi
9200: 6e 3d 3d 30 29 20 29 3b 0a 20 20 70 63 61 63 68  n==0) );.  pcach
9210: 65 31 45 6e 74 65 72 4d 75 74 65 78 28 70 47 72  e1EnterMutex(pGr
9220: 6f 75 70 29 3b 0a 20 20 70 63 61 63 68 65 31 54  oup);.  pcache1T
9230: 72 75 6e 63 61 74 65 55 6e 73 61 66 65 28 70 43  runcateUnsafe(pC
9240: 61 63 68 65 2c 20 30 29 3b 0a 20 20 61 73 73 65  ache, 0);.  asse
9250: 72 74 28 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78  rt( pGroup->nMax
9260: 50 61 67 65 20 3e 3d 20 70 43 61 63 68 65 2d 3e  Page >= pCache->
9270: 6e 4d 61 78 20 29 3b 0a 20 20 70 47 72 6f 75 70  nMax );.  pGroup
9280: 2d 3e 6e 4d 61 78 50 61 67 65 20 2d 3d 20 70 43  ->nMaxPage -= pC
9290: 61 63 68 65 2d 3e 6e 4d 61 78 3b 0a 20 20 61 73  ache->nMax;.  as
92a0: 73 65 72 74 28 20 70 47 72 6f 75 70 2d 3e 6e 4d  sert( pGroup->nM
92b0: 69 6e 50 61 67 65 20 3e 3d 20 70 43 61 63 68 65  inPage >= pCache
92c0: 2d 3e 6e 4d 69 6e 20 29 3b 0a 20 20 70 47 72 6f  ->nMin );.  pGro
92d0: 75 70 2d 3e 6e 4d 69 6e 50 61 67 65 20 2d 3d 20  up->nMinPage -= 
92e0: 70 43 61 63 68 65 2d 3e 6e 4d 69 6e 3b 0a 20 20  pCache->nMin;.  
92f0: 70 47 72 6f 75 70 2d 3e 6d 78 50 69 6e 6e 65 64  pGroup->mxPinned
9300: 20 3d 20 70 47 72 6f 75 70 2d 3e 6e 4d 61 78 50   = pGroup->nMaxP
9310: 61 67 65 20 2b 20 31 30 20 2d 20 70 47 72 6f 75  age + 10 - pGrou
9320: 70 2d 3e 6e 4d 69 6e 50 61 67 65 3b 0a 20 20 70  p->nMinPage;.  p
9330: 63 61 63 68 65 31 45 6e 66 6f 72 63 65 4d 61 78  cache1EnforceMax
9340: 50 61 67 65 28 70 43 61 63 68 65 29 3b 0a 20 20  Page(pCache);.  
9350: 70 63 61 63 68 65 31 4c 65 61 76 65 4d 75 74 65  pcache1LeaveMute
9360: 78 28 70 47 72 6f 75 70 29 3b 0a 20 20 73 71 6c  x(pGroup);.  sql
9370: 69 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65  ite3_free(pCache
9380: 2d 3e 70 42 75 6c 6b 29 3b 0a 20 20 73 71 6c 69  ->pBulk);.  sqli
9390: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 2d  te3_free(pCache-
93a0: 3e 61 70 48 61 73 68 29 3b 0a 20 20 73 71 6c 69  >apHash);.  sqli
93b0: 74 65 33 5f 66 72 65 65 28 70 43 61 63 68 65 29  te3_free(pCache)
93c0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
93d0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
93e0: 65 64 20 64 75 72 69 6e 67 20 69 6e 69 74 69 61  ed during initia
93f0: 6c 69 7a 61 74 69 6f 6e 20 28 73 71 6c 69 74 65  lization (sqlite
9400: 33 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 29 20  3_initialize()) 
9410: 74 6f 0a 2a 2a 20 69 6e 73 74 61 6c 6c 20 74 68  to.** install th
9420: 65 20 64 65 66 61 75 6c 74 20 70 6c 75 67 67 61  e default plugga
9430: 62 6c 65 20 63 61 63 68 65 20 6d 6f 64 75 6c 65  ble cache module
9440: 2c 20 61 73 73 75 6d 69 6e 67 20 74 68 65 20 75  , assuming the u
9450: 73 65 72 20 68 61 73 20 6e 6f 74 0a 2a 2a 20 61  ser has not.** a
9460: 6c 72 65 61 64 79 20 70 72 6f 76 69 64 65 64 20  lready provided 
9470: 61 6e 20 61 6c 74 65 72 6e 61 74 69 76 65 2e 0a  an alternative..
9480: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 50  */.void sqlite3P
9490: 43 61 63 68 65 53 65 74 44 65 66 61 75 6c 74 28  CacheSetDefault(
94a0: 76 6f 69 64 29 7b 0a 20 20 73 74 61 74 69 63 20  void){.  static 
94b0: 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 70 63  const sqlite3_pc
94c0: 61 63 68 65 5f 6d 65 74 68 6f 64 73 32 20 64 65  ache_methods2 de
94d0: 66 61 75 6c 74 4d 65 74 68 6f 64 73 20 3d 20 7b  faultMethods = {
94e0: 0a 20 20 20 20 31 2c 20 20 20 20 20 20 20 20 20  .    1,         
94f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9500: 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 20   iVersion */.   
9510: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
9520: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41 72            /* pAr
9530: 67 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31  g */.    pcache1
9540: 49 6e 69 74 2c 20 20 20 20 20 20 20 20 20 20 20  Init,           
9550: 20 20 2f 2a 20 78 49 6e 69 74 20 2a 2f 0a 20 20    /* xInit */.  
9560: 20 20 70 63 61 63 68 65 31 53 68 75 74 64 6f 77    pcache1Shutdow
9570: 6e 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53  n,         /* xS
9580: 68 75 74 64 6f 77 6e 20 2a 2f 0a 20 20 20 20 70  hutdown */.    p
9590: 63 61 63 68 65 31 43 72 65 61 74 65 2c 20 20 20  cache1Create,   
95a0: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61          /* xCrea
95b0: 74 65 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  te */.    pcache
95c0: 31 43 61 63 68 65 73 69 7a 65 2c 20 20 20 20 20  1Cachesize,     
95d0: 20 20 20 2f 2a 20 78 43 61 63 68 65 73 69 7a 65     /* xCachesize
95e0: 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65 31 50   */.    pcache1P
95f0: 61 67 65 63 6f 75 6e 74 2c 20 20 20 20 20 20 20  agecount,       
9600: 20 2f 2a 20 78 50 61 67 65 63 6f 75 6e 74 20 2a   /* xPagecount *
9610: 2f 0a 20 20 20 20 70 63 61 63 68 65 31 46 65 74  /.    pcache1Fet
9620: 63 68 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  ch,            /
9630: 2a 20 78 46 65 74 63 68 20 2a 2f 0a 20 20 20 20  * xFetch */.    
9640: 70 63 61 63 68 65 31 55 6e 70 69 6e 2c 20 20 20  pcache1Unpin,   
9650: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55 6e 70           /* xUnp
9660: 69 6e 20 2a 2f 0a 20 20 20 20 70 63 61 63 68 65  in */.    pcache
9670: 31 52 65 6b 65 79 2c 20 20 20 20 20 20 20 20 20  1Rekey,         
9680: 20 20 20 2f 2a 20 78 52 65 6b 65 79 20 2a 2f 0a     /* xRekey */.
9690: 20 20 20 20 70 63 61 63 68 65 31 54 72 75 6e 63      pcache1Trunc
96a0: 61 74 65 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  ate,         /* 
96b0: 78 54 72 75 6e 63 61 74 65 20 2a 2f 0a 20 20 20  xTruncate */.   
96c0: 20 70 63 61 63 68 65 31 44 65 73 74 72 6f 79 2c   pcache1Destroy,
96d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65            /* xDe
96e0: 73 74 72 6f 79 20 2a 2f 0a 20 20 20 20 70 63 61  stroy */.    pca
96f0: 63 68 65 31 53 68 72 69 6e 6b 20 20 20 20 20 20  che1Shrink      
9700: 20 20 20 20 20 20 2f 2a 20 78 53 68 72 69 6e 6b        /* xShrink
9710: 20 2a 2f 0a 20 20 7d 3b 0a 20 20 73 71 6c 69 74   */.  };.  sqlit
9720: 65 33 5f 63 6f 6e 66 69 67 28 53 51 4c 49 54 45  e3_config(SQLITE
9730: 5f 43 4f 4e 46 49 47 5f 50 43 41 43 48 45 32 2c  _CONFIG_PCACHE2,
9740: 20 26 64 65 66 61 75 6c 74 4d 65 74 68 6f 64 73   &defaultMethods
9750: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  );.}../*.** Retu
9760: 72 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74  rn the size of t
9770: 68 65 20 68 65 61 64 65 72 20 6f 6e 20 65 61 63  he header on eac
9780: 68 20 70 61 67 65 20 6f 66 20 74 68 69 73 20 50  h page of this P
9790: 43 41 43 48 45 20 69 6d 70 6c 65 6d 65 6e 74 61  CACHE implementa
97a0: 74 69 6f 6e 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  tion..*/.int sql
97b0: 69 74 65 33 48 65 61 64 65 72 53 69 7a 65 50 63  ite3HeaderSizePc
97c0: 61 63 68 65 31 28 76 6f 69 64 29 7b 20 72 65 74  ache1(void){ ret
97d0: 75 72 6e 20 52 4f 55 4e 44 38 28 73 69 7a 65 6f  urn ROUND8(sizeo
97e0: 66 28 50 67 48 64 72 31 29 29 3b 20 7d 0a 0a 2f  f(PgHdr1)); }../
97f0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
9800: 67 6c 6f 62 61 6c 20 6d 75 74 65 78 20 75 73 65  global mutex use
9810: 64 20 62 79 20 74 68 69 73 20 50 43 41 43 48 45  d by this PCACHE
9820: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e   implementation.
9830: 20 20 54 68 65 0a 2a 2a 20 73 71 6c 69 74 65 33    The.** sqlite3
9840: 5f 73 74 61 74 75 73 28 29 20 72 6f 75 74 69 6e  _status() routin
9850: 65 20 6e 65 65 64 73 20 61 63 63 65 73 73 20 74  e needs access t
9860: 6f 20 74 68 69 73 20 6d 75 74 65 78 2e 0a 2a 2f  o this mutex..*/
9870: 0a 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a  .sqlite3_mutex *
9880: 73 71 6c 69 74 65 33 50 63 61 63 68 65 31 4d 75  sqlite3Pcache1Mu
9890: 74 65 78 28 76 6f 69 64 29 7b 0a 20 20 72 65 74  tex(void){.  ret
98a0: 75 72 6e 20 70 63 61 63 68 65 31 2e 6d 75 74 65  urn pcache1.mute
98b0: 78 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c  x;.}..#ifdef SQL
98c0: 49 54 45 5f 45 4e 41 42 4c 45 5f 4d 45 4d 4f 52  ITE_ENABLE_MEMOR
98d0: 59 5f 4d 41 4e 41 47 45 4d 45 4e 54 0a 2f 2a 0a  Y_MANAGEMENT./*.
98e0: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
98f0: 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 66 72   is called to fr
9900: 65 65 20 73 75 70 65 72 66 6c 75 6f 75 73 20 64  ee superfluous d
9910: 79 6e 61 6d 69 63 61 6c 6c 79 20 61 6c 6c 6f 63  ynamically alloc
9920: 61 74 65 64 20 6d 65 6d 6f 72 79 0a 2a 2a 20 68  ated memory.** h
9930: 65 6c 64 20 62 79 20 74 68 65 20 70 61 67 65 72  eld by the pager
9940: 20 73 79 73 74 65 6d 2e 20 4d 65 6d 6f 72 79 20   system. Memory 
9950: 69 6e 20 75 73 65 20 62 79 20 61 6e 79 20 53 51  in use by any SQ
9960: 4c 69 74 65 20 70 61 67 65 72 20 61 6c 6c 6f 63  Lite pager alloc
9970: 61 74 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63  ated.** by the c
9980: 75 72 72 65 6e 74 20 74 68 72 65 61 64 20 6d 61  urrent thread ma
9990: 79 20 62 65 20 73 71 6c 69 74 65 33 5f 66 72 65  y be sqlite3_fre
99a0: 65 28 29 65 64 2e 0a 2a 2a 0a 2a 2a 20 6e 52 65  e()ed..**.** nRe
99b0: 71 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  q is the number 
99c0: 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d 6f  of bytes of memo
99d0: 72 79 20 72 65 71 75 69 72 65 64 2e 20 4f 6e 63  ry required. Onc
99e0: 65 20 74 68 69 73 20 6d 75 63 68 20 68 61 73 0a  e this much has.
99f0: 2a 2a 20 62 65 65 6e 20 72 65 6c 65 61 73 65 64  ** been released
9a00: 2c 20 74 68 65 20 66 75 6e 63 74 69 6f 6e 20 72  , the function r
9a10: 65 74 75 72 6e 73 2e 20 54 68 65 20 72 65 74 75  eturns. The retu
9a20: 72 6e 20 76 61 6c 75 65 20 69 73 20 74 68 65 20  rn value is the 
9a30: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 0a 2a 2a  total number .**
9a40: 20 6f 66 20 62 79 74 65 73 20 6f 66 20 6d 65 6d   of bytes of mem
9a50: 6f 72 79 20 72 65 6c 65 61 73 65 64 2e 0a 2a 2f  ory released..*/
9a60: 0a 69 6e 74 20 73 71 6c 69 74 65 33 50 63 61 63  .int sqlite3Pcac
9a70: 68 65 52 65 6c 65 61 73 65 4d 65 6d 6f 72 79 28  heReleaseMemory(
9a80: 69 6e 74 20 6e 52 65 71 29 7b 0a 20 20 69 6e 74  int nReq){.  int
9a90: 20 6e 46 72 65 65 20 3d 20 30 3b 0a 20 20 61 73   nFree = 0;.  as
9aa0: 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 6d 75  sert( sqlite3_mu
9ab0: 74 65 78 5f 6e 6f 74 68 65 6c 64 28 70 63 61 63  tex_notheld(pcac
9ac0: 68 65 31 2e 67 72 70 2e 6d 75 74 65 78 29 20 29  he1.grp.mutex) )
9ad0: 3b 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c 69  ;.  assert( sqli
9ae0: 74 65 33 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c  te3_mutex_nothel
9af0: 64 28 70 63 61 63 68 65 31 2e 6d 75 74 65 78 29  d(pcache1.mutex)
9b00: 20 29 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65   );.  if( sqlite
9b10: 33 47 6c 6f 62 61 6c 43 6f 6e 66 69 67 2e 6e 50  3GlobalConfig.nP
9b20: 61 67 65 3d 3d 30 20 29 7b 0a 20 20 20 20 50 67  age==0 ){.    Pg
9b30: 48 64 72 31 20 2a 70 3b 0a 20 20 20 20 70 63 61  Hdr1 *p;.    pca
9b40: 63 68 65 31 45 6e 74 65 72 4d 75 74 65 78 28 26  che1EnterMutex(&
9b50: 70 63 61 63 68 65 31 2e 67 72 70 29 3b 0a 20 20  pcache1.grp);.  
9b60: 20 20 77 68 69 6c 65 28 20 28 6e 52 65 71 3c 30    while( (nReq<0
9b70: 20 7c 7c 20 6e 46 72 65 65 3c 6e 52 65 71 29 20   || nFree<nReq) 
9b80: 26 26 20 28 28 70 3d 70 63 61 63 68 65 31 2e 67  && ((p=pcache1.g
9b90: 72 70 2e 70 4c 72 75 54 61 69 6c 29 21 3d 30 29  rp.pLruTail)!=0)
9ba0: 20 29 7b 0a 20 20 20 20 20 20 6e 46 72 65 65 20   ){.      nFree 
9bb0: 2b 3d 20 70 63 61 63 68 65 31 4d 65 6d 53 69 7a  += pcache1MemSiz
9bc0: 65 28 70 2d 3e 70 61 67 65 2e 70 42 75 66 29 3b  e(p->page.pBuf);
9bd0: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 50  .#ifdef SQLITE_P
9be0: 43 41 43 48 45 5f 53 45 50 41 52 41 54 45 5f 48  CACHE_SEPARATE_H
9bf0: 45 41 44 45 52 0a 20 20 20 20 20 20 6e 46 72 65  EADER.      nFre
9c00: 65 20 2b 3d 20 73 71 6c 69 74 65 33 4d 65 6d 53  e += sqlite3MemS
9c10: 69 7a 65 28 70 29 3b 0a 23 65 6e 64 69 66 0a 20  ize(p);.#endif. 
9c20: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e       assert( p->
9c30: 69 73 50 69 6e 6e 65 64 3d 3d 30 20 29 3b 0a 20  isPinned==0 );. 
9c40: 20 20 20 20 20 70 63 61 63 68 65 31 50 69 6e 50       pcache1PinP
9c50: 61 67 65 28 70 29 3b 0a 20 20 20 20 20 20 70 63  age(p);.      pc
9c60: 61 63 68 65 31 52 65 6d 6f 76 65 46 72 6f 6d 48  ache1RemoveFromH
9c70: 61 73 68 28 70 2c 20 31 29 3b 0a 20 20 20 20 7d  ash(p, 1);.    }
9c80: 0a 20 20 20 20 70 63 61 63 68 65 31 4c 65 61 76  .    pcache1Leav
9c90: 65 4d 75 74 65 78 28 26 70 63 61 63 68 65 31 2e  eMutex(&pcache1.
9ca0: 67 72 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  grp);.  }.  retu
9cb0: 72 6e 20 6e 46 72 65 65 3b 0a 7d 0a 23 65 6e 64  rn nFree;.}.#end
9cc0: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
9cd0: 42 4c 45 5f 4d 45 4d 4f 52 59 5f 4d 41 4e 41 47  BLE_MEMORY_MANAG
9ce0: 45 4d 45 4e 54 20 2a 2f 0a 0a 23 69 66 64 65 66  EMENT */..#ifdef
9cf0: 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 2f 2a 0a   SQLITE_TEST./*.
9d00: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
9d10: 20 69 73 20 75 73 65 64 20 62 79 20 74 65 73 74   is used by test
9d20: 20 70 72 6f 63 65 64 75 72 65 73 20 74 6f 20 69   procedures to i
9d30: 6e 73 70 65 63 74 20 74 68 65 20 69 6e 74 65 72  nspect the inter
9d40: 6e 61 6c 20 73 74 61 74 65 0a 2a 2a 20 6f 66 20  nal state.** of 
9d50: 74 68 65 20 67 6c 6f 62 61 6c 20 63 61 63 68 65  the global cache
9d60: 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
9d70: 33 50 63 61 63 68 65 53 74 61 74 73 28 0a 20 20  3PcacheStats(.  
9d80: 69 6e 74 20 2a 70 6e 43 75 72 72 65 6e 74 2c 20  int *pnCurrent, 
9d90: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 6f 74       /* OUT: Tot
9da0: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 70 61 67  al number of pag
9db0: 65 73 20 63 61 63 68 65 64 20 2a 2f 0a 20 20 69  es cached */.  i
9dc0: 6e 74 20 2a 70 6e 4d 61 78 2c 20 20 20 20 20 20  nt *pnMax,      
9dd0: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 47 6c 6f 62      /* OUT: Glob
9de0: 61 6c 20 6d 61 78 69 6d 75 6d 20 63 61 63 68 65  al maximum cache
9df0: 20 73 69 7a 65 20 2a 2f 0a 20 20 69 6e 74 20 2a   size */.  int *
9e00: 70 6e 4d 69 6e 2c 20 20 20 20 20 20 20 20 20 20  pnMin,          
9e10: 2f 2a 20 4f 55 54 3a 20 53 75 6d 20 6f 66 20 50  /* OUT: Sum of P
9e20: 43 61 63 68 65 31 2e 6e 4d 69 6e 20 66 6f 72 20  Cache1.nMin for 
9e30: 70 75 72 67 65 61 62 6c 65 20 63 61 63 68 65 73  purgeable caches
9e40: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 65 63   */.  int *pnRec
9e50: 79 63 6c 61 62 6c 65 20 20 20 20 2f 2a 20 4f 55  yclable    /* OU
9e60: 54 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20  T: Total number 
9e70: 6f 66 20 70 61 67 65 73 20 61 76 61 69 6c 61 62  of pages availab
9e80: 6c 65 20 66 6f 72 20 72 65 63 79 63 6c 69 6e 67  le for recycling
9e90: 20 2a 2f 0a 29 7b 0a 20 20 50 67 48 64 72 31 20   */.){.  PgHdr1 
9ea0: 2a 70 3b 0a 20 20 69 6e 74 20 6e 52 65 63 79 63  *p;.  int nRecyc
9eb0: 6c 61 62 6c 65 20 3d 20 30 3b 0a 20 20 66 6f 72  lable = 0;.  for
9ec0: 28 70 3d 70 63 61 63 68 65 31 2e 67 72 70 2e 70  (p=pcache1.grp.p
9ed0: 4c 72 75 48 65 61 64 3b 20 70 3b 20 70 3d 70 2d  LruHead; p; p=p-
9ee0: 3e 70 4c 72 75 4e 65 78 74 29 7b 0a 20 20 20 20  >pLruNext){.    
9ef0: 61 73 73 65 72 74 28 20 70 2d 3e 69 73 50 69 6e  assert( p->isPin
9f00: 6e 65 64 3d 3d 30 20 29 3b 0a 20 20 20 20 6e 52  ned==0 );.    nR
9f10: 65 63 79 63 6c 61 62 6c 65 2b 2b 3b 0a 20 20 7d  ecyclable++;.  }
9f20: 0a 20 20 2a 70 6e 43 75 72 72 65 6e 74 20 3d 20  .  *pnCurrent = 
9f30: 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 43 75 72  pcache1.grp.nCur
9f40: 72 65 6e 74 50 61 67 65 3b 0a 20 20 2a 70 6e 4d  rentPage;.  *pnM
9f50: 61 78 20 3d 20 28 69 6e 74 29 70 63 61 63 68 65  ax = (int)pcache
9f60: 31 2e 67 72 70 2e 6e 4d 61 78 50 61 67 65 3b 0a  1.grp.nMaxPage;.
9f70: 20 20 2a 70 6e 4d 69 6e 20 3d 20 28 69 6e 74 29    *pnMin = (int)
9f80: 70 63 61 63 68 65 31 2e 67 72 70 2e 6e 4d 69 6e  pcache1.grp.nMin
9f90: 50 61 67 65 3b 0a 20 20 2a 70 6e 52 65 63 79 63  Page;.  *pnRecyc
9fa0: 6c 61 62 6c 65 20 3d 20 6e 52 65 63 79 63 6c 61  lable = nRecycla
9fb0: 62 6c 65 3b 0a 7d 0a 23 65 6e 64 69 66 0a        ble;.}.#endif.