/ Hex Artifact Content
Login

Artifact 8bf87820896453ee3cca75f3082c57d7d82643e46cc089775612b18453732c12:


0000: 2f 2a 0a 2a 2a 20 32 30 31 30 20 46 65 62 72 75  /*.** 2010 Febru
0010: 61 72 79 20 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ary 1.**.** The 
0020: 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73  author disclaims
0030: 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68   copyright to th
0040: 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20  is source code. 
0050: 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20   In place of.** 
0060: 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20  a legal notice, 
0070: 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69  here is a blessi
0080: 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79  ng:.**.**    May
0090: 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64   you do good and
00a0: 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20   not evil..**   
00b0: 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f   May you find fo
00c0: 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f  rgiveness for yo
00d0: 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69  urself and forgi
00e0: 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20  ve others..**   
00f0: 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66   May you share f
0100: 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b  reely, never tak
0110: 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f  ing more than yo
0120: 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a  u 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 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 74 68  file contains th
0190: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
01a0: 20 6f 66 20 61 20 77 72 69 74 65 2d 61 68 65 61   of a write-ahea
01b0: 64 20 6c 6f 67 20 28 57 41 4c 29 20 75 73 65 64  d log (WAL) used
01c0: 20 69 6e 20 0a 2a 2a 20 22 6a 6f 75 72 6e 61 6c   in .** "journal
01d0: 5f 6d 6f 64 65 3d 57 41 4c 22 20 6d 6f 64 65 2e  _mode=WAL" mode.
01e0: 0a 2a 2a 0a 2a 2a 20 57 52 49 54 45 2d 41 48 45  .**.** WRITE-AHE
01f0: 41 44 20 4c 4f 47 20 28 57 41 4c 29 20 46 49 4c  AD LOG (WAL) FIL
0200: 45 20 46 4f 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 41  E FORMAT.**.** A
0210: 20 57 41 4c 20 66 69 6c 65 20 63 6f 6e 73 69 73   WAL file consis
0220: 74 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 66  ts of a header f
0230: 6f 6c 6c 6f 77 65 64 20 62 79 20 7a 65 72 6f 20  ollowed by zero 
0240: 6f 72 20 6d 6f 72 65 20 22 66 72 61 6d 65 73 22  or more "frames"
0250: 2e 0a 2a 2a 20 45 61 63 68 20 66 72 61 6d 65 20  ..** Each frame 
0260: 72 65 63 6f 72 64 73 20 74 68 65 20 72 65 76 69  records the revi
0270: 73 65 64 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  sed content of a
0280: 20 73 69 6e 67 6c 65 20 70 61 67 65 20 66 72 6f   single page fro
0290: 6d 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73  m the.** databas
02a0: 65 20 66 69 6c 65 2e 20 20 41 6c 6c 20 63 68 61  e file.  All cha
02b0: 6e 67 65 73 20 74 6f 20 74 68 65 20 64 61 74 61  nges to the data
02c0: 62 61 73 65 20 61 72 65 20 72 65 63 6f 72 64 65  base are recorde
02d0: 64 20 62 79 20 77 72 69 74 69 6e 67 0a 2a 2a 20  d by writing.** 
02e0: 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20  frames into the 
02f0: 57 41 4c 2e 20 20 54 72 61 6e 73 61 63 74 69 6f  WAL.  Transactio
0300: 6e 73 20 63 6f 6d 6d 69 74 20 77 68 65 6e 20 61  ns commit when a
0310: 20 66 72 61 6d 65 20 69 73 20 77 72 69 74 74 65   frame is writte
0320: 6e 20 74 68 61 74 0a 2a 2a 20 63 6f 6e 74 61 69  n that.** contai
0330: 6e 73 20 61 20 63 6f 6d 6d 69 74 20 6d 61 72 6b  ns a commit mark
0340: 65 72 2e 20 20 41 20 73 69 6e 67 6c 65 20 57 41  er.  A single WA
0350: 4c 20 63 61 6e 20 61 6e 64 20 75 73 75 61 6c 6c  L can and usuall
0360: 79 20 64 6f 65 73 20 72 65 63 6f 72 64 20 0a 2a  y does record .*
0370: 2a 20 6d 75 6c 74 69 70 6c 65 20 74 72 61 6e 73  * multiple trans
0380: 61 63 74 69 6f 6e 73 2e 20 20 50 65 72 69 6f 64  actions.  Period
0390: 69 63 61 6c 6c 79 2c 20 74 68 65 20 63 6f 6e 74  ically, the cont
03a0: 65 6e 74 20 6f 66 20 74 68 65 20 57 41 4c 20 69  ent of the WAL i
03b0: 73 0a 2a 2a 20 74 72 61 6e 73 66 65 72 72 65 64  s.** transferred
03c0: 20 62 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64   back into the d
03d0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 69 6e 20  atabase file in 
03e0: 61 6e 20 6f 70 65 72 61 74 69 6f 6e 20 63 61 6c  an operation cal
03f0: 6c 65 64 20 61 0a 2a 2a 20 22 63 68 65 63 6b 70  led a.** "checkp
0400: 6f 69 6e 74 22 2e 0a 2a 2a 0a 2a 2a 20 41 20 73  oint"..**.** A s
0410: 69 6e 67 6c 65 20 57 41 4c 20 66 69 6c 65 20 63  ingle WAL file c
0420: 61 6e 20 62 65 20 75 73 65 64 20 6d 75 6c 74 69  an be used multi
0430: 70 6c 65 20 74 69 6d 65 73 2e 20 20 49 6e 20 6f  ple times.  In o
0440: 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68 65 0a  ther words, the.
0450: 2a 2a 20 57 41 4c 20 63 61 6e 20 66 69 6c 6c 20  ** WAL can fill 
0460: 75 70 20 77 69 74 68 20 66 72 61 6d 65 73 20 61  up with frames a
0470: 6e 64 20 74 68 65 6e 20 62 65 20 63 68 65 63 6b  nd then be check
0480: 70 6f 69 6e 74 65 64 20 61 6e 64 20 74 68 65 6e  pointed and then
0490: 20 6e 65 77 0a 2a 2a 20 66 72 61 6d 65 73 20 63   new.** frames c
04a0: 61 6e 20 6f 76 65 72 77 72 69 74 65 20 74 68 65  an overwrite the
04b0: 20 6f 6c 64 20 6f 6e 65 73 2e 20 20 41 20 57 41   old ones.  A WA
04c0: 4c 20 61 6c 77 61 79 73 20 67 72 6f 77 73 20 66  L always grows f
04d0: 72 6f 6d 20 62 65 67 69 6e 6e 69 6e 67 0a 2a 2a  rom beginning.**
04e0: 20 74 6f 77 61 72 64 20 74 68 65 20 65 6e 64 2e   toward the end.
04f0: 20 20 43 68 65 63 6b 73 75 6d 73 20 61 6e 64 20    Checksums and 
0500: 63 6f 75 6e 74 65 72 73 20 61 74 74 61 63 68 65  counters attache
0510: 64 20 74 6f 20 65 61 63 68 20 66 72 61 6d 65 20  d to each frame 
0520: 61 72 65 0a 2a 2a 20 75 73 65 64 20 74 6f 20 64  are.** used to d
0530: 65 74 65 72 6d 69 6e 65 20 77 68 69 63 68 20 66  etermine which f
0540: 72 61 6d 65 73 20 77 69 74 68 69 6e 20 74 68 65  rames within the
0550: 20 57 41 4c 20 61 72 65 20 76 61 6c 69 64 20 61   WAL are valid a
0560: 6e 64 20 77 68 69 63 68 0a 2a 2a 20 61 72 65 20  nd which.** are 
0570: 6c 65 66 74 6f 76 65 72 73 20 66 72 6f 6d 20 70  leftovers from p
0580: 72 69 6f 72 20 63 68 65 63 6b 70 6f 69 6e 74 73  rior checkpoints
0590: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 57 41 4c 20  ..**.** The WAL 
05a0: 68 65 61 64 65 72 20 69 73 20 33 32 20 62 79 74  header is 32 byt
05b0: 65 73 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 63  es in size and c
05c0: 6f 6e 73 69 73 74 73 20 6f 66 20 74 68 65 20 66  onsists of the f
05d0: 6f 6c 6c 6f 77 69 6e 67 20 65 69 67 68 74 0a 2a  ollowing eight.*
05e0: 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 33 32 2d  * big-endian 32-
05f0: 62 69 74 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  bit unsigned int
0600: 65 67 65 72 20 76 61 6c 75 65 73 3a 0a 2a 2a 0a  eger values:.**.
0610: 2a 2a 20 20 20 20 20 30 3a 20 4d 61 67 69 63 20  **     0: Magic 
0620: 6e 75 6d 62 65 72 2e 20 20 30 78 33 37 37 66 30  number.  0x377f0
0630: 36 38 32 20 6f 72 20 30 78 33 37 37 66 30 36 38  682 or 0x377f068
0640: 33 0a 2a 2a 20 20 20 20 20 34 3a 20 46 69 6c 65  3.**     4: File
0650: 20 66 6f 72 6d 61 74 20 76 65 72 73 69 6f 6e 2e   format version.
0660: 20 20 43 75 72 72 65 6e 74 6c 79 20 33 30 30 37    Currently 3007
0670: 30 30 30 0a 2a 2a 20 20 20 20 20 38 3a 20 44 61  000.**     8: Da
0680: 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65  tabase page size
0690: 2e 20 20 45 78 61 6d 70 6c 65 3a 20 31 30 32 34  .  Example: 1024
06a0: 0a 2a 2a 20 20 20 20 31 32 3a 20 43 68 65 63 6b  .**    12: Check
06b0: 70 6f 69 6e 74 20 73 65 71 75 65 6e 63 65 20 6e  point sequence n
06c0: 75 6d 62 65 72 0a 2a 2a 20 20 20 20 31 36 3a 20  umber.**    16: 
06d0: 53 61 6c 74 2d 31 2c 20 72 61 6e 64 6f 6d 20 69  Salt-1, random i
06e0: 6e 74 65 67 65 72 20 69 6e 63 72 65 6d 65 6e 74  nteger increment
06f0: 65 64 20 77 69 74 68 20 65 61 63 68 20 63 68 65  ed with each che
0700: 63 6b 70 6f 69 6e 74 0a 2a 2a 20 20 20 20 32 30  ckpoint.**    20
0710: 3a 20 53 61 6c 74 2d 32 2c 20 61 20 64 69 66 66  : Salt-2, a diff
0720: 65 72 65 6e 74 20 72 61 6e 64 6f 6d 20 69 6e 74  erent random int
0730: 65 67 65 72 20 63 68 61 6e 67 69 6e 67 20 77 69  eger changing wi
0740: 74 68 20 65 61 63 68 20 63 6b 70 74 0a 2a 2a 20  th each ckpt.** 
0750: 20 20 20 32 34 3a 20 43 68 65 63 6b 73 75 6d 2d     24: Checksum-
0760: 31 20 28 66 69 72 73 74 20 70 61 72 74 20 6f 66  1 (first part of
0770: 20 63 68 65 63 6b 73 75 6d 20 66 6f 72 20 66 69   checksum for fi
0780: 72 73 74 20 32 34 20 62 79 74 65 73 20 6f 66 20  rst 24 bytes of 
0790: 68 65 61 64 65 72 29 2e 0a 2a 2a 20 20 20 20 32  header)..**    2
07a0: 38 3a 20 43 68 65 63 6b 73 75 6d 2d 32 20 28 73  8: Checksum-2 (s
07b0: 65 63 6f 6e 64 20 70 61 72 74 20 6f 66 20 63 68  econd part of ch
07c0: 65 63 6b 73 75 6d 20 66 6f 72 20 66 69 72 73 74  ecksum for first
07d0: 20 32 34 20 62 79 74 65 73 20 6f 66 20 68 65 61   24 bytes of hea
07e0: 64 65 72 29 2e 0a 2a 2a 0a 2a 2a 20 49 6d 6d 65  der)..**.** Imme
07f0: 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e  diately followin
0800: 67 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  g the wal-header
0810: 20 61 72 65 20 7a 65 72 6f 20 6f 72 20 6d 6f 72   are zero or mor
0820: 65 20 66 72 61 6d 65 73 2e 20 45 61 63 68 0a 2a  e frames. Each.*
0830: 2a 20 66 72 61 6d 65 20 63 6f 6e 73 69 73 74 73  * frame consists
0840: 20 6f 66 20 61 20 32 34 2d 62 79 74 65 20 66 72   of a 24-byte fr
0850: 61 6d 65 2d 68 65 61 64 65 72 20 66 6f 6c 6c 6f  ame-header follo
0860: 77 65 64 20 62 79 20 61 20 3c 70 61 67 65 2d 73  wed by a <page-s
0870: 69 7a 65 3e 20 62 79 74 65 73 0a 2a 2a 20 6f 66  ize> bytes.** of
0880: 20 70 61 67 65 20 64 61 74 61 2e 20 54 68 65 20   page data. The 
0890: 66 72 61 6d 65 2d 68 65 61 64 65 72 20 69 73 20  frame-header is 
08a0: 73 69 78 20 62 69 67 2d 65 6e 64 69 61 6e 20 33  six big-endian 3
08b0: 32 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20 0a  2-bit unsigned .
08c0: 2a 2a 20 69 6e 74 65 67 65 72 20 76 61 6c 75 65  ** integer value
08d0: 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  s, as follows:.*
08e0: 2a 0a 2a 2a 20 20 20 20 20 30 3a 20 50 61 67 65  *.**     0: Page
08f0: 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20 20 20 20   number..**     
0900: 34 3a 20 46 6f 72 20 63 6f 6d 6d 69 74 20 72 65  4: For commit re
0910: 63 6f 72 64 73 2c 20 74 68 65 20 73 69 7a 65 20  cords, the size 
0920: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  of the database 
0930: 69 6d 61 67 65 20 69 6e 20 70 61 67 65 73 20 0a  image in pages .
0940: 2a 2a 20 20 20 20 20 20 20 20 61 66 74 65 72 20  **        after 
0950: 74 68 65 20 63 6f 6d 6d 69 74 2e 20 46 6f 72 20  the commit. For 
0960: 61 6c 6c 20 6f 74 68 65 72 20 72 65 63 6f 72 64  all other record
0970: 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20 20  s, zero..**     
0980: 38 3a 20 53 61 6c 74 2d 31 20 28 63 6f 70 69 65  8: Salt-1 (copie
0990: 64 20 66 72 6f 6d 20 74 68 65 20 68 65 61 64 65  d from the heade
09a0: 72 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61 6c  r).**    12: Sal
09b0: 74 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f 6d  t-2 (copied from
09c0: 20 74 68 65 20 68 65 61 64 65 72 29 0a 2a 2a 20   the header).** 
09d0: 20 20 20 31 36 3a 20 43 68 65 63 6b 73 75 6d 2d     16: Checksum-
09e0: 31 2e 0a 2a 2a 20 20 20 20 32 30 3a 20 43 68 65  1..**    20: Che
09f0: 63 6b 73 75 6d 2d 32 2e 0a 2a 2a 0a 2a 2a 20 41  cksum-2..**.** A
0a00: 20 66 72 61 6d 65 20 69 73 20 63 6f 6e 73 69 64   frame is consid
0a10: 65 72 65 64 20 76 61 6c 69 64 20 69 66 20 61 6e  ered valid if an
0a20: 64 20 6f 6e 6c 79 20 69 66 20 74 68 65 20 66 6f  d only if the fo
0a30: 6c 6c 6f 77 69 6e 67 20 63 6f 6e 64 69 74 69 6f  llowing conditio
0a40: 6e 73 20 61 72 65 0a 2a 2a 20 74 72 75 65 3a 0a  ns are.** true:.
0a50: 2a 2a 0a 2a 2a 20 20 20 20 28 31 29 20 54 68 65  **.**    (1) The
0a60: 20 73 61 6c 74 2d 31 20 61 6e 64 20 73 61 6c 74   salt-1 and salt
0a70: 2d 32 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  -2 values in the
0a80: 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20 6d 61   frame-header ma
0a90: 74 63 68 0a 2a 2a 20 20 20 20 20 20 20 20 73 61  tch.**        sa
0aa0: 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  lt values in the
0ab0: 20 77 61 6c 2d 68 65 61 64 65 72 0a 2a 2a 0a 2a   wal-header.**.*
0ac0: 2a 20 20 20 20 28 32 29 20 54 68 65 20 63 68 65  *    (2) The che
0ad0: 63 6b 73 75 6d 20 76 61 6c 75 65 73 20 69 6e 20  cksum values in 
0ae0: 74 68 65 20 66 69 6e 61 6c 20 38 20 62 79 74 65  the final 8 byte
0af0: 73 20 6f 66 20 74 68 65 20 66 72 61 6d 65 2d 68  s of the frame-h
0b00: 65 61 64 65 72 0a 2a 2a 20 20 20 20 20 20 20 20  eader.**        
0b10: 65 78 61 63 74 6c 79 20 6d 61 74 63 68 20 74 68  exactly match th
0b20: 65 20 63 68 65 63 6b 73 75 6d 20 63 6f 6d 70 75  e checksum compu
0b30: 74 65 64 20 63 6f 6e 73 65 63 75 74 69 76 65 6c  ted consecutivel
0b40: 79 20 6f 6e 20 74 68 65 0a 2a 2a 20 20 20 20 20  y on the.**     
0b50: 20 20 20 57 41 4c 20 68 65 61 64 65 72 20 61 6e     WAL header an
0b60: 64 20 74 68 65 20 66 69 72 73 74 20 38 20 62 79  d the first 8 by
0b70: 74 65 73 20 61 6e 64 20 74 68 65 20 63 6f 6e 74  tes and the cont
0b80: 65 6e 74 20 6f 66 20 61 6c 6c 20 66 72 61 6d 65  ent of all frame
0b90: 73 0a 2a 2a 20 20 20 20 20 20 20 20 75 70 20 74  s.**        up t
0ba0: 6f 20 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20  o and including 
0bb0: 74 68 65 20 63 75 72 72 65 6e 74 20 66 72 61 6d  the current fram
0bc0: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65  e..**.** The che
0bd0: 63 6b 73 75 6d 20 69 73 20 63 6f 6d 70 75 74 65  cksum is compute
0be0: 64 20 75 73 69 6e 67 20 33 32 2d 62 69 74 20 62  d using 32-bit b
0bf0: 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65  ig-endian intege
0c00: 72 73 20 69 66 20 74 68 65 0a 2a 2a 20 6d 61 67  rs if the.** mag
0c10: 69 63 20 6e 75 6d 62 65 72 20 69 6e 20 74 68 65  ic number in the
0c20: 20 66 69 72 73 74 20 34 20 62 79 74 65 73 20 6f   first 4 bytes o
0c30: 66 20 74 68 65 20 57 41 4c 20 69 73 20 30 78 33  f the WAL is 0x3
0c40: 37 37 66 30 36 38 33 20 61 6e 64 20 69 74 0a 2a  77f0683 and it.*
0c50: 2a 20 69 73 20 63 6f 6d 70 75 74 65 64 20 75 73  * is computed us
0c60: 69 6e 67 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61  ing little-endia
0c70: 6e 20 69 66 20 74 68 65 20 6d 61 67 69 63 20 6e  n if the magic n
0c80: 75 6d 62 65 72 20 69 73 20 30 78 33 37 37 66 30  umber is 0x377f0
0c90: 36 38 32 2e 0a 2a 2a 20 54 68 65 20 63 68 65 63  682..** The chec
0ca0: 6b 73 75 6d 20 76 61 6c 75 65 73 20 61 72 65 20  ksum values are 
0cb0: 61 6c 77 61 79 73 20 73 74 6f 72 65 64 20 69 6e  always stored in
0cc0: 20 74 68 65 20 66 72 61 6d 65 20 68 65 61 64 65   the frame heade
0cd0: 72 20 69 6e 20 61 0a 2a 2a 20 62 69 67 2d 65 6e  r in a.** big-en
0ce0: 64 69 61 6e 20 66 6f 72 6d 61 74 20 72 65 67 61  dian format rega
0cf0: 72 64 6c 65 73 73 20 6f 66 20 77 68 69 63 68 20  rdless of which 
0d00: 62 79 74 65 20 6f 72 64 65 72 20 69 73 20 75 73  byte order is us
0d10: 65 64 20 74 6f 20 63 6f 6d 70 75 74 65 0a 2a 2a  ed to compute.**
0d20: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 2e 20 20   the checksum.  
0d30: 54 68 65 20 63 68 65 63 6b 73 75 6d 20 69 73 20  The checksum is 
0d40: 63 6f 6d 70 75 74 65 64 20 62 79 20 69 6e 74 65  computed by inte
0d50: 72 70 72 65 74 69 6e 67 20 74 68 65 20 69 6e 70  rpreting the inp
0d60: 75 74 20 61 73 0a 2a 2a 20 61 6e 20 65 76 65 6e  ut as.** an even
0d70: 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 73 69 67   number of unsig
0d80: 6e 65 64 20 33 32 2d 62 69 74 20 69 6e 74 65 67  ned 32-bit integ
0d90: 65 72 73 3a 20 78 5b 30 5d 20 74 68 72 6f 75 67  ers: x[0] throug
0da0: 68 20 78 5b 4e 5d 2e 20 20 54 68 65 0a 2a 2a 20  h x[N].  The.** 
0db0: 61 6c 67 6f 72 69 74 68 6d 20 75 73 65 64 20 66  algorithm used f
0dc0: 6f 72 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20  or the checksum 
0dd0: 69 73 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  is as follows:.*
0de0: 2a 20 0a 2a 2a 20 20 20 66 6f 72 20 69 20 66 72  * .**   for i fr
0df0: 6f 6d 20 30 20 74 6f 20 6e 2d 31 20 73 74 65 70  om 0 to n-1 step
0e00: 20 32 3a 0a 2a 2a 20 20 20 20 20 73 30 20 2b 3d   2:.**     s0 +=
0e10: 20 78 5b 69 5d 20 2b 20 73 31 3b 0a 2a 2a 20 20   x[i] + s1;.**  
0e20: 20 20 20 73 31 20 2b 3d 20 78 5b 69 2b 31 5d 20     s1 += x[i+1] 
0e30: 2b 20 73 30 3b 0a 2a 2a 20 20 20 65 6e 64 66 6f  + s0;.**   endfo
0e40: 72 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61  r.**.** Note tha
0e50: 74 20 73 30 20 61 6e 64 20 73 31 20 61 72 65 20  t s0 and s1 are 
0e60: 62 6f 74 68 20 77 65 69 67 68 74 65 64 20 63 68  both weighted ch
0e70: 65 63 6b 73 75 6d 73 20 75 73 69 6e 67 20 66 69  ecksums using fi
0e80: 62 6f 6e 61 63 63 69 20 77 65 69 67 68 74 73 0a  bonacci weights.
0e90: 2a 2a 20 69 6e 20 72 65 76 65 72 73 65 20 6f 72  ** in reverse or
0ea0: 64 65 72 20 28 74 68 65 20 6c 61 72 67 65 73 74  der (the largest
0eb0: 20 66 69 62 6f 6e 61 63 63 69 20 77 65 69 67 68   fibonacci weigh
0ec0: 74 20 6f 63 63 75 72 73 20 6f 6e 20 74 68 65 20  t occurs on the 
0ed0: 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 0a 2a 2a  first element.**
0ee0: 20 6f 66 20 74 68 65 20 73 65 71 75 65 6e 63 65   of the sequence
0ef0: 20 62 65 69 6e 67 20 73 75 6d 6d 65 64 2e 29 20   being summed.) 
0f00: 20 54 68 65 20 73 31 20 76 61 6c 75 65 20 73 70   The s1 value sp
0f10: 61 6e 73 20 61 6c 6c 20 33 32 2d 62 69 74 20 0a  ans all 32-bit .
0f20: 2a 2a 20 74 65 72 6d 73 20 6f 66 20 74 68 65 20  ** terms of the 
0f30: 73 65 71 75 65 6e 63 65 20 77 68 65 72 65 61 73  sequence whereas
0f40: 20 73 30 20 6f 6d 69 74 73 20 74 68 65 20 66 69   s0 omits the fi
0f50: 6e 61 6c 20 74 65 72 6d 2e 0a 2a 2a 0a 2a 2a 20  nal term..**.** 
0f60: 4f 6e 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c  On a checkpoint,
0f70: 20 74 68 65 20 57 41 4c 20 69 73 20 66 69 72 73   the WAL is firs
0f80: 74 20 56 46 53 2e 78 53 79 6e 63 2d 65 64 2c 20  t VFS.xSync-ed, 
0f90: 74 68 65 6e 20 76 61 6c 69 64 20 63 6f 6e 74 65  then valid conte
0fa0: 6e 74 20 6f 66 20 74 68 65 0a 2a 2a 20 57 41 4c  nt of the.** WAL
0fb0: 20 69 73 20 74 72 61 6e 73 66 65 72 72 65 64 20   is transferred 
0fc0: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
0fd0: 65 2c 20 74 68 65 6e 20 74 68 65 20 64 61 74 61  e, then the data
0fe0: 62 61 73 65 20 69 73 20 56 46 53 2e 78 53 79 6e  base is VFS.xSyn
0ff0: 63 2d 65 64 2e 0a 2a 2a 20 54 68 65 20 56 46 53  c-ed..** The VFS
1000: 2e 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e  .xSync operation
1010: 73 20 73 65 72 76 65 20 61 73 20 77 72 69 74 65  s serve as write
1020: 20 62 61 72 72 69 65 72 73 20 2d 20 61 6c 6c 20   barriers - all 
1030: 77 72 69 74 65 73 20 6c 61 75 6e 63 68 65 64 0a  writes launched.
1040: 2a 2a 20 62 65 66 6f 72 65 20 74 68 65 20 78 53  ** before the xS
1050: 79 6e 63 20 6d 75 73 74 20 63 6f 6d 70 6c 65 74  ync must complet
1060: 65 20 62 65 66 6f 72 65 20 61 6e 79 20 77 72 69  e before any wri
1070: 74 65 20 74 68 61 74 20 6c 61 75 6e 63 68 65 73  te that launches
1080: 20 61 66 74 65 72 20 74 68 65 0a 2a 2a 20 78 53   after the.** xS
1090: 79 6e 63 20 62 65 67 69 6e 73 2e 0a 2a 2a 0a 2a  ync begins..**.*
10a0: 2a 20 41 66 74 65 72 20 65 61 63 68 20 63 68 65  * After each che
10b0: 63 6b 70 6f 69 6e 74 2c 20 74 68 65 20 73 61 6c  ckpoint, the sal
10c0: 74 2d 31 20 76 61 6c 75 65 20 69 73 20 69 6e 63  t-1 value is inc
10d0: 72 65 6d 65 6e 74 65 64 20 61 6e 64 20 74 68 65  remented and the
10e0: 20 73 61 6c 74 2d 32 0a 2a 2a 20 76 61 6c 75 65   salt-2.** value
10f0: 20 69 73 20 72 61 6e 64 6f 6d 69 7a 65 64 2e 20   is randomized. 
1100: 20 54 68 69 73 20 70 72 65 76 65 6e 74 73 20 6f   This prevents o
1110: 6c 64 20 61 6e 64 20 6e 65 77 20 66 72 61 6d 65  ld and new frame
1120: 73 20 69 6e 20 74 68 65 20 57 41 4c 20 66 72 6f  s in the WAL fro
1130: 6d 0a 2a 2a 20 62 65 69 6e 67 20 63 6f 6e 73 69  m.** being consi
1140: 64 65 72 65 64 20 76 61 6c 69 64 20 61 74 20 74  dered valid at t
1150: 68 65 20 73 61 6d 65 20 74 69 6d 65 20 61 6e 64  he same time and
1160: 20 62 65 69 6e 67 20 63 68 65 63 6b 70 6f 69 6e   being checkpoin
1170: 74 69 6e 67 20 74 6f 67 65 74 68 65 72 0a 2a 2a  ting together.**
1180: 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 63 72 61   following a cra
1190: 73 68 2e 0a 2a 2a 0a 2a 2a 20 52 45 41 44 45 52  sh..**.** READER
11a0: 20 41 4c 47 4f 52 49 54 48 4d 0a 2a 2a 0a 2a 2a   ALGORITHM.**.**
11b0: 20 54 6f 20 72 65 61 64 20 61 20 70 61 67 65 20   To read a page 
11c0: 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
11d0: 65 20 28 63 61 6c 6c 20 69 74 20 70 61 67 65 20  e (call it page 
11e0: 6e 75 6d 62 65 72 20 50 29 2c 20 61 20 72 65 61  number P), a rea
11f0: 64 65 72 0a 2a 2a 20 66 69 72 73 74 20 63 68 65  der.** first che
1200: 63 6b 73 20 74 68 65 20 57 41 4c 20 74 6f 20 73  cks the WAL to s
1210: 65 65 20 69 66 20 69 74 20 63 6f 6e 74 61 69 6e  ee if it contain
1220: 73 20 70 61 67 65 20 50 2e 20 20 49 66 20 73 6f  s page P.  If so
1230: 2c 20 74 68 65 6e 20 74 68 65 0a 2a 2a 20 6c 61  , then the.** la
1240: 73 74 20 76 61 6c 69 64 20 69 6e 73 74 61 6e 63  st valid instanc
1250: 65 20 6f 66 20 70 61 67 65 20 50 20 74 68 61 74  e of page P that
1260: 20 69 73 20 61 20 66 6f 6c 6c 6f 77 65 64 20 62   is a followed b
1270: 79 20 61 20 63 6f 6d 6d 69 74 20 66 72 61 6d 65  y a commit frame
1280: 0a 2a 2a 20 6f 72 20 69 73 20 61 20 63 6f 6d 6d  .** or is a comm
1290: 69 74 20 66 72 61 6d 65 20 69 74 73 65 6c 66 20  it frame itself 
12a0: 62 65 63 6f 6d 65 73 20 74 68 65 20 76 61 6c 75  becomes the valu
12b0: 65 20 72 65 61 64 2e 20 20 49 66 20 74 68 65 20  e read.  If the 
12c0: 57 41 4c 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20  WAL.** contains 
12d0: 6e 6f 20 63 6f 70 69 65 73 20 6f 66 20 70 61 67  no copies of pag
12e0: 65 20 50 20 74 68 61 74 20 61 72 65 20 76 61 6c  e P that are val
12f0: 69 64 20 61 6e 64 20 77 68 69 63 68 20 61 72 65  id and which are
1300: 20 61 20 63 6f 6d 6d 69 74 0a 2a 2a 20 66 72 61   a commit.** fra
1310: 6d 65 20 6f 72 20 61 72 65 20 66 6f 6c 6c 6f 77  me or are follow
1320: 65 64 20 62 79 20 61 20 63 6f 6d 6d 69 74 20 66  ed by a commit f
1330: 72 61 6d 65 2c 20 74 68 65 6e 20 70 61 67 65 20  rame, then page 
1340: 50 20 69 73 20 72 65 61 64 20 66 72 6f 6d 0a 2a  P is read from.*
1350: 2a 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  * the database f
1360: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 73 74  ile..**.** To st
1370: 61 72 74 20 61 20 72 65 61 64 20 74 72 61 6e 73  art a read trans
1380: 61 63 74 69 6f 6e 2c 20 74 68 65 20 72 65 61 64  action, the read
1390: 65 72 20 72 65 63 6f 72 64 73 20 74 68 65 20 69  er records the i
13a0: 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 73 74  ndex of the last
13b0: 0a 2a 2a 20 76 61 6c 69 64 20 66 72 61 6d 65 20  .** valid frame 
13c0: 69 6e 20 74 68 65 20 57 41 4c 2e 20 20 54 68 65  in the WAL.  The
13d0: 20 72 65 61 64 65 72 20 75 73 65 73 20 74 68 69   reader uses thi
13e0: 73 20 72 65 63 6f 72 64 65 64 20 22 6d 78 46 72  s recorded "mxFr
13f0: 61 6d 65 22 20 76 61 6c 75 65 0a 2a 2a 20 66 6f  ame" value.** fo
1400: 72 20 61 6c 6c 20 73 75 62 73 65 71 75 65 6e 74  r all subsequent
1410: 20 72 65 61 64 20 6f 70 65 72 61 74 69 6f 6e 73   read operations
1420: 2e 20 20 4e 65 77 20 74 72 61 6e 73 61 63 74 69  .  New transacti
1430: 6f 6e 73 20 63 61 6e 20 62 65 20 61 70 70 65 6e  ons can be appen
1440: 64 65 64 0a 2a 2a 20 74 6f 20 74 68 65 20 57 41  ded.** to the WA
1450: 4c 2c 20 62 75 74 20 61 73 20 6c 6f 6e 67 20 61  L, but as long a
1460: 73 20 74 68 65 20 72 65 61 64 65 72 20 75 73 65  s the reader use
1470: 73 20 69 74 73 20 6f 72 69 67 69 6e 61 6c 20 6d  s its original m
1480: 78 46 72 61 6d 65 20 76 61 6c 75 65 0a 2a 2a 20  xFrame value.** 
1490: 61 6e 64 20 69 67 6e 6f 72 65 73 20 74 68 65 20  and ignores the 
14a0: 6e 65 77 6c 79 20 61 70 70 65 6e 64 65 64 20 63  newly appended c
14b0: 6f 6e 74 65 6e 74 2c 20 69 74 20 77 69 6c 6c 20  ontent, it will 
14c0: 73 65 65 20 61 20 63 6f 6e 73 69 73 74 65 6e 74  see a consistent
14d0: 20 73 6e 61 70 73 68 6f 74 0a 2a 2a 20 6f 66 20   snapshot.** of 
14e0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 72 6f  the database fro
14f0: 6d 20 61 20 73 69 6e 67 6c 65 20 70 6f 69 6e 74  m a single point
1500: 20 69 6e 20 74 69 6d 65 2e 20 20 54 68 69 73 20   in time.  This 
1510: 74 65 63 68 6e 69 71 75 65 20 61 6c 6c 6f 77 73  technique allows
1520: 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 63 6f 6e  .** multiple con
1530: 63 75 72 72 65 6e 74 20 72 65 61 64 65 72 73 20  current readers 
1540: 74 6f 20 76 69 65 77 20 64 69 66 66 65 72 65 6e  to view differen
1550: 74 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68  t versions of th
1560: 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 63 6f  e database.** co
1570: 6e 74 65 6e 74 20 73 69 6d 75 6c 74 61 6e 65 6f  ntent simultaneo
1580: 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  usly..**.** The 
1590: 72 65 61 64 65 72 20 61 6c 67 6f 72 69 74 68 6d  reader algorithm
15a0: 20 69 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73   in the previous
15b0: 20 70 61 72 61 67 72 61 70 68 73 20 77 6f 72 6b   paragraphs work
15c0: 73 20 63 6f 72 72 65 63 74 6c 79 2c 20 62 75 74  s correctly, but
15d0: 20 0a 2a 2a 20 62 65 63 61 75 73 65 20 66 72 61   .** because fra
15e0: 6d 65 73 20 66 6f 72 20 70 61 67 65 20 50 20 63  mes for page P c
15f0: 61 6e 20 61 70 70 65 61 72 20 61 6e 79 77 68 65  an appear anywhe
1600: 72 65 20 77 69 74 68 69 6e 20 74 68 65 20 57 41  re within the WA
1610: 4c 2c 20 74 68 65 0a 2a 2a 20 72 65 61 64 65 72  L, the.** reader
1620: 20 68 61 73 20 74 6f 20 73 63 61 6e 20 74 68 65   has to scan the
1630: 20 65 6e 74 69 72 65 20 57 41 4c 20 6c 6f 6f 6b   entire WAL look
1640: 69 6e 67 20 66 6f 72 20 70 61 67 65 20 50 20 66  ing for page P f
1650: 72 61 6d 65 73 2e 20 20 49 66 20 74 68 65 0a 2a  rames.  If the.*
1660: 2a 20 57 41 4c 20 69 73 20 6c 61 72 67 65 20 28  * WAL is large (
1670: 6d 75 6c 74 69 70 6c 65 20 6d 65 67 61 62 79 74  multiple megabyt
1680: 65 73 20 69 73 20 74 79 70 69 63 61 6c 29 20 74  es is typical) t
1690: 68 61 74 20 73 63 61 6e 20 63 61 6e 20 62 65 20  hat scan can be 
16a0: 73 6c 6f 77 2c 0a 2a 2a 20 61 6e 64 20 72 65 61  slow,.** and rea
16b0: 64 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 73 75  d performance su
16c0: 66 66 65 72 73 2e 20 20 54 6f 20 6f 76 65 72 63  ffers.  To overc
16d0: 6f 6d 65 20 74 68 69 73 20 70 72 6f 62 6c 65 6d  ome this problem
16e0: 2c 20 61 20 73 65 70 61 72 61 74 65 0a 2a 2a 20  , a separate.** 
16f0: 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20 63  data structure c
1700: 61 6c 6c 65 64 20 74 68 65 20 77 61 6c 2d 69 6e  alled the wal-in
1710: 64 65 78 20 69 73 20 6d 61 69 6e 74 61 69 6e 65  dex is maintaine
1720: 64 20 74 6f 20 65 78 70 65 64 69 74 65 20 74 68  d to expedite th
1730: 65 0a 2a 2a 20 73 65 61 72 63 68 20 66 6f 72 20  e.** search for 
1740: 66 72 61 6d 65 73 20 6f 66 20 61 20 70 61 72 74  frames of a part
1750: 69 63 75 6c 61 72 20 70 61 67 65 2e 0a 2a 2a 20  icular page..** 
1760: 0a 2a 2a 20 57 41 4c 2d 49 4e 44 45 58 20 46 4f  .** WAL-INDEX FO
1770: 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 43 6f 6e 63 65  RMAT.**.** Conce
1780: 70 74 75 61 6c 6c 79 2c 20 74 68 65 20 77 61 6c  ptually, the wal
1790: 2d 69 6e 64 65 78 20 69 73 20 73 68 61 72 65 64  -index is shared
17a0: 20 6d 65 6d 6f 72 79 2c 20 74 68 6f 75 67 68 20   memory, though 
17b0: 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  VFS implementati
17c0: 6f 6e 73 0a 2a 2a 20 6d 69 67 68 74 20 63 68 6f  ons.** might cho
17d0: 6f 73 65 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  ose to implement
17e0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 75   the wal-index u
17f0: 73 69 6e 67 20 61 20 6d 6d 61 70 70 65 64 20 66  sing a mmapped f
1800: 69 6c 65 2e 20 20 42 65 63 61 75 73 65 0a 2a 2a  ile.  Because.**
1810: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69   the wal-index i
1820: 73 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 2c  s shared memory,
1830: 20 53 51 4c 69 74 65 20 64 6f 65 73 20 6e 6f 74   SQLite does not
1840: 20 73 75 70 70 6f 72 74 20 6a 6f 75 72 6e 61 6c   support journal
1850: 5f 6d 6f 64 65 3d 57 41 4c 20 0a 2a 2a 20 6f 6e  _mode=WAL .** on
1860: 20 61 20 6e 65 74 77 6f 72 6b 20 66 69 6c 65 73   a network files
1870: 79 73 74 65 6d 2e 20 20 41 6c 6c 20 75 73 65 72  ystem.  All user
1880: 73 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  s of the databas
1890: 65 20 6d 75 73 74 20 62 65 20 61 62 6c 65 20 74  e must be able t
18a0: 6f 0a 2a 2a 20 73 68 61 72 65 20 6d 65 6d 6f 72  o.** share memor
18b0: 79 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20 74 68 65 20  y..**.** In the 
18c0: 64 65 66 61 75 6c 74 20 75 6e 69 78 20 61 6e 64  default unix and
18d0: 20 77 69 6e 64 6f 77 73 20 69 6d 70 6c 65 6d 65   windows impleme
18e0: 6e 74 61 74 69 6f 6e 2c 20 74 68 65 20 77 61 6c  ntation, the wal
18f0: 2d 69 6e 64 65 78 20 69 73 20 61 20 6d 6d 61 70  -index is a mmap
1900: 70 65 64 0a 2a 2a 20 66 69 6c 65 20 77 68 6f 73  ped.** file whos
1910: 65 20 6e 61 6d 65 20 69 73 20 74 68 65 20 64 61  e name is the da
1920: 74 61 62 61 73 65 20 6e 61 6d 65 20 77 69 74 68  tabase name with
1930: 20 61 20 22 2d 73 68 6d 22 20 73 75 66 66 69 78   a "-shm" suffix
1940: 20 61 64 64 65 64 2e 20 20 46 6f 72 20 74 68 61   added.  For tha
1950: 74 0a 2a 2a 20 72 65 61 73 6f 6e 2c 20 74 68 65  t.** reason, the
1960: 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 73 6f   wal-index is so
1970: 6d 65 74 69 6d 65 73 20 63 61 6c 6c 65 64 20 74  metimes called t
1980: 68 65 20 22 73 68 6d 22 20 66 69 6c 65 2e 0a 2a  he "shm" file..*
1990: 2a 0a 2a 2a 20 54 68 65 20 77 61 6c 2d 69 6e 64  *.** The wal-ind
19a0: 65 78 20 69 73 20 74 72 61 6e 73 69 65 6e 74 2e  ex is transient.
19b0: 20 20 41 66 74 65 72 20 61 20 63 72 61 73 68 2c    After a crash,
19c0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 63   the wal-index c
19d0: 61 6e 20 28 61 6e 64 20 73 68 6f 75 6c 64 0a 2a  an (and should.*
19e0: 2a 20 62 65 29 20 72 65 63 6f 6e 73 74 72 75 63  * be) reconstruc
19f0: 74 65 64 20 66 72 6f 6d 20 74 68 65 20 6f 72 69  ted from the ori
1a00: 67 69 6e 61 6c 20 57 41 4c 20 66 69 6c 65 2e 20  ginal WAL file. 
1a10: 20 49 6e 20 66 61 63 74 2c 20 74 68 65 20 56 46   In fact, the VF
1a20: 53 20 69 73 20 72 65 71 75 69 72 65 64 0a 2a 2a  S is required.**
1a30: 20 74 6f 20 65 69 74 68 65 72 20 74 72 75 6e 63   to either trunc
1a40: 61 74 65 20 6f 72 20 7a 65 72 6f 20 74 68 65 20  ate or zero the 
1a50: 68 65 61 64 65 72 20 6f 66 20 74 68 65 20 77 61  header of the wa
1a60: 6c 2d 69 6e 64 65 78 20 77 68 65 6e 20 74 68 65  l-index when the
1a70: 20 6c 61 73 74 0a 2a 2a 20 63 6f 6e 6e 65 63 74   last.** connect
1a80: 69 6f 6e 20 74 6f 20 69 74 20 63 6c 6f 73 65 73  ion to it closes
1a90: 2e 20 20 42 65 63 61 75 73 65 20 74 68 65 20 77  .  Because the w
1aa0: 61 6c 2d 69 6e 64 65 78 20 69 73 20 74 72 61 6e  al-index is tran
1ab0: 73 69 65 6e 74 2c 20 69 74 20 63 61 6e 0a 2a 2a  sient, it can.**
1ac0: 20 75 73 65 20 61 6e 20 61 72 63 68 69 74 65 63   use an architec
1ad0: 74 75 72 65 2d 73 70 65 63 69 66 69 63 20 66 6f  ture-specific fo
1ae0: 72 6d 61 74 3b 20 69 74 20 64 6f 65 73 20 6e 6f  rmat; it does no
1af0: 74 20 68 61 76 65 20 74 6f 20 62 65 20 63 72 6f  t have to be cro
1b00: 73 73 2d 70 6c 61 74 66 6f 72 6d 2e 0a 2a 2a 20  ss-platform..** 
1b10: 48 65 6e 63 65 2c 20 75 6e 6c 69 6b 65 20 74 68  Hence, unlike th
1b20: 65 20 64 61 74 61 62 61 73 65 20 61 6e 64 20 57  e database and W
1b30: 41 4c 20 66 69 6c 65 20 66 6f 72 6d 61 74 73 20  AL file formats 
1b40: 77 68 69 63 68 20 73 74 6f 72 65 20 61 6c 6c 20  which store all 
1b50: 76 61 6c 75 65 73 0a 2a 2a 20 61 73 20 62 69 67  values.** as big
1b60: 20 65 6e 64 69 61 6e 2c 20 74 68 65 20 77 61 6c   endian, the wal
1b70: 2d 69 6e 64 65 78 20 63 61 6e 20 73 74 6f 72 65  -index can store
1b80: 20 6d 75 6c 74 69 2d 62 79 74 65 20 76 61 6c 75   multi-byte valu
1b90: 65 73 20 69 6e 20 74 68 65 20 6e 61 74 69 76 65  es in the native
1ba0: 0a 2a 2a 20 62 79 74 65 20 6f 72 64 65 72 20 6f  .** byte order o
1bb0: 66 20 74 68 65 20 68 6f 73 74 20 63 6f 6d 70 75  f the host compu
1bc0: 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 70  ter..**.** The p
1bd0: 75 72 70 6f 73 65 20 6f 66 20 74 68 65 20 77 61  urpose of the wa
1be0: 6c 2d 69 6e 64 65 78 20 69 73 20 74 6f 20 61 6e  l-index is to an
1bf0: 73 77 65 72 20 74 68 69 73 20 71 75 65 73 74 69  swer this questi
1c00: 6f 6e 20 71 75 69 63 6b 6c 79 3a 20 20 47 69 76  on quickly:  Giv
1c10: 65 6e 0a 2a 2a 20 61 20 70 61 67 65 20 6e 75 6d  en.** a page num
1c20: 62 65 72 20 50 20 61 6e 64 20 61 20 6d 61 78 69  ber P and a maxi
1c30: 6d 75 6d 20 66 72 61 6d 65 20 69 6e 64 65 78 20  mum frame index 
1c40: 4d 2c 20 72 65 74 75 72 6e 20 74 68 65 20 69 6e  M, return the in
1c50: 64 65 78 20 6f 66 20 74 68 65 20 0a 2a 2a 20 6c  dex of the .** l
1c60: 61 73 74 20 66 72 61 6d 65 20 69 6e 20 74 68 65  ast frame in the
1c70: 20 77 61 6c 20 62 65 66 6f 72 65 20 66 72 61 6d   wal before fram
1c80: 65 20 4d 20 66 6f 72 20 70 61 67 65 20 50 20 69  e M for page P i
1c90: 6e 20 74 68 65 20 57 41 4c 2c 20 6f 72 20 72 65  n the WAL, or re
1ca0: 74 75 72 6e 0a 2a 2a 20 4e 55 4c 4c 20 69 66 20  turn.** NULL if 
1cb0: 74 68 65 72 65 20 61 72 65 20 6e 6f 20 66 72 61  there are no fra
1cc0: 6d 65 73 20 66 6f 72 20 70 61 67 65 20 50 20 69  mes for page P i
1cd0: 6e 20 74 68 65 20 57 41 4c 20 70 72 69 6f 72 20  n the WAL prior 
1ce0: 74 6f 20 4d 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  to M..**.** The 
1cf0: 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69 73  wal-index consis
1d00: 74 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 72  ts of a header r
1d10: 65 67 69 6f 6e 2c 20 66 6f 6c 6c 6f 77 65 64 20  egion, followed 
1d20: 62 79 20 61 6e 20 6f 6e 65 20 6f 72 0a 2a 2a 20  by an one or.** 
1d30: 6d 6f 72 65 20 69 6e 64 65 78 20 62 6c 6f 63 6b  more index block
1d40: 73 2e 20 20 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77  s.  .**.** The w
1d50: 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
1d60: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 74 6f 74  contains the tot
1d70: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61  al number of fra
1d80: 6d 65 73 20 77 69 74 68 69 6e 20 74 68 65 20 57  mes within the W
1d90: 41 4c 0a 2a 2a 20 69 6e 20 74 68 65 20 6d 78 46  AL.** in the mxF
1da0: 72 61 6d 65 20 66 69 65 6c 64 2e 0a 2a 2a 0a 2a  rame field..**.*
1db0: 2a 20 45 61 63 68 20 69 6e 64 65 78 20 62 6c 6f  * Each index blo
1dc0: 63 6b 20 65 78 63 65 70 74 20 66 6f 72 20 74 68  ck except for th
1dd0: 65 20 66 69 72 73 74 20 63 6f 6e 74 61 69 6e 73  e first contains
1de0: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f 6e 20   information on 
1df0: 0a 2a 2a 20 48 41 53 48 54 41 42 4c 45 5f 4e 50  .** HASHTABLE_NP
1e00: 41 47 45 20 66 72 61 6d 65 73 2e 20 54 68 65 20  AGE frames. The 
1e10: 66 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63  first index bloc
1e20: 6b 20 63 6f 6e 74 61 69 6e 73 20 69 6e 66 6f 72  k contains infor
1e30: 6d 61 74 69 6f 6e 20 6f 6e 0a 2a 2a 20 48 41 53  mation on.** HAS
1e40: 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45  HTABLE_NPAGE_ONE
1e50: 20 66 72 61 6d 65 73 2e 20 54 68 65 20 76 61 6c   frames. The val
1e60: 75 65 73 20 6f 66 20 48 41 53 48 54 41 42 4c 45  ues of HASHTABLE
1e70: 5f 4e 50 41 47 45 5f 4f 4e 45 20 61 6e 64 20 0a  _NPAGE_ONE and .
1e80: 2a 2a 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  ** HASHTABLE_NPA
1e90: 47 45 20 61 72 65 20 73 65 6c 65 63 74 65 64 20  GE are selected 
1ea0: 73 6f 20 74 68 61 74 20 74 6f 67 65 74 68 65 72  so that together
1eb0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
1ec0: 65 61 64 65 72 20 61 6e 64 0a 2a 2a 20 66 69 72  eader and.** fir
1ed0: 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 61  st index block a
1ee0: 72 65 20 74 68 65 20 73 61 6d 65 20 73 69 7a 65  re the same size
1ef0: 20 61 73 20 61 6c 6c 20 6f 74 68 65 72 20 69 6e   as all other in
1f00: 64 65 78 20 62 6c 6f 63 6b 73 20 69 6e 20 74 68  dex blocks in th
1f10: 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 2e 0a  e.** wal-index..
1f20: 2a 2a 0a 2a 2a 20 45 61 63 68 20 69 6e 64 65 78  **.** Each index
1f30: 20 62 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20   block contains 
1f40: 74 77 6f 20 73 65 63 74 69 6f 6e 73 2c 20 61 20  two sections, a 
1f50: 70 61 67 65 2d 6d 61 70 70 69 6e 67 20 74 68 61  page-mapping tha
1f60: 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 0a 2a  t contains the.*
1f70: 2a 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20  * database page 
1f80: 6e 75 6d 62 65 72 20 61 73 73 6f 63 69 61 74 65  number associate
1f90: 64 20 77 69 74 68 20 65 61 63 68 20 77 61 6c 20  d with each wal 
1fa0: 66 72 61 6d 65 2c 20 61 6e 64 20 61 20 68 61 73  frame, and a has
1fb0: 68 2d 74 61 62 6c 65 20 0a 2a 2a 20 74 68 61 74  h-table .** that
1fc0: 20 61 6c 6c 6f 77 73 20 72 65 61 64 65 72 73 20   allows readers 
1fd0: 74 6f 20 71 75 65 72 79 20 61 6e 20 69 6e 64 65  to query an inde
1fe0: 78 20 62 6c 6f 63 6b 20 66 6f 72 20 61 20 73 70  x block for a sp
1ff0: 65 63 69 66 69 63 20 70 61 67 65 20 6e 75 6d 62  ecific page numb
2000: 65 72 2e 0a 2a 2a 20 54 68 65 20 70 61 67 65 2d  er..** The page-
2010: 6d 61 70 70 69 6e 67 20 69 73 20 61 6e 20 61 72  mapping is an ar
2020: 72 61 79 20 6f 66 20 48 41 53 48 54 41 42 4c 45  ray of HASHTABLE
2030: 5f 4e 50 41 47 45 20 28 6f 72 20 48 41 53 48 54  _NPAGE (or HASHT
2040: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 0a 2a  ABLE_NPAGE_ONE.*
2050: 2a 20 66 6f 72 20 74 68 65 20 66 69 72 73 74 20  * for the first 
2060: 69 6e 64 65 78 20 62 6c 6f 63 6b 29 20 33 32 2d  index block) 32-
2070: 62 69 74 20 70 61 67 65 20 6e 75 6d 62 65 72 73  bit page numbers
2080: 2e 20 54 68 65 20 66 69 72 73 74 20 65 6e 74 72  . The first entr
2090: 79 20 69 6e 20 74 68 65 20 0a 2a 2a 20 66 69 72  y in the .** fir
20a0: 73 74 20 69 6e 64 65 78 2d 62 6c 6f 63 6b 20 63  st index-block c
20b0: 6f 6e 74 61 69 6e 73 20 74 68 65 20 64 61 74 61  ontains the data
20c0: 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72  base page number
20d0: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74   corresponding t
20e0: 6f 20 74 68 65 0a 2a 2a 20 66 69 72 73 74 20 66  o the.** first f
20f0: 72 61 6d 65 20 69 6e 20 74 68 65 20 57 41 4c 20  rame in the WAL 
2100: 66 69 6c 65 2e 20 54 68 65 20 66 69 72 73 74 20  file. The first 
2110: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 73 65 63  entry in the sec
2120: 6f 6e 64 20 69 6e 64 65 78 20 62 6c 6f 63 6b 0a  ond index block.
2130: 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 66 69  ** in the WAL fi
2140: 6c 65 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74  le corresponds t
2150: 6f 20 74 68 65 20 28 48 41 53 48 54 41 42 4c 45  o the (HASHTABLE
2160: 5f 4e 50 41 47 45 5f 4f 4e 45 2b 31 29 74 68 20  _NPAGE_ONE+1)th 
2170: 66 72 61 6d 65 20 69 6e 0a 2a 2a 20 74 68 65 20  frame in.** the 
2180: 6c 6f 67 2c 20 61 6e 64 20 73 6f 20 6f 6e 2e 0a  log, and so on..
2190: 2a 2a 0a 2a 2a 20 54 68 65 20 6c 61 73 74 20 69  **.** The last i
21a0: 6e 64 65 78 20 62 6c 6f 63 6b 20 69 6e 20 61 20  ndex block in a 
21b0: 77 61 6c 2d 69 6e 64 65 78 20 75 73 75 61 6c 6c  wal-index usuall
21c0: 79 20 63 6f 6e 74 61 69 6e 73 20 6c 65 73 73 20  y contains less 
21d0: 74 68 61 6e 20 74 68 65 20 66 75 6c 6c 0a 2a 2a  than the full.**
21e0: 20 63 6f 6d 70 6c 65 6d 65 6e 74 20 6f 66 20 48   complement of H
21f0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 28  ASHTABLE_NPAGE (
2200: 6f 72 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  or HASHTABLE_NPA
2210: 47 45 5f 4f 4e 45 29 20 70 61 67 65 2d 6e 75 6d  GE_ONE) page-num
2220: 62 65 72 73 2c 0a 2a 2a 20 64 65 70 65 6e 64 69  bers,.** dependi
2230: 6e 67 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e  ng on the conten
2240: 74 73 20 6f 66 20 74 68 65 20 57 41 4c 20 66 69  ts of the WAL fi
2250: 6c 65 2e 20 54 68 69 73 20 64 6f 65 73 20 6e 6f  le. This does no
2260: 74 20 63 68 61 6e 67 65 20 74 68 65 0a 2a 2a 20  t change the.** 
2270: 61 6c 6c 6f 63 61 74 65 64 20 73 69 7a 65 20 6f  allocated size o
2280: 66 20 74 68 65 20 70 61 67 65 2d 6d 61 70 70 69  f the page-mappi
2290: 6e 67 20 61 72 72 61 79 20 2d 20 74 68 65 20 70  ng array - the p
22a0: 61 67 65 2d 6d 61 70 70 69 6e 67 20 61 72 72 61  age-mapping arra
22b0: 79 20 6d 65 72 65 6c 79 0a 2a 2a 20 63 6f 6e 74  y merely.** cont
22c0: 61 69 6e 73 20 75 6e 75 73 65 64 20 65 6e 74 72  ains unused entr
22d0: 69 65 73 2e 0a 2a 2a 0a 2a 2a 20 45 76 65 6e 20  ies..**.** Even 
22e0: 77 69 74 68 6f 75 74 20 75 73 69 6e 67 20 74 68  without using th
22f0: 65 20 68 61 73 68 20 74 61 62 6c 65 2c 20 74 68  e hash table, th
2300: 65 20 6c 61 73 74 20 66 72 61 6d 65 20 66 6f 72  e last frame for
2310: 20 70 61 67 65 20 50 0a 2a 2a 20 63 61 6e 20 62   page P.** can b
2320: 65 20 66 6f 75 6e 64 20 62 79 20 73 63 61 6e 6e  e found by scann
2330: 69 6e 67 20 74 68 65 20 70 61 67 65 2d 6d 61 70  ing the page-map
2340: 70 69 6e 67 20 73 65 63 74 69 6f 6e 73 20 6f 66  ping sections of
2350: 20 65 61 63 68 20 69 6e 64 65 78 20 62 6c 6f 63   each index bloc
2360: 6b 0a 2a 2a 20 73 74 61 72 74 69 6e 67 20 77 69  k.** starting wi
2370: 74 68 20 74 68 65 20 6c 61 73 74 20 69 6e 64 65  th the last inde
2380: 78 20 62 6c 6f 63 6b 20 61 6e 64 20 6d 6f 76 69  x block and movi
2390: 6e 67 20 74 6f 77 61 72 64 20 74 68 65 20 66 69  ng toward the fi
23a0: 72 73 74 2c 20 61 6e 64 0a 2a 2a 20 77 69 74 68  rst, and.** with
23b0: 69 6e 20 65 61 63 68 20 69 6e 64 65 78 20 62 6c  in each index bl
23c0: 6f 63 6b 2c 20 73 74 61 72 74 69 6e 67 20 61 74  ock, starting at
23d0: 20 74 68 65 20 65 6e 64 20 61 6e 64 20 6d 6f 76   the end and mov
23e0: 69 6e 67 20 74 6f 77 61 72 64 20 74 68 65 0a 2a  ing toward the.*
23f0: 2a 20 62 65 67 69 6e 6e 69 6e 67 2e 20 20 54 68  * beginning.  Th
2400: 65 20 66 69 72 73 74 20 65 6e 74 72 79 20 74 68  e first entry th
2410: 61 74 20 65 71 75 61 6c 73 20 50 20 63 6f 72 72  at equals P corr
2420: 65 73 70 6f 6e 64 73 20 74 6f 20 74 68 65 20 66  esponds to the f
2430: 72 61 6d 65 0a 2a 2a 20 68 6f 6c 64 69 6e 67 20  rame.** holding 
2440: 74 68 65 20 63 6f 6e 74 65 6e 74 20 66 6f 72 20  the content for 
2450: 74 68 61 74 20 70 61 67 65 2e 0a 2a 2a 0a 2a 2a  that page..**.**
2460: 20 54 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   The hash table 
2470: 63 6f 6e 73 69 73 74 73 20 6f 66 20 48 41 53 48  consists of HASH
2480: 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 31 36 2d 62  TABLE_NSLOT 16-b
2490: 69 74 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 65  it unsigned inte
24a0: 67 65 72 73 2e 0a 2a 2a 20 48 41 53 48 54 41 42  gers..** HASHTAB
24b0: 4c 45 5f 4e 53 4c 4f 54 20 3d 20 32 2a 48 41 53  LE_NSLOT = 2*HAS
24c0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 2c 20 61 6e  HTABLE_NPAGE, an
24d0: 64 20 74 68 65 72 65 20 69 73 20 6f 6e 65 20 65  d there is one e
24e0: 6e 74 72 79 20 69 6e 20 74 68 65 0a 2a 2a 20 68  ntry in the.** h
24f0: 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20 65 61  ash table for ea
2500: 63 68 20 70 61 67 65 20 6e 75 6d 62 65 72 20 69  ch page number i
2510: 6e 20 74 68 65 20 6d 61 70 70 69 6e 67 20 73 65  n the mapping se
2520: 63 74 69 6f 6e 2c 20 73 6f 20 74 68 65 20 68 61  ction, so the ha
2530: 73 68 20 0a 2a 2a 20 74 61 62 6c 65 20 69 73 20  sh .** table is 
2540: 6e 65 76 65 72 20 6d 6f 72 65 20 74 68 61 6e 20  never more than 
2550: 68 61 6c 66 20 66 75 6c 6c 2e 20 20 54 68 65 20  half full.  The 
2560: 65 78 70 65 63 74 65 64 20 6e 75 6d 62 65 72 20  expected number 
2570: 6f 66 20 63 6f 6c 6c 69 73 69 6f 6e 73 20 0a 2a  of collisions .*
2580: 2a 20 70 72 69 6f 72 20 74 6f 20 66 69 6e 64 69  * prior to findi
2590: 6e 67 20 61 20 6d 61 74 63 68 20 69 73 20 31 2e  ng a match is 1.
25a0: 20 20 45 61 63 68 20 65 6e 74 72 79 20 6f 66 20    Each entry of 
25b0: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 69  the hash table i
25c0: 73 20 61 6e 0a 2a 2a 20 31 2d 62 61 73 65 64 20  s an.** 1-based 
25d0: 69 6e 64 65 78 20 6f 66 20 61 6e 20 65 6e 74 72  index of an entr
25e0: 79 20 69 6e 20 74 68 65 20 6d 61 70 70 69 6e 67  y in the mapping
25f0: 20 73 65 63 74 69 6f 6e 20 6f 66 20 74 68 65 20   section of the 
2600: 73 61 6d 65 0a 2a 2a 20 69 6e 64 65 78 20 62 6c  same.** index bl
2610: 6f 63 6b 2e 20 20 20 4c 65 74 20 4b 20 62 65 20  ock.   Let K be 
2620: 74 68 65 20 31 2d 62 61 73 65 64 20 69 6e 64 65  the 1-based inde
2630: 78 20 6f 66 20 74 68 65 20 6c 61 72 67 65 73 74  x of the largest
2640: 20 65 6e 74 72 79 20 69 6e 0a 2a 2a 20 74 68 65   entry in.** the
2650: 20 6d 61 70 70 69 6e 67 20 73 65 63 74 69 6f 6e   mapping section
2660: 2e 20 20 28 46 6f 72 20 69 6e 64 65 78 20 62 6c  .  (For index bl
2670: 6f 63 6b 73 20 6f 74 68 65 72 20 74 68 61 6e 20  ocks other than 
2680: 74 68 65 20 6c 61 73 74 2c 20 4b 20 77 69 6c 6c  the last, K will
2690: 0a 2a 2a 20 61 6c 77 61 79 73 20 62 65 20 65 78  .** always be ex
26a0: 61 63 74 6c 79 20 48 41 53 48 54 41 42 4c 45 5f  actly HASHTABLE_
26b0: 4e 50 41 47 45 20 28 34 30 39 36 29 20 61 6e 64  NPAGE (4096) and
26c0: 20 66 6f 72 20 74 68 65 20 6c 61 73 74 20 69 6e   for the last in
26d0: 64 65 78 20 62 6c 6f 63 6b 0a 2a 2a 20 4b 20 77  dex block.** K w
26e0: 69 6c 6c 20 62 65 20 28 6d 78 46 72 61 6d 65 25  ill be (mxFrame%
26f0: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 29  HASHTABLE_NPAGE)
2700: 2e 29 20 20 55 6e 75 73 65 64 20 73 6c 6f 74 73  .)  Unused slots
2710: 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61 62   of the hash tab
2720: 6c 65 0a 2a 2a 20 63 6f 6e 74 61 69 6e 20 61 20  le.** contain a 
2730: 76 61 6c 75 65 20 6f 66 20 30 2e 0a 2a 2a 0a 2a  value of 0..**.*
2740: 2a 20 54 6f 20 6c 6f 6f 6b 20 66 6f 72 20 70 61  * To look for pa
2750: 67 65 20 50 20 69 6e 20 74 68 65 20 68 61 73 68  ge P in the hash
2760: 20 74 61 62 6c 65 2c 20 66 69 72 73 74 20 63 6f   table, first co
2770: 6d 70 75 74 65 20 61 20 68 61 73 68 20 69 4b 65  mpute a hash iKe
2780: 79 20 6f 6e 0a 2a 2a 20 50 20 61 73 20 66 6f 6c  y on.** P as fol
2790: 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  lows:.**.**     
27a0: 20 69 4b 65 79 20 3d 20 28 50 20 2a 20 33 38 33   iKey = (P * 383
27b0: 29 20 25 20 48 41 53 48 54 41 42 4c 45 5f 4e 53  ) % HASHTABLE_NS
27c0: 4c 4f 54 0a 2a 2a 0a 2a 2a 20 54 68 65 6e 20 73  LOT.**.** Then s
27d0: 74 61 72 74 20 73 63 61 6e 6e 69 6e 67 20 65 6e  tart scanning en
27e0: 74 72 69 65 73 20 6f 66 20 74 68 65 20 68 61 73  tries of the has
27f0: 68 20 74 61 62 6c 65 2c 20 73 74 61 72 74 69 6e  h table, startin
2800: 67 20 77 69 74 68 20 69 4b 65 79 0a 2a 2a 20 28  g with iKey.** (
2810: 77 72 61 70 70 69 6e 67 20 61 72 6f 75 6e 64 20  wrapping around 
2820: 74 6f 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67  to the beginning
2830: 20 77 68 65 6e 20 74 68 65 20 65 6e 64 20 6f 66   when the end of
2840: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
2850: 69 73 0a 2a 2a 20 72 65 61 63 68 65 64 29 20 75  is.** reached) u
2860: 6e 74 69 6c 20 61 6e 20 75 6e 75 73 65 64 20 68  ntil an unused h
2870: 61 73 68 20 73 6c 6f 74 20 69 73 20 66 6f 75 6e  ash slot is foun
2880: 64 2e 20 4c 65 74 20 74 68 65 20 66 69 72 73 74  d. Let the first
2890: 20 75 6e 75 73 65 64 20 73 6c 6f 74 0a 2a 2a 20   unused slot.** 
28a0: 62 65 20 61 74 20 69 6e 64 65 78 20 69 55 6e 75  be at index iUnu
28b0: 73 65 64 2e 20 20 28 69 55 6e 75 73 65 64 20 6d  sed.  (iUnused m
28c0: 69 67 68 74 20 62 65 20 6c 65 73 73 20 74 68 61  ight be less tha
28d0: 6e 20 69 4b 65 79 20 69 66 20 74 68 65 72 65 20  n iKey if there 
28e0: 77 61 73 0a 2a 2a 20 77 72 61 70 2d 61 72 6f 75  was.** wrap-arou
28f0: 6e 64 2e 29 20 42 65 63 61 75 73 65 20 74 68 65  nd.) Because the
2900: 20 68 61 73 68 20 74 61 62 6c 65 20 69 73 20 6e   hash table is n
2910: 65 76 65 72 20 6d 6f 72 65 20 74 68 61 6e 20 68  ever more than h
2920: 61 6c 66 20 66 75 6c 6c 2c 0a 2a 2a 20 74 68 65  alf full,.** the
2930: 20 73 65 61 72 63 68 20 69 73 20 67 75 61 72 61   search is guara
2940: 6e 74 65 65 64 20 74 6f 20 65 76 65 6e 74 75 61  nteed to eventua
2950: 6c 6c 79 20 68 69 74 20 61 6e 20 75 6e 75 73 65  lly hit an unuse
2960: 64 20 65 6e 74 72 79 2e 20 20 4c 65 74 20 0a 2a  d entry.  Let .*
2970: 2a 20 69 4d 61 78 20 62 65 20 74 68 65 20 76 61  * iMax be the va
2980: 6c 75 65 20 62 65 74 77 65 65 6e 20 69 4b 65 79  lue between iKey
2990: 20 61 6e 64 20 69 55 6e 75 73 65 64 2c 20 63 6c   and iUnused, cl
29a0: 6f 73 65 73 74 20 74 6f 20 69 55 6e 75 73 65 64  osest to iUnused
29b0: 2c 0a 2a 2a 20 77 68 65 72 65 20 61 48 61 73 68  ,.** where aHash
29c0: 5b 69 4d 61 78 5d 3d 3d 50 2e 20 20 49 66 20 74  [iMax]==P.  If t
29d0: 68 65 72 65 20 69 73 20 6e 6f 20 69 4d 61 78 20  here is no iMax 
29e0: 65 6e 74 72 79 20 28 69 66 20 74 68 65 72 65 20  entry (if there 
29f0: 65 78 69 73 74 73 0a 2a 2a 20 6e 6f 20 68 61 73  exists.** no has
2a00: 68 20 73 6c 6f 74 20 73 75 63 68 20 74 68 61 74  h slot such that
2a10: 20 61 48 61 73 68 5b 69 5d 3d 3d 70 29 20 74 68   aHash[i]==p) th
2a20: 65 6e 20 70 61 67 65 20 50 20 69 73 20 6e 6f 74  en page P is not
2a30: 20 69 6e 20 74 68 65 0a 2a 2a 20 63 75 72 72 65   in the.** curre
2a40: 6e 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 2e 20  nt index block. 
2a50: 20 4f 74 68 65 72 77 69 73 65 20 74 68 65 20 69   Otherwise the i
2a60: 4d 61 78 2d 74 68 20 6d 61 70 70 69 6e 67 20 65  Max-th mapping e
2a70: 6e 74 72 79 20 6f 66 20 74 68 65 0a 2a 2a 20 63  ntry of the.** c
2a80: 75 72 72 65 6e 74 20 69 6e 64 65 78 20 62 6c 6f  urrent index blo
2a90: 63 6b 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74  ck corresponds t
2aa0: 6f 20 74 68 65 20 6c 61 73 74 20 65 6e 74 72 79  o the last entry
2ab0: 20 74 68 61 74 20 72 65 66 65 72 65 6e 63 65 73   that references
2ac0: 20 0a 2a 2a 20 70 61 67 65 20 50 2e 0a 2a 2a 0a   .** page P..**.
2ad0: 2a 2a 20 41 20 68 61 73 68 20 73 65 61 72 63 68  ** A hash search
2ae0: 20 62 65 67 69 6e 73 20 77 69 74 68 20 74 68 65   begins with the
2af0: 20 6c 61 73 74 20 69 6e 64 65 78 20 62 6c 6f 63   last index bloc
2b00: 6b 20 61 6e 64 20 6d 6f 76 65 73 20 74 6f 77 61  k and moves towa
2b10: 72 64 20 74 68 65 0a 2a 2a 20 66 69 72 73 74 20  rd the.** first 
2b20: 69 6e 64 65 78 20 62 6c 6f 63 6b 2c 20 6c 6f 6f  index block, loo
2b30: 6b 69 6e 67 20 66 6f 72 20 65 6e 74 72 69 65 73  king for entries
2b40: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74   corresponding t
2b50: 6f 20 70 61 67 65 20 50 2e 20 20 4f 6e 0a 2a 2a  o page P.  On.**
2b60: 20 61 76 65 72 61 67 65 2c 20 6f 6e 6c 79 20 74   average, only t
2b70: 77 6f 20 6f 72 20 74 68 72 65 65 20 73 6c 6f 74  wo or three slot
2b80: 73 20 69 6e 20 65 61 63 68 20 69 6e 64 65 78 20  s in each index 
2b90: 62 6c 6f 63 6b 20 6e 65 65 64 20 74 6f 20 62 65  block need to be
2ba0: 0a 2a 2a 20 65 78 61 6d 69 6e 65 64 20 69 6e 20  .** examined in 
2bb0: 6f 72 64 65 72 20 74 6f 20 65 69 74 68 65 72 20  order to either 
2bc0: 66 69 6e 64 20 74 68 65 20 6c 61 73 74 20 65 6e  find the last en
2bd0: 74 72 79 20 66 6f 72 20 70 61 67 65 20 50 2c 20  try for page P, 
2be0: 6f 72 20 74 6f 0a 2a 2a 20 65 73 74 61 62 6c 69  or to.** establi
2bf0: 73 68 20 74 68 61 74 20 6e 6f 20 73 75 63 68 20  sh that no such 
2c00: 65 6e 74 72 79 20 65 78 69 73 74 73 20 69 6e 20  entry exists in 
2c10: 74 68 65 20 62 6c 6f 63 6b 2e 20 20 45 61 63 68  the block.  Each
2c20: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 0a 2a 2a 20   index block.** 
2c30: 68 6f 6c 64 73 20 6f 76 65 72 20 34 30 30 30 20  holds over 4000 
2c40: 65 6e 74 72 69 65 73 2e 20 20 53 6f 20 74 77 6f  entries.  So two
2c50: 20 6f 72 20 74 68 72 65 65 20 69 6e 64 65 78 20   or three index 
2c60: 62 6c 6f 63 6b 73 20 61 72 65 20 73 75 66 66 69  blocks are suffi
2c70: 63 69 65 6e 74 0a 2a 2a 20 74 6f 20 63 6f 76 65  cient.** to cove
2c80: 72 20 61 20 74 79 70 69 63 61 6c 20 31 30 20 6d  r a typical 10 m
2c90: 65 67 61 62 79 74 65 20 57 41 4c 20 66 69 6c 65  egabyte WAL file
2ca0: 2c 20 61 73 73 75 6d 69 6e 67 20 31 4b 20 70 61  , assuming 1K pa
2cb0: 67 65 73 2e 20 20 38 20 6f 72 20 31 30 0a 2a 2a  ges.  8 or 10.**
2cc0: 20 63 6f 6d 70 61 72 69 73 6f 6e 73 20 28 6f 6e   comparisons (on
2cd0: 20 61 76 65 72 61 67 65 29 20 73 75 66 66 69 63   average) suffic
2ce0: 65 20 74 6f 20 65 69 74 68 65 72 20 6c 6f 63 61  e to either loca
2cf0: 74 65 20 61 20 66 72 61 6d 65 20 69 6e 20 74 68  te a frame in th
2d00: 65 0a 2a 2a 20 57 41 4c 20 6f 72 20 74 6f 20 65  e.** WAL or to e
2d10: 73 74 61 62 6c 69 73 68 20 74 68 61 74 20 74 68  stablish that th
2d20: 65 20 66 72 61 6d 65 20 64 6f 65 73 20 6e 6f 74  e frame does not
2d30: 20 65 78 69 73 74 20 69 6e 20 74 68 65 20 57 41   exist in the WA
2d40: 4c 2e 20 20 54 68 69 73 0a 2a 2a 20 69 73 20 6d  L.  This.** is m
2d50: 75 63 68 20 66 61 73 74 65 72 20 74 68 61 6e 20  uch faster than 
2d60: 73 63 61 6e 6e 69 6e 67 20 74 68 65 20 65 6e 74  scanning the ent
2d70: 69 72 65 20 31 30 4d 42 20 57 41 4c 2e 0a 2a 2a  ire 10MB WAL..**
2d80: 0a 2a 2a 20 4e 6f 74 65 20 74 68 61 74 20 65 6e  .** Note that en
2d90: 74 72 69 65 73 20 61 72 65 20 61 64 64 65 64 20  tries are added 
2da0: 69 6e 20 6f 72 64 65 72 20 6f 66 20 69 6e 63 72  in order of incr
2db0: 65 61 73 69 6e 67 20 4b 2e 20 20 48 65 6e 63 65  easing K.  Hence
2dc0: 2c 20 6f 6e 65 0a 2a 2a 20 72 65 61 64 65 72 20  , one.** reader 
2dd0: 6d 69 67 68 74 20 62 65 20 75 73 69 6e 67 20 73  might be using s
2de0: 6f 6d 65 20 76 61 6c 75 65 20 4b 30 20 61 6e 64  ome value K0 and
2df0: 20 61 20 73 65 63 6f 6e 64 20 72 65 61 64 65 72   a second reader
2e00: 20 74 68 61 74 20 73 74 61 72 74 65 64 0a 2a 2a   that started.**
2e10: 20 61 74 20 61 20 6c 61 74 65 72 20 74 69 6d 65   at a later time
2e20: 20 28 61 66 74 65 72 20 61 64 64 69 74 69 6f 6e   (after addition
2e30: 61 6c 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 20  al transactions 
2e40: 77 65 72 65 20 61 64 64 65 64 20 74 6f 20 74 68  were added to th
2e50: 65 20 57 41 4c 0a 2a 2a 20 61 6e 64 20 74 6f 20  e WAL.** and to 
2e60: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 29 20 6d  the wal-index) m
2e70: 69 67 68 74 20 62 65 20 75 73 69 6e 67 20 61 20  ight be using a 
2e80: 64 69 66 66 65 72 65 6e 74 20 76 61 6c 75 65 20  different value 
2e90: 4b 31 2c 20 77 68 65 72 65 20 4b 31 3e 4b 30 2e  K1, where K1>K0.
2ea0: 0a 2a 2a 20 42 6f 74 68 20 72 65 61 64 65 72 73  .** Both readers
2eb0: 20 63 61 6e 20 75 73 65 20 74 68 65 20 73 61 6d   can use the sam
2ec0: 65 20 68 61 73 68 20 74 61 62 6c 65 20 61 6e 64  e hash table and
2ed0: 20 6d 61 70 70 69 6e 67 20 73 65 63 74 69 6f 6e   mapping section
2ee0: 20 74 6f 20 67 65 74 0a 2a 2a 20 74 68 65 20 63   to get.** the c
2ef0: 6f 72 72 65 63 74 20 72 65 73 75 6c 74 2e 20 20  orrect result.  
2f00: 54 68 65 72 65 20 6d 61 79 20 62 65 20 65 6e 74  There may be ent
2f10: 72 69 65 73 20 69 6e 20 74 68 65 20 68 61 73 68  ries in the hash
2f20: 20 74 61 62 6c 65 20 77 69 74 68 0a 2a 2a 20 4b   table with.** K
2f30: 3e 4b 30 20 62 75 74 20 74 6f 20 74 68 65 20 66  >K0 but to the f
2f40: 69 72 73 74 20 72 65 61 64 65 72 2c 20 74 68 6f  irst reader, tho
2f50: 73 65 20 65 6e 74 72 69 65 73 20 77 69 6c 6c 20  se entries will 
2f60: 61 70 70 65 61 72 20 74 6f 20 62 65 20 75 6e 75  appear to be unu
2f70: 73 65 64 0a 2a 2a 20 73 6c 6f 74 73 20 69 6e 20  sed.** slots in 
2f80: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 61  the hash table a
2f90: 6e 64 20 73 6f 20 74 68 65 20 66 69 72 73 74 20  nd so the first 
2fa0: 72 65 61 64 65 72 20 77 69 6c 6c 20 67 65 74 20  reader will get 
2fb0: 61 6e 20 61 6e 73 77 65 72 20 61 73 0a 2a 2a 20  an answer as.** 
2fc0: 69 66 20 6e 6f 20 76 61 6c 75 65 73 20 67 72 65  if no values gre
2fd0: 61 74 65 72 20 74 68 61 6e 20 4b 30 20 68 61 64  ater than K0 had
2fe0: 20 65 76 65 72 20 62 65 65 6e 20 69 6e 73 65 72   ever been inser
2ff0: 74 65 64 20 69 6e 74 6f 20 74 68 65 20 68 61 73  ted into the has
3000: 68 20 74 61 62 6c 65 0a 2a 2a 20 69 6e 20 74 68  h table.** in th
3010: 65 20 66 69 72 73 74 20 70 6c 61 63 65 20 2d 20  e first place - 
3020: 77 68 69 63 68 20 69 73 20 77 68 61 74 20 72 65  which is what re
3030: 61 64 65 72 20 6f 6e 65 20 77 61 6e 74 73 2e 20  ader one wants. 
3040: 20 4d 65 61 6e 77 68 69 6c 65 2c 20 74 68 65 0a   Meanwhile, the.
3050: 2a 2a 20 73 65 63 6f 6e 64 20 72 65 61 64 65 72  ** second reader
3060: 20 75 73 69 6e 67 20 4b 31 20 77 69 6c 6c 20 73   using K1 will s
3070: 65 65 20 61 64 64 69 74 69 6f 6e 61 6c 20 76 61  ee additional va
3080: 6c 75 65 73 20 74 68 61 74 20 77 65 72 65 20 69  lues that were i
3090: 6e 73 65 72 74 65 64 0a 2a 2a 20 6c 61 74 65 72  nserted.** later
30a0: 2c 20 77 68 69 63 68 20 69 73 20 65 78 61 63 74  , which is exact
30b0: 6c 79 20 77 68 61 74 20 72 65 61 64 65 72 20 74  ly what reader t
30c0: 77 6f 20 77 61 6e 74 73 2e 20 20 0a 2a 2a 0a 2a  wo wants.  .**.*
30d0: 2a 20 57 68 65 6e 20 61 20 72 6f 6c 6c 62 61 63  * When a rollbac
30e0: 6b 20 6f 63 63 75 72 73 2c 20 74 68 65 20 76 61  k occurs, the va
30f0: 6c 75 65 20 6f 66 20 4b 20 69 73 20 64 65 63 72  lue of K is decr
3100: 65 61 73 65 64 2e 20 48 61 73 68 20 74 61 62 6c  eased. Hash tabl
3110: 65 20 65 6e 74 72 69 65 73 0a 2a 2a 20 74 68 61  e entries.** tha
3120: 74 20 63 6f 72 72 65 73 70 6f 6e 64 20 74 6f 20  t correspond to 
3130: 66 72 61 6d 65 73 20 67 72 65 61 74 65 72 20 74  frames greater t
3140: 68 61 6e 20 74 68 65 20 6e 65 77 20 4b 20 76 61  han the new K va
3150: 6c 75 65 20 61 72 65 20 72 65 6d 6f 76 65 64 0a  lue are removed.
3160: 2a 2a 20 66 72 6f 6d 20 74 68 65 20 68 61 73 68  ** from the hash
3170: 20 74 61 62 6c 65 20 61 74 20 74 68 69 73 20 70   table at this p
3180: 6f 69 6e 74 2e 0a 2a 2f 0a 23 69 66 6e 64 65 66  oint..*/.#ifndef
3190: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 57 41 4c   SQLITE_OMIT_WAL
31a0: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 77 61 6c 2e  ..#include "wal.
31b0: 68 22 0a 0a 2f 2a 0a 2a 2a 20 54 72 61 63 65 20  h"../*.** Trace 
31c0: 6f 75 74 70 75 74 20 6d 61 63 72 6f 73 0a 2a 2f  output macros.*/
31d0: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c  .#if defined(SQL
31e0: 49 54 45 5f 54 45 53 54 29 20 26 26 20 64 65 66  ITE_TEST) && def
31f0: 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42 55  ined(SQLITE_DEBU
3200: 47 29 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  G).int sqlite3Wa
3210: 6c 54 72 61 63 65 20 3d 20 30 3b 0a 23 20 64 65  lTrace = 0;.# de
3220: 66 69 6e 65 20 57 41 4c 54 52 41 43 45 28 58 29  fine WALTRACE(X)
3230: 20 20 69 66 28 73 71 6c 69 74 65 33 57 61 6c 54    if(sqlite3WalT
3240: 72 61 63 65 29 20 73 71 6c 69 74 65 33 44 65 62  race) sqlite3Deb
3250: 75 67 50 72 69 6e 74 66 20 58 0a 23 65 6c 73 65  ugPrintf X.#else
3260: 0a 23 20 64 65 66 69 6e 65 20 57 41 4c 54 52 41  .# define WALTRA
3270: 43 45 28 58 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a  CE(X).#endif../*
3280: 0a 2a 2a 20 57 41 4c 20 6d 6f 64 65 20 64 65 70  .** WAL mode dep
3290: 65 6e 64 73 20 6f 6e 20 61 74 6f 6d 69 63 20 61  ends on atomic a
32a0: 6c 69 67 6e 65 64 20 33 32 2d 62 69 74 20 6c 6f  ligned 32-bit lo
32b0: 61 64 73 20 61 6e 64 20 73 74 6f 72 65 73 20 69  ads and stores i
32c0: 6e 20 61 20 66 65 77 0a 2a 2a 20 70 6c 61 63 65  n a few.** place
32d0: 73 2e 20 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e  s.  The followin
32e0: 67 20 6d 61 63 72 6f 73 20 74 72 79 20 74 6f 20  g macros try to 
32f0: 6d 61 6b 65 20 74 68 69 73 20 65 78 70 6c 69 63  make this explic
3300: 69 74 2e 0a 2a 2f 0a 23 69 66 20 47 43 43 5f 56  it..*/.#if GCC_V
3310: 45 53 52 49 4f 4e 3e 3d 35 30 30 34 30 30 30 0a  ESRION>=5004000.
3320: 23 20 64 65 66 69 6e 65 20 41 74 6f 6d 69 63 4c  # define AtomicL
3330: 6f 61 64 28 50 54 52 29 20 20 20 20 20 20 20 5f  oad(PTR)       _
3340: 5f 61 74 6f 6d 69 63 5f 6c 6f 61 64 5f 6e 28 28  _atomic_load_n((
3350: 50 54 52 29 2c 5f 5f 41 54 4f 4d 49 43 5f 52 45  PTR),__ATOMIC_RE
3360: 4c 41 58 45 44 29 0a 23 20 64 65 66 69 6e 65 20  LAXED).# define 
3370: 41 74 6f 6d 69 63 53 74 6f 72 65 28 50 54 52 2c  AtomicStore(PTR,
3380: 56 41 4c 29 20 20 5f 5f 61 74 6f 6d 69 63 5f 73  VAL)  __atomic_s
3390: 74 6f 72 65 5f 6e 28 28 50 54 52 29 2c 28 56 41  tore_n((PTR),(VA
33a0: 4c 29 2c 5f 5f 41 54 4f 4d 49 43 5f 52 45 4c 41  L),__ATOMIC_RELA
33b0: 58 45 44 29 0a 23 65 6c 73 65 0a 23 20 64 65 66  XED).#else.# def
33c0: 69 6e 65 20 41 74 6f 6d 69 63 4c 6f 61 64 28 50  ine AtomicLoad(P
33d0: 54 52 29 20 20 20 20 20 20 20 28 2a 28 50 54 52  TR)       (*(PTR
33e0: 29 29 0a 23 20 64 65 66 69 6e 65 20 41 74 6f 6d  )).# define Atom
33f0: 69 63 53 74 6f 72 65 28 50 54 52 2c 56 41 4c 29  icStore(PTR,VAL)
3400: 20 20 28 2a 28 50 54 52 29 20 3d 20 28 56 41 4c    (*(PTR) = (VAL
3410: 29 29 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a  )).#endif../*.**
3420: 20 54 68 65 20 6d 61 78 69 6d 75 6d 20 28 61 6e   The maximum (an
3430: 64 20 6f 6e 6c 79 29 20 76 65 72 73 69 6f 6e 73  d only) versions
3440: 20 6f 66 20 74 68 65 20 77 61 6c 20 61 6e 64 20   of the wal and 
3450: 77 61 6c 2d 69 6e 64 65 78 20 66 6f 72 6d 61 74  wal-index format
3460: 73 0a 2a 2a 20 74 68 61 74 20 6d 61 79 20 62 65  s.** that may be
3470: 20 69 6e 74 65 72 70 72 65 74 65 64 20 62 79 20   interpreted by 
3480: 74 68 69 73 20 76 65 72 73 69 6f 6e 20 6f 66 20  this version of 
3490: 53 51 4c 69 74 65 2e 0a 2a 2a 0a 2a 2a 20 49 66  SQLite..**.** If
34a0: 20 61 20 63 6c 69 65 6e 74 20 62 65 67 69 6e 73   a client begins
34b0: 20 72 65 63 6f 76 65 72 69 6e 67 20 61 20 57 41   recovering a WA
34c0: 4c 20 66 69 6c 65 20 61 6e 64 20 66 69 6e 64 73  L file and finds
34d0: 20 74 68 61 74 20 28 61 29 20 74 68 65 20 63 68   that (a) the ch
34e0: 65 63 6b 73 75 6d 0a 2a 2a 20 76 61 6c 75 65 73  ecksum.** values
34f0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 68 65 61 64   in the wal-head
3500: 65 72 20 61 72 65 20 63 6f 72 72 65 63 74 20 61  er are correct a
3510: 6e 64 20 28 62 29 20 74 68 65 20 76 65 72 73 69  nd (b) the versi
3520: 6f 6e 20 66 69 65 6c 64 20 69 73 20 6e 6f 74 0a  on field is not.
3530: 2a 2a 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49  ** WAL_MAX_VERSI
3540: 4f 4e 2c 20 72 65 63 6f 76 65 72 79 20 66 61 69  ON, recovery fai
3550: 6c 73 20 61 6e 64 20 53 51 4c 69 74 65 20 72 65  ls and SQLite re
3560: 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 43 41 4e  turns SQLITE_CAN
3570: 54 4f 50 45 4e 2e 0a 2a 2a 0a 2a 2a 20 53 69 6d  TOPEN..**.** Sim
3580: 69 6c 61 72 6c 79 2c 20 69 66 20 61 20 63 6c 69  ilarly, if a cli
3590: 65 6e 74 20 73 75 63 63 65 73 73 66 75 6c 6c 79  ent successfully
35a0: 20 72 65 61 64 73 20 61 20 77 61 6c 2d 69 6e 64   reads a wal-ind
35b0: 65 78 20 68 65 61 64 65 72 20 28 69 2e 65 2e 20  ex header (i.e. 
35c0: 74 68 65 20 0a 2a 2a 20 63 68 65 63 6b 73 75 6d  the .** checksum
35d0: 20 74 65 73 74 20 69 73 20 73 75 63 63 65 73 73   test is success
35e0: 66 75 6c 29 20 61 6e 64 20 66 69 6e 64 73 20 74  ful) and finds t
35f0: 68 61 74 20 74 68 65 20 76 65 72 73 69 6f 6e 20  hat the version 
3600: 66 69 65 6c 64 20 69 73 20 6e 6f 74 0a 2a 2a 20  field is not.** 
3610: 57 41 4c 49 4e 44 45 58 5f 4d 41 58 5f 56 45 52  WALINDEX_MAX_VER
3620: 53 49 4f 4e 2c 20 74 68 65 6e 20 6e 6f 20 72 65  SION, then no re
3630: 61 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e 20 69  ad-transaction i
3640: 73 20 6f 70 65 6e 65 64 20 61 6e 64 20 53 51 4c  s opened and SQL
3650: 69 74 65 0a 2a 2a 20 72 65 74 75 72 6e 73 20 53  ite.** returns S
3660: 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2e 0a  QLITE_CANTOPEN..
3670: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 4d  */.#define WAL_M
3680: 41 58 5f 56 45 52 53 49 4f 4e 20 20 20 20 20 20  AX_VERSION      
3690: 33 30 30 37 30 30 30 0a 23 64 65 66 69 6e 65 20  3007000.#define 
36a0: 57 41 4c 49 4e 44 45 58 5f 4d 41 58 5f 56 45 52  WALINDEX_MAX_VER
36b0: 53 49 4f 4e 20 33 30 30 37 30 30 30 0a 0a 2f 2a  SION 3007000../*
36c0: 0a 2a 2a 20 49 6e 64 65 78 20 6e 75 6d 62 65 72  .** Index number
36d0: 73 20 66 6f 72 20 76 61 72 69 6f 75 73 20 6c 6f  s for various lo
36e0: 63 6b 69 6e 67 20 62 79 74 65 73 2e 20 20 20 57  cking bytes.   W
36f0: 41 4c 5f 4e 52 45 41 44 45 52 20 69 73 20 74 68  AL_NREADER is th
3700: 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 61  e number.** of a
3710: 76 61 69 6c 61 62 6c 65 20 72 65 61 64 65 72 20  vailable reader 
3720: 6c 6f 63 6b 73 20 61 6e 64 20 73 68 6f 75 6c 64  locks and should
3730: 20 62 65 20 61 74 20 6c 65 61 73 74 20 33 2e 20   be at least 3. 
3740: 20 54 68 65 20 64 65 66 61 75 6c 74 0a 2a 2a 20   The default.** 
3750: 69 73 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c  is SQLITE_SHM_NL
3760: 4f 43 4b 3d 3d 38 20 61 6e 64 20 20 57 41 4c 5f  OCK==8 and  WAL_
3770: 4e 52 45 41 44 45 52 3d 3d 35 2e 0a 2a 2a 0a 2a  NREADER==5..**.*
3780: 2a 20 54 65 63 68 6e 69 63 61 6c 6c 79 2c 20 74  * Technically, t
3790: 68 65 20 76 61 72 69 6f 75 73 20 56 46 53 65 73  he various VFSes
37a0: 20 61 72 65 20 66 72 65 65 20 74 6f 20 69 6d 70   are free to imp
37b0: 6c 65 6d 65 6e 74 20 74 68 65 73 65 20 6c 6f 63  lement these loc
37c0: 6b 73 20 68 6f 77 65 76 65 72 0a 2a 2a 20 74 68  ks however.** th
37d0: 65 79 20 73 65 65 20 66 69 74 2e 20 20 48 6f 77  ey see fit.  How
37e0: 65 76 65 72 2c 20 63 6f 6d 70 61 74 69 62 69 6c  ever, compatibil
37f0: 69 74 79 20 69 73 20 65 6e 63 6f 75 72 61 67 65  ity is encourage
3800: 64 20 73 6f 20 74 68 61 74 20 56 46 53 65 73 20  d so that VFSes 
3810: 63 61 6e 0a 2a 2a 20 69 6e 74 65 72 6f 70 65 72  can.** interoper
3820: 61 74 65 2e 20 20 54 68 65 20 73 74 61 6e 64 61  ate.  The standa
3830: 72 64 20 69 6d 70 6c 65 6d 65 6e 74 69 6f 6e 20  rd implemention 
3840: 75 73 65 64 20 6f 6e 20 62 6f 74 68 20 75 6e 69  used on both uni
3850: 78 20 61 6e 64 20 77 69 6e 64 6f 77 73 0a 2a 2a  x and windows.**
3860: 20 69 73 20 66 6f 72 20 74 68 65 20 69 6e 64 65   is for the inde
3870: 78 20 6e 75 6d 62 65 72 20 74 6f 20 69 6e 64 69  x number to indi
3880: 63 61 74 65 20 61 20 62 79 74 65 20 6f 66 66 73  cate a byte offs
3890: 65 74 20 69 6e 74 6f 20 74 68 65 0a 2a 2a 20 57  et into the.** W
38a0: 61 6c 43 6b 70 74 49 6e 66 6f 2e 61 4c 6f 63 6b  alCkptInfo.aLock
38b0: 5b 5d 20 61 72 72 61 79 20 69 6e 20 74 68 65 20  [] array in the 
38c0: 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
38d0: 2e 20 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64  .  In other word
38e0: 73 2c 20 61 6c 6c 0a 2a 2a 20 6c 6f 63 6b 73 20  s, all.** locks 
38f0: 61 72 65 20 6f 6e 20 74 68 65 20 73 68 6d 20 66  are on the shm f
3900: 69 6c 65 2e 20 20 54 68 65 20 57 41 4c 49 4e 44  ile.  The WALIND
3910: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 63  EX_LOCK_OFFSET c
3920: 6f 6e 73 74 61 6e 74 20 28 77 68 69 63 68 0a 2a  onstant (which.*
3930: 2a 20 73 68 6f 75 6c 64 20 62 65 20 31 32 30 29  * should be 120)
3940: 20 69 73 20 74 68 65 20 6c 6f 63 61 74 69 6f 6e   is the location
3950: 20 69 6e 20 74 68 65 20 73 68 6d 20 66 69 6c 65   in the shm file
3960: 20 66 6f 72 20 74 68 65 20 66 69 72 73 74 20 6c   for the first l
3970: 6f 63 6b 69 6e 67 0a 2a 2a 20 62 79 74 65 2e 0a  ocking.** byte..
3980: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 57  */.#define WAL_W
3990: 52 49 54 45 5f 4c 4f 43 4b 20 20 20 20 20 20 20  RITE_LOCK       
39a0: 20 20 30 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f    0.#define WAL_
39b0: 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 20 20  ALL_BUT_WRITE   
39c0: 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41 4c     1.#define WAL
39d0: 5f 43 4b 50 54 5f 4c 4f 43 4b 20 20 20 20 20 20  _CKPT_LOCK      
39e0: 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41      1.#define WA
39f0: 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20 20  L_RECOVER_LOCK  
3a00: 20 20 20 20 20 32 0a 23 64 65 66 69 6e 65 20 57       2.#define W
3a10: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 49 29 20  AL_READ_LOCK(I) 
3a20: 20 20 20 20 20 20 28 33 2b 28 49 29 29 0a 23 64        (3+(I)).#d
3a30: 65 66 69 6e 65 20 57 41 4c 5f 4e 52 45 41 44 45  efine WAL_NREADE
3a40: 52 20 20 20 20 20 20 20 20 20 20 20 20 28 53 51  R            (SQ
3a50: 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 2d 33  LITE_SHM_NLOCK-3
3a60: 29 0a 0a 0a 2f 2a 20 4f 62 6a 65 63 74 20 64 65  ).../* Object de
3a70: 63 6c 61 72 61 74 69 6f 6e 73 20 2a 2f 0a 74 79  clarations */.ty
3a80: 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61 6c  pedef struct Wal
3a90: 49 6e 64 65 78 48 64 72 20 57 61 6c 49 6e 64 65  IndexHdr WalInde
3aa0: 78 48 64 72 3b 0a 74 79 70 65 64 65 66 20 73 74  xHdr;.typedef st
3ab0: 72 75 63 74 20 57 61 6c 49 74 65 72 61 74 6f 72  ruct WalIterator
3ac0: 20 57 61 6c 49 74 65 72 61 74 6f 72 3b 0a 74 79   WalIterator;.ty
3ad0: 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61 6c  pedef struct Wal
3ae0: 43 6b 70 74 49 6e 66 6f 20 57 61 6c 43 6b 70 74  CkptInfo WalCkpt
3af0: 49 6e 66 6f 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68  Info;.../*.** Th
3b00: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65  e following obje
3b10: 63 74 20 68 6f 6c 64 73 20 61 20 63 6f 70 79 20  ct holds a copy 
3b20: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
3b30: 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74 2e   header content.
3b40: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63 74 75 61  .**.** The actua
3b50: 6c 20 68 65 61 64 65 72 20 69 6e 20 74 68 65 20  l header in the 
3b60: 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69 73  wal-index consis
3b70: 74 73 20 6f 66 20 74 77 6f 20 63 6f 70 69 65 73  ts of two copies
3b80: 20 6f 66 20 74 68 69 73 0a 2a 2a 20 6f 62 6a 65   of this.** obje
3b90: 63 74 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 6f  ct followed by o
3ba0: 6e 65 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74  ne instance of t
3bb0: 68 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 6f  he WalCkptInfo o
3bc0: 62 6a 65 63 74 2e 0a 2a 2a 20 46 6f 72 20 61 6c  bject..** For al
3bd0: 6c 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 53 51  l versions of SQ
3be0: 4c 69 74 65 20 74 68 72 6f 75 67 68 20 33 2e 31  Lite through 3.1
3bf0: 30 2e 30 20 61 6e 64 20 70 72 6f 62 61 62 6c 79  0.0 and probably
3c00: 20 62 65 79 6f 6e 64 2c 0a 2a 2a 20 74 68 65 20   beyond,.** the 
3c10: 6c 6f 63 6b 69 6e 67 20 62 79 74 65 73 20 28 57  locking bytes (W
3c20: 61 6c 43 6b 70 74 49 6e 66 6f 2e 61 4c 6f 63 6b  alCkptInfo.aLock
3c30: 29 20 73 74 61 72 74 20 61 74 20 6f 66 66 73 65  ) start at offse
3c40: 74 20 31 32 30 20 61 6e 64 0a 2a 2a 20 74 68 65  t 120 and.** the
3c50: 20 74 6f 74 61 6c 20 68 65 61 64 65 72 20 73 69   total header si
3c60: 7a 65 20 69 73 20 31 33 36 20 62 79 74 65 73 2e  ze is 136 bytes.
3c70: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 7a 50 61 67  .**.** The szPag
3c80: 65 20 76 61 6c 75 65 20 63 61 6e 20 62 65 20 61  e value can be a
3c90: 6e 79 20 70 6f 77 65 72 20 6f 66 20 32 20 62 65  ny power of 2 be
3ca0: 74 77 65 65 6e 20 35 31 32 20 61 6e 64 20 33 32  tween 512 and 32
3cb0: 37 36 38 2c 20 69 6e 63 6c 75 73 69 76 65 2e 0a  768, inclusive..
3cc0: 2a 2a 20 4f 72 20 69 74 20 63 61 6e 20 62 65 20  ** Or it can be 
3cd0: 31 20 74 6f 20 72 65 70 72 65 73 65 6e 74 20 61  1 to represent a
3ce0: 20 36 35 35 33 36 2d 62 79 74 65 20 70 61 67 65   65536-byte page
3cf0: 2e 20 20 54 68 65 20 6c 61 74 74 65 72 20 63 61  .  The latter ca
3d00: 73 65 20 77 61 73 0a 2a 2a 20 61 64 64 65 64 20  se was.** added 
3d10: 69 6e 20 33 2e 37 2e 31 20 77 68 65 6e 20 73 75  in 3.7.1 when su
3d20: 70 70 6f 72 74 20 66 6f 72 20 36 34 4b 20 70 61  pport for 64K pa
3d30: 67 65 73 20 77 61 73 20 61 64 64 65 64 2e 20 20  ges was added.  
3d40: 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61 6c 49 6e  .*/.struct WalIn
3d50: 64 65 78 48 64 72 20 7b 0a 20 20 75 33 32 20 69  dexHdr {.  u32 i
3d60: 56 65 72 73 69 6f 6e 3b 20 20 20 20 20 20 20 20  Version;        
3d70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61             /* Wa
3d80: 6c 2d 69 6e 64 65 78 20 76 65 72 73 69 6f 6e 20  l-index version 
3d90: 2a 2f 0a 20 20 75 33 32 20 75 6e 75 73 65 64 3b  */.  u32 unused;
3da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3db0: 20 20 20 20 20 2f 2a 20 55 6e 75 73 65 64 20 28       /* Unused (
3dc0: 70 61 64 64 69 6e 67 29 20 66 69 65 6c 64 20 2a  padding) field *
3dd0: 2f 0a 20 20 75 33 32 20 69 43 68 61 6e 67 65 3b  /.  u32 iChange;
3de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3df0: 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20 69      /* Counter i
3e00: 6e 63 72 65 6d 65 6e 74 65 64 20 65 61 63 68 20  ncremented each 
3e10: 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20  transaction */. 
3e20: 20 75 38 20 69 73 49 6e 69 74 3b 20 20 20 20 20   u8 isInit;     
3e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3e40: 20 2f 2a 20 31 20 77 68 65 6e 20 69 6e 69 74 69   /* 1 when initi
3e50: 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 75 38 20 62  alized */.  u8 b
3e60: 69 67 45 6e 64 43 6b 73 75 6d 3b 20 20 20 20 20  igEndCksum;     
3e70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
3e80: 72 75 65 20 69 66 20 63 68 65 63 6b 73 75 6d 73  rue if checksums
3e90: 20 69 6e 20 57 41 4c 20 61 72 65 20 62 69 67 2d   in WAL are big-
3ea0: 65 6e 64 69 61 6e 20 2a 2f 0a 20 20 75 31 36 20  endian */.  u16 
3eb0: 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20  szPage;         
3ec0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
3ed0: 61 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a  atabase page siz
3ee0: 65 20 69 6e 20 62 79 74 65 73 2e 20 31 3d 3d 36  e in bytes. 1==6
3ef0: 34 4b 20 2a 2f 0a 20 20 75 33 32 20 6d 78 46 72  4K */.  u32 mxFr
3f00: 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ame;            
3f10: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78          /* Index
3f20: 20 6f 66 20 6c 61 73 74 20 76 61 6c 69 64 20 66   of last valid f
3f30: 72 61 6d 65 20 69 6e 20 74 68 65 20 57 41 4c 20  rame in the WAL 
3f40: 2a 2f 0a 20 20 75 33 32 20 6e 50 61 67 65 3b 20  */.  u32 nPage; 
3f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3f60: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
3f70: 64 61 74 61 62 61 73 65 20 69 6e 20 70 61 67 65  database in page
3f80: 73 20 2a 2f 0a 20 20 75 33 32 20 61 46 72 61 6d  s */.  u32 aFram
3f90: 65 43 6b 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20  eCksum[2];      
3fa0: 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 73         /* Checks
3fb0: 75 6d 20 6f 66 20 6c 61 73 74 20 66 72 61 6d 65  um of last frame
3fc0: 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20 75 33 32   in log */.  u32
3fd0: 20 61 53 61 6c 74 5b 32 5d 3b 20 20 20 20 20 20   aSalt[2];      
3fe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3ff0: 54 77 6f 20 73 61 6c 74 20 76 61 6c 75 65 73 20  Two salt values 
4000: 63 6f 70 69 65 64 20 66 72 6f 6d 20 57 41 4c 20  copied from WAL 
4010: 68 65 61 64 65 72 20 2a 2f 0a 20 20 75 33 32 20  header */.  u32 
4020: 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20  aCksum[2];      
4030: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
4040: 68 65 63 6b 73 75 6d 20 6f 76 65 72 20 61 6c 6c  hecksum over all
4050: 20 70 72 69 6f 72 20 66 69 65 6c 64 73 20 2a 2f   prior fields */
4060: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 63 6f 70  .};../*.** A cop
4070: 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  y of the followi
4080: 6e 67 20 6f 62 6a 65 63 74 20 6f 63 63 75 72 73  ng object occurs
4090: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
40a0: 78 20 69 6d 6d 65 64 69 61 74 65 6c 79 0a 2a 2a  x immediately.**
40b0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 20 73   following the s
40c0: 65 63 6f 6e 64 20 63 6f 70 79 20 6f 66 20 74 68  econd copy of th
40d0: 65 20 57 61 6c 49 6e 64 65 78 48 64 72 2e 20 20  e WalIndexHdr.  
40e0: 54 68 69 73 20 6f 62 6a 65 63 74 20 73 74 6f 72  This object stor
40f0: 65 73 0a 2a 2a 20 69 6e 66 6f 72 6d 61 74 69 6f  es.** informatio
4100: 6e 20 75 73 65 64 20 62 79 20 63 68 65 63 6b 70  n used by checkp
4110: 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20 6e 42 61 63  oint..**.** nBac
4120: 6b 66 69 6c 6c 20 69 73 20 74 68 65 20 6e 75 6d  kfill is the num
4130: 62 65 72 20 6f 66 20 66 72 61 6d 65 73 20 69 6e  ber of frames in
4140: 20 74 68 65 20 57 41 4c 20 74 68 61 74 20 68 61   the WAL that ha
4150: 76 65 20 62 65 65 6e 20 77 72 69 74 74 65 6e 0a  ve been written.
4160: 2a 2a 20 62 61 63 6b 20 69 6e 74 6f 20 74 68 65  ** back into the
4170: 20 64 61 74 61 62 61 73 65 2e 20 28 57 65 20 63   database. (We c
4180: 61 6c 6c 20 74 68 65 20 61 63 74 20 6f 66 20 6d  all the act of m
4190: 6f 76 69 6e 67 20 63 6f 6e 74 65 6e 74 20 66 72  oving content fr
41a0: 6f 6d 20 57 41 4c 20 74 6f 0a 2a 2a 20 64 61 74  om WAL to.** dat
41b0: 61 62 61 73 65 20 22 62 61 63 6b 66 69 6c 6c 69  abase "backfilli
41c0: 6e 67 22 2e 29 20 20 54 68 65 20 6e 42 61 63 6b  ng".)  The nBack
41d0: 66 69 6c 6c 20 6e 75 6d 62 65 72 20 69 73 20 6e  fill number is n
41e0: 65 76 65 72 20 67 72 65 61 74 65 72 20 74 68 61  ever greater tha
41f0: 6e 0a 2a 2a 20 57 61 6c 49 6e 64 65 78 48 64 72  n.** WalIndexHdr
4200: 2e 6d 78 46 72 61 6d 65 2e 20 20 6e 42 61 63 6b  .mxFrame.  nBack
4210: 66 69 6c 6c 20 63 61 6e 20 6f 6e 6c 79 20 62 65  fill can only be
4220: 20 69 6e 63 72 65 61 73 65 64 20 62 79 20 74 68   increased by th
4230: 72 65 61 64 73 0a 2a 2a 20 68 6f 6c 64 69 6e 67  reads.** holding
4240: 20 74 68 65 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f   the WAL_CKPT_LO
4250: 43 4b 20 6c 6f 63 6b 20 28 77 68 69 63 68 20 69  CK lock (which i
4260: 6e 63 6c 75 64 65 73 20 61 20 72 65 63 6f 76 65  ncludes a recove
4270: 72 79 20 74 68 72 65 61 64 29 2e 0a 2a 2a 20 48  ry thread)..** H
4280: 6f 77 65 76 65 72 2c 20 61 20 57 41 4c 5f 57 52  owever, a WAL_WR
4290: 49 54 45 5f 4c 4f 43 4b 20 74 68 72 65 61 64 20  ITE_LOCK thread 
42a0: 63 61 6e 20 6d 6f 76 65 20 74 68 65 20 76 61 6c  can move the val
42b0: 75 65 20 6f 66 20 6e 42 61 63 6b 66 69 6c 6c 20  ue of nBackfill 
42c0: 66 72 6f 6d 0a 2a 2a 20 6d 78 46 72 61 6d 65 20  from.** mxFrame 
42d0: 62 61 63 6b 20 74 6f 20 7a 65 72 6f 20 77 68 65  back to zero whe
42e0: 6e 20 74 68 65 20 57 41 4c 20 69 73 20 72 65 73  n the WAL is res
42f0: 65 74 2e 0a 2a 2a 0a 2a 2a 20 6e 42 61 63 6b 66  et..**.** nBackf
4300: 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 69 73 20  illAttempted is 
4310: 74 68 65 20 6c 61 72 67 65 73 74 20 76 61 6c 75  the largest valu
4320: 65 20 6f 66 20 6e 42 61 63 6b 66 69 6c 6c 20 74  e of nBackfill t
4330: 68 61 74 20 61 20 63 68 65 63 6b 70 6f 69 6e 74  hat a checkpoint
4340: 0a 2a 2a 20 68 61 73 20 61 74 74 65 6d 70 74 65  .** has attempte
4350: 64 20 74 6f 20 61 63 68 69 65 76 65 2e 20 20 4e  d to achieve.  N
4360: 6f 72 6d 61 6c 6c 79 20 6e 42 61 63 6b 66 69 6c  ormally nBackfil
4370: 6c 3d 3d 6e 42 61 63 6b 66 69 6c 6c 41 74 65 6d  l==nBackfillAtem
4380: 70 74 65 64 2c 20 68 6f 77 65 76 65 72 0a 2a 2a  pted, however.**
4390: 20 74 68 65 20 6e 42 61 63 6b 66 69 6c 6c 41 74   the nBackfillAt
43a0: 74 65 6d 70 74 65 64 20 69 73 20 73 65 74 20 62  tempted is set b
43b0: 65 66 6f 72 65 20 61 6e 79 20 62 61 63 6b 66 69  efore any backfi
43c0: 6c 6c 69 6e 67 20 69 73 20 64 6f 6e 65 20 61 6e  lling is done an
43d0: 64 20 74 68 65 0a 2a 2a 20 6e 42 61 63 6b 66 69  d the.** nBackfi
43e0: 6c 6c 20 69 73 20 6f 6e 6c 79 20 73 65 74 20 61  ll is only set a
43f0: 66 74 65 72 20 61 6c 6c 20 62 61 63 6b 66 69 6c  fter all backfil
4400: 6c 69 6e 67 20 63 6f 6d 70 6c 65 74 65 73 2e 20  ling completes. 
4410: 20 53 6f 20 69 66 20 61 20 63 68 65 63 6b 70 6f   So if a checkpo
4420: 69 6e 74 0a 2a 2a 20 63 72 61 73 68 65 73 2c 20  int.** crashes, 
4430: 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74  nBackfillAttempt
4440: 65 64 20 6d 69 67 68 74 20 62 65 20 6c 61 72 67  ed might be larg
4450: 65 72 20 74 68 61 6e 20 6e 42 61 63 6b 66 69 6c  er than nBackfil
4460: 6c 2e 20 20 54 68 65 0a 2a 2a 20 57 61 6c 49 6e  l.  The.** WalIn
4470: 64 65 78 48 64 72 2e 6d 78 46 72 61 6d 65 20 6d  dexHdr.mxFrame m
4480: 75 73 74 20 6e 65 76 65 72 20 62 65 20 6c 65 73  ust never be les
4490: 73 20 74 68 61 6e 20 6e 42 61 63 6b 66 69 6c 6c  s than nBackfill
44a0: 41 74 74 65 6d 70 74 65 64 2e 0a 2a 2a 0a 2a 2a  Attempted..**.**
44b0: 20 54 68 65 20 61 4c 6f 63 6b 5b 5d 20 66 69 65   The aLock[] fie
44c0: 6c 64 20 69 73 20 61 20 73 65 74 20 6f 66 20 62  ld is a set of b
44d0: 79 74 65 73 20 75 73 65 64 20 66 6f 72 20 6c 6f  ytes used for lo
44e0: 63 6b 69 6e 67 2e 20 20 54 68 65 73 65 20 62 79  cking.  These by
44f0: 74 65 73 20 73 68 6f 75 6c 64 0a 2a 2a 20 6e 65  tes should.** ne
4500: 76 65 72 20 62 65 20 72 65 61 64 20 6f 72 20 77  ver be read or w
4510: 72 69 74 74 65 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68  ritten..**.** Th
4520: 65 72 65 20 69 73 20 6f 6e 65 20 65 6e 74 72 79  ere is one entry
4530: 20 69 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20   in aReadMark[] 
4540: 66 6f 72 20 65 61 63 68 20 72 65 61 64 65 72 20  for each reader 
4550: 6c 6f 63 6b 2e 20 20 49 66 20 61 20 72 65 61 64  lock.  If a read
4560: 65 72 0a 2a 2a 20 68 6f 6c 64 73 20 72 65 61 64  er.** holds read
4570: 2d 6c 6f 63 6b 20 4b 2c 20 74 68 65 6e 20 74 68  -lock K, then th
4580: 65 20 76 61 6c 75 65 20 69 6e 20 61 52 65 61 64  e value in aRead
4590: 4d 61 72 6b 5b 4b 5d 20 69 73 20 6e 6f 20 67 72  Mark[K] is no gr
45a0: 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 74 68  eater than.** th
45b0: 65 20 6d 78 46 72 61 6d 65 20 66 6f 72 20 74 68  e mxFrame for th
45c0: 61 74 20 72 65 61 64 65 72 2e 20 20 54 68 65 20  at reader.  The 
45d0: 76 61 6c 75 65 20 52 45 41 44 4d 41 52 4b 5f 4e  value READMARK_N
45e0: 4f 54 5f 55 53 45 44 20 28 30 78 66 66 66 66 66  OT_USED (0xfffff
45f0: 66 66 66 29 0a 2a 2a 20 66 6f 72 20 61 6e 79 20  fff).** for any 
4600: 61 52 65 61 64 4d 61 72 6b 5b 5d 20 6d 65 61 6e  aReadMark[] mean
4610: 73 20 74 68 61 74 20 65 6e 74 72 79 20 69 73 20  s that entry is 
4620: 75 6e 75 73 65 64 2e 20 20 61 52 65 61 64 4d 61  unused.  aReadMa
4630: 72 6b 5b 30 5d 20 69 73 20 0a 2a 2a 20 61 20 73  rk[0] is .** a s
4640: 70 65 63 69 61 6c 20 63 61 73 65 3b 20 69 74 73  pecial case; its
4650: 20 76 61 6c 75 65 20 69 73 20 6e 65 76 65 72 20   value is never 
4660: 75 73 65 64 20 61 6e 64 20 69 74 20 65 78 69 73  used and it exis
4670: 74 73 20 61 73 20 61 20 70 6c 61 63 65 2d 68 6f  ts as a place-ho
4680: 6c 64 65 72 0a 2a 2a 20 74 6f 20 61 76 6f 69 64  lder.** to avoid
4690: 20 68 61 76 69 6e 67 20 74 6f 20 6f 66 66 73 65   having to offse
46a0: 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 69 6e  t aReadMark[] in
46b0: 64 65 78 73 20 62 79 20 6f 6e 65 2e 20 20 52 65  dexs by one.  Re
46c0: 61 64 65 72 73 20 68 6f 6c 64 69 6e 67 0a 2a 2a  aders holding.**
46d0: 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
46e0: 29 20 61 6c 77 61 79 73 20 69 67 6e 6f 72 65 20  ) always ignore 
46f0: 74 68 65 20 65 6e 74 69 72 65 20 57 41 4c 20 61  the entire WAL a
4700: 6e 64 20 72 65 61 64 20 61 6c 6c 20 63 6f 6e 74  nd read all cont
4710: 65 6e 74 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20  ent.** directly 
4720: 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
4730: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c  e..**.** The val
4740: 75 65 20 6f 66 20 61 52 65 61 64 4d 61 72 6b 5b  ue of aReadMark[
4750: 4b 5d 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63  K] may only be c
4760: 68 61 6e 67 65 64 20 62 79 20 61 20 74 68 72 65  hanged by a thre
4770: 61 64 20 74 68 61 74 0a 2a 2a 20 69 73 20 68 6f  ad that.** is ho
4780: 6c 64 69 6e 67 20 61 6e 20 65 78 63 6c 75 73 69  lding an exclusi
4790: 76 65 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52  ve lock on WAL_R
47a0: 45 41 44 5f 4c 4f 43 4b 28 4b 29 2e 20 20 54 68  EAD_LOCK(K).  Th
47b0: 75 73 2c 20 74 68 65 20 76 61 6c 75 65 20 6f 66  us, the value of
47c0: 0a 2a 2a 20 61 52 65 61 64 4d 61 72 6b 5b 4b 5d  .** aReadMark[K]
47d0: 20 63 61 6e 6e 6f 74 20 63 68 61 6e 67 65 64 20   cannot changed 
47e0: 77 68 69 6c 65 20 74 68 65 72 65 20 69 73 20 61  while there is a
47f0: 20 72 65 61 64 65 72 20 69 73 20 75 73 69 6e 67   reader is using
4800: 20 74 68 61 74 20 6d 61 72 6b 0a 2a 2a 20 73 69   that mark.** si
4810: 6e 63 65 20 74 68 65 20 72 65 61 64 65 72 20 77  nce the reader w
4820: 69 6c 6c 20 62 65 20 68 6f 6c 64 69 6e 67 20 61  ill be holding a
4830: 20 73 68 61 72 65 64 20 6c 6f 63 6b 20 6f 6e 20   shared lock on 
4840: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 4b 29  WAL_READ_LOCK(K)
4850: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63  ..**.** The chec
4860: 6b 70 6f 69 6e 74 65 72 20 6d 61 79 20 6f 6e 6c  kpointer may onl
4870: 79 20 74 72 61 6e 73 66 65 72 20 66 72 61 6d 65  y transfer frame
4880: 73 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64 61  s from WAL to da
4890: 74 61 62 61 73 65 20 77 68 65 72 65 0a 2a 2a 20  tabase where.** 
48a0: 74 68 65 20 66 72 61 6d 65 20 6e 75 6d 62 65 72  the frame number
48b0: 73 20 61 72 65 20 6c 65 73 73 20 74 68 61 6e 20  s are less than 
48c0: 6f 72 20 65 71 75 61 6c 20 74 6f 20 65 76 65 72  or equal to ever
48d0: 79 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 74 68  y aReadMark[] th
48e0: 61 74 20 69 73 0a 2a 2a 20 69 6e 20 75 73 65 20  at is.** in use 
48f0: 28 74 68 61 74 20 69 73 2c 20 65 76 65 72 79 20  (that is, every 
4900: 61 52 65 61 64 4d 61 72 6b 5b 6a 5d 20 66 6f 72  aReadMark[j] for
4910: 20 77 68 69 63 68 20 74 68 65 72 65 20 69 73 20   which there is 
4920: 61 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a  a corresponding.
4930: 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  ** WAL_READ_LOCK
4940: 28 6a 29 29 2e 20 20 4e 65 77 20 72 65 61 64 65  (j)).  New reade
4950: 72 73 20 28 75 73 75 61 6c 6c 79 29 20 70 69 63  rs (usually) pic
4960: 6b 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b  k the aReadMark[
4970: 5d 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 6c 61  ] with the.** la
4980: 72 67 65 73 74 20 76 61 6c 75 65 20 61 6e 64 20  rgest value and 
4990: 77 69 6c 6c 20 69 6e 63 72 65 61 73 65 20 61 6e  will increase an
49a0: 20 75 6e 75 73 65 64 20 61 52 65 61 64 4d 61 72   unused aReadMar
49b0: 6b 5b 5d 20 74 6f 20 6d 78 46 72 61 6d 65 20 69  k[] to mxFrame i
49c0: 66 20 74 68 65 72 65 0a 2a 2a 20 69 73 20 6e 6f  f there.** is no
49d0: 74 20 61 6c 72 65 61 64 79 20 61 6e 20 61 52 65  t already an aRe
49e0: 61 64 4d 61 72 6b 5b 5d 20 65 71 75 61 6c 20 74  adMark[] equal t
49f0: 6f 20 6d 78 46 72 61 6d 65 2e 20 20 54 68 65 20  o mxFrame.  The 
4a00: 65 78 63 65 70 74 69 6f 6e 20 74 6f 20 74 68 65  exception to the
4a10: 0a 2a 2a 20 70 72 65 76 69 6f 75 73 20 73 65 6e  .** previous sen
4a20: 74 65 6e 63 65 20 69 73 20 77 68 65 6e 20 6e 42  tence is when nB
4a30: 61 63 6b 66 69 6c 6c 20 65 71 75 61 6c 73 20 6d  ackfill equals m
4a40: 78 46 72 61 6d 65 20 28 6d 65 61 6e 69 6e 67 20  xFrame (meaning 
4a50: 74 68 61 74 20 65 76 65 72 79 74 68 69 6e 67 0a  that everything.
4a60: 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 68 61  ** in the WAL ha
4a70: 73 20 62 65 65 6e 20 62 61 63 6b 66 69 6c 6c 65  s been backfille
4a80: 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  d into the datab
4a90: 61 73 65 29 20 74 68 65 6e 20 6e 65 77 20 72 65  ase) then new re
4aa0: 61 64 65 72 73 0a 2a 2a 20 77 69 6c 6c 20 63 68  aders.** will ch
4ab0: 6f 6f 73 65 20 61 52 65 61 64 4d 61 72 6b 5b 30  oose aReadMark[0
4ac0: 5d 20 77 68 69 63 68 20 68 61 73 20 76 61 6c 75  ] which has valu
4ad0: 65 20 30 20 61 6e 64 20 68 65 6e 63 65 20 73 75  e 0 and hence su
4ae0: 63 68 20 72 65 61 64 65 72 20 77 69 6c 6c 0a 2a  ch reader will.*
4af0: 2a 20 67 65 74 20 61 6c 6c 20 74 68 65 69 72 20  * get all their 
4b00: 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72 65  all content dire
4b10: 63 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61  ctly from the da
4b20: 74 61 62 61 73 65 20 66 69 6c 65 20 61 6e 64 20  tabase file and 
4b30: 69 67 6e 6f 72 65 20 0a 2a 2a 20 74 68 65 20 57  ignore .** the W
4b40: 41 4c 2e 0a 2a 2a 0a 2a 2a 20 57 72 69 74 65 72  AL..**.** Writer
4b50: 73 20 6e 6f 72 6d 61 6c 6c 79 20 61 70 70 65 6e  s normally appen
4b60: 64 20 6e 65 77 20 66 72 61 6d 65 73 20 74 6f 20  d new frames to 
4b70: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 57  the end of the W
4b80: 41 4c 2e 20 20 48 6f 77 65 76 65 72 2c 0a 2a 2a  AL.  However,.**
4b90: 20 69 66 20 6e 42 61 63 6b 66 69 6c 6c 20 65 71   if nBackfill eq
4ba0: 75 61 6c 73 20 6d 78 46 72 61 6d 65 20 28 6d 65  uals mxFrame (me
4bb0: 61 6e 69 6e 67 20 74 68 61 74 20 61 6c 6c 20 57  aning that all W
4bc0: 41 4c 20 63 6f 6e 74 65 6e 74 20 68 61 73 20 62  AL content has b
4bd0: 65 65 6e 0a 2a 2a 20 77 72 69 74 74 65 6e 20 62  een.** written b
4be0: 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74  ack into the dat
4bf0: 61 62 61 73 65 29 20 61 6e 64 20 69 66 20 6e 6f  abase) and if no
4c00: 20 72 65 61 64 65 72 73 20 61 72 65 20 75 73 69   readers are usi
4c10: 6e 67 20 74 68 65 20 57 41 4c 0a 2a 2a 20 28 69  ng the WAL.** (i
4c20: 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 69  n other words, i
4c30: 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 57  f there are no W
4c40: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 20  AL_READ_LOCK(i) 
4c50: 77 68 65 72 65 20 69 3e 30 29 20 74 68 65 6e 0a  where i>0) then.
4c60: 2a 2a 20 74 68 65 20 77 72 69 74 65 72 20 77 69  ** the writer wi
4c70: 6c 6c 20 66 69 72 73 74 20 22 72 65 73 65 74 22  ll first "reset"
4c80: 20 74 68 65 20 57 41 4c 20 62 61 63 6b 20 74 6f   the WAL back to
4c90: 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 61   the beginning a
4ca0: 6e 64 20 73 74 61 72 74 0a 2a 2a 20 77 72 69 74  nd start.** writ
4cb0: 69 6e 67 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20  ing new content 
4cc0: 62 65 67 69 6e 6e 69 6e 67 20 61 74 20 66 72 61  beginning at fra
4cd0: 6d 65 20 31 2e 0a 2a 2a 0a 2a 2a 20 57 65 20 61  me 1..**.** We a
4ce0: 73 73 75 6d 65 20 74 68 61 74 20 33 32 2d 62 69  ssume that 32-bi
4cf0: 74 20 6c 6f 61 64 73 20 61 72 65 20 61 74 6f 6d  t loads are atom
4d00: 69 63 20 61 6e 64 20 73 6f 20 6e 6f 20 6c 6f 63  ic and so no loc
4d10: 6b 73 20 61 72 65 20 6e 65 65 64 65 64 20 69 6e  ks are needed in
4d20: 0a 2a 2a 20 6f 72 64 65 72 20 74 6f 20 72 65 61  .** order to rea
4d30: 64 20 66 72 6f 6d 20 61 6e 79 20 61 52 65 61 64  d from any aRead
4d40: 4d 61 72 6b 5b 5d 20 65 6e 74 72 69 65 73 2e 0a  Mark[] entries..
4d50: 2a 2f 0a 73 74 72 75 63 74 20 57 61 6c 43 6b 70  */.struct WalCkp
4d60: 74 49 6e 66 6f 20 7b 0a 20 20 75 33 32 20 6e 42  tInfo {.  u32 nB
4d70: 61 63 6b 66 69 6c 6c 3b 20 20 20 20 20 20 20 20  ackfill;        
4d80: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
4d90: 62 65 72 20 6f 66 20 57 41 4c 20 66 72 61 6d 65  ber of WAL frame
4da0: 73 20 62 61 63 6b 66 69 6c 6c 65 64 20 69 6e 74  s backfilled int
4db0: 6f 20 44 42 20 2a 2f 0a 20 20 75 33 32 20 61 52  o DB */.  u32 aR
4dc0: 65 61 64 4d 61 72 6b 5b 57 41 4c 5f 4e 52 45 41  eadMark[WAL_NREA
4dd0: 44 45 52 5d 3b 20 20 20 20 20 2f 2a 20 52 65 61  DER];     /* Rea
4de0: 64 65 72 20 6d 61 72 6b 73 20 2a 2f 0a 20 20 75  der marks */.  u
4df0: 38 20 61 4c 6f 63 6b 5b 53 51 4c 49 54 45 5f 53  8 aLock[SQLITE_S
4e00: 48 4d 5f 4e 4c 4f 43 4b 5d 3b 20 20 20 20 20 2f  HM_NLOCK];     /
4e10: 2a 20 52 65 73 65 72 76 65 64 20 73 70 61 63 65  * Reserved space
4e20: 20 66 6f 72 20 6c 6f 63 6b 73 20 2a 2f 0a 20 20   for locks */.  
4e30: 75 33 32 20 6e 42 61 63 6b 66 69 6c 6c 41 74 74  u32 nBackfillAtt
4e40: 65 6d 70 74 65 64 3b 20 20 20 20 20 20 20 20 20  empted;         
4e50: 2f 2a 20 57 41 4c 20 66 72 61 6d 65 73 20 70 65  /* WAL frames pe
4e60: 72 68 61 70 73 20 77 72 69 74 74 65 6e 2c 20 6f  rhaps written, o
4e70: 72 20 6d 61 79 62 65 20 6e 6f 74 20 2a 2f 0a 20  r maybe not */. 
4e80: 20 75 33 32 20 6e 6f 74 55 73 65 64 30 3b 20 20   u32 notUsed0;  
4e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4ea0: 20 2f 2a 20 41 76 61 69 6c 61 62 6c 65 20 66 6f   /* Available fo
4eb0: 72 20 66 75 74 75 72 65 20 65 6e 68 61 6e 63 65  r future enhance
4ec0: 6d 65 6e 74 73 20 2a 2f 0a 7d 3b 0a 23 64 65 66  ments */.};.#def
4ed0: 69 6e 65 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54  ine READMARK_NOT
4ee0: 5f 55 53 45 44 20 20 30 78 66 66 66 66 66 66 66  _USED  0xfffffff
4ef0: 66 0a 0a 0a 2f 2a 20 41 20 62 6c 6f 63 6b 20 6f  f.../* A block o
4f00: 66 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f  f WALINDEX_LOCK_
4f10: 52 45 53 45 52 56 45 44 20 62 79 74 65 73 20 62  RESERVED bytes b
4f20: 65 67 69 6e 6e 69 6e 67 20 61 74 0a 2a 2a 20 57  eginning at.** W
4f30: 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46  ALINDEX_LOCK_OFF
4f40: 53 45 54 20 69 73 20 72 65 73 65 72 76 65 64 20  SET is reserved 
4f50: 66 6f 72 20 6c 6f 63 6b 73 2e 20 53 69 6e 63 65  for locks. Since
4f60: 20 73 6f 6d 65 20 73 79 73 74 65 6d 73 0a 2a 2a   some systems.**
4f70: 20 6f 6e 6c 79 20 73 75 70 70 6f 72 74 20 6d 61   only support ma
4f80: 6e 64 61 74 6f 72 79 20 66 69 6c 65 2d 6c 6f 63  ndatory file-loc
4f90: 6b 73 2c 20 77 65 20 64 6f 20 6e 6f 74 20 72 65  ks, we do not re
4fa0: 61 64 20 6f 72 20 77 72 69 74 65 20 64 61 74 61  ad or write data
4fb0: 0a 2a 2a 20 66 72 6f 6d 20 74 68 65 20 72 65 67  .** from the reg
4fc0: 69 6f 6e 20 6f 66 20 74 68 65 20 66 69 6c 65 20  ion of the file 
4fd0: 6f 6e 20 77 68 69 63 68 20 6c 6f 63 6b 73 20 61  on which locks a
4fe0: 72 65 20 61 70 70 6c 69 65 64 2e 0a 2a 2f 0a 23  re applied..*/.#
4ff0: 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58 5f  define WALINDEX_
5000: 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 28 73 69 7a  LOCK_OFFSET (siz
5010: 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29  eof(WalIndexHdr)
5020: 2a 32 2b 6f 66 66 73 65 74 6f 66 28 57 61 6c 43  *2+offsetof(WalC
5030: 6b 70 74 49 6e 66 6f 2c 61 4c 6f 63 6b 29 29 0a  kptInfo,aLock)).
5040: 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58  #define WALINDEX
5050: 5f 48 44 52 5f 53 49 5a 45 20 20 20 20 28 73 69  _HDR_SIZE    (si
5060: 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
5070: 29 2a 32 2b 73 69 7a 65 6f 66 28 57 61 6c 43 6b  )*2+sizeof(WalCk
5080: 70 74 49 6e 66 6f 29 29 0a 0a 2f 2a 20 53 69 7a  ptInfo))../* Siz
5090: 65 20 6f 66 20 68 65 61 64 65 72 20 62 65 66 6f  e of header befo
50a0: 72 65 20 65 61 63 68 20 66 72 61 6d 65 20 69 6e  re each frame in
50b0: 20 77 61 6c 20 2a 2f 0a 23 64 65 66 69 6e 65 20   wal */.#define 
50c0: 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a  WAL_FRAME_HDRSIZ
50d0: 45 20 32 34 0a 0a 2f 2a 20 53 69 7a 65 20 6f 66  E 24../* Size of
50e0: 20 77 72 69 74 65 20 61 68 65 61 64 20 6c 6f 67   write ahead log
50f0: 20 68 65 61 64 65 72 2c 20 69 6e 63 6c 75 64 69   header, includi
5100: 6e 67 20 63 68 65 63 6b 73 75 6d 2e 20 2a 2f 0a  ng checksum. */.
5110: 23 64 65 66 69 6e 65 20 57 41 4c 5f 48 44 52 53  #define WAL_HDRS
5120: 49 5a 45 20 33 32 0a 0a 2f 2a 20 57 41 4c 20 6d  IZE 32../* WAL m
5130: 61 67 69 63 20 76 61 6c 75 65 2e 20 45 69 74 68  agic value. Eith
5140: 65 72 20 74 68 69 73 20 76 61 6c 75 65 2c 20 6f  er this value, o
5150: 72 20 74 68 65 20 73 61 6d 65 20 76 61 6c 75 65  r the same value
5160: 20 77 69 74 68 20 74 68 65 20 6c 65 61 73 74 0a   with the least.
5170: 2a 2a 20 73 69 67 6e 69 66 69 63 61 6e 74 20 62  ** significant b
5180: 69 74 20 61 6c 73 6f 20 73 65 74 20 28 57 41 4c  it also set (WAL
5190: 5f 4d 41 47 49 43 20 7c 20 30 78 30 30 30 30 30  _MAGIC | 0x00000
51a0: 30 30 31 29 20 69 73 20 73 74 6f 72 65 64 20 69  001) is stored i
51b0: 6e 20 33 32 2d 62 69 74 0a 2a 2a 20 62 69 67 2d  n 32-bit.** big-
51c0: 65 6e 64 69 61 6e 20 66 6f 72 6d 61 74 20 69 6e  endian format in
51d0: 20 74 68 65 20 66 69 72 73 74 20 34 20 62 79 74   the first 4 byt
51e0: 65 73 20 6f 66 20 61 20 57 41 4c 20 66 69 6c 65  es of a WAL file
51f0: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 4c  ..**.** If the L
5200: 53 42 20 69 73 20 73 65 74 2c 20 74 68 65 6e 20  SB is set, then 
5210: 74 68 65 20 63 68 65 63 6b 73 75 6d 73 20 66 6f  the checksums fo
5220: 72 20 65 61 63 68 20 66 72 61 6d 65 20 77 69 74  r each frame wit
5230: 68 69 6e 20 74 68 65 20 57 41 4c 0a 2a 2a 20 66  hin the WAL.** f
5240: 69 6c 65 20 61 72 65 20 63 61 6c 63 75 6c 61 74  ile are calculat
5250: 65 64 20 62 79 20 74 72 65 61 74 69 6e 67 20 61  ed by treating a
5260: 6c 6c 20 64 61 74 61 20 61 73 20 61 6e 20 61 72  ll data as an ar
5270: 72 61 79 20 6f 66 20 33 32 2d 62 69 74 20 0a 2a  ray of 32-bit .*
5280: 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 77 6f 72  * big-endian wor
5290: 64 73 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 74  ds. Otherwise, t
52a0: 68 65 79 20 61 72 65 20 63 61 6c 63 75 6c 61 74  hey are calculat
52b0: 65 64 20 62 79 20 69 6e 74 65 72 70 72 65 74 69  ed by interpreti
52c0: 6e 67 20 0a 2a 2a 20 61 6c 6c 20 64 61 74 61 20  ng .** all data 
52d0: 61 73 20 33 32 2d 62 69 74 20 6c 69 74 74 6c 65  as 32-bit little
52e0: 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73 2e 0a 2a  -endian words..*
52f0: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 4d 41  /.#define WAL_MA
5300: 47 49 43 20 30 78 33 37 37 66 30 36 38 32 0a 0a  GIC 0x377f0682..
5310: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
5320: 20 6f 66 66 73 65 74 20 6f 66 20 66 72 61 6d 65   offset of frame
5330: 20 69 46 72 61 6d 65 20 69 6e 20 74 68 65 20 77   iFrame in the w
5340: 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66  rite-ahead log f
5350: 69 6c 65 2c 20 0a 2a 2a 20 61 73 73 75 6d 69 6e  ile, .** assumin
5360: 67 20 61 20 64 61 74 61 62 61 73 65 20 70 61 67  g a database pag
5370: 65 20 73 69 7a 65 20 6f 66 20 73 7a 50 61 67 65  e size of szPage
5380: 20 62 79 74 65 73 2e 20 54 68 65 20 6f 66 66 73   bytes. The offs
5390: 65 74 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69  et returned.** i
53a0: 73 20 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f  s to the start o
53b0: 66 20 74 68 65 20 77 72 69 74 65 2d 61 68 65 61  f the write-ahea
53c0: 64 20 6c 6f 67 20 66 72 61 6d 65 2d 68 65 61 64  d log frame-head
53d0: 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 77  er..*/.#define w
53e0: 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46  alFrameOffset(iF
53f0: 72 61 6d 65 2c 20 73 7a 50 61 67 65 29 20 28 20  rame, szPage) ( 
5400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a                \.
5420: 20 20 57 41 4c 5f 48 44 52 53 49 5a 45 20 2b 20    WAL_HDRSIZE + 
5430: 28 28 69 46 72 61 6d 65 29 2d 31 29 2a 28 69 36  ((iFrame)-1)*(i6
5440: 34 29 28 28 73 7a 50 61 67 65 29 2b 57 41 4c 5f  4)((szPage)+WAL_
5450: 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 29 20 20  FRAME_HDRSIZE)  
5460: 20 20 20 20 20 20 20 5c 0a 29 0a 0a 2f 2a 0a 2a         \.)../*.*
5470: 2a 20 41 6e 20 6f 70 65 6e 20 77 72 69 74 65 2d  * An open write-
5480: 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65 20 69  ahead log file i
5490: 73 20 72 65 70 72 65 73 65 6e 74 65 64 20 62 79  s represented by
54a0: 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   an instance of 
54b0: 74 68 65 0a 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67  the.** following
54c0: 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 72 75   object..*/.stru
54d0: 63 74 20 57 61 6c 20 7b 0a 20 20 73 71 6c 69 74  ct Wal {.  sqlit
54e0: 65 33 5f 76 66 73 20 2a 70 56 66 73 3b 20 20 20  e3_vfs *pVfs;   
54f0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 56 46 53        /* The VFS
5500: 20 75 73 65 64 20 74 6f 20 63 72 65 61 74 65 20   used to create 
5510: 70 44 62 46 64 20 2a 2f 0a 20 20 73 71 6c 69 74  pDbFd */.  sqlit
5520: 65 33 5f 66 69 6c 65 20 2a 70 44 62 46 64 3b 20  e3_file *pDbFd; 
5530: 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 68 61        /* File ha
5540: 6e 64 6c 65 20 66 6f 72 20 74 68 65 20 64 61 74  ndle for the dat
5550: 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20  abase file */.  
5560: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 57  sqlite3_file *pW
5570: 61 6c 46 64 3b 20 20 20 20 20 20 2f 2a 20 46 69  alFd;      /* Fi
5580: 6c 65 20 68 61 6e 64 6c 65 20 66 6f 72 20 57 41  le handle for WA
5590: 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32 20  L file */.  u32 
55a0: 69 43 61 6c 6c 62 61 63 6b 3b 20 20 20 20 20 20  iCallback;      
55b0: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
55c0: 74 6f 20 70 61 73 73 20 74 6f 20 6c 6f 67 20 63  to pass to log c
55d0: 61 6c 6c 62 61 63 6b 20 28 6f 72 20 30 29 20 2a  allback (or 0) *
55e0: 2f 0a 20 20 69 36 34 20 6d 78 57 61 6c 53 69 7a  /.  i64 mxWalSiz
55f0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  e;             /
5600: 2a 20 54 72 75 6e 63 61 74 65 20 57 41 4c 20 74  * Truncate WAL t
5610: 6f 20 74 68 69 73 20 73 69 7a 65 20 75 70 6f 6e  o this size upon
5620: 20 72 65 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20   reset */.  int 
5630: 6e 57 69 44 61 74 61 3b 20 20 20 20 20 20 20 20  nWiData;        
5640: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
5650: 66 20 61 72 72 61 79 20 61 70 57 69 44 61 74 61  f array apWiData
5660: 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 46 69 72 73   */.  int szFirs
5670: 74 42 6c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20  tBlock;         
5680: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 66 69 72 73   /* Size of firs
5690: 74 20 62 6c 6f 63 6b 20 77 72 69 74 74 65 6e 20  t block written 
56a0: 74 6f 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20  to WAL file */. 
56b0: 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a   volatile u32 **
56c0: 61 70 57 69 44 61 74 61 3b 20 20 20 2f 2a 20 50  apWiData;   /* P
56d0: 6f 69 6e 74 65 72 20 74 6f 20 77 61 6c 2d 69 6e  ointer to wal-in
56e0: 64 65 78 20 63 6f 6e 74 65 6e 74 20 69 6e 20 6d  dex content in m
56f0: 65 6d 6f 72 79 20 2a 2f 0a 20 20 75 33 32 20 73  emory */.  u32 s
5700: 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  zPage;          
5710: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
5720: 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20  e page size */. 
5730: 20 69 31 36 20 72 65 61 64 4c 6f 63 6b 3b 20 20   i16 readLock;  
5740: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
5750: 68 69 63 68 20 72 65 61 64 20 6c 6f 63 6b 20 69  hich read lock i
5760: 73 20 62 65 69 6e 67 20 68 65 6c 64 2e 20 20 2d  s being held.  -
5770: 31 20 66 6f 72 20 6e 6f 6e 65 20 2a 2f 0a 20 20  1 for none */.  
5780: 75 38 20 73 79 6e 63 46 6c 61 67 73 3b 20 20 20  u8 syncFlags;   
5790: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c             /* Fl
57a0: 61 67 73 20 74 6f 20 75 73 65 20 74 6f 20 73 79  ags to use to sy
57b0: 6e 63 20 68 65 61 64 65 72 20 77 72 69 74 65 73  nc header writes
57c0: 20 2a 2f 0a 20 20 75 38 20 65 78 63 6c 75 73 69   */.  u8 exclusi
57d0: 76 65 4d 6f 64 65 3b 20 20 20 20 20 20 20 20 20  veMode;         
57e0: 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69 66 20   /* Non-zero if 
57f0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20 69 6e  connection is in
5800: 20 65 78 63 6c 75 73 69 76 65 20 6d 6f 64 65 20   exclusive mode 
5810: 2a 2f 0a 20 20 75 38 20 77 72 69 74 65 4c 6f 63  */.  u8 writeLoc
5820: 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
5830: 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 20 61 20  /* True if in a 
5840: 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f  write transactio
5850: 6e 20 2a 2f 0a 20 20 75 38 20 63 6b 70 74 4c 6f  n */.  u8 ckptLo
5860: 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ck;             
5870: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 68 6f 6c    /* True if hol
5880: 64 69 6e 67 20 61 20 63 68 65 63 6b 70 6f 69 6e  ding a checkpoin
5890: 74 20 6c 6f 63 6b 20 2a 2f 0a 20 20 75 38 20 72  t lock */.  u8 r
58a0: 65 61 64 4f 6e 6c 79 3b 20 20 20 20 20 20 20 20  eadOnly;        
58b0: 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 5f 52 44         /* WAL_RD
58c0: 57 52 2c 20 57 41 4c 5f 52 44 4f 4e 4c 59 2c 20  WR, WAL_RDONLY, 
58d0: 6f 72 20 57 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c  or WAL_SHM_RDONL
58e0: 59 20 2a 2f 0a 20 20 75 38 20 74 72 75 6e 63 61  Y */.  u8 trunca
58f0: 74 65 4f 6e 43 6f 6d 6d 69 74 3b 20 20 20 20 20  teOnCommit;     
5900: 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 74 72 75    /* True to tru
5910: 6e 63 61 74 65 20 57 41 4c 20 66 69 6c 65 20 6f  ncate WAL file o
5920: 6e 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20 75 38  n commit */.  u8
5930: 20 73 79 6e 63 48 65 61 64 65 72 3b 20 20 20 20   syncHeader;    
5940: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 73 79 6e           /* Fsyn
5950: 63 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72  c the WAL header
5960: 20 69 66 20 74 72 75 65 20 2a 2f 0a 20 20 75 38   if true */.  u8
5970: 20 70 61 64 54 6f 53 65 63 74 6f 72 42 6f 75 6e   padToSectorBoun
5980: 64 61 72 79 3b 20 20 20 20 2f 2a 20 50 61 64 20  dary;    /* Pad 
5990: 74 72 61 6e 73 61 63 74 69 6f 6e 73 20 6f 75 74  transactions out
59a0: 20 74 6f 20 74 68 65 20 6e 65 78 74 20 73 65 63   to the next sec
59b0: 74 6f 72 20 2a 2f 0a 20 20 75 38 20 62 53 68 6d  tor */.  u8 bShm
59c0: 55 6e 72 65 6c 69 61 62 6c 65 3b 20 20 20 20 20  Unreliable;     
59d0: 20 20 20 20 2f 2a 20 53 48 4d 20 63 6f 6e 74 65      /* SHM conte
59e0: 6e 74 20 69 73 20 72 65 61 64 2d 6f 6e 6c 79 20  nt is read-only 
59f0: 61 6e 64 20 75 6e 72 65 6c 69 61 62 6c 65 20 2a  and unreliable *
5a00: 2f 0a 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20  /.  WalIndexHdr 
5a10: 68 64 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f  hdr;           /
5a20: 2a 20 57 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  * Wal-index head
5a30: 65 72 20 66 6f 72 20 63 75 72 72 65 6e 74 20 74  er for current t
5a40: 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20  ransaction */.  
5a50: 75 33 32 20 6d 69 6e 46 72 61 6d 65 3b 20 20 20  u32 minFrame;   
5a60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 67             /* Ig
5a70: 6e 6f 72 65 20 77 61 6c 20 66 72 61 6d 65 73 20  nore wal frames 
5a80: 62 65 66 6f 72 65 20 74 68 69 73 20 6f 6e 65 20  before this one 
5a90: 2a 2f 0a 20 20 75 33 32 20 69 52 65 43 6b 73 75  */.  u32 iReCksu
5aa0: 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  m;              
5ab0: 2f 2a 20 4f 6e 20 63 6f 6d 6d 69 74 2c 20 72 65  /* On commit, re
5ac0: 63 61 6c 63 75 6c 61 74 65 20 63 68 65 63 6b 73  calculate checks
5ad0: 75 6d 73 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f  ums from here */
5ae0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
5af0: 57 61 6c 4e 61 6d 65 3b 20 20 20 20 20 20 2f 2a  WalName;      /*
5b00: 20 4e 61 6d 65 20 6f 66 20 57 41 4c 20 66 69 6c   Name of WAL fil
5b10: 65 20 2a 2f 0a 20 20 75 33 32 20 6e 43 6b 70 74  e */.  u32 nCkpt
5b20: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
5b30: 20 20 2f 2a 20 43 68 65 63 6b 70 6f 69 6e 74 20    /* Checkpoint 
5b40: 73 65 71 75 65 6e 63 65 20 63 6f 75 6e 74 65 72  sequence counter
5b50: 20 69 6e 20 74 68 65 20 77 61 6c 2d 68 65 61 64   in the wal-head
5b60: 65 72 20 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c  er */.#ifdef SQL
5b70: 49 54 45 5f 44 45 42 55 47 0a 20 20 75 38 20 6c  ITE_DEBUG.  u8 l
5b80: 6f 63 6b 45 72 72 6f 72 3b 20 20 20 20 20 20 20  ockError;       
5b90: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
5ba0: 66 20 61 20 6c 6f 63 6b 69 6e 67 20 65 72 72 6f  f a locking erro
5bb0: 72 20 68 61 73 20 6f 63 63 75 72 72 65 64 20 2a  r has occurred *
5bc0: 2f 0a 23 65 6e 64 69 66 0a 23 69 66 64 65 66 20  /.#endif.#ifdef 
5bd0: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e  SQLITE_ENABLE_SN
5be0: 41 50 53 48 4f 54 0a 20 20 57 61 6c 49 6e 64 65  APSHOT.  WalInde
5bf0: 78 48 64 72 20 2a 70 53 6e 61 70 73 68 6f 74 3b  xHdr *pSnapshot;
5c00: 20 20 20 20 2f 2a 20 53 74 61 72 74 20 74 72 61      /* Start tra
5c10: 6e 73 61 63 74 69 6f 6e 20 68 65 72 65 20 69 66  nsaction here if
5c20: 20 6e 6f 74 20 4e 55 4c 4c 20 2a 2f 0a 23 65 6e   not NULL */.#en
5c30: 64 69 66 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 43 61  dif.};../*.** Ca
5c40: 6e 64 69 64 61 74 65 20 76 61 6c 75 65 73 20 66  ndidate values f
5c50: 6f 72 20 57 61 6c 2e 65 78 63 6c 75 73 69 76 65  or Wal.exclusive
5c60: 4d 6f 64 65 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  Mode..*/.#define
5c70: 20 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45   WAL_NORMAL_MODE
5c80: 20 20 20 20 20 30 0a 23 64 65 66 69 6e 65 20 57       0.#define W
5c90: 41 4c 5f 45 58 43 4c 55 53 49 56 45 5f 4d 4f 44  AL_EXCLUSIVE_MOD
5ca0: 45 20 20 31 20 20 20 20 20 0a 23 64 65 66 69 6e  E  1     .#defin
5cb0: 65 20 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59  e WAL_HEAPMEMORY
5cc0: 5f 4d 4f 44 45 20 32 0a 0a 2f 2a 0a 2a 2a 20 50  _MODE 2../*.** P
5cd0: 6f 73 73 69 62 6c 65 20 76 61 6c 75 65 73 20 66  ossible values f
5ce0: 6f 72 20 57 41 4c 2e 72 65 61 64 4f 6e 6c 79 0a  or WAL.readOnly.
5cf0: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 52  */.#define WAL_R
5d00: 44 57 52 20 20 20 20 20 20 20 20 30 20 20 20 20  DWR        0    
5d10: 2f 2a 20 4e 6f 72 6d 61 6c 20 72 65 61 64 2f 77  /* Normal read/w
5d20: 72 69 74 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  rite connection 
5d30: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 52  */.#define WAL_R
5d40: 44 4f 4e 4c 59 20 20 20 20 20 20 31 20 20 20 20  DONLY      1    
5d50: 2f 2a 20 54 68 65 20 57 41 4c 20 66 69 6c 65 20  /* The WAL file 
5d60: 69 73 20 72 65 61 64 6f 6e 6c 79 20 2a 2f 0a 23  is readonly */.#
5d70: 64 65 66 69 6e 65 20 57 41 4c 5f 53 48 4d 5f 52  define WAL_SHM_R
5d80: 44 4f 4e 4c 59 20 20 32 20 20 20 20 2f 2a 20 54  DONLY  2    /* T
5d90: 68 65 20 53 48 4d 20 66 69 6c 65 20 69 73 20 72  he SHM file is r
5da0: 65 61 64 6f 6e 6c 79 20 2a 2f 0a 0a 2f 2a 0a 2a  eadonly */../*.*
5db0: 2a 20 45 61 63 68 20 70 61 67 65 20 6f 66 20 74  * Each page of t
5dc0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 6d 61 70  he wal-index map
5dd0: 70 69 6e 67 20 63 6f 6e 74 61 69 6e 73 20 61 20  ping contains a 
5de0: 68 61 73 68 2d 74 61 62 6c 65 20 6d 61 64 65 20  hash-table made 
5df0: 75 70 20 6f 66 0a 2a 2a 20 61 6e 20 61 72 72 61  up of.** an arra
5e00: 79 20 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e  y of HASHTABLE_N
5e10: 53 4c 4f 54 20 65 6c 65 6d 65 6e 74 73 20 6f 66  SLOT elements of
5e20: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74   the following t
5e30: 79 70 65 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20  ype..*/.typedef 
5e40: 75 31 36 20 68 74 5f 73 6c 6f 74 3b 0a 0a 2f 2a  u16 ht_slot;../*
5e50: 0a 2a 2a 20 54 68 69 73 20 73 74 72 75 63 74 75  .** This structu
5e60: 72 65 20 69 73 20 75 73 65 64 20 74 6f 20 69 6d  re is used to im
5e70: 70 6c 65 6d 65 6e 74 20 61 6e 20 69 74 65 72 61  plement an itera
5e80: 74 6f 72 20 74 68 61 74 20 6c 6f 6f 70 73 20 74  tor that loops t
5e90: 68 72 6f 75 67 68 0a 2a 2a 20 61 6c 6c 20 66 72  hrough.** all fr
5ea0: 61 6d 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20  ames in the WAL 
5eb0: 69 6e 20 64 61 74 61 62 61 73 65 20 70 61 67 65  in database page
5ec0: 20 6f 72 64 65 72 2e 20 57 68 65 72 65 20 74 77   order. Where tw
5ed0: 6f 20 6f 72 20 6d 6f 72 65 20 66 72 61 6d 65 73  o or more frames
5ee0: 0a 2a 2a 20 63 6f 72 72 65 73 70 6f 6e 64 20 74  .** correspond t
5ef0: 6f 20 74 68 65 20 73 61 6d 65 20 64 61 74 61 62  o the same datab
5f00: 61 73 65 20 70 61 67 65 2c 20 74 68 65 20 69 74  ase page, the it
5f10: 65 72 61 74 6f 72 20 76 69 73 69 74 73 20 6f 6e  erator visits on
5f20: 6c 79 20 74 68 65 20 0a 2a 2a 20 66 72 61 6d 65  ly the .** frame
5f30: 20 6d 6f 73 74 20 72 65 63 65 6e 74 6c 79 20 77   most recently w
5f40: 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20 57 41  ritten to the WA
5f50: 4c 20 28 69 6e 20 6f 74 68 65 72 20 77 6f 72 64  L (in other word
5f60: 73 2c 20 74 68 65 20 66 72 61 6d 65 20 77 69 74  s, the frame wit
5f70: 68 0a 2a 2a 20 74 68 65 20 6c 61 72 67 65 73 74  h.** the largest
5f80: 20 69 6e 64 65 78 29 2e 0a 2a 2a 0a 2a 2a 20 54   index)..**.** T
5f90: 68 65 20 69 6e 74 65 72 6e 61 6c 73 20 6f 66 20  he internals of 
5fa0: 74 68 69 73 20 73 74 72 75 63 74 75 72 65 20 61  this structure a
5fb0: 72 65 20 6f 6e 6c 79 20 61 63 63 65 73 73 65 64  re only accessed
5fc0: 20 62 79 3a 0a 2a 2a 0a 2a 2a 20 20 20 77 61 6c   by:.**.**   wal
5fd0: 49 74 65 72 61 74 6f 72 49 6e 69 74 28 29 20 2d  IteratorInit() -
5fe0: 20 43 72 65 61 74 65 20 61 20 6e 65 77 20 69 74   Create a new it
5ff0: 65 72 61 74 6f 72 2c 0a 2a 2a 20 20 20 77 61 6c  erator,.**   wal
6000: 49 74 65 72 61 74 6f 72 4e 65 78 74 28 29 20 2d  IteratorNext() -
6010: 20 53 74 65 70 20 61 6e 20 69 74 65 72 61 74 6f   Step an iterato
6020: 72 2c 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61  r,.**   walItera
6030: 74 6f 72 46 72 65 65 28 29 20 2d 20 46 72 65 65  torFree() - Free
6040: 20 61 6e 20 69 74 65 72 61 74 6f 72 2e 0a 2a 2a   an iterator..**
6050: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
6060: 6e 61 6c 69 74 79 20 69 73 20 75 73 65 64 20 62  nality is used b
6070: 79 20 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74  y the checkpoint
6080: 20 63 6f 64 65 20 28 73 65 65 20 77 61 6c 43 68   code (see walCh
6090: 65 63 6b 70 6f 69 6e 74 28 29 29 2e 0a 2a 2f 0a  eckpoint())..*/.
60a0: 73 74 72 75 63 74 20 57 61 6c 49 74 65 72 61 74  struct WalIterat
60b0: 6f 72 20 7b 0a 20 20 69 6e 74 20 69 50 72 69 6f  or {.  int iPrio
60c0: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
60d0: 20 20 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 72         /* Last r
60e0: 65 73 75 6c 74 20 72 65 74 75 72 6e 65 64 20 66  esult returned f
60f0: 72 6f 6d 20 74 68 65 20 69 74 65 72 61 74 6f 72  rom the iterator
6100: 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 65 67 6d 65   */.  int nSegme
6110: 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  nt;             
6120: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
6130: 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 61 53  of entries in aS
6140: 65 67 6d 65 6e 74 5b 5d 20 2a 2f 0a 20 20 73 74  egment[] */.  st
6150: 72 75 63 74 20 57 61 6c 53 65 67 6d 65 6e 74 20  ruct WalSegment 
6160: 7b 0a 20 20 20 20 69 6e 74 20 69 4e 65 78 74 3b  {.    int iNext;
6170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6180: 20 20 20 20 2f 2a 20 4e 65 78 74 20 73 6c 6f 74      /* Next slot
6190: 20 69 6e 20 61 49 6e 64 65 78 5b 5d 20 6e 6f 74   in aIndex[] not
61a0: 20 79 65 74 20 72 65 74 75 72 6e 65 64 20 2a 2f   yet returned */
61b0: 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20 2a 61 49  .    ht_slot *aI
61c0: 6e 64 65 78 3b 20 20 20 20 20 20 20 20 20 20 20  ndex;           
61d0: 20 20 20 2f 2a 20 69 30 2c 20 69 31 2c 20 69 32     /* i0, i1, i2
61e0: 2e 2e 2e 20 73 75 63 68 20 74 68 61 74 20 61 50  ... such that aP
61f0: 67 6e 6f 5b 69 4e 5d 20 61 73 63 65 6e 64 20 2a  gno[iN] ascend *
6200: 2f 0a 20 20 20 20 75 33 32 20 2a 61 50 67 6e 6f  /.    u32 *aPgno
6210: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
6220: 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20      /* Array of 
6230: 70 61 67 65 20 6e 75 6d 62 65 72 73 2e 20 2a 2f  page numbers. */
6240: 0a 20 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 3b  .    int nEntry;
6250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6260: 20 20 20 2f 2a 20 4e 72 2e 20 6f 66 20 65 6e 74     /* Nr. of ent
6270: 72 69 65 73 20 69 6e 20 61 50 67 6e 6f 5b 5d 20  ries in aPgno[] 
6280: 61 6e 64 20 61 49 6e 64 65 78 5b 5d 20 2a 2f 0a  and aIndex[] */.
6290: 20 20 20 20 69 6e 74 20 69 5a 65 72 6f 3b 20 20      int iZero;  
62a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
62b0: 20 20 2f 2a 20 46 72 61 6d 65 20 6e 75 6d 62 65    /* Frame numbe
62c0: 72 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74  r associated wit
62d0: 68 20 61 50 67 6e 6f 5b 30 5d 20 2a 2f 0a 20 20  h aPgno[0] */.  
62e0: 7d 20 61 53 65 67 6d 65 6e 74 5b 31 5d 3b 20 20  } aSegment[1];  
62f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6300: 2f 2a 20 4f 6e 65 20 66 6f 72 20 65 76 65 72 79  /* One for every
6310: 20 33 32 4b 42 20 70 61 67 65 20 69 6e 20 74 68   32KB page in th
6320: 65 20 77 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a 7d  e wal-index */.}
6330: 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 66 69 6e 65 20  ;../*.** Define 
6340: 74 68 65 20 70 61 72 61 6d 65 74 65 72 73 20 6f  the parameters o
6350: 66 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  f the hash table
6360: 73 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64  s in the wal-ind
6370: 65 78 20 66 69 6c 65 2e 20 54 68 65 72 65 0a 2a  ex file. There.*
6380: 2a 20 69 73 20 61 20 68 61 73 68 2d 74 61 62 6c  * is a hash-tabl
6390: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 65 76 65 72  e following ever
63a0: 79 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  y HASHTABLE_NPAG
63b0: 45 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20 69  E page numbers i
63c0: 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64  n the.** wal-ind
63d0: 65 78 2e 0a 2a 2a 0a 2a 2a 20 43 68 61 6e 67 69  ex..**.** Changi
63e0: 6e 67 20 61 6e 79 20 6f 66 20 74 68 65 73 65 20  ng any of these 
63f0: 63 6f 6e 73 74 61 6e 74 73 20 77 69 6c 6c 20 61  constants will a
6400: 6c 74 65 72 20 74 68 65 20 77 61 6c 2d 69 6e 64  lter the wal-ind
6410: 65 78 20 66 6f 72 6d 61 74 20 61 6e 64 0a 2a 2a  ex format and.**
6420: 20 63 72 65 61 74 65 20 69 6e 63 6f 6d 70 61 74   create incompat
6430: 69 62 69 6c 69 74 69 65 73 2e 0a 2a 2f 0a 23 64  ibilities..*/.#d
6440: 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f  efine HASHTABLE_
6450: 4e 50 41 47 45 20 20 20 20 20 20 34 30 39 36 20  NPAGE      4096 
6460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6470: 2f 2a 20 4d 75 73 74 20 62 65 20 70 6f 77 65 72  /* Must be power
6480: 20 6f 66 20 32 20 2a 2f 0a 23 64 65 66 69 6e 65   of 2 */.#define
6490: 20 48 41 53 48 54 41 42 4c 45 5f 48 41 53 48 5f   HASHTABLE_HASH_
64a0: 31 20 20 20 20 20 33 38 33 20 20 20 20 20 20 20  1     383       
64b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 68             /* Sh
64c0: 6f 75 6c 64 20 62 65 20 70 72 69 6d 65 20 2a 2f  ould be prime */
64d0: 0a 23 64 65 66 69 6e 65 20 48 41 53 48 54 41 42  .#define HASHTAB
64e0: 4c 45 5f 4e 53 4c 4f 54 20 20 20 20 20 20 28 48  LE_NSLOT      (H
64f0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 2a 32  ASHTABLE_NPAGE*2
6500: 29 20 20 2f 2a 20 4d 75 73 74 20 62 65 20 61 20  )  /* Must be a 
6510: 70 6f 77 65 72 20 6f 66 20 32 20 2a 2f 0a 0a 2f  power of 2 */../
6520: 2a 20 0a 2a 2a 20 54 68 65 20 62 6c 6f 63 6b 20  * .** The block 
6530: 6f 66 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20  of page numbers 
6540: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20  associated with 
6550: 74 68 65 20 66 69 72 73 74 20 68 61 73 68 2d 74  the first hash-t
6560: 61 62 6c 65 20 69 6e 20 61 0a 2a 2a 20 77 61 6c  able in a.** wal
6570: 2d 69 6e 64 65 78 20 69 73 20 73 6d 61 6c 6c 65  -index is smalle
6580: 72 20 74 68 61 6e 20 75 73 75 61 6c 2e 20 54 68  r than usual. Th
6590: 69 73 20 69 73 20 73 6f 20 74 68 61 74 20 74 68  is is so that th
65a0: 65 72 65 20 69 73 20 61 20 63 6f 6d 70 6c 65 74  ere is a complet
65b0: 65 0a 2a 2a 20 68 61 73 68 2d 74 61 62 6c 65 20  e.** hash-table 
65c0: 6f 6e 20 65 61 63 68 20 61 6c 69 67 6e 65 64 20  on each aligned 
65d0: 33 32 4b 42 20 70 61 67 65 20 6f 66 20 74 68 65  32KB page of the
65e0: 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 23   wal-index..*/.#
65f0: 64 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45  define HASHTABLE
6600: 5f 4e 50 41 47 45 5f 4f 4e 45 20 20 28 48 41 53  _NPAGE_ONE  (HAS
6610: 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 2d 20 28  HTABLE_NPAGE - (
6620: 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a  WALINDEX_HDR_SIZ
6630: 45 2f 73 69 7a 65 6f 66 28 75 33 32 29 29 29 0a  E/sizeof(u32))).
6640: 0a 2f 2a 20 54 68 65 20 77 61 6c 2d 69 6e 64 65  ./* The wal-inde
6650: 78 20 69 73 20 64 69 76 69 64 65 64 20 69 6e 74  x is divided int
6660: 6f 20 70 61 67 65 73 20 6f 66 20 57 41 4c 49 4e  o pages of WALIN
6670: 44 45 58 5f 50 47 53 5a 20 62 79 74 65 73 20 65  DEX_PGSZ bytes e
6680: 61 63 68 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20  ach. */.#define 
6690: 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a 20 20 20  WALINDEX_PGSZ   
66a0: 28 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (               
66b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
66c0: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20            \.    
66d0: 73 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 2a  sizeof(ht_slot)*
66e0: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20  HASHTABLE_NSLOT 
66f0: 2b 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  + HASHTABLE_NPAG
6700: 45 2a 73 69 7a 65 6f 66 28 75 33 32 29 20 5c 0a  E*sizeof(u32) \.
6710: 29 0a 0a 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20  )../*.** Obtain 
6720: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65  a pointer to the
6730: 20 69 50 61 67 65 27 74 68 20 70 61 67 65 20 6f   iPage'th page o
6740: 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e  f the wal-index.
6750: 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 2a   The wal-index.*
6760: 2a 20 69 73 20 62 72 6f 6b 65 6e 20 69 6e 74 6f  * is broken into
6770: 20 70 61 67 65 73 20 6f 66 20 57 41 4c 49 4e 44   pages of WALIND
6780: 45 58 5f 50 47 53 5a 20 62 79 74 65 73 2e 20 57  EX_PGSZ bytes. W
6790: 61 6c 2d 69 6e 64 65 78 20 70 61 67 65 73 20 61  al-index pages a
67a0: 72 65 0a 2a 2a 20 6e 75 6d 62 65 72 65 64 20 66  re.** numbered f
67b0: 72 6f 6d 20 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20  rom zero..**.** 
67c0: 49 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  If the wal-index
67d0: 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 73 6d   is currently sm
67e0: 61 6c 6c 65 72 20 74 68 65 20 69 50 61 67 65 20  aller the iPage 
67f0: 70 61 67 65 73 20 74 68 65 6e 20 74 68 65 20 73  pages then the s
6800: 69 7a 65 0a 2a 2a 20 6f 66 20 74 68 65 20 77 61  ize.** of the wa
6810: 6c 2d 69 6e 64 65 78 20 6d 69 67 68 74 20 62 65  l-index might be
6820: 20 69 6e 63 72 65 61 73 65 64 2c 20 62 75 74 20   increased, but 
6830: 6f 6e 6c 79 20 69 66 20 69 74 20 69 73 20 73 61  only if it is sa
6840: 66 65 20 74 6f 20 64 6f 0a 2a 2a 20 73 6f 2e 20  fe to do.** so. 
6850: 20 49 74 20 69 73 20 73 61 66 65 20 74 6f 20 65   It is safe to e
6860: 6e 6c 61 72 67 65 20 74 68 65 20 77 61 6c 2d 69  nlarge the wal-i
6870: 6e 64 65 78 20 69 66 20 70 57 61 6c 2d 3e 77 72  ndex if pWal->wr
6880: 69 74 65 4c 6f 63 6b 20 69 73 20 74 72 75 65 0a  iteLock is true.
6890: 2a 2a 20 6f 72 20 70 57 61 6c 2d 3e 65 78 63 6c  ** or pWal->excl
68a0: 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48  usiveMode==WAL_H
68b0: 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 2e 0a  EAPMEMORY_MODE..
68c0: 2a 2a 0a 2a 2a 20 49 66 20 74 68 69 73 20 63 61  **.** If this ca
68d0: 6c 6c 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  ll is successful
68e0: 2c 20 2a 70 70 50 61 67 65 20 69 73 20 73 65 74  , *ppPage is set
68f0: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   to point to the
6900: 20 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a 20 70 61   wal-index.** pa
6910: 67 65 20 61 6e 64 20 53 51 4c 49 54 45 5f 4f 4b  ge and SQLITE_OK
6920: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 49 66   is returned. If
6930: 20 61 6e 20 65 72 72 6f 72 20 28 61 6e 20 4f 4f   an error (an OO
6940: 4d 20 6f 72 20 56 46 53 20 65 72 72 6f 72 29 20  M or VFS error) 
6950: 6f 63 63 75 72 73 2c 0a 2a 2a 20 74 68 65 6e 20  occurs,.** then 
6960: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
6970: 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65 64  code is returned
6980: 20 61 6e 64 20 2a 70 70 50 61 67 65 20 69 73 20   and *ppPage is 
6990: 73 65 74 20 74 6f 20 30 2e 0a 2a 2f 0a 73 74 61  set to 0..*/.sta
69a0: 74 69 63 20 53 51 4c 49 54 45 5f 4e 4f 49 4e 4c  tic SQLITE_NOINL
69b0: 49 4e 45 20 69 6e 74 20 77 61 6c 49 6e 64 65 78  INE int walIndex
69c0: 50 61 67 65 52 65 61 6c 6c 6f 63 28 0a 20 20 57  PageRealloc(.  W
69d0: 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20  al *pWal,       
69e0: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 57          /* The W
69f0: 41 4c 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20  AL context */.  
6a00: 69 6e 74 20 69 50 61 67 65 2c 20 20 20 20 20 20  int iPage,      
6a10: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
6a20: 70 61 67 65 20 77 65 20 73 65 65 6b 20 2a 2f 0a  page we seek */.
6a30: 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a    volatile u32 *
6a40: 2a 70 70 50 61 67 65 20 20 20 20 2f 2a 20 57 72  *ppPage    /* Wr
6a50: 69 74 65 20 74 68 65 20 70 61 67 65 20 70 6f 69  ite the page poi
6a60: 6e 74 65 72 20 68 65 72 65 20 2a 2f 0a 29 7b 0a  nter here */.){.
6a70: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
6a80: 45 5f 4f 4b 3b 0a 0a 20 20 2f 2a 20 45 6e 6c 61  E_OK;..  /* Enla
6a90: 72 67 65 20 74 68 65 20 70 57 61 6c 2d 3e 61 70  rge the pWal->ap
6aa0: 57 69 44 61 74 61 5b 5d 20 61 72 72 61 79 20 69  WiData[] array i
6ab0: 66 20 72 65 71 75 69 72 65 64 20 2a 2f 0a 20 20  f required */.  
6ac0: 69 66 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74  if( pWal->nWiDat
6ad0: 61 3c 3d 69 50 61 67 65 20 29 7b 0a 20 20 20 20  a<=iPage ){.    
6ae0: 69 6e 74 20 6e 42 79 74 65 20 3d 20 73 69 7a 65  int nByte = size
6af0: 6f 66 28 75 33 32 2a 29 2a 28 69 50 61 67 65 2b  of(u32*)*(iPage+
6b00: 31 29 3b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65  1);.    volatile
6b10: 20 75 33 32 20 2a 2a 61 70 4e 65 77 3b 0a 20 20   u32 **apNew;.  
6b20: 20 20 61 70 4e 65 77 20 3d 20 28 76 6f 6c 61 74    apNew = (volat
6b30: 69 6c 65 20 75 33 32 20 2a 2a 29 73 71 6c 69 74  ile u32 **)sqlit
6b40: 65 33 5f 72 65 61 6c 6c 6f 63 36 34 28 28 76 6f  e3_realloc64((vo
6b50: 69 64 20 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44  id *)pWal->apWiD
6b60: 61 74 61 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20  ata, nByte);.   
6b70: 20 69 66 28 20 21 61 70 4e 65 77 20 29 7b 0a 20   if( !apNew ){. 
6b80: 20 20 20 20 20 2a 70 70 50 61 67 65 20 3d 20 30       *ppPage = 0
6b90: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  ;.      return S
6ba0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54  QLITE_NOMEM_BKPT
6bb0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73  ;.    }.    mems
6bc0: 65 74 28 28 76 6f 69 64 2a 29 26 61 70 4e 65 77  et((void*)&apNew
6bd0: 5b 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 5d 2c  [pWal->nWiData],
6be0: 20 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20 73   0,.           s
6bf0: 69 7a 65 6f 66 28 75 33 32 2a 29 2a 28 69 50 61  izeof(u32*)*(iPa
6c00: 67 65 2b 31 2d 70 57 61 6c 2d 3e 6e 57 69 44 61  ge+1-pWal->nWiDa
6c10: 74 61 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  ta));.    pWal->
6c20: 61 70 57 69 44 61 74 61 20 3d 20 61 70 4e 65 77  apWiData = apNew
6c30: 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 6e 57 69 44  ;.    pWal->nWiD
6c40: 61 74 61 20 3d 20 69 50 61 67 65 2b 31 3b 0a 20  ata = iPage+1;. 
6c50: 20 7d 0a 0a 20 20 2f 2a 20 52 65 71 75 65 73 74   }..  /* Request
6c60: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
6c70: 65 20 72 65 71 75 69 72 65 64 20 70 61 67 65 20  e required page 
6c80: 66 72 6f 6d 20 74 68 65 20 56 46 53 20 2a 2f 0a  from the VFS */.
6c90: 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
6ca0: 61 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d 3d  apWiData[iPage]=
6cb0: 3d 30 20 29 3b 0a 20 20 69 66 28 20 70 57 61 6c  =0 );.  if( pWal
6cc0: 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d  ->exclusiveMode=
6cd0: 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f  =WAL_HEAPMEMORY_
6ce0: 4d 4f 44 45 20 29 7b 0a 20 20 20 20 70 57 61 6c  MODE ){.    pWal
6cf0: 2d 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65  ->apWiData[iPage
6d00: 5d 20 3d 20 28 75 33 32 20 76 6f 6c 61 74 69 6c  ] = (u32 volatil
6d10: 65 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  e *)sqlite3Mallo
6d20: 63 5a 65 72 6f 28 57 41 4c 49 4e 44 45 58 5f 50  cZero(WALINDEX_P
6d30: 47 53 5a 29 3b 0a 20 20 20 20 69 66 28 20 21 70  GSZ);.    if( !p
6d40: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50  Wal->apWiData[iP
6d50: 61 67 65 5d 20 29 20 72 63 20 3d 20 53 51 4c 49  age] ) rc = SQLI
6d60: 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20  TE_NOMEM_BKPT;. 
6d70: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d   }else{.    rc =
6d80: 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4d 61 70   sqlite3OsShmMap
6d90: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 50  (pWal->pDbFd, iP
6da0: 61 67 65 2c 20 57 41 4c 49 4e 44 45 58 5f 50 47  age, WALINDEX_PG
6db0: 53 5a 2c 20 0a 20 20 20 20 20 20 20 20 70 57 61  SZ, .        pWa
6dc0: 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 2c 20 28 76  l->writeLock, (v
6dd0: 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a 2a 29  oid volatile **)
6de0: 26 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b  &pWal->apWiData[
6df0: 69 50 61 67 65 5d 0a 20 20 20 20 29 3b 0a 20 20  iPage].    );.  
6e00: 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
6e10: 61 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d 21  apWiData[iPage]!
6e20: 3d 30 20 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45  =0 || rc!=SQLITE
6e30: 5f 4f 4b 20 7c 7c 20 70 57 61 6c 2d 3e 77 72 69  _OK || pWal->wri
6e40: 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 20  teLock==0 );.   
6e50: 20 74 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d   testcase( pWal-
6e60: 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d  >apWiData[iPage]
6e70: 3d 3d 30 20 26 26 20 72 63 3d 3d 53 51 4c 49 54  ==0 && rc==SQLIT
6e80: 45 5f 4f 4b 20 29 3b 0a 20 20 20 20 69 66 28 20  E_OK );.    if( 
6e90: 28 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49 54  (rc&0xff)==SQLIT
6ea0: 45 5f 52 45 41 44 4f 4e 4c 59 20 29 7b 0a 20 20  E_READONLY ){.  
6eb0: 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4f 6e      pWal->readOn
6ec0: 6c 79 20 7c 3d 20 57 41 4c 5f 53 48 4d 5f 52 44  ly |= WAL_SHM_RD
6ed0: 4f 4e 4c 59 3b 0a 20 20 20 20 20 20 69 66 28 20  ONLY;.      if( 
6ee0: 72 63 3d 3d 53 51 4c 49 54 45 5f 52 45 41 44 4f  rc==SQLITE_READO
6ef0: 4e 4c 59 20 29 7b 0a 20 20 20 20 20 20 20 20 72  NLY ){.        r
6f00: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
6f10: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
6f20: 0a 0a 20 20 2a 70 70 50 61 67 65 20 3d 20 70 57  ..  *ppPage = pW
6f30: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50 61  al->apWiData[iPa
6f40: 67 65 5d 3b 0a 20 20 61 73 73 65 72 74 28 20 69  ge];.  assert( i
6f50: 50 61 67 65 3d 3d 30 20 7c 7c 20 2a 70 70 50 61  Page==0 || *ppPa
6f60: 67 65 20 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45  ge || rc!=SQLITE
6f70: 5f 4f 4b 20 29 3b 0a 20 20 72 65 74 75 72 6e 20  _OK );.  return 
6f80: 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74  rc;.}.static int
6f90: 20 77 61 6c 49 6e 64 65 78 50 61 67 65 28 0a 20   walIndexPage(. 
6fa0: 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20   Wal *pWal,     
6fb0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
6fc0: 20 57 41 4c 20 63 6f 6e 74 65 78 74 20 2a 2f 0a   WAL context */.
6fd0: 20 20 69 6e 74 20 69 50 61 67 65 2c 20 20 20 20    int iPage,    
6fe0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
6ff0: 65 20 70 61 67 65 20 77 65 20 73 65 65 6b 20 2a  e page we seek *
7000: 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32  /.  volatile u32
7010: 20 2a 2a 70 70 50 61 67 65 20 20 20 20 2f 2a 20   **ppPage    /* 
7020: 57 72 69 74 65 20 74 68 65 20 70 61 67 65 20 70  Write the page p
7030: 6f 69 6e 74 65 72 20 68 65 72 65 20 2a 2f 0a 29  ointer here */.)
7040: 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 6e 57  {.  if( pWal->nW
7050: 69 44 61 74 61 3c 3d 69 50 61 67 65 20 7c 7c 20  iData<=iPage || 
7060: 28 2a 70 70 50 61 67 65 20 3d 20 70 57 61 6c 2d  (*ppPage = pWal-
7070: 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d  >apWiData[iPage]
7080: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )==0 ){.    retu
7090: 72 6e 20 77 61 6c 49 6e 64 65 78 50 61 67 65 52  rn walIndexPageR
70a0: 65 61 6c 6c 6f 63 28 70 57 61 6c 2c 20 69 50 61  ealloc(pWal, iPa
70b0: 67 65 2c 20 70 70 50 61 67 65 29 3b 0a 20 20 7d  ge, ppPage);.  }
70c0: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
70d0: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  _OK;.}../*.** Re
70e0: 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
70f0: 6f 20 74 68 65 20 57 61 6c 43 6b 70 74 49 6e 66  o the WalCkptInf
7100: 6f 20 73 74 72 75 63 74 75 72 65 20 69 6e 20 74  o structure in t
7110: 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f  he wal-index..*/
7120: 0a 73 74 61 74 69 63 20 76 6f 6c 61 74 69 6c 65  .static volatile
7130: 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 77 61   WalCkptInfo *wa
7140: 6c 43 6b 70 74 49 6e 66 6f 28 57 61 6c 20 2a 70  lCkptInfo(Wal *p
7150: 57 61 6c 29 7b 0a 20 20 61 73 73 65 72 74 28 20  Wal){.  assert( 
7160: 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20  pWal->nWiData>0 
7170: 26 26 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  && pWal->apWiDat
7180: 61 5b 30 5d 20 29 3b 0a 20 20 72 65 74 75 72 6e  a[0] );.  return
7190: 20 28 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b   (volatile WalCk
71a0: 70 74 49 6e 66 6f 2a 29 26 28 70 57 61 6c 2d 3e  ptInfo*)&(pWal->
71b0: 61 70 57 69 44 61 74 61 5b 30 5d 5b 73 69 7a 65  apWiData[0][size
71c0: 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 2f  of(WalIndexHdr)/
71d0: 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  2]);.}../*.** Re
71e0: 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
71f0: 6f 20 74 68 65 20 57 61 6c 49 6e 64 65 78 48 64  o the WalIndexHd
7200: 72 20 73 74 72 75 63 74 75 72 65 20 69 6e 20 74  r structure in t
7210: 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f  he wal-index..*/
7220: 0a 73 74 61 74 69 63 20 76 6f 6c 61 74 69 6c 65  .static volatile
7230: 20 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 77 61   WalIndexHdr *wa
7240: 6c 49 6e 64 65 78 48 64 72 28 57 61 6c 20 2a 70  lIndexHdr(Wal *p
7250: 57 61 6c 29 7b 0a 20 20 61 73 73 65 72 74 28 20  Wal){.  assert( 
7260: 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20  pWal->nWiData>0 
7270: 26 26 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  && pWal->apWiDat
7280: 61 5b 30 5d 20 29 3b 0a 20 20 72 65 74 75 72 6e  a[0] );.  return
7290: 20 28 76 6f 6c 61 74 69 6c 65 20 57 61 6c 49 6e   (volatile WalIn
72a0: 64 65 78 48 64 72 2a 29 70 57 61 6c 2d 3e 61 70  dexHdr*)pWal->ap
72b0: 57 69 44 61 74 61 5b 30 5d 3b 0a 7d 0a 0a 2f 2a  WiData[0];.}../*
72c0: 0a 2a 2a 20 54 68 65 20 61 72 67 75 6d 65 6e 74  .** The argument
72d0: 20 74 6f 20 74 68 69 73 20 6d 61 63 72 6f 20 6d   to this macro m
72e0: 75 73 74 20 62 65 20 6f 66 20 74 79 70 65 20 75  ust be of type u
72f0: 33 32 2e 20 4f 6e 20 61 20 6c 69 74 74 6c 65 2d  32. On a little-
7300: 65 6e 64 69 61 6e 0a 2a 2a 20 61 72 63 68 69 74  endian.** archit
7310: 65 63 74 75 72 65 2c 20 69 74 20 72 65 74 75 72  ecture, it retur
7320: 6e 73 20 74 68 65 20 75 33 32 20 76 61 6c 75 65  ns the u32 value
7330: 20 74 68 61 74 20 72 65 73 75 6c 74 73 20 66 72   that results fr
7340: 6f 6d 20 69 6e 74 65 72 70 72 65 74 69 6e 67 0a  om interpreting.
7350: 2a 2a 20 74 68 65 20 34 20 62 79 74 65 73 20 61  ** the 4 bytes a
7360: 73 20 61 20 62 69 67 2d 65 6e 64 69 61 6e 20 76  s a big-endian v
7370: 61 6c 75 65 2e 20 4f 6e 20 61 20 62 69 67 2d 65  alue. On a big-e
7380: 6e 64 69 61 6e 20 61 72 63 68 69 74 65 63 74 75  ndian architectu
7390: 72 65 2c 20 69 74 0a 2a 2a 20 72 65 74 75 72 6e  re, it.** return
73a0: 73 20 74 68 65 20 76 61 6c 75 65 20 74 68 61 74  s the value that
73b0: 20 77 6f 75 6c 64 20 62 65 20 70 72 6f 64 75 63   would be produc
73c0: 65 64 20 62 79 20 69 6e 74 65 72 70 72 65 74 69  ed by interpreti
73d0: 6e 67 20 74 68 65 20 34 20 62 79 74 65 73 0a 2a  ng the 4 bytes.*
73e0: 2a 20 6f 66 20 74 68 65 20 69 6e 70 75 74 20 76  * of the input v
73f0: 61 6c 75 65 20 61 73 20 61 20 6c 69 74 74 6c 65  alue as a little
7400: 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65 72 2e  -endian integer.
7410: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 42 59 54 45  .*/.#define BYTE
7420: 53 57 41 50 33 32 28 78 29 20 28 20 5c 0a 20 20  SWAP32(x) ( \.  
7430: 20 20 28 28 28 78 29 26 30 78 30 30 30 30 30 30    (((x)&0x000000
7440: 46 46 29 3c 3c 32 34 29 20 2b 20 28 28 28 78 29  FF)<<24) + (((x)
7450: 26 30 78 30 30 30 30 46 46 30 30 29 3c 3c 38 29  &0x0000FF00)<<8)
7460: 20 20 5c 0a 20 20 2b 20 28 28 28 78 29 26 30 78    \.  + (((x)&0x
7470: 30 30 46 46 30 30 30 30 29 3e 3e 38 29 20 20 2b  00FF0000)>>8)  +
7480: 20 28 28 28 78 29 26 30 78 46 46 30 30 30 30 30   (((x)&0xFF00000
7490: 30 29 3e 3e 32 34 29 20 5c 0a 29 0a 0a 2f 2a 0a  0)>>24) \.)../*.
74a0: 2a 2a 20 47 65 6e 65 72 61 74 65 20 6f 72 20 65  ** Generate or e
74b0: 78 74 65 6e 64 20 61 6e 20 38 20 62 79 74 65 20  xtend an 8 byte 
74c0: 63 68 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f  checksum based o
74d0: 6e 20 74 68 65 20 64 61 74 61 20 69 6e 20 0a 2a  n the data in .*
74e0: 2a 20 61 72 72 61 79 20 61 42 79 74 65 5b 5d 20  * array aByte[] 
74f0: 61 6e 64 20 74 68 65 20 69 6e 69 74 69 61 6c 20  and the initial 
7500: 76 61 6c 75 65 73 20 6f 66 20 61 49 6e 5b 30 5d  values of aIn[0]
7510: 20 61 6e 64 20 61 49 6e 5b 31 5d 20 28 6f 72 0a   and aIn[1] (or.
7520: 2a 2a 20 69 6e 69 74 69 61 6c 20 76 61 6c 75 65  ** initial value
7530: 73 20 6f 66 20 30 20 61 6e 64 20 30 20 69 66 20  s of 0 and 0 if 
7540: 61 49 6e 3d 3d 4e 55 4c 4c 29 2e 0a 2a 2a 0a 2a  aIn==NULL)..**.*
7550: 2a 20 54 68 65 20 63 68 65 63 6b 73 75 6d 20 69  * The checksum i
7560: 73 20 77 72 69 74 74 65 6e 20 62 61 63 6b 20 69  s written back i
7570: 6e 74 6f 20 61 4f 75 74 5b 5d 20 62 65 66 6f 72  nto aOut[] befor
7580: 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2a 0a  e returning..**.
7590: 2a 2a 20 6e 42 79 74 65 20 6d 75 73 74 20 62 65  ** nByte must be
75a0: 20 61 20 70 6f 73 69 74 69 76 65 20 6d 75 6c 74   a positive mult
75b0: 69 70 6c 65 20 6f 66 20 38 2e 0a 2a 2f 0a 73 74  iple of 8..*/.st
75c0: 61 74 69 63 20 76 6f 69 64 20 77 61 6c 43 68 65  atic void walChe
75d0: 63 6b 73 75 6d 42 79 74 65 73 28 0a 20 20 69 6e  cksumBytes(.  in
75e0: 74 20 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 2f  t nativeCksum, /
75f0: 2a 20 54 72 75 65 20 66 6f 72 20 6e 61 74 69 76  * True for nativ
7600: 65 20 62 79 74 65 2d 6f 72 64 65 72 2c 20 66 61  e byte-order, fa
7610: 6c 73 65 20 66 6f 72 20 6e 6f 6e 2d 6e 61 74 69  lse for non-nati
7620: 76 65 20 2a 2f 0a 20 20 75 38 20 2a 61 2c 20 20  ve */.  u8 *a,  
7630: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74           /* Cont
7640: 65 6e 74 20 74 6f 20 62 65 20 63 68 65 63 6b 73  ent to be checks
7650: 75 6d 6d 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e  ummed */.  int n
7660: 42 79 74 65 2c 20 20 20 20 20 20 20 2f 2a 20 42  Byte,       /* B
7670: 79 74 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74 20  ytes of content 
7680: 69 6e 20 61 5b 5d 2e 20 20 4d 75 73 74 20 62 65  in a[].  Must be
7690: 20 61 20 6d 75 6c 74 69 70 6c 65 20 6f 66 20 38   a multiple of 8
76a0: 2e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 75 33 32  . */.  const u32
76b0: 20 2a 61 49 6e 2c 20 20 2f 2a 20 49 6e 69 74 69   *aIn,  /* Initi
76c0: 61 6c 20 63 68 65 63 6b 73 75 6d 20 76 61 6c 75  al checksum valu
76d0: 65 20 69 6e 70 75 74 20 2a 2f 0a 20 20 75 33 32  e input */.  u32
76e0: 20 2a 61 4f 75 74 20 20 20 20 20 20 20 20 2f 2a   *aOut        /*
76f0: 20 4f 55 54 3a 20 46 69 6e 61 6c 20 63 68 65 63   OUT: Final chec
7700: 6b 73 75 6d 20 76 61 6c 75 65 20 6f 75 74 70 75  ksum value outpu
7710: 74 20 2a 2f 0a 29 7b 0a 20 20 75 33 32 20 73 31  t */.){.  u32 s1
7720: 2c 20 73 32 3b 0a 20 20 75 33 32 20 2a 61 44 61  , s2;.  u32 *aDa
7730: 74 61 20 3d 20 28 75 33 32 20 2a 29 61 3b 0a 20  ta = (u32 *)a;. 
7740: 20 75 33 32 20 2a 61 45 6e 64 20 3d 20 28 75 33   u32 *aEnd = (u3
7750: 32 20 2a 29 26 61 5b 6e 42 79 74 65 5d 3b 0a 0a  2 *)&a[nByte];..
7760: 20 20 69 66 28 20 61 49 6e 20 29 7b 0a 20 20 20    if( aIn ){.   
7770: 20 73 31 20 3d 20 61 49 6e 5b 30 5d 3b 0a 20 20   s1 = aIn[0];.  
7780: 20 20 73 32 20 3d 20 61 49 6e 5b 31 5d 3b 0a 20    s2 = aIn[1];. 
7790: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 31 20 3d   }else{.    s1 =
77a0: 20 73 32 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20   s2 = 0;.  }..  
77b0: 61 73 73 65 72 74 28 20 6e 42 79 74 65 3e 3d 38  assert( nByte>=8
77c0: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 28 6e   );.  assert( (n
77d0: 42 79 74 65 26 30 78 30 30 30 30 30 30 30 37 29  Byte&0x00000007)
77e0: 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 6e 61  ==0 );..  if( na
77f0: 74 69 76 65 43 6b 73 75 6d 20 29 7b 0a 20 20 20  tiveCksum ){.   
7800: 20 64 6f 20 7b 0a 20 20 20 20 20 20 73 31 20 2b   do {.      s1 +
7810: 3d 20 2a 61 44 61 74 61 2b 2b 20 2b 20 73 32 3b  = *aData++ + s2;
7820: 0a 20 20 20 20 20 20 73 32 20 2b 3d 20 2a 61 44  .      s2 += *aD
7830: 61 74 61 2b 2b 20 2b 20 73 31 3b 0a 20 20 20 20  ata++ + s1;.    
7840: 7d 77 68 69 6c 65 28 20 61 44 61 74 61 3c 61 45  }while( aData<aE
7850: 6e 64 20 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  nd );.  }else{. 
7860: 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 20 73 31     do {.      s1
7870: 20 2b 3d 20 42 59 54 45 53 57 41 50 33 32 28 61   += BYTESWAP32(a
7880: 44 61 74 61 5b 30 5d 29 20 2b 20 73 32 3b 0a 20  Data[0]) + s2;. 
7890: 20 20 20 20 20 73 32 20 2b 3d 20 42 59 54 45 53       s2 += BYTES
78a0: 57 41 50 33 32 28 61 44 61 74 61 5b 31 5d 29 20  WAP32(aData[1]) 
78b0: 2b 20 73 31 3b 0a 20 20 20 20 20 20 61 44 61 74  + s1;.      aDat
78c0: 61 20 2b 3d 20 32 3b 0a 20 20 20 20 7d 77 68 69  a += 2;.    }whi
78d0: 6c 65 28 20 61 44 61 74 61 3c 61 45 6e 64 20 29  le( aData<aEnd )
78e0: 3b 0a 20 20 7d 0a 0a 20 20 61 4f 75 74 5b 30 5d  ;.  }..  aOut[0]
78f0: 20 3d 20 73 31 3b 0a 20 20 61 4f 75 74 5b 31 5d   = s1;.  aOut[1]
7900: 20 3d 20 73 32 3b 0a 7d 0a 0a 73 74 61 74 69 63   = s2;.}..static
7910: 20 76 6f 69 64 20 77 61 6c 53 68 6d 42 61 72 72   void walShmBarr
7920: 69 65 72 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ier(Wal *pWal){.
7930: 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c    if( pWal->excl
7940: 75 73 69 76 65 4d 6f 64 65 21 3d 57 41 4c 5f 48  usiveMode!=WAL_H
7950: 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29  EAPMEMORY_MODE )
7960: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53  {.    sqlite3OsS
7970: 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c 2d 3e  hmBarrier(pWal->
7980: 70 44 62 46 64 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  pDbFd);.  }.}../
7990: 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68 65 20 68  *.** Write the h
79a0: 65 61 64 65 72 20 69 6e 66 6f 72 6d 61 74 69 6f  eader informatio
79b0: 6e 20 69 6e 20 70 57 61 6c 2d 3e 68 64 72 20 69  n in pWal->hdr i
79c0: 6e 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65  nto the wal-inde
79d0: 78 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65  x..**.** The che
79e0: 63 6b 73 75 6d 20 6f 6e 20 70 57 61 6c 2d 3e 68  cksum on pWal->h
79f0: 64 72 20 69 73 20 75 70 64 61 74 65 64 20 62 65  dr is updated be
7a00: 66 6f 72 65 20 69 74 20 69 73 20 77 72 69 74 74  fore it is writt
7a10: 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  en..*/.static vo
7a20: 69 64 20 77 61 6c 49 6e 64 65 78 57 72 69 74 65  id walIndexWrite
7a30: 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  Hdr(Wal *pWal){.
7a40: 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 49 6e    volatile WalIn
7a50: 64 65 78 48 64 72 20 2a 61 48 64 72 20 3d 20 77  dexHdr *aHdr = w
7a60: 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29  alIndexHdr(pWal)
7a70: 3b 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20 6e 43  ;.  const int nC
7a80: 6b 73 75 6d 20 3d 20 6f 66 66 73 65 74 6f 66 28  ksum = offsetof(
7a90: 57 61 6c 49 6e 64 65 78 48 64 72 2c 20 61 43 6b  WalIndexHdr, aCk
7aa0: 73 75 6d 29 3b 0a 0a 20 20 61 73 73 65 72 74 28  sum);..  assert(
7ab0: 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
7ac0: 20 29 3b 0a 20 20 70 57 61 6c 2d 3e 68 64 72 2e   );.  pWal->hdr.
7ad0: 69 73 49 6e 69 74 20 3d 20 31 3b 0a 20 20 70 57  isInit = 1;.  pW
7ae0: 61 6c 2d 3e 68 64 72 2e 69 56 65 72 73 69 6f 6e  al->hdr.iVersion
7af0: 20 3d 20 57 41 4c 49 4e 44 45 58 5f 4d 41 58 5f   = WALINDEX_MAX_
7b00: 56 45 52 53 49 4f 4e 3b 0a 20 20 77 61 6c 43 68  VERSION;.  walCh
7b10: 65 63 6b 73 75 6d 42 79 74 65 73 28 31 2c 20 28  ecksumBytes(1, (
7b20: 75 38 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c 20  u8*)&pWal->hdr, 
7b30: 6e 43 6b 73 75 6d 2c 20 30 2c 20 70 57 61 6c 2d  nCksum, 0, pWal-
7b40: 3e 68 64 72 2e 61 43 6b 73 75 6d 29 3b 0a 20 20  >hdr.aCksum);.  
7b50: 6d 65 6d 63 70 79 28 28 76 6f 69 64 2a 29 26 61  memcpy((void*)&a
7b60: 48 64 72 5b 31 5d 2c 20 28 63 6f 6e 73 74 20 76  Hdr[1], (const v
7b70: 6f 69 64 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c  oid*)&pWal->hdr,
7b80: 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
7b90: 48 64 72 29 29 3b 0a 20 20 77 61 6c 53 68 6d 42  Hdr));.  walShmB
7ba0: 61 72 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20  arrier(pWal);.  
7bb0: 6d 65 6d 63 70 79 28 28 76 6f 69 64 2a 29 26 61  memcpy((void*)&a
7bc0: 48 64 72 5b 30 5d 2c 20 28 63 6f 6e 73 74 20 76  Hdr[0], (const v
7bd0: 6f 69 64 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c  oid*)&pWal->hdr,
7be0: 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
7bf0: 48 64 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Hdr));.}../*.** 
7c00: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 65 6e  This function en
7c10: 63 6f 64 65 73 20 61 20 73 69 6e 67 6c 65 20 66  codes a single f
7c20: 72 61 6d 65 20 68 65 61 64 65 72 20 61 6e 64 20  rame header and 
7c30: 77 72 69 74 65 73 20 69 74 20 74 6f 20 61 20 62  writes it to a b
7c40: 75 66 66 65 72 0a 2a 2a 20 73 75 70 70 6c 69 65  uffer.** supplie
7c50: 64 20 62 79 20 74 68 65 20 63 61 6c 6c 65 72 2e  d by the caller.
7c60: 20 41 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20   A frame-header 
7c70: 69 73 20 6d 61 64 65 20 75 70 20 6f 66 20 61 20  is made up of a 
7c80: 73 65 72 69 65 73 20 6f 66 20 0a 2a 2a 20 34 2d  series of .** 4-
7c90: 62 79 74 65 20 62 69 67 2d 65 6e 64 69 61 6e 20  byte big-endian 
7ca0: 69 6e 74 65 67 65 72 73 2c 20 61 73 20 66 6f 6c  integers, as fol
7cb0: 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  lows:.**.**     
7cc0: 30 3a 20 50 61 67 65 20 6e 75 6d 62 65 72 2e 0a  0: Page number..
7cd0: 2a 2a 20 20 20 20 20 34 3a 20 46 6f 72 20 63 6f  **     4: For co
7ce0: 6d 6d 69 74 20 72 65 63 6f 72 64 73 2c 20 74 68  mmit records, th
7cf0: 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 64 61  e size of the da
7d00: 74 61 62 61 73 65 20 69 6d 61 67 65 20 69 6e 20  tabase image in 
7d10: 70 61 67 65 73 20 0a 2a 2a 20 20 20 20 20 20 20  pages .**       
7d20: 20 61 66 74 65 72 20 74 68 65 20 63 6f 6d 6d 69   after the commi
7d30: 74 2e 20 46 6f 72 20 61 6c 6c 20 6f 74 68 65 72  t. For all other
7d40: 20 72 65 63 6f 72 64 73 2c 20 7a 65 72 6f 2e 0a   records, zero..
7d50: 2a 2a 20 20 20 20 20 38 3a 20 53 61 6c 74 2d 31  **     8: Salt-1
7d60: 20 28 63 6f 70 69 65 64 20 66 72 6f 6d 20 74 68   (copied from th
7d70: 65 20 77 61 6c 2d 68 65 61 64 65 72 29 0a 2a 2a  e wal-header).**
7d80: 20 20 20 20 31 32 3a 20 53 61 6c 74 2d 32 20 28      12: Salt-2 (
7d90: 63 6f 70 69 65 64 20 66 72 6f 6d 20 74 68 65 20  copied from the 
7da0: 77 61 6c 2d 68 65 61 64 65 72 29 0a 2a 2a 20 20  wal-header).**  
7db0: 20 20 31 36 3a 20 43 68 65 63 6b 73 75 6d 2d 31    16: Checksum-1
7dc0: 2e 0a 2a 2a 20 20 20 20 32 30 3a 20 43 68 65 63  ..**    20: Chec
7dd0: 6b 73 75 6d 2d 32 2e 0a 2a 2f 0a 73 74 61 74 69  ksum-2..*/.stati
7de0: 63 20 76 6f 69 64 20 77 61 6c 45 6e 63 6f 64 65  c void walEncode
7df0: 46 72 61 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57  Frame(.  Wal *pW
7e00: 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
7e10: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
7e20: 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20  write-ahead log 
7e30: 2a 2f 0a 20 20 75 33 32 20 69 50 61 67 65 2c 20  */.  u32 iPage, 
7e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e50: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
7e60: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 66 6f 72   page number for
7e70: 20 66 72 61 6d 65 20 2a 2f 0a 20 20 75 33 32 20   frame */.  u32 
7e80: 6e 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20  nTruncate,      
7e90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
7ea0: 65 77 20 64 62 20 73 69 7a 65 20 28 6f 72 20 30  ew db size (or 0
7eb0: 20 66 6f 72 20 6e 6f 6e 2d 63 6f 6d 6d 69 74 20   for non-commit 
7ec0: 66 72 61 6d 65 73 29 20 2a 2f 0a 20 20 75 38 20  frames) */.  u8 
7ed0: 2a 61 44 61 74 61 2c 20 20 20 20 20 20 20 20 20  *aData,         
7ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7ef0: 50 6f 69 6e 74 65 72 20 74 6f 20 70 61 67 65 20  Pointer to page 
7f00: 64 61 74 61 20 2a 2f 0a 20 20 75 38 20 2a 61 46  data */.  u8 *aF
7f10: 72 61 6d 65 20 20 20 20 20 20 20 20 20 20 20 20  rame            
7f20: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
7f30: 3a 20 57 72 69 74 65 20 65 6e 63 6f 64 65 64 20  : Write encoded 
7f40: 66 72 61 6d 65 20 68 65 72 65 20 2a 2f 0a 29 7b  frame here */.){
7f50: 0a 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73  .  int nativeCks
7f60: 75 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  um;             
7f70: 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e     /* True for n
7f80: 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64 65 72  ative byte-order
7f90: 20 63 68 65 63 6b 73 75 6d 73 20 2a 2f 0a 20 20   checksums */.  
7fa0: 75 33 32 20 2a 61 43 6b 73 75 6d 20 3d 20 70 57  u32 *aCksum = pW
7fb0: 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
7fc0: 73 75 6d 3b 0a 20 20 61 73 73 65 72 74 28 20 57  sum;.  assert( W
7fd0: 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
7fe0: 3d 3d 32 34 20 29 3b 0a 20 20 73 71 6c 69 74 65  ==24 );.  sqlite
7ff0: 33 50 75 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Put4byte(&aFram
8000: 65 5b 30 5d 2c 20 69 50 61 67 65 29 3b 0a 20 20  e[0], iPage);.  
8010: 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28  sqlite3Put4byte(
8020: 26 61 46 72 61 6d 65 5b 34 5d 2c 20 6e 54 72 75  &aFrame[4], nTru
8030: 6e 63 61 74 65 29 3b 0a 20 20 69 66 28 20 70 57  ncate);.  if( pW
8040: 61 6c 2d 3e 69 52 65 43 6b 73 75 6d 3d 3d 30 20  al->iReCksum==0 
8050: 29 7b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 61  ){.    memcpy(&a
8060: 46 72 61 6d 65 5b 38 5d 2c 20 70 57 61 6c 2d 3e  Frame[8], pWal->
8070: 68 64 72 2e 61 53 61 6c 74 2c 20 38 29 3b 0a 0a  hdr.aSalt, 8);..
8080: 20 20 20 20 6e 61 74 69 76 65 43 6b 73 75 6d 20      nativeCksum 
8090: 3d 20 28 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67  = (pWal->hdr.big
80a0: 45 6e 64 43 6b 73 75 6d 3d 3d 53 51 4c 49 54 45  EndCksum==SQLITE
80b0: 5f 42 49 47 45 4e 44 49 41 4e 29 3b 0a 20 20 20  _BIGENDIAN);.   
80c0: 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65   walChecksumByte
80d0: 73 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 61  s(nativeCksum, a
80e0: 46 72 61 6d 65 2c 20 38 2c 20 61 43 6b 73 75 6d  Frame, 8, aCksum
80f0: 2c 20 61 43 6b 73 75 6d 29 3b 0a 20 20 20 20 77  , aCksum);.    w
8100: 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
8110: 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 61 44 61  nativeCksum, aDa
8120: 74 61 2c 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65  ta, pWal->szPage
8130: 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d  , aCksum, aCksum
8140: 29 3b 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 50  );..    sqlite3P
8150: 75 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b  ut4byte(&aFrame[
8160: 31 36 5d 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b  16], aCksum[0]);
8170: 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34  .    sqlite3Put4
8180: 62 79 74 65 28 26 61 46 72 61 6d 65 5b 32 30 5d  byte(&aFrame[20]
8190: 2c 20 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 20 20  , aCksum[1]);.  
81a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 6d 65 6d 73 65  }else{.    memse
81b0: 74 28 26 61 46 72 61 6d 65 5b 38 5d 2c 20 30 2c  t(&aFrame[8], 0,
81c0: 20 31 36 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a   16);.  }.}../*.
81d0: 2a 2a 20 43 68 65 63 6b 20 74 6f 20 73 65 65 20  ** Check to see 
81e0: 69 66 20 74 68 65 20 66 72 61 6d 65 20 77 69 74  if the frame wit
81f0: 68 20 68 65 61 64 65 72 20 69 6e 20 61 46 72 61  h header in aFra
8200: 6d 65 5b 5d 20 61 6e 64 20 63 6f 6e 74 65 6e 74  me[] and content
8210: 0a 2a 2a 20 69 6e 20 61 44 61 74 61 5b 5d 20 69  .** in aData[] i
8220: 73 20 76 61 6c 69 64 2e 20 20 49 66 20 69 74 20  s valid.  If it 
8230: 69 73 20 61 20 76 61 6c 69 64 20 66 72 61 6d 65  is a valid frame
8240: 2c 20 66 69 6c 6c 20 2a 70 69 50 61 67 65 20 61  , fill *piPage a
8250: 6e 64 0a 2a 2a 20 2a 70 6e 54 72 75 6e 63 61 74  nd.** *pnTruncat
8260: 65 20 61 6e 64 20 72 65 74 75 72 6e 20 74 72 75  e and return tru
8270: 65 2e 20 20 52 65 74 75 72 6e 20 69 66 20 74 68  e.  Return if th
8280: 65 20 66 72 61 6d 65 20 69 73 20 6e 6f 74 20 76  e frame is not v
8290: 61 6c 69 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  alid..*/.static 
82a0: 69 6e 74 20 77 61 6c 44 65 63 6f 64 65 46 72 61  int walDecodeFra
82b0: 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c  me(.  Wal *pWal,
82c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
82d0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 77 72 69        /* The wri
82e0: 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 2a 2f 0a  te-ahead log */.
82f0: 20 20 75 33 32 20 2a 70 69 50 61 67 65 2c 20 20    u32 *piPage,  
8300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8310: 20 20 2f 2a 20 4f 55 54 3a 20 44 61 74 61 62 61    /* OUT: Databa
8320: 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 66  se page number f
8330: 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20 20 75 33  or frame */.  u3
8340: 32 20 2a 70 6e 54 72 75 6e 63 61 74 65 2c 20 20  2 *pnTruncate,  
8350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8360: 20 4f 55 54 3a 20 4e 65 77 20 64 62 20 73 69 7a   OUT: New db siz
8370: 65 20 28 6f 72 20 30 20 69 66 20 6e 6f 74 20 63  e (or 0 if not c
8380: 6f 6d 6d 69 74 29 20 2a 2f 0a 20 20 75 38 20 2a  ommit) */.  u8 *
8390: 61 44 61 74 61 2c 20 20 20 20 20 20 20 20 20 20  aData,          
83a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
83b0: 6f 69 6e 74 65 72 20 74 6f 20 70 61 67 65 20 64  ointer to page d
83c0: 61 74 61 20 28 66 6f 72 20 63 68 65 63 6b 73 75  ata (for checksu
83d0: 6d 29 20 2a 2f 0a 20 20 75 38 20 2a 61 46 72 61  m) */.  u8 *aFra
83e0: 6d 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20  me              
83f0: 20 20 20 20 20 20 20 20 2f 2a 20 46 72 61 6d 65          /* Frame
8400: 20 64 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e   data */.){.  in
8410: 74 20 6e 61 74 69 76 65 43 6b 73 75 6d 3b 20 20  t nativeCksum;  
8420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8430: 20 54 72 75 65 20 66 6f 72 20 6e 61 74 69 76 65   True for native
8440: 20 62 79 74 65 2d 6f 72 64 65 72 20 63 68 65 63   byte-order chec
8450: 6b 73 75 6d 73 20 2a 2f 0a 20 20 75 33 32 20 2a  ksums */.  u32 *
8460: 61 43 6b 73 75 6d 20 3d 20 70 57 61 6c 2d 3e 68  aCksum = pWal->h
8470: 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 3b 0a  dr.aFrameCksum;.
8480: 20 20 75 33 32 20 70 67 6e 6f 3b 20 20 20 20 20    u32 pgno;     
8490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
84a0: 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72    /* Page number
84b0: 20 6f 66 20 74 68 65 20 66 72 61 6d 65 20 2a 2f   of the frame */
84c0: 0a 20 20 61 73 73 65 72 74 28 20 57 41 4c 5f 46  .  assert( WAL_F
84d0: 52 41 4d 45 5f 48 44 52 53 49 5a 45 3d 3d 32 34  RAME_HDRSIZE==24
84e0: 20 29 3b 0a 0a 20 20 2f 2a 20 41 20 66 72 61 6d   );..  /* A fram
84f0: 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20  e is only valid 
8500: 69 66 20 74 68 65 20 73 61 6c 74 20 76 61 6c 75  if the salt valu
8510: 65 73 20 69 6e 20 74 68 65 20 66 72 61 6d 65 2d  es in the frame-
8520: 68 65 61 64 65 72 0a 20 20 2a 2a 20 6d 61 74 63  header.  ** matc
8530: 68 20 74 68 65 20 73 61 6c 74 20 76 61 6c 75 65  h the salt value
8540: 73 20 69 6e 20 74 68 65 20 77 61 6c 2d 68 65 61  s in the wal-hea
8550: 64 65 72 2e 20 0a 20 20 2a 2f 0a 20 20 69 66 28  der. .  */.  if(
8560: 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68   memcmp(&pWal->h
8570: 64 72 2e 61 53 61 6c 74 2c 20 26 61 46 72 61 6d  dr.aSalt, &aFram
8580: 65 5b 38 5d 2c 20 38 29 21 3d 30 20 29 7b 0a 20  e[8], 8)!=0 ){. 
8590: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d     return 0;.  }
85a0: 0a 0a 20 20 2f 2a 20 41 20 66 72 61 6d 65 20 69  ..  /* A frame i
85b0: 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20 69 66 20  s only valid if 
85c0: 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  the page number 
85d0: 69 73 20 63 72 65 61 74 65 72 20 74 68 61 6e 20  is creater than 
85e0: 7a 65 72 6f 2e 0a 20 20 2a 2f 0a 20 20 70 67 6e  zero..  */.  pgn
85f0: 6f 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62  o = sqlite3Get4b
8600: 79 74 65 28 26 61 46 72 61 6d 65 5b 30 5d 29 3b  yte(&aFrame[0]);
8610: 0a 20 20 69 66 28 20 70 67 6e 6f 3d 3d 30 20 29  .  if( pgno==0 )
8620: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  {.    return 0;.
8630: 20 20 7d 0a 0a 20 20 2f 2a 20 41 20 66 72 61 6d    }..  /* A fram
8640: 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20  e is only valid 
8650: 69 66 20 61 20 63 68 65 63 6b 73 75 6d 20 6f 66  if a checksum of
8660: 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72 2c   the WAL header,
8670: 0a 20 20 2a 2a 20 61 6c 6c 20 70 72 69 6f 72 20  .  ** all prior 
8680: 66 72 61 6d 73 2c 20 74 68 65 20 66 69 72 73 74  frams, the first
8690: 20 31 36 20 62 79 74 65 73 20 6f 66 20 74 68 69   16 bytes of thi
86a0: 73 20 66 72 61 6d 65 2d 68 65 61 64 65 72 2c 20  s frame-header, 
86b0: 0a 20 20 2a 2a 20 61 6e 64 20 74 68 65 20 66 72  .  ** and the fr
86c0: 61 6d 65 2d 64 61 74 61 20 6d 61 74 63 68 65 73  ame-data matches
86d0: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 69 6e   the checksum in
86e0: 20 74 68 65 20 6c 61 73 74 20 38 20 0a 20 20 2a   the last 8 .  *
86f0: 2a 20 62 79 74 65 73 20 6f 66 20 74 68 69 73 20  * bytes of this 
8700: 66 72 61 6d 65 2d 68 65 61 64 65 72 2e 0a 20 20  frame-header..  
8710: 2a 2f 0a 20 20 6e 61 74 69 76 65 43 6b 73 75 6d  */.  nativeCksum
8720: 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72 2e 62 69   = (pWal->hdr.bi
8730: 67 45 6e 64 43 6b 73 75 6d 3d 3d 53 51 4c 49 54  gEndCksum==SQLIT
8740: 45 5f 42 49 47 45 4e 44 49 41 4e 29 3b 0a 20 20  E_BIGENDIAN);.  
8750: 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73  walChecksumBytes
8760: 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 61 46  (nativeCksum, aF
8770: 72 61 6d 65 2c 20 38 2c 20 61 43 6b 73 75 6d 2c  rame, 8, aCksum,
8780: 20 61 43 6b 73 75 6d 29 3b 0a 20 20 77 61 6c 43   aCksum);.  walC
8790: 68 65 63 6b 73 75 6d 42 79 74 65 73 28 6e 61 74  hecksumBytes(nat
87a0: 69 76 65 43 6b 73 75 6d 2c 20 61 44 61 74 61 2c  iveCksum, aData,
87b0: 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 2c 20 61   pWal->szPage, a
87c0: 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a  Cksum, aCksum);.
87d0: 20 20 69 66 28 20 61 43 6b 73 75 6d 5b 30 5d 21    if( aCksum[0]!
87e0: 3d 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65  =sqlite3Get4byte
87f0: 28 26 61 46 72 61 6d 65 5b 31 36 5d 29 20 0a 20  (&aFrame[16]) . 
8800: 20 20 7c 7c 20 61 43 6b 73 75 6d 5b 31 5d 21 3d    || aCksum[1]!=
8810: 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
8820: 26 61 46 72 61 6d 65 5b 32 30 5d 29 20 0a 20 20  &aFrame[20]) .  
8830: 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65 63 6b 73  ){.    /* Checks
8840: 75 6d 20 66 61 69 6c 65 64 2e 20 2a 2f 0a 20 20  um failed. */.  
8850: 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a    return 0;.  }.
8860: 0a 20 20 2f 2a 20 49 66 20 77 65 20 72 65 61 63  .  /* If we reac
8870: 68 20 74 68 69 73 20 70 6f 69 6e 74 2c 20 74 68  h this point, th
8880: 65 20 66 72 61 6d 65 20 69 73 20 76 61 6c 69 64  e frame is valid
8890: 2e 20 20 52 65 74 75 72 6e 20 74 68 65 20 70 61  .  Return the pa
88a0: 67 65 20 6e 75 6d 62 65 72 0a 20 20 2a 2a 20 61  ge number.  ** a
88b0: 6e 64 20 74 68 65 20 6e 65 77 20 64 61 74 61 62  nd the new datab
88c0: 61 73 65 20 73 69 7a 65 2e 0a 20 20 2a 2f 0a 20  ase size..  */. 
88d0: 20 2a 70 69 50 61 67 65 20 3d 20 70 67 6e 6f 3b   *piPage = pgno;
88e0: 0a 20 20 2a 70 6e 54 72 75 6e 63 61 74 65 20 3d  .  *pnTruncate =
88f0: 20 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65   sqlite3Get4byte
8900: 28 26 61 46 72 61 6d 65 5b 34 5d 29 3b 0a 20 20  (&aFrame[4]);.  
8910: 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 0a 23 69  return 1;.}...#i
8920: 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  f defined(SQLITE
8930: 5f 54 45 53 54 29 20 26 26 20 64 65 66 69 6e 65  _TEST) && define
8940: 64 28 53 51 4c 49 54 45 5f 44 45 42 55 47 29 0a  d(SQLITE_DEBUG).
8950: 2f 2a 0a 2a 2a 20 4e 61 6d 65 73 20 6f 66 20 6c  /*.** Names of l
8960: 6f 63 6b 73 2e 20 20 54 68 69 73 20 72 6f 75 74  ocks.  This rout
8970: 69 6e 65 20 69 73 20 75 73 65 64 20 74 6f 20 70  ine is used to p
8980: 72 6f 76 69 64 65 20 64 65 62 75 67 67 69 6e 67  rovide debugging
8990: 20 6f 75 74 70 75 74 20 61 6e 64 20 69 73 20 6e   output and is n
89a0: 6f 74 0a 2a 2a 20 61 20 70 61 72 74 20 6f 66 20  ot.** a part of 
89b0: 61 6e 20 6f 72 64 69 6e 61 72 79 20 62 75 69 6c  an ordinary buil
89c0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e  d..*/.static con
89d0: 73 74 20 63 68 61 72 20 2a 77 61 6c 4c 6f 63 6b  st char *walLock
89e0: 4e 61 6d 65 28 69 6e 74 20 6c 6f 63 6b 49 64 78  Name(int lockIdx
89f0: 29 7b 0a 20 20 69 66 28 20 6c 6f 63 6b 49 64 78  ){.  if( lockIdx
8a00: 3d 3d 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b  ==WAL_WRITE_LOCK
8a10: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 22   ){.    return "
8a20: 57 52 49 54 45 2d 4c 4f 43 4b 22 3b 0a 20 20 7d  WRITE-LOCK";.  }
8a30: 65 6c 73 65 20 69 66 28 20 6c 6f 63 6b 49 64 78  else if( lockIdx
8a40: 3d 3d 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20  ==WAL_CKPT_LOCK 
8a50: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 22 43  ){.    return "C
8a60: 4b 50 54 2d 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c  KPT-LOCK";.  }el
8a70: 73 65 20 69 66 28 20 6c 6f 63 6b 49 64 78 3d 3d  se if( lockIdx==
8a80: 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b  WAL_RECOVER_LOCK
8a90: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 22   ){.    return "
8aa0: 52 45 43 4f 56 45 52 2d 4c 4f 43 4b 22 3b 0a 20  RECOVER-LOCK";. 
8ab0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 74 61 74   }else{.    stat
8ac0: 69 63 20 63 68 61 72 20 7a 4e 61 6d 65 5b 31 35  ic char zName[15
8ad0: 5d 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73  ];.    sqlite3_s
8ae0: 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f 66 28 7a  nprintf(sizeof(z
8af0: 4e 61 6d 65 29 2c 20 7a 4e 61 6d 65 2c 20 22 52  Name), zName, "R
8b00: 45 41 44 2d 4c 4f 43 4b 5b 25 64 5d 22 2c 0a 20  EAD-LOCK[%d]",. 
8b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b20: 20 20 20 20 6c 6f 63 6b 49 64 78 2d 57 41 4c 5f      lockIdx-WAL_
8b30: 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20  READ_LOCK(0));. 
8b40: 20 20 20 72 65 74 75 72 6e 20 7a 4e 61 6d 65 3b     return zName;
8b50: 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a  .  }.}.#endif /*
8b60: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54  defined(SQLITE_T
8b70: 45 53 54 29 20 7c 7c 20 64 65 66 69 6e 65 64 28  EST) || defined(
8b80: 53 51 4c 49 54 45 5f 44 45 42 55 47 29 20 2a 2f  SQLITE_DEBUG) */
8b90: 0a 20 20 20 20 0a 0a 2f 2a 0a 2a 2a 20 53 65 74  .    ../*.** Set
8ba0: 20 6f 72 20 72 65 6c 65 61 73 65 20 6c 6f 63 6b   or release lock
8bb0: 73 20 6f 6e 20 74 68 65 20 57 41 4c 2e 20 20 4c  s on the WAL.  L
8bc0: 6f 63 6b 73 20 61 72 65 20 65 69 74 68 65 72 20  ocks are either 
8bd0: 73 68 61 72 65 64 20 6f 72 20 65 78 63 6c 75 73  shared or exclus
8be0: 69 76 65 2e 0a 2a 2a 20 41 20 6c 6f 63 6b 20 63  ive..** A lock c
8bf0: 61 6e 6e 6f 74 20 62 65 20 6d 6f 76 65 64 20 64  annot be moved d
8c00: 69 72 65 63 74 6c 79 20 62 65 74 77 65 65 6e 20  irectly between 
8c10: 73 68 61 72 65 64 20 61 6e 64 20 65 78 63 6c 75  shared and exclu
8c20: 73 69 76 65 20 2d 20 69 74 20 6d 75 73 74 20 67  sive - it must g
8c30: 6f 0a 2a 2a 20 74 68 72 6f 75 67 68 20 74 68 65  o.** through the
8c40: 20 75 6e 6c 6f 63 6b 65 64 20 73 74 61 74 65 20   unlocked state 
8c50: 66 69 72 73 74 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20  first..**.** In 
8c60: 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43  locking_mode=EXC
8c70: 4c 55 53 49 56 45 2c 20 61 6c 6c 20 6f 66 20 74  LUSIVE, all of t
8c80: 68 65 73 65 20 72 6f 75 74 69 6e 65 73 20 62 65  hese routines be
8c90: 63 6f 6d 65 20 6e 6f 2d 6f 70 73 2e 0a 2a 2f 0a  come no-ops..*/.
8ca0: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 4c 6f  static int walLo
8cb0: 63 6b 53 68 61 72 65 64 28 57 61 6c 20 2a 70 57  ckShared(Wal *pW
8cc0: 61 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 29  al, int lockIdx)
8cd0: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 66  {.  int rc;.  if
8ce0: 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76  ( pWal->exclusiv
8cf0: 65 4d 6f 64 65 20 29 20 72 65 74 75 72 6e 20 53  eMode ) return S
8d00: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72 63 20 3d  QLITE_OK;.  rc =
8d10: 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63   sqlite3OsShmLoc
8d20: 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c  k(pWal->pDbFd, l
8d30: 6f 63 6b 49 64 78 2c 20 31 2c 0a 20 20 20 20 20  ockIdx, 1,.     
8d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8d50: 20 20 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f     SQLITE_SHM_LO
8d60: 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f  CK | SQLITE_SHM_
8d70: 53 48 41 52 45 44 29 3b 0a 20 20 57 41 4c 54 52  SHARED);.  WALTR
8d80: 41 43 45 28 28 22 57 41 4c 25 70 3a 20 61 63 71  ACE(("WAL%p: acq
8d90: 75 69 72 65 20 53 48 41 52 45 44 2d 25 73 20 25  uire SHARED-%s %
8da0: 73 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20 20 20 20  s\n", pWal,.    
8db0: 20 20 20 20 20 20 20 20 77 61 6c 4c 6f 63 6b 4e          walLockN
8dc0: 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c 20 72 63  ame(lockIdx), rc
8dd0: 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f   ? "failed" : "o
8de0: 6b 22 29 29 3b 0a 20 20 56 56 41 5f 4f 4e 4c 59  k"));.  VVA_ONLY
8df0: 28 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f  ( pWal->lockErro
8e00: 72 20 3d 20 28 75 38 29 28 72 63 21 3d 53 51 4c  r = (u8)(rc!=SQL
8e10: 49 54 45 5f 4f 4b 20 26 26 20 72 63 21 3d 53 51  ITE_OK && rc!=SQ
8e20: 4c 49 54 45 5f 42 55 53 59 29 3b 20 29 0a 20 20  LITE_BUSY); ).  
8e30: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61  return rc;.}.sta
8e40: 74 69 63 20 76 6f 69 64 20 77 61 6c 55 6e 6c 6f  tic void walUnlo
8e50: 63 6b 53 68 61 72 65 64 28 57 61 6c 20 2a 70 57  ckShared(Wal *pW
8e60: 61 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 29  al, int lockIdx)
8e70: 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78  {.  if( pWal->ex
8e80: 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65  clusiveMode ) re
8e90: 74 75 72 6e 3b 0a 20 20 28 76 6f 69 64 29 73 71  turn;.  (void)sq
8ea0: 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70  lite3OsShmLock(p
8eb0: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b  Wal->pDbFd, lock
8ec0: 49 64 78 2c 20 31 2c 0a 20 20 20 20 20 20 20 20  Idx, 1,.        
8ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ee0: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f   SQLITE_SHM_UNLO
8ef0: 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f  CK | SQLITE_SHM_
8f00: 53 48 41 52 45 44 29 3b 0a 20 20 57 41 4c 54 52  SHARED);.  WALTR
8f10: 41 43 45 28 28 22 57 41 4c 25 70 3a 20 72 65 6c  ACE(("WAL%p: rel
8f20: 65 61 73 65 20 53 48 41 52 45 44 2d 25 73 5c 6e  ease SHARED-%s\n
8f30: 22 2c 20 70 57 61 6c 2c 20 77 61 6c 4c 6f 63 6b  ", pWal, walLock
8f40: 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 29 29 3b  Name(lockIdx)));
8f50: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  .}.static int wa
8f60: 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 57  lLockExclusive(W
8f70: 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f  al *pWal, int lo
8f80: 63 6b 49 64 78 2c 20 69 6e 74 20 6e 29 7b 0a 20  ckIdx, int n){. 
8f90: 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 70   int rc;.  if( p
8fa0: 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
8fb0: 64 65 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  de ) return SQLI
8fc0: 54 45 5f 4f 4b 3b 0a 20 20 72 63 20 3d 20 73 71  TE_OK;.  rc = sq
8fd0: 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70  lite3OsShmLock(p
8fe0: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b  Wal->pDbFd, lock
8ff0: 49 64 78 2c 20 6e 2c 0a 20 20 20 20 20 20 20 20  Idx, n,.        
9000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9010: 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20  SQLITE_SHM_LOCK 
9020: 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f 45 58 43  | SQLITE_SHM_EXC
9030: 4c 55 53 49 56 45 29 3b 0a 20 20 57 41 4c 54 52  LUSIVE);.  WALTR
9040: 41 43 45 28 28 22 57 41 4c 25 70 3a 20 61 63 71  ACE(("WAL%p: acq
9050: 75 69 72 65 20 45 58 43 4c 55 53 49 56 45 2d 25  uire EXCLUSIVE-%
9060: 73 20 63 6e 74 3d 25 64 20 25 73 5c 6e 22 2c 20  s cnt=%d %s\n", 
9070: 70 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20  pWal,.          
9080: 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f    walLockName(lo
9090: 63 6b 49 64 78 29 2c 20 6e 2c 20 72 63 20 3f 20  ckIdx), n, rc ? 
90a0: 22 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29  "failed" : "ok")
90b0: 29 3b 0a 20 20 56 56 41 5f 4f 4e 4c 59 28 20 70  );.  VVA_ONLY( p
90c0: 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d  Wal->lockError =
90d0: 20 28 75 38 29 28 72 63 21 3d 53 51 4c 49 54 45   (u8)(rc!=SQLITE
90e0: 5f 4f 4b 20 26 26 20 72 63 21 3d 53 51 4c 49 54  _OK && rc!=SQLIT
90f0: 45 5f 42 55 53 59 29 3b 20 29 0a 20 20 72 65 74  E_BUSY); ).  ret
9100: 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63  urn rc;.}.static
9110: 20 76 6f 69 64 20 77 61 6c 55 6e 6c 6f 63 6b 45   void walUnlockE
9120: 78 63 6c 75 73 69 76 65 28 57 61 6c 20 2a 70 57  xclusive(Wal *pW
9130: 61 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 2c  al, int lockIdx,
9140: 20 69 6e 74 20 6e 29 7b 0a 20 20 69 66 28 20 70   int n){.  if( p
9150: 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
9160: 64 65 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 28  de ) return;.  (
9170: 76 6f 69 64 29 73 71 6c 69 74 65 33 4f 73 53 68  void)sqlite3OsSh
9180: 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46  mLock(pWal->pDbF
9190: 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c 0a 20  d, lockIdx, n,. 
91a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
91b0: 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53          SQLITE_S
91c0: 48 4d 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51 4c 49  HM_UNLOCK | SQLI
91d0: 54 45 5f 53 48 4d 5f 45 58 43 4c 55 53 49 56 45  TE_SHM_EXCLUSIVE
91e0: 29 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  );.  WALTRACE(("
91f0: 57 41 4c 25 70 3a 20 72 65 6c 65 61 73 65 20 45  WAL%p: release E
9200: 58 43 4c 55 53 49 56 45 2d 25 73 20 63 6e 74 3d  XCLUSIVE-%s cnt=
9210: 25 64 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20 20 20  %d\n", pWal,.   
9220: 20 20 20 20 20 20 20 20 20 20 77 61 6c 4c 6f 63            walLoc
9230: 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c 20  kName(lockIdx), 
9240: 6e 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f  n));.}../*.** Co
9250: 6d 70 75 74 65 20 61 20 68 61 73 68 20 6f 6e 20  mpute a hash on 
9260: 61 20 70 61 67 65 20 6e 75 6d 62 65 72 2e 20 20  a page number.  
9270: 54 68 65 20 72 65 73 75 6c 74 69 6e 67 20 68 61  The resulting ha
9280: 73 68 20 76 61 6c 75 65 20 6d 75 73 74 20 6c 61  sh value must la
9290: 6e 64 0a 2a 2a 20 62 65 74 77 65 65 6e 20 30 20  nd.** between 0 
92a0: 61 6e 64 20 28 48 41 53 48 54 41 42 4c 45 5f 4e  and (HASHTABLE_N
92b0: 53 4c 4f 54 2d 31 29 2e 20 20 54 68 65 20 77 61  SLOT-1).  The wa
92c0: 6c 48 61 73 68 4e 65 78 74 28 29 20 66 75 6e 63  lHashNext() func
92d0: 74 69 6f 6e 20 61 64 76 61 6e 63 65 73 0a 2a 2a  tion advances.**
92e0: 20 74 68 65 20 68 61 73 68 20 74 6f 20 74 68 65   the hash to the
92f0: 20 6e 65 78 74 20 76 61 6c 75 65 20 69 6e 20 74   next value in t
9300: 68 65 20 65 76 65 6e 74 20 6f 66 20 61 20 63 6f  he event of a co
9310: 6c 6c 69 73 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74  llision..*/.stat
9320: 69 63 20 69 6e 74 20 77 61 6c 48 61 73 68 28 75  ic int walHash(u
9330: 33 32 20 69 50 61 67 65 29 7b 0a 20 20 61 73 73  32 iPage){.  ass
9340: 65 72 74 28 20 69 50 61 67 65 3e 30 20 29 3b 0a  ert( iPage>0 );.
9350: 20 20 61 73 73 65 72 74 28 20 28 48 41 53 48 54    assert( (HASHT
9360: 41 42 4c 45 5f 4e 53 4c 4f 54 20 26 20 28 48 41  ABLE_NSLOT & (HA
9370: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29  SHTABLE_NSLOT-1)
9380: 29 3d 3d 30 20 29 3b 0a 20 20 72 65 74 75 72 6e  )==0 );.  return
9390: 20 28 69 50 61 67 65 2a 48 41 53 48 54 41 42 4c   (iPage*HASHTABL
93a0: 45 5f 48 41 53 48 5f 31 29 20 26 20 28 48 41 53  E_HASH_1) & (HAS
93b0: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 3b  HTABLE_NSLOT-1);
93c0: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  .}.static int wa
93d0: 6c 4e 65 78 74 48 61 73 68 28 69 6e 74 20 69 50  lNextHash(int iP
93e0: 72 69 6f 72 48 61 73 68 29 7b 0a 20 20 72 65 74  riorHash){.  ret
93f0: 75 72 6e 20 28 69 50 72 69 6f 72 48 61 73 68 2b  urn (iPriorHash+
9400: 31 29 26 28 48 41 53 48 54 41 42 4c 45 5f 4e 53  1)&(HASHTABLE_NS
9410: 4c 4f 54 2d 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  LOT-1);.}../*.**
9420: 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   An instance of 
9430: 74 68 65 20 57 61 6c 48 61 73 68 4c 6f 63 20 6f  the WalHashLoc o
9440: 62 6a 65 63 74 20 69 73 20 75 73 65 64 20 74 6f  bject is used to
9450: 20 64 65 73 63 72 69 62 65 20 74 68 65 20 6c 6f   describe the lo
9460: 63 61 74 69 6f 6e 0a 2a 2a 20 6f 66 20 61 20 70  cation.** of a p
9470: 61 67 65 20 68 61 73 68 20 74 61 62 6c 65 20 69  age hash table i
9480: 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e  n the wal-index.
9490: 20 20 54 68 69 73 20 62 65 63 6f 6d 65 73 20 74    This becomes t
94a0: 68 65 20 72 65 74 75 72 6e 20 76 61 6c 75 65 0a  he return value.
94b0: 2a 2a 20 66 72 6f 6d 20 77 61 6c 48 61 73 68 47  ** from walHashG
94c0: 65 74 28 29 2e 0a 2a 2f 0a 74 79 70 65 64 65 66  et()..*/.typedef
94d0: 20 73 74 72 75 63 74 20 57 61 6c 48 61 73 68 4c   struct WalHashL
94e0: 6f 63 20 57 61 6c 48 61 73 68 4c 6f 63 3b 0a 73  oc WalHashLoc;.s
94f0: 74 72 75 63 74 20 57 61 6c 48 61 73 68 4c 6f 63  truct WalHashLoc
9500: 20 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 68 74   {.  volatile ht
9510: 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b 20 20 2f  _slot *aHash;  /
9520: 2a 20 53 74 61 72 74 20 6f 66 20 74 68 65 20 77  * Start of the w
9530: 61 6c 2d 69 6e 64 65 78 20 68 61 73 68 20 74 61  al-index hash ta
9540: 62 6c 65 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c  ble */.  volatil
9550: 65 20 75 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20  e u32 *aPgno;   
9560: 20 20 20 2f 2a 20 61 50 67 6e 6f 5b 31 5d 20 69     /* aPgno[1] i
9570: 73 20 74 68 65 20 70 61 67 65 20 6f 66 20 66 69  s the page of fi
9580: 72 73 74 20 66 72 61 6d 65 20 69 6e 64 65 78 65  rst frame indexe
9590: 64 20 2a 2f 0a 20 20 75 33 32 20 69 5a 65 72 6f  d */.  u32 iZero
95a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
95b0: 20 2f 2a 20 4f 6e 65 20 6c 65 73 73 20 74 68 61   /* One less tha
95c0: 6e 20 74 68 65 20 66 72 61 6d 65 20 6e 75 6d 62  n the frame numb
95d0: 65 72 20 6f 66 20 66 69 72 73 74 20 69 6e 64 65  er of first inde
95e0: 78 65 64 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 0a 2a 2a  xed*/.};../* .**
95f0: 20 52 65 74 75 72 6e 20 70 6f 69 6e 74 65 72 73   Return pointers
9600: 20 74 6f 20 74 68 65 20 68 61 73 68 20 74 61 62   to the hash tab
9610: 6c 65 20 61 6e 64 20 70 61 67 65 20 6e 75 6d 62  le and page numb
9620: 65 72 20 61 72 72 61 79 20 73 74 6f 72 65 64 20  er array stored 
9630: 6f 6e 0a 2a 2a 20 70 61 67 65 20 69 48 61 73 68  on.** page iHash
9640: 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
9650: 78 2e 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78  x. The wal-index
9660: 20 69 73 20 62 72 6f 6b 65 6e 20 69 6e 74 6f 20   is broken into 
9670: 33 32 4b 42 20 70 61 67 65 73 0a 2a 2a 20 6e 75  32KB pages.** nu
9680: 6d 62 65 72 65 64 20 73 74 61 72 74 69 6e 67 20  mbered starting 
9690: 66 72 6f 6d 20 30 2e 0a 2a 2a 0a 2a 2a 20 53 65  from 0..**.** Se
96a0: 74 20 6f 75 74 70 75 74 20 76 61 72 69 61 62 6c  t output variabl
96b0: 65 20 70 4c 6f 63 2d 3e 61 48 61 73 68 20 74 6f  e pLoc->aHash to
96c0: 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74   point to the st
96d0: 61 72 74 20 6f 66 20 74 68 65 20 68 61 73 68 20  art of the hash 
96e0: 74 61 62 6c 65 0a 2a 2a 20 69 6e 20 74 68 65 20  table.** in the 
96f0: 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 2e 20  wal-index file. 
9700: 53 65 74 20 70 4c 6f 63 2d 3e 69 5a 65 72 6f 20  Set pLoc->iZero 
9710: 74 6f 20 6f 6e 65 20 6c 65 73 73 20 74 68 61 6e  to one less than
9720: 20 74 68 65 20 66 72 61 6d 65 20 0a 2a 2a 20 6e   the frame .** n
9730: 75 6d 62 65 72 20 6f 66 20 74 68 65 20 66 69 72  umber of the fir
9740: 73 74 20 66 72 61 6d 65 20 69 6e 64 65 78 65 64  st frame indexed
9750: 20 62 79 20 74 68 69 73 20 68 61 73 68 20 74 61   by this hash ta
9760: 62 6c 65 2e 20 49 66 20 61 0a 2a 2a 20 73 6c 6f  ble. If a.** slo
9770: 74 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61  t in the hash ta
9780: 62 6c 65 20 69 73 20 73 65 74 20 74 6f 20 4e 2c  ble is set to N,
9790: 20 69 74 20 72 65 66 65 72 73 20 74 6f 20 66 72   it refers to fr
97a0: 61 6d 65 20 6e 75 6d 62 65 72 20 0a 2a 2a 20 28  ame number .** (
97b0: 70 4c 6f 63 2d 3e 69 5a 65 72 6f 2b 4e 29 20 69  pLoc->iZero+N) i
97c0: 6e 20 74 68 65 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a  n the log..**.**
97d0: 20 46 69 6e 61 6c 6c 79 2c 20 73 65 74 20 70 4c   Finally, set pL
97e0: 6f 63 2d 3e 61 50 67 6e 6f 20 73 6f 20 74 68 61  oc->aPgno so tha
97f0: 74 20 70 4c 6f 63 2d 3e 61 50 67 6e 6f 5b 31 5d  t pLoc->aPgno[1]
9800: 20 69 73 20 74 68 65 20 70 61 67 65 20 6e 75 6d   is the page num
9810: 62 65 72 20 6f 66 20 74 68 65 0a 2a 2a 20 66 69  ber of the.** fi
9820: 72 73 74 20 66 72 61 6d 65 20 69 6e 64 65 78 65  rst frame indexe
9830: 64 20 62 79 20 74 68 65 20 68 61 73 68 20 74 61  d by the hash ta
9840: 62 6c 65 2c 20 66 72 61 6d 65 20 28 70 4c 6f 63  ble, frame (pLoc
9850: 2d 3e 69 5a 65 72 6f 2b 31 29 2e 0a 2a 2f 0a 73  ->iZero+1)..*/.s
9860: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 48 61 73  tatic int walHas
9870: 68 47 65 74 28 0a 20 20 57 61 6c 20 2a 70 57 61  hGet(.  Wal *pWa
9880: 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
9890: 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 68          /* WAL h
98a0: 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 69  andle */.  int i
98b0: 48 61 73 68 2c 20 20 20 20 20 20 20 20 20 20 20  Hash,           
98c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
98d0: 6e 64 20 74 68 65 20 69 48 61 73 68 27 74 68 20  nd the iHash'th 
98e0: 74 61 62 6c 65 20 2a 2f 0a 20 20 57 61 6c 48 61  table */.  WalHa
98f0: 73 68 4c 6f 63 20 2a 70 4c 6f 63 20 20 20 20 20  shLoc *pLoc     
9900: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
9910: 54 3a 20 48 61 73 68 20 74 61 62 6c 65 20 6c 6f  T: Hash table lo
9920: 63 61 74 69 6f 6e 20 2a 2f 0a 29 7b 0a 20 20 69  cation */.){.  i
9930: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
9940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9950: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
9960: 0a 0a 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65  ..  rc = walInde
9970: 78 50 61 67 65 28 70 57 61 6c 2c 20 69 48 61 73  xPage(pWal, iHas
9980: 68 2c 20 26 70 4c 6f 63 2d 3e 61 50 67 6e 6f 29  h, &pLoc->aPgno)
9990: 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d  ;.  assert( rc==
99a0: 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 69 48 61  SQLITE_OK || iHa
99b0: 73 68 3e 30 20 29 3b 0a 0a 20 20 69 66 28 20 72  sh>0 );..  if( r
99c0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
99d0: 20 20 20 20 70 4c 6f 63 2d 3e 61 48 61 73 68 20      pLoc->aHash 
99e0: 3d 20 28 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73  = (volatile ht_s
99f0: 6c 6f 74 20 2a 29 26 70 4c 6f 63 2d 3e 61 50 67  lot *)&pLoc->aPg
9a00: 6e 6f 5b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  no[HASHTABLE_NPA
9a10: 47 45 5d 3b 0a 20 20 20 20 69 66 28 20 69 48 61  GE];.    if( iHa
9a20: 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 70  sh==0 ){.      p
9a30: 4c 6f 63 2d 3e 61 50 67 6e 6f 20 3d 20 26 70 4c  Loc->aPgno = &pL
9a40: 6f 63 2d 3e 61 50 67 6e 6f 5b 57 41 4c 49 4e 44  oc->aPgno[WALIND
9a50: 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65  EX_HDR_SIZE/size
9a60: 6f 66 28 75 33 32 29 5d 3b 0a 20 20 20 20 20 20  of(u32)];.      
9a70: 70 4c 6f 63 2d 3e 69 5a 65 72 6f 20 3d 20 30 3b  pLoc->iZero = 0;
9a80: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
9a90: 20 20 70 4c 6f 63 2d 3e 69 5a 65 72 6f 20 3d 20    pLoc->iZero = 
9aa0: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
9ab0: 4f 4e 45 20 2b 20 28 69 48 61 73 68 2d 31 29 2a  ONE + (iHash-1)*
9ac0: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3b  HASHTABLE_NPAGE;
9ad0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 4c 6f 63 2d  .    }.    pLoc-
9ae0: 3e 61 50 67 6e 6f 20 3d 20 26 70 4c 6f 63 2d 3e  >aPgno = &pLoc->
9af0: 61 50 67 6e 6f 5b 2d 31 5d 3b 0a 20 20 7d 0a 20  aPgno[-1];.  }. 
9b00: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
9b10: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
9b20: 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 77 61  number of the wa
9b30: 6c 2d 69 6e 64 65 78 20 70 61 67 65 20 74 68 61  l-index page tha
9b40: 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 68  t contains the h
9b50: 61 73 68 2d 74 61 62 6c 65 0a 2a 2a 20 61 6e 64  ash-table.** and
9b60: 20 70 61 67 65 2d 6e 75 6d 62 65 72 20 61 72 72   page-number arr
9b70: 61 79 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 20  ay that contain 
9b80: 65 6e 74 72 69 65 73 20 63 6f 72 72 65 73 70 6f  entries correspo
9b90: 6e 64 69 6e 67 20 74 6f 20 57 41 4c 20 66 72 61  nding to WAL fra
9ba0: 6d 65 0a 2a 2a 20 69 46 72 61 6d 65 2e 20 54 68  me.** iFrame. Th
9bb0: 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 62  e wal-index is b
9bc0: 72 6f 6b 65 6e 20 75 70 20 69 6e 74 6f 20 33 32  roken up into 32
9bd0: 4b 42 20 70 61 67 65 73 2e 20 57 61 6c 2d 69 6e  KB pages. Wal-in
9be0: 64 65 78 20 70 61 67 65 73 20 0a 2a 2a 20 61 72  dex pages .** ar
9bf0: 65 20 6e 75 6d 62 65 72 65 64 20 73 74 61 72 74  e numbered start
9c00: 69 6e 67 20 66 72 6f 6d 20 30 2e 0a 2a 2f 0a 73  ing from 0..*/.s
9c10: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 46 72 61  tatic int walFra
9c20: 6d 65 50 61 67 65 28 75 33 32 20 69 46 72 61 6d  mePage(u32 iFram
9c30: 65 29 7b 0a 20 20 69 6e 74 20 69 48 61 73 68 20  e){.  int iHash 
9c40: 3d 20 28 69 46 72 61 6d 65 2b 48 41 53 48 54 41  = (iFrame+HASHTA
9c50: 42 4c 45 5f 4e 50 41 47 45 2d 48 41 53 48 54 41  BLE_NPAGE-HASHTA
9c60: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2d 31 29  BLE_NPAGE_ONE-1)
9c70: 20 2f 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41   / HASHTABLE_NPA
9c80: 47 45 3b 0a 20 20 61 73 73 65 72 74 28 20 28 69  GE;.  assert( (i
9c90: 48 61 73 68 3d 3d 30 20 7c 7c 20 69 46 72 61 6d  Hash==0 || iFram
9ca0: 65 3e 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  e>HASHTABLE_NPAG
9cb0: 45 5f 4f 4e 45 29 0a 20 20 20 20 20 20 20 26 26  E_ONE).       &&
9cc0: 20 28 69 48 61 73 68 3e 3d 31 20 7c 7c 20 69 46   (iHash>=1 || iF
9cd0: 72 61 6d 65 3c 3d 48 41 53 48 54 41 42 4c 45 5f  rame<=HASHTABLE_
9ce0: 4e 50 41 47 45 5f 4f 4e 45 29 0a 20 20 20 20 20  NPAGE_ONE).     
9cf0: 20 20 26 26 20 28 69 48 61 73 68 3c 3d 31 20 7c    && (iHash<=1 |
9d00: 7c 20 69 46 72 61 6d 65 3e 28 48 41 53 48 54 41  | iFrame>(HASHTA
9d10: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 48 41  BLE_NPAGE_ONE+HA
9d20: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 29 29 0a  SHTABLE_NPAGE)).
9d30: 20 20 20 20 20 20 20 26 26 20 28 69 48 61 73 68         && (iHash
9d40: 3e 3d 32 20 7c 7c 20 69 46 72 61 6d 65 3c 3d 48  >=2 || iFrame<=H
9d50: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
9d60: 4e 45 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  NE+HASHTABLE_NPA
9d70: 47 45 29 0a 20 20 20 20 20 20 20 26 26 20 28 69  GE).       && (i
9d80: 48 61 73 68 3c 3d 32 20 7c 7c 20 69 46 72 61 6d  Hash<=2 || iFram
9d90: 65 3e 28 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  e>(HASHTABLE_NPA
9da0: 47 45 5f 4f 4e 45 2b 32 2a 48 41 53 48 54 41 42  GE_ONE+2*HASHTAB
9db0: 4c 45 5f 4e 50 41 47 45 29 29 0a 20 20 29 3b 0a  LE_NPAGE)).  );.
9dc0: 20 20 72 65 74 75 72 6e 20 69 48 61 73 68 3b 0a    return iHash;.
9dd0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
9de0: 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  the page number 
9df0: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20  associated with 
9e00: 66 72 61 6d 65 20 69 46 72 61 6d 65 20 69 6e 20  frame iFrame in 
9e10: 74 68 69 73 20 57 41 4c 2e 0a 2a 2f 0a 73 74 61  this WAL..*/.sta
9e20: 74 69 63 20 75 33 32 20 77 61 6c 46 72 61 6d 65  tic u32 walFrame
9e30: 50 67 6e 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Pgno(Wal *pWal, 
9e40: 75 33 32 20 69 46 72 61 6d 65 29 7b 0a 20 20 69  u32 iFrame){.  i
9e50: 6e 74 20 69 48 61 73 68 20 3d 20 77 61 6c 46 72  nt iHash = walFr
9e60: 61 6d 65 50 61 67 65 28 69 46 72 61 6d 65 29 3b  amePage(iFrame);
9e70: 0a 20 20 69 66 28 20 69 48 61 73 68 3d 3d 30 20  .  if( iHash==0 
9e80: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 57  ){.    return pW
9e90: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 5b  al->apWiData[0][
9ea0: 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a  WALINDEX_HDR_SIZ
9eb0: 45 2f 73 69 7a 65 6f 66 28 75 33 32 29 20 2b 20  E/sizeof(u32) + 
9ec0: 69 46 72 61 6d 65 20 2d 20 31 5d 3b 0a 20 20 7d  iFrame - 1];.  }
9ed0: 0a 20 20 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e  .  return pWal->
9ee0: 61 70 57 69 44 61 74 61 5b 69 48 61 73 68 5d 5b  apWiData[iHash][
9ef0: 28 69 46 72 61 6d 65 2d 31 2d 48 41 53 48 54 41  (iFrame-1-HASHTA
9f00: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 25 48  BLE_NPAGE_ONE)%H
9f10: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5d 3b  ASHTABLE_NPAGE];
9f20: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65  .}../*.** Remove
9f30: 20 65 6e 74 72 69 65 73 20 66 72 6f 6d 20 74 68   entries from th
9f40: 65 20 68 61 73 68 20 74 61 62 6c 65 20 74 68 61  e hash table tha
9f50: 74 20 70 6f 69 6e 74 20 74 6f 20 57 41 4c 20 73  t point to WAL s
9f60: 6c 6f 74 73 20 67 72 65 61 74 65 72 0a 2a 2a 20  lots greater.** 
9f70: 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  than pWal->hdr.m
9f80: 78 46 72 61 6d 65 2e 0a 2a 2a 0a 2a 2a 20 54 68  xFrame..**.** Th
9f90: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
9fa0: 61 6c 6c 65 64 20 77 68 65 6e 65 76 65 72 20 70  alled whenever p
9fb0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
9fc0: 20 69 73 20 64 65 63 72 65 61 73 65 64 20 64 75   is decreased du
9fd0: 65 0a 2a 2a 20 74 6f 20 61 20 72 6f 6c 6c 62 61  e.** to a rollba
9fe0: 63 6b 20 6f 72 20 73 61 76 65 70 6f 69 6e 74 2e  ck or savepoint.
9ff0: 0a 2a 2a 0a 2a 2a 20 41 74 20 6d 6f 73 74 20 6f  .**.** At most o
a000: 6e 6c 79 20 74 68 65 20 68 61 73 68 20 74 61 62  nly the hash tab
a010: 6c 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 70 57  le containing pW
a020: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
a030: 6e 65 65 64 73 20 74 6f 20 62 65 0a 2a 2a 20 75  needs to be.** u
a040: 70 64 61 74 65 64 2e 20 20 41 6e 79 20 6c 61 74  pdated.  Any lat
a050: 65 72 20 68 61 73 68 20 74 61 62 6c 65 73 20 77  er hash tables w
a060: 69 6c 6c 20 62 65 20 61 75 74 6f 6d 61 74 69 63  ill be automatic
a070: 61 6c 6c 79 20 63 6c 65 61 72 65 64 20 77 68 65  ally cleared whe
a080: 6e 0a 2a 2a 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  n.** pWal->hdr.m
a090: 78 46 72 61 6d 65 20 61 64 76 61 6e 63 65 73 20  xFrame advances 
a0a0: 74 6f 20 74 68 65 20 70 6f 69 6e 74 20 77 68 65  to the point whe
a0b0: 72 65 20 74 68 6f 73 65 20 68 61 73 68 20 74 61  re those hash ta
a0c0: 62 6c 65 73 20 61 72 65 0a 2a 2a 20 61 63 74 75  bles are.** actu
a0d0: 61 6c 6c 79 20 6e 65 65 64 65 64 2e 0a 2a 2f 0a  ally needed..*/.
a0e0: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 43  static void walC
a0f0: 6c 65 61 6e 75 70 48 61 73 68 28 57 61 6c 20 2a  leanupHash(Wal *
a100: 70 57 61 6c 29 7b 0a 20 20 57 61 6c 48 61 73 68  pWal){.  WalHash
a110: 4c 6f 63 20 73 4c 6f 63 3b 20 20 20 20 20 20 20  Loc sLoc;       
a120: 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68           /* Hash
a130: 20 74 61 62 6c 65 20 6c 6f 63 61 74 69 6f 6e 20   table location 
a140: 2a 2f 0a 20 20 69 6e 74 20 69 4c 69 6d 69 74 20  */.  int iLimit 
a150: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
a160: 20 20 20 20 20 2f 2a 20 5a 65 72 6f 20 76 61 6c       /* Zero val
a170: 75 65 73 20 67 72 65 61 74 65 72 20 74 68 61 6e  ues greater than
a180: 20 74 68 69 73 20 2a 2f 0a 20 20 69 6e 74 20 6e   this */.  int n
a190: 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20  Byte;           
a1a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
a1b0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f  mber of bytes to
a1c0: 20 7a 65 72 6f 20 69 6e 20 61 50 67 6e 6f 5b 5d   zero in aPgno[]
a1d0: 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20   */.  int i;    
a1e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a1f0: 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f        /* Used to
a200: 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68   iterate through
a210: 20 61 48 61 73 68 5b 5d 20 2a 2f 0a 20 20 69 6e   aHash[] */.  in
a220: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
a230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
a240: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 66 6f 72   Return code for
a250: 6d 20 77 61 6c 48 61 73 68 47 65 74 28 29 20 2a  m walHashGet() *
a260: 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  /..  assert( pWa
a270: 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a  l->writeLock );.
a280: 20 20 74 65 73 74 63 61 73 65 28 20 70 57 61 6c    testcase( pWal
a290: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 48  ->hdr.mxFrame==H
a2a0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
a2b0: 4e 45 2d 31 20 29 3b 0a 20 20 74 65 73 74 63 61  NE-1 );.  testca
a2c0: 73 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  se( pWal->hdr.mx
a2d0: 46 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45  Frame==HASHTABLE
a2e0: 5f 4e 50 41 47 45 5f 4f 4e 45 20 29 3b 0a 20 20  _NPAGE_ONE );.  
a2f0: 74 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d 3e  testcase( pWal->
a300: 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 48 41 53  hdr.mxFrame==HAS
a310: 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45  HTABLE_NPAGE_ONE
a320: 2b 31 20 29 3b 0a 0a 20 20 69 66 28 20 70 57 61  +1 );..  if( pWa
a330: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d  l->hdr.mxFrame==
a340: 30 20 29 20 72 65 74 75 72 6e 3b 0a 0a 20 20 2f  0 ) return;..  /
a350: 2a 20 4f 62 74 61 69 6e 20 70 6f 69 6e 74 65 72  * Obtain pointer
a360: 73 20 74 6f 20 74 68 65 20 68 61 73 68 2d 74 61  s to the hash-ta
a370: 62 6c 65 20 61 6e 64 20 70 61 67 65 2d 6e 75 6d  ble and page-num
a380: 62 65 72 20 61 72 72 61 79 20 63 6f 6e 74 61 69  ber array contai
a390: 6e 69 6e 67 20 0a 20 20 2a 2a 20 74 68 65 20 65  ning .  ** the e
a3a0: 6e 74 72 79 20 74 68 61 74 20 63 6f 72 72 65 73  ntry that corres
a3b0: 70 6f 6e 64 73 20 74 6f 20 66 72 61 6d 65 20 70  ponds to frame p
a3c0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
a3d0: 2e 20 49 74 20 69 73 20 67 75 61 72 61 6e 74 65  . It is guarante
a3e0: 65 64 0a 20 20 2a 2a 20 74 68 61 74 20 74 68 65  ed.  ** that the
a3f0: 20 70 61 67 65 20 73 61 69 64 20 68 61 73 68 2d   page said hash-
a400: 74 61 62 6c 65 20 61 6e 64 20 61 72 72 61 79 20  table and array 
a410: 72 65 73 69 64 65 20 6f 6e 20 69 73 20 61 6c 72  reside on is alr
a420: 65 61 64 79 20 6d 61 70 70 65 64 2e 28 31 29 0a  eady mapped.(1).
a430: 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
a440: 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 77 61 6c  Wal->nWiData>wal
a450: 46 72 61 6d 65 50 61 67 65 28 70 57 61 6c 2d 3e  FramePage(pWal->
a460: 68 64 72 2e 6d 78 46 72 61 6d 65 29 20 29 3b 0a  hdr.mxFrame) );.
a470: 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
a480: 61 70 57 69 44 61 74 61 5b 77 61 6c 46 72 61 6d  apWiData[walFram
a490: 65 50 61 67 65 28 70 57 61 6c 2d 3e 68 64 72 2e  ePage(pWal->hdr.
a4a0: 6d 78 46 72 61 6d 65 29 5d 20 29 3b 0a 20 20 72  mxFrame)] );.  r
a4b0: 63 20 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70  c = walHashGet(p
a4c0: 57 61 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61 67  Wal, walFramePag
a4d0: 65 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  e(pWal->hdr.mxFr
a4e0: 61 6d 65 29 2c 20 26 73 4c 6f 63 29 3b 0a 20 20  ame), &sLoc);.  
a4f0: 69 66 28 20 4e 45 56 45 52 28 72 63 29 20 29 20  if( NEVER(rc) ) 
a500: 72 65 74 75 72 6e 3b 20 2f 2a 20 44 65 66 65 6e  return; /* Defen
a510: 73 65 2d 69 6e 2d 64 65 70 74 68 2c 20 69 6e 20  se-in-depth, in 
a520: 63 61 73 65 20 28 31 29 20 61 62 6f 76 65 20 69  case (1) above i
a530: 73 20 77 72 6f 6e 67 20 2a 2f 0a 0a 20 20 2f 2a  s wrong */..  /*
a540: 20 5a 65 72 6f 20 61 6c 6c 20 68 61 73 68 2d 74   Zero all hash-t
a550: 61 62 6c 65 20 65 6e 74 72 69 65 73 20 74 68 61  able entries tha
a560: 74 20 63 6f 72 72 65 73 70 6f 6e 64 20 74 6f 20  t correspond to 
a570: 66 72 61 6d 65 20 6e 75 6d 62 65 72 73 20 67 72  frame numbers gr
a580: 65 61 74 65 72 0a 20 20 2a 2a 20 74 68 61 6e 20  eater.  ** than 
a590: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
a5a0: 65 2e 0a 20 20 2a 2f 0a 20 20 69 4c 69 6d 69 74  e..  */.  iLimit
a5b0: 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46   = pWal->hdr.mxF
a5c0: 72 61 6d 65 20 2d 20 73 4c 6f 63 2e 69 5a 65 72  rame - sLoc.iZer
a5d0: 6f 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4c 69  o;.  assert( iLi
a5e0: 6d 69 74 3e 30 20 29 3b 0a 20 20 66 6f 72 28 69  mit>0 );.  for(i
a5f0: 3d 30 3b 20 69 3c 48 41 53 48 54 41 42 4c 45 5f  =0; i<HASHTABLE_
a600: 4e 53 4c 4f 54 3b 20 69 2b 2b 29 7b 0a 20 20 20  NSLOT; i++){.   
a610: 20 69 66 28 20 73 4c 6f 63 2e 61 48 61 73 68 5b   if( sLoc.aHash[
a620: 69 5d 3e 69 4c 69 6d 69 74 20 29 7b 0a 20 20 20  i]>iLimit ){.   
a630: 20 20 20 73 4c 6f 63 2e 61 48 61 73 68 5b 69 5d     sLoc.aHash[i]
a640: 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   = 0;.    }.  }.
a650: 20 20 0a 20 20 2f 2a 20 5a 65 72 6f 20 74 68 65    .  /* Zero the
a660: 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20   entries in the 
a670: 61 50 67 6e 6f 20 61 72 72 61 79 20 74 68 61 74  aPgno array that
a680: 20 63 6f 72 72 65 73 70 6f 6e 64 20 74 6f 20 66   correspond to f
a690: 72 61 6d 65 73 20 77 69 74 68 0a 20 20 2a 2a 20  rames with.  ** 
a6a0: 66 72 61 6d 65 20 6e 75 6d 62 65 72 73 20 67 72  frame numbers gr
a6b0: 65 61 74 65 72 20 74 68 61 6e 20 70 57 61 6c 2d  eater than pWal-
a6c0: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 20 0a 20  >hdr.mxFrame. . 
a6d0: 20 2a 2f 0a 20 20 6e 42 79 74 65 20 3d 20 28 69   */.  nByte = (i
a6e0: 6e 74 29 28 28 63 68 61 72 20 2a 29 73 4c 6f 63  nt)((char *)sLoc
a6f0: 2e 61 48 61 73 68 20 2d 20 28 63 68 61 72 20 2a  .aHash - (char *
a700: 29 26 73 4c 6f 63 2e 61 50 67 6e 6f 5b 69 4c 69  )&sLoc.aPgno[iLi
a710: 6d 69 74 2b 31 5d 29 3b 0a 20 20 6d 65 6d 73 65  mit+1]);.  memse
a720: 74 28 28 76 6f 69 64 20 2a 29 26 73 4c 6f 63 2e  t((void *)&sLoc.
a730: 61 50 67 6e 6f 5b 69 4c 69 6d 69 74 2b 31 5d 2c  aPgno[iLimit+1],
a740: 20 30 2c 20 6e 42 79 74 65 29 3b 0a 0a 23 69 66   0, nByte);..#if
a750: 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c  def SQLITE_ENABL
a760: 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53 53 45  E_EXPENSIVE_ASSE
a770: 52 54 0a 20 20 2f 2a 20 56 65 72 69 66 79 20 74  RT.  /* Verify t
a780: 68 61 74 20 74 68 65 20 65 76 65 72 79 20 65 6e  hat the every en
a790: 74 72 79 20 69 6e 20 74 68 65 20 6d 61 70 70 69  try in the mappi
a7a0: 6e 67 20 72 65 67 69 6f 6e 20 69 73 20 73 74 69  ng region is sti
a7b0: 6c 6c 20 72 65 61 63 68 61 62 6c 65 0a 20 20 2a  ll reachable.  *
a7c0: 2a 20 76 69 61 20 74 68 65 20 68 61 73 68 20 74  * via the hash t
a7d0: 61 62 6c 65 20 65 76 65 6e 20 61 66 74 65 72 20  able even after 
a7e0: 74 68 65 20 63 6c 65 61 6e 75 70 2e 0a 20 20 2a  the cleanup..  *
a7f0: 2f 0a 20 20 69 66 28 20 69 4c 69 6d 69 74 20 29  /.  if( iLimit )
a800: 7b 0a 20 20 20 20 69 6e 74 20 6a 3b 20 20 20 20  {.    int j;    
a810: 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63         /* Loop c
a820: 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20 20 69 6e  ounter */.    in
a830: 74 20 69 4b 65 79 3b 20 20 20 20 20 20 20 20 2f  t iKey;        /
a840: 2a 20 48 61 73 68 20 6b 65 79 20 2a 2f 0a 20 20  * Hash key */.  
a850: 20 20 66 6f 72 28 6a 3d 31 3b 20 6a 3c 3d 69 4c    for(j=1; j<=iL
a860: 69 6d 69 74 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20  imit; j++){.    
a870: 20 20 66 6f 72 28 69 4b 65 79 3d 77 61 6c 48 61    for(iKey=walHa
a880: 73 68 28 73 4c 6f 63 2e 61 50 67 6e 6f 5b 6a 5d  sh(sLoc.aPgno[j]
a890: 29 3b 73 4c 6f 63 2e 61 48 61 73 68 5b 69 4b 65  );sLoc.aHash[iKe
a8a0: 79 5d 3b 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48  y];iKey=walNextH
a8b0: 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20  ash(iKey)){.    
a8c0: 20 20 20 20 69 66 28 20 73 4c 6f 63 2e 61 48 61      if( sLoc.aHa
a8d0: 73 68 5b 69 4b 65 79 5d 3d 3d 6a 20 29 20 62 72  sh[iKey]==j ) br
a8e0: 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
a8f0: 20 20 20 61 73 73 65 72 74 28 20 73 4c 6f 63 2e     assert( sLoc.
a900: 61 48 61 73 68 5b 69 4b 65 79 5d 3d 3d 6a 20 29  aHash[iKey]==j )
a910: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 23 65 6e 64  ;.    }.  }.#end
a920: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
a930: 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53  BLE_EXPENSIVE_AS
a940: 53 45 52 54 20 2a 2f 0a 7d 0a 0a 0a 2f 2a 0a 2a  SERT */.}.../*.*
a950: 2a 20 53 65 74 20 61 6e 20 65 6e 74 72 79 20 69  * Set an entry i
a960: 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  n the wal-index 
a970: 74 68 61 74 20 77 69 6c 6c 20 6d 61 70 20 64 61  that will map da
a980: 74 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62  tabase page numb
a990: 65 72 0a 2a 2a 20 70 50 61 67 65 20 69 6e 74 6f  er.** pPage into
a9a0: 20 57 41 4c 20 66 72 61 6d 65 20 69 46 72 61 6d   WAL frame iFram
a9b0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
a9c0: 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64 28   walIndexAppend(
a9d0: 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 69  Wal *pWal, u32 i
a9e0: 46 72 61 6d 65 2c 20 75 33 32 20 69 50 61 67 65  Frame, u32 iPage
a9f0: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  ){.  int rc;    
aa00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aa10: 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
aa20: 6f 64 65 20 2a 2f 0a 20 20 57 61 6c 48 61 73 68  ode */.  WalHash
aa30: 4c 6f 63 20 73 4c 6f 63 3b 20 20 20 20 20 20 20  Loc sLoc;       
aa40: 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 2d           /* Wal-
aa50: 69 6e 64 65 78 20 68 61 73 68 20 74 61 62 6c 65  index hash table
aa60: 20 6c 6f 63 61 74 69 6f 6e 20 2a 2f 0a 0a 20 20   location */..  
aa70: 72 63 20 3d 20 77 61 6c 48 61 73 68 47 65 74 28  rc = walHashGet(
aa80: 70 57 61 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61  pWal, walFramePa
aa90: 67 65 28 69 46 72 61 6d 65 29 2c 20 26 73 4c 6f  ge(iFrame), &sLo
aaa0: 63 29 3b 0a 0a 20 20 2f 2a 20 41 73 73 75 6d 69  c);..  /* Assumi
aab0: 6e 67 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  ng the wal-index
aac0: 20 66 69 6c 65 20 77 61 73 20 73 75 63 63 65 73   file was succes
aad0: 73 66 75 6c 6c 79 20 6d 61 70 70 65 64 2c 20 70  sfully mapped, p
aae0: 6f 70 75 6c 61 74 65 20 74 68 65 0a 20 20 2a 2a  opulate the.  **
aaf0: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72   page number arr
ab00: 61 79 20 61 6e 64 20 68 61 73 68 20 74 61 62 6c  ay and hash tabl
ab10: 65 20 65 6e 74 72 79 2e 0a 20 20 2a 2f 0a 20 20  e entry..  */.  
ab20: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
ab30: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 4b 65  K ){.    int iKe
ab40: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y;              
ab50: 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 74         /* Hash t
ab60: 61 62 6c 65 20 6b 65 79 20 2a 2f 0a 20 20 20 20  able key */.    
ab70: 69 6e 74 20 69 64 78 3b 20 20 20 20 20 20 20 20  int idx;        
ab80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
ab90: 20 56 61 6c 75 65 20 74 6f 20 77 72 69 74 65 20   Value to write 
aba0: 74 6f 20 68 61 73 68 2d 74 61 62 6c 65 20 73 6c  to hash-table sl
abb0: 6f 74 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 43  ot */.    int nC
abc0: 6f 6c 6c 69 64 65 3b 20 20 20 20 20 20 20 20 20  ollide;         
abd0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
abe0: 72 20 6f 66 20 68 61 73 68 20 63 6f 6c 6c 69 73  r of hash collis
abf0: 69 6f 6e 73 20 2a 2f 0a 0a 20 20 20 20 69 64 78  ions */..    idx
ac00: 20 3d 20 69 46 72 61 6d 65 20 2d 20 73 4c 6f 63   = iFrame - sLoc
ac10: 2e 69 5a 65 72 6f 3b 0a 20 20 20 20 61 73 73 65  .iZero;.    asse
ac20: 72 74 28 20 69 64 78 20 3c 3d 20 48 41 53 48 54  rt( idx <= HASHT
ac30: 41 42 4c 45 5f 4e 53 4c 4f 54 2f 32 20 2b 20 31  ABLE_NSLOT/2 + 1
ac40: 20 29 3b 0a 20 20 20 20 0a 20 20 20 20 2f 2a 20   );.    .    /* 
ac50: 49 66 20 74 68 69 73 20 69 73 20 74 68 65 20 66  If this is the f
ac60: 69 72 73 74 20 65 6e 74 72 79 20 74 6f 20 62 65  irst entry to be
ac70: 20 61 64 64 65 64 20 74 6f 20 74 68 69 73 20 68   added to this h
ac80: 61 73 68 2d 74 61 62 6c 65 2c 20 7a 65 72 6f 20  ash-table, zero 
ac90: 74 68 65 0a 20 20 20 20 2a 2a 20 65 6e 74 69 72  the.    ** entir
aca0: 65 20 68 61 73 68 20 74 61 62 6c 65 20 61 6e 64  e hash table and
acb0: 20 61 50 67 6e 6f 5b 5d 20 61 72 72 61 79 20 62   aPgno[] array b
acc0: 65 66 6f 72 65 20 70 72 6f 63 65 65 64 69 6e 67  efore proceeding
acd0: 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66  . .    */.    if
ace0: 28 20 69 64 78 3d 3d 31 20 29 7b 0a 20 20 20 20  ( idx==1 ){.    
acf0: 20 20 69 6e 74 20 6e 42 79 74 65 20 3d 20 28 69    int nByte = (i
ad00: 6e 74 29 28 28 75 38 20 2a 29 26 73 4c 6f 63 2e  nt)((u8 *)&sLoc.
ad10: 61 48 61 73 68 5b 48 41 53 48 54 41 42 4c 45 5f  aHash[HASHTABLE_
ad20: 4e 53 4c 4f 54 5d 0a 20 20 20 20 20 20 20 20 20  NSLOT].         
ad30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad40: 20 20 20 20 20 20 2d 20 28 75 38 20 2a 29 26 73        - (u8 *)&s
ad50: 4c 6f 63 2e 61 50 67 6e 6f 5b 31 5d 29 3b 0a 20  Loc.aPgno[1]);. 
ad60: 20 20 20 20 20 6d 65 6d 73 65 74 28 28 76 6f 69       memset((voi
ad70: 64 2a 29 26 73 4c 6f 63 2e 61 50 67 6e 6f 5b 31  d*)&sLoc.aPgno[1
ad80: 5d 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20  ], 0, nByte);.  
ad90: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74    }..    /* If t
ada0: 68 65 20 65 6e 74 72 79 20 69 6e 20 61 50 67 6e  he entry in aPgn
adb0: 6f 5b 5d 20 69 73 20 61 6c 72 65 61 64 79 20 73  o[] is already s
adc0: 65 74 2c 20 74 68 65 6e 20 74 68 65 20 70 72 65  et, then the pre
add0: 76 69 6f 75 73 20 77 72 69 74 65 72 0a 20 20 20  vious writer.   
ade0: 20 2a 2a 20 6d 75 73 74 20 68 61 76 65 20 65 78   ** must have ex
adf0: 69 74 65 64 20 75 6e 65 78 70 65 63 74 65 64 6c  ited unexpectedl
ae00: 79 20 69 6e 20 74 68 65 20 6d 69 64 64 6c 65 20  y in the middle 
ae10: 6f 66 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e  of a transaction
ae20: 20 28 61 66 74 65 72 0a 20 20 20 20 2a 2a 20 77   (after.    ** w
ae30: 72 69 74 69 6e 67 20 6f 6e 65 20 6f 72 20 6d 6f  riting one or mo
ae40: 72 65 20 64 69 72 74 79 20 70 61 67 65 73 20 74  re dirty pages t
ae50: 6f 20 74 68 65 20 57 41 4c 20 74 6f 20 66 72 65  o the WAL to fre
ae60: 65 20 75 70 20 6d 65 6d 6f 72 79 29 2e 20 0a 20  e up memory). . 
ae70: 20 20 20 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65     ** Remove the
ae80: 20 72 65 6d 6e 61 6e 74 73 20 6f 66 20 74 68 61   remnants of tha
ae90: 74 20 77 72 69 74 65 72 73 20 75 6e 63 6f 6d 6d  t writers uncomm
aea0: 69 74 74 65 64 20 74 72 61 6e 73 61 63 74 69 6f  itted transactio
aeb0: 6e 20 66 72 6f 6d 20 0a 20 20 20 20 2a 2a 20 74  n from .    ** t
aec0: 68 65 20 68 61 73 68 2d 74 61 62 6c 65 20 62 65  he hash-table be
aed0: 66 6f 72 65 20 77 72 69 74 69 6e 67 20 61 6e 79  fore writing any
aee0: 20 6e 65 77 20 65 6e 74 72 69 65 73 2e 0a 20 20   new entries..  
aef0: 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 73 4c 6f    */.    if( sLo
af00: 63 2e 61 50 67 6e 6f 5b 69 64 78 5d 20 29 7b 0a  c.aPgno[idx] ){.
af10: 20 20 20 20 20 20 77 61 6c 43 6c 65 61 6e 75 70        walCleanup
af20: 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 20 20  Hash(pWal);.    
af30: 20 20 61 73 73 65 72 74 28 20 21 73 4c 6f 63 2e    assert( !sLoc.
af40: 61 50 67 6e 6f 5b 69 64 78 5d 20 29 3b 0a 20 20  aPgno[idx] );.  
af50: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74    }..    /* Writ
af60: 65 20 74 68 65 20 61 50 67 6e 6f 5b 5d 20 61 72  e the aPgno[] ar
af70: 72 61 79 20 65 6e 74 72 79 20 61 6e 64 20 74 68  ray entry and th
af80: 65 20 68 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f  e hash-table slo
af90: 74 2e 20 2a 2f 0a 20 20 20 20 6e 43 6f 6c 6c 69  t. */.    nColli
afa0: 64 65 20 3d 20 69 64 78 3b 0a 20 20 20 20 66 6f  de = idx;.    fo
afb0: 72 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 69  r(iKey=walHash(i
afc0: 50 61 67 65 29 3b 20 73 4c 6f 63 2e 61 48 61 73  Page); sLoc.aHas
afd0: 68 5b 69 4b 65 79 5d 3b 20 69 4b 65 79 3d 77 61  h[iKey]; iKey=wa
afe0: 6c 4e 65 78 74 48 61 73 68 28 69 4b 65 79 29 29  lNextHash(iKey))
aff0: 7b 0a 20 20 20 20 20 20 69 66 28 20 28 6e 43 6f  {.      if( (nCo
b000: 6c 6c 69 64 65 2d 2d 29 3d 3d 30 20 29 20 72 65  llide--)==0 ) re
b010: 74 75 72 6e 20 53 51 4c 49 54 45 5f 43 4f 52 52  turn SQLITE_CORR
b020: 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20 20 7d 0a  UPT_BKPT;.    }.
b030: 20 20 20 20 73 4c 6f 63 2e 61 50 67 6e 6f 5b 69      sLoc.aPgno[i
b040: 64 78 5d 20 3d 20 69 50 61 67 65 3b 0a 20 20 20  dx] = iPage;.   
b050: 20 73 4c 6f 63 2e 61 48 61 73 68 5b 69 4b 65 79   sLoc.aHash[iKey
b060: 5d 20 3d 20 28 68 74 5f 73 6c 6f 74 29 69 64 78  ] = (ht_slot)idx
b070: 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  ;..#ifdef SQLITE
b080: 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56  _ENABLE_EXPENSIV
b090: 45 5f 41 53 53 45 52 54 0a 20 20 20 20 2f 2a 20  E_ASSERT.    /* 
b0a0: 56 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20  Verify that the 
b0b0: 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  number of entrie
b0c0: 73 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61  s in the hash ta
b0d0: 62 6c 65 20 65 78 61 63 74 6c 79 20 65 71 75 61  ble exactly equa
b0e0: 6c 73 0a 20 20 20 20 2a 2a 20 74 68 65 20 6e 75  ls.    ** the nu
b0f0: 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20  mber of entries 
b100: 69 6e 20 74 68 65 20 6d 61 70 70 69 6e 67 20 72  in the mapping r
b110: 65 67 69 6f 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20  egion..    */.  
b120: 20 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b    {.      int i;
b130: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f             /* Lo
b140: 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20  op counter */.  
b150: 20 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 20 3d      int nEntry =
b160: 20 30 3b 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f   0;  /* Number o
b170: 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65  f entries in the
b180: 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20   hash table */. 
b190: 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c       for(i=0; i<
b1a0: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b  HASHTABLE_NSLOT;
b1b0: 20 69 2b 2b 29 7b 20 69 66 28 20 73 4c 6f 63 2e   i++){ if( sLoc.
b1c0: 61 48 61 73 68 5b 69 5d 20 29 20 6e 45 6e 74 72  aHash[i] ) nEntr
b1d0: 79 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 61 73 73  y++; }.      ass
b1e0: 65 72 74 28 20 6e 45 6e 74 72 79 3d 3d 69 64 78  ert( nEntry==idx
b1f0: 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f   );.    }..    /
b200: 2a 20 56 65 72 69 66 79 20 74 68 61 74 20 74 68  * Verify that th
b210: 65 20 65 76 65 72 79 20 65 6e 74 72 79 20 69 6e  e every entry in
b220: 20 74 68 65 20 6d 61 70 70 69 6e 67 20 72 65 67   the mapping reg
b230: 69 6f 6e 20 69 73 20 72 65 61 63 68 61 62 6c 65  ion is reachable
b240: 0a 20 20 20 20 2a 2a 20 76 69 61 20 74 68 65 20  .    ** via the 
b250: 68 61 73 68 20 74 61 62 6c 65 2e 20 20 54 68 69  hash table.  Thi
b260: 73 20 74 75 72 6e 73 20 6f 75 74 20 74 6f 20 62  s turns out to b
b270: 65 20 61 20 72 65 61 6c 6c 79 2c 20 72 65 61 6c  e a really, real
b280: 6c 79 20 65 78 70 65 6e 73 69 76 65 0a 20 20 20  ly expensive.   
b290: 20 2a 2a 20 74 68 69 6e 67 20 74 6f 20 63 68 65   ** thing to che
b2a0: 63 6b 2c 20 73 6f 20 6f 6e 6c 79 20 64 6f 20 74  ck, so only do t
b2b0: 68 69 73 20 6f 63 63 61 73 69 6f 6e 61 6c 6c 79  his occasionally
b2c0: 20 2d 20 6e 6f 74 20 6f 6e 20 65 76 65 72 79 0a   - not on every.
b2d0: 20 20 20 20 2a 2a 20 69 74 65 72 61 74 69 6f 6e      ** iteration
b2e0: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28  ..    */.    if(
b2f0: 20 28 69 64 78 26 30 78 33 66 66 29 3d 3d 30 20   (idx&0x3ff)==0 
b300: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 20  ){.      int i; 
b310: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f            /* Loo
b320: 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20  p counter */.   
b330: 20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 3d 69     for(i=1; i<=i
b340: 64 78 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  dx; i++){.      
b350: 20 20 66 6f 72 28 69 4b 65 79 3d 77 61 6c 48 61    for(iKey=walHa
b360: 73 68 28 73 4c 6f 63 2e 61 50 67 6e 6f 5b 69 5d  sh(sLoc.aPgno[i]
b370: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  );.            s
b380: 4c 6f 63 2e 61 48 61 73 68 5b 69 4b 65 79 5d 3b  Loc.aHash[iKey];
b390: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 4b 65  .            iKe
b3a0: 79 3d 77 61 6c 4e 65 78 74 48 61 73 68 28 69 4b  y=walNextHash(iK
b3b0: 65 79 29 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ey)){.          
b3c0: 69 66 28 20 73 4c 6f 63 2e 61 48 61 73 68 5b 69  if( sLoc.aHash[i
b3d0: 4b 65 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b 3b  Key]==i ) break;
b3e0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
b3f0: 20 20 20 61 73 73 65 72 74 28 20 73 4c 6f 63 2e     assert( sLoc.
b400: 61 48 61 73 68 5b 69 4b 65 79 5d 3d 3d 69 20 29  aHash[iKey]==i )
b410: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
b420: 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45  #endif /* SQLITE
b430: 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56  _ENABLE_EXPENSIV
b440: 45 5f 41 53 53 45 52 54 20 2a 2f 0a 20 20 7d 0a  E_ASSERT */.  }.
b450: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
b460: 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 63 6f 76 65 72  .../*.** Recover
b470: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 62   the wal-index b
b480: 79 20 72 65 61 64 69 6e 67 20 74 68 65 20 77 72  y reading the wr
b490: 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69  ite-ahead log fi
b4a0: 6c 65 2e 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  le. .**.** This 
b4b0: 72 6f 75 74 69 6e 65 20 66 69 72 73 74 20 74 72  routine first tr
b4c0: 69 65 73 20 74 6f 20 65 73 74 61 62 6c 69 73 68  ies to establish
b4d0: 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c 6f   an exclusive lo
b4e0: 63 6b 20 6f 6e 20 74 68 65 0a 2a 2a 20 77 61 6c  ck on the.** wal
b4f0: 2d 69 6e 64 65 78 20 74 6f 20 70 72 65 76 65 6e  -index to preven
b500: 74 20 6f 74 68 65 72 20 74 68 72 65 61 64 73 2f  t other threads/
b510: 70 72 6f 63 65 73 73 65 73 20 66 72 6f 6d 20 64  processes from d
b520: 6f 69 6e 67 20 61 6e 79 74 68 69 6e 67 0a 2a 2a  oing anything.**
b530: 20 77 69 74 68 20 74 68 65 20 57 41 4c 20 6f 72   with the WAL or
b540: 20 77 61 6c 2d 69 6e 64 65 78 20 77 68 69 6c 65   wal-index while
b550: 20 72 65 63 6f 76 65 72 79 20 69 73 20 72 75 6e   recovery is run
b560: 6e 69 6e 67 2e 20 20 54 68 65 0a 2a 2a 20 57 41  ning.  The.** WA
b570: 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20 69  L_RECOVER_LOCK i
b580: 73 20 61 6c 73 6f 20 68 65 6c 64 20 73 6f 20 74  s also held so t
b590: 68 61 74 20 6f 74 68 65 72 20 74 68 72 65 61 64  hat other thread
b5a0: 73 20 77 69 6c 6c 20 6b 6e 6f 77 0a 2a 2a 20 74  s will know.** t
b5b0: 68 61 74 20 74 68 69 73 20 74 68 72 65 61 64 20  hat this thread 
b5c0: 69 73 20 72 75 6e 6e 69 6e 67 20 72 65 63 6f 76  is running recov
b5d0: 65 72 79 2e 20 20 49 66 20 75 6e 61 62 6c 65 20  ery.  If unable 
b5e0: 74 6f 20 65 73 74 61 62 6c 69 73 68 0a 2a 2a 20  to establish.** 
b5f0: 74 68 65 20 6e 65 63 65 73 73 61 72 79 20 6c 6f  the necessary lo
b600: 63 6b 73 2c 20 74 68 69 73 20 72 6f 75 74 69 6e  cks, this routin
b610: 65 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45  e returns SQLITE
b620: 5f 42 55 53 59 2e 0a 2a 2f 0a 73 74 61 74 69 63  _BUSY..*/.static
b630: 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 52 65 63   int walIndexRec
b640: 6f 76 65 72 28 57 61 6c 20 2a 70 57 61 6c 29 7b  over(Wal *pWal){
b650: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
b660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b670: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64     /* Return Cod
b680: 65 20 2a 2f 0a 20 20 69 36 34 20 6e 53 69 7a 65  e */.  i64 nSize
b690: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
b6a0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
b6b0: 66 20 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a 20 20  f log file */.  
b6c0: 75 33 32 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b  u32 aFrameCksum[
b6d0: 32 5d 20 3d 20 7b 30 2c 20 30 7d 3b 0a 20 20 69  2] = {0, 0};.  i
b6e0: 6e 74 20 69 4c 6f 63 6b 3b 20 20 20 20 20 20 20  nt iLock;       
b6f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
b700: 2a 20 4c 6f 63 6b 20 6f 66 66 73 65 74 20 74 6f  * Lock offset to
b710: 20 6c 6f 63 6b 20 66 6f 72 20 63 68 65 63 6b 70   lock for checkp
b720: 6f 69 6e 74 20 2a 2f 0a 0a 20 20 2f 2a 20 4f 62  oint */..  /* Ob
b730: 74 61 69 6e 20 61 6e 20 65 78 63 6c 75 73 69 76  tain an exclusiv
b740: 65 20 6c 6f 63 6b 20 6f 6e 20 61 6c 6c 20 62 79  e lock on all by
b750: 74 65 20 69 6e 20 74 68 65 20 6c 6f 63 6b 69 6e  te in the lockin
b760: 67 20 72 61 6e 67 65 20 6e 6f 74 20 61 6c 72 65  g range not alre
b770: 61 64 79 0a 20 20 2a 2a 20 6c 6f 63 6b 65 64 20  ady.  ** locked 
b780: 62 79 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 54  by the caller. T
b790: 68 65 20 63 61 6c 6c 65 72 20 69 73 20 67 75 61  he caller is gua
b7a0: 72 61 6e 74 65 65 64 20 74 6f 20 68 61 76 65 20  ranteed to have 
b7b0: 6c 6f 63 6b 65 64 20 74 68 65 0a 20 20 2a 2a 20  locked the.  ** 
b7c0: 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 62  WAL_WRITE_LOCK b
b7d0: 79 74 65 2c 20 61 6e 64 20 6d 61 79 20 68 61 76  yte, and may hav
b7e0: 65 20 61 6c 73 6f 20 6c 6f 63 6b 65 64 20 74 68  e also locked th
b7f0: 65 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20  e WAL_CKPT_LOCK 
b800: 62 79 74 65 2e 0a 20 20 2a 2a 20 49 66 20 73 75  byte..  ** If su
b810: 63 63 65 73 73 66 75 6c 2c 20 74 68 65 20 73 61  ccessful, the sa
b820: 6d 65 20 62 79 74 65 73 20 74 68 61 74 20 61 72  me bytes that ar
b830: 65 20 6c 6f 63 6b 65 64 20 68 65 72 65 20 61 72  e locked here ar
b840: 65 20 75 6e 6c 6f 63 6b 65 64 20 62 65 66 6f 72  e unlocked befor
b850: 65 0a 20 20 2a 2a 20 74 68 69 73 20 66 75 6e 63  e.  ** this func
b860: 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e 0a 20 20  tion returns..  
b870: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  */.  assert( pWa
b880: 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 31 20 7c  l->ckptLock==1 |
b890: 7c 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b  | pWal->ckptLock
b8a0: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
b8b0: 20 57 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49   WAL_ALL_BUT_WRI
b8c0: 54 45 3d 3d 57 41 4c 5f 57 52 49 54 45 5f 4c 4f  TE==WAL_WRITE_LO
b8d0: 43 4b 2b 31 20 29 3b 0a 20 20 61 73 73 65 72 74  CK+1 );.  assert
b8e0: 28 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 3d  ( WAL_CKPT_LOCK=
b8f0: 3d 57 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49  =WAL_ALL_BUT_WRI
b900: 54 45 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  TE );.  assert( 
b910: 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
b920: 29 3b 0a 20 20 69 4c 6f 63 6b 20 3d 20 57 41 4c  );.  iLock = WAL
b930: 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 2b  _ALL_BUT_WRITE +
b940: 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3b   pWal->ckptLock;
b950: 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45  .  rc = walLockE
b960: 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 69  xclusive(pWal, i
b970: 4c 6f 63 6b 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  Lock, WAL_READ_L
b980: 4f 43 4b 28 30 29 2d 69 4c 6f 63 6b 29 3b 0a 20  OCK(0)-iLock);. 
b990: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
b9a0: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 77  OK ){.    rc = w
b9b0: 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  alLockExclusive(
b9c0: 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  pWal, WAL_READ_L
b9d0: 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41  OCK(1), WAL_NREA
b9e0: 44 45 52 2d 31 29 3b 0a 20 20 20 20 69 66 28 20  DER-1);.    if( 
b9f0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
ba00: 0a 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b  .      walUnlock
ba10: 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
ba20: 69 4c 6f 63 6b 2c 20 57 41 4c 5f 52 45 41 44 5f  iLock, WAL_READ_
ba30: 4c 4f 43 4b 28 30 29 2d 69 4c 6f 63 6b 29 3b 0a  LOCK(0)-iLock);.
ba40: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20      }.  }.  if( 
ba50: 72 63 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  rc ){.    return
ba60: 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 57 41 4c 54   rc;.  }..  WALT
ba70: 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 72 65  RACE(("WAL%p: re
ba80: 63 6f 76 65 72 79 20 62 65 67 69 6e 2e 2e 2e 5c  covery begin...\
ba90: 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 0a 20 20 6d  n", pWal));..  m
baa0: 65 6d 73 65 74 28 26 70 57 61 6c 2d 3e 68 64 72  emset(&pWal->hdr
bab0: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49  , 0, sizeof(WalI
bac0: 6e 64 65 78 48 64 72 29 29 3b 0a 0a 20 20 72 63  ndexHdr));..  rc
bad0: 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65   = sqlite3OsFile
bae0: 53 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46  Size(pWal->pWalF
baf0: 64 2c 20 26 6e 53 69 7a 65 29 3b 0a 20 20 69 66  d, &nSize);.  if
bb00: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
bb10: 29 7b 0a 20 20 20 20 67 6f 74 6f 20 72 65 63 6f  ){.    goto reco
bb20: 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20 20 7d 0a  very_error;.  }.
bb30: 0a 20 20 69 66 28 20 6e 53 69 7a 65 3e 57 41 4c  .  if( nSize>WAL
bb40: 5f 48 44 52 53 49 5a 45 20 29 7b 0a 20 20 20 20  _HDRSIZE ){.    
bb50: 75 38 20 61 42 75 66 5b 57 41 4c 5f 48 44 52 53  u8 aBuf[WAL_HDRS
bb60: 49 5a 45 5d 3b 20 20 20 20 20 20 20 20 20 2f 2a  IZE];         /*
bb70: 20 42 75 66 66 65 72 20 74 6f 20 6c 6f 61 64 20   Buffer to load 
bb80: 57 41 4c 20 68 65 61 64 65 72 20 69 6e 74 6f 20  WAL header into 
bb90: 2a 2f 0a 20 20 20 20 75 38 20 2a 61 46 72 61 6d  */.    u8 *aFram
bba0: 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  e = 0;          
bbb0: 20 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f 63 27 64       /* Malloc'd
bbc0: 20 62 75 66 66 65 72 20 74 6f 20 6c 6f 61 64 20   buffer to load 
bbd0: 65 6e 74 69 72 65 20 66 72 61 6d 65 20 2a 2f 0a  entire frame */.
bbe0: 20 20 20 20 69 6e 74 20 73 7a 46 72 61 6d 65 3b      int szFrame;
bbf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bc00: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
bc10: 79 74 65 73 20 69 6e 20 62 75 66 66 65 72 20 61  ytes in buffer a
bc20: 46 72 61 6d 65 5b 5d 20 2a 2f 0a 20 20 20 20 75  Frame[] */.    u
bc30: 38 20 2a 61 44 61 74 61 3b 20 20 20 20 20 20 20  8 *aData;       
bc40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
bc50: 50 6f 69 6e 74 65 72 20 74 6f 20 64 61 74 61 20  Pointer to data 
bc60: 70 61 72 74 20 6f 66 20 61 46 72 61 6d 65 20 62  part of aFrame b
bc70: 75 66 66 65 72 20 2a 2f 0a 20 20 20 20 69 6e 74  uffer */.    int
bc80: 20 69 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20   iFrame;        
bc90: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
bca0: 64 65 78 20 6f 66 20 6c 61 73 74 20 66 72 61 6d  dex of last fram
bcb0: 65 20 72 65 61 64 20 2a 2f 0a 20 20 20 20 69 36  e read */.    i6
bcc0: 34 20 69 4f 66 66 73 65 74 3b 20 20 20 20 20 20  4 iOffset;      
bcd0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
bce0: 65 78 74 20 6f 66 66 73 65 74 20 74 6f 20 72 65  ext offset to re
bcf0: 61 64 20 66 72 6f 6d 20 6c 6f 67 20 66 69 6c 65  ad from log file
bd00: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 73 7a 50 61   */.    int szPa
bd10: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
bd20: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69        /* Page si
bd30: 7a 65 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20  ze according to 
bd40: 74 68 65 20 6c 6f 67 20 2a 2f 0a 20 20 20 20 75  the log */.    u
bd50: 33 32 20 6d 61 67 69 63 3b 20 20 20 20 20 20 20  32 magic;       
bd60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
bd70: 4d 61 67 69 63 20 76 61 6c 75 65 20 72 65 61 64  Magic value read
bd80: 20 66 72 6f 6d 20 57 41 4c 20 68 65 61 64 65 72   from WAL header
bd90: 20 2a 2f 0a 20 20 20 20 75 33 32 20 76 65 72 73   */.    u32 vers
bda0: 69 6f 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20  ion;            
bdb0: 20 20 20 20 20 20 2f 2a 20 4d 61 67 69 63 20 76        /* Magic v
bdc0: 61 6c 75 65 20 72 65 61 64 20 66 72 6f 6d 20 57  alue read from W
bdd0: 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 20  AL header */.   
bde0: 20 69 6e 74 20 69 73 56 61 6c 69 64 3b 20 20 20   int isValid;   
bdf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
be00: 2a 20 54 72 75 65 20 69 66 20 74 68 69 73 20 66  * True if this f
be10: 72 61 6d 65 20 69 73 20 76 61 6c 69 64 20 2a 2f  rame is valid */
be20: 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64 20 69 6e  ..    /* Read in
be30: 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72 2e   the WAL header.
be40: 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   */.    rc = sql
be50: 69 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d  ite3OsRead(pWal-
be60: 3e 70 57 61 6c 46 64 2c 20 61 42 75 66 2c 20 57  >pWalFd, aBuf, W
be70: 41 4c 5f 48 44 52 53 49 5a 45 2c 20 30 29 3b 0a  AL_HDRSIZE, 0);.
be80: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
be90: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 67  TE_OK ){.      g
bea0: 6f 74 6f 20 72 65 63 6f 76 65 72 79 5f 65 72 72  oto recovery_err
beb0: 6f 72 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  or;.    }..    /
bec0: 2a 20 49 66 20 74 68 65 20 64 61 74 61 62 61 73  * If the databas
bed0: 65 20 70 61 67 65 20 73 69 7a 65 20 69 73 20 6e  e page size is n
bee0: 6f 74 20 61 20 70 6f 77 65 72 20 6f 66 20 74 77  ot a power of tw
bef0: 6f 2c 20 6f 72 20 69 73 20 67 72 65 61 74 65 72  o, or is greater
bf00: 20 74 68 61 6e 0a 20 20 20 20 2a 2a 20 53 51 4c   than.    ** SQL
bf10: 49 54 45 5f 4d 41 58 5f 50 41 47 45 5f 53 49 5a  ITE_MAX_PAGE_SIZ
bf20: 45 2c 20 63 6f 6e 63 6c 75 64 65 20 74 68 61 74  E, conclude that
bf30: 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20 63 6f   the WAL file co
bf40: 6e 74 61 69 6e 73 20 6e 6f 20 76 61 6c 69 64 20  ntains no valid 
bf50: 0a 20 20 20 20 2a 2a 20 64 61 74 61 2e 20 53 69  .    ** data. Si
bf60: 6d 69 6c 61 72 6c 79 2c 20 69 66 20 74 68 65 20  milarly, if the 
bf70: 27 6d 61 67 69 63 27 20 76 61 6c 75 65 20 69 73  'magic' value is
bf80: 20 69 6e 76 61 6c 69 64 2c 20 69 67 6e 6f 72 65   invalid, ignore
bf90: 20 74 68 65 20 77 68 6f 6c 65 0a 20 20 20 20 2a   the whole.    *
bfa0: 2a 20 57 41 4c 20 66 69 6c 65 2e 0a 20 20 20 20  * WAL file..    
bfb0: 2a 2f 0a 20 20 20 20 6d 61 67 69 63 20 3d 20 73  */.    magic = s
bfc0: 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26  qlite3Get4byte(&
bfd0: 61 42 75 66 5b 30 5d 29 3b 0a 20 20 20 20 73 7a  aBuf[0]);.    sz
bfe0: 50 61 67 65 20 3d 20 73 71 6c 69 74 65 33 47 65  Page = sqlite3Ge
bff0: 74 34 62 79 74 65 28 26 61 42 75 66 5b 38 5d 29  t4byte(&aBuf[8])
c000: 3b 0a 20 20 20 20 69 66 28 20 28 6d 61 67 69 63  ;.    if( (magic
c010: 26 30 78 46 46 46 46 46 46 46 45 29 21 3d 57 41  &0xFFFFFFFE)!=WA
c020: 4c 5f 4d 41 47 49 43 20 0a 20 20 20 20 20 7c 7c  L_MAGIC .     ||
c030: 20 73 7a 50 61 67 65 26 28 73 7a 50 61 67 65 2d   szPage&(szPage-
c040: 31 29 20 0a 20 20 20 20 20 7c 7c 20 73 7a 50 61  1) .     || szPa
c050: 67 65 3e 53 51 4c 49 54 45 5f 4d 41 58 5f 50 41  ge>SQLITE_MAX_PA
c060: 47 45 5f 53 49 5a 45 20 0a 20 20 20 20 20 7c 7c  GE_SIZE .     ||
c070: 20 73 7a 50 61 67 65 3c 35 31 32 20 0a 20 20 20   szPage<512 .   
c080: 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 66   ){.      goto f
c090: 69 6e 69 73 68 65 64 3b 0a 20 20 20 20 7d 0a 20  inished;.    }. 
c0a0: 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67     pWal->hdr.big
c0b0: 45 6e 64 43 6b 73 75 6d 20 3d 20 28 75 38 29 28  EndCksum = (u8)(
c0c0: 6d 61 67 69 63 26 30 78 30 30 30 30 30 30 30 31  magic&0x00000001
c0d0: 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50  );.    pWal->szP
c0e0: 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20  age = szPage;.  
c0f0: 20 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 20 3d 20    pWal->nCkpt = 
c100: 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
c110: 26 61 42 75 66 5b 31 32 5d 29 3b 0a 20 20 20 20  &aBuf[12]);.    
c120: 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64  memcpy(&pWal->hd
c130: 72 2e 61 53 61 6c 74 2c 20 26 61 42 75 66 5b 31  r.aSalt, &aBuf[1
c140: 36 5d 2c 20 38 29 3b 0a 0a 20 20 20 20 2f 2a 20  6], 8);..    /* 
c150: 56 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20  Verify that the 
c160: 57 41 4c 20 68 65 61 64 65 72 20 63 68 65 63 6b  WAL header check
c170: 73 75 6d 20 69 73 20 63 6f 72 72 65 63 74 20 2a  sum is correct *
c180: 2f 0a 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75  /.    walChecksu
c190: 6d 42 79 74 65 73 28 70 57 61 6c 2d 3e 68 64 72  mBytes(pWal->hdr
c1a0: 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d 3d 53 51  .bigEndCksum==SQ
c1b0: 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e 2c 20  LITE_BIGENDIAN, 
c1c0: 0a 20 20 20 20 20 20 20 20 61 42 75 66 2c 20 57  .        aBuf, W
c1d0: 41 4c 5f 48 44 52 53 49 5a 45 2d 32 2a 34 2c 20  AL_HDRSIZE-2*4, 
c1e0: 30 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72  0, pWal->hdr.aFr
c1f0: 61 6d 65 43 6b 73 75 6d 0a 20 20 20 20 29 3b 0a  ameCksum.    );.
c200: 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64      if( pWal->hd
c210: 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d  r.aFrameCksum[0]
c220: 21 3d 73 71 6c 69 74 65 33 47 65 74 34 62 79 74  !=sqlite3Get4byt
c230: 65 28 26 61 42 75 66 5b 32 34 5d 29 0a 20 20 20  e(&aBuf[24]).   
c240: 20 20 7c 7c 20 70 57 61 6c 2d 3e 68 64 72 2e 61    || pWal->hdr.a
c250: 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 21 3d 73  FrameCksum[1]!=s
c260: 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26  qlite3Get4byte(&
c270: 61 42 75 66 5b 32 38 5d 29 0a 20 20 20 20 29 7b  aBuf[28]).    ){
c280: 0a 20 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69  .      goto fini
c290: 73 68 65 64 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  shed;.    }..   
c2a0: 20 2f 2a 20 56 65 72 69 66 79 20 74 68 61 74 20   /* Verify that 
c2b0: 74 68 65 20 76 65 72 73 69 6f 6e 20 6e 75 6d 62  the version numb
c2c0: 65 72 20 6f 6e 20 74 68 65 20 57 41 4c 20 66 6f  er on the WAL fo
c2d0: 72 6d 61 74 20 69 73 20 6f 6e 65 20 74 68 61 74  rmat is one that
c2e0: 0a 20 20 20 20 2a 2a 20 61 72 65 20 61 62 6c 65  .    ** are able
c2f0: 20 74 6f 20 75 6e 64 65 72 73 74 61 6e 64 20 2a   to understand *
c300: 2f 0a 20 20 20 20 76 65 72 73 69 6f 6e 20 3d 20  /.    version = 
c310: 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
c320: 26 61 42 75 66 5b 34 5d 29 3b 0a 20 20 20 20 69  &aBuf[4]);.    i
c330: 66 28 20 76 65 72 73 69 6f 6e 21 3d 57 41 4c 5f  f( version!=WAL_
c340: 4d 41 58 5f 56 45 52 53 49 4f 4e 20 29 7b 0a 20  MAX_VERSION ){. 
c350: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
c360: 5f 43 41 4e 54 4f 50 45 4e 5f 42 4b 50 54 3b 0a  _CANTOPEN_BKPT;.
c370: 20 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73        goto finis
c380: 68 65 64 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  hed;.    }..    
c390: 2f 2a 20 4d 61 6c 6c 6f 63 20 61 20 62 75 66 66  /* Malloc a buff
c3a0: 65 72 20 74 6f 20 72 65 61 64 20 66 72 61 6d 65  er to read frame
c3b0: 73 20 69 6e 74 6f 2e 20 2a 2f 0a 20 20 20 20 73  s into. */.    s
c3c0: 7a 46 72 61 6d 65 20 3d 20 73 7a 50 61 67 65 20  zFrame = szPage 
c3d0: 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  + WAL_FRAME_HDRS
c3e0: 49 5a 45 3b 0a 20 20 20 20 61 46 72 61 6d 65 20  IZE;.    aFrame 
c3f0: 3d 20 28 75 38 20 2a 29 73 71 6c 69 74 65 33 5f  = (u8 *)sqlite3_
c400: 6d 61 6c 6c 6f 63 36 34 28 73 7a 46 72 61 6d 65  malloc64(szFrame
c410: 29 3b 0a 20 20 20 20 69 66 28 20 21 61 46 72 61  );.    if( !aFra
c420: 6d 65 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  me ){.      rc =
c430: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b   SQLITE_NOMEM_BK
c440: 50 54 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 72  PT;.      goto r
c450: 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20  ecovery_error;. 
c460: 20 20 20 7d 0a 20 20 20 20 61 44 61 74 61 20 3d     }.    aData =
c470: 20 26 61 46 72 61 6d 65 5b 57 41 4c 5f 46 52 41   &aFrame[WAL_FRA
c480: 4d 45 5f 48 44 52 53 49 5a 45 5d 3b 0a 0a 20 20  ME_HDRSIZE];..  
c490: 20 20 2f 2a 20 52 65 61 64 20 61 6c 6c 20 66 72    /* Read all fr
c4a0: 61 6d 65 73 20 66 72 6f 6d 20 74 68 65 20 6c 6f  ames from the lo
c4b0: 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 20 20 69  g file. */.    i
c4c0: 46 72 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20 66  Frame = 0;.    f
c4d0: 6f 72 28 69 4f 66 66 73 65 74 3d 57 41 4c 5f 48  or(iOffset=WAL_H
c4e0: 44 52 53 49 5a 45 3b 20 28 69 4f 66 66 73 65 74  DRSIZE; (iOffset
c4f0: 2b 73 7a 46 72 61 6d 65 29 3c 3d 6e 53 69 7a 65  +szFrame)<=nSize
c500: 3b 20 69 4f 66 66 73 65 74 2b 3d 73 7a 46 72 61  ; iOffset+=szFra
c510: 6d 65 29 7b 0a 20 20 20 20 20 20 75 33 32 20 70  me){.      u32 p
c520: 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20  gno;            
c530: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
c540: 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 66  se page number f
c550: 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20 20 20 20  or frame */.    
c560: 20 20 75 33 32 20 6e 54 72 75 6e 63 61 74 65 3b    u32 nTruncate;
c570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c580: 20 64 62 73 69 7a 65 20 66 69 65 6c 64 20 66 72   dbsize field fr
c590: 6f 6d 20 66 72 61 6d 65 20 68 65 61 64 65 72 20  om frame header 
c5a0: 2a 2f 0a 0a 20 20 20 20 20 20 2f 2a 20 52 65 61  */..      /* Rea
c5b0: 64 20 61 6e 64 20 64 65 63 6f 64 65 20 74 68 65  d and decode the
c5c0: 20 6e 65 78 74 20 6c 6f 67 20 66 72 61 6d 65 2e   next log frame.
c5d0: 20 2a 2f 0a 20 20 20 20 20 20 69 46 72 61 6d 65   */.      iFrame
c5e0: 2b 2b 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  ++;.      rc = s
c5f0: 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57 61  qlite3OsRead(pWa
c600: 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 46 72 61 6d  l->pWalFd, aFram
c610: 65 2c 20 73 7a 46 72 61 6d 65 2c 20 69 4f 66 66  e, szFrame, iOff
c620: 73 65 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20  set);.      if( 
c630: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
c640: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 69 73 56  break;.      isV
c650: 61 6c 69 64 20 3d 20 77 61 6c 44 65 63 6f 64 65  alid = walDecode
c660: 46 72 61 6d 65 28 70 57 61 6c 2c 20 26 70 67 6e  Frame(pWal, &pgn
c670: 6f 2c 20 26 6e 54 72 75 6e 63 61 74 65 2c 20 61  o, &nTruncate, a
c680: 44 61 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a 20  Data, aFrame);. 
c690: 20 20 20 20 20 69 66 28 20 21 69 73 56 61 6c 69       if( !isVali
c6a0: 64 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  d ) break;.     
c6b0: 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70   rc = walIndexAp
c6c0: 70 65 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d  pend(pWal, iFram
c6d0: 65 2c 20 70 67 6e 6f 29 3b 0a 20 20 20 20 20 20  e, pgno);.      
c6e0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
c6f0: 4b 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20  K ) break;..    
c700: 20 20 2f 2a 20 49 66 20 6e 54 72 75 6e 63 61 74    /* If nTruncat
c710: 65 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74  e is non-zero, t
c720: 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 20  his is a commit 
c730: 72 65 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 20  record. */.     
c740: 20 69 66 28 20 6e 54 72 75 6e 63 61 74 65 20 29   if( nTruncate )
c750: 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e  {.        pWal->
c760: 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20 69 46  hdr.mxFrame = iF
c770: 72 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 70 57  rame;.        pW
c780: 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20 3d 20  al->hdr.nPage = 
c790: 6e 54 72 75 6e 63 61 74 65 3b 0a 20 20 20 20 20  nTruncate;.     
c7a0: 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50     pWal->hdr.szP
c7b0: 61 67 65 20 3d 20 28 75 31 36 29 28 28 73 7a 50  age = (u16)((szP
c7c0: 61 67 65 26 30 78 66 66 30 30 29 20 7c 20 28 73  age&0xff00) | (s
c7d0: 7a 50 61 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20  zPage>>16));.   
c7e0: 20 20 20 20 20 74 65 73 74 63 61 73 65 28 20 73       testcase( s
c7f0: 7a 50 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a  zPage<=32768 );.
c800: 20 20 20 20 20 20 20 20 74 65 73 74 63 61 73 65          testcase
c810: 28 20 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20  ( szPage>=65536 
c820: 29 3b 0a 20 20 20 20 20 20 20 20 61 46 72 61 6d  );.        aFram
c830: 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 70 57 61 6c  eCksum[0] = pWal
c840: 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
c850: 6d 5b 30 5d 3b 0a 20 20 20 20 20 20 20 20 61 46  m[0];.        aF
c860: 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 70  rameCksum[1] = p
c870: 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
c880: 6b 73 75 6d 5b 31 5d 3b 0a 20 20 20 20 20 20 7d  ksum[1];.      }
c890: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69  .    }..    sqli
c8a0: 74 65 33 5f 66 72 65 65 28 61 46 72 61 6d 65 29  te3_free(aFrame)
c8b0: 3b 0a 20 20 7d 0a 0a 66 69 6e 69 73 68 65 64 3a  ;.  }..finished:
c8c0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
c8d0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 6f 6c 61  E_OK ){.    vola
c8e0: 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f  tile WalCkptInfo
c8f0: 20 2a 70 49 6e 66 6f 3b 0a 20 20 20 20 69 6e 74   *pInfo;.    int
c900: 20 69 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64   i;.    pWal->hd
c910: 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d  r.aFrameCksum[0]
c920: 20 3d 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30   = aFrameCksum[0
c930: 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  ];.    pWal->hdr
c940: 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20  .aFrameCksum[1] 
c950: 3d 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d  = aFrameCksum[1]
c960: 3b 0a 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72  ;.    walIndexWr
c970: 69 74 65 48 64 72 28 70 57 61 6c 29 3b 0a 0a 20  iteHdr(pWal);.. 
c980: 20 20 20 2f 2a 20 52 65 73 65 74 20 74 68 65 20     /* Reset the 
c990: 63 68 65 63 6b 70 6f 69 6e 74 2d 68 65 61 64 65  checkpoint-heade
c9a0: 72 2e 20 54 68 69 73 20 69 73 20 73 61 66 65 20  r. This is safe 
c9b0: 62 65 63 61 75 73 65 20 74 68 69 73 20 74 68 72  because this thr
c9c0: 65 61 64 20 69 73 20 0a 20 20 20 20 2a 2a 20 63  ead is .    ** c
c9d0: 75 72 72 65 6e 74 6c 79 20 68 6f 6c 64 69 6e 67  urrently holding
c9e0: 20 6c 6f 63 6b 73 20 74 68 61 74 20 65 78 63 6c   locks that excl
c9f0: 75 64 65 20 61 6c 6c 20 6f 74 68 65 72 20 72 65  ude all other re
ca00: 61 64 65 72 73 2c 20 77 72 69 74 65 72 73 20 61  aders, writers a
ca10: 6e 64 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70  nd.    ** checkp
ca20: 6f 69 6e 74 65 72 73 2e 0a 20 20 20 20 2a 2f 0a  ointers..    */.
ca30: 20 20 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43      pInfo = walC
ca40: 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20  kptInfo(pWal);. 
ca50: 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66     pInfo->nBackf
ca60: 69 6c 6c 20 3d 20 30 3b 0a 20 20 20 20 70 49 6e  ill = 0;.    pIn
ca70: 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 41 74 74  fo->nBackfillAtt
ca80: 65 6d 70 74 65 64 20 3d 20 70 57 61 6c 2d 3e 68  empted = pWal->h
ca90: 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20  dr.mxFrame;.    
caa0: 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b  pInfo->aReadMark
cab0: 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72  [0] = 0;.    for
cac0: 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41  (i=1; i<WAL_NREA
cad0: 44 45 52 3b 20 69 2b 2b 29 20 70 49 6e 66 6f 2d  DER; i++) pInfo-
cae0: 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d 20  >aReadMark[i] = 
caf0: 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45  READMARK_NOT_USE
cb00: 44 3b 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d  D;.    if( pWal-
cb10: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 20 70  >hdr.mxFrame ) p
cb20: 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b  Info->aReadMark[
cb30: 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  1] = pWal->hdr.m
cb40: 78 46 72 61 6d 65 3b 0a 0a 20 20 20 20 2f 2a 20  xFrame;..    /* 
cb50: 49 66 20 6d 6f 72 65 20 74 68 61 6e 20 6f 6e 65  If more than one
cb60: 20 66 72 61 6d 65 20 77 61 73 20 72 65 63 6f 76   frame was recov
cb70: 65 72 65 64 20 66 72 6f 6d 20 74 68 65 20 6c 6f  ered from the lo
cb80: 67 20 66 69 6c 65 2c 20 72 65 70 6f 72 74 20 61  g file, report a
cb90: 6e 0a 20 20 20 20 2a 2a 20 65 76 65 6e 74 20 76  n.    ** event v
cba0: 69 61 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28 29  ia sqlite3_log()
cbb0: 2e 20 54 68 69 73 20 69 73 20 74 6f 20 68 65 6c  . This is to hel
cbc0: 70 20 77 69 74 68 20 69 64 65 6e 74 69 66 79 69  p with identifyi
cbd0: 6e 67 20 70 65 72 66 6f 72 6d 61 6e 63 65 0a 20  ng performance. 
cbe0: 20 20 20 2a 2a 20 70 72 6f 62 6c 65 6d 73 20 63     ** problems c
cbf0: 61 75 73 65 64 20 62 79 20 61 70 70 6c 69 63 61  aused by applica
cc00: 74 69 6f 6e 73 20 72 6f 75 74 69 6e 65 6c 79 20  tions routinely 
cc10: 73 68 75 74 74 69 6e 67 20 64 6f 77 6e 20 77 69  shutting down wi
cc20: 74 68 6f 75 74 0a 20 20 20 20 2a 2a 20 63 68 65  thout.    ** che
cc30: 63 6b 70 6f 69 6e 74 69 6e 67 20 74 68 65 20 6c  ckpointing the l
cc40: 6f 67 20 66 69 6c 65 2e 0a 20 20 20 20 2a 2f 0a  og file..    */.
cc50: 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64      if( pWal->hd
cc60: 72 2e 6e 50 61 67 65 20 29 7b 0a 20 20 20 20 20  r.nPage ){.     
cc70: 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28 53 51 4c   sqlite3_log(SQL
cc80: 49 54 45 5f 4e 4f 54 49 43 45 5f 52 45 43 4f 56  ITE_NOTICE_RECOV
cc90: 45 52 5f 57 41 4c 2c 0a 20 20 20 20 20 20 20 20  ER_WAL,.        
cca0: 20 20 22 72 65 63 6f 76 65 72 65 64 20 25 64 20    "recovered %d 
ccb0: 66 72 61 6d 65 73 20 66 72 6f 6d 20 57 41 4c 20  frames from WAL 
ccc0: 66 69 6c 65 20 25 73 22 2c 0a 20 20 20 20 20 20  file %s",.      
ccd0: 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78      pWal->hdr.mx
cce0: 46 72 61 6d 65 2c 20 70 57 61 6c 2d 3e 7a 57 61  Frame, pWal->zWa
ccf0: 6c 4e 61 6d 65 0a 20 20 20 20 20 20 29 3b 0a 20  lName.      );. 
cd00: 20 20 20 7d 0a 20 20 7d 0a 0a 72 65 63 6f 76 65     }.  }..recove
cd10: 72 79 5f 65 72 72 6f 72 3a 0a 20 20 57 41 4c 54  ry_error:.  WALT
cd20: 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 72 65  RACE(("WAL%p: re
cd30: 63 6f 76 65 72 79 20 25 73 5c 6e 22 2c 20 70 57  covery %s\n", pW
cd40: 61 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64  al, rc ? "failed
cd50: 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 77 61  " : "ok"));.  wa
cd60: 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65  lUnlockExclusive
cd70: 28 70 57 61 6c 2c 20 69 4c 6f 63 6b 2c 20 57 41  (pWal, iLock, WA
cd80: 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2d 69  L_READ_LOCK(0)-i
cd90: 4c 6f 63 6b 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f  Lock);.  walUnlo
cda0: 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
cdb0: 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
cdc0: 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d  1), WAL_NREADER-
cdd0: 31 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  1);.  return rc;
cde0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20  .}../*.** Close 
cdf0: 61 6e 20 6f 70 65 6e 20 77 61 6c 2d 69 6e 64 65  an open wal-inde
ce00: 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  x..*/.static voi
ce10: 64 20 77 61 6c 49 6e 64 65 78 43 6c 6f 73 65 28  d walIndexClose(
ce20: 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 69  Wal *pWal, int i
ce30: 73 44 65 6c 65 74 65 29 7b 0a 20 20 69 66 28 20  sDelete){.  if( 
ce40: 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
ce50: 6f 64 65 3d 3d 57 41 4c 5f 48 45 41 50 4d 45 4d  ode==WAL_HEAPMEM
ce60: 4f 52 59 5f 4d 4f 44 45 20 7c 7c 20 70 57 61 6c  ORY_MODE || pWal
ce70: 2d 3e 62 53 68 6d 55 6e 72 65 6c 69 61 62 6c 65  ->bShmUnreliable
ce80: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20   ){.    int i;. 
ce90: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 57     for(i=0; i<pW
cea0: 61 6c 2d 3e 6e 57 69 44 61 74 61 3b 20 69 2b 2b  al->nWiData; i++
ceb0: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
cec0: 5f 66 72 65 65 28 28 76 6f 69 64 20 2a 29 70 57  _free((void *)pW
ced0: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 5d 29  al->apWiData[i])
cee0: 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 61 70  ;.      pWal->ap
cef0: 57 69 44 61 74 61 5b 69 5d 20 3d 20 30 3b 0a 20  WiData[i] = 0;. 
cf00: 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 70     }.  }.  if( p
cf10: 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
cf20: 64 65 21 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f  de!=WAL_HEAPMEMO
cf30: 52 59 5f 4d 4f 44 45 20 29 7b 0a 20 20 20 20 73  RY_MODE ){.    s
cf40: 71 6c 69 74 65 33 4f 73 53 68 6d 55 6e 6d 61 70  qlite3OsShmUnmap
cf50: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 73  (pWal->pDbFd, is
cf60: 44 65 6c 65 74 65 29 3b 0a 20 20 7d 0a 7d 0a 0a  Delete);.  }.}..
cf70: 2f 2a 20 0a 2a 2a 20 4f 70 65 6e 20 61 20 63 6f  /* .** Open a co
cf80: 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 74 68 65 20  nnection to the 
cf90: 57 41 4c 20 66 69 6c 65 20 7a 57 61 6c 4e 61 6d  WAL file zWalNam
cfa0: 65 2e 20 54 68 65 20 64 61 74 61 62 61 73 65 20  e. The database 
cfb0: 66 69 6c 65 20 6d 75 73 74 20 0a 2a 2a 20 61 6c  file must .** al
cfc0: 72 65 61 64 79 20 62 65 20 6f 70 65 6e 65 64 20  ready be opened 
cfd0: 6f 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 70 44  on connection pD
cfe0: 62 46 64 2e 20 54 68 65 20 62 75 66 66 65 72 20  bFd. The buffer 
cff0: 74 68 61 74 20 7a 57 61 6c 4e 61 6d 65 20 70 6f  that zWalName po
d000: 69 6e 74 73 0a 2a 2a 20 74 6f 20 6d 75 73 74 20  ints.** to must 
d010: 72 65 6d 61 69 6e 20 76 61 6c 69 64 20 66 6f 72  remain valid for
d020: 20 74 68 65 20 6c 69 66 65 74 69 6d 65 20 6f 66   the lifetime of
d030: 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 57 61   the returned Wa
d040: 6c 2a 20 68 61 6e 64 6c 65 2e 0a 2a 2a 0a 2a 2a  l* handle..**.**
d050: 20 41 20 53 48 41 52 45 44 20 6c 6f 63 6b 20 73   A SHARED lock s
d060: 68 6f 75 6c 64 20 62 65 20 68 65 6c 64 20 6f 6e  hould be held on
d070: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
d080: 6c 65 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e  le when this fun
d090: 63 74 69 6f 6e 0a 2a 2a 20 69 73 20 63 61 6c 6c  ction.** is call
d0a0: 65 64 2e 20 54 68 65 20 70 75 72 70 6f 73 65 20  ed. The purpose 
d0b0: 6f 66 20 74 68 69 73 20 53 48 41 52 45 44 20 6c  of this SHARED l
d0c0: 6f 63 6b 20 69 73 20 74 6f 20 70 72 65 76 65 6e  ock is to preven
d0d0: 74 20 61 6e 79 20 6f 74 68 65 72 0a 2a 2a 20 63  t any other.** c
d0e0: 6c 69 65 6e 74 20 66 72 6f 6d 20 75 6e 6c 69 6e  lient from unlin
d0f0: 6b 69 6e 67 20 74 68 65 20 57 41 4c 20 6f 72 20  king the WAL or 
d100: 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 2e 20  wal-index file. 
d110: 49 66 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65  If another proce
d120: 73 73 0a 2a 2a 20 77 65 72 65 20 74 6f 20 64 6f  ss.** were to do
d130: 20 74 68 69 73 20 6a 75 73 74 20 61 66 74 65 72   this just after
d140: 20 74 68 69 73 20 63 6c 69 65 6e 74 20 6f 70 65   this client ope
d150: 6e 65 64 20 6f 6e 65 20 6f 66 20 74 68 65 73 65  ned one of these
d160: 20 66 69 6c 65 73 2c 20 74 68 65 0a 2a 2a 20 73   files, the.** s
d170: 79 73 74 65 6d 20 77 6f 75 6c 64 20 62 65 20 62  ystem would be b
d180: 61 64 6c 79 20 62 72 6f 6b 65 6e 2e 0a 2a 2a 0a  adly broken..**.
d190: 2a 2a 20 49 66 20 74 68 65 20 6c 6f 67 20 66 69  ** If the log fi
d1a0: 6c 65 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  le is successful
d1b0: 6c 79 20 6f 70 65 6e 65 64 2c 20 53 51 4c 49 54  ly opened, SQLIT
d1c0: 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
d1d0: 20 61 6e 64 20 0a 2a 2a 20 2a 70 70 57 61 6c 20   and .** *ppWal 
d1e0: 69 73 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20  is set to point 
d1f0: 74 6f 20 61 20 6e 65 77 20 57 41 4c 20 68 61 6e  to a new WAL han
d200: 64 6c 65 2e 20 49 66 20 61 6e 20 65 72 72 6f 72  dle. If an error
d210: 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 61 6e 20 53   occurs,.** an S
d220: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
d230: 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64   is returned and
d240: 20 2a 70 70 57 61 6c 20 69 73 20 6c 65 66 74 20   *ppWal is left 
d250: 75 6e 6d 6f 64 69 66 69 65 64 2e 0a 2a 2f 0a 69  unmodified..*/.i
d260: 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 4f 70 65  nt sqlite3WalOpe
d270: 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  n(.  sqlite3_vfs
d280: 20 2a 70 56 66 73 2c 20 20 20 20 20 20 20 20 20   *pVfs,         
d290: 20 20 20 20 20 2f 2a 20 76 66 73 20 6d 6f 64 75       /* vfs modu
d2a0: 6c 65 20 74 6f 20 6f 70 65 6e 20 77 61 6c 20 61  le to open wal a
d2b0: 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a  nd wal-index */.
d2c0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
d2d0: 70 44 62 46 64 2c 20 20 20 20 20 20 20 20 20 20  pDbFd,          
d2e0: 20 20 2f 2a 20 54 68 65 20 6f 70 65 6e 20 64 61    /* The open da
d2f0: 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20  tabase file */. 
d300: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 57 61   const char *zWa
d310: 6c 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20  lName,          
d320: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20   /* Name of the 
d330: 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e  WAL file */.  in
d340: 74 20 62 4e 6f 53 68 6d 2c 20 20 20 20 20 20 20  t bNoShm,       
d350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d360: 20 54 72 75 65 20 74 6f 20 72 75 6e 20 69 6e 20   True to run in 
d370: 68 65 61 70 2d 6d 65 6d 6f 72 79 20 6d 6f 64 65  heap-memory mode
d380: 20 2a 2f 0a 20 20 69 36 34 20 6d 78 57 61 6c 53   */.  i64 mxWalS
d390: 69 7a 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ize,            
d3a0: 20 20 20 20 20 20 2f 2a 20 54 72 75 6e 63 61 74        /* Truncat
d3b0: 65 20 57 41 4c 20 74 6f 20 74 68 69 73 20 73 69  e WAL to this si
d3c0: 7a 65 20 6f 6e 20 72 65 73 65 74 20 2a 2f 0a 20  ze on reset */. 
d3d0: 20 57 61 6c 20 2a 2a 70 70 57 61 6c 20 20 20 20   Wal **ppWal    
d3e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d3f0: 20 2f 2a 20 4f 55 54 3a 20 41 6c 6c 6f 63 61 74   /* OUT: Allocat
d400: 65 64 20 57 61 6c 20 68 61 6e 64 6c 65 20 2a 2f  ed Wal handle */
d410: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  .){.  int rc;   
d420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d430: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
d440: 43 6f 64 65 20 2a 2f 0a 20 20 57 61 6c 20 2a 70  Code */.  Wal *p
d450: 52 65 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  Ret;            
d460: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a            /* Obj
d470: 65 63 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  ect to allocate 
d480: 61 6e 64 20 72 65 74 75 72 6e 20 2a 2f 0a 20 20  and return */.  
d490: 69 6e 74 20 66 6c 61 67 73 3b 20 20 20 20 20 20  int flags;      
d4a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d4b0: 2f 2a 20 46 6c 61 67 73 20 70 61 73 73 65 64 20  /* Flags passed 
d4c0: 74 6f 20 4f 73 4f 70 65 6e 28 29 20 2a 2f 0a 0a  to OsOpen() */..
d4d0: 20 20 61 73 73 65 72 74 28 20 7a 57 61 6c 4e 61    assert( zWalNa
d4e0: 6d 65 20 26 26 20 7a 57 61 6c 4e 61 6d 65 5b 30  me && zWalName[0
d4f0: 5d 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ] );.  assert( p
d500: 44 62 46 64 20 29 3b 0a 0a 20 20 2f 2a 20 49 6e  DbFd );..  /* In
d510: 20 74 68 65 20 61 6d 61 6c 67 61 6d 61 74 69 6f   the amalgamatio
d520: 6e 2c 20 74 68 65 20 6f 73 5f 75 6e 69 78 2e 63  n, the os_unix.c
d530: 20 61 6e 64 20 6f 73 5f 77 69 6e 2e 63 20 73 6f   and os_win.c so
d540: 75 72 63 65 20 66 69 6c 65 73 20 63 6f 6d 65 20  urce files come 
d550: 62 65 66 6f 72 65 0a 20 20 2a 2a 20 74 68 69 73  before.  ** this
d560: 20 73 6f 75 72 63 65 20 66 69 6c 65 2e 20 20 56   source file.  V
d570: 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20 23  erify that the #
d580: 64 65 66 69 6e 65 73 20 6f 66 20 74 68 65 20 6c  defines of the l
d590: 6f 63 6b 69 6e 67 20 62 79 74 65 20 6f 66 66 73  ocking byte offs
d5a0: 65 74 73 0a 20 20 2a 2a 20 69 6e 20 6f 73 5f 75  ets.  ** in os_u
d5b0: 6e 69 78 2e 63 20 61 6e 64 20 6f 73 5f 77 69 6e  nix.c and os_win
d5c0: 2e 63 20 61 67 72 65 65 20 77 69 74 68 20 74 68  .c agree with th
d5d0: 65 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f  e WALINDEX_LOCK_
d5e0: 4f 46 46 53 45 54 20 76 61 6c 75 65 2e 0a 20 20  OFFSET value..  
d5f0: 2a 2a 20 46 6f 72 20 74 68 61 74 20 6d 61 74 74  ** For that matt
d600: 65 72 2c 20 69 66 20 74 68 65 20 6c 6f 63 6b 20  er, if the lock 
d610: 6f 66 66 73 65 74 20 65 76 65 72 20 63 68 61 6e  offset ever chan
d620: 67 65 73 20 66 72 6f 6d 20 69 74 73 20 69 6e 69  ges from its ini
d630: 74 69 61 6c 20 64 65 73 69 67 6e 0a 20 20 2a 2a  tial design.  **
d640: 20 76 61 6c 75 65 20 6f 66 20 31 32 30 2c 20 77   value of 120, w
d650: 65 20 6e 65 65 64 20 74 6f 20 6b 6e 6f 77 20 74  e need to know t
d660: 68 61 74 20 73 6f 20 74 68 65 72 65 20 69 73 20  hat so there is 
d670: 61 6e 20 61 73 73 65 72 74 28 29 20 74 6f 20 63  an assert() to c
d680: 68 65 63 6b 20 69 74 2e 0a 20 20 2a 2f 0a 20 20  heck it..  */.  
d690: 61 73 73 65 72 74 28 20 31 32 30 3d 3d 57 41 4c  assert( 120==WAL
d6a0: 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45  INDEX_LOCK_OFFSE
d6b0: 54 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 31  T );.  assert( 1
d6c0: 33 36 3d 3d 57 41 4c 49 4e 44 45 58 5f 48 44 52  36==WALINDEX_HDR
d6d0: 5f 53 49 5a 45 20 29 3b 0a 23 69 66 64 65 66 20  _SIZE );.#ifdef 
d6e0: 57 49 4e 5f 53 48 4d 5f 42 41 53 45 0a 20 20 61  WIN_SHM_BASE.  a
d6f0: 73 73 65 72 74 28 20 57 49 4e 5f 53 48 4d 5f 42  ssert( WIN_SHM_B
d700: 41 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f  ASE==WALINDEX_LO
d710: 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65 6e  CK_OFFSET );.#en
d720: 64 69 66 0a 23 69 66 64 65 66 20 55 4e 49 58 5f  dif.#ifdef UNIX_
d730: 53 48 4d 5f 42 41 53 45 0a 20 20 61 73 73 65 72  SHM_BASE.  asser
d740: 74 28 20 55 4e 49 58 5f 53 48 4d 5f 42 41 53 45  t( UNIX_SHM_BASE
d750: 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f  ==WALINDEX_LOCK_
d760: 4f 46 46 53 45 54 20 29 3b 0a 23 65 6e 64 69 66  OFFSET );.#endif
d770: 0a 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65  ...  /* Allocate
d780: 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   an instance of 
d790: 73 74 72 75 63 74 20 57 61 6c 20 74 6f 20 72 65  struct Wal to re
d7a0: 74 75 72 6e 2e 20 2a 2f 0a 20 20 2a 70 70 57 61  turn. */.  *ppWa
d7b0: 6c 20 3d 20 30 3b 0a 20 20 70 52 65 74 20 3d 20  l = 0;.  pRet = 
d7c0: 28 57 61 6c 2a 29 73 71 6c 69 74 65 33 4d 61 6c  (Wal*)sqlite3Mal
d7d0: 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 57  locZero(sizeof(W
d7e0: 61 6c 29 20 2b 20 70 56 66 73 2d 3e 73 7a 4f 73  al) + pVfs->szOs
d7f0: 46 69 6c 65 29 3b 0a 20 20 69 66 28 20 21 70 52  File);.  if( !pR
d800: 65 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  et ){.    return
d810: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b   SQLITE_NOMEM_BK
d820: 50 54 3b 0a 20 20 7d 0a 0a 20 20 70 52 65 74 2d  PT;.  }..  pRet-
d830: 3e 70 56 66 73 20 3d 20 70 56 66 73 3b 0a 20 20  >pVfs = pVfs;.  
d840: 70 52 65 74 2d 3e 70 57 61 6c 46 64 20 3d 20 28  pRet->pWalFd = (
d850: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 29 26  sqlite3_file *)&
d860: 70 52 65 74 5b 31 5d 3b 0a 20 20 70 52 65 74 2d  pRet[1];.  pRet-
d870: 3e 70 44 62 46 64 20 3d 20 70 44 62 46 64 3b 0a  >pDbFd = pDbFd;.
d880: 20 20 70 52 65 74 2d 3e 72 65 61 64 4c 6f 63 6b    pRet->readLock
d890: 20 3d 20 2d 31 3b 0a 20 20 70 52 65 74 2d 3e 6d   = -1;.  pRet->m
d8a0: 78 57 61 6c 53 69 7a 65 20 3d 20 6d 78 57 61 6c  xWalSize = mxWal
d8b0: 53 69 7a 65 3b 0a 20 20 70 52 65 74 2d 3e 7a 57  Size;.  pRet->zW
d8c0: 61 6c 4e 61 6d 65 20 3d 20 7a 57 61 6c 4e 61 6d  alName = zWalNam
d8d0: 65 3b 0a 20 20 70 52 65 74 2d 3e 73 79 6e 63 48  e;.  pRet->syncH
d8e0: 65 61 64 65 72 20 3d 20 31 3b 0a 20 20 70 52 65  eader = 1;.  pRe
d8f0: 74 2d 3e 70 61 64 54 6f 53 65 63 74 6f 72 42 6f  t->padToSectorBo
d900: 75 6e 64 61 72 79 20 3d 20 31 3b 0a 20 20 70 52  undary = 1;.  pR
d910: 65 74 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  et->exclusiveMod
d920: 65 20 3d 20 28 62 4e 6f 53 68 6d 20 3f 20 57 41  e = (bNoShm ? WA
d930: 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44  L_HEAPMEMORY_MOD
d940: 45 3a 20 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f  E: WAL_NORMAL_MO
d950: 44 45 29 3b 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20  DE);..  /* Open 
d960: 66 69 6c 65 20 68 61 6e 64 6c 65 20 6f 6e 20 74  file handle on t
d970: 68 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c  he write-ahead l
d980: 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 66 6c  og file. */.  fl
d990: 61 67 73 20 3d 20 28 53 51 4c 49 54 45 5f 4f 50  ags = (SQLITE_OP
d9a0: 45 4e 5f 52 45 41 44 57 52 49 54 45 7c 53 51 4c  EN_READWRITE|SQL
d9b0: 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54 45 7c  ITE_OPEN_CREATE|
d9c0: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 57 41 4c 29  SQLITE_OPEN_WAL)
d9d0: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
d9e0: 4f 73 4f 70 65 6e 28 70 56 66 73 2c 20 7a 57 61  OsOpen(pVfs, zWa
d9f0: 6c 4e 61 6d 65 2c 20 70 52 65 74 2d 3e 70 57 61  lName, pRet->pWa
da00: 6c 46 64 2c 20 66 6c 61 67 73 2c 20 26 66 6c 61  lFd, flags, &fla
da10: 67 73 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  gs);.  if( rc==S
da20: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 66 6c 61 67  QLITE_OK && flag
da30: 73 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45  s&SQLITE_OPEN_RE
da40: 41 44 4f 4e 4c 59 20 29 7b 0a 20 20 20 20 70 52  ADONLY ){.    pR
da50: 65 74 2d 3e 72 65 61 64 4f 6e 6c 79 20 3d 20 57  et->readOnly = W
da60: 41 4c 5f 52 44 4f 4e 4c 59 3b 0a 20 20 7d 0a 0a  AL_RDONLY;.  }..
da70: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
da80: 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49 6e  _OK ){.    walIn
da90: 64 65 78 43 6c 6f 73 65 28 70 52 65 74 2c 20 30  dexClose(pRet, 0
daa0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  );.    sqlite3Os
dab0: 43 6c 6f 73 65 28 70 52 65 74 2d 3e 70 57 61 6c  Close(pRet->pWal
dac0: 46 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  Fd);.    sqlite3
dad0: 5f 66 72 65 65 28 70 52 65 74 29 3b 0a 20 20 7d  _free(pRet);.  }
dae0: 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 69 44  else{.    int iD
daf0: 43 20 3d 20 73 71 6c 69 74 65 33 4f 73 44 65 76  C = sqlite3OsDev
db00: 69 63 65 43 68 61 72 61 63 74 65 72 69 73 74 69  iceCharacteristi
db10: 63 73 28 70 44 62 46 64 29 3b 0a 20 20 20 20 69  cs(pDbFd);.    i
db20: 66 28 20 69 44 43 20 26 20 53 51 4c 49 54 45 5f  f( iDC & SQLITE_
db30: 49 4f 43 41 50 5f 53 45 51 55 45 4e 54 49 41 4c  IOCAP_SEQUENTIAL
db40: 20 29 7b 20 70 52 65 74 2d 3e 73 79 6e 63 48 65   ){ pRet->syncHe
db50: 61 64 65 72 20 3d 20 30 3b 20 7d 0a 20 20 20 20  ader = 0; }.    
db60: 69 66 28 20 69 44 43 20 26 20 53 51 4c 49 54 45  if( iDC & SQLITE
db70: 5f 49 4f 43 41 50 5f 50 4f 57 45 52 53 41 46 45  _IOCAP_POWERSAFE
db80: 5f 4f 56 45 52 57 52 49 54 45 20 29 7b 0a 20 20  _OVERWRITE ){.  
db90: 20 20 20 20 70 52 65 74 2d 3e 70 61 64 54 6f 53      pRet->padToS
dba0: 65 63 74 6f 72 42 6f 75 6e 64 61 72 79 20 3d 20  ectorBoundary = 
dbb0: 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 70  0;.    }.    *pp
dbc0: 57 61 6c 20 3d 20 70 52 65 74 3b 0a 20 20 20 20  Wal = pRet;.    
dbd0: 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 64  WALTRACE(("WAL%d
dbe0: 3a 20 6f 70 65 6e 65 64 5c 6e 22 2c 20 70 52 65  : opened\n", pRe
dbf0: 74 29 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  t));.  }.  retur
dc00: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  n rc;.}../*.** C
dc10: 68 61 6e 67 65 20 74 68 65 20 73 69 7a 65 20 74  hange the size t
dc20: 6f 20 77 68 69 63 68 20 74 68 65 20 57 41 4c 20  o which the WAL 
dc30: 66 69 6c 65 20 69 73 20 74 72 75 63 61 74 65 64  file is trucated
dc40: 20 6f 6e 20 65 61 63 68 20 72 65 73 65 74 2e 0a   on each reset..
dc50: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 57  */.void sqlite3W
dc60: 61 6c 4c 69 6d 69 74 28 57 61 6c 20 2a 70 57 61  alLimit(Wal *pWa
dc70: 6c 2c 20 69 36 34 20 69 4c 69 6d 69 74 29 7b 0a  l, i64 iLimit){.
dc80: 20 20 69 66 28 20 70 57 61 6c 20 29 20 70 57 61    if( pWal ) pWa
dc90: 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 20 3d 20 69  l->mxWalSize = i
dca0: 4c 69 6d 69 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Limit;.}../*.** 
dcb0: 46 69 6e 64 20 74 68 65 20 73 6d 61 6c 6c 65 73  Find the smalles
dcc0: 74 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 75  t page number ou
dcd0: 74 20 6f 66 20 61 6c 6c 20 70 61 67 65 73 20 68  t of all pages h
dce0: 65 6c 64 20 69 6e 20 74 68 65 20 57 41 4c 20 74  eld in the WAL t
dcf0: 68 61 74 0a 2a 2a 20 68 61 73 20 6e 6f 74 20 62  hat.** has not b
dd00: 65 65 6e 20 72 65 74 75 72 6e 65 64 20 62 79 20  een returned by 
dd10: 61 6e 79 20 70 72 69 6f 72 20 69 6e 76 6f 63 61  any prior invoca
dd20: 74 69 6f 6e 20 6f 66 20 74 68 69 73 20 6d 65 74  tion of this met
dd30: 68 6f 64 20 6f 6e 20 74 68 65 0a 2a 2a 20 73 61  hod on the.** sa
dd40: 6d 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f  me WalIterator o
dd50: 62 6a 65 63 74 2e 20 20 20 57 72 69 74 65 20 69  bject.   Write i
dd60: 6e 74 6f 20 2a 70 69 46 72 61 6d 65 20 74 68 65  nto *piFrame the
dd70: 20 66 72 61 6d 65 20 69 6e 64 65 78 20 77 68 65   frame index whe
dd80: 72 65 0a 2a 2a 20 74 68 61 74 20 70 61 67 65 20  re.** that page 
dd90: 77 61 73 20 6c 61 73 74 20 77 72 69 74 74 65 6e  was last written
dda0: 20 69 6e 74 6f 20 74 68 65 20 57 41 4c 2e 20 20   into the WAL.  
ddb0: 57 72 69 74 65 20 69 6e 74 6f 20 2a 70 69 50 61  Write into *piPa
ddc0: 67 65 20 74 68 65 20 70 61 67 65 0a 2a 2a 20 6e  ge the page.** n
ddd0: 75 6d 62 65 72 2e 0a 2a 2a 0a 2a 2a 20 52 65 74  umber..**.** Ret
dde0: 75 72 6e 20 30 20 6f 6e 20 73 75 63 63 65 73 73  urn 0 on success
ddf0: 2e 20 20 49 66 20 74 68 65 72 65 20 61 72 65 20  .  If there are 
de00: 6e 6f 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  no pages in the 
de10: 57 41 4c 20 77 69 74 68 20 61 20 70 61 67 65 0a  WAL with a page.
de20: 2a 2a 20 6e 75 6d 62 65 72 20 6c 61 72 67 65 72  ** number larger
de30: 20 74 68 61 6e 20 2a 70 69 50 61 67 65 2c 20 74   than *piPage, t
de40: 68 65 6e 20 72 65 74 75 72 6e 20 31 2e 0a 2a 2f  hen return 1..*/
de50: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49  .static int walI
de60: 74 65 72 61 74 6f 72 4e 65 78 74 28 0a 20 20 57  teratorNext(.  W
de70: 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 2c 20 20  alIterator *p,  
de80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
de90: 49 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 75 33  Iterator */.  u3
dea0: 32 20 2a 70 69 50 61 67 65 2c 20 20 20 20 20 20  2 *piPage,      
deb0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
dec0: 55 54 3a 20 54 68 65 20 70 61 67 65 20 6e 75 6d  UT: The page num
ded0: 62 65 72 20 6f 66 20 74 68 65 20 6e 65 78 74 20  ber of the next 
dee0: 70 61 67 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70  page */.  u32 *p
def0: 69 46 72 61 6d 65 20 20 20 20 20 20 20 20 20 20  iFrame          
df00: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
df10: 57 61 6c 20 66 72 61 6d 65 20 69 6e 64 65 78 20  Wal frame index 
df20: 6f 66 20 6e 65 78 74 20 70 61 67 65 20 2a 2f 0a  of next page */.
df30: 29 7b 0a 20 20 75 33 32 20 69 4d 69 6e 3b 20 20  ){.  u32 iMin;  
df40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
df50: 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 70 67 6e     /* Result pgn
df60: 6f 20 6d 75 73 74 20 62 65 20 67 72 65 61 74 65  o must be greate
df70: 72 20 74 68 61 6e 20 69 4d 69 6e 20 2a 2f 0a 20  r than iMin */. 
df80: 20 75 33 32 20 69 52 65 74 20 3d 20 30 78 46 46   u32 iRet = 0xFF
df90: 46 46 46 46 46 46 3b 20 20 20 20 20 20 20 20 2f  FFFFFF;        /
dfa0: 2a 20 30 78 66 66 66 66 66 66 66 66 20 69 73 20  * 0xffffffff is 
dfb0: 6e 65 76 65 72 20 61 20 76 61 6c 69 64 20 70 61  never a valid pa
dfc0: 67 65 20 6e 75 6d 62 65 72 20 2a 2f 0a 20 20 69  ge number */.  i
dfd0: 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20  nt i;           
dfe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
dff0: 46 6f 72 20 6c 6f 6f 70 69 6e 67 20 74 68 72 6f  For looping thro
e000: 75 67 68 20 73 65 67 6d 65 6e 74 73 20 2a 2f 0a  ugh segments */.
e010: 0a 20 20 69 4d 69 6e 20 3d 20 70 2d 3e 69 50 72  .  iMin = p->iPr
e020: 69 6f 72 3b 0a 20 20 61 73 73 65 72 74 28 20 69  ior;.  assert( i
e030: 4d 69 6e 3c 30 78 66 66 66 66 66 66 66 66 20 29  Min<0xffffffff )
e040: 3b 0a 20 20 66 6f 72 28 69 3d 70 2d 3e 6e 53 65  ;.  for(i=p->nSe
e050: 67 6d 65 6e 74 2d 31 3b 20 69 3e 3d 30 3b 20 69  gment-1; i>=0; i
e060: 2d 2d 29 7b 0a 20 20 20 20 73 74 72 75 63 74 20  --){.    struct 
e070: 57 61 6c 53 65 67 6d 65 6e 74 20 2a 70 53 65 67  WalSegment *pSeg
e080: 6d 65 6e 74 20 3d 20 26 70 2d 3e 61 53 65 67 6d  ment = &p->aSegm
e090: 65 6e 74 5b 69 5d 3b 0a 20 20 20 20 77 68 69 6c  ent[i];.    whil
e0a0: 65 28 20 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65  e( pSegment->iNe
e0b0: 78 74 3c 70 53 65 67 6d 65 6e 74 2d 3e 6e 45 6e  xt<pSegment->nEn
e0c0: 74 72 79 20 29 7b 0a 20 20 20 20 20 20 75 33 32  try ){.      u32
e0d0: 20 69 50 67 20 3d 20 70 53 65 67 6d 65 6e 74 2d   iPg = pSegment-
e0e0: 3e 61 50 67 6e 6f 5b 70 53 65 67 6d 65 6e 74 2d  >aPgno[pSegment-
e0f0: 3e 61 49 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74  >aIndex[pSegment
e100: 2d 3e 69 4e 65 78 74 5d 5d 3b 0a 20 20 20 20 20  ->iNext]];.     
e110: 20 69 66 28 20 69 50 67 3e 69 4d 69 6e 20 29 7b   if( iPg>iMin ){
e120: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 50 67  .        if( iPg
e130: 3c 69 52 65 74 20 29 7b 0a 20 20 20 20 20 20 20  <iRet ){.       
e140: 20 20 20 69 52 65 74 20 3d 20 69 50 67 3b 0a 20     iRet = iPg;. 
e150: 20 20 20 20 20 20 20 20 20 2a 70 69 46 72 61 6d           *piFram
e160: 65 20 3d 20 70 53 65 67 6d 65 6e 74 2d 3e 69 5a  e = pSegment->iZ
e170: 65 72 6f 20 2b 20 70 53 65 67 6d 65 6e 74 2d 3e  ero + pSegment->
e180: 61 49 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d  aIndex[pSegment-
e190: 3e 69 4e 65 78 74 5d 3b 0a 20 20 20 20 20 20 20  >iNext];.       
e1a0: 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b   }.        break
e1b0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
e1c0: 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 2b  pSegment->iNext+
e1d0: 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  +;.    }.  }..  
e1e0: 2a 70 69 50 61 67 65 20 3d 20 70 2d 3e 69 50 72  *piPage = p->iPr
e1f0: 69 6f 72 20 3d 20 69 52 65 74 3b 0a 20 20 72 65  ior = iRet;.  re
e200: 74 75 72 6e 20 28 69 52 65 74 3d 3d 30 78 46 46  turn (iRet==0xFF
e210: 46 46 46 46 46 46 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  FFFFFF);.}../*.*
e220: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
e230: 6d 65 72 67 65 73 20 74 77 6f 20 73 6f 72 74 65  merges two sorte
e240: 64 20 6c 69 73 74 73 20 69 6e 74 6f 20 61 20 73  d lists into a s
e250: 69 6e 67 6c 65 20 73 6f 72 74 65 64 20 6c 69 73  ingle sorted lis
e260: 74 2e 0a 2a 2a 0a 2a 2a 20 61 4c 65 66 74 5b 5d  t..**.** aLeft[]
e270: 20 61 6e 64 20 61 52 69 67 68 74 5b 5d 20 61 72   and aRight[] ar
e280: 65 20 61 72 72 61 79 73 20 6f 66 20 69 6e 64 69  e arrays of indi
e290: 63 65 73 2e 20 20 54 68 65 20 73 6f 72 74 20 6b  ces.  The sort k
e2a0: 65 79 20 69 73 0a 2a 2a 20 61 43 6f 6e 74 65 6e  ey is.** aConten
e2b0: 74 5b 61 4c 65 66 74 5b 5d 5d 20 61 6e 64 20 61  t[aLeft[]] and a
e2c0: 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b 5d  Content[aRight[]
e2d0: 5d 2e 20 20 55 70 6f 6e 20 65 6e 74 72 79 2c 20  ].  Upon entry, 
e2e0: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a  the following.**
e2f0: 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 66   is guaranteed f
e300: 6f 72 20 61 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a 2a  or all J<K:.**.*
e310: 2a 20 20 20 20 20 20 20 20 61 43 6f 6e 74 65 6e  *        aConten
e320: 74 5b 61 4c 65 66 74 5b 4a 5d 5d 20 3c 20 61 43  t[aLeft[J]] < aC
e330: 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 4b 5d 5d  ontent[aLeft[K]]
e340: 0a 2a 2a 20 20 20 20 20 20 20 20 61 43 6f 6e 74  .**        aCont
e350: 65 6e 74 5b 61 52 69 67 68 74 5b 4a 5d 5d 20 3c  ent[aRight[J]] <
e360: 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74   aContent[aRight
e370: 5b 4b 5d 5d 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  [K]].**.** This 
e380: 72 6f 75 74 69 6e 65 20 6f 76 65 72 77 72 69 74  routine overwrit
e390: 65 73 20 61 52 69 67 68 74 5b 5d 20 77 69 74 68  es aRight[] with
e3a0: 20 61 20 6e 65 77 20 28 70 72 6f 62 61 62 6c 79   a new (probably
e3b0: 20 6c 6f 6e 67 65 72 29 20 73 65 71 75 65 6e 63   longer) sequenc
e3c0: 65 0a 2a 2a 20 6f 66 20 69 6e 64 69 63 65 73 20  e.** of indices 
e3d0: 73 75 63 68 20 74 68 61 74 20 74 68 65 20 61 52  such that the aR
e3e0: 69 67 68 74 5b 5d 20 63 6f 6e 74 61 69 6e 73 20  ight[] contains 
e3f0: 65 76 65 72 79 20 69 6e 64 65 78 20 74 68 61 74  every index that
e400: 20 61 70 70 65 61 72 73 20 69 6e 0a 2a 2a 20 65   appears in.** e
e410: 69 74 68 65 72 20 61 4c 65 66 74 5b 5d 20 6f 72  ither aLeft[] or
e420: 20 74 68 65 20 6f 6c 64 20 61 52 69 67 68 74 5b   the old aRight[
e430: 5d 20 61 6e 64 20 73 75 63 68 20 74 68 61 74 20  ] and such that 
e440: 74 68 65 20 73 65 63 6f 6e 64 20 63 6f 6e 64 69  the second condi
e450: 74 69 6f 6e 0a 2a 2a 20 61 62 6f 76 65 20 69 73  tion.** above is
e460: 20 73 74 69 6c 6c 20 6d 65 74 2e 0a 2a 2a 0a 2a   still met..**.*
e470: 2a 20 54 68 65 20 61 43 6f 6e 74 65 6e 74 5b 61  * The aContent[a
e480: 4c 65 66 74 5b 58 5d 5d 20 76 61 6c 75 65 73 20  Left[X]] values 
e490: 77 69 6c 6c 20 62 65 20 75 6e 69 71 75 65 20 66  will be unique f
e4a0: 6f 72 20 61 6c 6c 20 58 2e 20 20 41 6e 64 20 74  or all X.  And t
e4b0: 68 65 0a 2a 2a 20 61 43 6f 6e 74 65 6e 74 5b 61  he.** aContent[a
e4c0: 52 69 67 68 74 5b 58 5d 5d 20 76 61 6c 75 65 73  Right[X]] values
e4d0: 20 77 69 6c 6c 20 62 65 20 75 6e 69 71 75 65 20   will be unique 
e4e0: 74 6f 6f 2e 20 20 42 75 74 20 74 68 65 72 65 20  too.  But there 
e4f0: 6d 69 67 68 74 20 62 65 0a 2a 2a 20 6f 6e 65 20  might be.** one 
e500: 6f 72 20 6d 6f 72 65 20 63 6f 6d 62 69 6e 61 74  or more combinat
e510: 69 6f 6e 73 20 6f 66 20 58 20 61 6e 64 20 59 20  ions of X and Y 
e520: 73 75 63 68 20 74 68 61 74 0a 2a 2a 0a 2a 2a 20  such that.**.** 
e530: 20 20 20 20 20 61 4c 65 66 74 5b 58 5d 21 3d 61       aLeft[X]!=a
e540: 52 69 67 68 74 5b 59 5d 20 20 26 26 20 20 61 43  Right[Y]  &&  aC
e550: 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 58 5d 5d  ontent[aLeft[X]]
e560: 20 3d 3d 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69   == aContent[aRi
e570: 67 68 74 5b 59 5d 5d 0a 2a 2a 0a 2a 2a 20 57 68  ght[Y]].**.** Wh
e580: 65 6e 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c  en that happens,
e590: 20 6f 6d 69 74 20 74 68 65 20 61 4c 65 66 74 5b   omit the aLeft[
e5a0: 58 5d 20 61 6e 64 20 75 73 65 20 74 68 65 20 61  X] and use the a
e5b0: 52 69 67 68 74 5b 59 5d 20 69 6e 64 65 78 2e 0a  Right[Y] index..
e5c0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
e5d0: 61 6c 4d 65 72 67 65 28 0a 20 20 63 6f 6e 73 74  alMerge(.  const
e5e0: 20 75 33 32 20 2a 61 43 6f 6e 74 65 6e 74 2c 20   u32 *aContent, 
e5f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
e600: 67 65 73 20 69 6e 20 77 61 6c 20 2d 20 6b 65 79  ges in wal - key
e610: 73 20 66 6f 72 20 74 68 65 20 73 6f 72 74 20 2a  s for the sort *
e620: 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 65  /.  ht_slot *aLe
e630: 66 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ft,             
e640: 20 20 20 20 2f 2a 20 49 4e 3a 20 4c 65 66 74 20      /* IN: Left 
e650: 68 61 6e 64 20 69 6e 70 75 74 20 6c 69 73 74 20  hand input list 
e660: 2a 2f 0a 20 20 69 6e 74 20 6e 4c 65 66 74 2c 20  */.  int nLeft, 
e670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e680: 20 20 20 20 20 2f 2a 20 49 4e 3a 20 45 6c 65 6d       /* IN: Elem
e690: 65 6e 74 73 20 69 6e 20 61 72 72 61 79 20 2a 70  ents in array *p
e6a0: 61 4c 65 66 74 20 2a 2f 0a 20 20 68 74 5f 73 6c  aLeft */.  ht_sl
e6b0: 6f 74 20 2a 2a 70 61 52 69 67 68 74 2c 20 20 20  ot **paRight,   
e6c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e             /* IN
e6d0: 2f 4f 55 54 3a 20 52 69 67 68 74 20 68 61 6e 64  /OUT: Right hand
e6e0: 20 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20   input list */. 
e6f0: 20 69 6e 74 20 2a 70 6e 52 69 67 68 74 2c 20 20   int *pnRight,  
e700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e710: 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45 6c 65 6d   /* IN/OUT: Elem
e720: 65 6e 74 73 20 69 6e 20 2a 70 61 52 69 67 68 74  ents in *paRight
e730: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61   */.  ht_slot *a
e740: 54 6d 70 20 20 20 20 20 20 20 20 20 20 20 20 20  Tmp             
e750: 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61        /* Tempora
e760: 72 79 20 62 75 66 66 65 72 20 2a 2f 0a 29 7b 0a  ry buffer */.){.
e770: 20 20 69 6e 74 20 69 4c 65 66 74 20 3d 20 30 3b    int iLeft = 0;
e780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e790: 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64    /* Current ind
e7a0: 65 78 20 69 6e 20 61 4c 65 66 74 20 2a 2f 0a 20  ex in aLeft */. 
e7b0: 20 69 6e 74 20 69 52 69 67 68 74 20 3d 20 30 3b   int iRight = 0;
e7c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e7d0: 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65   /* Current inde
e7e0: 78 20 69 6e 20 61 52 69 67 68 74 20 2a 2f 0a 20  x in aRight */. 
e7f0: 20 69 6e 74 20 69 4f 75 74 20 3d 20 30 3b 20 20   int iOut = 0;  
e800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e810: 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65   /* Current inde
e820: 78 20 69 6e 20 6f 75 74 70 75 74 20 62 75 66 66  x in output buff
e830: 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 69 67  er */.  int nRig
e840: 68 74 20 3d 20 2a 70 6e 52 69 67 68 74 3b 0a 20  ht = *pnRight;. 
e850: 20 68 74 5f 73 6c 6f 74 20 2a 61 52 69 67 68 74   ht_slot *aRight
e860: 20 3d 20 2a 70 61 52 69 67 68 74 3b 0a 0a 20 20   = *paRight;..  
e870: 61 73 73 65 72 74 28 20 6e 4c 65 66 74 3e 30 20  assert( nLeft>0 
e880: 26 26 20 6e 52 69 67 68 74 3e 30 20 29 3b 0a 20  && nRight>0 );. 
e890: 20 77 68 69 6c 65 28 20 69 52 69 67 68 74 3c 6e   while( iRight<n
e8a0: 52 69 67 68 74 20 7c 7c 20 69 4c 65 66 74 3c 6e  Right || iLeft<n
e8b0: 4c 65 66 74 20 29 7b 0a 20 20 20 20 68 74 5f 73  Left ){.    ht_s
e8c0: 6c 6f 74 20 6c 6f 67 70 61 67 65 3b 0a 20 20 20  lot logpage;.   
e8d0: 20 50 67 6e 6f 20 64 62 70 61 67 65 3b 0a 0a 20   Pgno dbpage;.. 
e8e0: 20 20 20 69 66 28 20 28 69 4c 65 66 74 3c 6e 4c     if( (iLeft<nL
e8f0: 65 66 74 29 20 0a 20 20 20 20 20 26 26 20 28 69  eft) .     && (i
e900: 52 69 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c  Right>=nRight ||
e910: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b   aContent[aLeft[
e920: 69 4c 65 66 74 5d 5d 3c 61 43 6f 6e 74 65 6e 74  iLeft]]<aContent
e930: 5b 61 52 69 67 68 74 5b 69 52 69 67 68 74 5d 5d  [aRight[iRight]]
e940: 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 6c  ).    ){.      l
e950: 6f 67 70 61 67 65 20 3d 20 61 4c 65 66 74 5b 69  ogpage = aLeft[i
e960: 4c 65 66 74 2b 2b 5d 3b 0a 20 20 20 20 7d 65 6c  Left++];.    }el
e970: 73 65 7b 0a 20 20 20 20 20 20 6c 6f 67 70 61 67  se{.      logpag
e980: 65 20 3d 20 61 52 69 67 68 74 5b 69 52 69 67 68  e = aRight[iRigh
e990: 74 2b 2b 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20  t++];.    }.    
e9a0: 64 62 70 61 67 65 20 3d 20 61 43 6f 6e 74 65 6e  dbpage = aConten
e9b0: 74 5b 6c 6f 67 70 61 67 65 5d 3b 0a 0a 20 20 20  t[logpage];..   
e9c0: 20 61 54 6d 70 5b 69 4f 75 74 2b 2b 5d 20 3d 20   aTmp[iOut++] = 
e9d0: 6c 6f 67 70 61 67 65 3b 0a 20 20 20 20 69 66 28  logpage;.    if(
e9e0: 20 69 4c 65 66 74 3c 6e 4c 65 66 74 20 26 26 20   iLeft<nLeft && 
e9f0: 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69  aContent[aLeft[i
ea00: 4c 65 66 74 5d 5d 3d 3d 64 62 70 61 67 65 20 29  Left]]==dbpage )
ea10: 20 69 4c 65 66 74 2b 2b 3b 0a 0a 20 20 20 20 61   iLeft++;..    a
ea20: 73 73 65 72 74 28 20 69 4c 65 66 74 3e 3d 6e 4c  ssert( iLeft>=nL
ea30: 65 66 74 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b  eft || aContent[
ea40: 61 4c 65 66 74 5b 69 4c 65 66 74 5d 5d 3e 64 62  aLeft[iLeft]]>db
ea50: 70 61 67 65 20 29 3b 0a 20 20 20 20 61 73 73 65  page );.    asse
ea60: 72 74 28 20 69 52 69 67 68 74 3e 3d 6e 52 69 67  rt( iRight>=nRig
ea70: 68 74 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61  ht || aContent[a
ea80: 52 69 67 68 74 5b 69 52 69 67 68 74 5d 5d 3e 64  Right[iRight]]>d
ea90: 62 70 61 67 65 20 29 3b 0a 20 20 7d 0a 0a 20 20  bpage );.  }..  
eaa0: 2a 70 61 52 69 67 68 74 20 3d 20 61 4c 65 66 74  *paRight = aLeft
eab0: 3b 0a 20 20 2a 70 6e 52 69 67 68 74 20 3d 20 69  ;.  *pnRight = i
eac0: 4f 75 74 3b 0a 20 20 6d 65 6d 63 70 79 28 61 4c  Out;.  memcpy(aL
ead0: 65 66 74 2c 20 61 54 6d 70 2c 20 73 69 7a 65 6f  eft, aTmp, sizeo
eae0: 66 28 61 54 6d 70 5b 30 5d 29 2a 69 4f 75 74 29  f(aTmp[0])*iOut)
eaf0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20  ;.}../*.** Sort 
eb00: 74 68 65 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20  the elements in 
eb10: 6c 69 73 74 20 61 4c 69 73 74 20 75 73 69 6e 67  list aList using
eb20: 20 61 43 6f 6e 74 65 6e 74 5b 5d 20 61 73 20 74   aContent[] as t
eb30: 68 65 20 73 6f 72 74 20 6b 65 79 2e 0a 2a 2a 20  he sort key..** 
eb40: 52 65 6d 6f 76 65 20 65 6c 65 6d 65 6e 74 73 20  Remove elements 
eb50: 77 69 74 68 20 64 75 70 6c 69 63 61 74 65 20 6b  with duplicate k
eb60: 65 79 73 2c 20 70 72 65 66 65 72 72 69 6e 67 20  eys, preferring 
eb70: 74 6f 20 6b 65 65 70 20 74 68 65 0a 2a 2a 20 6c  to keep the.** l
eb80: 61 72 67 65 72 20 61 4c 69 73 74 5b 5d 20 76 61  arger aList[] va
eb90: 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  lues..**.** The 
eba0: 61 4c 69 73 74 5b 5d 20 65 6e 74 72 69 65 73 20  aList[] entries 
ebb0: 61 72 65 20 69 6e 64 69 63 65 73 20 69 6e 74 6f  are indices into
ebc0: 20 61 43 6f 6e 74 65 6e 74 5b 5d 2e 20 20 54 68   aContent[].  Th
ebd0: 65 20 76 61 6c 75 65 73 20 69 6e 0a 2a 2a 20 61  e values in.** a
ebe0: 4c 69 73 74 5b 5d 20 61 72 65 20 74 6f 20 62 65  List[] are to be
ebf0: 20 73 6f 72 74 65 64 20 73 6f 20 74 68 61 74 20   sorted so that 
ec00: 66 6f 72 20 61 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a  for all J<K:.**.
ec10: 2a 2a 20 20 20 20 20 20 61 43 6f 6e 74 65 6e 74  **      aContent
ec20: 5b 61 4c 69 73 74 5b 4a 5d 5d 20 3c 20 61 43 6f  [aList[J]] < aCo
ec30: 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 4b 5d 5d 0a  ntent[aList[K]].
ec40: 2a 2a 0a 2a 2a 20 46 6f 72 20 61 6e 79 20 58 20  **.** For any X 
ec50: 61 6e 64 20 59 20 73 75 63 68 20 74 68 61 74 0a  and Y such that.
ec60: 2a 2a 0a 2a 2a 20 20 20 20 20 20 61 43 6f 6e 74  **.**      aCont
ec70: 65 6e 74 5b 61 4c 69 73 74 5b 58 5d 5d 20 3d 3d  ent[aList[X]] ==
ec80: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b   aContent[aList[
ec90: 59 5d 5d 0a 2a 2a 0a 2a 2a 20 4b 65 65 70 20 74  Y]].**.** Keep t
eca0: 68 65 20 6c 61 72 67 65 72 20 6f 66 20 74 68 65  he larger of the
ecb0: 20 74 77 6f 20 76 61 6c 75 65 73 20 61 4c 69 73   two values aLis
ecc0: 74 5b 58 5d 20 61 6e 64 20 61 4c 69 73 74 5b 59  t[X] and aList[Y
ecd0: 5d 20 61 6e 64 20 64 69 73 63 61 72 64 0a 2a 2a  ] and discard.**
ece0: 20 74 68 65 20 73 6d 61 6c 6c 65 72 2e 0a 2a 2f   the smaller..*/
ecf0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
ed00: 4d 65 72 67 65 73 6f 72 74 28 0a 20 20 63 6f 6e  Mergesort(.  con
ed10: 73 74 20 75 33 32 20 2a 61 43 6f 6e 74 65 6e 74  st u32 *aContent
ed20: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
ed30: 50 61 67 65 73 20 69 6e 20 77 61 6c 20 2a 2f 0a  Pages in wal */.
ed40: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 42 75 66 66    ht_slot *aBuff
ed50: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
ed60: 20 20 2f 2a 20 42 75 66 66 65 72 20 6f 66 20 61    /* Buffer of a
ed70: 74 20 6c 65 61 73 74 20 2a 70 6e 4c 69 73 74 20  t least *pnList 
ed80: 69 74 65 6d 73 20 74 6f 20 75 73 65 20 2a 2f 0a  items to use */.
ed90: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 69 73 74    ht_slot *aList
eda0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
edb0: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4c 69 73    /* IN/OUT: Lis
edc0: 74 20 74 6f 20 73 6f 72 74 20 2a 2f 0a 20 20 69  t to sort */.  i
edd0: 6e 74 20 2a 70 6e 4c 69 73 74 20 20 20 20 20 20  nt *pnList      
ede0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
edf0: 2a 20 49 4e 2f 4f 55 54 3a 20 4e 75 6d 62 65 72  * IN/OUT: Number
ee00: 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20   of elements in 
ee10: 61 4c 69 73 74 5b 5d 20 2a 2f 0a 29 7b 0a 20 20  aList[] */.){.  
ee20: 73 74 72 75 63 74 20 53 75 62 6c 69 73 74 20 7b  struct Sublist {
ee30: 0a 20 20 20 20 69 6e 74 20 6e 4c 69 73 74 3b 20  .    int nList; 
ee40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ee50: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
ee60: 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 4c 69 73  elements in aLis
ee70: 74 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74  t */.    ht_slot
ee80: 20 2a 61 4c 69 73 74 3b 20 20 20 20 20 20 20 20   *aList;        
ee90: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
eea0: 72 20 74 6f 20 73 75 62 2d 6c 69 73 74 20 63 6f  r to sub-list co
eeb0: 6e 74 65 6e 74 20 2a 2f 0a 20 20 7d 3b 0a 0a 20  ntent */.  };.. 
eec0: 20 63 6f 6e 73 74 20 69 6e 74 20 6e 4c 69 73 74   const int nList
eed0: 20 3d 20 2a 70 6e 4c 69 73 74 3b 20 20 20 20 20   = *pnList;     
eee0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 69 6e 70 75   /* Size of inpu
eef0: 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20  t list */.  int 
ef00: 6e 4d 65 72 67 65 20 3d 20 30 3b 20 20 20 20 20  nMerge = 0;     
ef10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
ef20: 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74  umber of element
ef30: 73 20 69 6e 20 6c 69 73 74 20 61 4d 65 72 67 65  s in list aMerge
ef40: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61   */.  ht_slot *a
ef50: 4d 65 72 67 65 20 3d 20 30 3b 20 20 20 20 20 20  Merge = 0;      
ef60: 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 74 6f        /* List to
ef70: 20 62 65 20 6d 65 72 67 65 64 20 2a 2f 0a 20 20   be merged */.  
ef80: 69 6e 74 20 69 4c 69 73 74 3b 20 20 20 20 20 20  int iList;      
ef90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
efa0: 2f 2a 20 49 6e 64 65 78 20 69 6e 74 6f 20 69 6e  /* Index into in
efb0: 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 75 33  put list */.  u3
efc0: 32 20 69 53 75 62 20 3d 20 30 3b 20 20 20 20 20  2 iSub = 0;     
efd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
efe0: 20 49 6e 64 65 78 20 69 6e 74 6f 20 61 53 75 62   Index into aSub
eff0: 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 74 72 75   array */.  stru
f000: 63 74 20 53 75 62 6c 69 73 74 20 61 53 75 62 5b  ct Sublist aSub[
f010: 31 33 5d 3b 20 20 20 20 20 20 20 20 2f 2a 20 41  13];        /* A
f020: 72 72 61 79 20 6f 66 20 73 75 62 2d 6c 69 73 74  rray of sub-list
f030: 73 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65 74 28 61  s */..  memset(a
f040: 53 75 62 2c 20 30 2c 20 73 69 7a 65 6f 66 28 61  Sub, 0, sizeof(a
f050: 53 75 62 29 29 3b 0a 20 20 61 73 73 65 72 74 28  Sub));.  assert(
f060: 20 6e 4c 69 73 74 3c 3d 48 41 53 48 54 41 42 4c   nList<=HASHTABL
f070: 45 5f 4e 50 41 47 45 20 26 26 20 6e 4c 69 73 74  E_NPAGE && nList
f080: 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  >0 );.  assert( 
f090: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3d  HASHTABLE_NPAGE=
f0a0: 3d 28 31 3c 3c 28 41 72 72 61 79 53 69 7a 65 28  =(1<<(ArraySize(
f0b0: 61 53 75 62 29 2d 31 29 29 20 29 3b 0a 0a 20 20  aSub)-1)) );..  
f0c0: 66 6f 72 28 69 4c 69 73 74 3d 30 3b 20 69 4c 69  for(iList=0; iLi
f0d0: 73 74 3c 6e 4c 69 73 74 3b 20 69 4c 69 73 74 2b  st<nList; iList+
f0e0: 2b 29 7b 0a 20 20 20 20 6e 4d 65 72 67 65 20 3d  +){.    nMerge =
f0f0: 20 31 3b 0a 20 20 20 20 61 4d 65 72 67 65 20 3d   1;.    aMerge =
f100: 20 26 61 4c 69 73 74 5b 69 4c 69 73 74 5d 3b 0a   &aList[iList];.
f110: 20 20 20 20 66 6f 72 28 69 53 75 62 3d 30 3b 20      for(iSub=0; 
f120: 69 4c 69 73 74 20 26 20 28 31 3c 3c 69 53 75 62  iList & (1<<iSub
f130: 29 3b 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20  ); iSub++){.    
f140: 20 20 73 74 72 75 63 74 20 53 75 62 6c 69 73 74    struct Sublist
f150: 20 2a 70 3b 0a 20 20 20 20 20 20 61 73 73 65 72   *p;.      asser
f160: 74 28 20 69 53 75 62 3c 41 72 72 61 79 53 69 7a  t( iSub<ArraySiz
f170: 65 28 61 53 75 62 29 20 29 3b 0a 20 20 20 20 20  e(aSub) );.     
f180: 20 70 20 3d 20 26 61 53 75 62 5b 69 53 75 62 5d   p = &aSub[iSub]
f190: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
f1a0: 70 2d 3e 61 4c 69 73 74 20 26 26 20 70 2d 3e 6e  p->aList && p->n
f1b0: 4c 69 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29 20  List<=(1<<iSub) 
f1c0: 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
f1d0: 20 70 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69 73   p->aList==&aLis
f1e0: 74 5b 69 4c 69 73 74 26 7e 28 28 32 3c 3c 69 53  t[iList&~((2<<iS
f1f0: 75 62 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20 20  ub)-1)] );.     
f200: 20 77 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74 65   walMerge(aConte
f210: 6e 74 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70 2d  nt, p->aList, p-
f220: 3e 6e 4c 69 73 74 2c 20 26 61 4d 65 72 67 65 2c  >nList, &aMerge,
f230: 20 26 6e 4d 65 72 67 65 2c 20 61 42 75 66 66 65   &nMerge, aBuffe
f240: 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 53  r);.    }.    aS
f250: 75 62 5b 69 53 75 62 5d 2e 61 4c 69 73 74 20 3d  ub[iSub].aList =
f260: 20 61 4d 65 72 67 65 3b 0a 20 20 20 20 61 53 75   aMerge;.    aSu
f270: 62 5b 69 53 75 62 5d 2e 6e 4c 69 73 74 20 3d 20  b[iSub].nList = 
f280: 6e 4d 65 72 67 65 3b 0a 20 20 7d 0a 0a 20 20 66  nMerge;.  }..  f
f290: 6f 72 28 69 53 75 62 2b 2b 3b 20 69 53 75 62 3c  or(iSub++; iSub<
f2a0: 41 72 72 61 79 53 69 7a 65 28 61 53 75 62 29 3b  ArraySize(aSub);
f2b0: 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20 69 66   iSub++){.    if
f2c0: 28 20 6e 4c 69 73 74 20 26 20 28 31 3c 3c 69 53  ( nList & (1<<iS
f2d0: 75 62 29 20 29 7b 0a 20 20 20 20 20 20 73 74 72  ub) ){.      str
f2e0: 75 63 74 20 53 75 62 6c 69 73 74 20 2a 70 3b 0a  uct Sublist *p;.
f2f0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 53        assert( iS
f300: 75 62 3c 41 72 72 61 79 53 69 7a 65 28 61 53 75  ub<ArraySize(aSu
f310: 62 29 20 29 3b 0a 20 20 20 20 20 20 70 20 3d 20  b) );.      p = 
f320: 26 61 53 75 62 5b 69 53 75 62 5d 3b 0a 20 20 20  &aSub[iSub];.   
f330: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 4c     assert( p->nL
f340: 69 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29 20 29  ist<=(1<<iSub) )
f350: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
f360: 70 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69 73 74  p->aList==&aList
f370: 5b 6e 4c 69 73 74 26 7e 28 28 32 3c 3c 69 53 75  [nList&~((2<<iSu
f380: 62 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20 20 20  b)-1)] );.      
f390: 77 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74 65 6e  walMerge(aConten
f3a0: 74 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70 2d 3e  t, p->aList, p->
f3b0: 6e 4c 69 73 74 2c 20 26 61 4d 65 72 67 65 2c 20  nList, &aMerge, 
f3c0: 26 6e 4d 65 72 67 65 2c 20 61 42 75 66 66 65 72  &nMerge, aBuffer
f3d0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61  );.    }.  }.  a
f3e0: 73 73 65 72 74 28 20 61 4d 65 72 67 65 3d 3d 61  ssert( aMerge==a
f3f0: 4c 69 73 74 20 29 3b 0a 20 20 2a 70 6e 4c 69 73  List );.  *pnLis
f400: 74 20 3d 20 6e 4d 65 72 67 65 3b 0a 0a 23 69 66  t = nMerge;..#if
f410: 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47  def SQLITE_DEBUG
f420: 0a 20 20 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a  .  {.    int i;.
f430: 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 2a      for(i=1; i<*
f440: 70 6e 4c 69 73 74 3b 20 69 2b 2b 29 7b 0a 20 20  pnList; i++){.  
f450: 20 20 20 20 61 73 73 65 72 74 28 20 61 43 6f 6e      assert( aCon
f460: 74 65 6e 74 5b 61 4c 69 73 74 5b 69 5d 5d 20 3e  tent[aList[i]] >
f470: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b   aContent[aList[
f480: 69 2d 31 5d 5d 20 29 3b 0a 20 20 20 20 7d 0a 20  i-1]] );.    }. 
f490: 20 7d 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 20   }.#endif.}../* 
f4a0: 0a 2a 2a 20 46 72 65 65 20 61 6e 20 69 74 65 72  .** Free an iter
f4b0: 61 74 6f 72 20 61 6c 6c 6f 63 61 74 65 64 20 62  ator allocated b
f4c0: 79 20 77 61 6c 49 74 65 72 61 74 6f 72 49 6e 69  y walIteratorIni
f4d0: 74 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  t()..*/.static v
f4e0: 6f 69 64 20 77 61 6c 49 74 65 72 61 74 6f 72 46  oid walIteratorF
f4f0: 72 65 65 28 57 61 6c 49 74 65 72 61 74 6f 72 20  ree(WalIterator 
f500: 2a 70 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  *p){.  sqlite3_f
f510: 72 65 65 28 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ree(p);.}../*.**
f520: 20 43 6f 6e 73 74 72 75 63 74 20 61 20 57 61 6c   Construct a Wal
f530: 49 6e 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74  Interator object
f540: 20 74 68 61 74 20 63 61 6e 20 62 65 20 75 73 65   that can be use
f550: 64 20 74 6f 20 6c 6f 6f 70 20 6f 76 65 72 20 61  d to loop over a
f560: 6c 6c 20 0a 2a 2a 20 70 61 67 65 73 20 69 6e 20  ll .** pages in 
f570: 74 68 65 20 57 41 4c 20 66 6f 6c 6c 6f 77 69 6e  the WAL followin
f580: 67 20 66 72 61 6d 65 20 6e 42 61 63 6b 66 69 6c  g frame nBackfil
f590: 6c 20 69 6e 20 61 73 63 65 6e 64 69 6e 67 20 6f  l in ascending o
f5a0: 72 64 65 72 2e 20 46 72 61 6d 65 73 0a 2a 2a 20  rder. Frames.** 
f5b0: 6e 42 61 63 6b 66 69 6c 6c 20 6f 72 20 65 61 72  nBackfill or ear
f5c0: 6c 69 65 72 20 6d 61 79 20 62 65 20 69 6e 63 6c  lier may be incl
f5d0: 75 64 65 64 20 2d 20 65 78 63 6c 75 64 69 6e 67  uded - excluding
f5e0: 20 74 68 65 6d 20 69 73 20 61 6e 20 6f 70 74 69   them is an opti
f5f0: 6d 69 7a 61 74 69 6f 6e 0a 2a 2a 20 6f 6e 6c 79  mization.** only
f600: 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  . The caller mus
f610: 74 20 68 6f 6c 64 20 74 68 65 20 63 68 65 63 6b  t hold the check
f620: 70 6f 69 6e 74 20 6c 6f 63 6b 2e 0a 2a 2a 0a 2a  point lock..**.*
f630: 2a 20 4f 6e 20 73 75 63 63 65 73 73 2c 20 6d 61  * On success, ma
f640: 6b 65 20 2a 70 70 20 70 6f 69 6e 74 20 74 6f 20  ke *pp point to 
f650: 74 68 65 20 6e 65 77 6c 79 20 61 6c 6c 6f 63 61  the newly alloca
f660: 74 65 64 20 57 61 6c 49 6e 74 65 72 61 74 6f 72  ted WalInterator
f670: 20 6f 62 6a 65 63 74 0a 2a 2a 20 72 65 74 75 72   object.** retur
f680: 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f 74 68  n SQLITE_OK. Oth
f690: 65 72 77 69 73 65 2c 20 72 65 74 75 72 6e 20 61  erwise, return a
f6a0: 6e 20 65 72 72 6f 72 20 63 6f 64 65 2e 20 49 66  n error code. If
f6b0: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a   this routine.**
f6c0: 20 72 65 74 75 72 6e 73 20 61 6e 20 65 72 72 6f   returns an erro
f6d0: 72 2c 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20  r, the value of 
f6e0: 2a 70 70 20 69 73 20 75 6e 64 65 66 69 6e 65 64  *pp is undefined
f6f0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c  ..**.** The call
f700: 69 6e 67 20 72 6f 75 74 69 6e 65 20 73 68 6f 75  ing routine shou
f710: 6c 64 20 69 6e 76 6f 6b 65 20 77 61 6c 49 74 65  ld invoke walIte
f720: 72 61 74 6f 72 46 72 65 65 28 29 20 74 6f 20 64  ratorFree() to d
f730: 65 73 74 72 6f 79 20 74 68 65 0a 2a 2a 20 57 61  estroy the.** Wa
f740: 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74  lIterator object
f750: 20 77 68 65 6e 20 69 74 20 68 61 73 20 66 69 6e   when it has fin
f760: 69 73 68 65 64 20 77 69 74 68 20 69 74 2e 0a 2a  ished with it..*
f770: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
f780: 49 74 65 72 61 74 6f 72 49 6e 69 74 28 57 61 6c  IteratorInit(Wal
f790: 20 2a 70 57 61 6c 2c 20 75 33 32 20 6e 42 61 63   *pWal, u32 nBac
f7a0: 6b 66 69 6c 6c 2c 20 57 61 6c 49 74 65 72 61 74  kfill, WalIterat
f7b0: 6f 72 20 2a 2a 70 70 29 7b 0a 20 20 57 61 6c 49  or **pp){.  WalI
f7c0: 74 65 72 61 74 6f 72 20 2a 70 3b 20 20 20 20 20  terator *p;     
f7d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
f7e0: 65 74 75 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 20  eturn value */. 
f7f0: 20 69 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20   int nSegment;  
f800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f810: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 65   /* Number of se
f820: 67 6d 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20  gments to merge 
f830: 2a 2f 0a 20 20 75 33 32 20 69 4c 61 73 74 3b 20  */.  u32 iLast; 
f840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f850: 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 66 72 61       /* Last fra
f860: 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20 69  me in log */.  i
f870: 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20  nt nByte;       
f880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
f890: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
f8a0: 73 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f  s to allocate */
f8b0: 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
f8c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f8d0: 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 76     /* Iterator v
f8e0: 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 68 74 5f  ariable */.  ht_
f8f0: 73 6c 6f 74 20 2a 61 54 6d 70 3b 20 20 20 20 20  slot *aTmp;     
f900: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
f910: 54 65 6d 70 20 73 70 61 63 65 20 75 73 65 64 20  Temp space used 
f920: 62 79 20 6d 65 72 67 65 2d 73 6f 72 74 20 2a 2f  by merge-sort */
f930: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
f940: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
f950: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64     /* Return Cod
f960: 65 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 69 73 20  e */..  /* This 
f970: 72 6f 75 74 69 6e 65 20 6f 6e 6c 79 20 72 75 6e  routine only run
f980: 73 20 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67 20  s while holding 
f990: 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 6c  the checkpoint l
f9a0: 6f 63 6b 2e 20 41 6e 64 0a 20 20 2a 2a 20 69 74  ock. And.  ** it
f9b0: 20 6f 6e 6c 79 20 72 75 6e 73 20 69 66 20 74 68   only runs if th
f9c0: 65 72 65 20 69 73 20 61 63 74 75 61 6c 6c 79 20  ere is actually 
f9d0: 63 6f 6e 74 65 6e 74 20 69 6e 20 74 68 65 20 6c  content in the l
f9e0: 6f 67 20 28 6d 78 46 72 61 6d 65 3e 30 29 2e 0a  og (mxFrame>0)..
f9f0: 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
fa00: 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20 26 26  Wal->ckptLock &&
fa10: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
fa20: 6d 65 3e 30 20 29 3b 0a 20 20 69 4c 61 73 74 20  me>0 );.  iLast 
fa30: 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  = pWal->hdr.mxFr
fa40: 61 6d 65 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63  ame;..  /* Alloc
fa50: 61 74 65 20 73 70 61 63 65 20 66 6f 72 20 74 68  ate space for th
fa60: 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62  e WalIterator ob
fa70: 6a 65 63 74 2e 20 2a 2f 0a 20 20 6e 53 65 67 6d  ject. */.  nSegm
fa80: 65 6e 74 20 3d 20 77 61 6c 46 72 61 6d 65 50 61  ent = walFramePa
fa90: 67 65 28 69 4c 61 73 74 29 20 2b 20 31 3b 0a 20  ge(iLast) + 1;. 
faa0: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
fab0: 57 61 6c 49 74 65 72 61 74 6f 72 29 20 0a 20 20  WalIterator) .  
fac0: 20 20 20 20 20 20 2b 20 28 6e 53 65 67 6d 65 6e        + (nSegmen
fad0: 74 2d 31 29 2a 73 69 7a 65 6f 66 28 73 74 72 75  t-1)*sizeof(stru
fae0: 63 74 20 57 61 6c 53 65 67 6d 65 6e 74 29 0a 20  ct WalSegment). 
faf0: 20 20 20 20 20 20 20 2b 20 69 4c 61 73 74 2a 73         + iLast*s
fb00: 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 3b 0a  izeof(ht_slot);.
fb10: 20 20 70 20 3d 20 28 57 61 6c 49 74 65 72 61 74    p = (WalIterat
fb20: 6f 72 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c  or *)sqlite3_mal
fb30: 6c 6f 63 36 34 28 6e 42 79 74 65 29 3b 0a 20 20  loc64(nByte);.  
fb40: 69 66 28 20 21 70 20 29 7b 0a 20 20 20 20 72 65  if( !p ){.    re
fb50: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
fb60: 4d 5f 42 4b 50 54 3b 0a 20 20 7d 0a 20 20 6d 65  M_BKPT;.  }.  me
fb70: 6d 73 65 74 28 70 2c 20 30 2c 20 6e 42 79 74 65  mset(p, 0, nByte
fb80: 29 3b 0a 20 20 70 2d 3e 6e 53 65 67 6d 65 6e 74  );.  p->nSegment
fb90: 20 3d 20 6e 53 65 67 6d 65 6e 74 3b 0a 0a 20 20   = nSegment;..  
fba0: 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 65 6d 70  /* Allocate temp
fbb0: 6f 72 61 72 79 20 73 70 61 63 65 20 75 73 65 64  orary space used
fbc0: 20 62 79 20 74 68 65 20 6d 65 72 67 65 2d 73 6f   by the merge-so
fbd0: 72 74 20 72 6f 75 74 69 6e 65 2e 20 54 68 69 73  rt routine. This
fbe0: 20 62 6c 6f 63 6b 0a 20 20 2a 2a 20 6f 66 20 6d   block.  ** of m
fbf0: 65 6d 6f 72 79 20 77 69 6c 6c 20 62 65 20 66 72  emory will be fr
fc00: 65 65 64 20 62 65 66 6f 72 65 20 74 68 69 73 20  eed before this 
fc10: 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
fc20: 2e 0a 20 20 2a 2f 0a 20 20 61 54 6d 70 20 3d 20  ..  */.  aTmp = 
fc30: 28 68 74 5f 73 6c 6f 74 20 2a 29 73 71 6c 69 74  (ht_slot *)sqlit
fc40: 65 33 5f 6d 61 6c 6c 6f 63 36 34 28 0a 20 20 20  e3_malloc64(.   
fc50: 20 20 20 73 69 7a 65 6f 66 28 68 74 5f 73 6c 6f     sizeof(ht_slo
fc60: 74 29 20 2a 20 28 69 4c 61 73 74 3e 48 41 53 48  t) * (iLast>HASH
fc70: 54 41 42 4c 45 5f 4e 50 41 47 45 3f 48 41 53 48  TABLE_NPAGE?HASH
fc80: 54 41 42 4c 45 5f 4e 50 41 47 45 3a 69 4c 61 73  TABLE_NPAGE:iLas
fc90: 74 29 0a 20 20 29 3b 0a 20 20 69 66 28 20 21 61  t).  );.  if( !a
fca0: 54 6d 70 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  Tmp ){.    rc = 
fcb0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50  SQLITE_NOMEM_BKP
fcc0: 54 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69 3d  T;.  }..  for(i=
fcd0: 77 61 6c 46 72 61 6d 65 50 61 67 65 28 6e 42 61  walFramePage(nBa
fce0: 63 6b 66 69 6c 6c 2b 31 29 3b 20 72 63 3d 3d 53  ckfill+1); rc==S
fcf0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 53  QLITE_OK && i<nS
fd00: 65 67 6d 65 6e 74 3b 20 69 2b 2b 29 7b 0a 20 20  egment; i++){.  
fd10: 20 20 57 61 6c 48 61 73 68 4c 6f 63 20 73 4c 6f    WalHashLoc sLo
fd20: 63 3b 0a 0a 20 20 20 20 72 63 20 3d 20 77 61 6c  c;..    rc = wal
fd30: 48 61 73 68 47 65 74 28 70 57 61 6c 2c 20 69 2c  HashGet(pWal, i,
fd40: 20 26 73 4c 6f 63 29 3b 0a 20 20 20 20 69 66 28   &sLoc);.    if(
fd50: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
fd60: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6a 3b 20 20  {.      int j;  
fd70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fd80: 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20 76      /* Counter v
fd90: 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 20 20 20  ariable */.     
fda0: 20 69 6e 74 20 6e 45 6e 74 72 79 3b 20 20 20 20   int nEntry;    
fdb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
fdc0: 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  Number of entrie
fdd0: 73 20 69 6e 20 74 68 69 73 20 73 65 67 6d 65 6e  s in this segmen
fde0: 74 20 2a 2f 0a 20 20 20 20 20 20 68 74 5f 73 6c  t */.      ht_sl
fdf0: 6f 74 20 2a 61 49 6e 64 65 78 3b 20 20 20 20 20  ot *aIndex;     
fe00: 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65 64         /* Sorted
fe10: 20 69 6e 64 65 78 20 66 6f 72 20 74 68 69 73 20   index for this 
fe20: 73 65 67 6d 65 6e 74 20 2a 2f 0a 0a 20 20 20 20  segment */..    
fe30: 20 20 73 4c 6f 63 2e 61 50 67 6e 6f 2b 2b 3b 0a    sLoc.aPgno++;.
fe40: 20 20 20 20 20 20 69 66 28 20 28 69 2b 31 29 3d        if( (i+1)=
fe50: 3d 6e 53 65 67 6d 65 6e 74 20 29 7b 0a 20 20 20  =nSegment ){.   
fe60: 20 20 20 20 20 6e 45 6e 74 72 79 20 3d 20 28 69       nEntry = (i
fe70: 6e 74 29 28 69 4c 61 73 74 20 2d 20 73 4c 6f 63  nt)(iLast - sLoc
fe80: 2e 69 5a 65 72 6f 29 3b 0a 20 20 20 20 20 20 7d  .iZero);.      }
fe90: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 6e 45  else{.        nE
fea0: 6e 74 72 79 20 3d 20 28 69 6e 74 29 28 28 75 33  ntry = (int)((u3
feb0: 32 2a 29 73 4c 6f 63 2e 61 48 61 73 68 20 2d 20  2*)sLoc.aHash - 
fec0: 28 75 33 32 2a 29 73 4c 6f 63 2e 61 50 67 6e 6f  (u32*)sLoc.aPgno
fed0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
fee0: 20 61 49 6e 64 65 78 20 3d 20 26 28 28 68 74 5f   aIndex = &((ht_
fef0: 73 6c 6f 74 20 2a 29 26 70 2d 3e 61 53 65 67 6d  slot *)&p->aSegm
ff00: 65 6e 74 5b 70 2d 3e 6e 53 65 67 6d 65 6e 74 5d  ent[p->nSegment]
ff10: 29 5b 73 4c 6f 63 2e 69 5a 65 72 6f 5d 3b 0a 20  )[sLoc.iZero];. 
ff20: 20 20 20 20 20 73 4c 6f 63 2e 69 5a 65 72 6f 2b       sLoc.iZero+
ff30: 2b 3b 0a 20 20 0a 20 20 20 20 20 20 66 6f 72 28  +;.  .      for(
ff40: 6a 3d 30 3b 20 6a 3c 6e 45 6e 74 72 79 3b 20 6a  j=0; j<nEntry; j
ff50: 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 61 49 6e  ++){.        aIn
ff60: 64 65 78 5b 6a 5d 20 3d 20 28 68 74 5f 73 6c 6f  dex[j] = (ht_slo
ff70: 74 29 6a 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  t)j;.      }.   
ff80: 20 20 20 77 61 6c 4d 65 72 67 65 73 6f 72 74 28     walMergesort(
ff90: 28 75 33 32 20 2a 29 73 4c 6f 63 2e 61 50 67 6e  (u32 *)sLoc.aPgn
ffa0: 6f 2c 20 61 54 6d 70 2c 20 61 49 6e 64 65 78 2c  o, aTmp, aIndex,
ffb0: 20 26 6e 45 6e 74 72 79 29 3b 0a 20 20 20 20 20   &nEntry);.     
ffc0: 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e   p->aSegment[i].
ffd0: 69 5a 65 72 6f 20 3d 20 73 4c 6f 63 2e 69 5a 65  iZero = sLoc.iZe
ffe0: 72 6f 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65  ro;.      p->aSe
fff0: 67 6d 65 6e 74 5b 69 5d 2e 6e 45 6e 74 72 79 20  gment[i].nEntry 
10000 3d 20 6e 45 6e 74 72 79 3b 0a 20 20 20 20 20 20  = nEntry;.      
10010 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 61  p->aSegment[i].a
10020 49 6e 64 65 78 20 3d 20 61 49 6e 64 65 78 3b 0a  Index = aIndex;.
10030 20 20 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e        p->aSegmen
10040 74 5b 69 5d 2e 61 50 67 6e 6f 20 3d 20 28 75 33  t[i].aPgno = (u3
10050 32 20 2a 29 73 4c 6f 63 2e 61 50 67 6e 6f 3b 0a  2 *)sLoc.aPgno;.
10060 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69      }.  }.  sqli
10070 74 65 33 5f 66 72 65 65 28 61 54 6d 70 29 3b 0a  te3_free(aTmp);.
10080 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
10090 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49  E_OK ){.    walI
100a0 74 65 72 61 74 6f 72 46 72 65 65 28 70 29 3b 0a  teratorFree(p);.
100b0 20 20 20 20 70 20 3d 20 30 3b 0a 20 20 7d 0a 20      p = 0;.  }. 
100c0 20 2a 70 70 20 3d 20 70 3b 0a 20 20 72 65 74 75   *pp = p;.  retu
100d0 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
100e0 41 74 74 65 6d 70 74 20 74 6f 20 6f 62 74 61 69  Attempt to obtai
100f0 6e 20 74 68 65 20 65 78 63 6c 75 73 69 76 65 20  n the exclusive 
10100 57 41 4c 20 6c 6f 63 6b 20 64 65 66 69 6e 65 64  WAL lock defined
10110 20 62 79 20 70 61 72 61 6d 65 74 65 72 73 20 6c   by parameters l
10120 6f 63 6b 49 64 78 20 61 6e 64 0a 2a 2a 20 6e 2e  ockIdx and.** n.
10130 20 49 66 20 74 68 65 20 61 74 74 65 6d 70 74 20   If the attempt 
10140 66 61 69 6c 73 20 61 6e 64 20 70 61 72 61 6d 65  fails and parame
10150 74 65 72 20 78 42 75 73 79 20 69 73 20 6e 6f 74  ter xBusy is not
10160 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 69 74 20 69   NULL, then it i
10170 73 20 61 0a 2a 2a 20 62 75 73 79 2d 68 61 6e 64  s a.** busy-hand
10180 6c 65 72 20 66 75 6e 63 74 69 6f 6e 2e 20 49 6e  ler function. In
10190 76 6f 6b 65 20 69 74 20 61 6e 64 20 72 65 74 72  voke it and retr
101a0 79 20 74 68 65 20 6c 6f 63 6b 20 75 6e 74 69 6c  y the lock until
101b0 20 65 69 74 68 65 72 20 74 68 65 0a 2a 2a 20 6c   either the.** l
101c0 6f 63 6b 20 69 73 20 73 75 63 63 65 73 73 66 75  ock is successfu
101d0 6c 6c 79 20 6f 62 74 61 69 6e 65 64 20 6f 72 20  lly obtained or 
101e0 74 68 65 20 62 75 73 79 2d 68 61 6e 64 6c 65 72  the busy-handler
101f0 20 72 65 74 75 72 6e 73 20 30 2e 0a 2a 2f 0a 73   returns 0..*/.s
10200 74 61 74 69 63 20 69 6e 74 20 77 61 6c 42 75 73  tatic int walBus
10210 79 4c 6f 63 6b 28 0a 20 20 57 61 6c 20 2a 70 57  yLock(.  Wal *pW
10220 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
10230 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20           /* WAL 
10240 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20  connection */.  
10250 69 6e 74 20 28 2a 78 42 75 73 79 29 28 76 6f 69  int (*xBusy)(voi
10260 64 2a 29 2c 20 20 20 20 20 20 20 20 20 20 20 20  d*),            
10270 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63  /* Function to c
10280 61 6c 6c 20 77 68 65 6e 20 62 75 73 79 20 2a 2f  all when busy */
10290 0a 20 20 76 6f 69 64 20 2a 70 42 75 73 79 41 72  .  void *pBusyAr
102a0 67 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  g,              
102b0 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 61 72     /* Context ar
102c0 67 75 6d 65 6e 74 20 66 6f 72 20 78 42 75 73 79  gument for xBusy
102d0 48 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74  Handler */.  int
102e0 20 6c 6f 63 6b 49 64 78 2c 20 20 20 20 20 20 20   lockIdx,       
102f0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
10300 4f 66 66 73 65 74 20 6f 66 20 66 69 72 73 74 20  Offset of first 
10310 62 79 74 65 20 74 6f 20 6c 6f 63 6b 20 2a 2f 0a  byte to lock */.
10320 20 20 69 6e 74 20 6e 20 20 20 20 20 20 20 20 20    int n         
10330 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10340 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
10350 79 74 65 73 20 74 6f 20 6c 6f 63 6b 20 2a 2f 0a  ytes to lock */.
10360 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 64  ){.  int rc;.  d
10370 6f 20 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c  o {.    rc = wal
10380 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  LockExclusive(pW
10390 61 6c 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 29 3b  al, lockIdx, n);
103a0 0a 20 20 7d 77 68 69 6c 65 28 20 78 42 75 73 79  .  }while( xBusy
103b0 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42   && rc==SQLITE_B
103c0 55 53 59 20 26 26 20 78 42 75 73 79 28 70 42 75  USY && xBusy(pBu
103d0 73 79 41 72 67 29 20 29 3b 0a 20 20 72 65 74 75  syArg) );.  retu
103e0 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
103f0 54 68 65 20 63 61 63 68 65 20 6f 66 20 74 68 65  The cache of the
10400 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
10410 72 20 6d 75 73 74 20 62 65 20 76 61 6c 69 64 20  r must be valid 
10420 74 6f 20 63 61 6c 6c 20 74 68 69 73 20 66 75 6e  to call this fun
10430 63 74 69 6f 6e 2e 0a 2a 2a 20 52 65 74 75 72 6e  ction..** Return
10440 20 74 68 65 20 70 61 67 65 2d 73 69 7a 65 20 69   the page-size i
10450 6e 20 62 79 74 65 73 20 75 73 65 64 20 62 79 20  n bytes used by 
10460 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2f  the database..*/
10470 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 50  .static int walP
10480 61 67 65 73 69 7a 65 28 57 61 6c 20 2a 70 57 61  agesize(Wal *pWa
10490 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 70 57  l){.  return (pW
104a0 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26 30  al->hdr.szPage&0
104b0 78 66 65 30 30 29 20 2b 20 28 28 70 57 61 6c 2d  xfe00) + ((pWal-
104c0 3e 68 64 72 2e 73 7a 50 61 67 65 26 30 78 30 30  >hdr.szPage&0x00
104d0 30 31 29 3c 3c 31 36 29 3b 0a 7d 0a 0a 2f 2a 0a  01)<<16);.}../*.
104e0 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ** The following
104f0 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 77   is guaranteed w
10500 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f  hen this functio
10510 6e 20 69 73 20 63 61 6c 6c 65 64 3a 0a 2a 2a 0a  n is called:.**.
10520 2a 2a 20 20 20 61 29 20 74 68 65 20 57 52 49 54  **   a) the WRIT
10530 45 52 20 6c 6f 63 6b 20 69 73 20 68 65 6c 64 2c  ER lock is held,
10540 0a 2a 2a 20 20 20 62 29 20 74 68 65 20 65 6e 74  .**   b) the ent
10550 69 72 65 20 6c 6f 67 20 66 69 6c 65 20 68 61 73  ire log file has
10560 20 62 65 65 6e 20 63 68 65 63 6b 70 6f 69 6e 74   been checkpoint
10570 65 64 2c 20 61 6e 64 0a 2a 2a 20 20 20 63 29 20  ed, and.**   c) 
10580 61 6e 79 20 65 78 69 73 74 69 6e 67 20 72 65 61  any existing rea
10590 64 65 72 73 20 61 72 65 20 72 65 61 64 69 6e 67  ders are reading
105a0 20 65 78 63 6c 75 73 69 76 65 6c 79 20 66 72 6f   exclusively fro
105b0 6d 20 74 68 65 20 64 61 74 61 62 61 73 65 0a 2a  m the database.*
105c0 2a 20 20 20 20 20 20 66 69 6c 65 20 2d 20 74 68  *      file - th
105d0 65 72 65 20 61 72 65 20 6e 6f 20 72 65 61 64 65  ere are no reade
105e0 72 73 20 74 68 61 74 20 6d 61 79 20 61 74 74 65  rs that may atte
105f0 6d 70 74 20 74 6f 20 72 65 61 64 20 61 20 66 72  mpt to read a fr
10600 61 6d 65 20 66 72 6f 6d 0a 2a 2a 20 20 20 20 20  ame from.**     
10610 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 0a 2a   the log file..*
10620 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
10630 6f 6e 20 75 70 64 61 74 65 73 20 74 68 65 20 73  on updates the s
10640 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20 73 74 72  hared-memory str
10650 75 63 74 75 72 65 73 20 73 6f 20 74 68 61 74 20  uctures so that 
10660 74 68 65 20 6e 65 78 74 0a 2a 2a 20 63 6c 69 65  the next.** clie
10670 6e 74 20 74 6f 20 77 72 69 74 65 20 74 6f 20 74  nt to write to t
10680 68 65 20 64 61 74 61 62 61 73 65 20 28 77 68 69  he database (whi
10690 63 68 20 6d 61 79 20 62 65 20 74 68 69 73 20 6f  ch may be this o
106a0 6e 65 29 20 64 6f 65 73 20 73 6f 20 62 79 0a 2a  ne) does so by.*
106b0 2a 20 77 72 69 74 69 6e 67 20 66 72 61 6d 65 73  * writing frames
106c0 20 69 6e 74 6f 20 74 68 65 20 73 74 61 72 74 20   into the start 
106d0 6f 66 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e  of the log file.
106e0 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65  .**.** The value
106f0 20 6f 66 20 70 61 72 61 6d 65 74 65 72 20 73 61   of parameter sa
10700 6c 74 31 20 69 73 20 75 73 65 64 20 61 73 20 74  lt1 is used as t
10710 68 65 20 61 53 61 6c 74 5b 31 5d 20 76 61 6c 75  he aSalt[1] valu
10720 65 20 69 6e 20 74 68 65 20 0a 2a 2a 20 6e 65 77  e in the .** new
10730 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
10740 72 2e 20 49 74 20 73 68 6f 75 6c 64 20 62 65 20  r. It should be 
10750 70 61 73 73 65 64 20 61 20 70 73 65 75 64 6f 2d  passed a pseudo-
10760 72 61 6e 64 6f 6d 20 76 61 6c 75 65 20 28 69 2e  random value (i.
10770 65 2e 20 0a 2a 2a 20 6f 6e 65 20 6f 62 74 61 69  e. .** one obtai
10780 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33  ned from sqlite3
10790 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 29 29 2e 0a  _randomness())..
107a0 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
107b0 61 6c 52 65 73 74 61 72 74 48 64 72 28 57 61 6c  alRestartHdr(Wal
107c0 20 2a 70 57 61 6c 2c 20 75 33 32 20 73 61 6c 74   *pWal, u32 salt
107d0 31 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57  1){.  volatile W
107e0 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e 66  alCkptInfo *pInf
107f0 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f 28  o = walCkptInfo(
10800 70 57 61 6c 29 3b 0a 20 20 69 6e 74 20 69 3b 20  pWal);.  int i; 
10810 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10820 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70           /* Loop
10830 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 75 33   counter */.  u3
10840 32 20 2a 61 53 61 6c 74 20 3d 20 70 57 61 6c 2d  2 *aSalt = pWal-
10850 3e 68 64 72 2e 61 53 61 6c 74 3b 20 20 20 2f 2a  >hdr.aSalt;   /*
10860 20 42 69 67 2d 65 6e 64 69 61 6e 20 73 61 6c 74   Big-endian salt
10870 20 76 61 6c 75 65 73 20 2a 2f 0a 20 20 70 57 61   values */.  pWa
10880 6c 2d 3e 6e 43 6b 70 74 2b 2b 3b 0a 20 20 70 57  l->nCkpt++;.  pW
10890 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
108a0 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 50 75  = 0;.  sqlite3Pu
108b0 74 34 62 79 74 65 28 28 75 38 2a 29 26 61 53 61  t4byte((u8*)&aSa
108c0 6c 74 5b 30 5d 2c 20 31 20 2b 20 73 71 6c 69 74  lt[0], 1 + sqlit
108d0 65 33 47 65 74 34 62 79 74 65 28 28 75 38 2a 29  e3Get4byte((u8*)
108e0 26 61 53 61 6c 74 5b 30 5d 29 29 3b 0a 20 20 6d  &aSalt[0]));.  m
108f0 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72  emcpy(&pWal->hdr
10900 2e 61 53 61 6c 74 5b 31 5d 2c 20 26 73 61 6c 74  .aSalt[1], &salt
10910 31 2c 20 34 29 3b 0a 20 20 77 61 6c 49 6e 64 65  1, 4);.  walInde
10920 78 57 72 69 74 65 48 64 72 28 70 57 61 6c 29 3b  xWriteHdr(pWal);
10930 0a 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66  .  pInfo->nBackf
10940 69 6c 6c 20 3d 20 30 3b 0a 20 20 70 49 6e 66 6f  ill = 0;.  pInfo
10950 2d 3e 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d  ->nBackfillAttem
10960 70 74 65 64 20 3d 20 30 3b 0a 20 20 70 49 6e 66  pted = 0;.  pInf
10970 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 31 5d 20  o->aReadMark[1] 
10980 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 32 3b 20  = 0;.  for(i=2; 
10990 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69  i<WAL_NREADER; i
109a0 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64  ++) pInfo->aRead
109b0 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41  Mark[i] = READMA
109c0 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 61  RK_NOT_USED;.  a
109d0 73 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e 61 52  ssert( pInfo->aR
109e0 65 61 64 4d 61 72 6b 5b 30 5d 3d 3d 30 20 29 3b  eadMark[0]==0 );
109f0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 61  .}../*.** Copy a
10a00 73 20 6d 75 63 68 20 63 6f 6e 74 65 6e 74 20 61  s much content a
10a10 73 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 74 68  s we can from th
10a20 65 20 57 41 4c 20 62 61 63 6b 20 69 6e 74 6f 20  e WAL back into 
10a30 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
10a40 65 0a 2a 2a 20 69 6e 20 72 65 73 70 6f 6e 73 65  e.** in response
10a50 20 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f 77   to an sqlite3_w
10a60 61 6c 5f 63 68 65 63 6b 70 6f 69 6e 74 28 29 20  al_checkpoint() 
10a70 72 65 71 75 65 73 74 20 6f 72 20 74 68 65 20 65  request or the e
10a80 71 75 69 76 61 6c 65 6e 74 2e 0a 2a 2a 0a 2a 2a  quivalent..**.**
10a90 20 54 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20 69   The amount of i
10aa0 6e 66 6f 72 6d 61 74 69 6f 6e 20 63 6f 70 69 65  nformation copie
10ab0 73 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64 61  s from WAL to da
10ac0 74 61 62 61 73 65 20 6d 69 67 68 74 20 62 65 20  tabase might be 
10ad0 6c 69 6d 69 74 65 64 0a 2a 2a 20 62 79 20 61 63  limited.** by ac
10ae0 74 69 76 65 20 72 65 61 64 65 72 73 2e 20 20 54  tive readers.  T
10af0 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c  his routine will
10b00 20 6e 65 76 65 72 20 6f 76 65 72 77 72 69 74 65   never overwrite
10b10 20 61 20 64 61 74 61 62 61 73 65 20 70 61 67 65   a database page
10b20 0a 2a 2a 20 74 68 61 74 20 61 20 63 6f 6e 63 75  .** that a concu
10b30 72 72 65 6e 74 20 72 65 61 64 65 72 20 6d 69 67  rrent reader mig
10b40 68 74 20 62 65 20 75 73 69 6e 67 2e 0a 2a 2a 0a  ht be using..**.
10b50 2a 2a 20 41 6c 6c 20 49 2f 4f 20 62 61 72 72 69  ** All I/O barri
10b60 65 72 20 6f 70 65 72 61 74 69 6f 6e 73 20 28 61  er operations (a
10b70 2e 6b 2e 61 20 66 73 79 6e 63 73 29 20 6f 63 63  .k.a fsyncs) occ
10b80 75 72 20 69 6e 20 74 68 69 73 20 72 6f 75 74 69  ur in this routi
10b90 6e 65 20 77 68 65 6e 0a 2a 2a 20 53 51 4c 69 74  ne when.** SQLit
10ba0 65 20 69 73 20 69 6e 20 57 41 4c 2d 6d 6f 64 65  e is in WAL-mode
10bb0 20 69 6e 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d   in synchronous=
10bc0 4e 4f 52 4d 41 4c 2e 20 20 54 68 61 74 20 6d 65  NORMAL.  That me
10bd0 61 6e 73 20 74 68 61 74 20 69 66 20 0a 2a 2a 20  ans that if .** 
10be0 63 68 65 63 6b 70 6f 69 6e 74 73 20 61 72 65 20  checkpoints are 
10bf0 61 6c 77 61 79 73 20 72 75 6e 20 62 79 20 61 20  always run by a 
10c00 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61  background threa
10c10 64 20 6f 72 20 62 61 63 6b 67 72 6f 75 6e 64 20  d or background 
10c20 0a 2a 2a 20 70 72 6f 63 65 73 73 2c 20 66 6f 72  .** process, for
10c30 65 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20  eground threads 
10c40 77 69 6c 6c 20 6e 65 76 65 72 20 62 6c 6f 63 6b  will never block
10c50 20 6f 6e 20 61 20 6c 65 6e 67 74 68 79 20 66 73   on a lengthy fs
10c60 79 6e 63 20 63 61 6c 6c 2e 0a 2a 2a 0a 2a 2a 20  ync call..**.** 
10c70 46 73 79 6e 63 20 69 73 20 63 61 6c 6c 65 64 20  Fsync is called 
10c80 6f 6e 20 74 68 65 20 57 41 4c 20 62 65 66 6f 72  on the WAL befor
10c90 65 20 77 72 69 74 69 6e 67 20 63 6f 6e 74 65 6e  e writing conten
10ca0 74 20 6f 75 74 20 6f 66 20 74 68 65 20 57 41 4c  t out of the WAL
10cb0 20 61 6e 64 0a 2a 2a 20 69 6e 74 6f 20 74 68 65   and.** into the
10cc0 20 64 61 74 61 62 61 73 65 2e 20 20 54 68 69 73   database.  This
10cd0 20 65 6e 73 75 72 65 73 20 74 68 61 74 20 69 66   ensures that if
10ce0 20 74 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e 74   the new content
10cf0 20 69 73 20 70 65 72 73 69 73 74 65 6e 74 0a 2a   is persistent.*
10d00 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 61 6e 64  * in the WAL and
10d10 20 63 61 6e 20 62 65 20 72 65 63 6f 76 65 72 65   can be recovere
10d20 64 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 70 6f  d following a po
10d30 77 65 72 2d 6c 6f 73 73 20 6f 72 20 68 61 72 64  wer-loss or hard
10d40 20 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 46 73   reset..**.** Fs
10d50 79 6e 63 20 69 73 20 61 6c 73 6f 20 63 61 6c 6c  ync is also call
10d60 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 62 61  ed on the databa
10d70 73 65 20 66 69 6c 65 20 69 66 20 28 61 6e 64 20  se file if (and 
10d80 6f 6e 6c 79 20 69 66 29 20 74 68 65 20 65 6e 74  only if) the ent
10d90 69 72 65 0a 2a 2a 20 57 41 4c 20 63 6f 6e 74 65  ire.** WAL conte
10da0 6e 74 20 69 73 20 63 6f 70 69 65 64 20 69 6e 74  nt is copied int
10db0 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  o the database f
10dc0 69 6c 65 2e 20 20 54 68 69 73 20 73 65 63 6f 6e  ile.  This secon
10dd0 64 20 66 73 79 6e 63 20 6d 61 6b 65 73 0a 2a 2a  d fsync makes.**
10de0 20 69 74 20 73 61 66 65 20 74 6f 20 64 65 6c 65   it safe to dele
10df0 74 65 20 74 68 65 20 57 41 4c 20 73 69 6e 63 65  te the WAL since
10e00 20 74 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e 74   the new content
10e10 20 77 69 6c 6c 20 70 65 72 73 69 73 74 20 69 6e   will persist in
10e20 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65   the.** database
10e30 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69   file..**.** Thi
10e40 73 20 72 6f 75 74 69 6e 65 20 75 73 65 73 20 61  s routine uses a
10e50 6e 64 20 75 70 64 61 74 65 73 20 74 68 65 20 6e  nd updates the n
10e60 42 61 63 6b 66 69 6c 6c 20 66 69 65 6c 64 20 6f  Backfill field o
10e70 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
10e80 68 65 61 64 65 72 2e 0a 2a 2a 20 54 68 69 73 20  header..** This 
10e90 69 73 20 74 68 65 20 6f 6e 6c 79 20 72 6f 75 74  is the only rout
10ea0 69 6e 65 20 74 68 61 74 20 77 69 6c 6c 20 69 6e  ine that will in
10eb0 63 72 65 61 73 65 20 74 68 65 20 76 61 6c 75 65  crease the value
10ec0 20 6f 66 20 6e 42 61 63 6b 66 69 6c 6c 2e 20 20   of nBackfill.  
10ed0 0a 2a 2a 20 28 41 20 57 41 4c 20 72 65 73 65 74  .** (A WAL reset
10ee0 20 6f 72 20 72 65 63 6f 76 65 72 79 20 77 69 6c   or recovery wil
10ef0 6c 20 72 65 76 65 72 74 20 6e 42 61 63 6b 66 69  l revert nBackfi
10f00 6c 6c 20 74 6f 20 7a 65 72 6f 2c 20 62 75 74 20  ll to zero, but 
10f10 6e 6f 74 20 69 6e 63 72 65 61 73 65 0a 2a 2a 20  not increase.** 
10f20 69 74 73 20 76 61 6c 75 65 2e 29 0a 2a 2a 0a 2a  its value.).**.*
10f30 2a 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  * The caller mus
10f40 74 20 62 65 20 68 6f 6c 64 69 6e 67 20 73 75 66  t be holding suf
10f50 66 69 63 69 65 6e 74 20 6c 6f 63 6b 73 20 74 6f  ficient locks to
10f60 20 65 6e 73 75 72 65 20 74 68 61 74 20 6e 6f 20   ensure that no 
10f70 6f 74 68 65 72 0a 2a 2a 20 63 68 65 63 6b 70 6f  other.** checkpo
10f80 69 6e 74 20 69 73 20 72 75 6e 6e 69 6e 67 20 28  int is running (
10f90 69 6e 20 61 6e 79 20 6f 74 68 65 72 20 74 68 72  in any other thr
10fa0 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 29 20  ead or process) 
10fb0 61 74 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20 74  at the same.** t
10fc0 69 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ime..*/.static i
10fd0 6e 74 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74  nt walCheckpoint
10fe0 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20  (.  Wal *pWal,  
10ff0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11000 20 20 20 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65      /* Wal conne
11010 63 74 69 6f 6e 20 2a 2f 0a 20 20 73 71 6c 69 74  ction */.  sqlit
11020 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
11030 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68             /* Ch
11040 65 63 6b 20 66 6f 72 20 69 6e 74 65 72 72 75 70  eck for interrup
11050 74 73 20 6f 6e 20 74 68 69 73 20 68 61 6e 64 6c  ts on this handl
11060 65 20 2a 2f 0a 20 20 69 6e 74 20 65 4d 6f 64 65  e */.  int eMode
11070 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
11080 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 66         /* One of
11090 20 50 41 53 53 49 56 45 2c 20 46 55 4c 4c 20 6f   PASSIVE, FULL o
110a0 72 20 52 45 53 54 41 52 54 20 2a 2f 0a 20 20 69  r RESTART */.  i
110b0 6e 74 20 28 2a 78 42 75 73 79 29 28 76 6f 69 64  nt (*xBusy)(void
110c0 2a 29 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  *),            /
110d0 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63 61  * Function to ca
110e0 6c 6c 20 77 68 65 6e 20 62 75 73 79 20 2a 2f 0a  ll when busy */.
110f0 20 20 76 6f 69 64 20 2a 70 42 75 73 79 41 72 67    void *pBusyArg
11100 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
11110 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 61 72 67    /* Context arg
11120 75 6d 65 6e 74 20 66 6f 72 20 78 42 75 73 79 48  ument for xBusyH
11130 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74 20  andler */.  int 
11140 73 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20 20  sync_flags,     
11150 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
11160 6c 61 67 73 20 66 6f 72 20 4f 73 53 79 6e 63 28  lags for OsSync(
11170 29 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20 75 38  ) (or 0) */.  u8
11180 20 2a 7a 42 75 66 20 20 20 20 20 20 20 20 20 20   *zBuf          
11190 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
111a0 20 54 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65   Temporary buffe
111b0 72 20 74 6f 20 75 73 65 20 2a 2f 0a 29 7b 0a 20  r to use */.){. 
111c0 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
111d0 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
111e0 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
111f0 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 3b  */.  int szPage;
11200 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11210 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
11220 20 70 61 67 65 2d 73 69 7a 65 20 2a 2f 0a 20 20   page-size */.  
11230 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 49 74  WalIterator *pIt
11240 65 72 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  er = 0;         
11250 2f 2a 20 57 61 6c 20 69 74 65 72 61 74 6f 72 20  /* Wal iterator 
11260 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 75 33 32  context */.  u32
11270 20 69 44 62 70 61 67 65 20 3d 20 30 3b 20 20 20   iDbpage = 0;   
11280 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
11290 4e 65 78 74 20 64 61 74 61 62 61 73 65 20 70 61  Next database pa
112a0 67 65 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20  ge to write */. 
112b0 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20 30 3b   u32 iFrame = 0;
112c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
112d0 20 2f 2a 20 57 61 6c 20 66 72 61 6d 65 20 63 6f   /* Wal frame co
112e0 6e 74 61 69 6e 69 6e 67 20 64 61 74 61 20 66 6f  ntaining data fo
112f0 72 20 69 44 62 70 61 67 65 20 2a 2f 0a 20 20 75  r iDbpage */.  u
11300 33 32 20 6d 78 53 61 66 65 46 72 61 6d 65 3b 20  32 mxSafeFrame; 
11310 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
11320 2a 20 4d 61 78 20 66 72 61 6d 65 20 74 68 61 74  * Max frame that
11330 20 63 61 6e 20 62 65 20 62 61 63 6b 66 69 6c 6c   can be backfill
11340 65 64 20 2a 2f 0a 20 20 75 33 32 20 6d 78 50 61  ed */.  u32 mxPa
11350 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
11360 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78 20 64          /* Max d
11370 61 74 61 62 61 73 65 20 70 61 67 65 20 74 6f 20  atabase page to 
11380 77 72 69 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69  write */.  int i
11390 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
113a0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f             /* Lo
113b0 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20  op counter */.  
113c0 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74  volatile WalCkpt
113d0 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b 20 20 20 20  Info *pInfo;    
113e0 2f 2a 20 54 68 65 20 63 68 65 63 6b 70 6f 69 6e  /* The checkpoin
113f0 74 20 73 74 61 74 75 73 20 69 6e 66 6f 72 6d 61  t status informa
11400 74 69 6f 6e 20 2a 2f 0a 0a 20 20 73 7a 50 61 67  tion */..  szPag
11410 65 20 3d 20 77 61 6c 50 61 67 65 73 69 7a 65 28  e = walPagesize(
11420 70 57 61 6c 29 3b 0a 20 20 74 65 73 74 63 61 73  pWal);.  testcas
11430 65 28 20 73 7a 50 61 67 65 3c 3d 33 32 37 36 38  e( szPage<=32768
11440 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20   );.  testcase( 
11450 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20 29 3b  szPage>=65536 );
11460 0a 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b  .  pInfo = walCk
11470 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20  ptInfo(pWal);.  
11480 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b  if( pInfo->nBack
11490 66 69 6c 6c 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d  fill<pWal->hdr.m
114a0 78 46 72 61 6d 65 20 29 7b 0a 0a 20 20 20 20 2f  xFrame ){..    /
114b0 2a 20 45 56 49 44 45 4e 43 45 2d 4f 46 3a 20 52  * EVIDENCE-OF: R
114c0 2d 36 32 39 32 30 2d 34 37 34 35 30 20 54 68 65  -62920-47450 The
114d0 20 62 75 73 79 2d 68 61 6e 64 6c 65 72 20 63 61   busy-handler ca
114e0 6c 6c 62 61 63 6b 20 69 73 20 6e 65 76 65 72 20  llback is never 
114f0 69 6e 76 6f 6b 65 64 0a 20 20 20 20 2a 2a 20 69  invoked.    ** i
11500 6e 20 74 68 65 20 53 51 4c 49 54 45 5f 43 48 45  n the SQLITE_CHE
11510 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 20  CKPOINT_PASSIVE 
11520 6d 6f 64 65 2e 20 2a 2f 0a 20 20 20 20 61 73 73  mode. */.    ass
11530 65 72 74 28 20 65 4d 6f 64 65 21 3d 53 51 4c 49  ert( eMode!=SQLI
11540 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41  TE_CHECKPOINT_PA
11550 53 53 49 56 45 20 7c 7c 20 78 42 75 73 79 3d 3d  SSIVE || xBusy==
11560 30 20 29 3b 0a 0a 20 20 20 20 2f 2a 20 43 6f 6d  0 );..    /* Com
11570 70 75 74 65 20 69 6e 20 6d 78 53 61 66 65 46 72  pute in mxSafeFr
11580 61 6d 65 20 74 68 65 20 69 6e 64 65 78 20 6f 66  ame the index of
11590 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d 65 20   the last frame 
115a0 6f 66 20 74 68 65 20 57 41 4c 20 74 68 61 74 20  of the WAL that 
115b0 69 73 0a 20 20 20 20 2a 2a 20 73 61 66 65 20 74  is.    ** safe t
115c0 6f 20 77 72 69 74 65 20 69 6e 74 6f 20 74 68 65  o write into the
115d0 20 64 61 74 61 62 61 73 65 2e 20 20 46 72 61 6d   database.  Fram
115e0 65 73 20 62 65 79 6f 6e 64 20 6d 78 53 61 66 65  es beyond mxSafe
115f0 46 72 61 6d 65 20 6d 69 67 68 74 0a 20 20 20 20  Frame might.    
11600 2a 2a 20 6f 76 65 72 77 72 69 74 65 20 64 61 74  ** overwrite dat
11610 61 62 61 73 65 20 70 61 67 65 73 20 74 68 61 74  abase pages that
11620 20 61 72 65 20 69 6e 20 75 73 65 20 62 79 20 61   are in use by a
11630 63 74 69 76 65 20 72 65 61 64 65 72 73 20 61 6e  ctive readers an
11640 64 20 74 68 75 73 0a 20 20 20 20 2a 2a 20 63 61  d thus.    ** ca
11650 6e 6e 6f 74 20 62 65 20 62 61 63 6b 66 69 6c 6c  nnot be backfill
11660 65 64 20 66 72 6f 6d 20 74 68 65 20 57 41 4c 2e  ed from the WAL.
11670 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d 78 53 61  .    */.    mxSa
11680 66 65 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e  feFrame = pWal->
11690 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20  hdr.mxFrame;.   
116a0 20 6d 78 50 61 67 65 20 3d 20 70 57 61 6c 2d 3e   mxPage = pWal->
116b0 68 64 72 2e 6e 50 61 67 65 3b 0a 20 20 20 20 66  hdr.nPage;.    f
116c0 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52  or(i=1; i<WAL_NR
116d0 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20  EADER; i++){.   
116e0 20 20 20 2f 2a 20 54 68 72 65 61 64 2d 73 61 6e     /* Thread-san
116f0 69 74 69 7a 65 72 20 72 65 70 6f 72 74 73 20 74  itizer reports t
11700 68 61 74 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e  hat the followin
11710 67 20 69 73 20 61 6e 20 75 6e 73 61 66 65 20 72  g is an unsafe r
11720 65 61 64 2c 0a 20 20 20 20 20 20 2a 2a 20 61 73  ead,.      ** as
11730 20 73 6f 6d 65 20 6f 74 68 65 72 20 74 68 72 65   some other thre
11740 61 64 20 6d 61 79 20 62 65 20 69 6e 20 74 68 65  ad may be in the
11750 20 70 72 6f 63 65 73 73 20 6f 66 20 75 70 64 61   process of upda
11760 74 69 6e 67 20 74 68 65 20 76 61 6c 75 65 0a 20  ting the value. 
11770 20 20 20 20 20 2a 2a 20 6f 66 20 74 68 65 20 61       ** of the a
11780 52 65 61 64 4d 61 72 6b 5b 5d 20 73 6c 6f 74 2e  ReadMark[] slot.
11790 20 54 68 65 20 61 73 73 75 6d 70 74 69 6f 6e 20   The assumption 
117a0 68 65 72 65 20 69 73 20 74 68 61 74 20 69 66 20  here is that if 
117b0 74 68 61 74 20 69 73 0a 20 20 20 20 20 20 2a 2a  that is.      **
117c0 20 68 61 70 70 65 6e 69 6e 67 2c 20 74 68 65 20   happening, the 
117d0 6f 74 68 65 72 20 63 6c 69 65 6e 74 20 6d 61 79  other client may
117e0 20 6f 6e 6c 79 20 62 65 20 69 6e 63 72 65 61 73   only be increas
117f0 69 6e 67 20 74 68 65 20 76 61 6c 75 65 2c 0a 20  ing the value,. 
11800 20 20 20 20 20 2a 2a 20 6e 6f 74 20 64 65 63 72       ** not decr
11810 65 61 73 69 6e 67 20 69 74 2e 20 53 6f 20 61 73  easing it. So as
11820 73 75 6d 69 6e 67 20 65 69 74 68 65 72 20 74 68  suming either th
11830 61 74 20 65 69 74 68 65 72 20 74 68 65 20 22 6f  at either the "o
11840 6c 64 22 20 6f 72 0a 20 20 20 20 20 20 2a 2a 20  ld" or.      ** 
11850 22 6e 65 77 22 20 76 65 72 73 69 6f 6e 20 6f 66  "new" version of
11860 20 74 68 65 20 76 61 6c 75 65 20 69 73 20 72 65   the value is re
11870 61 64 2c 20 61 6e 64 20 6e 6f 74 20 73 6f 6d 65  ad, and not some
11880 20 61 72 62 69 74 72 61 72 79 20 76 61 6c 75 65   arbitrary value
11890 0a 20 20 20 20 20 20 2a 2a 20 74 68 61 74 20 77  .      ** that w
118a0 6f 75 6c 64 20 6e 65 76 65 72 20 62 65 20 77 72  ould never be wr
118b0 69 74 74 65 6e 20 62 79 20 61 20 72 65 61 6c 20  itten by a real 
118c0 63 6c 69 65 6e 74 2c 20 74 68 69 6e 67 73 20 61  client, things a
118d0 72 65 20 73 74 69 6c 6c 20 0a 20 20 20 20 20 20  re still .      
118e0 2a 2a 20 73 61 66 65 2e 20 20 2a 2f 0a 20 20 20  ** safe.  */.   
118f0 20 20 20 75 33 32 20 79 20 3d 20 70 49 6e 66 6f     u32 y = pInfo
11900 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a  ->aReadMark[i];.
11910 20 20 20 20 20 20 69 66 28 20 6d 78 53 61 66 65        if( mxSafe
11920 46 72 61 6d 65 3e 79 20 29 7b 0a 20 20 20 20 20  Frame>y ){.     
11930 20 20 20 61 73 73 65 72 74 28 20 79 3c 3d 70 57     assert( y<=pW
11940 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
11950 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  );.        rc = 
11960 77 61 6c 42 75 73 79 4c 6f 63 6b 28 70 57 61 6c  walBusyLock(pWal
11970 2c 20 78 42 75 73 79 2c 20 70 42 75 73 79 41 72  , xBusy, pBusyAr
11980 67 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  g, WAL_READ_LOCK
11990 28 69 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 20  (i), 1);.       
119a0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
119b0 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  OK ){.          
119c0 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b  pInfo->aReadMark
119d0 5b 69 5d 20 3d 20 28 69 3d 3d 31 20 3f 20 6d 78  [i] = (i==1 ? mx
119e0 53 61 66 65 46 72 61 6d 65 20 3a 20 52 45 41 44  SafeFrame : READ
119f0 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 29 3b 0a  MARK_NOT_USED);.
11a00 20 20 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c            walUnl
11a10 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
11a20 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  l, WAL_READ_LOCK
11a30 28 69 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 20  (i), 1);.       
11a40 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53   }else if( rc==S
11a50 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20  QLITE_BUSY ){.  
11a60 20 20 20 20 20 20 20 20 6d 78 53 61 66 65 46 72          mxSafeFr
11a70 61 6d 65 20 3d 20 79 3b 0a 20 20 20 20 20 20 20  ame = y;.       
11a80 20 20 20 78 42 75 73 79 20 3d 20 30 3b 0a 20 20     xBusy = 0;.  
11a90 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
11aa0 20 20 20 20 20 20 20 67 6f 74 6f 20 77 61 6c 63         goto walc
11ab0 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74 3b 0a 20  heckpoint_out;. 
11ac0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
11ad0 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 41  .    }..    /* A
11ae0 6c 6c 6f 63 61 74 65 20 74 68 65 20 69 74 65 72  llocate the iter
11af0 61 74 6f 72 20 2a 2f 0a 20 20 20 20 69 66 28 20  ator */.    if( 
11b00 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
11b10 3c 6d 78 53 61 66 65 46 72 61 6d 65 20 29 7b 0a  <mxSafeFrame ){.
11b20 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 49 74        rc = walIt
11b30 65 72 61 74 6f 72 49 6e 69 74 28 70 57 61 6c 2c  eratorInit(pWal,
11b40 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
11b50 6c 2c 20 26 70 49 74 65 72 29 3b 0a 20 20 20 20  l, &pIter);.    
11b60 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
11b70 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 49 74 65 72  LITE_OK || pIter
11b80 3d 3d 30 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  ==0 );.    }..  
11b90 20 20 69 66 28 20 70 49 74 65 72 0a 20 20 20 20    if( pIter.    
11ba0 20 26 26 20 28 72 63 20 3d 20 77 61 6c 42 75 73   && (rc = walBus
11bb0 79 4c 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73  yLock(pWal, xBus
11bc0 79 2c 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c  y, pBusyArg, WAL
11bd0 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 31 29  _READ_LOCK(0),1)
11be0 29 3d 3d 53 51 4c 49 54 45 5f 4f 4b 0a 20 20 20  )==SQLITE_OK.   
11bf0 20 29 7b 0a 20 20 20 20 20 20 75 33 32 20 6e 42   ){.      u32 nB
11c00 61 63 6b 66 69 6c 6c 20 3d 20 70 49 6e 66 6f 2d  ackfill = pInfo-
11c10 3e 6e 42 61 63 6b 66 69 6c 6c 3b 0a 0a 20 20 20  >nBackfill;..   
11c20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66     pInfo->nBackf
11c30 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 3d 20 6d  illAttempted = m
11c40 78 53 61 66 65 46 72 61 6d 65 3b 0a 0a 20 20 20  xSafeFrame;..   
11c50 20 20 20 2f 2a 20 53 79 6e 63 20 74 68 65 20 57     /* Sync the W
11c60 41 4c 20 74 6f 20 64 69 73 6b 20 2a 2f 0a 20 20  AL to disk */.  
11c70 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
11c80 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57 61  OsSync(pWal->pWa
11c90 6c 46 64 2c 20 43 4b 50 54 5f 53 59 4e 43 5f 46  lFd, CKPT_SYNC_F
11ca0 4c 41 47 53 28 73 79 6e 63 5f 66 6c 61 67 73 29  LAGS(sync_flags)
11cb0 29 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66 20  );..      /* If 
11cc0 74 68 65 20 64 61 74 61 62 61 73 65 20 6d 61 79  the database may
11cd0 20 67 72 6f 77 20 61 73 20 61 20 72 65 73 75 6c   grow as a resul
11ce0 74 20 6f 66 20 74 68 69 73 20 63 68 65 63 6b 70  t of this checkp
11cf0 6f 69 6e 74 2c 20 68 69 6e 74 0a 20 20 20 20 20  oint, hint.     
11d00 20 2a 2a 20 61 62 6f 75 74 20 74 68 65 20 65 76   ** about the ev
11d10 65 6e 74 75 61 6c 20 73 69 7a 65 20 6f 66 20 74  entual size of t
11d20 68 65 20 64 62 20 66 69 6c 65 20 74 6f 20 74 68  he db file to th
11d30 65 20 56 46 53 20 6c 61 79 65 72 2e 0a 20 20 20  e VFS layer..   
11d40 20 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20     */.      if( 
11d50 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
11d60 0a 20 20 20 20 20 20 20 20 69 36 34 20 6e 52 65  .        i64 nRe
11d70 71 20 3d 20 28 28 69 36 34 29 6d 78 50 61 67 65  q = ((i64)mxPage
11d80 20 2a 20 73 7a 50 61 67 65 29 3b 0a 20 20 20 20   * szPage);.    
11d90 20 20 20 20 69 36 34 20 6e 53 69 7a 65 3b 20 20      i64 nSize;  
11da0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11db0 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 73 69 7a    /* Current siz
11dc0 65 20 6f 66 20 64 61 74 61 62 61 73 65 20 66 69  e of database fi
11dd0 6c 65 20 2a 2f 0a 20 20 20 20 20 20 20 20 72 63  le */.        rc
11de0 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65   = sqlite3OsFile
11df0 53 69 7a 65 28 70 57 61 6c 2d 3e 70 44 62 46 64  Size(pWal->pDbFd
11e00 2c 20 26 6e 53 69 7a 65 29 3b 0a 20 20 20 20 20  , &nSize);.     
11e10 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
11e20 45 5f 4f 4b 20 26 26 20 6e 53 69 7a 65 3c 6e 52  E_OK && nSize<nR
11e30 65 71 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  eq ){.          
11e40 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 43 6f 6e  sqlite3OsFileCon
11e50 74 72 6f 6c 48 69 6e 74 28 70 57 61 6c 2d 3e 70  trolHint(pWal->p
11e60 44 62 46 64 2c 20 53 51 4c 49 54 45 5f 46 43 4e  DbFd, SQLITE_FCN
11e70 54 4c 5f 53 49 5a 45 5f 48 49 4e 54 2c 20 26 6e  TL_SIZE_HINT, &n
11e80 52 65 71 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  Req);.        }.
11e90 20 20 20 20 20 20 7d 0a 0a 0a 20 20 20 20 20 20        }...      
11ea0 2f 2a 20 49 74 65 72 61 74 65 20 74 68 72 6f 75  /* Iterate throu
11eb0 67 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  gh the contents 
11ec0 6f 66 20 74 68 65 20 57 41 4c 2c 20 63 6f 70 79  of the WAL, copy
11ed0 69 6e 67 20 64 61 74 61 20 74 6f 20 74 68 65 20  ing data to the 
11ee0 64 62 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 20  db file */.     
11ef0 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49   while( rc==SQLI
11f00 54 45 5f 4f 4b 20 26 26 20 30 3d 3d 77 61 6c 49  TE_OK && 0==walI
11f10 74 65 72 61 74 6f 72 4e 65 78 74 28 70 49 74 65  teratorNext(pIte
11f20 72 2c 20 26 69 44 62 70 61 67 65 2c 20 26 69 46  r, &iDbpage, &iF
11f30 72 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20 20  rame) ){.       
11f40 20 69 36 34 20 69 4f 66 66 73 65 74 3b 0a 20 20   i64 iOffset;.  
11f50 20 20 20 20 20 20 61 73 73 65 72 74 28 20 77 61        assert( wa
11f60 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c  lFramePgno(pWal,
11f70 20 69 46 72 61 6d 65 29 3d 3d 69 44 62 70 61 67   iFrame)==iDbpag
11f80 65 20 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  e );.        if(
11f90 20 64 62 2d 3e 75 31 2e 69 73 49 6e 74 65 72 72   db->u1.isInterr
11fa0 75 70 74 65 64 20 29 7b 0a 20 20 20 20 20 20 20  upted ){.       
11fb0 20 20 20 72 63 20 3d 20 64 62 2d 3e 6d 61 6c 6c     rc = db->mall
11fc0 6f 63 46 61 69 6c 65 64 20 3f 20 53 51 4c 49 54  ocFailed ? SQLIT
11fd0 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 20 3a 20 53  E_NOMEM_BKPT : S
11fe0 51 4c 49 54 45 5f 49 4e 54 45 52 52 55 50 54 3b  QLITE_INTERRUPT;
11ff0 0a 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b  .          break
12000 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
12010 20 20 20 20 69 66 28 20 69 46 72 61 6d 65 3c 3d      if( iFrame<=
12020 6e 42 61 63 6b 66 69 6c 6c 20 7c 7c 20 69 46 72  nBackfill || iFr
12030 61 6d 65 3e 6d 78 53 61 66 65 46 72 61 6d 65 20  ame>mxSafeFrame 
12040 7c 7c 20 69 44 62 70 61 67 65 3e 6d 78 50 61 67  || iDbpage>mxPag
12050 65 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63  e ){.          c
12060 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 20  ontinue;.       
12070 20 7d 0a 20 20 20 20 20 20 20 20 69 4f 66 66 73   }.        iOffs
12080 65 74 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66  et = walFrameOff
12090 73 65 74 28 69 46 72 61 6d 65 2c 20 73 7a 50 61  set(iFrame, szPa
120a0 67 65 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  ge) + WAL_FRAME_
120b0 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 20 20 20  HDRSIZE;.       
120c0 20 2f 2a 20 74 65 73 74 63 61 73 65 28 20 49 53   /* testcase( IS
120d0 5f 42 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74  _BIG_INT(iOffset
120e0 29 20 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73  ) ); // requires
120f0 20 61 20 34 47 69 42 20 57 41 4c 20 66 69 6c 65   a 4GiB WAL file
12100 20 2a 2f 0a 20 20 20 20 20 20 20 20 72 63 20 3d   */.        rc =
12110 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70   sqlite3OsRead(p
12120 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 7a 42 75  Wal->pWalFd, zBu
12130 66 2c 20 73 7a 50 61 67 65 2c 20 69 4f 66 66 73  f, szPage, iOffs
12140 65 74 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  et);.        if(
12150 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
12160 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
12170 69 4f 66 66 73 65 74 20 3d 20 28 69 44 62 70 61  iOffset = (iDbpa
12180 67 65 2d 31 29 2a 28 69 36 34 29 73 7a 50 61 67  ge-1)*(i64)szPag
12190 65 3b 0a 20 20 20 20 20 20 20 20 74 65 73 74 63  e;.        testc
121a0 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28  ase( IS_BIG_INT(
121b0 69 4f 66 66 73 65 74 29 20 29 3b 0a 20 20 20 20  iOffset) );.    
121c0 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
121d0 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 44  OsWrite(pWal->pD
121e0 62 46 64 2c 20 7a 42 75 66 2c 20 73 7a 50 61 67  bFd, zBuf, szPag
121f0 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20  e, iOffset);.   
12200 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c       if( rc!=SQL
12210 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a  ITE_OK ) break;.
12220 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f        }..      /
12230 2a 20 49 66 20 77 6f 72 6b 20 77 61 73 20 61 63  * If work was ac
12240 74 75 61 6c 6c 79 20 61 63 63 6f 6d 70 6c 69 73  tually accomplis
12250 68 65 64 2e 2e 2e 20 2a 2f 0a 20 20 20 20 20 20  hed... */.      
12260 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
12270 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  K ){.        if(
12280 20 6d 78 53 61 66 65 46 72 61 6d 65 3d 3d 77 61   mxSafeFrame==wa
12290 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29 2d  lIndexHdr(pWal)-
122a0 3e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20  >mxFrame ){.    
122b0 20 20 20 20 20 20 69 36 34 20 73 7a 44 62 20 3d        i64 szDb =
122c0 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65   pWal->hdr.nPage
122d0 2a 28 69 36 34 29 73 7a 50 61 67 65 3b 0a 20 20  *(i64)szPage;.  
122e0 20 20 20 20 20 20 20 20 74 65 73 74 63 61 73 65          testcase
122f0 28 20 49 53 5f 42 49 47 5f 49 4e 54 28 73 7a 44  ( IS_BIG_INT(szD
12300 62 29 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20  b) );.          
12310 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 54 72  rc = sqlite3OsTr
12320 75 6e 63 61 74 65 28 70 57 61 6c 2d 3e 70 44 62  uncate(pWal->pDb
12330 46 64 2c 20 73 7a 44 62 29 3b 0a 20 20 20 20 20  Fd, szDb);.     
12340 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
12350 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
12360 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
12370 65 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70  e3OsSync(pWal->p
12380 44 62 46 64 2c 20 43 4b 50 54 5f 53 59 4e 43 5f  DbFd, CKPT_SYNC_
12390 46 4c 41 47 53 28 73 79 6e 63 5f 66 6c 61 67 73  FLAGS(sync_flags
123a0 29 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  ));.          }.
123b0 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
123c0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
123d0 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20  _OK ){.         
123e0 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
123f0 6c 20 3d 20 6d 78 53 61 66 65 46 72 61 6d 65 3b  l = mxSafeFrame;
12400 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
12410 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 52 65 6c   }..      /* Rel
12420 65 61 73 65 20 74 68 65 20 72 65 61 64 65 72 20  ease the reader 
12430 6c 6f 63 6b 20 68 65 6c 64 20 77 68 69 6c 65 20  lock held while 
12440 62 61 63 6b 66 69 6c 6c 69 6e 67 20 2a 2f 0a 20  backfilling */. 
12450 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78       walUnlockEx
12460 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
12470 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20  L_READ_LOCK(0), 
12480 31 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69  1);.    }..    i
12490 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  f( rc==SQLITE_BU
124a0 53 59 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 52  SY ){.      /* R
124b0 65 73 65 74 20 74 68 65 20 72 65 74 75 72 6e 20  eset the return 
124c0 63 6f 64 65 20 73 6f 20 61 73 20 6e 6f 74 20 74  code so as not t
124d0 6f 20 72 65 70 6f 72 74 20 61 20 63 68 65 63 6b  o report a check
124e0 70 6f 69 6e 74 20 66 61 69 6c 75 72 65 0a 20 20  point failure.  
124f0 20 20 20 20 2a 2a 20 6a 75 73 74 20 62 65 63 61      ** just beca
12500 75 73 65 20 74 68 65 72 65 20 61 72 65 20 61 63  use there are ac
12510 74 69 76 65 20 72 65 61 64 65 72 73 2e 20 20 2a  tive readers.  *
12520 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  /.      rc = SQL
12530 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20  ITE_OK;.    }.  
12540 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 69 73 20  }..  /* If this 
12550 69 73 20 61 6e 20 53 51 4c 49 54 45 5f 43 48 45  is an SQLITE_CHE
12560 43 4b 50 4f 49 4e 54 5f 52 45 53 54 41 52 54 20  CKPOINT_RESTART 
12570 6f 72 20 54 52 55 4e 43 41 54 45 20 6f 70 65 72  or TRUNCATE oper
12580 61 74 69 6f 6e 2c 20 61 6e 64 20 74 68 65 0a 20  ation, and the. 
12590 20 2a 2a 20 65 6e 74 69 72 65 20 77 61 6c 20 66   ** entire wal f
125a0 69 6c 65 20 68 61 73 20 62 65 65 6e 20 63 6f 70  ile has been cop
125b0 69 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74  ied into the dat
125c0 61 62 61 73 65 20 66 69 6c 65 2c 20 74 68 65 6e  abase file, then
125d0 20 62 6c 6f 63 6b 20 0a 20 20 2a 2a 20 75 6e 74   block .  ** unt
125e0 69 6c 20 61 6c 6c 20 72 65 61 64 65 72 73 20 68  il all readers h
125f0 61 76 65 20 66 69 6e 69 73 68 65 64 20 75 73 69  ave finished usi
12600 6e 67 20 74 68 65 20 77 61 6c 20 66 69 6c 65 2e  ng the wal file.
12610 20 54 68 69 73 20 65 6e 73 75 72 65 73 20 74 68   This ensures th
12620 61 74 20 0a 20 20 2a 2a 20 74 68 65 20 6e 65 78  at .  ** the nex
12630 74 20 70 72 6f 63 65 73 73 20 74 6f 20 77 72 69  t process to wri
12640 74 65 20 74 6f 20 74 68 65 20 64 61 74 61 62 61  te to the databa
12650 73 65 20 72 65 73 74 61 72 74 73 20 74 68 65 20  se restarts the 
12660 77 61 6c 20 66 69 6c 65 2e 0a 20 20 2a 2f 0a 20  wal file..  */. 
12670 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
12680 4f 4b 20 26 26 20 65 4d 6f 64 65 21 3d 53 51 4c  OK && eMode!=SQL
12690 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50  ITE_CHECKPOINT_P
126a0 41 53 53 49 56 45 20 29 7b 0a 20 20 20 20 61 73  ASSIVE ){.    as
126b0 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74  sert( pWal->writ
126c0 65 4c 6f 63 6b 20 29 3b 0a 20 20 20 20 69 66 28  eLock );.    if(
126d0 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
126e0 6c 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  l<pWal->hdr.mxFr
126f0 61 6d 65 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ame ){.      rc 
12700 3d 20 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a 20  = SQLITE_BUSY;. 
12710 20 20 20 7d 65 6c 73 65 20 69 66 28 20 65 4d 6f     }else if( eMo
12720 64 65 3e 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b  de>=SQLITE_CHECK
12730 50 4f 49 4e 54 5f 52 45 53 54 41 52 54 20 29 7b  POINT_RESTART ){
12740 0a 20 20 20 20 20 20 75 33 32 20 73 61 6c 74 31  .      u32 salt1
12750 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
12760 72 61 6e 64 6f 6d 6e 65 73 73 28 34 2c 20 26 73  randomness(4, &s
12770 61 6c 74 31 29 3b 0a 20 20 20 20 20 20 61 73 73  alt1);.      ass
12780 65 72 74 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63  ert( pInfo->nBac
12790 6b 66 69 6c 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72  kfill==pWal->hdr
127a0 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20 20  .mxFrame );.    
127b0 20 20 72 63 20 3d 20 77 61 6c 42 75 73 79 4c 6f    rc = walBusyLo
127c0 63 6b 28 70 57 61 6c 2c 20 78 42 75 73 79 2c 20  ck(pWal, xBusy, 
127d0 70 42 75 73 79 41 72 67 2c 20 57 41 4c 5f 52 45  pBusyArg, WAL_RE
127e0 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f  AD_LOCK(1), WAL_
127f0 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20 20  NREADER-1);.    
12800 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
12810 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69  _OK ){.        i
12820 66 28 20 65 4d 6f 64 65 3d 3d 53 51 4c 49 54 45  f( eMode==SQLITE
12830 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 54 52 55 4e  _CHECKPOINT_TRUN
12840 43 41 54 45 20 29 7b 0a 20 20 20 20 20 20 20 20  CATE ){.        
12850 20 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54 41 54    /* IMPLEMENTAT
12860 49 4f 4e 2d 4f 46 3a 20 52 2d 34 34 36 39 39 2d  ION-OF: R-44699-
12870 35 37 31 34 30 20 54 68 69 73 20 6d 6f 64 65 20  57140 This mode 
12880 77 6f 72 6b 73 20 74 68 65 20 73 61 6d 65 20 77  works the same w
12890 61 79 20 61 73 0a 20 20 20 20 20 20 20 20 20 20  ay as.          
128a0 2a 2a 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 50  ** SQLITE_CHECKP
128b0 4f 49 4e 54 5f 52 45 53 54 41 52 54 20 77 69 74  OINT_RESTART wit
128c0 68 20 74 68 65 20 61 64 64 69 74 69 6f 6e 20 74  h the addition t
128d0 68 61 74 20 69 74 20 61 6c 73 6f 0a 20 20 20 20  hat it also.    
128e0 20 20 20 20 20 20 2a 2a 20 74 72 75 6e 63 61 74        ** truncat
128f0 65 73 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 20  es the log file 
12900 74 6f 20 7a 65 72 6f 20 62 79 74 65 73 20 6a 75  to zero bytes ju
12910 73 74 20 70 72 69 6f 72 20 74 6f 20 61 0a 20 20  st prior to a.  
12920 20 20 20 20 20 20 20 20 2a 2a 20 73 75 63 63 65          ** succe
12930 73 73 66 75 6c 20 72 65 74 75 72 6e 2e 0a 20 20  ssful return..  
12940 20 20 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20          **.     
12950 20 20 20 20 20 2a 2a 20 49 6e 20 74 68 65 6f 72       ** In theor
12960 79 2c 20 69 74 20 6d 69 67 68 74 20 62 65 20 73  y, it might be s
12970 61 66 65 20 74 6f 20 64 6f 20 74 68 69 73 20 77  afe to do this w
12980 69 74 68 6f 75 74 20 75 70 64 61 74 69 6e 67 20  ithout updating 
12990 74 68 65 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  the.          **
129a0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
129b0 72 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d 6f  r in shared memo
129c0 72 79 2c 20 61 73 20 61 6c 6c 20 73 75 62 73 65  ry, as all subse
129d0 71 75 65 6e 74 20 72 65 61 64 65 72 20 6f 72 0a  quent reader or.
129e0 20 20 20 20 20 20 20 20 20 20 2a 2a 20 77 72 69            ** wri
129f0 74 65 72 20 63 6c 69 65 6e 74 73 20 73 68 6f 75  ter clients shou
12a00 6c 64 20 73 65 65 20 74 68 61 74 20 74 68 65 20  ld see that the 
12a10 65 6e 74 69 72 65 20 6c 6f 67 20 66 69 6c 65 20  entire log file 
12a20 68 61 73 20 62 65 65 6e 0a 20 20 20 20 20 20 20  has been.       
12a30 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74     ** checkpoint
12a40 65 64 20 61 6e 64 20 62 65 68 61 76 65 20 61 63  ed and behave ac
12a50 63 6f 72 64 69 6e 67 6c 79 2e 20 54 68 69 73 20  cordingly. This 
12a60 73 65 65 6d 73 20 75 6e 73 61 66 65 20 74 68 6f  seems unsafe tho
12a70 75 67 68 2c 0a 20 20 20 20 20 20 20 20 20 20 2a  ugh,.          *
12a80 2a 20 61 73 20 69 74 20 77 6f 75 6c 64 20 6c 65  * as it would le
12a90 61 76 65 20 74 68 65 20 73 79 73 74 65 6d 20 69  ave the system i
12aa0 6e 20 61 20 73 74 61 74 65 20 77 68 65 72 65 20  n a state where 
12ab0 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 0a  the contents of.
12ac0 20 20 20 20 20 20 20 20 20 20 2a 2a 20 74 68 65            ** the
12ad0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
12ae0 72 20 64 6f 20 6e 6f 74 20 6d 61 74 63 68 20 74  r do not match t
12af0 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
12b00 68 65 20 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  he .          **
12b10 20 66 69 6c 65 2d 73 79 73 74 65 6d 2e 20 54 6f   file-system. To
12b20 20 61 76 6f 69 64 20 74 68 69 73 2c 20 75 70 64   avoid this, upd
12b30 61 74 65 20 74 68 65 20 77 61 6c 2d 69 6e 64 65  ate the wal-inde
12b40 78 20 68 65 61 64 65 72 20 74 6f 0a 20 20 20 20  x header to.    
12b50 20 20 20 20 20 20 2a 2a 20 69 6e 64 69 63 61 74        ** indicat
12b60 65 20 74 68 61 74 20 74 68 65 20 6c 6f 67 20 66  e that the log f
12b70 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 7a 65 72  ile contains zer
12b80 6f 20 76 61 6c 69 64 20 66 72 61 6d 65 73 2e 20  o valid frames. 
12b90 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 77 61   */.          wa
12ba0 6c 52 65 73 74 61 72 74 48 64 72 28 70 57 61 6c  lRestartHdr(pWal
12bb0 2c 20 73 61 6c 74 31 29 3b 0a 20 20 20 20 20 20  , salt1);.      
12bc0 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
12bd0 4f 73 54 72 75 6e 63 61 74 65 28 70 57 61 6c 2d  OsTruncate(pWal-
12be0 3e 70 57 61 6c 46 64 2c 20 30 29 3b 0a 20 20 20  >pWalFd, 0);.   
12bf0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 77       }.        w
12c00 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
12c10 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
12c20 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52  _LOCK(1), WAL_NR
12c30 45 41 44 45 52 2d 31 29 3b 0a 20 20 20 20 20 20  EADER-1);.      
12c40 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 77 61  }.    }.  }.. wa
12c50 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74 3a  lcheckpoint_out:
12c60 0a 20 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72  .  walIteratorFr
12c70 65 65 28 70 49 74 65 72 29 3b 0a 20 20 72 65 74  ee(pIter);.  ret
12c80 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
12c90 20 49 66 20 74 68 65 20 57 41 4c 20 66 69 6c 65   If the WAL file
12ca0 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 6c 61   is currently la
12cb0 72 67 65 72 20 74 68 61 6e 20 6e 4d 61 78 20 62  rger than nMax b
12cc0 79 74 65 73 20 69 6e 20 73 69 7a 65 2c 20 74 72  ytes in size, tr
12cd0 75 6e 63 61 74 65 0a 2a 2a 20 69 74 20 74 6f 20  uncate.** it to 
12ce0 65 78 61 63 74 6c 79 20 6e 4d 61 78 20 62 79 74  exactly nMax byt
12cf0 65 73 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 20  es. If an error 
12d00 6f 63 63 75 72 73 20 77 68 69 6c 65 20 64 6f 69  occurs while doi
12d10 6e 67 20 73 6f 2c 20 69 67 6e 6f 72 65 20 69 74  ng so, ignore it
12d20 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
12d30 20 77 61 6c 4c 69 6d 69 74 53 69 7a 65 28 57 61   walLimitSize(Wa
12d40 6c 20 2a 70 57 61 6c 2c 20 69 36 34 20 6e 4d 61  l *pWal, i64 nMa
12d50 78 29 7b 0a 20 20 69 36 34 20 73 7a 3b 0a 20 20  x){.  i64 sz;.  
12d60 69 6e 74 20 72 78 3b 0a 20 20 73 71 6c 69 74 65  int rx;.  sqlite
12d70 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c  3BeginBenignMall
12d80 6f 63 28 29 3b 0a 20 20 72 78 20 3d 20 73 71 6c  oc();.  rx = sql
12d90 69 74 65 33 4f 73 46 69 6c 65 53 69 7a 65 28 70  ite3OsFileSize(p
12da0 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 26 73 7a  Wal->pWalFd, &sz
12db0 29 3b 0a 20 20 69 66 28 20 72 78 3d 3d 53 51 4c  );.  if( rx==SQL
12dc0 49 54 45 5f 4f 4b 20 26 26 20 28 73 7a 20 3e 20  ITE_OK && (sz > 
12dd0 6e 4d 61 78 20 29 20 29 7b 0a 20 20 20 20 72 78  nMax ) ){.    rx
12de0 20 3d 20 73 71 6c 69 74 65 33 4f 73 54 72 75 6e   = sqlite3OsTrun
12df0 63 61 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46  cate(pWal->pWalF
12e00 64 2c 20 6e 4d 61 78 29 3b 0a 20 20 7d 0a 20 20  d, nMax);.  }.  
12e10 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e  sqlite3EndBenign
12e20 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 69 66 28 20  Malloc();.  if( 
12e30 72 78 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  rx ){.    sqlite
12e40 33 5f 6c 6f 67 28 72 78 2c 20 22 63 61 6e 6e 6f  3_log(rx, "canno
12e50 74 20 6c 69 6d 69 74 20 57 41 4c 20 73 69 7a 65  t limit WAL size
12e60 3a 20 25 73 22 2c 20 70 57 61 6c 2d 3e 7a 57 61  : %s", pWal->zWa
12e70 6c 4e 61 6d 65 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  lName);.  }.}../
12e80 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 63 6f 6e  *.** Close a con
12e90 6e 65 63 74 69 6f 6e 20 74 6f 20 61 20 6c 6f 67  nection to a log
12ea0 20 66 69 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71   file..*/.int sq
12eb0 6c 69 74 65 33 57 61 6c 43 6c 6f 73 65 28 0a 20  lite3WalClose(. 
12ec0 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20   Wal *pWal,     
12ed0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12ee0 20 2f 2a 20 57 61 6c 20 74 6f 20 63 6c 6f 73 65   /* Wal to close
12ef0 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64   */.  sqlite3 *d
12f00 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
12f10 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 69 6e 74        /* For int
12f20 65 72 72 75 70 74 20 66 6c 61 67 20 2a 2f 0a 20  errupt flag */. 
12f30 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67 73 2c   int sync_flags,
12f40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12f50 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20 70 61 73   /* Flags to pas
12f60 73 20 74 6f 20 4f 73 53 79 6e 63 28 29 20 28 6f  s to OsSync() (o
12f70 72 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  r 0) */.  int nB
12f80 75 66 2c 0a 20 20 75 38 20 2a 7a 42 75 66 20 20  uf,.  u8 *zBuf  
12f90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12fa0 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
12fb0 6f 66 20 61 74 20 6c 65 61 73 74 20 6e 42 75 66  of at least nBuf
12fc0 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 69   bytes */.){.  i
12fd0 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
12fe0 4b 3b 0a 20 20 69 66 28 20 70 57 61 6c 20 29 7b  K;.  if( pWal ){
12ff0 0a 20 20 20 20 69 6e 74 20 69 73 44 65 6c 65 74  .    int isDelet
13000 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  e = 0;          
13010 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 75 6e     /* True to un
13020 6c 69 6e 6b 20 77 61 6c 20 61 6e 64 20 77 61 6c  link wal and wal
13030 2d 69 6e 64 65 78 20 66 69 6c 65 73 20 2a 2f 0a  -index files */.
13040 0a 20 20 20 20 2f 2a 20 49 66 20 61 6e 20 45 58  .    /* If an EX
13050 43 4c 55 53 49 56 45 20 6c 6f 63 6b 20 63 61 6e  CLUSIVE lock can
13060 20 62 65 20 6f 62 74 61 69 6e 65 64 20 6f 6e 20   be obtained on 
13070 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
13080 65 20 28 75 73 69 6e 67 20 74 68 65 0a 20 20 20  e (using the.   
13090 20 2a 2a 20 6f 72 64 69 6e 61 72 79 2c 20 72 6f   ** ordinary, ro
130a0 6c 6c 62 61 63 6b 2d 6d 6f 64 65 20 6c 6f 63 6b  llback-mode lock
130b0 69 6e 67 20 6d 65 74 68 6f 64 73 2c 20 74 68 69  ing methods, thi
130c0 73 20 67 75 61 72 61 6e 74 65 65 73 20 74 68 61  s guarantees tha
130d0 74 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 6f 6e  t the.    ** con
130e0 6e 65 63 74 69 6f 6e 20 61 73 73 6f 63 69 61 74  nection associat
130f0 65 64 20 77 69 74 68 20 74 68 69 73 20 6c 6f 67  ed with this log
13100 20 66 69 6c 65 20 69 73 20 74 68 65 20 6f 6e 6c   file is the onl
13110 79 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 0a  y connection to.
13120 20 20 20 20 2a 2a 20 74 68 65 20 64 61 74 61 62      ** the datab
13130 61 73 65 2e 20 49 6e 20 74 68 69 73 20 63 61 73  ase. In this cas
13140 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 74 68 65  e checkpoint the
13150 20 64 61 74 61 62 61 73 65 20 61 6e 64 20 75 6e   database and un
13160 6c 69 6e 6b 20 62 6f 74 68 0a 20 20 20 20 2a 2a  link both.    **
13170 20 74 68 65 20 77 61 6c 20 61 6e 64 20 77 61 6c   the wal and wal
13180 2d 69 6e 64 65 78 20 66 69 6c 65 73 2e 0a 20 20  -index files..  
13190 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68 65 20    **.    ** The 
131a0 45 58 43 4c 55 53 49 56 45 20 6c 6f 63 6b 20 69  EXCLUSIVE lock i
131b0 73 20 6e 6f 74 20 72 65 6c 65 61 73 65 64 20 62  s not released b
131c0 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
131d0 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20  .    */.    if( 
131e0 7a 42 75 66 21 3d 30 0a 20 20 20 20 20 26 26 20  zBuf!=0.     && 
131f0 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d  SQLITE_OK==(rc =
13200 20 73 71 6c 69 74 65 33 4f 73 4c 6f 63 6b 28 70   sqlite3OsLock(p
13210 57 61 6c 2d 3e 70 44 62 46 64 2c 20 53 51 4c 49  Wal->pDbFd, SQLI
13220 54 45 5f 4c 4f 43 4b 5f 45 58 43 4c 55 53 49 56  TE_LOCK_EXCLUSIV
13230 45 29 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20  E)).    ){.     
13240 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75   if( pWal->exclu
13250 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 4e 4f  siveMode==WAL_NO
13260 52 4d 41 4c 5f 4d 4f 44 45 20 29 7b 0a 20 20 20  RMAL_MODE ){.   
13270 20 20 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c 75       pWal->exclu
13280 73 69 76 65 4d 6f 64 65 20 3d 20 57 41 4c 5f 45  siveMode = WAL_E
13290 58 43 4c 55 53 49 56 45 5f 4d 4f 44 45 3b 0a 20  XCLUSIVE_MODE;. 
132a0 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 63 20       }.      rc 
132b0 3d 20 73 71 6c 69 74 65 33 57 61 6c 43 68 65 63  = sqlite3WalChec
132c0 6b 70 6f 69 6e 74 28 70 57 61 6c 2c 20 64 62 2c  kpoint(pWal, db,
132d0 20 0a 20 20 20 20 20 20 20 20 20 20 53 51 4c 49   .          SQLI
132e0 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41  TE_CHECKPOINT_PA
132f0 53 53 49 56 45 2c 20 30 2c 20 30 2c 20 73 79 6e  SSIVE, 0, 0, syn
13300 63 5f 66 6c 61 67 73 2c 20 6e 42 75 66 2c 20 7a  c_flags, nBuf, z
13310 42 75 66 2c 20 30 2c 20 30 0a 20 20 20 20 20 20  Buf, 0, 0.      
13320 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
13330 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
13340 20 20 20 20 20 20 69 6e 74 20 62 50 65 72 73 69        int bPersi
13350 73 74 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20 20  st = -1;.       
13360 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 43 6f   sqlite3OsFileCo
13370 6e 74 72 6f 6c 48 69 6e 74 28 0a 20 20 20 20 20  ntrolHint(.     
13380 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 70 44 62         pWal->pDb
13390 46 64 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c  Fd, SQLITE_FCNTL
133a0 5f 50 45 52 53 49 53 54 5f 57 41 4c 2c 20 26 62  _PERSIST_WAL, &b
133b0 50 65 72 73 69 73 74 0a 20 20 20 20 20 20 20 20  Persist.        
133c0 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 62  );.        if( b
133d0 50 65 72 73 69 73 74 21 3d 31 20 29 7b 0a 20 20  Persist!=1 ){.  
133e0 20 20 20 20 20 20 20 20 2f 2a 20 54 72 79 20 74          /* Try t
133f0 6f 20 64 65 6c 65 74 65 20 74 68 65 20 57 41 4c  o delete the WAL
13400 20 66 69 6c 65 20 69 66 20 74 68 65 20 63 68 65   file if the che
13410 63 6b 70 6f 69 6e 74 20 63 6f 6d 70 6c 65 74 65  ckpoint complete
13420 64 20 61 6e 64 0a 20 20 20 20 20 20 20 20 20 20  d and.          
13430 2a 2a 20 66 73 79 6e 65 64 20 28 72 63 3d 3d 53  ** fsyned (rc==S
13440 51 4c 49 54 45 5f 4f 4b 29 20 61 6e 64 20 69 66  QLITE_OK) and if
13450 20 77 65 20 61 72 65 20 6e 6f 74 20 69 6e 20 70   we are not in p
13460 65 72 73 69 73 74 65 6e 74 2d 77 61 6c 0a 20 20  ersistent-wal.  
13470 20 20 20 20 20 20 20 20 2a 2a 20 6d 6f 64 65 20          ** mode 
13480 28 21 62 50 65 72 73 69 73 74 29 20 2a 2f 0a 20  (!bPersist) */. 
13490 20 20 20 20 20 20 20 20 20 69 73 44 65 6c 65 74           isDelet
134a0 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d  e = 1;.        }
134b0 65 6c 73 65 20 69 66 28 20 70 57 61 6c 2d 3e 6d  else if( pWal->m
134c0 78 57 61 6c 53 69 7a 65 3e 3d 30 20 29 7b 0a 20  xWalSize>=0 ){. 
134d0 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 79 20           /* Try 
134e0 74 6f 20 74 72 75 6e 63 61 74 65 20 74 68 65 20  to truncate the 
134f0 57 41 4c 20 66 69 6c 65 20 74 6f 20 7a 65 72 6f  WAL file to zero
13500 20 62 79 74 65 73 20 69 66 20 74 68 65 20 63 68   bytes if the ch
13510 65 63 6b 70 6f 69 6e 74 0a 20 20 20 20 20 20 20  eckpoint.       
13520 20 20 20 2a 2a 20 63 6f 6d 70 6c 65 74 65 64 20     ** completed 
13530 61 6e 64 20 66 73 79 6e 63 65 64 20 28 72 63 3d  and fsynced (rc=
13540 3d 53 51 4c 49 54 45 5f 4f 4b 29 20 61 6e 64 20  =SQLITE_OK) and 
13550 77 65 20 61 72 65 20 69 6e 20 70 65 72 73 69 73  we are in persis
13560 74 65 6e 74 0a 20 20 20 20 20 20 20 20 20 20 2a  tent.          *
13570 2a 20 57 41 4c 20 6d 6f 64 65 20 28 62 50 65 72  * WAL mode (bPer
13580 73 69 73 74 29 20 61 6e 64 20 69 66 20 74 68 65  sist) and if the
13590 20 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f   PRAGMA journal_
135a0 73 69 7a 65 5f 6c 69 6d 69 74 20 69 73 20 61 0a  size_limit is a.
135b0 20 20 20 20 20 20 20 20 20 20 2a 2a 20 6e 6f 6e            ** non
135c0 2d 6e 65 67 61 74 69 76 65 20 76 61 6c 75 65 20  -negative value 
135d0 28 70 57 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65  (pWal->mxWalSize
135e0 3e 3d 30 29 2e 20 20 4e 6f 74 65 20 74 68 61 74  >=0).  Note that
135f0 20 77 65 20 74 72 75 6e 63 61 74 65 0a 20 20 20   we truncate.   
13600 20 20 20 20 20 20 20 2a 2a 20 74 6f 20 7a 65 72         ** to zer
13610 6f 20 62 79 74 65 73 20 61 73 20 74 72 75 6e 63  o bytes as trunc
13620 61 74 69 6e 67 20 74 6f 20 74 68 65 20 6a 6f 75  ating to the jou
13630 72 6e 61 6c 5f 73 69 7a 65 5f 6c 69 6d 69 74 20  rnal_size_limit 
13640 6d 69 67 68 74 0a 20 20 20 20 20 20 20 20 20 20  might.          
13650 2a 2a 20 6c 65 61 76 65 20 61 20 63 6f 72 72 75  ** leave a corru
13660 70 74 20 57 41 4c 20 66 69 6c 65 20 6f 6e 20 64  pt WAL file on d
13670 69 73 6b 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20  isk. */.        
13680 20 20 77 61 6c 4c 69 6d 69 74 53 69 7a 65 28 70    walLimitSize(p
13690 57 61 6c 2c 20 30 29 3b 0a 20 20 20 20 20 20 20  Wal, 0);.       
136a0 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d   }.      }.    }
136b0 0a 0a 20 20 20 20 77 61 6c 49 6e 64 65 78 43 6c  ..    walIndexCl
136c0 6f 73 65 28 70 57 61 6c 2c 20 69 73 44 65 6c 65  ose(pWal, isDele
136d0 74 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  te);.    sqlite3
136e0 4f 73 43 6c 6f 73 65 28 70 57 61 6c 2d 3e 70 57  OsClose(pWal->pW
136f0 61 6c 46 64 29 3b 0a 20 20 20 20 69 66 28 20 69  alFd);.    if( i
13700 73 44 65 6c 65 74 65 20 29 7b 0a 20 20 20 20 20  sDelete ){.     
13710 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e   sqlite3BeginBen
13720 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 20  ignMalloc();.   
13730 20 20 20 73 71 6c 69 74 65 33 4f 73 44 65 6c 65     sqlite3OsDele
13740 74 65 28 70 57 61 6c 2d 3e 70 56 66 73 2c 20 70  te(pWal->pVfs, p
13750 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65 2c 20 30  Wal->zWalName, 0
13760 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
13770 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28  EndBenignMalloc(
13780 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 57 41 4c  );.    }.    WAL
13790 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63  TRACE(("WAL%p: c
137a0 6c 6f 73 65 64 5c 6e 22 2c 20 70 57 61 6c 29 29  losed\n", pWal))
137b0 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
137c0 65 65 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d  ee((void *)pWal-
137d0 3e 61 70 57 69 44 61 74 61 29 3b 0a 20 20 20 20  >apWiData);.    
137e0 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 57 61  sqlite3_free(pWa
137f0 6c 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  l);.  }.  return
13800 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72   rc;.}../*.** Tr
13810 79 20 74 6f 20 72 65 61 64 20 74 68 65 20 77 61  y to read the wa
13820 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 2e 20  l-index header. 
13830 20 52 65 74 75 72 6e 20 30 20 6f 6e 20 73 75 63   Return 0 on suc
13840 63 65 73 73 20 61 6e 64 20 31 20 69 66 0a 2a 2a  cess and 1 if.**
13850 20 74 68 65 72 65 20 69 73 20 61 20 70 72 6f 62   there is a prob
13860 6c 65 6d 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77  lem..**.** The w
13870 61 6c 2d 69 6e 64 65 78 20 69 73 20 69 6e 20 73  al-index is in s
13880 68 61 72 65 64 20 6d 65 6d 6f 72 79 2e 20 20 41  hared memory.  A
13890 6e 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f 72  nother thread or
138a0 20 70 72 6f 63 65 73 73 20 6d 69 67 68 74 0a 2a   process might.*
138b0 2a 20 62 65 20 77 72 69 74 69 6e 67 20 74 68 65  * be writing the
138c0 20 68 65 61 64 65 72 20 61 74 20 74 68 65 20 73   header at the s
138d0 61 6d 65 20 74 69 6d 65 20 74 68 69 73 20 70 72  ame time this pr
138e0 6f 63 65 64 75 72 65 20 69 73 20 74 72 79 69 6e  ocedure is tryin
138f0 67 20 74 6f 0a 2a 2a 20 72 65 61 64 20 69 74 2c  g to.** read it,
13900 20 77 68 69 63 68 20 6d 69 67 68 74 20 72 65 73   which might res
13910 75 6c 74 20 69 6e 20 69 6e 63 6f 6e 73 69 73 74  ult in inconsist
13920 65 6e 63 79 2e 20 20 41 20 64 69 72 74 79 20 72  ency.  A dirty r
13930 65 61 64 20 69 73 20 64 65 74 65 63 74 65 64 0a  ead is detected.
13940 2a 2a 20 62 79 20 76 65 72 69 66 79 69 6e 67 20  ** by verifying 
13950 74 68 61 74 20 62 6f 74 68 20 63 6f 70 69 65 73  that both copies
13960 20 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 61   of the header a
13970 72 65 20 74 68 65 20 73 61 6d 65 20 61 6e 64 20  re the same and 
13980 61 6c 73 6f 20 62 79 0a 2a 2a 20 61 20 63 68 65  also by.** a che
13990 63 6b 73 75 6d 20 6f 6e 20 74 68 65 20 68 65 61  cksum on the hea
139a0 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e  der..**.** If an
139b0 64 20 6f 6e 6c 79 20 69 66 20 74 68 65 20 72 65  d only if the re
139c0 61 64 20 69 73 20 63 6f 6e 73 69 73 74 65 6e 74  ad is consistent
139d0 20 61 6e 64 20 74 68 65 20 68 65 61 64 65 72 20   and the header 
139e0 69 73 20 64 69 66 66 65 72 65 6e 74 20 66 72 6f  is different fro
139f0 6d 0a 2a 2a 20 70 57 61 6c 2d 3e 68 64 72 2c 20  m.** pWal->hdr, 
13a00 74 68 65 6e 20 70 57 61 6c 2d 3e 68 64 72 20 69  then pWal->hdr i
13a10 73 20 75 70 64 61 74 65 64 20 74 6f 20 74 68 65  s updated to the
13a20 20 63 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65 20   content of the 
13a30 6e 65 77 20 68 65 61 64 65 72 0a 2a 2a 20 61 6e  new header.** an
13a40 64 20 2a 70 43 68 61 6e 67 65 64 20 69 73 20 73  d *pChanged is s
13a50 65 74 20 74 6f 20 31 2e 0a 2a 2a 0a 2a 2a 20 49  et to 1..**.** I
13a60 66 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 63  f the checksum c
13a70 61 6e 6e 6f 74 20 62 65 20 76 65 72 69 66 69 65  annot be verifie
13a80 64 20 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72  d return non-zer
13a90 6f 2e 20 49 66 20 74 68 65 20 68 65 61 64 65 72  o. If the header
13aa0 0a 2a 2a 20 69 73 20 72 65 61 64 20 73 75 63 63  .** is read succ
13ab0 65 73 73 66 75 6c 6c 79 20 61 6e 64 20 74 68 65  essfully and the
13ac0 20 63 68 65 63 6b 73 75 6d 20 76 65 72 69 66 69   checksum verifi
13ad0 65 64 2c 20 72 65 74 75 72 6e 20 7a 65 72 6f 2e  ed, return zero.
13ae0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
13af0 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28 57 61  alIndexTryHdr(Wa
13b00 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43  l *pWal, int *pC
13b10 68 61 6e 67 65 64 29 7b 0a 20 20 75 33 32 20 61  hanged){.  u32 a
13b20 43 6b 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20  Cksum[2];       
13b30 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68             /* Ch
13b40 65 63 6b 73 75 6d 20 6f 6e 20 74 68 65 20 68 65  ecksum on the he
13b50 61 64 65 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a  ader content */.
13b60 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20 68 31    WalIndexHdr h1
13b70 2c 20 68 32 3b 20 20 20 20 20 20 20 20 20 20 20  , h2;           
13b80 20 20 2f 2a 20 54 77 6f 20 63 6f 70 69 65 73 20    /* Two copies 
13b90 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 63 6f  of the header co
13ba0 6e 74 65 6e 74 20 2a 2f 0a 20 20 57 61 6c 49 6e  ntent */.  WalIn
13bb0 64 65 78 48 64 72 20 76 6f 6c 61 74 69 6c 65 20  dexHdr volatile 
13bc0 2a 61 48 64 72 3b 20 20 20 20 20 2f 2a 20 48 65  *aHdr;     /* He
13bd0 61 64 65 72 20 69 6e 20 73 68 61 72 65 64 20 6d  ader in shared m
13be0 65 6d 6f 72 79 20 2a 2f 0a 0a 20 20 2f 2a 20 54  emory */..  /* T
13bf0 68 65 20 66 69 72 73 74 20 70 61 67 65 20 6f 66  he first page of
13c00 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 6d   the wal-index m
13c10 75 73 74 20 62 65 20 6d 61 70 70 65 64 20 61 74  ust be mapped at
13c20 20 74 68 69 73 20 70 6f 69 6e 74 2e 20 2a 2f 0a   this point. */.
13c30 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
13c40 6e 57 69 44 61 74 61 3e 30 20 26 26 20 70 57 61  nWiData>0 && pWa
13c50 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 20 29  l->apWiData[0] )
13c60 3b 0a 0a 20 20 2f 2a 20 52 65 61 64 20 74 68 65  ;..  /* Read the
13c70 20 68 65 61 64 65 72 2e 20 54 68 69 73 20 6d 69   header. This mi
13c80 67 68 74 20 68 61 70 70 65 6e 20 63 6f 6e 63 75  ght happen concu
13c90 72 72 65 6e 74 6c 79 20 77 69 74 68 20 61 20 77  rrently with a w
13ca0 72 69 74 65 20 74 6f 20 74 68 65 0a 20 20 2a 2a  rite to the.  **
13cb0 20 73 61 6d 65 20 61 72 65 61 20 6f 66 20 73 68   same area of sh
13cc0 61 72 65 64 20 6d 65 6d 6f 72 79 20 6f 6e 20 61  ared memory on a
13cd0 20 64 69 66 66 65 72 65 6e 74 20 43 50 55 20 69   different CPU i
13ce0 6e 20 61 20 53 4d 50 2c 0a 20 20 2a 2a 20 6d 65  n a SMP,.  ** me
13cf0 61 6e 69 6e 67 20 69 74 20 69 73 20 70 6f 73 73  aning it is poss
13d00 69 62 6c 65 20 74 68 61 74 20 61 6e 20 69 6e 63  ible that an inc
13d10 6f 6e 73 69 73 74 65 6e 74 20 73 6e 61 70 73 68  onsistent snapsh
13d20 6f 74 20 69 73 20 72 65 61 64 0a 20 20 2a 2a 20  ot is read.  ** 
13d30 66 72 6f 6d 20 74 68 65 20 66 69 6c 65 2e 20 49  from the file. I
13d40 66 20 74 68 69 73 20 68 61 70 70 65 6e 73 2c 20  f this happens, 
13d50 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e  return non-zero.
13d60 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 72 65  .  **.  ** There
13d70 20 61 72 65 20 74 77 6f 20 63 6f 70 69 65 73 20   are two copies 
13d80 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 61 74  of the header at
13d90 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f   the beginning o
13da0 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e  f the wal-index.
13db0 0a 20 20 2a 2a 20 57 68 65 6e 20 72 65 61 64 69  .  ** When readi
13dc0 6e 67 2c 20 72 65 61 64 20 5b 30 5d 20 66 69 72  ng, read [0] fir
13dd0 73 74 20 74 68 65 6e 20 5b 31 5d 2e 20 20 57 72  st then [1].  Wr
13de0 69 74 65 73 20 61 72 65 20 69 6e 20 74 68 65 20  ites are in the 
13df0 72 65 76 65 72 73 65 20 6f 72 64 65 72 2e 0a 20  reverse order.. 
13e00 20 2a 2a 20 4d 65 6d 6f 72 79 20 62 61 72 72 69   ** Memory barri
13e10 65 72 73 20 61 72 65 20 75 73 65 64 20 74 6f 20  ers are used to 
13e20 70 72 65 76 65 6e 74 20 74 68 65 20 63 6f 6d 70  prevent the comp
13e30 69 6c 65 72 20 6f 72 20 74 68 65 20 68 61 72 64  iler or the hard
13e40 77 61 72 65 20 66 72 6f 6d 0a 20 20 2a 2a 20 72  ware from.  ** r
13e50 65 6f 72 64 65 72 69 6e 67 20 74 68 65 20 72 65  eordering the re
13e60 61 64 73 20 61 6e 64 20 77 72 69 74 65 73 2e 0a  ads and writes..
13e70 20 20 2a 2f 0a 20 20 61 48 64 72 20 3d 20 77 61    */.  aHdr = wa
13e80 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29 3b  lIndexHdr(pWal);
13e90 0a 20 20 6d 65 6d 63 70 79 28 26 68 31 2c 20 28  .  memcpy(&h1, (
13ea0 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 30 5d 2c  void *)&aHdr[0],
13eb0 20 73 69 7a 65 6f 66 28 68 31 29 29 3b 0a 20 20   sizeof(h1));.  
13ec0 77 61 6c 53 68 6d 42 61 72 72 69 65 72 28 70 57  walShmBarrier(pW
13ed0 61 6c 29 3b 0a 20 20 6d 65 6d 63 70 79 28 26 68  al);.  memcpy(&h
13ee0 32 2c 20 28 76 6f 69 64 20 2a 29 26 61 48 64 72  2, (void *)&aHdr
13ef0 5b 31 5d 2c 20 73 69 7a 65 6f 66 28 68 32 29 29  [1], sizeof(h2))
13f00 3b 0a 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28  ;..  if( memcmp(
13f10 26 68 31 2c 20 26 68 32 2c 20 73 69 7a 65 6f 66  &h1, &h2, sizeof
13f20 28 68 31 29 29 21 3d 30 20 29 7b 0a 20 20 20 20  (h1))!=0 ){.    
13f30 72 65 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20 44  return 1;   /* D
13f40 69 72 74 79 20 72 65 61 64 20 2a 2f 0a 20 20 7d  irty read */.  }
13f50 20 20 0a 20 20 69 66 28 20 68 31 2e 69 73 49 6e    .  if( h1.isIn
13f60 69 74 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  it==0 ){.    ret
13f70 75 72 6e 20 31 3b 20 20 20 2f 2a 20 4d 61 6c 66  urn 1;   /* Malf
13f80 6f 72 6d 65 64 20 68 65 61 64 65 72 20 2d 20 70  ormed header - p
13f90 72 6f 62 61 62 6c 79 20 61 6c 6c 20 7a 65 72 6f  robably all zero
13fa0 73 20 2a 2f 0a 20 20 7d 0a 20 20 77 61 6c 43 68  s */.  }.  walCh
13fb0 65 63 6b 73 75 6d 42 79 74 65 73 28 31 2c 20 28  ecksumBytes(1, (
13fc0 75 38 2a 29 26 68 31 2c 20 73 69 7a 65 6f 66 28  u8*)&h1, sizeof(
13fd0 68 31 29 2d 73 69 7a 65 6f 66 28 68 31 2e 61 43  h1)-sizeof(h1.aC
13fe0 6b 73 75 6d 29 2c 20 30 2c 20 61 43 6b 73 75 6d  ksum), 0, aCksum
13ff0 29 3b 0a 20 20 69 66 28 20 61 43 6b 73 75 6d 5b  );.  if( aCksum[
14000 30 5d 21 3d 68 31 2e 61 43 6b 73 75 6d 5b 30 5d  0]!=h1.aCksum[0]
14010 20 7c 7c 20 61 43 6b 73 75 6d 5b 31 5d 21 3d 68   || aCksum[1]!=h
14020 31 2e 61 43 6b 73 75 6d 5b 31 5d 20 29 7b 0a 20  1.aCksum[1] ){. 
14030 20 20 20 72 65 74 75 72 6e 20 31 3b 20 20 20 2f     return 1;   /
14040 2a 20 43 68 65 63 6b 73 75 6d 20 64 6f 65 73 20  * Checksum does 
14050 6e 6f 74 20 6d 61 74 63 68 20 2a 2f 0a 20 20 7d  not match */.  }
14060 0a 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26  ..  if( memcmp(&
14070 70 57 61 6c 2d 3e 68 64 72 2c 20 26 68 31 2c 20  pWal->hdr, &h1, 
14080 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48  sizeof(WalIndexH
14090 64 72 29 29 20 29 7b 0a 20 20 20 20 2a 70 43 68  dr)) ){.    *pCh
140a0 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20 20 20 6d  anged = 1;.    m
140b0 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72  emcpy(&pWal->hdr
140c0 2c 20 26 68 31 2c 20 73 69 7a 65 6f 66 28 57 61  , &h1, sizeof(Wa
140d0 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 20  lIndexHdr));.   
140e0 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 20 3d 20   pWal->szPage = 
140f0 28 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67  (pWal->hdr.szPag
14100 65 26 30 78 66 65 30 30 29 20 2b 20 28 28 70 57  e&0xfe00) + ((pW
14110 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26 30  al->hdr.szPage&0
14120 78 30 30 30 31 29 3c 3c 31 36 29 3b 0a 20 20 20  x0001)<<16);.   
14130 20 74 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d   testcase( pWal-
14140 3e 73 7a 50 61 67 65 3c 3d 33 32 37 36 38 20 29  >szPage<=32768 )
14150 3b 0a 20 20 20 20 74 65 73 74 63 61 73 65 28 20  ;.    testcase( 
14160 70 57 61 6c 2d 3e 73 7a 50 61 67 65 3e 3d 36 35  pWal->szPage>=65
14170 35 33 36 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  536 );.  }..  /*
14180 20 54 68 65 20 68 65 61 64 65 72 20 77 61 73 20   The header was 
14190 73 75 63 63 65 73 73 66 75 6c 6c 79 20 72 65 61  successfully rea
141a0 64 2e 20 52 65 74 75 72 6e 20 7a 65 72 6f 2e 20  d. Return zero. 
141b0 2a 2f 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d  */.  return 0;.}
141c0 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20  ../*.** This is 
141d0 74 68 65 20 76 61 6c 75 65 20 74 68 61 74 20 77  the value that w
141e0 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64 20 72  alTryBeginRead r
141f0 65 74 75 72 6e 73 20 77 68 65 6e 20 69 74 20 6e  eturns when it n
14200 65 65 64 73 20 74 6f 0a 2a 2a 20 62 65 20 72 65  eeds to.** be re
14210 74 72 69 65 64 2e 0a 2a 2f 0a 23 64 65 66 69 6e  tried..*/.#defin
14220 65 20 57 41 4c 5f 52 45 54 52 59 20 20 28 2d 31  e WAL_RETRY  (-1
14230 29 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 74 68  )../*.** Read th
14240 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
14250 65 72 20 66 72 6f 6d 20 74 68 65 20 77 61 6c 2d  er from the wal-
14260 69 6e 64 65 78 20 61 6e 64 20 69 6e 74 6f 20 70  index and into p
14270 57 61 6c 2d 3e 68 64 72 2e 0a 2a 2a 20 49 66 20  Wal->hdr..** If 
14280 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72 20 61  the wal-header a
14290 70 70 65 61 72 73 20 74 6f 20 62 65 20 63 6f 72  ppears to be cor
142a0 72 75 70 74 2c 20 74 72 79 20 74 6f 20 72 65 63  rupt, try to rec
142b0 6f 6e 73 74 72 75 63 74 20 74 68 65 0a 2a 2a 20  onstruct the.** 
142c0 77 61 6c 2d 69 6e 64 65 78 20 66 72 6f 6d 20 74  wal-index from t
142d0 68 65 20 57 41 4c 20 62 65 66 6f 72 65 20 72 65  he WAL before re
142e0 74 75 72 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 53  turning..**.** S
142f0 65 74 20 2a 70 43 68 61 6e 67 65 64 20 74 6f 20  et *pChanged to 
14300 31 20 69 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  1 if the wal-ind
14310 65 78 20 68 65 61 64 65 72 20 76 61 6c 75 65 20  ex header value 
14320 69 6e 20 70 57 61 6c 2d 3e 68 64 72 20 69 73 0a  in pWal->hdr is.
14330 2a 2a 20 63 68 61 6e 67 65 64 20 62 79 20 74 68  ** changed by th
14340 69 73 20 6f 70 65 72 61 74 69 6f 6e 2e 20 20 49  is operation.  I
14350 66 20 70 57 61 6c 2d 3e 68 64 72 20 69 73 20 75  f pWal->hdr is u
14360 6e 63 68 61 6e 67 65 64 2c 20 73 65 74 20 2a 70  nchanged, set *p
14370 43 68 61 6e 67 65 64 0a 2a 2a 20 74 6f 20 30 2e  Changed.** to 0.
14380 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 77 61  .**.** If the wa
14390 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69  l-index header i
143a0 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20 72  s successfully r
143b0 65 61 64 2c 20 72 65 74 75 72 6e 20 53 51 4c 49  ead, return SQLI
143c0 54 45 5f 4f 4b 2e 20 0a 2a 2a 20 4f 74 68 65 72  TE_OK. .** Other
143d0 77 69 73 65 20 61 6e 20 53 51 4c 69 74 65 20 65  wise an SQLite e
143e0 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a 73 74  rror code..*/.st
143f0 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e 64 65  atic int walInde
14400 78 52 65 61 64 48 64 72 28 57 61 6c 20 2a 70 57  xReadHdr(Wal *pW
14410 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e 67 65  al, int *pChange
14420 64 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  d){.  int rc;   
14430 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14440 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
14450 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 62 61  code */.  int ba
14460 64 48 64 72 3b 20 20 20 20 20 20 20 20 20 20 20  dHdr;           
14470 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
14480 65 20 69 66 20 61 20 68 65 61 64 65 72 20 72 65  e if a header re
14490 61 64 20 66 61 69 6c 65 64 20 2a 2f 0a 20 20 76  ad failed */.  v
144a0 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 70 61 67  olatile u32 *pag
144b0 65 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  e0;            /
144c0 2a 20 43 68 75 6e 6b 20 6f 66 20 77 61 6c 2d 69  * Chunk of wal-i
144d0 6e 64 65 78 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ndex containing 
144e0 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20 2f 2a 20  header */..  /* 
144f0 45 6e 73 75 72 65 20 74 68 61 74 20 70 61 67 65  Ensure that page
14500 20 30 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e   0 of the wal-in
14510 64 65 78 20 28 74 68 65 20 70 61 67 65 20 74 68  dex (the page th
14520 61 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  at contains the 
14530 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20  .  ** wal-index 
14540 68 65 61 64 65 72 29 20 69 73 20 6d 61 70 70 65  header) is mappe
14550 64 2e 20 52 65 74 75 72 6e 20 65 61 72 6c 79 20  d. Return early 
14560 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  if an error occu
14570 72 73 20 68 65 72 65 2e 0a 20 20 2a 2f 0a 20 20  rs here..  */.  
14580 61 73 73 65 72 74 28 20 70 43 68 61 6e 67 65 64  assert( pChanged
14590 20 29 3b 0a 20 20 72 63 20 3d 20 77 61 6c 49 6e   );.  rc = walIn
145a0 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20 30 2c  dexPage(pWal, 0,
145b0 20 26 70 61 67 65 30 29 3b 0a 20 20 69 66 28 20   &page0);.  if( 
145c0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
145d0 0a 20 20 20 20 61 73 73 65 72 74 28 20 72 63 21  .    assert( rc!
145e0 3d 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59  =SQLITE_READONLY
145f0 20 29 3b 20 2f 2a 20 52 45 41 44 4f 4e 4c 59 20   ); /* READONLY 
14600 63 68 61 6e 67 65 64 20 74 6f 20 4f 4b 20 69 6e  changed to OK in
14610 20 77 61 6c 49 6e 64 65 78 50 61 67 65 20 2a 2f   walIndexPage */
14620 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
14630 49 54 45 5f 52 45 41 44 4f 4e 4c 59 5f 43 41 4e  ITE_READONLY_CAN
14640 54 49 4e 49 54 20 29 7b 0a 20 20 20 20 20 20 2f  TINIT ){.      /
14650 2a 20 54 68 65 20 53 51 4c 49 54 45 5f 52 45 41  * The SQLITE_REA
14660 44 4f 4e 4c 59 5f 43 41 4e 54 49 4e 49 54 20 72  DONLY_CANTINIT r
14670 65 74 75 72 6e 20 6d 65 61 6e 73 20 74 68 61 74  eturn means that
14680 20 74 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f   the shared-memo
14690 72 79 0a 20 20 20 20 20 20 2a 2a 20 77 61 73 20  ry.      ** was 
146a0 6f 70 65 6e 61 62 6c 65 20 62 75 74 20 69 73 20  openable but is 
146b0 6e 6f 74 20 77 72 69 74 61 62 6c 65 2c 20 61 6e  not writable, an
146c0 64 20 74 68 69 73 20 74 68 72 65 61 64 20 69 73  d this thread is
146d0 20 75 6e 61 62 6c 65 20 74 6f 0a 20 20 20 20 20   unable to.     
146e0 20 2a 2a 20 63 6f 6e 66 69 72 6d 20 74 68 61 74   ** confirm that
146f0 20 61 6e 6f 74 68 65 72 20 77 72 69 74 65 2d 63   another write-c
14700 61 70 61 62 6c 65 20 63 6f 6e 6e 65 63 74 69 6f  apable connectio
14710 6e 20 68 61 73 20 74 68 65 20 73 68 61 72 65 64  n has the shared
14720 2d 6d 65 6d 6f 72 79 0a 20 20 20 20 20 20 2a 2a  -memory.      **
14730 20 6f 70 65 6e 2c 20 61 6e 64 20 68 65 6e 63 65   open, and hence
14740 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20   the content of 
14750 74 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72  the shared-memor
14760 79 20 69 73 20 75 6e 72 65 6c 69 61 62 6c 65 2c  y is unreliable,
14770 0a 20 20 20 20 20 20 2a 2a 20 73 69 6e 63 65 20  .      ** since 
14780 74 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72  the shared-memor
14790 79 20 6d 69 67 68 74 20 62 65 20 69 6e 63 6f 6e  y might be incon
147a0 73 69 73 74 65 6e 74 20 77 69 74 68 20 74 68 65  sistent with the
147b0 20 57 41 4c 20 66 69 6c 65 0a 20 20 20 20 20 20   WAL file.      
147c0 2a 2a 20 61 6e 64 20 74 68 65 72 65 20 69 73 20  ** and there is 
147d0 6e 6f 20 77 72 69 74 65 72 20 6f 6e 20 68 61 6e  no writer on han
147e0 64 20 74 6f 20 66 69 78 20 69 74 2e 20 2a 2f 0a  d to fix it. */.
147f0 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 61        assert( pa
14800 67 65 30 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20  ge0==0 );.      
14810 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72  assert( pWal->wr
14820 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20  iteLock==0 );.  
14830 20 20 20 20 61 73 73 65 72 74 28 20 70 57 61 6c      assert( pWal
14840 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57 41 4c  ->readOnly & WAL
14850 5f 53 48 4d 5f 52 44 4f 4e 4c 59 20 29 3b 0a 20  _SHM_RDONLY );. 
14860 20 20 20 20 20 70 57 61 6c 2d 3e 62 53 68 6d 55       pWal->bShmU
14870 6e 72 65 6c 69 61 62 6c 65 20 3d 20 31 3b 0a 20  nreliable = 1;. 
14880 20 20 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c 75       pWal->exclu
14890 73 69 76 65 4d 6f 64 65 20 3d 20 57 41 4c 5f 48  siveMode = WAL_H
148a0 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 3b 0a  EAPMEMORY_MODE;.
148b0 20 20 20 20 20 20 2a 70 43 68 61 6e 67 65 64 20        *pChanged 
148c0 3d 20 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  = 1;.    }else{.
148d0 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
148e0 20 2f 2a 20 41 6e 79 20 6f 74 68 65 72 20 6e 6f   /* Any other no
148f0 6e 2d 4f 4b 20 72 65 74 75 72 6e 20 69 73 20 6a  n-OK return is j
14900 75 73 74 20 61 6e 20 65 72 72 6f 72 20 2a 2f 0a  ust an error */.
14910 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20      }.  }else{. 
14920 20 20 20 2f 2a 20 70 61 67 65 30 20 63 61 6e 20     /* page0 can 
14930 62 65 20 4e 55 4c 4c 20 69 66 20 74 68 65 20 53  be NULL if the S
14940 48 4d 20 69 73 20 7a 65 72 6f 20 62 79 74 65 73  HM is zero bytes
14950 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 70 57 61   in size and pWa
14960 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 0a 20 20 20  l->writeLock.   
14970 20 2a 2a 20 69 73 20 7a 65 72 6f 2c 20 77 68 69   ** is zero, whi
14980 63 68 20 70 72 65 76 65 6e 74 73 20 74 68 65 20  ch prevents the 
14990 53 48 4d 20 66 72 6f 6d 20 67 72 6f 77 69 6e 67  SHM from growing
149a0 20 2a 2f 0a 20 20 20 20 74 65 73 74 63 61 73 65   */.    testcase
149b0 28 20 70 61 67 65 30 21 3d 30 20 29 3b 0a 20 20  ( page0!=0 );.  
149c0 7d 0a 20 20 61 73 73 65 72 74 28 20 70 61 67 65  }.  assert( page
149d0 30 21 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 77 72  0!=0 || pWal->wr
149e0 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 0a 20  iteLock==0 );.. 
149f0 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72 73 74   /* If the first
14a00 20 70 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c   page of the wal
14a10 2d 69 6e 64 65 78 20 68 61 73 20 62 65 65 6e 20  -index has been 
14a20 6d 61 70 70 65 64 2c 20 74 72 79 20 74 6f 20 72  mapped, try to r
14a30 65 61 64 20 74 68 65 0a 20 20 2a 2a 20 77 61 6c  ead the.  ** wal
14a40 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 6d  -index header im
14a50 6d 65 64 69 61 74 65 6c 79 2c 20 77 69 74 68 6f  mediately, witho
14a60 75 74 20 68 6f 6c 64 69 6e 67 20 61 6e 79 20 6c  ut holding any l
14a70 6f 63 6b 2e 20 54 68 69 73 20 75 73 75 61 6c 6c  ock. This usuall
14a80 79 0a 20 20 2a 2a 20 77 6f 72 6b 73 2c 20 62 75  y.  ** works, bu
14a90 74 20 6d 61 79 20 66 61 69 6c 20 69 66 20 74 68  t may fail if th
14aa0 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
14ab0 65 72 20 69 73 20 63 6f 72 72 75 70 74 20 6f 72  er is corrupt or
14ac0 20 63 75 72 72 65 6e 74 6c 79 20 0a 20 20 2a 2a   currently .  **
14ad0 20 62 65 69 6e 67 20 6d 6f 64 69 66 69 65 64 20   being modified 
14ae0 62 79 20 61 6e 6f 74 68 65 72 20 74 68 72 65 61  by another threa
14af0 64 20 6f 72 20 70 72 6f 63 65 73 73 2e 0a 20 20  d or process..  
14b00 2a 2f 0a 20 20 62 61 64 48 64 72 20 3d 20 28 70  */.  badHdr = (p
14b10 61 67 65 30 20 3f 20 77 61 6c 49 6e 64 65 78 54  age0 ? walIndexT
14b20 72 79 48 64 72 28 70 57 61 6c 2c 20 70 43 68 61  ryHdr(pWal, pCha
14b30 6e 67 65 64 29 20 3a 20 31 29 3b 0a 0a 20 20 2f  nged) : 1);..  /
14b40 2a 20 49 66 20 74 68 65 20 66 69 72 73 74 20 61  * If the first a
14b50 74 74 65 6d 70 74 20 66 61 69 6c 65 64 2c 20 69  ttempt failed, i
14b60 74 20 6d 69 67 68 74 20 68 61 76 65 20 62 65 65  t might have bee
14b70 6e 20 64 75 65 20 74 6f 20 61 20 72 61 63 65 0a  n due to a race.
14b80 20 20 2a 2a 20 77 69 74 68 20 61 20 77 72 69 74    ** with a writ
14b90 65 72 2e 20 20 53 6f 20 67 65 74 20 61 20 57 52  er.  So get a WR
14ba0 49 54 45 20 6c 6f 63 6b 20 61 6e 64 20 74 72 79  ITE lock and try
14bb0 20 61 67 61 69 6e 2e 0a 20 20 2a 2f 0a 20 20 61   again..  */.  a
14bc0 73 73 65 72 74 28 20 62 61 64 48 64 72 3d 3d 30  ssert( badHdr==0
14bd0 20 7c 7c 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c   || pWal->writeL
14be0 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20  ock==0 );.  if( 
14bf0 62 61 64 48 64 72 20 29 7b 0a 20 20 20 20 69 66  badHdr ){.    if
14c00 28 20 70 57 61 6c 2d 3e 62 53 68 6d 55 6e 72 65  ( pWal->bShmUnre
14c10 6c 69 61 62 6c 65 3d 3d 30 20 26 26 20 28 70 57  liable==0 && (pW
14c20 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57  al->readOnly & W
14c30 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 29 20 29  AL_SHM_RDONLY) )
14c40 7b 0a 20 20 20 20 20 20 69 66 28 20 53 51 4c 49  {.      if( SQLI
14c50 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c  TE_OK==(rc = wal
14c60 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  LockShared(pWal,
14c70 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 29   WAL_WRITE_LOCK)
14c80 29 20 29 7b 0a 20 20 20 20 20 20 20 20 77 61 6c  ) ){.        wal
14c90 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61  UnlockShared(pWa
14ca0 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43  l, WAL_WRITE_LOC
14cb0 4b 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  K);.        rc =
14cc0 20 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59   SQLITE_READONLY
14cd0 5f 52 45 43 4f 56 45 52 59 3b 0a 20 20 20 20 20  _RECOVERY;.     
14ce0 20 7d 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28   }.    }else if(
14cf0 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20   SQLITE_OK==(rc 
14d00 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69  = walLockExclusi
14d10 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49  ve(pWal, WAL_WRI
14d20 54 45 5f 4c 4f 43 4b 2c 20 31 29 29 20 29 7b 0a  TE_LOCK, 1)) ){.
14d30 20 20 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74        pWal->writ
14d40 65 4c 6f 63 6b 20 3d 20 31 3b 0a 20 20 20 20 20  eLock = 1;.     
14d50 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d   if( SQLITE_OK==
14d60 28 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 50 61  (rc = walIndexPa
14d70 67 65 28 70 57 61 6c 2c 20 30 2c 20 26 70 61 67  ge(pWal, 0, &pag
14d80 65 30 29 29 20 29 7b 0a 20 20 20 20 20 20 20 20  e0)) ){.        
14d90 62 61 64 48 64 72 20 3d 20 77 61 6c 49 6e 64 65  badHdr = walInde
14da0 78 54 72 79 48 64 72 28 70 57 61 6c 2c 20 70 43  xTryHdr(pWal, pC
14db0 68 61 6e 67 65 64 29 3b 0a 20 20 20 20 20 20 20  hanged);.       
14dc0 20 69 66 28 20 62 61 64 48 64 72 20 29 7b 0a 20   if( badHdr ){. 
14dd0 20 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74           /* If t
14de0 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
14df0 64 65 72 20 69 73 20 73 74 69 6c 6c 20 6d 61 6c  der is still mal
14e00 66 6f 72 6d 65 64 20 65 76 65 6e 20 77 68 69 6c  formed even whil
14e10 65 20 68 6f 6c 64 69 6e 67 0a 20 20 20 20 20 20  e holding.      
14e20 20 20 20 20 2a 2a 20 61 20 57 52 49 54 45 20 6c      ** a WRITE l
14e30 6f 63 6b 2c 20 69 74 20 63 61 6e 20 6f 6e 6c 79  ock, it can only
14e40 20 6d 65 61 6e 20 74 68 61 74 20 74 68 65 20 68   mean that the h
14e50 65 61 64 65 72 20 69 73 20 63 6f 72 72 75 70 74  eader is corrupt
14e60 65 64 20 61 6e 64 0a 20 20 20 20 20 20 20 20 20  ed and.         
14e70 20 2a 2a 20 6e 65 65 64 73 20 74 6f 20 62 65 20   ** needs to be 
14e80 72 65 63 6f 6e 73 74 72 75 63 74 65 64 2e 20 20  reconstructed.  
14e90 53 6f 20 72 75 6e 20 72 65 63 6f 76 65 72 79 20  So run recovery 
14ea0 74 6f 20 64 6f 20 65 78 61 63 74 6c 79 20 74 68  to do exactly th
14eb0 61 74 2e 0a 20 20 20 20 20 20 20 20 20 20 2a 2f  at..          */
14ec0 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
14ed0 77 61 6c 49 6e 64 65 78 52 65 63 6f 76 65 72 28  walIndexRecover(
14ee0 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20  pWal);.         
14ef0 20 2a 70 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a   *pChanged = 1;.
14f00 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
14f10 7d 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 77 72  }.      pWal->wr
14f20 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20  iteLock = 0;.   
14f30 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c     walUnlockExcl
14f40 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
14f50 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  WRITE_LOCK, 1);.
14f60 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20      }.  }..  /* 
14f70 49 66 20 74 68 65 20 68 65 61 64 65 72 20 69 73  If the header is
14f80 20 72 65 61 64 20 73 75 63 63 65 73 73 66 75 6c   read successful
14f90 6c 79 2c 20 63 68 65 63 6b 20 74 68 65 20 76 65  ly, check the ve
14fa0 72 73 69 6f 6e 20 6e 75 6d 62 65 72 20 74 6f 20  rsion number to 
14fb0 6d 61 6b 65 0a 20 20 2a 2a 20 73 75 72 65 20 74  make.  ** sure t
14fc0 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 77 61 73  he wal-index was
14fd0 20 6e 6f 74 20 63 6f 6e 73 74 72 75 63 74 65 64   not constructed
14fe0 20 77 69 74 68 20 73 6f 6d 65 20 66 75 74 75 72   with some futur
14ff0 65 20 66 6f 72 6d 61 74 20 74 68 61 74 0a 20 20  e format that.  
15000 2a 2a 20 74 68 69 73 20 76 65 72 73 69 6f 6e 20  ** this version 
15010 6f 66 20 53 51 4c 69 74 65 20 63 61 6e 6e 6f 74  of SQLite cannot
15020 20 75 6e 64 65 72 73 74 61 6e 64 2e 0a 20 20 2a   understand..  *
15030 2f 0a 20 20 69 66 28 20 62 61 64 48 64 72 3d 3d  /.  if( badHdr==
15040 30 20 26 26 20 70 57 61 6c 2d 3e 68 64 72 2e 69  0 && pWal->hdr.i
15050 56 65 72 73 69 6f 6e 21 3d 57 41 4c 49 4e 44 45  Version!=WALINDE
15060 58 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 20 29 7b  X_MAX_VERSION ){
15070 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
15080 5f 43 41 4e 54 4f 50 45 4e 5f 42 4b 50 54 3b 0a  _CANTOPEN_BKPT;.
15090 20 20 7d 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e    }.  if( pWal->
150a0 62 53 68 6d 55 6e 72 65 6c 69 61 62 6c 65 20 29  bShmUnreliable )
150b0 7b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  {.    if( rc!=SQ
150c0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
150d0 20 77 61 6c 49 6e 64 65 78 43 6c 6f 73 65 28 70   walIndexClose(p
150e0 57 61 6c 2c 20 30 29 3b 0a 20 20 20 20 20 20 70  Wal, 0);.      p
150f0 57 61 6c 2d 3e 62 53 68 6d 55 6e 72 65 6c 69 61  Wal->bShmUnrelia
15100 62 6c 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 61  ble = 0;.      a
15110 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69  ssert( pWal->nWi
15120 44 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e  Data>0 && pWal->
15130 61 70 57 69 44 61 74 61 5b 30 5d 3d 3d 30 20 29  apWiData[0]==0 )
15140 3b 0a 20 20 20 20 20 20 2f 2a 20 77 61 6c 49 6e  ;.      /* walIn
15150 64 65 78 52 65 63 6f 76 65 72 28 29 20 6d 69 67  dexRecover() mig
15160 68 74 20 68 61 76 65 20 72 65 74 75 72 6e 65 64  ht have returned
15170 20 53 48 4f 52 54 5f 52 45 41 44 20 69 66 20 61   SHORT_READ if a
15180 20 63 6f 6e 63 75 72 72 65 6e 74 0a 20 20 20 20   concurrent.    
15190 20 20 2a 2a 20 77 72 69 74 65 72 20 74 72 75 6e    ** writer trun
151a0 63 61 74 65 64 20 74 68 65 20 57 41 4c 20 6f 75  cated the WAL ou
151b0 74 20 66 72 6f 6d 20 75 6e 64 65 72 20 69 74 2e  t from under it.
151c0 20 20 49 66 20 74 68 61 74 20 68 61 70 70 65 6e    If that happen
151d0 73 2c 20 69 74 0a 20 20 20 20 20 20 2a 2a 20 69  s, it.      ** i
151e0 6e 64 69 63 61 74 65 73 20 74 68 61 74 20 61 20  ndicates that a 
151f0 77 72 69 74 65 72 20 68 61 73 20 66 69 78 65 64  writer has fixed
15200 20 74 68 65 20 53 48 4d 20 66 69 6c 65 20 66 6f   the SHM file fo
15210 72 20 75 73 2c 20 73 6f 20 72 65 74 72 79 20 2a  r us, so retry *
15220 2f 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  /.      if( rc==
15230 53 51 4c 49 54 45 5f 49 4f 45 52 52 5f 53 48 4f  SQLITE_IOERR_SHO
15240 52 54 5f 52 45 41 44 20 29 20 72 63 20 3d 20 57  RT_READ ) rc = W
15250 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 7d 0a  AL_RETRY;.    }.
15260 20 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73      pWal->exclus
15270 69 76 65 4d 6f 64 65 20 3d 20 57 41 4c 5f 4e 4f  iveMode = WAL_NO
15280 52 4d 41 4c 5f 4d 4f 44 45 3b 0a 20 20 7d 0a 0a  RMAL_MODE;.  }..
15290 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
152a0 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 61 20 74 72 61  /*.** Open a tra
152b0 6e 73 61 63 74 69 6f 6e 20 69 6e 20 61 20 63 6f  nsaction in a co
152c0 6e 6e 65 63 74 69 6f 6e 20 77 68 65 72 65 20 74  nnection where t
152d0 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79  he shared-memory
152e0 20 69 73 20 72 65 61 64 2d 6f 6e 6c 79 0a 2a 2a   is read-only.**
152f0 20 61 6e 64 20 77 68 65 72 65 20 77 65 20 63 61   and where we ca
15300 6e 6e 6f 74 20 76 65 72 69 66 79 20 74 68 61 74  nnot verify that
15310 20 74 68 65 72 65 20 69 73 20 61 20 73 65 70 61   there is a sepa
15320 72 61 74 65 20 77 72 69 74 65 2d 63 61 70 61 62  rate write-capab
15330 6c 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 0a 2a 2a  le connection.**
15340 20 6f 6e 20 68 61 6e 64 20 74 6f 20 6b 65 65 70   on hand to keep
15350 20 74 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f   the shared-memo
15360 72 79 20 75 70 2d 74 6f 2d 64 61 74 65 20 77 69  ry up-to-date wi
15370 74 68 20 74 68 65 20 57 41 4c 20 66 69 6c 65 2e  th the WAL file.
15380 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 63 61 6e 20  .**.** This can 
15390 68 61 70 70 65 6e 2c 20 66 6f 72 20 65 78 61 6d  happen, for exam
153a0 70 6c 65 2c 20 77 68 65 6e 20 74 68 65 20 73 68  ple, when the sh
153b0 61 72 65 64 2d 6d 65 6d 6f 72 79 20 69 73 20 69  ared-memory is i
153c0 6d 70 6c 65 6d 65 6e 74 65 64 20 62 79 0a 2a 2a  mplemented by.**
153d0 20 6d 65 6d 6f 72 79 2d 6d 61 70 70 69 6e 67 20   memory-mapping 
153e0 61 20 2a 2d 73 68 6d 20 66 69 6c 65 2c 20 77 68  a *-shm file, wh
153f0 65 72 65 20 61 20 70 72 69 6f 72 20 77 72 69 74  ere a prior writ
15400 65 72 20 68 61 73 20 73 68 75 74 20 64 6f 77 6e  er has shut down
15410 20 61 6e 64 0a 2a 2a 20 6c 65 66 74 20 74 68 65   and.** left the
15420 20 2a 2d 73 68 6d 20 66 69 6c 65 20 6f 6e 20 64   *-shm file on d
15430 69 73 6b 2c 20 61 6e 64 20 6e 6f 77 20 74 68 65  isk, and now the
15440 20 70 72 65 73 65 6e 74 20 63 6f 6e 6e 65 63 74   present connect
15450 69 6f 6e 20 69 73 20 74 72 79 69 6e 67 0a 2a 2a  ion is trying.**
15460 20 74 6f 20 75 73 65 20 74 68 61 74 20 64 61 74   to use that dat
15470 61 62 61 73 65 20 62 75 74 20 6c 61 63 6b 73 20  abase but lacks 
15480 77 72 69 74 65 20 70 65 72 6d 69 73 73 69 6f 6e  write permission
15490 20 6f 6e 20 74 68 65 20 2a 2d 73 68 6d 20 66 69   on the *-shm fi
154a0 6c 65 2e 0a 2a 2a 20 4f 74 68 65 72 20 73 63 65  le..** Other sce
154b0 6e 61 72 69 6f 73 20 61 72 65 20 61 6c 73 6f 20  narios are also 
154c0 70 6f 73 73 69 62 6c 65 2c 20 64 65 70 65 6e 64  possible, depend
154d0 69 6e 67 20 6f 6e 20 74 68 65 20 56 46 53 20 69  ing on the VFS i
154e0 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a  mplementation..*
154f0 2a 0a 2a 2a 20 50 72 65 63 6f 6e 64 69 74 69 6f  *.** Preconditio
15500 6e 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 54 68 65 20  n:.**.**    The 
15510 2a 2d 77 61 6c 20 66 69 6c 65 20 68 61 73 20 62  *-wal file has b
15520 65 65 6e 20 72 65 61 64 20 61 6e 64 20 61 6e 20  een read and an 
15530 61 70 70 72 6f 70 72 69 61 74 65 20 77 61 6c 2d  appropriate wal-
15540 69 6e 64 65 78 20 68 61 73 20 62 65 65 6e 0a 2a  index has been.*
15550 2a 20 20 20 20 63 6f 6e 73 74 72 75 63 74 65 64  *    constructed
15560 20 69 6e 20 70 57 61 6c 2d 3e 61 70 57 69 44 61   in pWal->apWiDa
15570 74 61 5b 5d 20 75 73 69 6e 67 20 68 65 61 70 20  ta[] using heap 
15580 6d 65 6d 6f 72 79 20 69 6e 73 74 65 61 64 20 6f  memory instead o
15590 66 20 73 68 61 72 65 64 0a 2a 2a 20 20 20 20 6d  f shared.**    m
155a0 65 6d 6f 72 79 2e 20 0a 2a 2a 0a 2a 2a 20 49 66  emory. .**.** If
155b0 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72   this function r
155c0 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b  eturns SQLITE_OK
155d0 2c 20 74 68 65 6e 20 74 68 65 20 72 65 61 64 20  , then the read 
155e0 74 72 61 6e 73 61 63 74 69 6f 6e 20 68 61 73 0a  transaction has.
155f0 2a 2a 20 62 65 65 6e 20 73 75 63 63 65 73 73 66  ** been successf
15600 75 6c 6c 79 20 6f 70 65 6e 65 64 2e 20 49 6e 20  ully opened. In 
15610 74 68 69 73 20 63 61 73 65 20 6f 75 74 70 75 74  this case output
15620 20 76 61 72 69 61 62 6c 65 20 28 2a 70 43 68 61   variable (*pCha
15630 6e 67 65 64 29 20 0a 2a 2a 20 69 73 20 73 65 74  nged) .** is set
15640 20 74 6f 20 74 72 75 65 20 62 65 66 6f 72 65 20   to true before 
15650 72 65 74 75 72 6e 69 6e 67 20 69 66 20 74 68 65  returning if the
15660 20 63 61 6c 6c 65 72 20 73 68 6f 75 6c 64 20 64   caller should d
15670 69 73 63 61 72 64 20 74 68 65 0a 2a 2a 20 63 6f  iscard the.** co
15680 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 70 61  ntents of the pa
15690 67 65 20 63 61 63 68 65 20 62 65 66 6f 72 65 20  ge cache before 
156a0 70 72 6f 63 65 65 64 69 6e 67 2e 20 4f 72 2c 20  proceeding. Or, 
156b0 69 66 20 69 74 20 72 65 74 75 72 6e 73 20 0a 2a  if it returns .*
156c0 2a 20 57 41 4c 5f 52 45 54 52 59 2c 20 74 68 65  * WAL_RETRY, the
156d0 6e 20 74 68 65 20 68 65 61 70 20 6d 65 6d 6f 72  n the heap memor
156e0 79 20 77 61 6c 2d 69 6e 64 65 78 20 68 61 73 20  y wal-index has 
156f0 62 65 65 6e 20 64 69 73 63 61 72 64 65 64 20 61  been discarded a
15700 6e 64 20 0a 2a 2a 20 74 68 65 20 63 61 6c 6c 65  nd .** the calle
15710 72 20 73 68 6f 75 6c 64 20 72 65 74 72 79 20 6f  r should retry o
15720 70 65 6e 69 6e 67 20 74 68 65 20 72 65 61 64 20  pening the read 
15730 74 72 61 6e 73 61 63 74 69 6f 6e 20 66 72 6f 6d  transaction from
15740 20 74 68 65 20 0a 2a 2a 20 62 65 67 69 6e 6e 69   the .** beginni
15750 6e 67 20 28 69 6e 63 6c 75 64 69 6e 67 20 61 74  ng (including at
15760 74 65 6d 70 74 69 6e 67 20 74 6f 20 6d 61 70 20  tempting to map 
15770 74 68 65 20 2a 2d 73 68 6d 20 66 69 6c 65 29 2e  the *-shm file).
15780 20 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 65 72   .**.** If an er
15790 72 6f 72 20 6f 63 63 75 72 73 2c 20 61 6e 20 53  ror occurs, an S
157a0 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
157b0 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2f   is returned..*/
157c0 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 42  .static int walB
157d0 65 67 69 6e 53 68 6d 55 6e 72 65 6c 69 61 62 6c  eginShmUnreliabl
157e0 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  e(Wal *pWal, int
157f0 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a 20 20 69   *pChanged){.  i
15800 36 34 20 73 7a 57 61 6c 3b 20 20 20 20 20 20 20  64 szWal;       
15810 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
15820 2a 20 53 69 7a 65 20 6f 66 20 77 61 6c 20 66 69  * Size of wal fi
15830 6c 65 20 6f 6e 20 64 69 73 6b 20 69 6e 20 62 79  le on disk in by
15840 74 65 73 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66  tes */.  i64 iOf
15850 66 73 65 74 3b 20 20 20 20 20 20 20 20 20 20 20  fset;           
15860 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72           /* Curr
15870 65 6e 74 20 6f 66 66 73 65 74 20 77 68 65 6e 20  ent offset when 
15880 72 65 61 64 69 6e 67 20 77 61 6c 20 66 69 6c 65  reading wal file
15890 20 2a 2f 0a 20 20 75 38 20 61 42 75 66 5b 57 41   */.  u8 aBuf[WA
158a0 4c 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20 20 20  L_HDRSIZE];     
158b0 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
158c0 74 6f 20 6c 6f 61 64 20 57 41 4c 20 68 65 61 64  to load WAL head
158d0 65 72 20 69 6e 74 6f 20 2a 2f 0a 20 20 75 38 20  er into */.  u8 
158e0 2a 61 46 72 61 6d 65 20 3d 20 30 3b 20 20 20 20  *aFrame = 0;    
158f0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
15900 4d 61 6c 6c 6f 63 27 64 20 62 75 66 66 65 72 20  Malloc'd buffer 
15910 74 6f 20 6c 6f 61 64 20 65 6e 74 69 72 65 20 66  to load entire f
15920 72 61 6d 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  rame */.  int sz
15930 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  Frame;          
15940 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
15950 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
15960 62 75 66 66 65 72 20 61 46 72 61 6d 65 5b 5d 20  buffer aFrame[] 
15970 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74 61 3b 20  */.  u8 *aData; 
15980 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15990 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
159a0 74 6f 20 64 61 74 61 20 70 61 72 74 20 6f 66 20  to data part of 
159b0 61 46 72 61 6d 65 20 62 75 66 66 65 72 20 2a 2f  aFrame buffer */
159c0 0a 20 20 76 6f 6c 61 74 69 6c 65 20 76 6f 69 64  .  volatile void
159d0 20 2a 70 44 75 6d 6d 79 3b 20 20 20 20 20 20 20   *pDummy;       
159e0 20 20 20 2f 2a 20 44 75 6d 6d 79 20 61 72 67 75     /* Dummy argu
159f0 6d 65 6e 74 20 66 6f 72 20 78 53 68 6d 4d 61 70  ment for xShmMap
15a00 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20 20   */.  int rc;   
15a10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15a20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
15a30 63 6f 64 65 20 2a 2f 0a 20 20 75 33 32 20 61 53  code */.  u32 aS
15a40 61 76 65 43 6b 73 75 6d 5b 32 5d 3b 20 20 20 20  aveCksum[2];    
15a50 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 61 76            /* Sav
15a60 65 64 20 63 6f 70 79 20 6f 66 20 70 57 61 6c 2d  ed copy of pWal-
15a70 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
15a80 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70   */..  assert( p
15a90 57 61 6c 2d 3e 62 53 68 6d 55 6e 72 65 6c 69 61  Wal->bShmUnrelia
15aa0 62 6c 65 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ble );.  assert(
15ab0 20 70 57 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20   pWal->readOnly 
15ac0 26 20 57 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59  & WAL_SHM_RDONLY
15ad0 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57   );.  assert( pW
15ae0 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20 26 26  al->nWiData>0 &&
15af0 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
15b00 30 5d 20 29 3b 0a 0a 20 20 2f 2a 20 54 61 6b 65  0] );..  /* Take
15b10 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
15b20 29 2e 20 54 68 69 73 20 68 61 73 20 74 68 65 20  ). This has the 
15b30 65 66 66 65 63 74 20 6f 66 20 70 72 65 76 65 6e  effect of preven
15b40 74 69 6e 67 20 61 6e 79 0a 20 20 2a 2a 20 77 72  ting any.  ** wr
15b50 69 74 65 72 73 20 66 72 6f 6d 20 72 75 6e 6e 69  iters from runni
15b60 6e 67 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c  ng a checkpoint,
15b70 20 62 75 74 20 64 6f 65 73 20 6e 6f 74 20 73 74   but does not st
15b80 6f 70 20 74 68 65 6d 0a 20 20 2a 2a 20 66 72 6f  op them.  ** fro
15b90 6d 20 72 75 6e 6e 69 6e 67 20 72 65 63 6f 76 65  m running recove
15ba0 72 79 2e 20 20 2a 2f 0a 20 20 72 63 20 3d 20 77  ry.  */.  rc = w
15bb0 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61  alLockShared(pWa
15bc0 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  l, WAL_READ_LOCK
15bd0 28 30 29 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  (0));.  if( rc!=
15be0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
15bf0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
15c00 42 55 53 59 20 29 20 72 63 20 3d 20 57 41 4c 5f  BUSY ) rc = WAL_
15c10 52 45 54 52 59 3b 0a 20 20 20 20 67 6f 74 6f 20  RETRY;.    goto 
15c20 62 65 67 69 6e 5f 75 6e 72 65 6c 69 61 62 6c 65  begin_unreliable
15c30 5f 73 68 6d 5f 6f 75 74 3b 0a 20 20 7d 0a 20 20  _shm_out;.  }.  
15c40 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d  pWal->readLock =
15c50 20 30 3b 0a 0a 20 20 2f 2a 20 43 68 65 63 6b 20   0;..  /* Check 
15c60 74 6f 20 73 65 65 20 69 66 20 61 20 73 65 70 61  to see if a sepa
15c70 72 61 74 65 20 77 72 69 74 65 72 20 68 61 73 20  rate writer has 
15c80 61 74 74 61 63 68 65 64 20 74 6f 20 74 68 65 20  attached to the 
15c90 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20 61 72  shared-memory ar
15ca0 65 61 2c 0a 20 20 2a 2a 20 74 68 75 73 20 6d 61  ea,.  ** thus ma
15cb0 6b 69 6e 67 20 74 68 65 20 73 68 61 72 65 64 2d  king the shared-
15cc0 6d 65 6d 6f 72 79 20 22 72 65 6c 69 61 62 6c 65  memory "reliable
15cd0 22 20 61 67 61 69 6e 2e 20 20 44 6f 20 74 68 69  " again.  Do thi
15ce0 73 20 62 79 20 69 6e 76 6f 6b 69 6e 67 0a 20 20  s by invoking.  
15cf0 2a 2a 20 74 68 65 20 78 53 68 6d 4d 61 70 28 29  ** the xShmMap()
15d00 20 72 6f 75 74 69 6e 65 20 6f 66 20 74 68 65 20   routine of the 
15d10 56 46 53 20 61 6e 64 20 6c 6f 6f 6b 69 6e 67 20  VFS and looking 
15d20 74 6f 20 73 65 65 20 69 66 20 74 68 65 20 72 65  to see if the re
15d30 74 75 72 6e 0a 20 20 2a 2a 20 69 73 20 53 51 4c  turn.  ** is SQL
15d40 49 54 45 5f 52 45 41 44 4f 4e 4c 59 20 69 6e 73  ITE_READONLY ins
15d50 74 65 61 64 20 6f 66 20 53 51 4c 49 54 45 5f 52  tead of SQLITE_R
15d60 45 41 44 4f 4e 4c 59 5f 43 41 4e 54 49 4e 49 54  EADONLY_CANTINIT
15d70 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66 20 74  ..  **.  ** If t
15d80 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79  he shared-memory
15d90 20 69 73 20 6e 6f 77 20 22 72 65 6c 69 61 62 6c   is now "reliabl
15da0 65 22 20 72 65 74 75 72 6e 20 57 41 4c 5f 52 45  e" return WAL_RE
15db0 54 52 59 2c 20 77 68 69 63 68 20 77 69 6c 6c 0a  TRY, which will.
15dc0 20 20 2a 2a 20 63 61 75 73 65 20 74 68 65 20 68    ** cause the h
15dd0 65 61 70 2d 6d 65 6d 6f 72 79 20 57 41 4c 2d 69  eap-memory WAL-i
15de0 6e 64 65 78 20 74 6f 20 62 65 20 64 69 73 63 61  ndex to be disca
15df0 72 64 65 64 20 61 6e 64 20 74 68 65 20 61 63 74  rded and the act
15e00 75 61 6c 0a 20 20 2a 2a 20 73 68 61 72 65 64 20  ual.  ** shared 
15e10 6d 65 6d 6f 72 79 20 74 6f 20 62 65 20 75 73 65  memory to be use
15e20 64 20 69 6e 20 69 74 73 20 70 6c 61 63 65 2e 0a  d in its place..
15e30 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 69 73 20 73    **.  ** This s
15e40 74 65 70 20 69 73 20 69 6d 70 6f 72 74 61 6e 74  tep is important
15e50 20 62 65 63 61 75 73 65 2c 20 65 76 65 6e 20 74   because, even t
15e60 68 6f 75 67 68 20 74 68 69 73 20 63 6f 6e 6e 65  hough this conne
15e70 63 74 69 6f 6e 20 69 73 20 68 6f 6c 64 69 6e 67  ction is holding
15e80 0a 20 20 2a 2a 20 74 68 65 20 57 41 4c 5f 52 45  .  ** the WAL_RE
15e90 41 44 5f 4c 4f 43 4b 28 30 29 20 77 68 69 63 68  AD_LOCK(0) which
15ea0 20 70 72 65 76 65 6e 74 73 20 61 20 63 68 65 63   prevents a chec
15eb0 6b 70 6f 69 6e 74 2c 20 61 20 77 72 69 74 65 72  kpoint, a writer
15ec0 20 6d 69 67 68 74 0a 20 20 2a 2a 20 68 61 76 65   might.  ** have
15ed0 20 61 6c 72 65 61 64 79 20 63 68 65 63 6b 70 6f   already checkpo
15ee0 69 6e 74 65 64 20 74 68 65 20 57 41 4c 20 66 69  inted the WAL fi
15ef0 6c 65 20 61 6e 64 2c 20 77 68 69 6c 65 20 74 68  le and, while th
15f00 65 20 63 75 72 72 65 6e 74 0a 20 20 2a 2a 20 69  e current.  ** i
15f10 73 20 61 63 74 69 76 65 2c 20 77 72 61 70 20 74  s active, wrap t
15f20 68 65 20 57 41 4c 20 61 6e 64 20 73 74 61 72 74  he WAL and start
15f30 20 6f 76 65 72 77 72 69 74 69 6e 67 20 66 72 61   overwriting fra
15f40 6d 65 73 20 74 68 61 74 20 74 68 69 73 0a 20 20  mes that this.  
15f50 2a 2a 20 70 72 6f 63 65 73 73 20 77 61 6e 74 73  ** process wants
15f60 20 74 6f 20 75 73 65 2e 0a 20 20 2a 2a 0a 20 20   to use..  **.  
15f70 2a 2a 20 4f 6e 63 65 20 73 71 6c 69 74 65 33 4f  ** Once sqlite3O
15f80 73 53 68 6d 4d 61 70 28 29 20 68 61 73 20 62 65  sShmMap() has be
15f90 65 6e 20 63 61 6c 6c 65 64 20 66 6f 72 20 61 6e  en called for an
15fa0 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 61 6e   sqlite3_file an
15fb0 64 20 68 61 73 0a 20 20 2a 2a 20 72 65 74 75 72  d has.  ** retur
15fc0 6e 65 64 20 61 6e 79 20 53 51 4c 49 54 45 5f 52  ned any SQLITE_R
15fd0 45 41 44 4f 4e 4c 59 20 76 61 6c 75 65 2c 20 69  EADONLY value, i
15fe0 74 20 6d 75 73 74 20 72 65 74 75 72 6e 20 6f 6e  t must return on
15ff0 6c 79 20 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e  ly SQLITE_READON
16000 4c 59 0a 20 20 2a 2a 20 6f 72 20 53 51 4c 49 54  LY.  ** or SQLIT
16010 45 5f 52 45 41 44 4f 4e 4c 59 5f 43 41 4e 54 49  E_READONLY_CANTI
16020 4e 49 54 20 6f 72 20 73 6f 6d 65 20 65 72 72 6f  NIT or some erro
16030 72 20 66 6f 72 20 61 6c 6c 20 73 75 62 73 65 71  r for all subseq
16040 75 65 6e 74 20 69 6e 76 6f 63 61 74 69 6f 6e 73  uent invocations
16050 2c 0a 20 20 2a 2a 20 65 76 65 6e 20 69 66 20 73  ,.  ** even if s
16060 6f 6d 65 20 65 78 74 65 72 6e 61 6c 20 61 67 65  ome external age
16070 6e 74 20 64 6f 65 73 20 61 20 22 63 68 6d 6f 64  nt does a "chmod
16080 22 20 74 6f 20 6d 61 6b 65 20 74 68 65 20 73 68  " to make the sh
16090 61 72 65 64 2d 6d 65 6d 6f 72 79 0a 20 20 2a 2a  ared-memory.  **
160a0 20 77 72 69 74 61 62 6c 65 20 62 79 20 75 73 2c   writable by us,
160b0 20 75 6e 74 69 6c 20 73 71 6c 69 74 65 33 4f 73   until sqlite3Os
160c0 53 68 6d 55 6e 6d 61 70 28 29 20 68 61 73 20 62  ShmUnmap() has b
160d0 65 65 6e 20 63 61 6c 6c 65 64 2e 0a 20 20 2a 2a  een called..  **
160e0 20 54 68 69 73 20 69 73 20 61 20 72 65 71 75 69   This is a requi
160f0 72 65 6d 65 6e 74 20 6f 6e 20 74 68 65 20 56 46  rement on the VF
16100 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  S implementation
16110 2e 0a 20 20 20 2a 2f 0a 20 20 72 63 20 3d 20 73  ..   */.  rc = s
16120 71 6c 69 74 65 33 4f 73 53 68 6d 4d 61 70 28 70  qlite3OsShmMap(p
16130 57 61 6c 2d 3e 70 44 62 46 64 2c 20 30 2c 20 57  Wal->pDbFd, 0, W
16140 41 4c 49 4e 44 45 58 5f 50 47 53 5a 2c 20 30 2c  ALINDEX_PGSZ, 0,
16150 20 26 70 44 75 6d 6d 79 29 3b 0a 20 20 61 73 73   &pDummy);.  ass
16160 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f  ert( rc!=SQLITE_
16170 4f 4b 20 29 3b 20 2f 2a 20 53 51 4c 49 54 45 5f  OK ); /* SQLITE_
16180 4f 4b 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20  OK not possible 
16190 66 6f 72 20 72 65 61 64 2d 6f 6e 6c 79 20 63 6f  for read-only co
161a0 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 66  nnection */.  if
161b0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 45 41  ( rc!=SQLITE_REA
161c0 44 4f 4e 4c 59 5f 43 41 4e 54 49 4e 49 54 20 29  DONLY_CANTINIT )
161d0 7b 0a 20 20 20 20 72 63 20 3d 20 28 72 63 3d 3d  {.    rc = (rc==
161e0 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 20  SQLITE_READONLY 
161f0 3f 20 57 41 4c 5f 52 45 54 52 59 20 3a 20 72 63  ? WAL_RETRY : rc
16200 29 3b 0a 20 20 20 20 67 6f 74 6f 20 62 65 67 69  );.    goto begi
16210 6e 5f 75 6e 72 65 6c 69 61 62 6c 65 5f 73 68 6d  n_unreliable_shm
16220 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  _out;.  }..  /* 
16230 57 65 20 72 65 61 63 68 20 74 68 69 73 20 70 6f  We reach this po
16240 69 6e 74 20 6f 6e 6c 79 20 69 66 20 74 68 65 20  int only if the 
16250 72 65 61 6c 20 73 68 61 72 65 64 2d 6d 65 6d 6f  real shared-memo
16260 72 79 20 69 73 20 73 74 69 6c 6c 20 75 6e 72 65  ry is still unre
16270 6c 69 61 62 6c 65 2e 0a 20 20 2a 2a 20 41 73 73  liable..  ** Ass
16280 75 6d 65 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72  ume the in-memor
16290 79 20 57 41 4c 2d 69 6e 64 65 78 20 73 75 62 73  y WAL-index subs
162a0 74 69 74 75 74 65 20 69 73 20 63 6f 72 72 65 63  titute is correc
162b0 74 20 61 6e 64 20 6c 6f 61 64 20 69 74 0a 20 20  t and load it.  
162c0 2a 2a 20 69 6e 74 6f 20 70 57 61 6c 2d 3e 68 64  ** into pWal->hd
162d0 72 2e 0a 20 20 2a 2f 0a 20 20 6d 65 6d 63 70 79  r..  */.  memcpy
162e0 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76 6f  (&pWal->hdr, (vo
162f0 69 64 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28  id*)walIndexHdr(
16300 70 57 61 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61  pWal), sizeof(Wa
16310 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 0a 20 20  lIndexHdr));..  
16320 2f 2a 20 4d 61 6b 65 20 73 75 72 65 20 73 6f 6d  /* Make sure som
16330 65 20 77 72 69 74 65 72 20 68 61 73 6e 27 74 20  e writer hasn't 
16340 63 6f 6d 65 20 69 6e 20 61 6e 64 20 63 68 61 6e  come in and chan
16350 67 65 64 20 74 68 65 20 57 41 4c 20 66 69 6c 65  ged the WAL file
16360 20 6f 75 74 0a 20 20 2a 2a 20 66 72 6f 6d 20 75   out.  ** from u
16370 6e 64 65 72 20 75 73 2c 20 74 68 65 6e 20 64 69  nder us, then di
16380 73 63 6f 6e 6e 65 63 74 65 64 2c 20 77 68 69 6c  sconnected, whil
16390 65 20 77 65 20 77 65 72 65 20 6e 6f 74 20 6c 6f  e we were not lo
163a0 6f 6b 69 6e 67 2e 0a 20 20 2a 2f 0a 20 20 72 63  oking..  */.  rc
163b0 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65   = sqlite3OsFile
163c0 53 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46  Size(pWal->pWalF
163d0 64 2c 20 26 73 7a 57 61 6c 29 3b 0a 20 20 69 66  d, &szWal);.  if
163e0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
163f0 29 7b 0a 20 20 20 20 67 6f 74 6f 20 62 65 67 69  ){.    goto begi
16400 6e 5f 75 6e 72 65 6c 69 61 62 6c 65 5f 73 68 6d  n_unreliable_shm
16410 5f 6f 75 74 3b 0a 20 20 7d 0a 20 20 69 66 28 20  _out;.  }.  if( 
16420 73 7a 57 61 6c 3c 57 41 4c 5f 48 44 52 53 49 5a  szWal<WAL_HDRSIZ
16430 45 20 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 74  E ){.    /* If t
16440 68 65 20 77 61 6c 20 66 69 6c 65 20 69 73 20 74  he wal file is t
16450 6f 6f 20 73 6d 61 6c 6c 20 74 6f 20 63 6f 6e 74  oo small to cont
16460 61 69 6e 20 61 20 77 61 6c 2d 68 65 61 64 65 72  ain a wal-header
16470 20 61 6e 64 20 74 68 65 0a 20 20 20 20 2a 2a 20   and the.    ** 
16480 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
16490 20 68 61 73 20 6d 78 46 72 61 6d 65 3d 3d 30 2c   has mxFrame==0,
164a0 20 74 68 65 6e 20 69 74 20 6d 75 73 74 20 62 65   then it must be
164b0 20 73 61 66 65 20 74 6f 20 70 72 6f 63 65 65 64   safe to proceed
164c0 0a 20 20 20 20 2a 2a 20 72 65 61 64 69 6e 67 20  .    ** reading 
164d0 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
164e0 65 20 6f 6e 6c 79 2e 20 48 6f 77 65 76 65 72 2c  e only. However,
164f0 20 74 68 65 20 70 61 67 65 20 63 61 63 68 65 20   the page cache 
16500 63 61 6e 6e 6f 74 0a 20 20 20 20 2a 2a 20 62 65  cannot.    ** be
16510 20 74 72 75 73 74 65 64 2c 20 61 73 20 61 20 72   trusted, as a r
16520 65 61 64 2f 77 72 69 74 65 20 63 6f 6e 6e 65 63  ead/write connec
16530 74 69 6f 6e 20 6d 61 79 20 68 61 76 65 20 63 6f  tion may have co
16540 6e 6e 65 63 74 65 64 2c 20 77 72 69 74 74 65 6e  nnected, written
16550 0a 20 20 20 20 2a 2a 20 74 68 65 20 64 62 2c 20  .    ** the db, 
16560 72 75 6e 20 61 20 63 68 65 63 6b 70 6f 69 6e 74  run a checkpoint
16570 2c 20 74 72 75 6e 63 61 74 65 64 20 74 68 65 20  , truncated the 
16580 77 61 6c 20 66 69 6c 65 20 61 6e 64 20 64 69 73  wal file and dis
16590 63 6f 6e 6e 65 63 74 65 64 0a 20 20 20 20 2a 2a  connected.    **
165a0 20 73 69 6e 63 65 20 74 68 69 73 20 63 6c 69 65   since this clie
165b0 6e 74 27 73 20 6c 61 73 74 20 72 65 61 64 20 74  nt's last read t
165c0 72 61 6e 73 61 63 74 69 6f 6e 2e 20 20 2a 2f 0a  ransaction.  */.
165d0 20 20 20 20 2a 70 43 68 61 6e 67 65 64 20 3d 20      *pChanged = 
165e0 31 3b 0a 20 20 20 20 72 63 20 3d 20 28 70 57 61  1;.    rc = (pWa
165f0 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d  l->hdr.mxFrame==
16600 30 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20  0 ? SQLITE_OK : 
16610 57 41 4c 5f 52 45 54 52 59 29 3b 0a 20 20 20 20  WAL_RETRY);.    
16620 67 6f 74 6f 20 62 65 67 69 6e 5f 75 6e 72 65 6c  goto begin_unrel
16630 69 61 62 6c 65 5f 73 68 6d 5f 6f 75 74 3b 0a 20  iable_shm_out;. 
16640 20 7d 0a 0a 20 20 2f 2a 20 43 68 65 63 6b 20 74   }..  /* Check t
16650 68 65 20 73 61 6c 74 20 6b 65 79 73 20 61 74 20  he salt keys at 
16660 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
16670 20 77 61 6c 20 66 69 6c 65 20 73 74 69 6c 6c 20   wal file still 
16680 6d 61 74 63 68 2e 20 2a 2f 0a 20 20 72 63 20 3d  match. */.  rc =
16690 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70   sqlite3OsRead(p
166a0 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 42 75  Wal->pWalFd, aBu
166b0 66 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2c 20  f, WAL_HDRSIZE, 
166c0 30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  0);.  if( rc!=SQ
166d0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 67  LITE_OK ){.    g
166e0 6f 74 6f 20 62 65 67 69 6e 5f 75 6e 72 65 6c 69  oto begin_unreli
166f0 61 62 6c 65 5f 73 68 6d 5f 6f 75 74 3b 0a 20 20  able_shm_out;.  
16700 7d 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26  }.  if( memcmp(&
16710 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c  pWal->hdr.aSalt,
16720 20 26 61 42 75 66 5b 31 36 5d 2c 20 38 29 20 29   &aBuf[16], 8) )
16730 7b 0a 20 20 20 20 2f 2a 20 53 6f 6d 65 20 77 72  {.    /* Some wr
16740 69 74 65 72 20 68 61 73 20 77 72 61 70 70 65 64  iter has wrapped
16750 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20 77 68   the WAL file wh
16760 69 6c 65 20 77 65 20 77 65 72 65 20 6e 6f 74 20  ile we were not 
16770 6c 6f 6f 6b 69 6e 67 2e 0a 20 20 20 20 2a 2a 20  looking..    ** 
16780 52 65 74 75 72 6e 20 57 41 4c 5f 52 45 54 52 59  Return WAL_RETRY
16790 20 77 68 69 63 68 20 77 69 6c 6c 20 63 61 75 73   which will caus
167a0 65 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  e the in-memory 
167b0 57 41 4c 2d 69 6e 64 65 78 20 74 6f 20 62 65 0a  WAL-index to be.
167c0 20 20 20 20 2a 2a 20 72 65 62 75 69 6c 74 2e 20      ** rebuilt. 
167d0 2a 2f 0a 20 20 20 20 72 63 20 3d 20 57 41 4c 5f  */.    rc = WAL_
167e0 52 45 54 52 59 3b 0a 20 20 20 20 67 6f 74 6f 20  RETRY;.    goto 
167f0 62 65 67 69 6e 5f 75 6e 72 65 6c 69 61 62 6c 65  begin_unreliable
16800 5f 73 68 6d 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20  _shm_out;.  }.. 
16810 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 62   /* Allocate a b
16820 75 66 66 65 72 20 74 6f 20 72 65 61 64 20 66 72  uffer to read fr
16830 61 6d 65 73 20 69 6e 74 6f 20 2a 2f 0a 20 20 73  ames into */.  s
16840 7a 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68  zFrame = pWal->h
16850 64 72 2e 73 7a 50 61 67 65 20 2b 20 57 41 4c 5f  dr.szPage + WAL_
16860 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20  FRAME_HDRSIZE;. 
16870 20 61 46 72 61 6d 65 20 3d 20 28 75 38 20 2a 29   aFrame = (u8 *)
16880 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34  sqlite3_malloc64
16890 28 73 7a 46 72 61 6d 65 29 3b 0a 20 20 69 66 28  (szFrame);.  if(
168a0 20 61 46 72 61 6d 65 3d 3d 30 20 29 7b 0a 20 20   aFrame==0 ){.  
168b0 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
168c0 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20 20 20 67 6f  MEM_BKPT;.    go
168d0 74 6f 20 62 65 67 69 6e 5f 75 6e 72 65 6c 69 61  to begin_unrelia
168e0 62 6c 65 5f 73 68 6d 5f 6f 75 74 3b 0a 20 20 7d  ble_shm_out;.  }
168f0 0a 20 20 61 44 61 74 61 20 3d 20 26 61 46 72 61  .  aData = &aFra
16900 6d 65 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52  me[WAL_FRAME_HDR
16910 53 49 5a 45 5d 3b 0a 0a 20 20 2f 2a 20 43 68 65  SIZE];..  /* Che
16920 63 6b 20 74 6f 20 73 65 65 20 69 66 20 61 20 63  ck to see if a c
16930 6f 6d 70 6c 65 74 65 20 74 72 61 6e 73 61 63 74  omplete transact
16940 69 6f 6e 20 68 61 73 20 62 65 65 6e 20 61 70 70  ion has been app
16950 65 6e 64 65 64 20 74 6f 20 74 68 65 0a 20 20 2a  ended to the.  *
16960 2a 20 77 61 6c 20 66 69 6c 65 20 73 69 6e 63 65  * wal file since
16970 20 74 68 65 20 68 65 61 70 2d 6d 65 6d 6f 72 79   the heap-memory
16980 20 77 61 6c 2d 69 6e 64 65 78 20 77 61 73 20 63   wal-index was c
16990 72 65 61 74 65 64 2e 20 49 66 20 73 6f 2c 20 74  reated. If so, t
169a0 68 65 0a 20 20 2a 2a 20 68 65 61 70 2d 6d 65 6d  he.  ** heap-mem
169b0 6f 72 79 20 77 61 6c 2d 69 6e 64 65 78 20 69 73  ory wal-index is
169c0 20 64 69 73 63 61 72 64 65 64 20 61 6e 64 20 57   discarded and W
169d0 41 4c 5f 52 45 54 52 59 20 72 65 74 75 72 6e 65  AL_RETRY returne
169e0 64 20 74 6f 0a 20 20 2a 2a 20 74 68 65 20 63 61  d to.  ** the ca
169f0 6c 6c 65 72 2e 20 20 2a 2f 0a 20 20 61 53 61 76  ller.  */.  aSav
16a00 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 70 57 61 6c  eCksum[0] = pWal
16a10 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
16a20 6d 5b 30 5d 3b 0a 20 20 61 53 61 76 65 43 6b 73  m[0];.  aSaveCks
16a30 75 6d 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64  um[1] = pWal->hd
16a40 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d  r.aFrameCksum[1]
16a50 3b 0a 20 20 66 6f 72 28 69 4f 66 66 73 65 74 3d  ;.  for(iOffset=
16a60 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 70  walFrameOffset(p
16a70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
16a80 2b 31 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a  +1, pWal->hdr.sz
16a90 50 61 67 65 29 3b 20 0a 20 20 20 20 20 20 69 4f  Page); .      iO
16aa0 66 66 73 65 74 2b 73 7a 46 72 61 6d 65 3c 3d 73  ffset+szFrame<=s
16ab0 7a 57 61 6c 3b 20 0a 20 20 20 20 20 20 69 4f 66  zWal; .      iOf
16ac0 66 73 65 74 2b 3d 73 7a 46 72 61 6d 65 0a 20 20  fset+=szFrame.  
16ad0 29 7b 0a 20 20 20 20 75 33 32 20 70 67 6e 6f 3b  ){.    u32 pgno;
16ae0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16af0 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 70     /* Database p
16b00 61 67 65 20 6e 75 6d 62 65 72 20 66 6f 72 20 66  age number for f
16b10 72 61 6d 65 20 2a 2f 0a 20 20 20 20 75 33 32 20  rame */.    u32 
16b20 6e 54 72 75 6e 63 61 74 65 3b 20 20 20 20 20 20  nTruncate;      
16b30 20 20 20 20 20 20 20 20 2f 2a 20 64 62 73 69 7a          /* dbsiz
16b40 65 20 66 69 65 6c 64 20 66 72 6f 6d 20 66 72 61  e field from fra
16b50 6d 65 20 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20  me header */..  
16b60 20 20 2f 2a 20 52 65 61 64 20 61 6e 64 20 64 65    /* Read and de
16b70 63 6f 64 65 20 74 68 65 20 6e 65 78 74 20 6c 6f  code the next lo
16b80 67 20 66 72 61 6d 65 2e 20 2a 2f 0a 20 20 20 20  g frame. */.    
16b90 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65  rc = sqlite3OsRe
16ba0 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  ad(pWal->pWalFd,
16bb0 20 61 46 72 61 6d 65 2c 20 73 7a 46 72 61 6d 65   aFrame, szFrame
16bc0 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20  , iOffset);.    
16bd0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
16be0 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 69  K ) break;.    i
16bf0 66 28 20 21 77 61 6c 44 65 63 6f 64 65 46 72 61  f( !walDecodeFra
16c00 6d 65 28 70 57 61 6c 2c 20 26 70 67 6e 6f 2c 20  me(pWal, &pgno, 
16c10 26 6e 54 72 75 6e 63 61 74 65 2c 20 61 44 61 74  &nTruncate, aDat
16c20 61 2c 20 61 46 72 61 6d 65 29 20 29 20 62 72 65  a, aFrame) ) bre
16c30 61 6b 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 6e  ak;..    /* If n
16c40 54 72 75 6e 63 61 74 65 20 69 73 20 6e 6f 6e 2d  Truncate is non-
16c50 7a 65 72 6f 2c 20 74 68 65 6e 20 61 20 63 6f 6d  zero, then a com
16c60 70 6c 65 74 65 20 74 72 61 6e 73 61 63 74 69 6f  plete transactio
16c70 6e 20 68 61 73 20 62 65 65 6e 0a 20 20 20 20 2a  n has been.    *
16c80 2a 20 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68  * appended to th
16c90 69 73 20 77 61 6c 20 66 69 6c 65 2e 20 53 65 74  is wal file. Set
16ca0 20 72 63 20 74 6f 20 57 41 4c 5f 52 45 54 52 59   rc to WAL_RETRY
16cb0 20 61 6e 64 20 62 72 65 61 6b 20 6f 75 74 20 6f   and break out o
16cc0 66 0a 20 20 20 20 2a 2a 20 74 68 65 20 6c 6f 6f  f.    ** the loo
16cd0 70 2e 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 6e  p.  */.    if( n
16ce0 54 72 75 6e 63 61 74 65 20 29 7b 0a 20 20 20 20  Truncate ){.    
16cf0 20 20 72 63 20 3d 20 57 41 4c 5f 52 45 54 52 59    rc = WAL_RETRY
16d00 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
16d10 20 20 20 7d 0a 20 20 7d 0a 20 20 70 57 61 6c 2d     }.  }.  pWal-
16d20 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
16d30 5b 30 5d 20 3d 20 61 53 61 76 65 43 6b 73 75 6d  [0] = aSaveCksum
16d40 5b 30 5d 3b 0a 20 20 70 57 61 6c 2d 3e 68 64 72  [0];.  pWal->hdr
16d50 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20  .aFrameCksum[1] 
16d60 3d 20 61 53 61 76 65 43 6b 73 75 6d 5b 31 5d 3b  = aSaveCksum[1];
16d70 0a 0a 20 62 65 67 69 6e 5f 75 6e 72 65 6c 69 61  .. begin_unrelia
16d80 62 6c 65 5f 73 68 6d 5f 6f 75 74 3a 0a 20 20 73  ble_shm_out:.  s
16d90 71 6c 69 74 65 33 5f 66 72 65 65 28 61 46 72 61  qlite3_free(aFra
16da0 6d 65 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  me);.  if( rc!=S
16db0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
16dc0 69 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69  int i;.    for(i
16dd0 3d 30 3b 20 69 3c 70 57 61 6c 2d 3e 6e 57 69 44  =0; i<pWal->nWiD
16de0 61 74 61 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  ata; i++){.     
16df0 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 28 76   sqlite3_free((v
16e00 6f 69 64 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44  oid*)pWal->apWiD
16e10 61 74 61 5b 69 5d 29 3b 0a 20 20 20 20 20 20 70  ata[i]);.      p
16e20 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 5d  Wal->apWiData[i]
16e30 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20   = 0;.    }.    
16e40 70 57 61 6c 2d 3e 62 53 68 6d 55 6e 72 65 6c 69  pWal->bShmUnreli
16e50 61 62 6c 65 20 3d 20 30 3b 0a 20 20 20 20 73 71  able = 0;.    sq
16e60 6c 69 74 65 33 57 61 6c 45 6e 64 52 65 61 64 54  lite3WalEndReadT
16e70 72 61 6e 73 61 63 74 69 6f 6e 28 70 57 61 6c 29  ransaction(pWal)
16e80 3b 0a 20 20 20 20 2a 70 43 68 61 6e 67 65 64 20  ;.    *pChanged 
16e90 3d 20 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  = 1;.  }.  retur
16ea0 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
16eb0 74 74 65 6d 70 74 20 74 6f 20 73 74 61 72 74 20  ttempt to start 
16ec0 61 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  a read transacti
16ed0 6f 6e 2e 20 20 54 68 69 73 20 6d 69 67 68 74 20  on.  This might 
16ee0 66 61 69 6c 20 64 75 65 20 74 6f 20 61 20 72 61  fail due to a ra
16ef0 63 65 20 6f 72 0a 2a 2a 20 6f 74 68 65 72 20 74  ce or.** other t
16f00 72 61 6e 73 69 65 6e 74 20 63 6f 6e 64 69 74 69  ransient conditi
16f10 6f 6e 2e 20 20 57 68 65 6e 20 74 68 61 74 20 68  on.  When that h
16f20 61 70 70 65 6e 73 2c 20 69 74 20 72 65 74 75 72  appens, it retur
16f30 6e 73 20 57 41 4c 5f 52 45 54 52 59 20 74 6f 0a  ns WAL_RETRY to.
16f40 2a 2a 20 69 6e 64 69 63 61 74 65 20 74 6f 20 74  ** indicate to t
16f50 68 65 20 63 61 6c 6c 65 72 20 74 68 61 74 20 69  he caller that i
16f60 74 20 69 73 20 73 61 66 65 20 74 6f 20 72 65 74  t is safe to ret
16f70 72 79 20 69 6d 6d 65 64 69 61 74 65 6c 79 2e 0a  ry immediately..
16f80 2a 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63 65 73 73  **.** On success
16f90 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
16fa0 4b 2e 20 20 4f 6e 20 61 20 70 65 72 6d 61 6e 65  K.  On a permane
16fb0 6e 74 20 66 61 69 6c 75 72 65 20 28 73 75 63 68  nt failure (such
16fc0 20 61 6e 0a 2a 2a 20 49 2f 4f 20 65 72 72 6f 72   an.** I/O error
16fd0 20 6f 72 20 61 6e 20 53 51 4c 49 54 45 5f 42 55   or an SQLITE_BU
16fe0 53 59 20 62 65 63 61 75 73 65 20 61 6e 6f 74 68  SY because anoth
16ff0 65 72 20 70 72 6f 63 65 73 73 20 69 73 20 72 75  er process is ru
17000 6e 6e 69 6e 67 0a 2a 2a 20 72 65 63 6f 76 65 72  nning.** recover
17010 79 29 20 72 65 74 75 72 6e 20 61 20 70 6f 73 69  y) return a posi
17020 74 69 76 65 20 65 72 72 6f 72 20 63 6f 64 65 2e  tive error code.
17030 0a 2a 2a 0a 2a 2a 20 54 68 65 20 75 73 65 57 61  .**.** The useWa
17040 6c 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 74  l parameter is t
17050 72 75 65 20 74 6f 20 66 6f 72 63 65 20 74 68 65  rue to force the
17060 20 75 73 65 20 6f 66 20 74 68 65 20 57 41 4c 20   use of the WAL 
17070 61 6e 64 20 64 69 73 61 62 6c 65 0a 2a 2a 20 74  and disable.** t
17080 68 65 20 63 61 73 65 20 77 68 65 72 65 20 74 68  he case where th
17090 65 20 57 41 4c 20 69 73 20 62 79 70 61 73 73 65  e WAL is bypasse
170a0 64 20 62 65 63 61 75 73 65 20 69 74 20 68 61 73  d because it has
170b0 20 62 65 65 6e 20 63 6f 6d 70 6c 65 74 65 6c 79   been completely
170c0 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 65 64  .** checkpointed
170d0 2e 20 20 49 66 20 75 73 65 57 61 6c 3d 3d 30 20  .  If useWal==0 
170e0 74 68 65 6e 20 74 68 69 73 20 72 6f 75 74 69 6e  then this routin
170f0 65 20 63 61 6c 6c 73 20 77 61 6c 49 6e 64 65 78  e calls walIndex
17100 52 65 61 64 48 64 72 28 29 20 0a 2a 2a 20 74 6f  ReadHdr() .** to
17110 20 6d 61 6b 65 20 61 20 63 6f 70 79 20 6f 66 20   make a copy of 
17120 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
17130 61 64 65 72 20 69 6e 74 6f 20 70 57 61 6c 2d 3e  ader into pWal->
17140 68 64 72 2e 20 20 49 66 20 74 68 65 20 0a 2a 2a  hdr.  If the .**
17150 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
17160 72 20 68 61 73 20 63 68 61 6e 67 65 64 2c 20 2a  r has changed, *
17170 70 43 68 61 6e 67 65 64 20 69 73 20 73 65 74 20  pChanged is set 
17180 74 6f 20 31 20 28 61 73 20 61 6e 20 69 6e 64 69  to 1 (as an indi
17190 63 61 74 69 6f 6e 20 0a 2a 2a 20 74 6f 20 74 68  cation .** to th
171a0 65 20 63 61 6c 6c 65 72 20 74 68 61 74 20 74 68  e caller that th
171b0 65 20 6c 6f 63 61 6c 20 70 61 67 65 20 63 61 63  e local page cac
171c0 68 65 20 69 73 20 6f 62 73 6f 6c 65 74 65 20 61  he is obsolete a
171d0 6e 64 20 6e 65 65 64 73 20 74 6f 20 62 65 20 0a  nd needs to be .
171e0 2a 2a 20 66 6c 75 73 68 65 64 2e 29 20 20 57 68  ** flushed.)  Wh
171f0 65 6e 20 75 73 65 57 61 6c 3d 3d 31 2c 20 74 68  en useWal==1, th
17200 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
17210 65 72 20 69 73 20 61 73 73 75 6d 65 64 20 74 6f  er is assumed to
17220 20 61 6c 72 65 61 64 79 0a 2a 2a 20 62 65 20 6c   already.** be l
17230 6f 61 64 65 64 20 61 6e 64 20 74 68 65 20 70 43  oaded and the pC
17240 68 61 6e 67 65 64 20 70 61 72 61 6d 65 74 65 72  hanged parameter
17250 20 69 73 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a   is unused..**.*
17260 2a 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  * The caller mus
17270 74 20 73 65 74 20 74 68 65 20 63 6e 74 20 70 61  t set the cnt pa
17280 72 61 6d 65 74 65 72 20 74 6f 20 74 68 65 20 6e  rameter to the n
17290 75 6d 62 65 72 20 6f 66 20 70 72 69 6f 72 20 63  umber of prior c
172a0 61 6c 6c 73 20 74 6f 0a 2a 2a 20 74 68 69 73 20  alls to.** this 
172b0 72 6f 75 74 69 6e 65 20 64 75 72 69 6e 67 20 74  routine during t
172c0 68 65 20 63 75 72 72 65 6e 74 20 72 65 61 64 20  he current read 
172d0 61 74 74 65 6d 70 74 20 74 68 61 74 20 72 65 74  attempt that ret
172e0 75 72 6e 65 64 20 57 41 4c 5f 52 45 54 52 59 2e  urned WAL_RETRY.
172f0 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
17300 20 77 69 6c 6c 20 73 74 61 72 74 20 74 61 6b 69   will start taki
17310 6e 67 20 6d 6f 72 65 20 61 67 67 72 65 73 73 69  ng more aggressi
17320 76 65 20 6d 65 61 73 75 72 65 73 20 74 6f 20 63  ve measures to c
17330 6c 65 61 72 20 74 68 65 0a 2a 2a 20 72 61 63 65  lear the.** race
17340 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61 66 74 65   conditions afte
17350 72 20 6d 75 6c 74 69 70 6c 65 20 57 41 4c 5f 52  r multiple WAL_R
17360 45 54 52 59 20 72 65 74 75 72 6e 73 2c 20 61 6e  ETRY returns, an
17370 64 20 61 66 74 65 72 20 61 6e 20 65 78 63 65 73  d after an exces
17380 73 69 76 65 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f  sive.** number o
17390 66 20 65 72 72 6f 72 73 20 77 69 6c 6c 20 75 6c  f errors will ul
173a0 74 69 6d 61 74 65 6c 79 20 72 65 74 75 72 6e 20  timately return 
173b0 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 2e  SQLITE_PROTOCOL.
173c0 20 20 54 68 65 0a 2a 2a 20 53 51 4c 49 54 45 5f    The.** SQLITE_
173d0 50 52 4f 54 4f 43 4f 4c 20 72 65 74 75 72 6e 20  PROTOCOL return 
173e0 69 6e 64 69 63 61 74 65 73 20 74 68 61 74 20 73  indicates that s
173f0 6f 6d 65 20 6f 74 68 65 72 20 70 72 6f 63 65 73  ome other proces
17400 73 20 68 61 73 20 67 6f 6e 65 20 72 6f 67 75 65  s has gone rogue
17410 0a 2a 2a 20 61 6e 64 20 69 73 20 6e 6f 74 20 68  .** and is not h
17420 6f 6e 6f 72 69 6e 67 20 74 68 65 20 6c 6f 63 6b  onoring the lock
17430 69 6e 67 20 70 72 6f 74 6f 63 6f 6c 2e 20 20 54  ing protocol.  T
17440 68 65 72 65 20 69 73 20 61 20 76 61 6e 69 73 68  here is a vanish
17450 69 6e 67 6c 79 20 73 6d 61 6c 6c 0a 2a 2a 20 63  ingly small.** c
17460 68 61 6e 63 65 20 74 68 61 74 20 53 51 4c 49 54  hance that SQLIT
17470 45 5f 50 52 4f 54 4f 43 4f 4c 20 63 6f 75 6c 64  E_PROTOCOL could
17480 20 62 65 20 72 65 74 75 72 6e 65 64 20 62 65 63   be returned bec
17490 61 75 73 65 20 6f 66 20 61 20 72 75 6e 20 6f 66  ause of a run of
174a0 20 72 65 61 6c 6c 79 0a 2a 2a 20 62 61 64 20 6c   really.** bad l
174b0 75 63 6b 20 77 68 65 6e 20 74 68 65 72 65 20 69  uck when there i
174c0 73 20 6c 6f 74 73 20 6f 66 20 63 6f 6e 74 65 6e  s lots of conten
174d0 74 69 6f 6e 20 66 6f 72 20 74 68 65 20 77 61 6c  tion for the wal
174e0 2d 69 6e 64 65 78 2c 20 62 75 74 20 74 68 61 74  -index, but that
174f0 0a 2a 2a 20 70 6f 73 73 69 62 69 6c 69 74 79 20  .** possibility 
17500 69 73 20 73 6f 20 73 6d 61 6c 6c 20 74 68 61 74  is so small that
17510 20 69 74 20 63 61 6e 20 62 65 20 73 61 66 65 6c   it can be safel
17520 79 20 6e 65 67 6c 65 63 74 65 64 2c 20 77 65 20  y neglected, we 
17530 62 65 6c 69 65 76 65 2e 0a 2a 2a 0a 2a 2a 20 4f  believe..**.** O
17540 6e 20 73 75 63 63 65 73 73 2c 20 74 68 69 73 20  n success, this 
17550 72 6f 75 74 69 6e 65 20 6f 62 74 61 69 6e 73 20  routine obtains 
17560 61 20 72 65 61 64 20 6c 6f 63 6b 20 6f 6e 20 0a  a read lock on .
17570 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  ** WAL_READ_LOCK
17580 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29  (pWal->readLock)
17590 2e 20 20 54 68 65 20 70 57 61 6c 2d 3e 72 65 61  .  The pWal->rea
175a0 64 4c 6f 63 6b 20 69 6e 74 65 67 65 72 20 69 73  dLock integer is
175b0 0a 2a 2a 20 69 6e 20 74 68 65 20 72 61 6e 67 65  .** in the range
175c0 20 30 20 3c 3d 20 70 57 61 6c 2d 3e 72 65 61 64   0 <= pWal->read
175d0 4c 6f 63 6b 20 3c 20 57 41 4c 5f 4e 52 45 41 44  Lock < WAL_NREAD
175e0 45 52 2e 20 20 49 66 20 70 57 61 6c 2d 3e 72 65  ER.  If pWal->re
175f0 61 64 4c 6f 63 6b 3d 3d 28 2d 31 29 0a 2a 2a 20  adLock==(-1).** 
17600 74 68 61 74 20 6d 65 61 6e 73 20 74 68 65 20 57  that means the W
17610 61 6c 20 64 6f 65 73 20 6e 6f 74 20 68 6f 6c 64  al does not hold
17620 20 61 6e 79 20 72 65 61 64 20 6c 6f 63 6b 2e 20   any read lock. 
17630 20 54 68 65 20 72 65 61 64 65 72 20 6d 75 73 74   The reader must
17640 20 6e 6f 74 0a 2a 2a 20 61 63 63 65 73 73 20 61   not.** access a
17650 6e 79 20 64 61 74 61 62 61 73 65 20 70 61 67 65  ny database page
17660 20 74 68 61 74 20 69 73 20 6d 6f 64 69 66 69 65   that is modifie
17670 64 20 62 79 20 61 20 57 41 4c 20 66 72 61 6d 65  d by a WAL frame
17680 20 75 70 20 74 6f 20 61 6e 64 0a 2a 2a 20 69 6e   up to and.** in
17690 63 6c 75 64 69 6e 67 20 66 72 61 6d 65 20 6e 75  cluding frame nu
176a0 6d 62 65 72 20 61 52 65 61 64 4d 61 72 6b 5b 70  mber aReadMark[p
176b0 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 5d 2e 20  Wal->readLock]. 
176c0 20 54 68 65 20 72 65 61 64 65 72 20 77 69 6c 6c   The reader will
176d0 0a 2a 2a 20 75 73 65 20 57 41 4c 20 66 72 61 6d  .** use WAL fram
176e0 65 73 20 75 70 20 74 6f 20 61 6e 64 20 69 6e 63  es up to and inc
176f0 6c 75 64 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72  luding pWal->hdr
17700 2e 6d 78 46 72 61 6d 65 20 69 66 20 70 57 61 6c  .mxFrame if pWal
17710 2d 3e 72 65 61 64 4c 6f 63 6b 3e 30 0a 2a 2a 20  ->readLock>0.** 
17720 4f 72 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64  Or if pWal->read
17730 4c 6f 63 6b 3d 3d 30 2c 20 74 68 65 6e 20 74 68  Lock==0, then th
17740 65 20 72 65 61 64 65 72 20 77 69 6c 6c 20 69 67  e reader will ig
17750 6e 6f 72 65 20 74 68 65 20 57 41 4c 0a 2a 2a 20  nore the WAL.** 
17760 63 6f 6d 70 6c 65 74 65 6c 79 20 61 6e 64 20 67  completely and g
17770 65 74 20 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 64  et all content d
17780 69 72 65 63 74 6c 79 20 66 72 6f 6d 20 74 68 65  irectly from the
17790 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 0a   database file..
177a0 2a 2a 20 49 66 20 74 68 65 20 75 73 65 57 61 6c  ** If the useWal
177b0 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 31 20   parameter is 1 
177c0 74 68 65 6e 20 74 68 65 20 57 41 4c 20 77 69 6c  then the WAL wil
177d0 6c 20 6e 65 76 65 72 20 62 65 20 69 67 6e 6f 72  l never be ignor
177e0 65 64 20 61 6e 64 0a 2a 2a 20 74 68 69 73 20 72  ed and.** this r
177f0 6f 75 74 69 6e 65 20 77 69 6c 6c 20 61 6c 77 61  outine will alwa
17800 79 73 20 73 65 74 20 70 57 61 6c 2d 3e 72 65 61  ys set pWal->rea
17810 64 4c 6f 63 6b 3e 30 20 6f 6e 20 73 75 63 63 65  dLock>0 on succe
17820 73 73 2e 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20  ss..** When the 
17830 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
17840 20 69 73 20 63 6f 6d 70 6c 65 74 65 64 2c 20 74   is completed, t
17850 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 72  he caller must r
17860 65 6c 65 61 73 65 20 74 68 65 0a 2a 2a 20 6c 6f  elease the.** lo
17870 63 6b 20 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c  ck on WAL_READ_L
17880 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  OCK(pWal->readLo
17890 63 6b 29 20 61 6e 64 20 73 65 74 20 70 57 61 6c  ck) and set pWal
178a0 2d 3e 72 65 61 64 4c 6f 63 6b 20 74 6f 20 2d 31  ->readLock to -1
178b0 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ..**.** This rou
178c0 74 69 6e 65 20 75 73 65 73 20 74 68 65 20 6e 42  tine uses the nB
178d0 61 63 6b 66 69 6c 6c 20 61 6e 64 20 61 52 65 61  ackfill and aRea
178e0 64 4d 61 72 6b 5b 5d 20 66 69 65 6c 64 73 20 6f  dMark[] fields o
178f0 66 20 74 68 65 20 68 65 61 64 65 72 0a 2a 2a 20  f the header.** 
17900 74 6f 20 73 65 6c 65 63 74 20 61 20 70 61 72 74  to select a part
17910 69 63 75 6c 61 72 20 57 41 4c 5f 52 45 41 44 5f  icular WAL_READ_
17920 4c 4f 43 4b 28 29 20 74 68 61 74 20 73 74 72 69  LOCK() that stri
17930 76 65 73 20 74 6f 20 6c 65 74 20 74 68 65 0a 2a  ves to let the.*
17940 2a 20 63 68 65 63 6b 70 6f 69 6e 74 20 70 72 6f  * checkpoint pro
17950 63 65 73 73 20 64 6f 20 61 73 20 6d 75 63 68 20  cess do as much 
17960 77 6f 72 6b 20 61 73 20 70 6f 73 73 69 62 6c 65  work as possible
17970 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  .  This routine 
17980 6d 69 67 68 74 0a 2a 2a 20 75 70 64 61 74 65 20  might.** update 
17990 76 61 6c 75 65 73 20 6f 66 20 74 68 65 20 61 52  values of the aR
179a0 65 61 64 4d 61 72 6b 5b 5d 20 61 72 72 61 79 20  eadMark[] array 
179b0 69 6e 20 74 68 65 20 68 65 61 64 65 72 2c 20 62  in the header, b
179c0 75 74 20 69 66 20 69 74 20 64 6f 65 73 0a 2a 2a  ut if it does.**
179d0 20 73 6f 20 69 74 20 74 61 6b 65 73 20 63 61 72   so it takes car
179e0 65 20 74 6f 20 68 6f 6c 64 20 61 6e 20 65 78 63  e to hold an exc
179f0 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 74  lusive lock on t
17a00 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67  he corresponding
17a10 0a 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  .** WAL_READ_LOC
17a20 4b 28 29 20 77 68 69 6c 65 20 63 68 61 6e 67 69  K() while changi
17a30 6e 67 20 76 61 6c 75 65 73 2e 0a 2a 2f 0a 73 74  ng values..*/.st
17a40 61 74 69 63 20 69 6e 74 20 77 61 6c 54 72 79 42  atic int walTryB
17a50 65 67 69 6e 52 65 61 64 28 57 61 6c 20 2a 70 57  eginRead(Wal *pW
17a60 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e 67 65  al, int *pChange
17a70 64 2c 20 69 6e 74 20 75 73 65 57 61 6c 2c 20 69  d, int useWal, i
17a80 6e 74 20 63 6e 74 29 7b 0a 20 20 76 6f 6c 61 74  nt cnt){.  volat
17a90 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20  ile WalCkptInfo 
17aa0 2a 70 49 6e 66 6f 3b 20 20 20 20 2f 2a 20 43 68  *pInfo;    /* Ch
17ab0 65 63 6b 70 6f 69 6e 74 20 69 6e 66 6f 72 6d 61  eckpoint informa
17ac0 74 69 6f 6e 20 69 6e 20 77 61 6c 2d 69 6e 64 65  tion in wal-inde
17ad0 78 20 2a 2f 0a 20 20 75 33 32 20 6d 78 52 65 61  x */.  u32 mxRea
17ae0 64 4d 61 72 6b 3b 20 20 20 20 20 20 20 20 20 20  dMark;          
17af0 20 20 20 20 20 20 20 2f 2a 20 4c 61 72 67 65 73         /* Larges
17b00 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 76 61  t aReadMark[] va
17b10 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 49  lue */.  int mxI
17b20 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
17b30 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65           /* Inde
17b40 78 20 6f 66 20 6c 61 72 67 65 73 74 20 61 52 65  x of largest aRe
17b50 61 64 4d 61 72 6b 5b 5d 20 76 61 6c 75 65 20 2a  adMark[] value *
17b60 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20  /.  int i;      
17b70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17b80 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e      /* Loop coun
17b90 74 65 72 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20  ter */.  int rc 
17ba0 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20  = SQLITE_OK;    
17bb0 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
17bc0 72 6e 20 63 6f 64 65 20 20 2a 2f 0a 20 20 75 33  rn code  */.  u3
17bd0 32 20 6d 78 46 72 61 6d 65 3b 20 20 20 20 20 20  2 mxFrame;      
17be0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
17bf0 20 57 61 6c 20 66 72 61 6d 65 20 74 6f 20 6c 6f   Wal frame to lo
17c00 63 6b 20 74 6f 20 2a 2f 0a 0a 20 20 61 73 73 65  ck to */..  asse
17c10 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  rt( pWal->readLo
17c20 63 6b 3c 30 20 29 3b 20 20 20 20 20 2f 2a 20 4e  ck<0 );     /* N
17c30 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 6c 6f 63  ot currently loc
17c40 6b 65 64 20 2a 2f 0a 0a 20 20 2f 2a 20 75 73 65  ked */..  /* use
17c50 57 61 6c 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20  Wal may only be 
17c60 73 65 74 20 66 6f 72 20 72 65 61 64 2f 77 72 69  set for read/wri
17c70 74 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 2a  te connections *
17c80 2f 0a 20 20 61 73 73 65 72 74 28 20 28 70 57 61  /.  assert( (pWa
17c90 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57 41  l->readOnly & WA
17ca0 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 29 3d 3d 30  L_SHM_RDONLY)==0
17cb0 20 7c 7c 20 75 73 65 57 61 6c 3d 3d 30 20 29 3b   || useWal==0 );
17cc0 0a 0a 20 20 2f 2a 20 54 61 6b 65 20 73 74 65 70  ..  /* Take step
17cd0 73 20 74 6f 20 61 76 6f 69 64 20 73 70 69 6e 6e  s to avoid spinn
17ce0 69 6e 67 20 66 6f 72 65 76 65 72 20 69 66 20 74  ing forever if t
17cf0 68 65 72 65 20 69 73 20 61 20 70 72 6f 74 6f 63  here is a protoc
17d00 6f 6c 20 65 72 72 6f 72 2e 0a 20 20 2a 2a 0a 20  ol error..  **. 
17d10 20 2a 2a 20 43 69 72 63 75 6d 73 74 61 6e 63 65   ** Circumstance
17d20 73 20 74 68 61 74 20 63 61 75 73 65 20 61 20 52  s that cause a R
17d30 45 54 52 59 20 73 68 6f 75 6c 64 20 6f 6e 6c 79  ETRY should only
17d40 20 6c 61 73 74 20 66 6f 72 20 74 68 65 20 62 72   last for the br
17d50 69 65 66 65 73 74 0a 20 20 2a 2a 20 69 6e 73 74  iefest.  ** inst
17d60 61 6e 63 65 73 20 6f 66 20 74 69 6d 65 2e 20 20  ances of time.  
17d70 4e 6f 20 49 2f 4f 20 6f 72 20 6f 74 68 65 72 20  No I/O or other 
17d80 73 79 73 74 65 6d 20 63 61 6c 6c 73 20 61 72 65  system calls are
17d90 20 64 6f 6e 65 20 77 68 69 6c 65 20 74 68 65 0a   done while the.
17da0 20 20 2a 2a 20 6c 6f 63 6b 73 20 61 72 65 20 68    ** locks are h
17db0 65 6c 64 2c 20 73 6f 20 74 68 65 20 6c 6f 63 6b  eld, so the lock
17dc0 73 20 73 68 6f 75 6c 64 20 6e 6f 74 20 62 65 20  s should not be 
17dd0 68 65 6c 64 20 66 6f 72 20 76 65 72 79 20 6c 6f  held for very lo
17de0 6e 67 2e 20 42 75 74 20 0a 20 20 2a 2a 20 69 66  ng. But .  ** if
17df0 20 77 65 20 61 72 65 20 75 6e 6c 75 63 6b 79 2c   we are unlucky,
17e00 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65 73 73   another process
17e10 20 74 68 61 74 20 69 73 20 68 6f 6c 64 69 6e 67   that is holding
17e20 20 61 20 6c 6f 63 6b 20 6d 69 67 68 74 20 67 65   a lock might ge
17e30 74 0a 20 20 2a 2a 20 70 61 67 65 64 20 6f 75 74  t.  ** paged out
17e40 20 6f 72 20 74 61 6b 65 20 61 20 70 61 67 65 2d   or take a page-
17e50 66 61 75 6c 74 20 74 68 61 74 20 69 73 20 74 69  fault that is ti
17e60 6d 65 2d 63 6f 6e 73 75 6d 69 6e 67 20 74 6f 20  me-consuming to 
17e70 72 65 73 6f 6c 76 65 2c 20 0a 20 20 2a 2a 20 64  resolve, .  ** d
17e80 75 72 69 6e 67 20 74 68 65 20 66 65 77 20 6e 61  uring the few na
17e90 6e 6f 73 65 63 6f 6e 64 73 20 74 68 61 74 20 69  noseconds that i
17ea0 74 20 69 73 20 68 6f 6c 64 69 6e 67 20 74 68 65  t is holding the
17eb0 20 6c 6f 63 6b 2e 20 20 49 6e 20 74 68 61 74 20   lock.  In that 
17ec0 63 61 73 65 2c 0a 20 20 2a 2a 20 69 74 20 6d 69  case,.  ** it mi
17ed0 67 68 74 20 74 61 6b 65 20 6c 6f 6e 67 65 72 20  ght take longer 
17ee0 74 68 61 6e 20 6e 6f 72 6d 61 6c 20 66 6f 72 20  than normal for 
17ef0 74 68 65 20 6c 6f 63 6b 20 74 6f 20 66 72 65 65  the lock to free
17f00 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 41 66 74 65  ..  **.  ** Afte
17f10 72 20 35 20 52 45 54 52 59 73 2c 20 77 65 20 62  r 5 RETRYs, we b
17f20 65 67 69 6e 20 63 61 6c 6c 69 6e 67 20 73 71 6c  egin calling sql
17f30 69 74 65 33 4f 73 53 6c 65 65 70 28 29 2e 20 20  ite3OsSleep().  
17f40 54 68 65 20 66 69 72 73 74 20 66 65 77 0a 20 20  The first few.  
17f50 2a 2a 20 63 61 6c 6c 73 20 74 6f 20 73 71 6c 69  ** calls to sqli
17f60 74 65 33 4f 73 53 6c 65 65 70 28 29 20 68 61 76  te3OsSleep() hav
17f70 65 20 61 20 64 65 6c 61 79 20 6f 66 20 31 20 6d  e a delay of 1 m
17f80 69 63 72 6f 73 65 63 6f 6e 64 2e 20 20 52 65 61  icrosecond.  Rea
17f90 6c 6c 79 20 74 68 69 73 0a 20 20 2a 2a 20 69 73  lly this.  ** is
17fa0 20 6d 6f 72 65 20 6f 66 20 61 20 73 63 68 65 64   more of a sched
17fb0 75 6c 65 72 20 79 69 65 6c 64 20 74 68 61 6e 20  uler yield than 
17fc0 61 6e 20 61 63 74 75 61 6c 20 64 65 6c 61 79 2e  an actual delay.
17fd0 20 20 42 75 74 20 6f 6e 20 74 68 65 20 31 30 74    But on the 10t
17fe0 68 0a 20 20 2a 2a 20 61 6e 20 73 75 62 73 65 71  h.  ** an subseq
17ff0 75 65 6e 74 20 72 65 74 72 69 65 73 2c 20 74 68  uent retries, th
18000 65 20 64 65 6c 61 79 73 20 73 74 61 72 74 20 62  e delays start b
18010 65 63 6f 6d 69 6e 67 20 6c 6f 6e 67 65 72 20 61  ecoming longer a
18020 6e 64 20 6c 6f 6e 67 65 72 2c 20 0a 20 20 2a 2a  nd longer, .  **
18030 20 73 6f 20 74 68 61 74 20 6f 6e 20 74 68 65 20   so that on the 
18040 31 30 30 74 68 20 28 61 6e 64 20 6c 61 73 74 29  100th (and last)
18050 20 52 45 54 52 59 20 77 65 20 64 65 6c 61 79 20   RETRY we delay 
18060 66 6f 72 20 33 32 33 20 6d 69 6c 6c 69 73 65 63  for 323 millisec
18070 6f 6e 64 73 2e 0a 20 20 2a 2a 20 54 68 65 20 74  onds..  ** The t
18080 6f 74 61 6c 20 64 65 6c 61 79 20 74 69 6d 65 20  otal delay time 
18090 62 65 66 6f 72 65 20 67 69 76 69 6e 67 20 75 70  before giving up
180a0 20 69 73 20 6c 65 73 73 20 74 68 61 6e 20 31 30   is less than 10
180b0 20 73 65 63 6f 6e 64 73 2e 0a 20 20 2a 2f 0a 20   seconds..  */. 
180c0 20 69 66 28 20 63 6e 74 3e 35 20 29 7b 0a 20 20   if( cnt>5 ){.  
180d0 20 20 69 6e 74 20 6e 44 65 6c 61 79 20 3d 20 31    int nDelay = 1
180e0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
180f0 20 20 20 20 20 20 20 2f 2a 20 50 61 75 73 65 20         /* Pause 
18100 74 69 6d 65 20 69 6e 20 6d 69 63 72 6f 73 65 63  time in microsec
18110 6f 6e 64 73 20 2a 2f 0a 20 20 20 20 69 66 28 20  onds */.    if( 
18120 63 6e 74 3e 31 30 30 20 29 7b 0a 20 20 20 20 20  cnt>100 ){.     
18130 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d   VVA_ONLY( pWal-
18140 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20 31 3b 20  >lockError = 1; 
18150 29 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  ).      return S
18160 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 3b 0a  QLITE_PROTOCOL;.
18170 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 63 6e      }.    if( cn
18180 74 3e 3d 31 30 20 29 20 6e 44 65 6c 61 79 20 3d  t>=10 ) nDelay =
18190 20 28 63 6e 74 2d 39 29 2a 28 63 6e 74 2d 39 29   (cnt-9)*(cnt-9)
181a0 2a 33 39 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  *39;.    sqlite3
181b0 4f 73 53 6c 65 65 70 28 70 57 61 6c 2d 3e 70 56  OsSleep(pWal->pV
181c0 66 73 2c 20 6e 44 65 6c 61 79 29 3b 0a 20 20 7d  fs, nDelay);.  }
181d0 0a 0a 20 20 69 66 28 20 21 75 73 65 57 61 6c 20  ..  if( !useWal 
181e0 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 72  ){.    assert( r
181f0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c==SQLITE_OK );.
18200 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 62 53      if( pWal->bS
18210 68 6d 55 6e 72 65 6c 69 61 62 6c 65 3d 3d 30 20  hmUnreliable==0 
18220 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61  ){.      rc = wa
18230 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28 70 57  lIndexReadHdr(pW
18240 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b 0a 20  al, pChanged);. 
18250 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d     }.    if( rc=
18260 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a  =SQLITE_BUSY ){.
18270 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 72        /* If ther
18280 65 20 69 73 20 6e 6f 74 20 61 20 72 65 63 6f 76  e is not a recov
18290 65 72 79 20 72 75 6e 6e 69 6e 67 20 69 6e 20 61  ery running in a
182a0 6e 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f 72  nother thread or
182b0 20 70 72 6f 63 65 73 73 0a 20 20 20 20 20 20 2a   process.      *
182c0 2a 20 74 68 65 6e 20 63 6f 6e 76 65 72 74 20 42  * then convert B
182d0 55 53 59 20 65 72 72 6f 72 73 20 74 6f 20 57 41  USY errors to WA
182e0 4c 5f 52 45 54 52 59 2e 20 20 49 66 20 72 65 63  L_RETRY.  If rec
182f0 6f 76 65 72 79 20 69 73 20 6b 6e 6f 77 6e 20 74  overy is known t
18300 6f 0a 20 20 20 20 20 20 2a 2a 20 62 65 20 72 75  o.      ** be ru
18310 6e 6e 69 6e 67 2c 20 63 6f 6e 76 65 72 74 20 42  nning, convert B
18320 55 53 59 20 74 6f 20 42 55 53 59 5f 52 45 43 4f  USY to BUSY_RECO
18330 56 45 52 59 2e 20 20 54 68 65 72 65 20 69 73 20  VERY.  There is 
18340 61 20 72 61 63 65 20 68 65 72 65 0a 20 20 20 20  a race here.    
18350 20 20 2a 2a 20 77 68 69 63 68 20 6d 69 67 68 74    ** which might
18360 20 63 61 75 73 65 20 57 41 4c 5f 52 45 54 52 59   cause WAL_RETRY
18370 20 74 6f 20 62 65 20 72 65 74 75 72 6e 65 64 20   to be returned 
18380 65 76 65 6e 20 69 66 20 42 55 53 59 5f 52 45 43  even if BUSY_REC
18390 4f 56 45 52 59 0a 20 20 20 20 20 20 2a 2a 20 77  OVERY.      ** w
183a0 6f 75 6c 64 20 62 65 20 74 65 63 68 6e 69 63 61  ould be technica
183b0 6c 6c 79 20 63 6f 72 72 65 63 74 2e 20 20 42 75  lly correct.  Bu
183c0 74 20 74 68 65 20 72 61 63 65 20 69 73 20 62 65  t the race is be
183d0 6e 69 67 6e 20 73 69 6e 63 65 20 77 69 74 68 0a  nign since with.
183e0 20 20 20 20 20 20 2a 2a 20 57 41 4c 5f 52 45 54        ** WAL_RET
183f0 52 59 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  RY this routine 
18400 77 69 6c 6c 20 62 65 20 63 61 6c 6c 65 64 20 61  will be called a
18410 67 61 69 6e 20 61 6e 64 20 77 69 6c 6c 20 70 72  gain and will pr
18420 6f 62 61 62 6c 79 20 62 65 0a 20 20 20 20 20 20  obably be.      
18430 2a 2a 20 72 69 67 68 74 20 6f 6e 20 74 68 65 20  ** right on the 
18440 73 65 63 6f 6e 64 20 69 74 65 72 61 74 69 6f 6e  second iteration
18450 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20  ..      */.     
18460 20 69 66 28 20 70 57 61 6c 2d 3e 61 70 57 69 44   if( pWal->apWiD
18470 61 74 61 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20  ata[0]==0 ){.   
18480 20 20 20 20 20 2f 2a 20 54 68 69 73 20 62 72 61       /* This bra
18490 6e 63 68 20 69 73 20 74 61 6b 65 6e 20 77 68 65  nch is taken whe
184a0 6e 20 74 68 65 20 78 53 68 6d 4d 61 70 28 29 20  n the xShmMap() 
184b0 6d 65 74 68 6f 64 20 72 65 74 75 72 6e 73 20 53  method returns S
184c0 51 4c 49 54 45 5f 42 55 53 59 2e 0a 20 20 20 20  QLITE_BUSY..    
184d0 20 20 20 20 2a 2a 20 57 65 20 61 73 73 75 6d 65      ** We assume
184e0 20 74 68 69 73 20 69 73 20 61 20 74 72 61 6e 73   this is a trans
184f0 69 65 6e 74 20 63 6f 6e 64 69 74 69 6f 6e 2c 20  ient condition, 
18500 73 6f 20 72 65 74 75 72 6e 20 57 41 4c 5f 52 45  so return WAL_RE
18510 54 52 59 2e 20 54 68 65 0a 20 20 20 20 20 20 20  TRY. The.       
18520 20 2a 2a 20 78 53 68 6d 4d 61 70 28 29 20 69 6d   ** xShmMap() im
18530 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 75 73 65  plementation use
18540 64 20 62 79 20 74 68 65 20 64 65 66 61 75 6c 74  d by the default
18550 20 75 6e 69 78 20 61 6e 64 20 77 69 6e 33 32 20   unix and win32 
18560 56 46 53 20 0a 20 20 20 20 20 20 20 20 2a 2a 20  VFS .        ** 
18570 6d 6f 64 75 6c 65 73 20 6d 61 79 20 72 65 74 75  modules may retu
18580 72 6e 20 53 51 4c 49 54 45 5f 42 55 53 59 20 64  rn SQLITE_BUSY d
18590 75 65 20 74 6f 20 61 20 72 61 63 65 20 63 6f 6e  ue to a race con
185a0 64 69 74 69 6f 6e 20 69 6e 20 74 68 65 20 0a 20  dition in the . 
185b0 20 20 20 20 20 20 20 2a 2a 20 63 6f 64 65 20 74         ** code t
185c0 68 61 74 20 64 65 74 65 72 6d 69 6e 65 73 20 77  hat determines w
185d0 68 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 74 68  hether or not th
185e0 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20  e shared-memory 
185f0 72 65 67 69 6f 6e 20 0a 20 20 20 20 20 20 20 20  region .        
18600 2a 2a 20 6d 75 73 74 20 62 65 20 7a 65 72 6f 65  ** must be zeroe
18610 64 20 62 65 66 6f 72 65 20 74 68 65 20 72 65 71  d before the req
18620 75 65 73 74 65 64 20 70 61 67 65 20 69 73 20 72  uested page is r
18630 65 74 75 72 6e 65 64 2e 0a 20 20 20 20 20 20 20  eturned..       
18640 20 2a 2f 0a 20 20 20 20 20 20 20 20 72 63 20 3d   */.        rc =
18650 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20   WAL_RETRY;.    
18660 20 20 7d 65 6c 73 65 20 69 66 28 20 53 51 4c 49    }else if( SQLI
18670 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c  TE_OK==(rc = wal
18680 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  LockShared(pWal,
18690 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43   WAL_RECOVER_LOC
186a0 4b 29 29 20 29 7b 0a 20 20 20 20 20 20 20 20 77  K)) ){.        w
186b0 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70  alUnlockShared(p
186c0 57 61 6c 2c 20 57 41 4c 5f 52 45 43 4f 56 45 52  Wal, WAL_RECOVER
186d0 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 20 20 20 20  _LOCK);.        
186e0 72 63 20 3d 20 57 41 4c 5f 52 45 54 52 59 3b 0a  rc = WAL_RETRY;.
186f0 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
18700 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc==SQLITE_BUSY 
18710 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  ){.        rc = 
18720 53 51 4c 49 54 45 5f 42 55 53 59 5f 52 45 43 4f  SQLITE_BUSY_RECO
18730 56 45 52 59 3b 0a 20 20 20 20 20 20 7d 0a 20 20  VERY;.      }.  
18740 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 21 3d    }.    if( rc!=
18750 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
18760 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
18770 20 20 7d 0a 20 20 20 20 65 6c 73 65 20 69 66 28    }.    else if(
18780 20 70 57 61 6c 2d 3e 62 53 68 6d 55 6e 72 65 6c   pWal->bShmUnrel
18790 69 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 72  iable ){.      r
187a0 65 74 75 72 6e 20 77 61 6c 42 65 67 69 6e 53 68  eturn walBeginSh
187b0 6d 55 6e 72 65 6c 69 61 62 6c 65 28 70 57 61 6c  mUnreliable(pWal
187c0 2c 20 70 43 68 61 6e 67 65 64 29 3b 0a 20 20 20  , pChanged);.   
187d0 20 7d 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74   }.  }..  assert
187e0 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e  ( pWal->nWiData>
187f0 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  0 );.  assert( p
18800 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
18810 21 3d 30 20 29 3b 0a 20 20 70 49 6e 66 6f 20 3d  !=0 );.  pInfo =
18820 20 77 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61   walCkptInfo(pWa
18830 6c 29 3b 0a 20 20 69 66 28 20 21 75 73 65 57 61  l);.  if( !useWa
18840 6c 20 26 26 20 70 49 6e 66 6f 2d 3e 6e 42 61 63  l && pInfo->nBac
18850 6b 66 69 6c 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72  kfill==pWal->hdr
18860 2e 6d 78 46 72 61 6d 65 0a 23 69 66 64 65 66 20  .mxFrame.#ifdef 
18870 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e  SQLITE_ENABLE_SN
18880 41 50 53 48 4f 54 0a 20 20 20 26 26 20 28 70 57  APSHOT.   && (pW
18890 61 6c 2d 3e 70 53 6e 61 70 73 68 6f 74 3d 3d 30  al->pSnapshot==0
188a0 20 7c 7c 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78   || pWal->hdr.mx
188b0 46 72 61 6d 65 3d 3d 30 29 0a 23 65 6e 64 69 66  Frame==0).#endif
188c0 0a 20 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65  .  ){.    /* The
188d0 20 57 41 4c 20 68 61 73 20 62 65 65 6e 20 63 6f   WAL has been co
188e0 6d 70 6c 65 74 65 6c 79 20 62 61 63 6b 66 69 6c  mpletely backfil
188f0 6c 65 64 20 28 6f 72 20 69 74 20 69 73 20 65 6d  led (or it is em
18900 70 74 79 29 2e 0a 20 20 20 20 2a 2a 20 61 6e 64  pty)..    ** and
18910 20 63 61 6e 20 62 65 20 73 61 66 65 6c 79 20 69   can be safely i
18920 67 6e 6f 72 65 64 2e 0a 20 20 20 20 2a 2f 0a 20  gnored..    */. 
18930 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53     rc = walLockS
18940 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
18950 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20  READ_LOCK(0));. 
18960 20 20 20 77 61 6c 53 68 6d 42 61 72 72 69 65 72     walShmBarrier
18970 28 70 57 61 6c 29 3b 0a 20 20 20 20 69 66 28 20  (pWal);.    if( 
18980 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
18990 0a 20 20 20 20 20 20 69 66 28 20 6d 65 6d 63 6d  .      if( memcm
189a0 70 28 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64  p((void *)walInd
189b0 65 78 48 64 72 28 70 57 61 6c 29 2c 20 26 70 57  exHdr(pWal), &pW
189c0 61 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28  al->hdr, sizeof(
189d0 57 61 6c 49 6e 64 65 78 48 64 72 29 29 20 29 7b  WalIndexHdr)) ){
189e0 0a 20 20 20 20 20 20 20 20 2f 2a 20 49 74 20 69  .        /* It i
189f0 73 20 6e 6f 74 20 73 61 66 65 20 74 6f 20 61 6c  s not safe to al
18a00 6c 6f 77 20 74 68 65 20 72 65 61 64 65 72 20 74  low the reader t
18a10 6f 20 63 6f 6e 74 69 6e 75 65 20 68 65 72 65 20  o continue here 
18a20 69 66 20 66 72 61 6d 65 73 0a 20 20 20 20 20 20  if frames.      
18a30 20 20 2a 2a 20 6d 61 79 20 68 61 76 65 20 62 65    ** may have be
18a40 65 6e 20 61 70 70 65 6e 64 65 64 20 74 6f 20 74  en appended to t
18a50 68 65 20 6c 6f 67 20 62 65 66 6f 72 65 20 52 45  he log before RE
18a60 41 44 5f 4c 4f 43 4b 28 30 29 20 77 61 73 20 6f  AD_LOCK(0) was o
18a70 62 74 61 69 6e 65 64 2e 0a 20 20 20 20 20 20 20  btained..       
18a80 20 2a 2a 20 57 68 65 6e 20 68 6f 6c 64 69 6e 67   ** When holding
18a90 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 74   READ_LOCK(0), t
18aa0 68 65 20 72 65 61 64 65 72 20 69 67 6e 6f 72 65  he reader ignore
18ab0 73 20 74 68 65 20 65 6e 74 69 72 65 20 6c 6f 67  s the entire log
18ac0 20 66 69 6c 65 2c 0a 20 20 20 20 20 20 20 20 2a   file,.        *
18ad0 2a 20 77 68 69 63 68 20 69 6d 70 6c 69 65 73 20  * which implies 
18ae0 74 68 61 74 20 74 68 65 20 64 61 74 61 62 61 73  that the databas
18af0 65 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20  e file contains 
18b00 61 20 74 72 75 73 74 77 6f 72 74 68 79 0a 20 20  a trustworthy.  
18b10 20 20 20 20 20 20 2a 2a 20 73 6e 61 70 73 68 6f        ** snapsho
18b20 74 2e 20 53 69 6e 63 65 20 68 6f 6c 64 69 6e 67  t. Since holding
18b30 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20 70 72   READ_LOCK(0) pr
18b40 65 76 65 6e 74 73 20 61 20 63 68 65 63 6b 70 6f  events a checkpo
18b50 69 6e 74 20 66 72 6f 6d 0a 20 20 20 20 20 20 20  int from.       
18b60 20 2a 2a 20 68 61 70 70 65 6e 69 6e 67 2c 20 74   ** happening, t
18b70 68 69 73 20 69 73 20 75 73 75 61 6c 6c 79 20 63  his is usually c
18b80 6f 72 72 65 63 74 2e 0a 20 20 20 20 20 20 20 20  orrect..        
18b90 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 48 6f  **.        ** Ho
18ba0 77 65 76 65 72 2c 20 69 66 20 66 72 61 6d 65 73  wever, if frames
18bb0 20 68 61 76 65 20 62 65 65 6e 20 61 70 70 65 6e   have been appen
18bc0 64 65 64 20 74 6f 20 74 68 65 20 6c 6f 67 20 28  ded to the log (
18bd0 6f 72 20 69 66 20 74 68 65 20 6c 6f 67 20 0a 20  or if the log . 
18be0 20 20 20 20 20 20 20 2a 2a 20 69 73 20 77 72 61         ** is wra
18bf0 70 70 65 64 20 61 6e 64 20 77 72 69 74 74 65 6e  pped and written
18c00 20 66 6f 72 20 74 68 61 74 20 6d 61 74 74 65 72   for that matter
18c10 29 20 62 65 66 6f 72 65 20 74 68 65 20 52 45 41  ) before the REA
18c20 44 5f 4c 4f 43 4b 28 30 29 0a 20 20 20 20 20 20  D_LOCK(0).      
18c30 20 20 2a 2a 20 69 73 20 6f 62 74 61 69 6e 65 64    ** is obtained
18c40 2c 20 74 68 61 74 20 69 73 20 6e 6f 74 20 6e 65  , that is not ne
18c50 63 65 73 73 61 72 69 6c 79 20 74 72 75 65 2e 20  cessarily true. 
18c60 41 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 20 6d  A checkpointer m
18c70 61 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 68 61  ay.        ** ha
18c80 76 65 20 73 74 61 72 74 65 64 20 74 6f 20 62 61  ve started to ba
18c90 63 6b 66 69 6c 6c 20 74 68 65 20 61 70 70 65 6e  ckfill the appen
18ca0 64 65 64 20 66 72 61 6d 65 73 20 62 75 74 20 63  ded frames but c
18cb0 72 61 73 68 65 64 20 62 65 66 6f 72 65 0a 20 20  rashed before.  
18cc0 20 20 20 20 20 20 2a 2a 20 69 74 20 66 69 6e 69        ** it fini
18cd0 73 68 65 64 2e 20 4c 65 61 76 69 6e 67 20 61 20  shed. Leaving a 
18ce0 63 6f 72 72 75 70 74 20 69 6d 61 67 65 20 69 6e  corrupt image in
18cf0 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
18d00 6c 65 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20  le..        */. 
18d10 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b         walUnlock
18d20 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c  Shared(pWal, WAL
18d30 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a  _READ_LOCK(0));.
18d40 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 57          return W
18d50 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20  AL_RETRY;.      
18d60 7d 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 72 65  }.      pWal->re
18d70 61 64 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20  adLock = 0;.    
18d80 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
18d90 4f 4b 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  OK;.    }else if
18da0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc!=SQLITE_BUS
18db0 59 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  Y ){.      retur
18dc0 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  n rc;.    }.  }.
18dd0 0a 20 20 2f 2a 20 49 66 20 77 65 20 67 65 74 20  .  /* If we get 
18de0 74 68 69 73 20 66 61 72 2c 20 69 74 20 6d 65 61  this far, it mea
18df0 6e 73 20 74 68 61 74 20 74 68 65 20 72 65 61 64  ns that the read
18e00 65 72 20 77 69 6c 6c 20 77 61 6e 74 20 74 6f 20  er will want to 
18e10 75 73 65 0a 20 20 2a 2a 20 74 68 65 20 57 41 4c  use.  ** the WAL
18e20 20 74 6f 20 67 65 74 20 61 74 20 63 6f 6e 74 65   to get at conte
18e30 6e 74 20 66 72 6f 6d 20 72 65 63 65 6e 74 20 63  nt from recent c
18e40 6f 6d 6d 69 74 73 2e 20 20 54 68 65 20 6a 6f 62  ommits.  The job
18e50 20 6e 6f 77 20 69 73 0a 20 20 2a 2a 20 74 6f 20   now is.  ** to 
18e60 73 65 6c 65 63 74 20 6f 6e 65 20 6f 66 20 74 68  select one of th
18e70 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e  e aReadMark[] en
18e80 74 72 69 65 73 20 74 68 61 74 20 69 73 20 63 6c  tries that is cl
18e90 6f 73 65 73 74 20 74 6f 0a 20 20 2a 2a 20 62 75  osest to.  ** bu
18ea0 74 20 6e 6f 74 20 65 78 63 65 65 64 69 6e 67 20  t not exceeding 
18eb0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
18ec0 65 20 61 6e 64 20 6c 6f 63 6b 20 74 68 61 74 20  e and lock that 
18ed0 65 6e 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 6d 78  entry..  */.  mx
18ee0 52 65 61 64 4d 61 72 6b 20 3d 20 30 3b 0a 20 20  ReadMark = 0;.  
18ef0 6d 78 49 20 3d 20 30 3b 0a 20 20 6d 78 46 72 61  mxI = 0;.  mxFra
18f00 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  me = pWal->hdr.m
18f10 78 46 72 61 6d 65 3b 0a 23 69 66 64 65 66 20 53  xFrame;.#ifdef S
18f20 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e 41  QLITE_ENABLE_SNA
18f30 50 53 48 4f 54 0a 20 20 69 66 28 20 70 57 61 6c  PSHOT.  if( pWal
18f40 2d 3e 70 53 6e 61 70 73 68 6f 74 20 26 26 20 70  ->pSnapshot && p
18f50 57 61 6c 2d 3e 70 53 6e 61 70 73 68 6f 74 2d 3e  Wal->pSnapshot->
18f60 6d 78 46 72 61 6d 65 3c 6d 78 46 72 61 6d 65 20  mxFrame<mxFrame 
18f70 29 7b 0a 20 20 20 20 6d 78 46 72 61 6d 65 20 3d  ){.    mxFrame =
18f80 20 70 57 61 6c 2d 3e 70 53 6e 61 70 73 68 6f 74   pWal->pSnapshot
18f90 2d 3e 6d 78 46 72 61 6d 65 3b 0a 20 20 7d 0a 23  ->mxFrame;.  }.#
18fa0 65 6e 64 69 66 0a 20 20 66 6f 72 28 69 3d 31 3b  endif.  for(i=1;
18fb0 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
18fc0 69 2b 2b 29 7b 0a 20 20 20 20 75 33 32 20 74 68  i++){.    u32 th
18fd0 69 73 4d 61 72 6b 20 3d 20 41 74 6f 6d 69 63 4c  isMark = AtomicL
18fe0 6f 61 64 28 70 49 6e 66 6f 2d 3e 61 52 65 61 64  oad(pInfo->aRead
18ff0 4d 61 72 6b 2b 69 29 3b 0a 20 20 20 20 69 66 28  Mark+i);.    if(
19000 20 6d 78 52 65 61 64 4d 61 72 6b 3c 3d 74 68 69   mxReadMark<=thi
19010 73 4d 61 72 6b 20 26 26 20 74 68 69 73 4d 61 72  sMark && thisMar
19020 6b 3c 3d 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20  k<=mxFrame ){.  
19030 20 20 20 20 61 73 73 65 72 74 28 20 74 68 69 73      assert( this
19040 4d 61 72 6b 21 3d 52 45 41 44 4d 41 52 4b 5f 4e  Mark!=READMARK_N
19050 4f 54 5f 55 53 45 44 20 29 3b 0a 20 20 20 20 20  OT_USED );.     
19060 20 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20 74 68   mxReadMark = th
19070 69 73 4d 61 72 6b 3b 0a 20 20 20 20 20 20 6d 78  isMark;.      mx
19080 49 20 3d 20 69 3b 0a 20 20 20 20 7d 0a 20 20 7d  I = i;.    }.  }
19090 0a 20 20 69 66 28 20 28 70 57 61 6c 2d 3e 72 65  .  if( (pWal->re
190a0 61 64 4f 6e 6c 79 20 26 20 57 41 4c 5f 53 48 4d  adOnly & WAL_SHM
190b0 5f 52 44 4f 4e 4c 59 29 3d 3d 30 0a 20 20 20 26  _RDONLY)==0.   &
190c0 26 20 28 6d 78 52 65 61 64 4d 61 72 6b 3c 6d 78  & (mxReadMark<mx
190d0 46 72 61 6d 65 20 7c 7c 20 6d 78 49 3d 3d 30 29  Frame || mxI==0)
190e0 0a 20 20 29 7b 0a 20 20 20 20 66 6f 72 28 69 3d  .  ){.    for(i=
190f0 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52  1; i<WAL_NREADER
19100 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 72 63  ; i++){.      rc
19110 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73   = walLockExclus
19120 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  ive(pWal, WAL_RE
19130 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a  AD_LOCK(i), 1);.
19140 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
19150 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
19160 20 20 20 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20     mxReadMark = 
19170 41 74 6f 6d 69 63 53 74 6f 72 65 28 70 49 6e 66  AtomicStore(pInf
19180 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 2b 69 2c 6d  o->aReadMark+i,m
19190 78 46 72 61 6d 65 29 3b 0a 20 20 20 20 20 20 20  xFrame);.       
191a0 20 6d 78 49 20 3d 20 69 3b 0a 20 20 20 20 20 20   mxI = i;.      
191b0 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75    walUnlockExclu
191c0 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52  sive(pWal, WAL_R
191d0 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b  EAD_LOCK(i), 1);
191e0 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
191f0 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
19200 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc!=SQLITE_BUSY 
19210 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
19220 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20 20  n rc;.      }.  
19230 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 6d 78    }.  }.  if( mx
19240 49 3d 3d 30 20 29 7b 0a 20 20 20 20 61 73 73 65  I==0 ){.    asse
19250 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42  rt( rc==SQLITE_B
19260 55 53 59 20 7c 7c 20 28 70 57 61 6c 2d 3e 72 65  USY || (pWal->re
19270 61 64 4f 6e 6c 79 20 26 20 57 41 4c 5f 53 48 4d  adOnly & WAL_SHM
19280 5f 52 44 4f 4e 4c 59 29 21 3d 30 20 29 3b 0a 20  _RDONLY)!=0 );. 
19290 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d 53 51     return rc==SQ
192a0 4c 49 54 45 5f 42 55 53 59 20 3f 20 57 41 4c 5f  LITE_BUSY ? WAL_
192b0 52 45 54 52 59 20 3a 20 53 51 4c 49 54 45 5f 52  RETRY : SQLITE_R
192c0 45 41 44 4f 4e 4c 59 5f 43 41 4e 54 49 4e 49 54  EADONLY_CANTINIT
192d0 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 77 61  ;.  }..  rc = wa
192e0 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  lLockShared(pWal
192f0 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
19300 6d 78 49 29 29 3b 0a 20 20 69 66 28 20 72 63 20  mxI));.  if( rc 
19310 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  ){.    return rc
19320 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 3f 20  ==SQLITE_BUSY ? 
19330 57 41 4c 5f 52 45 54 52 59 20 3a 20 72 63 3b 0a  WAL_RETRY : rc;.
19340 20 20 7d 0a 20 20 2f 2a 20 4e 6f 77 20 74 68 61    }.  /* Now tha
19350 74 20 74 68 65 20 72 65 61 64 2d 6c 6f 63 6b 20  t the read-lock 
19360 68 61 73 20 62 65 65 6e 20 6f 62 74 61 69 6e 65  has been obtaine
19370 64 2c 20 63 68 65 63 6b 20 74 68 61 74 20 6e 65  d, check that ne
19380 69 74 68 65 72 20 74 68 65 0a 20 20 2a 2a 20 76  ither the.  ** v
19390 61 6c 75 65 20 69 6e 20 74 68 65 20 61 52 65 61  alue in the aRea
193a0 64 4d 61 72 6b 5b 5d 20 61 72 72 61 79 20 6f 72  dMark[] array or
193b0 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
193c0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 20   the wal-index. 
193d0 20 2a 2a 20 68 65 61 64 65 72 20 68 61 76 65 20   ** header have 
193e0 63 68 61 6e 67 65 64 2e 0a 20 20 2a 2a 0a 20 20  changed..  **.  
193f0 2a 2a 20 49 74 20 69 73 20 6e 65 63 65 73 73 61  ** It is necessa
19400 72 79 20 74 6f 20 63 68 65 63 6b 20 74 68 61 74  ry to check that
19410 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
19420 65 61 64 65 72 20 64 69 64 20 6e 6f 74 20 63 68  eader did not ch
19430 61 6e 67 65 0a 20 20 2a 2a 20 62 65 74 77 65 65  ange.  ** betwee
19440 6e 20 74 68 65 20 74 69 6d 65 20 69 74 20 77 61  n the time it wa
19450 73 20 72 65 61 64 20 61 6e 64 20 77 68 65 6e 20  s read and when 
19460 74 68 65 20 73 68 61 72 65 64 2d 6c 6f 63 6b 20  the shared-lock 
19470 77 61 73 20 6f 62 74 61 69 6e 65 64 0a 20 20 2a  was obtained.  *
19480 2a 20 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  * on WAL_READ_LO
19490 43 4b 28 6d 78 49 29 20 77 61 73 20 6f 62 74 61  CK(mxI) was obta
194a0 69 6e 65 64 20 74 6f 20 61 63 63 6f 75 6e 74 20  ined to account 
194b0 66 6f 72 20 74 68 65 20 70 6f 73 73 69 62 69 6c  for the possibil
194c0 69 74 79 0a 20 20 2a 2a 20 74 68 61 74 20 74 68  ity.  ** that th
194d0 65 20 6c 6f 67 20 66 69 6c 65 20 6d 61 79 20 68  e log file may h
194e0 61 76 65 20 62 65 65 6e 20 77 72 61 70 70 65 64  ave been wrapped
194f0 20 62 79 20 61 20 77 72 69 74 65 72 2c 20 6f 72   by a writer, or
19500 20 74 68 61 74 20 66 72 61 6d 65 73 0a 20 20 2a   that frames.  *
19510 2a 20 74 68 61 74 20 6f 63 63 75 72 20 6c 61 74  * that occur lat
19520 65 72 20 69 6e 20 74 68 65 20 6c 6f 67 20 74 68  er in the log th
19530 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  an pWal->hdr.mxF
19540 72 61 6d 65 20 6d 61 79 20 68 61 76 65 20 62 65  rame may have be
19550 65 6e 0a 20 20 2a 2a 20 63 6f 70 69 65 64 20 69  en.  ** copied i
19560 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65  nto the database
19570 20 62 79 20 61 20 63 68 65 63 6b 70 6f 69 6e 74   by a checkpoint
19580 65 72 2e 20 49 66 20 65 69 74 68 65 72 20 6f 66  er. If either of
19590 20 74 68 65 73 65 20 74 68 69 6e 67 73 0a 20 20   these things.  
195a0 2a 2a 20 68 61 70 70 65 6e 65 64 2c 20 74 68 65  ** happened, the
195b0 6e 20 72 65 61 64 69 6e 67 20 74 68 65 20 64 61  n reading the da
195c0 74 61 62 61 73 65 20 77 69 74 68 20 74 68 65 20  tabase with the 
195d0 63 75 72 72 65 6e 74 20 76 61 6c 75 65 20 6f 66  current value of
195e0 0a 20 20 2a 2a 20 70 57 61 6c 2d 3e 68 64 72 2e  .  ** pWal->hdr.
195f0 6d 78 46 72 61 6d 65 20 72 69 73 6b 73 20 72 65  mxFrame risks re
19600 61 64 69 6e 67 20 61 20 63 6f 72 72 75 70 74 65  ading a corrupte
19610 64 20 73 6e 61 70 73 68 6f 74 2e 20 53 6f 2c 20  d snapshot. So, 
19620 72 65 74 72 79 0a 20 20 2a 2a 20 69 6e 73 74 65  retry.  ** inste
19630 61 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 42 65  ad..  **.  ** Be
19640 66 6f 72 65 20 63 68 65 63 6b 69 6e 67 20 74 68  fore checking th
19650 61 74 20 74 68 65 20 6c 69 76 65 20 77 61 6c 2d  at the live wal-
19660 69 6e 64 65 78 20 68 65 61 64 65 72 20 68 61 73  index header has
19670 20 6e 6f 74 20 63 68 61 6e 67 65 64 0a 20 20 2a   not changed.  *
19680 2a 20 73 69 6e 63 65 20 69 74 20 77 61 73 20 72  * since it was r
19690 65 61 64 2c 20 73 65 74 20 57 61 6c 2e 6d 69 6e  ead, set Wal.min
196a0 46 72 61 6d 65 20 74 6f 20 74 68 65 20 66 69 72  Frame to the fir
196b0 73 74 20 66 72 61 6d 65 20 69 6e 20 74 68 65 20  st frame in the 
196c0 77 61 6c 0a 20 20 2a 2a 20 66 69 6c 65 20 74 68  wal.  ** file th
196d0 61 74 20 68 61 73 20 6e 6f 74 20 79 65 74 20 62  at has not yet b
196e0 65 65 6e 20 63 68 65 63 6b 70 6f 69 6e 74 65 64  een checkpointed
196f0 2e 20 54 68 69 73 20 63 6c 69 65 6e 74 20 77 69  . This client wi
19700 6c 6c 20 6e 6f 74 20 6e 65 65 64 0a 20 20 2a 2a  ll not need.  **
19710 20 74 6f 20 72 65 61 64 20 61 6e 79 20 66 72 61   to read any fra
19720 6d 65 73 20 65 61 72 6c 69 65 72 20 74 68 61 6e  mes earlier than
19730 20 6d 69 6e 46 72 61 6d 65 20 66 72 6f 6d 20 74   minFrame from t
19740 68 65 20 77 61 6c 20 66 69 6c 65 20 2d 20 74 68  he wal file - th
19750 65 79 0a 20 20 2a 2a 20 63 61 6e 20 62 65 20 73  ey.  ** can be s
19760 61 66 65 6c 79 20 72 65 61 64 20 64 69 72 65 63  afely read direc
19770 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61 74  tly from the dat
19780 61 62 61 73 65 20 66 69 6c 65 2e 0a 20 20 2a 2a  abase file..  **
19790 0a 20 20 2a 2a 20 42 65 63 61 75 73 65 20 61 20  .  ** Because a 
197a0 53 68 6d 42 61 72 72 69 65 72 28 29 20 63 61 6c  ShmBarrier() cal
197b0 6c 20 69 73 20 6d 61 64 65 20 62 65 74 77 65 65  l is made betwee
197c0 6e 20 74 61 6b 69 6e 67 20 74 68 65 20 63 6f 70  n taking the cop
197d0 79 20 6f 66 20 0a 20 20 2a 2a 20 6e 42 61 63 6b  y of .  ** nBack
197e0 66 69 6c 6c 20 61 6e 64 20 63 68 65 63 6b 69 6e  fill and checkin
197f0 67 20 74 68 61 74 20 74 68 65 20 77 61 6c 2d 68  g that the wal-h
19800 65 61 64 65 72 20 69 6e 20 73 68 61 72 65 64 2d  eader in shared-
19810 6d 65 6d 6f 72 79 20 73 74 69 6c 6c 0a 20 20 2a  memory still.  *
19820 2a 20 6d 61 74 63 68 65 73 20 74 68 65 20 6f 6e  * matches the on
19830 65 20 63 61 63 68 65 64 20 69 6e 20 70 57 61 6c  e cached in pWal
19840 2d 3e 68 64 72 2c 20 69 74 20 69 73 20 67 75 61  ->hdr, it is gua
19850 72 61 6e 74 65 65 64 20 74 68 61 74 20 74 68 65  ranteed that the
19860 20 0a 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69 6e   .  ** checkpoin
19870 74 65 72 20 74 68 61 74 20 73 65 74 20 6e 42 61  ter that set nBa
19880 63 6b 66 69 6c 6c 20 77 61 73 20 6e 6f 74 20 77  ckfill was not w
19890 6f 72 6b 69 6e 67 20 77 69 74 68 20 61 20 77 61  orking with a wa
198a0 6c 2d 69 6e 64 65 78 0a 20 20 2a 2a 20 68 65 61  l-index.  ** hea
198b0 64 65 72 20 6e 65 77 65 72 20 74 68 61 6e 20 74  der newer than t
198c0 68 61 74 20 63 61 63 68 65 64 20 69 6e 20 70 57  hat cached in pW
198d0 61 6c 2d 3e 68 64 72 2e 20 49 66 20 69 74 20 77  al->hdr. If it w
198e0 65 72 65 2c 20 74 68 61 74 20 63 6f 75 6c 64 0a  ere, that could.
198f0 20 20 2a 2a 20 63 61 75 73 65 20 61 20 70 72 6f    ** cause a pro
19900 62 6c 65 6d 2e 20 54 68 65 20 63 68 65 63 6b 70  blem. The checkp
19910 6f 69 6e 74 65 72 20 63 6f 75 6c 64 20 6f 6d 69  ointer could omi
19920 74 20 74 6f 20 63 68 65 63 6b 70 6f 69 6e 74 0a  t to checkpoint.
19930 20 20 2a 2a 20 61 20 76 65 72 73 69 6f 6e 20 6f    ** a version o
19940 66 20 70 61 67 65 20 58 20 74 68 61 74 20 6c 69  f page X that li
19950 65 73 20 62 65 66 6f 72 65 20 70 57 61 6c 2d 3e  es before pWal->
19960 6d 69 6e 46 72 61 6d 65 20 28 63 61 6c 6c 20 74  minFrame (call t
19970 68 61 74 20 76 65 72 73 69 6f 6e 0a 20 20 2a 2a  hat version.  **
19980 20 41 29 20 6f 6e 20 74 68 65 20 62 61 73 69 73   A) on the basis
19990 20 74 68 61 74 20 74 68 65 72 65 20 69 73 20 61   that there is a
199a0 20 6e 65 77 65 72 20 76 65 72 73 69 6f 6e 20 28   newer version (
199b0 76 65 72 73 69 6f 6e 20 42 29 20 6f 66 20 74 68  version B) of th
199c0 65 20 73 61 6d 65 0a 20 20 2a 2a 20 70 61 67 65  e same.  ** page
199d0 20 6c 61 74 65 72 20 69 6e 20 74 68 65 20 77 61   later in the wa
199e0 6c 20 66 69 6c 65 2e 20 42 75 74 20 69 66 20 76  l file. But if v
199f0 65 72 73 69 6f 6e 20 42 20 68 61 70 70 65 6e 73  ersion B happens
19a00 20 74 6f 20 6c 69 6b 65 20 70 61 73 74 0a 20 20   to like past.  
19a10 2a 2a 20 66 72 61 6d 65 20 70 57 61 6c 2d 3e 68  ** frame pWal->h
19a20 64 72 2e 6d 78 46 72 61 6d 65 20 2d 20 74 68 65  dr.mxFrame - the
19a30 6e 20 74 68 65 20 63 6c 69 65 6e 74 20 77 6f 75  n the client wou
19a40 6c 64 20 69 6e 63 6f 72 72 65 63 74 6c 79 20 61  ld incorrectly a
19a50 73 73 75 6d 65 0a 20 20 2a 2a 20 74 68 61 74 20  ssume.  ** that 
19a60 69 74 20 63 61 6e 20 72 65 61 64 20 76 65 72 73  it can read vers
19a70 69 6f 6e 20 41 20 66 72 6f 6d 20 74 68 65 20 64  ion A from the d
19a80 61 74 61 62 61 73 65 20 66 69 6c 65 2e 20 48 6f  atabase file. Ho
19a90 77 65 76 65 72 2c 20 73 69 6e 63 65 0a 20 20 2a  wever, since.  *
19aa0 2a 20 77 65 20 63 61 6e 20 67 75 61 72 61 6e 74  * we can guarant
19ab0 65 65 20 74 68 61 74 20 74 68 65 20 63 68 65 63  ee that the chec
19ac0 6b 70 6f 69 6e 74 65 72 20 74 68 61 74 20 73 65  kpointer that se
19ad0 74 20 6e 42 61 63 6b 66 69 6c 6c 20 63 6f 75 6c  t nBackfill coul
19ae0 64 20 6e 6f 74 0a 20 20 2a 2a 20 73 65 65 20 61  d not.  ** see a
19af0 6e 79 20 70 61 67 65 73 20 70 61 73 74 20 70 57  ny pages past pW
19b00 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2c  al->hdr.mxFrame,
19b10 20 74 68 69 73 20 70 72 6f 62 6c 65 6d 20 64 6f   this problem do
19b20 65 73 20 6e 6f 74 20 63 6f 6d 65 20 75 70 2e 0a  es not come up..
19b30 20 20 2a 2f 0a 20 20 70 57 61 6c 2d 3e 6d 69 6e    */.  pWal->min
19b40 46 72 61 6d 65 20 3d 20 41 74 6f 6d 69 63 4c 6f  Frame = AtomicLo
19b50 61 64 28 26 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b  ad(&pInfo->nBack
19b60 66 69 6c 6c 29 2b 31 3b 0a 20 20 77 61 6c 53 68  fill)+1;.  walSh
19b70 6d 42 61 72 72 69 65 72 28 70 57 61 6c 29 3b 0a  mBarrier(pWal);.
19b80 20 20 69 66 28 20 41 74 6f 6d 69 63 4c 6f 61 64    if( AtomicLoad
19b90 28 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72  (pInfo->aReadMar
19ba0 6b 2b 6d 78 49 29 21 3d 6d 78 52 65 61 64 4d 61  k+mxI)!=mxReadMa
19bb0 72 6b 0a 20 20 20 7c 7c 20 6d 65 6d 63 6d 70 28  rk.   || memcmp(
19bc0 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78  (void *)walIndex
19bd0 48 64 72 28 70 57 61 6c 29 2c 20 26 70 57 61 6c  Hdr(pWal), &pWal
19be0 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61  ->hdr, sizeof(Wa
19bf0 6c 49 6e 64 65 78 48 64 72 29 29 0a 20 20 29 7b  lIndexHdr)).  ){
19c00 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68  .    walUnlockSh
19c10 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
19c20 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b 0a  EAD_LOCK(mxI));.
19c30 20 20 20 20 72 65 74 75 72 6e 20 57 41 4c 5f 52      return WAL_R
19c40 45 54 52 59 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ETRY;.  }else{. 
19c50 20 20 20 61 73 73 65 72 74 28 20 6d 78 52 65 61     assert( mxRea
19c60 64 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e 68 64 72  dMark<=pWal->hdr
19c70 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20 20  .mxFrame );.    
19c80 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d  pWal->readLock =
19c90 20 28 69 31 36 29 6d 78 49 3b 0a 20 20 7d 0a 20   (i16)mxI;.  }. 
19ca0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 23   return rc;.}..#
19cb0 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
19cc0 42 4c 45 5f 53 4e 41 50 53 48 4f 54 0a 2f 2a 0a  BLE_SNAPSHOT./*.
19cd0 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f 20 72 65  ** Attempt to re
19ce0 64 75 63 65 20 74 68 65 20 76 61 6c 75 65 20 6f  duce the value o
19cf0 66 20 74 68 65 20 57 61 6c 43 6b 70 74 49 6e 66  f the WalCkptInf
19d00 6f 2e 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d  o.nBackfillAttem
19d10 70 74 65 64 20 0a 2a 2a 20 76 61 72 69 61 62 6c  pted .** variabl
19d20 65 20 73 6f 20 74 68 61 74 20 6f 6c 64 65 72 20  e so that older 
19d30 73 6e 61 70 73 68 6f 74 73 20 63 61 6e 20 62 65  snapshots can be
19d40 20 61 63 63 65 73 73 65 64 2e 20 54 6f 20 64 6f   accessed. To do
19d50 20 74 68 69 73 2c 20 6c 6f 6f 70 0a 2a 2a 20 74   this, loop.** t
19d60 68 72 6f 75 67 68 20 61 6c 6c 20 77 61 6c 20 66  hrough all wal f
19d70 72 61 6d 65 73 20 66 72 6f 6d 20 6e 42 61 63 6b  rames from nBack
19d80 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 74 6f  fillAttempted to
19d90 20 28 6e 42 61 63 6b 66 69 6c 6c 2b 31 29 2c 20   (nBackfill+1), 
19da0 0a 2a 2a 20 63 6f 6d 70 61 72 69 6e 67 20 74 68  .** comparing th
19db0 65 69 72 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74  eir content to t
19dc0 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67  he corresponding
19dd0 20 70 61 67 65 20 77 69 74 68 20 74 68 65 20 64   page with the d
19de0 61 74 61 62 61 73 65 0a 2a 2a 20 66 69 6c 65 2c  atabase.** file,
19df0 20 69 66 20 61 6e 79 2e 20 53 65 74 20 6e 42 61   if any. Set nBa
19e00 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 20  ckfillAttempted 
19e10 74 6f 20 74 68 65 20 66 72 61 6d 65 20 6e 75 6d  to the frame num
19e20 62 65 72 20 6f 66 20 74 68 65 0a 2a 2a 20 66 69  ber of the.** fi
19e30 72 73 74 20 66 72 61 6d 65 20 66 6f 72 20 77 68  rst frame for wh
19e40 69 63 68 20 74 68 65 20 77 61 6c 20 66 69 6c 65  ich the wal file
19e50 20 63 6f 6e 74 65 6e 74 20 6d 61 74 63 68 65 73   content matches
19e60 20 74 68 65 20 64 62 20 66 69 6c 65 2e 0a 2a 2a   the db file..**
19e70 0a 2a 2a 20 54 68 69 73 20 69 73 20 6f 6e 6c 79  .** This is only
19e80 20 72 65 61 6c 6c 79 20 73 61 66 65 20 69 66 20   really safe if 
19e90 74 68 65 20 66 69 6c 65 2d 73 79 73 74 65 6d 20  the file-system 
19ea0 69 73 20 73 75 63 68 20 74 68 61 74 20 61 6e 79  is such that any
19eb0 20 70 61 67 65 20 0a 2a 2a 20 77 72 69 74 65 73   page .** writes
19ec0 20 6d 61 64 65 20 62 79 20 65 61 72 6c 69 65 72   made by earlier
19ed0 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 73 20 77   checkpointers w
19ee0 65 72 65 20 61 74 6f 6d 69 63 20 6f 70 65 72 61  ere atomic opera
19ef0 74 69 6f 6e 73 2c 20 77 68 69 63 68 20 0a 2a 2a  tions, which .**
19f00 20 69 73 20 6e 6f 74 20 61 6c 77 61 79 73 20 74   is not always t
19f10 72 75 65 2e 20 49 74 20 69 73 20 61 6c 73 6f 20  rue. It is also 
19f20 70 6f 73 73 69 62 6c 65 20 74 68 61 74 20 6e 42  possible that nB
19f30 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64  ackfillAttempted
19f40 0a 2a 2a 20 6d 61 79 20 62 65 20 6c 65 66 74 20  .** may be left 
19f50 73 65 74 20 74 6f 20 61 20 76 61 6c 75 65 20 6c  set to a value l
19f60 61 72 67 65 72 20 74 68 61 6e 20 65 78 70 65 63  arger than expec
19f70 74 65 64 2c 20 69 66 20 61 20 77 61 6c 20 66 72  ted, if a wal fr
19f80 61 6d 65 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20  ame.** contains 
19f90 63 6f 6e 74 65 6e 74 20 74 68 61 74 20 64 75 70  content that dup
19fa0 6c 69 63 61 74 65 20 6f 66 20 61 6e 20 65 61 72  licate of an ear
19fb0 6c 69 65 72 20 76 65 72 73 69 6f 6e 20 6f 66 20  lier version of 
19fc0 74 68 65 20 73 61 6d 65 0a 2a 2a 20 70 61 67 65  the same.** page
19fd0 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f  ..**.** SQLITE_O
19fe0 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 69 66  K is returned if
19ff0 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
1a000 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
1a010 63 6f 64 65 20 69 66 20 61 6e 0a 2a 2a 20 65 72  code if an.** er
1a020 72 6f 72 20 6f 63 63 75 72 73 2e 20 49 74 20 69  ror occurs. It i
1a030 73 20 6e 6f 74 20 61 6e 20 65 72 72 6f 72 20 69  s not an error i
1a040 66 20 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d  f nBackfillAttem
1a050 70 74 65 64 20 63 61 6e 6e 6f 74 20 62 65 0a 2a  pted cannot be.*
1a060 2a 20 64 65 63 72 65 61 73 65 64 20 61 74 20 61  * decreased at a
1a070 6c 6c 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ll..*/.int sqlit
1a080 65 33 57 61 6c 53 6e 61 70 73 68 6f 74 52 65 63  e3WalSnapshotRec
1a090 6f 76 65 72 28 57 61 6c 20 2a 70 57 61 6c 29 7b  over(Wal *pWal){
1a0a0 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 61 73  .  int rc;..  as
1a0b0 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64  sert( pWal->read
1a0c0 4c 6f 63 6b 3e 3d 30 20 29 3b 0a 20 20 72 63 20  Lock>=0 );.  rc 
1a0d0 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69  = walLockExclusi
1a0e0 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 43 4b 50  ve(pWal, WAL_CKP
1a0f0 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 69 66  T_LOCK, 1);.  if
1a100 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1a110 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  ){.    volatile 
1a120 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e  WalCkptInfo *pIn
1a130 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f  fo = walCkptInfo
1a140 28 70 57 61 6c 29 3b 0a 20 20 20 20 69 6e 74 20  (pWal);.    int 
1a150 73 7a 50 61 67 65 20 3d 20 28 69 6e 74 29 70 57  szPage = (int)pW
1a160 61 6c 2d 3e 73 7a 50 61 67 65 3b 0a 20 20 20 20  al->szPage;.    
1a170 69 36 34 20 73 7a 44 62 3b 20 20 20 20 20 20 20  i64 szDb;       
1a180 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
1a190 69 7a 65 20 6f 66 20 64 62 20 66 69 6c 65 20 69  ize of db file i
1a1a0 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20 20 20  n bytes */..    
1a1b0 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 69  rc = sqlite3OsFi
1a1c0 6c 65 53 69 7a 65 28 70 57 61 6c 2d 3e 70 44 62  leSize(pWal->pDb
1a1d0 46 64 2c 20 26 73 7a 44 62 29 3b 0a 20 20 20 20  Fd, &szDb);.    
1a1e0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
1a1f0 4b 20 29 7b 0a 20 20 20 20 20 20 76 6f 69 64 20  K ){.      void 
1a200 2a 70 42 75 66 31 20 3d 20 73 71 6c 69 74 65 33  *pBuf1 = sqlite3
1a210 5f 6d 61 6c 6c 6f 63 28 73 7a 50 61 67 65 29 3b  _malloc(szPage);
1a220 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 42 75  .      void *pBu
1a230 66 32 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c  f2 = sqlite3_mal
1a240 6c 6f 63 28 73 7a 50 61 67 65 29 3b 0a 20 20 20  loc(szPage);.   
1a250 20 20 20 69 66 28 20 70 42 75 66 31 3d 3d 30 20     if( pBuf1==0 
1a260 7c 7c 20 70 42 75 66 32 3d 3d 30 20 29 7b 0a 20  || pBuf2==0 ){. 
1a270 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
1a280 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
1a290 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 75  }else{.        u
1a2a0 33 32 20 69 20 3d 20 70 49 6e 66 6f 2d 3e 6e 42  32 i = pInfo->nB
1a2b0 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64  ackfillAttempted
1a2c0 3b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 3d  ;.        for(i=
1a2d0 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
1a2e0 41 74 74 65 6d 70 74 65 64 3b 20 69 3e 70 49 6e  Attempted; i>pIn
1a2f0 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3b 20 69  fo->nBackfill; i
1a300 2d 2d 29 7b 0a 20 20 20 20 20 20 20 20 20 20 57  --){.          W
1a310 61 6c 48 61 73 68 4c 6f 63 20 73 4c 6f 63 3b 20  alHashLoc sLoc; 
1a320 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68           /* Hash
1a330 20 74 61 62 6c 65 20 6c 6f 63 61 74 69 6f 6e 20   table location 
1a340 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 75 33 32  */.          u32
1a350 20 70 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20   pgno;          
1a360 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e         /* Page n
1a370 75 6d 62 65 72 20 69 6e 20 64 62 20 66 69 6c 65  umber in db file
1a380 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 69 36   */.          i6
1a390 34 20 69 44 62 4f 66 66 3b 20 20 20 20 20 20 20  4 iDbOff;       
1a3a0 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65          /* Offse
1a3b0 74 20 6f 66 20 64 62 20 66 69 6c 65 20 65 6e 74  t of db file ent
1a3c0 72 79 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  ry */.          
1a3d0 69 36 34 20 69 57 61 6c 4f 66 66 3b 20 20 20 20  i64 iWalOff;    
1a3e0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66            /* Off
1a3f0 73 65 74 20 6f 66 20 77 61 6c 20 66 69 6c 65 20  set of wal file 
1a400 65 6e 74 72 79 20 2a 2f 0a 0a 20 20 20 20 20 20  entry */..      
1a410 20 20 20 20 72 63 20 3d 20 77 61 6c 48 61 73 68      rc = walHash
1a420 47 65 74 28 70 57 61 6c 2c 20 77 61 6c 46 72 61  Get(pWal, walFra
1a430 6d 65 50 61 67 65 28 69 29 2c 20 26 73 4c 6f 63  mePage(i), &sLoc
1a440 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  );.          if(
1a450 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
1a460 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
1a470 20 20 70 67 6e 6f 20 3d 20 73 4c 6f 63 2e 61 50    pgno = sLoc.aP
1a480 67 6e 6f 5b 69 2d 73 4c 6f 63 2e 69 5a 65 72 6f  gno[i-sLoc.iZero
1a490 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 69 44 62  ];.          iDb
1a4a0 4f 66 66 20 3d 20 28 69 36 34 29 28 70 67 6e 6f  Off = (i64)(pgno
1a4b0 2d 31 29 20 2a 20 73 7a 50 61 67 65 3b 0a 0a 20  -1) * szPage;.. 
1a4c0 20 20 20 20 20 20 20 20 20 69 66 28 20 69 44 62           if( iDb
1a4d0 4f 66 66 2b 73 7a 50 61 67 65 3c 3d 73 7a 44 62  Off+szPage<=szDb
1a4e0 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
1a4f0 69 57 61 6c 4f 66 66 20 3d 20 77 61 6c 46 72 61  iWalOff = walFra
1a500 6d 65 4f 66 66 73 65 74 28 69 2c 20 73 7a 50 61  meOffset(i, szPa
1a510 67 65 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  ge) + WAL_FRAME_
1a520 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 20 20 20  HDRSIZE;.       
1a530 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
1a540 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57  3OsRead(pWal->pW
1a550 61 6c 46 64 2c 20 70 42 75 66 31 2c 20 73 7a 50  alFd, pBuf1, szP
1a560 61 67 65 2c 20 69 57 61 6c 4f 66 66 29 3b 0a 0a  age, iWalOff);..
1a570 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20              if( 
1a580 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1a590 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72  .              r
1a5a0 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61  c = sqlite3OsRea
1a5b0 64 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 70  d(pWal->pDbFd, p
1a5c0 42 75 66 32 2c 20 73 7a 50 61 67 65 2c 20 69 44  Buf2, szPage, iD
1a5d0 62 4f 66 66 29 3b 0a 20 20 20 20 20 20 20 20 20  bOff);.         
1a5e0 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 20 20     }..          
1a5f0 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
1a600 5f 4f 4b 20 7c 7c 20 30 3d 3d 6d 65 6d 63 6d 70  _OK || 0==memcmp
1a610 28 70 42 75 66 31 2c 20 70 42 75 66 32 2c 20 73  (pBuf1, pBuf2, s
1a620 7a 50 61 67 65 29 20 29 7b 0a 20 20 20 20 20 20  zPage) ){.      
1a630 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
1a640 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20             }.   
1a650 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20         }..      
1a660 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b      pInfo->nBack
1a670 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 3d 20  fillAttempted = 
1a680 69 2d 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  i-1;.        }. 
1a690 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 73 71       }..      sq
1a6a0 6c 69 74 65 33 5f 66 72 65 65 28 70 42 75 66 31  lite3_free(pBuf1
1a6b0 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
1a6c0 5f 66 72 65 65 28 70 42 75 66 32 29 3b 0a 20 20  _free(pBuf2);.  
1a6d0 20 20 7d 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63    }.    walUnloc
1a6e0 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
1a6f0 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20   WAL_CKPT_LOCK, 
1a700 31 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  1);.  }..  retur
1a710 6e 20 72 63 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f  n rc;.}.#endif /
1a720 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  * SQLITE_ENABLE_
1a730 53 4e 41 50 53 48 4f 54 20 2a 2f 0a 0a 2f 2a 0a  SNAPSHOT */../*.
1a740 2a 2a 20 42 65 67 69 6e 20 61 20 72 65 61 64 20  ** Begin a read 
1a750 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74  transaction on t
1a760 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2a 0a  he database..**.
1a770 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
1a780 75 73 65 64 20 74 6f 20 62 65 20 63 61 6c 6c 65  used to be calle
1a790 64 20 73 71 6c 69 74 65 33 4f 70 65 6e 53 6e 61  d sqlite3OpenSna
1a7a0 70 73 68 6f 74 28 29 20 61 6e 64 20 77 69 74 68  pshot() and with
1a7b0 20 67 6f 6f 64 20 72 65 61 73 6f 6e 3a 0a 2a 2a   good reason:.**
1a7c0 20 69 74 20 74 61 6b 65 73 20 61 20 73 6e 61 70   it takes a snap
1a7d0 73 68 6f 74 20 6f 66 20 74 68 65 20 73 74 61 74  shot of the stat
1a7e0 65 20 6f 66 20 74 68 65 20 57 41 4c 20 61 6e 64  e of the WAL and
1a7f0 20 77 61 6c 2d 69 6e 64 65 78 20 66 6f 72 20 74   wal-index for t
1a800 68 65 20 63 75 72 72 65 6e 74 0a 2a 2a 20 69 6e  he current.** in
1a810 73 74 61 6e 74 20 69 6e 20 74 69 6d 65 2e 20 20  stant in time.  
1a820 54 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65  The current thre
1a830 61 64 20 77 69 6c 6c 20 63 6f 6e 74 69 6e 75 65  ad will continue
1a840 20 74 6f 20 75 73 65 20 74 68 69 73 20 73 6e 61   to use this sna
1a850 70 73 68 6f 74 2e 0a 2a 2a 20 4f 74 68 65 72 20  pshot..** Other 
1a860 74 68 72 65 61 64 73 20 6d 69 67 68 74 20 61 70  threads might ap
1a870 70 65 6e 64 20 6e 65 77 20 63 6f 6e 74 65 6e 74  pend new content
1a880 20 74 6f 20 74 68 65 20 57 41 4c 20 61 6e 64 20   to the WAL and 
1a890 77 61 6c 2d 69 6e 64 65 78 20 62 75 74 0a 2a 2a  wal-index but.**
1a8a0 20 74 68 61 74 20 65 78 74 72 61 20 63 6f 6e 74   that extra cont
1a8b0 65 6e 74 20 69 73 20 69 67 6e 6f 72 65 64 20 62  ent is ignored b
1a8c0 79 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68  y the current th
1a8d0 72 65 61 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  read..**.** If t
1a8e0 68 65 20 64 61 74 61 62 61 73 65 20 63 6f 6e 74  he database cont
1a8f0 65 6e 74 73 20 68 61 76 65 20 63 68 61 6e 67 65  ents have change
1a900 73 20 73 69 6e 63 65 20 74 68 65 20 70 72 65 76  s since the prev
1a910 69 6f 75 73 20 72 65 61 64 0a 2a 2a 20 74 72 61  ious read.** tra
1a920 6e 73 61 63 74 69 6f 6e 2c 20 74 68 65 6e 20 2a  nsaction, then *
1a930 70 43 68 61 6e 67 65 64 20 69 73 20 73 65 74 20  pChanged is set 
1a940 74 6f 20 31 20 62 65 66 6f 72 65 20 72 65 74 75  to 1 before retu
1a950 72 6e 69 6e 67 2e 20 20 54 68 65 0a 2a 2a 20 50  rning.  The.** P
1a960 61 67 65 72 20 6c 61 79 65 72 20 77 69 6c 6c 20  ager layer will 
1a970 75 73 65 20 74 68 69 73 20 74 6f 20 6b 6e 6f 77  use this to know
1a980 20 74 68 61 74 20 69 74 73 20 63 61 63 68 65 20   that its cache 
1a990 69 73 20 73 74 61 6c 65 20 61 6e 64 0a 2a 2a 20  is stale and.** 
1a9a0 6e 65 65 64 73 20 74 6f 20 62 65 20 66 6c 75 73  needs to be flus
1a9b0 68 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  hed..*/.int sqli
1a9c0 74 65 33 57 61 6c 42 65 67 69 6e 52 65 61 64 54  te3WalBeginReadT
1a9d0 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a  ransaction(Wal *
1a9e0 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e  pWal, int *pChan
1a9f0 67 65 64 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  ged){.  int rc; 
1aa00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1aa10 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
1aa20 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
1aa30 63 6e 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20  cnt = 0;        
1aa40 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
1aa50 75 6d 62 65 72 20 6f 66 20 54 72 79 42 65 67 69  umber of TryBegi
1aa60 6e 52 65 61 64 20 61 74 74 65 6d 70 74 73 20 2a  nRead attempts *
1aa70 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  /..#ifdef SQLITE
1aa80 5f 45 4e 41 42 4c 45 5f 53 4e 41 50 53 48 4f 54  _ENABLE_SNAPSHOT
1aa90 0a 20 20 69 6e 74 20 62 43 68 61 6e 67 65 64 20  .  int bChanged 
1aaa0 3d 20 30 3b 0a 20 20 57 61 6c 49 6e 64 65 78 48  = 0;.  WalIndexH
1aab0 64 72 20 2a 70 53 6e 61 70 73 68 6f 74 20 3d 20  dr *pSnapshot = 
1aac0 70 57 61 6c 2d 3e 70 53 6e 61 70 73 68 6f 74 3b  pWal->pSnapshot;
1aad0 0a 20 20 69 66 28 20 70 53 6e 61 70 73 68 6f 74  .  if( pSnapshot
1aae0 20 26 26 20 6d 65 6d 63 6d 70 28 70 53 6e 61 70   && memcmp(pSnap
1aaf0 73 68 6f 74 2c 20 26 70 57 61 6c 2d 3e 68 64 72  shot, &pWal->hdr
1ab00 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65  , sizeof(WalInde
1ab10 78 48 64 72 29 29 21 3d 30 20 29 7b 0a 20 20 20  xHdr))!=0 ){.   
1ab20 20 62 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20   bChanged = 1;. 
1ab30 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 64 6f 7b   }.#endif..  do{
1ab40 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 54 72 79  .    rc = walTry
1ab50 42 65 67 69 6e 52 65 61 64 28 70 57 61 6c 2c 20  BeginRead(pWal, 
1ab60 70 43 68 61 6e 67 65 64 2c 20 30 2c 20 2b 2b 63  pChanged, 0, ++c
1ab70 6e 74 29 3b 0a 20 20 7d 77 68 69 6c 65 28 20 72  nt);.  }while( r
1ab80 63 3d 3d 57 41 4c 5f 52 45 54 52 59 20 29 3b 0a  c==WAL_RETRY );.
1ab90 20 20 74 65 73 74 63 61 73 65 28 20 28 72 63 26    testcase( (rc&
1aba0 30 78 66 66 29 3d 3d 53 51 4c 49 54 45 5f 42 55  0xff)==SQLITE_BU
1abb0 53 59 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65  SY );.  testcase
1abc0 28 20 28 72 63 26 30 78 66 66 29 3d 3d 53 51 4c  ( (rc&0xff)==SQL
1abd0 49 54 45 5f 49 4f 45 52 52 20 29 3b 0a 20 20 74  ITE_IOERR );.  t
1abe0 65 73 74 63 61 73 65 28 20 72 63 3d 3d 53 51 4c  estcase( rc==SQL
1abf0 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 20 29 3b 0a  ITE_PROTOCOL );.
1ac00 20 20 74 65 73 74 63 61 73 65 28 20 72 63 3d 3d    testcase( rc==
1ac10 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 0a 23 69  SQLITE_OK );..#i
1ac20 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42  fdef SQLITE_ENAB
1ac30 4c 45 5f 53 4e 41 50 53 48 4f 54 0a 20 20 69 66  LE_SNAPSHOT.  if
1ac40 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1ac50 29 7b 0a 20 20 20 20 69 66 28 20 70 53 6e 61 70  ){.    if( pSnap
1ac60 73 68 6f 74 20 26 26 20 6d 65 6d 63 6d 70 28 70  shot && memcmp(p
1ac70 53 6e 61 70 73 68 6f 74 2c 20 26 70 57 61 6c 2d  Snapshot, &pWal-
1ac80 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c  >hdr, sizeof(Wal
1ac90 49 6e 64 65 78 48 64 72 29 29 21 3d 30 20 29 7b  IndexHdr))!=0 ){
1aca0 0a 20 20 20 20 20 20 2f 2a 20 41 74 20 74 68 69  .      /* At thi
1acb0 73 20 70 6f 69 6e 74 20 74 68 65 20 63 6c 69 65  s point the clie
1acc0 6e 74 20 68 61 73 20 61 20 6c 6f 63 6b 20 6f 6e  nt has a lock on
1acd0 20 61 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20   an aReadMark[] 
1ace0 73 6c 6f 74 20 68 6f 6c 64 69 6e 67 0a 20 20 20  slot holding.   
1acf0 20 20 20 2a 2a 20 61 20 76 61 6c 75 65 20 65 71     ** a value eq
1ad00 75 61 6c 20 74 6f 20 6f 72 20 73 6d 61 6c 6c 65  ual to or smalle
1ad10 72 20 74 68 61 6e 20 70 53 6e 61 70 73 68 6f 74  r than pSnapshot
1ad20 2d 3e 6d 78 46 72 61 6d 65 2c 20 62 75 74 20 70  ->mxFrame, but p
1ad30 57 61 6c 2d 3e 68 64 72 0a 20 20 20 20 20 20 2a  Wal->hdr.      *
1ad40 2a 20 69 73 20 70 6f 70 75 6c 61 74 65 64 20 77  * is populated w
1ad50 69 74 68 20 74 68 65 20 77 61 6c 2d 69 6e 64 65  ith the wal-inde
1ad60 78 20 68 65 61 64 65 72 20 63 6f 72 72 65 73 70  x header corresp
1ad70 6f 6e 64 69 6e 67 20 74 6f 20 74 68 65 20 68 65  onding to the he
1ad80 61 64 0a 20 20 20 20 20 20 2a 2a 20 6f 66 20 74  ad.      ** of t
1ad90 68 65 20 77 61 6c 20 66 69 6c 65 2e 20 56 65 72  he wal file. Ver
1ada0 69 66 79 20 74 68 61 74 20 70 53 6e 61 70 73 68  ify that pSnapsh
1adb0 6f 74 20 69 73 20 73 74 69 6c 6c 20 76 61 6c 69  ot is still vali
1adc0 64 20 62 65 66 6f 72 65 0a 20 20 20 20 20 20 2a  d before.      *
1add0 2a 20 63 6f 6e 74 69 6e 75 69 6e 67 2e 20 20 52  * continuing.  R
1ade0 65 61 73 6f 6e 73 20 77 68 79 20 70 53 6e 61 70  easons why pSnap
1adf0 73 68 6f 74 20 6d 69 67 68 74 20 6e 6f 20 6c 6f  shot might no lo
1ae00 6e 67 65 72 20 62 65 20 76 61 6c 69 64 3a 0a 20  nger be valid:. 
1ae10 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a       **.      **
1ae20 20 20 20 20 28 31 29 20 20 54 68 65 20 57 41 4c      (1)  The WAL
1ae30 20 66 69 6c 65 20 68 61 73 20 62 65 65 6e 20 72   file has been r
1ae40 65 73 65 74 20 73 69 6e 63 65 20 74 68 65 20 73  eset since the s
1ae50 6e 61 70 73 68 6f 74 20 77 61 73 20 74 61 6b 65  napshot was take
1ae60 6e 2e 0a 20 20 20 20 20 20 2a 2a 20 20 20 20 20  n..      **     
1ae70 20 20 20 20 49 6e 20 74 68 69 73 20 63 61 73 65      In this case
1ae80 2c 20 74 68 65 20 73 61 6c 74 20 77 69 6c 6c 20  , the salt will 
1ae90 68 61 76 65 20 63 68 61 6e 67 65 64 2e 0a 20 20  have changed..  
1aea0 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20      **.      ** 
1aeb0 20 20 20 28 32 29 20 20 41 20 63 68 65 63 6b 70     (2)  A checkp
1aec0 6f 69 6e 74 20 61 73 20 62 65 65 6e 20 61 74 74  oint as been att
1aed0 65 6d 70 74 65 64 20 74 68 61 74 20 77 72 6f 74  empted that wrot
1aee0 65 20 66 72 61 6d 65 73 20 70 61 73 74 0a 20 20  e frames past.  
1aef0 20 20 20 20 2a 2a 20 20 20 20 20 20 20 20 20 70      **         p
1af00 53 6e 61 70 73 68 6f 74 2d 3e 6d 78 46 72 61 6d  Snapshot->mxFram
1af10 65 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  e into the datab
1af20 61 73 65 20 66 69 6c 65 2e 20 20 4e 6f 74 65 20  ase file.  Note 
1af30 74 68 61 74 20 74 68 65 0a 20 20 20 20 20 20 2a  that the.      *
1af40 2a 20 20 20 20 20 20 20 20 20 63 68 65 63 6b 70  *         checkp
1af50 6f 69 6e 74 20 6e 65 65 64 20 6e 6f 74 20 68 61  oint need not ha
1af60 76 65 20 63 6f 6d 70 6c 65 74 65 64 20 66 6f 72  ve completed for
1af70 20 74 68 69 73 20 74 6f 20 63 61 75 73 65 20 70   this to cause p
1af80 72 6f 62 6c 65 6d 73 2e 0a 20 20 20 20 20 20 2a  roblems..      *
1af90 2f 0a 20 20 20 20 20 20 76 6f 6c 61 74 69 6c 65  /.      volatile
1afa0 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49   WalCkptInfo *pI
1afb0 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66  nfo = walCkptInf
1afc0 6f 28 70 57 61 6c 29 3b 0a 0a 20 20 20 20 20 20  o(pWal);..      
1afd0 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65  assert( pWal->re
1afe0 61 64 4c 6f 63 6b 3e 30 20 7c 7c 20 70 57 61 6c  adLock>0 || pWal
1aff0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 30  ->hdr.mxFrame==0
1b000 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74   );.      assert
1b010 28 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61  ( pInfo->aReadMa
1b020 72 6b 5b 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  rk[pWal->readLoc
1b030 6b 5d 3c 3d 70 53 6e 61 70 73 68 6f 74 2d 3e 6d  k]<=pSnapshot->m
1b040 78 46 72 61 6d 65 20 29 3b 0a 0a 20 20 20 20 20  xFrame );..     
1b050 20 2f 2a 20 49 74 20 69 73 20 70 6f 73 73 69 62   /* It is possib
1b060 6c 65 20 74 68 61 74 20 74 68 65 72 65 20 69 73  le that there is
1b070 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 20   a checkpointer 
1b080 74 68 72 65 61 64 20 72 75 6e 6e 69 6e 67 20 0a  thread running .
1b090 20 20 20 20 20 20 2a 2a 20 63 6f 6e 63 75 72 72        ** concurr
1b0a0 65 6e 74 20 77 69 74 68 20 74 68 69 73 20 63 6f  ent with this co
1b0b0 64 65 2e 20 49 66 20 74 68 69 73 20 69 73 20 74  de. If this is t
1b0c0 68 65 20 63 61 73 65 2c 20 69 74 20 6d 61 79 20  he case, it may 
1b0d0 62 65 20 74 68 61 74 20 74 68 65 0a 20 20 20 20  be that the.    
1b0e0 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 65    ** checkpointe
1b0f0 72 20 68 61 73 20 61 6c 72 65 61 64 79 20 64 65  r has already de
1b100 74 65 72 6d 69 6e 65 64 20 74 68 61 74 20 69 74  termined that it
1b110 20 77 69 6c 6c 20 63 68 65 63 6b 70 6f 69 6e 74   will checkpoint
1b120 20 0a 20 20 20 20 20 20 2a 2a 20 73 6e 61 70 73   .      ** snaps
1b130 68 6f 74 20 58 2c 20 77 68 65 72 65 20 58 20 69  hot X, where X i
1b140 73 20 6c 61 74 65 72 20 69 6e 20 74 68 65 20 77  s later in the w
1b150 61 6c 20 66 69 6c 65 20 74 68 61 6e 20 70 53 6e  al file than pSn
1b160 61 70 73 68 6f 74 2c 20 62 75 74 20 0a 20 20 20  apshot, but .   
1b170 20 20 20 2a 2a 20 68 61 73 20 6e 6f 74 20 79 65     ** has not ye
1b180 74 20 73 65 74 20 74 68 65 20 70 49 6e 66 6f 2d  t set the pInfo-
1b190 3e 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70  >nBackfillAttemp
1b1a0 74 65 64 20 76 61 72 69 61 62 6c 65 20 74 6f 20  ted variable to 
1b1b0 69 6e 64 69 63 61 74 65 20 0a 20 20 20 20 20 20  indicate .      
1b1c0 2a 2a 20 69 74 73 20 69 6e 74 65 6e 74 2e 20 54  ** its intent. T
1b1d0 6f 20 61 76 6f 69 64 20 74 68 65 20 72 61 63 65  o avoid the race
1b1e0 20 63 6f 6e 64 69 74 69 6f 6e 20 74 68 69 73 20   condition this 
1b1f0 6c 65 61 64 73 20 74 6f 2c 20 65 6e 73 75 72 65  leads to, ensure
1b200 20 74 68 61 74 0a 20 20 20 20 20 20 2a 2a 20 74   that.      ** t
1b210 68 65 72 65 20 69 73 20 6e 6f 20 63 68 65 63 6b  here is no check
1b220 70 6f 69 6e 74 65 72 20 70 72 6f 63 65 73 73 20  pointer process 
1b230 62 79 20 74 61 6b 69 6e 67 20 61 20 73 68 61 72  by taking a shar
1b240 65 64 20 43 4b 50 54 20 6c 6f 63 6b 20 0a 20 20  ed CKPT lock .  
1b250 20 20 20 20 2a 2a 20 62 65 66 6f 72 65 20 63 68      ** before ch
1b260 65 63 6b 69 6e 67 20 70 49 6e 66 6f 2d 3e 6e 42  ecking pInfo->nB
1b270 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64  ackfillAttempted
1b280 2e 20 20 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20  .  .      **.   
1b290 20 20 20 2a 2a 20 54 4f 44 4f 3a 20 44 6f 65 73     ** TODO: Does
1b2a0 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d   the aReadMark[]
1b2b0 20 6c 6f 63 6b 20 70 72 65 76 65 6e 74 20 61 20   lock prevent a 
1b2c0 63 68 65 63 6b 70 6f 69 6e 74 65 72 20 66 72 6f  checkpointer fro
1b2d0 6d 20 64 6f 69 6e 67 0a 20 20 20 20 20 20 2a 2a  m doing.      **
1b2e0 20 20 20 20 20 20 20 74 68 69 73 20 61 6c 72 65         this alre
1b2f0 61 64 79 3f 0a 20 20 20 20 20 20 2a 2f 0a 20 20  ady?.      */.  
1b300 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b      rc = walLock
1b310 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c  Shared(pWal, WAL
1b320 5f 43 4b 50 54 5f 4c 4f 43 4b 29 3b 0a 0a 20 20  _CKPT_LOCK);..  
1b330 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
1b340 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
1b350 20 2f 2a 20 43 68 65 63 6b 20 74 68 61 74 20 74   /* Check that t
1b360 68 65 20 77 61 6c 20 66 69 6c 65 20 68 61 73 20  he wal file has 
1b370 6e 6f 74 20 62 65 65 6e 20 77 72 61 70 70 65 64  not been wrapped
1b380 2e 20 41 73 73 75 6d 69 6e 67 20 74 68 61 74 20  . Assuming that 
1b390 69 74 20 68 61 73 0a 20 20 20 20 20 20 20 20 2a  it has.        *
1b3a0 2a 20 6e 6f 74 2c 20 61 6c 73 6f 20 63 68 65 63  * not, also chec
1b3b0 6b 20 74 68 61 74 20 6e 6f 20 63 68 65 63 6b 70  k that no checkp
1b3c0 6f 69 6e 74 65 72 20 68 61 73 20 61 74 74 65 6d  ointer has attem
1b3d0 70 74 65 64 20 74 6f 20 63 68 65 63 6b 70 6f 69  pted to checkpoi
1b3e0 6e 74 20 61 6e 79 0a 20 20 20 20 20 20 20 20 2a  nt any.        *
1b3f0 2a 20 66 72 61 6d 65 73 20 62 65 79 6f 6e 64 20  * frames beyond 
1b400 70 53 6e 61 70 73 68 6f 74 2d 3e 6d 78 46 72 61  pSnapshot->mxFra
1b410 6d 65 2e 20 49 66 20 65 69 74 68 65 72 20 6f 66  me. If either of
1b420 20 74 68 65 73 65 20 63 6f 6e 64 69 74 69 6f 6e   these condition
1b430 73 20 61 72 65 0a 20 20 20 20 20 20 20 20 2a 2a  s are.        **
1b440 20 74 72 75 65 2c 20 72 65 74 75 72 6e 20 53 51   true, return SQ
1b450 4c 49 54 45 5f 45 52 52 4f 52 5f 53 4e 41 50 53  LITE_ERROR_SNAPS
1b460 48 4f 54 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  HOT. Otherwise, 
1b470 6f 76 65 72 77 72 69 74 65 20 70 57 61 6c 2d 3e  overwrite pWal->
1b480 68 64 72 0a 20 20 20 20 20 20 20 20 2a 2a 20 77  hdr.        ** w
1b490 69 74 68 20 2a 70 53 6e 61 70 73 68 6f 74 20 61  ith *pSnapshot a
1b4a0 6e 64 20 73 65 74 20 2a 70 43 68 61 6e 67 65 64  nd set *pChanged
1b4b0 20 61 73 20 61 70 70 72 6f 70 72 69 61 74 65 20   as appropriate 
1b4c0 66 6f 72 20 6f 70 65 6e 69 6e 67 20 74 68 65 0a  for opening the.
1b4d0 20 20 20 20 20 20 20 20 2a 2a 20 73 6e 61 70 73          ** snaps
1b4e0 68 6f 74 2e 20 20 2a 2f 0a 20 20 20 20 20 20 20  hot.  */.       
1b4f0 20 69 66 28 20 21 6d 65 6d 63 6d 70 28 70 53 6e   if( !memcmp(pSn
1b500 61 70 73 68 6f 74 2d 3e 61 53 61 6c 74 2c 20 70  apshot->aSalt, p
1b510 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20  Wal->hdr.aSalt, 
1b520 73 69 7a 65 6f 66 28 70 57 61 6c 2d 3e 68 64 72  sizeof(pWal->hdr
1b530 2e 61 53 61 6c 74 29 29 0a 20 20 20 20 20 20 20  .aSalt)).       
1b540 20 20 26 26 20 70 53 6e 61 70 73 68 6f 74 2d 3e    && pSnapshot->
1b550 6d 78 46 72 61 6d 65 3e 3d 70 49 6e 66 6f 2d 3e  mxFrame>=pInfo->
1b560 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74  nBackfillAttempt
1b570 65 64 0a 20 20 20 20 20 20 20 20 29 7b 0a 20 20  ed.        ){.  
1b580 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
1b590 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 30  pWal->readLock>0
1b5a0 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20 6d 65   );.          me
1b5b0 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c  mcpy(&pWal->hdr,
1b5c0 20 70 53 6e 61 70 73 68 6f 74 2c 20 73 69 7a 65   pSnapshot, size
1b5d0 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
1b5e0 3b 0a 20 20 20 20 20 20 20 20 20 20 2a 70 43 68  ;.          *pCh
1b5f0 61 6e 67 65 64 20 3d 20 62 43 68 61 6e 67 65 64  anged = bChanged
1b600 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b  ;.        }else{
1b610 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
1b620 53 51 4c 49 54 45 5f 45 52 52 4f 52 5f 53 4e 41  SQLITE_ERROR_SNA
1b630 50 53 48 4f 54 3b 0a 20 20 20 20 20 20 20 20 7d  PSHOT;.        }
1b640 0a 0a 20 20 20 20 20 20 20 20 2f 2a 20 52 65 6c  ..        /* Rel
1b650 65 61 73 65 20 74 68 65 20 73 68 61 72 65 64 20  ease the shared 
1b660 43 4b 50 54 20 6c 6f 63 6b 20 6f 62 74 61 69 6e  CKPT lock obtain
1b670 65 64 20 61 62 6f 76 65 2e 20 2a 2f 0a 20 20 20  ed above. */.   
1b680 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68       walUnlockSh
1b690 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 43  ared(pWal, WAL_C
1b6a0 4b 50 54 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 20  KPT_LOCK);.     
1b6b0 20 20 20 70 57 61 6c 2d 3e 6d 69 6e 46 72 61 6d     pWal->minFram
1b6c0 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 0a  e = 1;.      }..
1b6d0 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
1b6e0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1b6f0 20 20 20 20 73 71 6c 69 74 65 33 57 61 6c 45 6e      sqlite3WalEn
1b700 64 52 65 61 64 54 72 61 6e 73 61 63 74 69 6f 6e  dReadTransaction
1b710 28 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 7d 0a  (pWal);.      }.
1b720 20 20 20 20 7d 0a 20 20 7d 0a 23 65 6e 64 69 66      }.  }.#endif
1b730 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
1b740 0a 2f 2a 0a 2a 2a 20 46 69 6e 69 73 68 20 77 69  ./*.** Finish wi
1b750 74 68 20 61 20 72 65 61 64 20 74 72 61 6e 73 61  th a read transa
1b760 63 74 69 6f 6e 2e 20 20 41 6c 6c 20 74 68 69 73  ction.  All this
1b770 20 64 6f 65 73 20 69 73 20 72 65 6c 65 61 73 65   does is release
1b780 20 74 68 65 0a 2a 2a 20 72 65 61 64 2d 6c 6f 63   the.** read-loc
1b790 6b 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  k..*/.void sqlit
1b7a0 65 33 57 61 6c 45 6e 64 52 65 61 64 54 72 61 6e  e3WalEndReadTran
1b7b0 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61  saction(Wal *pWa
1b7c0 6c 29 7b 0a 20 20 73 71 6c 69 74 65 33 57 61 6c  l){.  sqlite3Wal
1b7d0 45 6e 64 57 72 69 74 65 54 72 61 6e 73 61 63 74  EndWriteTransact
1b7e0 69 6f 6e 28 70 57 61 6c 29 3b 0a 20 20 69 66 28  ion(pWal);.  if(
1b7f0 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e   pWal->readLock>
1b800 3d 30 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c  =0 ){.    walUnl
1b810 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20  ockShared(pWal, 
1b820 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57  WAL_READ_LOCK(pW
1b830 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 3b 0a  al->readLock));.
1b840 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f      pWal->readLo
1b850 63 6b 20 3d 20 2d 31 3b 0a 20 20 7d 0a 7d 0a 0a  ck = -1;.  }.}..
1b860 2f 2a 0a 2a 2a 20 53 65 61 72 63 68 20 74 68 65  /*.** Search the
1b870 20 77 61 6c 20 66 69 6c 65 20 66 6f 72 20 70 61   wal file for pa
1b880 67 65 20 70 67 6e 6f 2e 20 49 66 20 66 6f 75 6e  ge pgno. If foun
1b890 64 2c 20 73 65 74 20 2a 70 69 52 65 61 64 20 74  d, set *piRead t
1b8a0 6f 20 74 68 65 20 66 72 61 6d 65 20 74 68 61 74  o the frame that
1b8b0 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  .** contains the
1b8c0 20 70 61 67 65 2e 20 4f 74 68 65 72 77 69 73 65   page. Otherwise
1b8d0 2c 20 69 66 20 70 67 6e 6f 20 69 73 20 6e 6f 74  , if pgno is not
1b8e0 20 69 6e 20 74 68 65 20 77 61 6c 20 66 69 6c 65   in the wal file
1b8f0 2c 20 73 65 74 20 2a 70 69 52 65 61 64 0a 2a 2a  , set *piRead.**
1b900 20 74 6f 20 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20   to zero..**.** 
1b910 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  Return SQLITE_OK
1b920 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
1b930 6f 72 20 61 6e 20 65 72 72 6f 72 20 63 6f 64 65  or an error code
1b940 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
1b950 75 72 73 2e 20 49 66 20 61 6e 0a 2a 2a 20 65 72  urs. If an.** er
1b960 72 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c 20  ror does occur, 
1b970 74 68 65 20 66 69 6e 61 6c 20 76 61 6c 75 65 20  the final value 
1b980 6f 66 20 2a 70 69 52 65 61 64 20 69 73 20 75 6e  of *piRead is un
1b990 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74 20  defined..*/.int 
1b9a0 73 71 6c 69 74 65 33 57 61 6c 46 69 6e 64 46 72  sqlite3WalFindFr
1b9b0 61 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c  ame(.  Wal *pWal
1b9c0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1b9d0 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 68 61         /* WAL ha
1b9e0 6e 64 6c 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70  ndle */.  Pgno p
1b9f0 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20 20  gno,            
1ba00 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
1ba10 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65  abase page numbe
1ba20 72 20 74 6f 20 72 65 61 64 20 64 61 74 61 20 66  r to read data f
1ba30 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 52  or */.  u32 *piR
1ba40 65 61 64 20 20 20 20 20 20 20 20 20 20 20 20 20  ead             
1ba50 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
1ba60 46 72 61 6d 65 20 6e 75 6d 62 65 72 20 28 6f 72  Frame number (or
1ba70 20 7a 65 72 6f 29 20 2a 2f 0a 29 7b 0a 20 20 75   zero) */.){.  u
1ba80 33 32 20 69 52 65 61 64 20 3d 20 30 3b 20 20 20  32 iRead = 0;   
1ba90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1baa0 2a 20 49 66 20 21 3d 30 2c 20 57 41 4c 20 66 72  * If !=0, WAL fr
1bab0 61 6d 65 20 74 6f 20 72 65 74 75 72 6e 20 64 61  ame to return da
1bac0 74 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 75 33 32  ta from */.  u32
1bad0 20 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d 3e 68   iLast = pWal->h
1bae0 64 72 2e 6d 78 46 72 61 6d 65 3b 20 20 2f 2a 20  dr.mxFrame;  /* 
1baf0 4c 61 73 74 20 70 61 67 65 20 69 6e 20 57 41 4c  Last page in WAL
1bb00 20 66 6f 72 20 74 68 69 73 20 72 65 61 64 65 72   for this reader
1bb10 20 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73 68 3b   */.  int iHash;
1bb20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bb30 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f        /* Used to
1bb40 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20 4e 20   loop through N 
1bb50 68 61 73 68 20 74 61 62 6c 65 73 20 2a 2f 0a 20  hash tables */. 
1bb60 20 69 6e 74 20 69 4d 69 6e 48 61 73 68 3b 0a 0a   int iMinHash;..
1bb70 20 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69 6e    /* This routin
1bb80 65 20 69 73 20 6f 6e 6c 79 20 62 65 20 63 61 6c  e is only be cal
1bb90 6c 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e 20  led from within 
1bba0 61 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  a read transacti
1bbb0 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  on. */.  assert(
1bbc0 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e   pWal->readLock>
1bbd0 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b  =0 || pWal->lock
1bbe0 45 72 72 6f 72 20 29 3b 0a 0a 20 20 2f 2a 20 49  Error );..  /* I
1bbf0 66 20 74 68 65 20 22 6c 61 73 74 20 70 61 67 65  f the "last page
1bc00 22 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20 77  " field of the w
1bc10 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
1bc20 73 6e 61 70 73 68 6f 74 20 69 73 20 30 2c 20 74  snapshot is 0, t
1bc30 68 65 6e 0a 20 20 2a 2a 20 6e 6f 20 64 61 74 61  hen.  ** no data
1bc40 20 77 69 6c 6c 20 62 65 20 72 65 61 64 20 66 72   will be read fr
1bc50 6f 6d 20 74 68 65 20 77 61 6c 20 75 6e 64 65 72  om the wal under
1bc60 20 61 6e 79 20 63 69 72 63 75 6d 73 74 61 6e 63   any circumstanc
1bc70 65 73 2e 20 52 65 74 75 72 6e 20 65 61 72 6c 79  es. Return early
1bc80 0a 20 20 2a 2a 20 69 6e 20 74 68 69 73 20 63 61  .  ** in this ca
1bc90 73 65 20 61 73 20 61 6e 20 6f 70 74 69 6d 69 7a  se as an optimiz
1bca0 61 74 69 6f 6e 2e 20 20 4c 69 6b 65 77 69 73 65  ation.  Likewise
1bcb0 2c 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c  , if pWal->readL
1bcc0 6f 63 6b 3d 3d 30 2c 20 0a 20 20 2a 2a 20 74 68  ock==0, .  ** th
1bcd0 65 6e 20 74 68 65 20 57 41 4c 20 69 73 20 69 67  en the WAL is ig
1bce0 6e 6f 72 65 64 20 62 79 20 74 68 65 20 72 65 61  nored by the rea
1bcf0 64 65 72 20 73 6f 20 72 65 74 75 72 6e 20 65 61  der so return ea
1bd00 72 6c 79 2c 20 61 73 20 69 66 20 74 68 65 20 0a  rly, as if the .
1bd10 20 20 2a 2a 20 57 41 4c 20 77 65 72 65 20 65 6d    ** WAL were em
1bd20 70 74 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  pty..  */.  if( 
1bd30 69 4c 61 73 74 3d 3d 30 20 7c 7c 20 28 70 57 61  iLast==0 || (pWa
1bd40 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20 26  l->readLock==0 &
1bd50 26 20 70 57 61 6c 2d 3e 62 53 68 6d 55 6e 72 65  & pWal->bShmUnre
1bd60 6c 69 61 62 6c 65 3d 3d 30 29 20 29 7b 0a 20 20  liable==0) ){.  
1bd70 20 20 2a 70 69 52 65 61 64 20 3d 20 30 3b 0a 20    *piRead = 0;. 
1bd80 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
1bd90 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53  _OK;.  }..  /* S
1bda0 65 61 72 63 68 20 74 68 65 20 68 61 73 68 20 74  earch the hash t
1bdb0 61 62 6c 65 20 6f 72 20 74 61 62 6c 65 73 20 66  able or tables f
1bdc0 6f 72 20 61 6e 20 65 6e 74 72 79 20 6d 61 74 63  or an entry matc
1bdd0 68 69 6e 67 20 70 61 67 65 20 6e 75 6d 62 65 72  hing page number
1bde0 0a 20 20 2a 2a 20 70 67 6e 6f 2e 20 45 61 63 68  .  ** pgno. Each
1bdf0 20 69 74 65 72 61 74 69 6f 6e 20 6f 66 20 74 68   iteration of th
1be00 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 66 6f 72 28  e following for(
1be10 29 20 6c 6f 6f 70 20 73 65 61 72 63 68 65 73 20  ) loop searches 
1be20 6f 6e 65 0a 20 20 2a 2a 20 68 61 73 68 20 74 61  one.  ** hash ta
1be30 62 6c 65 20 28 65 61 63 68 20 68 61 73 68 20 74  ble (each hash t
1be40 61 62 6c 65 20 69 6e 64 65 78 65 73 20 75 70 20  able indexes up 
1be50 74 6f 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  to HASHTABLE_NPA
1be60 47 45 20 66 72 61 6d 65 73 29 2e 0a 20 20 2a 2a  GE frames)..  **
1be70 0a 20 20 2a 2a 20 54 68 69 73 20 63 6f 64 65 20  .  ** This code 
1be80 6d 69 67 68 74 20 72 75 6e 20 63 6f 6e 63 75 72  might run concur
1be90 72 65 6e 74 6c 79 20 74 6f 20 74 68 65 20 63 6f  rently to the co
1bea0 64 65 20 69 6e 20 77 61 6c 49 6e 64 65 78 41 70  de in walIndexAp
1beb0 70 65 6e 64 28 29 0a 20 20 2a 2a 20 74 68 61 74  pend().  ** that
1bec0 20 61 64 64 73 20 65 6e 74 72 69 65 73 20 74 6f   adds entries to
1bed0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 28   the wal-index (
1bee0 61 6e 64 20 70 6f 73 73 69 62 6c 79 20 74 6f 20  and possibly to 
1bef0 74 68 69 73 20 68 61 73 68 20 0a 20 20 2a 2a 20  this hash .  ** 
1bf00 74 61 62 6c 65 29 2e 20 54 68 69 73 20 6d 65 61  table). This mea
1bf10 6e 73 20 74 68 65 20 76 61 6c 75 65 20 6a 75 73  ns the value jus
1bf20 74 20 72 65 61 64 20 66 72 6f 6d 20 74 68 65 20  t read from the 
1bf30 68 61 73 68 20 0a 20 20 2a 2a 20 73 6c 6f 74 20  hash .  ** slot 
1bf40 28 61 48 61 73 68 5b 69 4b 65 79 5d 29 20 6d 61  (aHash[iKey]) ma
1bf50 79 20 68 61 76 65 20 62 65 65 6e 20 61 64 64 65  y have been adde
1bf60 64 20 62 65 66 6f 72 65 20 6f 72 20 61 66 74 65  d before or afte
1bf70 72 20 74 68 65 20 0a 20 20 2a 2a 20 63 75 72 72  r the .  ** curr
1bf80 65 6e 74 20 72 65 61 64 20 74 72 61 6e 73 61 63  ent read transac
1bf90 74 69 6f 6e 20 77 61 73 20 6f 70 65 6e 65 64 2e  tion was opened.
1bfa0 20 56 61 6c 75 65 73 20 61 64 64 65 64 20 61 66   Values added af
1bfb0 74 65 72 20 74 68 65 0a 20 20 2a 2a 20 72 65 61  ter the.  ** rea
1bfc0 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61  d transaction wa
1bfd0 73 20 6f 70 65 6e 65 64 20 6d 61 79 20 68 61 76  s opened may hav
1bfe0 65 20 62 65 65 6e 20 77 72 69 74 74 65 6e 20 69  e been written i
1bff0 6e 63 6f 72 72 65 63 74 6c 79 20 2d 0a 20 20 2a  ncorrectly -.  *
1c000 2a 20 69 2e 65 2e 20 74 68 65 73 65 20 73 6c 6f  * i.e. these slo
1c010 74 73 20 6d 61 79 20 63 6f 6e 74 61 69 6e 20 67  ts may contain g
1c020 61 72 62 61 67 65 20 64 61 74 61 2e 20 48 6f 77  arbage data. How
1c030 65 76 65 72 2c 20 77 65 20 61 73 73 75 6d 65 0a  ever, we assume.
1c040 20 20 2a 2a 20 74 68 61 74 20 61 6e 79 20 73 6c    ** that any sl
1c050 6f 74 73 20 77 72 69 74 74 65 6e 20 62 65 66 6f  ots written befo
1c060 72 65 20 74 68 65 20 63 75 72 72 65 6e 74 20 72  re the current r
1c070 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
1c080 77 61 73 0a 20 20 2a 2a 20 6f 70 65 6e 65 64 20  was.  ** opened 
1c090 72 65 6d 61 69 6e 20 75 6e 6d 6f 64 69 66 69 65  remain unmodifie
1c0a0 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 46 6f 72  d..  **.  ** For
1c0b0 20 74 68 65 20 72 65 61 73 6f 6e 73 20 61 62 6f   the reasons abo
1c0c0 76 65 2c 20 74 68 65 20 69 66 28 2e 2e 2e 29 20  ve, the if(...) 
1c0d0 63 6f 6e 64 69 74 69 6f 6e 20 66 65 61 74 75 72  condition featur
1c0e0 65 64 20 69 6e 20 74 68 65 20 69 6e 6e 65 72 0a  ed in the inner.
1c0f0 20 20 2a 2a 20 6c 6f 6f 70 20 6f 66 20 74 68 65    ** loop of the
1c100 20 66 6f 6c 6c 6f 77 69 6e 67 20 62 6c 6f 63 6b   following block
1c110 20 69 73 20 6d 6f 72 65 20 73 74 72 69 6e 67 65   is more stringe
1c120 6e 74 20 74 68 61 74 20 77 6f 75 6c 64 20 62 65  nt that would be
1c130 20 72 65 71 75 69 72 65 64 20 0a 20 20 2a 2a 20   required .  ** 
1c140 69 66 20 77 65 20 68 61 64 20 65 78 63 6c 75 73  if we had exclus
1c150 69 76 65 20 61 63 63 65 73 73 20 74 6f 20 74 68  ive access to th
1c160 65 20 68 61 73 68 2d 74 61 62 6c 65 3a 0a 20 20  e hash-table:.  
1c170 2a 2a 0a 20 20 2a 2a 20 20 20 28 61 50 67 6e 6f  **.  **   (aPgno
1c180 5b 69 46 72 61 6d 65 5d 3d 3d 70 67 6e 6f 29 3a  [iFrame]==pgno):
1c190 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69 73 20   .  **     This 
1c1a0 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74 65 72  condition filter
1c1b0 73 20 6f 75 74 20 6e 6f 72 6d 61 6c 20 68 61 73  s out normal has
1c1c0 68 2d 74 61 62 6c 65 20 63 6f 6c 6c 69 73 69 6f  h-table collisio
1c1d0 6e 73 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  ns..  **.  **   
1c1e0 28 69 46 72 61 6d 65 3c 3d 69 4c 61 73 74 29 3a  (iFrame<=iLast):
1c1f0 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69 73 20   .  **     This 
1c200 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74 65 72  condition filter
1c210 73 20 6f 75 74 20 65 6e 74 72 69 65 73 20 74 68  s out entries th
1c220 61 74 20 77 65 72 65 20 61 64 64 65 64 20 74 6f  at were added to
1c230 20 74 68 65 20 68 61 73 68 0a 20 20 2a 2a 20 20   the hash.  **  
1c240 20 20 20 74 61 62 6c 65 20 61 66 74 65 72 20 74     table after t
1c250 68 65 20 63 75 72 72 65 6e 74 20 72 65 61 64 2d  he current read-
1c260 74 72 61 6e 73 61 63 74 69 6f 6e 20 68 61 64 20  transaction had 
1c270 73 74 61 72 74 65 64 2e 0a 20 20 2a 2f 0a 20 20  started..  */.  
1c280 69 4d 69 6e 48 61 73 68 20 3d 20 77 61 6c 46 72  iMinHash = walFr
1c290 61 6d 65 50 61 67 65 28 70 57 61 6c 2d 3e 6d 69  amePage(pWal->mi
1c2a0 6e 46 72 61 6d 65 29 3b 0a 20 20 66 6f 72 28 69  nFrame);.  for(i
1c2b0 48 61 73 68 3d 77 61 6c 46 72 61 6d 65 50 61 67  Hash=walFramePag
1c2c0 65 28 69 4c 61 73 74 29 3b 20 69 48 61 73 68 3e  e(iLast); iHash>
1c2d0 3d 69 4d 69 6e 48 61 73 68 3b 20 69 48 61 73 68  =iMinHash; iHash
1c2e0 2d 2d 29 7b 0a 20 20 20 20 57 61 6c 48 61 73 68  --){.    WalHash
1c2f0 4c 6f 63 20 73 4c 6f 63 3b 20 20 20 20 20 20 20  Loc sLoc;       
1c300 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 74         /* Hash t
1c310 61 62 6c 65 20 6c 6f 63 61 74 69 6f 6e 20 2a 2f  able location */
1c320 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20  .    int iKey;  
1c330 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c340 20 20 20 2f 2a 20 48 61 73 68 20 73 6c 6f 74 20     /* Hash slot 
1c350 69 6e 64 65 78 20 2a 2f 0a 20 20 20 20 69 6e 74  index */.    int
1c360 20 6e 43 6f 6c 6c 69 64 65 3b 20 20 20 20 20 20   nCollide;      
1c370 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
1c380 6d 62 65 72 20 6f 66 20 68 61 73 68 20 63 6f 6c  mber of hash col
1c390 6c 69 73 69 6f 6e 73 20 72 65 6d 61 69 6e 69 6e  lisions remainin
1c3a0 67 20 2a 2f 0a 20 20 20 20 69 6e 74 20 72 63 3b  g */.    int rc;
1c3b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c3c0 20 20 20 20 20 20 20 2f 2a 20 45 72 72 6f 72 20         /* Error 
1c3d0 63 6f 64 65 20 2a 2f 0a 0a 20 20 20 20 72 63 20  code */..    rc 
1c3e0 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70 57 61  = walHashGet(pWa
1c3f0 6c 2c 20 69 48 61 73 68 2c 20 26 73 4c 6f 63 29  l, iHash, &sLoc)
1c400 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
1c410 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
1c420 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
1c430 7d 0a 20 20 20 20 6e 43 6f 6c 6c 69 64 65 20 3d  }.    nCollide =
1c440 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54   HASHTABLE_NSLOT
1c450 3b 0a 20 20 20 20 66 6f 72 28 69 4b 65 79 3d 77  ;.    for(iKey=w
1c460 61 6c 48 61 73 68 28 70 67 6e 6f 29 3b 20 73 4c  alHash(pgno); sL
1c470 6f 63 2e 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20  oc.aHash[iKey]; 
1c480 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68  iKey=walNextHash
1c490 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 75  (iKey)){.      u
1c4a0 33 32 20 69 46 72 61 6d 65 20 3d 20 73 4c 6f 63  32 iFrame = sLoc
1c4b0 2e 61 48 61 73 68 5b 69 4b 65 79 5d 20 2b 20 73  .aHash[iKey] + s
1c4c0 4c 6f 63 2e 69 5a 65 72 6f 3b 0a 20 20 20 20 20  Loc.iZero;.     
1c4d0 20 69 66 28 20 69 46 72 61 6d 65 3c 3d 69 4c 61   if( iFrame<=iLa
1c4e0 73 74 20 26 26 20 69 46 72 61 6d 65 3e 3d 70 57  st && iFrame>=pW
1c4f0 61 6c 2d 3e 6d 69 6e 46 72 61 6d 65 0a 20 20 20  al->minFrame.   
1c500 20 20 20 20 26 26 20 73 4c 6f 63 2e 61 50 67 6e      && sLoc.aPgn
1c510 6f 5b 73 4c 6f 63 2e 61 48 61 73 68 5b 69 4b 65  o[sLoc.aHash[iKe
1c520 79 5d 5d 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20  y]]==pgno ){.   
1c530 20 20 20 20 20 61 73 73 65 72 74 28 20 69 46 72       assert( iFr
1c540 61 6d 65 3e 69 52 65 61 64 20 7c 7c 20 43 4f 52  ame>iRead || COR
1c550 52 55 50 54 5f 44 42 20 29 3b 0a 20 20 20 20 20  RUPT_DB );.     
1c560 20 20 20 69 52 65 61 64 20 3d 20 69 46 72 61 6d     iRead = iFram
1c570 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  e;.      }.     
1c580 20 69 66 28 20 28 6e 43 6f 6c 6c 69 64 65 2d 2d   if( (nCollide--
1c590 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  )==0 ){.        
1c5a0 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 43 4f  return SQLITE_CO
1c5b0 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20 20  RRUPT_BKPT;.    
1c5c0 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
1c5d0 28 20 69 52 65 61 64 20 29 20 62 72 65 61 6b 3b  ( iRead ) break;
1c5e0 0a 20 20 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c  .  }..#ifdef SQL
1c5f0 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e  ITE_ENABLE_EXPEN
1c600 53 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a  SIVE_ASSERT.  /*
1c610 20 49 66 20 65 78 70 65 6e 73 69 76 65 20 61 73   If expensive as
1c620 73 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74  sert() statement
1c630 73 20 61 72 65 20 61 76 61 69 6c 61 62 6c 65 2c  s are available,
1c640 20 64 6f 20 61 20 6c 69 6e 65 61 72 20 73 65 61   do a linear sea
1c650 72 63 68 0a 20 20 2a 2a 20 6f 66 20 74 68 65 20  rch.  ** of the 
1c660 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20 63  wal-index file c
1c670 6f 6e 74 65 6e 74 2e 20 4d 61 6b 65 20 73 75 72  ontent. Make sur
1c680 65 20 74 68 65 20 72 65 73 75 6c 74 73 20 61 67  e the results ag
1c690 72 65 65 20 77 69 74 68 20 74 68 65 0a 20 20 2a  ree with the.  *
1c6a0 2a 20 72 65 73 75 6c 74 20 6f 62 74 61 69 6e 65  * result obtaine
1c6b0 64 20 75 73 69 6e 67 20 74 68 65 20 68 61 73 68  d using the hash
1c6c0 20 69 6e 64 65 78 65 73 20 61 62 6f 76 65 2e 20   indexes above. 
1c6d0 20 2a 2f 0a 20 20 7b 0a 20 20 20 20 75 33 32 20   */.  {.    u32 
1c6e0 69 52 65 61 64 32 20 3d 20 30 3b 0a 20 20 20 20  iRead2 = 0;.    
1c6f0 75 33 32 20 69 54 65 73 74 3b 0a 20 20 20 20 61  u32 iTest;.    a
1c700 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 62 53 68  ssert( pWal->bSh
1c710 6d 55 6e 72 65 6c 69 61 62 6c 65 20 7c 7c 20 70  mUnreliable || p
1c720 57 61 6c 2d 3e 6d 69 6e 46 72 61 6d 65 3e 30 20  Wal->minFrame>0 
1c730 29 3b 0a 20 20 20 20 66 6f 72 28 69 54 65 73 74  );.    for(iTest
1c740 3d 69 4c 61 73 74 3b 20 69 54 65 73 74 3e 3d 70  =iLast; iTest>=p
1c750 57 61 6c 2d 3e 6d 69 6e 46 72 61 6d 65 20 26 26  Wal->minFrame &&
1c760 20 69 54 65 73 74 3e 30 3b 20 69 54 65 73 74 2d   iTest>0; iTest-
1c770 2d 29 7b 0a 20 20 20 20 20 20 69 66 28 20 77 61  -){.      if( wa
1c780 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c  lFramePgno(pWal,
1c790 20 69 54 65 73 74 29 3d 3d 70 67 6e 6f 20 29 7b   iTest)==pgno ){
1c7a0 0a 20 20 20 20 20 20 20 20 69 52 65 61 64 32 20  .        iRead2 
1c7b0 3d 20 69 54 65 73 74 3b 0a 20 20 20 20 20 20 20  = iTest;.       
1c7c0 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
1c7d0 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74      }.    assert
1c7e0 28 20 69 52 65 61 64 3d 3d 69 52 65 61 64 32 20  ( iRead==iRead2 
1c7f0 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20  );.  }.#endif.. 
1c800 20 2a 70 69 52 65 61 64 20 3d 20 69 52 65 61 64   *piRead = iRead
1c810 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
1c820 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  E_OK;.}../*.** R
1c830 65 61 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ead the contents
1c840 20 6f 66 20 66 72 61 6d 65 20 69 52 65 61 64 20   of frame iRead 
1c850 66 72 6f 6d 20 74 68 65 20 77 61 6c 20 66 69 6c  from the wal fil
1c860 65 20 69 6e 74 6f 20 62 75 66 66 65 72 20 70 4f  e into buffer pO
1c870 75 74 0a 2a 2a 20 28 77 68 69 63 68 20 69 73 20  ut.** (which is 
1c880 6e 4f 75 74 20 62 79 74 65 73 20 69 6e 20 73 69  nOut bytes in si
1c890 7a 65 29 2e 20 52 65 74 75 72 6e 20 53 51 4c 49  ze). Return SQLI
1c8a0 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73  TE_OK if success
1c8b0 66 75 6c 2c 20 6f 72 20 61 6e 0a 2a 2a 20 65 72  ful, or an.** er
1c8c0 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77 69  ror code otherwi
1c8d0 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  se..*/.int sqlit
1c8e0 65 33 57 61 6c 52 65 61 64 46 72 61 6d 65 28 0a  e3WalReadFrame(.
1c8f0 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
1c900 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c910 20 20 2f 2a 20 57 41 4c 20 68 61 6e 64 6c 65 20    /* WAL handle 
1c920 2a 2f 0a 20 20 75 33 32 20 69 52 65 61 64 2c 20  */.  u32 iRead, 
1c930 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c940 20 20 20 20 20 2f 2a 20 46 72 61 6d 65 20 74 6f       /* Frame to
1c950 20 72 65 61 64 20 2a 2f 0a 20 20 69 6e 74 20 6e   read */.  int n
1c960 4f 75 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  Out,            
1c970 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
1c980 7a 65 20 6f 66 20 62 75 66 66 65 72 20 70 4f 75  ze of buffer pOu
1c990 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  t in bytes */.  
1c9a0 75 38 20 2a 70 4f 75 74 20 20 20 20 20 20 20 20  u8 *pOut        
1c9b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c9c0 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 77 72 69  /* Buffer to wri
1c9d0 74 65 20 70 61 67 65 20 64 61 74 61 20 74 6f 20  te page data to 
1c9e0 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 73 7a 3b 0a  */.){.  int sz;.
1c9f0 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 0a 20    i64 iOffset;. 
1ca00 20 73 7a 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e   sz = pWal->hdr.
1ca10 73 7a 50 61 67 65 3b 0a 20 20 73 7a 20 3d 20 28  szPage;.  sz = (
1ca20 73 7a 26 30 78 66 65 30 30 29 20 2b 20 28 28 73  sz&0xfe00) + ((s
1ca30 7a 26 30 78 30 30 30 31 29 3c 3c 31 36 29 3b 0a  z&0x0001)<<16);.
1ca40 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 3c 3d    testcase( sz<=
1ca50 33 32 37 36 38 20 29 3b 0a 20 20 74 65 73 74 63  32768 );.  testc
1ca60 61 73 65 28 20 73 7a 3e 3d 36 35 35 33 36 20 29  ase( sz>=65536 )
1ca70 3b 0a 20 20 69 4f 66 66 73 65 74 20 3d 20 77 61  ;.  iOffset = wa
1ca80 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 52 65  lFrameOffset(iRe
1ca90 61 64 2c 20 73 7a 29 20 2b 20 57 41 4c 5f 46 52  ad, sz) + WAL_FR
1caa0 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20 20 2f  AME_HDRSIZE;.  /
1cab0 2a 20 74 65 73 74 63 61 73 65 28 20 49 53 5f 42  * testcase( IS_B
1cac0 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20  IG_INT(iOffset) 
1cad0 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73 20 61  ); // requires a
1cae0 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20 20 72   4GiB WAL */.  r
1caf0 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52  eturn sqlite3OsR
1cb00 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ead(pWal->pWalFd
1cb10 2c 20 70 4f 75 74 2c 20 28 6e 4f 75 74 3e 73 7a  , pOut, (nOut>sz
1cb20 20 3f 20 73 7a 20 3a 20 6e 4f 75 74 29 2c 20 69   ? sz : nOut), i
1cb30 4f 66 66 73 65 74 29 3b 0a 7d 0a 0a 2f 2a 20 0a  Offset);.}../* .
1cb40 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73 69  ** Return the si
1cb50 7a 65 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  ze of the databa
1cb60 73 65 20 69 6e 20 70 61 67 65 73 20 28 6f 72 20  se in pages (or 
1cb70 7a 65 72 6f 2c 20 69 66 20 75 6e 6b 6e 6f 77 6e  zero, if unknown
1cb80 29 2e 0a 2a 2f 0a 50 67 6e 6f 20 73 71 6c 69 74  )..*/.Pgno sqlit
1cb90 65 33 57 61 6c 44 62 73 69 7a 65 28 57 61 6c 20  e3WalDbsize(Wal 
1cba0 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28 20 70 57  *pWal){.  if( pW
1cbb0 61 6c 20 26 26 20 41 4c 57 41 59 53 28 70 57 61  al && ALWAYS(pWa
1cbc0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 29 20  l->readLock>=0) 
1cbd0 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 57  ){.    return pW
1cbe0 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 3b 0a 20  al->hdr.nPage;. 
1cbf0 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d   }.  return 0;.}
1cc00 0a 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 66  .../* .** This f
1cc10 75 6e 63 74 69 6f 6e 20 73 74 61 72 74 73 20 61  unction starts a
1cc20 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69   write transacti
1cc30 6f 6e 20 6f 6e 20 74 68 65 20 57 41 4c 2e 0a 2a  on on the WAL..*
1cc40 2a 0a 2a 2a 20 41 20 72 65 61 64 20 74 72 61 6e  *.** A read tran
1cc50 73 61 63 74 69 6f 6e 20 6d 75 73 74 20 68 61 76  saction must hav
1cc60 65 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 73  e already been s
1cc70 74 61 72 74 65 64 20 62 79 20 61 20 70 72 69 6f  tarted by a prio
1cc80 72 20 63 61 6c 6c 0a 2a 2a 20 74 6f 20 73 71 6c  r call.** to sql
1cc90 69 74 65 33 57 61 6c 42 65 67 69 6e 52 65 61 64  ite3WalBeginRead
1cca0 54 72 61 6e 73 61 63 74 69 6f 6e 28 29 2e 0a 2a  Transaction()..*
1ccb0 2a 0a 2a 2a 20 49 66 20 61 6e 6f 74 68 65 72 20  *.** If another 
1ccc0 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73  thread or proces
1ccd0 73 20 68 61 73 20 77 72 69 74 74 65 6e 20 69 6e  s has written in
1cce0 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20  to the database 
1ccf0 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 72 65 61  since.** the rea
1cd00 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61  d transaction wa
1cd10 73 20 73 74 61 72 74 65 64 2c 20 74 68 65 6e 20  s started, then 
1cd20 69 74 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62  it is not possib
1cd30 6c 65 20 66 6f 72 20 74 68 69 73 0a 2a 2a 20 74  le for this.** t
1cd40 68 72 65 61 64 20 74 6f 20 77 72 69 74 65 20 61  hread to write a
1cd50 73 20 64 6f 69 6e 67 20 73 6f 20 77 6f 75 6c 64  s doing so would
1cd60 20 63 61 75 73 65 20 61 20 66 6f 72 6b 2e 20 20   cause a fork.  
1cd70 53 6f 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a  So this routine.
1cd80 2a 2a 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  ** returns SQLIT
1cd90 45 5f 42 55 53 59 20 69 6e 20 74 68 61 74 20 63  E_BUSY in that c
1cda0 61 73 65 20 61 6e 64 20 6e 6f 20 77 72 69 74 65  ase and no write
1cdb0 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20   transaction is 
1cdc0 73 74 61 72 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 54  started..**.** T
1cdd0 68 65 72 65 20 63 61 6e 20 6f 6e 6c 79 20 62 65  here can only be
1cde0 20 61 20 73 69 6e 67 6c 65 20 77 72 69 74 65 72   a single writer
1cdf0 20 61 63 74 69 76 65 20 61 74 20 61 20 74 69 6d   active at a tim
1ce00 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
1ce10 33 57 61 6c 42 65 67 69 6e 57 72 69 74 65 54 72  3WalBeginWriteTr
1ce20 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70  ansaction(Wal *p
1ce30 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  Wal){.  int rc;.
1ce40 0a 20 20 2f 2a 20 43 61 6e 6e 6f 74 20 73 74 61  .  /* Cannot sta
1ce50 72 74 20 61 20 77 72 69 74 65 20 74 72 61 6e 73  rt a write trans
1ce60 61 63 74 69 6f 6e 20 77 69 74 68 6f 75 74 20 66  action without f
1ce70 69 72 73 74 20 68 6f 6c 64 69 6e 67 20 61 20 72  irst holding a r
1ce80 65 61 64 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63  ead.  ** transac
1ce90 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72  tion. */.  asser
1cea0 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  t( pWal->readLoc
1ceb0 6b 3e 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  k>=0 );.  assert
1cec0 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
1ced0 6b 3d 3d 30 20 26 26 20 70 57 61 6c 2d 3e 69 52  k==0 && pWal->iR
1cee0 65 43 6b 73 75 6d 3d 3d 30 20 29 3b 0a 0a 20 20  eCksum==0 );..  
1cef0 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4f 6e  if( pWal->readOn
1cf00 6c 79 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ly ){.    return
1cf10 20 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59   SQLITE_READONLY
1cf20 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4f 6e 6c 79  ;.  }..  /* Only
1cf30 20 6f 6e 65 20 77 72 69 74 65 72 20 61 6c 6c 6f   one writer allo
1cf40 77 65 64 20 61 74 20 61 20 74 69 6d 65 2e 20 20  wed at a time.  
1cf50 47 65 74 20 74 68 65 20 77 72 69 74 65 20 6c 6f  Get the write lo
1cf60 63 6b 2e 20 20 52 65 74 75 72 6e 0a 20 20 2a 2a  ck.  Return.  **
1cf70 20 53 51 4c 49 54 45 5f 42 55 53 59 20 69 66 20   SQLITE_BUSY if 
1cf80 75 6e 61 62 6c 65 2e 0a 20 20 2a 2f 0a 20 20 72  unable..  */.  r
1cf90 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75  c = walLockExclu
1cfa0 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57  sive(pWal, WAL_W
1cfb0 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  RITE_LOCK, 1);. 
1cfc0 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 72   if( rc ){.    r
1cfd0 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20  eturn rc;.  }.  
1cfe0 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
1cff0 3d 20 31 3b 0a 0a 20 20 2f 2a 20 49 66 20 61 6e  = 1;..  /* If an
1d000 6f 74 68 65 72 20 63 6f 6e 6e 65 63 74 69 6f 6e  other connection
1d010 20 68 61 73 20 77 72 69 74 74 65 6e 20 74 6f 20   has written to 
1d020 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
1d030 65 20 73 69 6e 63 65 20 74 68 65 0a 20 20 2a 2a  e since the.  **
1d040 20 74 69 6d 65 20 74 68 65 20 72 65 61 64 20 74   time the read t
1d050 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68  ransaction on th
1d060 69 73 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 77 61  is connection wa
1d070 73 20 73 74 61 72 74 65 64 2c 20 74 68 65 6e 0a  s started, then.
1d080 20 20 2a 2a 20 74 68 65 20 77 72 69 74 65 20 69    ** the write i
1d090 73 20 64 69 73 61 6c 6c 6f 77 65 64 2e 0a 20 20  s disallowed..  
1d0a0 2a 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28  */.  if( memcmp(
1d0b0 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69  &pWal->hdr, (voi
1d0c0 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28  d *)walIndexHdr(
1d0d0 70 57 61 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61  pWal), sizeof(Wa
1d0e0 6c 49 6e 64 65 78 48 64 72 29 29 21 3d 30 20 29  lIndexHdr))!=0 )
1d0f0 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45  {.    walUnlockE
1d100 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
1d110 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31  AL_WRITE_LOCK, 1
1d120 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72 69  );.    pWal->wri
1d130 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20  teLock = 0;.    
1d140 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55 53 59  rc = SQLITE_BUSY
1d150 5f 53 4e 41 50 53 48 4f 54 3b 0a 20 20 7d 0a 0a  _SNAPSHOT;.  }..
1d160 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
1d170 2f 2a 0a 2a 2a 20 45 6e 64 20 61 20 77 72 69 74  /*.** End a writ
1d180 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 20  e transaction.  
1d190 54 68 65 20 63 6f 6d 6d 69 74 20 68 61 73 20 61  The commit has a
1d1a0 6c 72 65 61 64 79 20 62 65 65 6e 20 64 6f 6e 65  lready been done
1d1b0 2e 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75 74 69  .  This.** routi
1d1c0 6e 65 20 6d 65 72 65 6c 79 20 72 65 6c 65 61 73  ne merely releas
1d1d0 65 73 20 74 68 65 20 6c 6f 63 6b 2e 0a 2a 2f 0a  es the lock..*/.
1d1e0 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 45 6e  int sqlite3WalEn
1d1f0 64 57 72 69 74 65 54 72 61 6e 73 61 63 74 69 6f  dWriteTransactio
1d200 6e 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20  n(Wal *pWal){.  
1d210 69 66 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c  if( pWal->writeL
1d220 6f 63 6b 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e  ock ){.    walUn
1d230 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  lockExclusive(pW
1d240 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f  al, WAL_WRITE_LO
1d250 43 4b 2c 20 31 29 3b 0a 20 20 20 20 70 57 61 6c  CK, 1);.    pWal
1d260 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b  ->writeLock = 0;
1d270 0a 20 20 20 20 70 57 61 6c 2d 3e 69 52 65 43 6b  .    pWal->iReCk
1d280 73 75 6d 20 3d 20 30 3b 0a 20 20 20 20 70 57 61  sum = 0;.    pWa
1d290 6c 2d 3e 74 72 75 6e 63 61 74 65 4f 6e 43 6f 6d  l->truncateOnCom
1d2a0 6d 69 74 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72  mit = 0;.  }.  r
1d2b0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
1d2c0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 61 6e 79  .}../*.** If any
1d2d0 20 64 61 74 61 20 68 61 73 20 62 65 65 6e 20 77   data has been w
1d2e0 72 69 74 74 65 6e 20 28 62 75 74 20 6e 6f 74 20  ritten (but not 
1d2f0 63 6f 6d 6d 69 74 74 65 64 29 20 74 6f 20 74 68  committed) to th
1d300 65 20 6c 6f 67 20 66 69 6c 65 2c 20 74 68 69 73  e log file, this
1d310 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 6d 6f 76  .** function mov
1d320 65 73 20 74 68 65 20 77 72 69 74 65 2d 70 6f 69  es the write-poi
1d330 6e 74 65 72 20 62 61 63 6b 20 74 6f 20 74 68 65  nter back to the
1d340 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 74 72   start of the tr
1d350 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a  ansaction..**.**
1d360 20 41 64 64 69 74 69 6f 6e 61 6c 6c 79 2c 20 74   Additionally, t
1d370 68 65 20 63 61 6c 6c 62 61 63 6b 20 66 75 6e 63  he callback func
1d380 74 69 6f 6e 20 69 73 20 69 6e 76 6f 6b 65 64 20  tion is invoked 
1d390 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65 20 77  for each frame w
1d3a0 72 69 74 74 65 6e 0a 2a 2a 20 74 6f 20 74 68 65  ritten.** to the
1d3b0 20 57 41 4c 20 73 69 6e 63 65 20 74 68 65 20 73   WAL since the s
1d3c0 74 61 72 74 20 6f 66 20 74 68 65 20 74 72 61 6e  tart of the tran
1d3d0 73 61 63 74 69 6f 6e 2e 20 49 66 20 74 68 65 20  saction. If the 
1d3e0 63 61 6c 6c 62 61 63 6b 20 72 65 74 75 72 6e 73  callback returns
1d3f0 0a 2a 2a 20 6f 74 68 65 72 20 74 68 61 6e 20 53  .** other than S
1d400 51 4c 49 54 45 5f 4f 4b 2c 20 69 74 20 69 73 20  QLITE_OK, it is 
1d410 6e 6f 74 20 69 6e 76 6f 6b 65 64 20 61 67 61 69  not invoked agai
1d420 6e 20 61 6e 64 20 74 68 65 20 65 72 72 6f 72 20  n and the error 
1d430 63 6f 64 65 20 69 73 0a 2a 2a 20 72 65 74 75 72  code is.** retur
1d440 6e 65 64 20 74 6f 20 74 68 65 20 63 61 6c 6c 65  ned to the calle
1d450 72 2e 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77 69  r..**.** Otherwi
1d460 73 65 2c 20 69 66 20 74 68 65 20 63 61 6c 6c 62  se, if the callb
1d470 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20 64 6f 65  ack function doe
1d480 73 20 6e 6f 74 20 72 65 74 75 72 6e 20 61 6e 20  s not return an 
1d490 65 72 72 6f 72 2c 20 74 68 69 73 0a 2a 2a 20 66  error, this.** f
1d4a0 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20  unction returns 
1d4b0 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e  SQLITE_OK..*/.in
1d4c0 74 20 73 71 6c 69 74 65 33 57 61 6c 55 6e 64 6f  t sqlite3WalUndo
1d4d0 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20  (Wal *pWal, int 
1d4e0 28 2a 78 55 6e 64 6f 29 28 76 6f 69 64 20 2a 2c  (*xUndo)(void *,
1d4f0 20 50 67 6e 6f 29 2c 20 76 6f 69 64 20 2a 70 55   Pgno), void *pU
1d500 6e 64 6f 43 74 78 29 7b 0a 20 20 69 6e 74 20 72  ndoCtx){.  int r
1d510 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
1d520 20 69 66 28 20 41 4c 57 41 59 53 28 70 57 61 6c   if( ALWAYS(pWal
1d530 2d 3e 77 72 69 74 65 4c 6f 63 6b 29 20 29 7b 0a  ->writeLock) ){.
1d540 20 20 20 20 50 67 6e 6f 20 69 4d 61 78 20 3d 20      Pgno iMax = 
1d550 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
1d560 65 3b 0a 20 20 20 20 50 67 6e 6f 20 69 46 72 61  e;.    Pgno iFra
1d570 6d 65 3b 0a 20 20 0a 20 20 20 20 2f 2a 20 52 65  me;.  .    /* Re
1d580 73 74 6f 72 65 20 74 68 65 20 63 6c 69 65 6e 74  store the client
1d590 73 20 63 61 63 68 65 20 6f 66 20 74 68 65 20 77  s cache of the w
1d5a0 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
1d5b0 74 6f 20 74 68 65 20 73 74 61 74 65 20 69 74 0a  to the state it.
1d5c0 20 20 20 20 2a 2a 20 77 61 73 20 69 6e 20 62 65      ** was in be
1d5d0 66 6f 72 65 20 74 68 65 20 63 6c 69 65 6e 74 20  fore the client 
1d5e0 62 65 67 61 6e 20 77 72 69 74 69 6e 67 20 74 6f  began writing to
1d5f0 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 0a   the database. .
1d600 20 20 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 63 70      */.    memcp
1d610 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76  y(&pWal->hdr, (v
1d620 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64  oid *)walIndexHd
1d630 72 28 70 57 61 6c 29 2c 20 73 69 7a 65 6f 66 28  r(pWal), sizeof(
1d640 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 0a  WalIndexHdr));..
1d650 20 20 20 20 66 6f 72 28 69 46 72 61 6d 65 3d 70      for(iFrame=p
1d660 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
1d670 2b 31 3b 20 0a 20 20 20 20 20 20 20 20 41 4c 57  +1; .        ALW
1d680 41 59 53 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  AYS(rc==SQLITE_O
1d690 4b 29 20 26 26 20 69 46 72 61 6d 65 3c 3d 69 4d  K) && iFrame<=iM
1d6a0 61 78 3b 20 0a 20 20 20 20 20 20 20 20 69 46 72  ax; .        iFr
1d6b0 61 6d 65 2b 2b 0a 20 20 20 20 29 7b 0a 20 20 20  ame++.    ){.   
1d6c0 20 20 20 2f 2a 20 54 68 69 73 20 63 61 6c 6c 20     /* This call 
1d6d0 63 61 6e 6e 6f 74 20 66 61 69 6c 2e 20 55 6e 6c  cannot fail. Unl
1d6e0 65 73 73 20 74 68 65 20 70 61 67 65 20 66 6f 72  ess the page for
1d6f0 20 77 68 69 63 68 20 74 68 65 20 70 61 67 65 20   which the page 
1d700 6e 75 6d 62 65 72 0a 20 20 20 20 20 20 2a 2a 20  number.      ** 
1d710 69 73 20 70 61 73 73 65 64 20 61 73 20 74 68 65  is passed as the
1d720 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74   second argument
1d730 20 69 73 20 28 61 29 20 69 6e 20 74 68 65 20 63   is (a) in the c
1d740 61 63 68 65 20 61 6e 64 20 0a 20 20 20 20 20 20  ache and .      
1d750 2a 2a 20 28 62 29 20 68 61 73 20 61 6e 20 6f 75  ** (b) has an ou
1d760 74 73 74 61 6e 64 69 6e 67 20 72 65 66 65 72 65  tstanding refere
1d770 6e 63 65 2c 20 74 68 65 6e 20 78 55 6e 64 6f 20  nce, then xUndo 
1d780 69 73 20 65 69 74 68 65 72 20 61 20 6e 6f 2d 6f  is either a no-o
1d790 70 0a 20 20 20 20 20 20 2a 2a 20 28 69 66 20 28  p.      ** (if (
1d7a0 61 29 20 69 73 20 66 61 6c 73 65 29 20 6f 72 20  a) is false) or 
1d7b0 73 69 6d 70 6c 79 20 65 78 70 65 6c 73 20 74 68  simply expels th
1d7c0 65 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20  e page from the 
1d7d0 63 61 63 68 65 20 28 69 66 20 28 62 29 0a 20 20  cache (if (b).  
1d7e0 20 20 20 20 2a 2a 20 69 73 20 66 61 6c 73 65 29      ** is false)
1d7f0 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20  ..      **.     
1d800 20 2a 2a 20 49 66 20 74 68 65 20 75 70 70 65 72   ** If the upper
1d810 20 6c 61 79 65 72 20 69 73 20 64 6f 69 6e 67 20   layer is doing 
1d820 61 20 72 6f 6c 6c 62 61 63 6b 2c 20 69 74 20 69  a rollback, it i
1d830 73 20 67 75 61 72 61 6e 74 65 65 64 20 74 68 61  s guaranteed tha
1d840 74 20 74 68 65 72 65 0a 20 20 20 20 20 20 2a 2a  t there.      **
1d850 20 61 72 65 20 6e 6f 20 6f 75 74 73 74 61 6e 64   are no outstand
1d860 69 6e 67 20 72 65 66 65 72 65 6e 63 65 73 20 74  ing references t
1d870 6f 20 61 6e 79 20 70 61 67 65 20 6f 74 68 65 72  o any page other
1d880 20 74 68 61 6e 20 70 61 67 65 20 31 2e 20 41 6e   than page 1. An
1d890 64 0a 20 20 20 20 20 20 2a 2a 20 70 61 67 65 20  d.      ** page 
1d8a0 31 20 69 73 20 6e 65 76 65 72 20 77 72 69 74 74  1 is never writt
1d8b0 65 6e 20 74 6f 20 74 68 65 20 6c 6f 67 20 75 6e  en to the log un
1d8c0 74 69 6c 20 74 68 65 20 74 72 61 6e 73 61 63 74  til the transact
1d8d0 69 6f 6e 20 69 73 0a 20 20 20 20 20 20 2a 2a 20  ion is.      ** 
1d8e0 63 6f 6d 6d 69 74 74 65 64 2e 20 41 73 20 61 20  committed. As a 
1d8f0 72 65 73 75 6c 74 2c 20 74 68 65 20 63 61 6c 6c  result, the call
1d900 20 74 6f 20 78 55 6e 64 6f 20 6d 61 79 20 6e 6f   to xUndo may no
1d910 74 20 66 61 69 6c 2e 0a 20 20 20 20 20 20 2a 2f  t fail..      */
1d920 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 77  .      assert( w
1d930 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c  alFramePgno(pWal
1d940 2c 20 69 46 72 61 6d 65 29 21 3d 31 20 29 3b 0a  , iFrame)!=1 );.
1d950 20 20 20 20 20 20 72 63 20 3d 20 78 55 6e 64 6f        rc = xUndo
1d960 28 70 55 6e 64 6f 43 74 78 2c 20 77 61 6c 46 72  (pUndoCtx, walFr
1d970 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 46  amePgno(pWal, iF
1d980 72 61 6d 65 29 29 3b 0a 20 20 20 20 7d 0a 20 20  rame));.    }.  
1d990 20 20 69 66 28 20 69 4d 61 78 21 3d 70 57 61 6c    if( iMax!=pWal
1d9a0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 20  ->hdr.mxFrame ) 
1d9b0 77 61 6c 43 6c 65 61 6e 75 70 48 61 73 68 28 70  walCleanupHash(p
1d9c0 57 61 6c 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  Wal);.  }.  retu
1d9d0 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
1d9e0 20 41 72 67 75 6d 65 6e 74 20 61 57 61 6c 44 61   Argument aWalDa
1d9f0 74 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f  ta must point to
1da00 20 61 6e 20 61 72 72 61 79 20 6f 66 20 57 41 4c   an array of WAL
1da10 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54 41  _SAVEPOINT_NDATA
1da20 20 75 33 32 20 0a 2a 2a 20 76 61 6c 75 65 73 2e   u32 .** values.
1da30 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 70   This function p
1da40 6f 70 75 6c 61 74 65 73 20 74 68 65 20 61 72 72  opulates the arr
1da50 61 79 20 77 69 74 68 20 76 61 6c 75 65 73 20 72  ay with values r
1da60 65 71 75 69 72 65 64 20 74 6f 20 0a 2a 2a 20 22  equired to .** "
1da70 72 6f 6c 6c 62 61 63 6b 22 20 74 68 65 20 77 72  rollback" the wr
1da80 69 74 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66 20  ite position of 
1da90 74 68 65 20 57 41 4c 20 68 61 6e 64 6c 65 20 62  the WAL handle b
1daa0 61 63 6b 20 74 6f 20 74 68 65 20 63 75 72 72 65  ack to the curre
1dab0 6e 74 20 0a 2a 2a 20 70 6f 69 6e 74 20 69 6e 20  nt .** point in 
1dac0 74 68 65 20 65 76 65 6e 74 20 6f 66 20 61 20 73  the event of a s
1dad0 61 76 65 70 6f 69 6e 74 20 72 6f 6c 6c 62 61 63  avepoint rollbac
1dae0 6b 20 28 76 69 61 20 57 61 6c 53 61 76 65 70 6f  k (via WalSavepo
1daf0 69 6e 74 55 6e 64 6f 28 29 29 2e 0a 2a 2f 0a 76  intUndo())..*/.v
1db00 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 53 61  oid sqlite3WalSa
1db10 76 65 70 6f 69 6e 74 28 57 61 6c 20 2a 70 57 61  vepoint(Wal *pWa
1db20 6c 2c 20 75 33 32 20 2a 61 57 61 6c 44 61 74 61  l, u32 *aWalData
1db30 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  ){.  assert( pWa
1db40 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a  l->writeLock );.
1db50 20 20 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d 20    aWalData[0] = 
1db60 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
1db70 65 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 31 5d  e;.  aWalData[1]
1db80 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72   = pWal->hdr.aFr
1db90 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 61  ameCksum[0];.  a
1dba0 57 61 6c 44 61 74 61 5b 32 5d 20 3d 20 70 57 61  WalData[2] = pWa
1dbb0 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
1dbc0 75 6d 5b 31 5d 3b 0a 20 20 61 57 61 6c 44 61 74  um[1];.  aWalDat
1dbd0 61 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e 6e 43 6b  a[3] = pWal->nCk
1dbe0 70 74 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4d 6f  pt;.}../* .** Mo
1dbf0 76 65 20 74 68 65 20 77 72 69 74 65 20 70 6f 73  ve the write pos
1dc00 69 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41 4c  ition of the WAL
1dc10 20 62 61 63 6b 20 74 6f 20 74 68 65 20 70 6f 69   back to the poi
1dc20 6e 74 20 69 64 65 6e 74 69 66 69 65 64 20 62 79  nt identified by
1dc30 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 73 20 69  .** the values i
1dc40 6e 20 74 68 65 20 61 57 61 6c 44 61 74 61 5b 5d  n the aWalData[]
1dc50 20 61 72 72 61 79 2e 20 61 57 61 6c 44 61 74 61   array. aWalData
1dc60 20 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f 20 61   must point to a
1dc70 6e 20 61 72 72 61 79 0a 2a 2a 20 6f 66 20 57 41  n array.** of WA
1dc80 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54  L_SAVEPOINT_NDAT
1dc90 41 20 75 33 32 20 76 61 6c 75 65 73 20 74 68 61  A u32 values tha
1dca0 74 20 68 61 73 20 62 65 65 6e 20 70 72 65 76 69  t has been previ
1dcb0 6f 75 73 6c 79 20 70 6f 70 75 6c 61 74 65 64 0a  ously populated.
1dcc0 2a 2a 20 62 79 20 61 20 63 61 6c 6c 20 74 6f 20  ** by a call to 
1dcd0 57 61 6c 53 61 76 65 70 6f 69 6e 74 28 29 2e 0a  WalSavepoint()..
1dce0 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
1dcf0 6c 53 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28 57  lSavepointUndo(W
1dd00 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a 61  al *pWal, u32 *a
1dd10 57 61 6c 44 61 74 61 29 7b 0a 20 20 69 6e 74 20  WalData){.  int 
1dd20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
1dd30 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
1dd40 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20  >writeLock );.  
1dd50 61 73 73 65 72 74 28 20 61 57 61 6c 44 61 74 61  assert( aWalData
1dd60 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43 6b 70 74  [3]!=pWal->nCkpt
1dd70 20 7c 7c 20 61 57 61 6c 44 61 74 61 5b 30 5d 3c   || aWalData[0]<
1dd80 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  =pWal->hdr.mxFra
1dd90 6d 65 20 29 3b 0a 0a 20 20 69 66 28 20 61 57 61  me );..  if( aWa
1dda0 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e  lData[3]!=pWal->
1ddb0 6e 43 6b 70 74 20 29 7b 0a 20 20 20 20 2f 2a 20  nCkpt ){.    /* 
1ddc0 54 68 69 73 20 73 61 76 65 70 6f 69 6e 74 20 77  This savepoint w
1ddd0 61 73 20 6f 70 65 6e 65 64 20 69 6d 6d 65 64 69  as opened immedi
1dde0 61 74 65 6c 79 20 61 66 74 65 72 20 74 68 65 20  ately after the 
1ddf0 77 72 69 74 65 2d 74 72 61 6e 73 61 63 74 69 6f  write-transactio
1de00 6e 0a 20 20 20 20 2a 2a 20 77 61 73 20 73 74 61  n.    ** was sta
1de10 72 74 65 64 2e 20 52 69 67 68 74 20 61 66 74 65  rted. Right afte
1de20 72 20 74 68 61 74 2c 20 74 68 65 20 77 72 69 74  r that, the writ
1de30 65 72 20 64 65 63 69 64 65 64 20 74 6f 20 77 72  er decided to wr
1de40 61 70 20 61 72 6f 75 6e 64 0a 20 20 20 20 2a 2a  ap around.    **
1de50 20 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66   to the start of
1de60 20 74 68 65 20 6c 6f 67 2e 20 55 70 64 61 74 65   the log. Update
1de70 20 74 68 65 20 73 61 76 65 70 6f 69 6e 74 20 76   the savepoint v
1de80 61 6c 75 65 73 20 74 6f 20 6d 61 74 63 68 2e 0a  alues to match..
1de90 20 20 20 20 2a 2f 0a 20 20 20 20 61 57 61 6c 44      */.    aWalD
1dea0 61 74 61 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20  ata[0] = 0;.    
1deb0 61 57 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70 57  aWalData[3] = pW
1dec0 61 6c 2d 3e 6e 43 6b 70 74 3b 0a 20 20 7d 0a 0a  al->nCkpt;.  }..
1ded0 20 20 69 66 28 20 61 57 61 6c 44 61 74 61 5b 30    if( aWalData[0
1dee0 5d 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  ]<pWal->hdr.mxFr
1def0 61 6d 65 20 29 7b 0a 20 20 20 20 70 57 61 6c 2d  ame ){.    pWal-
1df00 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20 61  >hdr.mxFrame = a
1df10 57 61 6c 44 61 74 61 5b 30 5d 3b 0a 20 20 20 20  WalData[0];.    
1df20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
1df30 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 57 61 6c 44  Cksum[0] = aWalD
1df40 61 74 61 5b 31 5d 3b 0a 20 20 20 20 70 57 61 6c  ata[1];.    pWal
1df50 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
1df60 6d 5b 31 5d 20 3d 20 61 57 61 6c 44 61 74 61 5b  m[1] = aWalData[
1df70 32 5d 3b 0a 20 20 20 20 77 61 6c 43 6c 65 61 6e  2];.    walClean
1df80 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20  upHash(pWal);.  
1df90 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
1dfa0 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
1dfb0 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
1dfc0 20 6a 75 73 74 20 62 65 66 6f 72 65 20 77 72 69   just before wri
1dfd0 74 69 6e 67 20 61 20 73 65 74 20 6f 66 20 66 72  ting a set of fr
1dfe0 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67 0a  ames to the log.
1dff0 2a 2a 20 66 69 6c 65 20 28 73 65 65 20 73 71 6c  ** file (see sql
1e000 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28 29 29  ite3WalFrames())
1e010 2e 20 49 74 20 63 68 65 63 6b 73 20 74 6f 20 73  . It checks to s
1e020 65 65 20 69 66 2c 20 69 6e 73 74 65 61 64 20 6f  ee if, instead o
1e030 66 20 61 70 70 65 6e 64 69 6e 67 0a 2a 2a 20 74  f appending.** t
1e040 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c 6f  o the current lo
1e050 67 20 66 69 6c 65 2c 20 69 74 20 69 73 20 70 6f  g file, it is po
1e060 73 73 69 62 6c 65 20 74 6f 20 6f 76 65 72 77 72  ssible to overwr
1e070 69 74 65 20 74 68 65 20 73 74 61 72 74 20 6f 66  ite the start of
1e080 20 74 68 65 0a 2a 2a 20 65 78 69 73 74 69 6e 67   the.** existing
1e090 20 6c 6f 67 20 66 69 6c 65 20 77 69 74 68 20 74   log file with t
1e0a0 68 65 20 6e 65 77 20 66 72 61 6d 65 73 20 28 69  he new frames (i
1e0b0 2e 65 2e 20 22 72 65 73 65 74 22 20 74 68 65 20  .e. "reset" the 
1e0c0 6c 6f 67 29 2e 20 49 66 20 73 6f 2c 0a 2a 2a 20  log). If so,.** 
1e0d0 69 74 20 73 65 74 73 20 70 57 61 6c 2d 3e 68 64  it sets pWal->hd
1e0e0 72 2e 6d 78 46 72 61 6d 65 20 74 6f 20 30 2e 20  r.mxFrame to 0. 
1e0f0 4f 74 68 65 72 77 69 73 65 2c 20 70 57 61 6c 2d  Otherwise, pWal-
1e100 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20  >hdr.mxFrame is 
1e110 6c 65 66 74 0a 2a 2a 20 75 6e 63 68 61 6e 67 65  left.** unchange
1e120 64 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f  d..**.** SQLITE_
1e130 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 69  OK is returned i
1e140 66 20 6e 6f 20 65 72 72 6f 72 20 69 73 20 65 6e  f no error is en
1e150 63 6f 75 6e 74 65 72 65 64 20 28 72 65 67 61 72  countered (regar
1e160 64 6c 65 73 73 20 6f 66 20 77 68 65 74 68 65 72  dless of whether
1e170 0a 2a 2a 20 6f 72 20 6e 6f 74 20 70 57 61 6c 2d  .** or not pWal-
1e180 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20  >hdr.mxFrame is 
1e190 6d 6f 64 69 66 69 65 64 29 2e 20 41 6e 20 53 51  modified). An SQ
1e1a0 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20  Lite error code 
1e1b0 69 73 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69  is returned.** i
1e1c0 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
1e1d0 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
1e1e0 20 77 61 6c 52 65 73 74 61 72 74 4c 6f 67 28 57   walRestartLog(W
1e1f0 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74  al *pWal){.  int
1e200 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
1e210 0a 20 20 69 6e 74 20 63 6e 74 3b 0a 0a 20 20 69  .  int cnt;..  i
1e220 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  f( pWal->readLoc
1e230 6b 3d 3d 30 20 29 7b 0a 20 20 20 20 76 6f 6c 61  k==0 ){.    vola
1e240 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f  tile WalCkptInfo
1e250 20 2a 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70   *pInfo = walCkp
1e260 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20  tInfo(pWal);.   
1e270 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e   assert( pInfo->
1e280 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70 57 61 6c 2d  nBackfill==pWal-
1e290 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a  >hdr.mxFrame );.
1e2a0 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e      if( pInfo->n
1e2b0 42 61 63 6b 66 69 6c 6c 3e 30 20 29 7b 0a 20 20  Backfill>0 ){.  
1e2c0 20 20 20 20 75 33 32 20 73 61 6c 74 31 3b 0a 20      u32 salt1;. 
1e2d0 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 61 6e       sqlite3_ran
1e2e0 64 6f 6d 6e 65 73 73 28 34 2c 20 26 73 61 6c 74  domness(4, &salt
1e2f0 31 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 77  1);.      rc = w
1e300 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  alLockExclusive(
1e310 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  pWal, WAL_READ_L
1e320 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41  OCK(1), WAL_NREA
1e330 44 45 52 2d 31 29 3b 0a 20 20 20 20 20 20 69 66  DER-1);.      if
1e340 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1e350 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49 66  ){.        /* If
1e360 20 61 6c 6c 20 72 65 61 64 65 72 73 20 61 72 65   all readers are
1e370 20 75 73 69 6e 67 20 57 41 4c 5f 52 45 41 44 5f   using WAL_READ_
1e380 4c 4f 43 4b 28 30 29 20 28 69 6e 20 6f 74 68 65  LOCK(0) (in othe
1e390 72 20 77 6f 72 64 73 20 69 66 20 6e 6f 0a 20 20  r words if no.  
1e3a0 20 20 20 20 20 20 2a 2a 20 72 65 61 64 65 72 73        ** readers
1e3b0 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20 75   are currently u
1e3c0 73 69 6e 67 20 74 68 65 20 57 41 4c 29 2c 20 74  sing the WAL), t
1e3d0 68 65 6e 20 74 68 65 20 74 72 61 6e 73 61 63 74  hen the transact
1e3e0 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 2a 2a 20  ions.        ** 
1e3f0 66 72 61 6d 65 73 20 77 69 6c 6c 20 6f 76 65 72  frames will over
1e400 77 72 69 74 65 20 74 68 65 20 73 74 61 72 74 20  write the start 
1e410 6f 66 20 74 68 65 20 65 78 69 73 74 69 6e 67 20  of the existing 
1e420 6c 6f 67 2e 20 55 70 64 61 74 65 20 74 68 65 0a  log. Update the.
1e430 20 20 20 20 20 20 20 20 2a 2a 20 77 61 6c 2d 69          ** wal-i
1e440 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f 20 72  ndex header to r
1e450 65 66 6c 65 63 74 20 74 68 69 73 2e 0a 20 20 20  eflect this..   
1e460 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20       **.        
1e470 2a 2a 20 49 6e 20 74 68 65 6f 72 79 20 69 74 20  ** In theory it 
1e480 77 6f 75 6c 64 20 62 65 20 4f 6b 20 74 6f 20 75  would be Ok to u
1e490 70 64 61 74 65 20 74 68 65 20 63 61 63 68 65 20  pdate the cache 
1e4a0 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 6f 6e  of the header on
1e4b0 6c 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 74  ly.        ** at
1e4c0 20 74 68 69 73 20 70 6f 69 6e 74 2e 20 42 75 74   this point. But
1e4d0 20 75 70 64 61 74 69 6e 67 20 74 68 65 20 61 63   updating the ac
1e4e0 74 75 61 6c 20 77 61 6c 2d 69 6e 64 65 78 20 68  tual wal-index h
1e4f0 65 61 64 65 72 20 69 73 20 61 6c 73 6f 0a 20 20  eader is also.  
1e500 20 20 20 20 20 20 2a 2a 20 73 61 66 65 20 61 6e        ** safe an
1e510 64 20 6d 65 61 6e 73 20 74 68 65 72 65 20 69 73  d means there is
1e520 20 6e 6f 20 73 70 65 63 69 61 6c 20 63 61 73 65   no special case
1e530 20 66 6f 72 20 73 71 6c 69 74 65 33 57 61 6c 55   for sqlite3WalU
1e540 6e 64 6f 28 29 0a 20 20 20 20 20 20 20 20 2a 2a  ndo().        **
1e550 20 74 6f 20 68 61 6e 64 6c 65 20 69 66 20 74 68   to handle if th
1e560 69 73 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69  is transaction i
1e570 73 20 72 6f 6c 6c 65 64 20 62 61 63 6b 2e 20 20  s rolled back.  
1e580 2a 2f 0a 20 20 20 20 20 20 20 20 77 61 6c 52 65  */.        walRe
1e590 73 74 61 72 74 48 64 72 28 70 57 61 6c 2c 20 73  startHdr(pWal, s
1e5a0 61 6c 74 31 29 3b 0a 20 20 20 20 20 20 20 20 77  alt1);.        w
1e5b0 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
1e5c0 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
1e5d0 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52  _LOCK(1), WAL_NR
1e5e0 45 41 44 45 52 2d 31 29 3b 0a 20 20 20 20 20 20  EADER-1);.      
1e5f0 7d 65 6c 73 65 20 69 66 28 20 72 63 21 3d 53 51  }else if( rc!=SQ
1e600 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
1e610 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a       return rc;.
1e620 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
1e630 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65    walUnlockShare
1e640 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  d(pWal, WAL_READ
1e650 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20 20 70  _LOCK(0));.    p
1e660 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20  Wal->readLock = 
1e670 2d 31 3b 0a 20 20 20 20 63 6e 74 20 3d 20 30 3b  -1;.    cnt = 0;
1e680 0a 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20 69  .    do{.      i
1e690 6e 74 20 6e 6f 74 55 73 65 64 3b 0a 20 20 20 20  nt notUsed;.    
1e6a0 20 20 72 63 20 3d 20 77 61 6c 54 72 79 42 65 67    rc = walTryBeg
1e6b0 69 6e 52 65 61 64 28 70 57 61 6c 2c 20 26 6e 6f  inRead(pWal, &no
1e6c0 74 55 73 65 64 2c 20 31 2c 20 2b 2b 63 6e 74 29  tUsed, 1, ++cnt)
1e6d0 3b 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 72 63  ;.    }while( rc
1e6e0 3d 3d 57 41 4c 5f 52 45 54 52 59 20 29 3b 0a 20  ==WAL_RETRY );. 
1e6f0 20 20 20 61 73 73 65 72 74 28 20 28 72 63 26 30     assert( (rc&0
1e700 78 66 66 29 21 3d 53 51 4c 49 54 45 5f 42 55 53  xff)!=SQLITE_BUS
1e710 59 20 29 3b 20 2f 2a 20 42 55 53 59 20 6e 6f 74  Y ); /* BUSY not
1e720 20 70 6f 73 73 69 62 6c 65 20 77 68 65 6e 20 75   possible when u
1e730 73 65 57 61 6c 3d 3d 31 20 2a 2f 0a 20 20 20 20  seWal==1 */.    
1e740 74 65 73 74 63 61 73 65 28 20 28 72 63 26 30 78  testcase( (rc&0x
1e750 66 66 29 3d 3d 53 51 4c 49 54 45 5f 49 4f 45 52  ff)==SQLITE_IOER
1e760 52 20 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73  R );.    testcas
1e770 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 50 52  e( rc==SQLITE_PR
1e780 4f 54 4f 43 4f 4c 20 29 3b 0a 20 20 20 20 74 65  OTOCOL );.    te
1e790 73 74 63 61 73 65 28 20 72 63 3d 3d 53 51 4c 49  stcase( rc==SQLI
1e7a0 54 45 5f 4f 4b 20 29 3b 0a 20 20 7d 0a 20 20 72  TE_OK );.  }.  r
1e7b0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
1e7c0 2a 2a 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 61  ** Information a
1e7d0 62 6f 75 74 20 74 68 65 20 63 75 72 72 65 6e 74  bout the current
1e7e0 20 73 74 61 74 65 20 6f 66 20 74 68 65 20 57 41   state of the WA
1e7f0 4c 20 66 69 6c 65 20 61 6e 64 20 77 68 65 72 65  L file and where
1e800 0a 2a 2a 20 74 68 65 20 6e 65 78 74 20 66 73 79  .** the next fsy
1e810 6e 63 20 73 68 6f 75 6c 64 20 6f 63 63 75 72 20  nc should occur 
1e820 2d 20 70 61 73 73 65 64 20 66 72 6f 6d 20 73 71  - passed from sq
1e830 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28 29  lite3WalFrames()
1e840 20 69 6e 74 6f 0a 2a 2a 20 77 61 6c 57 72 69 74   into.** walWrit
1e850 65 54 6f 4c 6f 67 28 29 2e 0a 2a 2f 0a 74 79 70  eToLog()..*/.typ
1e860 65 64 65 66 20 73 74 72 75 63 74 20 57 61 6c 57  edef struct WalW
1e870 72 69 74 65 72 20 7b 0a 20 20 57 61 6c 20 2a 70  riter {.  Wal *p
1e880 57 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  Wal;            
1e890 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63 6f         /* The co
1e8a0 6d 70 6c 65 74 65 20 57 41 4c 20 69 6e 66 6f 72  mplete WAL infor
1e8b0 6d 61 74 69 6f 6e 20 2a 2f 0a 20 20 73 71 6c 69  mation */.  sqli
1e8c0 74 65 33 5f 66 69 6c 65 20 2a 70 46 64 3b 20 20  te3_file *pFd;  
1e8d0 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
1e8e0 57 41 4c 20 66 69 6c 65 20 74 6f 20 77 68 69 63  WAL file to whic
1e8f0 68 20 77 65 20 77 72 69 74 65 20 2a 2f 0a 20 20  h we write */.  
1e900 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 53  sqlite3_int64 iS
1e910 79 6e 63 50 6f 69 6e 74 3b 20 20 20 20 2f 2a 20  yncPoint;    /* 
1e920 46 73 79 6e 63 20 61 74 20 74 68 69 73 20 6f 66  Fsync at this of
1e930 66 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20 73 79  fset */.  int sy
1e940 6e 63 46 6c 61 67 73 3b 20 20 20 20 20 20 20 20  ncFlags;        
1e950 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20         /* Flags 
1e960 66 6f 72 20 74 68 65 20 66 73 79 6e 63 20 2a 2f  for the fsync */
1e970 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 3b 20 20  .  int szPage;  
1e980 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e990 2f 2a 20 53 69 7a 65 20 6f 66 20 6f 6e 65 20 70  /* Size of one p
1e9a0 61 67 65 20 2a 2f 0a 7d 20 57 61 6c 57 72 69 74  age */.} WalWrit
1e9b0 65 72 3b 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65  er;../*.** Write
1e9c0 20 69 41 6d 74 20 62 79 74 65 73 20 6f 66 20 63   iAmt bytes of c
1e9d0 6f 6e 74 65 6e 74 20 69 6e 74 6f 20 74 68 65 20  ontent into the 
1e9e0 57 41 4c 20 66 69 6c 65 20 62 65 67 69 6e 6e 69  WAL file beginni
1e9f0 6e 67 20 61 74 20 69 4f 66 66 73 65 74 2e 0a 2a  ng at iOffset..*
1ea00 2a 20 44 6f 20 61 20 73 79 6e 63 20 77 68 65 6e  * Do a sync when
1ea10 20 63 72 6f 73 73 69 6e 67 20 74 68 65 20 70 2d   crossing the p-
1ea20 3e 69 53 79 6e 63 50 6f 69 6e 74 20 62 6f 75 6e  >iSyncPoint boun
1ea30 64 61 72 79 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f  dary..**.** In o
1ea40 74 68 65 72 20 77 6f 72 64 73 2c 20 69 66 20 69  ther words, if i
1ea50 53 79 6e 63 50 6f 69 6e 74 20 69 73 20 69 6e 20  SyncPoint is in 
1ea60 62 65 74 77 65 65 6e 20 69 4f 66 66 73 65 74 20  between iOffset 
1ea70 61 6e 64 20 69 4f 66 66 73 65 74 2b 69 41 6d 74  and iOffset+iAmt
1ea80 2c 0a 2a 2a 20 66 69 72 73 74 20 77 72 69 74 65  ,.** first write
1ea90 20 74 68 65 20 70 61 72 74 20 62 65 66 6f 72 65   the part before
1eaa0 20 69 53 79 6e 63 50 6f 69 6e 74 2c 20 74 68 65   iSyncPoint, the
1eab0 6e 20 73 79 6e 63 2c 20 74 68 65 6e 20 77 72 69  n sync, then wri
1eac0 74 65 20 74 68 65 0a 2a 2a 20 72 65 73 74 2e 0a  te the.** rest..
1ead0 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  */.static int wa
1eae0 6c 57 72 69 74 65 54 6f 4c 6f 67 28 0a 20 20 57  lWriteToLog(.  W
1eaf0 61 6c 57 72 69 74 65 72 20 2a 70 2c 20 20 20 20  alWriter *p,    
1eb00 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c            /* WAL
1eb10 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a   to write to */.
1eb20 20 20 76 6f 69 64 20 2a 70 43 6f 6e 74 65 6e 74    void *pContent
1eb30 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
1eb40 43 6f 6e 74 65 6e 74 20 74 6f 20 62 65 20 77 72  Content to be wr
1eb50 69 74 74 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69  itten */.  int i
1eb60 41 6d 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  Amt,            
1eb70 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
1eb80 6f 66 20 62 79 74 65 73 20 74 6f 20 77 72 69 74  of bytes to writ
1eb90 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69  e */.  sqlite3_i
1eba0 6e 74 36 34 20 69 4f 66 66 73 65 74 20 20 20 20  nt64 iOffset    
1ebb0 20 20 2f 2a 20 53 74 61 72 74 20 77 72 69 74 69    /* Start writi
1ebc0 6e 67 20 61 74 20 74 68 69 73 20 6f 66 66 73 65  ng at this offse
1ebd0 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  t */.){.  int rc
1ebe0 3b 0a 20 20 69 66 28 20 69 4f 66 66 73 65 74 3c  ;.  if( iOffset<
1ebf0 70 2d 3e 69 53 79 6e 63 50 6f 69 6e 74 20 26 26  p->iSyncPoint &&
1ec00 20 69 4f 66 66 73 65 74 2b 69 41 6d 74 3e 3d 70   iOffset+iAmt>=p
1ec10 2d 3e 69 53 79 6e 63 50 6f 69 6e 74 20 29 7b 0a  ->iSyncPoint ){.
1ec20 20 20 20 20 69 6e 74 20 69 46 69 72 73 74 41 6d      int iFirstAm
1ec30 74 20 3d 20 28 69 6e 74 29 28 70 2d 3e 69 53 79  t = (int)(p->iSy
1ec40 6e 63 50 6f 69 6e 74 20 2d 20 69 4f 66 66 73 65  ncPoint - iOffse
1ec50 74 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c  t);.    rc = sql
1ec60 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70  ite3OsWrite(p->p
1ec70 46 64 2c 20 70 43 6f 6e 74 65 6e 74 2c 20 69 46  Fd, pContent, iF
1ec80 69 72 73 74 41 6d 74 2c 20 69 4f 66 66 73 65 74  irstAmt, iOffset
1ec90 29 3b 0a 20 20 20 20 69 66 28 20 72 63 20 29 20  );.    if( rc ) 
1eca0 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 69  return rc;.    i
1ecb0 4f 66 66 73 65 74 20 2b 3d 20 69 46 69 72 73 74  Offset += iFirst
1ecc0 41 6d 74 3b 0a 20 20 20 20 69 41 6d 74 20 2d 3d  Amt;.    iAmt -=
1ecd0 20 69 46 69 72 73 74 41 6d 74 3b 0a 20 20 20 20   iFirstAmt;.    
1ece0 70 43 6f 6e 74 65 6e 74 20 3d 20 28 76 6f 69 64  pContent = (void
1ecf0 2a 29 28 69 46 69 72 73 74 41 6d 74 20 2b 20 28  *)(iFirstAmt + (
1ed00 63 68 61 72 2a 29 70 43 6f 6e 74 65 6e 74 29 3b  char*)pContent);
1ed10 0a 20 20 20 20 61 73 73 65 72 74 28 20 57 41 4c  .    assert( WAL
1ed20 5f 53 59 4e 43 5f 46 4c 41 47 53 28 70 2d 3e 73  _SYNC_FLAGS(p->s
1ed30 79 6e 63 46 6c 61 67 73 29 21 3d 30 20 29 3b 0a  yncFlags)!=0 );.
1ed40 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
1ed50 4f 73 53 79 6e 63 28 70 2d 3e 70 46 64 2c 20 57  OsSync(p->pFd, W
1ed60 41 4c 5f 53 59 4e 43 5f 46 4c 41 47 53 28 70 2d  AL_SYNC_FLAGS(p-
1ed70 3e 73 79 6e 63 46 6c 61 67 73 29 29 3b 0a 20 20  >syncFlags));.  
1ed80 20 20 69 66 28 20 69 41 6d 74 3d 3d 30 20 7c 7c    if( iAmt==0 ||
1ed90 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b   rc ) return rc;
1eda0 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69  .  }.  rc = sqli
1edb0 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46  te3OsWrite(p->pF
1edc0 64 2c 20 70 43 6f 6e 74 65 6e 74 2c 20 69 41 6d  d, pContent, iAm
1edd0 74 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 72  t, iOffset);.  r
1ede0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
1edf0 2a 2a 20 57 72 69 74 65 20 6f 75 74 20 61 20 73  ** Write out a s
1ee00 69 6e 67 6c 65 20 66 72 61 6d 65 20 6f 66 20 74  ingle frame of t
1ee10 68 65 20 57 41 4c 0a 2a 2f 0a 73 74 61 74 69 63  he WAL.*/.static
1ee20 20 69 6e 74 20 77 61 6c 57 72 69 74 65 4f 6e 65   int walWriteOne
1ee30 46 72 61 6d 65 28 0a 20 20 57 61 6c 57 72 69 74  Frame(.  WalWrit
1ee40 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20  er *p,          
1ee50 20 20 20 20 20 2f 2a 20 57 68 65 72 65 20 74 6f       /* Where to
1ee60 20 77 72 69 74 65 20 74 68 65 20 66 72 61 6d 65   write the frame
1ee70 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 50 61   */.  PgHdr *pPa
1ee80 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ge,             
1ee90 20 20 2f 2a 20 54 68 65 20 70 61 67 65 20 6f 66    /* The page of
1eea0 20 74 68 65 20 66 72 61 6d 65 20 74 6f 20 62 65   the frame to be
1eeb0 20 77 72 69 74 74 65 6e 20 2a 2f 0a 20 20 69 6e   written */.  in
1eec0 74 20 6e 54 72 75 6e 63 61 74 65 2c 20 20 20 20  t nTruncate,    
1eed0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
1eee0 20 63 6f 6d 6d 69 74 20 66 6c 61 67 2e 20 20 55   commit flag.  U
1eef0 73 75 61 6c 6c 79 20 30 2e 20 20 3e 30 20 66 6f  sually 0.  >0 fo
1ef00 72 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20 73 71  r commit */.  sq
1ef10 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 66  lite3_int64 iOff
1ef20 73 65 74 20 20 20 20 20 20 20 2f 2a 20 42 79 74  set       /* Byt
1ef30 65 20 6f 66 66 73 65 74 20 61 74 20 77 68 69 63  e offset at whic
1ef40 68 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 29 7b  h to write */.){
1ef50 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
1ef60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ef70 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 63 6f 64     /* Result cod
1ef80 65 20 66 72 6f 6d 20 73 75 62 66 75 6e 63 74 69  e from subfuncti
1ef90 6f 6e 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  ons */.  void *p
1efa0 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
1efb0 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
1efc0 20 61 63 74 75 61 6c 6c 79 20 77 72 69 74 74 65   actually writte
1efd0 6e 20 2a 2f 0a 20 20 75 38 20 61 46 72 61 6d 65  n */.  u8 aFrame
1efe0 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49  [WAL_FRAME_HDRSI
1eff0 5a 45 5d 3b 20 20 20 2f 2a 20 42 75 66 66 65 72  ZE];   /* Buffer
1f000 20 74 6f 20 61 73 73 65 6d 62 6c 65 20 66 72 61   to assemble fra
1f010 6d 65 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f 0a  me-header in */.
1f020 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49  #if defined(SQLI
1f030 54 45 5f 48 41 53 5f 43 4f 44 45 43 29 0a 20 20  TE_HAS_CODEC).  
1f040 69 66 28 20 28 70 44 61 74 61 20 3d 20 73 71 6c  if( (pData = sql
1f050 69 74 65 33 50 61 67 65 72 43 6f 64 65 63 28 70  ite3PagerCodec(p
1f060 50 61 67 65 29 29 3d 3d 30 20 29 20 72 65 74 75  Page))==0 ) retu
1f070 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f  rn SQLITE_NOMEM_
1f080 42 4b 50 54 3b 0a 23 65 6c 73 65 0a 20 20 70 44  BKPT;.#else.  pD
1f090 61 74 61 20 3d 20 70 50 61 67 65 2d 3e 70 44 61  ata = pPage->pDa
1f0a0 74 61 3b 0a 23 65 6e 64 69 66 0a 20 20 77 61 6c  ta;.#endif.  wal
1f0b0 45 6e 63 6f 64 65 46 72 61 6d 65 28 70 2d 3e 70  EncodeFrame(p->p
1f0c0 57 61 6c 2c 20 70 50 61 67 65 2d 3e 70 67 6e 6f  Wal, pPage->pgno
1f0d0 2c 20 6e 54 72 75 6e 63 61 74 65 2c 20 70 44 61  , nTruncate, pDa
1f0e0 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20 72  ta, aFrame);.  r
1f0f0 63 20 3d 20 77 61 6c 57 72 69 74 65 54 6f 4c 6f  c = walWriteToLo
1f100 67 28 70 2c 20 61 46 72 61 6d 65 2c 20 73 69 7a  g(p, aFrame, siz
1f110 65 6f 66 28 61 46 72 61 6d 65 29 2c 20 69 4f 66  eof(aFrame), iOf
1f120 66 73 65 74 29 3b 0a 20 20 69 66 28 20 72 63 20  fset);.  if( rc 
1f130 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 2f  ) return rc;.  /
1f140 2a 20 57 72 69 74 65 20 74 68 65 20 70 61 67 65  * Write the page
1f150 20 64 61 74 61 20 2a 2f 0a 20 20 72 63 20 3d 20   data */.  rc = 
1f160 77 61 6c 57 72 69 74 65 54 6f 4c 6f 67 28 70 2c  walWriteToLog(p,
1f170 20 70 44 61 74 61 2c 20 70 2d 3e 73 7a 50 61 67   pData, p->szPag
1f180 65 2c 20 69 4f 66 66 73 65 74 2b 73 69 7a 65 6f  e, iOffset+sizeo
1f190 66 28 61 46 72 61 6d 65 29 29 3b 0a 20 20 72 65  f(aFrame));.  re
1f1a0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
1f1b0 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
1f1c0 69 73 20 63 61 6c 6c 65 64 20 61 73 20 70 61 72  is called as par
1f1d0 74 20 6f 66 20 63 6f 6d 6d 69 74 74 69 6e 67 20  t of committing 
1f1e0 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 69  a transaction wi
1f1f0 74 68 69 6e 20 77 68 69 63 68 0a 2a 2a 20 6f 6e  thin which.** on
1f200 65 20 6f 72 20 6d 6f 72 65 20 66 72 61 6d 65 73  e or more frames
1f210 20 68 61 76 65 20 62 65 65 6e 20 6f 76 65 72 77   have been overw
1f220 72 69 74 74 65 6e 2e 20 49 74 20 75 70 64 61 74  ritten. It updat
1f230 65 73 20 74 68 65 20 63 68 65 63 6b 73 75 6d 73  es the checksums
1f240 20 66 6f 72 0a 2a 2a 20 61 6c 6c 20 66 72 61 6d   for.** all fram
1f250 65 73 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68  es written to th
1f260 65 20 77 61 6c 20 66 69 6c 65 20 62 79 20 74 68  e wal file by th
1f270 65 20 63 75 72 72 65 6e 74 20 74 72 61 6e 73 61  e current transa
1f280 63 74 69 6f 6e 20 73 74 61 72 74 69 6e 67 0a 2a  ction starting.*
1f290 2a 20 77 69 74 68 20 74 68 65 20 65 61 72 6c 69  * with the earli
1f2a0 65 73 74 20 74 6f 20 68 61 76 65 20 62 65 65 6e  est to have been
1f2b0 20 6f 76 65 72 77 72 69 74 74 65 6e 2e 0a 2a 2a   overwritten..**
1f2c0 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73  .** SQLITE_OK is
1f2d0 20 72 65 74 75 72 6e 65 64 20 69 66 20 73 75 63   returned if suc
1f2e0 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
1f2f0 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
1f300 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73   otherwise..*/.s
1f310 74 61 74 69 63 20 69 6e 74 20 77 61 6c 52 65 77  tatic int walRew
1f320 72 69 74 65 43 68 65 63 6b 73 75 6d 73 28 57 61  riteChecksums(Wa
1f330 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 69 4c 61  l *pWal, u32 iLa
1f340 73 74 29 7b 0a 20 20 63 6f 6e 73 74 20 69 6e 74  st){.  const int
1f350 20 73 7a 50 61 67 65 20 3d 20 70 57 61 6c 2d 3e   szPage = pWal->
1f360 73 7a 50 61 67 65 3b 2f 2a 20 44 61 74 61 62 61  szPage;/* Databa
1f370 73 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f 0a  se page size */.
1f380 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
1f390 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  E_OK;           
1f3a0 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
1f3b0 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 3b 20   */.  u8 *aBuf; 
1f3c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f3d0 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
1f3e0 74 6f 20 6c 6f 61 64 20 64 61 74 61 20 66 72 6f  to load data fro
1f3f0 6d 20 77 61 6c 20 66 69 6c 65 20 69 6e 74 6f 20  m wal file into 
1f400 2a 2f 0a 20 20 75 38 20 61 46 72 61 6d 65 5b 57  */.  u8 aFrame[W
1f410 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
1f420 5d 3b 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74  ];   /* Buffer t
1f430 6f 20 61 73 73 65 6d 62 6c 65 20 66 72 61 6d 65  o assemble frame
1f440 2d 68 65 61 64 65 72 73 20 69 6e 20 2a 2f 0a 20  -headers in */. 
1f450 20 75 33 32 20 69 52 65 61 64 3b 20 20 20 20 20   u32 iRead;     
1f460 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f470 20 2f 2a 20 4e 65 78 74 20 66 72 61 6d 65 20 74   /* Next frame t
1f480 6f 20 72 65 61 64 20 66 72 6f 6d 20 77 61 6c 20  o read from wal 
1f490 66 69 6c 65 20 2a 2f 0a 20 20 69 36 34 20 69 43  file */.  i64 iC
1f4a0 6b 73 75 6d 4f 66 66 3b 0a 0a 20 20 61 42 75 66  ksumOff;..  aBuf
1f4b0 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   = sqlite3_mallo
1f4c0 63 28 73 7a 50 61 67 65 20 2b 20 57 41 4c 5f 46  c(szPage + WAL_F
1f4d0 52 41 4d 45 5f 48 44 52 53 49 5a 45 29 3b 0a 20  RAME_HDRSIZE);. 
1f4e0 20 69 66 28 20 61 42 75 66 3d 3d 30 20 29 20 72   if( aBuf==0 ) r
1f4f0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
1f500 45 4d 5f 42 4b 50 54 3b 0a 0a 20 20 2f 2a 20 46  EM_BKPT;..  /* F
1f510 69 6e 64 20 74 68 65 20 63 68 65 63 6b 73 75 6d  ind the checksum
1f520 20 76 61 6c 75 65 73 20 74 6f 20 75 73 65 20 61   values to use a
1f530 73 20 69 6e 70 75 74 20 66 6f 72 20 74 68 65 20  s input for the 
1f540 72 65 63 61 6c 63 75 6c 61 74 69 6e 67 20 74 68  recalculating th
1f550 65 0a 20 20 2a 2a 20 66 69 72 73 74 20 63 68 65  e.  ** first che
1f560 63 6b 73 75 6d 2e 20 49 66 20 74 68 65 20 66 69  cksum. If the fi
1f570 72 73 74 20 66 72 61 6d 65 20 69 73 20 66 72 61  rst frame is fra
1f580 6d 65 20 31 20 28 69 6d 70 6c 79 69 6e 67 20 74  me 1 (implying t
1f590 68 61 74 20 74 68 65 20 63 75 72 72 65 6e 74 0a  hat the current.
1f5a0 20 20 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e    ** transaction
1f5b0 20 72 65 73 74 61 72 74 65 64 20 74 68 65 20 77   restarted the w
1f5c0 61 6c 20 66 69 6c 65 29 2c 20 74 68 65 73 65 20  al file), these 
1f5d0 76 61 6c 75 65 73 20 6d 75 73 74 20 62 65 20 72  values must be r
1f5e0 65 61 64 20 66 72 6f 6d 20 74 68 65 0a 20 20 2a  ead from the.  *
1f5f0 2a 20 77 61 6c 2d 66 69 6c 65 20 68 65 61 64 65  * wal-file heade
1f600 72 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 72 65  r. Otherwise, re
1f610 61 64 20 74 68 65 6d 20 66 72 6f 6d 20 74 68 65  ad them from the
1f620 20 66 72 61 6d 65 20 68 65 61 64 65 72 20 6f 66   frame header of
1f630 20 74 68 65 0a 20 20 2a 2a 20 70 72 65 76 69 6f   the.  ** previo
1f640 75 73 20 66 72 61 6d 65 2e 20 20 2a 2f 0a 20 20  us frame.  */.  
1f650 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 69 52  assert( pWal->iR
1f660 65 43 6b 73 75 6d 3e 30 20 29 3b 0a 20 20 69 66  eCksum>0 );.  if
1f670 28 20 70 57 61 6c 2d 3e 69 52 65 43 6b 73 75 6d  ( pWal->iReCksum
1f680 3d 3d 31 20 29 7b 0a 20 20 20 20 69 43 6b 73 75  ==1 ){.    iCksu
1f690 6d 4f 66 66 20 3d 20 32 34 3b 0a 20 20 7d 65 6c  mOff = 24;.  }el
1f6a0 73 65 7b 0a 20 20 20 20 69 43 6b 73 75 6d 4f 66  se{.    iCksumOf
1f6b0 66 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73  f = walFrameOffs
1f6c0 65 74 28 70 57 61 6c 2d 3e 69 52 65 43 6b 73 75  et(pWal->iReCksu
1f6d0 6d 2d 31 2c 20 73 7a 50 61 67 65 29 20 2b 20 31  m-1, szPage) + 1
1f6e0 36 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71  6;.  }.  rc = sq
1f6f0 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c  lite3OsRead(pWal
1f700 2d 3e 70 57 61 6c 46 64 2c 20 61 42 75 66 2c 20  ->pWalFd, aBuf, 
1f710 73 69 7a 65 6f 66 28 75 33 32 29 2a 32 2c 20 69  sizeof(u32)*2, i
1f720 43 6b 73 75 6d 4f 66 66 29 3b 0a 20 20 70 57 61  CksumOff);.  pWa
1f730 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
1f740 75 6d 5b 30 5d 20 3d 20 73 71 6c 69 74 65 33 47  um[0] = sqlite3G
1f750 65 74 34 62 79 74 65 28 61 42 75 66 29 3b 0a 20  et4byte(aBuf);. 
1f760 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
1f770 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 73 71 6c 69  eCksum[1] = sqli
1f780 74 65 33 47 65 74 34 62 79 74 65 28 26 61 42 75  te3Get4byte(&aBu
1f790 66 5b 73 69 7a 65 6f 66 28 75 33 32 29 5d 29 3b  f[sizeof(u32)]);
1f7a0 0a 0a 20 20 69 52 65 61 64 20 3d 20 70 57 61 6c  ..  iRead = pWal
1f7b0 2d 3e 69 52 65 43 6b 73 75 6d 3b 0a 20 20 70 57  ->iReCksum;.  pW
1f7c0 61 6c 2d 3e 69 52 65 43 6b 73 75 6d 20 3d 20 30  al->iReCksum = 0
1f7d0 3b 0a 20 20 66 6f 72 28 3b 20 72 63 3d 3d 53 51  ;.  for(; rc==SQ
1f7e0 4c 49 54 45 5f 4f 4b 20 26 26 20 69 52 65 61 64  LITE_OK && iRead
1f7f0 3c 3d 69 4c 61 73 74 3b 20 69 52 65 61 64 2b 2b  <=iLast; iRead++
1f800 29 7b 0a 20 20 20 20 69 36 34 20 69 4f 66 66 20  ){.    i64 iOff 
1f810 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74  = walFrameOffset
1f820 28 69 52 65 61 64 2c 20 73 7a 50 61 67 65 29 3b  (iRead, szPage);
1f830 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
1f840 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57  3OsRead(pWal->pW
1f850 61 6c 46 64 2c 20 61 42 75 66 2c 20 73 7a 50 61  alFd, aBuf, szPa
1f860 67 65 2b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52  ge+WAL_FRAME_HDR
1f870 53 49 5a 45 2c 20 69 4f 66 66 29 3b 0a 20 20 20  SIZE, iOff);.   
1f880 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
1f890 4f 4b 20 29 7b 0a 20 20 20 20 20 20 75 33 32 20  OK ){.      u32 
1f8a0 69 50 67 6e 6f 2c 20 6e 44 62 53 69 7a 65 3b 0a  iPgno, nDbSize;.
1f8b0 20 20 20 20 20 20 69 50 67 6e 6f 20 3d 20 73 71        iPgno = sq
1f8c0 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 61 42  lite3Get4byte(aB
1f8d0 75 66 29 3b 0a 20 20 20 20 20 20 6e 44 62 53 69  uf);.      nDbSi
1f8e0 7a 65 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34  ze = sqlite3Get4
1f8f0 62 79 74 65 28 26 61 42 75 66 5b 34 5d 29 3b 0a  byte(&aBuf[4]);.
1f900 0a 20 20 20 20 20 20 77 61 6c 45 6e 63 6f 64 65  .      walEncode
1f910 46 72 61 6d 65 28 70 57 61 6c 2c 20 69 50 67 6e  Frame(pWal, iPgn
1f920 6f 2c 20 6e 44 62 53 69 7a 65 2c 20 26 61 42 75  o, nDbSize, &aBu
1f930 66 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  f[WAL_FRAME_HDRS
1f940 49 5a 45 5d 2c 20 61 46 72 61 6d 65 29 3b 0a 20  IZE], aFrame);. 
1f950 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
1f960 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70  3OsWrite(pWal->p
1f970 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20 73  WalFd, aFrame, s
1f980 69 7a 65 6f 66 28 61 46 72 61 6d 65 29 2c 20 69  izeof(aFrame), i
1f990 4f 66 66 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  Off);.    }.  }.
1f9a0 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
1f9b0 61 42 75 66 29 3b 0a 20 20 72 65 74 75 72 6e 20  aBuf);.  return 
1f9c0 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 57 72  rc;.}../* .** Wr
1f9d0 69 74 65 20 61 20 73 65 74 20 6f 66 20 66 72 61  ite a set of fra
1f9e0 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67 2e 20  mes to the log. 
1f9f0 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20  The caller must 
1fa00 68 6f 6c 64 20 74 68 65 20 77 72 69 74 65 2d 6c  hold the write-l
1fa10 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20 6c 6f  ock.** on the lo
1fa20 67 20 66 69 6c 65 20 28 6f 62 74 61 69 6e 65 64  g file (obtained
1fa30 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 57 61   using sqlite3Wa
1fa40 6c 42 65 67 69 6e 57 72 69 74 65 54 72 61 6e 73  lBeginWriteTrans
1fa50 61 63 74 69 6f 6e 28 29 29 2e 0a 2a 2f 0a 69 6e  action())..*/.in
1fa60 74 20 73 71 6c 69 74 65 33 57 61 6c 46 72 61 6d  t sqlite3WalFram
1fa70 65 73 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c  es(.  Wal *pWal,
1fa80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fa90 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 68 61 6e        /* Wal han
1faa0 64 6c 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20  dle to write to 
1fab0 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 2c  */.  int szPage,
1fac0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fad0 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
1fae0 20 70 61 67 65 2d 73 69 7a 65 20 69 6e 20 62 79   page-size in by
1faf0 74 65 73 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a  tes */.  PgHdr *
1fb00 70 4c 69 73 74 2c 20 20 20 20 20 20 20 20 20 20  pList,          
1fb10 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74           /* List
1fb20 20 6f 66 20 64 69 72 74 79 20 70 61 67 65 73 20   of dirty pages 
1fb30 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 50 67  to write */.  Pg
1fb40 6e 6f 20 6e 54 72 75 6e 63 61 74 65 2c 20 20 20  no nTruncate,   
1fb50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1fb60 20 44 61 74 61 62 61 73 65 20 73 69 7a 65 20 61   Database size a
1fb70 66 74 65 72 20 74 68 69 73 20 63 6f 6d 6d 69 74  fter this commit
1fb80 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43 6f 6d 6d   */.  int isComm
1fb90 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  it,             
1fba0 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
1fbb0 20 74 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 69   this is a commi
1fbc0 74 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f  t */.  int sync_
1fbd0 66 6c 61 67 73 20 20 20 20 20 20 20 20 20 20 20  flags           
1fbe0 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20         /* Flags 
1fbf0 74 6f 20 70 61 73 73 20 74 6f 20 4f 73 53 79 6e  to pass to OsSyn
1fc00 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 29 7b  c() (or 0) */.){
1fc10 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
1fc20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fc30 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 63 61     /* Used to ca
1fc40 74 63 68 20 72 65 74 75 72 6e 20 63 6f 64 65 73  tch return codes
1fc50 20 2a 2f 0a 20 20 75 33 32 20 69 46 72 61 6d 65   */.  u32 iFrame
1fc60 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1fc70 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 66 72        /* Next fr
1fc80 61 6d 65 20 61 64 64 72 65 73 73 20 2a 2f 0a 20  ame address */. 
1fc90 20 50 67 48 64 72 20 2a 70 3b 20 20 20 20 20 20   PgHdr *p;      
1fca0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fcb0 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f 20   /* Iterator to 
1fcc0 72 75 6e 20 74 68 72 6f 75 67 68 20 70 4c 69 73  run through pLis
1fcd0 74 20 77 69 74 68 2e 20 2a 2f 0a 20 20 50 67 48  t with. */.  PgH
1fce0 64 72 20 2a 70 4c 61 73 74 20 3d 20 30 3b 20 20  dr *pLast = 0;  
1fcf0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1fd00 4c 61 73 74 20 66 72 61 6d 65 20 69 6e 20 6c 69  Last frame in li
1fd10 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 45 78 74  st */.  int nExt
1fd20 72 61 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  ra = 0;         
1fd30 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
1fd40 72 20 6f 66 20 65 78 74 72 61 20 63 6f 70 69 65  r of extra copie
1fd50 73 20 6f 66 20 6c 61 73 74 20 70 61 67 65 20 2a  s of last page *
1fd60 2f 0a 20 20 69 6e 74 20 73 7a 46 72 61 6d 65 3b  /.  int szFrame;
1fd70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fd80 20 20 20 20 2f 2a 20 54 68 65 20 73 69 7a 65 20      /* The size 
1fd90 6f 66 20 61 20 73 69 6e 67 6c 65 20 66 72 61 6d  of a single fram
1fda0 65 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66 73  e */.  i64 iOffs
1fdb0 65 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  et;             
1fdc0 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 62         /* Next b
1fdd0 79 74 65 20 74 6f 20 77 72 69 74 65 20 69 6e 20  yte to write in 
1fde0 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 57 61  WAL file */.  Wa
1fdf0 6c 57 72 69 74 65 72 20 77 3b 20 20 20 20 20 20  lWriter w;      
1fe00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1fe10 20 54 68 65 20 77 72 69 74 65 72 20 2a 2f 0a 20   The writer */. 
1fe20 20 75 33 32 20 69 46 69 72 73 74 20 3d 20 30 3b   u32 iFirst = 0;
1fe30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1fe40 20 2f 2a 20 46 69 72 73 74 20 66 72 61 6d 65 20   /* First frame 
1fe50 74 68 61 74 20 6d 61 79 20 62 65 20 6f 76 65 72  that may be over
1fe60 77 72 69 74 74 65 6e 20 2a 2f 0a 20 20 57 61 6c  written */.  Wal
1fe70 49 6e 64 65 78 48 64 72 20 2a 70 4c 69 76 65 3b  IndexHdr *pLive;
1fe80 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1fe90 50 6f 69 6e 74 65 72 20 74 6f 20 73 68 61 72 65  Pointer to share
1fea0 64 20 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20 61  d header */..  a
1feb0 73 73 65 72 74 28 20 70 4c 69 73 74 20 29 3b 0a  ssert( pList );.
1fec0 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
1fed0 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 0a 20 20  writeLock );..  
1fee0 2f 2a 20 49 66 20 74 68 69 73 20 66 72 61 6d 65  /* If this frame
1fef0 20 73 65 74 20 63 6f 6d 70 6c 65 74 65 73 20 61   set completes a
1ff00 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20 74 68   transaction, th
1ff10 65 6e 20 6e 54 72 75 6e 63 61 74 65 3e 30 2e 20  en nTruncate>0. 
1ff20 20 49 66 0a 20 20 2a 2a 20 6e 54 72 75 6e 63 61   If.  ** nTrunca
1ff30 74 65 3d 3d 30 20 74 68 65 6e 20 74 68 69 73 20  te==0 then this 
1ff40 66 72 61 6d 65 20 73 65 74 20 64 6f 65 73 20 6e  frame set does n
1ff50 6f 74 20 63 6f 6d 70 6c 65 74 65 20 74 68 65 20  ot complete the 
1ff60 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 2a 2f 0a  transaction. */.
1ff70 20 20 61 73 73 65 72 74 28 20 28 69 73 43 6f 6d    assert( (isCom
1ff80 6d 69 74 21 3d 30 29 3d 3d 28 6e 54 72 75 6e 63  mit!=0)==(nTrunc
1ff90 61 74 65 21 3d 30 29 20 29 3b 0a 0a 23 69 66 20  ate!=0) );..#if 
1ffa0 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54  defined(SQLITE_T
1ffb0 45 53 54 29 20 26 26 20 64 65 66 69 6e 65 64 28  EST) && defined(
1ffc0 53 51 4c 49 54 45 5f 44 45 42 55 47 29 0a 20 20  SQLITE_DEBUG).  
1ffd0 7b 20 69 6e 74 20 63 6e 74 3b 20 66 6f 72 28 63  { int cnt; for(c
1ffe0 6e 74 3d 30 2c 20 70 3d 70 4c 69 73 74 3b 20 70  nt=0, p=pList; p
1fff0 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 2c 20 63  ; p=p->pDirty, c
20000 6e 74 2b 2b 29 7b 7d 0a 20 20 20 20 57 41 4c 54  nt++){}.    WALT
20010 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 66 72  RACE(("WAL%p: fr
20020 61 6d 65 20 77 72 69 74 65 20 62 65 67 69 6e 2e  ame write begin.
20030 20 25 64 20 66 72 61 6d 65 73 2e 20 6d 78 46 72   %d frames. mxFr
20040 61 6d 65 3d 25 64 2e 20 25 73 5c 6e 22 2c 0a 20  ame=%d. %s\n",. 
20050 20 20 20 20 20 20 20 20 20 20 20 20 20 70 57 61               pWa
20060 6c 2c 20 63 6e 74 2c 20 70 57 61 6c 2d 3e 68 64  l, cnt, pWal->hd
20070 72 2e 6d 78 46 72 61 6d 65 2c 20 69 73 43 6f 6d  r.mxFrame, isCom
20080 6d 69 74 20 3f 20 22 43 6f 6d 6d 69 74 22 20 3a  mit ? "Commit" :
20090 20 22 53 70 69 6c 6c 22 29 29 3b 0a 20 20 7d 0a   "Spill"));.  }.
200a0 23 65 6e 64 69 66 0a 0a 20 20 70 4c 69 76 65 20  #endif..  pLive 
200b0 3d 20 28 57 61 6c 49 6e 64 65 78 48 64 72 2a 29  = (WalIndexHdr*)
200c0 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c  walIndexHdr(pWal
200d0 29 3b 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28  );.  if( memcmp(
200e0 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69  &pWal->hdr, (voi
200f0 64 20 2a 29 70 4c 69 76 65 2c 20 73 69 7a 65 6f  d *)pLive, sizeo
20100 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 21  f(WalIndexHdr))!
20110 3d 30 20 29 7b 0a 20 20 20 20 69 46 69 72 73 74  =0 ){.    iFirst
20120 20 3d 20 70 4c 69 76 65 2d 3e 6d 78 46 72 61 6d   = pLive->mxFram
20130 65 2b 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53  e+1;.  }..  /* S
20140 65 65 20 69 66 20 69 74 20 69 73 20 70 6f 73 73  ee if it is poss
20150 69 62 6c 65 20 74 6f 20 77 72 69 74 65 20 74 68  ible to write th
20160 65 73 65 20 66 72 61 6d 65 73 20 69 6e 74 6f 20  ese frames into 
20170 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
20180 0a 20 20 2a 2a 20 6c 6f 67 20 66 69 6c 65 2c 20  .  ** log file, 
20190 69 6e 73 74 65 61 64 20 6f 66 20 61 70 70 65 6e  instead of appen
201a0 64 69 6e 67 20 74 6f 20 69 74 20 61 74 20 70 57  ding to it at pW
201b0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e  al->hdr.mxFrame.
201c0 0a 20 20 2a 2f 0a 20 20 69 66 28 20 53 51 4c 49  .  */.  if( SQLI
201d0 54 45 5f 4f 4b 21 3d 28 72 63 20 3d 20 77 61 6c  TE_OK!=(rc = wal
201e0 52 65 73 74 61 72 74 4c 6f 67 28 70 57 61 6c 29  RestartLog(pWal)
201f0 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
20200 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66  rc;.  }..  /* If
20210 20 74 68 69 73 20 69 73 20 74 68 65 20 66 69 72   this is the fir
20220 73 74 20 66 72 61 6d 65 20 77 72 69 74 74 65 6e  st frame written
20230 20 69 6e 74 6f 20 74 68 65 20 6c 6f 67 2c 20 77   into the log, w
20240 72 69 74 65 20 74 68 65 20 57 41 4c 0a 20 20 2a  rite the WAL.  *
20250 2a 20 68 65 61 64 65 72 20 74 6f 20 74 68 65 20  * header to the 
20260 73 74 61 72 74 20 6f 66 20 74 68 65 20 57 41 4c  start of the WAL
20270 20 66 69 6c 65 2e 20 53 65 65 20 63 6f 6d 6d 65   file. See comme
20280 6e 74 73 20 61 74 20 74 68 65 20 74 6f 70 20 6f  nts at the top o
20290 66 0a 20 20 2a 2a 20 74 68 69 73 20 73 6f 75 72  f.  ** this sour
202a0 63 65 20 66 69 6c 65 20 66 6f 72 20 61 20 64 65  ce file for a de
202b0 73 63 72 69 70 74 69 6f 6e 20 6f 66 20 74 68 65  scription of the
202c0 20 57 41 4c 20 68 65 61 64 65 72 20 66 6f 72 6d   WAL header form
202d0 61 74 2e 0a 20 20 2a 2f 0a 20 20 69 46 72 61 6d  at..  */.  iFram
202e0 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  e = pWal->hdr.mx
202f0 46 72 61 6d 65 3b 0a 20 20 69 66 28 20 69 46 72  Frame;.  if( iFr
20300 61 6d 65 3d 3d 30 20 29 7b 0a 20 20 20 20 75 38  ame==0 ){.    u8
20310 20 61 57 61 6c 48 64 72 5b 57 41 4c 5f 48 44 52   aWalHdr[WAL_HDR
20320 53 49 5a 45 5d 3b 20 20 20 20 20 20 2f 2a 20 42  SIZE];      /* B
20330 75 66 66 65 72 20 74 6f 20 61 73 73 65 6d 62 6c  uffer to assembl
20340 65 20 77 61 6c 2d 68 65 61 64 65 72 20 69 6e 20  e wal-header in 
20350 2a 2f 0a 20 20 20 20 75 33 32 20 61 43 6b 73 75  */.    u32 aCksu
20360 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20 20  m[2];           
20370 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d       /* Checksum
20380 20 66 6f 72 20 77 61 6c 2d 68 65 61 64 65 72 20   for wal-header 
20390 2a 2f 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 50  */..    sqlite3P
203a0 75 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72  ut4byte(&aWalHdr
203b0 5b 30 5d 2c 20 28 57 41 4c 5f 4d 41 47 49 43 20  [0], (WAL_MAGIC 
203c0 7c 20 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49  | SQLITE_BIGENDI
203d0 41 4e 29 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  AN));.    sqlite
203e0 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c 48  3Put4byte(&aWalH
203f0 64 72 5b 34 5d 2c 20 57 41 4c 5f 4d 41 58 5f 56  dr[4], WAL_MAX_V
20400 45 52 53 49 4f 4e 29 3b 0a 20 20 20 20 73 71 6c  ERSION);.    sql
20410 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57  ite3Put4byte(&aW
20420 61 6c 48 64 72 5b 38 5d 2c 20 73 7a 50 61 67 65  alHdr[8], szPage
20430 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75  );.    sqlite3Pu
20440 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b  t4byte(&aWalHdr[
20450 31 32 5d 2c 20 70 57 61 6c 2d 3e 6e 43 6b 70 74  12], pWal->nCkpt
20460 29 3b 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d  );.    if( pWal-
20470 3e 6e 43 6b 70 74 3d 3d 30 20 29 20 73 71 6c 69  >nCkpt==0 ) sqli
20480 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 38  te3_randomness(8
20490 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c  , pWal->hdr.aSal
204a0 74 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26  t);.    memcpy(&
204b0 61 57 61 6c 48 64 72 5b 31 36 5d 2c 20 70 57 61  aWalHdr[16], pWa
204c0 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 38 29  l->hdr.aSalt, 8)
204d0 3b 0a 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75  ;.    walChecksu
204e0 6d 42 79 74 65 73 28 31 2c 20 61 57 61 6c 48 64  mBytes(1, aWalHd
204f0 72 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2d 32  r, WAL_HDRSIZE-2
20500 2a 34 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b 0a  *4, 0, aCksum);.
20510 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62      sqlite3Put4b
20520 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32 34 5d  yte(&aWalHdr[24]
20530 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b 0a 20 20  , aCksum[0]);.  
20540 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74    sqlite3Put4byt
20550 65 28 26 61 57 61 6c 48 64 72 5b 32 38 5d 2c 20  e(&aWalHdr[28], 
20560 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 20 20 20 20  aCksum[1]);.    
20570 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50 61 67  .    pWal->szPag
20580 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20  e = szPage;.    
20590 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64  pWal->hdr.bigEnd
205a0 43 6b 73 75 6d 20 3d 20 53 51 4c 49 54 45 5f 42  Cksum = SQLITE_B
205b0 49 47 45 4e 44 49 41 4e 3b 0a 20 20 20 20 70 57  IGENDIAN;.    pW
205c0 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
205d0 73 75 6d 5b 30 5d 20 3d 20 61 43 6b 73 75 6d 5b  sum[0] = aCksum[
205e0 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64  0];.    pWal->hd
205f0 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d  r.aFrameCksum[1]
20600 20 3d 20 61 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20   = aCksum[1];.  
20610 20 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61 74 65    pWal->truncate
20620 4f 6e 43 6f 6d 6d 69 74 20 3d 20 31 3b 0a 0a 20  OnCommit = 1;.. 
20630 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
20640 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 57 61  sWrite(pWal->pWa
20650 6c 46 64 2c 20 61 57 61 6c 48 64 72 2c 20 73 69  lFd, aWalHdr, si
20660 7a 65 6f 66 28 61 57 61 6c 48 64 72 29 2c 20 30  zeof(aWalHdr), 0
20670 29 3b 0a 20 20 20 20 57 41 4c 54 52 41 43 45 28  );.    WALTRACE(
20680 28 22 57 41 4c 25 70 3a 20 77 61 6c 2d 68 65 61  ("WAL%p: wal-hea
20690 64 65 72 20 77 72 69 74 65 20 25 73 5c 6e 22 2c  der write %s\n",
206a0 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69   pWal, rc ? "fai
206b0 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
206c0 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
206d0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65  E_OK ){.      re
206e0 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 0a  turn rc;.    }..
206f0 20 20 20 20 2f 2a 20 53 79 6e 63 20 74 68 65 20      /* Sync the 
20700 68 65 61 64 65 72 20 28 75 6e 6c 65 73 73 20 53  header (unless S
20710 51 4c 49 54 45 5f 49 4f 43 41 50 5f 53 45 51 55  QLITE_IOCAP_SEQU
20720 45 4e 54 49 41 4c 20 69 73 20 74 72 75 65 20 6f  ENTIAL is true o
20730 72 20 75 6e 6c 65 73 73 0a 20 20 20 20 2a 2a 20  r unless.    ** 
20740 61 6c 6c 20 73 79 6e 63 69 6e 67 20 69 73 20 74  all syncing is t
20750 75 72 6e 65 64 20 6f 66 66 20 62 79 20 50 52 41  urned off by PRA
20760 47 4d 41 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d  GMA synchronous=
20770 4f 46 46 29 2e 20 20 4f 74 68 65 72 77 69 73 65  OFF).  Otherwise
20780 0a 20 20 20 20 2a 2a 20 61 6e 20 6f 75 74 2d 6f  .    ** an out-o
20790 66 2d 6f 72 64 65 72 20 77 72 69 74 65 20 66 6f  f-order write fo
207a0 6c 6c 6f 77 69 6e 67 20 61 20 57 41 4c 20 72 65  llowing a WAL re
207b0 73 74 61 72 74 20 63 6f 75 6c 64 20 72 65 73 75  start could resu
207c0 6c 74 20 69 6e 0a 20 20 20 20 2a 2a 20 64 61 74  lt in.    ** dat
207d0 61 62 61 73 65 20 63 6f 72 72 75 70 74 69 6f 6e  abase corruption
207e0 2e 20 20 53 65 65 20 74 68 65 20 74 69 63 6b 65  .  See the ticke
207f0 74 3a 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a  t:.    **.    **
20800 20 20 20 20 20 68 74 74 70 73 3a 2f 2f 73 71 6c       https://sql
20810 69 74 65 2e 6f 72 67 2f 73 72 63 2f 69 6e 66 6f  ite.org/src/info
20820 2f 66 66 35 62 65 37 33 64 65 65 0a 20 20 20 20  /ff5be73dee.    
20830 2a 2f 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d  */.    if( pWal-
20840 3e 73 79 6e 63 48 65 61 64 65 72 20 29 7b 0a 20  >syncHeader ){. 
20850 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
20860 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57  3OsSync(pWal->pW
20870 61 6c 46 64 2c 20 43 4b 50 54 5f 53 59 4e 43 5f  alFd, CKPT_SYNC_
20880 46 4c 41 47 53 28 73 79 6e 63 5f 66 6c 61 67 73  FLAGS(sync_flags
20890 29 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  ));.      if( rc
208a0 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
208b0 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65 72 74    }.  }.  assert
208c0 28 20 28 69 6e 74 29 70 57 61 6c 2d 3e 73 7a 50  ( (int)pWal->szP
208d0 61 67 65 3d 3d 73 7a 50 61 67 65 20 29 3b 0a 0a  age==szPage );..
208e0 20 20 2f 2a 20 53 65 74 75 70 20 69 6e 66 6f 72    /* Setup infor
208f0 6d 61 74 69 6f 6e 20 6e 65 65 64 65 64 20 74 6f  mation needed to
20900 20 77 72 69 74 65 20 66 72 61 6d 65 73 20 69 6e   write frames in
20910 74 6f 20 74 68 65 20 57 41 4c 20 2a 2f 0a 20 20  to the WAL */.  
20920 77 2e 70 57 61 6c 20 3d 20 70 57 61 6c 3b 0a 20  w.pWal = pWal;. 
20930 20 77 2e 70 46 64 20 3d 20 70 57 61 6c 2d 3e 70   w.pFd = pWal->p
20940 57 61 6c 46 64 3b 0a 20 20 77 2e 69 53 79 6e 63  WalFd;.  w.iSync
20950 50 6f 69 6e 74 20 3d 20 30 3b 0a 20 20 77 2e 73  Point = 0;.  w.s
20960 79 6e 63 46 6c 61 67 73 20 3d 20 73 79 6e 63 5f  yncFlags = sync_
20970 66 6c 61 67 73 3b 0a 20 20 77 2e 73 7a 50 61 67  flags;.  w.szPag
20980 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 69 4f  e = szPage;.  iO
20990 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61 6d 65  ffset = walFrame
209a0 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2b 31 2c  Offset(iFrame+1,
209b0 20 73 7a 50 61 67 65 29 3b 0a 20 20 73 7a 46 72   szPage);.  szFr
209c0 61 6d 65 20 3d 20 73 7a 50 61 67 65 20 2b 20 57  ame = szPage + W
209d0 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
209e0 3b 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20 61 6c  ;..  /* Write al
209f0 6c 20 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68  l frames into th
20a00 65 20 6c 6f 67 20 66 69 6c 65 20 65 78 61 63 74  e log file exact
20a10 6c 79 20 6f 6e 63 65 20 2a 2f 0a 20 20 66 6f 72  ly once */.  for
20a20 28 70 3d 70 4c 69 73 74 3b 20 70 3b 20 70 3d 70  (p=pList; p; p=p
20a30 2d 3e 70 44 69 72 74 79 29 7b 0a 20 20 20 20 69  ->pDirty){.    i
20a40 6e 74 20 6e 44 62 53 69 7a 65 3b 20 20 20 2f 2a  nt nDbSize;   /*
20a50 20 30 20 6e 6f 72 6d 61 6c 6c 79 2e 20 20 50 6f   0 normally.  Po
20a60 73 69 74 69 76 65 20 3d 3d 20 63 6f 6d 6d 69 74  sitive == commit
20a70 20 66 6c 61 67 20 2a 2f 0a 0a 20 20 20 20 2f 2a   flag */..    /*
20a80 20 43 68 65 63 6b 20 69 66 20 74 68 69 73 20 70   Check if this p
20a90 61 67 65 20 68 61 73 20 61 6c 72 65 61 64 79 20  age has already 
20aa0 62 65 65 6e 20 77 72 69 74 74 65 6e 20 69 6e 74  been written int
20ab0 6f 20 74 68 65 20 77 61 6c 20 66 69 6c 65 20 62  o the wal file b
20ac0 79 0a 20 20 20 20 2a 2a 20 74 68 65 20 63 75 72  y.    ** the cur
20ad0 72 65 6e 74 20 74 72 61 6e 73 61 63 74 69 6f 6e  rent transaction
20ae0 2e 20 49 66 20 73 6f 2c 20 6f 76 65 72 77 72 69  . If so, overwri
20af0 74 65 20 74 68 65 20 65 78 69 73 74 69 6e 67 20  te the existing 
20b00 66 72 61 6d 65 20 61 6e 64 0a 20 20 20 20 2a 2a  frame and.    **
20b10 20 73 65 74 20 57 61 6c 2e 77 72 69 74 65 4c 6f   set Wal.writeLo
20b20 63 6b 20 74 6f 20 57 41 4c 5f 57 52 49 54 45 4c  ck to WAL_WRITEL
20b30 4f 43 4b 5f 52 45 43 4b 53 55 4d 20 2d 20 69 6e  OCK_RECKSUM - in
20b40 64 69 63 61 74 69 6e 67 20 74 68 61 74 20 0a 20  dicating that . 
20b50 20 20 20 2a 2a 20 63 68 65 63 6b 73 75 6d 73 20     ** checksums 
20b60 6d 75 73 74 20 62 65 20 72 65 63 6f 6d 70 75 74  must be recomput
20b70 65 64 20 77 68 65 6e 20 74 68 65 20 74 72 61 6e  ed when the tran
20b80 73 61 63 74 69 6f 6e 20 69 73 20 63 6f 6d 6d 69  saction is commi
20b90 74 74 65 64 2e 20 20 2a 2f 0a 20 20 20 20 69 66  tted.  */.    if
20ba0 28 20 69 46 69 72 73 74 20 26 26 20 28 70 2d 3e  ( iFirst && (p->
20bb0 70 44 69 72 74 79 20 7c 7c 20 69 73 43 6f 6d 6d  pDirty || isComm
20bc0 69 74 3d 3d 30 29 20 29 7b 0a 20 20 20 20 20 20  it==0) ){.      
20bd0 75 33 32 20 69 57 72 69 74 65 20 3d 20 30 3b 0a  u32 iWrite = 0;.
20be0 20 20 20 20 20 20 56 56 41 5f 4f 4e 4c 59 28 72        VVA_ONLY(r
20bf0 63 20 3d 29 20 73 71 6c 69 74 65 33 57 61 6c 46  c =) sqlite3WalF
20c00 69 6e 64 46 72 61 6d 65 28 70 57 61 6c 2c 20 70  indFrame(pWal, p
20c10 2d 3e 70 67 6e 6f 2c 20 26 69 57 72 69 74 65 29  ->pgno, &iWrite)
20c20 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
20c30 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c  rc==SQLITE_OK ||
20c40 20 69 57 72 69 74 65 3d 3d 30 20 29 3b 0a 20 20   iWrite==0 );.  
20c50 20 20 20 20 69 66 28 20 69 57 72 69 74 65 3e 3d      if( iWrite>=
20c60 69 46 69 72 73 74 20 29 7b 0a 20 20 20 20 20 20  iFirst ){.      
20c70 20 20 69 36 34 20 69 4f 66 66 20 3d 20 77 61 6c    i64 iOff = wal
20c80 46 72 61 6d 65 4f 66 66 73 65 74 28 69 57 72 69  FrameOffset(iWri
20c90 74 65 2c 20 73 7a 50 61 67 65 29 20 2b 20 57 41  te, szPage) + WA
20ca0 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b  L_FRAME_HDRSIZE;
20cb0 0a 20 20 20 20 20 20 20 20 76 6f 69 64 20 2a 70  .        void *p
20cc0 44 61 74 61 3b 0a 20 20 20 20 20 20 20 20 69 66  Data;.        if
20cd0 28 20 70 57 61 6c 2d 3e 69 52 65 43 6b 73 75 6d  ( pWal->iReCksum
20ce0 3d 3d 30 20 7c 7c 20 69 57 72 69 74 65 3c 70 57  ==0 || iWrite<pW
20cf0 61 6c 2d 3e 69 52 65 43 6b 73 75 6d 20 29 7b 0a  al->iReCksum ){.
20d00 20 20 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e            pWal->
20d10 69 52 65 43 6b 73 75 6d 20 3d 20 69 57 72 69 74  iReCksum = iWrit
20d20 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 23 69 66  e;.        }.#if
20d30 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
20d40 48 41 53 5f 43 4f 44 45 43 29 0a 20 20 20 20 20  HAS_CODEC).     
20d50 20 20 20 69 66 28 20 28 70 44 61 74 61 20 3d 20     if( (pData = 
20d60 73 71 6c 69 74 65 33 50 61 67 65 72 43 6f 64 65  sqlite3PagerCode
20d70 63 28 70 29 29 3d 3d 30 20 29 20 72 65 74 75 72  c(p))==0 ) retur
20d80 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
20d90 23 65 6c 73 65 0a 20 20 20 20 20 20 20 20 70 44  #else.        pD
20da0 61 74 61 20 3d 20 70 2d 3e 70 44 61 74 61 3b 0a  ata = p->pData;.
20db0 23 65 6e 64 69 66 0a 20 20 20 20 20 20 20 20 72  #endif.        r
20dc0 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69  c = sqlite3OsWri
20dd0 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  te(pWal->pWalFd,
20de0 20 70 44 61 74 61 2c 20 73 7a 50 61 67 65 2c 20   pData, szPage, 
20df0 69 4f 66 66 29 3b 0a 20 20 20 20 20 20 20 20 69  iOff);.        i
20e00 66 28 20 72 63 20 29 20 72 65 74 75 72 6e 20 72  f( rc ) return r
20e10 63 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e 66 6c  c;.        p->fl
20e20 61 67 73 20 26 3d 20 7e 50 47 48 44 52 5f 57 41  ags &= ~PGHDR_WA
20e30 4c 5f 41 50 50 45 4e 44 3b 0a 20 20 20 20 20 20  L_APPEND;.      
20e40 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20    continue;.    
20e50 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69    }.    }..    i
20e60 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 61 73 73  Frame++;.    ass
20e70 65 72 74 28 20 69 4f 66 66 73 65 74 3d 3d 77 61  ert( iOffset==wa
20e80 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46 72  lFrameOffset(iFr
20e90 61 6d 65 2c 20 73 7a 50 61 67 65 29 20 29 3b 0a  ame, szPage) );.
20ea0 20 20 20 20 6e 44 62 53 69 7a 65 20 3d 20 28 69      nDbSize = (i
20eb0 73 43 6f 6d 6d 69 74 20 26 26 20 70 2d 3e 70 44  sCommit && p->pD
20ec0 69 72 74 79 3d 3d 30 29 20 3f 20 6e 54 72 75 6e  irty==0) ? nTrun
20ed0 63 61 74 65 20 3a 20 30 3b 0a 20 20 20 20 72 63  cate : 0;.    rc
20ee0 20 3d 20 77 61 6c 57 72 69 74 65 4f 6e 65 46 72   = walWriteOneFr
20ef0 61 6d 65 28 26 77 2c 20 70 2c 20 6e 44 62 53 69  ame(&w, p, nDbSi
20f00 7a 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  ze, iOffset);.  
20f10 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72    if( rc ) retur
20f20 6e 20 72 63 3b 0a 20 20 20 20 70 4c 61 73 74 20  n rc;.    pLast 
20f30 3d 20 70 3b 0a 20 20 20 20 69 4f 66 66 73 65 74  = p;.    iOffset
20f40 20 2b 3d 20 73 7a 46 72 61 6d 65 3b 0a 20 20 20   += szFrame;.   
20f50 20 70 2d 3e 66 6c 61 67 73 20 7c 3d 20 50 47 48   p->flags |= PGH
20f60 44 52 5f 57 41 4c 5f 41 50 50 45 4e 44 3b 0a 20  DR_WAL_APPEND;. 
20f70 20 7d 0a 0a 20 20 2f 2a 20 52 65 63 61 6c 63 75   }..  /* Recalcu
20f80 6c 61 74 65 20 63 68 65 63 6b 73 75 6d 73 20 77  late checksums w
20f90 69 74 68 69 6e 20 74 68 65 20 77 61 6c 20 66 69  ithin the wal fi
20fa0 6c 65 20 69 66 20 72 65 71 75 69 72 65 64 2e 20  le if required. 
20fb0 2a 2f 0a 20 20 69 66 28 20 69 73 43 6f 6d 6d 69  */.  if( isCommi
20fc0 74 20 26 26 20 70 57 61 6c 2d 3e 69 52 65 43 6b  t && pWal->iReCk
20fd0 73 75 6d 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  sum ){.    rc = 
20fe0 77 61 6c 52 65 77 72 69 74 65 43 68 65 63 6b 73  walRewriteChecks
20ff0 75 6d 73 28 70 57 61 6c 2c 20 69 46 72 61 6d 65  ums(pWal, iFrame
21000 29 3b 0a 20 20 20 20 69 66 28 20 72 63 20 29 20  );.    if( rc ) 
21010 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a  return rc;.  }..
21020 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20    /* If this is 
21030 74 68 65 20 65 6e 64 20 6f 66 20 61 20 74 72 61  the end of a tra
21040 6e 73 61 63 74 69 6f 6e 2c 20 74 68 65 6e 20 77  nsaction, then w
21050 65 20 6d 69 67 68 74 20 6e 65 65 64 20 74 6f 20  e might need to 
21060 70 61 64 0a 20 20 2a 2a 20 74 68 65 20 74 72 61  pad.  ** the tra
21070 6e 73 61 63 74 69 6f 6e 20 61 6e 64 2f 6f 72 20  nsaction and/or 
21080 73 79 6e 63 20 74 68 65 20 57 41 4c 20 66 69 6c  sync the WAL fil
21090 65 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 50 61 64  e..  **.  ** Pad
210a0 64 69 6e 67 20 61 6e 64 20 73 79 6e 63 69 6e 67  ding and syncing
210b0 20 6f 6e 6c 79 20 6f 63 63 75 72 20 69 66 20 74   only occur if t
210c0 68 69 73 20 73 65 74 20 6f 66 20 66 72 61 6d 65  his set of frame
210d0 73 20 63 6f 6d 70 6c 65 74 65 20 61 0a 20 20 2a  s complete a.  *
210e0 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 61 6e  * transaction an
210f0 64 20 69 66 20 50 52 41 47 4d 41 20 73 79 6e 63  d if PRAGMA sync
21100 68 72 6f 6e 6f 75 73 3d 46 55 4c 4c 2e 20 20 49  hronous=FULL.  I
21110 66 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 3d 4e  f synchronous==N
21120 4f 52 4d 41 4c 0a 20 20 2a 2a 20 6f 72 20 73 79  ORMAL.  ** or sy
21130 6e 63 68 72 6f 6e 6f 75 73 3d 3d 4f 46 46 2c 20  nchronous==OFF, 
21140 74 68 65 6e 20 6e 6f 20 70 61 64 64 69 6e 67 20  then no padding 
21150 6f 72 20 73 79 6e 63 69 6e 67 20 61 72 65 20 6e  or syncing are n
21160 65 65 64 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  eeded..  **.  **
21170 20 49 66 20 53 51 4c 49 54 45 5f 49 4f 43 41 50   If SQLITE_IOCAP
21180 5f 50 4f 57 45 52 53 41 46 45 5f 4f 56 45 52 57  _POWERSAFE_OVERW
21190 52 49 54 45 20 69 73 20 64 65 66 69 6e 65 64 2c  RITE is defined,
211a0 20 74 68 65 6e 20 70 61 64 64 69 6e 67 20 69 73   then padding is
211b0 20 6e 6f 74 0a 20 20 2a 2a 20 6e 65 65 64 65 64   not.  ** needed
211c0 20 61 6e 64 20 6f 6e 6c 79 20 74 68 65 20 73 79   and only the sy
211d0 6e 63 20 69 73 20 64 6f 6e 65 2e 20 20 49 66 20  nc is done.  If 
211e0 70 61 64 64 69 6e 67 20 69 73 20 6e 65 65 64 65  padding is neede
211f0 64 2c 20 74 68 65 6e 20 74 68 65 0a 20 20 2a 2a  d, then the.  **
21200 20 66 69 6e 61 6c 20 66 72 61 6d 65 20 69 73 20   final frame is 
21210 72 65 70 65 61 74 65 64 20 28 77 69 74 68 20 69  repeated (with i
21220 74 73 20 63 6f 6d 6d 69 74 20 6d 61 72 6b 29 20  ts commit mark) 
21230 75 6e 74 69 6c 20 74 68 65 20 6e 65 78 74 20 73  until the next s
21240 65 63 74 6f 72 0a 20 20 2a 2a 20 62 6f 75 6e 64  ector.  ** bound
21250 61 72 79 20 69 73 20 63 72 6f 73 73 65 64 2e 20  ary is crossed. 
21260 20 4f 6e 6c 79 20 74 68 65 20 70 61 72 74 20 6f   Only the part o
21270 66 20 74 68 65 20 57 41 4c 20 70 72 69 6f 72 20  f the WAL prior 
21280 74 6f 20 74 68 65 20 6c 61 73 74 0a 20 20 2a 2a  to the last.  **
21290 20 73 65 63 74 6f 72 20 62 6f 75 6e 64 61 72 79   sector boundary
212a0 20 69 73 20 73 79 6e 63 65 64 3b 20 74 68 65 20   is synced; the 
212b0 70 61 72 74 20 6f 66 20 74 68 65 20 6c 61 73 74  part of the last
212c0 20 66 72 61 6d 65 20 74 68 61 74 20 65 78 74 65   frame that exte
212d0 6e 64 73 0a 20 20 2a 2a 20 70 61 73 74 20 74 68  nds.  ** past th
212e0 65 20 73 65 63 74 6f 72 20 62 6f 75 6e 64 61 72  e sector boundar
212f0 79 20 69 73 20 77 72 69 74 74 65 6e 20 61 66 74  y is written aft
21300 65 72 20 74 68 65 20 73 79 6e 63 2e 0a 20 20 2a  er the sync..  *
21310 2f 0a 20 20 69 66 28 20 69 73 43 6f 6d 6d 69 74  /.  if( isCommit
21320 20 26 26 20 57 41 4c 5f 53 59 4e 43 5f 46 4c 41   && WAL_SYNC_FLA
21330 47 53 28 73 79 6e 63 5f 66 6c 61 67 73 29 21 3d  GS(sync_flags)!=
21340 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 62 53 79  0 ){.    int bSy
21350 6e 63 20 3d 20 31 3b 0a 20 20 20 20 69 66 28 20  nc = 1;.    if( 
21360 70 57 61 6c 2d 3e 70 61 64 54 6f 53 65 63 74 6f  pWal->padToSecto
21370 72 42 6f 75 6e 64 61 72 79 20 29 7b 0a 20 20 20  rBoundary ){.   
21380 20 20 20 69 6e 74 20 73 65 63 74 6f 72 53 69 7a     int sectorSiz
21390 65 20 3d 20 73 71 6c 69 74 65 33 53 65 63 74 6f  e = sqlite3Secto
213a0 72 53 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c  rSize(pWal->pWal
213b0 46 64 29 3b 0a 20 20 20 20 20 20 77 2e 69 53 79  Fd);.      w.iSy
213c0 6e 63 50 6f 69 6e 74 20 3d 20 28 28 69 4f 66 66  ncPoint = ((iOff
213d0 73 65 74 2b 73 65 63 74 6f 72 53 69 7a 65 2d 31  set+sectorSize-1
213e0 29 2f 73 65 63 74 6f 72 53 69 7a 65 29 2a 73 65  )/sectorSize)*se
213f0 63 74 6f 72 53 69 7a 65 3b 0a 20 20 20 20 20 20  ctorSize;.      
21400 62 53 79 6e 63 20 3d 20 28 77 2e 69 53 79 6e 63  bSync = (w.iSync
21410 50 6f 69 6e 74 3d 3d 69 4f 66 66 73 65 74 29 3b  Point==iOffset);
21420 0a 20 20 20 20 20 20 74 65 73 74 63 61 73 65 28  .      testcase(
21430 20 62 53 79 6e 63 20 29 3b 0a 20 20 20 20 20 20   bSync );.      
21440 77 68 69 6c 65 28 20 69 4f 66 66 73 65 74 3c 77  while( iOffset<w
21450 2e 69 53 79 6e 63 50 6f 69 6e 74 20 29 7b 0a 20  .iSyncPoint ){. 
21460 20 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 57         rc = walW
21470 72 69 74 65 4f 6e 65 46 72 61 6d 65 28 26 77 2c  riteOneFrame(&w,
21480 20 70 4c 61 73 74 2c 20 6e 54 72 75 6e 63 61 74   pLast, nTruncat
21490 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20  e, iOffset);.   
214a0 20 20 20 20 20 69 66 28 20 72 63 20 29 20 72 65       if( rc ) re
214b0 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 20  turn rc;.       
214c0 20 69 4f 66 66 73 65 74 20 2b 3d 20 73 7a 46 72   iOffset += szFr
214d0 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 6e 45 78  ame;.        nEx
214e0 74 72 61 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20  tra++;.      }. 
214f0 20 20 20 7d 0a 20 20 20 20 69 66 28 20 62 53 79     }.    if( bSy
21500 6e 63 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65  nc ){.      asse
21510 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  rt( rc==SQLITE_O
21520 4b 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  K );.      rc = 
21530 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 77 2e  sqlite3OsSync(w.
21540 70 46 64 2c 20 57 41 4c 5f 53 59 4e 43 5f 46 4c  pFd, WAL_SYNC_FL
21550 41 47 53 28 73 79 6e 63 5f 66 6c 61 67 73 29 29  AGS(sync_flags))
21560 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
21570 2a 20 49 66 20 74 68 69 73 20 66 72 61 6d 65 20  * If this frame 
21580 73 65 74 20 63 6f 6d 70 6c 65 74 65 73 20 74 68  set completes th
21590 65 20 66 69 72 73 74 20 74 72 61 6e 73 61 63 74  e first transact
215a0 69 6f 6e 20 69 6e 20 74 68 65 20 57 41 4c 20 61  ion in the WAL a
215b0 6e 64 0a 20 20 2a 2a 20 69 66 20 50 52 41 47 4d  nd.  ** if PRAGM
215c0 41 20 6a 6f 75 72 6e 61 6c 5f 73 69 7a 65 5f 6c  A journal_size_l
215d0 69 6d 69 74 20 69 73 20 73 65 74 2c 20 74 68 65  imit is set, the
215e0 6e 20 74 72 75 6e 63 61 74 65 20 74 68 65 20 57  n truncate the W
215f0 41 4c 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20 6a  AL to the.  ** j
21600 6f 75 72 6e 61 6c 20 73 69 7a 65 20 6c 69 6d 69  ournal size limi
21610 74 2c 20 69 66 20 70 6f 73 73 69 62 6c 65 2e 0a  t, if possible..
21620 20 20 2a 2f 0a 20 20 69 66 28 20 69 73 43 6f 6d    */.  if( isCom
21630 6d 69 74 20 26 26 20 70 57 61 6c 2d 3e 74 72 75  mit && pWal->tru
21640 6e 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 20 26 26  ncateOnCommit &&
21650 20 70 57 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65   pWal->mxWalSize
21660 3e 3d 30 20 29 7b 0a 20 20 20 20 69 36 34 20 73  >=0 ){.    i64 s
21670 7a 20 3d 20 70 57 61 6c 2d 3e 6d 78 57 61 6c 53  z = pWal->mxWalS
21680 69 7a 65 3b 0a 20 20 20 20 69 66 28 20 77 61 6c  ize;.    if( wal
21690 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46 72 61  FrameOffset(iFra
216a0 6d 65 2b 6e 45 78 74 72 61 2b 31 2c 20 73 7a 50  me+nExtra+1, szP
216b0 61 67 65 29 3e 70 57 61 6c 2d 3e 6d 78 57 61 6c  age)>pWal->mxWal
216c0 53 69 7a 65 20 29 7b 0a 20 20 20 20 20 20 73 7a  Size ){.      sz
216d0 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65   = walFrameOffse
216e0 74 28 69 46 72 61 6d 65 2b 6e 45 78 74 72 61 2b  t(iFrame+nExtra+
216f0 31 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20 20 20  1, szPage);.    
21700 7d 0a 20 20 20 20 77 61 6c 4c 69 6d 69 74 53 69  }.    walLimitSi
21710 7a 65 28 70 57 61 6c 2c 20 73 7a 29 3b 0a 20 20  ze(pWal, sz);.  
21720 20 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61 74 65    pWal->truncate
21730 4f 6e 43 6f 6d 6d 69 74 20 3d 20 30 3b 0a 20 20  OnCommit = 0;.  
21740 7d 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 64  }..  /* Append d
21750 61 74 61 20 74 6f 20 74 68 65 20 77 61 6c 2d 69  ata to the wal-i
21760 6e 64 65 78 2e 20 49 74 20 69 73 20 6e 6f 74 20  ndex. It is not 
21770 6e 65 63 65 73 73 61 72 79 20 74 6f 20 6c 6f 63  necessary to loc
21780 6b 20 74 68 65 20 0a 20 20 2a 2a 20 77 61 6c 2d  k the .  ** wal-
21790 69 6e 64 65 78 20 74 6f 20 64 6f 20 74 68 69 73  index to do this
217a0 20 61 73 20 74 68 65 20 53 51 4c 49 54 45 5f 53   as the SQLITE_S
217b0 48 4d 5f 57 52 49 54 45 20 6c 6f 63 6b 20 68 65  HM_WRITE lock he
217c0 6c 64 20 6f 6e 20 74 68 65 20 77 61 6c 2d 69 6e  ld on the wal-in
217d0 64 65 78 0a 20 20 2a 2a 20 67 75 61 72 61 6e 74  dex.  ** guarant
217e0 65 65 73 20 74 68 61 74 20 74 68 65 72 65 20 61  ees that there a
217f0 72 65 20 6e 6f 20 6f 74 68 65 72 20 77 72 69 74  re no other writ
21800 65 72 73 2c 20 61 6e 64 20 6e 6f 20 64 61 74 61  ers, and no data
21810 20 74 68 61 74 20 6d 61 79 0a 20 20 2a 2a 20 62   that may.  ** b
21820 65 20 69 6e 20 75 73 65 20 62 79 20 65 78 69 73  e in use by exis
21830 74 69 6e 67 20 72 65 61 64 65 72 73 20 69 73 20  ting readers is 
21840 62 65 69 6e 67 20 6f 76 65 72 77 72 69 74 74 65  being overwritte
21850 6e 2e 0a 20 20 2a 2f 0a 20 20 69 46 72 61 6d 65  n..  */.  iFrame
21860 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46   = pWal->hdr.mxF
21870 72 61 6d 65 3b 0a 20 20 66 6f 72 28 70 3d 70 4c  rame;.  for(p=pL
21880 69 73 74 3b 20 70 20 26 26 20 72 63 3d 3d 53 51  ist; p && rc==SQ
21890 4c 49 54 45 5f 4f 4b 3b 20 70 3d 70 2d 3e 70 44  LITE_OK; p=p->pD
218a0 69 72 74 79 29 7b 0a 20 20 20 20 69 66 28 20 28  irty){.    if( (
218b0 70 2d 3e 66 6c 61 67 73 20 26 20 50 47 48 44 52  p->flags & PGHDR
218c0 5f 57 41 4c 5f 41 50 50 45 4e 44 29 3d 3d 30 20  _WAL_APPEND)==0 
218d0 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20  ) continue;.    
218e0 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 72 63  iFrame++;.    rc
218f0 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e   = walIndexAppen
21900 64 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c 20  d(pWal, iFrame, 
21910 70 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 20 20  p->pgno);.  }.  
21920 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54  while( rc==SQLIT
21930 45 5f 4f 4b 20 26 26 20 6e 45 78 74 72 61 3e 30  E_OK && nExtra>0
21940 20 29 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b 2b   ){.    iFrame++
21950 3b 0a 20 20 20 20 6e 45 78 74 72 61 2d 2d 3b 0a  ;.    nExtra--;.
21960 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65      rc = walInde
21970 78 41 70 70 65 6e 64 28 70 57 61 6c 2c 20 69 46  xAppend(pWal, iF
21980 72 61 6d 65 2c 20 70 4c 61 73 74 2d 3e 70 67 6e  rame, pLast->pgn
21990 6f 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  o);.  }..  if( r
219a0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
219b0 20 20 20 20 2f 2a 20 55 70 64 61 74 65 20 74 68      /* Update th
219c0 65 20 70 72 69 76 61 74 65 20 63 6f 70 79 20 6f  e private copy o
219d0 66 20 74 68 65 20 68 65 61 64 65 72 2e 20 2a 2f  f the header. */
219e0 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 73  .    pWal->hdr.s
219f0 7a 50 61 67 65 20 3d 20 28 75 31 36 29 28 28 73  zPage = (u16)((s
21a00 7a 50 61 67 65 26 30 78 66 66 30 30 29 20 7c 20  zPage&0xff00) | 
21a10 28 73 7a 50 61 67 65 3e 3e 31 36 29 29 3b 0a 20  (szPage>>16));. 
21a20 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50     testcase( szP
21a30 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20  age<=32768 );.  
21a40 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50 61    testcase( szPa
21a50 67 65 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 20  ge>=65536 );.   
21a60 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
21a70 6d 65 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20  me = iFrame;.   
21a80 20 69 66 28 20 69 73 43 6f 6d 6d 69 74 20 29 7b   if( isCommit ){
21a90 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  .      pWal->hdr
21aa0 2e 69 43 68 61 6e 67 65 2b 2b 3b 0a 20 20 20 20  .iChange++;.    
21ab0 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67    pWal->hdr.nPag
21ac0 65 20 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a 20  e = nTruncate;. 
21ad0 20 20 20 7d 0a 20 20 20 20 2f 2a 20 49 66 20 74     }.    /* If t
21ae0 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 2c  his is a commit,
21af0 20 75 70 64 61 74 65 20 74 68 65 20 77 61 6c 2d   update the wal-
21b00 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f 6f  index header too
21b10 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 69 73 43  . */.    if( isC
21b20 6f 6d 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 77  ommit ){.      w
21b30 61 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72 28  alIndexWriteHdr(
21b40 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 70 57 61  pWal);.      pWa
21b50 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20 69  l->iCallback = i
21b60 46 72 61 6d 65 3b 0a 20 20 20 20 7d 0a 20 20 7d  Frame;.    }.  }
21b70 0a 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ..  WALTRACE(("W
21b80 41 4c 25 70 3a 20 66 72 61 6d 65 20 77 72 69 74  AL%p: frame writ
21b90 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  e %s\n", pWal, r
21ba0 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
21bb0 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75 72 6e 20  ok"));.  return 
21bc0 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68  rc;.}../* .** Th
21bd0 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61  is routine is ca
21be0 6c 6c 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e  lled to implemen
21bf0 74 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68  t sqlite3_wal_ch
21c00 65 63 6b 70 6f 69 6e 74 28 29 20 61 6e 64 0a 2a  eckpoint() and.*
21c10 2a 20 72 65 6c 61 74 65 64 20 69 6e 74 65 72 66  * related interf
21c20 61 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74 61  aces..**.** Obta
21c30 69 6e 20 61 20 43 48 45 43 4b 50 4f 49 4e 54 20  in a CHECKPOINT 
21c40 6c 6f 63 6b 20 61 6e 64 20 74 68 65 6e 20 62 61  lock and then ba
21c50 63 6b 66 69 6c 6c 20 61 73 20 6d 75 63 68 20 69  ckfill as much i
21c60 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 73 0a 2a 2a  nformation as.**
21c70 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 57 41 4c   we can from WAL
21c80 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
21c90 73 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70 61 72  se..**.** If par
21ca0 61 6d 65 74 65 72 20 78 42 75 73 79 20 69 73 20  ameter xBusy is 
21cb0 6e 6f 74 20 4e 55 4c 4c 2c 20 69 74 20 69 73 20  not NULL, it is 
21cc0 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 62  a pointer to a b
21cd0 75 73 79 2d 68 61 6e 64 6c 65 72 0a 2a 2a 20 63  usy-handler.** c
21ce0 61 6c 6c 62 61 63 6b 2e 20 49 6e 20 74 68 69 73  allback. In this
21cf0 20 63 61 73 65 20 74 68 69 73 20 66 75 6e 63 74   case this funct
21d00 69 6f 6e 20 72 75 6e 73 20 61 20 62 6c 6f 63 6b  ion runs a block
21d10 69 6e 67 20 63 68 65 63 6b 70 6f 69 6e 74 2e 0a  ing checkpoint..
21d20 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
21d30 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a 20 20 57  lCheckpoint(.  W
21d40 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20  al *pWal,       
21d50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
21d60 2a 20 57 61 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e  * Wal connection
21d70 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64   */.  sqlite3 *d
21d80 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
21d90 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 20 74        /* Check t
21da0 68 69 73 20 68 61 6e 64 6c 65 27 73 20 69 6e 74  his handle's int
21db0 65 72 72 75 70 74 20 66 6c 61 67 20 2a 2f 0a 20  errupt flag */. 
21dc0 20 69 6e 74 20 65 4d 6f 64 65 2c 20 20 20 20 20   int eMode,     
21dd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21de0 20 2f 2a 20 50 41 53 53 49 56 45 2c 20 46 55 4c   /* PASSIVE, FUL
21df0 4c 2c 20 52 45 53 54 41 52 54 2c 20 6f 72 20 54  L, RESTART, or T
21e00 52 55 4e 43 41 54 45 20 2a 2f 0a 20 20 69 6e 74  RUNCATE */.  int
21e10 20 28 2a 78 42 75 73 79 29 28 76 6f 69 64 2a 29   (*xBusy)(void*)
21e20 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
21e30 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63 61 6c 6c  Function to call
21e40 20 77 68 65 6e 20 62 75 73 79 20 2a 2f 0a 20 20   when busy */.  
21e50 76 6f 69 64 20 2a 70 42 75 73 79 41 72 67 2c 20  void *pBusyArg, 
21e60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21e70 2f 2a 20 43 6f 6e 74 65 78 74 20 61 72 67 75 6d  /* Context argum
21e80 65 6e 74 20 66 6f 72 20 78 42 75 73 79 48 61 6e  ent for xBusyHan
21e90 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74 20 73 79  dler */.  int sy
21ea0 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20 20  nc_flags,       
21eb0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61            /* Fla
21ec0 67 73 20 74 6f 20 73 79 6e 63 20 64 62 20 66 69  gs to sync db fi
21ed0 6c 65 20 77 69 74 68 20 28 6f 72 20 30 29 20 2a  le with (or 0) *
21ee0 2f 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20  /.  int nBuf,   
21ef0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21f00 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74      /* Size of t
21f10 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72 20  emporary buffer 
21f20 2a 2f 0a 20 20 75 38 20 2a 7a 42 75 66 2c 20 20  */.  u8 *zBuf,  
21f30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21f40 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72       /* Temporar
21f50 79 20 62 75 66 66 65 72 20 74 6f 20 75 73 65 20  y buffer to use 
21f60 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4c 6f 67 2c  */.  int *pnLog,
21f70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21f80 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d       /* OUT: Num
21f90 62 65 72 20 6f 66 20 66 72 61 6d 65 73 20 69 6e  ber of frames in
21fa0 20 57 41 4c 20 2a 2f 0a 20 20 69 6e 74 20 2a 70   WAL */.  int *p
21fb0 6e 43 6b 70 74 20 20 20 20 20 20 20 20 20 20 20  nCkpt           
21fc0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
21fd0 3a 20 4e 75 6d 62 65 72 20 6f 66 20 62 61 63 6b  : Number of back
21fe0 66 69 6c 6c 65 64 20 66 72 61 6d 65 73 20 69 6e  filled frames in
21ff0 20 57 41 4c 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74   WAL */.){.  int
22000 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
22010 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
22020 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
22030 20 69 6e 74 20 69 73 43 68 61 6e 67 65 64 20 3d   int isChanged =
22040 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
22050 20 2f 2a 20 54 72 75 65 20 69 66 20 61 20 6e 65   /* True if a ne
22060 77 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  w wal-index head
22070 65 72 20 69 73 20 6c 6f 61 64 65 64 20 2a 2f 0a  er is loaded */.
22080 20 20 69 6e 74 20 65 4d 6f 64 65 32 20 3d 20 65    int eMode2 = e
22090 4d 6f 64 65 3b 20 20 20 20 20 20 20 20 20 20 20  Mode;           
220a0 20 20 2f 2a 20 4d 6f 64 65 20 74 6f 20 70 61 73    /* Mode to pas
220b0 73 20 74 6f 20 77 61 6c 43 68 65 63 6b 70 6f 69  s to walCheckpoi
220c0 6e 74 28 29 20 2a 2f 0a 20 20 69 6e 74 20 28 2a  nt() */.  int (*
220d0 78 42 75 73 79 32 29 28 76 6f 69 64 2a 29 20 3d  xBusy2)(void*) =
220e0 20 78 42 75 73 79 3b 20 20 20 2f 2a 20 42 75 73   xBusy;   /* Bus
220f0 79 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 65 4d  y handler for eM
22100 6f 64 65 32 20 2a 2f 0a 0a 20 20 61 73 73 65 72  ode2 */..  asser
22110 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63  t( pWal->ckptLoc
22120 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  k==0 );.  assert
22130 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
22140 6b 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 45 56  k==0 );..  /* EV
22150 49 44 45 4e 43 45 2d 4f 46 3a 20 52 2d 36 32 39  IDENCE-OF: R-629
22160 32 30 2d 34 37 34 35 30 20 54 68 65 20 62 75 73  20-47450 The bus
22170 79 2d 68 61 6e 64 6c 65 72 20 63 61 6c 6c 62 61  y-handler callba
22180 63 6b 20 69 73 20 6e 65 76 65 72 20 69 6e 76 6f  ck is never invo
22190 6b 65 64 0a 20 20 2a 2a 20 69 6e 20 74 68 65 20  ked.  ** in the 
221a0 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e  SQLITE_CHECKPOIN
221b0 54 5f 50 41 53 53 49 56 45 20 6d 6f 64 65 2e 20  T_PASSIVE mode. 
221c0 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 65 4d 6f  */.  assert( eMo
221d0 64 65 21 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b  de!=SQLITE_CHECK
221e0 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 7c 7c  POINT_PASSIVE ||
221f0 20 78 42 75 73 79 3d 3d 30 20 29 3b 0a 0a 20 20   xBusy==0 );..  
22200 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4f 6e  if( pWal->readOn
22210 6c 79 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  ly ) return SQLI
22220 54 45 5f 52 45 41 44 4f 4e 4c 59 3b 0a 20 20 57  TE_READONLY;.  W
22230 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
22240 20 63 68 65 63 6b 70 6f 69 6e 74 20 62 65 67 69   checkpoint begi
22250 6e 73 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 0a  ns\n", pWal));..
22260 20 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54 41 54    /* IMPLEMENTAT
22270 49 4f 4e 2d 4f 46 3a 20 52 2d 36 32 30 32 38 2d  ION-OF: R-62028-
22280 34 37 32 31 32 20 41 6c 6c 20 63 61 6c 6c 73 20  47212 All calls 
22290 6f 62 74 61 69 6e 20 61 6e 20 65 78 63 6c 75 73  obtain an exclus
222a0 69 76 65 20 0a 20 20 2a 2a 20 22 63 68 65 63 6b  ive .  ** "check
222b0 70 6f 69 6e 74 22 20 6c 6f 63 6b 20 6f 6e 20 74  point" lock on t
222c0 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
222d0 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 77 61 6c 4c  . */.  rc = walL
222e0 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
222f0 6c 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b  l, WAL_CKPT_LOCK
22300 2c 20 31 29 3b 0a 20 20 69 66 28 20 72 63 20 29  , 1);.  if( rc )
22310 7b 0a 20 20 20 20 2f 2a 20 45 56 49 44 45 4e 43  {.    /* EVIDENC
22320 45 2d 4f 46 3a 20 52 2d 31 30 34 32 31 2d 31 39  E-OF: R-10421-19
22330 37 33 36 20 49 66 20 61 6e 79 20 6f 74 68 65 72  736 If any other
22340 20 70 72 6f 63 65 73 73 20 69 73 20 72 75 6e 6e   process is runn
22350 69 6e 67 20 61 0a 20 20 20 20 2a 2a 20 63 68 65  ing a.    ** che
22360 63 6b 70 6f 69 6e 74 20 6f 70 65 72 61 74 69 6f  ckpoint operatio
22370 6e 20 61 74 20 74 68 65 20 73 61 6d 65 20 74 69  n at the same ti
22380 6d 65 2c 20 74 68 65 20 6c 6f 63 6b 20 63 61 6e  me, the lock can
22390 6e 6f 74 20 62 65 20 6f 62 74 61 69 6e 65 64 20  not be obtained 
223a0 61 6e 64 0a 20 20 20 20 2a 2a 20 53 51 4c 49 54  and.    ** SQLIT
223b0 45 5f 42 55 53 59 20 69 73 20 72 65 74 75 72 6e  E_BUSY is return
223c0 65 64 2e 0a 20 20 20 20 2a 2a 20 45 56 49 44 45  ed..    ** EVIDE
223d0 4e 43 45 2d 4f 46 3a 20 52 2d 35 33 38 32 30 2d  NCE-OF: R-53820-
223e0 33 33 38 39 37 20 45 76 65 6e 20 69 66 20 74 68  33897 Even if th
223f0 65 72 65 20 69 73 20 61 20 62 75 73 79 2d 68 61  ere is a busy-ha
22400 6e 64 6c 65 72 20 63 6f 6e 66 69 67 75 72 65 64  ndler configured
22410 2c 0a 20 20 20 20 2a 2a 20 69 74 20 77 69 6c 6c  ,.    ** it will
22420 20 6e 6f 74 20 62 65 20 69 6e 76 6f 6b 65 64 20   not be invoked 
22430 69 6e 20 74 68 69 73 20 63 61 73 65 2e 0a 20 20  in this case..  
22440 20 20 2a 2f 0a 20 20 20 20 74 65 73 74 63 61 73    */.    testcas
22450 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  e( rc==SQLITE_BU
22460 53 59 20 29 3b 0a 20 20 20 20 74 65 73 74 63 61  SY );.    testca
22470 73 65 28 20 78 42 75 73 79 21 3d 30 20 29 3b 0a  se( xBusy!=0 );.
22480 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
22490 20 7d 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74 4c   }.  pWal->ckptL
224a0 6f 63 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 49  ock = 1;..  /* I
224b0 4d 50 4c 45 4d 45 4e 54 41 54 49 4f 4e 2d 4f 46  MPLEMENTATION-OF
224c0 3a 20 52 2d 35 39 37 38 32 2d 33 36 38 31 38 20  : R-59782-36818 
224d0 54 68 65 20 53 51 4c 49 54 45 5f 43 48 45 43 4b  The SQLITE_CHECK
224e0 50 4f 49 4e 54 5f 46 55 4c 4c 2c 20 52 45 53 54  POINT_FULL, REST
224f0 41 52 54 20 61 6e 64 0a 20 20 2a 2a 20 54 52 55  ART and.  ** TRU
22500 4e 43 41 54 45 20 6d 6f 64 65 73 20 61 6c 73 6f  NCATE modes also
22510 20 6f 62 74 61 69 6e 20 74 68 65 20 65 78 63 6c   obtain the excl
22520 75 73 69 76 65 20 22 77 72 69 74 65 72 22 20 6c  usive "writer" l
22530 6f 63 6b 20 6f 6e 20 74 68 65 20 64 61 74 61 62  ock on the datab
22540 61 73 65 0a 20 20 2a 2a 20 66 69 6c 65 2e 0a 20  ase.  ** file.. 
22550 20 2a 2a 0a 20 20 2a 2a 20 45 56 49 44 45 4e 43   **.  ** EVIDENC
22560 45 2d 4f 46 3a 20 52 2d 36 30 36 34 32 2d 30 34  E-OF: R-60642-04
22570 30 38 32 20 49 66 20 74 68 65 20 77 72 69 74 65  082 If the write
22580 72 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62 65  r lock cannot be
22590 20 6f 62 74 61 69 6e 65 64 0a 20 20 2a 2a 20 69   obtained.  ** i
225a0 6d 6d 65 64 69 61 74 65 6c 79 2c 20 61 6e 64 20  mmediately, and 
225b0 61 20 62 75 73 79 2d 68 61 6e 64 6c 65 72 20 69  a busy-handler i
225c0 73 20 63 6f 6e 66 69 67 75 72 65 64 2c 20 69 74  s configured, it
225d0 20 69 73 20 69 6e 76 6f 6b 65 64 20 61 6e 64 20   is invoked and 
225e0 74 68 65 0a 20 20 2a 2a 20 77 72 69 74 65 72 20  the.  ** writer 
225f0 6c 6f 63 6b 20 72 65 74 72 69 65 64 20 75 6e 74  lock retried unt
22600 69 6c 20 65 69 74 68 65 72 20 74 68 65 20 62 75  il either the bu
22610 73 79 2d 68 61 6e 64 6c 65 72 20 72 65 74 75 72  sy-handler retur
22620 6e 73 20 30 20 6f 72 20 74 68 65 0a 20 20 2a 2a  ns 0 or the.  **
22630 20 6c 6f 63 6b 20 69 73 20 73 75 63 63 65 73 73   lock is success
22640 66 75 6c 6c 79 20 6f 62 74 61 69 6e 65 64 2e 0a  fully obtained..
22650 20 20 2a 2f 0a 20 20 69 66 28 20 65 4d 6f 64 65    */.  if( eMode
22660 21 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f  !=SQLITE_CHECKPO
22670 49 4e 54 5f 50 41 53 53 49 56 45 20 29 7b 0a 20  INT_PASSIVE ){. 
22680 20 20 20 72 63 20 3d 20 77 61 6c 42 75 73 79 4c     rc = walBusyL
22690 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73 79 2c  ock(pWal, xBusy,
226a0 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c 5f 57   pBusyArg, WAL_W
226b0 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  RITE_LOCK, 1);. 
226c0 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
226d0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70 57  E_OK ){.      pW
226e0 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20  al->writeLock = 
226f0 31 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  1;.    }else if(
22700 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc==SQLITE_BUSY
22710 20 29 7b 0a 20 20 20 20 20 20 65 4d 6f 64 65 32   ){.      eMode2
22720 20 3d 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 50   = SQLITE_CHECKP
22730 4f 49 4e 54 5f 50 41 53 53 49 56 45 3b 0a 20 20  OINT_PASSIVE;.  
22740 20 20 20 20 78 42 75 73 79 32 20 3d 20 30 3b 0a      xBusy2 = 0;.
22750 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
22760 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  E_OK;.    }.  }.
22770 0a 20 20 2f 2a 20 52 65 61 64 20 74 68 65 20 77  .  /* Read the w
22780 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 2e  al-index header.
22790 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   */.  if( rc==SQ
227a0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
227b0 63 20 3d 20 77 61 6c 49 6e 64 65 78 52 65 61 64  c = walIndexRead
227c0 48 64 72 28 70 57 61 6c 2c 20 26 69 73 43 68 61  Hdr(pWal, &isCha
227d0 6e 67 65 64 29 3b 0a 20 20 20 20 69 66 28 20 69  nged);.    if( i
227e0 73 43 68 61 6e 67 65 64 20 26 26 20 70 57 61 6c  sChanged && pWal
227f0 2d 3e 70 44 62 46 64 2d 3e 70 4d 65 74 68 6f 64  ->pDbFd->pMethod
22800 73 2d 3e 69 56 65 72 73 69 6f 6e 3e 3d 33 20 29  s->iVersion>=3 )
22810 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f  {.      sqlite3O
22820 73 55 6e 66 65 74 63 68 28 70 57 61 6c 2d 3e 70  sUnfetch(pWal->p
22830 44 62 46 64 2c 20 30 2c 20 30 29 3b 0a 20 20 20  DbFd, 0, 0);.   
22840 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 70   }.  }..  /* Cop
22850 79 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20  y data from the 
22860 6c 6f 67 20 74 6f 20 74 68 65 20 64 61 74 61 62  log to the datab
22870 61 73 65 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 69  ase file. */.  i
22880 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
22890 20 29 7b 0a 0a 20 20 20 20 69 66 28 20 70 57 61   ){..    if( pWa
228a0 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 26  l->hdr.mxFrame &
228b0 26 20 77 61 6c 50 61 67 65 73 69 7a 65 28 70 57  & walPagesize(pW
228c0 61 6c 29 21 3d 6e 42 75 66 20 29 7b 0a 20 20 20  al)!=nBuf ){.   
228d0 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43     rc = SQLITE_C
228e0 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20  ORRUPT_BKPT;.   
228f0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
22900 20 3d 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74   = walCheckpoint
22910 28 70 57 61 6c 2c 20 64 62 2c 20 65 4d 6f 64 65  (pWal, db, eMode
22920 32 2c 20 78 42 75 73 79 32 2c 20 70 42 75 73 79  2, xBusy2, pBusy
22930 41 72 67 2c 20 73 79 6e 63 5f 66 6c 61 67 73 2c  Arg, sync_flags,
22940 20 7a 42 75 66 29 3b 0a 20 20 20 20 7d 0a 0a 20   zBuf);.    }.. 
22950 20 20 20 2f 2a 20 49 66 20 6e 6f 20 65 72 72 6f     /* If no erro
22960 72 20 6f 63 63 75 72 72 65 64 2c 20 73 65 74 20  r occurred, set 
22970 74 68 65 20 6f 75 74 70 75 74 20 76 61 72 69 61  the output varia
22980 62 6c 65 73 2e 20 2a 2f 0a 20 20 20 20 69 66 28  bles. */.    if(
22990 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc==SQLITE_OK |
229a0 7c 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  | rc==SQLITE_BUS
229b0 59 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  Y ){.      if( p
229c0 6e 4c 6f 67 20 29 20 2a 70 6e 4c 6f 67 20 3d 20  nLog ) *pnLog = 
229d0 28 69 6e 74 29 70 57 61 6c 2d 3e 68 64 72 2e 6d  (int)pWal->hdr.m
229e0 78 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 69 66  xFrame;.      if
229f0 28 20 70 6e 43 6b 70 74 20 29 20 2a 70 6e 43 6b  ( pnCkpt ) *pnCk
22a00 70 74 20 3d 20 28 69 6e 74 29 28 77 61 6c 43 6b  pt = (int)(walCk
22a10 70 74 49 6e 66 6f 28 70 57 61 6c 29 2d 3e 6e 42  ptInfo(pWal)->nB
22a20 61 63 6b 66 69 6c 6c 29 3b 0a 20 20 20 20 7d 0a  ackfill);.    }.
22a30 20 20 7d 0a 0a 20 20 69 66 28 20 69 73 43 68 61    }..  if( isCha
22a40 6e 67 65 64 20 29 7b 0a 20 20 20 20 2f 2a 20 49  nged ){.    /* I
22a50 66 20 61 20 6e 65 77 20 77 61 6c 2d 69 6e 64 65  f a new wal-inde
22a60 78 20 68 65 61 64 65 72 20 77 61 73 20 6c 6f 61  x header was loa
22a70 64 65 64 20 62 65 66 6f 72 65 20 74 68 65 20 63  ded before the c
22a80 68 65 63 6b 70 6f 69 6e 74 20 77 61 73 20 0a 20  heckpoint was . 
22a90 20 20 20 2a 2a 20 70 65 72 66 6f 72 6d 65 64 2c     ** performed,
22aa0 20 74 68 65 6e 20 74 68 65 20 70 61 67 65 72 2d   then the pager-
22ab0 63 61 63 68 65 20 61 73 73 6f 63 69 61 74 65 64  cache associated
22ac0 20 77 69 74 68 20 70 57 61 6c 20 69 73 20 6e 6f   with pWal is no
22ad0 77 0a 20 20 20 20 2a 2a 20 6f 75 74 20 6f 66 20  w.    ** out of 
22ae0 64 61 74 65 2e 20 53 6f 20 7a 65 72 6f 20 74 68  date. So zero th
22af0 65 20 63 61 63 68 65 64 20 77 61 6c 2d 69 6e 64  e cached wal-ind
22b00 65 78 20 68 65 61 64 65 72 20 74 6f 20 65 6e 73  ex header to ens
22b10 75 72 65 20 74 68 61 74 0a 20 20 20 20 2a 2a 20  ure that.    ** 
22b20 6e 65 78 74 20 74 69 6d 65 20 74 68 65 20 70 61  next time the pa
22b30 67 65 72 20 6f 70 65 6e 73 20 61 20 73 6e 61 70  ger opens a snap
22b40 73 68 6f 74 20 6f 6e 20 74 68 69 73 20 64 61 74  shot on this dat
22b50 61 62 61 73 65 20 69 74 20 6b 6e 6f 77 73 20 74  abase it knows t
22b60 68 61 74 0a 20 20 20 20 2a 2a 20 74 68 65 20 63  hat.    ** the c
22b70 61 63 68 65 20 6e 65 65 64 73 20 74 6f 20 62 65  ache needs to be
22b80 20 72 65 73 65 74 2e 0a 20 20 20 20 2a 2f 0a 20   reset..    */. 
22b90 20 20 20 6d 65 6d 73 65 74 28 26 70 57 61 6c 2d     memset(&pWal-
22ba0 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  >hdr, 0, sizeof(
22bb0 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 20  WalIndexHdr));. 
22bc0 20 7d 0a 0a 20 20 2f 2a 20 52 65 6c 65 61 73 65   }..  /* Release
22bd0 20 74 68 65 20 6c 6f 63 6b 73 2e 20 2a 2f 0a 20   the locks. */. 
22be0 20 73 71 6c 69 74 65 33 57 61 6c 45 6e 64 57 72   sqlite3WalEndWr
22bf0 69 74 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 70  iteTransaction(p
22c00 57 61 6c 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f 63  Wal);.  walUnloc
22c10 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
22c20 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20   WAL_CKPT_LOCK, 
22c30 31 29 3b 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74  1);.  pWal->ckpt
22c40 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 57 41 4c 54  Lock = 0;.  WALT
22c50 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63 68  RACE(("WAL%p: ch
22c60 65 63 6b 70 6f 69 6e 74 20 25 73 5c 6e 22 2c 20  eckpoint %s\n", 
22c70 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c  pWal, rc ? "fail
22c80 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20  ed" : "ok"));.  
22c90 72 65 74 75 72 6e 20 28 72 63 3d 3d 53 51 4c 49  return (rc==SQLI
22ca0 54 45 5f 4f 4b 20 26 26 20 65 4d 6f 64 65 21 3d  TE_OK && eMode!=
22cb0 65 4d 6f 64 65 32 20 3f 20 53 51 4c 49 54 45 5f  eMode2 ? SQLITE_
22cc0 42 55 53 59 20 3a 20 72 63 29 3b 0a 7d 0a 0a 2f  BUSY : rc);.}../
22cd0 2a 20 52 65 74 75 72 6e 20 74 68 65 20 76 61 6c  * Return the val
22ce0 75 65 20 74 6f 20 70 61 73 73 20 74 6f 20 61 20  ue to pass to a 
22cf0 73 71 6c 69 74 65 33 5f 77 61 6c 5f 68 6f 6f 6b  sqlite3_wal_hook
22d00 20 63 61 6c 6c 62 61 63 6b 2c 20 74 68 65 0a 2a   callback, the.*
22d10 2a 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d  * number of fram
22d20 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20 61 74  es in the WAL at
22d30 20 74 68 65 20 70 6f 69 6e 74 20 6f 66 20 74 68   the point of th
22d40 65 20 6c 61 73 74 20 63 6f 6d 6d 69 74 20 73 69  e last commit si
22d50 6e 63 65 0a 2a 2a 20 73 71 6c 69 74 65 33 57 61  nce.** sqlite3Wa
22d60 6c 43 61 6c 6c 62 61 63 6b 28 29 20 77 61 73 20  lCallback() was 
22d70 63 61 6c 6c 65 64 2e 20 20 49 66 20 6e 6f 20 63  called.  If no c
22d80 6f 6d 6d 69 74 73 20 68 61 76 65 20 6f 63 63 75  ommits have occu
22d90 72 72 65 64 20 73 69 6e 63 65 0a 2a 2a 20 74 68  rred since.** th
22da0 65 20 6c 61 73 74 20 63 61 6c 6c 2c 20 74 68 65  e last call, the
22db0 6e 20 72 65 74 75 72 6e 20 30 2e 0a 2a 2f 0a 69  n return 0..*/.i
22dc0 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 43 61 6c  nt sqlite3WalCal
22dd0 6c 62 61 63 6b 28 57 61 6c 20 2a 70 57 61 6c 29  lback(Wal *pWal)
22de0 7b 0a 20 20 75 33 32 20 72 65 74 20 3d 20 30 3b  {.  u32 ret = 0;
22df0 0a 20 20 69 66 28 20 70 57 61 6c 20 29 7b 0a 20  .  if( pWal ){. 
22e00 20 20 20 72 65 74 20 3d 20 70 57 61 6c 2d 3e 69     ret = pWal->i
22e10 43 61 6c 6c 62 61 63 6b 3b 0a 20 20 20 20 70 57  Callback;.    pW
22e20 61 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20  al->iCallback = 
22e30 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  0;.  }.  return 
22e40 28 69 6e 74 29 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a  (int)ret;.}../*.
22e50 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
22e60 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 63 68   is called to ch
22e70 61 6e 67 65 20 74 68 65 20 57 41 4c 20 73 75 62  ange the WAL sub
22e80 73 79 73 74 65 6d 20 69 6e 74 6f 20 6f 72 20 6f  system into or o
22e90 75 74 0a 2a 2a 20 6f 66 20 6c 6f 63 6b 69 6e 67  ut.** of locking
22ea0 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2e  _mode=EXCLUSIVE.
22eb0 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20  .**.** If op is 
22ec0 7a 65 72 6f 2c 20 74 68 65 6e 20 61 74 74 65 6d  zero, then attem
22ed0 70 74 20 74 6f 20 63 68 61 6e 67 65 20 66 72 6f  pt to change fro
22ee0 6d 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45  m locking_mode=E
22ef0 58 43 4c 55 53 49 56 45 0a 2a 2a 20 69 6e 74 6f  XCLUSIVE.** into
22f00 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f   locking_mode=NO
22f10 52 4d 41 4c 2e 20 20 54 68 69 73 20 6d 65 61 6e  RMAL.  This mean
22f20 73 20 74 68 61 74 20 77 65 20 6d 75 73 74 20 61  s that we must a
22f30 63 71 75 69 72 65 20 61 20 6c 6f 63 6b 0a 2a 2a  cquire a lock.**
22f40 20 6f 6e 20 74 68 65 20 70 57 61 6c 2d 3e 72 65   on the pWal->re
22f50 61 64 4c 6f 63 6b 20 62 79 74 65 2e 20 20 49 66  adLock byte.  If
22f60 20 74 68 65 20 57 41 4c 20 69 73 20 61 6c 72 65   the WAL is alre
22f70 61 64 79 20 69 6e 20 6c 6f 63 6b 69 6e 67 5f 6d  ady in locking_m
22f80 6f 64 65 3d 4e 4f 52 4d 41 4c 0a 2a 2a 20 6f 72  ode=NORMAL.** or
22f90 20 69 66 20 74 68 65 20 61 63 71 75 69 73 69 74   if the acquisit
22fa0 69 6f 6e 20 6f 66 20 74 68 65 20 6c 6f 63 6b 20  ion of the lock 
22fb0 66 61 69 6c 73 2c 20 74 68 65 6e 20 72 65 74 75  fails, then retu
22fc0 72 6e 20 30 2e 20 20 49 66 20 74 68 65 0a 2a 2a  rn 0.  If the.**
22fd0 20 74 72 61 6e 73 69 74 69 6f 6e 20 6f 75 74 20   transition out 
22fe0 6f 66 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f 64  of exclusive-mod
22ff0 65 20 69 73 20 73 75 63 63 65 73 73 66 75 6c 2c  e is successful,
23000 20 72 65 74 75 72 6e 20 31 2e 20 20 54 68 69 73   return 1.  This
23010 0a 2a 2a 20 6f 70 65 72 61 74 69 6f 6e 20 6d 75  .** operation mu
23020 73 74 20 6f 63 63 75 72 20 77 68 69 6c 65 20 74  st occur while t
23030 68 65 20 70 61 67 65 72 20 69 73 20 73 74 69 6c  he pager is stil
23040 6c 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 65 78  l holding the ex
23050 63 6c 75 73 69 76 65 0a 2a 2a 20 6c 6f 63 6b 20  clusive.** lock 
23060 6f 6e 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61  on the main data
23070 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a  base file..**.**
23080 20 49 66 20 6f 70 20 69 73 20 6f 6e 65 2c 20 74   If op is one, t
23090 68 65 6e 20 63 68 61 6e 67 65 20 66 72 6f 6d 20  hen change from 
230a0 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52  locking_mode=NOR
230b0 4d 41 4c 20 69 6e 74 6f 20 0a 2a 2a 20 6c 6f 63  MAL into .** loc
230c0 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53  king_mode=EXCLUS
230d0 49 56 45 2e 20 20 54 68 69 73 20 6d 65 61 6e 73  IVE.  This means
230e0 20 74 68 61 74 20 74 68 65 20 70 57 61 6c 2d 3e   that the pWal->
230f0 72 65 61 64 4c 6f 63 6b 20 6d 75 73 74 0a 2a 2a  readLock must.**
23100 20 62 65 20 72 65 6c 65 61 73 65 64 2e 20 20 52   be released.  R
23110 65 74 75 72 6e 20 31 20 69 66 20 74 68 65 20 74  eturn 1 if the t
23120 72 61 6e 73 69 74 69 6f 6e 20 69 73 20 6d 61 64  ransition is mad
23130 65 20 61 6e 64 20 30 20 69 66 20 74 68 65 0a 2a  e and 0 if the.*
23140 2a 20 57 41 4c 20 69 73 20 61 6c 72 65 61 64 79  * WAL is already
23150 20 69 6e 20 65 78 63 6c 75 73 69 76 65 2d 6c 6f   in exclusive-lo
23160 63 6b 69 6e 67 20 6d 6f 64 65 20 2d 20 6d 65 61  cking mode - mea
23170 6e 69 6e 67 20 74 68 61 74 20 74 68 69 73 0a 2a  ning that this.*
23180 2a 20 72 6f 75 74 69 6e 65 20 69 73 20 61 20 6e  * routine is a n
23190 6f 2d 6f 70 2e 20 20 54 68 65 20 70 61 67 65 72  o-op.  The pager
231a0 20 6d 75 73 74 20 61 6c 72 65 61 64 79 20 68 6f   must already ho
231b0 6c 64 20 74 68 65 20 65 78 63 6c 75 73 69 76 65  ld the exclusive
231c0 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20   lock.** on the 
231d0 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 66 69  main database fi
231e0 6c 65 20 62 65 66 6f 72 65 20 69 6e 76 6f 6b 69  le before invoki
231f0 6e 67 20 74 68 69 73 20 6f 70 65 72 61 74 69 6f  ng this operatio
23200 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20 69  n..**.** If op i
23210 73 20 6e 65 67 61 74 69 76 65 2c 20 74 68 65 6e  s negative, then
23220 20 64 6f 20 61 20 64 72 79 2d 72 75 6e 20 6f 66   do a dry-run of
23230 20 74 68 65 20 6f 70 3d 3d 31 20 63 61 73 65 20   the op==1 case 
23240 62 75 74 20 64 6f 0a 2a 2a 20 6e 6f 74 20 61 63  but do.** not ac
23250 74 75 61 6c 6c 79 20 63 68 61 6e 67 65 20 61 6e  tually change an
23260 79 74 68 69 6e 67 2e 20 54 68 65 20 70 61 67 65  ything. The page
23270 72 20 75 73 65 73 20 74 68 69 73 20 74 6f 20 73  r uses this to s
23280 65 65 20 69 66 20 69 74 0a 2a 2a 20 73 68 6f 75  ee if it.** shou
23290 6c 64 20 61 63 71 75 69 72 65 20 74 68 65 20 64  ld acquire the d
232a0 61 74 61 62 61 73 65 20 65 78 63 6c 75 73 69 76  atabase exclusiv
232b0 65 20 6c 6f 63 6b 20 70 72 69 6f 72 20 74 6f 20  e lock prior to 
232c0 69 6e 76 6f 6b 69 6e 67 0a 2a 2a 20 74 68 65 20  invoking.** the 
232d0 6f 70 3d 3d 31 20 63 61 73 65 2e 0a 2a 2f 0a 69  op==1 case..*/.i
232e0 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 45 78 63  nt sqlite3WalExc
232f0 6c 75 73 69 76 65 4d 6f 64 65 28 57 61 6c 20 2a  lusiveMode(Wal *
23300 70 57 61 6c 2c 20 69 6e 74 20 6f 70 29 7b 0a 20  pWal, int op){. 
23310 20 69 6e 74 20 72 63 3b 0a 20 20 61 73 73 65 72   int rc;.  asser
23320 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  t( pWal->writeLo
23330 63 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  ck==0 );.  asser
23340 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69  t( pWal->exclusi
23350 76 65 4d 6f 64 65 21 3d 57 41 4c 5f 48 45 41 50  veMode!=WAL_HEAP
23360 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 7c 7c 20 6f  MEMORY_MODE || o
23370 70 3d 3d 2d 31 20 29 3b 0a 0a 20 20 2f 2a 20 70  p==-1 );..  /* p
23380 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69 73  Wal->readLock is
23390 20 75 73 75 61 6c 6c 79 20 73 65 74 2c 20 62 75   usually set, bu
233a0 74 20 6d 69 67 68 74 20 62 65 20 2d 31 20 69 66  t might be -1 if
233b0 20 74 68 65 72 65 20 77 61 73 20 61 20 0a 20 20   there was a .  
233c0 2a 2a 20 70 72 69 6f 72 20 65 72 72 6f 72 20 77  ** prior error w
233d0 68 69 6c 65 20 61 74 74 65 6d 70 74 69 6e 67 20  hile attempting 
233e0 74 6f 20 61 63 71 75 69 72 65 20 61 72 65 20 72  to acquire are r
233f0 65 61 64 2d 6c 6f 63 6b 2e 20 54 68 69 73 20 63  ead-lock. This c
23400 61 6e 6e 6f 74 20 0a 20 20 2a 2a 20 68 61 70 70  annot .  ** happ
23410 65 6e 20 69 66 20 74 68 65 20 63 6f 6e 6e 65 63  en if the connec
23420 74 69 6f 6e 20 69 73 20 61 63 74 75 61 6c 6c 79  tion is actually
23430 20 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f   in exclusive mo
23440 64 65 20 28 61 73 20 6e 6f 20 78 53 68 6d 4c 6f  de (as no xShmLo
23450 63 6b 0a 20 20 2a 2a 20 6c 6f 63 6b 73 20 61 72  ck.  ** locks ar
23460 65 20 74 61 6b 65 6e 20 69 6e 20 74 68 69 73 20  e taken in this 
23470 63 61 73 65 29 2e 20 4e 6f 72 20 73 68 6f 75 6c  case). Nor shoul
23480 64 20 74 68 65 20 70 61 67 65 72 20 61 74 74 65  d the pager atte
23490 6d 70 74 20 74 6f 0a 20 20 2a 2a 20 75 70 67 72  mpt to.  ** upgr
234a0 61 64 65 20 74 6f 20 65 78 63 6c 75 73 69 76 65  ade to exclusive
234b0 2d 6d 6f 64 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  -mode following 
234c0 73 75 63 68 20 61 6e 20 65 72 72 6f 72 2e 0a 20  such an error.. 
234d0 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57   */.  assert( pW
234e0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20  al->readLock>=0 
234f0 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72  || pWal->lockErr
23500 6f 72 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  or );.  assert( 
23510 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
23520 30 20 7c 7c 20 28 6f 70 3c 3d 30 20 26 26 20 70  0 || (op<=0 && p
23530 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
23540 64 65 3d 3d 30 29 20 29 3b 0a 0a 20 20 69 66 28  de==0) );..  if(
23550 20 6f 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66   op==0 ){.    if
23560 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76  ( pWal->exclusiv
23570 65 4d 6f 64 65 21 3d 57 41 4c 5f 4e 4f 52 4d 41  eMode!=WAL_NORMA
23580 4c 5f 4d 4f 44 45 20 29 7b 0a 20 20 20 20 20 20  L_MODE ){.      
23590 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
235a0 6f 64 65 20 3d 20 57 41 4c 5f 4e 4f 52 4d 41 4c  ode = WAL_NORMAL
235b0 5f 4d 4f 44 45 3b 0a 20 20 20 20 20 20 69 66 28  _MODE;.      if(
235c0 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70   walLockShared(p
235d0 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
235e0 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  CK(pWal->readLoc
235f0 6b 29 29 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29  k))!=SQLITE_OK )
23600 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e  {.        pWal->
23610 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20  exclusiveMode = 
23620 57 41 4c 5f 45 58 43 4c 55 53 49 56 45 5f 4d 4f  WAL_EXCLUSIVE_MO
23630 44 45 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  DE;.      }.    
23640 20 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63    rc = pWal->exc
23650 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f  lusiveMode==WAL_
23660 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 3b 0a 20 20 20  NORMAL_MODE;.   
23670 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a   }else{.      /*
23680 20 41 6c 72 65 61 64 79 20 69 6e 20 6c 6f 63 6b   Already in lock
23690 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20  ing_mode=NORMAL 
236a0 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 30 3b  */.      rc = 0;
236b0 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69  .    }.  }else i
236c0 66 28 20 6f 70 3e 30 20 29 7b 0a 20 20 20 20 61  f( op>0 ){.    a
236d0 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 65 78 63  ssert( pWal->exc
236e0 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f  lusiveMode==WAL_
236f0 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 20 29 3b 0a 20  NORMAL_MODE );. 
23700 20 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d     assert( pWal-
23710 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b 0a  >readLock>=0 );.
23720 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61      walUnlockSha
23730 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
23740 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65  AD_LOCK(pWal->re
23750 61 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70 57  adLock));.    pW
23760 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  al->exclusiveMod
23770 65 20 3d 20 57 41 4c 5f 45 58 43 4c 55 53 49 56  e = WAL_EXCLUSIV
23780 45 5f 4d 4f 44 45 3b 0a 20 20 20 20 72 63 20 3d  E_MODE;.    rc =
23790 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20   1;.  }else{.   
237a0 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c   rc = pWal->excl
237b0 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 4e  usiveMode==WAL_N
237c0 4f 52 4d 41 4c 5f 4d 4f 44 45 3b 0a 20 20 7d 0a  ORMAL_MODE;.  }.
237d0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
237e0 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72  /* .** Return tr
237f0 75 65 20 69 66 20 74 68 65 20 61 72 67 75 6d 65  ue if the argume
23800 6e 74 20 69 73 20 6e 6f 6e 2d 4e 55 4c 4c 20 61  nt is non-NULL a
23810 6e 64 20 74 68 65 20 57 41 4c 20 6d 6f 64 75 6c  nd the WAL modul
23820 65 20 69 73 20 75 73 69 6e 67 0a 2a 2a 20 68 65  e is using.** he
23830 61 70 2d 6d 65 6d 6f 72 79 20 66 6f 72 20 74 68  ap-memory for th
23840 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 4f 74 68  e wal-index. Oth
23850 65 72 77 69 73 65 2c 20 69 66 20 74 68 65 20 61  erwise, if the a
23860 72 67 75 6d 65 6e 74 20 69 73 20 4e 55 4c 4c 20  rgument is NULL 
23870 6f 72 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6d 6f  or the.** WAL mo
23880 64 75 6c 65 20 69 73 20 75 73 69 6e 67 20 73 68  dule is using sh
23890 61 72 65 64 2d 6d 65 6d 6f 72 79 2c 20 72 65 74  ared-memory, ret
238a0 75 72 6e 20 66 61 6c 73 65 2e 20 0a 2a 2f 0a 69  urn false. .*/.i
238b0 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 48 65 61  nt sqlite3WalHea
238c0 70 4d 65 6d 6f 72 79 28 57 61 6c 20 2a 70 57 61  pMemory(Wal *pWa
238d0 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 70 57  l){.  return (pW
238e0 61 6c 20 26 26 20 70 57 61 6c 2d 3e 65 78 63 6c  al && pWal->excl
238f0 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48  usiveMode==WAL_H
23900 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29  EAPMEMORY_MODE )
23910 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49  ;.}..#ifdef SQLI
23920 54 45 5f 45 4e 41 42 4c 45 5f 53 4e 41 50 53 48  TE_ENABLE_SNAPSH
23930 4f 54 0a 2f 2a 20 43 72 65 61 74 65 20 61 20 73  OT./* Create a s
23940 6e 61 70 73 68 6f 74 20 6f 62 6a 65 63 74 2e 20  napshot object. 
23950 20 54 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20   The content of 
23960 61 20 73 6e 61 70 73 68 6f 74 20 69 73 20 6f 70  a snapshot is op
23970 61 71 75 65 20 74 6f 0a 2a 2a 20 65 76 65 72 79  aque to.** every
23980 20 6f 74 68 65 72 20 73 75 62 73 79 73 74 65 6d   other subsystem
23990 2c 20 73 6f 20 74 68 65 20 57 41 4c 20 6d 6f 64  , so the WAL mod
239a0 75 6c 65 20 63 61 6e 20 70 75 74 20 77 68 61 74  ule can put what
239b0 65 76 65 72 20 69 74 20 6e 65 65 64 73 0a 2a 2a  ever it needs.**
239c0 20 69 6e 20 74 68 65 20 6f 62 6a 65 63 74 2e 0a   in the object..
239d0 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
239e0 6c 53 6e 61 70 73 68 6f 74 47 65 74 28 57 61 6c  lSnapshotGet(Wal
239f0 20 2a 70 57 61 6c 2c 20 73 71 6c 69 74 65 33 5f   *pWal, sqlite3_
23a00 73 6e 61 70 73 68 6f 74 20 2a 2a 70 70 53 6e 61  snapshot **ppSna
23a10 70 73 68 6f 74 29 7b 0a 20 20 69 6e 74 20 72 63  pshot){.  int rc
23a20 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
23a30 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 70 52 65  WalIndexHdr *pRe
23a40 74 3b 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73  t;.  static cons
23a50 74 20 75 33 32 20 61 5a 65 72 6f 5b 34 5d 20 3d  t u32 aZero[4] =
23a60 20 7b 20 30 2c 20 30 2c 20 30 2c 20 30 20 7d 3b   { 0, 0, 0, 0 };
23a70 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ..  assert( pWal
23a80 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 26 26  ->readLock>=0 &&
23a90 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
23aa0 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 6d 65  ==0 );..  if( me
23ab0 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72 2e  mcmp(&pWal->hdr.
23ac0 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 2c 61  aFrameCksum[0],a
23ad0 5a 65 72 6f 2c 31 36 29 3d 3d 30 20 29 7b 0a 20  Zero,16)==0 ){. 
23ae0 20 20 20 2a 70 70 53 6e 61 70 73 68 6f 74 20 3d     *ppSnapshot =
23af0 20 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   0;.    return S
23b00 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
23b10 0a 20 20 70 52 65 74 20 3d 20 28 57 61 6c 49 6e  .  pRet = (WalIn
23b20 64 65 78 48 64 72 2a 29 73 71 6c 69 74 65 33 5f  dexHdr*)sqlite3_
23b30 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 57 61  malloc(sizeof(Wa
23b40 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 69  lIndexHdr));.  i
23b50 66 28 20 70 52 65 74 3d 3d 30 20 29 7b 0a 20 20  f( pRet==0 ){.  
23b60 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
23b70 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20 7d 65 6c 73  MEM_BKPT;.  }els
23b80 65 7b 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 52  e{.    memcpy(pR
23b90 65 74 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c 20  et, &pWal->hdr, 
23ba0 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48  sizeof(WalIndexH
23bb0 64 72 29 29 3b 0a 20 20 20 20 2a 70 70 53 6e 61  dr));.    *ppSna
23bc0 70 73 68 6f 74 20 3d 20 28 73 71 6c 69 74 65 33  pshot = (sqlite3
23bd0 5f 73 6e 61 70 73 68 6f 74 2a 29 70 52 65 74 3b  _snapshot*)pRet;
23be0 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
23bf0 63 3b 0a 7d 0a 0a 2f 2a 20 54 72 79 20 74 6f 20  c;.}../* Try to 
23c00 6f 70 65 6e 20 6f 6e 20 70 53 6e 61 70 73 68 6f  open on pSnapsho
23c10 74 20 77 68 65 6e 20 74 68 65 20 6e 65 78 74 20  t when the next 
23c20 72 65 61 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e  read-transaction
23c30 20 73 74 61 72 74 73 0a 2a 2f 0a 76 6f 69 64 20   starts.*/.void 
23c40 73 71 6c 69 74 65 33 57 61 6c 53 6e 61 70 73 68  sqlite3WalSnapsh
23c50 6f 74 4f 70 65 6e 28 57 61 6c 20 2a 70 57 61 6c  otOpen(Wal *pWal
23c60 2c 20 73 71 6c 69 74 65 33 5f 73 6e 61 70 73 68  , sqlite3_snapsh
23c70 6f 74 20 2a 70 53 6e 61 70 73 68 6f 74 29 7b 0a  ot *pSnapshot){.
23c80 20 20 70 57 61 6c 2d 3e 70 53 6e 61 70 73 68 6f    pWal->pSnapsho
23c90 74 20 3d 20 28 57 61 6c 49 6e 64 65 78 48 64 72  t = (WalIndexHdr
23ca0 2a 29 70 53 6e 61 70 73 68 6f 74 3b 0a 7d 0a 0a  *)pSnapshot;.}..
23cb0 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20  /* .** Return a 
23cc0 2b 76 65 20 76 61 6c 75 65 20 69 66 20 73 6e 61  +ve value if sna
23cd0 70 73 68 6f 74 20 70 31 20 69 73 20 6e 65 77 65  pshot p1 is newe
23ce0 72 20 74 68 61 6e 20 70 32 2e 20 41 20 2d 76 65  r than p2. A -ve
23cf0 20 76 61 6c 75 65 20 69 66 0a 2a 2a 20 70 31 20   value if.** p1 
23d00 69 73 20 6f 6c 64 65 72 20 74 68 61 6e 20 70 32  is older than p2
23d10 20 61 6e 64 20 7a 65 72 6f 20 69 66 20 70 31 20   and zero if p1 
23d20 61 6e 64 20 70 32 20 61 72 65 20 74 68 65 20 73  and p2 are the s
23d30 61 6d 65 20 73 6e 61 70 73 68 6f 74 2e 0a 2a 2f  ame snapshot..*/
23d40 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 73 6e 61  .int sqlite3_sna
23d50 70 73 68 6f 74 5f 63 6d 70 28 73 71 6c 69 74 65  pshot_cmp(sqlite
23d60 33 5f 73 6e 61 70 73 68 6f 74 20 2a 70 31 2c 20  3_snapshot *p1, 
23d70 73 71 6c 69 74 65 33 5f 73 6e 61 70 73 68 6f 74  sqlite3_snapshot
23d80 20 2a 70 32 29 7b 0a 20 20 57 61 6c 49 6e 64 65   *p2){.  WalInde
23d90 78 48 64 72 20 2a 70 48 64 72 31 20 3d 20 28 57  xHdr *pHdr1 = (W
23da0 61 6c 49 6e 64 65 78 48 64 72 2a 29 70 31 3b 0a  alIndexHdr*)p1;.
23db0 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 70    WalIndexHdr *p
23dc0 48 64 72 32 20 3d 20 28 57 61 6c 49 6e 64 65 78  Hdr2 = (WalIndex
23dd0 48 64 72 2a 29 70 32 3b 0a 0a 20 20 2f 2a 20 61  Hdr*)p2;..  /* a
23de0 53 61 6c 74 5b 30 5d 20 69 73 20 61 20 63 6f 70  Salt[0] is a cop
23df0 79 20 6f 66 20 74 68 65 20 76 61 6c 75 65 20 73  y of the value s
23e00 74 6f 72 65 64 20 69 6e 20 74 68 65 20 77 61 6c  tored in the wal
23e10 20 66 69 6c 65 20 68 65 61 64 65 72 2e 20 49 74   file header. It
23e20 0a 20 20 2a 2a 20 69 73 20 69 6e 63 72 65 6d 65  .  ** is increme
23e30 6e 74 65 64 20 65 61 63 68 20 74 69 6d 65 20 74  nted each time t
23e40 68 65 20 77 61 6c 20 66 69 6c 65 20 69 73 20 72  he wal file is r
23e50 65 73 74 61 72 74 65 64 2e 20 20 2a 2f 0a 20 20  estarted.  */.  
23e60 69 66 28 20 70 48 64 72 31 2d 3e 61 53 61 6c 74  if( pHdr1->aSalt
23e70 5b 30 5d 3c 70 48 64 72 32 2d 3e 61 53 61 6c 74  [0]<pHdr2->aSalt
23e80 5b 30 5d 20 29 20 72 65 74 75 72 6e 20 2d 31 3b  [0] ) return -1;
23e90 0a 20 20 69 66 28 20 70 48 64 72 31 2d 3e 61 53  .  if( pHdr1->aS
23ea0 61 6c 74 5b 30 5d 3e 70 48 64 72 32 2d 3e 61 53  alt[0]>pHdr2->aS
23eb0 61 6c 74 5b 30 5d 20 29 20 72 65 74 75 72 6e 20  alt[0] ) return 
23ec0 2b 31 3b 0a 20 20 69 66 28 20 70 48 64 72 31 2d  +1;.  if( pHdr1-
23ed0 3e 6d 78 46 72 61 6d 65 3c 70 48 64 72 32 2d 3e  >mxFrame<pHdr2->
23ee0 6d 78 46 72 61 6d 65 20 29 20 72 65 74 75 72 6e  mxFrame ) return
23ef0 20 2d 31 3b 0a 20 20 69 66 28 20 70 48 64 72 31   -1;.  if( pHdr1
23f00 2d 3e 6d 78 46 72 61 6d 65 3e 70 48 64 72 32 2d  ->mxFrame>pHdr2-
23f10 3e 6d 78 46 72 61 6d 65 20 29 20 72 65 74 75 72  >mxFrame ) retur
23f20 6e 20 2b 31 3b 0a 20 20 72 65 74 75 72 6e 20 30  n +1;.  return 0
23f30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 63  ;.}../*.** The c
23f40 61 6c 6c 65 72 20 63 75 72 72 65 6e 74 6c 79 20  aller currently 
23f50 68 61 73 20 61 20 72 65 61 64 20 74 72 61 6e 73  has a read trans
23f60 61 63 74 69 6f 6e 20 6f 70 65 6e 20 6f 6e 20 74  action open on t
23f70 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2a 20  he database..** 
23f80 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 74 61  This function ta
23f90 6b 65 73 20 61 20 53 48 41 52 45 44 20 6c 6f 63  kes a SHARED loc
23fa0 6b 20 6f 6e 20 74 68 65 20 43 48 45 43 4b 50 4f  k on the CHECKPO
23fb0 49 4e 54 45 52 20 73 6c 6f 74 20 61 6e 64 20 74  INTER slot and t
23fc0 68 65 6e 0a 2a 2a 20 63 68 65 63 6b 73 20 69 66  hen.** checks if
23fd0 20 74 68 65 20 73 6e 61 70 73 68 6f 74 20 70 61   the snapshot pa
23fe0 73 73 65 64 20 61 73 20 74 68 65 20 73 65 63 6f  ssed as the seco
23ff0 6e 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20 73  nd argument is s
24000 74 69 6c 6c 20 0a 2a 2a 20 61 76 61 69 6c 61 62  till .** availab
24010 6c 65 2e 20 49 66 20 73 6f 2c 20 53 51 4c 49 54  le. If so, SQLIT
24020 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
24030 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 73  ..**.** If the s
24040 6e 61 70 73 68 6f 74 20 69 73 20 6e 6f 74 20 61  napshot is not a
24050 76 61 69 6c 61 62 6c 65 2c 20 53 51 4c 49 54 45  vailable, SQLITE
24060 5f 45 52 52 4f 52 20 69 73 20 72 65 74 75 72 6e  _ERROR is return
24070 65 64 2e 20 4f 72 2c 20 69 66 0a 2a 2a 20 74 68  ed. Or, if.** th
24080 65 20 43 48 45 43 4b 50 4f 49 4e 54 45 52 20 6c  e CHECKPOINTER l
24090 6f 63 6b 20 63 61 6e 6e 6f 74 20 62 65 20 6f 62  ock cannot be ob
240a0 74 61 69 6e 65 64 2c 20 53 51 4c 49 54 45 5f 42  tained, SQLITE_B
240b0 55 53 59 2e 20 49 66 20 61 6e 79 20 65 72 72 6f  USY. If any erro
240c0 72 0a 2a 2a 20 6f 63 63 75 72 73 20 28 61 6e 79  r.** occurs (any
240d0 20 76 61 6c 75 65 20 6f 74 68 65 72 20 74 68 61   value other tha
240e0 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  n SQLITE_OK is r
240f0 65 74 75 72 6e 65 64 29 2c 20 74 68 65 20 43 48  eturned), the CH
24100 45 43 4b 50 4f 49 4e 54 45 52 0a 2a 2a 20 6c 6f  ECKPOINTER.** lo
24110 63 6b 20 69 73 20 72 65 6c 65 61 73 65 64 20 62  ck is released b
24120 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
24130 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
24140 61 6c 53 6e 61 70 73 68 6f 74 43 68 65 63 6b 28  alSnapshotCheck(
24150 57 61 6c 20 2a 70 57 61 6c 2c 20 73 71 6c 69 74  Wal *pWal, sqlit
24160 65 33 5f 73 6e 61 70 73 68 6f 74 20 2a 70 53 6e  e3_snapshot *pSn
24170 61 70 73 68 6f 74 29 7b 0a 20 20 69 6e 74 20 72  apshot){.  int r
24180 63 3b 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63  c;.  rc = walLoc
24190 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
241a0 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 29 3b 0a 20 20  L_CKPT_LOCK);.  
241b0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
241c0 4b 20 29 7b 0a 20 20 20 20 57 61 6c 49 6e 64 65  K ){.    WalInde
241d0 78 48 64 72 20 2a 70 4e 65 77 20 3d 20 28 57 61  xHdr *pNew = (Wa
241e0 6c 49 6e 64 65 78 48 64 72 2a 29 70 53 6e 61 70  lIndexHdr*)pSnap
241f0 73 68 6f 74 3b 0a 20 20 20 20 69 66 28 20 6d 65  shot;.    if( me
24200 6d 63 6d 70 28 70 4e 65 77 2d 3e 61 53 61 6c 74  mcmp(pNew->aSalt
24210 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c  , pWal->hdr.aSal
24220 74 2c 20 73 69 7a 65 6f 66 28 70 57 61 6c 2d 3e  t, sizeof(pWal->
24230 68 64 72 2e 61 53 61 6c 74 29 29 0a 20 20 20 20  hdr.aSalt)).    
24240 20 7c 7c 20 70 4e 65 77 2d 3e 6d 78 46 72 61 6d   || pNew->mxFram
24250 65 3c 77 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57  e<walCkptInfo(pW
24260 61 6c 29 2d 3e 6e 42 61 63 6b 66 69 6c 6c 41 74  al)->nBackfillAt
24270 74 65 6d 70 74 65 64 0a 20 20 20 20 29 7b 0a 20  tempted.    ){. 
24280 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
24290 5f 45 52 52 4f 52 5f 53 4e 41 50 53 48 4f 54 3b  _ERROR_SNAPSHOT;
242a0 0a 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b  .      walUnlock
242b0 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c  Shared(pWal, WAL
242c0 5f 43 4b 50 54 5f 4c 4f 43 4b 29 3b 0a 20 20 20  _CKPT_LOCK);.   
242d0 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
242e0 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6c  rc;.}../*.** Rel
242f0 65 61 73 65 20 61 20 6c 6f 63 6b 20 6f 62 74 61  ease a lock obta
24300 69 6e 65 64 20 62 79 20 61 6e 20 65 61 72 6c 69  ined by an earli
24310 65 72 20 73 75 63 63 65 73 73 66 75 6c 20 63 61  er successful ca
24320 6c 6c 20 74 6f 0a 2a 2a 20 73 71 6c 69 74 65 33  ll to.** sqlite3
24330 57 61 6c 53 6e 61 70 73 68 6f 74 43 68 65 63 6b  WalSnapshotCheck
24340 28 29 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  ()..*/.void sqli
24350 74 65 33 57 61 6c 53 6e 61 70 73 68 6f 74 55 6e  te3WalSnapshotUn
24360 6c 6f 63 6b 28 57 61 6c 20 2a 70 57 61 6c 29 7b  lock(Wal *pWal){
24370 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 20  .  assert( pWal 
24380 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68  );.  walUnlockSh
24390 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 43  ared(pWal, WAL_C
243a0 4b 50 54 5f 4c 4f 43 4b 29 3b 0a 7d 0a 0a 0a 23  KPT_LOCK);.}...#
243b0 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f  endif /* SQLITE_
243c0 45 4e 41 42 4c 45 5f 53 4e 41 50 53 48 4f 54 20  ENABLE_SNAPSHOT 
243d0 2a 2f 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  */..#ifdef SQLIT
243e0 45 5f 45 4e 41 42 4c 45 5f 5a 49 50 56 46 53 0a  E_ENABLE_ZIPVFS.
243f0 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 20 61 72 67  /*.** If the arg
24400 75 6d 65 6e 74 20 69 73 20 6e 6f 74 20 4e 55 4c  ument is not NUL
24410 4c 2c 20 69 74 20 70 6f 69 6e 74 73 20 74 6f 20  L, it points to 
24420 61 20 57 61 6c 20 6f 62 6a 65 63 74 20 74 68 61  a Wal object tha
24430 74 20 68 6f 6c 64 73 20 61 0a 2a 2a 20 72 65 61  t holds a.** rea
24440 64 2d 6c 6f 63 6b 2e 20 54 68 69 73 20 66 75 6e  d-lock. This fun
24450 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 74 68  ction returns th
24460 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65 2d  e database page-
24470 73 69 7a 65 20 69 66 20 69 74 20 69 73 20 6b 6e  size if it is kn
24480 6f 77 6e 2c 0a 2a 2a 20 6f 72 20 7a 65 72 6f 20  own,.** or zero 
24490 69 66 20 69 74 20 69 73 20 6e 6f 74 20 28 6f 72  if it is not (or
244a0 20 69 66 20 70 57 61 6c 20 69 73 20 4e 55 4c 4c   if pWal is NULL
244b0 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  )..*/.int sqlite
244c0 33 57 61 6c 46 72 61 6d 65 73 69 7a 65 28 57 61  3WalFramesize(Wa
244d0 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73 65  l *pWal){.  asse
244e0 72 74 28 20 70 57 61 6c 3d 3d 30 20 7c 7c 20 70  rt( pWal==0 || p
244f0 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30  Wal->readLock>=0
24500 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 70 57   );.  return (pW
24510 61 6c 20 3f 20 70 57 61 6c 2d 3e 73 7a 50 61 67  al ? pWal->szPag
24520 65 20 3a 20 30 29 3b 0a 7d 0a 23 65 6e 64 69 66  e : 0);.}.#endif
24530 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 74 68 65 20  ../* Return the 
24540 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 6f 62 6a  sqlite3_file obj
24550 65 63 74 20 66 6f 72 20 74 68 65 20 57 41 4c 20  ect for the WAL 
24560 66 69 6c 65 0a 2a 2f 0a 73 71 6c 69 74 65 33 5f  file.*/.sqlite3_
24570 66 69 6c 65 20 2a 73 71 6c 69 74 65 33 57 61 6c  file *sqlite3Wal
24580 46 69 6c 65 28 57 61 6c 20 2a 70 57 61 6c 29 7b  File(Wal *pWal){
24590 0a 20 20 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e  .  return pWal->
245a0 70 57 61 6c 46 64 3b 0a 7d 0a 0a 23 65 6e 64 69  pWalFd;.}..#endi
245b0 66 20 2f 2a 20 23 69 66 6e 64 65 66 20 53 51 4c  f /* #ifndef SQL
245c0 49 54 45 5f 4f 4d 49 54 5f 57 41 4c 20 2a 2f 0a  ITE_OMIT_WAL */.