/ Hex Artifact Content
Login

Artifact 5a3f464edd64596f601683ed321d12e6fd93c5fb9afdfb3653d6ffd0fee9c48f:


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 54 68 65 20 6d 61 78 69 6d 75 6d 20  .** The maximum 
3290: 28 61 6e 64 20 6f 6e 6c 79 29 20 76 65 72 73 69  (and only) versi
32a0: 6f 6e 73 20 6f 66 20 74 68 65 20 77 61 6c 20 61  ons of the wal a
32b0: 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 6f 72  nd wal-index for
32c0: 6d 61 74 73 0a 2a 2a 20 74 68 61 74 20 6d 61 79  mats.** that may
32d0: 20 62 65 20 69 6e 74 65 72 70 72 65 74 65 64 20   be interpreted 
32e0: 62 79 20 74 68 69 73 20 76 65 72 73 69 6f 6e 20  by this version 
32f0: 6f 66 20 53 51 4c 69 74 65 2e 0a 2a 2a 0a 2a 2a  of SQLite..**.**
3300: 20 49 66 20 61 20 63 6c 69 65 6e 74 20 62 65 67   If a client beg
3310: 69 6e 73 20 72 65 63 6f 76 65 72 69 6e 67 20 61  ins recovering a
3320: 20 57 41 4c 20 66 69 6c 65 20 61 6e 64 20 66 69   WAL file and fi
3330: 6e 64 73 20 74 68 61 74 20 28 61 29 20 74 68 65  nds that (a) the
3340: 20 63 68 65 63 6b 73 75 6d 0a 2a 2a 20 76 61 6c   checksum.** val
3350: 75 65 73 20 69 6e 20 74 68 65 20 77 61 6c 2d 68  ues in the wal-h
3360: 65 61 64 65 72 20 61 72 65 20 63 6f 72 72 65 63  eader are correc
3370: 74 20 61 6e 64 20 28 62 29 20 74 68 65 20 76 65  t and (b) the ve
3380: 72 73 69 6f 6e 20 66 69 65 6c 64 20 69 73 20 6e  rsion field is n
3390: 6f 74 0a 2a 2a 20 57 41 4c 5f 4d 41 58 5f 56 45  ot.** WAL_MAX_VE
33a0: 52 53 49 4f 4e 2c 20 72 65 63 6f 76 65 72 79 20  RSION, recovery 
33b0: 66 61 69 6c 73 20 61 6e 64 20 53 51 4c 69 74 65  fails and SQLite
33c0: 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f   returns SQLITE_
33d0: 43 41 4e 54 4f 50 45 4e 2e 0a 2a 2a 0a 2a 2a 20  CANTOPEN..**.** 
33e0: 53 69 6d 69 6c 61 72 6c 79 2c 20 69 66 20 61 20  Similarly, if a 
33f0: 63 6c 69 65 6e 74 20 73 75 63 63 65 73 73 66 75  client successfu
3400: 6c 6c 79 20 72 65 61 64 73 20 61 20 77 61 6c 2d  lly reads a wal-
3410: 69 6e 64 65 78 20 68 65 61 64 65 72 20 28 69 2e  index header (i.
3420: 65 2e 20 74 68 65 20 0a 2a 2a 20 63 68 65 63 6b  e. the .** check
3430: 73 75 6d 20 74 65 73 74 20 69 73 20 73 75 63 63  sum test is succ
3440: 65 73 73 66 75 6c 29 20 61 6e 64 20 66 69 6e 64  essful) and find
3450: 73 20 74 68 61 74 20 74 68 65 20 76 65 72 73 69  s that the versi
3460: 6f 6e 20 66 69 65 6c 64 20 69 73 20 6e 6f 74 0a  on field is not.
3470: 2a 2a 20 57 41 4c 49 4e 44 45 58 5f 4d 41 58 5f  ** WALINDEX_MAX_
3480: 56 45 52 53 49 4f 4e 2c 20 74 68 65 6e 20 6e 6f  VERSION, then no
3490: 20 72 65 61 64 2d 74 72 61 6e 73 61 63 74 69 6f   read-transactio
34a0: 6e 20 69 73 20 6f 70 65 6e 65 64 20 61 6e 64 20  n is opened and 
34b0: 53 51 4c 69 74 65 0a 2a 2a 20 72 65 74 75 72 6e  SQLite.** return
34c0: 73 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45  s SQLITE_CANTOPE
34d0: 4e 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41  N..*/.#define WA
34e0: 4c 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 20 20 20  L_MAX_VERSION   
34f0: 20 20 20 33 30 30 37 30 30 30 0a 23 64 65 66 69     3007000.#defi
3500: 6e 65 20 57 41 4c 49 4e 44 45 58 5f 4d 41 58 5f  ne WALINDEX_MAX_
3510: 56 45 52 53 49 4f 4e 20 33 30 30 37 30 30 30 0a  VERSION 3007000.
3520: 0a 2f 2a 0a 2a 2a 20 49 6e 64 65 78 20 6e 75 6d  ./*.** Index num
3530: 62 65 72 73 20 66 6f 72 20 76 61 72 69 6f 75 73  bers for various
3540: 20 6c 6f 63 6b 69 6e 67 20 62 79 74 65 73 2e 20   locking bytes. 
3550: 20 20 57 41 4c 5f 4e 52 45 41 44 45 52 20 69 73    WAL_NREADER is
3560: 20 74 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f   the number.** o
3570: 66 20 61 76 61 69 6c 61 62 6c 65 20 72 65 61 64  f available read
3580: 65 72 20 6c 6f 63 6b 73 20 61 6e 64 20 73 68 6f  er locks and sho
3590: 75 6c 64 20 62 65 20 61 74 20 6c 65 61 73 74 20  uld be at least 
35a0: 33 2e 20 20 54 68 65 20 64 65 66 61 75 6c 74 0a  3.  The default.
35b0: 2a 2a 20 69 73 20 53 51 4c 49 54 45 5f 53 48 4d  ** is SQLITE_SHM
35c0: 5f 4e 4c 4f 43 4b 3d 3d 38 20 61 6e 64 20 20 57  _NLOCK==8 and  W
35d0: 41 4c 5f 4e 52 45 41 44 45 52 3d 3d 35 2e 0a 2a  AL_NREADER==5..*
35e0: 2a 0a 2a 2a 20 54 65 63 68 6e 69 63 61 6c 6c 79  *.** Technically
35f0: 2c 20 74 68 65 20 76 61 72 69 6f 75 73 20 56 46  , the various VF
3600: 53 65 73 20 61 72 65 20 66 72 65 65 20 74 6f 20  Ses are free to 
3610: 69 6d 70 6c 65 6d 65 6e 74 20 74 68 65 73 65 20  implement these 
3620: 6c 6f 63 6b 73 20 68 6f 77 65 76 65 72 0a 2a 2a  locks however.**
3630: 20 74 68 65 79 20 73 65 65 20 66 69 74 2e 20 20   they see fit.  
3640: 48 6f 77 65 76 65 72 2c 20 63 6f 6d 70 61 74 69  However, compati
3650: 62 69 6c 69 74 79 20 69 73 20 65 6e 63 6f 75 72  bility is encour
3660: 61 67 65 64 20 73 6f 20 74 68 61 74 20 56 46 53  aged so that VFS
3670: 65 73 20 63 61 6e 0a 2a 2a 20 69 6e 74 65 72 6f  es can.** intero
3680: 70 65 72 61 74 65 2e 20 20 54 68 65 20 73 74 61  perate.  The sta
3690: 6e 64 61 72 64 20 69 6d 70 6c 65 6d 65 6e 74 69  ndard implementi
36a0: 6f 6e 20 75 73 65 64 20 6f 6e 20 62 6f 74 68 20  on used on both 
36b0: 75 6e 69 78 20 61 6e 64 20 77 69 6e 64 6f 77 73  unix and windows
36c0: 0a 2a 2a 20 69 73 20 66 6f 72 20 74 68 65 20 69  .** is for the i
36d0: 6e 64 65 78 20 6e 75 6d 62 65 72 20 74 6f 20 69  ndex number to i
36e0: 6e 64 69 63 61 74 65 20 61 20 62 79 74 65 20 6f  ndicate a byte o
36f0: 66 66 73 65 74 20 69 6e 74 6f 20 74 68 65 0a 2a  ffset into the.*
3700: 2a 20 57 61 6c 43 6b 70 74 49 6e 66 6f 2e 61 4c  * WalCkptInfo.aL
3710: 6f 63 6b 5b 5d 20 61 72 72 61 79 20 69 6e 20 74  ock[] array in t
3720: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
3730: 64 65 72 2e 20 20 49 6e 20 6f 74 68 65 72 20 77  der.  In other w
3740: 6f 72 64 73 2c 20 61 6c 6c 0a 2a 2a 20 6c 6f 63  ords, all.** loc
3750: 6b 73 20 61 72 65 20 6f 6e 20 74 68 65 20 73 68  ks are on the sh
3760: 6d 20 66 69 6c 65 2e 20 20 54 68 65 20 57 41 4c  m file.  The WAL
3770: 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45  INDEX_LOCK_OFFSE
3780: 54 20 63 6f 6e 73 74 61 6e 74 20 28 77 68 69 63  T constant (whic
3790: 68 0a 2a 2a 20 73 68 6f 75 6c 64 20 62 65 20 31  h.** should be 1
37a0: 32 30 29 20 69 73 20 74 68 65 20 6c 6f 63 61 74  20) is the locat
37b0: 69 6f 6e 20 69 6e 20 74 68 65 20 73 68 6d 20 66  ion in the shm f
37c0: 69 6c 65 20 66 6f 72 20 74 68 65 20 66 69 72 73  ile for the firs
37d0: 74 20 6c 6f 63 6b 69 6e 67 0a 2a 2a 20 62 79 74  t locking.** byt
37e0: 65 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41  e..*/.#define WA
37f0: 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 20 20 20  L_WRITE_LOCK    
3800: 20 20 20 20 20 30 0a 23 64 65 66 69 6e 65 20 57       0.#define W
3810: 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45  AL_ALL_BUT_WRITE
3820: 20 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20        1.#define 
3830: 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 20 20  WAL_CKPT_LOCK   
3840: 20 20 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65         1.#define
3850: 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43   WAL_RECOVER_LOC
3860: 4b 20 20 20 20 20 20 20 32 0a 23 64 65 66 69 6e  K       2.#defin
3870: 65 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  e WAL_READ_LOCK(
3880: 49 29 20 20 20 20 20 20 20 28 33 2b 28 49 29 29  I)       (3+(I))
3890: 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 4e 52 45  .#define WAL_NRE
38a0: 41 44 45 52 20 20 20 20 20 20 20 20 20 20 20 20  ADER            
38b0: 28 53 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43  (SQLITE_SHM_NLOC
38c0: 4b 2d 33 29 0a 0a 0a 2f 2a 20 4f 62 6a 65 63 74  K-3).../* Object
38d0: 20 64 65 63 6c 61 72 61 74 69 6f 6e 73 20 2a 2f   declarations */
38e0: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
38f0: 57 61 6c 49 6e 64 65 78 48 64 72 20 57 61 6c 49  WalIndexHdr WalI
3900: 6e 64 65 78 48 64 72 3b 0a 74 79 70 65 64 65 66  ndexHdr;.typedef
3910: 20 73 74 72 75 63 74 20 57 61 6c 49 74 65 72 61   struct WalItera
3920: 74 6f 72 20 57 61 6c 49 74 65 72 61 74 6f 72 3b  tor WalIterator;
3930: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
3940: 57 61 6c 43 6b 70 74 49 6e 66 6f 20 57 61 6c 43  WalCkptInfo WalC
3950: 6b 70 74 49 6e 66 6f 3b 0a 0a 0a 2f 2a 0a 2a 2a  kptInfo;.../*.**
3960: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f   The following o
3970: 62 6a 65 63 74 20 68 6f 6c 64 73 20 61 20 63 6f  bject holds a co
3980: 70 79 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  py of the wal-in
3990: 64 65 78 20 68 65 61 64 65 72 20 63 6f 6e 74 65  dex header conte
39a0: 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63  nt..**.** The ac
39b0: 74 75 61 6c 20 68 65 61 64 65 72 20 69 6e 20 74  tual header in t
39c0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e  he wal-index con
39d0: 73 69 73 74 73 20 6f 66 20 74 77 6f 20 63 6f 70  sists of two cop
39e0: 69 65 73 20 6f 66 20 74 68 69 73 0a 2a 2a 20 6f  ies of this.** o
39f0: 62 6a 65 63 74 20 66 6f 6c 6c 6f 77 65 64 20 62  bject followed b
3a00: 79 20 6f 6e 65 20 69 6e 73 74 61 6e 63 65 20 6f  y one instance o
3a10: 66 20 74 68 65 20 57 61 6c 43 6b 70 74 49 6e 66  f the WalCkptInf
3a20: 6f 20 6f 62 6a 65 63 74 2e 0a 2a 2a 20 46 6f 72  o object..** For
3a30: 20 61 6c 6c 20 76 65 72 73 69 6f 6e 73 20 6f 66   all versions of
3a40: 20 53 51 4c 69 74 65 20 74 68 72 6f 75 67 68 20   SQLite through 
3a50: 33 2e 31 30 2e 30 20 61 6e 64 20 70 72 6f 62 61  3.10.0 and proba
3a60: 62 6c 79 20 62 65 79 6f 6e 64 2c 0a 2a 2a 20 74  bly beyond,.** t
3a70: 68 65 20 6c 6f 63 6b 69 6e 67 20 62 79 74 65 73  he locking bytes
3a80: 20 28 57 61 6c 43 6b 70 74 49 6e 66 6f 2e 61 4c   (WalCkptInfo.aL
3a90: 6f 63 6b 29 20 73 74 61 72 74 20 61 74 20 6f 66  ock) start at of
3aa0: 66 73 65 74 20 31 32 30 20 61 6e 64 0a 2a 2a 20  fset 120 and.** 
3ab0: 74 68 65 20 74 6f 74 61 6c 20 68 65 61 64 65 72  the total header
3ac0: 20 73 69 7a 65 20 69 73 20 31 33 36 20 62 79 74   size is 136 byt
3ad0: 65 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 7a  es..**.** The sz
3ae0: 50 61 67 65 20 76 61 6c 75 65 20 63 61 6e 20 62  Page value can b
3af0: 65 20 61 6e 79 20 70 6f 77 65 72 20 6f 66 20 32  e any power of 2
3b00: 20 62 65 74 77 65 65 6e 20 35 31 32 20 61 6e 64   between 512 and
3b10: 20 33 32 37 36 38 2c 20 69 6e 63 6c 75 73 69 76   32768, inclusiv
3b20: 65 2e 0a 2a 2a 20 4f 72 20 69 74 20 63 61 6e 20  e..** Or it can 
3b30: 62 65 20 31 20 74 6f 20 72 65 70 72 65 73 65 6e  be 1 to represen
3b40: 74 20 61 20 36 35 35 33 36 2d 62 79 74 65 20 70  t a 65536-byte p
3b50: 61 67 65 2e 20 20 54 68 65 20 6c 61 74 74 65 72  age.  The latter
3b60: 20 63 61 73 65 20 77 61 73 0a 2a 2a 20 61 64 64   case was.** add
3b70: 65 64 20 69 6e 20 33 2e 37 2e 31 20 77 68 65 6e  ed in 3.7.1 when
3b80: 20 73 75 70 70 6f 72 74 20 66 6f 72 20 36 34 4b   support for 64K
3b90: 20 70 61 67 65 73 20 77 61 73 20 61 64 64 65 64   pages was added
3ba0: 2e 20 20 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61  .  .*/.struct Wa
3bb0: 6c 49 6e 64 65 78 48 64 72 20 7b 0a 20 20 75 33  lIndexHdr {.  u3
3bc0: 32 20 69 56 65 72 73 69 6f 6e 3b 20 20 20 20 20  2 iVersion;     
3bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3be0: 20 57 61 6c 2d 69 6e 64 65 78 20 76 65 72 73 69   Wal-index versi
3bf0: 6f 6e 20 2a 2f 0a 20 20 75 33 32 20 75 6e 75 73  on */.  u32 unus
3c00: 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ed;             
3c10: 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 75 73 65          /* Unuse
3c20: 64 20 28 70 61 64 64 69 6e 67 29 20 66 69 65 6c  d (padding) fiel
3c30: 64 20 2a 2f 0a 20 20 75 33 32 20 69 43 68 61 6e  d */.  u32 iChan
3c40: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
3c50: 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65         /* Counte
3c60: 72 20 69 6e 63 72 65 6d 65 6e 74 65 64 20 65 61  r incremented ea
3c70: 63 68 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a  ch transaction *
3c80: 2f 0a 20 20 75 38 20 69 73 49 6e 69 74 3b 20 20  /.  u8 isInit;  
3c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ca0: 20 20 20 20 2f 2a 20 31 20 77 68 65 6e 20 69 6e      /* 1 when in
3cb0: 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 75  itialized */.  u
3cc0: 38 20 62 69 67 45 6e 64 43 6b 73 75 6d 3b 20 20  8 bigEndCksum;  
3cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3ce0: 2a 20 54 72 75 65 20 69 66 20 63 68 65 63 6b 73  * True if checks
3cf0: 75 6d 73 20 69 6e 20 57 41 4c 20 61 72 65 20 62  ums in WAL are b
3d00: 69 67 2d 65 6e 64 69 61 6e 20 2a 2f 0a 20 20 75  ig-endian */.  u
3d10: 31 36 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20  16 szPage;      
3d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3d30: 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20  * Database page 
3d40: 73 69 7a 65 20 69 6e 20 62 79 74 65 73 2e 20 31  size in bytes. 1
3d50: 3d 3d 36 34 4b 20 2a 2f 0a 20 20 75 33 32 20 6d  ==64K */.  u32 m
3d60: 78 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20  xFrame;         
3d70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
3d80: 64 65 78 20 6f 66 20 6c 61 73 74 20 76 61 6c 69  dex of last vali
3d90: 64 20 66 72 61 6d 65 20 69 6e 20 74 68 65 20 57  d frame in the W
3da0: 41 4c 20 2a 2f 0a 20 20 75 33 32 20 6e 50 61 67  AL */.  u32 nPag
3db0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
3dc0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
3dd0: 6f 66 20 64 61 74 61 62 61 73 65 20 69 6e 20 70  of database in p
3de0: 61 67 65 73 20 2a 2f 0a 20 20 75 33 32 20 61 46  ages */.  u32 aF
3df0: 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  rameCksum[2];   
3e00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65            /* Che
3e10: 63 6b 73 75 6d 20 6f 66 20 6c 61 73 74 20 66 72  cksum of last fr
3e20: 61 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20  ame in log */.  
3e30: 75 33 32 20 61 53 61 6c 74 5b 32 5d 3b 20 20 20  u32 aSalt[2];   
3e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3e50: 2f 2a 20 54 77 6f 20 73 61 6c 74 20 76 61 6c 75  /* Two salt valu
3e60: 65 73 20 63 6f 70 69 65 64 20 66 72 6f 6d 20 57  es copied from W
3e70: 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 75  AL header */.  u
3e80: 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  32 aCksum[2];   
3e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3ea0: 2a 20 43 68 65 63 6b 73 75 6d 20 6f 76 65 72 20  * Checksum over 
3eb0: 61 6c 6c 20 70 72 69 6f 72 20 66 69 65 6c 64 73  all prior fields
3ec0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20   */.};../*.** A 
3ed0: 63 6f 70 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c  copy of the foll
3ee0: 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 6f 63 63  owing object occ
3ef0: 75 72 73 20 69 6e 20 74 68 65 20 77 61 6c 2d 69  urs in the wal-i
3f00: 6e 64 65 78 20 69 6d 6d 65 64 69 61 74 65 6c 79  ndex immediately
3f10: 0a 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68  .** following th
3f20: 65 20 73 65 63 6f 6e 64 20 63 6f 70 79 20 6f 66  e second copy of
3f30: 20 74 68 65 20 57 61 6c 49 6e 64 65 78 48 64 72   the WalIndexHdr
3f40: 2e 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20 73  .  This object s
3f50: 74 6f 72 65 73 0a 2a 2a 20 69 6e 66 6f 72 6d 61  tores.** informa
3f60: 74 69 6f 6e 20 75 73 65 64 20 62 79 20 63 68 65  tion used by che
3f70: 63 6b 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20 6e  ckpoint..**.** n
3f80: 42 61 63 6b 66 69 6c 6c 20 69 73 20 74 68 65 20  Backfill is the 
3f90: 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d 65 73  number of frames
3fa0: 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68 61 74   in the WAL that
3fb0: 20 68 61 76 65 20 62 65 65 6e 20 77 72 69 74 74   have been writt
3fc0: 65 6e 0a 2a 2a 20 62 61 63 6b 20 69 6e 74 6f 20  en.** back into 
3fd0: 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 28 57  the database. (W
3fe0: 65 20 63 61 6c 6c 20 74 68 65 20 61 63 74 20 6f  e call the act o
3ff0: 66 20 6d 6f 76 69 6e 67 20 63 6f 6e 74 65 6e 74  f moving content
4000: 20 66 72 6f 6d 20 57 41 4c 20 74 6f 0a 2a 2a 20   from WAL to.** 
4010: 64 61 74 61 62 61 73 65 20 22 62 61 63 6b 66 69  database "backfi
4020: 6c 6c 69 6e 67 22 2e 29 20 20 54 68 65 20 6e 42  lling".)  The nB
4030: 61 63 6b 66 69 6c 6c 20 6e 75 6d 62 65 72 20 69  ackfill number i
4040: 73 20 6e 65 76 65 72 20 67 72 65 61 74 65 72 20  s never greater 
4050: 74 68 61 6e 0a 2a 2a 20 57 61 6c 49 6e 64 65 78  than.** WalIndex
4060: 48 64 72 2e 6d 78 46 72 61 6d 65 2e 20 20 6e 42  Hdr.mxFrame.  nB
4070: 61 63 6b 66 69 6c 6c 20 63 61 6e 20 6f 6e 6c 79  ackfill can only
4080: 20 62 65 20 69 6e 63 72 65 61 73 65 64 20 62 79   be increased by
4090: 20 74 68 72 65 61 64 73 0a 2a 2a 20 68 6f 6c 64   threads.** hold
40a0: 69 6e 67 20 74 68 65 20 57 41 4c 5f 43 4b 50 54  ing the WAL_CKPT
40b0: 5f 4c 4f 43 4b 20 6c 6f 63 6b 20 28 77 68 69 63  _LOCK lock (whic
40c0: 68 20 69 6e 63 6c 75 64 65 73 20 61 20 72 65 63  h includes a rec
40d0: 6f 76 65 72 79 20 74 68 72 65 61 64 29 2e 0a 2a  overy thread)..*
40e0: 2a 20 48 6f 77 65 76 65 72 2c 20 61 20 57 41 4c  * However, a WAL
40f0: 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 74 68 72 65  _WRITE_LOCK thre
4100: 61 64 20 63 61 6e 20 6d 6f 76 65 20 74 68 65 20  ad can move the 
4110: 76 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b 66 69  value of nBackfi
4120: 6c 6c 20 66 72 6f 6d 0a 2a 2a 20 6d 78 46 72 61  ll from.** mxFra
4130: 6d 65 20 62 61 63 6b 20 74 6f 20 7a 65 72 6f 20  me back to zero 
4140: 77 68 65 6e 20 74 68 65 20 57 41 4c 20 69 73 20  when the WAL is 
4150: 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 6e 42 61  reset..**.** nBa
4160: 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 20  ckfillAttempted 
4170: 69 73 20 74 68 65 20 6c 61 72 67 65 73 74 20 76  is the largest v
4180: 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b 66 69 6c  alue of nBackfil
4190: 6c 20 74 68 61 74 20 61 20 63 68 65 63 6b 70 6f  l that a checkpo
41a0: 69 6e 74 0a 2a 2a 20 68 61 73 20 61 74 74 65 6d  int.** has attem
41b0: 70 74 65 64 20 74 6f 20 61 63 68 69 65 76 65 2e  pted to achieve.
41c0: 20 20 4e 6f 72 6d 61 6c 6c 79 20 6e 42 61 63 6b    Normally nBack
41d0: 66 69 6c 6c 3d 3d 6e 42 61 63 6b 66 69 6c 6c 41  fill==nBackfillA
41e0: 74 65 6d 70 74 65 64 2c 20 68 6f 77 65 76 65 72  tempted, however
41f0: 0a 2a 2a 20 74 68 65 20 6e 42 61 63 6b 66 69 6c  .** the nBackfil
4200: 6c 41 74 74 65 6d 70 74 65 64 20 69 73 20 73 65  lAttempted is se
4210: 74 20 62 65 66 6f 72 65 20 61 6e 79 20 62 61 63  t before any bac
4220: 6b 66 69 6c 6c 69 6e 67 20 69 73 20 64 6f 6e 65  kfilling is done
4230: 20 61 6e 64 20 74 68 65 0a 2a 2a 20 6e 42 61 63   and the.** nBac
4240: 6b 66 69 6c 6c 20 69 73 20 6f 6e 6c 79 20 73 65  kfill is only se
4250: 74 20 61 66 74 65 72 20 61 6c 6c 20 62 61 63 6b  t after all back
4260: 66 69 6c 6c 69 6e 67 20 63 6f 6d 70 6c 65 74 65  filling complete
4270: 73 2e 20 20 53 6f 20 69 66 20 61 20 63 68 65 63  s.  So if a chec
4280: 6b 70 6f 69 6e 74 0a 2a 2a 20 63 72 61 73 68 65  kpoint.** crashe
4290: 73 2c 20 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65  s, nBackfillAtte
42a0: 6d 70 74 65 64 20 6d 69 67 68 74 20 62 65 20 6c  mpted might be l
42b0: 61 72 67 65 72 20 74 68 61 6e 20 6e 42 61 63 6b  arger than nBack
42c0: 66 69 6c 6c 2e 20 20 54 68 65 0a 2a 2a 20 57 61  fill.  The.** Wa
42d0: 6c 49 6e 64 65 78 48 64 72 2e 6d 78 46 72 61 6d  lIndexHdr.mxFram
42e0: 65 20 6d 75 73 74 20 6e 65 76 65 72 20 62 65 20  e must never be 
42f0: 6c 65 73 73 20 74 68 61 6e 20 6e 42 61 63 6b 66  less than nBackf
4300: 69 6c 6c 41 74 74 65 6d 70 74 65 64 2e 0a 2a 2a  illAttempted..**
4310: 0a 2a 2a 20 54 68 65 20 61 4c 6f 63 6b 5b 5d 20  .** The aLock[] 
4320: 66 69 65 6c 64 20 69 73 20 61 20 73 65 74 20 6f  field is a set o
4330: 66 20 62 79 74 65 73 20 75 73 65 64 20 66 6f 72  f bytes used for
4340: 20 6c 6f 63 6b 69 6e 67 2e 20 20 54 68 65 73 65   locking.  These
4350: 20 62 79 74 65 73 20 73 68 6f 75 6c 64 0a 2a 2a   bytes should.**
4360: 20 6e 65 76 65 72 20 62 65 20 72 65 61 64 20 6f   never be read o
4370: 72 20 77 72 69 74 74 65 6e 2e 0a 2a 2a 0a 2a 2a  r written..**.**
4380: 20 54 68 65 72 65 20 69 73 20 6f 6e 65 20 65 6e   There is one en
4390: 74 72 79 20 69 6e 20 61 52 65 61 64 4d 61 72 6b  try in aReadMark
43a0: 5b 5d 20 66 6f 72 20 65 61 63 68 20 72 65 61 64  [] for each read
43b0: 65 72 20 6c 6f 63 6b 2e 20 20 49 66 20 61 20 72  er lock.  If a r
43c0: 65 61 64 65 72 0a 2a 2a 20 68 6f 6c 64 73 20 72  eader.** holds r
43d0: 65 61 64 2d 6c 6f 63 6b 20 4b 2c 20 74 68 65 6e  ead-lock K, then
43e0: 20 74 68 65 20 76 61 6c 75 65 20 69 6e 20 61 52   the value in aR
43f0: 65 61 64 4d 61 72 6b 5b 4b 5d 20 69 73 20 6e 6f  eadMark[K] is no
4400: 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a   greater than.**
4410: 20 74 68 65 20 6d 78 46 72 61 6d 65 20 66 6f 72   the mxFrame for
4420: 20 74 68 61 74 20 72 65 61 64 65 72 2e 20 20 54   that reader.  T
4430: 68 65 20 76 61 6c 75 65 20 52 45 41 44 4d 41 52  he value READMAR
4440: 4b 5f 4e 4f 54 5f 55 53 45 44 20 28 30 78 66 66  K_NOT_USED (0xff
4450: 66 66 66 66 66 66 29 0a 2a 2a 20 66 6f 72 20 61  ffffff).** for a
4460: 6e 79 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 6d  ny aReadMark[] m
4470: 65 61 6e 73 20 74 68 61 74 20 65 6e 74 72 79 20  eans that entry 
4480: 69 73 20 75 6e 75 73 65 64 2e 20 20 61 52 65 61  is unused.  aRea
4490: 64 4d 61 72 6b 5b 30 5d 20 69 73 20 0a 2a 2a 20  dMark[0] is .** 
44a0: 61 20 73 70 65 63 69 61 6c 20 63 61 73 65 3b 20  a special case; 
44b0: 69 74 73 20 76 61 6c 75 65 20 69 73 20 6e 65 76  its value is nev
44c0: 65 72 20 75 73 65 64 20 61 6e 64 20 69 74 20 65  er used and it e
44d0: 78 69 73 74 73 20 61 73 20 61 20 70 6c 61 63 65  xists as a place
44e0: 2d 68 6f 6c 64 65 72 0a 2a 2a 20 74 6f 20 61 76  -holder.** to av
44f0: 6f 69 64 20 68 61 76 69 6e 67 20 74 6f 20 6f 66  oid having to of
4500: 66 73 65 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d  fset aReadMark[]
4510: 20 69 6e 64 65 78 73 20 62 79 20 6f 6e 65 2e 20   indexs by one. 
4520: 20 52 65 61 64 65 72 73 20 68 6f 6c 64 69 6e 67   Readers holding
4530: 0a 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  .** WAL_READ_LOC
4540: 4b 28 30 29 20 61 6c 77 61 79 73 20 69 67 6e 6f  K(0) always igno
4550: 72 65 20 74 68 65 20 65 6e 74 69 72 65 20 57 41  re the entire WA
4560: 4c 20 61 6e 64 20 72 65 61 64 20 61 6c 6c 20 63  L and read all c
4570: 6f 6e 74 65 6e 74 0a 2a 2a 20 64 69 72 65 63 74  ontent.** direct
4580: 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61 74 61  ly from the data
4590: 62 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  base..**.** The 
45a0: 76 61 6c 75 65 20 6f 66 20 61 52 65 61 64 4d 61  value of aReadMa
45b0: 72 6b 5b 4b 5d 20 6d 61 79 20 6f 6e 6c 79 20 62  rk[K] may only b
45c0: 65 20 63 68 61 6e 67 65 64 20 62 79 20 61 20 74  e changed by a t
45d0: 68 72 65 61 64 20 74 68 61 74 0a 2a 2a 20 69 73  hread that.** is
45e0: 20 68 6f 6c 64 69 6e 67 20 61 6e 20 65 78 63 6c   holding an excl
45f0: 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 57 41  usive lock on WA
4600: 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 4b 29 2e 20  L_READ_LOCK(K). 
4610: 20 54 68 75 73 2c 20 74 68 65 20 76 61 6c 75 65   Thus, the value
4620: 20 6f 66 0a 2a 2a 20 61 52 65 61 64 4d 61 72 6b   of.** aReadMark
4630: 5b 4b 5d 20 63 61 6e 6e 6f 74 20 63 68 61 6e 67  [K] cannot chang
4640: 65 64 20 77 68 69 6c 65 20 74 68 65 72 65 20 69  ed while there i
4650: 73 20 61 20 72 65 61 64 65 72 20 69 73 20 75 73  s a reader is us
4660: 69 6e 67 20 74 68 61 74 20 6d 61 72 6b 0a 2a 2a  ing that mark.**
4670: 20 73 69 6e 63 65 20 74 68 65 20 72 65 61 64 65   since the reade
4680: 72 20 77 69 6c 6c 20 62 65 20 68 6f 6c 64 69 6e  r will be holdin
4690: 67 20 61 20 73 68 61 72 65 64 20 6c 6f 63 6b 20  g a shared lock 
46a0: 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  on WAL_READ_LOCK
46b0: 28 4b 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63  (K)..**.** The c
46c0: 68 65 63 6b 70 6f 69 6e 74 65 72 20 6d 61 79 20  heckpointer may 
46d0: 6f 6e 6c 79 20 74 72 61 6e 73 66 65 72 20 66 72  only transfer fr
46e0: 61 6d 65 73 20 66 72 6f 6d 20 57 41 4c 20 74 6f  ames from WAL to
46f0: 20 64 61 74 61 62 61 73 65 20 77 68 65 72 65 0a   database where.
4700: 2a 2a 20 74 68 65 20 66 72 61 6d 65 20 6e 75 6d  ** the frame num
4710: 62 65 72 73 20 61 72 65 20 6c 65 73 73 20 74 68  bers are less th
4720: 61 6e 20 6f 72 20 65 71 75 61 6c 20 74 6f 20 65  an or equal to e
4730: 76 65 72 79 20 61 52 65 61 64 4d 61 72 6b 5b 5d  very aReadMark[]
4740: 20 74 68 61 74 20 69 73 0a 2a 2a 20 69 6e 20 75   that is.** in u
4750: 73 65 20 28 74 68 61 74 20 69 73 2c 20 65 76 65  se (that is, eve
4760: 72 79 20 61 52 65 61 64 4d 61 72 6b 5b 6a 5d 20  ry aReadMark[j] 
4770: 66 6f 72 20 77 68 69 63 68 20 74 68 65 72 65 20  for which there 
4780: 69 73 20 61 20 63 6f 72 72 65 73 70 6f 6e 64 69  is a correspondi
4790: 6e 67 0a 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c  ng.** WAL_READ_L
47a0: 4f 43 4b 28 6a 29 29 2e 20 20 4e 65 77 20 72 65  OCK(j)).  New re
47b0: 61 64 65 72 73 20 28 75 73 75 61 6c 6c 79 29 20  aders (usually) 
47c0: 70 69 63 6b 20 74 68 65 20 61 52 65 61 64 4d 61  pick the aReadMa
47d0: 72 6b 5b 5d 20 77 69 74 68 20 74 68 65 0a 2a 2a  rk[] with the.**
47e0: 20 6c 61 72 67 65 73 74 20 76 61 6c 75 65 20 61   largest value a
47f0: 6e 64 20 77 69 6c 6c 20 69 6e 63 72 65 61 73 65  nd will increase
4800: 20 61 6e 20 75 6e 75 73 65 64 20 61 52 65 61 64   an unused aRead
4810: 4d 61 72 6b 5b 5d 20 74 6f 20 6d 78 46 72 61 6d  Mark[] to mxFram
4820: 65 20 69 66 20 74 68 65 72 65 0a 2a 2a 20 69 73  e if there.** is
4830: 20 6e 6f 74 20 61 6c 72 65 61 64 79 20 61 6e 20   not already an 
4840: 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65 71 75 61  aReadMark[] equa
4850: 6c 20 74 6f 20 6d 78 46 72 61 6d 65 2e 20 20 54  l to mxFrame.  T
4860: 68 65 20 65 78 63 65 70 74 69 6f 6e 20 74 6f 20  he exception to 
4870: 74 68 65 0a 2a 2a 20 70 72 65 76 69 6f 75 73 20  the.** previous 
4880: 73 65 6e 74 65 6e 63 65 20 69 73 20 77 68 65 6e  sentence is when
4890: 20 6e 42 61 63 6b 66 69 6c 6c 20 65 71 75 61 6c   nBackfill equal
48a0: 73 20 6d 78 46 72 61 6d 65 20 28 6d 65 61 6e 69  s mxFrame (meani
48b0: 6e 67 20 74 68 61 74 20 65 76 65 72 79 74 68 69  ng that everythi
48c0: 6e 67 0a 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c  ng.** in the WAL
48d0: 20 68 61 73 20 62 65 65 6e 20 62 61 63 6b 66 69   has been backfi
48e0: 6c 6c 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61  lled into the da
48f0: 74 61 62 61 73 65 29 20 74 68 65 6e 20 6e 65 77  tabase) then new
4900: 20 72 65 61 64 65 72 73 0a 2a 2a 20 77 69 6c 6c   readers.** will
4910: 20 63 68 6f 6f 73 65 20 61 52 65 61 64 4d 61 72   choose aReadMar
4920: 6b 5b 30 5d 20 77 68 69 63 68 20 68 61 73 20 76  k[0] which has v
4930: 61 6c 75 65 20 30 20 61 6e 64 20 68 65 6e 63 65  alue 0 and hence
4940: 20 73 75 63 68 20 72 65 61 64 65 72 20 77 69 6c   such reader wil
4950: 6c 0a 2a 2a 20 67 65 74 20 61 6c 6c 20 74 68 65  l.** get all the
4960: 69 72 20 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 64  ir all content d
4970: 69 72 65 63 74 6c 79 20 66 72 6f 6d 20 74 68 65  irectly from the
4980: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 61   database file a
4990: 6e 64 20 69 67 6e 6f 72 65 20 0a 2a 2a 20 74 68  nd ignore .** th
49a0: 65 20 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20 57 72 69  e WAL..**.** Wri
49b0: 74 65 72 73 20 6e 6f 72 6d 61 6c 6c 79 20 61 70  ters normally ap
49c0: 70 65 6e 64 20 6e 65 77 20 66 72 61 6d 65 73 20  pend new frames 
49d0: 74 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68  to the end of th
49e0: 65 20 57 41 4c 2e 20 20 48 6f 77 65 76 65 72 2c  e WAL.  However,
49f0: 0a 2a 2a 20 69 66 20 6e 42 61 63 6b 66 69 6c 6c  .** if nBackfill
4a00: 20 65 71 75 61 6c 73 20 6d 78 46 72 61 6d 65 20   equals mxFrame 
4a10: 28 6d 65 61 6e 69 6e 67 20 74 68 61 74 20 61 6c  (meaning that al
4a20: 6c 20 57 41 4c 20 63 6f 6e 74 65 6e 74 20 68 61  l WAL content ha
4a30: 73 20 62 65 65 6e 0a 2a 2a 20 77 72 69 74 74 65  s been.** writte
4a40: 6e 20 62 61 63 6b 20 69 6e 74 6f 20 74 68 65 20  n back into the 
4a50: 64 61 74 61 62 61 73 65 29 20 61 6e 64 20 69 66  database) and if
4a60: 20 6e 6f 20 72 65 61 64 65 72 73 20 61 72 65 20   no readers are 
4a70: 75 73 69 6e 67 20 74 68 65 20 57 41 4c 0a 2a 2a  using the WAL.**
4a80: 20 28 69 6e 20 6f 74 68 65 72 20 77 6f 72 64 73   (in other words
4a90: 2c 20 69 66 20 74 68 65 72 65 20 61 72 65 20 6e  , if there are n
4aa0: 6f 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  o WAL_READ_LOCK(
4ab0: 69 29 20 77 68 65 72 65 20 69 3e 30 29 20 74 68  i) where i>0) th
4ac0: 65 6e 0a 2a 2a 20 74 68 65 20 77 72 69 74 65 72  en.** the writer
4ad0: 20 77 69 6c 6c 20 66 69 72 73 74 20 22 72 65 73   will first "res
4ae0: 65 74 22 20 74 68 65 20 57 41 4c 20 62 61 63 6b  et" the WAL back
4af0: 20 74 6f 20 74 68 65 20 62 65 67 69 6e 6e 69 6e   to the beginnin
4b00: 67 20 61 6e 64 20 73 74 61 72 74 0a 2a 2a 20 77  g and start.** w
4b10: 72 69 74 69 6e 67 20 6e 65 77 20 63 6f 6e 74 65  riting new conte
4b20: 6e 74 20 62 65 67 69 6e 6e 69 6e 67 20 61 74 20  nt beginning at 
4b30: 66 72 61 6d 65 20 31 2e 0a 2a 2a 0a 2a 2a 20 57  frame 1..**.** W
4b40: 65 20 61 73 73 75 6d 65 20 74 68 61 74 20 33 32  e assume that 32
4b50: 2d 62 69 74 20 6c 6f 61 64 73 20 61 72 65 20 61  -bit loads are a
4b60: 74 6f 6d 69 63 20 61 6e 64 20 73 6f 20 6e 6f 20  tomic and so no 
4b70: 6c 6f 63 6b 73 20 61 72 65 20 6e 65 65 64 65 64  locks are needed
4b80: 20 69 6e 0a 2a 2a 20 6f 72 64 65 72 20 74 6f 20   in.** order to 
4b90: 72 65 61 64 20 66 72 6f 6d 20 61 6e 79 20 61 52  read from any aR
4ba0: 65 61 64 4d 61 72 6b 5b 5d 20 65 6e 74 72 69 65  eadMark[] entrie
4bb0: 73 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61 6c  s..*/.struct Wal
4bc0: 43 6b 70 74 49 6e 66 6f 20 7b 0a 20 20 75 33 32  CkptInfo {.  u32
4bd0: 20 6e 42 61 63 6b 66 69 6c 6c 3b 20 20 20 20 20   nBackfill;     
4be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4bf0: 4e 75 6d 62 65 72 20 6f 66 20 57 41 4c 20 66 72  Number of WAL fr
4c00: 61 6d 65 73 20 62 61 63 6b 66 69 6c 6c 65 64 20  ames backfilled 
4c10: 69 6e 74 6f 20 44 42 20 2a 2f 0a 20 20 75 33 32  into DB */.  u32
4c20: 20 61 52 65 61 64 4d 61 72 6b 5b 57 41 4c 5f 4e   aReadMark[WAL_N
4c30: 52 45 41 44 45 52 5d 3b 20 20 20 20 20 2f 2a 20  READER];     /* 
4c40: 52 65 61 64 65 72 20 6d 61 72 6b 73 20 2a 2f 0a  Reader marks */.
4c50: 20 20 75 38 20 61 4c 6f 63 6b 5b 53 51 4c 49 54    u8 aLock[SQLIT
4c60: 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 5d 3b 20 20 20  E_SHM_NLOCK];   
4c70: 20 20 2f 2a 20 52 65 73 65 72 76 65 64 20 73 70    /* Reserved sp
4c80: 61 63 65 20 66 6f 72 20 6c 6f 63 6b 73 20 2a 2f  ace for locks */
4c90: 0a 20 20 75 33 32 20 6e 42 61 63 6b 66 69 6c 6c  .  u32 nBackfill
4ca0: 41 74 74 65 6d 70 74 65 64 3b 20 20 20 20 20 20  Attempted;      
4cb0: 20 20 20 2f 2a 20 57 41 4c 20 66 72 61 6d 65 73     /* WAL frames
4cc0: 20 70 65 72 68 61 70 73 20 77 72 69 74 74 65 6e   perhaps written
4cd0: 2c 20 6f 72 20 6d 61 79 62 65 20 6e 6f 74 20 2a  , or maybe not *
4ce0: 2f 0a 20 20 75 33 32 20 6e 6f 74 55 73 65 64 30  /.  u32 notUsed0
4cf0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4d00: 20 20 20 20 2f 2a 20 41 76 61 69 6c 61 62 6c 65      /* Available
4d10: 20 66 6f 72 20 66 75 74 75 72 65 20 65 6e 68 61   for future enha
4d20: 6e 63 65 6d 65 6e 74 73 20 2a 2f 0a 7d 3b 0a 23  ncements */.};.#
4d30: 64 65 66 69 6e 65 20 52 45 41 44 4d 41 52 4b 5f  define READMARK_
4d40: 4e 4f 54 5f 55 53 45 44 20 20 30 78 66 66 66 66  NOT_USED  0xffff
4d50: 66 66 66 66 0a 0a 0a 2f 2a 20 41 20 62 6c 6f 63  ffff.../* A bloc
4d60: 6b 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 4c 4f  k of WALINDEX_LO
4d70: 43 4b 5f 52 45 53 45 52 56 45 44 20 62 79 74 65  CK_RESERVED byte
4d80: 73 20 62 65 67 69 6e 6e 69 6e 67 20 61 74 0a 2a  s beginning at.*
4d90: 2a 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f  * WALINDEX_LOCK_
4da0: 4f 46 46 53 45 54 20 69 73 20 72 65 73 65 72 76  OFFSET is reserv
4db0: 65 64 20 66 6f 72 20 6c 6f 63 6b 73 2e 20 53 69  ed for locks. Si
4dc0: 6e 63 65 20 73 6f 6d 65 20 73 79 73 74 65 6d 73  nce some systems
4dd0: 0a 2a 2a 20 6f 6e 6c 79 20 73 75 70 70 6f 72 74  .** only support
4de0: 20 6d 61 6e 64 61 74 6f 72 79 20 66 69 6c 65 2d   mandatory file-
4df0: 6c 6f 63 6b 73 2c 20 77 65 20 64 6f 20 6e 6f 74  locks, we do not
4e00: 20 72 65 61 64 20 6f 72 20 77 72 69 74 65 20 64   read or write d
4e10: 61 74 61 0a 2a 2a 20 66 72 6f 6d 20 74 68 65 20  ata.** from the 
4e20: 72 65 67 69 6f 6e 20 6f 66 20 74 68 65 20 66 69  region of the fi
4e30: 6c 65 20 6f 6e 20 77 68 69 63 68 20 6c 6f 63 6b  le on which lock
4e40: 73 20 61 72 65 20 61 70 70 6c 69 65 64 2e 0a 2a  s are applied..*
4e50: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44  /.#define WALIND
4e60: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 28  EX_LOCK_OFFSET (
4e70: 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48  sizeof(WalIndexH
4e80: 64 72 29 2a 32 2b 6f 66 66 73 65 74 6f 66 28 57  dr)*2+offsetof(W
4e90: 61 6c 43 6b 70 74 49 6e 66 6f 2c 61 4c 6f 63 6b  alCkptInfo,aLock
4ea0: 29 29 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e  )).#define WALIN
4eb0: 44 45 58 5f 48 44 52 5f 53 49 5a 45 20 20 20 20  DEX_HDR_SIZE    
4ec0: 28 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78  (sizeof(WalIndex
4ed0: 48 64 72 29 2a 32 2b 73 69 7a 65 6f 66 28 57 61  Hdr)*2+sizeof(Wa
4ee0: 6c 43 6b 70 74 49 6e 66 6f 29 29 0a 0a 2f 2a 20  lCkptInfo))../* 
4ef0: 53 69 7a 65 20 6f 66 20 68 65 61 64 65 72 20 62  Size of header b
4f00: 65 66 6f 72 65 20 65 61 63 68 20 66 72 61 6d 65  efore each frame
4f10: 20 69 6e 20 77 61 6c 20 2a 2f 0a 23 64 65 66 69   in wal */.#defi
4f20: 6e 65 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52  ne WAL_FRAME_HDR
4f30: 53 49 5a 45 20 32 34 0a 0a 2f 2a 20 53 69 7a 65  SIZE 24../* Size
4f40: 20 6f 66 20 77 72 69 74 65 20 61 68 65 61 64 20   of write ahead 
4f50: 6c 6f 67 20 68 65 61 64 65 72 2c 20 69 6e 63 6c  log header, incl
4f60: 75 64 69 6e 67 20 63 68 65 63 6b 73 75 6d 2e 20  uding checksum. 
4f70: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48  */.#define WAL_H
4f80: 44 52 53 49 5a 45 20 33 32 0a 0a 2f 2a 20 57 41  DRSIZE 32../* WA
4f90: 4c 20 6d 61 67 69 63 20 76 61 6c 75 65 2e 20 45  L magic value. E
4fa0: 69 74 68 65 72 20 74 68 69 73 20 76 61 6c 75 65  ither this value
4fb0: 2c 20 6f 72 20 74 68 65 20 73 61 6d 65 20 76 61  , or the same va
4fc0: 6c 75 65 20 77 69 74 68 20 74 68 65 20 6c 65 61  lue with the lea
4fd0: 73 74 0a 2a 2a 20 73 69 67 6e 69 66 69 63 61 6e  st.** significan
4fe0: 74 20 62 69 74 20 61 6c 73 6f 20 73 65 74 20 28  t bit also set (
4ff0: 57 41 4c 5f 4d 41 47 49 43 20 7c 20 30 78 30 30  WAL_MAGIC | 0x00
5000: 30 30 30 30 30 31 29 20 69 73 20 73 74 6f 72 65  000001) is store
5010: 64 20 69 6e 20 33 32 2d 62 69 74 0a 2a 2a 20 62  d in 32-bit.** b
5020: 69 67 2d 65 6e 64 69 61 6e 20 66 6f 72 6d 61 74  ig-endian format
5030: 20 69 6e 20 74 68 65 20 66 69 72 73 74 20 34 20   in the first 4 
5040: 62 79 74 65 73 20 6f 66 20 61 20 57 41 4c 20 66  bytes of a WAL f
5050: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ile..**.** If th
5060: 65 20 4c 53 42 20 69 73 20 73 65 74 2c 20 74 68  e LSB is set, th
5070: 65 6e 20 74 68 65 20 63 68 65 63 6b 73 75 6d 73  en the checksums
5080: 20 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65 20   for each frame 
5090: 77 69 74 68 69 6e 20 74 68 65 20 57 41 4c 0a 2a  within the WAL.*
50a0: 2a 20 66 69 6c 65 20 61 72 65 20 63 61 6c 63 75  * file are calcu
50b0: 6c 61 74 65 64 20 62 79 20 74 72 65 61 74 69 6e  lated by treatin
50c0: 67 20 61 6c 6c 20 64 61 74 61 20 61 73 20 61 6e  g all data as an
50d0: 20 61 72 72 61 79 20 6f 66 20 33 32 2d 62 69 74   array of 32-bit
50e0: 20 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20   .** big-endian 
50f0: 77 6f 72 64 73 2e 20 4f 74 68 65 72 77 69 73 65  words. Otherwise
5100: 2c 20 74 68 65 79 20 61 72 65 20 63 61 6c 63 75  , they are calcu
5110: 6c 61 74 65 64 20 62 79 20 69 6e 74 65 72 70 72  lated by interpr
5120: 65 74 69 6e 67 20 0a 2a 2a 20 61 6c 6c 20 64 61  eting .** all da
5130: 74 61 20 61 73 20 33 32 2d 62 69 74 20 6c 69 74  ta as 32-bit lit
5140: 74 6c 65 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73  tle-endian words
5150: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c  ..*/.#define WAL
5160: 5f 4d 41 47 49 43 20 30 78 33 37 37 66 30 36 38  _MAGIC 0x377f068
5170: 32 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  2../*.** Return 
5180: 74 68 65 20 6f 66 66 73 65 74 20 6f 66 20 66 72  the offset of fr
5190: 61 6d 65 20 69 46 72 61 6d 65 20 69 6e 20 74 68  ame iFrame in th
51a0: 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f  e write-ahead lo
51b0: 67 20 66 69 6c 65 2c 20 0a 2a 2a 20 61 73 73 75  g file, .** assu
51c0: 6d 69 6e 67 20 61 20 64 61 74 61 62 61 73 65 20  ming a database 
51d0: 70 61 67 65 20 73 69 7a 65 20 6f 66 20 73 7a 50  page size of szP
51e0: 61 67 65 20 62 79 74 65 73 2e 20 54 68 65 20 6f  age bytes. The o
51f0: 66 66 73 65 74 20 72 65 74 75 72 6e 65 64 0a 2a  ffset returned.*
5200: 2a 20 69 73 20 74 6f 20 74 68 65 20 73 74 61 72  * is to the star
5210: 74 20 6f 66 20 74 68 65 20 77 72 69 74 65 2d 61  t of the write-a
5220: 68 65 61 64 20 6c 6f 67 20 66 72 61 6d 65 2d 68  head log frame-h
5230: 65 61 64 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e  eader..*/.#defin
5240: 65 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74  e walFrameOffset
5250: 28 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29  (iFrame, szPage)
5260: 20 28 20 20 20 20 20 20 20 20 20 20 20 20 20 20   (              
5270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5280: 20 5c 0a 20 20 57 41 4c 5f 48 44 52 53 49 5a 45   \.  WAL_HDRSIZE
5290: 20 2b 20 28 28 69 46 72 61 6d 65 29 2d 31 29 2a   + ((iFrame)-1)*
52a0: 28 69 36 34 29 28 28 73 7a 50 61 67 65 29 2b 57  (i64)((szPage)+W
52b0: 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
52c0: 29 20 20 20 20 20 20 20 20 20 5c 0a 29 0a 0a 2f  )         \.)../
52d0: 2a 0a 2a 2a 20 41 6e 20 6f 70 65 6e 20 77 72 69  *.** An open wri
52e0: 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c  te-ahead log fil
52f0: 65 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64  e is represented
5300: 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   by an instance 
5310: 6f 66 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c 6f 77  of the.** follow
5320: 69 6e 67 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73  ing object..*/.s
5330: 74 72 75 63 74 20 57 61 6c 20 7b 0a 20 20 73 71  truct Wal {.  sq
5340: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 3b  lite3_vfs *pVfs;
5350: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
5360: 56 46 53 20 75 73 65 64 20 74 6f 20 63 72 65 61  VFS used to crea
5370: 74 65 20 70 44 62 46 64 20 2a 2f 0a 20 20 73 71  te pDbFd */.  sq
5380: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 44 62 46  lite3_file *pDbF
5390: 64 3b 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65  d;       /* File
53a0: 20 68 61 6e 64 6c 65 20 66 6f 72 20 74 68 65 20   handle for the 
53b0: 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f  database file */
53c0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
53d0: 2a 70 57 61 6c 46 64 3b 20 20 20 20 20 20 2f 2a  *pWalFd;      /*
53e0: 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 66 6f 72   File handle for
53f0: 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 75   WAL file */.  u
5400: 33 32 20 69 43 61 6c 6c 62 61 63 6b 3b 20 20 20  32 iCallback;   
5410: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
5420: 75 65 20 74 6f 20 70 61 73 73 20 74 6f 20 6c 6f  ue to pass to lo
5430: 67 20 63 61 6c 6c 62 61 63 6b 20 28 6f 72 20 30  g callback (or 0
5440: 29 20 2a 2f 0a 20 20 69 36 34 20 6d 78 57 61 6c  ) */.  i64 mxWal
5450: 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20  Size;           
5460: 20 20 2f 2a 20 54 72 75 6e 63 61 74 65 20 57 41    /* Truncate WA
5470: 4c 20 74 6f 20 74 68 69 73 20 73 69 7a 65 20 75  L to this size u
5480: 70 6f 6e 20 72 65 73 65 74 20 2a 2f 0a 20 20 69  pon reset */.  i
5490: 6e 74 20 6e 57 69 44 61 74 61 3b 20 20 20 20 20  nt nWiData;     
54a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
54b0: 65 20 6f 66 20 61 72 72 61 79 20 61 70 57 69 44  e of array apWiD
54c0: 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 46  ata */.  int szF
54d0: 69 72 73 74 42 6c 6f 63 6b 3b 20 20 20 20 20 20  irstBlock;      
54e0: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 66      /* Size of f
54f0: 69 72 73 74 20 62 6c 6f 63 6b 20 77 72 69 74 74  irst block writt
5500: 65 6e 20 74 6f 20 57 41 4c 20 66 69 6c 65 20 2a  en to WAL file *
5510: 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32  /.  volatile u32
5520: 20 2a 2a 61 70 57 69 44 61 74 61 3b 20 20 20 2f   **apWiData;   /
5530: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 61 6c  * Pointer to wal
5540: 2d 69 6e 64 65 78 20 63 6f 6e 74 65 6e 74 20 69  -index content i
5550: 6e 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 75 33  n memory */.  u3
5560: 32 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20  2 szPage;       
5570: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
5580: 62 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 2a  base page size *
5590: 2f 0a 20 20 69 31 36 20 72 65 61 64 4c 6f 63 6b  /.  i16 readLock
55a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
55b0: 2a 20 57 68 69 63 68 20 72 65 61 64 20 6c 6f 63  * Which read loc
55c0: 6b 20 69 73 20 62 65 69 6e 67 20 68 65 6c 64 2e  k is being held.
55d0: 20 20 2d 31 20 66 6f 72 20 6e 6f 6e 65 20 2a 2f    -1 for none */
55e0: 0a 20 20 75 38 20 73 79 6e 63 46 6c 61 67 73 3b  .  u8 syncFlags;
55f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5600: 20 46 6c 61 67 73 20 74 6f 20 75 73 65 20 74 6f   Flags to use to
5610: 20 73 79 6e 63 20 68 65 61 64 65 72 20 77 72 69   sync header wri
5620: 74 65 73 20 2a 2f 0a 20 20 75 38 20 65 78 63 6c  tes */.  u8 excl
5630: 75 73 69 76 65 4d 6f 64 65 3b 20 20 20 20 20 20  usiveMode;      
5640: 20 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20      /* Non-zero 
5650: 69 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73  if connection is
5660: 20 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f   in exclusive mo
5670: 64 65 20 2a 2f 0a 20 20 75 38 20 77 72 69 74 65  de */.  u8 write
5680: 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Lock;           
5690: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e     /* True if in
56a0: 20 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63   a write transac
56b0: 74 69 6f 6e 20 2a 2f 0a 20 20 75 38 20 63 6b 70  tion */.  u8 ckp
56c0: 74 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20  tLock;          
56d0: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
56e0: 68 6f 6c 64 69 6e 67 20 61 20 63 68 65 63 6b 70  holding a checkp
56f0: 6f 69 6e 74 20 6c 6f 63 6b 20 2a 2f 0a 20 20 75  oint lock */.  u
5700: 38 20 72 65 61 64 4f 6e 6c 79 3b 20 20 20 20 20  8 readOnly;     
5710: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c            /* WAL
5720: 5f 52 44 57 52 2c 20 57 41 4c 5f 52 44 4f 4e 4c  _RDWR, WAL_RDONL
5730: 59 2c 20 6f 72 20 57 41 4c 5f 53 48 4d 5f 52 44  Y, or WAL_SHM_RD
5740: 4f 4e 4c 59 20 2a 2f 0a 20 20 75 38 20 74 72 75  ONLY */.  u8 tru
5750: 6e 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 3b 20 20  ncateOnCommit;  
5760: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20       /* True to 
5770: 74 72 75 6e 63 61 74 65 20 57 41 4c 20 66 69 6c  truncate WAL fil
5780: 65 20 6f 6e 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20  e on commit */. 
5790: 20 75 38 20 73 79 6e 63 48 65 61 64 65 72 3b 20   u8 syncHeader; 
57a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
57b0: 73 79 6e 63 20 74 68 65 20 57 41 4c 20 68 65 61  sync the WAL hea
57c0: 64 65 72 20 69 66 20 74 72 75 65 20 2a 2f 0a 20  der if true */. 
57d0: 20 75 38 20 70 61 64 54 6f 53 65 63 74 6f 72 42   u8 padToSectorB
57e0: 6f 75 6e 64 61 72 79 3b 20 20 20 20 2f 2a 20 50  oundary;    /* P
57f0: 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 20  ad transactions 
5800: 6f 75 74 20 74 6f 20 74 68 65 20 6e 65 78 74 20  out to the next 
5810: 73 65 63 74 6f 72 20 2a 2f 0a 20 20 75 38 20 62  sector */.  u8 b
5820: 53 68 6d 55 6e 72 65 6c 69 61 62 6c 65 3b 20 20  ShmUnreliable;  
5830: 20 20 20 20 20 20 20 2f 2a 20 53 48 4d 20 63 6f         /* SHM co
5840: 6e 74 65 6e 74 20 69 73 20 72 65 61 64 2d 6f 6e  ntent is read-on
5850: 6c 79 20 61 6e 64 20 75 6e 72 65 6c 69 61 62 6c  ly and unreliabl
5860: 65 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65 78 48  e */.  WalIndexH
5870: 64 72 20 68 64 72 3b 20 20 20 20 20 20 20 20 20  dr hdr;         
5880: 20 20 2f 2a 20 57 61 6c 2d 69 6e 64 65 78 20 68    /* Wal-index h
5890: 65 61 64 65 72 20 66 6f 72 20 63 75 72 72 65 6e  eader for curren
58a0: 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f  t transaction */
58b0: 0a 20 20 75 33 32 20 6d 69 6e 46 72 61 6d 65 3b  .  u32 minFrame;
58c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
58d0: 20 49 67 6e 6f 72 65 20 77 61 6c 20 66 72 61 6d   Ignore wal fram
58e0: 65 73 20 62 65 66 6f 72 65 20 74 68 69 73 20 6f  es before this o
58f0: 6e 65 20 2a 2f 0a 20 20 75 33 32 20 69 52 65 43  ne */.  u32 iReC
5900: 6b 73 75 6d 3b 20 20 20 20 20 20 20 20 20 20 20  ksum;           
5910: 20 20 20 2f 2a 20 4f 6e 20 63 6f 6d 6d 69 74 2c     /* On commit,
5920: 20 72 65 63 61 6c 63 75 6c 61 74 65 20 63 68 65   recalculate che
5930: 63 6b 73 75 6d 73 20 66 72 6f 6d 20 68 65 72 65  cksums from here
5940: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
5950: 20 2a 7a 57 61 6c 4e 61 6d 65 3b 20 20 20 20 20   *zWalName;     
5960: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 57 41 4c 20   /* Name of WAL 
5970: 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32 20 6e 43  file */.  u32 nC
5980: 6b 70 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  kpt;            
5990: 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 70 6f 69       /* Checkpoi
59a0: 6e 74 20 73 65 71 75 65 6e 63 65 20 63 6f 75 6e  nt sequence coun
59b0: 74 65 72 20 69 6e 20 74 68 65 20 77 61 6c 2d 68  ter in the wal-h
59c0: 65 61 64 65 72 20 2a 2f 0a 23 69 66 64 65 66 20  eader */.#ifdef 
59d0: 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 75  SQLITE_DEBUG.  u
59e0: 38 20 6c 6f 63 6b 45 72 72 6f 72 3b 20 20 20 20  8 lockError;    
59f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
5a00: 65 20 69 66 20 61 20 6c 6f 63 6b 69 6e 67 20 65  e if a locking e
5a10: 72 72 6f 72 20 68 61 73 20 6f 63 63 75 72 72 65  rror has occurre
5a20: 64 20 2a 2f 0a 23 65 6e 64 69 66 0a 23 69 66 64  d */.#endif.#ifd
5a30: 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45  ef SQLITE_ENABLE
5a40: 5f 53 4e 41 50 53 48 4f 54 0a 20 20 57 61 6c 49  _SNAPSHOT.  WalI
5a50: 6e 64 65 78 48 64 72 20 2a 70 53 6e 61 70 73 68  ndexHdr *pSnapsh
5a60: 6f 74 3b 20 20 20 20 2f 2a 20 53 74 61 72 74 20  ot;    /* Start 
5a70: 74 72 61 6e 73 61 63 74 69 6f 6e 20 68 65 72 65  transaction here
5a80: 20 69 66 20 6e 6f 74 20 4e 55 4c 4c 20 2a 2f 0a   if not NULL */.
5a90: 23 65 6e 64 69 66 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  #endif.};../*.**
5aa0: 20 43 61 6e 64 69 64 61 74 65 20 76 61 6c 75 65   Candidate value
5ab0: 73 20 66 6f 72 20 57 61 6c 2e 65 78 63 6c 75 73  s for Wal.exclus
5ac0: 69 76 65 4d 6f 64 65 2e 0a 2a 2f 0a 23 64 65 66  iveMode..*/.#def
5ad0: 69 6e 65 20 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d  ine WAL_NORMAL_M
5ae0: 4f 44 45 20 20 20 20 20 30 0a 23 64 65 66 69 6e  ODE     0.#defin
5af0: 65 20 57 41 4c 5f 45 58 43 4c 55 53 49 56 45 5f  e WAL_EXCLUSIVE_
5b00: 4d 4f 44 45 20 20 31 20 20 20 20 20 0a 23 64 65  MODE  1     .#de
5b10: 66 69 6e 65 20 57 41 4c 5f 48 45 41 50 4d 45 4d  fine WAL_HEAPMEM
5b20: 4f 52 59 5f 4d 4f 44 45 20 32 0a 0a 2f 2a 0a 2a  ORY_MODE 2../*.*
5b30: 2a 20 50 6f 73 73 69 62 6c 65 20 76 61 6c 75 65  * Possible value
5b40: 73 20 66 6f 72 20 57 41 4c 2e 72 65 61 64 4f 6e  s for WAL.readOn
5b50: 6c 79 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41  ly.*/.#define WA
5b60: 4c 5f 52 44 57 52 20 20 20 20 20 20 20 20 30 20  L_RDWR        0 
5b70: 20 20 20 2f 2a 20 4e 6f 72 6d 61 6c 20 72 65 61     /* Normal rea
5b80: 64 2f 77 72 69 74 65 20 63 6f 6e 6e 65 63 74 69  d/write connecti
5b90: 6f 6e 20 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41  on */.#define WA
5ba0: 4c 5f 52 44 4f 4e 4c 59 20 20 20 20 20 20 31 20  L_RDONLY      1 
5bb0: 20 20 20 2f 2a 20 54 68 65 20 57 41 4c 20 66 69     /* The WAL fi
5bc0: 6c 65 20 69 73 20 72 65 61 64 6f 6e 6c 79 20 2a  le is readonly *
5bd0: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 53 48  /.#define WAL_SH
5be0: 4d 5f 52 44 4f 4e 4c 59 20 20 32 20 20 20 20 2f  M_RDONLY  2    /
5bf0: 2a 20 54 68 65 20 53 48 4d 20 66 69 6c 65 20 69  * The SHM file i
5c00: 73 20 72 65 61 64 6f 6e 6c 79 20 2a 2f 0a 0a 2f  s readonly */../
5c10: 2a 0a 2a 2a 20 45 61 63 68 20 70 61 67 65 20 6f  *.** Each page o
5c20: 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
5c30: 6d 61 70 70 69 6e 67 20 63 6f 6e 74 61 69 6e 73  mapping contains
5c40: 20 61 20 68 61 73 68 2d 74 61 62 6c 65 20 6d 61   a hash-table ma
5c50: 64 65 20 75 70 20 6f 66 0a 2a 2a 20 61 6e 20 61  de up of.** an a
5c60: 72 72 61 79 20 6f 66 20 48 41 53 48 54 41 42 4c  rray of HASHTABL
5c70: 45 5f 4e 53 4c 4f 54 20 65 6c 65 6d 65 6e 74 73  E_NSLOT elements
5c80: 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   of the followin
5c90: 67 20 74 79 70 65 2e 0a 2a 2f 0a 74 79 70 65 64  g type..*/.typed
5ca0: 65 66 20 75 31 36 20 68 74 5f 73 6c 6f 74 3b 0a  ef u16 ht_slot;.
5cb0: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 73 74 72 75  ./*.** This stru
5cc0: 63 74 75 72 65 20 69 73 20 75 73 65 64 20 74 6f  cture is used to
5cd0: 20 69 6d 70 6c 65 6d 65 6e 74 20 61 6e 20 69 74   implement an it
5ce0: 65 72 61 74 6f 72 20 74 68 61 74 20 6c 6f 6f 70  erator that loop
5cf0: 73 20 74 68 72 6f 75 67 68 0a 2a 2a 20 61 6c 6c  s through.** all
5d00: 20 66 72 61 6d 65 73 20 69 6e 20 74 68 65 20 57   frames in the W
5d10: 41 4c 20 69 6e 20 64 61 74 61 62 61 73 65 20 70  AL in database p
5d20: 61 67 65 20 6f 72 64 65 72 2e 20 57 68 65 72 65  age order. Where
5d30: 20 74 77 6f 20 6f 72 20 6d 6f 72 65 20 66 72 61   two or more fra
5d40: 6d 65 73 0a 2a 2a 20 63 6f 72 72 65 73 70 6f 6e  mes.** correspon
5d50: 64 20 74 6f 20 74 68 65 20 73 61 6d 65 20 64 61  d to the same da
5d60: 74 61 62 61 73 65 20 70 61 67 65 2c 20 74 68 65  tabase page, the
5d70: 20 69 74 65 72 61 74 6f 72 20 76 69 73 69 74 73   iterator visits
5d80: 20 6f 6e 6c 79 20 74 68 65 20 0a 2a 2a 20 66 72   only the .** fr
5d90: 61 6d 65 20 6d 6f 73 74 20 72 65 63 65 6e 74 6c  ame most recentl
5da0: 79 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65  y written to the
5db0: 20 57 41 4c 20 28 69 6e 20 6f 74 68 65 72 20 77   WAL (in other w
5dc0: 6f 72 64 73 2c 20 74 68 65 20 66 72 61 6d 65 20  ords, the frame 
5dd0: 77 69 74 68 0a 2a 2a 20 74 68 65 20 6c 61 72 67  with.** the larg
5de0: 65 73 74 20 69 6e 64 65 78 29 2e 0a 2a 2a 0a 2a  est index)..**.*
5df0: 2a 20 54 68 65 20 69 6e 74 65 72 6e 61 6c 73 20  * The internals 
5e00: 6f 66 20 74 68 69 73 20 73 74 72 75 63 74 75 72  of this structur
5e10: 65 20 61 72 65 20 6f 6e 6c 79 20 61 63 63 65 73  e are only acces
5e20: 73 65 64 20 62 79 3a 0a 2a 2a 0a 2a 2a 20 20 20  sed by:.**.**   
5e30: 77 61 6c 49 74 65 72 61 74 6f 72 49 6e 69 74 28  walIteratorInit(
5e40: 29 20 2d 20 43 72 65 61 74 65 20 61 20 6e 65 77  ) - Create a new
5e50: 20 69 74 65 72 61 74 6f 72 2c 0a 2a 2a 20 20 20   iterator,.**   
5e60: 77 61 6c 49 74 65 72 61 74 6f 72 4e 65 78 74 28  walIteratorNext(
5e70: 29 20 2d 20 53 74 65 70 20 61 6e 20 69 74 65 72  ) - Step an iter
5e80: 61 74 6f 72 2c 0a 2a 2a 20 20 20 77 61 6c 49 74  ator,.**   walIt
5e90: 65 72 61 74 6f 72 46 72 65 65 28 29 20 2d 20 46  eratorFree() - F
5ea0: 72 65 65 20 61 6e 20 69 74 65 72 61 74 6f 72 2e  ree an iterator.
5eb0: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  .**.** This func
5ec0: 74 69 6f 6e 61 6c 69 74 79 20 69 73 20 75 73 65  tionality is use
5ed0: 64 20 62 79 20 74 68 65 20 63 68 65 63 6b 70 6f  d by the checkpo
5ee0: 69 6e 74 20 63 6f 64 65 20 28 73 65 65 20 77 61  int code (see wa
5ef0: 6c 43 68 65 63 6b 70 6f 69 6e 74 28 29 29 2e 0a  lCheckpoint())..
5f00: 2a 2f 0a 73 74 72 75 63 74 20 57 61 6c 49 74 65  */.struct WalIte
5f10: 72 61 74 6f 72 20 7b 0a 20 20 69 6e 74 20 69 50  rator {.  int iP
5f20: 72 69 6f 72 3b 20 20 20 20 20 20 20 20 20 20 20  rior;           
5f30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73            /* Las
5f40: 74 20 72 65 73 75 6c 74 20 72 65 74 75 72 6e 65  t result returne
5f50: 64 20 66 72 6f 6d 20 74 68 65 20 69 74 65 72 61  d from the itera
5f60: 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 65  tor */.  int nSe
5f70: 67 6d 65 6e 74 3b 20 20 20 20 20 20 20 20 20 20  gment;          
5f80: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
5f90: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e  er of entries in
5fa0: 20 61 53 65 67 6d 65 6e 74 5b 5d 20 2a 2f 0a 20   aSegment[] */. 
5fb0: 20 73 74 72 75 63 74 20 57 61 6c 53 65 67 6d 65   struct WalSegme
5fc0: 6e 74 20 7b 0a 20 20 20 20 69 6e 74 20 69 4e 65  nt {.    int iNe
5fd0: 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  xt;             
5fe0: 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 73         /* Next s
5ff0: 6c 6f 74 20 69 6e 20 61 49 6e 64 65 78 5b 5d 20  lot in aIndex[] 
6000: 6e 6f 74 20 79 65 74 20 72 65 74 75 72 6e 65 64  not yet returned
6010: 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20   */.    ht_slot 
6020: 2a 61 49 6e 64 65 78 3b 20 20 20 20 20 20 20 20  *aIndex;        
6030: 20 20 20 20 20 20 2f 2a 20 69 30 2c 20 69 31 2c        /* i0, i1,
6040: 20 69 32 2e 2e 2e 20 73 75 63 68 20 74 68 61 74   i2... such that
6050: 20 61 50 67 6e 6f 5b 69 4e 5d 20 61 73 63 65 6e   aPgno[iN] ascen
6060: 64 20 2a 2f 0a 20 20 20 20 75 33 32 20 2a 61 50  d */.    u32 *aP
6070: 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20  gno;            
6080: 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20         /* Array 
6090: 6f 66 20 70 61 67 65 20 6e 75 6d 62 65 72 73 2e  of page numbers.
60a0: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 45 6e 74   */.    int nEnt
60b0: 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ry;             
60c0: 20 20 20 20 20 20 2f 2a 20 4e 72 2e 20 6f 66 20        /* Nr. of 
60d0: 65 6e 74 72 69 65 73 20 69 6e 20 61 50 67 6e 6f  entries in aPgno
60e0: 5b 5d 20 61 6e 64 20 61 49 6e 64 65 78 5b 5d 20  [] and aIndex[] 
60f0: 2a 2f 0a 20 20 20 20 69 6e 74 20 69 5a 65 72 6f  */.    int iZero
6100: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
6110: 20 20 20 20 20 2f 2a 20 46 72 61 6d 65 20 6e 75       /* Frame nu
6120: 6d 62 65 72 20 61 73 73 6f 63 69 61 74 65 64 20  mber associated 
6130: 77 69 74 68 20 61 50 67 6e 6f 5b 30 5d 20 2a 2f  with aPgno[0] */
6140: 0a 20 20 7d 20 61 53 65 67 6d 65 6e 74 5b 31 5d  .  } aSegment[1]
6150: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
6160: 20 20 20 2f 2a 20 4f 6e 65 20 66 6f 72 20 65 76     /* One for ev
6170: 65 72 79 20 33 32 4b 42 20 70 61 67 65 20 69 6e  ery 32KB page in
6180: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 2a   the wal-index *
6190: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 66 69  /.};../*.** Defi
61a0: 6e 65 20 74 68 65 20 70 61 72 61 6d 65 74 65 72  ne the parameter
61b0: 73 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61  s of the hash ta
61c0: 62 6c 65 73 20 69 6e 20 74 68 65 20 77 61 6c 2d  bles in the wal-
61d0: 69 6e 64 65 78 20 66 69 6c 65 2e 20 54 68 65 72  index file. Ther
61e0: 65 0a 2a 2a 20 69 73 20 61 20 68 61 73 68 2d 74  e.** is a hash-t
61f0: 61 62 6c 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 65  able following e
6200: 76 65 72 79 20 48 41 53 48 54 41 42 4c 45 5f 4e  very HASHTABLE_N
6210: 50 41 47 45 20 70 61 67 65 20 6e 75 6d 62 65 72  PAGE page number
6220: 73 20 69 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d  s in the.** wal-
6230: 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 43 68 61  index..**.** Cha
6240: 6e 67 69 6e 67 20 61 6e 79 20 6f 66 20 74 68 65  nging any of the
6250: 73 65 20 63 6f 6e 73 74 61 6e 74 73 20 77 69 6c  se constants wil
6260: 6c 20 61 6c 74 65 72 20 74 68 65 20 77 61 6c 2d  l alter the wal-
6270: 69 6e 64 65 78 20 66 6f 72 6d 61 74 20 61 6e 64  index format and
6280: 0a 2a 2a 20 63 72 65 61 74 65 20 69 6e 63 6f 6d  .** create incom
6290: 70 61 74 69 62 69 6c 69 74 69 65 73 2e 0a 2a 2f  patibilities..*/
62a0: 0a 23 64 65 66 69 6e 65 20 48 41 53 48 54 41 42  .#define HASHTAB
62b0: 4c 45 5f 4e 50 41 47 45 20 20 20 20 20 20 34 30  LE_NPAGE      40
62c0: 39 36 20 20 20 20 20 20 20 20 20 20 20 20 20 20  96              
62d0: 20 20 20 2f 2a 20 4d 75 73 74 20 62 65 20 70 6f     /* Must be po
62e0: 77 65 72 20 6f 66 20 32 20 2a 2f 0a 23 64 65 66  wer of 2 */.#def
62f0: 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f 48 41  ine HASHTABLE_HA
6300: 53 48 5f 31 20 20 20 20 20 33 38 33 20 20 20 20  SH_1     383    
6310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6320: 20 53 68 6f 75 6c 64 20 62 65 20 70 72 69 6d 65   Should be prime
6330: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48   */.#define HASH
6340: 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 20 20 20 20  TABLE_NSLOT     
6350: 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47   (HASHTABLE_NPAG
6360: 45 2a 32 29 20 20 2f 2a 20 4d 75 73 74 20 62 65  E*2)  /* Must be
6370: 20 61 20 70 6f 77 65 72 20 6f 66 20 32 20 2a 2f   a power of 2 */
6380: 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 65 20 62 6c 6f  ../* .** The blo
6390: 63 6b 20 6f 66 20 70 61 67 65 20 6e 75 6d 62 65  ck of page numbe
63a0: 72 73 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  rs associated wi
63b0: 74 68 20 74 68 65 20 66 69 72 73 74 20 68 61 73  th the first has
63c0: 68 2d 74 61 62 6c 65 20 69 6e 20 61 0a 2a 2a 20  h-table in a.** 
63d0: 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 73 6d 61  wal-index is sma
63e0: 6c 6c 65 72 20 74 68 61 6e 20 75 73 75 61 6c 2e  ller than usual.
63f0: 20 54 68 69 73 20 69 73 20 73 6f 20 74 68 61 74   This is so that
6400: 20 74 68 65 72 65 20 69 73 20 61 20 63 6f 6d 70   there is a comp
6410: 6c 65 74 65 0a 2a 2a 20 68 61 73 68 2d 74 61 62  lete.** hash-tab
6420: 6c 65 20 6f 6e 20 65 61 63 68 20 61 6c 69 67 6e  le on each align
6430: 65 64 20 33 32 4b 42 20 70 61 67 65 20 6f 66 20  ed 32KB page of 
6440: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a  the wal-index..*
6450: 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48 54 41  /.#define HASHTA
6460: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20 20 28  BLE_NPAGE_ONE  (
6470: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20  HASHTABLE_NPAGE 
6480: 2d 20 28 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f  - (WALINDEX_HDR_
6490: 53 49 5a 45 2f 73 69 7a 65 6f 66 28 75 33 32 29  SIZE/sizeof(u32)
64a0: 29 29 0a 0a 2f 2a 20 54 68 65 20 77 61 6c 2d 69  ))../* The wal-i
64b0: 6e 64 65 78 20 69 73 20 64 69 76 69 64 65 64 20  ndex is divided 
64c0: 69 6e 74 6f 20 70 61 67 65 73 20 6f 66 20 57 41  into pages of WA
64d0: 4c 49 4e 44 45 58 5f 50 47 53 5a 20 62 79 74 65  LINDEX_PGSZ byte
64e0: 73 20 65 61 63 68 2e 20 2a 2f 0a 23 64 65 66 69  s each. */.#defi
64f0: 6e 65 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a  ne WALINDEX_PGSZ
6500: 20 20 20 28 20 20 20 20 20 20 20 20 20 20 20 20     (            
6510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6520: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 0a 20               \. 
6530: 20 20 20 73 69 7a 65 6f 66 28 68 74 5f 73 6c 6f     sizeof(ht_slo
6540: 74 29 2a 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c  t)*HASHTABLE_NSL
6550: 4f 54 20 2b 20 48 41 53 48 54 41 42 4c 45 5f 4e  OT + HASHTABLE_N
6560: 50 41 47 45 2a 73 69 7a 65 6f 66 28 75 33 32 29  PAGE*sizeof(u32)
6570: 20 5c 0a 29 0a 0a 2f 2a 0a 2a 2a 20 4f 62 74 61   \.)../*.** Obta
6580: 69 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  in a pointer to 
6590: 74 68 65 20 69 50 61 67 65 27 74 68 20 70 61 67  the iPage'th pag
65a0: 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  e of the wal-ind
65b0: 65 78 2e 20 54 68 65 20 77 61 6c 2d 69 6e 64 65  ex. The wal-inde
65c0: 78 0a 2a 2a 20 69 73 20 62 72 6f 6b 65 6e 20 69  x.** is broken i
65d0: 6e 74 6f 20 70 61 67 65 73 20 6f 66 20 57 41 4c  nto pages of WAL
65e0: 49 4e 44 45 58 5f 50 47 53 5a 20 62 79 74 65 73  INDEX_PGSZ bytes
65f0: 2e 20 57 61 6c 2d 69 6e 64 65 78 20 70 61 67 65  . Wal-index page
6600: 73 20 61 72 65 0a 2a 2a 20 6e 75 6d 62 65 72 65  s are.** numbere
6610: 64 20 66 72 6f 6d 20 7a 65 72 6f 2e 0a 2a 2a 0a  d from zero..**.
6620: 2a 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 69 6e  ** If the wal-in
6630: 64 65 78 20 69 73 20 63 75 72 72 65 6e 74 6c 79  dex is currently
6640: 20 73 6d 61 6c 6c 65 72 20 74 68 65 20 69 50 61   smaller the iPa
6650: 67 65 20 70 61 67 65 73 20 74 68 65 6e 20 74 68  ge pages then th
6660: 65 20 73 69 7a 65 0a 2a 2a 20 6f 66 20 74 68 65  e size.** of the
6670: 20 77 61 6c 2d 69 6e 64 65 78 20 6d 69 67 68 74   wal-index might
6680: 20 62 65 20 69 6e 63 72 65 61 73 65 64 2c 20 62   be increased, b
6690: 75 74 20 6f 6e 6c 79 20 69 66 20 69 74 20 69 73  ut only if it is
66a0: 20 73 61 66 65 20 74 6f 20 64 6f 0a 2a 2a 20 73   safe to do.** s
66b0: 6f 2e 20 20 49 74 20 69 73 20 73 61 66 65 20 74  o.  It is safe t
66c0: 6f 20 65 6e 6c 61 72 67 65 20 74 68 65 20 77 61  o enlarge the wa
66d0: 6c 2d 69 6e 64 65 78 20 69 66 20 70 57 61 6c 2d  l-index if pWal-
66e0: 3e 77 72 69 74 65 4c 6f 63 6b 20 69 73 20 74 72  >writeLock is tr
66f0: 75 65 0a 2a 2a 20 6f 72 20 70 57 61 6c 2d 3e 65  ue.** or pWal->e
6700: 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41  xclusiveMode==WA
6710: 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44  L_HEAPMEMORY_MOD
6720: 45 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 69 73  E..**.** If this
6730: 20 63 61 6c 6c 20 69 73 20 73 75 63 63 65 73 73   call is success
6740: 66 75 6c 2c 20 2a 70 70 50 61 67 65 20 69 73 20  ful, *ppPage is 
6750: 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  set to point to 
6760: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a  the wal-index.**
6770: 20 70 61 67 65 20 61 6e 64 20 53 51 4c 49 54 45   page and SQLITE
6780: 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 2e  _OK is returned.
6790: 20 49 66 20 61 6e 20 65 72 72 6f 72 20 28 61 6e   If an error (an
67a0: 20 4f 4f 4d 20 6f 72 20 56 46 53 20 65 72 72 6f   OOM or VFS erro
67b0: 72 29 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 74 68  r) occurs,.** th
67c0: 65 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  en an SQLite err
67d0: 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  or code is retur
67e0: 6e 65 64 20 61 6e 64 20 2a 70 70 50 61 67 65 20  ned and *ppPage 
67f0: 69 73 20 73 65 74 20 74 6f 20 30 2e 0a 2a 2f 0a  is set to 0..*/.
6800: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e  static int walIn
6810: 64 65 78 50 61 67 65 28 57 61 6c 20 2a 70 57 61  dexPage(Wal *pWa
6820: 6c 2c 20 69 6e 74 20 69 50 61 67 65 2c 20 76 6f  l, int iPage, vo
6830: 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 70 70 50  latile u32 **ppP
6840: 61 67 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  age){.  int rc =
6850: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f   SQLITE_OK;..  /
6860: 2a 20 45 6e 6c 61 72 67 65 20 74 68 65 20 70 57  * Enlarge the pW
6870: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 5d 20 61  al->apWiData[] a
6880: 72 72 61 79 20 69 66 20 72 65 71 75 69 72 65 64  rray if required
6890: 20 2a 2f 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e   */.  if( pWal->
68a0: 6e 57 69 44 61 74 61 3c 3d 69 50 61 67 65 20 29  nWiData<=iPage )
68b0: 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20  {.    int nByte 
68c0: 3d 20 73 69 7a 65 6f 66 28 75 33 32 2a 29 2a 28  = sizeof(u32*)*(
68d0: 69 50 61 67 65 2b 31 29 3b 0a 20 20 20 20 76 6f  iPage+1);.    vo
68e0: 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 61 70 4e  latile u32 **apN
68f0: 65 77 3b 0a 20 20 20 20 61 70 4e 65 77 20 3d 20  ew;.    apNew = 
6900: 28 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a  (volatile u32 **
6910: 29 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63  )sqlite3_realloc
6920: 36 34 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d  64((void *)pWal-
6930: 3e 61 70 57 69 44 61 74 61 2c 20 6e 42 79 74 65  >apWiData, nByte
6940: 29 3b 0a 20 20 20 20 69 66 28 20 21 61 70 4e 65  );.    if( !apNe
6950: 77 20 29 7b 0a 20 20 20 20 20 20 2a 70 70 50 61  w ){.      *ppPa
6960: 67 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 65  ge = 0;.      re
6970: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
6980: 4d 5f 42 4b 50 54 3b 0a 20 20 20 20 7d 0a 20 20  M_BKPT;.    }.  
6990: 20 20 6d 65 6d 73 65 74 28 28 76 6f 69 64 2a 29    memset((void*)
69a0: 26 61 70 4e 65 77 5b 70 57 61 6c 2d 3e 6e 57 69  &apNew[pWal->nWi
69b0: 44 61 74 61 5d 2c 20 30 2c 0a 20 20 20 20 20 20  Data], 0,.      
69c0: 20 20 20 20 20 73 69 7a 65 6f 66 28 75 33 32 2a       sizeof(u32*
69d0: 29 2a 28 69 50 61 67 65 2b 31 2d 70 57 61 6c 2d  )*(iPage+1-pWal-
69e0: 3e 6e 57 69 44 61 74 61 29 29 3b 0a 20 20 20 20  >nWiData));.    
69f0: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 20 3d  pWal->apWiData =
6a00: 20 61 70 4e 65 77 3b 0a 20 20 20 20 70 57 61 6c   apNew;.    pWal
6a10: 2d 3e 6e 57 69 44 61 74 61 20 3d 20 69 50 61 67  ->nWiData = iPag
6a20: 65 2b 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52  e+1;.  }..  /* R
6a30: 65 71 75 65 73 74 20 61 20 70 6f 69 6e 74 65 72  equest a pointer
6a40: 20 74 6f 20 74 68 65 20 72 65 71 75 69 72 65 64   to the required
6a50: 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20 56   page from the V
6a60: 46 53 20 2a 2f 0a 20 20 69 66 28 20 70 57 61 6c  FS */.  if( pWal
6a70: 2d 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65  ->apWiData[iPage
6a80: 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20  ]==0 ){.    if( 
6a90: 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
6aa0: 6f 64 65 3d 3d 57 41 4c 5f 48 45 41 50 4d 45 4d  ode==WAL_HEAPMEM
6ab0: 4f 52 59 5f 4d 4f 44 45 20 29 7b 0a 20 20 20 20  ORY_MODE ){.    
6ac0: 20 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61    pWal->apWiData
6ad0: 5b 69 50 61 67 65 5d 20 3d 20 28 75 33 32 20 76  [iPage] = (u32 v
6ae0: 6f 6c 61 74 69 6c 65 20 2a 29 73 71 6c 69 74 65  olatile *)sqlite
6af0: 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 57 41 4c 49  3MallocZero(WALI
6b00: 4e 44 45 58 5f 50 47 53 5a 29 3b 0a 20 20 20 20  NDEX_PGSZ);.    
6b10: 20 20 69 66 28 20 21 70 57 61 6c 2d 3e 61 70 57    if( !pWal->apW
6b20: 69 44 61 74 61 5b 69 50 61 67 65 5d 20 29 20 72  iData[iPage] ) r
6b30: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
6b40: 5f 42 4b 50 54 3b 0a 20 20 20 20 7d 65 6c 73 65  _BKPT;.    }else
6b50: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  {.      rc = sql
6b60: 69 74 65 33 4f 73 53 68 6d 4d 61 70 28 70 57 61  ite3OsShmMap(pWa
6b70: 6c 2d 3e 70 44 62 46 64 2c 20 69 50 61 67 65 2c  l->pDbFd, iPage,
6b80: 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a 2c 20   WALINDEX_PGSZ, 
6b90: 0a 20 20 20 20 20 20 20 20 20 20 70 57 61 6c 2d  .          pWal-
6ba0: 3e 77 72 69 74 65 4c 6f 63 6b 2c 20 28 76 6f 69  >writeLock, (voi
6bb0: 64 20 76 6f 6c 61 74 69 6c 65 20 2a 2a 29 26 70  d volatile **)&p
6bc0: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50  Wal->apWiData[iP
6bd0: 61 67 65 5d 0a 20 20 20 20 20 20 29 3b 0a 20 20  age].      );.  
6be0: 20 20 20 20 61 73 73 65 72 74 28 20 70 57 61 6c      assert( pWal
6bf0: 2d 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65  ->apWiData[iPage
6c00: 5d 21 3d 30 20 7c 7c 20 72 63 21 3d 53 51 4c 49  ]!=0 || rc!=SQLI
6c10: 54 45 5f 4f 4b 20 7c 7c 20 70 57 61 6c 2d 3e 77  TE_OK || pWal->w
6c20: 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20  riteLock==0 );. 
6c30: 20 20 20 20 20 74 65 73 74 63 61 73 65 28 20 70       testcase( p
6c40: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50  Wal->apWiData[iP
6c50: 61 67 65 5d 3d 3d 30 20 26 26 20 72 63 3d 3d 53  age]==0 && rc==S
6c60: 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 20 20  QLITE_OK );.    
6c70: 20 20 69 66 28 20 28 72 63 26 30 78 66 66 29 3d    if( (rc&0xff)=
6c80: 3d 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59  =SQLITE_READONLY
6c90: 20 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c   ){.        pWal
6ca0: 2d 3e 72 65 61 64 4f 6e 6c 79 20 7c 3d 20 57 41  ->readOnly |= WA
6cb0: 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 3b 0a 20 20  L_SHM_RDONLY;.  
6cc0: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
6cd0: 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 20 29 7b  LITE_READONLY ){
6ce0: 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
6cf0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 20  SQLITE_OK;.     
6d00: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
6d10: 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 50 61 67   }.  }..  *ppPag
6d20: 65 20 3d 20 70 57 61 6c 2d 3e 61 70 57 69 44 61  e = pWal->apWiDa
6d30: 74 61 5b 69 50 61 67 65 5d 3b 0a 20 20 61 73 73  ta[iPage];.  ass
6d40: 65 72 74 28 20 69 50 61 67 65 3d 3d 30 20 7c 7c  ert( iPage==0 ||
6d50: 20 2a 70 70 50 61 67 65 20 7c 7c 20 72 63 21 3d   *ppPage || rc!=
6d60: 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72  SQLITE_OK );.  r
6d70: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
6d80: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  ** Return a poin
6d90: 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c 43 6b  ter to the WalCk
6da0: 70 74 49 6e 66 6f 20 73 74 72 75 63 74 75 72 65  ptInfo structure
6db0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
6dc0: 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c  x..*/.static vol
6dd0: 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66  atile WalCkptInf
6de0: 6f 20 2a 77 61 6c 43 6b 70 74 49 6e 66 6f 28 57  o *walCkptInfo(W
6df0: 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73  al *pWal){.  ass
6e00: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
6e10: 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70  ta>0 && pWal->ap
6e20: 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72  WiData[0] );.  r
6e30: 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20  eturn (volatile 
6e40: 57 61 6c 43 6b 70 74 49 6e 66 6f 2a 29 26 28 70  WalCkptInfo*)&(p
6e50: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
6e60: 5b 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78  [sizeof(WalIndex
6e70: 48 64 72 29 2f 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a  Hdr)/2]);.}../*.
6e80: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  ** Return a poin
6e90: 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c 49 6e  ter to the WalIn
6ea0: 64 65 78 48 64 72 20 73 74 72 75 63 74 75 72 65  dexHdr structure
6eb0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
6ec0: 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c  x..*/.static vol
6ed0: 61 74 69 6c 65 20 57 61 6c 49 6e 64 65 78 48 64  atile WalIndexHd
6ee0: 72 20 2a 77 61 6c 49 6e 64 65 78 48 64 72 28 57  r *walIndexHdr(W
6ef0: 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73  al *pWal){.  ass
6f00: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
6f10: 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70  ta>0 && pWal->ap
6f20: 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72  WiData[0] );.  r
6f30: 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20  eturn (volatile 
6f40: 57 61 6c 49 6e 64 65 78 48 64 72 2a 29 70 57 61  WalIndexHdr*)pWa
6f50: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 3b 0a  l->apWiData[0];.
6f60: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61 72 67  }../*.** The arg
6f70: 75 6d 65 6e 74 20 74 6f 20 74 68 69 73 20 6d 61  ument to this ma
6f80: 63 72 6f 20 6d 75 73 74 20 62 65 20 6f 66 20 74  cro must be of t
6f90: 79 70 65 20 75 33 32 2e 20 4f 6e 20 61 20 6c 69  ype u32. On a li
6fa0: 74 74 6c 65 2d 65 6e 64 69 61 6e 0a 2a 2a 20 61  ttle-endian.** a
6fb0: 72 63 68 69 74 65 63 74 75 72 65 2c 20 69 74 20  rchitecture, it 
6fc0: 72 65 74 75 72 6e 73 20 74 68 65 20 75 33 32 20  returns the u32 
6fd0: 76 61 6c 75 65 20 74 68 61 74 20 72 65 73 75 6c  value that resul
6fe0: 74 73 20 66 72 6f 6d 20 69 6e 74 65 72 70 72 65  ts from interpre
6ff0: 74 69 6e 67 0a 2a 2a 20 74 68 65 20 34 20 62 79  ting.** the 4 by
7000: 74 65 73 20 61 73 20 61 20 62 69 67 2d 65 6e 64  tes as a big-end
7010: 69 61 6e 20 76 61 6c 75 65 2e 20 4f 6e 20 61 20  ian value. On a 
7020: 62 69 67 2d 65 6e 64 69 61 6e 20 61 72 63 68 69  big-endian archi
7030: 74 65 63 74 75 72 65 2c 20 69 74 0a 2a 2a 20 72  tecture, it.** r
7040: 65 74 75 72 6e 73 20 74 68 65 20 76 61 6c 75 65  eturns the value
7050: 20 74 68 61 74 20 77 6f 75 6c 64 20 62 65 20 70   that would be p
7060: 72 6f 64 75 63 65 64 20 62 79 20 69 6e 74 65 72  roduced by inter
7070: 70 72 65 74 69 6e 67 20 74 68 65 20 34 20 62 79  preting the 4 by
7080: 74 65 73 0a 2a 2a 20 6f 66 20 74 68 65 20 69 6e  tes.** of the in
7090: 70 75 74 20 76 61 6c 75 65 20 61 73 20 61 20 6c  put value as a l
70a0: 69 74 74 6c 65 2d 65 6e 64 69 61 6e 20 69 6e 74  ittle-endian int
70b0: 65 67 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  eger..*/.#define
70c0: 20 42 59 54 45 53 57 41 50 33 32 28 78 29 20 28   BYTESWAP32(x) (
70d0: 20 5c 0a 20 20 20 20 28 28 28 78 29 26 30 78 30   \.    (((x)&0x0
70e0: 30 30 30 30 30 46 46 29 3c 3c 32 34 29 20 2b 20  00000FF)<<24) + 
70f0: 28 28 28 78 29 26 30 78 30 30 30 30 46 46 30 30  (((x)&0x0000FF00
7100: 29 3c 3c 38 29 20 20 5c 0a 20 20 2b 20 28 28 28  )<<8)  \.  + (((
7110: 78 29 26 30 78 30 30 46 46 30 30 30 30 29 3e 3e  x)&0x00FF0000)>>
7120: 38 29 20 20 2b 20 28 28 28 78 29 26 30 78 46 46  8)  + (((x)&0xFF
7130: 30 30 30 30 30 30 29 3e 3e 32 34 29 20 5c 0a 29  000000)>>24) \.)
7140: 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65  ../*.** Generate
7150: 20 6f 72 20 65 78 74 65 6e 64 20 61 6e 20 38 20   or extend an 8 
7160: 62 79 74 65 20 63 68 65 63 6b 73 75 6d 20 62 61  byte checksum ba
7170: 73 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 20  sed on the data 
7180: 69 6e 20 0a 2a 2a 20 61 72 72 61 79 20 61 42 79  in .** array aBy
7190: 74 65 5b 5d 20 61 6e 64 20 74 68 65 20 69 6e 69  te[] and the ini
71a0: 74 69 61 6c 20 76 61 6c 75 65 73 20 6f 66 20 61  tial values of a
71b0: 49 6e 5b 30 5d 20 61 6e 64 20 61 49 6e 5b 31 5d  In[0] and aIn[1]
71c0: 20 28 6f 72 0a 2a 2a 20 69 6e 69 74 69 61 6c 20   (or.** initial 
71d0: 76 61 6c 75 65 73 20 6f 66 20 30 20 61 6e 64 20  values of 0 and 
71e0: 30 20 69 66 20 61 49 6e 3d 3d 4e 55 4c 4c 29 2e  0 if aIn==NULL).
71f0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b  .**.** The check
7200: 73 75 6d 20 69 73 20 77 72 69 74 74 65 6e 20 62  sum is written b
7210: 61 63 6b 20 69 6e 74 6f 20 61 4f 75 74 5b 5d 20  ack into aOut[] 
7220: 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
7230: 2e 0a 2a 2a 0a 2a 2a 20 6e 42 79 74 65 20 6d 75  ..**.** nByte mu
7240: 73 74 20 62 65 20 61 20 70 6f 73 69 74 69 76 65  st be a positive
7250: 20 6d 75 6c 74 69 70 6c 65 20 6f 66 20 38 2e 0a   multiple of 8..
7260: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
7270: 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
7280: 0a 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73  .  int nativeCks
7290: 75 6d 2c 20 2f 2a 20 54 72 75 65 20 66 6f 72 20  um, /* True for 
72a0: 6e 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64 65  native byte-orde
72b0: 72 2c 20 66 61 6c 73 65 20 66 6f 72 20 6e 6f 6e  r, false for non
72c0: 2d 6e 61 74 69 76 65 20 2a 2f 0a 20 20 75 38 20  -native */.  u8 
72d0: 2a 61 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  *a,           /*
72e0: 20 43 6f 6e 74 65 6e 74 20 74 6f 20 62 65 20 63   Content to be c
72f0: 68 65 63 6b 73 75 6d 6d 65 64 20 2a 2f 0a 20 20  hecksummed */.  
7300: 69 6e 74 20 6e 42 79 74 65 2c 20 20 20 20 20 20  int nByte,      
7310: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 63 6f 6e   /* Bytes of con
7320: 74 65 6e 74 20 69 6e 20 61 5b 5d 2e 20 20 4d 75  tent in a[].  Mu
7330: 73 74 20 62 65 20 61 20 6d 75 6c 74 69 70 6c 65  st be a multiple
7340: 20 6f 66 20 38 2e 20 2a 2f 0a 20 20 63 6f 6e 73   of 8. */.  cons
7350: 74 20 75 33 32 20 2a 61 49 6e 2c 20 20 2f 2a 20  t u32 *aIn,  /* 
7360: 49 6e 69 74 69 61 6c 20 63 68 65 63 6b 73 75 6d  Initial checksum
7370: 20 76 61 6c 75 65 20 69 6e 70 75 74 20 2a 2f 0a   value input */.
7380: 20 20 75 33 32 20 2a 61 4f 75 74 20 20 20 20 20    u32 *aOut     
7390: 20 20 20 2f 2a 20 4f 55 54 3a 20 46 69 6e 61 6c     /* OUT: Final
73a0: 20 63 68 65 63 6b 73 75 6d 20 76 61 6c 75 65 20   checksum value 
73b0: 6f 75 74 70 75 74 20 2a 2f 0a 29 7b 0a 20 20 75  output */.){.  u
73c0: 33 32 20 73 31 2c 20 73 32 3b 0a 20 20 75 33 32  32 s1, s2;.  u32
73d0: 20 2a 61 44 61 74 61 20 3d 20 28 75 33 32 20 2a   *aData = (u32 *
73e0: 29 61 3b 0a 20 20 75 33 32 20 2a 61 45 6e 64 20  )a;.  u32 *aEnd 
73f0: 3d 20 28 75 33 32 20 2a 29 26 61 5b 6e 42 79 74  = (u32 *)&a[nByt
7400: 65 5d 3b 0a 0a 20 20 69 66 28 20 61 49 6e 20 29  e];..  if( aIn )
7410: 7b 0a 20 20 20 20 73 31 20 3d 20 61 49 6e 5b 30  {.    s1 = aIn[0
7420: 5d 3b 0a 20 20 20 20 73 32 20 3d 20 61 49 6e 5b  ];.    s2 = aIn[
7430: 31 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  1];.  }else{.   
7440: 20 73 31 20 3d 20 73 32 20 3d 20 30 3b 0a 20 20   s1 = s2 = 0;.  
7450: 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 42 79  }..  assert( nBy
7460: 74 65 3e 3d 38 20 29 3b 0a 20 20 61 73 73 65 72  te>=8 );.  asser
7470: 74 28 20 28 6e 42 79 74 65 26 30 78 30 30 30 30  t( (nByte&0x0000
7480: 30 30 30 37 29 3d 3d 30 20 29 3b 0a 0a 20 20 69  0007)==0 );..  i
7490: 66 28 20 6e 61 74 69 76 65 43 6b 73 75 6d 20 29  f( nativeCksum )
74a0: 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 20  {.    do {.     
74b0: 20 73 31 20 2b 3d 20 2a 61 44 61 74 61 2b 2b 20   s1 += *aData++ 
74c0: 2b 20 73 32 3b 0a 20 20 20 20 20 20 73 32 20 2b  + s2;.      s2 +
74d0: 3d 20 2a 61 44 61 74 61 2b 2b 20 2b 20 73 31 3b  = *aData++ + s1;
74e0: 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 61 44 61  .    }while( aDa
74f0: 74 61 3c 61 45 6e 64 20 29 3b 0a 20 20 7d 65 6c  ta<aEnd );.  }el
7500: 73 65 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20  se{.    do {.   
7510: 20 20 20 73 31 20 2b 3d 20 42 59 54 45 53 57 41     s1 += BYTESWA
7520: 50 33 32 28 61 44 61 74 61 5b 30 5d 29 20 2b 20  P32(aData[0]) + 
7530: 73 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d 20  s2;.      s2 += 
7540: 42 59 54 45 53 57 41 50 33 32 28 61 44 61 74 61  BYTESWAP32(aData
7550: 5b 31 5d 29 20 2b 20 73 31 3b 0a 20 20 20 20 20  [1]) + s1;.     
7560: 20 61 44 61 74 61 20 2b 3d 20 32 3b 0a 20 20 20   aData += 2;.   
7570: 20 7d 77 68 69 6c 65 28 20 61 44 61 74 61 3c 61   }while( aData<a
7580: 45 6e 64 20 29 3b 0a 20 20 7d 0a 0a 20 20 61 4f  End );.  }..  aO
7590: 75 74 5b 30 5d 20 3d 20 73 31 3b 0a 20 20 61 4f  ut[0] = s1;.  aO
75a0: 75 74 5b 31 5d 20 3d 20 73 32 3b 0a 7d 0a 0a 73  ut[1] = s2;.}..s
75b0: 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 53 68  tatic void walSh
75c0: 6d 42 61 72 72 69 65 72 28 57 61 6c 20 2a 70 57  mBarrier(Wal *pW
75d0: 61 6c 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d  al){.  if( pWal-
75e0: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 21 3d  >exclusiveMode!=
75f0: 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d  WAL_HEAPMEMORY_M
7600: 4f 44 45 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  ODE ){.    sqlit
7610: 65 33 4f 73 53 68 6d 42 61 72 72 69 65 72 28 70  e3OsShmBarrier(p
7620: 57 61 6c 2d 3e 70 44 62 46 64 29 3b 0a 20 20 7d  Wal->pDbFd);.  }
7630: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20  .}../*.** Write 
7640: 74 68 65 20 68 65 61 64 65 72 20 69 6e 66 6f 72  the header infor
7650: 6d 61 74 69 6f 6e 20 69 6e 20 70 57 61 6c 2d 3e  mation in pWal->
7660: 68 64 72 20 69 6e 74 6f 20 74 68 65 20 77 61 6c  hdr into the wal
7670: 2d 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 54 68  -index..**.** Th
7680: 65 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20 70 57  e checksum on pW
7690: 61 6c 2d 3e 68 64 72 20 69 73 20 75 70 64 61 74  al->hdr is updat
76a0: 65 64 20 62 65 66 6f 72 65 20 69 74 20 69 73 20  ed before it is 
76b0: 77 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 61 74  written..*/.stat
76c0: 69 63 20 76 6f 69 64 20 77 61 6c 49 6e 64 65 78  ic void walIndex
76d0: 57 72 69 74 65 48 64 72 28 57 61 6c 20 2a 70 57  WriteHdr(Wal *pW
76e0: 61 6c 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20  al){.  volatile 
76f0: 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 61 48 64  WalIndexHdr *aHd
7700: 72 20 3d 20 77 61 6c 49 6e 64 65 78 48 64 72 28  r = walIndexHdr(
7710: 70 57 61 6c 29 3b 0a 20 20 63 6f 6e 73 74 20 69  pWal);.  const i
7720: 6e 74 20 6e 43 6b 73 75 6d 20 3d 20 6f 66 66 73  nt nCksum = offs
7730: 65 74 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  etof(WalIndexHdr
7740: 2c 20 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 61 73  , aCksum);..  as
7750: 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74  sert( pWal->writ
7760: 65 4c 6f 63 6b 20 29 3b 0a 20 20 70 57 61 6c 2d  eLock );.  pWal-
7770: 3e 68 64 72 2e 69 73 49 6e 69 74 20 3d 20 31 3b  >hdr.isInit = 1;
7780: 0a 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56 65  .  pWal->hdr.iVe
7790: 72 73 69 6f 6e 20 3d 20 57 41 4c 49 4e 44 45 58  rsion = WALINDEX
77a0: 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 3b 0a 20 20  _MAX_VERSION;.  
77b0: 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73  walChecksumBytes
77c0: 28 31 2c 20 28 75 38 2a 29 26 70 57 61 6c 2d 3e  (1, (u8*)&pWal->
77d0: 68 64 72 2c 20 6e 43 6b 73 75 6d 2c 20 30 2c 20  hdr, nCksum, 0, 
77e0: 70 57 61 6c 2d 3e 68 64 72 2e 61 43 6b 73 75 6d  pWal->hdr.aCksum
77f0: 29 3b 0a 20 20 6d 65 6d 63 70 79 28 28 76 6f 69  );.  memcpy((voi
7800: 64 2a 29 26 61 48 64 72 5b 31 5d 2c 20 28 63 6f  d*)&aHdr[1], (co
7810: 6e 73 74 20 76 6f 69 64 2a 29 26 70 57 61 6c 2d  nst void*)&pWal-
7820: 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c  >hdr, sizeof(Wal
7830: 49 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 77 61  IndexHdr));.  wa
7840: 6c 53 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c  lShmBarrier(pWal
7850: 29 3b 0a 20 20 6d 65 6d 63 70 79 28 28 76 6f 69  );.  memcpy((voi
7860: 64 2a 29 26 61 48 64 72 5b 30 5d 2c 20 28 63 6f  d*)&aHdr[0], (co
7870: 6e 73 74 20 76 6f 69 64 2a 29 26 70 57 61 6c 2d  nst void*)&pWal-
7880: 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c  >hdr, sizeof(Wal
7890: 49 6e 64 65 78 48 64 72 29 29 3b 0a 7d 0a 0a 2f  IndexHdr));.}../
78a0: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
78b0: 6f 6e 20 65 6e 63 6f 64 65 73 20 61 20 73 69 6e  on encodes a sin
78c0: 67 6c 65 20 66 72 61 6d 65 20 68 65 61 64 65 72  gle frame header
78d0: 20 61 6e 64 20 77 72 69 74 65 73 20 69 74 20 74   and writes it t
78e0: 6f 20 61 20 62 75 66 66 65 72 0a 2a 2a 20 73 75  o a buffer.** su
78f0: 70 70 6c 69 65 64 20 62 79 20 74 68 65 20 63 61  pplied by the ca
7900: 6c 6c 65 72 2e 20 41 20 66 72 61 6d 65 2d 68 65  ller. A frame-he
7910: 61 64 65 72 20 69 73 20 6d 61 64 65 20 75 70 20  ader is made up 
7920: 6f 66 20 61 20 73 65 72 69 65 73 20 6f 66 20 0a  of a series of .
7930: 2a 2a 20 34 2d 62 79 74 65 20 62 69 67 2d 65 6e  ** 4-byte big-en
7940: 64 69 61 6e 20 69 6e 74 65 67 65 72 73 2c 20 61  dian integers, a
7950: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a  s follows:.**.**
7960: 20 20 20 20 20 30 3a 20 50 61 67 65 20 6e 75 6d       0: Page num
7970: 62 65 72 2e 0a 2a 2a 20 20 20 20 20 34 3a 20 46  ber..**     4: F
7980: 6f 72 20 63 6f 6d 6d 69 74 20 72 65 63 6f 72 64  or commit record
7990: 73 2c 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74  s, the size of t
79a0: 68 65 20 64 61 74 61 62 61 73 65 20 69 6d 61 67  he database imag
79b0: 65 20 69 6e 20 70 61 67 65 73 20 0a 2a 2a 20 20  e in pages .**  
79c0: 20 20 20 20 20 20 61 66 74 65 72 20 74 68 65 20        after the 
79d0: 63 6f 6d 6d 69 74 2e 20 46 6f 72 20 61 6c 6c 20  commit. For all 
79e0: 6f 74 68 65 72 20 72 65 63 6f 72 64 73 2c 20 7a  other records, z
79f0: 65 72 6f 2e 0a 2a 2a 20 20 20 20 20 38 3a 20 53  ero..**     8: S
7a00: 61 6c 74 2d 31 20 28 63 6f 70 69 65 64 20 66 72  alt-1 (copied fr
7a10: 6f 6d 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65  om the wal-heade
7a20: 72 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61 6c  r).**    12: Sal
7a30: 74 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f 6d  t-2 (copied from
7a40: 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72 29   the wal-header)
7a50: 0a 2a 2a 20 20 20 20 31 36 3a 20 43 68 65 63 6b  .**    16: Check
7a60: 73 75 6d 2d 31 2e 0a 2a 2a 20 20 20 20 32 30 3a  sum-1..**    20:
7a70: 20 43 68 65 63 6b 73 75 6d 2d 32 2e 0a 2a 2f 0a   Checksum-2..*/.
7a80: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 45  static void walE
7a90: 6e 63 6f 64 65 46 72 61 6d 65 28 0a 20 20 57 61  ncodeFrame(.  Wa
7aa0: 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20  l *pWal,        
7ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7ac0: 20 54 68 65 20 77 72 69 74 65 2d 61 68 65 61 64   The write-ahead
7ad0: 20 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 69 50   log */.  u32 iP
7ae0: 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  age,            
7af0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
7b00: 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65  abase page numbe
7b10: 72 20 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20  r for frame */. 
7b20: 20 75 33 32 20 6e 54 72 75 6e 63 61 74 65 2c 20   u32 nTruncate, 
7b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b40: 20 2f 2a 20 4e 65 77 20 64 62 20 73 69 7a 65 20   /* New db size 
7b50: 28 6f 72 20 30 20 66 6f 72 20 6e 6f 6e 2d 63 6f  (or 0 for non-co
7b60: 6d 6d 69 74 20 66 72 61 6d 65 73 29 20 2a 2f 0a  mmit frames) */.
7b70: 20 20 75 38 20 2a 61 44 61 74 61 2c 20 20 20 20    u8 *aData,    
7b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b90: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
7ba0: 70 61 67 65 20 64 61 74 61 20 2a 2f 0a 20 20 75  page data */.  u
7bb0: 38 20 2a 61 46 72 61 6d 65 20 20 20 20 20 20 20  8 *aFrame       
7bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7bd0: 2a 20 4f 55 54 3a 20 57 72 69 74 65 20 65 6e 63  * OUT: Write enc
7be0: 6f 64 65 64 20 66 72 61 6d 65 20 68 65 72 65 20  oded frame here 
7bf0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 61 74 69  */.){.  int nati
7c00: 76 65 43 6b 73 75 6d 3b 20 20 20 20 20 20 20 20  veCksum;        
7c10: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
7c20: 66 6f 72 20 6e 61 74 69 76 65 20 62 79 74 65 2d  for native byte-
7c30: 6f 72 64 65 72 20 63 68 65 63 6b 73 75 6d 73 20  order checksums 
7c40: 2a 2f 0a 20 20 75 33 32 20 2a 61 43 6b 73 75 6d  */.  u32 *aCksum
7c50: 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72   = pWal->hdr.aFr
7c60: 61 6d 65 43 6b 73 75 6d 3b 0a 20 20 61 73 73 65  ameCksum;.  asse
7c70: 72 74 28 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44  rt( WAL_FRAME_HD
7c80: 52 53 49 5a 45 3d 3d 32 34 20 29 3b 0a 20 20 73  RSIZE==24 );.  s
7c90: 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
7ca0: 61 46 72 61 6d 65 5b 30 5d 2c 20 69 50 61 67 65  aFrame[0], iPage
7cb0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74 34  );.  sqlite3Put4
7cc0: 62 79 74 65 28 26 61 46 72 61 6d 65 5b 34 5d 2c  byte(&aFrame[4],
7cd0: 20 6e 54 72 75 6e 63 61 74 65 29 3b 0a 20 20 69   nTruncate);.  i
7ce0: 66 28 20 70 57 61 6c 2d 3e 69 52 65 43 6b 73 75  f( pWal->iReCksu
7cf0: 6d 3d 3d 30 20 29 7b 0a 20 20 20 20 6d 65 6d 63  m==0 ){.    memc
7d00: 70 79 28 26 61 46 72 61 6d 65 5b 38 5d 2c 20 70  py(&aFrame[8], p
7d10: 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20  Wal->hdr.aSalt, 
7d20: 38 29 3b 0a 0a 20 20 20 20 6e 61 74 69 76 65 43  8);..    nativeC
7d30: 6b 73 75 6d 20 3d 20 28 70 57 61 6c 2d 3e 68 64  ksum = (pWal->hd
7d40: 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d 3d 53  r.bigEndCksum==S
7d50: 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e 29  QLITE_BIGENDIAN)
7d60: 3b 0a 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75  ;.    walChecksu
7d70: 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73  mBytes(nativeCks
7d80: 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38 2c 20 61  um, aFrame, 8, a
7d90: 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a  Cksum, aCksum);.
7da0: 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42      walChecksumB
7db0: 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75 6d  ytes(nativeCksum
7dc0: 2c 20 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e 73  , aData, pWal->s
7dd0: 7a 50 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20 61  zPage, aCksum, a
7de0: 43 6b 73 75 6d 29 3b 0a 0a 20 20 20 20 73 71 6c  Cksum);..    sql
7df0: 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 46  ite3Put4byte(&aF
7e00: 72 61 6d 65 5b 31 36 5d 2c 20 61 43 6b 73 75 6d  rame[16], aCksum
7e10: 5b 30 5d 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  [0]);.    sqlite
7e20: 33 50 75 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Put4byte(&aFram
7e30: 65 5b 32 30 5d 2c 20 61 43 6b 73 75 6d 5b 31 5d  e[20], aCksum[1]
7e40: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
7e50: 6d 65 6d 73 65 74 28 26 61 46 72 61 6d 65 5b 38  memset(&aFrame[8
7e60: 5d 2c 20 30 2c 20 31 36 29 3b 0a 20 20 7d 0a 7d  ], 0, 16);.  }.}
7e70: 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 6f  ../*.** Check to
7e80: 20 73 65 65 20 69 66 20 74 68 65 20 66 72 61 6d   see if the fram
7e90: 65 20 77 69 74 68 20 68 65 61 64 65 72 20 69 6e  e with header in
7ea0: 20 61 46 72 61 6d 65 5b 5d 20 61 6e 64 20 63 6f   aFrame[] and co
7eb0: 6e 74 65 6e 74 0a 2a 2a 20 69 6e 20 61 44 61 74  ntent.** in aDat
7ec0: 61 5b 5d 20 69 73 20 76 61 6c 69 64 2e 20 20 49  a[] is valid.  I
7ed0: 66 20 69 74 20 69 73 20 61 20 76 61 6c 69 64 20  f it is a valid 
7ee0: 66 72 61 6d 65 2c 20 66 69 6c 6c 20 2a 70 69 50  frame, fill *piP
7ef0: 61 67 65 20 61 6e 64 0a 2a 2a 20 2a 70 6e 54 72  age and.** *pnTr
7f00: 75 6e 63 61 74 65 20 61 6e 64 20 72 65 74 75 72  uncate and retur
7f10: 6e 20 74 72 75 65 2e 20 20 52 65 74 75 72 6e 20  n true.  Return 
7f20: 69 66 20 74 68 65 20 66 72 61 6d 65 20 69 73 20  if the frame is 
7f30: 6e 6f 74 20 76 61 6c 69 64 2e 0a 2a 2f 0a 73 74  not valid..*/.st
7f40: 61 74 69 63 20 69 6e 74 20 77 61 6c 44 65 63 6f  atic int walDeco
7f50: 64 65 46 72 61 6d 65 28 0a 20 20 57 61 6c 20 2a  deFrame(.  Wal *
7f60: 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  pWal,           
7f70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
7f80: 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f  e write-ahead lo
7f90: 67 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 50 61  g */.  u32 *piPa
7fa0: 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ge,             
7fb0: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 44         /* OUT: D
7fc0: 61 74 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d  atabase page num
7fd0: 62 65 72 20 66 6f 72 20 66 72 61 6d 65 20 2a 2f  ber for frame */
7fe0: 0a 20 20 75 33 32 20 2a 70 6e 54 72 75 6e 63 61  .  u32 *pnTrunca
7ff0: 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  te,             
8000: 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 64     /* OUT: New d
8010: 62 20 73 69 7a 65 20 28 6f 72 20 30 20 69 66 20  b size (or 0 if 
8020: 6e 6f 74 20 63 6f 6d 6d 69 74 29 20 2a 2f 0a 20  not commit) */. 
8030: 20 75 38 20 2a 61 44 61 74 61 2c 20 20 20 20 20   u8 *aData,     
8040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8050: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 70   /* Pointer to p
8060: 61 67 65 20 64 61 74 61 20 28 66 6f 72 20 63 68  age data (for ch
8070: 65 63 6b 73 75 6d 29 20 2a 2f 0a 20 20 75 38 20  ecksum) */.  u8 
8080: 2a 61 46 72 61 6d 65 20 20 20 20 20 20 20 20 20  *aFrame         
8090: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
80a0: 46 72 61 6d 65 20 64 61 74 61 20 2a 2f 0a 29 7b  Frame data */.){
80b0: 0a 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73  .  int nativeCks
80c0: 75 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  um;             
80d0: 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e     /* True for n
80e0: 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64 65 72  ative byte-order
80f0: 20 63 68 65 63 6b 73 75 6d 73 20 2a 2f 0a 20 20   checksums */.  
8100: 75 33 32 20 2a 61 43 6b 73 75 6d 20 3d 20 70 57  u32 *aCksum = pW
8110: 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
8120: 73 75 6d 3b 0a 20 20 75 33 32 20 70 67 6e 6f 3b  sum;.  u32 pgno;
8130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8140: 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e         /* Page n
8150: 75 6d 62 65 72 20 6f 66 20 74 68 65 20 66 72 61  umber of the fra
8160: 6d 65 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  me */.  assert( 
8170: 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a  WAL_FRAME_HDRSIZ
8180: 45 3d 3d 32 34 20 29 3b 0a 0a 20 20 2f 2a 20 41  E==24 );..  /* A
8190: 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20 76   frame is only v
81a0: 61 6c 69 64 20 69 66 20 74 68 65 20 73 61 6c 74  alid if the salt
81b0: 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 66   values in the f
81c0: 72 61 6d 65 2d 68 65 61 64 65 72 0a 20 20 2a 2a  rame-header.  **
81d0: 20 6d 61 74 63 68 20 74 68 65 20 73 61 6c 74 20   match the salt 
81e0: 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 77 61  values in the wa
81f0: 6c 2d 68 65 61 64 65 72 2e 20 0a 20 20 2a 2f 0a  l-header. .  */.
8200: 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57    if( memcmp(&pW
8210: 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 26  al->hdr.aSalt, &
8220: 61 46 72 61 6d 65 5b 38 5d 2c 20 38 29 21 3d 30  aFrame[8], 8)!=0
8230: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30   ){.    return 0
8240: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 20 66 72  ;.  }..  /* A fr
8250: 61 6d 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c 69  ame is only vali
8260: 64 20 69 66 20 74 68 65 20 70 61 67 65 20 6e 75  d if the page nu
8270: 6d 62 65 72 20 69 73 20 63 72 65 61 74 65 72 20  mber is creater 
8280: 74 68 61 6e 20 7a 65 72 6f 2e 0a 20 20 2a 2f 0a  than zero..  */.
8290: 20 20 70 67 6e 6f 20 3d 20 73 71 6c 69 74 65 33    pgno = sqlite3
82a0: 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Get4byte(&aFrame
82b0: 5b 30 5d 29 3b 0a 20 20 69 66 28 20 70 67 6e 6f  [0]);.  if( pgno
82c0: 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  ==0 ){.    retur
82d0: 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41  n 0;.  }..  /* A
82e0: 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20 76   frame is only v
82f0: 61 6c 69 64 20 69 66 20 61 20 63 68 65 63 6b 73  alid if a checks
8300: 75 6d 20 6f 66 20 74 68 65 20 57 41 4c 20 68 65  um of the WAL he
8310: 61 64 65 72 2c 0a 20 20 2a 2a 20 61 6c 6c 20 70  ader,.  ** all p
8320: 72 69 6f 72 20 66 72 61 6d 73 2c 20 74 68 65 20  rior frams, the 
8330: 66 69 72 73 74 20 31 36 20 62 79 74 65 73 20 6f  first 16 bytes o
8340: 66 20 74 68 69 73 20 66 72 61 6d 65 2d 68 65 61  f this frame-hea
8350: 64 65 72 2c 20 0a 20 20 2a 2a 20 61 6e 64 20 74  der, .  ** and t
8360: 68 65 20 66 72 61 6d 65 2d 64 61 74 61 20 6d 61  he frame-data ma
8370: 74 63 68 65 73 20 74 68 65 20 63 68 65 63 6b 73  tches the checks
8380: 75 6d 20 69 6e 20 74 68 65 20 6c 61 73 74 20 38  um in the last 8
8390: 20 0a 20 20 2a 2a 20 62 79 74 65 73 20 6f 66 20   .  ** bytes of 
83a0: 74 68 69 73 20 66 72 61 6d 65 2d 68 65 61 64 65  this frame-heade
83b0: 72 2e 0a 20 20 2a 2f 0a 20 20 6e 61 74 69 76 65  r..  */.  native
83c0: 43 6b 73 75 6d 20 3d 20 28 70 57 61 6c 2d 3e 68  Cksum = (pWal->h
83d0: 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d 3d  dr.bigEndCksum==
83e0: 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e  SQLITE_BIGENDIAN
83f0: 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d  );.  walChecksum
8400: 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75  Bytes(nativeCksu
8410: 6d 2c 20 61 46 72 61 6d 65 2c 20 38 2c 20 61 43  m, aFrame, 8, aC
8420: 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a 20  ksum, aCksum);. 
8430: 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65   walChecksumByte
8440: 73 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 61  s(nativeCksum, a
8450: 44 61 74 61 2c 20 70 57 61 6c 2d 3e 73 7a 50 61  Data, pWal->szPa
8460: 67 65 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73  ge, aCksum, aCks
8470: 75 6d 29 3b 0a 20 20 69 66 28 20 61 43 6b 73 75  um);.  if( aCksu
8480: 6d 5b 30 5d 21 3d 73 71 6c 69 74 65 33 47 65 74  m[0]!=sqlite3Get
8490: 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 31 36  4byte(&aFrame[16
84a0: 5d 29 20 0a 20 20 20 7c 7c 20 61 43 6b 73 75 6d  ]) .   || aCksum
84b0: 5b 31 5d 21 3d 73 71 6c 69 74 65 33 47 65 74 34  [1]!=sqlite3Get4
84c0: 62 79 74 65 28 26 61 46 72 61 6d 65 5b 32 30 5d  byte(&aFrame[20]
84d0: 29 20 0a 20 20 29 7b 0a 20 20 20 20 2f 2a 20 43  ) .  ){.    /* C
84e0: 68 65 63 6b 73 75 6d 20 66 61 69 6c 65 64 2e 20  hecksum failed. 
84f0: 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b  */.    return 0;
8500: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 77 65  .  }..  /* If we
8510: 20 72 65 61 63 68 20 74 68 69 73 20 70 6f 69 6e   reach this poin
8520: 74 2c 20 74 68 65 20 66 72 61 6d 65 20 69 73 20  t, the frame is 
8530: 76 61 6c 69 64 2e 20 20 52 65 74 75 72 6e 20 74  valid.  Return t
8540: 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 20  he page number. 
8550: 20 2a 2a 20 61 6e 64 20 74 68 65 20 6e 65 77 20   ** and the new 
8560: 64 61 74 61 62 61 73 65 20 73 69 7a 65 2e 0a 20  database size.. 
8570: 20 2a 2f 0a 20 20 2a 70 69 50 61 67 65 20 3d 20   */.  *piPage = 
8580: 70 67 6e 6f 3b 0a 20 20 2a 70 6e 54 72 75 6e 63  pgno;.  *pnTrunc
8590: 61 74 65 20 3d 20 73 71 6c 69 74 65 33 47 65 74  ate = sqlite3Get
85a0: 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 34 5d  4byte(&aFrame[4]
85b0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d  );.  return 1;.}
85c0: 0a 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53  ...#if defined(S
85d0: 51 4c 49 54 45 5f 54 45 53 54 29 20 26 26 20 64  QLITE_TEST) && d
85e0: 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45  efined(SQLITE_DE
85f0: 42 55 47 29 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 73  BUG)./*.** Names
8600: 20 6f 66 20 6c 6f 63 6b 73 2e 20 20 54 68 69 73   of locks.  This
8610: 20 72 6f 75 74 69 6e 65 20 69 73 20 75 73 65 64   routine is used
8620: 20 74 6f 20 70 72 6f 76 69 64 65 20 64 65 62 75   to provide debu
8630: 67 67 69 6e 67 20 6f 75 74 70 75 74 20 61 6e 64  gging output and
8640: 20 69 73 20 6e 6f 74 0a 2a 2a 20 61 20 70 61 72   is not.** a par
8650: 74 20 6f 66 20 61 6e 20 6f 72 64 69 6e 61 72 79  t of an ordinary
8660: 20 62 75 69 6c 64 2e 0a 2a 2f 0a 73 74 61 74 69   build..*/.stati
8670: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 77 61  c const char *wa
8680: 6c 4c 6f 63 6b 4e 61 6d 65 28 69 6e 74 20 6c 6f  lLockName(int lo
8690: 63 6b 49 64 78 29 7b 0a 20 20 69 66 28 20 6c 6f  ckIdx){.  if( lo
86a0: 63 6b 49 64 78 3d 3d 57 41 4c 5f 57 52 49 54 45  ckIdx==WAL_WRITE
86b0: 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 72 65 74  _LOCK ){.    ret
86c0: 75 72 6e 20 22 57 52 49 54 45 2d 4c 4f 43 4b 22  urn "WRITE-LOCK"
86d0: 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 6c 6f  ;.  }else if( lo
86e0: 63 6b 49 64 78 3d 3d 57 41 4c 5f 43 4b 50 54 5f  ckIdx==WAL_CKPT_
86f0: 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 72 65 74 75  LOCK ){.    retu
8700: 72 6e 20 22 43 4b 50 54 2d 4c 4f 43 4b 22 3b 0a  rn "CKPT-LOCK";.
8710: 20 20 7d 65 6c 73 65 20 69 66 28 20 6c 6f 63 6b    }else if( lock
8720: 49 64 78 3d 3d 57 41 4c 5f 52 45 43 4f 56 45 52  Idx==WAL_RECOVER
8730: 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 72 65 74  _LOCK ){.    ret
8740: 75 72 6e 20 22 52 45 43 4f 56 45 52 2d 4c 4f 43  urn "RECOVER-LOC
8750: 4b 22 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  K";.  }else{.   
8760: 20 73 74 61 74 69 63 20 63 68 61 72 20 7a 4e 61   static char zNa
8770: 6d 65 5b 31 35 5d 3b 0a 20 20 20 20 73 71 6c 69  me[15];.    sqli
8780: 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a  te3_snprintf(siz
8790: 65 6f 66 28 7a 4e 61 6d 65 29 2c 20 7a 4e 61 6d  eof(zName), zNam
87a0: 65 2c 20 22 52 45 41 44 2d 4c 4f 43 4b 5b 25 64  e, "READ-LOCK[%d
87b0: 5d 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  ]",.            
87c0: 20 20 20 20 20 20 20 20 20 6c 6f 63 6b 49 64 78           lockIdx
87d0: 2d 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30  -WAL_READ_LOCK(0
87e0: 29 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 7a  ));.    return z
87f0: 4e 61 6d 65 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64  Name;.  }.}.#end
8800: 69 66 20 2f 2a 64 65 66 69 6e 65 64 28 53 51 4c  if /*defined(SQL
8810: 49 54 45 5f 54 45 53 54 29 20 7c 7c 20 64 65 66  ITE_TEST) || def
8820: 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42 55  ined(SQLITE_DEBU
8830: 47 29 20 2a 2f 0a 20 20 20 20 0a 0a 2f 2a 0a 2a  G) */.    ../*.*
8840: 2a 20 53 65 74 20 6f 72 20 72 65 6c 65 61 73 65  * Set or release
8850: 20 6c 6f 63 6b 73 20 6f 6e 20 74 68 65 20 57 41   locks on the WA
8860: 4c 2e 20 20 4c 6f 63 6b 73 20 61 72 65 20 65 69  L.  Locks are ei
8870: 74 68 65 72 20 73 68 61 72 65 64 20 6f 72 20 65  ther shared or e
8880: 78 63 6c 75 73 69 76 65 2e 0a 2a 2a 20 41 20 6c  xclusive..** A l
8890: 6f 63 6b 20 63 61 6e 6e 6f 74 20 62 65 20 6d 6f  ock cannot be mo
88a0: 76 65 64 20 64 69 72 65 63 74 6c 79 20 62 65 74  ved directly bet
88b0: 77 65 65 6e 20 73 68 61 72 65 64 20 61 6e 64 20  ween shared and 
88c0: 65 78 63 6c 75 73 69 76 65 20 2d 20 69 74 20 6d  exclusive - it m
88d0: 75 73 74 20 67 6f 0a 2a 2a 20 74 68 72 6f 75 67  ust go.** throug
88e0: 68 20 74 68 65 20 75 6e 6c 6f 63 6b 65 64 20 73  h the unlocked s
88f0: 74 61 74 65 20 66 69 72 73 74 2e 0a 2a 2a 0a 2a  tate first..**.*
8900: 2a 20 49 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64  * In locking_mod
8910: 65 3d 45 58 43 4c 55 53 49 56 45 2c 20 61 6c 6c  e=EXCLUSIVE, all
8920: 20 6f 66 20 74 68 65 73 65 20 72 6f 75 74 69 6e   of these routin
8930: 65 73 20 62 65 63 6f 6d 65 20 6e 6f 2d 6f 70 73  es become no-ops
8940: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
8950: 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 57 61  walLockShared(Wa
8960: 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f 63  l *pWal, int loc
8970: 6b 49 64 78 29 7b 0a 20 20 69 6e 74 20 72 63 3b  kIdx){.  int rc;
8980: 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63  .  if( pWal->exc
8990: 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65 74  lusiveMode ) ret
89a0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  urn SQLITE_OK;. 
89b0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53   rc = sqlite3OsS
89c0: 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62  hmLock(pWal->pDb
89d0: 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 31 2c 0a  Fd, lockIdx, 1,.
89e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
89f0: 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53          SQLITE_S
8a00: 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45  HM_LOCK | SQLITE
8a10: 5f 53 48 4d 5f 53 48 41 52 45 44 29 3b 0a 20 20  _SHM_SHARED);.  
8a20: 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70  WALTRACE(("WAL%p
8a30: 3a 20 61 63 71 75 69 72 65 20 53 48 41 52 45 44  : acquire SHARED
8a40: 2d 25 73 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c  -%s %s\n", pWal,
8a50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 77 61 6c  .            wal
8a60: 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64 78  LockName(lockIdx
8a70: 29 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22  ), rc ? "failed"
8a80: 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 56 56 41   : "ok"));.  VVA
8a90: 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f 63  _ONLY( pWal->loc
8aa0: 6b 45 72 72 6f 72 20 3d 20 28 75 38 29 28 72 63  kError = (u8)(rc
8ab0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72  !=SQLITE_OK && r
8ac0: 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 29 3b  c!=SQLITE_BUSY);
8ad0: 20 29 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   ).  return rc;.
8ae0: 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61  }.static void wa
8af0: 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 57 61  lUnlockShared(Wa
8b00: 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f 63  l *pWal, int loc
8b10: 6b 49 64 78 29 7b 0a 20 20 69 66 28 20 70 57 61  kIdx){.  if( pWa
8b20: 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
8b30: 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 28 76 6f   ) return;.  (vo
8b40: 69 64 29 73 71 6c 69 74 65 33 4f 73 53 68 6d 4c  id)sqlite3OsShmL
8b50: 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  ock(pWal->pDbFd,
8b60: 20 6c 6f 63 6b 49 64 78 2c 20 31 2c 0a 20 20 20   lockIdx, 1,.   
8b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b80: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53 48 4d        SQLITE_SHM
8b90: 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45  _UNLOCK | SQLITE
8ba0: 5f 53 48 4d 5f 53 48 41 52 45 44 29 3b 0a 20 20  _SHM_SHARED);.  
8bb0: 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70  WALTRACE(("WAL%p
8bc0: 3a 20 72 65 6c 65 61 73 65 20 53 48 41 52 45 44  : release SHARED
8bd0: 2d 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 77 61  -%s\n", pWal, wa
8be0: 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64  lLockName(lockId
8bf0: 78 29 29 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69  x)));.}.static i
8c00: 6e 74 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73  nt walLockExclus
8c10: 69 76 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69  ive(Wal *pWal, i
8c20: 6e 74 20 6c 6f 63 6b 49 64 78 2c 20 69 6e 74 20  nt lockIdx, int 
8c30: 6e 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  n){.  int rc;.  
8c40: 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  if( pWal->exclus
8c50: 69 76 65 4d 6f 64 65 20 29 20 72 65 74 75 72 6e  iveMode ) return
8c60: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72 63   SQLITE_OK;.  rc
8c70: 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4c   = sqlite3OsShmL
8c80: 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  ock(pWal->pDbFd,
8c90: 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c 0a 20 20 20   lockIdx, n,.   
8ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8cb0: 20 20 20 20 20 53 51 4c 49 54 45 5f 53 48 4d 5f       SQLITE_SHM_
8cc0: 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48  LOCK | SQLITE_SH
8cd0: 4d 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20  M_EXCLUSIVE);.  
8ce0: 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70  WALTRACE(("WAL%p
8cf0: 3a 20 61 63 71 75 69 72 65 20 45 58 43 4c 55 53  : acquire EXCLUS
8d00: 49 56 45 2d 25 73 20 63 6e 74 3d 25 64 20 25 73  IVE-%s cnt=%d %s
8d10: 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20 20 20 20 20  \n", pWal,.     
8d20: 20 20 20 20 20 20 20 77 61 6c 4c 6f 63 6b 4e 61         walLockNa
8d30: 6d 65 28 6c 6f 63 6b 49 64 78 29 2c 20 6e 2c 20  me(lockIdx), n, 
8d40: 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20  rc ? "failed" : 
8d50: 22 6f 6b 22 29 29 3b 0a 20 20 56 56 41 5f 4f 4e  "ok"));.  VVA_ON
8d60: 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72  LY( pWal->lockEr
8d70: 72 6f 72 20 3d 20 28 75 38 29 28 72 63 21 3d 53  ror = (u8)(rc!=S
8d80: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72 63 21 3d  QLITE_OK && rc!=
8d90: 53 51 4c 49 54 45 5f 42 55 53 59 29 3b 20 29 0a  SQLITE_BUSY); ).
8da0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73    return rc;.}.s
8db0: 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 55 6e  tatic void walUn
8dc0: 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 57 61  lockExclusive(Wa
8dd0: 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f 63  l *pWal, int loc
8de0: 6b 49 64 78 2c 20 69 6e 74 20 6e 29 7b 0a 20 20  kIdx, int n){.  
8df0: 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  if( pWal->exclus
8e00: 69 76 65 4d 6f 64 65 20 29 20 72 65 74 75 72 6e  iveMode ) return
8e10: 3b 0a 20 20 28 76 6f 69 64 29 73 71 6c 69 74 65  ;.  (void)sqlite
8e20: 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d  3OsShmLock(pWal-
8e30: 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c  >pDbFd, lockIdx,
8e40: 20 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20   n,.            
8e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
8e60: 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f 43 4b 20 7c  ITE_SHM_UNLOCK |
8e70: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 45 58 43 4c   SQLITE_SHM_EXCL
8e80: 55 53 49 56 45 29 3b 0a 20 20 57 41 4c 54 52 41  USIVE);.  WALTRA
8e90: 43 45 28 28 22 57 41 4c 25 70 3a 20 72 65 6c 65  CE(("WAL%p: rele
8ea0: 61 73 65 20 45 58 43 4c 55 53 49 56 45 2d 25 73  ase EXCLUSIVE-%s
8eb0: 20 63 6e 74 3d 25 64 5c 6e 22 2c 20 70 57 61 6c   cnt=%d\n", pWal
8ec0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 77  ,.             w
8ed0: 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49  alLockName(lockI
8ee0: 64 78 29 2c 20 6e 29 29 3b 0a 7d 0a 0a 2f 2a 0a  dx), n));.}../*.
8ef0: 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20 68 61 73  ** Compute a has
8f00: 68 20 6f 6e 20 61 20 70 61 67 65 20 6e 75 6d 62  h on a page numb
8f10: 65 72 2e 20 20 54 68 65 20 72 65 73 75 6c 74 69  er.  The resulti
8f20: 6e 67 20 68 61 73 68 20 76 61 6c 75 65 20 6d 75  ng hash value mu
8f30: 73 74 20 6c 61 6e 64 0a 2a 2a 20 62 65 74 77 65  st land.** betwe
8f40: 65 6e 20 30 20 61 6e 64 20 28 48 41 53 48 54 41  en 0 and (HASHTA
8f50: 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 2e 20 20 54  BLE_NSLOT-1).  T
8f60: 68 65 20 77 61 6c 48 61 73 68 4e 65 78 74 28 29  he walHashNext()
8f70: 20 66 75 6e 63 74 69 6f 6e 20 61 64 76 61 6e 63   function advanc
8f80: 65 73 0a 2a 2a 20 74 68 65 20 68 61 73 68 20 74  es.** the hash t
8f90: 6f 20 74 68 65 20 6e 65 78 74 20 76 61 6c 75 65  o the next value
8fa0: 20 69 6e 20 74 68 65 20 65 76 65 6e 74 20 6f 66   in the event of
8fb0: 20 61 20 63 6f 6c 6c 69 73 69 6f 6e 2e 0a 2a 2f   a collision..*/
8fc0: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 48  .static int walH
8fd0: 61 73 68 28 75 33 32 20 69 50 61 67 65 29 7b 0a  ash(u32 iPage){.
8fe0: 20 20 61 73 73 65 72 74 28 20 69 50 61 67 65 3e    assert( iPage>
8ff0: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 28  0 );.  assert( (
9000: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20  HASHTABLE_NSLOT 
9010: 26 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c  & (HASHTABLE_NSL
9020: 4f 54 2d 31 29 29 3d 3d 30 20 29 3b 0a 20 20 72  OT-1))==0 );.  r
9030: 65 74 75 72 6e 20 28 69 50 61 67 65 2a 48 41 53  eturn (iPage*HAS
9040: 48 54 41 42 4c 45 5f 48 41 53 48 5f 31 29 20 26  HTABLE_HASH_1) &
9050: 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f   (HASHTABLE_NSLO
9060: 54 2d 31 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69  T-1);.}.static i
9070: 6e 74 20 77 61 6c 4e 65 78 74 48 61 73 68 28 69  nt walNextHash(i
9080: 6e 74 20 69 50 72 69 6f 72 48 61 73 68 29 7b 0a  nt iPriorHash){.
9090: 20 20 72 65 74 75 72 6e 20 28 69 50 72 69 6f 72    return (iPrior
90a0: 48 61 73 68 2b 31 29 26 28 48 41 53 48 54 41 42  Hash+1)&(HASHTAB
90b0: 4c 45 5f 4e 53 4c 4f 54 2d 31 29 3b 0a 7d 0a 0a  LE_NSLOT-1);.}..
90c0: 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 70 6f  /* .** Return po
90d0: 69 6e 74 65 72 73 20 74 6f 20 74 68 65 20 68 61  inters to the ha
90e0: 73 68 20 74 61 62 6c 65 20 61 6e 64 20 70 61 67  sh table and pag
90f0: 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 73  e number array s
9100: 74 6f 72 65 64 20 6f 6e 0a 2a 2a 20 70 61 67 65  tored on.** page
9110: 20 69 48 61 73 68 20 6f 66 20 74 68 65 20 77 61   iHash of the wa
9120: 6c 2d 69 6e 64 65 78 2e 20 54 68 65 20 77 61 6c  l-index. The wal
9130: 2d 69 6e 64 65 78 20 69 73 20 62 72 6f 6b 65 6e  -index is broken
9140: 20 69 6e 74 6f 20 33 32 4b 42 20 70 61 67 65 73   into 32KB pages
9150: 0a 2a 2a 20 6e 75 6d 62 65 72 65 64 20 73 74 61  .** numbered sta
9160: 72 74 69 6e 67 20 66 72 6f 6d 20 30 2e 0a 2a 2a  rting from 0..**
9170: 0a 2a 2a 20 53 65 74 20 6f 75 74 70 75 74 20 76  .** Set output v
9180: 61 72 69 61 62 6c 65 20 2a 70 61 48 61 73 68 20  ariable *paHash 
9190: 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20  to point to the 
91a0: 73 74 61 72 74 20 6f 66 20 74 68 65 20 68 61 73  start of the has
91b0: 68 20 74 61 62 6c 65 0a 2a 2a 20 69 6e 20 74 68  h table.** in th
91c0: 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65  e wal-index file
91d0: 2e 20 53 65 74 20 2a 70 69 5a 65 72 6f 20 74 6f  . Set *piZero to
91e0: 20 6f 6e 65 20 6c 65 73 73 20 74 68 61 6e 20 74   one less than t
91f0: 68 65 20 66 72 61 6d 65 20 0a 2a 2a 20 6e 75 6d  he frame .** num
9200: 62 65 72 20 6f 66 20 74 68 65 20 66 69 72 73 74  ber of the first
9210: 20 66 72 61 6d 65 20 69 6e 64 65 78 65 64 20 62   frame indexed b
9220: 79 20 74 68 69 73 20 68 61 73 68 20 74 61 62 6c  y this hash tabl
9230: 65 2e 20 49 66 20 61 0a 2a 2a 20 73 6c 6f 74 20  e. If a.** slot 
9240: 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  in the hash tabl
9250: 65 20 69 73 20 73 65 74 20 74 6f 20 4e 2c 20 69  e is set to N, i
9260: 74 20 72 65 66 65 72 73 20 74 6f 20 66 72 61 6d  t refers to fram
9270: 65 20 6e 75 6d 62 65 72 20 0a 2a 2a 20 28 2a 70  e number .** (*p
9280: 69 5a 65 72 6f 2b 4e 29 20 69 6e 20 74 68 65 20  iZero+N) in the 
9290: 6c 6f 67 2e 0a 2a 2a 0a 2a 2a 20 46 69 6e 61 6c  log..**.** Final
92a0: 6c 79 2c 20 73 65 74 20 2a 70 61 50 67 6e 6f 20  ly, set *paPgno 
92b0: 73 6f 20 74 68 61 74 20 2a 70 61 50 67 6e 6f 5b  so that *paPgno[
92c0: 31 5d 20 69 73 20 74 68 65 20 70 61 67 65 20 6e  1] is the page n
92d0: 75 6d 62 65 72 20 6f 66 20 74 68 65 0a 2a 2a 20  umber of the.** 
92e0: 66 69 72 73 74 20 66 72 61 6d 65 20 69 6e 64 65  first frame inde
92f0: 78 65 64 20 62 79 20 74 68 65 20 68 61 73 68 20  xed by the hash 
9300: 74 61 62 6c 65 2c 20 66 72 61 6d 65 20 28 2a 70  table, frame (*p
9310: 69 5a 65 72 6f 2b 31 29 2e 0a 2a 2f 0a 73 74 61  iZero+1)..*/.sta
9320: 74 69 63 20 69 6e 74 20 77 61 6c 48 61 73 68 47  tic int walHashG
9330: 65 74 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c  et(.  Wal *pWal,
9340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9350: 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 68 61 6e        /* WAL han
9360: 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 69 48 61  dle */.  int iHa
9370: 73 68 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  sh,             
9380: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6e 64           /* Find
9390: 20 74 68 65 20 69 48 61 73 68 27 74 68 20 74 61   the iHash'th ta
93a0: 62 6c 65 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c  ble */.  volatil
93b0: 65 20 68 74 5f 73 6c 6f 74 20 2a 2a 70 61 48 61  e ht_slot **paHa
93c0: 73 68 2c 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a  sh,      /* OUT:
93d0: 20 50 6f 69 6e 74 65 72 20 74 6f 20 68 61 73 68   Pointer to hash
93e0: 20 69 6e 64 65 78 20 2a 2f 0a 20 20 76 6f 6c 61   index */.  vola
93f0: 74 69 6c 65 20 75 33 32 20 2a 2a 70 61 50 67 6e  tile u32 **paPgn
9400: 6f 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f  o,          /* O
9410: 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20 70  UT: Pointer to p
9420: 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79  age number array
9430: 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 5a 65 72   */.  u32 *piZer
9440: 6f 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o               
9450: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 46 72        /* OUT: Fr
9460: 61 6d 65 20 61 73 73 6f 63 69 61 74 65 64 20 77  ame associated w
9470: 69 74 68 20 2a 70 61 50 67 6e 6f 5b 30 5d 20 2a  ith *paPgno[0] *
9480: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20  /.){.  int rc;  
9490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
94a0: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
94b0: 20 63 6f 64 65 20 2a 2f 0a 20 20 76 6f 6c 61 74   code */.  volat
94c0: 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 3b 0a  ile u32 *aPgno;.
94d0: 0a 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78  .  rc = walIndex
94e0: 50 61 67 65 28 70 57 61 6c 2c 20 69 48 61 73 68  Page(pWal, iHash
94f0: 2c 20 26 61 50 67 6e 6f 29 3b 0a 20 20 61 73 73  , &aPgno);.  ass
9500: 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ert( rc==SQLITE_
9510: 4f 4b 20 7c 7c 20 69 48 61 73 68 3e 30 20 29 3b  OK || iHash>0 );
9520: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
9530: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 75 33 32  TE_OK ){.    u32
9540: 20 69 5a 65 72 6f 3b 0a 20 20 20 20 76 6f 6c 61   iZero;.    vola
9550: 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 61 48  tile ht_slot *aH
9560: 61 73 68 3b 0a 0a 20 20 20 20 61 48 61 73 68 20  ash;..    aHash 
9570: 3d 20 28 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73  = (volatile ht_s
9580: 6c 6f 74 20 2a 29 26 61 50 67 6e 6f 5b 48 41 53  lot *)&aPgno[HAS
9590: 48 54 41 42 4c 45 5f 4e 50 41 47 45 5d 3b 0a 20  HTABLE_NPAGE];. 
95a0: 20 20 20 69 66 28 20 69 48 61 73 68 3d 3d 30 20     if( iHash==0 
95b0: 29 7b 0a 20 20 20 20 20 20 61 50 67 6e 6f 20 3d  ){.      aPgno =
95c0: 20 26 61 50 67 6e 6f 5b 57 41 4c 49 4e 44 45 58   &aPgno[WALINDEX
95d0: 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f 66  _HDR_SIZE/sizeof
95e0: 28 75 33 32 29 5d 3b 0a 20 20 20 20 20 20 69 5a  (u32)];.      iZ
95f0: 65 72 6f 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c  ero = 0;.    }el
9600: 73 65 7b 0a 20 20 20 20 20 20 69 5a 65 72 6f 20  se{.      iZero 
9610: 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  = HASHTABLE_NPAG
9620: 45 5f 4f 4e 45 20 2b 20 28 69 48 61 73 68 2d 31  E_ONE + (iHash-1
9630: 29 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  )*HASHTABLE_NPAG
9640: 45 3b 0a 20 20 20 20 7d 0a 20 20 0a 20 20 20 20  E;.    }.  .    
9650: 2a 70 61 50 67 6e 6f 20 3d 20 26 61 50 67 6e 6f  *paPgno = &aPgno
9660: 5b 2d 31 5d 3b 0a 20 20 20 20 2a 70 61 48 61 73  [-1];.    *paHas
9670: 68 20 3d 20 61 48 61 73 68 3b 0a 20 20 20 20 2a  h = aHash;.    *
9680: 70 69 5a 65 72 6f 20 3d 20 69 5a 65 72 6f 3b 0a  piZero = iZero;.
9690: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
96a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
96b0: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 74   the number of t
96c0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 70 61 67  he wal-index pag
96d0: 65 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  e that contains 
96e0: 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65 0a 2a  the hash-table.*
96f0: 2a 20 61 6e 64 20 70 61 67 65 2d 6e 75 6d 62 65  * and page-numbe
9700: 72 20 61 72 72 61 79 20 74 68 61 74 20 63 6f 6e  r array that con
9710: 74 61 69 6e 20 65 6e 74 72 69 65 73 20 63 6f 72  tain entries cor
9720: 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 57 41  responding to WA
9730: 4c 20 66 72 61 6d 65 0a 2a 2a 20 69 46 72 61 6d  L frame.** iFram
9740: 65 2e 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78  e. The wal-index
9750: 20 69 73 20 62 72 6f 6b 65 6e 20 75 70 20 69 6e   is broken up in
9760: 74 6f 20 33 32 4b 42 20 70 61 67 65 73 2e 20 57  to 32KB pages. W
9770: 61 6c 2d 69 6e 64 65 78 20 70 61 67 65 73 20 0a  al-index pages .
9780: 2a 2a 20 61 72 65 20 6e 75 6d 62 65 72 65 64 20  ** are numbered 
9790: 73 74 61 72 74 69 6e 67 20 66 72 6f 6d 20 30 2e  starting from 0.
97a0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
97b0: 61 6c 46 72 61 6d 65 50 61 67 65 28 75 33 32 20  alFramePage(u32 
97c0: 69 46 72 61 6d 65 29 7b 0a 20 20 69 6e 74 20 69  iFrame){.  int i
97d0: 48 61 73 68 20 3d 20 28 69 46 72 61 6d 65 2b 48  Hash = (iFrame+H
97e0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 2d 48  ASHTABLE_NPAGE-H
97f0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
9800: 4e 45 2d 31 29 20 2f 20 48 41 53 48 54 41 42 4c  NE-1) / HASHTABL
9810: 45 5f 4e 50 41 47 45 3b 0a 20 20 61 73 73 65 72  E_NPAGE;.  asser
9820: 74 28 20 28 69 48 61 73 68 3d 3d 30 20 7c 7c 20  t( (iHash==0 || 
9830: 69 46 72 61 6d 65 3e 48 41 53 48 54 41 42 4c 45  iFrame>HASHTABLE
9840: 5f 4e 50 41 47 45 5f 4f 4e 45 29 0a 20 20 20 20  _NPAGE_ONE).    
9850: 20 20 20 26 26 20 28 69 48 61 73 68 3e 3d 31 20     && (iHash>=1 
9860: 7c 7c 20 69 46 72 61 6d 65 3c 3d 48 41 53 48 54  || iFrame<=HASHT
9870: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 0a  ABLE_NPAGE_ONE).
9880: 20 20 20 20 20 20 20 26 26 20 28 69 48 61 73 68         && (iHash
9890: 3c 3d 31 20 7c 7c 20 69 46 72 61 6d 65 3e 28 48  <=1 || iFrame>(H
98a0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
98b0: 4e 45 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  NE+HASHTABLE_NPA
98c0: 47 45 29 29 0a 20 20 20 20 20 20 20 26 26 20 28  GE)).       && (
98d0: 69 48 61 73 68 3e 3d 32 20 7c 7c 20 69 46 72 61  iHash>=2 || iFra
98e0: 6d 65 3c 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50  me<=HASHTABLE_NP
98f0: 41 47 45 5f 4f 4e 45 2b 48 41 53 48 54 41 42 4c  AGE_ONE+HASHTABL
9900: 45 5f 4e 50 41 47 45 29 0a 20 20 20 20 20 20 20  E_NPAGE).       
9910: 26 26 20 28 69 48 61 73 68 3c 3d 32 20 7c 7c 20  && (iHash<=2 || 
9920: 69 46 72 61 6d 65 3e 28 48 41 53 48 54 41 42 4c  iFrame>(HASHTABL
9930: 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 32 2a 48 41  E_NPAGE_ONE+2*HA
9940: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 29 29 0a  SHTABLE_NPAGE)).
9950: 20 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 69 48    );.  return iH
9960: 61 73 68 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  ash;.}../*.** Re
9970: 74 75 72 6e 20 74 68 65 20 70 61 67 65 20 6e 75  turn the page nu
9980: 6d 62 65 72 20 61 73 73 6f 63 69 61 74 65 64 20  mber associated 
9990: 77 69 74 68 20 66 72 61 6d 65 20 69 46 72 61 6d  with frame iFram
99a0: 65 20 69 6e 20 74 68 69 73 20 57 41 4c 2e 0a 2a  e in this WAL..*
99b0: 2f 0a 73 74 61 74 69 63 20 75 33 32 20 77 61 6c  /.static u32 wal
99c0: 46 72 61 6d 65 50 67 6e 6f 28 57 61 6c 20 2a 70  FramePgno(Wal *p
99d0: 57 61 6c 2c 20 75 33 32 20 69 46 72 61 6d 65 29  Wal, u32 iFrame)
99e0: 7b 0a 20 20 69 6e 74 20 69 48 61 73 68 20 3d 20  {.  int iHash = 
99f0: 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69 46 72  walFramePage(iFr
9a00: 61 6d 65 29 3b 0a 20 20 69 66 28 20 69 48 61 73  ame);.  if( iHas
9a10: 68 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  h==0 ){.    retu
9a20: 72 6e 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  rn pWal->apWiDat
9a30: 61 5b 30 5d 5b 57 41 4c 49 4e 44 45 58 5f 48 44  a[0][WALINDEX_HD
9a40: 52 5f 53 49 5a 45 2f 73 69 7a 65 6f 66 28 75 33  R_SIZE/sizeof(u3
9a50: 32 29 20 2b 20 69 46 72 61 6d 65 20 2d 20 31 5d  2) + iFrame - 1]
9a60: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70  ;.  }.  return p
9a70: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 48  Wal->apWiData[iH
9a80: 61 73 68 5d 5b 28 69 46 72 61 6d 65 2d 31 2d 48  ash][(iFrame-1-H
9a90: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
9aa0: 4e 45 29 25 48 41 53 48 54 41 42 4c 45 5f 4e 50  NE)%HASHTABLE_NP
9ab0: 41 47 45 5d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  AGE];.}../*.** R
9ac0: 65 6d 6f 76 65 20 65 6e 74 72 69 65 73 20 66 72  emove entries fr
9ad0: 6f 6d 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  om the hash tabl
9ae0: 65 20 74 68 61 74 20 70 6f 69 6e 74 20 74 6f 20  e that point to 
9af0: 57 41 4c 20 73 6c 6f 74 73 20 67 72 65 61 74 65  WAL slots greate
9b00: 72 0a 2a 2a 20 74 68 61 6e 20 70 57 61 6c 2d 3e  r.** than pWal->
9b10: 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a 2a 2a 0a  hdr.mxFrame..**.
9b20: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
9b30: 20 69 73 20 63 61 6c 6c 65 64 20 77 68 65 6e 65   is called whene
9b40: 76 65 72 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  ver pWal->hdr.mx
9b50: 46 72 61 6d 65 20 69 73 20 64 65 63 72 65 61 73  Frame is decreas
9b60: 65 64 20 64 75 65 0a 2a 2a 20 74 6f 20 61 20 72  ed due.** to a r
9b70: 6f 6c 6c 62 61 63 6b 20 6f 72 20 73 61 76 65 70  ollback or savep
9b80: 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20 41 74 20 6d  oint..**.** At m
9b90: 6f 73 74 20 6f 6e 6c 79 20 74 68 65 20 68 61 73  ost only the has
9ba0: 68 20 74 61 62 6c 65 20 63 6f 6e 74 61 69 6e 69  h table containi
9bb0: 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ng pWal->hdr.mxF
9bc0: 72 61 6d 65 20 6e 65 65 64 73 20 74 6f 20 62 65  rame needs to be
9bd0: 0a 2a 2a 20 75 70 64 61 74 65 64 2e 20 20 41 6e  .** updated.  An
9be0: 79 20 6c 61 74 65 72 20 68 61 73 68 20 74 61 62  y later hash tab
9bf0: 6c 65 73 20 77 69 6c 6c 20 62 65 20 61 75 74 6f  les will be auto
9c00: 6d 61 74 69 63 61 6c 6c 79 20 63 6c 65 61 72 65  matically cleare
9c10: 64 20 77 68 65 6e 0a 2a 2a 20 70 57 61 6c 2d 3e  d when.** pWal->
9c20: 68 64 72 2e 6d 78 46 72 61 6d 65 20 61 64 76 61  hdr.mxFrame adva
9c30: 6e 63 65 73 20 74 6f 20 74 68 65 20 70 6f 69 6e  nces to the poin
9c40: 74 20 77 68 65 72 65 20 74 68 6f 73 65 20 68 61  t where those ha
9c50: 73 68 20 74 61 62 6c 65 73 20 61 72 65 0a 2a 2a  sh tables are.**
9c60: 20 61 63 74 75 61 6c 6c 79 20 6e 65 65 64 65 64   actually needed
9c70: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
9c80: 20 77 61 6c 43 6c 65 61 6e 75 70 48 61 73 68 28   walCleanupHash(
9c90: 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 76 6f  Wal *pWal){.  vo
9ca0: 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a  latile ht_slot *
9cb0: 61 48 61 73 68 20 3d 20 30 3b 20 20 20 20 2f 2a  aHash = 0;    /*
9cc0: 20 50 6f 69 6e 74 65 72 20 74 6f 20 68 61 73 68   Pointer to hash
9cd0: 20 74 61 62 6c 65 20 74 6f 20 63 6c 65 61 72 20   table to clear 
9ce0: 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33  */.  volatile u3
9cf0: 32 20 2a 61 50 67 6e 6f 20 3d 20 30 3b 20 20 20  2 *aPgno = 0;   
9d00: 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d       /* Page num
9d10: 62 65 72 20 61 72 72 61 79 20 66 6f 72 20 68 61  ber array for ha
9d20: 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 75 33  sh table */.  u3
9d30: 32 20 69 5a 65 72 6f 20 3d 20 30 3b 20 20 20 20  2 iZero = 0;    
9d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9d50: 20 66 72 61 6d 65 20 3d 3d 20 28 61 48 61 73 68   frame == (aHash
9d60: 5b 78 5d 2b 69 5a 65 72 6f 29 20 2a 2f 0a 20 20  [x]+iZero) */.  
9d70: 69 6e 74 20 69 4c 69 6d 69 74 20 3d 20 30 3b 20  int iLimit = 0; 
9d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9d90: 2f 2a 20 5a 65 72 6f 20 76 61 6c 75 65 73 20 67  /* Zero values g
9da0: 72 65 61 74 65 72 20 74 68 61 6e 20 74 68 69 73  reater than this
9db0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b   */.  int nByte;
9dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9dd0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
9de0: 6f 66 20 62 79 74 65 73 20 74 6f 20 7a 65 72 6f  of bytes to zero
9df0: 20 69 6e 20 61 50 67 6e 6f 5b 5d 20 2a 2f 0a 20   in aPgno[] */. 
9e00: 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
9e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9e20: 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65 72   /* Used to iter
9e30: 61 74 65 20 74 68 72 6f 75 67 68 20 61 48 61 73  ate through aHas
9e40: 68 5b 5d 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  h[] */..  assert
9e50: 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
9e60: 6b 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28  k );.  testcase(
9e70: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
9e80: 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50  me==HASHTABLE_NP
9e90: 41 47 45 5f 4f 4e 45 2d 31 20 29 3b 0a 20 20 74  AGE_ONE-1 );.  t
9ea0: 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d 3e 68  estcase( pWal->h
9eb0: 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 48 41 53 48  dr.mxFrame==HASH
9ec0: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20  TABLE_NPAGE_ONE 
9ed0: 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 70  );.  testcase( p
9ee0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
9ef0: 3d 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  ==HASHTABLE_NPAG
9f00: 45 5f 4f 4e 45 2b 31 20 29 3b 0a 0a 20 20 69 66  E_ONE+1 );..  if
9f10: 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  ( pWal->hdr.mxFr
9f20: 61 6d 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b  ame==0 ) return;
9f30: 0a 0a 20 20 2f 2a 20 4f 62 74 61 69 6e 20 70 6f  ..  /* Obtain po
9f40: 69 6e 74 65 72 73 20 74 6f 20 74 68 65 20 68 61  inters to the ha
9f50: 73 68 2d 74 61 62 6c 65 20 61 6e 64 20 70 61 67  sh-table and pag
9f60: 65 2d 6e 75 6d 62 65 72 20 61 72 72 61 79 20 63  e-number array c
9f70: 6f 6e 74 61 69 6e 69 6e 67 20 0a 20 20 2a 2a 20  ontaining .  ** 
9f80: 74 68 65 20 65 6e 74 72 79 20 74 68 61 74 20 63  the entry that c
9f90: 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20 66 72  orresponds to fr
9fa0: 61 6d 65 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  ame pWal->hdr.mx
9fb0: 46 72 61 6d 65 2e 20 49 74 20 69 73 20 67 75 61  Frame. It is gua
9fc0: 72 61 6e 74 65 65 64 0a 20 20 2a 2a 20 74 68 61  ranteed.  ** tha
9fd0: 74 20 74 68 65 20 70 61 67 65 20 73 61 69 64 20  t the page said 
9fe0: 68 61 73 68 2d 74 61 62 6c 65 20 61 6e 64 20 61  hash-table and a
9ff0: 72 72 61 79 20 72 65 73 69 64 65 20 6f 6e 20 69  rray reside on i
a000: 73 20 61 6c 72 65 61 64 79 20 6d 61 70 70 65 64  s already mapped
a010: 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  ..  */.  assert(
a020: 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 77   pWal->nWiData>w
a030: 61 6c 46 72 61 6d 65 50 61 67 65 28 70 57 61 6c  alFramePage(pWal
a040: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 29 20 29  ->hdr.mxFrame) )
a050: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ;.  assert( pWal
a060: 2d 3e 61 70 57 69 44 61 74 61 5b 77 61 6c 46 72  ->apWiData[walFr
a070: 61 6d 65 50 61 67 65 28 70 57 61 6c 2d 3e 68 64  amePage(pWal->hd
a080: 72 2e 6d 78 46 72 61 6d 65 29 5d 20 29 3b 0a 20  r.mxFrame)] );. 
a090: 20 77 61 6c 48 61 73 68 47 65 74 28 70 57 61 6c   walHashGet(pWal
a0a0: 2c 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 70  , walFramePage(p
a0b0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
a0c0: 29 2c 20 26 61 48 61 73 68 2c 20 26 61 50 67 6e  ), &aHash, &aPgn
a0d0: 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 0a 20 20 2f  o, &iZero);..  /
a0e0: 2a 20 5a 65 72 6f 20 61 6c 6c 20 68 61 73 68 2d  * Zero all hash-
a0f0: 74 61 62 6c 65 20 65 6e 74 72 69 65 73 20 74 68  table entries th
a100: 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 20 74 6f  at correspond to
a110: 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 73 20 67   frame numbers g
a120: 72 65 61 74 65 72 0a 20 20 2a 2a 20 74 68 61 6e  reater.  ** than
a130: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
a140: 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 4c 69 6d 69  me..  */.  iLimi
a150: 74 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  t = pWal->hdr.mx
a160: 46 72 61 6d 65 20 2d 20 69 5a 65 72 6f 3b 0a 20  Frame - iZero;. 
a170: 20 61 73 73 65 72 74 28 20 69 4c 69 6d 69 74 3e   assert( iLimit>
a180: 30 20 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  0 );.  for(i=0; 
a190: 69 3c 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f  i<HASHTABLE_NSLO
a1a0: 54 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  T; i++){.    if(
a1b0: 20 61 48 61 73 68 5b 69 5d 3e 69 4c 69 6d 69 74   aHash[i]>iLimit
a1c0: 20 29 7b 0a 20 20 20 20 20 20 61 48 61 73 68 5b   ){.      aHash[
a1d0: 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20  i] = 0;.    }.  
a1e0: 7d 0a 20 20 0a 20 20 2f 2a 20 5a 65 72 6f 20 74  }.  .  /* Zero t
a1f0: 68 65 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68  he entries in th
a200: 65 20 61 50 67 6e 6f 20 61 72 72 61 79 20 74 68  e aPgno array th
a210: 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 20 74 6f  at correspond to
a220: 20 66 72 61 6d 65 73 20 77 69 74 68 0a 20 20 2a   frames with.  *
a230: 2a 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 73 20  * frame numbers 
a240: 67 72 65 61 74 65 72 20 74 68 61 6e 20 70 57 61  greater than pWa
a250: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 20  l->hdr.mxFrame. 
a260: 0a 20 20 2a 2f 0a 20 20 6e 42 79 74 65 20 3d 20  .  */.  nByte = 
a270: 28 69 6e 74 29 28 28 63 68 61 72 20 2a 29 61 48  (int)((char *)aH
a280: 61 73 68 20 2d 20 28 63 68 61 72 20 2a 29 26 61  ash - (char *)&a
a290: 50 67 6e 6f 5b 69 4c 69 6d 69 74 2b 31 5d 29 3b  Pgno[iLimit+1]);
a2a0: 0a 20 20 6d 65 6d 73 65 74 28 28 76 6f 69 64 20  .  memset((void 
a2b0: 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d 69 74 2b  *)&aPgno[iLimit+
a2c0: 31 5d 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 0a  1], 0, nByte);..
a2d0: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
a2e0: 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41  ABLE_EXPENSIVE_A
a2f0: 53 53 45 52 54 0a 20 20 2f 2a 20 56 65 72 69 66  SSERT.  /* Verif
a300: 79 20 74 68 61 74 20 74 68 65 20 65 76 65 72 79  y that the every
a310: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61   entry in the ma
a320: 70 70 69 6e 67 20 72 65 67 69 6f 6e 20 69 73 20  pping region is 
a330: 73 74 69 6c 6c 20 72 65 61 63 68 61 62 6c 65 0a  still reachable.
a340: 20 20 2a 2a 20 76 69 61 20 74 68 65 20 68 61 73    ** via the has
a350: 68 20 74 61 62 6c 65 20 65 76 65 6e 20 61 66 74  h table even aft
a360: 65 72 20 74 68 65 20 63 6c 65 61 6e 75 70 2e 0a  er the cleanup..
a370: 20 20 2a 2f 0a 20 20 69 66 28 20 69 4c 69 6d 69    */.  if( iLimi
a380: 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 6a 3b 20  t ){.    int j; 
a390: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f            /* Loo
a3a0: 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20  p counter */.   
a3b0: 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20 20   int iKey;      
a3c0: 20 20 2f 2a 20 48 61 73 68 20 6b 65 79 20 2a 2f    /* Hash key */
a3d0: 0a 20 20 20 20 66 6f 72 28 6a 3d 31 3b 20 6a 3c  .    for(j=1; j<
a3e0: 3d 69 4c 69 6d 69 74 3b 20 6a 2b 2b 29 7b 0a 20  =iLimit; j++){. 
a3f0: 20 20 20 20 20 66 6f 72 28 69 4b 65 79 3d 77 61       for(iKey=wa
a400: 6c 48 61 73 68 28 61 50 67 6e 6f 5b 6a 5d 29 3b  lHash(aPgno[j]);
a410: 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20 69 4b   aHash[iKey]; iK
a420: 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68 28 69  ey=walNextHash(i
a430: 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 20 20 69  Key)){.        i
a440: 66 28 20 61 48 61 73 68 5b 69 4b 65 79 5d 3d 3d  f( aHash[iKey]==
a450: 6a 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  j ) break;.     
a460: 20 7d 0a 20 20 20 20 20 20 61 73 73 65 72 74 28   }.      assert(
a470: 20 61 48 61 73 68 5b 69 4b 65 79 5d 3d 3d 6a 20   aHash[iKey]==j 
a480: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 23 65 6e  );.    }.  }.#en
a490: 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e  dif /* SQLITE_EN
a4a0: 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41  ABLE_EXPENSIVE_A
a4b0: 53 53 45 52 54 20 2a 2f 0a 7d 0a 0a 0a 2f 2a 0a  SSERT */.}.../*.
a4c0: 2a 2a 20 53 65 74 20 61 6e 20 65 6e 74 72 79 20  ** Set an entry 
a4d0: 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  in the wal-index
a4e0: 20 74 68 61 74 20 77 69 6c 6c 20 6d 61 70 20 64   that will map d
a4f0: 61 74 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d  atabase page num
a500: 62 65 72 0a 2a 2a 20 70 50 61 67 65 20 69 6e 74  ber.** pPage int
a510: 6f 20 57 41 4c 20 66 72 61 6d 65 20 69 46 72 61  o WAL frame iFra
a520: 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  me..*/.static in
a530: 74 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64  t walIndexAppend
a540: 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20  (Wal *pWal, u32 
a550: 69 46 72 61 6d 65 2c 20 75 33 32 20 69 50 61 67  iFrame, u32 iPag
a560: 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  e){.  int rc;   
a570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a580: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
a590: 63 6f 64 65 20 2a 2f 0a 20 20 75 33 32 20 69 5a  code */.  u32 iZ
a5a0: 65 72 6f 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ero = 0;        
a5b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65            /* One
a5c0: 20 6c 65 73 73 20 74 68 61 6e 20 66 72 61 6d 65   less than frame
a5d0: 20 6e 75 6d 62 65 72 20 6f 66 20 61 50 67 6e 6f   number of aPgno
a5e0: 5b 31 5d 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c  [1] */.  volatil
a5f0: 65 20 75 33 32 20 2a 61 50 67 6e 6f 20 3d 20 30  e u32 *aPgno = 0
a600: 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65  ;        /* Page
a610: 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 2a 2f   number array */
a620: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73  .  volatile ht_s
a630: 6c 6f 74 20 2a 61 48 61 73 68 20 3d 20 30 3b 20  lot *aHash = 0; 
a640: 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65     /* Hash table
a650: 20 2a 2f 0a 0a 20 20 72 63 20 3d 20 77 61 6c 48   */..  rc = walH
a660: 61 73 68 47 65 74 28 70 57 61 6c 2c 20 77 61 6c  ashGet(pWal, wal
a670: 46 72 61 6d 65 50 61 67 65 28 69 46 72 61 6d 65  FramePage(iFrame
a680: 29 2c 20 26 61 48 61 73 68 2c 20 26 61 50 67 6e  ), &aHash, &aPgn
a690: 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 0a 20 20 2f  o, &iZero);..  /
a6a0: 2a 20 41 73 73 75 6d 69 6e 67 20 74 68 65 20 77  * Assuming the w
a6b0: 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20 77 61  al-index file wa
a6c0: 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20 6d  s successfully m
a6d0: 61 70 70 65 64 2c 20 70 6f 70 75 6c 61 74 65 20  apped, populate 
a6e0: 74 68 65 0a 20 20 2a 2a 20 70 61 67 65 20 6e 75  the.  ** page nu
a6f0: 6d 62 65 72 20 61 72 72 61 79 20 61 6e 64 20 68  mber array and h
a700: 61 73 68 20 74 61 62 6c 65 20 65 6e 74 72 79 2e  ash table entry.
a710: 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  .  */.  if( rc==
a720: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
a730: 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20 20   int iKey;      
a740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
a750: 2a 20 48 61 73 68 20 74 61 62 6c 65 20 6b 65 79  * Hash table key
a760: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 64 78 3b   */.    int idx;
a770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a780: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 74        /* Value t
a790: 6f 20 77 72 69 74 65 20 74 6f 20 68 61 73 68 2d  o write to hash-
a7a0: 74 61 62 6c 65 20 73 6c 6f 74 20 2a 2f 0a 20 20  table slot */.  
a7b0: 20 20 69 6e 74 20 6e 43 6f 6c 6c 69 64 65 3b 20    int nCollide; 
a7c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a7d0: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 68 61 73  /* Number of has
a7e0: 68 20 63 6f 6c 6c 69 73 69 6f 6e 73 20 2a 2f 0a  h collisions */.
a7f0: 0a 20 20 20 20 69 64 78 20 3d 20 69 46 72 61 6d  .    idx = iFram
a800: 65 20 2d 20 69 5a 65 72 6f 3b 0a 20 20 20 20 61  e - iZero;.    a
a810: 73 73 65 72 74 28 20 69 64 78 20 3c 3d 20 48 41  ssert( idx <= HA
a820: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2f 32 20  SHTABLE_NSLOT/2 
a830: 2b 20 31 20 29 3b 0a 20 20 20 20 0a 20 20 20 20  + 1 );.    .    
a840: 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20 74 68  /* If this is th
a850: 65 20 66 69 72 73 74 20 65 6e 74 72 79 20 74 6f  e first entry to
a860: 20 62 65 20 61 64 64 65 64 20 74 6f 20 74 68 69   be added to thi
a870: 73 20 68 61 73 68 2d 74 61 62 6c 65 2c 20 7a 65  s hash-table, ze
a880: 72 6f 20 74 68 65 0a 20 20 20 20 2a 2a 20 65 6e  ro the.    ** en
a890: 74 69 72 65 20 68 61 73 68 20 74 61 62 6c 65 20  tire hash table 
a8a0: 61 6e 64 20 61 50 67 6e 6f 5b 5d 20 61 72 72 61  and aPgno[] arra
a8b0: 79 20 62 65 66 6f 72 65 20 70 72 6f 63 65 65 64  y before proceed
a8c0: 69 6e 67 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20  ing. .    */.   
a8d0: 20 69 66 28 20 69 64 78 3d 3d 31 20 29 7b 0a 20   if( idx==1 ){. 
a8e0: 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20 3d       int nByte =
a8f0: 20 28 69 6e 74 29 28 28 75 38 20 2a 29 26 61 48   (int)((u8 *)&aH
a900: 61 73 68 5b 48 41 53 48 54 41 42 4c 45 5f 4e 53  ash[HASHTABLE_NS
a910: 4c 4f 54 5d 20 2d 20 28 75 38 20 2a 29 26 61 50  LOT] - (u8 *)&aP
a920: 67 6e 6f 5b 31 5d 29 3b 0a 20 20 20 20 20 20 6d  gno[1]);.      m
a930: 65 6d 73 65 74 28 28 76 6f 69 64 2a 29 26 61 50  emset((void*)&aP
a940: 67 6e 6f 5b 31 5d 2c 20 30 2c 20 6e 42 79 74 65  gno[1], 0, nByte
a950: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
a960: 20 49 66 20 74 68 65 20 65 6e 74 72 79 20 69 6e   If the entry in
a970: 20 61 50 67 6e 6f 5b 5d 20 69 73 20 61 6c 72 65   aPgno[] is alre
a980: 61 64 79 20 73 65 74 2c 20 74 68 65 6e 20 74 68  ady set, then th
a990: 65 20 70 72 65 76 69 6f 75 73 20 77 72 69 74 65  e previous write
a9a0: 72 0a 20 20 20 20 2a 2a 20 6d 75 73 74 20 68 61  r.    ** must ha
a9b0: 76 65 20 65 78 69 74 65 64 20 75 6e 65 78 70 65  ve exited unexpe
a9c0: 63 74 65 64 6c 79 20 69 6e 20 74 68 65 20 6d 69  ctedly in the mi
a9d0: 64 64 6c 65 20 6f 66 20 61 20 74 72 61 6e 73 61  ddle of a transa
a9e0: 63 74 69 6f 6e 20 28 61 66 74 65 72 0a 20 20 20  ction (after.   
a9f0: 20 2a 2a 20 77 72 69 74 69 6e 67 20 6f 6e 65 20   ** writing one 
aa00: 6f 72 20 6d 6f 72 65 20 64 69 72 74 79 20 70 61  or more dirty pa
aa10: 67 65 73 20 74 6f 20 74 68 65 20 57 41 4c 20 74  ges to the WAL t
aa20: 6f 20 66 72 65 65 20 75 70 20 6d 65 6d 6f 72 79  o free up memory
aa30: 29 2e 20 0a 20 20 20 20 2a 2a 20 52 65 6d 6f 76  ). .    ** Remov
aa40: 65 20 74 68 65 20 72 65 6d 6e 61 6e 74 73 20 6f  e the remnants o
aa50: 66 20 74 68 61 74 20 77 72 69 74 65 72 73 20 75  f that writers u
aa60: 6e 63 6f 6d 6d 69 74 74 65 64 20 74 72 61 6e 73  ncommitted trans
aa70: 61 63 74 69 6f 6e 20 66 72 6f 6d 20 0a 20 20 20  action from .   
aa80: 20 2a 2a 20 74 68 65 20 68 61 73 68 2d 74 61 62   ** the hash-tab
aa90: 6c 65 20 62 65 66 6f 72 65 20 77 72 69 74 69 6e  le before writin
aaa0: 67 20 61 6e 79 20 6e 65 77 20 65 6e 74 72 69 65  g any new entrie
aab0: 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66  s..    */.    if
aac0: 28 20 61 50 67 6e 6f 5b 69 64 78 5d 20 29 7b 0a  ( aPgno[idx] ){.
aad0: 20 20 20 20 20 20 77 61 6c 43 6c 65 61 6e 75 70        walCleanup
aae0: 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 20 20  Hash(pWal);.    
aaf0: 20 20 61 73 73 65 72 74 28 20 21 61 50 67 6e 6f    assert( !aPgno
ab00: 5b 69 64 78 5d 20 29 3b 0a 20 20 20 20 7d 0a 0a  [idx] );.    }..
ab10: 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65      /* Write the
ab20: 20 61 50 67 6e 6f 5b 5d 20 61 72 72 61 79 20 65   aPgno[] array e
ab30: 6e 74 72 79 20 61 6e 64 20 74 68 65 20 68 61 73  ntry and the has
ab40: 68 2d 74 61 62 6c 65 20 73 6c 6f 74 2e 20 2a 2f  h-table slot. */
ab50: 0a 20 20 20 20 6e 43 6f 6c 6c 69 64 65 20 3d 20  .    nCollide = 
ab60: 69 64 78 3b 0a 20 20 20 20 66 6f 72 28 69 4b 65  idx;.    for(iKe
ab70: 79 3d 77 61 6c 48 61 73 68 28 69 50 61 67 65 29  y=walHash(iPage)
ab80: 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20 69  ; aHash[iKey]; i
ab90: 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68 28  Key=walNextHash(
aba0: 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 69 66  iKey)){.      if
abb0: 28 20 28 6e 43 6f 6c 6c 69 64 65 2d 2d 29 3d 3d  ( (nCollide--)==
abc0: 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  0 ) return SQLIT
abd0: 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a  E_CORRUPT_BKPT;.
abe0: 20 20 20 20 7d 0a 20 20 20 20 61 50 67 6e 6f 5b      }.    aPgno[
abf0: 69 64 78 5d 20 3d 20 69 50 61 67 65 3b 0a 20 20  idx] = iPage;.  
ac00: 20 20 61 48 61 73 68 5b 69 4b 65 79 5d 20 3d 20    aHash[iKey] = 
ac10: 28 68 74 5f 73 6c 6f 74 29 69 64 78 3b 0a 0a 23  (ht_slot)idx;..#
ac20: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
ac30: 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53  BLE_EXPENSIVE_AS
ac40: 53 45 52 54 0a 20 20 20 20 2f 2a 20 56 65 72 69  SERT.    /* Veri
ac50: 66 79 20 74 68 61 74 20 74 68 65 20 6e 75 6d 62  fy that the numb
ac60: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e  er of entries in
ac70: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
ac80: 65 78 61 63 74 6c 79 20 65 71 75 61 6c 73 0a 20  exactly equals. 
ac90: 20 20 20 2a 2a 20 74 68 65 20 6e 75 6d 62 65 72     ** the number
aca0: 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74   of entries in t
acb0: 68 65 20 6d 61 70 70 69 6e 67 20 72 65 67 69 6f  he mapping regio
acc0: 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7b 0a  n..    */.    {.
acd0: 20 20 20 20 20 20 69 6e 74 20 69 3b 20 20 20 20        int i;    
ace0: 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63         /* Loop c
acf0: 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20 20 20 20  ounter */.      
ad00: 69 6e 74 20 6e 45 6e 74 72 79 20 3d 20 30 3b 20  int nEntry = 0; 
ad10: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e   /* Number of en
ad20: 74 72 69 65 73 20 69 6e 20 74 68 65 20 68 61 73  tries in the has
ad30: 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 20  h table */.     
ad40: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48 41 53 48   for(i=0; i<HASH
ad50: 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 20 69 2b 2b  TABLE_NSLOT; i++
ad60: 29 7b 20 69 66 28 20 61 48 61 73 68 5b 69 5d 20  ){ if( aHash[i] 
ad70: 29 20 6e 45 6e 74 72 79 2b 2b 3b 20 7d 0a 20 20  ) nEntry++; }.  
ad80: 20 20 20 20 61 73 73 65 72 74 28 20 6e 45 6e 74      assert( nEnt
ad90: 72 79 3d 3d 69 64 78 20 29 3b 0a 20 20 20 20 7d  ry==idx );.    }
ada0: 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20  ..    /* Verify 
adb0: 74 68 61 74 20 74 68 65 20 65 76 65 72 79 20 65  that the every e
adc0: 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61 70 70  ntry in the mapp
add0: 69 6e 67 20 72 65 67 69 6f 6e 20 69 73 20 72 65  ing region is re
ade0: 61 63 68 61 62 6c 65 0a 20 20 20 20 2a 2a 20 76  achable.    ** v
adf0: 69 61 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ia the hash tabl
ae00: 65 2e 20 20 54 68 69 73 20 74 75 72 6e 73 20 6f  e.  This turns o
ae10: 75 74 20 74 6f 20 62 65 20 61 20 72 65 61 6c 6c  ut to be a reall
ae20: 79 2c 20 72 65 61 6c 6c 79 20 65 78 70 65 6e 73  y, really expens
ae30: 69 76 65 0a 20 20 20 20 2a 2a 20 74 68 69 6e 67  ive.    ** thing
ae40: 20 74 6f 20 63 68 65 63 6b 2c 20 73 6f 20 6f 6e   to check, so on
ae50: 6c 79 20 64 6f 20 74 68 69 73 20 6f 63 63 61 73  ly do this occas
ae60: 69 6f 6e 61 6c 6c 79 20 2d 20 6e 6f 74 20 6f 6e  ionally - not on
ae70: 20 65 76 65 72 79 0a 20 20 20 20 2a 2a 20 69 74   every.    ** it
ae80: 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20 2a 2f 0a  eration..    */.
ae90: 20 20 20 20 69 66 28 20 28 69 64 78 26 30 78 33      if( (idx&0x3
aea0: 66 66 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ff)==0 ){.      
aeb0: 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
aec0: 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72   /* Loop counter
aed0: 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28 69 3d   */.      for(i=
aee0: 31 3b 20 69 3c 3d 69 64 78 3b 20 69 2b 2b 29 7b  1; i<=idx; i++){
aef0: 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 4b 65  .        for(iKe
af00: 79 3d 77 61 6c 48 61 73 68 28 61 50 67 6e 6f 5b  y=walHash(aPgno[
af10: 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  i]); aHash[iKey]
af20: 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
af30: 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
af40: 20 20 20 20 20 69 66 28 20 61 48 61 73 68 5b 69       if( aHash[i
af50: 4b 65 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b 3b  Key]==i ) break;
af60: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
af70: 20 20 20 61 73 73 65 72 74 28 20 61 48 61 73 68     assert( aHash
af80: 5b 69 4b 65 79 5d 3d 3d 69 20 29 3b 0a 20 20 20  [iKey]==i );.   
af90: 20 20 20 7d 0a 20 20 20 20 7d 0a 23 65 6e 64 69     }.    }.#endi
afa0: 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42  f /* SQLITE_ENAB
afb0: 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53 53  LE_EXPENSIVE_ASS
afc0: 45 52 54 20 2a 2f 0a 20 20 7d 0a 0a 0a 20 20 72  ERT */.  }...  r
afd0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a  eturn rc;.}.../*
afe0: 0a 2a 2a 20 52 65 63 6f 76 65 72 20 74 68 65 20  .** Recover the 
aff0: 77 61 6c 2d 69 6e 64 65 78 20 62 79 20 72 65 61  wal-index by rea
b000: 64 69 6e 67 20 74 68 65 20 77 72 69 74 65 2d 61  ding the write-a
b010: 68 65 61 64 20 6c 6f 67 20 66 69 6c 65 2e 20 0a  head log file. .
b020: 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  **.** This routi
b030: 6e 65 20 66 69 72 73 74 20 74 72 69 65 73 20 74  ne first tries t
b040: 6f 20 65 73 74 61 62 6c 69 73 68 20 61 6e 20 65  o establish an e
b050: 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e  xclusive lock on
b060: 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65   the.** wal-inde
b070: 78 20 74 6f 20 70 72 65 76 65 6e 74 20 6f 74 68  x to prevent oth
b080: 65 72 20 74 68 72 65 61 64 73 2f 70 72 6f 63 65  er threads/proce
b090: 73 73 65 73 20 66 72 6f 6d 20 64 6f 69 6e 67 20  sses from doing 
b0a0: 61 6e 79 74 68 69 6e 67 0a 2a 2a 20 77 69 74 68  anything.** with
b0b0: 20 74 68 65 20 57 41 4c 20 6f 72 20 77 61 6c 2d   the WAL or wal-
b0c0: 69 6e 64 65 78 20 77 68 69 6c 65 20 72 65 63 6f  index while reco
b0d0: 76 65 72 79 20 69 73 20 72 75 6e 6e 69 6e 67 2e  very is running.
b0e0: 20 20 54 68 65 0a 2a 2a 20 57 41 4c 5f 52 45 43    The.** WAL_REC
b0f0: 4f 56 45 52 5f 4c 4f 43 4b 20 69 73 20 61 6c 73  OVER_LOCK is als
b100: 6f 20 68 65 6c 64 20 73 6f 20 74 68 61 74 20 6f  o held so that o
b110: 74 68 65 72 20 74 68 72 65 61 64 73 20 77 69 6c  ther threads wil
b120: 6c 20 6b 6e 6f 77 0a 2a 2a 20 74 68 61 74 20 74  l know.** that t
b130: 68 69 73 20 74 68 72 65 61 64 20 69 73 20 72 75  his thread is ru
b140: 6e 6e 69 6e 67 20 72 65 63 6f 76 65 72 79 2e 20  nning recovery. 
b150: 20 49 66 20 75 6e 61 62 6c 65 20 74 6f 20 65 73   If unable to es
b160: 74 61 62 6c 69 73 68 0a 2a 2a 20 74 68 65 20 6e  tablish.** the n
b170: 65 63 65 73 73 61 72 79 20 6c 6f 63 6b 73 2c 20  ecessary locks, 
b180: 74 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65 74  this routine ret
b190: 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53 59  urns SQLITE_BUSY
b1a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
b1b0: 77 61 6c 49 6e 64 65 78 52 65 63 6f 76 65 72 28  walIndexRecover(
b1c0: 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e  Wal *pWal){.  in
b1d0: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
b1e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
b1f0: 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a   Return Code */.
b200: 20 20 69 36 34 20 6e 53 69 7a 65 3b 20 20 20 20    i64 nSize;    
b210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b220: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 6c 6f 67    /* Size of log
b230: 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32 20 61   file */.  u32 a
b240: 46 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 20 3d 20  FrameCksum[2] = 
b250: 7b 30 2c 20 30 7d 3b 0a 20 20 69 6e 74 20 69 4c  {0, 0};.  int iL
b260: 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ock;            
b270: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 63            /* Loc
b280: 6b 20 6f 66 66 73 65 74 20 74 6f 20 6c 6f 63 6b  k offset to lock
b290: 20 66 6f 72 20 63 68 65 63 6b 70 6f 69 6e 74 20   for checkpoint 
b2a0: 2a 2f 0a 0a 20 20 2f 2a 20 4f 62 74 61 69 6e 20  */..  /* Obtain 
b2b0: 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63  an exclusive loc
b2c0: 6b 20 6f 6e 20 61 6c 6c 20 62 79 74 65 20 69 6e  k on all byte in
b2d0: 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 72 61 6e   the locking ran
b2e0: 67 65 20 6e 6f 74 20 61 6c 72 65 61 64 79 0a 20  ge not already. 
b2f0: 20 2a 2a 20 6c 6f 63 6b 65 64 20 62 79 20 74 68   ** locked by th
b300: 65 20 63 61 6c 6c 65 72 2e 20 54 68 65 20 63 61  e caller. The ca
b310: 6c 6c 65 72 20 69 73 20 67 75 61 72 61 6e 74 65  ller is guarante
b320: 65 64 20 74 6f 20 68 61 76 65 20 6c 6f 63 6b 65  ed to have locke
b330: 64 20 74 68 65 0a 20 20 2a 2a 20 57 41 4c 5f 57  d the.  ** WAL_W
b340: 52 49 54 45 5f 4c 4f 43 4b 20 62 79 74 65 2c 20  RITE_LOCK byte, 
b350: 61 6e 64 20 6d 61 79 20 68 61 76 65 20 61 6c 73  and may have als
b360: 6f 20 6c 6f 63 6b 65 64 20 74 68 65 20 57 41 4c  o locked the WAL
b370: 5f 43 4b 50 54 5f 4c 4f 43 4b 20 62 79 74 65 2e  _CKPT_LOCK byte.
b380: 0a 20 20 2a 2a 20 49 66 20 73 75 63 63 65 73 73  .  ** If success
b390: 66 75 6c 2c 20 74 68 65 20 73 61 6d 65 20 62 79  ful, the same by
b3a0: 74 65 73 20 74 68 61 74 20 61 72 65 20 6c 6f 63  tes that are loc
b3b0: 6b 65 64 20 68 65 72 65 20 61 72 65 20 75 6e 6c  ked here are unl
b3c0: 6f 63 6b 65 64 20 62 65 66 6f 72 65 0a 20 20 2a  ocked before.  *
b3d0: 2a 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * this function 
b3e0: 72 65 74 75 72 6e 73 2e 0a 20 20 2a 2f 0a 20 20  returns..  */.  
b3f0: 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 63 6b  assert( pWal->ck
b400: 70 74 4c 6f 63 6b 3d 3d 31 20 7c 7c 20 70 57 61  ptLock==1 || pWa
b410: 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 30 20 29  l->ckptLock==0 )
b420: 3b 0a 20 20 61 73 73 65 72 74 28 20 57 41 4c 5f  ;.  assert( WAL_
b430: 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 3d 3d 57  ALL_BUT_WRITE==W
b440: 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2b 31 20  AL_WRITE_LOCK+1 
b450: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 57 41 4c  );.  assert( WAL
b460: 5f 43 4b 50 54 5f 4c 4f 43 4b 3d 3d 57 41 4c 5f  _CKPT_LOCK==WAL_
b470: 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 29 3b  ALL_BUT_WRITE );
b480: 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
b490: 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20  >writeLock );.  
b4a0: 69 4c 6f 63 6b 20 3d 20 57 41 4c 5f 41 4c 4c 5f  iLock = WAL_ALL_
b4b0: 42 55 54 5f 57 52 49 54 45 20 2b 20 70 57 61 6c  BUT_WRITE + pWal
b4c0: 2d 3e 63 6b 70 74 4c 6f 63 6b 3b 0a 20 20 72 63  ->ckptLock;.  rc
b4d0: 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73   = walLockExclus
b4e0: 69 76 65 28 70 57 61 6c 2c 20 69 4c 6f 63 6b 2c  ive(pWal, iLock,
b4f0: 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
b500: 29 2d 69 4c 6f 63 6b 29 3b 0a 20 20 69 66 28 20  )-iLock);.  if( 
b510: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
b520: 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63  .    rc = walLoc
b530: 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
b540: 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31   WAL_READ_LOCK(1
b550: 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31  ), WAL_NREADER-1
b560: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
b570: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
b580: 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75    walUnlockExclu
b590: 73 69 76 65 28 70 57 61 6c 2c 20 69 4c 6f 63 6b  sive(pWal, iLock
b5a0: 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
b5b0: 30 29 2d 69 4c 6f 63 6b 29 3b 0a 20 20 20 20 7d  0)-iLock);.    }
b5c0: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 20 29 7b  .  }.  if( rc ){
b5d0: 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
b5e0: 20 20 7d 0a 0a 20 20 57 41 4c 54 52 41 43 45 28    }..  WALTRACE(
b5f0: 28 22 57 41 4c 25 70 3a 20 72 65 63 6f 76 65 72  ("WAL%p: recover
b600: 79 20 62 65 67 69 6e 2e 2e 2e 5c 6e 22 2c 20 70  y begin...\n", p
b610: 57 61 6c 29 29 3b 0a 0a 20 20 6d 65 6d 73 65 74  Wal));..  memset
b620: 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 30 2c 20  (&pWal->hdr, 0, 
b630: 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48  sizeof(WalIndexH
b640: 64 72 29 29 3b 0a 0a 20 20 72 63 20 3d 20 73 71  dr));..  rc = sq
b650: 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a 65 28  lite3OsFileSize(
b660: 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 26 6e  pWal->pWalFd, &n
b670: 53 69 7a 65 29 3b 0a 20 20 69 66 28 20 72 63 21  Size);.  if( rc!
b680: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
b690: 20 20 67 6f 74 6f 20 72 65 63 6f 76 65 72 79 5f    goto recovery_
b6a0: 65 72 72 6f 72 3b 0a 20 20 7d 0a 0a 20 20 69 66  error;.  }..  if
b6b0: 28 20 6e 53 69 7a 65 3e 57 41 4c 5f 48 44 52 53  ( nSize>WAL_HDRS
b6c0: 49 5a 45 20 29 7b 0a 20 20 20 20 75 38 20 61 42  IZE ){.    u8 aB
b6d0: 75 66 5b 57 41 4c 5f 48 44 52 53 49 5a 45 5d 3b  uf[WAL_HDRSIZE];
b6e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66           /* Buff
b6f0: 65 72 20 74 6f 20 6c 6f 61 64 20 57 41 4c 20 68  er to load WAL h
b700: 65 61 64 65 72 20 69 6e 74 6f 20 2a 2f 0a 20 20  eader into */.  
b710: 20 20 75 38 20 2a 61 46 72 61 6d 65 20 3d 20 30    u8 *aFrame = 0
b720: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
b730: 2f 2a 20 4d 61 6c 6c 6f 63 27 64 20 62 75 66 66  /* Malloc'd buff
b740: 65 72 20 74 6f 20 6c 6f 61 64 20 65 6e 74 69 72  er to load entir
b750: 65 20 66 72 61 6d 65 20 2a 2f 0a 20 20 20 20 69  e frame */.    i
b760: 6e 74 20 73 7a 46 72 61 6d 65 3b 20 20 20 20 20  nt szFrame;     
b770: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
b780: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
b790: 69 6e 20 62 75 66 66 65 72 20 61 46 72 61 6d 65  in buffer aFrame
b7a0: 5b 5d 20 2a 2f 0a 20 20 20 20 75 38 20 2a 61 44  [] */.    u8 *aD
b7b0: 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20  ata;            
b7c0: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
b7d0: 65 72 20 74 6f 20 64 61 74 61 20 70 61 72 74 20  er to data part 
b7e0: 6f 66 20 61 46 72 61 6d 65 20 62 75 66 66 65 72  of aFrame buffer
b7f0: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 46 72 61   */.    int iFra
b800: 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  me;             
b810: 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f        /* Index o
b820: 66 20 6c 61 73 74 20 66 72 61 6d 65 20 72 65 61  f last frame rea
b830: 64 20 2a 2f 0a 20 20 20 20 69 36 34 20 69 4f 66  d */.    i64 iOf
b840: 66 73 65 74 3b 20 20 20 20 20 20 20 20 20 20 20  fset;           
b850: 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 6f         /* Next o
b860: 66 66 73 65 74 20 74 6f 20 72 65 61 64 20 66 72  ffset to read fr
b870: 6f 6d 20 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a 20  om log file */. 
b880: 20 20 20 69 6e 74 20 73 7a 50 61 67 65 3b 20 20     int szPage;  
b890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b8a0: 20 2f 2a 20 50 61 67 65 20 73 69 7a 65 20 61 63   /* Page size ac
b8b0: 63 6f 72 64 69 6e 67 20 74 6f 20 74 68 65 20 6c  cording to the l
b8c0: 6f 67 20 2a 2f 0a 20 20 20 20 75 33 32 20 6d 61  og */.    u32 ma
b8d0: 67 69 63 3b 20 20 20 20 20 20 20 20 20 20 20 20  gic;            
b8e0: 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 67 69 63          /* Magic
b8f0: 20 76 61 6c 75 65 20 72 65 61 64 20 66 72 6f 6d   value read from
b900: 20 57 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a 20   WAL header */. 
b910: 20 20 20 75 33 32 20 76 65 72 73 69 6f 6e 3b 20     u32 version; 
b920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b930: 20 2f 2a 20 4d 61 67 69 63 20 76 61 6c 75 65 20   /* Magic value 
b940: 72 65 61 64 20 66 72 6f 6d 20 57 41 4c 20 68 65  read from WAL he
b950: 61 64 65 72 20 2a 2f 0a 20 20 20 20 69 6e 74 20  ader */.    int 
b960: 69 73 56 61 6c 69 64 3b 20 20 20 20 20 20 20 20  isValid;        
b970: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
b980: 65 20 69 66 20 74 68 69 73 20 66 72 61 6d 65 20  e if this frame 
b990: 69 73 20 76 61 6c 69 64 20 2a 2f 0a 0a 20 20 20  is valid */..   
b9a0: 20 2f 2a 20 52 65 61 64 20 69 6e 20 74 68 65 20   /* Read in the 
b9b0: 57 41 4c 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20  WAL header. */. 
b9c0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
b9d0: 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c  sRead(pWal->pWal
b9e0: 46 64 2c 20 61 42 75 66 2c 20 57 41 4c 5f 48 44  Fd, aBuf, WAL_HD
b9f0: 52 53 49 5a 45 2c 20 30 29 3b 0a 20 20 20 20 69  RSIZE, 0);.    i
ba00: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
ba10: 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 72   ){.      goto r
ba20: 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20  ecovery_error;. 
ba30: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20     }..    /* If 
ba40: 74 68 65 20 64 61 74 61 62 61 73 65 20 70 61 67  the database pag
ba50: 65 20 73 69 7a 65 20 69 73 20 6e 6f 74 20 61 20  e size is not a 
ba60: 70 6f 77 65 72 20 6f 66 20 74 77 6f 2c 20 6f 72  power of two, or
ba70: 20 69 73 20 67 72 65 61 74 65 72 20 74 68 61 6e   is greater than
ba80: 0a 20 20 20 20 2a 2a 20 53 51 4c 49 54 45 5f 4d  .    ** SQLITE_M
ba90: 41 58 5f 50 41 47 45 5f 53 49 5a 45 2c 20 63 6f  AX_PAGE_SIZE, co
baa0: 6e 63 6c 75 64 65 20 74 68 61 74 20 74 68 65 20  nclude that the 
bab0: 57 41 4c 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e  WAL file contain
bac0: 73 20 6e 6f 20 76 61 6c 69 64 20 0a 20 20 20 20  s no valid .    
bad0: 2a 2a 20 64 61 74 61 2e 20 53 69 6d 69 6c 61 72  ** data. Similar
bae0: 6c 79 2c 20 69 66 20 74 68 65 20 27 6d 61 67 69  ly, if the 'magi
baf0: 63 27 20 76 61 6c 75 65 20 69 73 20 69 6e 76 61  c' value is inva
bb00: 6c 69 64 2c 20 69 67 6e 6f 72 65 20 74 68 65 20  lid, ignore the 
bb10: 77 68 6f 6c 65 0a 20 20 20 20 2a 2a 20 57 41 4c  whole.    ** WAL
bb20: 20 66 69 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20 20   file..    */.  
bb30: 20 20 6d 61 67 69 63 20 3d 20 73 71 6c 69 74 65    magic = sqlite
bb40: 33 47 65 74 34 62 79 74 65 28 26 61 42 75 66 5b  3Get4byte(&aBuf[
bb50: 30 5d 29 3b 0a 20 20 20 20 73 7a 50 61 67 65 20  0]);.    szPage 
bb60: 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62 79 74  = sqlite3Get4byt
bb70: 65 28 26 61 42 75 66 5b 38 5d 29 3b 0a 20 20 20  e(&aBuf[8]);.   
bb80: 20 69 66 28 20 28 6d 61 67 69 63 26 30 78 46 46   if( (magic&0xFF
bb90: 46 46 46 46 46 45 29 21 3d 57 41 4c 5f 4d 41 47  FFFFFE)!=WAL_MAG
bba0: 49 43 20 0a 20 20 20 20 20 7c 7c 20 73 7a 50 61  IC .     || szPa
bbb0: 67 65 26 28 73 7a 50 61 67 65 2d 31 29 20 0a 20  ge&(szPage-1) . 
bbc0: 20 20 20 20 7c 7c 20 73 7a 50 61 67 65 3e 53 51      || szPage>SQ
bbd0: 4c 49 54 45 5f 4d 41 58 5f 50 41 47 45 5f 53 49  LITE_MAX_PAGE_SI
bbe0: 5a 45 20 0a 20 20 20 20 20 7c 7c 20 73 7a 50 61  ZE .     || szPa
bbf0: 67 65 3c 35 31 32 20 0a 20 20 20 20 29 7b 0a 20  ge<512 .    ){. 
bc00: 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73 68       goto finish
bc10: 65 64 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 57  ed;.    }.    pW
bc20: 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b  al->hdr.bigEndCk
bc30: 73 75 6d 20 3d 20 28 75 38 29 28 6d 61 67 69 63  sum = (u8)(magic
bc40: 26 30 78 30 30 30 30 30 30 30 31 29 3b 0a 20 20  &0x00000001);.  
bc50: 20 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 20 3d    pWal->szPage =
bc60: 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 70 57 61   szPage;.    pWa
bc70: 6c 2d 3e 6e 43 6b 70 74 20 3d 20 73 71 6c 69 74  l->nCkpt = sqlit
bc80: 65 33 47 65 74 34 62 79 74 65 28 26 61 42 75 66  e3Get4byte(&aBuf
bc90: 5b 31 32 5d 29 3b 0a 20 20 20 20 6d 65 6d 63 70  [12]);.    memcp
bca0: 79 28 26 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61  y(&pWal->hdr.aSa
bcb0: 6c 74 2c 20 26 61 42 75 66 5b 31 36 5d 2c 20 38  lt, &aBuf[16], 8
bcc0: 29 3b 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69 66  );..    /* Verif
bcd0: 79 20 74 68 61 74 20 74 68 65 20 57 41 4c 20 68  y that the WAL h
bce0: 65 61 64 65 72 20 63 68 65 63 6b 73 75 6d 20 69  eader checksum i
bcf0: 73 20 63 6f 72 72 65 63 74 20 2a 2f 0a 20 20 20  s correct */.   
bd00: 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65   walChecksumByte
bd10: 73 28 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45  s(pWal->hdr.bigE
bd20: 6e 64 43 6b 73 75 6d 3d 3d 53 51 4c 49 54 45 5f  ndCksum==SQLITE_
bd30: 42 49 47 45 4e 44 49 41 4e 2c 20 0a 20 20 20 20  BIGENDIAN, .    
bd40: 20 20 20 20 61 42 75 66 2c 20 57 41 4c 5f 48 44      aBuf, WAL_HD
bd50: 52 53 49 5a 45 2d 32 2a 34 2c 20 30 2c 20 70 57  RSIZE-2*4, 0, pW
bd60: 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
bd70: 73 75 6d 0a 20 20 20 20 29 3b 0a 20 20 20 20 69  sum.    );.    i
bd80: 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72  f( pWal->hdr.aFr
bd90: 61 6d 65 43 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c  ameCksum[0]!=sql
bda0: 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61 42  ite3Get4byte(&aB
bdb0: 75 66 5b 32 34 5d 29 0a 20 20 20 20 20 7c 7c 20  uf[24]).     || 
bdc0: 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
bdd0: 43 6b 73 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65  Cksum[1]!=sqlite
bde0: 33 47 65 74 34 62 79 74 65 28 26 61 42 75 66 5b  3Get4byte(&aBuf[
bdf0: 32 38 5d 29 0a 20 20 20 20 29 7b 0a 20 20 20 20  28]).    ){.    
be00: 20 20 67 6f 74 6f 20 66 69 6e 69 73 68 65 64 3b    goto finished;
be10: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 56  .    }..    /* V
be20: 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20 76  erify that the v
be30: 65 72 73 69 6f 6e 20 6e 75 6d 62 65 72 20 6f 6e  ersion number on
be40: 20 74 68 65 20 57 41 4c 20 66 6f 72 6d 61 74 20   the WAL format 
be50: 69 73 20 6f 6e 65 20 74 68 61 74 0a 20 20 20 20  is one that.    
be60: 2a 2a 20 61 72 65 20 61 62 6c 65 20 74 6f 20 75  ** are able to u
be70: 6e 64 65 72 73 74 61 6e 64 20 2a 2f 0a 20 20 20  nderstand */.   
be80: 20 76 65 72 73 69 6f 6e 20 3d 20 73 71 6c 69 74   version = sqlit
be90: 65 33 47 65 74 34 62 79 74 65 28 26 61 42 75 66  e3Get4byte(&aBuf
bea0: 5b 34 5d 29 3b 0a 20 20 20 20 69 66 28 20 76 65  [4]);.    if( ve
beb0: 72 73 69 6f 6e 21 3d 57 41 4c 5f 4d 41 58 5f 56  rsion!=WAL_MAX_V
bec0: 45 52 53 49 4f 4e 20 29 7b 0a 20 20 20 20 20 20  ERSION ){.      
bed0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 43 41 4e 54  rc = SQLITE_CANT
bee0: 4f 50 45 4e 5f 42 4b 50 54 3b 0a 20 20 20 20 20  OPEN_BKPT;.     
bef0: 20 67 6f 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a   goto finished;.
bf00: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 4d 61      }..    /* Ma
bf10: 6c 6c 6f 63 20 61 20 62 75 66 66 65 72 20 74 6f  lloc a buffer to
bf20: 20 72 65 61 64 20 66 72 61 6d 65 73 20 69 6e 74   read frames int
bf30: 6f 2e 20 2a 2f 0a 20 20 20 20 73 7a 46 72 61 6d  o. */.    szFram
bf40: 65 20 3d 20 73 7a 50 61 67 65 20 2b 20 57 41 4c  e = szPage + WAL
bf50: 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a  _FRAME_HDRSIZE;.
bf60: 20 20 20 20 61 46 72 61 6d 65 20 3d 20 28 75 38      aFrame = (u8
bf70: 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   *)sqlite3_mallo
bf80: 63 36 34 28 73 7a 46 72 61 6d 65 29 3b 0a 20 20  c64(szFrame);.  
bf90: 20 20 69 66 28 20 21 61 46 72 61 6d 65 20 29 7b    if( !aFrame ){
bfa0: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
bfb0: 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20  TE_NOMEM_BKPT;. 
bfc0: 20 20 20 20 20 67 6f 74 6f 20 72 65 63 6f 76 65       goto recove
bfd0: 72 79 5f 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a  ry_error;.    }.
bfe0: 20 20 20 20 61 44 61 74 61 20 3d 20 26 61 46 72      aData = &aFr
bff0: 61 6d 65 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44  ame[WAL_FRAME_HD
c000: 52 53 49 5a 45 5d 3b 0a 0a 20 20 20 20 2f 2a 20  RSIZE];..    /* 
c010: 52 65 61 64 20 61 6c 6c 20 66 72 61 6d 65 73 20  Read all frames 
c020: 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20 66 69 6c  from the log fil
c030: 65 2e 20 2a 2f 0a 20 20 20 20 69 46 72 61 6d 65  e. */.    iFrame
c040: 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 4f   = 0;.    for(iO
c050: 66 66 73 65 74 3d 57 41 4c 5f 48 44 52 53 49 5a  ffset=WAL_HDRSIZ
c060: 45 3b 20 28 69 4f 66 66 73 65 74 2b 73 7a 46 72  E; (iOffset+szFr
c070: 61 6d 65 29 3c 3d 6e 53 69 7a 65 3b 20 69 4f 66  ame)<=nSize; iOf
c080: 66 73 65 74 2b 3d 73 7a 46 72 61 6d 65 29 7b 0a  fset+=szFrame){.
c090: 20 20 20 20 20 20 75 33 32 20 70 67 6e 6f 3b 20        u32 pgno; 
c0a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c0b0: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61    /* Database pa
c0c0: 67 65 20 6e 75 6d 62 65 72 20 66 6f 72 20 66 72  ge number for fr
c0d0: 61 6d 65 20 2a 2f 0a 20 20 20 20 20 20 75 33 32  ame */.      u32
c0e0: 20 6e 54 72 75 6e 63 61 74 65 3b 20 20 20 20 20   nTruncate;     
c0f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 64 62 73 69           /* dbsi
c100: 7a 65 20 66 69 65 6c 64 20 66 72 6f 6d 20 66 72  ze field from fr
c110: 61 6d 65 20 68 65 61 64 65 72 20 2a 2f 0a 0a 20  ame header */.. 
c120: 20 20 20 20 20 2f 2a 20 52 65 61 64 20 61 6e 64       /* Read and
c130: 20 64 65 63 6f 64 65 20 74 68 65 20 6e 65 78 74   decode the next
c140: 20 6c 6f 67 20 66 72 61 6d 65 2e 20 2a 2f 0a 20   log frame. */. 
c150: 20 20 20 20 20 69 46 72 61 6d 65 2b 2b 3b 0a 20       iFrame++;. 
c160: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
c170: 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57  3OsRead(pWal->pW
c180: 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20 73 7a  alFd, aFrame, sz
c190: 46 72 61 6d 65 2c 20 69 4f 66 66 73 65 74 29 3b  Frame, iOffset);
c1a0: 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
c1b0: 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
c1c0: 3b 0a 20 20 20 20 20 20 69 73 56 61 6c 69 64 20  ;.      isValid 
c1d0: 3d 20 77 61 6c 44 65 63 6f 64 65 46 72 61 6d 65  = walDecodeFrame
c1e0: 28 70 57 61 6c 2c 20 26 70 67 6e 6f 2c 20 26 6e  (pWal, &pgno, &n
c1f0: 54 72 75 6e 63 61 74 65 2c 20 61 44 61 74 61 2c  Truncate, aData,
c200: 20 61 46 72 61 6d 65 29 3b 0a 20 20 20 20 20 20   aFrame);.      
c210: 69 66 28 20 21 69 73 56 61 6c 69 64 20 29 20 62  if( !isValid ) b
c220: 72 65 61 6b 3b 0a 20 20 20 20 20 20 72 63 20 3d  reak;.      rc =
c230: 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64 28   walIndexAppend(
c240: 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c 20 70 67  pWal, iFrame, pg
c250: 6e 6f 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  no);.      if( r
c260: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62  c!=SQLITE_OK ) b
c270: 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 2f 2a 20  reak;..      /* 
c280: 49 66 20 6e 54 72 75 6e 63 61 74 65 20 69 73 20  If nTruncate is 
c290: 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 69 73 20 69  non-zero, this i
c2a0: 73 20 61 20 63 6f 6d 6d 69 74 20 72 65 63 6f 72  s a commit recor
c2b0: 64 2e 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20  d. */.      if( 
c2c0: 6e 54 72 75 6e 63 61 74 65 20 29 7b 0a 20 20 20  nTruncate ){.   
c2d0: 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d       pWal->hdr.m
c2e0: 78 46 72 61 6d 65 20 3d 20 69 46 72 61 6d 65 3b  xFrame = iFrame;
c2f0: 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 68  .        pWal->h
c300: 64 72 2e 6e 50 61 67 65 20 3d 20 6e 54 72 75 6e  dr.nPage = nTrun
c310: 63 61 74 65 3b 0a 20 20 20 20 20 20 20 20 70 57  cate;.        pW
c320: 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 20 3d  al->hdr.szPage =
c330: 20 28 75 31 36 29 28 28 73 7a 50 61 67 65 26 30   (u16)((szPage&0
c340: 78 66 66 30 30 29 20 7c 20 28 73 7a 50 61 67 65  xff00) | (szPage
c350: 3e 3e 31 36 29 29 3b 0a 20 20 20 20 20 20 20 20  >>16));.        
c360: 74 65 73 74 63 61 73 65 28 20 73 7a 50 61 67 65  testcase( szPage
c370: 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20 20 20 20  <=32768 );.     
c380: 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50     testcase( szP
c390: 61 67 65 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20  age>=65536 );.  
c3a0: 20 20 20 20 20 20 61 46 72 61 6d 65 43 6b 73 75        aFrameCksu
c3b0: 6d 5b 30 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72  m[0] = pWal->hdr
c3c0: 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b  .aFrameCksum[0];
c3d0: 0a 20 20 20 20 20 20 20 20 61 46 72 61 6d 65 43  .        aFrameC
c3e0: 6b 73 75 6d 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e  ksum[1] = pWal->
c3f0: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
c400: 31 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  1];.      }.    
c410: 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  }..    sqlite3_f
c420: 72 65 65 28 61 46 72 61 6d 65 29 3b 0a 20 20 7d  ree(aFrame);.  }
c430: 0a 0a 66 69 6e 69 73 68 65 64 3a 0a 20 20 69 66  ..finished:.  if
c440: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
c450: 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  ){.    volatile 
c460: 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e  WalCkptInfo *pIn
c470: 66 6f 3b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20  fo;.    int i;. 
c480: 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72     pWal->hdr.aFr
c490: 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 46  ameCksum[0] = aF
c4a0: 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20  rameCksum[0];.  
c4b0: 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61    pWal->hdr.aFra
c4c0: 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 61 46 72  meCksum[1] = aFr
c4d0: 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 20  ameCksum[1];.   
c4e0: 20 77 61 6c 49 6e 64 65 78 57 72 69 74 65 48 64   walIndexWriteHd
c4f0: 72 28 70 57 61 6c 29 3b 0a 0a 20 20 20 20 2f 2a  r(pWal);..    /*
c500: 20 52 65 73 65 74 20 74 68 65 20 63 68 65 63 6b   Reset the check
c510: 70 6f 69 6e 74 2d 68 65 61 64 65 72 2e 20 54 68  point-header. Th
c520: 69 73 20 69 73 20 73 61 66 65 20 62 65 63 61 75  is is safe becau
c530: 73 65 20 74 68 69 73 20 74 68 72 65 61 64 20 69  se this thread i
c540: 73 20 0a 20 20 20 20 2a 2a 20 63 75 72 72 65 6e  s .    ** curren
c550: 74 6c 79 20 68 6f 6c 64 69 6e 67 20 6c 6f 63 6b  tly holding lock
c560: 73 20 74 68 61 74 20 65 78 63 6c 75 64 65 20 61  s that exclude a
c570: 6c 6c 20 6f 74 68 65 72 20 72 65 61 64 65 72 73  ll other readers
c580: 2c 20 77 72 69 74 65 72 73 20 61 6e 64 0a 20 20  , writers and.  
c590: 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 65    ** checkpointe
c5a0: 72 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 70  rs..    */.    p
c5b0: 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e  Info = walCkptIn
c5c0: 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20 20 70 49  fo(pWal);.    pI
c5d0: 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 20 3d  nfo->nBackfill =
c5e0: 20 30 3b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 6e   0;.    pInfo->n
c5f0: 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65  BackfillAttempte
c600: 64 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  d = pWal->hdr.mx
c610: 46 72 61 6d 65 3b 0a 20 20 20 20 70 49 6e 66 6f  Frame;.    pInfo
c620: 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20 3d  ->aReadMark[0] =
c630: 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b   0;.    for(i=1;
c640: 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
c650: 69 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61  i++) pInfo->aRea
c660: 64 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d  dMark[i] = READM
c670: 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20  ARK_NOT_USED;.  
c680: 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e    if( pWal->hdr.
c690: 6d 78 46 72 61 6d 65 20 29 20 70 49 6e 66 6f 2d  mxFrame ) pInfo-
c6a0: 3e 61 52 65 61 64 4d 61 72 6b 5b 31 5d 20 3d 20  >aReadMark[1] = 
c6b0: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
c6c0: 65 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 6d 6f  e;..    /* If mo
c6d0: 72 65 20 74 68 61 6e 20 6f 6e 65 20 66 72 61 6d  re than one fram
c6e0: 65 20 77 61 73 20 72 65 63 6f 76 65 72 65 64 20  e was recovered 
c6f0: 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20 66 69 6c  from the log fil
c700: 65 2c 20 72 65 70 6f 72 74 20 61 6e 0a 20 20 20  e, report an.   
c710: 20 2a 2a 20 65 76 65 6e 74 20 76 69 61 20 73 71   ** event via sq
c720: 6c 69 74 65 33 5f 6c 6f 67 28 29 2e 20 54 68 69  lite3_log(). Thi
c730: 73 20 69 73 20 74 6f 20 68 65 6c 70 20 77 69 74  s is to help wit
c740: 68 20 69 64 65 6e 74 69 66 79 69 6e 67 20 70 65  h identifying pe
c750: 72 66 6f 72 6d 61 6e 63 65 0a 20 20 20 20 2a 2a  rformance.    **
c760: 20 70 72 6f 62 6c 65 6d 73 20 63 61 75 73 65 64   problems caused
c770: 20 62 79 20 61 70 70 6c 69 63 61 74 69 6f 6e 73   by applications
c780: 20 72 6f 75 74 69 6e 65 6c 79 20 73 68 75 74 74   routinely shutt
c790: 69 6e 67 20 64 6f 77 6e 20 77 69 74 68 6f 75 74  ing down without
c7a0: 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69  .    ** checkpoi
c7b0: 6e 74 69 6e 67 20 74 68 65 20 6c 6f 67 20 66 69  nting the log fi
c7c0: 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  le..    */.    i
c7d0: 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61  f( pWal->hdr.nPa
c7e0: 67 65 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  ge ){.      sqli
c7f0: 74 65 33 5f 6c 6f 67 28 53 51 4c 49 54 45 5f 4e  te3_log(SQLITE_N
c800: 4f 54 49 43 45 5f 52 45 43 4f 56 45 52 5f 57 41  OTICE_RECOVER_WA
c810: 4c 2c 0a 20 20 20 20 20 20 20 20 20 20 22 72 65  L,.          "re
c820: 63 6f 76 65 72 65 64 20 25 64 20 66 72 61 6d 65  covered %d frame
c830: 73 20 66 72 6f 6d 20 57 41 4c 20 66 69 6c 65 20  s from WAL file 
c840: 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20 20 70  %s",.          p
c850: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
c860: 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65  , pWal->zWalName
c870: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a  .      );.    }.
c880: 20 20 7d 0a 0a 72 65 63 6f 76 65 72 79 5f 65 72    }..recovery_er
c890: 72 6f 72 3a 0a 20 20 57 41 4c 54 52 41 43 45 28  ror:.  WALTRACE(
c8a0: 28 22 57 41 4c 25 70 3a 20 72 65 63 6f 76 65 72  ("WAL%p: recover
c8b0: 79 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  y %s\n", pWal, r
c8c0: 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
c8d0: 6f 6b 22 29 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f  ok"));.  walUnlo
c8e0: 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
c8f0: 2c 20 69 4c 6f 63 6b 2c 20 57 41 4c 5f 52 45 41  , iLock, WAL_REA
c900: 44 5f 4c 4f 43 4b 28 30 29 2d 69 4c 6f 63 6b 29  D_LOCK(0)-iLock)
c910: 3b 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63  ;.  walUnlockExc
c920: 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
c930: 5f 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57  _READ_LOCK(1), W
c940: 41 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20  AL_NREADER-1);. 
c950: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
c960: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20 6f 70  *.** Close an op
c970: 65 6e 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f  en wal-index..*/
c980: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
c990: 49 6e 64 65 78 43 6c 6f 73 65 28 57 61 6c 20 2a  IndexClose(Wal *
c9a0: 70 57 61 6c 2c 20 69 6e 74 20 69 73 44 65 6c 65  pWal, int isDele
c9b0: 74 65 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d  te){.  if( pWal-
c9c0: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d  >exclusiveMode==
c9d0: 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d  WAL_HEAPMEMORY_M
c9e0: 4f 44 45 20 7c 7c 20 70 57 61 6c 2d 3e 62 53 68  ODE || pWal->bSh
c9f0: 6d 55 6e 72 65 6c 69 61 62 6c 65 20 29 7b 0a 20  mUnreliable ){. 
ca00: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 66 6f     int i;.    fo
ca10: 72 28 69 3d 30 3b 20 69 3c 70 57 61 6c 2d 3e 6e  r(i=0; i<pWal->n
ca20: 57 69 44 61 74 61 3b 20 69 2b 2b 29 7b 0a 20 20  WiData; i++){.  
ca30: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
ca40: 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d 3e 61  ((void *)pWal->a
ca50: 70 57 69 44 61 74 61 5b 69 5d 29 3b 0a 20 20 20  pWiData[i]);.   
ca60: 20 20 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74     pWal->apWiDat
ca70: 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  a[i] = 0;.    }.
ca80: 20 20 7d 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e    }.  if( pWal->
ca90: 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 21 3d 57  exclusiveMode!=W
caa0: 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f  AL_HEAPMEMORY_MO
cab0: 44 45 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  DE ){.    sqlite
cac0: 33 4f 73 53 68 6d 55 6e 6d 61 70 28 70 57 61 6c  3OsShmUnmap(pWal
cad0: 2d 3e 70 44 62 46 64 2c 20 69 73 44 65 6c 65 74  ->pDbFd, isDelet
cae0: 65 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a  e);.  }.}../* .*
caf0: 2a 20 4f 70 65 6e 20 61 20 63 6f 6e 6e 65 63 74  * Open a connect
cb00: 69 6f 6e 20 74 6f 20 74 68 65 20 57 41 4c 20 66  ion to the WAL f
cb10: 69 6c 65 20 7a 57 61 6c 4e 61 6d 65 2e 20 54 68  ile zWalName. Th
cb20: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  e database file 
cb30: 6d 75 73 74 20 0a 2a 2a 20 61 6c 72 65 61 64 79  must .** already
cb40: 20 62 65 20 6f 70 65 6e 65 64 20 6f 6e 20 63 6f   be opened on co
cb50: 6e 6e 65 63 74 69 6f 6e 20 70 44 62 46 64 2e 20  nnection pDbFd. 
cb60: 54 68 65 20 62 75 66 66 65 72 20 74 68 61 74 20  The buffer that 
cb70: 7a 57 61 6c 4e 61 6d 65 20 70 6f 69 6e 74 73 0a  zWalName points.
cb80: 2a 2a 20 74 6f 20 6d 75 73 74 20 72 65 6d 61 69  ** to must remai
cb90: 6e 20 76 61 6c 69 64 20 66 6f 72 20 74 68 65 20  n valid for the 
cba0: 6c 69 66 65 74 69 6d 65 20 6f 66 20 74 68 65 20  lifetime of the 
cbb0: 72 65 74 75 72 6e 65 64 20 57 61 6c 2a 20 68 61  returned Wal* ha
cbc0: 6e 64 6c 65 2e 0a 2a 2a 0a 2a 2a 20 41 20 53 48  ndle..**.** A SH
cbd0: 41 52 45 44 20 6c 6f 63 6b 20 73 68 6f 75 6c 64  ARED lock should
cbe0: 20 62 65 20 68 65 6c 64 20 6f 6e 20 74 68 65 20   be held on the 
cbf0: 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 77 68  database file wh
cc00: 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  en this function
cc10: 0a 2a 2a 20 69 73 20 63 61 6c 6c 65 64 2e 20 54  .** is called. T
cc20: 68 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74 68  he purpose of th
cc30: 69 73 20 53 48 41 52 45 44 20 6c 6f 63 6b 20 69  is SHARED lock i
cc40: 73 20 74 6f 20 70 72 65 76 65 6e 74 20 61 6e 79  s to prevent any
cc50: 20 6f 74 68 65 72 0a 2a 2a 20 63 6c 69 65 6e 74   other.** client
cc60: 20 66 72 6f 6d 20 75 6e 6c 69 6e 6b 69 6e 67 20   from unlinking 
cc70: 74 68 65 20 57 41 4c 20 6f 72 20 77 61 6c 2d 69  the WAL or wal-i
cc80: 6e 64 65 78 20 66 69 6c 65 2e 20 49 66 20 61 6e  ndex file. If an
cc90: 6f 74 68 65 72 20 70 72 6f 63 65 73 73 0a 2a 2a  other process.**
cca0: 20 77 65 72 65 20 74 6f 20 64 6f 20 74 68 69 73   were to do this
ccb0: 20 6a 75 73 74 20 61 66 74 65 72 20 74 68 69 73   just after this
ccc0: 20 63 6c 69 65 6e 74 20 6f 70 65 6e 65 64 20 6f   client opened o
ccd0: 6e 65 20 6f 66 20 74 68 65 73 65 20 66 69 6c 65  ne of these file
cce0: 73 2c 20 74 68 65 0a 2a 2a 20 73 79 73 74 65 6d  s, the.** system
ccf0: 20 77 6f 75 6c 64 20 62 65 20 62 61 64 6c 79 20   would be badly 
cd00: 62 72 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66  broken..**.** If
cd10: 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 69 73   the log file is
cd20: 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20 6f 70   successfully op
cd30: 65 6e 65 64 2c 20 53 51 4c 49 54 45 5f 4f 4b 20  ened, SQLITE_OK 
cd40: 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20  is returned and 
cd50: 0a 2a 2a 20 2a 70 70 57 61 6c 20 69 73 20 73 65  .** *ppWal is se
cd60: 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20  t to point to a 
cd70: 6e 65 77 20 57 41 4c 20 68 61 6e 64 6c 65 2e 20  new WAL handle. 
cd80: 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  If an error occu
cd90: 72 73 2c 0a 2a 2a 20 61 6e 20 53 51 4c 69 74 65  rs,.** an SQLite
cda0: 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72   error code is r
cdb0: 65 74 75 72 6e 65 64 20 61 6e 64 20 2a 70 70 57  eturned and *ppW
cdc0: 61 6c 20 69 73 20 6c 65 66 74 20 75 6e 6d 6f 64  al is left unmod
cdd0: 69 66 69 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71  ified..*/.int sq
cde0: 6c 69 74 65 33 57 61 6c 4f 70 65 6e 28 0a 20 20  lite3WalOpen(.  
cdf0: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
ce00: 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s,              
ce10: 2f 2a 20 76 66 73 20 6d 6f 64 75 6c 65 20 74 6f  /* vfs module to
ce20: 20 6f 70 65 6e 20 77 61 6c 20 61 6e 64 20 77 61   open wal and wa
ce30: 6c 2d 69 6e 64 65 78 20 2a 2f 0a 20 20 73 71 6c  l-index */.  sql
ce40: 69 74 65 33 5f 66 69 6c 65 20 2a 70 44 62 46 64  ite3_file *pDbFd
ce50: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
ce60: 54 68 65 20 6f 70 65 6e 20 64 61 74 61 62 61 73  The open databas
ce70: 65 20 66 69 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73  e file */.  cons
ce80: 74 20 63 68 61 72 20 2a 7a 57 61 6c 4e 61 6d 65  t char *zWalName
ce90: 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  ,           /* N
cea0: 61 6d 65 20 6f 66 20 74 68 65 20 57 41 4c 20 66  ame of the WAL f
ceb0: 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 62 4e 6f  ile */.  int bNo
cec0: 53 68 6d 2c 20 20 20 20 20 20 20 20 20 20 20 20  Shm,            
ced0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
cee0: 20 74 6f 20 72 75 6e 20 69 6e 20 68 65 61 70 2d   to run in heap-
cef0: 6d 65 6d 6f 72 79 20 6d 6f 64 65 20 2a 2f 0a 20  memory mode */. 
cf00: 20 69 36 34 20 6d 78 57 61 6c 53 69 7a 65 2c 20   i64 mxWalSize, 
cf10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cf20: 20 2f 2a 20 54 72 75 6e 63 61 74 65 20 57 41 4c   /* Truncate WAL
cf30: 20 74 6f 20 74 68 69 73 20 73 69 7a 65 20 6f 6e   to this size on
cf40: 20 72 65 73 65 74 20 2a 2f 0a 20 20 57 61 6c 20   reset */.  Wal 
cf50: 2a 2a 70 70 57 61 6c 20 20 20 20 20 20 20 20 20  **ppWal         
cf60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
cf70: 55 54 3a 20 41 6c 6c 6f 63 61 74 65 64 20 57 61  UT: Allocated Wa
cf80: 6c 20 68 61 6e 64 6c 65 20 2a 2f 0a 29 7b 0a 20  l handle */.){. 
cf90: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
cfa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cfb0: 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20   /* Return Code 
cfc0: 2a 2f 0a 20 20 57 61 6c 20 2a 70 52 65 74 3b 20  */.  Wal *pRet; 
cfd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cfe0: 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 74       /* Object t
cff0: 6f 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72  o allocate and r
d000: 65 74 75 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 66  eturn */.  int f
d010: 6c 61 67 73 3b 20 20 20 20 20 20 20 20 20 20 20  lags;           
d020: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c             /* Fl
d030: 61 67 73 20 70 61 73 73 65 64 20 74 6f 20 4f 73  ags passed to Os
d040: 4f 70 65 6e 28 29 20 2a 2f 0a 0a 20 20 61 73 73  Open() */..  ass
d050: 65 72 74 28 20 7a 57 61 6c 4e 61 6d 65 20 26 26  ert( zWalName &&
d060: 20 7a 57 61 6c 4e 61 6d 65 5b 30 5d 20 29 3b 0a   zWalName[0] );.
d070: 20 20 61 73 73 65 72 74 28 20 70 44 62 46 64 20    assert( pDbFd 
d080: 29 3b 0a 0a 20 20 2f 2a 20 49 6e 20 74 68 65 20  );..  /* In the 
d090: 61 6d 61 6c 67 61 6d 61 74 69 6f 6e 2c 20 74 68  amalgamation, th
d0a0: 65 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e 64 20  e os_unix.c and 
d0b0: 6f 73 5f 77 69 6e 2e 63 20 73 6f 75 72 63 65 20  os_win.c source 
d0c0: 66 69 6c 65 73 20 63 6f 6d 65 20 62 65 66 6f 72  files come befor
d0d0: 65 0a 20 20 2a 2a 20 74 68 69 73 20 73 6f 75 72  e.  ** this sour
d0e0: 63 65 20 66 69 6c 65 2e 20 20 56 65 72 69 66 79  ce file.  Verify
d0f0: 20 74 68 61 74 20 74 68 65 20 23 64 65 66 69 6e   that the #defin
d100: 65 73 20 6f 66 20 74 68 65 20 6c 6f 63 6b 69 6e  es of the lockin
d110: 67 20 62 79 74 65 20 6f 66 66 73 65 74 73 0a 20  g byte offsets. 
d120: 20 2a 2a 20 69 6e 20 6f 73 5f 75 6e 69 78 2e 63   ** in os_unix.c
d130: 20 61 6e 64 20 6f 73 5f 77 69 6e 2e 63 20 61 67   and os_win.c ag
d140: 72 65 65 20 77 69 74 68 20 74 68 65 20 57 41 4c  ree with the WAL
d150: 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45  INDEX_LOCK_OFFSE
d160: 54 20 76 61 6c 75 65 2e 0a 20 20 2a 2a 20 46 6f  T value..  ** Fo
d170: 72 20 74 68 61 74 20 6d 61 74 74 65 72 2c 20 69  r that matter, i
d180: 66 20 74 68 65 20 6c 6f 63 6b 20 6f 66 66 73 65  f the lock offse
d190: 74 20 65 76 65 72 20 63 68 61 6e 67 65 73 20 66  t ever changes f
d1a0: 72 6f 6d 20 69 74 73 20 69 6e 69 74 69 61 6c 20  rom its initial 
d1b0: 64 65 73 69 67 6e 0a 20 20 2a 2a 20 76 61 6c 75  design.  ** valu
d1c0: 65 20 6f 66 20 31 32 30 2c 20 77 65 20 6e 65 65  e of 120, we nee
d1d0: 64 20 74 6f 20 6b 6e 6f 77 20 74 68 61 74 20 73  d to know that s
d1e0: 6f 20 74 68 65 72 65 20 69 73 20 61 6e 20 61 73  o there is an as
d1f0: 73 65 72 74 28 29 20 74 6f 20 63 68 65 63 6b 20  sert() to check 
d200: 69 74 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72  it..  */.  asser
d210: 74 28 20 31 32 30 3d 3d 57 41 4c 49 4e 44 45 58  t( 120==WALINDEX
d220: 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a  _LOCK_OFFSET );.
d230: 20 20 61 73 73 65 72 74 28 20 31 33 36 3d 3d 57    assert( 136==W
d240: 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45  ALINDEX_HDR_SIZE
d250: 20 29 3b 0a 23 69 66 64 65 66 20 57 49 4e 5f 53   );.#ifdef WIN_S
d260: 48 4d 5f 42 41 53 45 0a 20 20 61 73 73 65 72 74  HM_BASE.  assert
d270: 28 20 57 49 4e 5f 53 48 4d 5f 42 41 53 45 3d 3d  ( WIN_SHM_BASE==
d280: 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46  WALINDEX_LOCK_OF
d290: 46 53 45 54 20 29 3b 0a 23 65 6e 64 69 66 0a 23  FSET );.#endif.#
d2a0: 69 66 64 65 66 20 55 4e 49 58 5f 53 48 4d 5f 42  ifdef UNIX_SHM_B
d2b0: 41 53 45 0a 20 20 61 73 73 65 72 74 28 20 55 4e  ASE.  assert( UN
d2c0: 49 58 5f 53 48 4d 5f 42 41 53 45 3d 3d 57 41 4c  IX_SHM_BASE==WAL
d2d0: 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45  INDEX_LOCK_OFFSE
d2e0: 54 20 29 3b 0a 23 65 6e 64 69 66 0a 0a 0a 20 20  T );.#endif...  
d2f0: 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 6e 20 69  /* Allocate an i
d300: 6e 73 74 61 6e 63 65 20 6f 66 20 73 74 72 75 63  nstance of struc
d310: 74 20 57 61 6c 20 74 6f 20 72 65 74 75 72 6e 2e  t Wal to return.
d320: 20 2a 2f 0a 20 20 2a 70 70 57 61 6c 20 3d 20 30   */.  *ppWal = 0
d330: 3b 0a 20 20 70 52 65 74 20 3d 20 28 57 61 6c 2a  ;.  pRet = (Wal*
d340: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65  )sqlite3MallocZe
d350: 72 6f 28 73 69 7a 65 6f 66 28 57 61 6c 29 20 2b  ro(sizeof(Wal) +
d360: 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 29   pVfs->szOsFile)
d370: 3b 0a 20 20 69 66 28 20 21 70 52 65 74 20 29 7b  ;.  if( !pRet ){
d380: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
d390: 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20  TE_NOMEM_BKPT;. 
d3a0: 20 7d 0a 0a 20 20 70 52 65 74 2d 3e 70 56 66 73   }..  pRet->pVfs
d3b0: 20 3d 20 70 56 66 73 3b 0a 20 20 70 52 65 74 2d   = pVfs;.  pRet-
d3c0: 3e 70 57 61 6c 46 64 20 3d 20 28 73 71 6c 69 74  >pWalFd = (sqlit
d3d0: 65 33 5f 66 69 6c 65 20 2a 29 26 70 52 65 74 5b  e3_file *)&pRet[
d3e0: 31 5d 3b 0a 20 20 70 52 65 74 2d 3e 70 44 62 46  1];.  pRet->pDbF
d3f0: 64 20 3d 20 70 44 62 46 64 3b 0a 20 20 70 52 65  d = pDbFd;.  pRe
d400: 74 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31  t->readLock = -1
d410: 3b 0a 20 20 70 52 65 74 2d 3e 6d 78 57 61 6c 53  ;.  pRet->mxWalS
d420: 69 7a 65 20 3d 20 6d 78 57 61 6c 53 69 7a 65 3b  ize = mxWalSize;
d430: 0a 20 20 70 52 65 74 2d 3e 7a 57 61 6c 4e 61 6d  .  pRet->zWalNam
d440: 65 20 3d 20 7a 57 61 6c 4e 61 6d 65 3b 0a 20 20  e = zWalName;.  
d450: 70 52 65 74 2d 3e 73 79 6e 63 48 65 61 64 65 72  pRet->syncHeader
d460: 20 3d 20 31 3b 0a 20 20 70 52 65 74 2d 3e 70 61   = 1;.  pRet->pa
d470: 64 54 6f 53 65 63 74 6f 72 42 6f 75 6e 64 61 72  dToSectorBoundar
d480: 79 20 3d 20 31 3b 0a 20 20 70 52 65 74 2d 3e 65  y = 1;.  pRet->e
d490: 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 28  xclusiveMode = (
d4a0: 62 4e 6f 53 68 6d 20 3f 20 57 41 4c 5f 48 45 41  bNoShm ? WAL_HEA
d4b0: 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 3a 20 57 41  PMEMORY_MODE: WA
d4c0: 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 29 3b 0a  L_NORMAL_MODE);.
d4d0: 0a 20 20 2f 2a 20 4f 70 65 6e 20 66 69 6c 65 20  .  /* Open file 
d4e0: 68 61 6e 64 6c 65 20 6f 6e 20 74 68 65 20 77 72  handle on the wr
d4f0: 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69  ite-ahead log fi
d500: 6c 65 2e 20 2a 2f 0a 20 20 66 6c 61 67 73 20 3d  le. */.  flags =
d510: 20 28 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45   (SQLITE_OPEN_RE
d520: 41 44 57 52 49 54 45 7c 53 51 4c 49 54 45 5f 4f  ADWRITE|SQLITE_O
d530: 50 45 4e 5f 43 52 45 41 54 45 7c 53 51 4c 49 54  PEN_CREATE|SQLIT
d540: 45 5f 4f 50 45 4e 5f 57 41 4c 29 3b 0a 20 20 72  E_OPEN_WAL);.  r
d550: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 4f 70 65  c = sqlite3OsOpe
d560: 6e 28 70 56 66 73 2c 20 7a 57 61 6c 4e 61 6d 65  n(pVfs, zWalName
d570: 2c 20 70 52 65 74 2d 3e 70 57 61 6c 46 64 2c 20  , pRet->pWalFd, 
d580: 66 6c 61 67 73 2c 20 26 66 6c 61 67 73 29 3b 0a  flags, &flags);.
d590: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
d5a0: 5f 4f 4b 20 26 26 20 66 6c 61 67 73 26 53 51 4c  _OK && flags&SQL
d5b0: 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 4f 4e 4c  ITE_OPEN_READONL
d5c0: 59 20 29 7b 0a 20 20 20 20 70 52 65 74 2d 3e 72  Y ){.    pRet->r
d5d0: 65 61 64 4f 6e 6c 79 20 3d 20 57 41 4c 5f 52 44  eadOnly = WAL_RD
d5e0: 4f 4e 4c 59 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  ONLY;.  }..  if(
d5f0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
d600: 7b 0a 20 20 20 20 77 61 6c 49 6e 64 65 78 43 6c  {.    walIndexCl
d610: 6f 73 65 28 70 52 65 74 2c 20 30 29 3b 0a 20 20  ose(pRet, 0);.  
d620: 20 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65    sqlite3OsClose
d630: 28 70 52 65 74 2d 3e 70 57 61 6c 46 64 29 3b 0a  (pRet->pWalFd);.
d640: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
d650: 28 70 52 65 74 29 3b 0a 20 20 7d 65 6c 73 65 7b  (pRet);.  }else{
d660: 0a 20 20 20 20 69 6e 74 20 69 44 43 20 3d 20 73  .    int iDC = s
d670: 71 6c 69 74 65 33 4f 73 44 65 76 69 63 65 43 68  qlite3OsDeviceCh
d680: 61 72 61 63 74 65 72 69 73 74 69 63 73 28 70 44  aracteristics(pD
d690: 62 46 64 29 3b 0a 20 20 20 20 69 66 28 20 69 44  bFd);.    if( iD
d6a0: 43 20 26 20 53 51 4c 49 54 45 5f 49 4f 43 41 50  C & SQLITE_IOCAP
d6b0: 5f 53 45 51 55 45 4e 54 49 41 4c 20 29 7b 20 70  _SEQUENTIAL ){ p
d6c0: 52 65 74 2d 3e 73 79 6e 63 48 65 61 64 65 72 20  Ret->syncHeader 
d6d0: 3d 20 30 3b 20 7d 0a 20 20 20 20 69 66 28 20 69  = 0; }.    if( i
d6e0: 44 43 20 26 20 53 51 4c 49 54 45 5f 49 4f 43 41  DC & SQLITE_IOCA
d6f0: 50 5f 50 4f 57 45 52 53 41 46 45 5f 4f 56 45 52  P_POWERSAFE_OVER
d700: 57 52 49 54 45 20 29 7b 0a 20 20 20 20 20 20 70  WRITE ){.      p
d710: 52 65 74 2d 3e 70 61 64 54 6f 53 65 63 74 6f 72  Ret->padToSector
d720: 42 6f 75 6e 64 61 72 79 20 3d 20 30 3b 0a 20 20  Boundary = 0;.  
d730: 20 20 7d 0a 20 20 20 20 2a 70 70 57 61 6c 20 3d    }.    *ppWal =
d740: 20 70 52 65 74 3b 0a 20 20 20 20 57 41 4c 54 52   pRet;.    WALTR
d750: 41 43 45 28 28 22 57 41 4c 25 64 3a 20 6f 70 65  ACE(("WAL%d: ope
d760: 6e 65 64 5c 6e 22 2c 20 70 52 65 74 29 29 3b 0a  ned\n", pRet));.
d770: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
d780: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65  .}../*.** Change
d790: 20 74 68 65 20 73 69 7a 65 20 74 6f 20 77 68 69   the size to whi
d7a0: 63 68 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20  ch the WAL file 
d7b0: 69 73 20 74 72 75 63 61 74 65 64 20 6f 6e 20 65  is trucated on e
d7c0: 61 63 68 20 72 65 73 65 74 2e 0a 2a 2f 0a 76 6f  ach reset..*/.vo
d7d0: 69 64 20 73 71 6c 69 74 65 33 57 61 6c 4c 69 6d  id sqlite3WalLim
d7e0: 69 74 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 36  it(Wal *pWal, i6
d7f0: 34 20 69 4c 69 6d 69 74 29 7b 0a 20 20 69 66 28  4 iLimit){.  if(
d800: 20 70 57 61 6c 20 29 20 70 57 61 6c 2d 3e 6d 78   pWal ) pWal->mx
d810: 57 61 6c 53 69 7a 65 20 3d 20 69 4c 69 6d 69 74  WalSize = iLimit
d820: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 64 20  ;.}../*.** Find 
d830: 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70 61 67  the smallest pag
d840: 65 20 6e 75 6d 62 65 72 20 6f 75 74 20 6f 66 20  e number out of 
d850: 61 6c 6c 20 70 61 67 65 73 20 68 65 6c 64 20 69  all pages held i
d860: 6e 20 74 68 65 20 57 41 4c 20 74 68 61 74 0a 2a  n the WAL that.*
d870: 2a 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 72  * has not been r
d880: 65 74 75 72 6e 65 64 20 62 79 20 61 6e 79 20 70  eturned by any p
d890: 72 69 6f 72 20 69 6e 76 6f 63 61 74 69 6f 6e 20  rior invocation 
d8a0: 6f 66 20 74 68 69 73 20 6d 65 74 68 6f 64 20 6f  of this method o
d8b0: 6e 20 74 68 65 0a 2a 2a 20 73 61 6d 65 20 57 61  n the.** same Wa
d8c0: 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74  lIterator object
d8d0: 2e 20 20 20 57 72 69 74 65 20 69 6e 74 6f 20 2a  .   Write into *
d8e0: 70 69 46 72 61 6d 65 20 74 68 65 20 66 72 61 6d  piFrame the fram
d8f0: 65 20 69 6e 64 65 78 20 77 68 65 72 65 0a 2a 2a  e index where.**
d900: 20 74 68 61 74 20 70 61 67 65 20 77 61 73 20 6c   that page was l
d910: 61 73 74 20 77 72 69 74 74 65 6e 20 69 6e 74 6f  ast written into
d920: 20 74 68 65 20 57 41 4c 2e 20 20 57 72 69 74 65   the WAL.  Write
d930: 20 69 6e 74 6f 20 2a 70 69 50 61 67 65 20 74 68   into *piPage th
d940: 65 20 70 61 67 65 0a 2a 2a 20 6e 75 6d 62 65 72  e page.** number
d950: 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 30  ..**.** Return 0
d960: 20 6f 6e 20 73 75 63 63 65 73 73 2e 20 20 49 66   on success.  If
d970: 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 70 61   there are no pa
d980: 67 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20 77  ges in the WAL w
d990: 69 74 68 20 61 20 70 61 67 65 0a 2a 2a 20 6e 75  ith a page.** nu
d9a0: 6d 62 65 72 20 6c 61 72 67 65 72 20 74 68 61 6e  mber larger than
d9b0: 20 2a 70 69 50 61 67 65 2c 20 74 68 65 6e 20 72   *piPage, then r
d9c0: 65 74 75 72 6e 20 31 2e 0a 2a 2f 0a 73 74 61 74  eturn 1..*/.stat
d9d0: 69 63 20 69 6e 74 20 77 61 6c 49 74 65 72 61 74  ic int walIterat
d9e0: 6f 72 4e 65 78 74 28 0a 20 20 57 61 6c 49 74 65  orNext(.  WalIte
d9f0: 72 61 74 6f 72 20 2a 70 2c 20 20 20 20 20 20 20  rator *p,       
da00: 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61          /* Itera
da10: 74 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69  tor */.  u32 *pi
da20: 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20  Page,           
da30: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54         /* OUT: T
da40: 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f  he page number o
da50: 66 20 74 68 65 20 6e 65 78 74 20 70 61 67 65 20  f the next page 
da60: 2a 2f 0a 20 20 75 33 32 20 2a 70 69 46 72 61 6d  */.  u32 *piFram
da70: 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e               
da80: 20 20 20 2f 2a 20 4f 55 54 3a 20 57 61 6c 20 66     /* OUT: Wal f
da90: 72 61 6d 65 20 69 6e 64 65 78 20 6f 66 20 6e 65  rame index of ne
daa0: 78 74 20 70 61 67 65 20 2a 2f 0a 29 7b 0a 20 20  xt page */.){.  
dab0: 75 33 32 20 69 4d 69 6e 3b 20 20 20 20 20 20 20  u32 iMin;       
dac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
dad0: 20 52 65 73 75 6c 74 20 70 67 6e 6f 20 6d 75 73   Result pgno mus
dae0: 74 20 62 65 20 67 72 65 61 74 65 72 20 74 68 61  t be greater tha
daf0: 6e 20 69 4d 69 6e 20 2a 2f 0a 20 20 75 33 32 20  n iMin */.  u32 
db00: 69 52 65 74 20 3d 20 30 78 46 46 46 46 46 46 46  iRet = 0xFFFFFFF
db10: 46 3b 20 20 20 20 20 20 20 20 2f 2a 20 30 78 66  F;        /* 0xf
db20: 66 66 66 66 66 66 66 20 69 73 20 6e 65 76 65 72  fffffff is never
db30: 20 61 20 76 61 6c 69 64 20 70 61 67 65 20 6e 75   a valid page nu
db40: 6d 62 65 72 20 2a 2f 0a 20 20 69 6e 74 20 69 3b  mber */.  int i;
db50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
db60: 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 6c          /* For l
db70: 6f 6f 70 69 6e 67 20 74 68 72 6f 75 67 68 20 73  ooping through s
db80: 65 67 6d 65 6e 74 73 20 2a 2f 0a 0a 20 20 69 4d  egments */..  iM
db90: 69 6e 20 3d 20 70 2d 3e 69 50 72 69 6f 72 3b 0a  in = p->iPrior;.
dba0: 20 20 61 73 73 65 72 74 28 20 69 4d 69 6e 3c 30    assert( iMin<0
dbb0: 78 66 66 66 66 66 66 66 66 20 29 3b 0a 20 20 66  xffffffff );.  f
dbc0: 6f 72 28 69 3d 70 2d 3e 6e 53 65 67 6d 65 6e 74  or(i=p->nSegment
dbd0: 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29 7b 0a  -1; i>=0; i--){.
dbe0: 20 20 20 20 73 74 72 75 63 74 20 57 61 6c 53 65      struct WalSe
dbf0: 67 6d 65 6e 74 20 2a 70 53 65 67 6d 65 6e 74 20  gment *pSegment 
dc00: 3d 20 26 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69  = &p->aSegment[i
dc10: 5d 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 70 53  ];.    while( pS
dc20: 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 3c 70 53  egment->iNext<pS
dc30: 65 67 6d 65 6e 74 2d 3e 6e 45 6e 74 72 79 20 29  egment->nEntry )
dc40: 7b 0a 20 20 20 20 20 20 75 33 32 20 69 50 67 20  {.      u32 iPg 
dc50: 3d 20 70 53 65 67 6d 65 6e 74 2d 3e 61 50 67 6e  = pSegment->aPgn
dc60: 6f 5b 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e 64  o[pSegment->aInd
dc70: 65 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65  ex[pSegment->iNe
dc80: 78 74 5d 5d 3b 0a 20 20 20 20 20 20 69 66 28 20  xt]];.      if( 
dc90: 69 50 67 3e 69 4d 69 6e 20 29 7b 0a 20 20 20 20  iPg>iMin ){.    
dca0: 20 20 20 20 69 66 28 20 69 50 67 3c 69 52 65 74      if( iPg<iRet
dcb0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 52   ){.          iR
dcc0: 65 74 20 3d 20 69 50 67 3b 0a 20 20 20 20 20 20  et = iPg;.      
dcd0: 20 20 20 20 2a 70 69 46 72 61 6d 65 20 3d 20 70      *piFrame = p
dce0: 53 65 67 6d 65 6e 74 2d 3e 69 5a 65 72 6f 20 2b  Segment->iZero +
dcf0: 20 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e 64 65   pSegment->aInde
dd00: 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78  x[pSegment->iNex
dd10: 74 5d 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  t];.        }.  
dd20: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
dd30: 20 20 20 7d 0a 20 20 20 20 20 20 70 53 65 67 6d     }.      pSegm
dd40: 65 6e 74 2d 3e 69 4e 65 78 74 2b 2b 3b 0a 20 20  ent->iNext++;.  
dd50: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 69 50 61    }.  }..  *piPa
dd60: 67 65 20 3d 20 70 2d 3e 69 50 72 69 6f 72 20 3d  ge = p->iPrior =
dd70: 20 69 52 65 74 3b 0a 20 20 72 65 74 75 72 6e 20   iRet;.  return 
dd80: 28 69 52 65 74 3d 3d 30 78 46 46 46 46 46 46 46  (iRet==0xFFFFFFF
dd90: 46 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  F);.}../*.** Thi
dda0: 73 20 66 75 6e 63 74 69 6f 6e 20 6d 65 72 67 65  s function merge
ddb0: 73 20 74 77 6f 20 73 6f 72 74 65 64 20 6c 69 73  s two sorted lis
ddc0: 74 73 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65  ts into a single
ddd0: 20 73 6f 72 74 65 64 20 6c 69 73 74 2e 0a 2a 2a   sorted list..**
dde0: 0a 2a 2a 20 61 4c 65 66 74 5b 5d 20 61 6e 64 20  .** aLeft[] and 
ddf0: 61 52 69 67 68 74 5b 5d 20 61 72 65 20 61 72 72  aRight[] are arr
de00: 61 79 73 20 6f 66 20 69 6e 64 69 63 65 73 2e 20  ays of indices. 
de10: 20 54 68 65 20 73 6f 72 74 20 6b 65 79 20 69 73   The sort key is
de20: 0a 2a 2a 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65  .** aContent[aLe
de30: 66 74 5b 5d 5d 20 61 6e 64 20 61 43 6f 6e 74 65  ft[]] and aConte
de40: 6e 74 5b 61 52 69 67 68 74 5b 5d 5d 2e 20 20 55  nt[aRight[]].  U
de50: 70 6f 6e 20 65 6e 74 72 79 2c 20 74 68 65 20 66  pon entry, the f
de60: 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 69 73 20 67  ollowing.** is g
de70: 75 61 72 61 6e 74 65 65 64 20 66 6f 72 20 61 6c  uaranteed for al
de80: 6c 20 4a 3c 4b 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  l J<K:.**.**    
de90: 20 20 20 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65      aContent[aLe
dea0: 66 74 5b 4a 5d 5d 20 3c 20 61 43 6f 6e 74 65 6e  ft[J]] < aConten
deb0: 74 5b 61 4c 65 66 74 5b 4b 5d 5d 0a 2a 2a 20 20  t[aLeft[K]].**  
dec0: 20 20 20 20 20 20 61 43 6f 6e 74 65 6e 74 5b 61        aContent[a
ded0: 52 69 67 68 74 5b 4a 5d 5d 20 3c 20 61 43 6f 6e  Right[J]] < aCon
dee0: 74 65 6e 74 5b 61 52 69 67 68 74 5b 4b 5d 5d 0a  tent[aRight[K]].
def0: 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  **.** This routi
df00: 6e 65 20 6f 76 65 72 77 72 69 74 65 73 20 61 52  ne overwrites aR
df10: 69 67 68 74 5b 5d 20 77 69 74 68 20 61 20 6e 65  ight[] with a ne
df20: 77 20 28 70 72 6f 62 61 62 6c 79 20 6c 6f 6e 67  w (probably long
df30: 65 72 29 20 73 65 71 75 65 6e 63 65 0a 2a 2a 20  er) sequence.** 
df40: 6f 66 20 69 6e 64 69 63 65 73 20 73 75 63 68 20  of indices such 
df50: 74 68 61 74 20 74 68 65 20 61 52 69 67 68 74 5b  that the aRight[
df60: 5d 20 63 6f 6e 74 61 69 6e 73 20 65 76 65 72 79  ] contains every
df70: 20 69 6e 64 65 78 20 74 68 61 74 20 61 70 70 65   index that appe
df80: 61 72 73 20 69 6e 0a 2a 2a 20 65 69 74 68 65 72  ars in.** either
df90: 20 61 4c 65 66 74 5b 5d 20 6f 72 20 74 68 65 20   aLeft[] or the 
dfa0: 6f 6c 64 20 61 52 69 67 68 74 5b 5d 20 61 6e 64  old aRight[] and
dfb0: 20 73 75 63 68 20 74 68 61 74 20 74 68 65 20 73   such that the s
dfc0: 65 63 6f 6e 64 20 63 6f 6e 64 69 74 69 6f 6e 0a  econd condition.
dfd0: 2a 2a 20 61 62 6f 76 65 20 69 73 20 73 74 69 6c  ** above is stil
dfe0: 6c 20 6d 65 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  l met..**.** The
dff0: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b   aContent[aLeft[
e000: 58 5d 5d 20 76 61 6c 75 65 73 20 77 69 6c 6c 20  X]] values will 
e010: 62 65 20 75 6e 69 71 75 65 20 66 6f 72 20 61 6c  be unique for al
e020: 6c 20 58 2e 20 20 41 6e 64 20 74 68 65 0a 2a 2a  l X.  And the.**
e030: 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74   aContent[aRight
e040: 5b 58 5d 5d 20 76 61 6c 75 65 73 20 77 69 6c 6c  [X]] values will
e050: 20 62 65 20 75 6e 69 71 75 65 20 74 6f 6f 2e 20   be unique too. 
e060: 20 42 75 74 20 74 68 65 72 65 20 6d 69 67 68 74   But there might
e070: 20 62 65 0a 2a 2a 20 6f 6e 65 20 6f 72 20 6d 6f   be.** one or mo
e080: 72 65 20 63 6f 6d 62 69 6e 61 74 69 6f 6e 73 20  re combinations 
e090: 6f 66 20 58 20 61 6e 64 20 59 20 73 75 63 68 20  of X and Y such 
e0a0: 74 68 61 74 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  that.**.**      
e0b0: 61 4c 65 66 74 5b 58 5d 21 3d 61 52 69 67 68 74  aLeft[X]!=aRight
e0c0: 5b 59 5d 20 20 26 26 20 20 61 43 6f 6e 74 65 6e  [Y]  &&  aConten
e0d0: 74 5b 61 4c 65 66 74 5b 58 5d 5d 20 3d 3d 20 61  t[aLeft[X]] == a
e0e0: 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b 59  Content[aRight[Y
e0f0: 5d 5d 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 74 68  ]].**.** When th
e100: 61 74 20 68 61 70 70 65 6e 73 2c 20 6f 6d 69 74  at happens, omit
e110: 20 74 68 65 20 61 4c 65 66 74 5b 58 5d 20 61 6e   the aLeft[X] an
e120: 64 20 75 73 65 20 74 68 65 20 61 52 69 67 68 74  d use the aRight
e130: 5b 59 5d 20 69 6e 64 65 78 2e 0a 2a 2f 0a 73 74  [Y] index..*/.st
e140: 61 74 69 63 20 76 6f 69 64 20 77 61 6c 4d 65 72  atic void walMer
e150: 67 65 28 0a 20 20 63 6f 6e 73 74 20 75 33 32 20  ge(.  const u32 
e160: 2a 61 43 6f 6e 74 65 6e 74 2c 20 20 20 20 20 20  *aContent,      
e170: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 73 20 69        /* Pages i
e180: 6e 20 77 61 6c 20 2d 20 6b 65 79 73 20 66 6f 72  n wal - keys for
e190: 20 74 68 65 20 73 6f 72 74 20 2a 2f 0a 20 20 68   the sort */.  h
e1a0: 74 5f 73 6c 6f 74 20 2a 61 4c 65 66 74 2c 20 20  t_slot *aLeft,  
e1b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e1c0: 2a 20 49 4e 3a 20 4c 65 66 74 20 68 61 6e 64 20  * IN: Left hand 
e1d0: 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20  input list */.  
e1e0: 69 6e 74 20 6e 4c 65 66 74 2c 20 20 20 20 20 20  int nLeft,      
e1f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e200: 2f 2a 20 49 4e 3a 20 45 6c 65 6d 65 6e 74 73 20  /* IN: Elements 
e210: 69 6e 20 61 72 72 61 79 20 2a 70 61 4c 65 66 74  in array *paLeft
e220: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 2a   */.  ht_slot **
e230: 70 61 52 69 67 68 74 2c 20 20 20 20 20 20 20 20  paRight,        
e240: 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a        /* IN/OUT:
e250: 20 52 69 67 68 74 20 68 61 6e 64 20 69 6e 70 75   Right hand inpu
e260: 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20  t list */.  int 
e270: 2a 70 6e 52 69 67 68 74 2c 20 20 20 20 20 20 20  *pnRight,       
e280: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
e290: 4e 2f 4f 55 54 3a 20 45 6c 65 6d 65 6e 74 73 20  N/OUT: Elements 
e2a0: 69 6e 20 2a 70 61 52 69 67 68 74 20 2a 2f 0a 20  in *paRight */. 
e2b0: 20 68 74 5f 73 6c 6f 74 20 2a 61 54 6d 70 20 20   ht_slot *aTmp  
e2c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e2d0: 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62 75   /* Temporary bu
e2e0: 66 66 65 72 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ffer */.){.  int
e2f0: 20 69 4c 65 66 74 20 3d 20 30 3b 20 20 20 20 20   iLeft = 0;     
e300: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e310: 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e  Current index in
e320: 20 61 4c 65 66 74 20 2a 2f 0a 20 20 69 6e 74 20   aLeft */.  int 
e330: 69 52 69 67 68 74 20 3d 20 30 3b 20 20 20 20 20  iRight = 0;     
e340: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
e350: 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e 20  urrent index in 
e360: 61 52 69 67 68 74 20 2a 2f 0a 20 20 69 6e 74 20  aRight */.  int 
e370: 69 4f 75 74 20 3d 20 30 3b 20 20 20 20 20 20 20  iOut = 0;       
e380: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
e390: 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e 20  urrent index in 
e3a0: 6f 75 74 70 75 74 20 62 75 66 66 65 72 20 2a 2f  output buffer */
e3b0: 0a 20 20 69 6e 74 20 6e 52 69 67 68 74 20 3d 20  .  int nRight = 
e3c0: 2a 70 6e 52 69 67 68 74 3b 0a 20 20 68 74 5f 73  *pnRight;.  ht_s
e3d0: 6c 6f 74 20 2a 61 52 69 67 68 74 20 3d 20 2a 70  lot *aRight = *p
e3e0: 61 52 69 67 68 74 3b 0a 0a 20 20 61 73 73 65 72  aRight;..  asser
e3f0: 74 28 20 6e 4c 65 66 74 3e 30 20 26 26 20 6e 52  t( nLeft>0 && nR
e400: 69 67 68 74 3e 30 20 29 3b 0a 20 20 77 68 69 6c  ight>0 );.  whil
e410: 65 28 20 69 52 69 67 68 74 3c 6e 52 69 67 68 74  e( iRight<nRight
e420: 20 7c 7c 20 69 4c 65 66 74 3c 6e 4c 65 66 74 20   || iLeft<nLeft 
e430: 29 7b 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20 6c  ){.    ht_slot l
e440: 6f 67 70 61 67 65 3b 0a 20 20 20 20 50 67 6e 6f  ogpage;.    Pgno
e450: 20 64 62 70 61 67 65 3b 0a 0a 20 20 20 20 69 66   dbpage;..    if
e460: 28 20 28 69 4c 65 66 74 3c 6e 4c 65 66 74 29 20  ( (iLeft<nLeft) 
e470: 0a 20 20 20 20 20 26 26 20 28 69 52 69 67 68 74  .     && (iRight
e480: 3e 3d 6e 52 69 67 68 74 20 7c 7c 20 61 43 6f 6e  >=nRight || aCon
e490: 74 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74  tent[aLeft[iLeft
e4a0: 5d 5d 3c 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67  ]]<aContent[aRig
e4b0: 68 74 5b 69 52 69 67 68 74 5d 5d 29 0a 20 20 20  ht[iRight]]).   
e4c0: 20 29 7b 0a 20 20 20 20 20 20 6c 6f 67 70 61 67   ){.      logpag
e4d0: 65 20 3d 20 61 4c 65 66 74 5b 69 4c 65 66 74 2b  e = aLeft[iLeft+
e4e0: 2b 5d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  +];.    }else{. 
e4f0: 20 20 20 20 20 6c 6f 67 70 61 67 65 20 3d 20 61       logpage = a
e500: 52 69 67 68 74 5b 69 52 69 67 68 74 2b 2b 5d 3b  Right[iRight++];
e510: 0a 20 20 20 20 7d 0a 20 20 20 20 64 62 70 61 67  .    }.    dbpag
e520: 65 20 3d 20 61 43 6f 6e 74 65 6e 74 5b 6c 6f 67  e = aContent[log
e530: 70 61 67 65 5d 3b 0a 0a 20 20 20 20 61 54 6d 70  page];..    aTmp
e540: 5b 69 4f 75 74 2b 2b 5d 20 3d 20 6c 6f 67 70 61  [iOut++] = logpa
e550: 67 65 3b 0a 20 20 20 20 69 66 28 20 69 4c 65 66  ge;.    if( iLef
e560: 74 3c 6e 4c 65 66 74 20 26 26 20 61 43 6f 6e 74  t<nLeft && aCont
e570: 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74 5d  ent[aLeft[iLeft]
e580: 5d 3d 3d 64 62 70 61 67 65 20 29 20 69 4c 65 66  ]==dbpage ) iLef
e590: 74 2b 2b 3b 0a 0a 20 20 20 20 61 73 73 65 72 74  t++;..    assert
e5a0: 28 20 69 4c 65 66 74 3e 3d 6e 4c 65 66 74 20 7c  ( iLeft>=nLeft |
e5b0: 7c 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74  | aContent[aLeft
e5c0: 5b 69 4c 65 66 74 5d 5d 3e 64 62 70 61 67 65 20  [iLeft]]>dbpage 
e5d0: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 69  );.    assert( i
e5e0: 52 69 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c  Right>=nRight ||
e5f0: 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74   aContent[aRight
e600: 5b 69 52 69 67 68 74 5d 5d 3e 64 62 70 61 67 65  [iRight]]>dbpage
e610: 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 61 52 69   );.  }..  *paRi
e620: 67 68 74 20 3d 20 61 4c 65 66 74 3b 0a 20 20 2a  ght = aLeft;.  *
e630: 70 6e 52 69 67 68 74 20 3d 20 69 4f 75 74 3b 0a  pnRight = iOut;.
e640: 20 20 6d 65 6d 63 70 79 28 61 4c 65 66 74 2c 20    memcpy(aLeft, 
e650: 61 54 6d 70 2c 20 73 69 7a 65 6f 66 28 61 54 6d  aTmp, sizeof(aTm
e660: 70 5b 30 5d 29 2a 69 4f 75 74 29 3b 0a 7d 0a 0a  p[0])*iOut);.}..
e670: 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74 68 65 20 65  /*.** Sort the e
e680: 6c 65 6d 65 6e 74 73 20 69 6e 20 6c 69 73 74 20  lements in list 
e690: 61 4c 69 73 74 20 75 73 69 6e 67 20 61 43 6f 6e  aList using aCon
e6a0: 74 65 6e 74 5b 5d 20 61 73 20 74 68 65 20 73 6f  tent[] as the so
e6b0: 72 74 20 6b 65 79 2e 0a 2a 2a 20 52 65 6d 6f 76  rt key..** Remov
e6c0: 65 20 65 6c 65 6d 65 6e 74 73 20 77 69 74 68 20  e elements with 
e6d0: 64 75 70 6c 69 63 61 74 65 20 6b 65 79 73 2c 20  duplicate keys, 
e6e0: 70 72 65 66 65 72 72 69 6e 67 20 74 6f 20 6b 65  preferring to ke
e6f0: 65 70 20 74 68 65 0a 2a 2a 20 6c 61 72 67 65 72  ep the.** larger
e700: 20 61 4c 69 73 74 5b 5d 20 76 61 6c 75 65 73 2e   aList[] values.
e710: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 4c 69 73 74  .**.** The aList
e720: 5b 5d 20 65 6e 74 72 69 65 73 20 61 72 65 20 69  [] entries are i
e730: 6e 64 69 63 65 73 20 69 6e 74 6f 20 61 43 6f 6e  ndices into aCon
e740: 74 65 6e 74 5b 5d 2e 20 20 54 68 65 20 76 61 6c  tent[].  The val
e750: 75 65 73 20 69 6e 0a 2a 2a 20 61 4c 69 73 74 5b  ues in.** aList[
e760: 5d 20 61 72 65 20 74 6f 20 62 65 20 73 6f 72 74  ] are to be sort
e770: 65 64 20 73 6f 20 74 68 61 74 20 66 6f 72 20 61  ed so that for a
e780: 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a 2a 2a 20 20 20  ll J<K:.**.**   
e790: 20 20 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73     aContent[aLis
e7a0: 74 5b 4a 5d 5d 20 3c 20 61 43 6f 6e 74 65 6e 74  t[J]] < aContent
e7b0: 5b 61 4c 69 73 74 5b 4b 5d 5d 0a 2a 2a 0a 2a 2a  [aList[K]].**.**
e7c0: 20 46 6f 72 20 61 6e 79 20 58 20 61 6e 64 20 59   For any X and Y
e7d0: 20 73 75 63 68 20 74 68 61 74 0a 2a 2a 0a 2a 2a   such that.**.**
e7e0: 20 20 20 20 20 20 61 43 6f 6e 74 65 6e 74 5b 61        aContent[a
e7f0: 4c 69 73 74 5b 58 5d 5d 20 3d 3d 20 61 43 6f 6e  List[X]] == aCon
e800: 74 65 6e 74 5b 61 4c 69 73 74 5b 59 5d 5d 0a 2a  tent[aList[Y]].*
e810: 2a 0a 2a 2a 20 4b 65 65 70 20 74 68 65 20 6c 61  *.** Keep the la
e820: 72 67 65 72 20 6f 66 20 74 68 65 20 74 77 6f 20  rger of the two 
e830: 76 61 6c 75 65 73 20 61 4c 69 73 74 5b 58 5d 20  values aList[X] 
e840: 61 6e 64 20 61 4c 69 73 74 5b 59 5d 20 61 6e 64  and aList[Y] and
e850: 20 64 69 73 63 61 72 64 0a 2a 2a 20 74 68 65 20   discard.** the 
e860: 73 6d 61 6c 6c 65 72 2e 0a 2a 2f 0a 73 74 61 74  smaller..*/.stat
e870: 69 63 20 76 6f 69 64 20 77 61 6c 4d 65 72 67 65  ic void walMerge
e880: 73 6f 72 74 28 0a 20 20 63 6f 6e 73 74 20 75 33  sort(.  const u3
e890: 32 20 2a 61 43 6f 6e 74 65 6e 74 2c 20 20 20 20  2 *aContent,    
e8a0: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 73          /* Pages
e8b0: 20 69 6e 20 77 61 6c 20 2a 2f 0a 20 20 68 74 5f   in wal */.  ht_
e8c0: 73 6c 6f 74 20 2a 61 42 75 66 66 65 72 2c 20 20  slot *aBuffer,  
e8d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e8e0: 42 75 66 66 65 72 20 6f 66 20 61 74 20 6c 65 61  Buffer of at lea
e8f0: 73 74 20 2a 70 6e 4c 69 73 74 20 69 74 65 6d 73  st *pnList items
e900: 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20 68 74 5f   to use */.  ht_
e910: 73 6c 6f 74 20 2a 61 4c 69 73 74 2c 20 20 20 20  slot *aList,    
e920: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e930: 49 4e 2f 4f 55 54 3a 20 4c 69 73 74 20 74 6f 20  IN/OUT: List to 
e940: 73 6f 72 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  sort */.  int *p
e950: 6e 4c 69 73 74 20 20 20 20 20 20 20 20 20 20 20  nList           
e960: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f            /* IN/
e970: 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66 20 65  OUT: Number of e
e980: 6c 65 6d 65 6e 74 73 20 69 6e 20 61 4c 69 73 74  lements in aList
e990: 5b 5d 20 2a 2f 0a 29 7b 0a 20 20 73 74 72 75 63  [] */.){.  struc
e9a0: 74 20 53 75 62 6c 69 73 74 20 7b 0a 20 20 20 20  t Sublist {.    
e9b0: 69 6e 74 20 6e 4c 69 73 74 3b 20 20 20 20 20 20  int nList;      
e9c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
e9d0: 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65   Number of eleme
e9e0: 6e 74 73 20 69 6e 20 61 4c 69 73 74 20 2a 2f 0a  nts in aList */.
e9f0: 20 20 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 69      ht_slot *aLi
ea00: 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  st;             
ea10: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
ea20: 73 75 62 2d 6c 69 73 74 20 63 6f 6e 74 65 6e 74  sub-list content
ea30: 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20 63 6f 6e 73   */.  };..  cons
ea40: 74 20 69 6e 74 20 6e 4c 69 73 74 20 3d 20 2a 70  t int nList = *p
ea50: 6e 4c 69 73 74 3b 20 20 20 20 20 20 2f 2a 20 53  nList;      /* S
ea60: 69 7a 65 20 6f 66 20 69 6e 70 75 74 20 6c 69 73  ize of input lis
ea70: 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 65 72 67  t */.  int nMerg
ea80: 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  e = 0;          
ea90: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
eaa0: 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20   of elements in 
eab0: 6c 69 73 74 20 61 4d 65 72 67 65 20 2a 2f 0a 20  list aMerge */. 
eac0: 20 68 74 5f 73 6c 6f 74 20 2a 61 4d 65 72 67 65   ht_slot *aMerge
ead0: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
eae0: 20 2f 2a 20 4c 69 73 74 20 74 6f 20 62 65 20 6d   /* List to be m
eaf0: 65 72 67 65 64 20 2a 2f 0a 20 20 69 6e 74 20 69  erged */.  int i
eb00: 4c 69 73 74 3b 20 20 20 20 20 20 20 20 20 20 20  List;           
eb10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
eb20: 64 65 78 20 69 6e 74 6f 20 69 6e 70 75 74 20 6c  dex into input l
eb30: 69 73 74 20 2a 2f 0a 20 20 75 33 32 20 69 53 75  ist */.  u32 iSu
eb40: 62 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  b = 0;          
eb50: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65           /* Inde
eb60: 78 20 69 6e 74 6f 20 61 53 75 62 20 61 72 72 61  x into aSub arra
eb70: 79 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 53 75  y */.  struct Su
eb80: 62 6c 69 73 74 20 61 53 75 62 5b 31 33 5d 3b 20  blist aSub[13]; 
eb90: 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20         /* Array 
eba0: 6f 66 20 73 75 62 2d 6c 69 73 74 73 20 2a 2f 0a  of sub-lists */.
ebb0: 0a 20 20 6d 65 6d 73 65 74 28 61 53 75 62 2c 20  .  memset(aSub, 
ebc0: 30 2c 20 73 69 7a 65 6f 66 28 61 53 75 62 29 29  0, sizeof(aSub))
ebd0: 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 4c 69 73  ;.  assert( nLis
ebe0: 74 3c 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  t<=HASHTABLE_NPA
ebf0: 47 45 20 26 26 20 6e 4c 69 73 74 3e 30 20 29 3b  GE && nList>0 );
ec00: 0a 20 20 61 73 73 65 72 74 28 20 48 41 53 48 54  .  assert( HASHT
ec10: 41 42 4c 45 5f 4e 50 41 47 45 3d 3d 28 31 3c 3c  ABLE_NPAGE==(1<<
ec20: 28 41 72 72 61 79 53 69 7a 65 28 61 53 75 62 29  (ArraySize(aSub)
ec30: 2d 31 29 29 20 29 3b 0a 0a 20 20 66 6f 72 28 69  -1)) );..  for(i
ec40: 4c 69 73 74 3d 30 3b 20 69 4c 69 73 74 3c 6e 4c  List=0; iList<nL
ec50: 69 73 74 3b 20 69 4c 69 73 74 2b 2b 29 7b 0a 20  ist; iList++){. 
ec60: 20 20 20 6e 4d 65 72 67 65 20 3d 20 31 3b 0a 20     nMerge = 1;. 
ec70: 20 20 20 61 4d 65 72 67 65 20 3d 20 26 61 4c 69     aMerge = &aLi
ec80: 73 74 5b 69 4c 69 73 74 5d 3b 0a 20 20 20 20 66  st[iList];.    f
ec90: 6f 72 28 69 53 75 62 3d 30 3b 20 69 4c 69 73 74  or(iSub=0; iList
eca0: 20 26 20 28 31 3c 3c 69 53 75 62 29 3b 20 69 53   & (1<<iSub); iS
ecb0: 75 62 2b 2b 29 7b 0a 20 20 20 20 20 20 73 74 72  ub++){.      str
ecc0: 75 63 74 20 53 75 62 6c 69 73 74 20 2a 70 3b 0a  uct Sublist *p;.
ecd0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 53        assert( iS
ece0: 75 62 3c 41 72 72 61 79 53 69 7a 65 28 61 53 75  ub<ArraySize(aSu
ecf0: 62 29 20 29 3b 0a 20 20 20 20 20 20 70 20 3d 20  b) );.      p = 
ed00: 26 61 53 75 62 5b 69 53 75 62 5d 3b 0a 20 20 20  &aSub[iSub];.   
ed10: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 4c     assert( p->aL
ed20: 69 73 74 20 26 26 20 70 2d 3e 6e 4c 69 73 74 3c  ist && p->nList<
ed30: 3d 28 31 3c 3c 69 53 75 62 29 20 29 3b 0a 20 20  =(1<<iSub) );.  
ed40: 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61      assert( p->a
ed50: 4c 69 73 74 3d 3d 26 61 4c 69 73 74 5b 69 4c 69  List==&aList[iLi
ed60: 73 74 26 7e 28 28 32 3c 3c 69 53 75 62 29 2d 31  st&~((2<<iSub)-1
ed70: 29 5d 20 29 3b 0a 20 20 20 20 20 20 77 61 6c 4d  )] );.      walM
ed80: 65 72 67 65 28 61 43 6f 6e 74 65 6e 74 2c 20 70  erge(aContent, p
ed90: 2d 3e 61 4c 69 73 74 2c 20 70 2d 3e 6e 4c 69 73  ->aList, p->nLis
eda0: 74 2c 20 26 61 4d 65 72 67 65 2c 20 26 6e 4d 65  t, &aMerge, &nMe
edb0: 72 67 65 2c 20 61 42 75 66 66 65 72 29 3b 0a 20  rge, aBuffer);. 
edc0: 20 20 20 7d 0a 20 20 20 20 61 53 75 62 5b 69 53     }.    aSub[iS
edd0: 75 62 5d 2e 61 4c 69 73 74 20 3d 20 61 4d 65 72  ub].aList = aMer
ede0: 67 65 3b 0a 20 20 20 20 61 53 75 62 5b 69 53 75  ge;.    aSub[iSu
edf0: 62 5d 2e 6e 4c 69 73 74 20 3d 20 6e 4d 65 72 67  b].nList = nMerg
ee00: 65 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69 53  e;.  }..  for(iS
ee10: 75 62 2b 2b 3b 20 69 53 75 62 3c 41 72 72 61 79  ub++; iSub<Array
ee20: 53 69 7a 65 28 61 53 75 62 29 3b 20 69 53 75 62  Size(aSub); iSub
ee30: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 6e 4c 69  ++){.    if( nLi
ee40: 73 74 20 26 20 28 31 3c 3c 69 53 75 62 29 20 29  st & (1<<iSub) )
ee50: 7b 0a 20 20 20 20 20 20 73 74 72 75 63 74 20 53  {.      struct S
ee60: 75 62 6c 69 73 74 20 2a 70 3b 0a 20 20 20 20 20  ublist *p;.     
ee70: 20 61 73 73 65 72 74 28 20 69 53 75 62 3c 41 72   assert( iSub<Ar
ee80: 72 61 79 53 69 7a 65 28 61 53 75 62 29 20 29 3b  raySize(aSub) );
ee90: 0a 20 20 20 20 20 20 70 20 3d 20 26 61 53 75 62  .      p = &aSub
eea0: 5b 69 53 75 62 5d 3b 0a 20 20 20 20 20 20 61 73  [iSub];.      as
eeb0: 73 65 72 74 28 20 70 2d 3e 6e 4c 69 73 74 3c 3d  sert( p->nList<=
eec0: 28 31 3c 3c 69 53 75 62 29 20 29 3b 0a 20 20 20  (1<<iSub) );.   
eed0: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 4c     assert( p->aL
eee0: 69 73 74 3d 3d 26 61 4c 69 73 74 5b 6e 4c 69 73  ist==&aList[nLis
eef0: 74 26 7e 28 28 32 3c 3c 69 53 75 62 29 2d 31 29  t&~((2<<iSub)-1)
ef00: 5d 20 29 3b 0a 20 20 20 20 20 20 77 61 6c 4d 65  ] );.      walMe
ef10: 72 67 65 28 61 43 6f 6e 74 65 6e 74 2c 20 70 2d  rge(aContent, p-
ef20: 3e 61 4c 69 73 74 2c 20 70 2d 3e 6e 4c 69 73 74  >aList, p->nList
ef30: 2c 20 26 61 4d 65 72 67 65 2c 20 26 6e 4d 65 72  , &aMerge, &nMer
ef40: 67 65 2c 20 61 42 75 66 66 65 72 29 3b 0a 20 20  ge, aBuffer);.  
ef50: 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65 72 74    }.  }.  assert
ef60: 28 20 61 4d 65 72 67 65 3d 3d 61 4c 69 73 74 20  ( aMerge==aList 
ef70: 29 3b 0a 20 20 2a 70 6e 4c 69 73 74 20 3d 20 6e  );.  *pnList = n
ef80: 4d 65 72 67 65 3b 0a 0a 23 69 66 64 65 66 20 53  Merge;..#ifdef S
ef90: 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 7b 0a  QLITE_DEBUG.  {.
efa0: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 66      int i;.    f
efb0: 6f 72 28 69 3d 31 3b 20 69 3c 2a 70 6e 4c 69 73  or(i=1; i<*pnLis
efc0: 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 61  t; i++){.      a
efd0: 73 73 65 72 74 28 20 61 43 6f 6e 74 65 6e 74 5b  ssert( aContent[
efe0: 61 4c 69 73 74 5b 69 5d 5d 20 3e 20 61 43 6f 6e  aList[i]] > aCon
eff0: 74 65 6e 74 5b 61 4c 69 73 74 5b 69 2d 31 5d 5d  tent[aList[i-1]]
f000: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 23 65   );.    }.  }.#e
f010: 6e 64 69 66 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 46  ndif.}../* .** F
f020: 72 65 65 20 61 6e 20 69 74 65 72 61 74 6f 72 20  ree an iterator 
f030: 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 77 61 6c  allocated by wal
f040: 49 74 65 72 61 74 6f 72 49 6e 69 74 28 29 2e 0a  IteratorInit()..
f050: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
f060: 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28 57  alIteratorFree(W
f070: 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 29 7b 0a  alIterator *p){.
f080: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
f090: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73  );.}../*.** Cons
f0a0: 74 72 75 63 74 20 61 20 57 61 6c 49 6e 74 65 72  truct a WalInter
f0b0: 61 74 6f 72 20 6f 62 6a 65 63 74 20 74 68 61 74  ator object that
f0c0: 20 63 61 6e 20 62 65 20 75 73 65 64 20 74 6f 20   can be used to 
f0d0: 6c 6f 6f 70 20 6f 76 65 72 20 61 6c 6c 20 0a 2a  loop over all .*
f0e0: 2a 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 57  * pages in the W
f0f0: 41 4c 20 69 6e 20 61 73 63 65 6e 64 69 6e 67 20  AL in ascending 
f100: 6f 72 64 65 72 2e 20 54 68 65 20 63 61 6c 6c 65  order. The calle
f110: 72 20 6d 75 73 74 20 68 6f 6c 64 20 74 68 65 20  r must hold the 
f120: 63 68 65 63 6b 70 6f 69 6e 74 0a 2a 2a 20 6c 6f  checkpoint.** lo
f130: 63 6b 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75 63  ck..**.** On suc
f140: 63 65 73 73 2c 20 6d 61 6b 65 20 2a 70 70 20 70  cess, make *pp p
f150: 6f 69 6e 74 20 74 6f 20 74 68 65 20 6e 65 77 6c  oint to the newl
f160: 79 20 61 6c 6c 6f 63 61 74 65 64 20 57 61 6c 49  y allocated WalI
f170: 6e 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 0a  nterator object.
f180: 2a 2a 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  ** return SQLITE
f190: 5f 4f 4b 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  _OK. Otherwise, 
f1a0: 72 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72 20  return an error 
f1b0: 63 6f 64 65 2e 20 49 66 20 74 68 69 73 20 72 6f  code. If this ro
f1c0: 75 74 69 6e 65 0a 2a 2a 20 72 65 74 75 72 6e 73  utine.** returns
f1d0: 20 61 6e 20 65 72 72 6f 72 2c 20 74 68 65 20 76   an error, the v
f1e0: 61 6c 75 65 20 6f 66 20 2a 70 70 20 69 73 20 75  alue of *pp is u
f1f0: 6e 64 65 66 69 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20  ndefined..**.** 
f200: 54 68 65 20 63 61 6c 6c 69 6e 67 20 72 6f 75 74  The calling rout
f210: 69 6e 65 20 73 68 6f 75 6c 64 20 69 6e 76 6f 6b  ine should invok
f220: 65 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72 65  e walIteratorFre
f230: 65 28 29 20 74 6f 20 64 65 73 74 72 6f 79 20 74  e() to destroy t
f240: 68 65 0a 2a 2a 20 57 61 6c 49 74 65 72 61 74 6f  he.** WalIterato
f250: 72 20 6f 62 6a 65 63 74 20 77 68 65 6e 20 69 74  r object when it
f260: 20 68 61 73 20 66 69 6e 69 73 68 65 64 20 77 69   has finished wi
f270: 74 68 20 69 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  th it..*/.static
f280: 20 69 6e 74 20 77 61 6c 49 74 65 72 61 74 6f 72   int walIterator
f290: 49 6e 69 74 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Init(Wal *pWal, 
f2a0: 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 2a 70 70  WalIterator **pp
f2b0: 29 7b 0a 20 20 57 61 6c 49 74 65 72 61 74 6f 72  ){.  WalIterator
f2c0: 20 2a 70 3b 20 20 20 20 20 20 20 20 20 20 20 20   *p;            
f2d0: 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 76       /* Return v
f2e0: 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 53  alue */.  int nS
f2f0: 65 67 6d 65 6e 74 3b 20 20 20 20 20 20 20 20 20  egment;         
f300: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
f310: 62 65 72 20 6f 66 20 73 65 67 6d 65 6e 74 73 20  ber of segments 
f320: 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20 75 33  to merge */.  u3
f330: 32 20 69 4c 61 73 74 3b 20 20 20 20 20 20 20 20  2 iLast;        
f340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
f350: 20 4c 61 73 74 20 66 72 61 6d 65 20 69 6e 20 6c   Last frame in l
f360: 6f 67 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74  og */.  int nByt
f370: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
f380: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
f390: 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20 61 6c  r of bytes to al
f3a0: 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 69 6e 74 20  locate */.  int 
f3b0: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
f3c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
f3d0: 74 65 72 61 74 6f 72 20 76 61 72 69 61 62 6c 65  terator variable
f3e0: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61   */.  ht_slot *a
f3f0: 54 6d 70 3b 20 20 20 20 20 20 20 20 20 20 20 20  Tmp;            
f400: 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 20 73 70        /* Temp sp
f410: 61 63 65 20 75 73 65 64 20 62 79 20 6d 65 72 67  ace used by merg
f420: 65 2d 73 6f 72 74 20 2a 2f 0a 20 20 69 6e 74 20  e-sort */.  int 
f430: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
f440: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
f450: 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 0a 20  eturn Code */.. 
f460: 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65   /* This routine
f470: 20 6f 6e 6c 79 20 72 75 6e 73 20 77 68 69 6c 65   only runs while
f480: 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 63 68 65   holding the che
f490: 63 6b 70 6f 69 6e 74 20 6c 6f 63 6b 2e 20 41 6e  ckpoint lock. An
f4a0: 64 0a 20 20 2a 2a 20 69 74 20 6f 6e 6c 79 20 72  d.  ** it only r
f4b0: 75 6e 73 20 69 66 20 74 68 65 72 65 20 69 73 20  uns if there is 
f4c0: 61 63 74 75 61 6c 6c 79 20 63 6f 6e 74 65 6e 74  actually content
f4d0: 20 69 6e 20 74 68 65 20 6c 6f 67 20 28 6d 78 46   in the log (mxF
f4e0: 72 61 6d 65 3e 30 29 2e 0a 20 20 2a 2f 0a 20 20  rame>0)..  */.  
f4f0: 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 63 6b  assert( pWal->ck
f500: 70 74 4c 6f 63 6b 20 26 26 20 70 57 61 6c 2d 3e  ptLock && pWal->
f510: 68 64 72 2e 6d 78 46 72 61 6d 65 3e 30 20 29 3b  hdr.mxFrame>0 );
f520: 0a 20 20 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d  .  iLast = pWal-
f530: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 0a 20  >hdr.mxFrame;.. 
f540: 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70 61   /* Allocate spa
f550: 63 65 20 66 6f 72 20 74 68 65 20 57 61 6c 49 74  ce for the WalIt
f560: 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 2e 20 2a  erator object. *
f570: 2f 0a 20 20 6e 53 65 67 6d 65 6e 74 20 3d 20 77  /.  nSegment = w
f580: 61 6c 46 72 61 6d 65 50 61 67 65 28 69 4c 61 73  alFramePage(iLas
f590: 74 29 20 2b 20 31 3b 0a 20 20 6e 42 79 74 65 20  t) + 1;.  nByte 
f5a0: 3d 20 73 69 7a 65 6f 66 28 57 61 6c 49 74 65 72  = sizeof(WalIter
f5b0: 61 74 6f 72 29 20 0a 20 20 20 20 20 20 20 20 2b  ator) .        +
f5c0: 20 28 6e 53 65 67 6d 65 6e 74 2d 31 29 2a 73 69   (nSegment-1)*si
f5d0: 7a 65 6f 66 28 73 74 72 75 63 74 20 57 61 6c 53  zeof(struct WalS
f5e0: 65 67 6d 65 6e 74 29 0a 20 20 20 20 20 20 20 20  egment).        
f5f0: 2b 20 69 4c 61 73 74 2a 73 69 7a 65 6f 66 28 68  + iLast*sizeof(h
f600: 74 5f 73 6c 6f 74 29 3b 0a 20 20 70 20 3d 20 28  t_slot);.  p = (
f610: 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 29 73 71  WalIterator *)sq
f620: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34 28 6e  lite3_malloc64(n
f630: 42 79 74 65 29 3b 0a 20 20 69 66 28 20 21 70 20  Byte);.  if( !p 
f640: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
f650: 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b  LITE_NOMEM_BKPT;
f660: 0a 20 20 7d 0a 20 20 6d 65 6d 73 65 74 28 70 2c  .  }.  memset(p,
f670: 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 70 2d   0, nByte);.  p-
f680: 3e 6e 53 65 67 6d 65 6e 74 20 3d 20 6e 53 65 67  >nSegment = nSeg
f690: 6d 65 6e 74 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f  ment;..  /* Allo
f6a0: 63 61 74 65 20 74 65 6d 70 6f 72 61 72 79 20 73  cate temporary s
f6b0: 70 61 63 65 20 75 73 65 64 20 62 79 20 74 68 65  pace used by the
f6c0: 20 6d 65 72 67 65 2d 73 6f 72 74 20 72 6f 75 74   merge-sort rout
f6d0: 69 6e 65 2e 20 54 68 69 73 20 62 6c 6f 63 6b 0a  ine. This block.
f6e0: 20 20 2a 2a 20 6f 66 20 6d 65 6d 6f 72 79 20 77    ** of memory w
f6f0: 69 6c 6c 20 62 65 20 66 72 65 65 64 20 62 65 66  ill be freed bef
f700: 6f 72 65 20 74 68 69 73 20 66 75 6e 63 74 69 6f  ore this functio
f710: 6e 20 72 65 74 75 72 6e 73 2e 0a 20 20 2a 2f 0a  n returns..  */.
f720: 20 20 61 54 6d 70 20 3d 20 28 68 74 5f 73 6c 6f    aTmp = (ht_slo
f730: 74 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  t *)sqlite3_mall
f740: 6f 63 36 34 28 0a 20 20 20 20 20 20 73 69 7a 65  oc64(.      size
f750: 6f 66 28 68 74 5f 73 6c 6f 74 29 20 2a 20 28 69  of(ht_slot) * (i
f760: 4c 61 73 74 3e 48 41 53 48 54 41 42 4c 45 5f 4e  Last>HASHTABLE_N
f770: 50 41 47 45 3f 48 41 53 48 54 41 42 4c 45 5f 4e  PAGE?HASHTABLE_N
f780: 50 41 47 45 3a 69 4c 61 73 74 29 0a 20 20 29 3b  PAGE:iLast).  );
f790: 0a 20 20 69 66 28 20 21 61 54 6d 70 20 29 7b 0a  .  if( !aTmp ){.
f7a0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
f7b0: 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20 7d 0a  NOMEM_BKPT;.  }.
f7c0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d  .  for(i=0; rc==
f7d0: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e  SQLITE_OK && i<n
f7e0: 53 65 67 6d 65 6e 74 3b 20 69 2b 2b 29 7b 0a 20  Segment; i++){. 
f7f0: 20 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73     volatile ht_s
f800: 6c 6f 74 20 2a 61 48 61 73 68 3b 0a 20 20 20 20  lot *aHash;.    
f810: 75 33 32 20 69 5a 65 72 6f 3b 0a 20 20 20 20 76  u32 iZero;.    v
f820: 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67  olatile u32 *aPg
f830: 6e 6f 3b 0a 0a 20 20 20 20 72 63 20 3d 20 77 61  no;..    rc = wa
f840: 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c 20 69  lHashGet(pWal, i
f850: 2c 20 26 61 48 61 73 68 2c 20 26 61 50 67 6e 6f  , &aHash, &aPgno
f860: 2c 20 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20 69  , &iZero);.    i
f870: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
f880: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6a 3b   ){.      int j;
f890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f8a0: 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65 72        /* Counter
f8b0: 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 20   variable */.   
f8c0: 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 3b 20 20     int nEntry;  
f8d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
f8e0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72  * Number of entr
f8f0: 69 65 73 20 69 6e 20 74 68 69 73 20 73 65 67 6d  ies in this segm
f900: 65 6e 74 20 2a 2f 0a 20 20 20 20 20 20 68 74 5f  ent */.      ht_
f910: 73 6c 6f 74 20 2a 61 49 6e 64 65 78 3b 20 20 20  slot *aIndex;   
f920: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74           /* Sort
f930: 65 64 20 69 6e 64 65 78 20 66 6f 72 20 74 68 69  ed index for thi
f940: 73 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 0a 20 20  s segment */..  
f950: 20 20 20 20 61 50 67 6e 6f 2b 2b 3b 0a 20 20 20      aPgno++;.   
f960: 20 20 20 69 66 28 20 28 69 2b 31 29 3d 3d 6e 53     if( (i+1)==nS
f970: 65 67 6d 65 6e 74 20 29 7b 0a 20 20 20 20 20 20  egment ){.      
f980: 20 20 6e 45 6e 74 72 79 20 3d 20 28 69 6e 74 29    nEntry = (int)
f990: 28 69 4c 61 73 74 20 2d 20 69 5a 65 72 6f 29 3b  (iLast - iZero);
f9a0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
f9b0: 20 20 20 20 20 20 6e 45 6e 74 72 79 20 3d 20 28        nEntry = (
f9c0: 69 6e 74 29 28 28 75 33 32 2a 29 61 48 61 73 68  int)((u32*)aHash
f9d0: 20 2d 20 28 75 33 32 2a 29 61 50 67 6e 6f 29 3b   - (u32*)aPgno);
f9e0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61  .      }.      a
f9f0: 49 6e 64 65 78 20 3d 20 26 28 28 68 74 5f 73 6c  Index = &((ht_sl
fa00: 6f 74 20 2a 29 26 70 2d 3e 61 53 65 67 6d 65 6e  ot *)&p->aSegmen
fa10: 74 5b 70 2d 3e 6e 53 65 67 6d 65 6e 74 5d 29 5b  t[p->nSegment])[
fa20: 69 5a 65 72 6f 5d 3b 0a 20 20 20 20 20 20 69 5a  iZero];.      iZ
fa30: 65 72 6f 2b 2b 3b 0a 20 20 0a 20 20 20 20 20 20  ero++;.  .      
fa40: 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 45 6e 74 72  for(j=0; j<nEntr
fa50: 79 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20  y; j++){.       
fa60: 20 61 49 6e 64 65 78 5b 6a 5d 20 3d 20 28 68 74   aIndex[j] = (ht
fa70: 5f 73 6c 6f 74 29 6a 3b 0a 20 20 20 20 20 20 7d  _slot)j;.      }
fa80: 0a 20 20 20 20 20 20 77 61 6c 4d 65 72 67 65 73  .      walMerges
fa90: 6f 72 74 28 28 75 33 32 20 2a 29 61 50 67 6e 6f  ort((u32 *)aPgno
faa0: 2c 20 61 54 6d 70 2c 20 61 49 6e 64 65 78 2c 20  , aTmp, aIndex, 
fab0: 26 6e 45 6e 74 72 79 29 3b 0a 20 20 20 20 20 20  &nEntry);.      
fac0: 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 69  p->aSegment[i].i
fad0: 5a 65 72 6f 20 3d 20 69 5a 65 72 6f 3b 0a 20 20  Zero = iZero;.  
fae0: 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b      p->aSegment[
faf0: 69 5d 2e 6e 45 6e 74 72 79 20 3d 20 6e 45 6e 74  i].nEntry = nEnt
fb00: 72 79 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65  ry;.      p->aSe
fb10: 67 6d 65 6e 74 5b 69 5d 2e 61 49 6e 64 65 78 20  gment[i].aIndex 
fb20: 3d 20 61 49 6e 64 65 78 3b 0a 20 20 20 20 20 20  = aIndex;.      
fb30: 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 61  p->aSegment[i].a
fb40: 50 67 6e 6f 20 3d 20 28 75 33 32 20 2a 29 61 50  Pgno = (u32 *)aP
fb50: 67 6e 6f 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  gno;.    }.  }. 
fb60: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 54   sqlite3_free(aT
fb70: 6d 70 29 3b 0a 0a 20 20 69 66 28 20 72 63 21 3d  mp);..  if( rc!=
fb80: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
fb90: 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65   walIteratorFree
fba0: 28 70 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 20 3d  (p);.  }.  *pp =
fbb0: 20 70 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   p;.  return rc;
fbc0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70  .}../*.** Attemp
fbd0: 74 20 74 6f 20 6f 62 74 61 69 6e 20 74 68 65 20  t to obtain the 
fbe0: 65 78 63 6c 75 73 69 76 65 20 57 41 4c 20 6c 6f  exclusive WAL lo
fbf0: 63 6b 20 64 65 66 69 6e 65 64 20 62 79 20 70 61  ck defined by pa
fc00: 72 61 6d 65 74 65 72 73 20 6c 6f 63 6b 49 64 78  rameters lockIdx
fc10: 20 61 6e 64 0a 2a 2a 20 6e 2e 20 49 66 20 74 68   and.** n. If th
fc20: 65 20 61 74 74 65 6d 70 74 20 66 61 69 6c 73 20  e attempt fails 
fc30: 61 6e 64 20 70 61 72 61 6d 65 74 65 72 20 78 42  and parameter xB
fc40: 75 73 79 20 69 73 20 6e 6f 74 20 4e 55 4c 4c 2c  usy is not NULL,
fc50: 20 74 68 65 6e 20 69 74 20 69 73 20 61 0a 2a 2a   then it is a.**
fc60: 20 62 75 73 79 2d 68 61 6e 64 6c 65 72 20 66 75   busy-handler fu
fc70: 6e 63 74 69 6f 6e 2e 20 49 6e 76 6f 6b 65 20 69  nction. Invoke i
fc80: 74 20 61 6e 64 20 72 65 74 72 79 20 74 68 65 20  t and retry the 
fc90: 6c 6f 63 6b 20 75 6e 74 69 6c 20 65 69 74 68 65  lock until eithe
fca0: 72 20 74 68 65 0a 2a 2a 20 6c 6f 63 6b 20 69 73  r the.** lock is
fcb0: 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20 6f 62   successfully ob
fcc0: 74 61 69 6e 65 64 20 6f 72 20 74 68 65 20 62 75  tained or the bu
fcd0: 73 79 2d 68 61 6e 64 6c 65 72 20 72 65 74 75 72  sy-handler retur
fce0: 6e 73 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ns 0..*/.static 
fcf0: 69 6e 74 20 77 61 6c 42 75 73 79 4c 6f 63 6b 28  int walBusyLock(
fd00: 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20  .  Wal *pWal,   
fd10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fd20: 20 20 20 2f 2a 20 57 41 4c 20 63 6f 6e 6e 65 63     /* WAL connec
fd30: 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 28 2a  tion */.  int (*
fd40: 78 42 75 73 79 29 28 76 6f 69 64 2a 29 2c 20 20  xBusy)(void*),  
fd50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e            /* Fun
fd60: 63 74 69 6f 6e 20 74 6f 20 63 61 6c 6c 20 77 68  ction to call wh
fd70: 65 6e 20 62 75 73 79 20 2a 2f 0a 20 20 76 6f 69  en busy */.  voi
fd80: 64 20 2a 70 42 75 73 79 41 72 67 2c 20 20 20 20  d *pBusyArg,    
fd90: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
fda0: 43 6f 6e 74 65 78 74 20 61 72 67 75 6d 65 6e 74  Context argument
fdb0: 20 66 6f 72 20 78 42 75 73 79 48 61 6e 64 6c 65   for xBusyHandle
fdc0: 72 20 2a 2f 0a 20 20 69 6e 74 20 6c 6f 63 6b 49  r */.  int lockI
fdd0: 64 78 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  dx,             
fde0: 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74         /* Offset
fdf0: 20 6f 66 20 66 69 72 73 74 20 62 79 74 65 20 74   of first byte t
fe00: 6f 20 6c 6f 63 6b 20 2a 2f 0a 20 20 69 6e 74 20  o lock */.  int 
fe10: 6e 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n               
fe20: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
fe30: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 74  umber of bytes t
fe40: 6f 20 6c 6f 63 6b 20 2a 2f 0a 29 7b 0a 20 20 69  o lock */.){.  i
fe50: 6e 74 20 72 63 3b 0a 20 20 64 6f 20 7b 0a 20 20  nt rc;.  do {.  
fe60: 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78    rc = walLockEx
fe70: 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 6c 6f  clusive(pWal, lo
fe80: 63 6b 49 64 78 2c 20 6e 29 3b 0a 20 20 7d 77 68  ckIdx, n);.  }wh
fe90: 69 6c 65 28 20 78 42 75 73 79 20 26 26 20 72 63  ile( xBusy && rc
fea0: 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 26 26  ==SQLITE_BUSY &&
feb0: 20 78 42 75 73 79 28 70 42 75 73 79 41 72 67 29   xBusy(pBusyArg)
fec0: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   );.  return rc;
fed0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 63 61  .}../*.** The ca
fee0: 63 68 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69  che of the wal-i
fef0: 6e 64 65 78 20 68 65 61 64 65 72 20 6d 75 73 74  ndex header must
ff00: 20 62 65 20 76 61 6c 69 64 20 74 6f 20 63 61 6c   be valid to cal
ff10: 6c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e  l this function.
ff20: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 70  .** Return the p
ff30: 61 67 65 2d 73 69 7a 65 20 69 6e 20 62 79 74 65  age-size in byte
ff40: 73 20 75 73 65 64 20 62 79 20 74 68 65 20 64 61  s used by the da
ff50: 74 61 62 61 73 65 2e 0a 2a 2f 0a 73 74 61 74 69  tabase..*/.stati
ff60: 63 20 69 6e 74 20 77 61 6c 50 61 67 65 73 69 7a  c int walPagesiz
ff70: 65 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20  e(Wal *pWal){.  
ff80: 72 65 74 75 72 6e 20 28 70 57 61 6c 2d 3e 68 64  return (pWal->hd
ff90: 72 2e 73 7a 50 61 67 65 26 30 78 66 65 30 30 29  r.szPage&0xfe00)
ffa0: 20 2b 20 28 28 70 57 61 6c 2d 3e 68 64 72 2e 73   + ((pWal->hdr.s
ffb0: 7a 50 61 67 65 26 30 78 30 30 30 31 29 3c 3c 31  zPage&0x0001)<<1
ffc0: 36 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  6);.}../*.** The
ffd0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 67 75   following is gu
ffe0: 61 72 61 6e 74 65 65 64 20 77 68 65 6e 20 74 68  aranteed when th
fff0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
10000 61 6c 6c 65 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 61  alled:.**.**   a
10010 29 20 74 68 65 20 57 52 49 54 45 52 20 6c 6f 63  ) the WRITER loc
10020 6b 20 69 73 20 68 65 6c 64 2c 0a 2a 2a 20 20 20  k is held,.**   
10030 62 29 20 74 68 65 20 65 6e 74 69 72 65 20 6c 6f  b) the entire lo
10040 67 20 66 69 6c 65 20 68 61 73 20 62 65 65 6e 20  g file has been 
10050 63 68 65 63 6b 70 6f 69 6e 74 65 64 2c 20 61 6e  checkpointed, an
10060 64 0a 2a 2a 20 20 20 63 29 20 61 6e 79 20 65 78  d.**   c) any ex
10070 69 73 74 69 6e 67 20 72 65 61 64 65 72 73 20 61  isting readers a
10080 72 65 20 72 65 61 64 69 6e 67 20 65 78 63 6c 75  re reading exclu
10090 73 69 76 65 6c 79 20 66 72 6f 6d 20 74 68 65 20  sively from the 
100a0 64 61 74 61 62 61 73 65 0a 2a 2a 20 20 20 20 20  database.**     
100b0 20 66 69 6c 65 20 2d 20 74 68 65 72 65 20 61 72   file - there ar
100c0 65 20 6e 6f 20 72 65 61 64 65 72 73 20 74 68 61  e no readers tha
100d0 74 20 6d 61 79 20 61 74 74 65 6d 70 74 20 74 6f  t may attempt to
100e0 20 72 65 61 64 20 61 20 66 72 61 6d 65 20 66 72   read a frame fr
100f0 6f 6d 0a 2a 2a 20 20 20 20 20 20 74 68 65 20 6c  om.**      the l
10100 6f 67 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54  og file..**.** T
10110 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 75 70 64  his function upd
10120 61 74 65 73 20 74 68 65 20 73 68 61 72 65 64 2d  ates the shared-
10130 6d 65 6d 6f 72 79 20 73 74 72 75 63 74 75 72 65  memory structure
10140 73 20 73 6f 20 74 68 61 74 20 74 68 65 20 6e 65  s so that the ne
10150 78 74 0a 2a 2a 20 63 6c 69 65 6e 74 20 74 6f 20  xt.** client to 
10160 77 72 69 74 65 20 74 6f 20 74 68 65 20 64 61 74  write to the dat
10170 61 62 61 73 65 20 28 77 68 69 63 68 20 6d 61 79  abase (which may
10180 20 62 65 20 74 68 69 73 20 6f 6e 65 29 20 64 6f   be this one) do
10190 65 73 20 73 6f 20 62 79 0a 2a 2a 20 77 72 69 74  es so by.** writ
101a0 69 6e 67 20 66 72 61 6d 65 73 20 69 6e 74 6f 20  ing frames into 
101b0 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
101c0 20 6c 6f 67 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a   log file..**.**
101d0 20 54 68 65 20 76 61 6c 75 65 20 6f 66 20 70 61   The value of pa
101e0 72 61 6d 65 74 65 72 20 73 61 6c 74 31 20 69 73  rameter salt1 is
101f0 20 75 73 65 64 20 61 73 20 74 68 65 20 61 53 61   used as the aSa
10200 6c 74 5b 31 5d 20 76 61 6c 75 65 20 69 6e 20 74  lt[1] value in t
10210 68 65 20 0a 2a 2a 20 6e 65 77 20 77 61 6c 2d 69  he .** new wal-i
10220 6e 64 65 78 20 68 65 61 64 65 72 2e 20 49 74 20  ndex header. It 
10230 73 68 6f 75 6c 64 20 62 65 20 70 61 73 73 65 64  should be passed
10240 20 61 20 70 73 65 75 64 6f 2d 72 61 6e 64 6f 6d   a pseudo-random
10250 20 76 61 6c 75 65 20 28 69 2e 65 2e 20 0a 2a 2a   value (i.e. .**
10260 20 6f 6e 65 20 6f 62 74 61 69 6e 65 64 20 66 72   one obtained fr
10270 6f 6d 20 73 71 6c 69 74 65 33 5f 72 61 6e 64 6f  om sqlite3_rando
10280 6d 6e 65 73 73 28 29 29 2e 0a 2a 2f 0a 73 74 61  mness())..*/.sta
10290 74 69 63 20 76 6f 69 64 20 77 61 6c 52 65 73 74  tic void walRest
102a0 61 72 74 48 64 72 28 57 61 6c 20 2a 70 57 61 6c  artHdr(Wal *pWal
102b0 2c 20 75 33 32 20 73 61 6c 74 31 29 7b 0a 20 20  , u32 salt1){.  
102c0 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74  volatile WalCkpt
102d0 49 6e 66 6f 20 2a 70 49 6e 66 6f 20 3d 20 77 61  Info *pInfo = wa
102e0 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b  lCkptInfo(pWal);
102f0 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
10300 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10310 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74     /* Loop count
10320 65 72 20 2a 2f 0a 20 20 75 33 32 20 2a 61 53 61  er */.  u32 *aSa
10330 6c 74 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61  lt = pWal->hdr.a
10340 53 61 6c 74 3b 20 20 20 2f 2a 20 42 69 67 2d 65  Salt;   /* Big-e
10350 6e 64 69 61 6e 20 73 61 6c 74 20 76 61 6c 75 65  ndian salt value
10360 73 20 2a 2f 0a 20 20 70 57 61 6c 2d 3e 6e 43 6b  s */.  pWal->nCk
10370 70 74 2b 2b 3b 0a 20 20 70 57 61 6c 2d 3e 68 64  pt++;.  pWal->hd
10380 72 2e 6d 78 46 72 61 6d 65 20 3d 20 30 3b 0a 20  r.mxFrame = 0;. 
10390 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65   sqlite3Put4byte
103a0 28 28 75 38 2a 29 26 61 53 61 6c 74 5b 30 5d 2c  ((u8*)&aSalt[0],
103b0 20 31 20 2b 20 73 71 6c 69 74 65 33 47 65 74 34   1 + sqlite3Get4
103c0 62 79 74 65 28 28 75 38 2a 29 26 61 53 61 6c 74  byte((u8*)&aSalt
103d0 5b 30 5d 29 29 3b 0a 20 20 6d 65 6d 63 70 79 28  [0]));.  memcpy(
103e0 26 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74  &pWal->hdr.aSalt
103f0 5b 31 5d 2c 20 26 73 61 6c 74 31 2c 20 34 29 3b  [1], &salt1, 4);
10400 0a 20 20 77 61 6c 49 6e 64 65 78 57 72 69 74 65  .  walIndexWrite
10410 48 64 72 28 70 57 61 6c 29 3b 0a 20 20 70 49 6e  Hdr(pWal);.  pIn
10420 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 20 3d 20  fo->nBackfill = 
10430 30 3b 0a 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63  0;.  pInfo->nBac
10440 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 3d  kfillAttempted =
10450 20 30 3b 0a 20 20 70 49 6e 66 6f 2d 3e 61 52 65   0;.  pInfo->aRe
10460 61 64 4d 61 72 6b 5b 31 5d 20 3d 20 30 3b 0a 20  adMark[1] = 0;. 
10470 20 66 6f 72 28 69 3d 32 3b 20 69 3c 57 41 4c 5f   for(i=2; i<WAL_
10480 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29 20 70 49  NREADER; i++) pI
10490 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69  nfo->aReadMark[i
104a0 5d 20 3d 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54  ] = READMARK_NOT
104b0 5f 55 53 45 44 3b 0a 20 20 61 73 73 65 72 74 28  _USED;.  assert(
104c0 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
104d0 6b 5b 30 5d 3d 3d 30 20 29 3b 0a 7d 0a 0a 2f 2a  k[0]==0 );.}../*
104e0 0a 2a 2a 20 43 6f 70 79 20 61 73 20 6d 75 63 68  .** Copy as much
104f0 20 63 6f 6e 74 65 6e 74 20 61 73 20 77 65 20 63   content as we c
10500 61 6e 20 66 72 6f 6d 20 74 68 65 20 57 41 4c 20  an from the WAL 
10510 62 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61  back into the da
10520 74 61 62 61 73 65 20 66 69 6c 65 0a 2a 2a 20 69  tabase file.** i
10530 6e 20 72 65 73 70 6f 6e 73 65 20 74 6f 20 61 6e  n response to an
10540 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68 65   sqlite3_wal_che
10550 63 6b 70 6f 69 6e 74 28 29 20 72 65 71 75 65 73  ckpoint() reques
10560 74 20 6f 72 20 74 68 65 20 65 71 75 69 76 61 6c  t or the equival
10570 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61  ent..**.** The a
10580 6d 6f 75 6e 74 20 6f 66 20 69 6e 66 6f 72 6d 61  mount of informa
10590 74 69 6f 6e 20 63 6f 70 69 65 73 20 66 72 6f 6d  tion copies from
105a0 20 57 41 4c 20 74 6f 20 64 61 74 61 62 61 73 65   WAL to database
105b0 20 6d 69 67 68 74 20 62 65 20 6c 69 6d 69 74 65   might be limite
105c0 64 0a 2a 2a 20 62 79 20 61 63 74 69 76 65 20 72  d.** by active r
105d0 65 61 64 65 72 73 2e 20 20 54 68 69 73 20 72 6f  eaders.  This ro
105e0 75 74 69 6e 65 20 77 69 6c 6c 20 6e 65 76 65 72  utine will never
105f0 20 6f 76 65 72 77 72 69 74 65 20 61 20 64 61 74   overwrite a dat
10600 61 62 61 73 65 20 70 61 67 65 0a 2a 2a 20 74 68  abase page.** th
10610 61 74 20 61 20 63 6f 6e 63 75 72 72 65 6e 74 20  at a concurrent 
10620 72 65 61 64 65 72 20 6d 69 67 68 74 20 62 65 20  reader might be 
10630 75 73 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c  using..**.** All
10640 20 49 2f 4f 20 62 61 72 72 69 65 72 20 6f 70 65   I/O barrier ope
10650 72 61 74 69 6f 6e 73 20 28 61 2e 6b 2e 61 20 66  rations (a.k.a f
10660 73 79 6e 63 73 29 20 6f 63 63 75 72 20 69 6e 20  syncs) occur in 
10670 74 68 69 73 20 72 6f 75 74 69 6e 65 20 77 68 65  this routine whe
10680 6e 0a 2a 2a 20 53 51 4c 69 74 65 20 69 73 20 69  n.** SQLite is i
10690 6e 20 57 41 4c 2d 6d 6f 64 65 20 69 6e 20 73 79  n WAL-mode in sy
106a0 6e 63 68 72 6f 6e 6f 75 73 3d 4e 4f 52 4d 41 4c  nchronous=NORMAL
106b0 2e 20 20 54 68 61 74 20 6d 65 61 6e 73 20 74 68  .  That means th
106c0 61 74 20 69 66 20 0a 2a 2a 20 63 68 65 63 6b 70  at if .** checkp
106d0 6f 69 6e 74 73 20 61 72 65 20 61 6c 77 61 79 73  oints are always
106e0 20 72 75 6e 20 62 79 20 61 20 62 61 63 6b 67 72   run by a backgr
106f0 6f 75 6e 64 20 74 68 72 65 61 64 20 6f 72 20 62  ound thread or b
10700 61 63 6b 67 72 6f 75 6e 64 20 0a 2a 2a 20 70 72  ackground .** pr
10710 6f 63 65 73 73 2c 20 66 6f 72 65 67 72 6f 75 6e  ocess, foregroun
10720 64 20 74 68 72 65 61 64 73 20 77 69 6c 6c 20 6e  d threads will n
10730 65 76 65 72 20 62 6c 6f 63 6b 20 6f 6e 20 61 20  ever block on a 
10740 6c 65 6e 67 74 68 79 20 66 73 79 6e 63 20 63 61  lengthy fsync ca
10750 6c 6c 2e 0a 2a 2a 0a 2a 2a 20 46 73 79 6e 63 20  ll..**.** Fsync 
10760 69 73 20 63 61 6c 6c 65 64 20 6f 6e 20 74 68 65  is called on the
10770 20 57 41 4c 20 62 65 66 6f 72 65 20 77 72 69 74   WAL before writ
10780 69 6e 67 20 63 6f 6e 74 65 6e 74 20 6f 75 74 20  ing content out 
10790 6f 66 20 74 68 65 20 57 41 4c 20 61 6e 64 0a 2a  of the WAL and.*
107a0 2a 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  * into the datab
107b0 61 73 65 2e 20 20 54 68 69 73 20 65 6e 73 75 72  ase.  This ensur
107c0 65 73 20 74 68 61 74 20 69 66 20 74 68 65 20 6e  es that if the n
107d0 65 77 20 63 6f 6e 74 65 6e 74 20 69 73 20 70 65  ew content is pe
107e0 72 73 69 73 74 65 6e 74 0a 2a 2a 20 69 6e 20 74  rsistent.** in t
107f0 68 65 20 57 41 4c 20 61 6e 64 20 63 61 6e 20 62  he WAL and can b
10800 65 20 72 65 63 6f 76 65 72 65 64 20 66 6f 6c 6c  e recovered foll
10810 6f 77 69 6e 67 20 61 20 70 6f 77 65 72 2d 6c 6f  owing a power-lo
10820 73 73 20 6f 72 20 68 61 72 64 20 72 65 73 65 74  ss or hard reset
10830 2e 0a 2a 2a 0a 2a 2a 20 46 73 79 6e 63 20 69 73  ..**.** Fsync is
10840 20 61 6c 73 6f 20 63 61 6c 6c 65 64 20 6f 6e 20   also called on 
10850 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
10860 65 20 69 66 20 28 61 6e 64 20 6f 6e 6c 79 20 69  e if (and only i
10870 66 29 20 74 68 65 20 65 6e 74 69 72 65 0a 2a 2a  f) the entire.**
10880 20 57 41 4c 20 63 6f 6e 74 65 6e 74 20 69 73 20   WAL content is 
10890 63 6f 70 69 65 64 20 69 6e 74 6f 20 74 68 65 20  copied into the 
108a0 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 20 20  database file.  
108b0 54 68 69 73 20 73 65 63 6f 6e 64 20 66 73 79 6e  This second fsyn
108c0 63 20 6d 61 6b 65 73 0a 2a 2a 20 69 74 20 73 61  c makes.** it sa
108d0 66 65 20 74 6f 20 64 65 6c 65 74 65 20 74 68 65  fe to delete the
108e0 20 57 41 4c 20 73 69 6e 63 65 20 74 68 65 20 6e   WAL since the n
108f0 65 77 20 63 6f 6e 74 65 6e 74 20 77 69 6c 6c 20  ew content will 
10900 70 65 72 73 69 73 74 20 69 6e 20 74 68 65 0a 2a  persist in the.*
10910 2a 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e  * database file.
10920 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74  .**.** This rout
10930 69 6e 65 20 75 73 65 73 20 61 6e 64 20 75 70 64  ine uses and upd
10940 61 74 65 73 20 74 68 65 20 6e 42 61 63 6b 66 69  ates the nBackfi
10950 6c 6c 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20  ll field of the 
10960 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
10970 2e 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65  ..** This is the
10980 20 6f 6e 6c 79 20 72 6f 75 74 69 6e 65 20 74 68   only routine th
10990 61 74 20 77 69 6c 6c 20 69 6e 63 72 65 61 73 65  at will increase
109a0 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 6e 42   the value of nB
109b0 61 63 6b 66 69 6c 6c 2e 20 20 0a 2a 2a 20 28 41  ackfill.  .** (A
109c0 20 57 41 4c 20 72 65 73 65 74 20 6f 72 20 72 65   WAL reset or re
109d0 63 6f 76 65 72 79 20 77 69 6c 6c 20 72 65 76 65  covery will reve
109e0 72 74 20 6e 42 61 63 6b 66 69 6c 6c 20 74 6f 20  rt nBackfill to 
109f0 7a 65 72 6f 2c 20 62 75 74 20 6e 6f 74 20 69 6e  zero, but not in
10a00 63 72 65 61 73 65 0a 2a 2a 20 69 74 73 20 76 61  crease.** its va
10a10 6c 75 65 2e 29 0a 2a 2a 0a 2a 2a 20 54 68 65 20  lue.).**.** The 
10a20 63 61 6c 6c 65 72 20 6d 75 73 74 20 62 65 20 68  caller must be h
10a30 6f 6c 64 69 6e 67 20 73 75 66 66 69 63 69 65 6e  olding sufficien
10a40 74 20 6c 6f 63 6b 73 20 74 6f 20 65 6e 73 75 72  t locks to ensur
10a50 65 20 74 68 61 74 20 6e 6f 20 6f 74 68 65 72 0a  e that no other.
10a60 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 20 69 73  ** checkpoint is
10a70 20 72 75 6e 6e 69 6e 67 20 28 69 6e 20 61 6e 79   running (in any
10a80 20 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f 72   other thread or
10a90 20 70 72 6f 63 65 73 73 29 20 61 74 20 74 68 65   process) at the
10aa0 20 73 61 6d 65 0a 2a 2a 20 74 69 6d 65 2e 0a 2a   same.** time..*
10ab0 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
10ac0 43 68 65 63 6b 70 6f 69 6e 74 28 0a 20 20 57 61  Checkpoint(.  Wa
10ad0 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20  l *pWal,        
10ae0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
10af0 20 57 61 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20   Wal connection 
10b00 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  */.  sqlite3 *db
10b10 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
10b20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 20 66 6f       /* Check fo
10b30 72 20 69 6e 74 65 72 72 75 70 74 73 20 6f 6e 20  r interrupts on 
10b40 74 68 69 73 20 68 61 6e 64 6c 65 20 2a 2f 0a 20  this handle */. 
10b50 20 69 6e 74 20 65 4d 6f 64 65 2c 20 20 20 20 20   int eMode,     
10b60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10b70 20 2f 2a 20 4f 6e 65 20 6f 66 20 50 41 53 53 49   /* One of PASSI
10b80 56 45 2c 20 46 55 4c 4c 20 6f 72 20 52 45 53 54  VE, FULL or REST
10b90 41 52 54 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78  ART */.  int (*x
10ba0 42 75 73 79 29 28 76 6f 69 64 2a 29 2c 20 20 20  Busy)(void*),   
10bb0 20 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63           /* Func
10bc0 74 69 6f 6e 20 74 6f 20 63 61 6c 6c 20 77 68 65  tion to call whe
10bd0 6e 20 62 75 73 79 20 2a 2f 0a 20 20 76 6f 69 64  n busy */.  void
10be0 20 2a 70 42 75 73 79 41 72 67 2c 20 20 20 20 20   *pBusyArg,     
10bf0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
10c00 6f 6e 74 65 78 74 20 61 72 67 75 6d 65 6e 74 20  ontext argument 
10c10 66 6f 72 20 78 42 75 73 79 48 61 6e 64 6c 65 72  for xBusyHandler
10c20 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66   */.  int sync_f
10c30 6c 61 67 73 2c 20 20 20 20 20 20 20 20 20 20 20  lags,           
10c40 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 66        /* Flags f
10c50 6f 72 20 4f 73 53 79 6e 63 28 29 20 28 6f 72 20  or OsSync() (or 
10c60 30 29 20 2a 2f 0a 20 20 75 38 20 2a 7a 42 75 66  0) */.  u8 *zBuf
10c70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10c80 20 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f          /* Tempo
10c90 72 61 72 79 20 62 75 66 66 65 72 20 74 6f 20 75  rary buffer to u
10ca0 73 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  se */.){.  int r
10cb0 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
10cc0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
10cd0 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69  turn code */.  i
10ce0 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20  nt szPage;      
10cf0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
10d00 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 2d  * Database page-
10d10 73 69 7a 65 20 2a 2f 0a 20 20 57 61 6c 49 74 65  size */.  WalIte
10d20 72 61 74 6f 72 20 2a 70 49 74 65 72 20 3d 20 30  rator *pIter = 0
10d30 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c  ;         /* Wal
10d40 20 69 74 65 72 61 74 6f 72 20 63 6f 6e 74 65 78   iterator contex
10d50 74 20 2a 2f 0a 20 20 75 33 32 20 69 44 62 70 61  t */.  u32 iDbpa
10d60 67 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  ge = 0;         
10d70 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 64         /* Next d
10d80 61 74 61 62 61 73 65 20 70 61 67 65 20 74 6f 20  atabase page to 
10d90 77 72 69 74 65 20 2a 2f 0a 20 20 75 33 32 20 69  write */.  u32 i
10da0 46 72 61 6d 65 20 3d 20 30 3b 20 20 20 20 20 20  Frame = 0;      
10db0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61             /* Wa
10dc0 6c 20 66 72 61 6d 65 20 63 6f 6e 74 61 69 6e 69  l frame containi
10dd0 6e 67 20 64 61 74 61 20 66 6f 72 20 69 44 62 70  ng data for iDbp
10de0 61 67 65 20 2a 2f 0a 20 20 75 33 32 20 6d 78 53  age */.  u32 mxS
10df0 61 66 65 46 72 61 6d 65 3b 20 20 20 20 20 20 20  afeFrame;       
10e00 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78 20           /* Max 
10e10 66 72 61 6d 65 20 74 68 61 74 20 63 61 6e 20 62  frame that can b
10e20 65 20 62 61 63 6b 66 69 6c 6c 65 64 20 2a 2f 0a  e backfilled */.
10e30 20 20 75 33 32 20 6d 78 50 61 67 65 3b 20 20 20    u32 mxPage;   
10e40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10e50 20 20 2f 2a 20 4d 61 78 20 64 61 74 61 62 61 73    /* Max databas
10e60 65 20 70 61 67 65 20 74 6f 20 77 72 69 74 65 20  e page to write 
10e70 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20  */.  int i;     
10e80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10e90 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75       /* Loop cou
10ea0 6e 74 65 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  nter */.  volati
10eb0 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a  le WalCkptInfo *
10ec0 70 49 6e 66 6f 3b 20 20 20 20 2f 2a 20 54 68 65  pInfo;    /* The
10ed0 20 63 68 65 63 6b 70 6f 69 6e 74 20 73 74 61 74   checkpoint stat
10ee0 75 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 2a  us information *
10ef0 2f 0a 0a 20 20 73 7a 50 61 67 65 20 3d 20 77 61  /..  szPage = wa
10f00 6c 50 61 67 65 73 69 7a 65 28 70 57 61 6c 29 3b  lPagesize(pWal);
10f10 0a 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50  .  testcase( szP
10f20 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20  age<=32768 );.  
10f30 74 65 73 74 63 61 73 65 28 20 73 7a 50 61 67 65  testcase( szPage
10f40 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 70 49 6e  >=65536 );.  pIn
10f50 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f  fo = walCkptInfo
10f60 28 70 57 61 6c 29 3b 0a 20 20 69 66 28 20 70 49  (pWal);.  if( pI
10f70 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3c 70  nfo->nBackfill<p
10f80 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
10f90 20 29 7b 0a 0a 20 20 20 20 2f 2a 20 41 6c 6c 6f   ){..    /* Allo
10fa0 63 61 74 65 20 74 68 65 20 69 74 65 72 61 74 6f  cate the iterato
10fb0 72 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 77 61  r */.    rc = wa
10fc0 6c 49 74 65 72 61 74 6f 72 49 6e 69 74 28 70 57  lIteratorInit(pW
10fd0 61 6c 2c 20 26 70 49 74 65 72 29 3b 0a 20 20 20  al, &pIter);.   
10fe0 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
10ff0 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75  OK ){.      retu
11000 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20  rn rc;.    }.   
11010 20 61 73 73 65 72 74 28 20 70 49 74 65 72 20 29   assert( pIter )
11020 3b 0a 0a 20 20 20 20 2f 2a 20 45 56 49 44 45 4e  ;..    /* EVIDEN
11030 43 45 2d 4f 46 3a 20 52 2d 36 32 39 32 30 2d 34  CE-OF: R-62920-4
11040 37 34 35 30 20 54 68 65 20 62 75 73 79 2d 68 61  7450 The busy-ha
11050 6e 64 6c 65 72 20 63 61 6c 6c 62 61 63 6b 20 69  ndler callback i
11060 73 20 6e 65 76 65 72 20 69 6e 76 6f 6b 65 64 0a  s never invoked.
11070 20 20 20 20 2a 2a 20 69 6e 20 74 68 65 20 53 51      ** in the SQ
11080 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f  LITE_CHECKPOINT_
11090 50 41 53 53 49 56 45 20 6d 6f 64 65 2e 20 2a 2f  PASSIVE mode. */
110a0 0a 20 20 20 20 61 73 73 65 72 74 28 20 65 4d 6f  .    assert( eMo
110b0 64 65 21 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b  de!=SQLITE_CHECK
110c0 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 7c 7c  POINT_PASSIVE ||
110d0 20 78 42 75 73 79 3d 3d 30 20 29 3b 0a 0a 20 20   xBusy==0 );..  
110e0 20 20 2f 2a 20 43 6f 6d 70 75 74 65 20 69 6e 20    /* Compute in 
110f0 6d 78 53 61 66 65 46 72 61 6d 65 20 74 68 65 20  mxSafeFrame the 
11100 69 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 73  index of the las
11110 74 20 66 72 61 6d 65 20 6f 66 20 74 68 65 20 57  t frame of the W
11120 41 4c 20 74 68 61 74 20 69 73 0a 20 20 20 20 2a  AL that is.    *
11130 2a 20 73 61 66 65 20 74 6f 20 77 72 69 74 65 20  * safe to write 
11140 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
11150 65 2e 20 20 46 72 61 6d 65 73 20 62 65 79 6f 6e  e.  Frames beyon
11160 64 20 6d 78 53 61 66 65 46 72 61 6d 65 20 6d 69  d mxSafeFrame mi
11170 67 68 74 0a 20 20 20 20 2a 2a 20 6f 76 65 72 77  ght.    ** overw
11180 72 69 74 65 20 64 61 74 61 62 61 73 65 20 70 61  rite database pa
11190 67 65 73 20 74 68 61 74 20 61 72 65 20 69 6e 20  ges that are in 
111a0 75 73 65 20 62 79 20 61 63 74 69 76 65 20 72 65  use by active re
111b0 61 64 65 72 73 20 61 6e 64 20 74 68 75 73 0a 20  aders and thus. 
111c0 20 20 20 2a 2a 20 63 61 6e 6e 6f 74 20 62 65 20     ** cannot be 
111d0 62 61 63 6b 66 69 6c 6c 65 64 20 66 72 6f 6d 20  backfilled from 
111e0 74 68 65 20 57 41 4c 2e 0a 20 20 20 20 2a 2f 0a  the WAL..    */.
111f0 20 20 20 20 6d 78 53 61 66 65 46 72 61 6d 65 20      mxSafeFrame 
11200 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  = pWal->hdr.mxFr
11210 61 6d 65 3b 0a 20 20 20 20 6d 78 50 61 67 65 20  ame;.    mxPage 
11220 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67  = pWal->hdr.nPag
11230 65 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20  e;.    for(i=1; 
11240 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69  i<WAL_NREADER; i
11250 2b 2b 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68  ++){.      /* Th
11260 72 65 61 64 2d 73 61 6e 69 74 69 7a 65 72 20 72  read-sanitizer r
11270 65 70 6f 72 74 73 20 74 68 61 74 20 74 68 65 20  eports that the 
11280 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 61 6e 20  following is an 
11290 75 6e 73 61 66 65 20 72 65 61 64 2c 0a 20 20 20  unsafe read,.   
112a0 20 20 20 2a 2a 20 61 73 20 73 6f 6d 65 20 6f 74     ** as some ot
112b0 68 65 72 20 74 68 72 65 61 64 20 6d 61 79 20 62  her thread may b
112c0 65 20 69 6e 20 74 68 65 20 70 72 6f 63 65 73 73  e in the process
112d0 20 6f 66 20 75 70 64 61 74 69 6e 67 20 74 68 65   of updating the
112e0 20 76 61 6c 75 65 0a 20 20 20 20 20 20 2a 2a 20   value.      ** 
112f0 6f 66 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b  of the aReadMark
11300 5b 5d 20 73 6c 6f 74 2e 20 54 68 65 20 61 73 73  [] slot. The ass
11310 75 6d 70 74 69 6f 6e 20 68 65 72 65 20 69 73 20  umption here is 
11320 74 68 61 74 20 69 66 20 74 68 61 74 20 69 73 0a  that if that is.
11330 20 20 20 20 20 20 2a 2a 20 68 61 70 70 65 6e 69        ** happeni
11340 6e 67 2c 20 74 68 65 20 6f 74 68 65 72 20 63 6c  ng, the other cl
11350 69 65 6e 74 20 6d 61 79 20 6f 6e 6c 79 20 62 65  ient may only be
11360 20 69 6e 63 72 65 61 73 69 6e 67 20 74 68 65 20   increasing the 
11370 76 61 6c 75 65 2c 0a 20 20 20 20 20 20 2a 2a 20  value,.      ** 
11380 6e 6f 74 20 64 65 63 72 65 61 73 69 6e 67 20 69  not decreasing i
11390 74 2e 20 53 6f 20 61 73 73 75 6d 69 6e 67 20 65  t. So assuming e
113a0 69 74 68 65 72 20 74 68 61 74 20 65 69 74 68 65  ither that eithe
113b0 72 20 74 68 65 20 22 6f 6c 64 22 20 6f 72 0a 20  r the "old" or. 
113c0 20 20 20 20 20 2a 2a 20 22 6e 65 77 22 20 76 65       ** "new" ve
113d0 72 73 69 6f 6e 20 6f 66 20 74 68 65 20 76 61 6c  rsion of the val
113e0 75 65 20 69 73 20 72 65 61 64 2c 20 61 6e 64 20  ue is read, and 
113f0 6e 6f 74 20 73 6f 6d 65 20 61 72 62 69 74 72 61  not some arbitra
11400 72 79 20 76 61 6c 75 65 0a 20 20 20 20 20 20 2a  ry value.      *
11410 2a 20 74 68 61 74 20 77 6f 75 6c 64 20 6e 65 76  * that would nev
11420 65 72 20 62 65 20 77 72 69 74 74 65 6e 20 62 79  er be written by
11430 20 61 20 72 65 61 6c 20 63 6c 69 65 6e 74 2c 20   a real client, 
11440 74 68 69 6e 67 73 20 61 72 65 20 73 74 69 6c 6c  things are still
11450 20 0a 20 20 20 20 20 20 2a 2a 20 73 61 66 65 2e   .      ** safe.
11460 20 20 2a 2f 0a 20 20 20 20 20 20 75 33 32 20 79    */.      u32 y
11470 20 3d 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d   = pInfo->aReadM
11480 61 72 6b 5b 69 5d 3b 0a 20 20 20 20 20 20 69 66  ark[i];.      if
11490 28 20 6d 78 53 61 66 65 46 72 61 6d 65 3e 79 20  ( mxSafeFrame>y 
114a0 29 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72  ){.        asser
114b0 74 28 20 79 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e  t( y<=pWal->hdr.
114c0 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20 20 20  mxFrame );.     
114d0 20 20 20 72 63 20 3d 20 77 61 6c 42 75 73 79 4c     rc = walBusyL
114e0 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73 79 2c  ock(pWal, xBusy,
114f0 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c 5f 52   pBusyArg, WAL_R
11500 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b  EAD_LOCK(i), 1);
11510 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d  .        if( rc=
11520 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
11530 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 61          pInfo->a
11540 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 28 69  ReadMark[i] = (i
11550 3d 3d 31 20 3f 20 6d 78 53 61 66 65 46 72 61 6d  ==1 ? mxSafeFram
11560 65 20 3a 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54  e : READMARK_NOT
11570 5f 55 53 45 44 29 3b 0a 20 20 20 20 20 20 20 20  _USED);.        
11580 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75    walUnlockExclu
11590 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52  sive(pWal, WAL_R
115a0 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b  EAD_LOCK(i), 1);
115b0 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69  .        }else i
115c0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  f( rc==SQLITE_BU
115d0 53 59 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  SY ){.          
115e0 6d 78 53 61 66 65 46 72 61 6d 65 20 3d 20 79 3b  mxSafeFrame = y;
115f0 0a 20 20 20 20 20 20 20 20 20 20 78 42 75 73 79  .          xBusy
11600 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 65   = 0;.        }e
11610 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 67  lse{.          g
11620 6f 74 6f 20 77 61 6c 63 68 65 63 6b 70 6f 69 6e  oto walcheckpoin
11630 74 5f 6f 75 74 3b 0a 20 20 20 20 20 20 20 20 7d  t_out;.        }
11640 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
11650 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e      if( pInfo->n
11660 42 61 63 6b 66 69 6c 6c 3c 6d 78 53 61 66 65 46  Backfill<mxSafeF
11670 72 61 6d 65 0a 20 20 20 20 20 26 26 20 28 72 63  rame.     && (rc
11680 20 3d 20 77 61 6c 42 75 73 79 4c 6f 63 6b 28 70   = walBusyLock(p
11690 57 61 6c 2c 20 78 42 75 73 79 2c 20 70 42 75 73  Wal, xBusy, pBus
116a0 79 41 72 67 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  yArg, WAL_READ_L
116b0 4f 43 4b 28 30 29 2c 31 29 29 3d 3d 53 51 4c 49  OCK(0),1))==SQLI
116c0 54 45 5f 4f 4b 0a 20 20 20 20 29 7b 0a 20 20 20  TE_OK.    ){.   
116d0 20 20 20 69 36 34 20 6e 53 69 7a 65 3b 20 20 20     i64 nSize;   
116e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
116f0 20 2f 2a 20 43 75 72 72 65 6e 74 20 73 69 7a 65   /* Current size
11700 20 6f 66 20 64 61 74 61 62 61 73 65 20 66 69 6c   of database fil
11710 65 20 2a 2f 0a 20 20 20 20 20 20 75 33 32 20 6e  e */.      u32 n
11720 42 61 63 6b 66 69 6c 6c 20 3d 20 70 49 6e 66 6f  Backfill = pInfo
11730 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3b 0a 0a 20 20  ->nBackfill;..  
11740 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b      pInfo->nBack
11750 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 3d 20  fillAttempted = 
11760 6d 78 53 61 66 65 46 72 61 6d 65 3b 0a 0a 20 20  mxSafeFrame;..  
11770 20 20 20 20 2f 2a 20 53 79 6e 63 20 74 68 65 20      /* Sync the 
11780 57 41 4c 20 74 6f 20 64 69 73 6b 20 2a 2f 0a 20  WAL to disk */. 
11790 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
117a0 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57  3OsSync(pWal->pW
117b0 61 6c 46 64 2c 20 43 4b 50 54 5f 53 59 4e 43 5f  alFd, CKPT_SYNC_
117c0 46 4c 41 47 53 28 73 79 6e 63 5f 66 6c 61 67 73  FLAGS(sync_flags
117d0 29 29 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66  ));..      /* If
117e0 20 74 68 65 20 64 61 74 61 62 61 73 65 20 6d 61   the database ma
117f0 79 20 67 72 6f 77 20 61 73 20 61 20 72 65 73 75  y grow as a resu
11800 6c 74 20 6f 66 20 74 68 69 73 20 63 68 65 63 6b  lt of this check
11810 70 6f 69 6e 74 2c 20 68 69 6e 74 0a 20 20 20 20  point, hint.    
11820 20 20 2a 2a 20 61 62 6f 75 74 20 74 68 65 20 65    ** about the e
11830 76 65 6e 74 75 61 6c 20 73 69 7a 65 20 6f 66 20  ventual size of 
11840 74 68 65 20 64 62 20 66 69 6c 65 20 74 6f 20 74  the db file to t
11850 68 65 20 56 46 53 20 6c 61 79 65 72 2e 0a 20 20  he VFS layer..  
11860 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28      */.      if(
11870 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
11880 7b 0a 20 20 20 20 20 20 20 20 69 36 34 20 6e 52  {.        i64 nR
11890 65 71 20 3d 20 28 28 69 36 34 29 6d 78 50 61 67  eq = ((i64)mxPag
118a0 65 20 2a 20 73 7a 50 61 67 65 29 3b 0a 20 20 20  e * szPage);.   
118b0 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
118c0 33 4f 73 46 69 6c 65 53 69 7a 65 28 70 57 61 6c  3OsFileSize(pWal
118d0 2d 3e 70 44 62 46 64 2c 20 26 6e 53 69 7a 65 29  ->pDbFd, &nSize)
118e0 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
118f0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 6e  ==SQLITE_OK && n
11900 53 69 7a 65 3c 6e 52 65 71 20 29 7b 0a 20 20 20  Size<nReq ){.   
11910 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73         sqlite3Os
11920 46 69 6c 65 43 6f 6e 74 72 6f 6c 48 69 6e 74 28  FileControlHint(
11930 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 53 51 4c  pWal->pDbFd, SQL
11940 49 54 45 5f 46 43 4e 54 4c 5f 53 49 5a 45 5f 48  ITE_FCNTL_SIZE_H
11950 49 4e 54 2c 20 26 6e 52 65 71 29 3b 0a 20 20 20  INT, &nReq);.   
11960 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a       }.      }..
11970 0a 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74  .      /* Iterat
11980 65 20 74 68 72 6f 75 67 68 20 74 68 65 20 63 6f  e through the co
11990 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 57 41  ntents of the WA
119a0 4c 2c 20 63 6f 70 79 69 6e 67 20 64 61 74 61 20  L, copying data 
119b0 74 6f 20 74 68 65 20 64 62 20 66 69 6c 65 20 2a  to the db file *
119c0 2f 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 72  /.      while( r
119d0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
119e0 30 3d 3d 77 61 6c 49 74 65 72 61 74 6f 72 4e 65  0==walIteratorNe
119f0 78 74 28 70 49 74 65 72 2c 20 26 69 44 62 70 61  xt(pIter, &iDbpa
11a00 67 65 2c 20 26 69 46 72 61 6d 65 29 20 29 7b 0a  ge, &iFrame) ){.
11a10 20 20 20 20 20 20 20 20 69 36 34 20 69 4f 66 66          i64 iOff
11a20 73 65 74 3b 0a 20 20 20 20 20 20 20 20 61 73 73  set;.        ass
11a30 65 72 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e  ert( walFramePgn
11a40 6f 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 3d  o(pWal, iFrame)=
11a50 3d 69 44 62 70 61 67 65 20 29 3b 0a 20 20 20 20  =iDbpage );.    
11a60 20 20 20 20 69 66 28 20 64 62 2d 3e 75 31 2e 69      if( db->u1.i
11a70 73 49 6e 74 65 72 72 75 70 74 65 64 20 29 7b 0a  sInterrupted ){.
11a80 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 64            rc = d
11a90 62 2d 3e 6d 61 6c 6c 6f 63 46 61 69 6c 65 64 20  b->mallocFailed 
11aa0 3f 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42  ? SQLITE_NOMEM_B
11ab0 4b 50 54 20 3a 20 53 51 4c 49 54 45 5f 49 4e 54  KPT : SQLITE_INT
11ac0 45 52 52 55 50 54 3b 0a 20 20 20 20 20 20 20 20  ERRUPT;.        
11ad0 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20    break;.       
11ae0 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20 69   }.        if( i
11af0 46 72 61 6d 65 3c 3d 6e 42 61 63 6b 66 69 6c 6c  Frame<=nBackfill
11b00 20 7c 7c 20 69 46 72 61 6d 65 3e 6d 78 53 61 66   || iFrame>mxSaf
11b10 65 46 72 61 6d 65 20 7c 7c 20 69 44 62 70 61 67  eFrame || iDbpag
11b20 65 3e 6d 78 50 61 67 65 20 29 7b 0a 20 20 20 20  e>mxPage ){.    
11b30 20 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a        continue;.
11b40 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
11b50 20 20 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46    iOffset = walF
11b60 72 61 6d 65 4f 66 66 73 65 74 28 69 46 72 61 6d  rameOffset(iFram
11b70 65 2c 20 73 7a 50 61 67 65 29 20 2b 20 57 41 4c  e, szPage) + WAL
11b80 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a  _FRAME_HDRSIZE;.
11b90 20 20 20 20 20 20 20 20 2f 2a 20 74 65 73 74 63          /* testc
11ba0 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28  ase( IS_BIG_INT(
11bb0 69 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f 20 72  iOffset) ); // r
11bc0 65 71 75 69 72 65 73 20 61 20 34 47 69 42 20 57  equires a 4GiB W
11bd0 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 20  AL file */.     
11be0 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
11bf0 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c  sRead(pWal->pWal
11c00 46 64 2c 20 7a 42 75 66 2c 20 73 7a 50 61 67 65  Fd, zBuf, szPage
11c10 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20  , iOffset);.    
11c20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
11c30 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20  TE_OK ) break;. 
11c40 20 20 20 20 20 20 20 69 4f 66 66 73 65 74 20 3d         iOffset =
11c50 20 28 69 44 62 70 61 67 65 2d 31 29 2a 28 69 36   (iDbpage-1)*(i6
11c60 34 29 73 7a 50 61 67 65 3b 0a 20 20 20 20 20 20  4)szPage;.      
11c70 20 20 74 65 73 74 63 61 73 65 28 20 49 53 5f 42    testcase( IS_B
11c80 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20  IG_INT(iOffset) 
11c90 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  );.        rc = 
11ca0 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70  sqlite3OsWrite(p
11cb0 57 61 6c 2d 3e 70 44 62 46 64 2c 20 7a 42 75 66  Wal->pDbFd, zBuf
11cc0 2c 20 73 7a 50 61 67 65 2c 20 69 4f 66 66 73 65  , szPage, iOffse
11cd0 74 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  t);.        if( 
11ce0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
11cf0 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a  break;.      }..
11d00 20 20 20 20 20 20 2f 2a 20 49 66 20 77 6f 72 6b        /* If work
11d10 20 77 61 73 20 61 63 74 75 61 6c 6c 79 20 61 63   was actually ac
11d20 63 6f 6d 70 6c 69 73 68 65 64 2e 2e 2e 20 2a 2f  complished... */
11d30 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
11d40 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
11d50 20 20 20 20 69 66 28 20 6d 78 53 61 66 65 46 72      if( mxSafeFr
11d60 61 6d 65 3d 3d 77 61 6c 49 6e 64 65 78 48 64 72  ame==walIndexHdr
11d70 28 70 57 61 6c 29 2d 3e 6d 78 46 72 61 6d 65 20  (pWal)->mxFrame 
11d80 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 36 34  ){.          i64
11d90 20 73 7a 44 62 20 3d 20 70 57 61 6c 2d 3e 68 64   szDb = pWal->hd
11da0 72 2e 6e 50 61 67 65 2a 28 69 36 34 29 73 7a 50  r.nPage*(i64)szP
11db0 61 67 65 3b 0a 20 20 20 20 20 20 20 20 20 20 74  age;.          t
11dc0 65 73 74 63 61 73 65 28 20 49 53 5f 42 49 47 5f  estcase( IS_BIG_
11dd0 49 4e 54 28 73 7a 44 62 29 20 29 3b 0a 20 20 20  INT(szDb) );.   
11de0 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
11df0 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28 70 57  te3OsTruncate(pW
11e00 61 6c 2d 3e 70 44 62 46 64 2c 20 73 7a 44 62 29  al->pDbFd, szDb)
11e10 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
11e20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
11e30 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20  .            rc 
11e40 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28  = sqlite3OsSync(
11e50 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 43 4b 50  pWal->pDbFd, CKP
11e60 54 5f 53 59 4e 43 5f 46 4c 41 47 53 28 73 79 6e  T_SYNC_FLAGS(syn
11e70 63 5f 66 6c 61 67 73 29 29 3b 0a 20 20 20 20 20  c_flags));.     
11e80 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
11e90 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d  .        if( rc=
11ea0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
11eb0 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 6e          pInfo->n
11ec0 42 61 63 6b 66 69 6c 6c 20 3d 20 6d 78 53 61 66  Backfill = mxSaf
11ed0 65 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 20 20  eFrame;.        
11ee0 7d 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20  }.      }..     
11ef0 20 2f 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20   /* Release the 
11f00 72 65 61 64 65 72 20 6c 6f 63 6b 20 68 65 6c 64  reader lock held
11f10 20 77 68 69 6c 65 20 62 61 63 6b 66 69 6c 6c 69   while backfilli
11f20 6e 67 20 2a 2f 0a 20 20 20 20 20 20 77 61 6c 55  ng */.      walU
11f30 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  nlockExclusive(p
11f40 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
11f50 43 4b 28 30 29 2c 20 31 29 3b 0a 20 20 20 20 7d  CK(0), 1);.    }
11f60 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ..    if( rc==SQ
11f70 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
11f80 20 20 20 2f 2a 20 52 65 73 65 74 20 74 68 65 20     /* Reset the 
11f90 72 65 74 75 72 6e 20 63 6f 64 65 20 73 6f 20 61  return code so a
11fa0 73 20 6e 6f 74 20 74 6f 20 72 65 70 6f 72 74 20  s not to report 
11fb0 61 20 63 68 65 63 6b 70 6f 69 6e 74 20 66 61 69  a checkpoint fai
11fc0 6c 75 72 65 0a 20 20 20 20 20 20 2a 2a 20 6a 75  lure.      ** ju
11fd0 73 74 20 62 65 63 61 75 73 65 20 74 68 65 72 65  st because there
11fe0 20 61 72 65 20 61 63 74 69 76 65 20 72 65 61 64   are active read
11ff0 65 72 73 2e 20 20 2a 2f 0a 20 20 20 20 20 20 72  ers.  */.      r
12000 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
12010 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49     }.  }..  /* I
12020 66 20 74 68 69 73 20 69 73 20 61 6e 20 53 51 4c  f this is an SQL
12030 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 52  ITE_CHECKPOINT_R
12040 45 53 54 41 52 54 20 6f 72 20 54 52 55 4e 43 41  ESTART or TRUNCA
12050 54 45 20 6f 70 65 72 61 74 69 6f 6e 2c 20 61 6e  TE operation, an
12060 64 20 74 68 65 0a 20 20 2a 2a 20 65 6e 74 69 72  d the.  ** entir
12070 65 20 77 61 6c 20 66 69 6c 65 20 68 61 73 20 62  e wal file has b
12080 65 65 6e 20 63 6f 70 69 65 64 20 69 6e 74 6f 20  een copied into 
12090 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
120a0 65 2c 20 74 68 65 6e 20 62 6c 6f 63 6b 20 0a 20  e, then block . 
120b0 20 2a 2a 20 75 6e 74 69 6c 20 61 6c 6c 20 72 65   ** until all re
120c0 61 64 65 72 73 20 68 61 76 65 20 66 69 6e 69 73  aders have finis
120d0 68 65 64 20 75 73 69 6e 67 20 74 68 65 20 77 61  hed using the wa
120e0 6c 20 66 69 6c 65 2e 20 54 68 69 73 20 65 6e 73  l file. This ens
120f0 75 72 65 73 20 74 68 61 74 20 0a 20 20 2a 2a 20  ures that .  ** 
12100 74 68 65 20 6e 65 78 74 20 70 72 6f 63 65 73 73  the next process
12110 20 74 6f 20 77 72 69 74 65 20 74 6f 20 74 68 65   to write to the
12120 20 64 61 74 61 62 61 73 65 20 72 65 73 74 61 72   database restar
12130 74 73 20 74 68 65 20 77 61 6c 20 66 69 6c 65 2e  ts the wal file.
12140 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  .  */.  if( rc==
12150 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 65 4d 6f  SQLITE_OK && eMo
12160 64 65 21 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b  de!=SQLITE_CHECK
12170 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 29 7b  POINT_PASSIVE ){
12180 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 57 61  .    assert( pWa
12190 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a  l->writeLock );.
121a0 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e      if( pInfo->n
121b0 42 61 63 6b 66 69 6c 6c 3c 70 57 61 6c 2d 3e 68  Backfill<pWal->h
121c0 64 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20  dr.mxFrame ){.  
121d0 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
121e0 42 55 53 59 3b 0a 20 20 20 20 7d 65 6c 73 65 20  BUSY;.    }else 
121f0 69 66 28 20 65 4d 6f 64 65 3e 3d 53 51 4c 49 54  if( eMode>=SQLIT
12200 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 52 45 53  E_CHECKPOINT_RES
12210 54 41 52 54 20 29 7b 0a 20 20 20 20 20 20 75 33  TART ){.      u3
12220 32 20 73 61 6c 74 31 3b 0a 20 20 20 20 20 20 73  2 salt1;.      s
12230 71 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73  qlite3_randomnes
12240 73 28 34 2c 20 26 73 61 6c 74 31 29 3b 0a 20 20  s(4, &salt1);.  
12250 20 20 20 20 61 73 73 65 72 74 28 20 70 49 6e 66      assert( pInf
12260 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70 57  o->nBackfill==pW
12270 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
12280 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61  );.      rc = wa
12290 6c 42 75 73 79 4c 6f 63 6b 28 70 57 61 6c 2c 20  lBusyLock(pWal, 
122a0 78 42 75 73 79 2c 20 70 42 75 73 79 41 72 67 2c  xBusy, pBusyArg,
122b0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31   WAL_READ_LOCK(1
122c0 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31  ), WAL_NREADER-1
122d0 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
122e0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
122f0 20 20 20 20 20 20 69 66 28 20 65 4d 6f 64 65 3d        if( eMode=
12300 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49  =SQLITE_CHECKPOI
12310 4e 54 5f 54 52 55 4e 43 41 54 45 20 29 7b 0a 20  NT_TRUNCATE ){. 
12320 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4d 50 4c           /* IMPL
12330 45 4d 45 4e 54 41 54 49 4f 4e 2d 4f 46 3a 20 52  EMENTATION-OF: R
12340 2d 34 34 36 39 39 2d 35 37 31 34 30 20 54 68 69  -44699-57140 Thi
12350 73 20 6d 6f 64 65 20 77 6f 72 6b 73 20 74 68 65  s mode works the
12360 20 73 61 6d 65 20 77 61 79 20 61 73 0a 20 20 20   same way as.   
12370 20 20 20 20 20 20 20 2a 2a 20 53 51 4c 49 54 45         ** SQLITE
12380 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 52 45 53 54  _CHECKPOINT_REST
12390 41 52 54 20 77 69 74 68 20 74 68 65 20 61 64 64  ART with the add
123a0 69 74 69 6f 6e 20 74 68 61 74 20 69 74 20 61 6c  ition that it al
123b0 73 6f 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20  so.          ** 
123c0 74 72 75 6e 63 61 74 65 73 20 74 68 65 20 6c 6f  truncates the lo
123d0 67 20 66 69 6c 65 20 74 6f 20 7a 65 72 6f 20 62  g file to zero b
123e0 79 74 65 73 20 6a 75 73 74 20 70 72 69 6f 72 20  ytes just prior 
123f0 74 6f 20 61 0a 20 20 20 20 20 20 20 20 20 20 2a  to a.          *
12400 2a 20 73 75 63 63 65 73 73 66 75 6c 20 72 65 74  * successful ret
12410 75 72 6e 2e 0a 20 20 20 20 20 20 20 20 20 20 2a  urn..          *
12420 2a 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 49  *.          ** I
12430 6e 20 74 68 65 6f 72 79 2c 20 69 74 20 6d 69 67  n theory, it mig
12440 68 74 20 62 65 20 73 61 66 65 20 74 6f 20 64 6f  ht be safe to do
12450 20 74 68 69 73 20 77 69 74 68 6f 75 74 20 75 70   this without up
12460 64 61 74 69 6e 67 20 74 68 65 0a 20 20 20 20 20  dating the.     
12470 20 20 20 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65       ** wal-inde
12480 78 20 68 65 61 64 65 72 20 69 6e 20 73 68 61 72  x header in shar
12490 65 64 20 6d 65 6d 6f 72 79 2c 20 61 73 20 61 6c  ed memory, as al
124a0 6c 20 73 75 62 73 65 71 75 65 6e 74 20 72 65 61  l subsequent rea
124b0 64 65 72 20 6f 72 0a 20 20 20 20 20 20 20 20 20  der or.         
124c0 20 2a 2a 20 77 72 69 74 65 72 20 63 6c 69 65 6e   ** writer clien
124d0 74 73 20 73 68 6f 75 6c 64 20 73 65 65 20 74 68  ts should see th
124e0 61 74 20 74 68 65 20 65 6e 74 69 72 65 20 6c 6f  at the entire lo
124f0 67 20 66 69 6c 65 20 68 61 73 20 62 65 65 6e 0a  g file has been.
12500 20 20 20 20 20 20 20 20 20 20 2a 2a 20 63 68 65            ** che
12510 63 6b 70 6f 69 6e 74 65 64 20 61 6e 64 20 62 65  ckpointed and be
12520 68 61 76 65 20 61 63 63 6f 72 64 69 6e 67 6c 79  have accordingly
12530 2e 20 54 68 69 73 20 73 65 65 6d 73 20 75 6e 73  . This seems uns
12540 61 66 65 20 74 68 6f 75 67 68 2c 0a 20 20 20 20  afe though,.    
12550 20 20 20 20 20 20 2a 2a 20 61 73 20 69 74 20 77        ** as it w
12560 6f 75 6c 64 20 6c 65 61 76 65 20 74 68 65 20 73  ould leave the s
12570 79 73 74 65 6d 20 69 6e 20 61 20 73 74 61 74 65  ystem in a state
12580 20 77 68 65 72 65 20 74 68 65 20 63 6f 6e 74 65   where the conte
12590 6e 74 73 20 6f 66 0a 20 20 20 20 20 20 20 20 20  nts of.         
125a0 20 2a 2a 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   ** the wal-inde
125b0 78 20 68 65 61 64 65 72 20 64 6f 20 6e 6f 74 20  x header do not 
125c0 6d 61 74 63 68 20 74 68 65 20 63 6f 6e 74 65 6e  match the conten
125d0 74 73 20 6f 66 20 74 68 65 20 0a 20 20 20 20 20  ts of the .     
125e0 20 20 20 20 20 2a 2a 20 66 69 6c 65 2d 73 79 73       ** file-sys
125f0 74 65 6d 2e 20 54 6f 20 61 76 6f 69 64 20 74 68  tem. To avoid th
12600 69 73 2c 20 75 70 64 61 74 65 20 74 68 65 20 77  is, update the w
12610 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
12620 74 6f 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20  to.          ** 
12630 69 6e 64 69 63 61 74 65 20 74 68 61 74 20 74 68  indicate that th
12640 65 20 6c 6f 67 20 66 69 6c 65 20 63 6f 6e 74 61  e log file conta
12650 69 6e 73 20 7a 65 72 6f 20 76 61 6c 69 64 20 66  ins zero valid f
12660 72 61 6d 65 73 2e 20 20 2a 2f 0a 20 20 20 20 20  rames.  */.     
12670 20 20 20 20 20 77 61 6c 52 65 73 74 61 72 74 48       walRestartH
12680 64 72 28 70 57 61 6c 2c 20 73 61 6c 74 31 29 3b  dr(pWal, salt1);
12690 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
126a0 73 71 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74  sqlite3OsTruncat
126b0 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20  e(pWal->pWalFd, 
126c0 30 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  0);.        }.  
126d0 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45        walUnlockE
126e0 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
126f0 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c  AL_READ_LOCK(1),
12700 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b   WAL_NREADER-1);
12710 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
12720 20 7d 0a 0a 20 77 61 6c 63 68 65 63 6b 70 6f 69   }.. walcheckpoi
12730 6e 74 5f 6f 75 74 3a 0a 20 20 77 61 6c 49 74 65  nt_out:.  walIte
12740 72 61 74 6f 72 46 72 65 65 28 70 49 74 65 72 29  ratorFree(pIter)
12750 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
12760 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 20 57  ../*.** If the W
12770 41 4c 20 66 69 6c 65 20 69 73 20 63 75 72 72 65  AL file is curre
12780 6e 74 6c 79 20 6c 61 72 67 65 72 20 74 68 61 6e  ntly larger than
12790 20 6e 4d 61 78 20 62 79 74 65 73 20 69 6e 20 73   nMax bytes in s
127a0 69 7a 65 2c 20 74 72 75 6e 63 61 74 65 0a 2a 2a  ize, truncate.**
127b0 20 69 74 20 74 6f 20 65 78 61 63 74 6c 79 20 6e   it to exactly n
127c0 4d 61 78 20 62 79 74 65 73 2e 20 49 66 20 61 6e  Max bytes. If an
127d0 20 65 72 72 6f 72 20 6f 63 63 75 72 73 20 77 68   error occurs wh
127e0 69 6c 65 20 64 6f 69 6e 67 20 73 6f 2c 20 69 67  ile doing so, ig
127f0 6e 6f 72 65 20 69 74 2e 0a 2a 2f 0a 73 74 61 74  nore it..*/.stat
12800 69 63 20 76 6f 69 64 20 77 61 6c 4c 69 6d 69 74  ic void walLimit
12810 53 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Size(Wal *pWal, 
12820 69 36 34 20 6e 4d 61 78 29 7b 0a 20 20 69 36 34  i64 nMax){.  i64
12830 20 73 7a 3b 0a 20 20 69 6e 74 20 72 78 3b 0a 20   sz;.  int rx;. 
12840 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e   sqlite3BeginBen
12850 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 72  ignMalloc();.  r
12860 78 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 69 6c  x = sqlite3OsFil
12870 65 53 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c  eSize(pWal->pWal
12880 46 64 2c 20 26 73 7a 29 3b 0a 20 20 69 66 28 20  Fd, &sz);.  if( 
12890 72 78 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rx==SQLITE_OK &&
128a0 20 28 73 7a 20 3e 20 6e 4d 61 78 20 29 20 29 7b   (sz > nMax ) ){
128b0 0a 20 20 20 20 72 78 20 3d 20 73 71 6c 69 74 65  .    rx = sqlite
128c0 33 4f 73 54 72 75 6e 63 61 74 65 28 70 57 61 6c  3OsTruncate(pWal
128d0 2d 3e 70 57 61 6c 46 64 2c 20 6e 4d 61 78 29 3b  ->pWalFd, nMax);
128e0 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 45 6e  .  }.  sqlite3En
128f0 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  dBenignMalloc();
12900 0a 20 20 69 66 28 20 72 78 20 29 7b 0a 20 20 20  .  if( rx ){.   
12910 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28 72 78 2c   sqlite3_log(rx,
12920 20 22 63 61 6e 6e 6f 74 20 6c 69 6d 69 74 20 57   "cannot limit W
12930 41 4c 20 73 69 7a 65 3a 20 25 73 22 2c 20 70 57  AL size: %s", pW
12940 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65 29 3b 0a 20  al->zWalName);. 
12950 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73   }.}../*.** Clos
12960 65 20 61 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74  e a connection t
12970 6f 20 61 20 6c 6f 67 20 66 69 6c 65 2e 0a 2a 2f  o a log file..*/
12980 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 43  .int sqlite3WalC
12990 6c 6f 73 65 28 0a 20 20 57 61 6c 20 2a 70 57 61  lose(.  Wal *pWa
129a0 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
129b0 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 74          /* Wal t
129c0 6f 20 63 6c 6f 73 65 20 2a 2f 0a 20 20 73 71 6c  o close */.  sql
129d0 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20  ite3 *db,       
129e0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
129f0 46 6f 72 20 69 6e 74 65 72 72 75 70 74 20 66 6c  For interrupt fl
12a00 61 67 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63  ag */.  int sync
12a10 5f 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20 20  _flags,         
12a20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73          /* Flags
12a30 20 74 6f 20 70 61 73 73 20 74 6f 20 4f 73 53 79   to pass to OsSy
12a40 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 20  nc() (or 0) */. 
12a50 20 69 6e 74 20 6e 42 75 66 2c 0a 20 20 75 38 20   int nBuf,.  u8 
12a60 2a 7a 42 75 66 20 20 20 20 20 20 20 20 20 20 20  *zBuf           
12a70 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12a80 42 75 66 66 65 72 20 6f 66 20 61 74 20 6c 65 61  Buffer of at lea
12a90 73 74 20 6e 42 75 66 20 62 79 74 65 73 20 2a 2f  st nBuf bytes */
12aa0 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
12ab0 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20  QLITE_OK;.  if( 
12ac0 70 57 61 6c 20 29 7b 0a 20 20 20 20 69 6e 74 20  pWal ){.    int 
12ad0 69 73 44 65 6c 65 74 65 20 3d 20 30 3b 20 20 20  isDelete = 0;   
12ae0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
12af0 65 20 74 6f 20 75 6e 6c 69 6e 6b 20 77 61 6c 20  e to unlink wal 
12b00 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 69  and wal-index fi
12b10 6c 65 73 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 49  les */..    /* I
12b20 66 20 61 6e 20 45 58 43 4c 55 53 49 56 45 20 6c  f an EXCLUSIVE l
12b30 6f 63 6b 20 63 61 6e 20 62 65 20 6f 62 74 61 69  ock can be obtai
12b40 6e 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 62  ned on the datab
12b50 61 73 65 20 66 69 6c 65 20 28 75 73 69 6e 67 20  ase file (using 
12b60 74 68 65 0a 20 20 20 20 2a 2a 20 6f 72 64 69 6e  the.    ** ordin
12b70 61 72 79 2c 20 72 6f 6c 6c 62 61 63 6b 2d 6d 6f  ary, rollback-mo
12b80 64 65 20 6c 6f 63 6b 69 6e 67 20 6d 65 74 68 6f  de locking metho
12b90 64 73 2c 20 74 68 69 73 20 67 75 61 72 61 6e 74  ds, this guarant
12ba0 65 65 73 20 74 68 61 74 20 74 68 65 0a 20 20 20  ees that the.   
12bb0 20 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 61   ** connection a
12bc0 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74  ssociated with t
12bd0 68 69 73 20 6c 6f 67 20 66 69 6c 65 20 69 73 20  his log file is 
12be0 74 68 65 20 6f 6e 6c 79 20 63 6f 6e 6e 65 63 74  the only connect
12bf0 69 6f 6e 20 74 6f 0a 20 20 20 20 2a 2a 20 74 68  ion to.    ** th
12c00 65 20 64 61 74 61 62 61 73 65 2e 20 49 6e 20 74  e database. In t
12c10 68 69 73 20 63 61 73 65 20 63 68 65 63 6b 70 6f  his case checkpo
12c20 69 6e 74 20 74 68 65 20 64 61 74 61 62 61 73 65  int the database
12c30 20 61 6e 64 20 75 6e 6c 69 6e 6b 20 62 6f 74 68   and unlink both
12c40 0a 20 20 20 20 2a 2a 20 74 68 65 20 77 61 6c 20  .    ** the wal 
12c50 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 69  and wal-index fi
12c60 6c 65 73 2e 0a 20 20 20 20 2a 2a 0a 20 20 20 20  les..    **.    
12c70 2a 2a 20 54 68 65 20 45 58 43 4c 55 53 49 56 45  ** The EXCLUSIVE
12c80 20 6c 6f 63 6b 20 69 73 20 6e 6f 74 20 72 65 6c   lock is not rel
12c90 65 61 73 65 64 20 62 65 66 6f 72 65 20 72 65 74  eased before ret
12ca0 75 72 6e 69 6e 67 2e 0a 20 20 20 20 2a 2f 0a 20  urning..    */. 
12cb0 20 20 20 69 66 28 20 7a 42 75 66 21 3d 30 0a 20     if( zBuf!=0. 
12cc0 20 20 20 20 26 26 20 53 51 4c 49 54 45 5f 4f 4b      && SQLITE_OK
12cd0 3d 3d 28 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  ==(rc = sqlite3O
12ce0 73 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46  sLock(pWal->pDbF
12cf0 64 2c 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 5f 45  d, SQLITE_LOCK_E
12d00 58 43 4c 55 53 49 56 45 29 29 0a 20 20 20 20 29  XCLUSIVE)).    )
12d10 7b 0a 20 20 20 20 20 20 69 66 28 20 70 57 61 6c  {.      if( pWal
12d20 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d  ->exclusiveMode=
12d30 3d 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45  =WAL_NORMAL_MODE
12d40 20 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c   ){.        pWal
12d50 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20  ->exclusiveMode 
12d60 3d 20 57 41 4c 5f 45 58 43 4c 55 53 49 56 45 5f  = WAL_EXCLUSIVE_
12d70 4d 4f 44 45 3b 0a 20 20 20 20 20 20 7d 0a 20 20  MODE;.      }.  
12d80 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
12d90 57 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 70 57  WalCheckpoint(pW
12da0 61 6c 2c 20 64 62 2c 20 0a 20 20 20 20 20 20 20  al, db, .       
12db0 20 20 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 50     SQLITE_CHECKP
12dc0 4f 49 4e 54 5f 50 41 53 53 49 56 45 2c 20 30 2c  OINT_PASSIVE, 0,
12dd0 20 30 2c 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20   0, sync_flags, 
12de0 6e 42 75 66 2c 20 7a 42 75 66 2c 20 30 2c 20 30  nBuf, zBuf, 0, 0
12df0 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20  .      );.      
12e00 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
12e10 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74  K ){.        int
12e20 20 62 50 65 72 73 69 73 74 20 3d 20 2d 31 3b 0a   bPersist = -1;.
12e30 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f          sqlite3O
12e40 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 48 69 6e 74  sFileControlHint
12e50 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 57  (.            pW
12e60 61 6c 2d 3e 70 44 62 46 64 2c 20 53 51 4c 49 54  al->pDbFd, SQLIT
12e70 45 5f 46 43 4e 54 4c 5f 50 45 52 53 49 53 54 5f  E_FCNTL_PERSIST_
12e80 57 41 4c 2c 20 26 62 50 65 72 73 69 73 74 0a 20  WAL, &bPersist. 
12e90 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20         );.      
12ea0 20 20 69 66 28 20 62 50 65 72 73 69 73 74 21 3d    if( bPersist!=
12eb0 31 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2f  1 ){.          /
12ec0 2a 20 54 72 79 20 74 6f 20 64 65 6c 65 74 65 20  * Try to delete 
12ed0 74 68 65 20 57 41 4c 20 66 69 6c 65 20 69 66 20  the WAL file if 
12ee0 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 63  the checkpoint c
12ef0 6f 6d 70 6c 65 74 65 64 20 61 6e 64 0a 20 20 20  ompleted and.   
12f00 20 20 20 20 20 20 20 2a 2a 20 66 73 79 6e 65 64         ** fsyned
12f10 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29   (rc==SQLITE_OK)
12f20 20 61 6e 64 20 69 66 20 77 65 20 61 72 65 20 6e   and if we are n
12f30 6f 74 20 69 6e 20 70 65 72 73 69 73 74 65 6e 74  ot in persistent
12f40 2d 77 61 6c 0a 20 20 20 20 20 20 20 20 20 20 2a  -wal.          *
12f50 2a 20 6d 6f 64 65 20 28 21 62 50 65 72 73 69 73  * mode (!bPersis
12f60 74 29 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  t) */.          
12f70 69 73 44 65 6c 65 74 65 20 3d 20 31 3b 0a 20 20  isDelete = 1;.  
12f80 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
12f90 70 57 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 3e  pWal->mxWalSize>
12fa0 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
12fb0 2f 2a 20 54 72 79 20 74 6f 20 74 72 75 6e 63 61  /* Try to trunca
12fc0 74 65 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20  te the WAL file 
12fd0 74 6f 20 7a 65 72 6f 20 62 79 74 65 73 20 69 66  to zero bytes if
12fe0 20 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 0a   the checkpoint.
12ff0 20 20 20 20 20 20 20 20 20 20 2a 2a 20 63 6f 6d            ** com
13000 70 6c 65 74 65 64 20 61 6e 64 20 66 73 79 6e 63  pleted and fsync
13010 65 64 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  ed (rc==SQLITE_O
13020 4b 29 20 61 6e 64 20 77 65 20 61 72 65 20 69 6e  K) and we are in
13030 20 70 65 72 73 69 73 74 65 6e 74 0a 20 20 20 20   persistent.    
13040 20 20 20 20 20 20 2a 2a 20 57 41 4c 20 6d 6f 64        ** WAL mod
13050 65 20 28 62 50 65 72 73 69 73 74 29 20 61 6e 64  e (bPersist) and
13060 20 69 66 20 74 68 65 20 50 52 41 47 4d 41 20 6a   if the PRAGMA j
13070 6f 75 72 6e 61 6c 5f 73 69 7a 65 5f 6c 69 6d 69  ournal_size_limi
13080 74 20 69 73 20 61 0a 20 20 20 20 20 20 20 20 20  t is a.         
13090 20 2a 2a 20 6e 6f 6e 2d 6e 65 67 61 74 69 76 65   ** non-negative
130a0 20 76 61 6c 75 65 20 28 70 57 61 6c 2d 3e 6d 78   value (pWal->mx
130b0 57 61 6c 53 69 7a 65 3e 3d 30 29 2e 20 20 4e 6f  WalSize>=0).  No
130c0 74 65 20 74 68 61 74 20 77 65 20 74 72 75 6e 63  te that we trunc
130d0 61 74 65 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  ate.          **
130e0 20 74 6f 20 7a 65 72 6f 20 62 79 74 65 73 20 61   to zero bytes a
130f0 73 20 74 72 75 6e 63 61 74 69 6e 67 20 74 6f 20  s truncating to 
13100 74 68 65 20 6a 6f 75 72 6e 61 6c 5f 73 69 7a 65  the journal_size
13110 5f 6c 69 6d 69 74 20 6d 69 67 68 74 0a 20 20 20  _limit might.   
13120 20 20 20 20 20 20 20 2a 2a 20 6c 65 61 76 65 20         ** leave 
13130 61 20 63 6f 72 72 75 70 74 20 57 41 4c 20 66 69  a corrupt WAL fi
13140 6c 65 20 6f 6e 20 64 69 73 6b 2e 20 2a 2f 0a 20  le on disk. */. 
13150 20 20 20 20 20 20 20 20 20 77 61 6c 4c 69 6d 69           walLimi
13160 74 53 69 7a 65 28 70 57 61 6c 2c 20 30 29 3b 0a  tSize(pWal, 0);.
13170 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
13180 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 77 61 6c  }.    }..    wal
13190 49 6e 64 65 78 43 6c 6f 73 65 28 70 57 61 6c 2c  IndexClose(pWal,
131a0 20 69 73 44 65 6c 65 74 65 29 3b 0a 20 20 20 20   isDelete);.    
131b0 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 28 70  sqlite3OsClose(p
131c0 57 61 6c 2d 3e 70 57 61 6c 46 64 29 3b 0a 20 20  Wal->pWalFd);.  
131d0 20 20 69 66 28 20 69 73 44 65 6c 65 74 65 20 29    if( isDelete )
131e0 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 42  {.      sqlite3B
131f0 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63  eginBenignMalloc
13200 28 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  ();.      sqlite
13210 33 4f 73 44 65 6c 65 74 65 28 70 57 61 6c 2d 3e  3OsDelete(pWal->
13220 70 56 66 73 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c  pVfs, pWal->zWal
13230 4e 61 6d 65 2c 20 30 29 3b 0a 20 20 20 20 20 20  Name, 0);.      
13240 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e  sqlite3EndBenign
13250 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 20 20 7d 0a  Malloc();.    }.
13260 20 20 20 20 57 41 4c 54 52 41 43 45 28 28 22 57      WALTRACE(("W
13270 41 4c 25 70 3a 20 63 6c 6f 73 65 64 5c 6e 22 2c  AL%p: closed\n",
13280 20 70 57 61 6c 29 29 3b 0a 20 20 20 20 73 71 6c   pWal));.    sql
13290 69 74 65 33 5f 66 72 65 65 28 28 76 6f 69 64 20  ite3_free((void 
132a0 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61  *)pWal->apWiData
132b0 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
132c0 72 65 65 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20  ree(pWal);.  }. 
132d0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
132e0 2a 0a 2a 2a 20 54 72 79 20 74 6f 20 72 65 61 64  *.** Try to read
132f0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
13300 65 61 64 65 72 2e 20 20 52 65 74 75 72 6e 20 30  eader.  Return 0
13310 20 6f 6e 20 73 75 63 63 65 73 73 20 61 6e 64 20   on success and 
13320 31 20 69 66 0a 2a 2a 20 74 68 65 72 65 20 69 73  1 if.** there is
13330 20 61 20 70 72 6f 62 6c 65 6d 2e 0a 2a 2a 0a 2a   a problem..**.*
13340 2a 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  * The wal-index 
13350 69 73 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d  is in shared mem
13360 6f 72 79 2e 20 20 41 6e 6f 74 68 65 72 20 74 68  ory.  Another th
13370 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 20  read or process 
13380 6d 69 67 68 74 0a 2a 2a 20 62 65 20 77 72 69 74  might.** be writ
13390 69 6e 67 20 74 68 65 20 68 65 61 64 65 72 20 61  ing the header a
133a0 74 20 74 68 65 20 73 61 6d 65 20 74 69 6d 65 20  t the same time 
133b0 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 20 69  this procedure i
133c0 73 20 74 72 79 69 6e 67 20 74 6f 0a 2a 2a 20 72  s trying to.** r
133d0 65 61 64 20 69 74 2c 20 77 68 69 63 68 20 6d 69  ead it, which mi
133e0 67 68 74 20 72 65 73 75 6c 74 20 69 6e 20 69 6e  ght result in in
133f0 63 6f 6e 73 69 73 74 65 6e 63 79 2e 20 20 41 20  consistency.  A 
13400 64 69 72 74 79 20 72 65 61 64 20 69 73 20 64 65  dirty read is de
13410 74 65 63 74 65 64 0a 2a 2a 20 62 79 20 76 65 72  tected.** by ver
13420 69 66 79 69 6e 67 20 74 68 61 74 20 62 6f 74 68  ifying that both
13430 20 63 6f 70 69 65 73 20 6f 66 20 74 68 65 20 68   copies of the h
13440 65 61 64 65 72 20 61 72 65 20 74 68 65 20 73 61  eader are the sa
13450 6d 65 20 61 6e 64 20 61 6c 73 6f 20 62 79 0a 2a  me and also by.*
13460 2a 20 61 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20  * a checksum on 
13470 74 68 65 20 68 65 61 64 65 72 2e 0a 2a 2a 0a 2a  the header..**.*
13480 2a 20 49 66 20 61 6e 64 20 6f 6e 6c 79 20 69 66  * If and only if
13490 20 74 68 65 20 72 65 61 64 20 69 73 20 63 6f 6e   the read is con
134a0 73 69 73 74 65 6e 74 20 61 6e 64 20 74 68 65 20  sistent and the 
134b0 68 65 61 64 65 72 20 69 73 20 64 69 66 66 65 72  header is differ
134c0 65 6e 74 20 66 72 6f 6d 0a 2a 2a 20 70 57 61 6c  ent from.** pWal
134d0 2d 3e 68 64 72 2c 20 74 68 65 6e 20 70 57 61 6c  ->hdr, then pWal
134e0 2d 3e 68 64 72 20 69 73 20 75 70 64 61 74 65 64  ->hdr is updated
134f0 20 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e 74 20   to the content 
13500 6f 66 20 74 68 65 20 6e 65 77 20 68 65 61 64 65  of the new heade
13510 72 0a 2a 2a 20 61 6e 64 20 2a 70 43 68 61 6e 67  r.** and *pChang
13520 65 64 20 69 73 20 73 65 74 20 74 6f 20 31 2e 0a  ed is set to 1..
13530 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 63 68 65  **.** If the che
13540 63 6b 73 75 6d 20 63 61 6e 6e 6f 74 20 62 65 20  cksum cannot be 
13550 76 65 72 69 66 69 65 64 20 72 65 74 75 72 6e 20  verified return 
13560 6e 6f 6e 2d 7a 65 72 6f 2e 20 49 66 20 74 68 65  non-zero. If the
13570 20 68 65 61 64 65 72 0a 2a 2a 20 69 73 20 72 65   header.** is re
13580 61 64 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20  ad successfully 
13590 61 6e 64 20 74 68 65 20 63 68 65 63 6b 73 75 6d  and the checksum
135a0 20 76 65 72 69 66 69 65 64 2c 20 72 65 74 75 72   verified, retur
135b0 6e 20 7a 65 72 6f 2e 0a 2a 2f 0a 73 74 61 74 69  n zero..*/.stati
135c0 63 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 54 72  c int walIndexTr
135d0 79 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 2c 20  yHdr(Wal *pWal, 
135e0 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a  int *pChanged){.
135f0 20 20 75 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b    u32 aCksum[2];
13600 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13610 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 6f 6e    /* Checksum on
13620 20 74 68 65 20 68 65 61 64 65 72 20 63 6f 6e 74   the header cont
13630 65 6e 74 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65  ent */.  WalInde
13640 78 48 64 72 20 68 31 2c 20 68 32 3b 20 20 20 20  xHdr h1, h2;    
13650 20 20 20 20 20 20 20 20 20 2f 2a 20 54 77 6f 20           /* Two 
13660 63 6f 70 69 65 73 20 6f 66 20 74 68 65 20 68 65  copies of the he
13670 61 64 65 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a  ader content */.
13680 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20 76 6f    WalIndexHdr vo
13690 6c 61 74 69 6c 65 20 2a 61 48 64 72 3b 20 20 20  latile *aHdr;   
136a0 20 20 2f 2a 20 48 65 61 64 65 72 20 69 6e 20 73    /* Header in s
136b0 68 61 72 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a  hared memory */.
136c0 0a 20 20 2f 2a 20 54 68 65 20 66 69 72 73 74 20  .  /* The first 
136d0 70 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d  page of the wal-
136e0 69 6e 64 65 78 20 6d 75 73 74 20 62 65 20 6d 61  index must be ma
136f0 70 70 65 64 20 61 74 20 74 68 69 73 20 70 6f 69  pped at this poi
13700 6e 74 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  nt. */.  assert(
13710 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30   pWal->nWiData>0
13720 20 26 26 20 70 57 61 6c 2d 3e 61 70 57 69 44 61   && pWal->apWiDa
13730 74 61 5b 30 5d 20 29 3b 0a 0a 20 20 2f 2a 20 52  ta[0] );..  /* R
13740 65 61 64 20 74 68 65 20 68 65 61 64 65 72 2e 20  ead the header. 
13750 54 68 69 73 20 6d 69 67 68 74 20 68 61 70 70 65  This might happe
13760 6e 20 63 6f 6e 63 75 72 72 65 6e 74 6c 79 20 77  n concurrently w
13770 69 74 68 20 61 20 77 72 69 74 65 20 74 6f 20 74  ith a write to t
13780 68 65 0a 20 20 2a 2a 20 73 61 6d 65 20 61 72 65  he.  ** same are
13790 61 20 6f 66 20 73 68 61 72 65 64 20 6d 65 6d 6f  a of shared memo
137a0 72 79 20 6f 6e 20 61 20 64 69 66 66 65 72 65 6e  ry on a differen
137b0 74 20 43 50 55 20 69 6e 20 61 20 53 4d 50 2c 0a  t CPU in a SMP,.
137c0 20 20 2a 2a 20 6d 65 61 6e 69 6e 67 20 69 74 20    ** meaning it 
137d0 69 73 20 70 6f 73 73 69 62 6c 65 20 74 68 61 74  is possible that
137e0 20 61 6e 20 69 6e 63 6f 6e 73 69 73 74 65 6e 74   an inconsistent
137f0 20 73 6e 61 70 73 68 6f 74 20 69 73 20 72 65 61   snapshot is rea
13800 64 0a 20 20 2a 2a 20 66 72 6f 6d 20 74 68 65 20  d.  ** from the 
13810 66 69 6c 65 2e 20 49 66 20 74 68 69 73 20 68 61  file. If this ha
13820 70 70 65 6e 73 2c 20 72 65 74 75 72 6e 20 6e 6f  ppens, return no
13830 6e 2d 7a 65 72 6f 2e 0a 20 20 2a 2a 0a 20 20 2a  n-zero..  **.  *
13840 2a 20 54 68 65 72 65 20 61 72 65 20 74 77 6f 20  * There are two 
13850 63 6f 70 69 65 73 20 6f 66 20 74 68 65 20 68 65  copies of the he
13860 61 64 65 72 20 61 74 20 74 68 65 20 62 65 67 69  ader at the begi
13870 6e 6e 69 6e 67 20 6f 66 20 74 68 65 20 77 61 6c  nning of the wal
13880 2d 69 6e 64 65 78 2e 0a 20 20 2a 2a 20 57 68 65  -index..  ** Whe
13890 6e 20 72 65 61 64 69 6e 67 2c 20 72 65 61 64 20  n reading, read 
138a0 5b 30 5d 20 66 69 72 73 74 20 74 68 65 6e 20 5b  [0] first then [
138b0 31 5d 2e 20 20 57 72 69 74 65 73 20 61 72 65 20  1].  Writes are 
138c0 69 6e 20 74 68 65 20 72 65 76 65 72 73 65 20 6f  in the reverse o
138d0 72 64 65 72 2e 0a 20 20 2a 2a 20 4d 65 6d 6f 72  rder..  ** Memor
138e0 79 20 62 61 72 72 69 65 72 73 20 61 72 65 20 75  y barriers are u
138f0 73 65 64 20 74 6f 20 70 72 65 76 65 6e 74 20 74  sed to prevent t
13900 68 65 20 63 6f 6d 70 69 6c 65 72 20 6f 72 20 74  he compiler or t
13910 68 65 20 68 61 72 64 77 61 72 65 20 66 72 6f 6d  he hardware from
13920 0a 20 20 2a 2a 20 72 65 6f 72 64 65 72 69 6e 67  .  ** reordering
13930 20 74 68 65 20 72 65 61 64 73 20 61 6e 64 20 77   the reads and w
13940 72 69 74 65 73 2e 0a 20 20 2a 2f 0a 20 20 61 48  rites..  */.  aH
13950 64 72 20 3d 20 77 61 6c 49 6e 64 65 78 48 64 72  dr = walIndexHdr
13960 28 70 57 61 6c 29 3b 0a 20 20 6d 65 6d 63 70 79  (pWal);.  memcpy
13970 28 26 68 31 2c 20 28 76 6f 69 64 20 2a 29 26 61  (&h1, (void *)&a
13980 48 64 72 5b 30 5d 2c 20 73 69 7a 65 6f 66 28 68  Hdr[0], sizeof(h
13990 31 29 29 3b 0a 20 20 77 61 6c 53 68 6d 42 61 72  1));.  walShmBar
139a0 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20 6d 65  rier(pWal);.  me
139b0 6d 63 70 79 28 26 68 32 2c 20 28 76 6f 69 64 20  mcpy(&h2, (void 
139c0 2a 29 26 61 48 64 72 5b 31 5d 2c 20 73 69 7a 65  *)&aHdr[1], size
139d0 6f 66 28 68 32 29 29 3b 0a 0a 20 20 69 66 28 20  of(h2));..  if( 
139e0 6d 65 6d 63 6d 70 28 26 68 31 2c 20 26 68 32 2c  memcmp(&h1, &h2,
139f0 20 73 69 7a 65 6f 66 28 68 31 29 29 21 3d 30 20   sizeof(h1))!=0 
13a00 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b  ){.    return 1;
13a10 20 20 20 2f 2a 20 44 69 72 74 79 20 72 65 61 64     /* Dirty read
13a20 20 2a 2f 0a 20 20 7d 20 20 0a 20 20 69 66 28 20   */.  }  .  if( 
13a30 68 31 2e 69 73 49 6e 69 74 3d 3d 30 20 29 7b 0a  h1.isInit==0 ){.
13a40 20 20 20 20 72 65 74 75 72 6e 20 31 3b 20 20 20      return 1;   
13a50 2f 2a 20 4d 61 6c 66 6f 72 6d 65 64 20 68 65 61  /* Malformed hea
13a60 64 65 72 20 2d 20 70 72 6f 62 61 62 6c 79 20 61  der - probably a
13a70 6c 6c 20 7a 65 72 6f 73 20 2a 2f 0a 20 20 7d 0a  ll zeros */.  }.
13a80 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74    walChecksumByt
13a90 65 73 28 31 2c 20 28 75 38 2a 29 26 68 31 2c 20  es(1, (u8*)&h1, 
13aa0 73 69 7a 65 6f 66 28 68 31 29 2d 73 69 7a 65 6f  sizeof(h1)-sizeo
13ab0 66 28 68 31 2e 61 43 6b 73 75 6d 29 2c 20 30 2c  f(h1.aCksum), 0,
13ac0 20 61 43 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20   aCksum);.  if( 
13ad0 61 43 6b 73 75 6d 5b 30 5d 21 3d 68 31 2e 61 43  aCksum[0]!=h1.aC
13ae0 6b 73 75 6d 5b 30 5d 20 7c 7c 20 61 43 6b 73 75  ksum[0] || aCksu
13af0 6d 5b 31 5d 21 3d 68 31 2e 61 43 6b 73 75 6d 5b  m[1]!=h1.aCksum[
13b00 31 5d 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  1] ){.    return
13b10 20 31 3b 20 20 20 2f 2a 20 43 68 65 63 6b 73 75   1;   /* Checksu
13b20 6d 20 64 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68  m does not match
13b30 20 2a 2f 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6d   */.  }..  if( m
13b40 65 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72  emcmp(&pWal->hdr
13b50 2c 20 26 68 31 2c 20 73 69 7a 65 6f 66 28 57 61  , &h1, sizeof(Wa
13b60 6c 49 6e 64 65 78 48 64 72 29 29 20 29 7b 0a 20  lIndexHdr)) ){. 
13b70 20 20 20 2a 70 43 68 61 6e 67 65 64 20 3d 20 31     *pChanged = 1
13b80 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 57  ;.    memcpy(&pW
13b90 61 6c 2d 3e 68 64 72 2c 20 26 68 31 2c 20 73 69  al->hdr, &h1, si
13ba0 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
13bb0 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a  ));.    pWal->sz
13bc0 50 61 67 65 20 3d 20 28 70 57 61 6c 2d 3e 68 64  Page = (pWal->hd
13bd0 72 2e 73 7a 50 61 67 65 26 30 78 66 65 30 30 29  r.szPage&0xfe00)
13be0 20 2b 20 28 28 70 57 61 6c 2d 3e 68 64 72 2e 73   + ((pWal->hdr.s
13bf0 7a 50 61 67 65 26 30 78 30 30 30 31 29 3c 3c 31  zPage&0x0001)<<1
13c00 36 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73 65  6);.    testcase
13c10 28 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 3c 3d  ( pWal->szPage<=
13c20 33 32 37 36 38 20 29 3b 0a 20 20 20 20 74 65 73  32768 );.    tes
13c30 74 63 61 73 65 28 20 70 57 61 6c 2d 3e 73 7a 50  tcase( pWal->szP
13c40 61 67 65 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20  age>=65536 );.  
13c50 7d 0a 0a 20 20 2f 2a 20 54 68 65 20 68 65 61 64  }..  /* The head
13c60 65 72 20 77 61 73 20 73 75 63 63 65 73 73 66 75  er was successfu
13c70 6c 6c 79 20 72 65 61 64 2e 20 52 65 74 75 72 6e  lly read. Return
13c80 20 7a 65 72 6f 2e 20 2a 2f 0a 20 20 72 65 74 75   zero. */.  retu
13c90 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  rn 0;.}../*.** T
13ca0 68 69 73 20 69 73 20 74 68 65 20 76 61 6c 75 65  his is the value
13cb0 20 74 68 61 74 20 77 61 6c 54 72 79 42 65 67 69   that walTryBegi
13cc0 6e 52 65 61 64 20 72 65 74 75 72 6e 73 20 77 68  nRead returns wh
13cd0 65 6e 20 69 74 20 6e 65 65 64 73 20 74 6f 0a 2a  en it needs to.*
13ce0 2a 20 62 65 20 72 65 74 72 69 65 64 2e 0a 2a 2f  * be retried..*/
13cf0 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 52 45 54  .#define WAL_RET
13d00 52 59 20 20 28 2d 31 29 0a 0a 2f 2a 0a 2a 2a 20  RY  (-1)../*.** 
13d10 52 65 61 64 20 74 68 65 20 77 61 6c 2d 69 6e 64  Read the wal-ind
13d20 65 78 20 68 65 61 64 65 72 20 66 72 6f 6d 20 74  ex header from t
13d30 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 61 6e 64  he wal-index and
13d40 20 69 6e 74 6f 20 70 57 61 6c 2d 3e 68 64 72 2e   into pWal->hdr.
13d50 0a 2a 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 68  .** If the wal-h
13d60 65 61 64 65 72 20 61 70 70 65 61 72 73 20 74 6f  eader appears to
13d70 20 62 65 20 63 6f 72 72 75 70 74 2c 20 74 72 79   be corrupt, try
13d80 20 74 6f 20 72 65 63 6f 6e 73 74 72 75 63 74 20   to reconstruct 
13d90 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78  the.** wal-index
13da0 20 66 72 6f 6d 20 74 68 65 20 57 41 4c 20 62 65   from the WAL be
13db0 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
13dc0 2a 2a 0a 2a 2a 20 53 65 74 20 2a 70 43 68 61 6e  **.** Set *pChan
13dd0 67 65 64 20 74 6f 20 31 20 69 66 20 74 68 65 20  ged to 1 if the 
13de0 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
13df0 20 76 61 6c 75 65 20 69 6e 20 70 57 61 6c 2d 3e   value in pWal->
13e00 68 64 72 20 69 73 0a 2a 2a 20 63 68 61 6e 67 65  hdr is.** change
13e10 64 20 62 79 20 74 68 69 73 20 6f 70 65 72 61 74  d by this operat
13e20 69 6f 6e 2e 20 20 49 66 20 70 57 61 6c 2d 3e 68  ion.  If pWal->h
13e30 64 72 20 69 73 20 75 6e 63 68 61 6e 67 65 64 2c  dr is unchanged,
13e40 20 73 65 74 20 2a 70 43 68 61 6e 67 65 64 0a 2a   set *pChanged.*
13e50 2a 20 74 6f 20 30 2e 0a 2a 2a 0a 2a 2a 20 49 66  * to 0..**.** If
13e60 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
13e70 65 61 64 65 72 20 69 73 20 73 75 63 63 65 73 73  eader is success
13e80 66 75 6c 6c 79 20 72 65 61 64 2c 20 72 65 74 75  fully read, retu
13e90 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 0a 2a  rn SQLITE_OK. .*
13ea0 2a 20 4f 74 68 65 72 77 69 73 65 20 61 6e 20 53  * Otherwise an S
13eb0 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
13ec0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
13ed0 77 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28  walIndexReadHdr(
13ee0 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a  Wal *pWal, int *
13ef0 70 43 68 61 6e 67 65 64 29 7b 0a 20 20 69 6e 74  pChanged){.  int
13f00 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
13f10 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
13f20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
13f30 20 69 6e 74 20 62 61 64 48 64 72 3b 20 20 20 20   int badHdr;    
13f40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13f50 20 2f 2a 20 54 72 75 65 20 69 66 20 61 20 68 65   /* True if a he
13f60 61 64 65 72 20 72 65 61 64 20 66 61 69 6c 65 64  ader read failed
13f70 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75   */.  volatile u
13f80 33 32 20 2a 70 61 67 65 30 3b 20 20 20 20 20 20  32 *page0;      
13f90 20 20 20 20 20 20 2f 2a 20 43 68 75 6e 6b 20 6f        /* Chunk o
13fa0 66 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 74  f wal-index cont
13fb0 61 69 6e 69 6e 67 20 68 65 61 64 65 72 20 2a 2f  aining header */
13fc0 0a 0a 20 20 2f 2a 20 45 6e 73 75 72 65 20 74 68  ..  /* Ensure th
13fd0 61 74 20 70 61 67 65 20 30 20 6f 66 20 74 68 65  at page 0 of the
13fe0 20 77 61 6c 2d 69 6e 64 65 78 20 28 74 68 65 20   wal-index (the 
13ff0 70 61 67 65 20 74 68 61 74 20 63 6f 6e 74 61 69  page that contai
14000 6e 73 20 74 68 65 20 0a 20 20 2a 2a 20 77 61 6c  ns the .  ** wal
14010 2d 69 6e 64 65 78 20 68 65 61 64 65 72 29 20 69  -index header) i
14020 73 20 6d 61 70 70 65 64 2e 20 52 65 74 75 72 6e  s mapped. Return
14030 20 65 61 72 6c 79 20 69 66 20 61 6e 20 65 72 72   early if an err
14040 6f 72 20 6f 63 63 75 72 73 20 68 65 72 65 2e 0a  or occurs here..
14050 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
14060 43 68 61 6e 67 65 64 20 29 3b 0a 20 20 72 63 20  Changed );.  rc 
14070 3d 20 77 61 6c 49 6e 64 65 78 50 61 67 65 28 70  = walIndexPage(p
14080 57 61 6c 2c 20 30 2c 20 26 70 61 67 65 30 29 3b  Wal, 0, &page0);
14090 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
140a0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 61 73 73 65  E_OK ){.    asse
140b0 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 52  rt( rc!=SQLITE_R
140c0 45 41 44 4f 4e 4c 59 20 29 3b 20 2f 2a 20 52 45  EADONLY ); /* RE
140d0 41 44 4f 4e 4c 59 20 63 68 61 6e 67 65 64 20 74  ADONLY changed t
140e0 6f 20 4f 4b 20 69 6e 20 77 61 6c 49 6e 64 65 78  o OK in walIndex
140f0 50 61 67 65 20 2a 2f 0a 20 20 20 20 69 66 28 20  Page */.    if( 
14100 72 63 3d 3d 53 51 4c 49 54 45 5f 52 45 41 44 4f  rc==SQLITE_READO
14110 4e 4c 59 5f 43 41 4e 54 49 4e 49 54 20 29 7b 0a  NLY_CANTINIT ){.
14120 20 20 20 20 20 20 2f 2a 20 54 68 65 20 53 51 4c        /* The SQL
14130 49 54 45 5f 52 45 41 44 4f 4e 4c 59 5f 43 41 4e  ITE_READONLY_CAN
14140 54 49 4e 49 54 20 72 65 74 75 72 6e 20 6d 65 61  TINIT return mea
14150 6e 73 20 74 68 61 74 20 74 68 65 20 73 68 61 72  ns that the shar
14160 65 64 2d 6d 65 6d 6f 72 79 0a 20 20 20 20 20 20  ed-memory.      
14170 2a 2a 20 77 61 73 20 6f 70 65 6e 61 62 6c 65 20  ** was openable 
14180 62 75 74 20 69 73 20 6e 6f 74 20 77 72 69 74 61  but is not writa
14190 62 6c 65 2c 20 61 6e 64 20 74 68 69 73 20 74 68  ble, and this th
141a0 72 65 61 64 20 69 73 20 75 6e 61 62 6c 65 20 74  read is unable t
141b0 6f 0a 20 20 20 20 20 20 2a 2a 20 63 6f 6e 66 69  o.      ** confi
141c0 72 6d 20 74 68 61 74 20 61 6e 6f 74 68 65 72 20  rm that another 
141d0 77 72 69 74 65 2d 63 61 70 61 62 6c 65 20 63 6f  write-capable co
141e0 6e 6e 65 63 74 69 6f 6e 20 68 61 73 20 74 68 65  nnection has the
141f0 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 0a 20   shared-memory. 
14200 20 20 20 20 20 2a 2a 20 6f 70 65 6e 2c 20 61 6e       ** open, an
14210 64 20 68 65 6e 63 65 20 74 68 65 20 63 6f 6e 74  d hence the cont
14220 65 6e 74 20 6f 66 20 74 68 65 20 73 68 61 72 65  ent of the share
14230 64 2d 6d 65 6d 6f 72 79 20 69 73 20 75 6e 72 65  d-memory is unre
14240 6c 69 61 62 6c 65 2c 0a 20 20 20 20 20 20 2a 2a  liable,.      **
14250 20 73 69 6e 63 65 20 74 68 65 20 73 68 61 72 65   since the share
14260 64 2d 6d 65 6d 6f 72 79 20 6d 69 67 68 74 20 62  d-memory might b
14270 65 20 69 6e 63 6f 6e 73 69 73 74 65 6e 74 20 77  e inconsistent w
14280 69 74 68 20 74 68 65 20 57 41 4c 20 66 69 6c 65  ith the WAL file
14290 0a 20 20 20 20 20 20 2a 2a 20 61 6e 64 20 74 68  .      ** and th
142a0 65 72 65 20 69 73 20 6e 6f 20 77 72 69 74 65 72  ere is no writer
142b0 20 6f 6e 20 68 61 6e 64 20 74 6f 20 66 69 78 20   on hand to fix 
142c0 69 74 2e 20 2a 2f 0a 20 20 20 20 20 20 61 73 73  it. */.      ass
142d0 65 72 74 28 20 70 61 67 65 30 3d 3d 30 20 29 3b  ert( page0==0 );
142e0 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
142f0 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d  Wal->writeLock==
14300 30 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72  0 );.      asser
14310 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4f 6e 6c  t( pWal->readOnl
14320 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52 44 4f 4e  y & WAL_SHM_RDON
14330 4c 59 20 29 3b 0a 20 20 20 20 20 20 70 57 61 6c  LY );.      pWal
14340 2d 3e 62 53 68 6d 55 6e 72 65 6c 69 61 62 6c 65  ->bShmUnreliable
14350 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 57 61 6c   = 1;.      pWal
14360 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20  ->exclusiveMode 
14370 3d 20 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59  = WAL_HEAPMEMORY
14380 5f 4d 4f 44 45 3b 0a 20 20 20 20 20 20 2a 70 43  _MODE;.      *pC
14390 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20 20 20  hanged = 1;.    
143a0 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 65 74  }else{.      ret
143b0 75 72 6e 20 72 63 3b 20 2f 2a 20 41 6e 79 20 6f  urn rc; /* Any o
143c0 74 68 65 72 20 6e 6f 6e 2d 4f 4b 20 72 65 74 75  ther non-OK retu
143d0 72 6e 20 69 73 20 6a 75 73 74 20 61 6e 20 65 72  rn is just an er
143e0 72 6f 72 20 2a 2f 0a 20 20 20 20 7d 0a 20 20 7d  ror */.    }.  }
143f0 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 70 61 67  else{.    /* pag
14400 65 30 20 63 61 6e 20 62 65 20 4e 55 4c 4c 20 69  e0 can be NULL i
14410 66 20 74 68 65 20 53 48 4d 20 69 73 20 7a 65 72  f the SHM is zer
14420 6f 20 62 79 74 65 73 20 69 6e 20 73 69 7a 65 20  o bytes in size 
14430 61 6e 64 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c  and pWal->writeL
14440 6f 63 6b 0a 20 20 20 20 2a 2a 20 69 73 20 7a 65  ock.    ** is ze
14450 72 6f 2c 20 77 68 69 63 68 20 70 72 65 76 65 6e  ro, which preven
14460 74 73 20 74 68 65 20 53 48 4d 20 66 72 6f 6d 20  ts the SHM from 
14470 67 72 6f 77 69 6e 67 20 2a 2f 0a 20 20 20 20 74  growing */.    t
14480 65 73 74 63 61 73 65 28 20 70 61 67 65 30 21 3d  estcase( page0!=
14490 30 20 29 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72  0 );.  }.  asser
144a0 74 28 20 70 61 67 65 30 21 3d 30 20 7c 7c 20 70  t( page0!=0 || p
144b0 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d  Wal->writeLock==
144c0 30 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68  0 );..  /* If th
144d0 65 20 66 69 72 73 74 20 70 61 67 65 20 6f 66 20  e first page of 
144e0 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 61  the wal-index ha
144f0 73 20 62 65 65 6e 20 6d 61 70 70 65 64 2c 20 74  s been mapped, t
14500 72 79 20 74 6f 20 72 65 61 64 20 74 68 65 0a 20  ry to read the. 
14510 20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65   ** wal-index he
14520 61 64 65 72 20 69 6d 6d 65 64 69 61 74 65 6c 79  ader immediately
14530 2c 20 77 69 74 68 6f 75 74 20 68 6f 6c 64 69 6e  , without holdin
14540 67 20 61 6e 79 20 6c 6f 63 6b 2e 20 54 68 69 73  g any lock. This
14550 20 75 73 75 61 6c 6c 79 0a 20 20 2a 2a 20 77 6f   usually.  ** wo
14560 72 6b 73 2c 20 62 75 74 20 6d 61 79 20 66 61 69  rks, but may fai
14570 6c 20 69 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  l if the wal-ind
14580 65 78 20 68 65 61 64 65 72 20 69 73 20 63 6f 72  ex header is cor
14590 72 75 70 74 20 6f 72 20 63 75 72 72 65 6e 74 6c  rupt or currentl
145a0 79 20 0a 20 20 2a 2a 20 62 65 69 6e 67 20 6d 6f  y .  ** being mo
145b0 64 69 66 69 65 64 20 62 79 20 61 6e 6f 74 68 65  dified by anothe
145c0 72 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63  r thread or proc
145d0 65 73 73 2e 0a 20 20 2a 2f 0a 20 20 62 61 64 48  ess..  */.  badH
145e0 64 72 20 3d 20 28 70 61 67 65 30 20 3f 20 77 61  dr = (page0 ? wa
145f0 6c 49 6e 64 65 78 54 72 79 48 64 72 28 70 57 61  lIndexTryHdr(pWa
14600 6c 2c 20 70 43 68 61 6e 67 65 64 29 20 3a 20 31  l, pChanged) : 1
14610 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20  );..  /* If the 
14620 66 69 72 73 74 20 61 74 74 65 6d 70 74 20 66 61  first attempt fa
14630 69 6c 65 64 2c 20 69 74 20 6d 69 67 68 74 20 68  iled, it might h
14640 61 76 65 20 62 65 65 6e 20 64 75 65 20 74 6f 20  ave been due to 
14650 61 20 72 61 63 65 0a 20 20 2a 2a 20 77 69 74 68  a race.  ** with
14660 20 61 20 77 72 69 74 65 72 2e 20 20 53 6f 20 67   a writer.  So g
14670 65 74 20 61 20 57 52 49 54 45 20 6c 6f 63 6b 20  et a WRITE lock 
14680 61 6e 64 20 74 72 79 20 61 67 61 69 6e 2e 0a 20  and try again.. 
14690 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 62 61   */.  assert( ba
146a0 64 48 64 72 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d  dHdr==0 || pWal-
146b0 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b  >writeLock==0 );
146c0 0a 20 20 69 66 28 20 62 61 64 48 64 72 20 29 7b  .  if( badHdr ){
146d0 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 62  .    if( pWal->b
146e0 53 68 6d 55 6e 72 65 6c 69 61 62 6c 65 3d 3d 30  ShmUnreliable==0
146f0 20 26 26 20 28 70 57 61 6c 2d 3e 72 65 61 64 4f   && (pWal->readO
14700 6e 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52 44  nly & WAL_SHM_RD
14710 4f 4e 4c 59 29 20 29 7b 0a 20 20 20 20 20 20 69  ONLY) ){.      i
14720 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72  f( SQLITE_OK==(r
14730 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65  c = walLockShare
14740 64 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54  d(pWal, WAL_WRIT
14750 45 5f 4c 4f 43 4b 29 29 20 29 7b 0a 20 20 20 20  E_LOCK)) ){.    
14760 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61      walUnlockSha
14770 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52  red(pWal, WAL_WR
14780 49 54 45 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 20  ITE_LOCK);.     
14790 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 52     rc = SQLITE_R
147a0 45 41 44 4f 4e 4c 59 5f 52 45 43 4f 56 45 52 59  EADONLY_RECOVERY
147b0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65  ;.      }.    }e
147c0 6c 73 65 20 69 66 28 20 53 51 4c 49 54 45 5f 4f  lse if( SQLITE_O
147d0 4b 3d 3d 28 72 63 20 3d 20 77 61 6c 4c 6f 63 6b  K==(rc = walLock
147e0 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
147f0 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20  WAL_WRITE_LOCK, 
14800 31 29 29 20 29 7b 0a 20 20 20 20 20 20 70 57 61  1)) ){.      pWa
14810 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 31  l->writeLock = 1
14820 3b 0a 20 20 20 20 20 20 69 66 28 20 53 51 4c 49  ;.      if( SQLI
14830 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c  TE_OK==(rc = wal
14840 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20  IndexPage(pWal, 
14850 30 2c 20 26 70 61 67 65 30 29 29 20 29 7b 0a 20  0, &page0)) ){. 
14860 20 20 20 20 20 20 20 62 61 64 48 64 72 20 3d 20         badHdr = 
14870 77 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28 70  walIndexTryHdr(p
14880 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b 0a  Wal, pChanged);.
14890 20 20 20 20 20 20 20 20 69 66 28 20 62 61 64 48          if( badH
148a0 64 72 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  dr ){.          
148b0 2f 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 69 6e  /* If the wal-in
148c0 64 65 78 20 68 65 61 64 65 72 20 69 73 20 73 74  dex header is st
148d0 69 6c 6c 20 6d 61 6c 66 6f 72 6d 65 64 20 65 76  ill malformed ev
148e0 65 6e 20 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67  en while holding
148f0 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 61 20  .          ** a 
14900 57 52 49 54 45 20 6c 6f 63 6b 2c 20 69 74 20 63  WRITE lock, it c
14910 61 6e 20 6f 6e 6c 79 20 6d 65 61 6e 20 74 68 61  an only mean tha
14920 74 20 74 68 65 20 68 65 61 64 65 72 20 69 73 20  t the header is 
14930 63 6f 72 72 75 70 74 65 64 20 61 6e 64 0a 20 20  corrupted and.  
14940 20 20 20 20 20 20 20 20 2a 2a 20 6e 65 65 64 73          ** needs
14950 20 74 6f 20 62 65 20 72 65 63 6f 6e 73 74 72 75   to be reconstru
14960 63 74 65 64 2e 20 20 53 6f 20 72 75 6e 20 72 65  cted.  So run re
14970 63 6f 76 65 72 79 20 74 6f 20 64 6f 20 65 78 61  covery to do exa
14980 63 74 6c 79 20 74 68 61 74 2e 0a 20 20 20 20 20  ctly that..     
14990 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20       */.        
149a0 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52    rc = walIndexR
149b0 65 63 6f 76 65 72 28 70 57 61 6c 29 3b 0a 20 20  ecover(pWal);.  
149c0 20 20 20 20 20 20 20 20 2a 70 43 68 61 6e 67 65          *pChange
149d0 64 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d  d = 1;.        }
149e0 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70  .      }.      p
149f0 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d  Wal->writeLock =
14a00 20 30 3b 0a 20 20 20 20 20 20 77 61 6c 55 6e 6c   0;.      walUnl
14a10 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
14a20 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43  l, WAL_WRITE_LOC
14a30 4b 2c 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  K, 1);.    }.  }
14a40 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 68 65  ..  /* If the he
14a50 61 64 65 72 20 69 73 20 72 65 61 64 20 73 75 63  ader is read suc
14a60 63 65 73 73 66 75 6c 6c 79 2c 20 63 68 65 63 6b  cessfully, check
14a70 20 74 68 65 20 76 65 72 73 69 6f 6e 20 6e 75 6d   the version num
14a80 62 65 72 20 74 6f 20 6d 61 6b 65 0a 20 20 2a 2a  ber to make.  **
14a90 20 73 75 72 65 20 74 68 65 20 77 61 6c 2d 69 6e   sure the wal-in
14aa0 64 65 78 20 77 61 73 20 6e 6f 74 20 63 6f 6e 73  dex was not cons
14ab0 74 72 75 63 74 65 64 20 77 69 74 68 20 73 6f 6d  tructed with som
14ac0 65 20 66 75 74 75 72 65 20 66 6f 72 6d 61 74 20  e future format 
14ad0 74 68 61 74 0a 20 20 2a 2a 20 74 68 69 73 20 76  that.  ** this v
14ae0 65 72 73 69 6f 6e 20 6f 66 20 53 51 4c 69 74 65  ersion of SQLite
14af0 20 63 61 6e 6e 6f 74 20 75 6e 64 65 72 73 74 61   cannot understa
14b00 6e 64 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 62  nd..  */.  if( b
14b10 61 64 48 64 72 3d 3d 30 20 26 26 20 70 57 61 6c  adHdr==0 && pWal
14b20 2d 3e 68 64 72 2e 69 56 65 72 73 69 6f 6e 21 3d  ->hdr.iVersion!=
14b30 57 41 4c 49 4e 44 45 58 5f 4d 41 58 5f 56 45 52  WALINDEX_MAX_VER
14b40 53 49 4f 4e 20 29 7b 0a 20 20 20 20 72 63 20 3d  SION ){.    rc =
14b50 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e   SQLITE_CANTOPEN
14b60 5f 42 4b 50 54 3b 0a 20 20 7d 0a 20 20 69 66 28  _BKPT;.  }.  if(
14b70 20 70 57 61 6c 2d 3e 62 53 68 6d 55 6e 72 65 6c   pWal->bShmUnrel
14b80 69 61 62 6c 65 20 29 7b 0a 20 20 20 20 69 66 28  iable ){.    if(
14b90 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
14ba0 7b 0a 20 20 20 20 20 20 77 61 6c 49 6e 64 65 78  {.      walIndex
14bb0 43 6c 6f 73 65 28 70 57 61 6c 2c 20 30 29 3b 0a  Close(pWal, 0);.
14bc0 20 20 20 20 20 20 70 57 61 6c 2d 3e 62 53 68 6d        pWal->bShm
14bd0 55 6e 72 65 6c 69 61 62 6c 65 20 3d 20 30 3b 0a  Unreliable = 0;.
14be0 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 57        assert( pW
14bf0 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20 26 26  al->nWiData>0 &&
14c00 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
14c10 30 5d 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 2f  0]==0 );.      /
14c20 2a 20 77 61 6c 49 6e 64 65 78 52 65 63 6f 76 65  * walIndexRecove
14c30 72 28 29 20 6d 69 67 68 74 20 68 61 76 65 20 72  r() might have r
14c40 65 74 75 72 6e 65 64 20 53 48 4f 52 54 5f 52 45  eturned SHORT_RE
14c50 41 44 20 69 66 20 61 20 63 6f 6e 63 75 72 72 65  AD if a concurre
14c60 6e 74 0a 20 20 20 20 20 20 2a 2a 20 77 72 69 74  nt.      ** writ
14c70 65 72 20 74 72 75 6e 63 61 74 65 64 20 74 68 65  er truncated the
14c80 20 57 41 4c 20 6f 75 74 20 66 72 6f 6d 20 75 6e   WAL out from un
14c90 64 65 72 20 69 74 2e 20 20 49 66 20 74 68 61 74  der it.  If that
14ca0 20 68 61 70 70 65 6e 73 2c 20 69 74 0a 20 20 20   happens, it.   
14cb0 20 20 20 2a 2a 20 69 6e 64 69 63 61 74 65 73 20     ** indicates 
14cc0 74 68 61 74 20 61 20 77 72 69 74 65 72 20 68 61  that a writer ha
14cd0 73 20 66 69 78 65 64 20 74 68 65 20 53 48 4d 20  s fixed the SHM 
14ce0 66 69 6c 65 20 66 6f 72 20 75 73 2c 20 73 6f 20  file for us, so 
14cf0 72 65 74 72 79 20 2a 2f 0a 20 20 20 20 20 20 69  retry */.      i
14d00 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 49 4f  f( rc==SQLITE_IO
14d10 45 52 52 5f 53 48 4f 52 54 5f 52 45 41 44 20 29  ERR_SHORT_READ )
14d20 20 72 63 20 3d 20 57 41 4c 5f 52 45 54 52 59 3b   rc = WAL_RETRY;
14d30 0a 20 20 20 20 7d 0a 20 20 20 20 70 57 61 6c 2d  .    }.    pWal-
14d40 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d  >exclusiveMode =
14d50 20 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45   WAL_NORMAL_MODE
14d60 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
14d70 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65  rc;.}../*.** Ope
14d80 6e 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  n a transaction 
14d90 69 6e 20 61 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  in a connection 
14da0 77 68 65 72 65 20 74 68 65 20 73 68 61 72 65 64  where the shared
14db0 2d 6d 65 6d 6f 72 79 20 69 73 20 72 65 61 64 2d  -memory is read-
14dc0 6f 6e 6c 79 0a 2a 2a 20 61 6e 64 20 77 68 65 72  only.** and wher
14dd0 65 20 77 65 20 63 61 6e 6e 6f 74 20 76 65 72 69  e we cannot veri
14de0 66 79 20 74 68 61 74 20 74 68 65 72 65 20 69 73  fy that there is
14df0 20 61 20 73 65 70 61 72 61 74 65 20 77 72 69 74   a separate writ
14e00 65 2d 63 61 70 61 62 6c 65 20 63 6f 6e 6e 65 63  e-capable connec
14e10 74 69 6f 6e 0a 2a 2a 20 6f 6e 20 68 61 6e 64 20  tion.** on hand 
14e20 74 6f 20 6b 65 65 70 20 74 68 65 20 73 68 61 72  to keep the shar
14e30 65 64 2d 6d 65 6d 6f 72 79 20 75 70 2d 74 6f 2d  ed-memory up-to-
14e40 64 61 74 65 20 77 69 74 68 20 74 68 65 20 57 41  date with the WA
14e50 4c 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68  L file..**.** Th
14e60 69 73 20 63 61 6e 20 68 61 70 70 65 6e 2c 20 66  is can happen, f
14e70 6f 72 20 65 78 61 6d 70 6c 65 2c 20 77 68 65 6e  or example, when
14e80 20 74 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f   the shared-memo
14e90 72 79 20 69 73 20 69 6d 70 6c 65 6d 65 6e 74 65  ry is implemente
14ea0 64 20 62 79 0a 2a 2a 20 6d 65 6d 6f 72 79 2d 6d  d by.** memory-m
14eb0 61 70 70 69 6e 67 20 61 20 2a 2d 73 68 6d 20 66  apping a *-shm f
14ec0 69 6c 65 2c 20 77 68 65 72 65 20 61 20 70 72 69  ile, where a pri
14ed0 6f 72 20 77 72 69 74 65 72 20 68 61 73 20 73 68  or writer has sh
14ee0 75 74 20 64 6f 77 6e 20 61 6e 64 0a 2a 2a 20 6c  ut down and.** l
14ef0 65 66 74 20 74 68 65 20 2a 2d 73 68 6d 20 66 69  eft the *-shm fi
14f00 6c 65 20 6f 6e 20 64 69 73 6b 2c 20 61 6e 64 20  le on disk, and 
14f10 6e 6f 77 20 74 68 65 20 70 72 65 73 65 6e 74 20  now the present 
14f20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20 74 72  connection is tr
14f30 79 69 6e 67 0a 2a 2a 20 74 6f 20 75 73 65 20 74  ying.** to use t
14f40 68 61 74 20 64 61 74 61 62 61 73 65 20 62 75 74  hat database but
14f50 20 6c 61 63 6b 73 20 77 72 69 74 65 20 70 65 72   lacks write per
14f60 6d 69 73 73 69 6f 6e 20 6f 6e 20 74 68 65 20 2a  mission on the *
14f70 2d 73 68 6d 20 66 69 6c 65 2e 0a 2a 2a 20 4f 74  -shm file..** Ot
14f80 68 65 72 20 73 63 65 6e 61 72 69 6f 73 20 61 72  her scenarios ar
14f90 65 20 61 6c 73 6f 20 70 6f 73 73 69 62 6c 65 2c  e also possible,
14fa0 20 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68   depending on th
14fb0 65 20 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61  e VFS implementa
14fc0 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50 72 65 63  tion..**.** Prec
14fd0 6f 6e 64 69 74 69 6f 6e 3a 0a 2a 2a 0a 2a 2a 20  ondition:.**.** 
14fe0 20 20 20 54 68 65 20 2a 2d 77 61 6c 20 66 69 6c     The *-wal fil
14ff0 65 20 68 61 73 20 62 65 65 6e 20 72 65 61 64 20  e has been read 
15000 61 6e 64 20 61 6e 20 61 70 70 72 6f 70 72 69 61  and an appropria
15010 74 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 61 73  te wal-index has
15020 20 62 65 65 6e 0a 2a 2a 20 20 20 20 63 6f 6e 73   been.**    cons
15030 74 72 75 63 74 65 64 20 69 6e 20 70 57 61 6c 2d  tructed in pWal-
15040 3e 61 70 57 69 44 61 74 61 5b 5d 20 75 73 69 6e  >apWiData[] usin
15050 67 20 68 65 61 70 20 6d 65 6d 6f 72 79 20 69 6e  g heap memory in
15060 73 74 65 61 64 20 6f 66 20 73 68 61 72 65 64 0a  stead of shared.
15070 2a 2a 20 20 20 20 6d 65 6d 6f 72 79 2e 20 0a 2a  **    memory. .*
15080 2a 0a 2a 2a 20 49 66 20 74 68 69 73 20 66 75 6e  *.** If this fun
15090 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 53 51  ction returns SQ
150a0 4c 49 54 45 5f 4f 4b 2c 20 74 68 65 6e 20 74 68  LITE_OK, then th
150b0 65 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  e read transacti
150c0 6f 6e 20 68 61 73 0a 2a 2a 20 62 65 65 6e 20 73  on has.** been s
150d0 75 63 63 65 73 73 66 75 6c 6c 79 20 6f 70 65 6e  uccessfully open
150e0 65 64 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65  ed. In this case
150f0 20 6f 75 74 70 75 74 20 76 61 72 69 61 62 6c 65   output variable
15100 20 28 2a 70 43 68 61 6e 67 65 64 29 20 0a 2a 2a   (*pChanged) .**
15110 20 69 73 20 73 65 74 20 74 6f 20 74 72 75 65 20   is set to true 
15120 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
15130 20 69 66 20 74 68 65 20 63 61 6c 6c 65 72 20 73   if the caller s
15140 68 6f 75 6c 64 20 64 69 73 63 61 72 64 20 74 68  hould discard th
15150 65 0a 2a 2a 20 63 6f 6e 74 65 6e 74 73 20 6f 66  e.** contents of
15160 20 74 68 65 20 70 61 67 65 20 63 61 63 68 65 20   the page cache 
15170 62 65 66 6f 72 65 20 70 72 6f 63 65 65 64 69 6e  before proceedin
15180 67 2e 20 4f 72 2c 20 69 66 20 69 74 20 72 65 74  g. Or, if it ret
15190 75 72 6e 73 20 0a 2a 2a 20 57 41 4c 5f 52 45 54  urns .** WAL_RET
151a0 52 59 2c 20 74 68 65 6e 20 74 68 65 20 68 65 61  RY, then the hea
151b0 70 20 6d 65 6d 6f 72 79 20 77 61 6c 2d 69 6e 64  p memory wal-ind
151c0 65 78 20 68 61 73 20 62 65 65 6e 20 64 69 73 63  ex has been disc
151d0 61 72 64 65 64 20 61 6e 64 20 0a 2a 2a 20 74 68  arded and .** th
151e0 65 20 63 61 6c 6c 65 72 20 73 68 6f 75 6c 64 20  e caller should 
151f0 72 65 74 72 79 20 6f 70 65 6e 69 6e 67 20 74 68  retry opening th
15200 65 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  e read transacti
15210 6f 6e 20 66 72 6f 6d 20 74 68 65 20 0a 2a 2a 20  on from the .** 
15220 62 65 67 69 6e 6e 69 6e 67 20 28 69 6e 63 6c 75  beginning (inclu
15230 64 69 6e 67 20 61 74 74 65 6d 70 74 69 6e 67 20  ding attempting 
15240 74 6f 20 6d 61 70 20 74 68 65 20 2a 2d 73 68 6d  to map the *-shm
15250 20 66 69 6c 65 29 2e 20 0a 2a 2a 0a 2a 2a 20 49   file). .**.** I
15260 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
15270 73 2c 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  s, an SQLite err
15280 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  or code is retur
15290 6e 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ned..*/.static i
152a0 6e 74 20 77 61 6c 42 65 67 69 6e 53 68 6d 55 6e  nt walBeginShmUn
152b0 72 65 6c 69 61 62 6c 65 28 57 61 6c 20 2a 70 57  reliable(Wal *pW
152c0 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e 67 65  al, int *pChange
152d0 64 29 7b 0a 20 20 69 36 34 20 73 7a 57 61 6c 3b  d){.  i64 szWal;
152e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
152f0 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
15300 20 77 61 6c 20 66 69 6c 65 20 6f 6e 20 64 69 73   wal file on dis
15310 6b 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  k in bytes */.  
15320 69 36 34 20 69 4f 66 66 73 65 74 3b 20 20 20 20  i64 iOffset;    
15330 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15340 2f 2a 20 43 75 72 72 65 6e 74 20 6f 66 66 73 65  /* Current offse
15350 74 20 77 68 65 6e 20 72 65 61 64 69 6e 67 20 77  t when reading w
15360 61 6c 20 66 69 6c 65 20 2a 2f 0a 20 20 75 38 20  al file */.  u8 
15370 61 42 75 66 5b 57 41 4c 5f 48 44 52 53 49 5a 45  aBuf[WAL_HDRSIZE
15380 5d 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ];           /* 
15390 42 75 66 66 65 72 20 74 6f 20 6c 6f 61 64 20 57  Buffer to load W
153a0 41 4c 20 68 65 61 64 65 72 20 69 6e 74 6f 20 2a  AL header into *
153b0 2f 0a 20 20 75 38 20 2a 61 46 72 61 6d 65 20 3d  /.  u8 *aFrame =
153c0 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
153d0 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f 63 27 64 20      /* Malloc'd 
153e0 62 75 66 66 65 72 20 74 6f 20 6c 6f 61 64 20 65  buffer to load e
153f0 6e 74 69 72 65 20 66 72 61 6d 65 20 2a 2f 0a 20  ntire frame */. 
15400 20 69 6e 74 20 73 7a 46 72 61 6d 65 3b 20 20 20   int szFrame;   
15410 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15420 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
15430 74 65 73 20 69 6e 20 62 75 66 66 65 72 20 61 46  tes in buffer aF
15440 72 61 6d 65 5b 5d 20 2a 2f 0a 20 20 75 38 20 2a  rame[] */.  u8 *
15450 61 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20  aData;          
15460 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
15470 6f 69 6e 74 65 72 20 74 6f 20 64 61 74 61 20 70  ointer to data p
15480 61 72 74 20 6f 66 20 61 46 72 61 6d 65 20 62 75  art of aFrame bu
15490 66 66 65 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  ffer */.  volati
154a0 6c 65 20 76 6f 69 64 20 2a 70 44 75 6d 6d 79 3b  le void *pDummy;
154b0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 75 6d            /* Dum
154c0 6d 79 20 61 72 67 75 6d 65 6e 74 20 66 6f 72 20  my argument for 
154d0 78 53 68 6d 4d 61 70 20 2a 2f 0a 20 20 69 6e 74  xShmMap */.  int
154e0 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
154f0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
15500 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
15510 20 75 33 32 20 61 53 61 76 65 43 6b 73 75 6d 5b   u32 aSaveCksum[
15520 32 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  2];             
15530 20 2f 2a 20 53 61 76 65 64 20 63 6f 70 79 20 6f   /* Saved copy o
15540 66 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61  f pWal->hdr.aFra
15550 6d 65 43 6b 73 75 6d 20 2a 2f 0a 0a 20 20 61 73  meCksum */..  as
15560 73 65 72 74 28 20 70 57 61 6c 2d 3e 62 53 68 6d  sert( pWal->bShm
15570 55 6e 72 65 6c 69 61 62 6c 65 20 29 3b 0a 20 20  Unreliable );.  
15580 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65  assert( pWal->re
15590 61 64 4f 6e 6c 79 20 26 20 57 41 4c 5f 53 48 4d  adOnly & WAL_SHM
155a0 5f 52 44 4f 4e 4c 59 20 29 3b 0a 20 20 61 73 73  _RDONLY );.  ass
155b0 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
155c0 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70  ta>0 && pWal->ap
155d0 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 0a 20 20  WiData[0] );..  
155e0 2f 2a 20 54 61 6b 65 20 57 41 4c 5f 52 45 41 44  /* Take WAL_READ
155f0 5f 4c 4f 43 4b 28 30 29 2e 20 54 68 69 73 20 68  _LOCK(0). This h
15600 61 73 20 74 68 65 20 65 66 66 65 63 74 20 6f 66  as the effect of
15610 20 70 72 65 76 65 6e 74 69 6e 67 20 61 6e 79 0a   preventing any.
15620 20 20 2a 2a 20 77 72 69 74 65 72 73 20 66 72 6f    ** writers fro
15630 6d 20 72 75 6e 6e 69 6e 67 20 61 20 63 68 65 63  m running a chec
15640 6b 70 6f 69 6e 74 2c 20 62 75 74 20 64 6f 65 73  kpoint, but does
15650 20 6e 6f 74 20 73 74 6f 70 20 74 68 65 6d 0a 20   not stop them. 
15660 20 2a 2a 20 66 72 6f 6d 20 72 75 6e 6e 69 6e 67   ** from running
15670 20 72 65 63 6f 76 65 72 79 2e 20 20 2a 2f 0a 20   recovery.  */. 
15680 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61   rc = walLockSha
15690 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
156a0 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 69  AD_LOCK(0));.  i
156b0 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
156c0 20 29 7b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d   ){.    if( rc==
156d0 53 51 4c 49 54 45 5f 42 55 53 59 20 29 20 72 63  SQLITE_BUSY ) rc
156e0 20 3d 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20   = WAL_RETRY;.  
156f0 20 20 67 6f 74 6f 20 62 65 67 69 6e 5f 75 6e 72    goto begin_unr
15700 65 6c 69 61 62 6c 65 5f 73 68 6d 5f 6f 75 74 3b  eliable_shm_out;
15710 0a 20 20 7d 0a 20 20 70 57 61 6c 2d 3e 72 65 61  .  }.  pWal->rea
15720 64 4c 6f 63 6b 20 3d 20 30 3b 0a 0a 20 20 2f 2a  dLock = 0;..  /*
15730 20 43 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66   Check to see if
15740 20 61 20 73 65 70 61 72 61 74 65 20 77 72 69 74   a separate writ
15750 65 72 20 68 61 73 20 61 74 74 61 63 68 65 64 20  er has attached 
15760 74 6f 20 74 68 65 20 73 68 61 72 65 64 2d 6d 65  to the shared-me
15770 6d 6f 72 79 20 61 72 65 61 2c 0a 20 20 2a 2a 20  mory area,.  ** 
15780 74 68 75 73 20 6d 61 6b 69 6e 67 20 74 68 65 20  thus making the 
15790 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20 22 72  shared-memory "r
157a0 65 6c 69 61 62 6c 65 22 20 61 67 61 69 6e 2e 20  eliable" again. 
157b0 20 44 6f 20 74 68 69 73 20 62 79 20 69 6e 76 6f   Do this by invo
157c0 6b 69 6e 67 0a 20 20 2a 2a 20 74 68 65 20 78 53  king.  ** the xS
157d0 68 6d 4d 61 70 28 29 20 72 6f 75 74 69 6e 65 20  hmMap() routine 
157e0 6f 66 20 74 68 65 20 56 46 53 20 61 6e 64 20 6c  of the VFS and l
157f0 6f 6f 6b 69 6e 67 20 74 6f 20 73 65 65 20 69 66  ooking to see if
15800 20 74 68 65 20 72 65 74 75 72 6e 0a 20 20 2a 2a   the return.  **
15810 20 69 73 20 53 51 4c 49 54 45 5f 52 45 41 44 4f   is SQLITE_READO
15820 4e 4c 59 20 69 6e 73 74 65 61 64 20 6f 66 20 53  NLY instead of S
15830 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 5f 43  QLITE_READONLY_C
15840 41 4e 54 49 4e 49 54 2e 0a 20 20 2a 2a 0a 20 20  ANTINIT..  **.  
15850 2a 2a 20 49 66 20 74 68 65 20 73 68 61 72 65 64  ** If the shared
15860 2d 6d 65 6d 6f 72 79 20 69 73 20 6e 6f 77 20 22  -memory is now "
15870 72 65 6c 69 61 62 6c 65 22 20 72 65 74 75 72 6e  reliable" return
15880 20 57 41 4c 5f 52 45 54 52 59 2c 20 77 68 69 63   WAL_RETRY, whic
15890 68 20 77 69 6c 6c 0a 20 20 2a 2a 20 63 61 75 73  h will.  ** caus
158a0 65 20 74 68 65 20 68 65 61 70 2d 6d 65 6d 6f 72  e the heap-memor
158b0 79 20 57 41 4c 2d 69 6e 64 65 78 20 74 6f 20 62  y WAL-index to b
158c0 65 20 64 69 73 63 61 72 64 65 64 20 61 6e 64 20  e discarded and 
158d0 74 68 65 20 61 63 74 75 61 6c 0a 20 20 2a 2a 20  the actual.  ** 
158e0 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 20 74 6f  shared memory to
158f0 20 62 65 20 75 73 65 64 20 69 6e 20 69 74 73 20   be used in its 
15900 70 6c 61 63 65 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  place..  **.  **
15910 20 54 68 69 73 20 73 74 65 70 20 69 73 20 69 6d   This step is im
15920 70 6f 72 74 61 6e 74 20 62 65 63 61 75 73 65 2c  portant because,
15930 20 65 76 65 6e 20 74 68 6f 75 67 68 20 74 68 69   even though thi
15940 73 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20  s connection is 
15950 68 6f 6c 64 69 6e 67 0a 20 20 2a 2a 20 74 68 65  holding.  ** the
15960 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
15970 29 20 77 68 69 63 68 20 70 72 65 76 65 6e 74 73  ) which prevents
15980 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c 20 61   a checkpoint, a
15990 20 77 72 69 74 65 72 20 6d 69 67 68 74 0a 20 20   writer might.  
159a0 2a 2a 20 68 61 76 65 20 61 6c 72 65 61 64 79 20  ** have already 
159b0 63 68 65 63 6b 70 6f 69 6e 74 65 64 20 74 68 65  checkpointed the
159c0 20 57 41 4c 20 66 69 6c 65 20 61 6e 64 2c 20 77   WAL file and, w
159d0 68 69 6c 65 20 74 68 65 20 63 75 72 72 65 6e 74  hile the current
159e0 0a 20 20 2a 2a 20 69 73 20 61 63 74 69 76 65 2c  .  ** is active,
159f0 20 77 72 61 70 20 74 68 65 20 57 41 4c 20 61 6e   wrap the WAL an
15a00 64 20 73 74 61 72 74 20 6f 76 65 72 77 72 69 74  d start overwrit
15a10 69 6e 67 20 66 72 61 6d 65 73 20 74 68 61 74 20  ing frames that 
15a20 74 68 69 73 0a 20 20 2a 2a 20 70 72 6f 63 65 73  this.  ** proces
15a30 73 20 77 61 6e 74 73 20 74 6f 20 75 73 65 2e 0a  s wants to use..
15a40 20 20 2a 2a 0a 20 20 2a 2a 20 4f 6e 63 65 20 73    **.  ** Once s
15a50 71 6c 69 74 65 33 4f 73 53 68 6d 4d 61 70 28 29  qlite3OsShmMap()
15a60 20 68 61 73 20 62 65 65 6e 20 63 61 6c 6c 65 64   has been called
15a70 20 66 6f 72 20 61 6e 20 73 71 6c 69 74 65 33 5f   for an sqlite3_
15a80 66 69 6c 65 20 61 6e 64 20 68 61 73 0a 20 20 2a  file and has.  *
15a90 2a 20 72 65 74 75 72 6e 65 64 20 61 6e 79 20 53  * returned any S
15aa0 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 20 76  QLITE_READONLY v
15ab0 61 6c 75 65 2c 20 69 74 20 6d 75 73 74 20 72 65  alue, it must re
15ac0 74 75 72 6e 20 6f 6e 6c 79 20 53 51 4c 49 54 45  turn only SQLITE
15ad0 5f 52 45 41 44 4f 4e 4c 59 0a 20 20 2a 2a 20 6f  _READONLY.  ** o
15ae0 72 20 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c  r SQLITE_READONL
15af0 59 5f 43 41 4e 54 49 4e 49 54 20 6f 72 20 73 6f  Y_CANTINIT or so
15b00 6d 65 20 65 72 72 6f 72 20 66 6f 72 20 61 6c 6c  me error for all
15b10 20 73 75 62 73 65 71 75 65 6e 74 20 69 6e 76 6f   subsequent invo
15b20 63 61 74 69 6f 6e 73 2c 0a 20 20 2a 2a 20 65 76  cations,.  ** ev
15b30 65 6e 20 69 66 20 73 6f 6d 65 20 65 78 74 65 72  en if some exter
15b40 6e 61 6c 20 61 67 65 6e 74 20 64 6f 65 73 20 61  nal agent does a
15b50 20 22 63 68 6d 6f 64 22 20 74 6f 20 6d 61 6b 65   "chmod" to make
15b60 20 74 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f   the shared-memo
15b70 72 79 0a 20 20 2a 2a 20 77 72 69 74 61 62 6c 65  ry.  ** writable
15b80 20 62 79 20 75 73 2c 20 75 6e 74 69 6c 20 73 71   by us, until sq
15b90 6c 69 74 65 33 4f 73 53 68 6d 55 6e 6d 61 70 28  lite3OsShmUnmap(
15ba0 29 20 68 61 73 20 62 65 65 6e 20 63 61 6c 6c 65  ) has been calle
15bb0 64 2e 0a 20 20 2a 2a 20 54 68 69 73 20 69 73 20  d..  ** This is 
15bc0 61 20 72 65 71 75 69 72 65 6d 65 6e 74 20 6f 6e  a requirement on
15bd0 20 74 68 65 20 56 46 53 20 69 6d 70 6c 65 6d 65   the VFS impleme
15be0 6e 74 61 74 69 6f 6e 2e 0a 20 20 20 2a 2f 0a 20  ntation..   */. 
15bf0 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53   rc = sqlite3OsS
15c00 68 6d 4d 61 70 28 70 57 61 6c 2d 3e 70 44 62 46  hmMap(pWal->pDbF
15c10 64 2c 20 30 2c 20 57 41 4c 49 4e 44 45 58 5f 50  d, 0, WALINDEX_P
15c20 47 53 5a 2c 20 30 2c 20 26 70 44 75 6d 6d 79 29  GSZ, 0, &pDummy)
15c30 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 21 3d  ;.  assert( rc!=
15c40 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 20 2f 2a 20  SQLITE_OK ); /* 
15c50 53 51 4c 49 54 45 5f 4f 4b 20 6e 6f 74 20 70 6f  SQLITE_OK not po
15c60 73 73 69 62 6c 65 20 66 6f 72 20 72 65 61 64 2d  ssible for read-
15c70 6f 6e 6c 79 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  only connection 
15c80 2a 2f 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  */.  if( rc!=SQL
15c90 49 54 45 5f 52 45 41 44 4f 4e 4c 59 5f 43 41 4e  ITE_READONLY_CAN
15ca0 54 49 4e 49 54 20 29 7b 0a 20 20 20 20 72 63 20  TINIT ){.    rc 
15cb0 3d 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 52 45  = (rc==SQLITE_RE
15cc0 41 44 4f 4e 4c 59 20 3f 20 57 41 4c 5f 52 45 54  ADONLY ? WAL_RET
15cd0 52 59 20 3a 20 72 63 29 3b 0a 20 20 20 20 67 6f  RY : rc);.    go
15ce0 74 6f 20 62 65 67 69 6e 5f 75 6e 72 65 6c 69 61  to begin_unrelia
15cf0 62 6c 65 5f 73 68 6d 5f 6f 75 74 3b 0a 20 20 7d  ble_shm_out;.  }
15d00 0a 0a 20 20 2f 2a 20 57 65 20 72 65 61 63 68 20  ..  /* We reach 
15d10 74 68 69 73 20 70 6f 69 6e 74 20 6f 6e 6c 79 20  this point only 
15d20 69 66 20 74 68 65 20 72 65 61 6c 20 73 68 61 72  if the real shar
15d30 65 64 2d 6d 65 6d 6f 72 79 20 69 73 20 73 74 69  ed-memory is sti
15d40 6c 6c 20 75 6e 72 65 6c 69 61 62 6c 65 2e 0a 20  ll unreliable.. 
15d50 20 2a 2a 20 41 73 73 75 6d 65 20 74 68 65 20 69   ** Assume the i
15d60 6e 2d 6d 65 6d 6f 72 79 20 57 41 4c 2d 69 6e 64  n-memory WAL-ind
15d70 65 78 20 73 75 62 73 74 69 74 75 74 65 20 69 73  ex substitute is
15d80 20 63 6f 72 72 65 63 74 20 61 6e 64 20 6c 6f 61   correct and loa
15d90 64 20 69 74 0a 20 20 2a 2a 20 69 6e 74 6f 20 70  d it.  ** into p
15da0 57 61 6c 2d 3e 68 64 72 2e 0a 20 20 2a 2f 0a 20  Wal->hdr..  */. 
15db0 20 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68   memcpy(&pWal->h
15dc0 64 72 2c 20 28 76 6f 69 64 2a 29 77 61 6c 49 6e  dr, (void*)walIn
15dd0 64 65 78 48 64 72 28 70 57 61 6c 29 2c 20 73 69  dexHdr(pWal), si
15de0 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
15df0 29 29 3b 0a 0a 20 20 2f 2a 20 4d 61 6b 65 20 73  ));..  /* Make s
15e00 75 72 65 20 73 6f 6d 65 20 77 72 69 74 65 72 20  ure some writer 
15e10 68 61 73 6e 27 74 20 63 6f 6d 65 20 69 6e 20 61  hasn't come in a
15e20 6e 64 20 63 68 61 6e 67 65 64 20 74 68 65 20 57  nd changed the W
15e30 41 4c 20 66 69 6c 65 20 6f 75 74 0a 20 20 2a 2a  AL file out.  **
15e40 20 66 72 6f 6d 20 75 6e 64 65 72 20 75 73 2c 20   from under us, 
15e50 74 68 65 6e 20 64 69 73 63 6f 6e 6e 65 63 74 65  then disconnecte
15e60 64 2c 20 77 68 69 6c 65 20 77 65 20 77 65 72 65  d, while we were
15e70 20 6e 6f 74 20 6c 6f 6f 6b 69 6e 67 2e 0a 20 20   not looking..  
15e80 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  */.  rc = sqlite
15e90 33 4f 73 46 69 6c 65 53 69 7a 65 28 70 57 61 6c  3OsFileSize(pWal
15ea0 2d 3e 70 57 61 6c 46 64 2c 20 26 73 7a 57 61 6c  ->pWalFd, &szWal
15eb0 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
15ec0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 67 6f  ITE_OK ){.    go
15ed0 74 6f 20 62 65 67 69 6e 5f 75 6e 72 65 6c 69 61  to begin_unrelia
15ee0 62 6c 65 5f 73 68 6d 5f 6f 75 74 3b 0a 20 20 7d  ble_shm_out;.  }
15ef0 0a 20 20 69 66 28 20 73 7a 57 61 6c 3c 57 41 4c  .  if( szWal<WAL
15f00 5f 48 44 52 53 49 5a 45 20 29 7b 0a 20 20 20 20  _HDRSIZE ){.    
15f10 2f 2a 20 49 66 20 74 68 65 20 77 61 6c 20 66 69  /* If the wal fi
15f20 6c 65 20 69 73 20 74 6f 6f 20 73 6d 61 6c 6c 20  le is too small 
15f30 74 6f 20 63 6f 6e 74 61 69 6e 20 61 20 77 61 6c  to contain a wal
15f40 2d 68 65 61 64 65 72 20 61 6e 64 20 74 68 65 0a  -header and the.
15f50 20 20 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78      ** wal-index
15f60 20 68 65 61 64 65 72 20 68 61 73 20 6d 78 46 72   header has mxFr
15f70 61 6d 65 3d 3d 30 2c 20 74 68 65 6e 20 69 74 20  ame==0, then it 
15f80 6d 75 73 74 20 62 65 20 73 61 66 65 20 74 6f 20  must be safe to 
15f90 70 72 6f 63 65 65 64 0a 20 20 20 20 2a 2a 20 72  proceed.    ** r
15fa0 65 61 64 69 6e 67 20 74 68 65 20 64 61 74 61 62  eading the datab
15fb0 61 73 65 20 66 69 6c 65 20 6f 6e 6c 79 2e 20 48  ase file only. H
15fc0 6f 77 65 76 65 72 2c 20 74 68 65 20 70 61 67 65  owever, the page
15fd0 20 63 61 63 68 65 20 63 61 6e 6e 6f 74 0a 20 20   cache cannot.  
15fe0 20 20 2a 2a 20 62 65 20 74 72 75 73 74 65 64 2c    ** be trusted,
15ff0 20 61 73 20 61 20 72 65 61 64 2f 77 72 69 74 65   as a read/write
16000 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 6d 61 79 20   connection may 
16010 68 61 76 65 20 63 6f 6e 6e 65 63 74 65 64 2c 20  have connected, 
16020 77 72 69 74 74 65 6e 0a 20 20 20 20 2a 2a 20 74  written.    ** t
16030 68 65 20 64 62 2c 20 72 75 6e 20 61 20 63 68 65  he db, run a che
16040 63 6b 70 6f 69 6e 74 2c 20 74 72 75 6e 63 61 74  ckpoint, truncat
16050 65 64 20 74 68 65 20 77 61 6c 20 66 69 6c 65 20  ed the wal file 
16060 61 6e 64 20 64 69 73 63 6f 6e 6e 65 63 74 65 64  and disconnected
16070 0a 20 20 20 20 2a 2a 20 73 69 6e 63 65 20 74 68  .    ** since th
16080 69 73 20 63 6c 69 65 6e 74 27 73 20 6c 61 73 74  is client's last
16090 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
160a0 6e 2e 20 20 2a 2f 0a 20 20 20 20 2a 70 43 68 61  n.  */.    *pCha
160b0 6e 67 65 64 20 3d 20 31 3b 0a 20 20 20 20 72 63  nged = 1;.    rc
160c0 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78   = (pWal->hdr.mx
160d0 46 72 61 6d 65 3d 3d 30 20 3f 20 53 51 4c 49 54  Frame==0 ? SQLIT
160e0 45 5f 4f 4b 20 3a 20 57 41 4c 5f 52 45 54 52 59  E_OK : WAL_RETRY
160f0 29 3b 0a 20 20 20 20 67 6f 74 6f 20 62 65 67 69  );.    goto begi
16100 6e 5f 75 6e 72 65 6c 69 61 62 6c 65 5f 73 68 6d  n_unreliable_shm
16110 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  _out;.  }..  /* 
16120 43 68 65 63 6b 20 74 68 65 20 73 61 6c 74 20 6b  Check the salt k
16130 65 79 73 20 61 74 20 74 68 65 20 73 74 61 72 74  eys at the start
16140 20 6f 66 20 74 68 65 20 77 61 6c 20 66 69 6c 65   of the wal file
16150 20 73 74 69 6c 6c 20 6d 61 74 63 68 2e 20 2a 2f   still match. */
16160 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  .  rc = sqlite3O
16170 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c  sRead(pWal->pWal
16180 46 64 2c 20 61 42 75 66 2c 20 57 41 4c 5f 48 44  Fd, aBuf, WAL_HD
16190 52 53 49 5a 45 2c 20 30 29 3b 0a 20 20 69 66 28  RSIZE, 0);.  if(
161a0 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
161b0 7b 0a 20 20 20 20 67 6f 74 6f 20 62 65 67 69 6e  {.    goto begin
161c0 5f 75 6e 72 65 6c 69 61 62 6c 65 5f 73 68 6d 5f  _unreliable_shm_
161d0 6f 75 74 3b 0a 20 20 7d 0a 20 20 69 66 28 20 6d  out;.  }.  if( m
161e0 65 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72  emcmp(&pWal->hdr
161f0 2e 61 53 61 6c 74 2c 20 26 61 42 75 66 5b 31 36  .aSalt, &aBuf[16
16200 5d 2c 20 38 29 20 29 7b 0a 20 20 20 20 2f 2a 20  ], 8) ){.    /* 
16210 53 6f 6d 65 20 77 72 69 74 65 72 20 68 61 73 20  Some writer has 
16220 77 72 61 70 70 65 64 20 74 68 65 20 57 41 4c 20  wrapped the WAL 
16230 66 69 6c 65 20 77 68 69 6c 65 20 77 65 20 77 65  file while we we
16240 72 65 20 6e 6f 74 20 6c 6f 6f 6b 69 6e 67 2e 0a  re not looking..
16250 20 20 20 20 2a 2a 20 52 65 74 75 72 6e 20 57 41      ** Return WA
16260 4c 5f 52 45 54 52 59 20 77 68 69 63 68 20 77 69  L_RETRY which wi
16270 6c 6c 20 63 61 75 73 65 20 74 68 65 20 69 6e 2d  ll cause the in-
16280 6d 65 6d 6f 72 79 20 57 41 4c 2d 69 6e 64 65 78  memory WAL-index
16290 20 74 6f 20 62 65 0a 20 20 20 20 2a 2a 20 72 65   to be.    ** re
162a0 62 75 69 6c 74 2e 20 2a 2f 0a 20 20 20 20 72 63  built. */.    rc
162b0 20 3d 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20   = WAL_RETRY;.  
162c0 20 20 67 6f 74 6f 20 62 65 67 69 6e 5f 75 6e 72    goto begin_unr
162d0 65 6c 69 61 62 6c 65 5f 73 68 6d 5f 6f 75 74 3b  eliable_shm_out;
162e0 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63  .  }..  /* Alloc
162f0 61 74 65 20 61 20 62 75 66 66 65 72 20 74 6f 20  ate a buffer to 
16300 72 65 61 64 20 66 72 61 6d 65 73 20 69 6e 74 6f  read frames into
16310 20 2a 2f 0a 20 20 73 7a 46 72 61 6d 65 20 3d 20   */.  szFrame = 
16320 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65  pWal->hdr.szPage
16330 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52   + WAL_FRAME_HDR
16340 53 49 5a 45 3b 0a 20 20 61 46 72 61 6d 65 20 3d  SIZE;.  aFrame =
16350 20 28 75 38 20 2a 29 73 71 6c 69 74 65 33 5f 6d   (u8 *)sqlite3_m
16360 61 6c 6c 6f 63 36 34 28 73 7a 46 72 61 6d 65 29  alloc64(szFrame)
16370 3b 0a 20 20 69 66 28 20 61 46 72 61 6d 65 3d 3d  ;.  if( aFrame==
16380 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  0 ){.    rc = SQ
16390 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b  LITE_NOMEM_BKPT;
163a0 0a 20 20 20 20 67 6f 74 6f 20 62 65 67 69 6e 5f  .    goto begin_
163b0 75 6e 72 65 6c 69 61 62 6c 65 5f 73 68 6d 5f 6f  unreliable_shm_o
163c0 75 74 3b 0a 20 20 7d 0a 20 20 61 44 61 74 61 20  ut;.  }.  aData 
163d0 3d 20 26 61 46 72 61 6d 65 5b 57 41 4c 5f 46 52  = &aFrame[WAL_FR
163e0 41 4d 45 5f 48 44 52 53 49 5a 45 5d 3b 0a 0a 20  AME_HDRSIZE];.. 
163f0 20 2f 2a 20 43 68 65 63 6b 20 74 6f 20 73 65 65   /* Check to see
16400 20 69 66 20 61 20 63 6f 6d 70 6c 65 74 65 20 74   if a complete t
16410 72 61 6e 73 61 63 74 69 6f 6e 20 68 61 73 20 62  ransaction has b
16420 65 65 6e 20 61 70 70 65 6e 64 65 64 20 74 6f 20  een appended to 
16430 74 68 65 0a 20 20 2a 2a 20 77 61 6c 20 66 69 6c  the.  ** wal fil
16440 65 20 73 69 6e 63 65 20 74 68 65 20 68 65 61 70  e since the heap
16450 2d 6d 65 6d 6f 72 79 20 77 61 6c 2d 69 6e 64 65  -memory wal-inde
16460 78 20 77 61 73 20 63 72 65 61 74 65 64 2e 20 49  x was created. I
16470 66 20 73 6f 2c 20 74 68 65 0a 20 20 2a 2a 20 68  f so, the.  ** h
16480 65 61 70 2d 6d 65 6d 6f 72 79 20 77 61 6c 2d 69  eap-memory wal-i
16490 6e 64 65 78 20 69 73 20 64 69 73 63 61 72 64 65  ndex is discarde
164a0 64 20 61 6e 64 20 57 41 4c 5f 52 45 54 52 59 20  d and WAL_RETRY 
164b0 72 65 74 75 72 6e 65 64 20 74 6f 0a 20 20 2a 2a  returned to.  **
164c0 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 20 2a 2f   the caller.  */
164d0 0a 20 20 61 53 61 76 65 43 6b 73 75 6d 5b 30 5d  .  aSaveCksum[0]
164e0 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72   = pWal->hdr.aFr
164f0 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 61  ameCksum[0];.  a
16500 53 61 76 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 70  SaveCksum[1] = p
16510 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
16520 6b 73 75 6d 5b 31 5d 3b 0a 20 20 66 6f 72 28 69  ksum[1];.  for(i
16530 4f 66 66 73 65 74 3d 77 61 6c 46 72 61 6d 65 4f  Offset=walFrameO
16540 66 66 73 65 74 28 70 57 61 6c 2d 3e 68 64 72 2e  ffset(pWal->hdr.
16550 6d 78 46 72 61 6d 65 2b 31 2c 20 70 57 61 6c 2d  mxFrame+1, pWal-
16560 3e 68 64 72 2e 73 7a 50 61 67 65 29 3b 20 0a 20  >hdr.szPage); . 
16570 20 20 20 20 20 69 4f 66 66 73 65 74 2b 73 7a 46       iOffset+szF
16580 72 61 6d 65 3c 3d 73 7a 57 61 6c 3b 20 0a 20 20  rame<=szWal; .  
16590 20 20 20 20 69 4f 66 66 73 65 74 2b 3d 73 7a 46      iOffset+=szF
165a0 72 61 6d 65 0a 20 20 29 7b 0a 20 20 20 20 75 33  rame.  ){.    u3
165b0 32 20 70 67 6e 6f 3b 20 20 20 20 20 20 20 20 20  2 pgno;         
165c0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
165d0 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65  abase page numbe
165e0 72 20 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20  r for frame */. 
165f0 20 20 20 75 33 32 20 6e 54 72 75 6e 63 61 74 65     u32 nTruncate
16600 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
16610 2a 20 64 62 73 69 7a 65 20 66 69 65 6c 64 20 66  * dbsize field f
16620 72 6f 6d 20 66 72 61 6d 65 20 68 65 61 64 65 72  rom frame header
16630 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64   */..    /* Read
16640 20 61 6e 64 20 64 65 63 6f 64 65 20 74 68 65 20   and decode the 
16650 6e 65 78 74 20 6c 6f 67 20 66 72 61 6d 65 2e 20  next log frame. 
16660 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  */.    rc = sqli
16670 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e  te3OsRead(pWal->
16680 70 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20  pWalFd, aFrame, 
16690 73 7a 46 72 61 6d 65 2c 20 69 4f 66 66 73 65 74  szFrame, iOffset
166a0 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
166b0 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
166c0 3b 0a 20 20 20 20 69 66 28 20 21 77 61 6c 44 65  ;.    if( !walDe
166d0 63 6f 64 65 46 72 61 6d 65 28 70 57 61 6c 2c 20  codeFrame(pWal, 
166e0 26 70 67 6e 6f 2c 20 26 6e 54 72 75 6e 63 61 74  &pgno, &nTruncat
166f0 65 2c 20 61 44 61 74 61 2c 20 61 46 72 61 6d 65  e, aData, aFrame
16700 29 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20  ) ) break;..    
16710 2f 2a 20 49 66 20 6e 54 72 75 6e 63 61 74 65 20  /* If nTruncate 
16720 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65  is non-zero, the
16730 6e 20 61 20 63 6f 6d 70 6c 65 74 65 20 74 72 61  n a complete tra
16740 6e 73 61 63 74 69 6f 6e 20 68 61 73 20 62 65 65  nsaction has bee
16750 6e 0a 20 20 20 20 2a 2a 20 61 70 70 65 6e 64 65  n.    ** appende
16760 64 20 74 6f 20 74 68 69 73 20 77 61 6c 20 66 69  d to this wal fi
16770 6c 65 2e 20 53 65 74 20 72 63 20 74 6f 20 57 41  le. Set rc to WA
16780 4c 5f 52 45 54 52 59 20 61 6e 64 20 62 72 65 61  L_RETRY and brea
16790 6b 20 6f 75 74 20 6f 66 0a 20 20 20 20 2a 2a 20  k out of.    ** 
167a0 74 68 65 20 6c 6f 6f 70 2e 20 20 2a 2f 0a 20 20  the loop.  */.  
167b0 20 20 69 66 28 20 6e 54 72 75 6e 63 61 74 65 20    if( nTruncate 
167c0 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 57 41  ){.      rc = WA
167d0 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20 62  L_RETRY;.      b
167e0 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  reak;.    }.  }.
167f0 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61    pWal->hdr.aFra
16800 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 53 61  meCksum[0] = aSa
16810 76 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 70 57  veCksum[0];.  pW
16820 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
16830 73 75 6d 5b 31 5d 20 3d 20 61 53 61 76 65 43 6b  sum[1] = aSaveCk
16840 73 75 6d 5b 31 5d 3b 0a 0a 20 62 65 67 69 6e 5f  sum[1];.. begin_
16850 75 6e 72 65 6c 69 61 62 6c 65 5f 73 68 6d 5f 6f  unreliable_shm_o
16860 75 74 3a 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  ut:.  sqlite3_fr
16870 65 65 28 61 46 72 61 6d 65 29 3b 0a 20 20 69 66  ee(aFrame);.  if
16880 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
16890 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  ){.    int i;.  
168a0 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 57 61    for(i=0; i<pWa
168b0 6c 2d 3e 6e 57 69 44 61 74 61 3b 20 69 2b 2b 29  l->nWiData; i++)
168c0 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
168d0 66 72 65 65 28 28 76 6f 69 64 2a 29 70 57 61 6c  free((void*)pWal
168e0 2d 3e 61 70 57 69 44 61 74 61 5b 69 5d 29 3b 0a  ->apWiData[i]);.
168f0 20 20 20 20 20 20 70 57 61 6c 2d 3e 61 70 57 69        pWal->apWi
16900 44 61 74 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20  Data[i] = 0;.   
16910 20 7d 0a 20 20 20 20 70 57 61 6c 2d 3e 62 53 68   }.    pWal->bSh
16920 6d 55 6e 72 65 6c 69 61 62 6c 65 20 3d 20 30 3b  mUnreliable = 0;
16930 0a 20 20 20 20 73 71 6c 69 74 65 33 57 61 6c 45  .    sqlite3WalE
16940 6e 64 52 65 61 64 54 72 61 6e 73 61 63 74 69 6f  ndReadTransactio
16950 6e 28 70 57 61 6c 29 3b 0a 20 20 20 20 2a 70 43  n(pWal);.    *pC
16960 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20 7d 0a  hanged = 1;.  }.
16970 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
16980 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f  /*.** Attempt to
16990 20 73 74 61 72 74 20 61 20 72 65 61 64 20 74 72   start a read tr
169a0 61 6e 73 61 63 74 69 6f 6e 2e 20 20 54 68 69 73  ansaction.  This
169b0 20 6d 69 67 68 74 20 66 61 69 6c 20 64 75 65 20   might fail due 
169c0 74 6f 20 61 20 72 61 63 65 20 6f 72 0a 2a 2a 20  to a race or.** 
169d0 6f 74 68 65 72 20 74 72 61 6e 73 69 65 6e 74 20  other transient 
169e0 63 6f 6e 64 69 74 69 6f 6e 2e 20 20 57 68 65 6e  condition.  When
169f0 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c 20 69   that happens, i
16a00 74 20 72 65 74 75 72 6e 73 20 57 41 4c 5f 52 45  t returns WAL_RE
16a10 54 52 59 20 74 6f 0a 2a 2a 20 69 6e 64 69 63 61  TRY to.** indica
16a20 74 65 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72  te to the caller
16a30 20 74 68 61 74 20 69 74 20 69 73 20 73 61 66 65   that it is safe
16a40 20 74 6f 20 72 65 74 72 79 20 69 6d 6d 65 64 69   to retry immedi
16a50 61 74 65 6c 79 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20  ately..**.** On 
16a60 73 75 63 63 65 73 73 20 72 65 74 75 72 6e 20 53  success return S
16a70 51 4c 49 54 45 5f 4f 4b 2e 20 20 4f 6e 20 61 20  QLITE_OK.  On a 
16a80 70 65 72 6d 61 6e 65 6e 74 20 66 61 69 6c 75 72  permanent failur
16a90 65 20 28 73 75 63 68 20 61 6e 0a 2a 2a 20 49 2f  e (such an.** I/
16aa0 4f 20 65 72 72 6f 72 20 6f 72 20 61 6e 20 53 51  O error or an SQ
16ab0 4c 49 54 45 5f 42 55 53 59 20 62 65 63 61 75 73  LITE_BUSY becaus
16ac0 65 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65 73  e another proces
16ad0 73 20 69 73 20 72 75 6e 6e 69 6e 67 0a 2a 2a 20  s is running.** 
16ae0 72 65 63 6f 76 65 72 79 29 20 72 65 74 75 72 6e  recovery) return
16af0 20 61 20 70 6f 73 69 74 69 76 65 20 65 72 72 6f   a positive erro
16b00 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 54 68  r code..**.** Th
16b10 65 20 75 73 65 57 61 6c 20 70 61 72 61 6d 65 74  e useWal paramet
16b20 65 72 20 69 73 20 74 72 75 65 20 74 6f 20 66 6f  er is true to fo
16b30 72 63 65 20 74 68 65 20 75 73 65 20 6f 66 20 74  rce the use of t
16b40 68 65 20 57 41 4c 20 61 6e 64 20 64 69 73 61 62  he WAL and disab
16b50 6c 65 0a 2a 2a 20 74 68 65 20 63 61 73 65 20 77  le.** the case w
16b60 68 65 72 65 20 74 68 65 20 57 41 4c 20 69 73 20  here the WAL is 
16b70 62 79 70 61 73 73 65 64 20 62 65 63 61 75 73 65  bypassed because
16b80 20 69 74 20 68 61 73 20 62 65 65 6e 20 63 6f 6d   it has been com
16b90 70 6c 65 74 65 6c 79 0a 2a 2a 20 63 68 65 63 6b  pletely.** check
16ba0 70 6f 69 6e 74 65 64 2e 20 20 49 66 20 75 73 65  pointed.  If use
16bb0 57 61 6c 3d 3d 30 20 74 68 65 6e 20 74 68 69 73  Wal==0 then this
16bc0 20 72 6f 75 74 69 6e 65 20 63 61 6c 6c 73 20 77   routine calls w
16bd0 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28 29  alIndexReadHdr()
16be0 20 0a 2a 2a 20 74 6f 20 6d 61 6b 65 20 61 20 63   .** to make a c
16bf0 6f 70 79 20 6f 66 20 74 68 65 20 77 61 6c 2d 69  opy of the wal-i
16c00 6e 64 65 78 20 68 65 61 64 65 72 20 69 6e 74 6f  ndex header into
16c10 20 70 57 61 6c 2d 3e 68 64 72 2e 20 20 49 66 20   pWal->hdr.  If 
16c20 74 68 65 20 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65  the .** wal-inde
16c30 78 20 68 65 61 64 65 72 20 68 61 73 20 63 68 61  x header has cha
16c40 6e 67 65 64 2c 20 2a 70 43 68 61 6e 67 65 64 20  nged, *pChanged 
16c50 69 73 20 73 65 74 20 74 6f 20 31 20 28 61 73 20  is set to 1 (as 
16c60 61 6e 20 69 6e 64 69 63 61 74 69 6f 6e 20 0a 2a  an indication .*
16c70 2a 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 20  * to the caller 
16c80 74 68 61 74 20 74 68 65 20 6c 6f 63 61 6c 20 70  that the local p
16c90 61 67 65 20 63 61 63 68 65 20 69 73 20 6f 62 73  age cache is obs
16ca0 6f 6c 65 74 65 20 61 6e 64 20 6e 65 65 64 73 20  olete and needs 
16cb0 74 6f 20 62 65 20 0a 2a 2a 20 66 6c 75 73 68 65  to be .** flushe
16cc0 64 2e 29 20 20 57 68 65 6e 20 75 73 65 57 61 6c  d.)  When useWal
16cd0 3d 3d 31 2c 20 74 68 65 20 77 61 6c 2d 69 6e 64  ==1, the wal-ind
16ce0 65 78 20 68 65 61 64 65 72 20 69 73 20 61 73 73  ex header is ass
16cf0 75 6d 65 64 20 74 6f 20 61 6c 72 65 61 64 79 0a  umed to already.
16d00 2a 2a 20 62 65 20 6c 6f 61 64 65 64 20 61 6e 64  ** be loaded and
16d10 20 74 68 65 20 70 43 68 61 6e 67 65 64 20 70 61   the pChanged pa
16d20 72 61 6d 65 74 65 72 20 69 73 20 75 6e 75 73 65  rameter is unuse
16d30 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c  d..**.** The cal
16d40 6c 65 72 20 6d 75 73 74 20 73 65 74 20 74 68 65  ler must set the
16d50 20 63 6e 74 20 70 61 72 61 6d 65 74 65 72 20 74   cnt parameter t
16d60 6f 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  o the number of 
16d70 70 72 69 6f 72 20 63 61 6c 6c 73 20 74 6f 0a 2a  prior calls to.*
16d80 2a 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 64  * this routine d
16d90 75 72 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e  uring the curren
16da0 74 20 72 65 61 64 20 61 74 74 65 6d 70 74 20 74  t read attempt t
16db0 68 61 74 20 72 65 74 75 72 6e 65 64 20 57 41 4c  hat returned WAL
16dc0 5f 52 45 54 52 59 2e 0a 2a 2a 20 54 68 69 73 20  _RETRY..** This 
16dd0 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20 73 74 61  routine will sta
16de0 72 74 20 74 61 6b 69 6e 67 20 6d 6f 72 65 20 61  rt taking more a
16df0 67 67 72 65 73 73 69 76 65 20 6d 65 61 73 75 72  ggressive measur
16e00 65 73 20 74 6f 20 63 6c 65 61 72 20 74 68 65 0a  es to clear the.
16e10 2a 2a 20 72 61 63 65 20 63 6f 6e 64 69 74 69 6f  ** race conditio
16e20 6e 73 20 61 66 74 65 72 20 6d 75 6c 74 69 70 6c  ns after multipl
16e30 65 20 57 41 4c 5f 52 45 54 52 59 20 72 65 74 75  e WAL_RETRY retu
16e40 72 6e 73 2c 20 61 6e 64 20 61 66 74 65 72 20 61  rns, and after a
16e50 6e 20 65 78 63 65 73 73 69 76 65 0a 2a 2a 20 6e  n excessive.** n
16e60 75 6d 62 65 72 20 6f 66 20 65 72 72 6f 72 73 20  umber of errors 
16e70 77 69 6c 6c 20 75 6c 74 69 6d 61 74 65 6c 79 20  will ultimately 
16e80 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 50 52  return SQLITE_PR
16e90 4f 54 4f 43 4f 4c 2e 20 20 54 68 65 0a 2a 2a 20  OTOCOL.  The.** 
16ea0 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 20  SQLITE_PROTOCOL 
16eb0 72 65 74 75 72 6e 20 69 6e 64 69 63 61 74 65 73  return indicates
16ec0 20 74 68 61 74 20 73 6f 6d 65 20 6f 74 68 65 72   that some other
16ed0 20 70 72 6f 63 65 73 73 20 68 61 73 20 67 6f 6e   process has gon
16ee0 65 20 72 6f 67 75 65 0a 2a 2a 20 61 6e 64 20 69  e rogue.** and i
16ef0 73 20 6e 6f 74 20 68 6f 6e 6f 72 69 6e 67 20 74  s not honoring t
16f00 68 65 20 6c 6f 63 6b 69 6e 67 20 70 72 6f 74 6f  he locking proto
16f10 63 6f 6c 2e 20 20 54 68 65 72 65 20 69 73 20 61  col.  There is a
16f20 20 76 61 6e 69 73 68 69 6e 67 6c 79 20 73 6d 61   vanishingly sma
16f30 6c 6c 0a 2a 2a 20 63 68 61 6e 63 65 20 74 68 61  ll.** chance tha
16f40 74 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f  t SQLITE_PROTOCO
16f50 4c 20 63 6f 75 6c 64 20 62 65 20 72 65 74 75 72  L could be retur
16f60 6e 65 64 20 62 65 63 61 75 73 65 20 6f 66 20 61  ned because of a
16f70 20 72 75 6e 20 6f 66 20 72 65 61 6c 6c 79 0a 2a   run of really.*
16f80 2a 20 62 61 64 20 6c 75 63 6b 20 77 68 65 6e 20  * bad luck when 
16f90 74 68 65 72 65 20 69 73 20 6c 6f 74 73 20 6f 66  there is lots of
16fa0 20 63 6f 6e 74 65 6e 74 69 6f 6e 20 66 6f 72 20   contention for 
16fb0 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2c 20 62  the wal-index, b
16fc0 75 74 20 74 68 61 74 0a 2a 2a 20 70 6f 73 73 69  ut that.** possi
16fd0 62 69 6c 69 74 79 20 69 73 20 73 6f 20 73 6d 61  bility is so sma
16fe0 6c 6c 20 74 68 61 74 20 69 74 20 63 61 6e 20 62  ll that it can b
16ff0 65 20 73 61 66 65 6c 79 20 6e 65 67 6c 65 63 74  e safely neglect
17000 65 64 2c 20 77 65 20 62 65 6c 69 65 76 65 2e 0a  ed, we believe..
17010 2a 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63 65 73 73  **.** On success
17020 2c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 6f  , this routine o
17030 62 74 61 69 6e 73 20 61 20 72 65 61 64 20 6c 6f  btains a read lo
17040 63 6b 20 6f 6e 20 0a 2a 2a 20 57 41 4c 5f 52 45  ck on .** WAL_RE
17050 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65  AD_LOCK(pWal->re
17060 61 64 4c 6f 63 6b 29 2e 20 20 54 68 65 20 70 57  adLock).  The pW
17070 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69 6e 74  al->readLock int
17080 65 67 65 72 20 69 73 0a 2a 2a 20 69 6e 20 74 68  eger is.** in th
17090 65 20 72 61 6e 67 65 20 30 20 3c 3d 20 70 57 61  e range 0 <= pWa
170a0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3c 20 57 41  l->readLock < WA
170b0 4c 5f 4e 52 45 41 44 45 52 2e 20 20 49 66 20 70  L_NREADER.  If p
170c0 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 28  Wal->readLock==(
170d0 2d 31 29 0a 2a 2a 20 74 68 61 74 20 6d 65 61 6e  -1).** that mean
170e0 73 20 74 68 65 20 57 61 6c 20 64 6f 65 73 20 6e  s the Wal does n
170f0 6f 74 20 68 6f 6c 64 20 61 6e 79 20 72 65 61 64  ot hold any read
17100 20 6c 6f 63 6b 2e 20 20 54 68 65 20 72 65 61 64   lock.  The read
17110 65 72 20 6d 75 73 74 20 6e 6f 74 0a 2a 2a 20 61  er must not.** a
17120 63 63 65 73 73 20 61 6e 79 20 64 61 74 61 62 61  ccess any databa
17130 73 65 20 70 61 67 65 20 74 68 61 74 20 69 73 20  se page that is 
17140 6d 6f 64 69 66 69 65 64 20 62 79 20 61 20 57 41  modified by a WA
17150 4c 20 66 72 61 6d 65 20 75 70 20 74 6f 20 61 6e  L frame up to an
17160 64 0a 2a 2a 20 69 6e 63 6c 75 64 69 6e 67 20 66  d.** including f
17170 72 61 6d 65 20 6e 75 6d 62 65 72 20 61 52 65 61  rame number aRea
17180 64 4d 61 72 6b 5b 70 57 61 6c 2d 3e 72 65 61 64  dMark[pWal->read
17190 4c 6f 63 6b 5d 2e 20 20 54 68 65 20 72 65 61 64  Lock].  The read
171a0 65 72 20 77 69 6c 6c 0a 2a 2a 20 75 73 65 20 57  er will.** use W
171b0 41 4c 20 66 72 61 6d 65 73 20 75 70 20 74 6f 20  AL frames up to 
171c0 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20 70 57  and including pW
171d0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
171e0 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  if pWal->readLoc
171f0 6b 3e 30 0a 2a 2a 20 4f 72 20 69 66 20 70 57 61  k>0.** Or if pWa
17200 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 2c 20  l->readLock==0, 
17210 74 68 65 6e 20 74 68 65 20 72 65 61 64 65 72 20  then the reader 
17220 77 69 6c 6c 20 69 67 6e 6f 72 65 20 74 68 65 20  will ignore the 
17230 57 41 4c 0a 2a 2a 20 63 6f 6d 70 6c 65 74 65 6c  WAL.** completel
17240 79 20 61 6e 64 20 67 65 74 20 61 6c 6c 20 63 6f  y and get all co
17250 6e 74 65 6e 74 20 64 69 72 65 63 74 6c 79 20 66  ntent directly f
17260 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73 65  rom the database
17270 20 66 69 6c 65 2e 0a 2a 2a 20 49 66 20 74 68 65   file..** If the
17280 20 75 73 65 57 61 6c 20 70 61 72 61 6d 65 74 65   useWal paramete
17290 72 20 69 73 20 31 20 74 68 65 6e 20 74 68 65 20  r is 1 then the 
172a0 57 41 4c 20 77 69 6c 6c 20 6e 65 76 65 72 20 62  WAL will never b
172b0 65 20 69 67 6e 6f 72 65 64 20 61 6e 64 0a 2a 2a  e ignored and.**
172c0 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69   this routine wi
172d0 6c 6c 20 61 6c 77 61 79 73 20 73 65 74 20 70 57  ll always set pW
172e0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 30 20 6f  al->readLock>0 o
172f0 6e 20 73 75 63 63 65 73 73 2e 0a 2a 2a 20 57 68  n success..** Wh
17300 65 6e 20 74 68 65 20 72 65 61 64 20 74 72 61 6e  en the read tran
17310 73 61 63 74 69 6f 6e 20 69 73 20 63 6f 6d 70 6c  saction is compl
17320 65 74 65 64 2c 20 74 68 65 20 63 61 6c 6c 65 72  eted, the caller
17330 20 6d 75 73 74 20 72 65 6c 65 61 73 65 20 74 68   must release th
17340 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c  e.** lock on WAL
17350 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d  _READ_LOCK(pWal-
17360 3e 72 65 61 64 4c 6f 63 6b 29 20 61 6e 64 20 73  >readLock) and s
17370 65 74 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  et pWal->readLoc
17380 6b 20 74 6f 20 2d 31 2e 0a 2a 2a 0a 2a 2a 20 54  k to -1..**.** T
17390 68 69 73 20 72 6f 75 74 69 6e 65 20 75 73 65 73  his routine uses
173a0 20 74 68 65 20 6e 42 61 63 6b 66 69 6c 6c 20 61   the nBackfill a
173b0 6e 64 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 66  nd aReadMark[] f
173c0 69 65 6c 64 73 20 6f 66 20 74 68 65 20 68 65 61  ields of the hea
173d0 64 65 72 0a 2a 2a 20 74 6f 20 73 65 6c 65 63 74  der.** to select
173e0 20 61 20 70 61 72 74 69 63 75 6c 61 72 20 57 41   a particular WA
173f0 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 29 20 74 68  L_READ_LOCK() th
17400 61 74 20 73 74 72 69 76 65 73 20 74 6f 20 6c 65  at strives to le
17410 74 20 74 68 65 0a 2a 2a 20 63 68 65 63 6b 70 6f  t the.** checkpo
17420 69 6e 74 20 70 72 6f 63 65 73 73 20 64 6f 20 61  int process do a
17430 73 20 6d 75 63 68 20 77 6f 72 6b 20 61 73 20 70  s much work as p
17440 6f 73 73 69 62 6c 65 2e 20 20 54 68 69 73 20 72  ossible.  This r
17450 6f 75 74 69 6e 65 20 6d 69 67 68 74 0a 2a 2a 20  outine might.** 
17460 75 70 64 61 74 65 20 76 61 6c 75 65 73 20 6f 66  update values of
17470 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d   the aReadMark[]
17480 20 61 72 72 61 79 20 69 6e 20 74 68 65 20 68 65   array in the he
17490 61 64 65 72 2c 20 62 75 74 20 69 66 20 69 74 20  ader, but if it 
174a0 64 6f 65 73 0a 2a 2a 20 73 6f 20 69 74 20 74 61  does.** so it ta
174b0 6b 65 73 20 63 61 72 65 20 74 6f 20 68 6f 6c 64  kes care to hold
174c0 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c 6f   an exclusive lo
174d0 63 6b 20 6f 6e 20 74 68 65 20 63 6f 72 72 65 73  ck on the corres
174e0 70 6f 6e 64 69 6e 67 0a 2a 2a 20 57 41 4c 5f 52  ponding.** WAL_R
174f0 45 41 44 5f 4c 4f 43 4b 28 29 20 77 68 69 6c 65  EAD_LOCK() while
17500 20 63 68 61 6e 67 69 6e 67 20 76 61 6c 75 65 73   changing values
17510 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
17520 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64 28  walTryBeginRead(
17530 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a  Wal *pWal, int *
17540 70 43 68 61 6e 67 65 64 2c 20 69 6e 74 20 75 73  pChanged, int us
17550 65 57 61 6c 2c 20 69 6e 74 20 63 6e 74 29 7b 0a  eWal, int cnt){.
17560 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b    volatile WalCk
17570 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b 20 20  ptInfo *pInfo;  
17580 20 20 2f 2a 20 43 68 65 63 6b 70 6f 69 6e 74 20    /* Checkpoint 
17590 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e 20 77  information in w
175a0 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a 20 20 75 33  al-index */.  u3
175b0 32 20 6d 78 52 65 61 64 4d 61 72 6b 3b 20 20 20  2 mxReadMark;   
175c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
175d0 20 4c 61 72 67 65 73 74 20 61 52 65 61 64 4d 61   Largest aReadMa
175e0 72 6b 5b 5d 20 76 61 6c 75 65 20 2a 2f 0a 20 20  rk[] value */.  
175f0 69 6e 74 20 6d 78 49 3b 20 20 20 20 20 20 20 20  int mxI;        
17600 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17610 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6c 61 72 67  /* Index of larg
17620 65 73 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20  est aReadMark[] 
17630 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20 69  value */.  int i
17640 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
17650 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f             /* Lo
17660 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20  op counter */.  
17670 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
17680 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
17690 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 20  /* Return code  
176a0 2a 2f 0a 20 20 75 33 32 20 6d 78 46 72 61 6d 65  */.  u32 mxFrame
176b0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
176c0 20 20 20 20 20 2f 2a 20 57 61 6c 20 66 72 61 6d       /* Wal fram
176d0 65 20 74 6f 20 6c 6f 63 6b 20 74 6f 20 2a 2f 0a  e to lock to */.
176e0 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
176f0 3e 72 65 61 64 4c 6f 63 6b 3c 30 20 29 3b 20 20  >readLock<0 );  
17700 20 20 20 2f 2a 20 4e 6f 74 20 63 75 72 72 65 6e     /* Not curren
17710 74 6c 79 20 6c 6f 63 6b 65 64 20 2a 2f 0a 0a 20  tly locked */.. 
17720 20 2f 2a 20 75 73 65 57 61 6c 20 6d 61 79 20 6f   /* useWal may o
17730 6e 6c 79 20 62 65 20 73 65 74 20 66 6f 72 20 72  nly be set for r
17740 65 61 64 2f 77 72 69 74 65 20 63 6f 6e 6e 65 63  ead/write connec
17750 74 69 6f 6e 73 20 2a 2f 0a 20 20 61 73 73 65 72  tions */.  asser
17760 74 28 20 28 70 57 61 6c 2d 3e 72 65 61 64 4f 6e  t( (pWal->readOn
17770 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  ly & WAL_SHM_RDO
17780 4e 4c 59 29 3d 3d 30 20 7c 7c 20 75 73 65 57 61  NLY)==0 || useWa
17790 6c 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 54 61  l==0 );..  /* Ta
177a0 6b 65 20 73 74 65 70 73 20 74 6f 20 61 76 6f 69  ke steps to avoi
177b0 64 20 73 70 69 6e 6e 69 6e 67 20 66 6f 72 65 76  d spinning forev
177c0 65 72 20 69 66 20 74 68 65 72 65 20 69 73 20 61  er if there is a
177d0 20 70 72 6f 74 6f 63 6f 6c 20 65 72 72 6f 72 2e   protocol error.
177e0 0a 20 20 2a 2a 0a 20 20 2a 2a 20 43 69 72 63 75  .  **.  ** Circu
177f0 6d 73 74 61 6e 63 65 73 20 74 68 61 74 20 63 61  mstances that ca
17800 75 73 65 20 61 20 52 45 54 52 59 20 73 68 6f 75  use a RETRY shou
17810 6c 64 20 6f 6e 6c 79 20 6c 61 73 74 20 66 6f 72  ld only last for
17820 20 74 68 65 20 62 72 69 65 66 65 73 74 0a 20 20   the briefest.  
17830 2a 2a 20 69 6e 73 74 61 6e 63 65 73 20 6f 66 20  ** instances of 
17840 74 69 6d 65 2e 20 20 4e 6f 20 49 2f 4f 20 6f 72  time.  No I/O or
17850 20 6f 74 68 65 72 20 73 79 73 74 65 6d 20 63 61   other system ca
17860 6c 6c 73 20 61 72 65 20 64 6f 6e 65 20 77 68 69  lls are done whi
17870 6c 65 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 63 6b  le the.  ** lock
17880 73 20 61 72 65 20 68 65 6c 64 2c 20 73 6f 20 74  s are held, so t
17890 68 65 20 6c 6f 63 6b 73 20 73 68 6f 75 6c 64 20  he locks should 
178a0 6e 6f 74 20 62 65 20 68 65 6c 64 20 66 6f 72 20  not be held for 
178b0 76 65 72 79 20 6c 6f 6e 67 2e 20 42 75 74 20 0a  very long. But .
178c0 20 20 2a 2a 20 69 66 20 77 65 20 61 72 65 20 75    ** if we are u
178d0 6e 6c 75 63 6b 79 2c 20 61 6e 6f 74 68 65 72 20  nlucky, another 
178e0 70 72 6f 63 65 73 73 20 74 68 61 74 20 69 73 20  process that is 
178f0 68 6f 6c 64 69 6e 67 20 61 20 6c 6f 63 6b 20 6d  holding a lock m
17900 69 67 68 74 20 67 65 74 0a 20 20 2a 2a 20 70 61  ight get.  ** pa
17910 67 65 64 20 6f 75 74 20 6f 72 20 74 61 6b 65 20  ged out or take 
17920 61 20 70 61 67 65 2d 66 61 75 6c 74 20 74 68 61  a page-fault tha
17930 74 20 69 73 20 74 69 6d 65 2d 63 6f 6e 73 75 6d  t is time-consum
17940 69 6e 67 20 74 6f 20 72 65 73 6f 6c 76 65 2c 20  ing to resolve, 
17950 0a 20 20 2a 2a 20 64 75 72 69 6e 67 20 74 68 65  .  ** during the
17960 20 66 65 77 20 6e 61 6e 6f 73 65 63 6f 6e 64 73   few nanoseconds
17970 20 74 68 61 74 20 69 74 20 69 73 20 68 6f 6c 64   that it is hold
17980 69 6e 67 20 74 68 65 20 6c 6f 63 6b 2e 20 20 49  ing the lock.  I
17990 6e 20 74 68 61 74 20 63 61 73 65 2c 0a 20 20 2a  n that case,.  *
179a0 2a 20 69 74 20 6d 69 67 68 74 20 74 61 6b 65 20  * it might take 
179b0 6c 6f 6e 67 65 72 20 74 68 61 6e 20 6e 6f 72 6d  longer than norm
179c0 61 6c 20 66 6f 72 20 74 68 65 20 6c 6f 63 6b 20  al for the lock 
179d0 74 6f 20 66 72 65 65 2e 0a 20 20 2a 2a 0a 20 20  to free..  **.  
179e0 2a 2a 20 41 66 74 65 72 20 35 20 52 45 54 52 59  ** After 5 RETRY
179f0 73 2c 20 77 65 20 62 65 67 69 6e 20 63 61 6c 6c  s, we begin call
17a00 69 6e 67 20 73 71 6c 69 74 65 33 4f 73 53 6c 65  ing sqlite3OsSle
17a10 65 70 28 29 2e 20 20 54 68 65 20 66 69 72 73 74  ep().  The first
17a20 20 66 65 77 0a 20 20 2a 2a 20 63 61 6c 6c 73 20   few.  ** calls 
17a30 74 6f 20 73 71 6c 69 74 65 33 4f 73 53 6c 65 65  to sqlite3OsSlee
17a40 70 28 29 20 68 61 76 65 20 61 20 64 65 6c 61 79  p() have a delay
17a50 20 6f 66 20 31 20 6d 69 63 72 6f 73 65 63 6f 6e   of 1 microsecon
17a60 64 2e 20 20 52 65 61 6c 6c 79 20 74 68 69 73 0a  d.  Really this.
17a70 20 20 2a 2a 20 69 73 20 6d 6f 72 65 20 6f 66 20    ** is more of 
17a80 61 20 73 63 68 65 64 75 6c 65 72 20 79 69 65 6c  a scheduler yiel
17a90 64 20 74 68 61 6e 20 61 6e 20 61 63 74 75 61 6c  d than an actual
17aa0 20 64 65 6c 61 79 2e 20 20 42 75 74 20 6f 6e 20   delay.  But on 
17ab0 74 68 65 20 31 30 74 68 0a 20 20 2a 2a 20 61 6e  the 10th.  ** an
17ac0 20 73 75 62 73 65 71 75 65 6e 74 20 72 65 74 72   subsequent retr
17ad0 69 65 73 2c 20 74 68 65 20 64 65 6c 61 79 73 20  ies, the delays 
17ae0 73 74 61 72 74 20 62 65 63 6f 6d 69 6e 67 20 6c  start becoming l
17af0 6f 6e 67 65 72 20 61 6e 64 20 6c 6f 6e 67 65 72  onger and longer
17b00 2c 20 0a 20 20 2a 2a 20 73 6f 20 74 68 61 74 20  , .  ** so that 
17b10 6f 6e 20 74 68 65 20 31 30 30 74 68 20 28 61 6e  on the 100th (an
17b20 64 20 6c 61 73 74 29 20 52 45 54 52 59 20 77 65  d last) RETRY we
17b30 20 64 65 6c 61 79 20 66 6f 72 20 33 32 33 20 6d   delay for 323 m
17b40 69 6c 6c 69 73 65 63 6f 6e 64 73 2e 0a 20 20 2a  illiseconds..  *
17b50 2a 20 54 68 65 20 74 6f 74 61 6c 20 64 65 6c 61  * The total dela
17b60 79 20 74 69 6d 65 20 62 65 66 6f 72 65 20 67 69  y time before gi
17b70 76 69 6e 67 20 75 70 20 69 73 20 6c 65 73 73 20  ving up is less 
17b80 74 68 61 6e 20 31 30 20 73 65 63 6f 6e 64 73 2e  than 10 seconds.
17b90 0a 20 20 2a 2f 0a 20 20 69 66 28 20 63 6e 74 3e  .  */.  if( cnt>
17ba0 35 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 44 65  5 ){.    int nDe
17bb0 6c 61 79 20 3d 20 31 3b 20 20 20 20 20 20 20 20  lay = 1;        
17bc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
17bd0 20 50 61 75 73 65 20 74 69 6d 65 20 69 6e 20 6d   Pause time in m
17be0 69 63 72 6f 73 65 63 6f 6e 64 73 20 2a 2f 0a 20  icroseconds */. 
17bf0 20 20 20 69 66 28 20 63 6e 74 3e 31 30 30 20 29     if( cnt>100 )
17c00 7b 0a 20 20 20 20 20 20 56 56 41 5f 4f 4e 4c 59  {.      VVA_ONLY
17c10 28 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f  ( pWal->lockErro
17c20 72 20 3d 20 31 3b 20 29 0a 20 20 20 20 20 20 72  r = 1; ).      r
17c30 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 50 52 4f  eturn SQLITE_PRO
17c40 54 4f 43 4f 4c 3b 0a 20 20 20 20 7d 0a 20 20 20  TOCOL;.    }.   
17c50 20 69 66 28 20 63 6e 74 3e 3d 31 30 20 29 20 6e   if( cnt>=10 ) n
17c60 44 65 6c 61 79 20 3d 20 28 63 6e 74 2d 39 29 2a  Delay = (cnt-9)*
17c70 28 63 6e 74 2d 39 29 2a 33 39 3b 0a 20 20 20 20  (cnt-9)*39;.    
17c80 73 71 6c 69 74 65 33 4f 73 53 6c 65 65 70 28 70  sqlite3OsSleep(p
17c90 57 61 6c 2d 3e 70 56 66 73 2c 20 6e 44 65 6c 61  Wal->pVfs, nDela
17ca0 79 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21  y);.  }..  if( !
17cb0 75 73 65 57 61 6c 20 29 7b 0a 20 20 20 20 61 73  useWal ){.    as
17cc0 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45  sert( rc==SQLITE
17cd0 5f 4f 4b 20 29 3b 0a 20 20 20 20 69 66 28 20 70  _OK );.    if( p
17ce0 57 61 6c 2d 3e 62 53 68 6d 55 6e 72 65 6c 69 61  Wal->bShmUnrelia
17cf0 62 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ble==0 ){.      
17d00 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52 65 61  rc = walIndexRea
17d10 64 48 64 72 28 70 57 61 6c 2c 20 70 43 68 61 6e  dHdr(pWal, pChan
17d20 67 65 64 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  ged);.    }.    
17d30 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42  if( rc==SQLITE_B
17d40 55 53 59 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  USY ){.      /* 
17d50 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 74 20  If there is not 
17d60 61 20 72 65 63 6f 76 65 72 79 20 72 75 6e 6e 69  a recovery runni
17d70 6e 67 20 69 6e 20 61 6e 6f 74 68 65 72 20 74 68  ng in another th
17d80 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 0a  read or process.
17d90 20 20 20 20 20 20 2a 2a 20 74 68 65 6e 20 63 6f        ** then co
17da0 6e 76 65 72 74 20 42 55 53 59 20 65 72 72 6f 72  nvert BUSY error
17db0 73 20 74 6f 20 57 41 4c 5f 52 45 54 52 59 2e 20  s to WAL_RETRY. 
17dc0 20 49 66 20 72 65 63 6f 76 65 72 79 20 69 73 20   If recovery is 
17dd0 6b 6e 6f 77 6e 20 74 6f 0a 20 20 20 20 20 20 2a  known to.      *
17de0 2a 20 62 65 20 72 75 6e 6e 69 6e 67 2c 20 63 6f  * be running, co
17df0 6e 76 65 72 74 20 42 55 53 59 20 74 6f 20 42 55  nvert BUSY to BU
17e00 53 59 5f 52 45 43 4f 56 45 52 59 2e 20 20 54 68  SY_RECOVERY.  Th
17e10 65 72 65 20 69 73 20 61 20 72 61 63 65 20 68 65  ere is a race he
17e20 72 65 0a 20 20 20 20 20 20 2a 2a 20 77 68 69 63  re.      ** whic
17e30 68 20 6d 69 67 68 74 20 63 61 75 73 65 20 57 41  h might cause WA
17e40 4c 5f 52 45 54 52 59 20 74 6f 20 62 65 20 72 65  L_RETRY to be re
17e50 74 75 72 6e 65 64 20 65 76 65 6e 20 69 66 20 42  turned even if B
17e60 55 53 59 5f 52 45 43 4f 56 45 52 59 0a 20 20 20  USY_RECOVERY.   
17e70 20 20 20 2a 2a 20 77 6f 75 6c 64 20 62 65 20 74     ** would be t
17e80 65 63 68 6e 69 63 61 6c 6c 79 20 63 6f 72 72 65  echnically corre
17e90 63 74 2e 20 20 42 75 74 20 74 68 65 20 72 61 63  ct.  But the rac
17ea0 65 20 69 73 20 62 65 6e 69 67 6e 20 73 69 6e 63  e is benign sinc
17eb0 65 20 77 69 74 68 0a 20 20 20 20 20 20 2a 2a 20  e with.      ** 
17ec0 57 41 4c 5f 52 45 54 52 59 20 74 68 69 73 20 72  WAL_RETRY this r
17ed0 6f 75 74 69 6e 65 20 77 69 6c 6c 20 62 65 20 63  outine will be c
17ee0 61 6c 6c 65 64 20 61 67 61 69 6e 20 61 6e 64 20  alled again and 
17ef0 77 69 6c 6c 20 70 72 6f 62 61 62 6c 79 20 62 65  will probably be
17f00 0a 20 20 20 20 20 20 2a 2a 20 72 69 67 68 74 20  .      ** right 
17f10 6f 6e 20 74 68 65 20 73 65 63 6f 6e 64 20 69 74  on the second it
17f20 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20 20 20 2a  eration..      *
17f30 2f 0a 20 20 20 20 20 20 69 66 28 20 70 57 61 6c  /.      if( pWal
17f40 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 3d 3d 30  ->apWiData[0]==0
17f50 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 54   ){.        /* T
17f60 68 69 73 20 62 72 61 6e 63 68 20 69 73 20 74 61  his branch is ta
17f70 6b 65 6e 20 77 68 65 6e 20 74 68 65 20 78 53 68  ken when the xSh
17f80 6d 4d 61 70 28 29 20 6d 65 74 68 6f 64 20 72 65  mMap() method re
17f90 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53  turns SQLITE_BUS
17fa0 59 2e 0a 20 20 20 20 20 20 20 20 2a 2a 20 57 65  Y..        ** We
17fb0 20 61 73 73 75 6d 65 20 74 68 69 73 20 69 73 20   assume this is 
17fc0 61 20 74 72 61 6e 73 69 65 6e 74 20 63 6f 6e 64  a transient cond
17fd0 69 74 69 6f 6e 2c 20 73 6f 20 72 65 74 75 72 6e  ition, so return
17fe0 20 57 41 4c 5f 52 45 54 52 59 2e 20 54 68 65 0a   WAL_RETRY. The.
17ff0 20 20 20 20 20 20 20 20 2a 2a 20 78 53 68 6d 4d          ** xShmM
18000 61 70 28 29 20 69 6d 70 6c 65 6d 65 6e 74 61 74  ap() implementat
18010 69 6f 6e 20 75 73 65 64 20 62 79 20 74 68 65 20  ion used by the 
18020 64 65 66 61 75 6c 74 20 75 6e 69 78 20 61 6e 64  default unix and
18030 20 77 69 6e 33 32 20 56 46 53 20 0a 20 20 20 20   win32 VFS .    
18040 20 20 20 20 2a 2a 20 6d 6f 64 75 6c 65 73 20 6d      ** modules m
18050 61 79 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  ay return SQLITE
18060 5f 42 55 53 59 20 64 75 65 20 74 6f 20 61 20 72  _BUSY due to a r
18070 61 63 65 20 63 6f 6e 64 69 74 69 6f 6e 20 69 6e  ace condition in
18080 20 74 68 65 20 0a 20 20 20 20 20 20 20 20 2a 2a   the .        **
18090 20 63 6f 64 65 20 74 68 61 74 20 64 65 74 65 72   code that deter
180a0 6d 69 6e 65 73 20 77 68 65 74 68 65 72 20 6f 72  mines whether or
180b0 20 6e 6f 74 20 74 68 65 20 73 68 61 72 65 64 2d   not the shared-
180c0 6d 65 6d 6f 72 79 20 72 65 67 69 6f 6e 20 0a 20  memory region . 
180d0 20 20 20 20 20 20 20 2a 2a 20 6d 75 73 74 20 62         ** must b
180e0 65 20 7a 65 72 6f 65 64 20 62 65 66 6f 72 65 20  e zeroed before 
180f0 74 68 65 20 72 65 71 75 65 73 74 65 64 20 70 61  the requested pa
18100 67 65 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a  ge is returned..
18110 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20          */.     
18120 20 20 20 72 63 20 3d 20 57 41 4c 5f 52 45 54 52     rc = WAL_RETR
18130 59 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69  Y;.      }else i
18140 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72  f( SQLITE_OK==(r
18150 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65  c = walLockShare
18160 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 43 4f  d(pWal, WAL_RECO
18170 56 45 52 5f 4c 4f 43 4b 29 29 20 29 7b 0a 20 20  VER_LOCK)) ){.  
18180 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53        walUnlockS
18190 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
181a0 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 29 3b 0a 20  RECOVER_LOCK);. 
181b0 20 20 20 20 20 20 20 72 63 20 3d 20 57 41 4c 5f         rc = WAL_
181c0 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 65 6c  RETRY;.      }el
181d0 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  se if( rc==SQLIT
181e0 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20  E_BUSY ){.      
181f0 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55    rc = SQLITE_BU
18200 53 59 5f 52 45 43 4f 56 45 52 59 3b 0a 20 20 20  SY_RECOVERY;.   
18210 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
18220 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
18230 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
18240 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 65   rc;.    }.    e
18250 6c 73 65 20 69 66 28 20 70 57 61 6c 2d 3e 62 53  lse if( pWal->bS
18260 68 6d 55 6e 72 65 6c 69 61 62 6c 65 20 29 7b 0a  hmUnreliable ){.
18270 20 20 20 20 20 20 72 65 74 75 72 6e 20 77 61 6c        return wal
18280 42 65 67 69 6e 53 68 6d 55 6e 72 65 6c 69 61 62  BeginShmUnreliab
18290 6c 65 28 70 57 61 6c 2c 20 70 43 68 61 6e 67 65  le(pWal, pChange
182a0 64 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  d);.    }.  }.. 
182b0 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e   assert( pWal->n
182c0 57 69 44 61 74 61 3e 30 20 29 3b 0a 20 20 61 73  WiData>0 );.  as
182d0 73 65 72 74 28 20 70 57 61 6c 2d 3e 61 70 57 69  sert( pWal->apWi
182e0 44 61 74 61 5b 30 5d 21 3d 30 20 29 3b 0a 20 20  Data[0]!=0 );.  
182f0 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49  pInfo = walCkptI
18300 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 69 66 28  nfo(pWal);.  if(
18310 20 21 75 73 65 57 61 6c 20 26 26 20 70 49 6e 66   !useWal && pInf
18320 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70 57  o->nBackfill==pW
18330 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 0a  al->hdr.mxFrame.
18340 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
18350 41 42 4c 45 5f 53 4e 41 50 53 48 4f 54 0a 20 20  ABLE_SNAPSHOT.  
18360 20 26 26 20 28 70 57 61 6c 2d 3e 70 53 6e 61 70   && (pWal->pSnap
18370 73 68 6f 74 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d  shot==0 || pWal-
18380 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 30 29  >hdr.mxFrame==0)
18390 0a 23 65 6e 64 69 66 0a 20 20 29 7b 0a 20 20 20  .#endif.  ){.   
183a0 20 2f 2a 20 54 68 65 20 57 41 4c 20 68 61 73 20   /* The WAL has 
183b0 62 65 65 6e 20 63 6f 6d 70 6c 65 74 65 6c 79 20  been completely 
183c0 62 61 63 6b 66 69 6c 6c 65 64 20 28 6f 72 20 69  backfilled (or i
183d0 74 20 69 73 20 65 6d 70 74 79 29 2e 0a 20 20 20  t is empty)..   
183e0 20 2a 2a 20 61 6e 64 20 63 61 6e 20 62 65 20 73   ** and can be s
183f0 61 66 65 6c 79 20 69 67 6e 6f 72 65 64 2e 0a 20  afely ignored.. 
18400 20 20 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 77     */.    rc = w
18410 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61  alLockShared(pWa
18420 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  l, WAL_READ_LOCK
18430 28 30 29 29 3b 0a 20 20 20 20 77 61 6c 53 68 6d  (0));.    walShm
18440 42 61 72 72 69 65 72 28 70 57 61 6c 29 3b 0a 20  Barrier(pWal);. 
18450 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
18460 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 66  E_OK ){.      if
18470 28 20 6d 65 6d 63 6d 70 28 28 76 6f 69 64 20 2a  ( memcmp((void *
18480 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61  )walIndexHdr(pWa
18490 6c 29 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c 20  l), &pWal->hdr, 
184a0 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48  sizeof(WalIndexH
184b0 64 72 29 29 20 29 7b 0a 20 20 20 20 20 20 20 20  dr)) ){.        
184c0 2f 2a 20 49 74 20 69 73 20 6e 6f 74 20 73 61 66  /* It is not saf
184d0 65 20 74 6f 20 61 6c 6c 6f 77 20 74 68 65 20 72  e to allow the r
184e0 65 61 64 65 72 20 74 6f 20 63 6f 6e 74 69 6e 75  eader to continu
184f0 65 20 68 65 72 65 20 69 66 20 66 72 61 6d 65 73  e here if frames
18500 0a 20 20 20 20 20 20 20 20 2a 2a 20 6d 61 79 20  .        ** may 
18510 68 61 76 65 20 62 65 65 6e 20 61 70 70 65 6e 64  have been append
18520 65 64 20 74 6f 20 74 68 65 20 6c 6f 67 20 62 65  ed to the log be
18530 66 6f 72 65 20 52 45 41 44 5f 4c 4f 43 4b 28 30  fore READ_LOCK(0
18540 29 20 77 61 73 20 6f 62 74 61 69 6e 65 64 2e 0a  ) was obtained..
18550 20 20 20 20 20 20 20 20 2a 2a 20 57 68 65 6e 20          ** When 
18560 68 6f 6c 64 69 6e 67 20 52 45 41 44 5f 4c 4f 43  holding READ_LOC
18570 4b 28 30 29 2c 20 74 68 65 20 72 65 61 64 65 72  K(0), the reader
18580 20 69 67 6e 6f 72 65 73 20 74 68 65 20 65 6e 74   ignores the ent
18590 69 72 65 20 6c 6f 67 20 66 69 6c 65 2c 0a 20 20  ire log file,.  
185a0 20 20 20 20 20 20 2a 2a 20 77 68 69 63 68 20 69        ** which i
185b0 6d 70 6c 69 65 73 20 74 68 61 74 20 74 68 65 20  mplies that the 
185c0 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 63 6f  database file co
185d0 6e 74 61 69 6e 73 20 61 20 74 72 75 73 74 77 6f  ntains a trustwo
185e0 72 74 68 79 0a 20 20 20 20 20 20 20 20 2a 2a 20  rthy.        ** 
185f0 73 6e 61 70 73 68 6f 74 2e 20 53 69 6e 63 65 20  snapshot. Since 
18600 68 6f 6c 64 69 6e 67 20 52 45 41 44 5f 4c 4f 43  holding READ_LOC
18610 4b 28 30 29 20 70 72 65 76 65 6e 74 73 20 61 20  K(0) prevents a 
18620 63 68 65 63 6b 70 6f 69 6e 74 20 66 72 6f 6d 0a  checkpoint from.
18630 20 20 20 20 20 20 20 20 2a 2a 20 68 61 70 70 65          ** happe
18640 6e 69 6e 67 2c 20 74 68 69 73 20 69 73 20 75 73  ning, this is us
18650 75 61 6c 6c 79 20 63 6f 72 72 65 63 74 2e 0a 20  ually correct.. 
18660 20 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20         **.      
18670 20 20 2a 2a 20 48 6f 77 65 76 65 72 2c 20 69 66    ** However, if
18680 20 66 72 61 6d 65 73 20 68 61 76 65 20 62 65 65   frames have bee
18690 6e 20 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68  n appended to th
186a0 65 20 6c 6f 67 20 28 6f 72 20 69 66 20 74 68 65  e log (or if the
186b0 20 6c 6f 67 20 0a 20 20 20 20 20 20 20 20 2a 2a   log .        **
186c0 20 69 73 20 77 72 61 70 70 65 64 20 61 6e 64 20   is wrapped and 
186d0 77 72 69 74 74 65 6e 20 66 6f 72 20 74 68 61 74  written for that
186e0 20 6d 61 74 74 65 72 29 20 62 65 66 6f 72 65 20   matter) before 
186f0 74 68 65 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29  the READ_LOCK(0)
18700 0a 20 20 20 20 20 20 20 20 2a 2a 20 69 73 20 6f  .        ** is o
18710 62 74 61 69 6e 65 64 2c 20 74 68 61 74 20 69 73  btained, that is
18720 20 6e 6f 74 20 6e 65 63 65 73 73 61 72 69 6c 79   not necessarily
18730 20 74 72 75 65 2e 20 41 20 63 68 65 63 6b 70 6f   true. A checkpo
18740 69 6e 74 65 72 20 6d 61 79 0a 20 20 20 20 20 20  inter may.      
18750 20 20 2a 2a 20 68 61 76 65 20 73 74 61 72 74 65    ** have starte
18760 64 20 74 6f 20 62 61 63 6b 66 69 6c 6c 20 74 68  d to backfill th
18770 65 20 61 70 70 65 6e 64 65 64 20 66 72 61 6d 65  e appended frame
18780 73 20 62 75 74 20 63 72 61 73 68 65 64 20 62 65  s but crashed be
18790 66 6f 72 65 0a 20 20 20 20 20 20 20 20 2a 2a 20  fore.        ** 
187a0 69 74 20 66 69 6e 69 73 68 65 64 2e 20 4c 65 61  it finished. Lea
187b0 76 69 6e 67 20 61 20 63 6f 72 72 75 70 74 20 69  ving a corrupt i
187c0 6d 61 67 65 20 69 6e 20 74 68 65 20 64 61 74 61  mage in the data
187d0 62 61 73 65 20 66 69 6c 65 2e 0a 20 20 20 20 20  base file..     
187e0 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 77 61     */.        wa
187f0 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57  lUnlockShared(pW
18800 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  al, WAL_READ_LOC
18810 4b 28 30 29 29 3b 0a 20 20 20 20 20 20 20 20 72  K(0));.        r
18820 65 74 75 72 6e 20 57 41 4c 5f 52 45 54 52 59 3b  eturn WAL_RETRY;
18830 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70  .      }.      p
18840 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20  Wal->readLock = 
18850 30 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  0;.      return 
18860 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d  SQLITE_OK;.    }
18870 65 6c 73 65 20 69 66 28 20 72 63 21 3d 53 51 4c  else if( rc!=SQL
18880 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20  ITE_BUSY ){.    
18890 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20    return rc;.   
188a0 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20   }.  }..  /* If 
188b0 77 65 20 67 65 74 20 74 68 69 73 20 66 61 72 2c  we get this far,
188c0 20 69 74 20 6d 65 61 6e 73 20 74 68 61 74 20 74   it means that t
188d0 68 65 20 72 65 61 64 65 72 20 77 69 6c 6c 20 77  he reader will w
188e0 61 6e 74 20 74 6f 20 75 73 65 0a 20 20 2a 2a 20  ant to use.  ** 
188f0 74 68 65 20 57 41 4c 20 74 6f 20 67 65 74 20 61  the WAL to get a
18900 74 20 63 6f 6e 74 65 6e 74 20 66 72 6f 6d 20 72  t content from r
18910 65 63 65 6e 74 20 63 6f 6d 6d 69 74 73 2e 20 20  ecent commits.  
18920 54 68 65 20 6a 6f 62 20 6e 6f 77 20 69 73 0a 20  The job now is. 
18930 20 2a 2a 20 74 6f 20 73 65 6c 65 63 74 20 6f 6e   ** to select on
18940 65 20 6f 66 20 74 68 65 20 61 52 65 61 64 4d 61  e of the aReadMa
18950 72 6b 5b 5d 20 65 6e 74 72 69 65 73 20 74 68 61  rk[] entries tha
18960 74 20 69 73 20 63 6c 6f 73 65 73 74 20 74 6f 0a  t is closest to.
18970 20 20 2a 2a 20 62 75 74 20 6e 6f 74 20 65 78 63    ** but not exc
18980 65 65 64 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72  eeding pWal->hdr
18990 2e 6d 78 46 72 61 6d 65 20 61 6e 64 20 6c 6f 63  .mxFrame and loc
189a0 6b 20 74 68 61 74 20 65 6e 74 72 79 2e 0a 20 20  k that entry..  
189b0 2a 2f 0a 20 20 6d 78 52 65 61 64 4d 61 72 6b 20  */.  mxReadMark 
189c0 3d 20 30 3b 0a 20 20 6d 78 49 20 3d 20 30 3b 0a  = 0;.  mxI = 0;.
189d0 20 20 6d 78 46 72 61 6d 65 20 3d 20 70 57 61 6c    mxFrame = pWal
189e0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 23  ->hdr.mxFrame;.#
189f0 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41  ifdef SQLITE_ENA
18a00 42 4c 45 5f 53 4e 41 50 53 48 4f 54 0a 20 20 69  BLE_SNAPSHOT.  i
18a10 66 28 20 70 57 61 6c 2d 3e 70 53 6e 61 70 73 68  f( pWal->pSnapsh
18a20 6f 74 20 26 26 20 70 57 61 6c 2d 3e 70 53 6e 61  ot && pWal->pSna
18a30 70 73 68 6f 74 2d 3e 6d 78 46 72 61 6d 65 3c 6d  pshot->mxFrame<m
18a40 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 6d 78  xFrame ){.    mx
18a50 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 70 53  Frame = pWal->pS
18a60 6e 61 70 73 68 6f 74 2d 3e 6d 78 46 72 61 6d 65  napshot->mxFrame
18a70 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 66  ;.  }.#endif.  f
18a80 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52  or(i=1; i<WAL_NR
18a90 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20  EADER; i++){.   
18aa0 20 75 33 32 20 74 68 69 73 4d 61 72 6b 20 3d 20   u32 thisMark = 
18ab0 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b  pInfo->aReadMark
18ac0 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 6d 78 52  [i];.    if( mxR
18ad0 65 61 64 4d 61 72 6b 3c 3d 74 68 69 73 4d 61 72  eadMark<=thisMar
18ae0 6b 20 26 26 20 74 68 69 73 4d 61 72 6b 3c 3d 6d  k && thisMark<=m
18af0 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 20 20  xFrame ){.      
18b00 61 73 73 65 72 74 28 20 74 68 69 73 4d 61 72 6b  assert( thisMark
18b10 21 3d 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55  !=READMARK_NOT_U
18b20 53 45 44 20 29 3b 0a 20 20 20 20 20 20 6d 78 52  SED );.      mxR
18b30 65 61 64 4d 61 72 6b 20 3d 20 74 68 69 73 4d 61  eadMark = thisMa
18b40 72 6b 3b 0a 20 20 20 20 20 20 6d 78 49 20 3d 20  rk;.      mxI = 
18b50 69 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  i;.    }.  }.  i
18b60 66 28 20 28 70 57 61 6c 2d 3e 72 65 61 64 4f 6e  f( (pWal->readOn
18b70 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  ly & WAL_SHM_RDO
18b80 4e 4c 59 29 3d 3d 30 0a 20 20 20 26 26 20 28 6d  NLY)==0.   && (m
18b90 78 52 65 61 64 4d 61 72 6b 3c 6d 78 46 72 61 6d  xReadMark<mxFram
18ba0 65 20 7c 7c 20 6d 78 49 3d 3d 30 29 0a 20 20 29  e || mxI==0).  )
18bb0 7b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69  {.    for(i=1; i
18bc0 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b  <WAL_NREADER; i+
18bd0 2b 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 77  +){.      rc = w
18be0 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  alLockExclusive(
18bf0 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  pWal, WAL_READ_L
18c00 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20 20  OCK(i), 1);.    
18c10 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
18c20 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 6d  _OK ){.        m
18c30 78 52 65 61 64 4d 61 72 6b 20 3d 20 70 49 6e 66  xReadMark = pInf
18c40 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20  o->aReadMark[i] 
18c50 3d 20 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 20  = mxFrame;.     
18c60 20 20 20 6d 78 49 20 3d 20 69 3b 0a 20 20 20 20     mxI = i;.    
18c70 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63      walUnlockExc
18c80 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
18c90 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31  _READ_LOCK(i), 1
18ca0 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  );.        break
18cb0 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  ;.      }else if
18cc0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc!=SQLITE_BUS
18cd0 59 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74  Y ){.        ret
18ce0 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a  urn rc;.      }.
18cf0 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20      }.  }.  if( 
18d00 6d 78 49 3d 3d 30 20 29 7b 0a 20 20 20 20 61 73  mxI==0 ){.    as
18d10 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45  sert( rc==SQLITE
18d20 5f 42 55 53 59 20 7c 7c 20 28 70 57 61 6c 2d 3e  _BUSY || (pWal->
18d30 72 65 61 64 4f 6e 6c 79 20 26 20 57 41 4c 5f 53  readOnly & WAL_S
18d40 48 4d 5f 52 44 4f 4e 4c 59 29 21 3d 30 20 29 3b  HM_RDONLY)!=0 );
18d50 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d  .    return rc==
18d60 53 51 4c 49 54 45 5f 42 55 53 59 20 3f 20 57 41  SQLITE_BUSY ? WA
18d70 4c 5f 52 45 54 52 59 20 3a 20 53 51 4c 49 54 45  L_RETRY : SQLITE
18d80 5f 52 45 41 44 4f 4e 4c 59 5f 43 41 4e 54 49 4e  _READONLY_CANTIN
18d90 49 54 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20  IT;.  }..  rc = 
18da0 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57  walLockShared(pW
18db0 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  al, WAL_READ_LOC
18dc0 4b 28 6d 78 49 29 29 3b 0a 20 20 69 66 28 20 72  K(mxI));.  if( r
18dd0 63 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  c ){.    return 
18de0 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc==SQLITE_BUSY 
18df0 3f 20 57 41 4c 5f 52 45 54 52 59 20 3a 20 72 63  ? WAL_RETRY : rc
18e00 3b 0a 20 20 7d 0a 20 20 2f 2a 20 4e 6f 77 20 74  ;.  }.  /* Now t
18e10 68 61 74 20 74 68 65 20 72 65 61 64 2d 6c 6f 63  hat the read-loc
18e20 6b 20 68 61 73 20 62 65 65 6e 20 6f 62 74 61 69  k has been obtai
18e30 6e 65 64 2c 20 63 68 65 63 6b 20 74 68 61 74 20  ned, check that 
18e40 6e 65 69 74 68 65 72 20 74 68 65 0a 20 20 2a 2a  neither the.  **
18e50 20 76 61 6c 75 65 20 69 6e 20 74 68 65 20 61 52   value in the aR
18e60 65 61 64 4d 61 72 6b 5b 5d 20 61 72 72 61 79 20  eadMark[] array 
18e70 6f 72 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  or the contents 
18e80 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
18e90 0a 20 20 2a 2a 20 68 65 61 64 65 72 20 68 61 76  .  ** header hav
18ea0 65 20 63 68 61 6e 67 65 64 2e 0a 20 20 2a 2a 0a  e changed..  **.
18eb0 20 20 2a 2a 20 49 74 20 69 73 20 6e 65 63 65 73    ** It is neces
18ec0 73 61 72 79 20 74 6f 20 63 68 65 63 6b 20 74 68  sary to check th
18ed0 61 74 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  at the wal-index
18ee0 20 68 65 61 64 65 72 20 64 69 64 20 6e 6f 74 20   header did not 
18ef0 63 68 61 6e 67 65 0a 20 20 2a 2a 20 62 65 74 77  change.  ** betw
18f00 65 65 6e 20 74 68 65 20 74 69 6d 65 20 69 74 20  een the time it 
18f10 77 61 73 20 72 65 61 64 20 61 6e 64 20 77 68 65  was read and whe
18f20 6e 20 74 68 65 20 73 68 61 72 65 64 2d 6c 6f 63  n the shared-loc
18f30 6b 20 77 61 73 20 6f 62 74 61 69 6e 65 64 0a 20  k was obtained. 
18f40 20 2a 2a 20 6f 6e 20 57 41 4c 5f 52 45 41 44 5f   ** on WAL_READ_
18f50 4c 4f 43 4b 28 6d 78 49 29 20 77 61 73 20 6f 62  LOCK(mxI) was ob
18f60 74 61 69 6e 65 64 20 74 6f 20 61 63 63 6f 75 6e  tained to accoun
18f70 74 20 66 6f 72 20 74 68 65 20 70 6f 73 73 69 62  t for the possib
18f80 69 6c 69 74 79 0a 20 20 2a 2a 20 74 68 61 74 20  ility.  ** that 
18f90 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 6d 61 79  the log file may
18fa0 20 68 61 76 65 20 62 65 65 6e 20 77 72 61 70 70   have been wrapp
18fb0 65 64 20 62 79 20 61 20 77 72 69 74 65 72 2c 20  ed by a writer, 
18fc0 6f 72 20 74 68 61 74 20 66 72 61 6d 65 73 0a 20  or that frames. 
18fd0 20 2a 2a 20 74 68 61 74 20 6f 63 63 75 72 20 6c   ** that occur l
18fe0 61 74 65 72 20 69 6e 20 74 68 65 20 6c 6f 67 20  ater in the log 
18ff0 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  than pWal->hdr.m
19000 78 46 72 61 6d 65 20 6d 61 79 20 68 61 76 65 20  xFrame may have 
19010 62 65 65 6e 0a 20 20 2a 2a 20 63 6f 70 69 65 64  been.  ** copied
19020 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
19030 73 65 20 62 79 20 61 20 63 68 65 63 6b 70 6f 69  se by a checkpoi
19040 6e 74 65 72 2e 20 49 66 20 65 69 74 68 65 72 20  nter. If either 
19050 6f 66 20 74 68 65 73 65 20 74 68 69 6e 67 73 0a  of these things.
19060 20 20 2a 2a 20 68 61 70 70 65 6e 65 64 2c 20 74    ** happened, t
19070 68 65 6e 20 72 65 61 64 69 6e 67 20 74 68 65 20  hen reading the 
19080 64 61 74 61 62 61 73 65 20 77 69 74 68 20 74 68  database with th
19090 65 20 63 75 72 72 65 6e 74 20 76 61 6c 75 65 20  e current value 
190a0 6f 66 0a 20 20 2a 2a 20 70 57 61 6c 2d 3e 68 64  of.  ** pWal->hd
190b0 72 2e 6d 78 46 72 61 6d 65 20 72 69 73 6b 73 20  r.mxFrame risks 
190c0 72 65 61 64 69 6e 67 20 61 20 63 6f 72 72 75 70  reading a corrup
190d0 74 65 64 20 73 6e 61 70 73 68 6f 74 2e 20 53 6f  ted snapshot. So
190e0 2c 20 72 65 74 72 79 0a 20 20 2a 2a 20 69 6e 73  , retry.  ** ins
190f0 74 65 61 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20  tead..  **.  ** 
19100 42 65 66 6f 72 65 20 63 68 65 63 6b 69 6e 67 20  Before checking 
19110 74 68 61 74 20 74 68 65 20 6c 69 76 65 20 77 61  that the live wa
19120 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 68  l-index header h
19130 61 73 20 6e 6f 74 20 63 68 61 6e 67 65 64 0a 20  as not changed. 
19140 20 2a 2a 20 73 69 6e 63 65 20 69 74 20 77 61 73   ** since it was
19150 20 72 65 61 64 2c 20 73 65 74 20 57 61 6c 2e 6d   read, set Wal.m
19160 69 6e 46 72 61 6d 65 20 74 6f 20 74 68 65 20 66  inFrame to the f
19170 69 72 73 74 20 66 72 61 6d 65 20 69 6e 20 74 68  irst frame in th
19180 65 20 77 61 6c 0a 20 20 2a 2a 20 66 69 6c 65 20  e wal.  ** file 
19190 74 68 61 74 20 68 61 73 20 6e 6f 74 20 79 65 74  that has not yet
191a0 20 62 65 65 6e 20 63 68 65 63 6b 70 6f 69 6e 74   been checkpoint
191b0 65 64 2e 20 54 68 69 73 20 63 6c 69 65 6e 74 20  ed. This client 
191c0 77 69 6c 6c 20 6e 6f 74 20 6e 65 65 64 0a 20 20  will not need.  
191d0 2a 2a 20 74 6f 20 72 65 61 64 20 61 6e 79 20 66  ** to read any f
191e0 72 61 6d 65 73 20 65 61 72 6c 69 65 72 20 74 68  rames earlier th
191f0 61 6e 20 6d 69 6e 46 72 61 6d 65 20 66 72 6f 6d  an minFrame from
19200 20 74 68 65 20 77 61 6c 20 66 69 6c 65 20 2d 20   the wal file - 
19210 74 68 65 79 0a 20 20 2a 2a 20 63 61 6e 20 62 65  they.  ** can be
19220 20 73 61 66 65 6c 79 20 72 65 61 64 20 64 69 72   safely read dir
19230 65 63 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64  ectly from the d
19240 61 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 20 20  atabase file..  
19250 2a 2a 0a 20 20 2a 2a 20 42 65 63 61 75 73 65 20  **.  ** Because 
19260 61 20 53 68 6d 42 61 72 72 69 65 72 28 29 20 63  a ShmBarrier() c
19270 61 6c 6c 20 69 73 20 6d 61 64 65 20 62 65 74 77  all is made betw
19280 65 65 6e 20 74 61 6b 69 6e 67 20 74 68 65 20 63  een taking the c
19290 6f 70 79 20 6f 66 20 0a 20 20 2a 2a 20 6e 42 61  opy of .  ** nBa
192a0 63 6b 66 69 6c 6c 20 61 6e 64 20 63 68 65 63 6b  ckfill and check
192b0 69 6e 67 20 74 68 61 74 20 74 68 65 20 77 61 6c  ing that the wal
192c0 2d 68 65 61 64 65 72 20 69 6e 20 73 68 61 72 65  -header in share
192d0 64 2d 6d 65 6d 6f 72 79 20 73 74 69 6c 6c 0a 20  d-memory still. 
192e0 20 2a 2a 20 6d 61 74 63 68 65 73 20 74 68 65 20   ** matches the 
192f0 6f 6e 65 20 63 61 63 68 65 64 20 69 6e 20 70 57  one cached in pW
19300 61 6c 2d 3e 68 64 72 2c 20 69 74 20 69 73 20 67  al->hdr, it is g
19310 75 61 72 61 6e 74 65 65 64 20 74 68 61 74 20 74  uaranteed that t
19320 68 65 20 0a 20 20 2a 2a 20 63 68 65 63 6b 70 6f  he .  ** checkpo
19330 69 6e 74 65 72 20 74 68 61 74 20 73 65 74 20 6e  inter that set n
19340 42 61 63 6b 66 69 6c 6c 20 77 61 73 20 6e 6f 74  Backfill was not
19350 20 77 6f 72 6b 69 6e 67 20 77 69 74 68 20 61 20   working with a 
19360 77 61 6c 2d 69 6e 64 65 78 0a 20 20 2a 2a 20 68  wal-index.  ** h
19370 65 61 64 65 72 20 6e 65 77 65 72 20 74 68 61 6e  eader newer than
19380 20 74 68 61 74 20 63 61 63 68 65 64 20 69 6e 20   that cached in 
19390 70 57 61 6c 2d 3e 68 64 72 2e 20 49 66 20 69 74  pWal->hdr. If it
193a0 20 77 65 72 65 2c 20 74 68 61 74 20 63 6f 75 6c   were, that coul
193b0 64 0a 20 20 2a 2a 20 63 61 75 73 65 20 61 20 70  d.  ** cause a p
193c0 72 6f 62 6c 65 6d 2e 20 54 68 65 20 63 68 65 63  roblem. The chec
193d0 6b 70 6f 69 6e 74 65 72 20 63 6f 75 6c 64 20 6f  kpointer could o
193e0 6d 69 74 20 74 6f 20 63 68 65 63 6b 70 6f 69 6e  mit to checkpoin
193f0 74 0a 20 20 2a 2a 20 61 20 76 65 72 73 69 6f 6e  t.  ** a version
19400 20 6f 66 20 70 61 67 65 20 58 20 74 68 61 74 20   of page X that 
19410 6c 69 65 73 20 62 65 66 6f 72 65 20 70 57 61 6c  lies before pWal
19420 2d 3e 6d 69 6e 46 72 61 6d 65 20 28 63 61 6c 6c  ->minFrame (call
19430 20 74 68 61 74 20 76 65 72 73 69 6f 6e 0a 20 20   that version.  
19440 2a 2a 20 41 29 20 6f 6e 20 74 68 65 20 62 61 73  ** A) on the bas
19450 69 73 20 74 68 61 74 20 74 68 65 72 65 20 69 73  is that there is
19460 20 61 20 6e 65 77 65 72 20 76 65 72 73 69 6f 6e   a newer version
19470 20 28 76 65 72 73 69 6f 6e 20 42 29 20 6f 66 20   (version B) of 
19480 74 68 65 20 73 61 6d 65 0a 20 20 2a 2a 20 70 61  the same.  ** pa
19490 67 65 20 6c 61 74 65 72 20 69 6e 20 74 68 65 20  ge later in the 
194a0 77 61 6c 20 66 69 6c 65 2e 20 42 75 74 20 69 66  wal file. But if
194b0 20 76 65 72 73 69 6f 6e 20 42 20 68 61 70 70 65   version B happe
194c0 6e 73 20 74 6f 20 6c 69 6b 65 20 70 61 73 74 0a  ns to like past.
194d0 20 20 2a 2a 20 66 72 61 6d 65 20 70 57 61 6c 2d    ** frame pWal-
194e0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 2d 20 74  >hdr.mxFrame - t
194f0 68 65 6e 20 74 68 65 20 63 6c 69 65 6e 74 20 77  hen the client w
19500 6f 75 6c 64 20 69 6e 63 6f 72 72 65 63 74 6c 79  ould incorrectly
19510 20 61 73 73 75 6d 65 0a 20 20 2a 2a 20 74 68 61   assume.  ** tha
19520 74 20 69 74 20 63 61 6e 20 72 65 61 64 20 76 65  t it can read ve
19530 72 73 69 6f 6e 20 41 20 66 72 6f 6d 20 74 68 65  rsion A from the
19540 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 20   database file. 
19550 48 6f 77 65 76 65 72 2c 20 73 69 6e 63 65 0a 20  However, since. 
19560 20 2a 2a 20 77 65 20 63 61 6e 20 67 75 61 72 61   ** we can guara
19570 6e 74 65 65 20 74 68 61 74 20 74 68 65 20 63 68  ntee that the ch
19580 65 63 6b 70 6f 69 6e 74 65 72 20 74 68 61 74 20  eckpointer that 
19590 73 65 74 20 6e 42 61 63 6b 66 69 6c 6c 20 63 6f  set nBackfill co
195a0 75 6c 64 20 6e 6f 74 0a 20 20 2a 2a 20 73 65 65  uld not.  ** see
195b0 20 61 6e 79 20 70 61 67 65 73 20 70 61 73 74 20   any pages past 
195c0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
195d0 65 2c 20 74 68 69 73 20 70 72 6f 62 6c 65 6d 20  e, this problem 
195e0 64 6f 65 73 20 6e 6f 74 20 63 6f 6d 65 20 75 70  does not come up
195f0 2e 0a 20 20 2a 2f 0a 20 20 70 57 61 6c 2d 3e 6d  ..  */.  pWal->m
19600 69 6e 46 72 61 6d 65 20 3d 20 70 49 6e 66 6f 2d  inFrame = pInfo-
19610 3e 6e 42 61 63 6b 66 69 6c 6c 2b 31 3b 0a 20 20  >nBackfill+1;.  
19620 77 61 6c 53 68 6d 42 61 72 72 69 65 72 28 70 57  walShmBarrier(pW
19630 61 6c 29 3b 0a 20 20 69 66 28 20 70 49 6e 66 6f  al);.  if( pInfo
19640 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 6d 78 49 5d  ->aReadMark[mxI]
19650 21 3d 6d 78 52 65 61 64 4d 61 72 6b 0a 20 20 20  !=mxReadMark.   
19660 7c 7c 20 6d 65 6d 63 6d 70 28 28 76 6f 69 64 20  || memcmp((void 
19670 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57  *)walIndexHdr(pW
19680 61 6c 29 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c  al), &pWal->hdr,
19690 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
196a0 48 64 72 29 29 0a 20 20 29 7b 0a 20 20 20 20 77  Hdr)).  ){.    w
196b0 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70  alUnlockShared(p
196c0 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
196d0 43 4b 28 6d 78 49 29 29 3b 0a 20 20 20 20 72 65  CK(mxI));.    re
196e0 74 75 72 6e 20 57 41 4c 5f 52 45 54 52 59 3b 0a  turn WAL_RETRY;.
196f0 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73    }else{.    ass
19700 65 72 74 28 20 6d 78 52 65 61 64 4d 61 72 6b 3c  ert( mxReadMark<
19710 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  =pWal->hdr.mxFra
19720 6d 65 20 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  me );.    pWal->
19730 72 65 61 64 4c 6f 63 6b 20 3d 20 28 69 31 36 29  readLock = (i16)
19740 6d 78 49 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  mxI;.  }.  retur
19750 6e 20 72 63 3b 0a 7d 0a 0a 23 69 66 64 65 66 20  n rc;.}..#ifdef 
19760 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e  SQLITE_ENABLE_SN
19770 41 50 53 48 4f 54 0a 2f 2a 0a 2a 2a 20 41 74 74  APSHOT./*.** Att
19780 65 6d 70 74 20 74 6f 20 72 65 64 75 63 65 20 74  empt to reduce t
19790 68 65 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20  he value of the 
197a0 57 61 6c 43 6b 70 74 49 6e 66 6f 2e 6e 42 61 63  WalCkptInfo.nBac
197b0 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 0a  kfillAttempted .
197c0 2a 2a 20 76 61 72 69 61 62 6c 65 20 73 6f 20 74  ** variable so t
197d0 68 61 74 20 6f 6c 64 65 72 20 73 6e 61 70 73 68  hat older snapsh
197e0 6f 74 73 20 63 61 6e 20 62 65 20 61 63 63 65 73  ots can be acces
197f0 73 65 64 2e 20 54 6f 20 64 6f 20 74 68 69 73 2c  sed. To do this,
19800 20 6c 6f 6f 70 0a 2a 2a 20 74 68 72 6f 75 67 68   loop.** through
19810 20 61 6c 6c 20 77 61 6c 20 66 72 61 6d 65 73 20   all wal frames 
19820 66 72 6f 6d 20 6e 42 61 63 6b 66 69 6c 6c 41 74  from nBackfillAt
19830 74 65 6d 70 74 65 64 20 74 6f 20 28 6e 42 61 63  tempted to (nBac
19840 6b 66 69 6c 6c 2b 31 29 2c 20 0a 2a 2a 20 63 6f  kfill+1), .** co
19850 6d 70 61 72 69 6e 67 20 74 68 65 69 72 20 63 6f  mparing their co
19860 6e 74 65 6e 74 20 74 6f 20 74 68 65 20 63 6f 72  ntent to the cor
19870 72 65 73 70 6f 6e 64 69 6e 67 20 70 61 67 65 20  responding page 
19880 77 69 74 68 20 74 68 65 20 64 61 74 61 62 61 73  with the databas
19890 65 0a 2a 2a 20 66 69 6c 65 2c 20 69 66 20 61 6e  e.** file, if an
198a0 79 2e 20 53 65 74 20 6e 42 61 63 6b 66 69 6c 6c  y. Set nBackfill
198b0 41 74 74 65 6d 70 74 65 64 20 74 6f 20 74 68 65  Attempted to the
198c0 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 6f 66   frame number of
198d0 20 74 68 65 0a 2a 2a 20 66 69 72 73 74 20 66 72   the.** first fr
198e0 61 6d 65 20 66 6f 72 20 77 68 69 63 68 20 74 68  ame for which th
198f0 65 20 77 61 6c 20 66 69 6c 65 20 63 6f 6e 74 65  e wal file conte
19900 6e 74 20 6d 61 74 63 68 65 73 20 74 68 65 20 64  nt matches the d
19910 62 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68  b file..**.** Th
19920 69 73 20 69 73 20 6f 6e 6c 79 20 72 65 61 6c 6c  is is only reall
19930 79 20 73 61 66 65 20 69 66 20 74 68 65 20 66 69  y safe if the fi
19940 6c 65 2d 73 79 73 74 65 6d 20 69 73 20 73 75 63  le-system is suc
19950 68 20 74 68 61 74 20 61 6e 79 20 70 61 67 65 20  h that any page 
19960 0a 2a 2a 20 77 72 69 74 65 73 20 6d 61 64 65 20  .** writes made 
19970 62 79 20 65 61 72 6c 69 65 72 20 63 68 65 63 6b  by earlier check
19980 70 6f 69 6e 74 65 72 73 20 77 65 72 65 20 61 74  pointers were at
19990 6f 6d 69 63 20 6f 70 65 72 61 74 69 6f 6e 73 2c  omic operations,
199a0 20 77 68 69 63 68 20 0a 2a 2a 20 69 73 20 6e 6f   which .** is no
199b0 74 20 61 6c 77 61 79 73 20 74 72 75 65 2e 20 49  t always true. I
199c0 74 20 69 73 20 61 6c 73 6f 20 70 6f 73 73 69 62  t is also possib
199d0 6c 65 20 74 68 61 74 20 6e 42 61 63 6b 66 69 6c  le that nBackfil
199e0 6c 41 74 74 65 6d 70 74 65 64 0a 2a 2a 20 6d 61  lAttempted.** ma
199f0 79 20 62 65 20 6c 65 66 74 20 73 65 74 20 74 6f  y be left set to
19a00 20 61 20 76 61 6c 75 65 20 6c 61 72 67 65 72 20   a value larger 
19a10 74 68 61 6e 20 65 78 70 65 63 74 65 64 2c 20 69  than expected, i
19a20 66 20 61 20 77 61 6c 20 66 72 61 6d 65 0a 2a 2a  f a wal frame.**
19a30 20 63 6f 6e 74 61 69 6e 73 20 63 6f 6e 74 65 6e   contains conten
19a40 74 20 74 68 61 74 20 64 75 70 6c 69 63 61 74 65  t that duplicate
19a50 20 6f 66 20 61 6e 20 65 61 72 6c 69 65 72 20 76   of an earlier v
19a60 65 72 73 69 6f 6e 20 6f 66 20 74 68 65 20 73 61  ersion of the sa
19a70 6d 65 0a 2a 2a 20 70 61 67 65 2e 0a 2a 2a 0a 2a  me.** page..**.*
19a80 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  * SQLITE_OK is r
19a90 65 74 75 72 6e 65 64 20 69 66 20 73 75 63 63 65  eturned if succe
19aa0 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c  ssful, or an SQL
19ab0 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
19ac0 66 20 61 6e 0a 2a 2a 20 65 72 72 6f 72 20 6f 63  f an.** error oc
19ad0 63 75 72 73 2e 20 49 74 20 69 73 20 6e 6f 74 20  curs. It is not 
19ae0 61 6e 20 65 72 72 6f 72 20 69 66 20 6e 42 61 63  an error if nBac
19af0 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 63  kfillAttempted c
19b00 61 6e 6e 6f 74 20 62 65 0a 2a 2a 20 64 65 63 72  annot be.** decr
19b10 65 61 73 65 64 20 61 74 20 61 6c 6c 2e 0a 2a 2f  eased at all..*/
19b20 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 53  .int sqlite3WalS
19b30 6e 61 70 73 68 6f 74 52 65 63 6f 76 65 72 28 57  napshotRecover(W
19b40 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74  al *pWal){.  int
19b50 20 72 63 3b 0a 0a 20 20 61 73 73 65 72 74 28 20   rc;..  assert( 
19b60 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
19b70 30 20 29 3b 0a 20 20 72 63 20 3d 20 77 61 6c 4c  0 );.  rc = walL
19b80 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
19b90 6c 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b  l, WAL_CKPT_LOCK
19ba0 2c 20 31 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  , 1);.  if( rc==
19bb0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
19bc0 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70   volatile WalCkp
19bd0 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 20 3d 20 77  tInfo *pInfo = w
19be0 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29  alCkptInfo(pWal)
19bf0 3b 0a 20 20 20 20 69 6e 74 20 73 7a 50 61 67 65  ;.    int szPage
19c00 20 3d 20 28 69 6e 74 29 70 57 61 6c 2d 3e 73 7a   = (int)pWal->sz
19c10 50 61 67 65 3b 0a 20 20 20 20 69 36 34 20 73 7a  Page;.    i64 sz
19c20 44 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  Db;             
19c30 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
19c40 20 64 62 20 66 69 6c 65 20 69 6e 20 62 79 74 65   db file in byte
19c50 73 20 2a 2f 0a 0a 20 20 20 20 72 63 20 3d 20 73  s */..    rc = s
19c60 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a 65  qlite3OsFileSize
19c70 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 26 73  (pWal->pDbFd, &s
19c80 7a 44 62 29 3b 0a 20 20 20 20 69 66 28 20 72 63  zDb);.    if( rc
19c90 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
19ca0 20 20 20 20 20 76 6f 69 64 20 2a 70 42 75 66 31       void *pBuf1
19cb0 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   = sqlite3_mallo
19cc0 63 28 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 20  c(szPage);.     
19cd0 20 76 6f 69 64 20 2a 70 42 75 66 32 20 3d 20 73   void *pBuf2 = s
19ce0 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 7a  qlite3_malloc(sz
19cf0 50 61 67 65 29 3b 0a 20 20 20 20 20 20 69 66 28  Page);.      if(
19d00 20 70 42 75 66 31 3d 3d 30 20 7c 7c 20 70 42 75   pBuf1==0 || pBu
19d10 66 32 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  f2==0 ){.       
19d20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
19d30 45 4d 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  EM;.      }else{
19d40 0a 20 20 20 20 20 20 20 20 75 33 32 20 69 20 3d  .        u32 i =
19d50 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
19d60 6c 41 74 74 65 6d 70 74 65 64 3b 0a 20 20 20 20  lAttempted;.    
19d70 20 20 20 20 66 6f 72 28 69 3d 70 49 6e 66 6f 2d      for(i=pInfo-
19d80 3e 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70  >nBackfillAttemp
19d90 74 65 64 3b 20 69 3e 70 49 6e 66 6f 2d 3e 6e 42  ted; i>pInfo->nB
19da0 61 63 6b 66 69 6c 6c 3b 20 69 2d 2d 29 7b 0a 20  ackfill; i--){. 
19db0 20 20 20 20 20 20 20 20 20 76 6f 6c 61 74 69 6c           volatil
19dc0 65 20 68 74 5f 73 6c 6f 74 20 2a 64 75 6d 6d 79  e ht_slot *dummy
19dd0 3b 0a 20 20 20 20 20 20 20 20 20 20 76 6f 6c 61  ;.          vola
19de0 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 3b  tile u32 *aPgno;
19df0 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
19e00 66 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20 2a  f page numbers *
19e10 2f 0a 20 20 20 20 20 20 20 20 20 20 75 33 32 20  /.          u32 
19e20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20 20  iZero;          
19e30 20 20 20 20 20 20 2f 2a 20 46 72 61 6d 65 20 63        /* Frame c
19e40 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20  orresponding to 
19e50 61 50 67 6e 6f 5b 30 5d 20 2a 2f 0a 20 20 20 20  aPgno[0] */.    
19e60 20 20 20 20 20 20 75 33 32 20 70 67 6e 6f 3b 20        u32 pgno; 
19e70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19e80 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20 69  /* Page number i
19e90 6e 20 64 62 20 66 69 6c 65 20 2a 2f 0a 20 20 20  n db file */.   
19ea0 20 20 20 20 20 20 20 69 36 34 20 69 44 62 4f 66         i64 iDbOf
19eb0 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f;              
19ec0 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 64 62   /* Offset of db
19ed0 20 66 69 6c 65 20 65 6e 74 72 79 20 2a 2f 0a 20   file entry */. 
19ee0 20 20 20 20 20 20 20 20 20 69 36 34 20 69 57 61           i64 iWa
19ef0 6c 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20 20  lOff;           
19f00 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20     /* Offset of 
19f10 77 61 6c 20 66 69 6c 65 20 65 6e 74 72 79 20 2a  wal file entry *
19f20 2f 0a 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  /..          rc 
19f30 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70 57 61  = walHashGet(pWa
19f40 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28  l, walFramePage(
19f50 69 29 2c 20 26 64 75 6d 6d 79 2c 20 26 61 50 67  i), &dummy, &aPg
19f60 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 20 20 20  no, &iZero);.   
19f70 20 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53         if( rc!=S
19f80 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
19f90 3b 0a 20 20 20 20 20 20 20 20 20 20 70 67 6e 6f  ;.          pgno
19fa0 20 3d 20 61 50 67 6e 6f 5b 69 2d 69 5a 65 72 6f   = aPgno[i-iZero
19fb0 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 69 44 62  ];.          iDb
19fc0 4f 66 66 20 3d 20 28 69 36 34 29 28 70 67 6e 6f  Off = (i64)(pgno
19fd0 2d 31 29 20 2a 20 73 7a 50 61 67 65 3b 0a 0a 20  -1) * szPage;.. 
19fe0 20 20 20 20 20 20 20 20 20 69 66 28 20 69 44 62           if( iDb
19ff0 4f 66 66 2b 73 7a 50 61 67 65 3c 3d 73 7a 44 62  Off+szPage<=szDb
1a000 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
1a010 69 57 61 6c 4f 66 66 20 3d 20 77 61 6c 46 72 61  iWalOff = walFra
1a020 6d 65 4f 66 66 73 65 74 28 69 2c 20 73 7a 50 61  meOffset(i, szPa
1a030 67 65 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  ge) + WAL_FRAME_
1a040 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 20 20 20  HDRSIZE;.       
1a050 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
1a060 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57  3OsRead(pWal->pW
1a070 61 6c 46 64 2c 20 70 42 75 66 31 2c 20 73 7a 50  alFd, pBuf1, szP
1a080 61 67 65 2c 20 69 57 61 6c 4f 66 66 29 3b 0a 0a  age, iWalOff);..
1a090 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20              if( 
1a0a0 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1a0b0 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72  .              r
1a0c0 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61  c = sqlite3OsRea
1a0d0 64 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 70  d(pWal->pDbFd, p
1a0e0 42 75 66 32 2c 20 73 7a 50 61 67 65 2c 20 69 44  Buf2, szPage, iD
1a0f0 62 4f 66 66 29 3b 0a 20 20 20 20 20 20 20 20 20  bOff);.         
1a100 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 20 20     }..          
1a110 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
1a120 5f 4f 4b 20 7c 7c 20 30 3d 3d 6d 65 6d 63 6d 70  _OK || 0==memcmp
1a130 28 70 42 75 66 31 2c 20 70 42 75 66 32 2c 20 73  (pBuf1, pBuf2, s
1a140 7a 50 61 67 65 29 20 29 7b 0a 20 20 20 20 20 20  zPage) ){.      
1a150 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
1a160 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20             }.   
1a170 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20         }..      
1a180 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b      pInfo->nBack
1a190 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 3d 20  fillAttempted = 
1a1a0 69 2d 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  i-1;.        }. 
1a1b0 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 73 71       }..      sq
1a1c0 6c 69 74 65 33 5f 66 72 65 65 28 70 42 75 66 31  lite3_free(pBuf1
1a1d0 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  );.      sqlite3
1a1e0 5f 66 72 65 65 28 70 42 75 66 32 29 3b 0a 20 20  _free(pBuf2);.  
1a1f0 20 20 7d 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63    }.    walUnloc
1a200 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
1a210 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20   WAL_CKPT_LOCK, 
1a220 31 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  1);.  }..  retur
1a230 6e 20 72 63 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f  n rc;.}.#endif /
1a240 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  * SQLITE_ENABLE_
1a250 53 4e 41 50 53 48 4f 54 20 2a 2f 0a 0a 2f 2a 0a  SNAPSHOT */../*.
1a260 2a 2a 20 42 65 67 69 6e 20 61 20 72 65 61 64 20  ** Begin a read 
1a270 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74  transaction on t
1a280 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2a 0a  he database..**.
1a290 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
1a2a0 75 73 65 64 20 74 6f 20 62 65 20 63 61 6c 6c 65  used to be calle
1a2b0 64 20 73 71 6c 69 74 65 33 4f 70 65 6e 53 6e 61  d sqlite3OpenSna
1a2c0 70 73 68 6f 74 28 29 20 61 6e 64 20 77 69 74 68  pshot() and with
1a2d0 20 67 6f 6f 64 20 72 65 61 73 6f 6e 3a 0a 2a 2a   good reason:.**
1a2e0 20 69 74 20 74 61 6b 65 73 20 61 20 73 6e 61 70   it takes a snap
1a2f0 73 68 6f 74 20 6f 66 20 74 68 65 20 73 74 61 74  shot of the stat
1a300 65 20 6f 66 20 74 68 65 20 57 41 4c 20 61 6e 64  e of the WAL and
1a310 20 77 61 6c 2d 69 6e 64 65 78 20 66 6f 72 20 74   wal-index for t
1a320 68 65 20 63 75 72 72 65 6e 74 0a 2a 2a 20 69 6e  he current.** in
1a330 73 74 61 6e 74 20 69 6e 20 74 69 6d 65 2e 20 20  stant in time.  
1a340 54 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65  The current thre
1a350 61 64 20 77 69 6c 6c 20 63 6f 6e 74 69 6e 75 65  ad will continue
1a360 20 74 6f 20 75 73 65 20 74 68 69 73 20 73 6e 61   to use this sna
1a370 70 73 68 6f 74 2e 0a 2a 2a 20 4f 74 68 65 72 20  pshot..** Other 
1a380 74 68 72 65 61 64 73 20 6d 69 67 68 74 20 61 70  threads might ap
1a390 70 65 6e 64 20 6e 65 77 20 63 6f 6e 74 65 6e 74  pend new content
1a3a0 20 74 6f 20 74 68 65 20 57 41 4c 20 61 6e 64 20   to the WAL and 
1a3b0 77 61 6c 2d 69 6e 64 65 78 20 62 75 74 0a 2a 2a  wal-index but.**
1a3c0 20 74 68 61 74 20 65 78 74 72 61 20 63 6f 6e 74   that extra cont
1a3d0 65 6e 74 20 69 73 20 69 67 6e 6f 72 65 64 20 62  ent is ignored b
1a3e0 79 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68  y the current th
1a3f0 72 65 61 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  read..**.** If t
1a400 68 65 20 64 61 74 61 62 61 73 65 20 63 6f 6e 74  he database cont
1a410 65 6e 74 73 20 68 61 76 65 20 63 68 61 6e 67 65  ents have change
1a420 73 20 73 69 6e 63 65 20 74 68 65 20 70 72 65 76  s since the prev
1a430 69 6f 75 73 20 72 65 61 64 0a 2a 2a 20 74 72 61  ious read.** tra
1a440 6e 73 61 63 74 69 6f 6e 2c 20 74 68 65 6e 20 2a  nsaction, then *
1a450 70 43 68 61 6e 67 65 64 20 69 73 20 73 65 74 20  pChanged is set 
1a460 74 6f 20 31 20 62 65 66 6f 72 65 20 72 65 74 75  to 1 before retu
1a470 72 6e 69 6e 67 2e 20 20 54 68 65 0a 2a 2a 20 50  rning.  The.** P
1a480 61 67 65 72 20 6c 61 79 65 72 20 77 69 6c 6c 20  ager layer will 
1a490 75 73 65 20 74 68 69 73 20 74 6f 20 6b 6e 6f 77  use this to know
1a4a0 20 74 68 61 74 20 69 73 20 63 61 63 68 65 20 69   that is cache i
1a4b0 73 20 73 74 61 6c 65 20 61 6e 64 0a 2a 2a 20 6e  s stale and.** n
1a4c0 65 65 64 73 20 74 6f 20 62 65 20 66 6c 75 73 68  eeds to be flush
1a4d0 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ed..*/.int sqlit
1a4e0 65 33 57 61 6c 42 65 67 69 6e 52 65 61 64 54 72  e3WalBeginReadTr
1a4f0 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70  ansaction(Wal *p
1a500 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e 67  Wal, int *pChang
1a510 65 64 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20  ed){.  int rc;  
1a520 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a530 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
1a540 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 63   code */.  int c
1a550 6e 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  nt = 0;         
1a560 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
1a570 6d 62 65 72 20 6f 66 20 54 72 79 42 65 67 69 6e  mber of TryBegin
1a580 52 65 61 64 20 61 74 74 65 6d 70 74 73 20 2a 2f  Read attempts */
1a590 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
1a5a0 45 4e 41 42 4c 45 5f 53 4e 41 50 53 48 4f 54 0a  ENABLE_SNAPSHOT.
1a5b0 20 20 69 6e 74 20 62 43 68 61 6e 67 65 64 20 3d    int bChanged =
1a5c0 20 30 3b 0a 20 20 57 61 6c 49 6e 64 65 78 48 64   0;.  WalIndexHd
1a5d0 72 20 2a 70 53 6e 61 70 73 68 6f 74 20 3d 20 70  r *pSnapshot = p
1a5e0 57 61 6c 2d 3e 70 53 6e 61 70 73 68 6f 74 3b 0a  Wal->pSnapshot;.
1a5f0 20 20 69 66 28 20 70 53 6e 61 70 73 68 6f 74 20    if( pSnapshot 
1a600 26 26 20 6d 65 6d 63 6d 70 28 70 53 6e 61 70 73  && memcmp(pSnaps
1a610 68 6f 74 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c  hot, &pWal->hdr,
1a620 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
1a630 48 64 72 29 29 21 3d 30 20 29 7b 0a 20 20 20 20  Hdr))!=0 ){.    
1a640 62 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20  bChanged = 1;.  
1a650 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 64 6f 7b 0a  }.#endif..  do{.
1a660 20 20 20 20 72 63 20 3d 20 77 61 6c 54 72 79 42      rc = walTryB
1a670 65 67 69 6e 52 65 61 64 28 70 57 61 6c 2c 20 70  eginRead(pWal, p
1a680 43 68 61 6e 67 65 64 2c 20 30 2c 20 2b 2b 63 6e  Changed, 0, ++cn
1a690 74 29 3b 0a 20 20 7d 77 68 69 6c 65 28 20 72 63  t);.  }while( rc
1a6a0 3d 3d 57 41 4c 5f 52 45 54 52 59 20 29 3b 0a 20  ==WAL_RETRY );. 
1a6b0 20 74 65 73 74 63 61 73 65 28 20 28 72 63 26 30   testcase( (rc&0
1a6c0 78 66 66 29 3d 3d 53 51 4c 49 54 45 5f 42 55 53  xff)==SQLITE_BUS
1a6d0 59 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28  Y );.  testcase(
1a6e0 20 28 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49   (rc&0xff)==SQLI
1a6f0 54 45 5f 49 4f 45 52 52 20 29 3b 0a 20 20 74 65  TE_IOERR );.  te
1a700 73 74 63 61 73 65 28 20 72 63 3d 3d 53 51 4c 49  stcase( rc==SQLI
1a710 54 45 5f 50 52 4f 54 4f 43 4f 4c 20 29 3b 0a 20  TE_PROTOCOL );. 
1a720 20 74 65 73 74 63 61 73 65 28 20 72 63 3d 3d 53   testcase( rc==S
1a730 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 0a 23 69 66  QLITE_OK );..#if
1a740 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c  def SQLITE_ENABL
1a750 45 5f 53 4e 41 50 53 48 4f 54 0a 20 20 69 66 28  E_SNAPSHOT.  if(
1a760 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
1a770 7b 0a 20 20 20 20 69 66 28 20 70 53 6e 61 70 73  {.    if( pSnaps
1a780 68 6f 74 20 26 26 20 6d 65 6d 63 6d 70 28 70 53  hot && memcmp(pS
1a790 6e 61 70 73 68 6f 74 2c 20 26 70 57 61 6c 2d 3e  napshot, &pWal->
1a7a0 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49  hdr, sizeof(WalI
1a7b0 6e 64 65 78 48 64 72 29 29 21 3d 30 20 29 7b 0a  ndexHdr))!=0 ){.
1a7c0 20 20 20 20 20 20 2f 2a 20 41 74 20 74 68 69 73        /* At this
1a7d0 20 70 6f 69 6e 74 20 74 68 65 20 63 6c 69 65 6e   point the clien
1a7e0 74 20 68 61 73 20 61 20 6c 6f 63 6b 20 6f 6e 20  t has a lock on 
1a7f0 61 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 73  an aReadMark[] s
1a800 6c 6f 74 20 68 6f 6c 64 69 6e 67 0a 20 20 20 20  lot holding.    
1a810 20 20 2a 2a 20 61 20 76 61 6c 75 65 20 65 71 75    ** a value equ
1a820 61 6c 20 74 6f 20 6f 72 20 73 6d 61 6c 6c 65 72  al to or smaller
1a830 20 74 68 61 6e 20 70 53 6e 61 70 73 68 6f 74 2d   than pSnapshot-
1a840 3e 6d 78 46 72 61 6d 65 2c 20 62 75 74 20 70 57  >mxFrame, but pW
1a850 61 6c 2d 3e 68 64 72 0a 20 20 20 20 20 20 2a 2a  al->hdr.      **
1a860 20 69 73 20 70 6f 70 75 6c 61 74 65 64 20 77 69   is populated wi
1a870 74 68 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  th the wal-index
1a880 20 68 65 61 64 65 72 20 63 6f 72 72 65 73 70 6f   header correspo
1a890 6e 64 69 6e 67 20 74 6f 20 74 68 65 20 68 65 61  nding to the hea
1a8a0 64 0a 20 20 20 20 20 20 2a 2a 20 6f 66 20 74 68  d.      ** of th
1a8b0 65 20 77 61 6c 20 66 69 6c 65 2e 20 56 65 72 69  e wal file. Veri
1a8c0 66 79 20 74 68 61 74 20 70 53 6e 61 70 73 68 6f  fy that pSnapsho
1a8d0 74 20 69 73 20 73 74 69 6c 6c 20 76 61 6c 69 64  t is still valid
1a8e0 20 62 65 66 6f 72 65 0a 20 20 20 20 20 20 2a 2a   before.      **
1a8f0 20 63 6f 6e 74 69 6e 75 69 6e 67 2e 20 20 52 65   continuing.  Re
1a900 61 73 6f 6e 73 20 77 68 79 20 70 53 6e 61 70 73  asons why pSnaps
1a910 68 6f 74 20 6d 69 67 68 74 20 6e 6f 20 6c 6f 6e  hot might no lon
1a920 67 65 72 20 62 65 20 76 61 6c 69 64 3a 0a 20 20  ger be valid:.  
1a930 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20      **.      ** 
1a940 20 20 20 28 31 29 20 20 54 68 65 20 57 41 4c 20     (1)  The WAL 
1a950 66 69 6c 65 20 68 61 73 20 62 65 65 6e 20 72 65  file has been re
1a960 73 65 74 20 73 69 6e 63 65 20 74 68 65 20 73 6e  set since the sn
1a970 61 70 73 68 6f 74 20 77 61 73 20 74 61 6b 65 6e  apshot was taken
1a980 2e 0a 20 20 20 20 20 20 2a 2a 20 20 20 20 20 20  ..      **      
1a990 20 20 20 49 6e 20 74 68 69 73 20 63 61 73 65 2c     In this case,
1a9a0 20 74 68 65 20 73 61 6c 74 20 77 69 6c 6c 20 68   the salt will h
1a9b0 61 76 65 20 63 68 61 6e 67 65 64 2e 0a 20 20 20  ave changed..   
1a9c0 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 20     **.      **  
1a9d0 20 20 28 32 29 20 20 41 20 63 68 65 63 6b 70 6f    (2)  A checkpo
1a9e0 69 6e 74 20 61 73 20 62 65 65 6e 20 61 74 74 65  int as been atte
1a9f0 6d 70 74 65 64 20 74 68 61 74 20 77 72 6f 74 65  mpted that wrote
1aa00 20 66 72 61 6d 65 73 20 70 61 73 74 0a 20 20 20   frames past.   
1aa10 20 20 20 2a 2a 20 20 20 20 20 20 20 20 20 70 53     **         pS
1aa20 6e 61 70 73 68 6f 74 2d 3e 6d 78 46 72 61 6d 65  napshot->mxFrame
1aa30 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
1aa40 73 65 20 66 69 6c 65 2e 20 20 4e 6f 74 65 20 74  se file.  Note t
1aa50 68 61 74 20 74 68 65 0a 20 20 20 20 20 20 2a 2a  hat the.      **
1aa60 20 20 20 20 20 20 20 20 20 63 68 65 63 6b 70 6f           checkpo
1aa70 69 6e 74 20 6e 65 65 64 20 6e 6f 74 20 68 61 76  int need not hav
1aa80 65 20 63 6f 6d 70 6c 65 74 65 64 20 66 6f 72 20  e completed for 
1aa90 74 68 69 73 20 74 6f 20 63 61 75 73 65 20 70 72  this to cause pr
1aaa0 6f 62 6c 65 6d 73 2e 0a 20 20 20 20 20 20 2a 2f  oblems..      */
1aab0 0a 20 20 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  .      volatile 
1aac0 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e  WalCkptInfo *pIn
1aad0 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f  fo = walCkptInfo
1aae0 28 70 57 61 6c 29 3b 0a 0a 20 20 20 20 20 20 61  (pWal);..      a
1aaf0 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65 61  ssert( pWal->rea
1ab00 64 4c 6f 63 6b 3e 30 20 7c 7c 20 70 57 61 6c 2d  dLock>0 || pWal-
1ab10 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 30 20  >hdr.mxFrame==0 
1ab20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
1ab30 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
1ab40 6b 5b 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  k[pWal->readLock
1ab50 5d 3c 3d 70 53 6e 61 70 73 68 6f 74 2d 3e 6d 78  ]<=pSnapshot->mx
1ab60 46 72 61 6d 65 20 29 3b 0a 0a 20 20 20 20 20 20  Frame );..      
1ab70 2f 2a 20 49 74 20 69 73 20 70 6f 73 73 69 62 6c  /* It is possibl
1ab80 65 20 74 68 61 74 20 74 68 65 72 65 20 69 73 20  e that there is 
1ab90 61 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 20 74  a checkpointer t
1aba0 68 72 65 61 64 20 72 75 6e 6e 69 6e 67 20 0a 20  hread running . 
1abb0 20 20 20 20 20 2a 2a 20 63 6f 6e 63 75 72 72 65       ** concurre
1abc0 6e 74 20 77 69 74 68 20 74 68 69 73 20 63 6f 64  nt with this cod
1abd0 65 2e 20 49 66 20 74 68 69 73 20 69 73 20 74 68  e. If this is th
1abe0 65 20 63 61 73 65 2c 20 69 74 20 6d 61 79 20 62  e case, it may b
1abf0 65 20 74 68 61 74 20 74 68 65 0a 20 20 20 20 20  e that the.     
1ac00 20 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 65 72   ** checkpointer
1ac10 20 68 61 73 20 61 6c 72 65 61 64 79 20 64 65 74   has already det
1ac20 65 72 6d 69 6e 65 64 20 74 68 61 74 20 69 74 20  ermined that it 
1ac30 77 69 6c 6c 20 63 68 65 63 6b 70 6f 69 6e 74 20  will checkpoint 
1ac40 0a 20 20 20 20 20 20 2a 2a 20 73 6e 61 70 73 68  .      ** snapsh
1ac50 6f 74 20 58 2c 20 77 68 65 72 65 20 58 20 69 73  ot X, where X is
1ac60 20 6c 61 74 65 72 20 69 6e 20 74 68 65 20 77 61   later in the wa
1ac70 6c 20 66 69 6c 65 20 74 68 61 6e 20 70 53 6e 61  l file than pSna
1ac80 70 73 68 6f 74 2c 20 62 75 74 20 0a 20 20 20 20  pshot, but .    
1ac90 20 20 2a 2a 20 68 61 73 20 6e 6f 74 20 79 65 74    ** has not yet
1aca0 20 73 65 74 20 74 68 65 20 70 49 6e 66 6f 2d 3e   set the pInfo->
1acb0 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74  nBackfillAttempt
1acc0 65 64 20 76 61 72 69 61 62 6c 65 20 74 6f 20 69  ed variable to i
1acd0 6e 64 69 63 61 74 65 20 0a 20 20 20 20 20 20 2a  ndicate .      *
1ace0 2a 20 69 74 73 20 69 6e 74 65 6e 74 2e 20 54 6f  * its intent. To
1acf0 20 61 76 6f 69 64 20 74 68 65 20 72 61 63 65 20   avoid the race 
1ad00 63 6f 6e 64 69 74 69 6f 6e 20 74 68 69 73 20 6c  condition this l
1ad10 65 61 64 73 20 74 6f 2c 20 65 6e 73 75 72 65 20  eads to, ensure 
1ad20 74 68 61 74 0a 20 20 20 20 20 20 2a 2a 20 74 68  that.      ** th
1ad30 65 72 65 20 69 73 20 6e 6f 20 63 68 65 63 6b 70  ere is no checkp
1ad40 6f 69 6e 74 65 72 20 70 72 6f 63 65 73 73 20 62  ointer process b
1ad50 79 20 74 61 6b 69 6e 67 20 61 20 73 68 61 72 65  y taking a share
1ad60 64 20 43 4b 50 54 20 6c 6f 63 6b 20 0a 20 20 20  d CKPT lock .   
1ad70 20 20 20 2a 2a 20 62 65 66 6f 72 65 20 63 68 65     ** before che
1ad80 63 6b 69 6e 67 20 70 49 6e 66 6f 2d 3e 6e 42 61  cking pInfo->nBa
1ad90 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 2e  ckfillAttempted.
1ada0 20 20 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20    .      **.    
1adb0 20 20 2a 2a 20 54 4f 44 4f 3a 20 44 6f 65 73 20    ** TODO: Does 
1adc0 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20  the aReadMark[] 
1add0 6c 6f 63 6b 20 70 72 65 76 65 6e 74 20 61 20 63  lock prevent a c
1ade0 68 65 63 6b 70 6f 69 6e 74 65 72 20 66 72 6f 6d  heckpointer from
1adf0 20 64 6f 69 6e 67 0a 20 20 20 20 20 20 2a 2a 20   doing.      ** 
1ae00 20 20 20 20 20 20 74 68 69 73 20 61 6c 72 65 61        this alrea
1ae10 64 79 3f 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20  dy?.      */.   
1ae20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53     rc = walLockS
1ae30 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
1ae40 43 4b 50 54 5f 4c 4f 43 4b 29 3b 0a 0a 20 20 20  CKPT_LOCK);..   
1ae50 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
1ae60 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
1ae70 2f 2a 20 43 68 65 63 6b 20 74 68 61 74 20 74 68  /* Check that th
1ae80 65 20 77 61 6c 20 66 69 6c 65 20 68 61 73 20 6e  e wal file has n
1ae90 6f 74 20 62 65 65 6e 20 77 72 61 70 70 65 64 2e  ot been wrapped.
1aea0 20 41 73 73 75 6d 69 6e 67 20 74 68 61 74 20 69   Assuming that i
1aeb0 74 20 68 61 73 0a 20 20 20 20 20 20 20 20 2a 2a  t has.        **
1aec0 20 6e 6f 74 2c 20 61 6c 73 6f 20 63 68 65 63 6b   not, also check
1aed0 20 74 68 61 74 20 6e 6f 20 63 68 65 63 6b 70 6f   that no checkpo
1aee0 69 6e 74 65 72 20 68 61 73 20 61 74 74 65 6d 70  inter has attemp
1aef0 74 65 64 20 74 6f 20 63 68 65 63 6b 70 6f 69 6e  ted to checkpoin
1af00 74 20 61 6e 79 0a 20 20 20 20 20 20 20 20 2a 2a  t any.        **
1af10 20 66 72 61 6d 65 73 20 62 65 79 6f 6e 64 20 70   frames beyond p
1af20 53 6e 61 70 73 68 6f 74 2d 3e 6d 78 46 72 61 6d  Snapshot->mxFram
1af30 65 2e 20 49 66 20 65 69 74 68 65 72 20 6f 66 20  e. If either of 
1af40 74 68 65 73 65 20 63 6f 6e 64 69 74 69 6f 6e 73  these conditions
1af50 20 61 72 65 0a 20 20 20 20 20 20 20 20 2a 2a 20   are.        ** 
1af60 74 72 75 65 2c 20 72 65 74 75 72 6e 20 53 51 4c  true, return SQL
1af70 49 54 45 5f 42 55 53 59 5f 53 4e 41 50 53 48 4f  ITE_BUSY_SNAPSHO
1af80 54 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 6f 76  T. Otherwise, ov
1af90 65 72 77 72 69 74 65 20 70 57 61 6c 2d 3e 68 64  erwrite pWal->hd
1afa0 72 0a 20 20 20 20 20 20 20 20 2a 2a 20 77 69 74  r.        ** wit
1afb0 68 20 2a 70 53 6e 61 70 73 68 6f 74 20 61 6e 64  h *pSnapshot and
1afc0 20 73 65 74 20 2a 70 43 68 61 6e 67 65 64 20 61   set *pChanged a
1afd0 73 20 61 70 70 72 6f 70 72 69 61 74 65 20 66 6f  s appropriate fo
1afe0 72 20 6f 70 65 6e 69 6e 67 20 74 68 65 0a 20 20  r opening the.  
1aff0 20 20 20 20 20 20 2a 2a 20 73 6e 61 70 73 68 6f        ** snapsho
1b000 74 2e 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 69  t.  */.        i
1b010 66 28 20 21 6d 65 6d 63 6d 70 28 70 53 6e 61 70  f( !memcmp(pSnap
1b020 73 68 6f 74 2d 3e 61 53 61 6c 74 2c 20 70 57 61  shot->aSalt, pWa
1b030 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 73 69  l->hdr.aSalt, si
1b040 7a 65 6f 66 28 70 57 61 6c 2d 3e 68 64 72 2e 61  zeof(pWal->hdr.a
1b050 53 61 6c 74 29 29 0a 20 20 20 20 20 20 20 20 20  Salt)).         
1b060 26 26 20 70 53 6e 61 70 73 68 6f 74 2d 3e 6d 78  && pSnapshot->mx
1b070 46 72 61 6d 65 3e 3d 70 49 6e 66 6f 2d 3e 6e 42  Frame>=pInfo->nB
1b080 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64  ackfillAttempted
1b090 0a 20 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20  .        ){.    
1b0a0 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 57        assert( pW
1b0b0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 30 20 29  al->readLock>0 )
1b0c0 3b 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63  ;.          memc
1b0d0 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 70  py(&pWal->hdr, p
1b0e0 53 6e 61 70 73 68 6f 74 2c 20 73 69 7a 65 6f 66  Snapshot, sizeof
1b0f0 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a  (WalIndexHdr));.
1b100 20 20 20 20 20 20 20 20 20 20 2a 70 43 68 61 6e            *pChan
1b110 67 65 64 20 3d 20 62 43 68 61 6e 67 65 64 3b 0a  ged = bChanged;.
1b120 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
1b130 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51           rc = SQ
1b140 4c 49 54 45 5f 42 55 53 59 5f 53 4e 41 50 53 48  LITE_BUSY_SNAPSH
1b150 4f 54 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20  OT;.        }.. 
1b160 20 20 20 20 20 20 20 2f 2a 20 52 65 6c 65 61 73         /* Releas
1b170 65 20 74 68 65 20 73 68 61 72 65 64 20 43 4b 50  e the shared CKP
1b180 54 20 6c 6f 63 6b 20 6f 62 74 61 69 6e 65 64 20  T lock obtained 
1b190 61 62 6f 76 65 2e 20 2a 2f 0a 20 20 20 20 20 20  above. */.      
1b1a0 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65    walUnlockShare
1b1b0 64 28 70 57 61 6c 2c 20 57 41 4c 5f 43 4b 50 54  d(pWal, WAL_CKPT
1b1c0 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 20 20 7d 0a  _LOCK);.      }.
1b1d0 0a 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ..      if( rc!=
1b1e0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
1b1f0 20 20 20 20 20 73 71 6c 69 74 65 33 57 61 6c 45       sqlite3WalE
1b200 6e 64 52 65 61 64 54 72 61 6e 73 61 63 74 69 6f  ndReadTransactio
1b210 6e 28 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 7d  n(pWal);.      }
1b220 0a 20 20 20 20 7d 0a 20 20 7d 0a 23 65 6e 64 69  .    }.  }.#endi
1b230 66 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  f.  return rc;.}
1b240 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 69 73 68 20 77  ../*.** Finish w
1b250 69 74 68 20 61 20 72 65 61 64 20 74 72 61 6e 73  ith a read trans
1b260 61 63 74 69 6f 6e 2e 20 20 41 6c 6c 20 74 68 69  action.  All thi
1b270 73 20 64 6f 65 73 20 69 73 20 72 65 6c 65 61 73  s does is releas
1b280 65 20 74 68 65 0a 2a 2a 20 72 65 61 64 2d 6c 6f  e the.** read-lo
1b290 63 6b 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  ck..*/.void sqli
1b2a0 74 65 33 57 61 6c 45 6e 64 52 65 61 64 54 72 61  te3WalEndReadTra
1b2b0 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57  nsaction(Wal *pW
1b2c0 61 6c 29 7b 0a 20 20 73 71 6c 69 74 65 33 57 61  al){.  sqlite3Wa
1b2d0 6c 45 6e 64 57 72 69 74 65 54 72 61 6e 73 61 63  lEndWriteTransac
1b2e0 74 69 6f 6e 28 70 57 61 6c 29 3b 0a 20 20 69 66  tion(pWal);.  if
1b2f0 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  ( pWal->readLock
1b300 3e 3d 30 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e  >=0 ){.    walUn
1b310 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  lockShared(pWal,
1b320 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70   WAL_READ_LOCK(p
1b330 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 3b  Wal->readLock));
1b340 0a 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c  .    pWal->readL
1b350 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20 7d 0a 7d 0a  ock = -1;.  }.}.
1b360 0a 2f 2a 0a 2a 2a 20 53 65 61 72 63 68 20 74 68  ./*.** Search th
1b370 65 20 77 61 6c 20 66 69 6c 65 20 66 6f 72 20 70  e wal file for p
1b380 61 67 65 20 70 67 6e 6f 2e 20 49 66 20 66 6f 75  age pgno. If fou
1b390 6e 64 2c 20 73 65 74 20 2a 70 69 52 65 61 64 20  nd, set *piRead 
1b3a0 74 6f 20 74 68 65 20 66 72 61 6d 65 20 74 68 61  to the frame tha
1b3b0 74 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 74 68  t.** contains th
1b3c0 65 20 70 61 67 65 2e 20 4f 74 68 65 72 77 69 73  e page. Otherwis
1b3d0 65 2c 20 69 66 20 70 67 6e 6f 20 69 73 20 6e 6f  e, if pgno is no
1b3e0 74 20 69 6e 20 74 68 65 20 77 61 6c 20 66 69 6c  t in the wal fil
1b3f0 65 2c 20 73 65 74 20 2a 70 69 52 65 61 64 0a 2a  e, set *piRead.*
1b400 2a 20 74 6f 20 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a  * to zero..**.**
1b410 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   Return SQLITE_O
1b420 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c  K if successful,
1b430 20 6f 72 20 61 6e 20 65 72 72 6f 72 20 63 6f 64   or an error cod
1b440 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  e if an error oc
1b450 63 75 72 73 2e 20 49 66 20 61 6e 0a 2a 2a 20 65  curs. If an.** e
1b460 72 72 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c  rror does occur,
1b470 20 74 68 65 20 66 69 6e 61 6c 20 76 61 6c 75 65   the final value
1b480 20 6f 66 20 2a 70 69 52 65 61 64 20 69 73 20 75   of *piRead is u
1b490 6e 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74  ndefined..*/.int
1b4a0 20 73 71 6c 69 74 65 33 57 61 6c 46 69 6e 64 46   sqlite3WalFindF
1b4b0 72 61 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57 61  rame(.  Wal *pWa
1b4c0 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
1b4d0 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 68          /* WAL h
1b4e0 61 6e 64 6c 65 20 2a 2f 0a 20 20 50 67 6e 6f 20  andle */.  Pgno 
1b4f0 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20  pgno,           
1b500 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
1b510 74 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62  tabase page numb
1b520 65 72 20 74 6f 20 72 65 61 64 20 64 61 74 61 20  er to read data 
1b530 66 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69  for */.  u32 *pi
1b540 52 65 61 64 20 20 20 20 20 20 20 20 20 20 20 20  Read            
1b550 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
1b560 20 46 72 61 6d 65 20 6e 75 6d 62 65 72 20 28 6f   Frame number (o
1b570 72 20 7a 65 72 6f 29 20 2a 2f 0a 29 7b 0a 20 20  r zero) */.){.  
1b580 75 33 32 20 69 52 65 61 64 20 3d 20 30 3b 20 20  u32 iRead = 0;  
1b590 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b5a0 2f 2a 20 49 66 20 21 3d 30 2c 20 57 41 4c 20 66  /* If !=0, WAL f
1b5b0 72 61 6d 65 20 74 6f 20 72 65 74 75 72 6e 20 64  rame to return d
1b5c0 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 75 33  ata from */.  u3
1b5d0 32 20 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d 3e  2 iLast = pWal->
1b5e0 68 64 72 2e 6d 78 46 72 61 6d 65 3b 20 20 2f 2a  hdr.mxFrame;  /*
1b5f0 20 4c 61 73 74 20 70 61 67 65 20 69 6e 20 57 41   Last page in WA
1b600 4c 20 66 6f 72 20 74 68 69 73 20 72 65 61 64 65  L for this reade
1b610 72 20 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73 68  r */.  int iHash
1b620 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1b630 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
1b640 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20 4e  o loop through N
1b650 20 68 61 73 68 20 74 61 62 6c 65 73 20 2a 2f 0a   hash tables */.
1b660 20 20 69 6e 74 20 69 4d 69 6e 48 61 73 68 3b 0a    int iMinHash;.
1b670 0a 20 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69  .  /* This routi
1b680 6e 65 20 69 73 20 6f 6e 6c 79 20 62 65 20 63 61  ne is only be ca
1b690 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e  lled from within
1b6a0 20 61 20 72 65 61 64 20 74 72 61 6e 73 61 63 74   a read transact
1b6b0 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74  ion. */.  assert
1b6c0 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  ( pWal->readLock
1b6d0 3e 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63  >=0 || pWal->loc
1b6e0 6b 45 72 72 6f 72 20 29 3b 0a 0a 20 20 2f 2a 20  kError );..  /* 
1b6f0 49 66 20 74 68 65 20 22 6c 61 73 74 20 70 61 67  If the "last pag
1b700 65 22 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20  e" field of the 
1b710 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
1b720 20 73 6e 61 70 73 68 6f 74 20 69 73 20 30 2c 20   snapshot is 0, 
1b730 74 68 65 6e 0a 20 20 2a 2a 20 6e 6f 20 64 61 74  then.  ** no dat
1b740 61 20 77 69 6c 6c 20 62 65 20 72 65 61 64 20 66  a will be read f
1b750 72 6f 6d 20 74 68 65 20 77 61 6c 20 75 6e 64 65  rom the wal unde
1b760 72 20 61 6e 79 20 63 69 72 63 75 6d 73 74 61 6e  r any circumstan
1b770 63 65 73 2e 20 52 65 74 75 72 6e 20 65 61 72 6c  ces. Return earl
1b780 79 0a 20 20 2a 2a 20 69 6e 20 74 68 69 73 20 63  y.  ** in this c
1b790 61 73 65 20 61 73 20 61 6e 20 6f 70 74 69 6d 69  ase as an optimi
1b7a0 7a 61 74 69 6f 6e 2e 20 20 4c 69 6b 65 77 69 73  zation.  Likewis
1b7b0 65 2c 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64  e, if pWal->read
1b7c0 4c 6f 63 6b 3d 3d 30 2c 20 0a 20 20 2a 2a 20 74  Lock==0, .  ** t
1b7d0 68 65 6e 20 74 68 65 20 57 41 4c 20 69 73 20 69  hen the WAL is i
1b7e0 67 6e 6f 72 65 64 20 62 79 20 74 68 65 20 72 65  gnored by the re
1b7f0 61 64 65 72 20 73 6f 20 72 65 74 75 72 6e 20 65  ader so return e
1b800 61 72 6c 79 2c 20 61 73 20 69 66 20 74 68 65 20  arly, as if the 
1b810 0a 20 20 2a 2a 20 57 41 4c 20 77 65 72 65 20 65  .  ** WAL were e
1b820 6d 70 74 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  mpty..  */.  if(
1b830 20 69 4c 61 73 74 3d 3d 30 20 7c 7c 20 28 70 57   iLast==0 || (pW
1b840 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20  al->readLock==0 
1b850 26 26 20 70 57 61 6c 2d 3e 62 53 68 6d 55 6e 72  && pWal->bShmUnr
1b860 65 6c 69 61 62 6c 65 3d 3d 30 29 20 29 7b 0a 20  eliable==0) ){. 
1b870 20 20 20 2a 70 69 52 65 61 64 20 3d 20 30 3b 0a     *piRead = 0;.
1b880 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
1b890 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  E_OK;.  }..  /* 
1b8a0 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68 20  Search the hash 
1b8b0 74 61 62 6c 65 20 6f 72 20 74 61 62 6c 65 73 20  table or tables 
1b8c0 66 6f 72 20 61 6e 20 65 6e 74 72 79 20 6d 61 74  for an entry mat
1b8d0 63 68 69 6e 67 20 70 61 67 65 20 6e 75 6d 62 65  ching page numbe
1b8e0 72 0a 20 20 2a 2a 20 70 67 6e 6f 2e 20 45 61 63  r.  ** pgno. Eac
1b8f0 68 20 69 74 65 72 61 74 69 6f 6e 20 6f 66 20 74  h iteration of t
1b900 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 66 6f 72  he following for
1b910 28 29 20 6c 6f 6f 70 20 73 65 61 72 63 68 65 73  () loop searches
1b920 20 6f 6e 65 0a 20 20 2a 2a 20 68 61 73 68 20 74   one.  ** hash t
1b930 61 62 6c 65 20 28 65 61 63 68 20 68 61 73 68 20  able (each hash 
1b940 74 61 62 6c 65 20 69 6e 64 65 78 65 73 20 75 70  table indexes up
1b950 20 74 6f 20 48 41 53 48 54 41 42 4c 45 5f 4e 50   to HASHTABLE_NP
1b960 41 47 45 20 66 72 61 6d 65 73 29 2e 0a 20 20 2a  AGE frames)..  *
1b970 2a 0a 20 20 2a 2a 20 54 68 69 73 20 63 6f 64 65  *.  ** This code
1b980 20 6d 69 67 68 74 20 72 75 6e 20 63 6f 6e 63 75   might run concu
1b990 72 72 65 6e 74 6c 79 20 74 6f 20 74 68 65 20 63  rrently to the c
1b9a0 6f 64 65 20 69 6e 20 77 61 6c 49 6e 64 65 78 41  ode in walIndexA
1b9b0 70 70 65 6e 64 28 29 0a 20 20 2a 2a 20 74 68 61  ppend().  ** tha
1b9c0 74 20 61 64 64 73 20 65 6e 74 72 69 65 73 20 74  t adds entries t
1b9d0 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  o the wal-index 
1b9e0 28 61 6e 64 20 70 6f 73 73 69 62 6c 79 20 74 6f  (and possibly to
1b9f0 20 74 68 69 73 20 68 61 73 68 20 0a 20 20 2a 2a   this hash .  **
1ba00 20 74 61 62 6c 65 29 2e 20 54 68 69 73 20 6d 65   table). This me
1ba10 61 6e 73 20 74 68 65 20 76 61 6c 75 65 20 6a 75  ans the value ju
1ba20 73 74 20 72 65 61 64 20 66 72 6f 6d 20 74 68 65  st read from the
1ba30 20 68 61 73 68 20 0a 20 20 2a 2a 20 73 6c 6f 74   hash .  ** slot
1ba40 20 28 61 48 61 73 68 5b 69 4b 65 79 5d 29 20 6d   (aHash[iKey]) m
1ba50 61 79 20 68 61 76 65 20 62 65 65 6e 20 61 64 64  ay have been add
1ba60 65 64 20 62 65 66 6f 72 65 20 6f 72 20 61 66 74  ed before or aft
1ba70 65 72 20 74 68 65 20 0a 20 20 2a 2a 20 63 75 72  er the .  ** cur
1ba80 72 65 6e 74 20 72 65 61 64 20 74 72 61 6e 73 61  rent read transa
1ba90 63 74 69 6f 6e 20 77 61 73 20 6f 70 65 6e 65 64  ction was opened
1baa0 2e 20 56 61 6c 75 65 73 20 61 64 64 65 64 20 61  . Values added a
1bab0 66 74 65 72 20 74 68 65 0a 20 20 2a 2a 20 72 65  fter the.  ** re
1bac0 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77  ad transaction w
1bad0 61 73 20 6f 70 65 6e 65 64 20 6d 61 79 20 68 61  as opened may ha
1bae0 76 65 20 62 65 65 6e 20 77 72 69 74 74 65 6e 20  ve been written 
1baf0 69 6e 63 6f 72 72 65 63 74 6c 79 20 2d 0a 20 20  incorrectly -.  
1bb00 2a 2a 20 69 2e 65 2e 20 74 68 65 73 65 20 73 6c  ** i.e. these sl
1bb10 6f 74 73 20 6d 61 79 20 63 6f 6e 74 61 69 6e 20  ots may contain 
1bb20 67 61 72 62 61 67 65 20 64 61 74 61 2e 20 48 6f  garbage data. Ho
1bb30 77 65 76 65 72 2c 20 77 65 20 61 73 73 75 6d 65  wever, we assume
1bb40 0a 20 20 2a 2a 20 74 68 61 74 20 61 6e 79 20 73  .  ** that any s
1bb50 6c 6f 74 73 20 77 72 69 74 74 65 6e 20 62 65 66  lots written bef
1bb60 6f 72 65 20 74 68 65 20 63 75 72 72 65 6e 74 20  ore the current 
1bb70 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
1bb80 20 77 61 73 0a 20 20 2a 2a 20 6f 70 65 6e 65 64   was.  ** opened
1bb90 20 72 65 6d 61 69 6e 20 75 6e 6d 6f 64 69 66 69   remain unmodifi
1bba0 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 46 6f  ed..  **.  ** Fo
1bbb0 72 20 74 68 65 20 72 65 61 73 6f 6e 73 20 61 62  r the reasons ab
1bbc0 6f 76 65 2c 20 74 68 65 20 69 66 28 2e 2e 2e 29  ove, the if(...)
1bbd0 20 63 6f 6e 64 69 74 69 6f 6e 20 66 65 61 74 75   condition featu
1bbe0 72 65 64 20 69 6e 20 74 68 65 20 69 6e 6e 65 72  red in the inner
1bbf0 0a 20 20 2a 2a 20 6c 6f 6f 70 20 6f 66 20 74 68  .  ** loop of th
1bc00 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62 6c 6f 63  e following bloc
1bc10 6b 20 69 73 20 6d 6f 72 65 20 73 74 72 69 6e 67  k is more string
1bc20 65 6e 74 20 74 68 61 74 20 77 6f 75 6c 64 20 62  ent that would b
1bc30 65 20 72 65 71 75 69 72 65 64 20 0a 20 20 2a 2a  e required .  **
1bc40 20 69 66 20 77 65 20 68 61 64 20 65 78 63 6c 75   if we had exclu
1bc50 73 69 76 65 20 61 63 63 65 73 73 20 74 6f 20 74  sive access to t
1bc60 68 65 20 68 61 73 68 2d 74 61 62 6c 65 3a 0a 20  he hash-table:. 
1bc70 20 2a 2a 0a 20 20 2a 2a 20 20 20 28 61 50 67 6e   **.  **   (aPgn
1bc80 6f 5b 69 46 72 61 6d 65 5d 3d 3d 70 67 6e 6f 29  o[iFrame]==pgno)
1bc90 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69 73  : .  **     This
1bca0 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74 65   condition filte
1bcb0 72 73 20 6f 75 74 20 6e 6f 72 6d 61 6c 20 68 61  rs out normal ha
1bcc0 73 68 2d 74 61 62 6c 65 20 63 6f 6c 6c 69 73 69  sh-table collisi
1bcd0 6f 6e 73 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20  ons..  **.  **  
1bce0 20 28 69 46 72 61 6d 65 3c 3d 69 4c 61 73 74 29   (iFrame<=iLast)
1bcf0 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69 73  : .  **     This
1bd00 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74 65   condition filte
1bd10 72 73 20 6f 75 74 20 65 6e 74 72 69 65 73 20 74  rs out entries t
1bd20 68 61 74 20 77 65 72 65 20 61 64 64 65 64 20 74  hat were added t
1bd30 6f 20 74 68 65 20 68 61 73 68 0a 20 20 2a 2a 20  o the hash.  ** 
1bd40 20 20 20 20 74 61 62 6c 65 20 61 66 74 65 72 20      table after 
1bd50 74 68 65 20 63 75 72 72 65 6e 74 20 72 65 61 64  the current read
1bd60 2d 74 72 61 6e 73 61 63 74 69 6f 6e 20 68 61 64  -transaction had
1bd70 20 73 74 61 72 74 65 64 2e 0a 20 20 2a 2f 0a 20   started..  */. 
1bd80 20 69 4d 69 6e 48 61 73 68 20 3d 20 77 61 6c 46   iMinHash = walF
1bd90 72 61 6d 65 50 61 67 65 28 70 57 61 6c 2d 3e 6d  ramePage(pWal->m
1bda0 69 6e 46 72 61 6d 65 29 3b 0a 20 20 66 6f 72 28  inFrame);.  for(
1bdb0 69 48 61 73 68 3d 77 61 6c 46 72 61 6d 65 50 61  iHash=walFramePa
1bdc0 67 65 28 69 4c 61 73 74 29 3b 20 69 48 61 73 68  ge(iLast); iHash
1bdd0 3e 3d 69 4d 69 6e 48 61 73 68 20 26 26 20 69 52  >=iMinHash && iR
1bde0 65 61 64 3d 3d 30 3b 20 69 48 61 73 68 2d 2d 29  ead==0; iHash--)
1bdf0 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 68  {.    volatile h
1be00 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b 20 20  t_slot *aHash;  
1be10 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
1be20 6f 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a  o hash table */.
1be30 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32      volatile u32
1be40 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20 20 20   *aPgno;        
1be50 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
1be60 61 72 72 61 79 20 6f 66 20 70 61 67 65 20 6e 75  array of page nu
1be70 6d 62 65 72 73 20 2a 2f 0a 20 20 20 20 75 33 32  mbers */.    u32
1be80 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20   iZero;         
1be90 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
1bea0 61 6d 65 20 6e 75 6d 62 65 72 20 63 6f 72 72 65  ame number corre
1beb0 73 70 6f 6e 64 69 6e 67 20 74 6f 20 61 50 67 6e  sponding to aPgn
1bec0 6f 5b 30 5d 20 2a 2f 0a 20 20 20 20 69 6e 74 20  o[0] */.    int 
1bed0 69 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20  iKey;           
1bee0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73            /* Has
1bef0 68 20 73 6c 6f 74 20 69 6e 64 65 78 20 2a 2f 0a  h slot index */.
1bf00 20 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69 64 65      int nCollide
1bf10 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1bf20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 68    /* Number of h
1bf30 61 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73 20 72  ash collisions r
1bf40 65 6d 61 69 6e 69 6e 67 20 2a 2f 0a 20 20 20 20  emaining */.    
1bf50 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
1bf60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1bf70 20 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 0a   Error code */..
1bf80 20 20 20 20 72 63 20 3d 20 77 61 6c 48 61 73 68      rc = walHash
1bf90 47 65 74 28 70 57 61 6c 2c 20 69 48 61 73 68 2c  Get(pWal, iHash,
1bfa0 20 26 61 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c   &aHash, &aPgno,
1bfb0 20 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20 69 66   &iZero);.    if
1bfc0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
1bfd0 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
1bfe0 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e 43  rc;.    }.    nC
1bff0 6f 6c 6c 69 64 65 20 3d 20 48 41 53 48 54 41 42  ollide = HASHTAB
1c000 4c 45 5f 4e 53 4c 4f 54 3b 0a 20 20 20 20 66 6f  LE_NSLOT;.    fo
1c010 72 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 70  r(iKey=walHash(p
1c020 67 6e 6f 29 3b 20 61 48 61 73 68 5b 69 4b 65 79  gno); aHash[iKey
1c030 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48  ]; iKey=walNextH
1c040 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20  ash(iKey)){.    
1c050 20 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20 61    u32 iFrame = a
1c060 48 61 73 68 5b 69 4b 65 79 5d 20 2b 20 69 5a 65  Hash[iKey] + iZe
1c070 72 6f 3b 0a 20 20 20 20 20 20 69 66 28 20 69 46  ro;.      if( iF
1c080 72 61 6d 65 3c 3d 69 4c 61 73 74 20 26 26 20 69  rame<=iLast && i
1c090 46 72 61 6d 65 3e 3d 70 57 61 6c 2d 3e 6d 69 6e  Frame>=pWal->min
1c0a0 46 72 61 6d 65 20 26 26 20 61 50 67 6e 6f 5b 61  Frame && aPgno[a
1c0b0 48 61 73 68 5b 69 4b 65 79 5d 5d 3d 3d 70 67 6e  Hash[iKey]]==pgn
1c0c0 6f 20 29 7b 0a 20 20 20 20 20 20 20 20 61 73 73  o ){.        ass
1c0d0 65 72 74 28 20 69 46 72 61 6d 65 3e 69 52 65 61  ert( iFrame>iRea
1c0e0 64 20 7c 7c 20 43 4f 52 52 55 50 54 5f 44 42 20  d || CORRUPT_DB 
1c0f0 29 3b 0a 20 20 20 20 20 20 20 20 69 52 65 61 64  );.        iRead
1c100 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20 20 20   = iFrame;.     
1c110 20 7d 0a 20 20 20 20 20 20 69 66 28 20 28 6e 43   }.      if( (nC
1c120 6f 6c 6c 69 64 65 2d 2d 29 3d 3d 30 20 29 7b 0a  ollide--)==0 ){.
1c130 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 53          return S
1c140 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b  QLITE_CORRUPT_BK
1c150 50 54 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  PT;.      }.    
1c160 7d 0a 20 20 7d 0a 0a 23 69 66 64 65 66 20 53 51  }.  }..#ifdef SQ
1c170 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45  LITE_ENABLE_EXPE
1c180 4e 53 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f  NSIVE_ASSERT.  /
1c190 2a 20 49 66 20 65 78 70 65 6e 73 69 76 65 20 61  * If expensive a
1c1a0 73 73 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e  ssert() statemen
1c1b0 74 73 20 61 72 65 20 61 76 61 69 6c 61 62 6c 65  ts are available
1c1c0 2c 20 64 6f 20 61 20 6c 69 6e 65 61 72 20 73 65  , do a linear se
1c1d0 61 72 63 68 0a 20 20 2a 2a 20 6f 66 20 74 68 65  arch.  ** of the
1c1e0 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20   wal-index file 
1c1f0 63 6f 6e 74 65 6e 74 2e 20 4d 61 6b 65 20 73 75  content. Make su
1c200 72 65 20 74 68 65 20 72 65 73 75 6c 74 73 20 61  re the results a
1c210 67 72 65 65 20 77 69 74 68 20 74 68 65 0a 20 20  gree with the.  
1c220 2a 2a 20 72 65 73 75 6c 74 20 6f 62 74 61 69 6e  ** result obtain
1c230 65 64 20 75 73 69 6e 67 20 74 68 65 20 68 61 73  ed using the has
1c240 68 20 69 6e 64 65 78 65 73 20 61 62 6f 76 65 2e  h indexes above.
1c250 20 20 2a 2f 0a 20 20 7b 0a 20 20 20 20 75 33 32    */.  {.    u32
1c260 20 69 52 65 61 64 32 20 3d 20 30 3b 0a 20 20 20   iRead2 = 0;.   
1c270 20 75 33 32 20 69 54 65 73 74 3b 0a 20 20 20 20   u32 iTest;.    
1c280 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 62 53  assert( pWal->bS
1c290 68 6d 55 6e 72 65 6c 69 61 62 6c 65 20 7c 7c 20  hmUnreliable || 
1c2a0 70 57 61 6c 2d 3e 6d 69 6e 46 72 61 6d 65 3e 30  pWal->minFrame>0
1c2b0 20 29 3b 0a 20 20 20 20 66 6f 72 28 69 54 65 73   );.    for(iTes
1c2c0 74 3d 69 4c 61 73 74 3b 20 69 54 65 73 74 3e 3d  t=iLast; iTest>=
1c2d0 70 57 61 6c 2d 3e 6d 69 6e 46 72 61 6d 65 20 26  pWal->minFrame &
1c2e0 26 20 69 54 65 73 74 3e 30 3b 20 69 54 65 73 74  & iTest>0; iTest
1c2f0 2d 2d 29 7b 0a 20 20 20 20 20 20 69 66 28 20 77  --){.      if( w
1c300 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c  alFramePgno(pWal
1c310 2c 20 69 54 65 73 74 29 3d 3d 70 67 6e 6f 20 29  , iTest)==pgno )
1c320 7b 0a 20 20 20 20 20 20 20 20 69 52 65 61 64 32  {.        iRead2
1c330 20 3d 20 69 54 65 73 74 3b 0a 20 20 20 20 20 20   = iTest;.      
1c340 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d    break;.      }
1c350 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72  .    }.    asser
1c360 74 28 20 69 52 65 61 64 3d 3d 69 52 65 61 64 32  t( iRead==iRead2
1c370 20 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a   );.  }.#endif..
1c380 20 20 2a 70 69 52 65 61 64 20 3d 20 69 52 65 61    *piRead = iRea
1c390 64 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  d;.  return SQLI
1c3a0 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
1c3b0 52 65 61 64 20 74 68 65 20 63 6f 6e 74 65 6e 74  Read the content
1c3c0 73 20 6f 66 20 66 72 61 6d 65 20 69 52 65 61 64  s of frame iRead
1c3d0 20 66 72 6f 6d 20 74 68 65 20 77 61 6c 20 66 69   from the wal fi
1c3e0 6c 65 20 69 6e 74 6f 20 62 75 66 66 65 72 20 70  le into buffer p
1c3f0 4f 75 74 0a 2a 2a 20 28 77 68 69 63 68 20 69 73  Out.** (which is
1c400 20 6e 4f 75 74 20 62 79 74 65 73 20 69 6e 20 73   nOut bytes in s
1c410 69 7a 65 29 2e 20 52 65 74 75 72 6e 20 53 51 4c  ize). Return SQL
1c420 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73  ITE_OK if succes
1c430 73 66 75 6c 2c 20 6f 72 20 61 6e 0a 2a 2a 20 65  sful, or an.** e
1c440 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77  rror code otherw
1c450 69 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ise..*/.int sqli
1c460 74 65 33 57 61 6c 52 65 61 64 46 72 61 6d 65 28  te3WalReadFrame(
1c470 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20  .  Wal *pWal,   
1c480 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c490 20 20 20 2f 2a 20 57 41 4c 20 68 61 6e 64 6c 65     /* WAL handle
1c4a0 20 2a 2f 0a 20 20 75 33 32 20 69 52 65 61 64 2c   */.  u32 iRead,
1c4b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c4c0 20 20 20 20 20 20 2f 2a 20 46 72 61 6d 65 20 74        /* Frame t
1c4d0 6f 20 72 65 61 64 20 2a 2f 0a 20 20 69 6e 74 20  o read */.  int 
1c4e0 6e 4f 75 74 2c 20 20 20 20 20 20 20 20 20 20 20  nOut,           
1c4f0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
1c500 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20 70 4f  ize of buffer pO
1c510 75 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20  ut in bytes */. 
1c520 20 75 38 20 2a 70 4f 75 74 20 20 20 20 20 20 20   u8 *pOut       
1c530 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c540 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 77 72   /* Buffer to wr
1c550 69 74 65 20 70 61 67 65 20 64 61 74 61 20 74 6f  ite page data to
1c560 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 73 7a 3b   */.){.  int sz;
1c570 0a 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 0a  .  i64 iOffset;.
1c580 20 20 73 7a 20 3d 20 70 57 61 6c 2d 3e 68 64 72    sz = pWal->hdr
1c590 2e 73 7a 50 61 67 65 3b 0a 20 20 73 7a 20 3d 20  .szPage;.  sz = 
1c5a0 28 73 7a 26 30 78 66 65 30 30 29 20 2b 20 28 28  (sz&0xfe00) + ((
1c5b0 73 7a 26 30 78 30 30 30 31 29 3c 3c 31 36 29 3b  sz&0x0001)<<16);
1c5c0 0a 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 3c  .  testcase( sz<
1c5d0 3d 33 32 37 36 38 20 29 3b 0a 20 20 74 65 73 74  =32768 );.  test
1c5e0 63 61 73 65 28 20 73 7a 3e 3d 36 35 35 33 36 20  case( sz>=65536 
1c5f0 29 3b 0a 20 20 69 4f 66 66 73 65 74 20 3d 20 77  );.  iOffset = w
1c600 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 52  alFrameOffset(iR
1c610 65 61 64 2c 20 73 7a 29 20 2b 20 57 41 4c 5f 46  ead, sz) + WAL_F
1c620 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20 20  RAME_HDRSIZE;.  
1c630 2f 2a 20 74 65 73 74 63 61 73 65 28 20 49 53 5f  /* testcase( IS_
1c640 42 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29  BIG_INT(iOffset)
1c650 20 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73 20   ); // requires 
1c660 61 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20 20  a 4GiB WAL */.  
1c670 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73  return sqlite3Os
1c680 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46  Read(pWal->pWalF
1c690 64 2c 20 70 4f 75 74 2c 20 28 6e 4f 75 74 3e 73  d, pOut, (nOut>s
1c6a0 7a 20 3f 20 73 7a 20 3a 20 6e 4f 75 74 29 2c 20  z ? sz : nOut), 
1c6b0 69 4f 66 66 73 65 74 29 3b 0a 7d 0a 0a 2f 2a 20  iOffset);.}../* 
1c6c0 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73  .** Return the s
1c6d0 69 7a 65 20 6f 66 20 74 68 65 20 64 61 74 61 62  ize of the datab
1c6e0 61 73 65 20 69 6e 20 70 61 67 65 73 20 28 6f 72  ase in pages (or
1c6f0 20 7a 65 72 6f 2c 20 69 66 20 75 6e 6b 6e 6f 77   zero, if unknow
1c700 6e 29 2e 0a 2a 2f 0a 50 67 6e 6f 20 73 71 6c 69  n)..*/.Pgno sqli
1c710 74 65 33 57 61 6c 44 62 73 69 7a 65 28 57 61 6c  te3WalDbsize(Wal
1c720 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28 20 70   *pWal){.  if( p
1c730 57 61 6c 20 26 26 20 41 4c 57 41 59 53 28 70 57  Wal && ALWAYS(pW
1c740 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 29  al->readLock>=0)
1c750 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
1c760 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 3b 0a  Wal->hdr.nPage;.
1c770 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a    }.  return 0;.
1c780 7d 0a 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20  }.../* .** This 
1c790 66 75 6e 63 74 69 6f 6e 20 73 74 61 72 74 73 20  function starts 
1c7a0 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74  a write transact
1c7b0 69 6f 6e 20 6f 6e 20 74 68 65 20 57 41 4c 2e 0a  ion on the WAL..
1c7c0 2a 2a 0a 2a 2a 20 41 20 72 65 61 64 20 74 72 61  **.** A read tra
1c7d0 6e 73 61 63 74 69 6f 6e 20 6d 75 73 74 20 68 61  nsaction must ha
1c7e0 76 65 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20  ve already been 
1c7f0 73 74 61 72 74 65 64 20 62 79 20 61 20 70 72 69  started by a pri
1c800 6f 72 20 63 61 6c 6c 0a 2a 2a 20 74 6f 20 73 71  or call.** to sq
1c810 6c 69 74 65 33 57 61 6c 42 65 67 69 6e 52 65 61  lite3WalBeginRea
1c820 64 54 72 61 6e 73 61 63 74 69 6f 6e 28 29 2e 0a  dTransaction()..
1c830 2a 2a 0a 2a 2a 20 49 66 20 61 6e 6f 74 68 65 72  **.** If another
1c840 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65   thread or proce
1c850 73 73 20 68 61 73 20 77 72 69 74 74 65 6e 20 69  ss has written i
1c860 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65  nto the database
1c870 20 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 72 65   since.** the re
1c880 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77  ad transaction w
1c890 61 73 20 73 74 61 72 74 65 64 2c 20 74 68 65 6e  as started, then
1c8a0 20 69 74 20 69 73 20 6e 6f 74 20 70 6f 73 73 69   it is not possi
1c8b0 62 6c 65 20 66 6f 72 20 74 68 69 73 0a 2a 2a 20  ble for this.** 
1c8c0 74 68 72 65 61 64 20 74 6f 20 77 72 69 74 65 20  thread to write 
1c8d0 61 73 20 64 6f 69 6e 67 20 73 6f 20 77 6f 75 6c  as doing so woul
1c8e0 64 20 63 61 75 73 65 20 61 20 66 6f 72 6b 2e 20  d cause a fork. 
1c8f0 20 53 6f 20 74 68 69 73 20 72 6f 75 74 69 6e 65   So this routine
1c900 0a 2a 2a 20 72 65 74 75 72 6e 73 20 53 51 4c 49  .** returns SQLI
1c910 54 45 5f 42 55 53 59 20 69 6e 20 74 68 61 74 20  TE_BUSY in that 
1c920 63 61 73 65 20 61 6e 64 20 6e 6f 20 77 72 69 74  case and no writ
1c930 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73  e transaction is
1c940 20 73 74 61 72 74 65 64 2e 0a 2a 2a 0a 2a 2a 20   started..**.** 
1c950 54 68 65 72 65 20 63 61 6e 20 6f 6e 6c 79 20 62  There can only b
1c960 65 20 61 20 73 69 6e 67 6c 65 20 77 72 69 74 65  e a single write
1c970 72 20 61 63 74 69 76 65 20 61 74 20 61 20 74 69  r active at a ti
1c980 6d 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  me..*/.int sqlit
1c990 65 33 57 61 6c 42 65 67 69 6e 57 72 69 74 65 54  e3WalBeginWriteT
1c9a0 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a  ransaction(Wal *
1c9b0 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 3b  pWal){.  int rc;
1c9c0 0a 0a 20 20 2f 2a 20 43 61 6e 6e 6f 74 20 73 74  ..  /* Cannot st
1c9d0 61 72 74 20 61 20 77 72 69 74 65 20 74 72 61 6e  art a write tran
1c9e0 73 61 63 74 69 6f 6e 20 77 69 74 68 6f 75 74 20  saction without 
1c9f0 66 69 72 73 74 20 68 6f 6c 64 69 6e 67 20 61 20  first holding a 
1ca00 72 65 61 64 0a 20 20 2a 2a 20 74 72 61 6e 73 61  read.  ** transa
1ca10 63 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65  ction. */.  asse
1ca20 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  rt( pWal->readLo
1ca30 63 6b 3e 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  ck>=0 );.  asser
1ca40 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  t( pWal->writeLo
1ca50 63 6b 3d 3d 30 20 26 26 20 70 57 61 6c 2d 3e 69  ck==0 && pWal->i
1ca60 52 65 43 6b 73 75 6d 3d 3d 30 20 29 3b 0a 0a 20  ReCksum==0 );.. 
1ca70 20 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4f   if( pWal->readO
1ca80 6e 6c 79 20 29 7b 0a 20 20 20 20 72 65 74 75 72  nly ){.    retur
1ca90 6e 20 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c  n SQLITE_READONL
1caa0 59 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4f 6e 6c  Y;.  }..  /* Onl
1cab0 79 20 6f 6e 65 20 77 72 69 74 65 72 20 61 6c 6c  y one writer all
1cac0 6f 77 65 64 20 61 74 20 61 20 74 69 6d 65 2e 20  owed at a time. 
1cad0 20 47 65 74 20 74 68 65 20 77 72 69 74 65 20 6c   Get the write l
1cae0 6f 63 6b 2e 20 20 52 65 74 75 72 6e 0a 20 20 2a  ock.  Return.  *
1caf0 2a 20 53 51 4c 49 54 45 5f 42 55 53 59 20 69 66  * SQLITE_BUSY if
1cb00 20 75 6e 61 62 6c 65 2e 0a 20 20 2a 2f 0a 20 20   unable..  */.  
1cb10 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
1cb20 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
1cb30 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  WRITE_LOCK, 1);.
1cb40 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20    if( rc ){.    
1cb50 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20  return rc;.  }. 
1cb60 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
1cb70 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 49 66 20 61   = 1;..  /* If a
1cb80 6e 6f 74 68 65 72 20 63 6f 6e 6e 65 63 74 69 6f  nother connectio
1cb90 6e 20 68 61 73 20 77 72 69 74 74 65 6e 20 74 6f  n has written to
1cba0 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
1cbb0 6c 65 20 73 69 6e 63 65 20 74 68 65 0a 20 20 2a  le since the.  *
1cbc0 2a 20 74 69 6d 65 20 74 68 65 20 72 65 61 64 20  * time the read 
1cbd0 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74  transaction on t
1cbe0 68 69 73 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 77  his connection w
1cbf0 61 73 20 73 74 61 72 74 65 64 2c 20 74 68 65 6e  as started, then
1cc00 0a 20 20 2a 2a 20 74 68 65 20 77 72 69 74 65 20  .  ** the write 
1cc10 69 73 20 64 69 73 61 6c 6c 6f 77 65 64 2e 0a 20  is disallowed.. 
1cc20 20 2a 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70   */.  if( memcmp
1cc30 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76 6f  (&pWal->hdr, (vo
1cc40 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72  id *)walIndexHdr
1cc50 28 70 57 61 6c 29 2c 20 73 69 7a 65 6f 66 28 57  (pWal), sizeof(W
1cc60 61 6c 49 6e 64 65 78 48 64 72 29 29 21 3d 30 20  alIndexHdr))!=0 
1cc70 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b  ){.    walUnlock
1cc80 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
1cc90 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20  WAL_WRITE_LOCK, 
1cca0 31 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72  1);.    pWal->wr
1ccb0 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20  iteLock = 0;.   
1ccc0 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55 53   rc = SQLITE_BUS
1ccd0 59 5f 53 4e 41 50 53 48 4f 54 3b 0a 20 20 7d 0a  Y_SNAPSHOT;.  }.
1cce0 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
1ccf0 0a 2f 2a 0a 2a 2a 20 45 6e 64 20 61 20 77 72 69  ./*.** End a wri
1cd00 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20  te transaction. 
1cd10 20 54 68 65 20 63 6f 6d 6d 69 74 20 68 61 73 20   The commit has 
1cd20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 64 6f 6e  already been don
1cd30 65 2e 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75 74  e.  This.** rout
1cd40 69 6e 65 20 6d 65 72 65 6c 79 20 72 65 6c 65 61  ine merely relea
1cd50 73 65 73 20 74 68 65 20 6c 6f 63 6b 2e 0a 2a 2f  ses the lock..*/
1cd60 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 45  .int sqlite3WalE
1cd70 6e 64 57 72 69 74 65 54 72 61 6e 73 61 63 74 69  ndWriteTransacti
1cd80 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20  on(Wal *pWal){. 
1cd90 20 69 66 28 20 70 57 61 6c 2d 3e 77 72 69 74 65   if( pWal->write
1cda0 4c 6f 63 6b 20 29 7b 0a 20 20 20 20 77 61 6c 55  Lock ){.    walU
1cdb0 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  nlockExclusive(p
1cdc0 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c  Wal, WAL_WRITE_L
1cdd0 4f 43 4b 2c 20 31 29 3b 0a 20 20 20 20 70 57 61  OCK, 1);.    pWa
1cde0 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30  l->writeLock = 0
1cdf0 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 69 52 65 43  ;.    pWal->iReC
1ce00 6b 73 75 6d 20 3d 20 30 3b 0a 20 20 20 20 70 57  ksum = 0;.    pW
1ce10 61 6c 2d 3e 74 72 75 6e 63 61 74 65 4f 6e 43 6f  al->truncateOnCo
1ce20 6d 6d 69 74 20 3d 20 30 3b 0a 20 20 7d 0a 20 20  mmit = 0;.  }.  
1ce30 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
1ce40 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 61 6e  ;.}../*.** If an
1ce50 79 20 64 61 74 61 20 68 61 73 20 62 65 65 6e 20  y data has been 
1ce60 77 72 69 74 74 65 6e 20 28 62 75 74 20 6e 6f 74  written (but not
1ce70 20 63 6f 6d 6d 69 74 74 65 64 29 20 74 6f 20 74   committed) to t
1ce80 68 65 20 6c 6f 67 20 66 69 6c 65 2c 20 74 68 69  he log file, thi
1ce90 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 6d 6f  s.** function mo
1cea0 76 65 73 20 74 68 65 20 77 72 69 74 65 2d 70 6f  ves the write-po
1ceb0 69 6e 74 65 72 20 62 61 63 6b 20 74 6f 20 74 68  inter back to th
1cec0 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 74  e start of the t
1ced0 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a  ransaction..**.*
1cee0 2a 20 41 64 64 69 74 69 6f 6e 61 6c 6c 79 2c 20  * Additionally, 
1cef0 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 66 75 6e  the callback fun
1cf00 63 74 69 6f 6e 20 69 73 20 69 6e 76 6f 6b 65 64  ction is invoked
1cf10 20 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65 20   for each frame 
1cf20 77 72 69 74 74 65 6e 0a 2a 2a 20 74 6f 20 74 68  written.** to th
1cf30 65 20 57 41 4c 20 73 69 6e 63 65 20 74 68 65 20  e WAL since the 
1cf40 73 74 61 72 74 20 6f 66 20 74 68 65 20 74 72 61  start of the tra
1cf50 6e 73 61 63 74 69 6f 6e 2e 20 49 66 20 74 68 65  nsaction. If the
1cf60 20 63 61 6c 6c 62 61 63 6b 20 72 65 74 75 72 6e   callback return
1cf70 73 0a 2a 2a 20 6f 74 68 65 72 20 74 68 61 6e 20  s.** other than 
1cf80 53 51 4c 49 54 45 5f 4f 4b 2c 20 69 74 20 69 73  SQLITE_OK, it is
1cf90 20 6e 6f 74 20 69 6e 76 6f 6b 65 64 20 61 67 61   not invoked aga
1cfa0 69 6e 20 61 6e 64 20 74 68 65 20 65 72 72 6f 72  in and the error
1cfb0 20 63 6f 64 65 20 69 73 0a 2a 2a 20 72 65 74 75   code is.** retu
1cfc0 72 6e 65 64 20 74 6f 20 74 68 65 20 63 61 6c 6c  rned to the call
1cfd0 65 72 2e 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77  er..**.** Otherw
1cfe0 69 73 65 2c 20 69 66 20 74 68 65 20 63 61 6c 6c  ise, if the call
1cff0 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20 64 6f  back function do
1d000 65 73 20 6e 6f 74 20 72 65 74 75 72 6e 20 61 6e  es not return an
1d010 20 65 72 72 6f 72 2c 20 74 68 69 73 0a 2a 2a 20   error, this.** 
1d020 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
1d030 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69   SQLITE_OK..*/.i
1d040 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 55 6e 64  nt sqlite3WalUnd
1d050 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  o(Wal *pWal, int
1d060 20 28 2a 78 55 6e 64 6f 29 28 76 6f 69 64 20 2a   (*xUndo)(void *
1d070 2c 20 50 67 6e 6f 29 2c 20 76 6f 69 64 20 2a 70  , Pgno), void *p
1d080 55 6e 64 6f 43 74 78 29 7b 0a 20 20 69 6e 74 20  UndoCtx){.  int 
1d090 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
1d0a0 20 20 69 66 28 20 41 4c 57 41 59 53 28 70 57 61    if( ALWAYS(pWa
1d0b0 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 29 20 29 7b  l->writeLock) ){
1d0c0 0a 20 20 20 20 50 67 6e 6f 20 69 4d 61 78 20 3d  .    Pgno iMax =
1d0d0 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
1d0e0 6d 65 3b 0a 20 20 20 20 50 67 6e 6f 20 69 46 72  me;.    Pgno iFr
1d0f0 61 6d 65 3b 0a 20 20 0a 20 20 20 20 2f 2a 20 52  ame;.  .    /* R
1d100 65 73 74 6f 72 65 20 74 68 65 20 63 6c 69 65 6e  estore the clien
1d110 74 73 20 63 61 63 68 65 20 6f 66 20 74 68 65 20  ts cache of the 
1d120 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
1d130 20 74 6f 20 74 68 65 20 73 74 61 74 65 20 69 74   to the state it
1d140 0a 20 20 20 20 2a 2a 20 77 61 73 20 69 6e 20 62  .    ** was in b
1d150 65 66 6f 72 65 20 74 68 65 20 63 6c 69 65 6e 74  efore the client
1d160 20 62 65 67 61 6e 20 77 72 69 74 69 6e 67 20 74   began writing t
1d170 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20  o the database. 
1d180 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 63  .    */.    memc
1d190 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28  py(&pWal->hdr, (
1d1a0 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48  void *)walIndexH
1d1b0 64 72 28 70 57 61 6c 29 2c 20 73 69 7a 65 6f 66  dr(pWal), sizeof
1d1c0 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a  (WalIndexHdr));.
1d1d0 0a 20 20 20 20 66 6f 72 28 69 46 72 61 6d 65 3d  .    for(iFrame=
1d1e0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
1d1f0 65 2b 31 3b 20 0a 20 20 20 20 20 20 20 20 41 4c  e+1; .        AL
1d200 57 41 59 53 28 72 63 3d 3d 53 51 4c 49 54 45 5f  WAYS(rc==SQLITE_
1d210 4f 4b 29 20 26 26 20 69 46 72 61 6d 65 3c 3d 69  OK) && iFrame<=i
1d220 4d 61 78 3b 20 0a 20 20 20 20 20 20 20 20 69 46  Max; .        iF
1d230 72 61 6d 65 2b 2b 0a 20 20 20 20 29 7b 0a 20 20  rame++.    ){.  
1d240 20 20 20 20 2f 2a 20 54 68 69 73 20 63 61 6c 6c      /* This call
1d250 20 63 61 6e 6e 6f 74 20 66 61 69 6c 2e 20 55 6e   cannot fail. Un
1d260 6c 65 73 73 20 74 68 65 20 70 61 67 65 20 66 6f  less the page fo
1d270 72 20 77 68 69 63 68 20 74 68 65 20 70 61 67 65  r which the page
1d280 20 6e 75 6d 62 65 72 0a 20 20 20 20 20 20 2a 2a   number.      **
1d290 20 69 73 20 70 61 73 73 65 64 20 61 73 20 74 68   is passed as th
1d2a0 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
1d2b0 74 20 69 73 20 28 61 29 20 69 6e 20 74 68 65 20  t is (a) in the 
1d2c0 63 61 63 68 65 20 61 6e 64 20 0a 20 20 20 20 20  cache and .     
1d2d0 20 2a 2a 20 28 62 29 20 68 61 73 20 61 6e 20 6f   ** (b) has an o
1d2e0 75 74 73 74 61 6e 64 69 6e 67 20 72 65 66 65 72  utstanding refer
1d2f0 65 6e 63 65 2c 20 74 68 65 6e 20 78 55 6e 64 6f  ence, then xUndo
1d300 20 69 73 20 65 69 74 68 65 72 20 61 20 6e 6f 2d   is either a no-
1d310 6f 70 0a 20 20 20 20 20 20 2a 2a 20 28 69 66 20  op.      ** (if 
1d320 28 61 29 20 69 73 20 66 61 6c 73 65 29 20 6f 72  (a) is false) or
1d330 20 73 69 6d 70 6c 79 20 65 78 70 65 6c 73 20 74   simply expels t
1d340 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65  he page from the
1d350 20 63 61 63 68 65 20 28 69 66 20 28 62 29 0a 20   cache (if (b). 
1d360 20 20 20 20 20 2a 2a 20 69 73 20 66 61 6c 73 65       ** is false
1d370 29 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20 20  )..      **.    
1d380 20 20 2a 2a 20 49 66 20 74 68 65 20 75 70 70 65    ** If the uppe
1d390 72 20 6c 61 79 65 72 20 69 73 20 64 6f 69 6e 67  r layer is doing
1d3a0 20 61 20 72 6f 6c 6c 62 61 63 6b 2c 20 69 74 20   a rollback, it 
1d3b0 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74 68  is guaranteed th
1d3c0 61 74 20 74 68 65 72 65 0a 20 20 20 20 20 20 2a  at there.      *
1d3d0 2a 20 61 72 65 20 6e 6f 20 6f 75 74 73 74 61 6e  * are no outstan
1d3e0 64 69 6e 67 20 72 65 66 65 72 65 6e 63 65 73 20  ding references 
1d3f0 74 6f 20 61 6e 79 20 70 61 67 65 20 6f 74 68 65  to any page othe
1d400 72 20 74 68 61 6e 20 70 61 67 65 20 31 2e 20 41  r than page 1. A
1d410 6e 64 0a 20 20 20 20 20 20 2a 2a 20 70 61 67 65  nd.      ** page
1d420 20 31 20 69 73 20 6e 65 76 65 72 20 77 72 69 74   1 is never writ
1d430 74 65 6e 20 74 6f 20 74 68 65 20 6c 6f 67 20 75  ten to the log u
1d440 6e 74 69 6c 20 74 68 65 20 74 72 61 6e 73 61 63  ntil the transac
1d450 74 69 6f 6e 20 69 73 0a 20 20 20 20 20 20 2a 2a  tion is.      **
1d460 20 63 6f 6d 6d 69 74 74 65 64 2e 20 41 73 20 61   committed. As a
1d470 20 72 65 73 75 6c 74 2c 20 74 68 65 20 63 61 6c   result, the cal
1d480 6c 20 74 6f 20 78 55 6e 64 6f 20 6d 61 79 20 6e  l to xUndo may n
1d490 6f 74 20 66 61 69 6c 2e 0a 20 20 20 20 20 20 2a  ot fail..      *
1d4a0 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  /.      assert( 
1d4b0 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61  walFramePgno(pWa
1d4c0 6c 2c 20 69 46 72 61 6d 65 29 21 3d 31 20 29 3b  l, iFrame)!=1 );
1d4d0 0a 20 20 20 20 20 20 72 63 20 3d 20 78 55 6e 64  .      rc = xUnd
1d4e0 6f 28 70 55 6e 64 6f 43 74 78 2c 20 77 61 6c 46  o(pUndoCtx, walF
1d4f0 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69  ramePgno(pWal, i
1d500 46 72 61 6d 65 29 29 3b 0a 20 20 20 20 7d 0a 20  Frame));.    }. 
1d510 20 20 20 69 66 28 20 69 4d 61 78 21 3d 70 57 61     if( iMax!=pWa
1d520 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29  l->hdr.mxFrame )
1d530 20 77 61 6c 43 6c 65 61 6e 75 70 48 61 73 68 28   walCleanupHash(
1d540 70 57 61 6c 29 3b 0a 20 20 7d 0a 20 20 72 65 74  pWal);.  }.  ret
1d550 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  urn rc;.}../* .*
1d560 2a 20 41 72 67 75 6d 65 6e 74 20 61 57 61 6c 44  * Argument aWalD
1d570 61 74 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74  ata must point t
1d580 6f 20 61 6e 20 61 72 72 61 79 20 6f 66 20 57 41  o an array of WA
1d590 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54  L_SAVEPOINT_NDAT
1d5a0 41 20 75 33 32 20 0a 2a 2a 20 76 61 6c 75 65 73  A u32 .** values
1d5b0 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
1d5c0 70 6f 70 75 6c 61 74 65 73 20 74 68 65 20 61 72  populates the ar
1d5d0 72 61 79 20 77 69 74 68 20 76 61 6c 75 65 73 20  ray with values 
1d5e0 72 65 71 75 69 72 65 64 20 74 6f 20 0a 2a 2a 20  required to .** 
1d5f0 22 72 6f 6c 6c 62 61 63 6b 22 20 74 68 65 20 77  "rollback" the w
1d600 72 69 74 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66  rite position of
1d610 20 74 68 65 20 57 41 4c 20 68 61 6e 64 6c 65 20   the WAL handle 
1d620 62 61 63 6b 20 74 6f 20 74 68 65 20 63 75 72 72  back to the curr
1d630 65 6e 74 20 0a 2a 2a 20 70 6f 69 6e 74 20 69 6e  ent .** point in
1d640 20 74 68 65 20 65 76 65 6e 74 20 6f 66 20 61 20   the event of a 
1d650 73 61 76 65 70 6f 69 6e 74 20 72 6f 6c 6c 62 61  savepoint rollba
1d660 63 6b 20 28 76 69 61 20 57 61 6c 53 61 76 65 70  ck (via WalSavep
1d670 6f 69 6e 74 55 6e 64 6f 28 29 29 2e 0a 2a 2f 0a  ointUndo())..*/.
1d680 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 53  void sqlite3WalS
1d690 61 76 65 70 6f 69 6e 74 28 57 61 6c 20 2a 70 57  avepoint(Wal *pW
1d6a0 61 6c 2c 20 75 33 32 20 2a 61 57 61 6c 44 61 74  al, u32 *aWalDat
1d6b0 61 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57  a){.  assert( pW
1d6c0 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
1d6d0 0a 20 20 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d  .  aWalData[0] =
1d6e0 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
1d6f0 6d 65 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 31  me;.  aWalData[1
1d700 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46  ] = pWal->hdr.aF
1d710 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20  rameCksum[0];.  
1d720 61 57 61 6c 44 61 74 61 5b 32 5d 20 3d 20 70 57  aWalData[2] = pW
1d730 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
1d740 73 75 6d 5b 31 5d 3b 0a 20 20 61 57 61 6c 44 61  sum[1];.  aWalDa
1d750 74 61 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e 6e 43  ta[3] = pWal->nC
1d760 6b 70 74 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4d  kpt;.}../* .** M
1d770 6f 76 65 20 74 68 65 20 77 72 69 74 65 20 70 6f  ove the write po
1d780 73 69 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41  sition of the WA
1d790 4c 20 62 61 63 6b 20 74 6f 20 74 68 65 20 70 6f  L back to the po
1d7a0 69 6e 74 20 69 64 65 6e 74 69 66 69 65 64 20 62  int identified b
1d7b0 79 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 73 20  y.** the values 
1d7c0 69 6e 20 74 68 65 20 61 57 61 6c 44 61 74 61 5b  in the aWalData[
1d7d0 5d 20 61 72 72 61 79 2e 20 61 57 61 6c 44 61 74  ] array. aWalDat
1d7e0 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f 20  a must point to 
1d7f0 61 6e 20 61 72 72 61 79 0a 2a 2a 20 6f 66 20 57  an array.** of W
1d800 41 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41  AL_SAVEPOINT_NDA
1d810 54 41 20 75 33 32 20 76 61 6c 75 65 73 20 74 68  TA u32 values th
1d820 61 74 20 68 61 73 20 62 65 65 6e 20 70 72 65 76  at has been prev
1d830 69 6f 75 73 6c 79 20 70 6f 70 75 6c 61 74 65 64  iously populated
1d840 0a 2a 2a 20 62 79 20 61 20 63 61 6c 6c 20 74 6f  .** by a call to
1d850 20 57 61 6c 53 61 76 65 70 6f 69 6e 74 28 29 2e   WalSavepoint().
1d860 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
1d870 61 6c 53 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28  alSavepointUndo(
1d880 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a  Wal *pWal, u32 *
1d890 61 57 61 6c 44 61 74 61 29 7b 0a 20 20 69 6e 74  aWalData){.  int
1d8a0 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
1d8b0 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ..  assert( pWal
1d8c0 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20  ->writeLock );. 
1d8d0 20 61 73 73 65 72 74 28 20 61 57 61 6c 44 61 74   assert( aWalDat
1d8e0 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43 6b 70  a[3]!=pWal->nCkp
1d8f0 74 20 7c 7c 20 61 57 61 6c 44 61 74 61 5b 30 5d  t || aWalData[0]
1d900 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  <=pWal->hdr.mxFr
1d910 61 6d 65 20 29 3b 0a 0a 20 20 69 66 28 20 61 57  ame );..  if( aW
1d920 61 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d  alData[3]!=pWal-
1d930 3e 6e 43 6b 70 74 20 29 7b 0a 20 20 20 20 2f 2a  >nCkpt ){.    /*
1d940 20 54 68 69 73 20 73 61 76 65 70 6f 69 6e 74 20   This savepoint 
1d950 77 61 73 20 6f 70 65 6e 65 64 20 69 6d 6d 65 64  was opened immed
1d960 69 61 74 65 6c 79 20 61 66 74 65 72 20 74 68 65  iately after the
1d970 20 77 72 69 74 65 2d 74 72 61 6e 73 61 63 74 69   write-transacti
1d980 6f 6e 0a 20 20 20 20 2a 2a 20 77 61 73 20 73 74  on.    ** was st
1d990 61 72 74 65 64 2e 20 52 69 67 68 74 20 61 66 74  arted. Right aft
1d9a0 65 72 20 74 68 61 74 2c 20 74 68 65 20 77 72 69  er that, the wri
1d9b0 74 65 72 20 64 65 63 69 64 65 64 20 74 6f 20 77  ter decided to w
1d9c0 72 61 70 20 61 72 6f 75 6e 64 0a 20 20 20 20 2a  rap around.    *
1d9d0 2a 20 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f  * to the start o
1d9e0 66 20 74 68 65 20 6c 6f 67 2e 20 55 70 64 61 74  f the log. Updat
1d9f0 65 20 74 68 65 20 73 61 76 65 70 6f 69 6e 74 20  e the savepoint 
1da00 76 61 6c 75 65 73 20 74 6f 20 6d 61 74 63 68 2e  values to match.
1da10 0a 20 20 20 20 2a 2f 0a 20 20 20 20 61 57 61 6c  .    */.    aWal
1da20 44 61 74 61 5b 30 5d 20 3d 20 30 3b 0a 20 20 20  Data[0] = 0;.   
1da30 20 61 57 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70   aWalData[3] = p
1da40 57 61 6c 2d 3e 6e 43 6b 70 74 3b 0a 20 20 7d 0a  Wal->nCkpt;.  }.
1da50 0a 20 20 69 66 28 20 61 57 61 6c 44 61 74 61 5b  .  if( aWalData[
1da60 30 5d 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  0]<pWal->hdr.mxF
1da70 72 61 6d 65 20 29 7b 0a 20 20 20 20 70 57 61 6c  rame ){.    pWal
1da80 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20  ->hdr.mxFrame = 
1da90 61 57 61 6c 44 61 74 61 5b 30 5d 3b 0a 20 20 20  aWalData[0];.   
1daa0 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
1dab0 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 57 61 6c  eCksum[0] = aWal
1dac0 44 61 74 61 5b 31 5d 3b 0a 20 20 20 20 70 57 61  Data[1];.    pWa
1dad0 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
1dae0 75 6d 5b 31 5d 20 3d 20 61 57 61 6c 44 61 74 61  um[1] = aWalData
1daf0 5b 32 5d 3b 0a 20 20 20 20 77 61 6c 43 6c 65 61  [2];.    walClea
1db00 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20  nupHash(pWal);. 
1db10 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
1db20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
1db30 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
1db40 64 20 6a 75 73 74 20 62 65 66 6f 72 65 20 77 72  d just before wr
1db50 69 74 69 6e 67 20 61 20 73 65 74 20 6f 66 20 66  iting a set of f
1db60 72 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67  rames to the log
1db70 0a 2a 2a 20 66 69 6c 65 20 28 73 65 65 20 73 71  .** file (see sq
1db80 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28 29  lite3WalFrames()
1db90 29 2e 20 49 74 20 63 68 65 63 6b 73 20 74 6f 20  ). It checks to 
1dba0 73 65 65 20 69 66 2c 20 69 6e 73 74 65 61 64 20  see if, instead 
1dbb0 6f 66 20 61 70 70 65 6e 64 69 6e 67 0a 2a 2a 20  of appending.** 
1dbc0 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c  to the current l
1dbd0 6f 67 20 66 69 6c 65 2c 20 69 74 20 69 73 20 70  og file, it is p
1dbe0 6f 73 73 69 62 6c 65 20 74 6f 20 6f 76 65 72 77  ossible to overw
1dbf0 72 69 74 65 20 74 68 65 20 73 74 61 72 74 20 6f  rite the start o
1dc00 66 20 74 68 65 0a 2a 2a 20 65 78 69 73 74 69 6e  f the.** existin
1dc10 67 20 6c 6f 67 20 66 69 6c 65 20 77 69 74 68 20  g log file with 
1dc20 74 68 65 20 6e 65 77 20 66 72 61 6d 65 73 20 28  the new frames (
1dc30 69 2e 65 2e 20 22 72 65 73 65 74 22 20 74 68 65  i.e. "reset" the
1dc40 20 6c 6f 67 29 2e 20 49 66 20 73 6f 2c 0a 2a 2a   log). If so,.**
1dc50 20 69 74 20 73 65 74 73 20 70 57 61 6c 2d 3e 68   it sets pWal->h
1dc60 64 72 2e 6d 78 46 72 61 6d 65 20 74 6f 20 30 2e  dr.mxFrame to 0.
1dc70 20 4f 74 68 65 72 77 69 73 65 2c 20 70 57 61 6c   Otherwise, pWal
1dc80 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73  ->hdr.mxFrame is
1dc90 20 6c 65 66 74 0a 2a 2a 20 75 6e 63 68 61 6e 67   left.** unchang
1dca0 65 64 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45  ed..**.** SQLITE
1dcb0 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20  _OK is returned 
1dcc0 69 66 20 6e 6f 20 65 72 72 6f 72 20 69 73 20 65  if no error is e
1dcd0 6e 63 6f 75 6e 74 65 72 65 64 20 28 72 65 67 61  ncountered (rega
1dce0 72 64 6c 65 73 73 20 6f 66 20 77 68 65 74 68 65  rdless of whethe
1dcf0 72 0a 2a 2a 20 6f 72 20 6e 6f 74 20 70 57 61 6c  r.** or not pWal
1dd00 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73  ->hdr.mxFrame is
1dd10 20 6d 6f 64 69 66 69 65 64 29 2e 20 41 6e 20 53   modified). An S
1dd20 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
1dd30 20 69 73 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20   is returned.** 
1dd40 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  if an error occu
1dd50 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  rs..*/.static in
1dd60 74 20 77 61 6c 52 65 73 74 61 72 74 4c 6f 67 28  t walRestartLog(
1dd70 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e  Wal *pWal){.  in
1dd80 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
1dd90 3b 0a 20 20 69 6e 74 20 63 6e 74 3b 0a 0a 20 20  ;.  int cnt;..  
1dda0 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  if( pWal->readLo
1ddb0 63 6b 3d 3d 30 20 29 7b 0a 20 20 20 20 76 6f 6c  ck==0 ){.    vol
1ddc0 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66  atile WalCkptInf
1ddd0 6f 20 2a 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b  o *pInfo = walCk
1dde0 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20  ptInfo(pWal);.  
1ddf0 20 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d    assert( pInfo-
1de00 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70 57 61 6c  >nBackfill==pWal
1de10 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b  ->hdr.mxFrame );
1de20 0a 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e  .    if( pInfo->
1de30 6e 42 61 63 6b 66 69 6c 6c 3e 30 20 29 7b 0a 20  nBackfill>0 ){. 
1de40 20 20 20 20 20 75 33 32 20 73 61 6c 74 31 3b 0a       u32 salt1;.
1de50 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 61        sqlite3_ra
1de60 6e 64 6f 6d 6e 65 73 73 28 34 2c 20 26 73 61 6c  ndomness(4, &sal
1de70 74 31 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  t1);.      rc = 
1de80 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65  walLockExclusive
1de90 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f  (pWal, WAL_READ_
1dea0 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45  LOCK(1), WAL_NRE
1deb0 41 44 45 52 2d 31 29 3b 0a 20 20 20 20 20 20 69  ADER-1);.      i
1dec0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
1ded0 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49   ){.        /* I
1dee0 66 20 61 6c 6c 20 72 65 61 64 65 72 73 20 61 72  f all readers ar
1def0 65 20 75 73 69 6e 67 20 57 41 4c 5f 52 45 41 44  e using WAL_READ
1df00 5f 4c 4f 43 4b 28 30 29 20 28 69 6e 20 6f 74 68  _LOCK(0) (in oth
1df10 65 72 20 77 6f 72 64 73 20 69 66 20 6e 6f 0a 20  er words if no. 
1df20 20 20 20 20 20 20 20 2a 2a 20 72 65 61 64 65 72         ** reader
1df30 73 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20  s are currently 
1df40 75 73 69 6e 67 20 74 68 65 20 57 41 4c 29 2c 20  using the WAL), 
1df50 74 68 65 6e 20 74 68 65 20 74 72 61 6e 73 61 63  then the transac
1df60 74 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 2a 2a  tions.        **
1df70 20 66 72 61 6d 65 73 20 77 69 6c 6c 20 6f 76 65   frames will ove
1df80 72 77 72 69 74 65 20 74 68 65 20 73 74 61 72 74  rwrite the start
1df90 20 6f 66 20 74 68 65 20 65 78 69 73 74 69 6e 67   of the existing
1dfa0 20 6c 6f 67 2e 20 55 70 64 61 74 65 20 74 68 65   log. Update the
1dfb0 0a 20 20 20 20 20 20 20 20 2a 2a 20 77 61 6c 2d  .        ** wal-
1dfc0 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f 20  index header to 
1dfd0 72 65 66 6c 65 63 74 20 74 68 69 73 2e 0a 20 20  reflect this..  
1dfe0 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20        **.       
1dff0 20 2a 2a 20 49 6e 20 74 68 65 6f 72 79 20 69 74   ** In theory it
1e000 20 77 6f 75 6c 64 20 62 65 20 4f 6b 20 74 6f 20   would be Ok to 
1e010 75 70 64 61 74 65 20 74 68 65 20 63 61 63 68 65  update the cache
1e020 20 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 6f   of the header o
1e030 6e 6c 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 61  nly.        ** a
1e040 74 20 74 68 69 73 20 70 6f 69 6e 74 2e 20 42 75  t this point. Bu
1e050 74 20 75 70 64 61 74 69 6e 67 20 74 68 65 20 61  t updating the a
1e060 63 74 75 61 6c 20 77 61 6c 2d 69 6e 64 65 78 20  ctual wal-index 
1e070 68 65 61 64 65 72 20 69 73 20 61 6c 73 6f 0a 20  header is also. 
1e080 20 20 20 20 20 20 20 2a 2a 20 73 61 66 65 20 61         ** safe a
1e090 6e 64 20 6d 65 61 6e 73 20 74 68 65 72 65 20 69  nd means there i
1e0a0 73 20 6e 6f 20 73 70 65 63 69 61 6c 20 63 61 73  s no special cas
1e0b0 65 20 66 6f 72 20 73 71 6c 69 74 65 33 57 61 6c  e for sqlite3Wal
1e0c0 55 6e 64 6f 28 29 0a 20 20 20 20 20 20 20 20 2a  Undo().        *
1e0d0 2a 20 74 6f 20 68 61 6e 64 6c 65 20 69 66 20 74  * to handle if t
1e0e0 68 69 73 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  his transaction 
1e0f0 69 73 20 72 6f 6c 6c 65 64 20 62 61 63 6b 2e 20  is rolled back. 
1e100 20 2a 2f 0a 20 20 20 20 20 20 20 20 77 61 6c 52   */.        walR
1e110 65 73 74 61 72 74 48 64 72 28 70 57 61 6c 2c 20  estartHdr(pWal, 
1e120 73 61 6c 74 31 29 3b 0a 20 20 20 20 20 20 20 20  salt1);.        
1e130 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69  walUnlockExclusi
1e140 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ve(pWal, WAL_REA
1e150 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e  D_LOCK(1), WAL_N
1e160 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20 20 20  READER-1);.     
1e170 20 7d 65 6c 73 65 20 69 66 28 20 72 63 21 3d 53   }else if( rc!=S
1e180 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20  QLITE_BUSY ){.  
1e190 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
1e1a0 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
1e1b0 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72     walUnlockShar
1e1c0 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ed(pWal, WAL_REA
1e1d0 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20 20  D_LOCK(0));.    
1e1e0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d  pWal->readLock =
1e1f0 20 2d 31 3b 0a 20 20 20 20 63 6e 74 20 3d 20 30   -1;.    cnt = 0
1e200 3b 0a 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20  ;.    do{.      
1e210 69 6e 74 20 6e 6f 74 55 73 65 64 3b 0a 20 20 20  int notUsed;.   
1e220 20 20 20 72 63 20 3d 20 77 61 6c 54 72 79 42 65     rc = walTryBe
1e230 67 69 6e 52 65 61 64 28 70 57 61 6c 2c 20 26 6e  ginRead(pWal, &n
1e240 6f 74 55 73 65 64 2c 20 31 2c 20 2b 2b 63 6e 74  otUsed, 1, ++cnt
1e250 29 3b 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 72  );.    }while( r
1e260 63 3d 3d 57 41 4c 5f 52 45 54 52 59 20 29 3b 0a  c==WAL_RETRY );.
1e270 20 20 20 20 61 73 73 65 72 74 28 20 28 72 63 26      assert( (rc&
1e280 30 78 66 66 29 21 3d 53 51 4c 49 54 45 5f 42 55  0xff)!=SQLITE_BU
1e290 53 59 20 29 3b 20 2f 2a 20 42 55 53 59 20 6e 6f  SY ); /* BUSY no
1e2a0 74 20 70 6f 73 73 69 62 6c 65 20 77 68 65 6e 20  t possible when 
1e2b0 75 73 65 57 61 6c 3d 3d 31 20 2a 2f 0a 20 20 20  useWal==1 */.   
1e2c0 20 74 65 73 74 63 61 73 65 28 20 28 72 63 26 30   testcase( (rc&0
1e2d0 78 66 66 29 3d 3d 53 51 4c 49 54 45 5f 49 4f 45  xff)==SQLITE_IOE
1e2e0 52 52 20 29 3b 0a 20 20 20 20 74 65 73 74 63 61  RR );.    testca
1e2f0 73 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 50  se( rc==SQLITE_P
1e300 52 4f 54 4f 43 4f 4c 20 29 3b 0a 20 20 20 20 74  ROTOCOL );.    t
1e310 65 73 74 63 61 73 65 28 20 72 63 3d 3d 53 51 4c  estcase( rc==SQL
1e320 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 7d 0a 20 20  ITE_OK );.  }.  
1e330 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
1e340 0a 2a 2a 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 20  .** Information 
1e350 61 62 6f 75 74 20 74 68 65 20 63 75 72 72 65 6e  about the curren
1e360 74 20 73 74 61 74 65 20 6f 66 20 74 68 65 20 57  t state of the W
1e370 41 4c 20 66 69 6c 65 20 61 6e 64 20 77 68 65 72  AL file and wher
1e380 65 0a 2a 2a 20 74 68 65 20 6e 65 78 74 20 66 73  e.** the next fs
1e390 79 6e 63 20 73 68 6f 75 6c 64 20 6f 63 63 75 72  ync should occur
1e3a0 20 2d 20 70 61 73 73 65 64 20 66 72 6f 6d 20 73   - passed from s
1e3b0 71 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28  qlite3WalFrames(
1e3c0 29 20 69 6e 74 6f 0a 2a 2a 20 77 61 6c 57 72 69  ) into.** walWri
1e3d0 74 65 54 6f 4c 6f 67 28 29 2e 0a 2a 2f 0a 74 79  teToLog()..*/.ty
1e3e0 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61 6c  pedef struct Wal
1e3f0 57 72 69 74 65 72 20 7b 0a 20 20 57 61 6c 20 2a  Writer {.  Wal *
1e400 70 57 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20  pWal;           
1e410 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63          /* The c
1e420 6f 6d 70 6c 65 74 65 20 57 41 4c 20 69 6e 66 6f  omplete WAL info
1e430 72 6d 61 74 69 6f 6e 20 2a 2f 0a 20 20 73 71 6c  rmation */.  sql
1e440 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 64 3b 20  ite3_file *pFd; 
1e450 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
1e460 20 57 41 4c 20 66 69 6c 65 20 74 6f 20 77 68 69   WAL file to whi
1e470 63 68 20 77 65 20 77 72 69 74 65 20 2a 2f 0a 20  ch we write */. 
1e480 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69   sqlite3_int64 i
1e490 53 79 6e 63 50 6f 69 6e 74 3b 20 20 20 20 2f 2a  SyncPoint;    /*
1e4a0 20 46 73 79 6e 63 20 61 74 20 74 68 69 73 20 6f   Fsync at this o
1e4b0 66 66 73 65 74 20 2a 2f 0a 20 20 69 6e 74 20 73  ffset */.  int s
1e4c0 79 6e 63 46 6c 61 67 73 3b 20 20 20 20 20 20 20  yncFlags;       
1e4d0 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73          /* Flags
1e4e0 20 66 6f 72 20 74 68 65 20 66 73 79 6e 63 20 2a   for the fsync *
1e4f0 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 3b 20  /.  int szPage; 
1e500 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e510 20 2f 2a 20 53 69 7a 65 20 6f 66 20 6f 6e 65 20   /* Size of one 
1e520 70 61 67 65 20 2a 2f 0a 7d 20 57 61 6c 57 72 69  page */.} WalWri
1e530 74 65 72 3b 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74  ter;../*.** Writ
1e540 65 20 69 41 6d 74 20 62 79 74 65 73 20 6f 66 20  e iAmt bytes of 
1e550 63 6f 6e 74 65 6e 74 20 69 6e 74 6f 20 74 68 65  content into the
1e560 20 57 41 4c 20 66 69 6c 65 20 62 65 67 69 6e 6e   WAL file beginn
1e570 69 6e 67 20 61 74 20 69 4f 66 66 73 65 74 2e 0a  ing at iOffset..
1e580 2a 2a 20 44 6f 20 61 20 73 79 6e 63 20 77 68 65  ** Do a sync whe
1e590 6e 20 63 72 6f 73 73 69 6e 67 20 74 68 65 20 70  n crossing the p
1e5a0 2d 3e 69 53 79 6e 63 50 6f 69 6e 74 20 62 6f 75  ->iSyncPoint bou
1e5b0 6e 64 61 72 79 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20  ndary..**.** In 
1e5c0 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 69 66 20  other words, if 
1e5d0 69 53 79 6e 63 50 6f 69 6e 74 20 69 73 20 69 6e  iSyncPoint is in
1e5e0 20 62 65 74 77 65 65 6e 20 69 4f 66 66 73 65 74   between iOffset
1e5f0 20 61 6e 64 20 69 4f 66 66 73 65 74 2b 69 41 6d   and iOffset+iAm
1e600 74 2c 0a 2a 2a 20 66 69 72 73 74 20 77 72 69 74  t,.** first writ
1e610 65 20 74 68 65 20 70 61 72 74 20 62 65 66 6f 72  e the part befor
1e620 65 20 69 53 79 6e 63 50 6f 69 6e 74 2c 20 74 68  e iSyncPoint, th
1e630 65 6e 20 73 79 6e 63 2c 20 74 68 65 6e 20 77 72  en sync, then wr
1e640 69 74 65 20 74 68 65 0a 2a 2a 20 72 65 73 74 2e  ite the.** rest.
1e650 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
1e660 61 6c 57 72 69 74 65 54 6f 4c 6f 67 28 0a 20 20  alWriteToLog(.  
1e670 57 61 6c 57 72 69 74 65 72 20 2a 70 2c 20 20 20  WalWriter *p,   
1e680 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41             /* WA
1e690 4c 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f  L to write to */
1e6a0 0a 20 20 76 6f 69 64 20 2a 70 43 6f 6e 74 65 6e  .  void *pConten
1e6b0 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  t,            /*
1e6c0 20 43 6f 6e 74 65 6e 74 20 74 6f 20 62 65 20 77   Content to be w
1e6d0 72 69 74 74 65 6e 20 2a 2f 0a 20 20 69 6e 74 20  ritten */.  int 
1e6e0 69 41 6d 74 2c 20 20 20 20 20 20 20 20 20 20 20  iAmt,           
1e6f0 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
1e700 20 6f 66 20 62 79 74 65 73 20 74 6f 20 77 72 69   of bytes to wri
1e710 74 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  te */.  sqlite3_
1e720 69 6e 74 36 34 20 69 4f 66 66 73 65 74 20 20 20  int64 iOffset   
1e730 20 20 20 2f 2a 20 53 74 61 72 74 20 77 72 69 74     /* Start writ
1e740 69 6e 67 20 61 74 20 74 68 69 73 20 6f 66 66 73  ing at this offs
1e750 65 74 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  et */.){.  int r
1e760 63 3b 0a 20 20 69 66 28 20 69 4f 66 66 73 65 74  c;.  if( iOffset
1e770 3c 70 2d 3e 69 53 79 6e 63 50 6f 69 6e 74 20 26  <p->iSyncPoint &
1e780 26 20 69 4f 66 66 73 65 74 2b 69 41 6d 74 3e 3d  & iOffset+iAmt>=
1e790 70 2d 3e 69 53 79 6e 63 50 6f 69 6e 74 20 29 7b  p->iSyncPoint ){
1e7a0 0a 20 20 20 20 69 6e 74 20 69 46 69 72 73 74 41  .    int iFirstA
1e7b0 6d 74 20 3d 20 28 69 6e 74 29 28 70 2d 3e 69 53  mt = (int)(p->iS
1e7c0 79 6e 63 50 6f 69 6e 74 20 2d 20 69 4f 66 66 73  yncPoint - iOffs
1e7d0 65 74 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71  et);.    rc = sq
1e7e0 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e  lite3OsWrite(p->
1e7f0 70 46 64 2c 20 70 43 6f 6e 74 65 6e 74 2c 20 69  pFd, pContent, i
1e800 46 69 72 73 74 41 6d 74 2c 20 69 4f 66 66 73 65  FirstAmt, iOffse
1e810 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63 20 29  t);.    if( rc )
1e820 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
1e830 69 4f 66 66 73 65 74 20 2b 3d 20 69 46 69 72 73  iOffset += iFirs
1e840 74 41 6d 74 3b 0a 20 20 20 20 69 41 6d 74 20 2d  tAmt;.    iAmt -
1e850 3d 20 69 46 69 72 73 74 41 6d 74 3b 0a 20 20 20  = iFirstAmt;.   
1e860 20 70 43 6f 6e 74 65 6e 74 20 3d 20 28 76 6f 69   pContent = (voi
1e870 64 2a 29 28 69 46 69 72 73 74 41 6d 74 20 2b 20  d*)(iFirstAmt + 
1e880 28 63 68 61 72 2a 29 70 43 6f 6e 74 65 6e 74 29  (char*)pContent)
1e890 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 57 41  ;.    assert( WA
1e8a0 4c 5f 53 59 4e 43 5f 46 4c 41 47 53 28 70 2d 3e  L_SYNC_FLAGS(p->
1e8b0 73 79 6e 63 46 6c 61 67 73 29 21 3d 30 20 29 3b  syncFlags)!=0 );
1e8c0 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
1e8d0 33 4f 73 53 79 6e 63 28 70 2d 3e 70 46 64 2c 20  3OsSync(p->pFd, 
1e8e0 57 41 4c 5f 53 59 4e 43 5f 46 4c 41 47 53 28 70  WAL_SYNC_FLAGS(p
1e8f0 2d 3e 73 79 6e 63 46 6c 61 67 73 29 29 3b 0a 20  ->syncFlags));. 
1e900 20 20 20 69 66 28 20 69 41 6d 74 3d 3d 30 20 7c     if( iAmt==0 |
1e910 7c 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63  | rc ) return rc
1e920 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c  ;.  }.  rc = sql
1e930 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70  ite3OsWrite(p->p
1e940 46 64 2c 20 70 43 6f 6e 74 65 6e 74 2c 20 69 41  Fd, pContent, iA
1e950 6d 74 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  mt, iOffset);.  
1e960 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
1e970 0a 2a 2a 20 57 72 69 74 65 20 6f 75 74 20 61 20  .** Write out a 
1e980 73 69 6e 67 6c 65 20 66 72 61 6d 65 20 6f 66 20  single frame of 
1e990 74 68 65 20 57 41 4c 0a 2a 2f 0a 73 74 61 74 69  the WAL.*/.stati
1e9a0 63 20 69 6e 74 20 77 61 6c 57 72 69 74 65 4f 6e  c int walWriteOn
1e9b0 65 46 72 61 6d 65 28 0a 20 20 57 61 6c 57 72 69  eFrame(.  WalWri
1e9c0 74 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20  ter *p,         
1e9d0 20 20 20 20 20 20 2f 2a 20 57 68 65 72 65 20 74        /* Where t
1e9e0 6f 20 77 72 69 74 65 20 74 68 65 20 66 72 61 6d  o write the fram
1e9f0 65 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 50  e */.  PgHdr *pP
1ea00 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  age,            
1ea10 20 20 20 2f 2a 20 54 68 65 20 70 61 67 65 20 6f     /* The page o
1ea20 66 20 74 68 65 20 66 72 61 6d 65 20 74 6f 20 62  f the frame to b
1ea30 65 20 77 72 69 74 74 65 6e 20 2a 2f 0a 20 20 69  e written */.  i
1ea40 6e 74 20 6e 54 72 75 6e 63 61 74 65 2c 20 20 20  nt nTruncate,   
1ea50 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
1ea60 65 20 63 6f 6d 6d 69 74 20 66 6c 61 67 2e 20 20  e commit flag.  
1ea70 55 73 75 61 6c 6c 79 20 30 2e 20 20 3e 30 20 66  Usually 0.  >0 f
1ea80 6f 72 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20 73  or commit */.  s
1ea90 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66  qlite3_int64 iOf
1eaa0 66 73 65 74 20 20 20 20 20 20 20 2f 2a 20 42 79  fset       /* By
1eab0 74 65 20 6f 66 66 73 65 74 20 61 74 20 77 68 69  te offset at whi
1eac0 63 68 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 29  ch to write */.)
1ead0 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  {.  int rc;     
1eae0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1eaf0 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 63 6f      /* Result co
1eb00 64 65 20 66 72 6f 6d 20 73 75 62 66 75 6e 63 74  de from subfunct
1eb10 69 6f 6e 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  ions */.  void *
1eb20 70 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20  pData;          
1eb30 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
1eb40 61 20 61 63 74 75 61 6c 6c 79 20 77 72 69 74 74  a actually writt
1eb50 65 6e 20 2a 2f 0a 20 20 75 38 20 61 46 72 61 6d  en */.  u8 aFram
1eb60 65 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  e[WAL_FRAME_HDRS
1eb70 49 5a 45 5d 3b 20 20 20 2f 2a 20 42 75 66 66 65  IZE];   /* Buffe
1eb80 72 20 74 6f 20 61 73 73 65 6d 62 6c 65 20 66 72  r to assemble fr
1eb90 61 6d 65 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f  ame-header in */
1eba0 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c  .#if defined(SQL
1ebb0 49 54 45 5f 48 41 53 5f 43 4f 44 45 43 29 0a 20  ITE_HAS_CODEC). 
1ebc0 20 69 66 28 20 28 70 44 61 74 61 20 3d 20 73 71   if( (pData = sq
1ebd0 6c 69 74 65 33 50 61 67 65 72 43 6f 64 65 63 28  lite3PagerCodec(
1ebe0 70 50 61 67 65 29 29 3d 3d 30 20 29 20 72 65 74  pPage))==0 ) ret
1ebf0 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
1ec00 5f 42 4b 50 54 3b 0a 23 65 6c 73 65 0a 20 20 70  _BKPT;.#else.  p
1ec10 44 61 74 61 20 3d 20 70 50 61 67 65 2d 3e 70 44  Data = pPage->pD
1ec20 61 74 61 3b 0a 23 65 6e 64 69 66 0a 20 20 77 61  ata;.#endif.  wa
1ec30 6c 45 6e 63 6f 64 65 46 72 61 6d 65 28 70 2d 3e  lEncodeFrame(p->
1ec40 70 57 61 6c 2c 20 70 50 61 67 65 2d 3e 70 67 6e  pWal, pPage->pgn
1ec50 6f 2c 20 6e 54 72 75 6e 63 61 74 65 2c 20 70 44  o, nTruncate, pD
1ec60 61 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20  ata, aFrame);.  
1ec70 72 63 20 3d 20 77 61 6c 57 72 69 74 65 54 6f 4c  rc = walWriteToL
1ec80 6f 67 28 70 2c 20 61 46 72 61 6d 65 2c 20 73 69  og(p, aFrame, si
1ec90 7a 65 6f 66 28 61 46 72 61 6d 65 29 2c 20 69 4f  zeof(aFrame), iO
1eca0 66 66 73 65 74 29 3b 0a 20 20 69 66 28 20 72 63  ffset);.  if( rc
1ecb0 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
1ecc0 2f 2a 20 57 72 69 74 65 20 74 68 65 20 70 61 67  /* Write the pag
1ecd0 65 20 64 61 74 61 20 2a 2f 0a 20 20 72 63 20 3d  e data */.  rc =
1ece0 20 77 61 6c 57 72 69 74 65 54 6f 4c 6f 67 28 70   walWriteToLog(p
1ecf0 2c 20 70 44 61 74 61 2c 20 70 2d 3e 73 7a 50 61  , pData, p->szPa
1ed00 67 65 2c 20 69 4f 66 66 73 65 74 2b 73 69 7a 65  ge, iOffset+size
1ed10 6f 66 28 61 46 72 61 6d 65 29 29 3b 0a 20 20 72  of(aFrame));.  r
1ed20 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
1ed30 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
1ed40 20 69 73 20 63 61 6c 6c 65 64 20 61 73 20 70 61   is called as pa
1ed50 72 74 20 6f 66 20 63 6f 6d 6d 69 74 74 69 6e 67  rt of committing
1ed60 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77   a transaction w
1ed70 69 74 68 69 6e 20 77 68 69 63 68 0a 2a 2a 20 6f  ithin which.** o
1ed80 6e 65 20 6f 72 20 6d 6f 72 65 20 66 72 61 6d 65  ne or more frame
1ed90 73 20 68 61 76 65 20 62 65 65 6e 20 6f 76 65 72  s have been over
1eda0 77 72 69 74 74 65 6e 2e 20 49 74 20 75 70 64 61  written. It upda
1edb0 74 65 73 20 74 68 65 20 63 68 65 63 6b 73 75 6d  tes the checksum
1edc0 73 20 66 6f 72 0a 2a 2a 20 61 6c 6c 20 66 72 61  s for.** all fra
1edd0 6d 65 73 20 77 72 69 74 74 65 6e 20 74 6f 20 74  mes written to t
1ede0 68 65 20 77 61 6c 20 66 69 6c 65 20 62 79 20 74  he wal file by t
1edf0 68 65 20 63 75 72 72 65 6e 74 20 74 72 61 6e 73  he current trans
1ee00 61 63 74 69 6f 6e 20 73 74 61 72 74 69 6e 67 0a  action starting.
1ee10 2a 2a 20 77 69 74 68 20 74 68 65 20 65 61 72 6c  ** with the earl
1ee20 69 65 73 74 20 74 6f 20 68 61 76 65 20 62 65 65  iest to have bee
1ee30 6e 20 6f 76 65 72 77 72 69 74 74 65 6e 2e 0a 2a  n overwritten..*
1ee40 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69  *.** SQLITE_OK i
1ee50 73 20 72 65 74 75 72 6e 65 64 20 69 66 20 73 75  s returned if su
1ee60 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
1ee70 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
1ee80 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a  e otherwise..*/.
1ee90 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 52 65  static int walRe
1eea0 77 72 69 74 65 43 68 65 63 6b 73 75 6d 73 28 57  writeChecksums(W
1eeb0 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 69 4c  al *pWal, u32 iL
1eec0 61 73 74 29 7b 0a 20 20 63 6f 6e 73 74 20 69 6e  ast){.  const in
1eed0 74 20 73 7a 50 61 67 65 20 3d 20 70 57 61 6c 2d  t szPage = pWal-
1eee0 3e 73 7a 50 61 67 65 3b 2f 2a 20 44 61 74 61 62  >szPage;/* Datab
1eef0 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f  ase page size */
1ef00 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
1ef10 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
1ef20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
1ef30 65 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 3b  e */.  u8 *aBuf;
1ef40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ef50 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72         /* Buffer
1ef60 20 74 6f 20 6c 6f 61 64 20 64 61 74 61 20 66 72   to load data fr
1ef70 6f 6d 20 77 61 6c 20 66 69 6c 65 20 69 6e 74 6f  om wal file into
1ef80 20 2a 2f 0a 20 20 75 38 20 61 46 72 61 6d 65 5b   */.  u8 aFrame[
1ef90 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a  WAL_FRAME_HDRSIZ
1efa0 45 5d 3b 20 20 20 2f 2a 20 42 75 66 66 65 72 20  E];   /* Buffer 
1efb0 74 6f 20 61 73 73 65 6d 62 6c 65 20 66 72 61 6d  to assemble fram
1efc0 65 2d 68 65 61 64 65 72 73 20 69 6e 20 2a 2f 0a  e-headers in */.
1efd0 20 20 75 33 32 20 69 52 65 61 64 3b 20 20 20 20    u32 iRead;    
1efe0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1eff0 20 20 2f 2a 20 4e 65 78 74 20 66 72 61 6d 65 20    /* Next frame 
1f000 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 77 61 6c  to read from wal
1f010 20 66 69 6c 65 20 2a 2f 0a 20 20 69 36 34 20 69   file */.  i64 i
1f020 43 6b 73 75 6d 4f 66 66 3b 0a 0a 20 20 61 42 75  CksumOff;..  aBu
1f030 66 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  f = sqlite3_mall
1f040 6f 63 28 73 7a 50 61 67 65 20 2b 20 57 41 4c 5f  oc(szPage + WAL_
1f050 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 29 3b 0a  FRAME_HDRSIZE);.
1f060 20 20 69 66 28 20 61 42 75 66 3d 3d 30 20 29 20    if( aBuf==0 ) 
1f070 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
1f080 4d 45 4d 5f 42 4b 50 54 3b 0a 0a 20 20 2f 2a 20  MEM_BKPT;..  /* 
1f090 46 69 6e 64 20 74 68 65 20 63 68 65 63 6b 73 75  Find the checksu
1f0a0 6d 20 76 61 6c 75 65 73 20 74 6f 20 75 73 65 20  m values to use 
1f0b0 61 73 20 69 6e 70 75 74 20 66 6f 72 20 74 68 65  as input for the
1f0c0 20 72 65 63 61 6c 63 75 6c 61 74 69 6e 67 20 74   recalculating t
1f0d0 68 65 0a 20 20 2a 2a 20 66 69 72 73 74 20 63 68  he.  ** first ch
1f0e0 65 63 6b 73 75 6d 2e 20 49 66 20 74 68 65 20 66  ecksum. If the f
1f0f0 69 72 73 74 20 66 72 61 6d 65 20 69 73 20 66 72  irst frame is fr
1f100 61 6d 65 20 31 20 28 69 6d 70 6c 79 69 6e 67 20  ame 1 (implying 
1f110 74 68 61 74 20 74 68 65 20 63 75 72 72 65 6e 74  that the current
1f120 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f  .  ** transactio
1f130 6e 20 72 65 73 74 61 72 74 65 64 20 74 68 65 20  n restarted the 
1f140 77 61 6c 20 66 69 6c 65 29 2c 20 74 68 65 73 65  wal file), these
1f150 20 76 61 6c 75 65 73 20 6d 75 73 74 20 62 65 20   values must be 
1f160 72 65 61 64 20 66 72 6f 6d 20 74 68 65 0a 20 20  read from the.  
1f170 2a 2a 20 77 61 6c 2d 66 69 6c 65 20 68 65 61 64  ** wal-file head
1f180 65 72 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 72  er. Otherwise, r
1f190 65 61 64 20 74 68 65 6d 20 66 72 6f 6d 20 74 68  ead them from th
1f1a0 65 20 66 72 61 6d 65 20 68 65 61 64 65 72 20 6f  e frame header o
1f1b0 66 20 74 68 65 0a 20 20 2a 2a 20 70 72 65 76 69  f the.  ** previ
1f1c0 6f 75 73 20 66 72 61 6d 65 2e 20 20 2a 2f 0a 20  ous frame.  */. 
1f1d0 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 69   assert( pWal->i
1f1e0 52 65 43 6b 73 75 6d 3e 30 20 29 3b 0a 20 20 69  ReCksum>0 );.  i
1f1f0 66 28 20 70 57 61 6c 2d 3e 69 52 65 43 6b 73 75  f( pWal->iReCksu
1f200 6d 3d 3d 31 20 29 7b 0a 20 20 20 20 69 43 6b 73  m==1 ){.    iCks
1f210 75 6d 4f 66 66 20 3d 20 32 34 3b 0a 20 20 7d 65  umOff = 24;.  }e
1f220 6c 73 65 7b 0a 20 20 20 20 69 43 6b 73 75 6d 4f  lse{.    iCksumO
1f230 66 66 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66  ff = walFrameOff
1f240 73 65 74 28 70 57 61 6c 2d 3e 69 52 65 43 6b 73  set(pWal->iReCks
1f250 75 6d 2d 31 2c 20 73 7a 50 61 67 65 29 20 2b 20  um-1, szPage) + 
1f260 31 36 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73  16;.  }.  rc = s
1f270 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57 61  qlite3OsRead(pWa
1f280 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 42 75 66 2c  l->pWalFd, aBuf,
1f290 20 73 69 7a 65 6f 66 28 75 33 32 29 2a 32 2c 20   sizeof(u32)*2, 
1f2a0 69 43 6b 73 75 6d 4f 66 66 29 3b 0a 20 20 70 57  iCksumOff);.  pW
1f2b0 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
1f2c0 73 75 6d 5b 30 5d 20 3d 20 73 71 6c 69 74 65 33  sum[0] = sqlite3
1f2d0 47 65 74 34 62 79 74 65 28 61 42 75 66 29 3b 0a  Get4byte(aBuf);.
1f2e0 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61    pWal->hdr.aFra
1f2f0 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 73 71 6c  meCksum[1] = sql
1f300 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61 42  ite3Get4byte(&aB
1f310 75 66 5b 73 69 7a 65 6f 66 28 75 33 32 29 5d 29  uf[sizeof(u32)])
1f320 3b 0a 0a 20 20 69 52 65 61 64 20 3d 20 70 57 61  ;..  iRead = pWa
1f330 6c 2d 3e 69 52 65 43 6b 73 75 6d 3b 0a 20 20 70  l->iReCksum;.  p
1f340 57 61 6c 2d 3e 69 52 65 43 6b 73 75 6d 20 3d 20  Wal->iReCksum = 
1f350 30 3b 0a 20 20 66 6f 72 28 3b 20 72 63 3d 3d 53  0;.  for(; rc==S
1f360 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 52 65 61  QLITE_OK && iRea
1f370 64 3c 3d 69 4c 61 73 74 3b 20 69 52 65 61 64 2b  d<=iLast; iRead+
1f380 2b 29 7b 0a 20 20 20 20 69 36 34 20 69 4f 66 66  +){.    i64 iOff
1f390 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65   = walFrameOffse
1f3a0 74 28 69 52 65 61 64 2c 20 73 7a 50 61 67 65 29  t(iRead, szPage)
1f3b0 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
1f3c0 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70  e3OsRead(pWal->p
1f3d0 57 61 6c 46 64 2c 20 61 42 75 66 2c 20 73 7a 50  WalFd, aBuf, szP
1f3e0 61 67 65 2b 57 41 4c 5f 46 52 41 4d 45 5f 48 44  age+WAL_FRAME_HD
1f3f0 52 53 49 5a 45 2c 20 69 4f 66 66 29 3b 0a 20 20  RSIZE, iOff);.  
1f400 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
1f410 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 75 33 32  _OK ){.      u32
1f420 20 69 50 67 6e 6f 2c 20 6e 44 62 53 69 7a 65 3b   iPgno, nDbSize;
1f430 0a 20 20 20 20 20 20 69 50 67 6e 6f 20 3d 20 73  .      iPgno = s
1f440 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 61  qlite3Get4byte(a
1f450 42 75 66 29 3b 0a 20 20 20 20 20 20 6e 44 62 53  Buf);.      nDbS
1f460 69 7a 65 20 3d 20 73 71 6c 69 74 65 33 47 65 74  ize = sqlite3Get
1f470 34 62 79 74 65 28 26 61 42 75 66 5b 34 5d 29 3b  4byte(&aBuf[4]);
1f480 0a 0a 20 20 20 20 20 20 77 61 6c 45 6e 63 6f 64  ..      walEncod
1f490 65 46 72 61 6d 65 28 70 57 61 6c 2c 20 69 50 67  eFrame(pWal, iPg
1f4a0 6e 6f 2c 20 6e 44 62 53 69 7a 65 2c 20 26 61 42  no, nDbSize, &aB
1f4b0 75 66 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52  uf[WAL_FRAME_HDR
1f4c0 53 49 5a 45 5d 2c 20 61 46 72 61 6d 65 29 3b 0a  SIZE], aFrame);.
1f4d0 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
1f4e0 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e  e3OsWrite(pWal->
1f4f0 70 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20  pWalFd, aFrame, 
1f500 73 69 7a 65 6f 66 28 61 46 72 61 6d 65 29 2c 20  sizeof(aFrame), 
1f510 69 4f 66 66 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  iOff);.    }.  }
1f520 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ..  sqlite3_free
1f530 28 61 42 75 66 29 3b 0a 20 20 72 65 74 75 72 6e  (aBuf);.  return
1f540 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 57   rc;.}../* .** W
1f550 72 69 74 65 20 61 20 73 65 74 20 6f 66 20 66 72  rite a set of fr
1f560 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67 2e  ames to the log.
1f570 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74   The caller must
1f580 20 68 6f 6c 64 20 74 68 65 20 77 72 69 74 65 2d   hold the write-
1f590 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20 6c  lock.** on the l
1f5a0 6f 67 20 66 69 6c 65 20 28 6f 62 74 61 69 6e 65  og file (obtaine
1f5b0 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 57  d using sqlite3W
1f5c0 61 6c 42 65 67 69 6e 57 72 69 74 65 54 72 61 6e  alBeginWriteTran
1f5d0 73 61 63 74 69 6f 6e 28 29 29 2e 0a 2a 2f 0a 69  saction())..*/.i
1f5e0 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 46 72 61  nt sqlite3WalFra
1f5f0 6d 65 73 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c  mes(.  Wal *pWal
1f600 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1f610 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 68 61         /* Wal ha
1f620 6e 64 6c 65 20 74 6f 20 77 72 69 74 65 20 74 6f  ndle to write to
1f630 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65   */.  int szPage
1f640 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1f650 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
1f660 65 20 70 61 67 65 2d 73 69 7a 65 20 69 6e 20 62  e page-size in b
1f670 79 74 65 73 20 2a 2f 0a 20 20 50 67 48 64 72 20  ytes */.  PgHdr 
1f680 2a 70 4c 69 73 74 2c 20 20 20 20 20 20 20 20 20  *pList,         
1f690 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73            /* Lis
1f6a0 74 20 6f 66 20 64 69 72 74 79 20 70 61 67 65 73  t of dirty pages
1f6b0 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 50   to write */.  P
1f6c0 67 6e 6f 20 6e 54 72 75 6e 63 61 74 65 2c 20 20  gno nTruncate,  
1f6d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1f6e0 2a 20 44 61 74 61 62 61 73 65 20 73 69 7a 65 20  * Database size 
1f6f0 61 66 74 65 72 20 74 68 69 73 20 63 6f 6d 6d 69  after this commi
1f700 74 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43 6f 6d  t */.  int isCom
1f710 6d 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  mit,            
1f720 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
1f730 66 20 74 68 69 73 20 69 73 20 61 20 63 6f 6d 6d  f this is a comm
1f740 69 74 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63  it */.  int sync
1f750 5f 66 6c 61 67 73 20 20 20 20 20 20 20 20 20 20  _flags          
1f760 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73          /* Flags
1f770 20 74 6f 20 70 61 73 73 20 74 6f 20 4f 73 53 79   to pass to OsSy
1f780 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 29  nc() (or 0) */.)
1f790 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  {.  int rc;     
1f7a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f7b0 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 63      /* Used to c
1f7c0 61 74 63 68 20 72 65 74 75 72 6e 20 63 6f 64 65  atch return code
1f7d0 73 20 2a 2f 0a 20 20 75 33 32 20 69 46 72 61 6d  s */.  u32 iFram
1f7e0 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
1f7f0 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 66         /* Next f
1f800 72 61 6d 65 20 61 64 64 72 65 73 73 20 2a 2f 0a  rame address */.
1f810 20 20 50 67 48 64 72 20 2a 70 3b 20 20 20 20 20    PgHdr *p;     
1f820 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f830 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f    /* Iterator to
1f840 20 72 75 6e 20 74 68 72 6f 75 67 68 20 70 4c 69   run through pLi
1f850 73 74 20 77 69 74 68 2e 20 2a 2f 0a 20 20 50 67  st with. */.  Pg
1f860 48 64 72 20 2a 70 4c 61 73 74 20 3d 20 30 3b 20  Hdr *pLast = 0; 
1f870 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1f880 20 4c 61 73 74 20 66 72 61 6d 65 20 69 6e 20 6c   Last frame in l
1f890 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 45 78  ist */.  int nEx
1f8a0 74 72 61 20 3d 20 30 3b 20 20 20 20 20 20 20 20  tra = 0;        
1f8b0 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
1f8c0 65 72 20 6f 66 20 65 78 74 72 61 20 63 6f 70 69  er of extra copi
1f8d0 65 73 20 6f 66 20 6c 61 73 74 20 70 61 67 65 20  es of last page 
1f8e0 2a 2f 0a 20 20 69 6e 74 20 73 7a 46 72 61 6d 65  */.  int szFrame
1f8f0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1f900 20 20 20 20 20 2f 2a 20 54 68 65 20 73 69 7a 65       /* The size
1f910 20 6f 66 20 61 20 73 69 6e 67 6c 65 20 66 72 61   of a single fra
1f920 6d 65 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66  me */.  i64 iOff
1f930 73 65 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  set;            
1f940 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
1f950 62 79 74 65 20 74 6f 20 77 72 69 74 65 20 69 6e  byte to write in
1f960 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 57   WAL file */.  W
1f970 61 6c 57 72 69 74 65 72 20 77 3b 20 20 20 20 20  alWriter w;     
1f980 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1f990 2a 20 54 68 65 20 77 72 69 74 65 72 20 2a 2f 0a  * The writer */.
1f9a0 20 20 75 33 32 20 69 46 69 72 73 74 20 3d 20 30    u32 iFirst = 0
1f9b0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1f9c0 20 20 2f 2a 20 46 69 72 73 74 20 66 72 61 6d 65    /* First frame
1f9d0 20 74 68 61 74 20 6d 61 79 20 62 65 20 6f 76 65   that may be ove
1f9e0 72 77 72 69 74 74 65 6e 20 2a 2f 0a 20 20 57 61  rwritten */.  Wa
1f9f0 6c 49 6e 64 65 78 48 64 72 20 2a 70 4c 69 76 65  lIndexHdr *pLive
1fa00 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
1fa10 20 50 6f 69 6e 74 65 72 20 74 6f 20 73 68 61 72   Pointer to shar
1fa20 65 64 20 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20  ed header */..  
1fa30 61 73 73 65 72 74 28 20 70 4c 69 73 74 20 29 3b  assert( pList );
1fa40 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
1fa50 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 0a 20  >writeLock );.. 
1fa60 20 2f 2a 20 49 66 20 74 68 69 73 20 66 72 61 6d   /* If this fram
1fa70 65 20 73 65 74 20 63 6f 6d 70 6c 65 74 65 73 20  e set completes 
1fa80 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20 74  a transaction, t
1fa90 68 65 6e 20 6e 54 72 75 6e 63 61 74 65 3e 30 2e  hen nTruncate>0.
1faa0 20 20 49 66 0a 20 20 2a 2a 20 6e 54 72 75 6e 63    If.  ** nTrunc
1fab0 61 74 65 3d 3d 30 20 74 68 65 6e 20 74 68 69 73  ate==0 then this
1fac0 20 66 72 61 6d 65 20 73 65 74 20 64 6f 65 73 20   frame set does 
1fad0 6e 6f 74 20 63 6f 6d 70 6c 65 74 65 20 74 68 65  not complete the
1fae0 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 2a 2f   transaction. */
1faf0 0a 20 20 61 73 73 65 72 74 28 20 28 69 73 43 6f  .  assert( (isCo
1fb00 6d 6d 69 74 21 3d 30 29 3d 3d 28 6e 54 72 75 6e  mmit!=0)==(nTrun
1fb10 63 61 74 65 21 3d 30 29 20 29 3b 0a 0a 23 69 66  cate!=0) );..#if
1fb20 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
1fb30 54 45 53 54 29 20 26 26 20 64 65 66 69 6e 65 64  TEST) && defined
1fb40 28 53 51 4c 49 54 45 5f 44 45 42 55 47 29 0a 20  (SQLITE_DEBUG). 
1fb50 20 7b 20 69 6e 74 20 63 6e 74 3b 20 66 6f 72 28   { int cnt; for(
1fb60 63 6e 74 3d 30 2c 20 70 3d 70 4c 69 73 74 3b 20  cnt=0, p=pList; 
1fb70 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 2c 20  p; p=p->pDirty, 
1fb80 63 6e 74 2b 2b 29 7b 7d 0a 20 20 20 20 57 41 4c  cnt++){}.    WAL
1fb90 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 66  TRACE(("WAL%p: f
1fba0 72 61 6d 65 20 77 72 69 74 65 20 62 65 67 69 6e  rame write begin
1fbb0 2e 20 25 64 20 66 72 61 6d 65 73 2e 20 6d 78 46  . %d frames. mxF
1fbc0 72 61 6d 65 3d 25 64 2e 20 25 73 5c 6e 22 2c 0a  rame=%d. %s\n",.
1fbd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 57                pW
1fbe0 61 6c 2c 20 63 6e 74 2c 20 70 57 61 6c 2d 3e 68  al, cnt, pWal->h
1fbf0 64 72 2e 6d 78 46 72 61 6d 65 2c 20 69 73 43 6f  dr.mxFrame, isCo
1fc00 6d 6d 69 74 20 3f 20 22 43 6f 6d 6d 69 74 22 20  mmit ? "Commit" 
1fc10 3a 20 22 53 70 69 6c 6c 22 29 29 3b 0a 20 20 7d  : "Spill"));.  }
1fc20 0a 23 65 6e 64 69 66 0a 0a 20 20 70 4c 69 76 65  .#endif..  pLive
1fc30 20 3d 20 28 57 61 6c 49 6e 64 65 78 48 64 72 2a   = (WalIndexHdr*
1fc40 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61  )walIndexHdr(pWa
1fc50 6c 29 3b 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70  l);.  if( memcmp
1fc60 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76 6f  (&pWal->hdr, (vo
1fc70 69 64 20 2a 29 70 4c 69 76 65 2c 20 73 69 7a 65  id *)pLive, size
1fc80 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
1fc90 21 3d 30 20 29 7b 0a 20 20 20 20 69 46 69 72 73  !=0 ){.    iFirs
1fca0 74 20 3d 20 70 4c 69 76 65 2d 3e 6d 78 46 72 61  t = pLive->mxFra
1fcb0 6d 65 2b 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  me+1;.  }..  /* 
1fcc0 53 65 65 20 69 66 20 69 74 20 69 73 20 70 6f 73  See if it is pos
1fcd0 73 69 62 6c 65 20 74 6f 20 77 72 69 74 65 20 74  sible to write t
1fce0 68 65 73 65 20 66 72 61 6d 65 73 20 69 6e 74 6f  hese frames into
1fcf0 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
1fd00 65 0a 20 20 2a 2a 20 6c 6f 67 20 66 69 6c 65 2c  e.  ** log file,
1fd10 20 69 6e 73 74 65 61 64 20 6f 66 20 61 70 70 65   instead of appe
1fd20 6e 64 69 6e 67 20 74 6f 20 69 74 20 61 74 20 70  nding to it at p
1fd30 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
1fd40 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 53 51 4c  ..  */.  if( SQL
1fd50 49 54 45 5f 4f 4b 21 3d 28 72 63 20 3d 20 77 61  ITE_OK!=(rc = wa
1fd60 6c 52 65 73 74 61 72 74 4c 6f 67 28 70 57 61 6c  lRestartLog(pWal
1fd70 29 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  )) ){.    return
1fd80 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49   rc;.  }..  /* I
1fd90 66 20 74 68 69 73 20 69 73 20 74 68 65 20 66 69  f this is the fi
1fda0 72 73 74 20 66 72 61 6d 65 20 77 72 69 74 74 65  rst frame writte
1fdb0 6e 20 69 6e 74 6f 20 74 68 65 20 6c 6f 67 2c 20  n into the log, 
1fdc0 77 72 69 74 65 20 74 68 65 20 57 41 4c 0a 20 20  write the WAL.  
1fdd0 2a 2a 20 68 65 61 64 65 72 20 74 6f 20 74 68 65  ** header to the
1fde0 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 57 41   start of the WA
1fdf0 4c 20 66 69 6c 65 2e 20 53 65 65 20 63 6f 6d 6d  L file. See comm
1fe00 65 6e 74 73 20 61 74 20 74 68 65 20 74 6f 70 20  ents at the top 
1fe10 6f 66 0a 20 20 2a 2a 20 74 68 69 73 20 73 6f 75  of.  ** this sou
1fe20 72 63 65 20 66 69 6c 65 20 66 6f 72 20 61 20 64  rce file for a d
1fe30 65 73 63 72 69 70 74 69 6f 6e 20 6f 66 20 74 68  escription of th
1fe40 65 20 57 41 4c 20 68 65 61 64 65 72 20 66 6f 72  e WAL header for
1fe50 6d 61 74 2e 0a 20 20 2a 2f 0a 20 20 69 46 72 61  mat..  */.  iFra
1fe60 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  me = pWal->hdr.m
1fe70 78 46 72 61 6d 65 3b 0a 20 20 69 66 28 20 69 46  xFrame;.  if( iF
1fe80 72 61 6d 65 3d 3d 30 20 29 7b 0a 20 20 20 20 75  rame==0 ){.    u
1fe90 38 20 61 57 61 6c 48 64 72 5b 57 41 4c 5f 48 44  8 aWalHdr[WAL_HD
1fea0 52 53 49 5a 45 5d 3b 20 20 20 20 20 20 2f 2a 20  RSIZE];      /* 
1feb0 42 75 66 66 65 72 20 74 6f 20 61 73 73 65 6d 62  Buffer to assemb
1fec0 6c 65 20 77 61 6c 2d 68 65 61 64 65 72 20 69 6e  le wal-header in
1fed0 20 2a 2f 0a 20 20 20 20 75 33 32 20 61 43 6b 73   */.    u32 aCks
1fee0 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  um[2];          
1fef0 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 73 75        /* Checksu
1ff00 6d 20 66 6f 72 20 77 61 6c 2d 68 65 61 64 65 72  m for wal-header
1ff10 20 2a 2f 0a 0a 20 20 20 20 73 71 6c 69 74 65 33   */..    sqlite3
1ff20 50 75 74 34 62 79 74 65 28 26 61 57 61 6c 48 64  Put4byte(&aWalHd
1ff30 72 5b 30 5d 2c 20 28 57 41 4c 5f 4d 41 47 49 43  r[0], (WAL_MAGIC
1ff40 20 7c 20 53 51 4c 49 54 45 5f 42 49 47 45 4e 44   | SQLITE_BIGEND
1ff50 49 41 4e 29 29 3b 0a 20 20 20 20 73 71 6c 69 74  IAN));.    sqlit
1ff60 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c  e3Put4byte(&aWal
1ff70 48 64 72 5b 34 5d 2c 20 57 41 4c 5f 4d 41 58 5f  Hdr[4], WAL_MAX_
1ff80 56 45 52 53 49 4f 4e 29 3b 0a 20 20 20 20 73 71  VERSION);.    sq
1ff90 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61  lite3Put4byte(&a
1ffa0 57 61 6c 48 64 72 5b 38 5d 2c 20 73 7a 50 61 67  WalHdr[8], szPag
1ffb0 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50  e);.    sqlite3P
1ffc0 75 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72  ut4byte(&aWalHdr
1ffd0 5b 31 32 5d 2c 20 70 57 61 6c 2d 3e 6e 43 6b 70  [12], pWal->nCkp
1ffe0 74 29 3b 0a 20 20 20 20 69 66 28 20 70 57 61 6c  t);.    if( pWal
1fff0 2d 3e 6e 43 6b 70 74 3d 3d 30 20 29 20 73 71 6c  ->nCkpt==0 ) sql
20000 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28  ite3_randomness(
20010 38 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61  8, pWal->hdr.aSa
20020 6c 74 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28  lt);.    memcpy(
20030 26 61 57 61 6c 48 64 72 5b 31 36 5d 2c 20 70 57  &aWalHdr[16], pW
20040 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 38  al->hdr.aSalt, 8
20050 29 3b 0a 20 20 20 20 77 61 6c 43 68 65 63 6b 73  );.    walChecks
20060 75 6d 42 79 74 65 73 28 31 2c 20 61 57 61 6c 48  umBytes(1, aWalH
20070 64 72 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2d  dr, WAL_HDRSIZE-
20080 32 2a 34 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b  2*4, 0, aCksum);
20090 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34  .    sqlite3Put4
200a0 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32 34  byte(&aWalHdr[24
200b0 5d 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b 0a 20  ], aCksum[0]);. 
200c0 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79     sqlite3Put4by
200d0 74 65 28 26 61 57 61 6c 48 64 72 5b 32 38 5d 2c  te(&aWalHdr[28],
200e0 20 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 20 20 20   aCksum[1]);.   
200f0 20 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50 61   .    pWal->szPa
20100 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20  ge = szPage;.   
20110 20 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e   pWal->hdr.bigEn
20120 64 43 6b 73 75 6d 20 3d 20 53 51 4c 49 54 45 5f  dCksum = SQLITE_
20130 42 49 47 45 4e 44 49 41 4e 3b 0a 20 20 20 20 70  BIGENDIAN;.    p
20140 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
20150 6b 73 75 6d 5b 30 5d 20 3d 20 61 43 6b 73 75 6d  ksum[0] = aCksum
20160 5b 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68  [0];.    pWal->h
20170 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31  dr.aFrameCksum[1
20180 5d 20 3d 20 61 43 6b 73 75 6d 5b 31 5d 3b 0a 20  ] = aCksum[1];. 
20190 20 20 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61 74     pWal->truncat
201a0 65 4f 6e 43 6f 6d 6d 69 74 20 3d 20 31 3b 0a 0a  eOnCommit = 1;..
201b0 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
201c0 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 57  OsWrite(pWal->pW
201d0 61 6c 46 64 2c 20 61 57 61 6c 48 64 72 2c 20 73  alFd, aWalHdr, s
201e0 69 7a 65 6f 66 28 61 57 61 6c 48 64 72 29 2c 20  izeof(aWalHdr), 
201f0 30 29 3b 0a 20 20 20 20 57 41 4c 54 52 41 43 45  0);.    WALTRACE
20200 28 28 22 57 41 4c 25 70 3a 20 77 61 6c 2d 68 65  (("WAL%p: wal-he
20210 61 64 65 72 20 77 72 69 74 65 20 25 73 5c 6e 22  ader write %s\n"
20220 2c 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61  , pWal, rc ? "fa
20230 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a  iled" : "ok"));.
20240 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
20250 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  TE_OK ){.      r
20260 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
20270 0a 20 20 20 20 2f 2a 20 53 79 6e 63 20 74 68 65  .    /* Sync the
20280 20 68 65 61 64 65 72 20 28 75 6e 6c 65 73 73 20   header (unless 
20290 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 53 45 51  SQLITE_IOCAP_SEQ
202a0 55 45 4e 54 49 41 4c 20 69 73 20 74 72 75 65 20  UENTIAL is true 
202b0 6f 72 20 75 6e 6c 65 73 73 0a 20 20 20 20 2a 2a  or unless.    **
202c0 20 61 6c 6c 20 73 79 6e 63 69 6e 67 20 69 73 20   all syncing is 
202d0 74 75 72 6e 65 64 20 6f 66 66 20 62 79 20 50 52  turned off by PR
202e0 41 47 4d 41 20 73 79 6e 63 68 72 6f 6e 6f 75 73  AGMA synchronous
202f0 3d 4f 46 46 29 2e 20 20 4f 74 68 65 72 77 69 73  =OFF).  Otherwis
20300 65 0a 20 20 20 20 2a 2a 20 61 6e 20 6f 75 74 2d  e.    ** an out-
20310 6f 66 2d 6f 72 64 65 72 20 77 72 69 74 65 20 66  of-order write f
20320 6f 6c 6c 6f 77 69 6e 67 20 61 20 57 41 4c 20 72  ollowing a WAL r
20330 65 73 74 61 72 74 20 63 6f 75 6c 64 20 72 65 73  estart could res
20340 75 6c 74 20 69 6e 0a 20 20 20 20 2a 2a 20 64 61  ult in.    ** da
20350 74 61 62 61 73 65 20 63 6f 72 72 75 70 74 69 6f  tabase corruptio
20360 6e 2e 20 20 53 65 65 20 74 68 65 20 74 69 63 6b  n.  See the tick
20370 65 74 3a 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a  et:.    **.    *
20380 2a 20 20 20 20 20 68 74 74 70 73 3a 2f 2f 73 71  *     https://sq
20390 6c 69 74 65 2e 6f 72 67 2f 73 72 63 2f 69 6e 66  lite.org/src/inf
203a0 6f 2f 66 66 35 62 65 37 33 64 65 65 0a 20 20 20  o/ff5be73dee.   
203b0 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 57 61 6c   */.    if( pWal
203c0 2d 3e 73 79 6e 63 48 65 61 64 65 72 20 29 7b 0a  ->syncHeader ){.
203d0 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
203e0 65 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70  e3OsSync(pWal->p
203f0 57 61 6c 46 64 2c 20 43 4b 50 54 5f 53 59 4e 43  WalFd, CKPT_SYNC
20400 5f 46 4c 41 47 53 28 73 79 6e 63 5f 66 6c 61 67  _FLAGS(sync_flag
20410 73 29 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  s));.      if( r
20420 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20  c ) return rc;. 
20430 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65 72     }.  }.  asser
20440 74 28 20 28 69 6e 74 29 70 57 61 6c 2d 3e 73 7a  t( (int)pWal->sz
20450 50 61 67 65 3d 3d 73 7a 50 61 67 65 20 29 3b 0a  Page==szPage );.
20460 0a 20 20 2f 2a 20 53 65 74 75 70 20 69 6e 66 6f  .  /* Setup info
20470 72 6d 61 74 69 6f 6e 20 6e 65 65 64 65 64 20 74  rmation needed t
20480 6f 20 77 72 69 74 65 20 66 72 61 6d 65 73 20 69  o write frames i
20490 6e 74 6f 20 74 68 65 20 57 41 4c 20 2a 2f 0a 20  nto the WAL */. 
204a0 20 77 2e 70 57 61 6c 20 3d 20 70 57 61 6c 3b 0a   w.pWal = pWal;.
204b0 20 20 77 2e 70 46 64 20 3d 20 70 57 61 6c 2d 3e    w.pFd = pWal->
204c0 70 57 61 6c 46 64 3b 0a 20 20 77 2e 69 53 79 6e  pWalFd;.  w.iSyn
204d0 63 50 6f 69 6e 74 20 3d 20 30 3b 0a 20 20 77 2e  cPoint = 0;.  w.
204e0 73 79 6e 63 46 6c 61 67 73 20 3d 20 73 79 6e 63  syncFlags = sync
204f0 5f 66 6c 61 67 73 3b 0a 20 20 77 2e 73 7a 50 61  _flags;.  w.szPa
20500 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 69  ge = szPage;.  i
20510 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61 6d  Offset = walFram
20520 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2b 31  eOffset(iFrame+1
20530 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20 73 7a 46  , szPage);.  szF
20540 72 61 6d 65 20 3d 20 73 7a 50 61 67 65 20 2b 20  rame = szPage + 
20550 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a  WAL_FRAME_HDRSIZ
20560 45 3b 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20 61  E;..  /* Write a
20570 6c 6c 20 66 72 61 6d 65 73 20 69 6e 74 6f 20 74  ll frames into t
20580 68 65 20 6c 6f 67 20 66 69 6c 65 20 65 78 61 63  he log file exac
20590 74 6c 79 20 6f 6e 63 65 20 2a 2f 0a 20 20 66 6f  tly once */.  fo
205a0 72 28 70 3d 70 4c 69 73 74 3b 20 70 3b 20 70 3d  r(p=pList; p; p=
205b0 70 2d 3e 70 44 69 72 74 79 29 7b 0a 20 20 20 20  p->pDirty){.    
205c0 69 6e 74 20 6e 44 62 53 69 7a 65 3b 20 20 20 2f  int nDbSize;   /
205d0 2a 20 30 20 6e 6f 72 6d 61 6c 6c 79 2e 20 20 50  * 0 normally.  P
205e0 6f 73 69 74 69 76 65 20 3d 3d 20 63 6f 6d 6d 69  ositive == commi
205f0 74 20 66 6c 61 67 20 2a 2f 0a 0a 20 20 20 20 2f  t flag */..    /
20600 2a 20 43 68 65 63 6b 20 69 66 20 74 68 69 73 20  * Check if this 
20610 70 61 67 65 20 68 61 73 20 61 6c 72 65 61 64 79  page has already
20620 20 62 65 65 6e 20 77 72 69 74 74 65 6e 20 69 6e   been written in
20630 74 6f 20 74 68 65 20 77 61 6c 20 66 69 6c 65 20  to the wal file 
20640 62 79 0a 20 20 20 20 2a 2a 20 74 68 65 20 63 75  by.    ** the cu
20650 72 72 65 6e 74 20 74 72 61 6e 73 61 63 74 69 6f  rrent transactio
20660 6e 2e 20 49 66 20 73 6f 2c 20 6f 76 65 72 77 72  n. If so, overwr
20670 69 74 65 20 74 68 65 20 65 78 69 73 74 69 6e 67  ite the existing
20680 20 66 72 61 6d 65 20 61 6e 64 0a 20 20 20 20 2a   frame and.    *
20690 2a 20 73 65 74 20 57 61 6c 2e 77 72 69 74 65 4c  * set Wal.writeL
206a0 6f 63 6b 20 74 6f 20 57 41 4c 5f 57 52 49 54 45  ock to WAL_WRITE
206b0 4c 4f 43 4b 5f 52 45 43 4b 53 55 4d 20 2d 20 69  LOCK_RECKSUM - i
206c0 6e 64 69 63 61 74 69 6e 67 20 74 68 61 74 20 0a  ndicating that .
206d0 20 20 20 20 2a 2a 20 63 68 65 63 6b 73 75 6d 73      ** checksums
206e0 20 6d 75 73 74 20 62 65 20 72 65 63 6f 6d 70 75   must be recompu
206f0 74 65 64 20 77 68 65 6e 20 74 68 65 20 74 72 61  ted when the tra
20700 6e 73 61 63 74 69 6f 6e 20 69 73 20 63 6f 6d 6d  nsaction is comm
20710 69 74 74 65 64 2e 20 20 2a 2f 0a 20 20 20 20 69  itted.  */.    i
20720 66 28 20 69 46 69 72 73 74 20 26 26 20 28 70 2d  f( iFirst && (p-
20730 3e 70 44 69 72 74 79 20 7c 7c 20 69 73 43 6f 6d  >pDirty || isCom
20740 6d 69 74 3d 3d 30 29 20 29 7b 0a 20 20 20 20 20  mit==0) ){.     
20750 20 75 33 32 20 69 57 72 69 74 65 20 3d 20 30 3b   u32 iWrite = 0;
20760 0a 20 20 20 20 20 20 56 56 41 5f 4f 4e 4c 59 28  .      VVA_ONLY(
20770 72 63 20 3d 29 20 73 71 6c 69 74 65 33 57 61 6c  rc =) sqlite3Wal
20780 46 69 6e 64 46 72 61 6d 65 28 70 57 61 6c 2c 20  FindFrame(pWal, 
20790 70 2d 3e 70 67 6e 6f 2c 20 26 69 57 72 69 74 65  p->pgno, &iWrite
207a0 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
207b0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc==SQLITE_OK |
207c0 7c 20 69 57 72 69 74 65 3d 3d 30 20 29 3b 0a 20  | iWrite==0 );. 
207d0 20 20 20 20 20 69 66 28 20 69 57 72 69 74 65 3e       if( iWrite>
207e0 3d 69 46 69 72 73 74 20 29 7b 0a 20 20 20 20 20  =iFirst ){.     
207f0 20 20 20 69 36 34 20 69 4f 66 66 20 3d 20 77 61     i64 iOff = wa
20800 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 57 72  lFrameOffset(iWr
20810 69 74 65 2c 20 73 7a 50 61 67 65 29 20 2b 20 57  ite, szPage) + W
20820 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
20830 3b 0a 20 20 20 20 20 20 20 20 76 6f 69 64 20 2a  ;.        void *
20840 70 44 61 74 61 3b 0a 20 20 20 20 20 20 20 20 69  pData;.        i
20850 66 28 20 70 57 61 6c 2d 3e 69 52 65 43 6b 73 75  f( pWal->iReCksu
20860 6d 3d 3d 30 20 7c 7c 20 69 57 72 69 74 65 3c 70  m==0 || iWrite<p
20870 57 61 6c 2d 3e 69 52 65 43 6b 73 75 6d 20 29 7b  Wal->iReCksum ){
20880 0a 20 20 20 20 20 20 20 20 20 20 70 57 61 6c 2d  .          pWal-
20890 3e 69 52 65 43 6b 73 75 6d 20 3d 20 69 57 72 69  >iReCksum = iWri
208a0 74 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 23 69  te;.        }.#i
208b0 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  f defined(SQLITE
208c0 5f 48 41 53 5f 43 4f 44 45 43 29 0a 20 20 20 20  _HAS_CODEC).    
208d0 20 20 20 20 69 66 28 20 28 70 44 61 74 61 20 3d      if( (pData =
208e0 20 73 71 6c 69 74 65 33 50 61 67 65 72 43 6f 64   sqlite3PagerCod
208f0 65 63 28 70 29 29 3d 3d 30 20 29 20 72 65 74 75  ec(p))==0 ) retu
20900 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
20910 0a 23 65 6c 73 65 0a 20 20 20 20 20 20 20 20 70  .#else.        p
20920 44 61 74 61 20 3d 20 70 2d 3e 70 44 61 74 61 3b  Data = p->pData;
20930 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 20 20  .#endif.        
20940 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72  rc = sqlite3OsWr
20950 69 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ite(pWal->pWalFd
20960 2c 20 70 44 61 74 61 2c 20 73 7a 50 61 67 65 2c  , pData, szPage,
20970 20 69 4f 66 66 29 3b 0a 20 20 20 20 20 20 20 20   iOff);.        
20980 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e 20  if( rc ) return 
20990 72 63 3b 0a 20 20 20 20 20 20 20 20 70 2d 3e 66  rc;.        p->f
209a0 6c 61 67 73 20 26 3d 20 7e 50 47 48 44 52 5f 57  lags &= ~PGHDR_W
209b0 41 4c 5f 41 50 50 45 4e 44 3b 0a 20 20 20 20 20  AL_APPEND;.     
209c0 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20     continue;.   
209d0 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20     }.    }..    
209e0 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 61 73  iFrame++;.    as
209f0 73 65 72 74 28 20 69 4f 66 66 73 65 74 3d 3d 77  sert( iOffset==w
20a00 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46  alFrameOffset(iF
20a10 72 61 6d 65 2c 20 73 7a 50 61 67 65 29 20 29 3b  rame, szPage) );
20a20 0a 20 20 20 20 6e 44 62 53 69 7a 65 20 3d 20 28  .    nDbSize = (
20a30 69 73 43 6f 6d 6d 69 74 20 26 26 20 70 2d 3e 70  isCommit && p->p
20a40 44 69 72 74 79 3d 3d 30 29 20 3f 20 6e 54 72 75  Dirty==0) ? nTru
20a50 6e 63 61 74 65 20 3a 20 30 3b 0a 20 20 20 20 72  ncate : 0;.    r
20a60 63 20 3d 20 77 61 6c 57 72 69 74 65 4f 6e 65 46  c = walWriteOneF
20a70 72 61 6d 65 28 26 77 2c 20 70 2c 20 6e 44 62 53  rame(&w, p, nDbS
20a80 69 7a 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20  ize, iOffset);. 
20a90 20 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75     if( rc ) retu
20aa0 72 6e 20 72 63 3b 0a 20 20 20 20 70 4c 61 73 74  rn rc;.    pLast
20ab0 20 3d 20 70 3b 0a 20 20 20 20 69 4f 66 66 73 65   = p;.    iOffse
20ac0 74 20 2b 3d 20 73 7a 46 72 61 6d 65 3b 0a 20 20  t += szFrame;.  
20ad0 20 20 70 2d 3e 66 6c 61 67 73 20 7c 3d 20 50 47    p->flags |= PG
20ae0 48 44 52 5f 57 41 4c 5f 41 50 50 45 4e 44 3b 0a  HDR_WAL_APPEND;.
20af0 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 63 61 6c 63    }..  /* Recalc
20b00 75 6c 61 74 65 20 63 68 65 63 6b 73 75 6d 73 20  ulate checksums 
20b10 77 69 74 68 69 6e 20 74 68 65 20 77 61 6c 20 66  within the wal f
20b20 69 6c 65 20 69 66 20 72 65 71 75 69 72 65 64 2e  ile if required.
20b30 20 2a 2f 0a 20 20 69 66 28 20 69 73 43 6f 6d 6d   */.  if( isComm
20b40 69 74 20 26 26 20 70 57 61 6c 2d 3e 69 52 65 43  it && pWal->iReC
20b50 6b 73 75 6d 20 29 7b 0a 20 20 20 20 72 63 20 3d  ksum ){.    rc =
20b60 20 77 61 6c 52 65 77 72 69 74 65 43 68 65 63 6b   walRewriteCheck
20b70 73 75 6d 73 28 70 57 61 6c 2c 20 69 46 72 61 6d  sums(pWal, iFram
20b80 65 29 3b 0a 20 20 20 20 69 66 28 20 72 63 20 29  e);.    if( rc )
20b90 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
20ba0 0a 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73  .  /* If this is
20bb0 20 74 68 65 20 65 6e 64 20 6f 66 20 61 20 74 72   the end of a tr
20bc0 61 6e 73 61 63 74 69 6f 6e 2c 20 74 68 65 6e 20  ansaction, then 
20bd0 77 65 20 6d 69 67 68 74 20 6e 65 65 64 20 74 6f  we might need to
20be0 20 70 61 64 0a 20 20 2a 2a 20 74 68 65 20 74 72   pad.  ** the tr
20bf0 61 6e 73 61 63 74 69 6f 6e 20 61 6e 64 2f 6f 72  ansaction and/or
20c00 20 73 79 6e 63 20 74 68 65 20 57 41 4c 20 66 69   sync the WAL fi
20c10 6c 65 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 50 61  le..  **.  ** Pa
20c20 64 64 69 6e 67 20 61 6e 64 20 73 79 6e 63 69 6e  dding and syncin
20c30 67 20 6f 6e 6c 79 20 6f 63 63 75 72 20 69 66 20  g only occur if 
20c40 74 68 69 73 20 73 65 74 20 6f 66 20 66 72 61 6d  this set of fram
20c50 65 73 20 63 6f 6d 70 6c 65 74 65 20 61 0a 20 20  es complete a.  
20c60 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 61  ** transaction a
20c70 6e 64 20 69 66 20 50 52 41 47 4d 41 20 73 79 6e  nd if PRAGMA syn
20c80 63 68 72 6f 6e 6f 75 73 3d 46 55 4c 4c 2e 20 20  chronous=FULL.  
20c90 49 66 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 3d  If synchronous==
20ca0 4e 4f 52 4d 41 4c 0a 20 20 2a 2a 20 6f 72 20 73  NORMAL.  ** or s
20cb0 79 6e 63 68 72 6f 6e 6f 75 73 3d 3d 4f 46 46 2c  ynchronous==OFF,
20cc0 20 74 68 65 6e 20 6e 6f 20 70 61 64 64 69 6e 67   then no padding
20cd0 20 6f 72 20 73 79 6e 63 69 6e 67 20 61 72 65 20   or syncing are 
20ce0 6e 65 65 64 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a  needed..  **.  *
20cf0 2a 20 49 66 20 53 51 4c 49 54 45 5f 49 4f 43 41  * If SQLITE_IOCA
20d00 50 5f 50 4f 57 45 52 53 41 46 45 5f 4f 56 45 52  P_POWERSAFE_OVER
20d10 57 52 49 54 45 20 69 73 20 64 65 66 69 6e 65 64  WRITE is defined
20d20 2c 20 74 68 65 6e 20 70 61 64 64 69 6e 67 20 69  , then padding i
20d30 73 20 6e 6f 74 0a 20 20 2a 2a 20 6e 65 65 64 65  s not.  ** neede
20d40 64 20 61 6e 64 20 6f 6e 6c 79 20 74 68 65 20 73  d and only the s
20d50 79 6e 63 20 69 73 20 64 6f 6e 65 2e 20 20 49 66  ync is done.  If
20d60 20 70 61 64 64 69 6e 67 20 69 73 20 6e 65 65 64   padding is need
20d70 65 64 2c 20 74 68 65 6e 20 74 68 65 0a 20 20 2a  ed, then the.  *
20d80 2a 20 66 69 6e 61 6c 20 66 72 61 6d 65 20 69 73  * final frame is
20d90 20 72 65 70 65 61 74 65 64 20 28 77 69 74 68 20   repeated (with 
20da0 69 74 73 20 63 6f 6d 6d 69 74 20 6d 61 72 6b 29  its commit mark)
20db0 20 75 6e 74 69 6c 20 74 68 65 20 6e 65 78 74 20   until the next 
20dc0 73 65 63 74 6f 72 0a 20 20 2a 2a 20 62 6f 75 6e  sector.  ** boun
20dd0 64 61 72 79 20 69 73 20 63 72 6f 73 73 65 64 2e  dary is crossed.
20de0 20 20 4f 6e 6c 79 20 74 68 65 20 70 61 72 74 20    Only the part 
20df0 6f 66 20 74 68 65 20 57 41 4c 20 70 72 69 6f 72  of the WAL prior
20e00 20 74 6f 20 74 68 65 20 6c 61 73 74 0a 20 20 2a   to the last.  *
20e10 2a 20 73 65 63 74 6f 72 20 62 6f 75 6e 64 61 72  * sector boundar
20e20 79 20 69 73 20 73 79 6e 63 65 64 3b 20 74 68 65  y is synced; the
20e30 20 70 61 72 74 20 6f 66 20 74 68 65 20 6c 61 73   part of the las
20e40 74 20 66 72 61 6d 65 20 74 68 61 74 20 65 78 74  t frame that ext
20e50 65 6e 64 73 0a 20 20 2a 2a 20 70 61 73 74 20 74  ends.  ** past t
20e60 68 65 20 73 65 63 74 6f 72 20 62 6f 75 6e 64 61  he sector bounda
20e70 72 79 20 69 73 20 77 72 69 74 74 65 6e 20 61 66  ry is written af
20e80 74 65 72 20 74 68 65 20 73 79 6e 63 2e 0a 20 20  ter the sync..  
20e90 2a 2f 0a 20 20 69 66 28 20 69 73 43 6f 6d 6d 69  */.  if( isCommi
20ea0 74 20 26 26 20 57 41 4c 5f 53 59 4e 43 5f 46 4c  t && WAL_SYNC_FL
20eb0 41 47 53 28 73 79 6e 63 5f 66 6c 61 67 73 29 21  AGS(sync_flags)!
20ec0 3d 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 62 53  =0 ){.    int bS
20ed0 79 6e 63 20 3d 20 31 3b 0a 20 20 20 20 69 66 28  ync = 1;.    if(
20ee0 20 70 57 61 6c 2d 3e 70 61 64 54 6f 53 65 63 74   pWal->padToSect
20ef0 6f 72 42 6f 75 6e 64 61 72 79 20 29 7b 0a 20 20  orBoundary ){.  
20f00 20 20 20 20 69 6e 74 20 73 65 63 74 6f 72 53 69      int sectorSi
20f10 7a 65 20 3d 20 73 71 6c 69 74 65 33 53 65 63 74  ze = sqlite3Sect
20f20 6f 72 53 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61  orSize(pWal->pWa
20f30 6c 46 64 29 3b 0a 20 20 20 20 20 20 77 2e 69 53  lFd);.      w.iS
20f40 79 6e 63 50 6f 69 6e 74 20 3d 20 28 28 69 4f 66  yncPoint = ((iOf
20f50 66 73 65 74 2b 73 65 63 74 6f 72 53 69 7a 65 2d  fset+sectorSize-
20f60 31 29 2f 73 65 63 74 6f 72 53 69 7a 65 29 2a 73  1)/sectorSize)*s
20f70 65 63 74 6f 72 53 69 7a 65 3b 0a 20 20 20 20 20  ectorSize;.     
20f80 20 62 53 79 6e 63 20 3d 20 28 77 2e 69 53 79 6e   bSync = (w.iSyn
20f90 63 50 6f 69 6e 74 3d 3d 69 4f 66 66 73 65 74 29  cPoint==iOffset)
20fa0 3b 0a 20 20 20 20 20 20 74 65 73 74 63 61 73 65  ;.      testcase
20fb0 28 20 62 53 79 6e 63 20 29 3b 0a 20 20 20 20 20  ( bSync );.     
20fc0 20 77 68 69 6c 65 28 20 69 4f 66 66 73 65 74 3c   while( iOffset<
20fd0 77 2e 69 53 79 6e 63 50 6f 69 6e 74 20 29 7b 0a  w.iSyncPoint ){.
20fe0 20 20 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c          rc = wal
20ff0 57 72 69 74 65 4f 6e 65 46 72 61 6d 65 28 26 77  WriteOneFrame(&w
21000 2c 20 70 4c 61 73 74 2c 20 6e 54 72 75 6e 63 61  , pLast, nTrunca
21010 74 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  te, iOffset);.  
21020 20 20 20 20 20 20 69 66 28 20 72 63 20 29 20 72        if( rc ) r
21030 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20  eturn rc;.      
21040 20 20 69 4f 66 66 73 65 74 20 2b 3d 20 73 7a 46    iOffset += szF
21050 72 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 6e 45  rame;.        nE
21060 78 74 72 61 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a  xtra++;.      }.
21070 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 62 53      }.    if( bS
21080 79 6e 63 20 29 7b 0a 20 20 20 20 20 20 61 73 73  ync ){.      ass
21090 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ert( rc==SQLITE_
210a0 4f 4b 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  OK );.      rc =
210b0 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 77   sqlite3OsSync(w
210c0 2e 70 46 64 2c 20 57 41 4c 5f 53 59 4e 43 5f 46  .pFd, WAL_SYNC_F
210d0 4c 41 47 53 28 73 79 6e 63 5f 66 6c 61 67 73 29  LAGS(sync_flags)
210e0 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
210f0 2f 2a 20 49 66 20 74 68 69 73 20 66 72 61 6d 65  /* If this frame
21100 20 73 65 74 20 63 6f 6d 70 6c 65 74 65 73 20 74   set completes t
21110 68 65 20 66 69 72 73 74 20 74 72 61 6e 73 61 63  he first transac
21120 74 69 6f 6e 20 69 6e 20 74 68 65 20 57 41 4c 20  tion in the WAL 
21130 61 6e 64 0a 20 20 2a 2a 20 69 66 20 50 52 41 47  and.  ** if PRAG
21140 4d 41 20 6a 6f 75 72 6e 61 6c 5f 73 69 7a 65 5f  MA journal_size_
21150 6c 69 6d 69 74 20 69 73 20 73 65 74 2c 20 74 68  limit is set, th
21160 65 6e 20 74 72 75 6e 63 61 74 65 20 74 68 65 20  en truncate the 
21170 57 41 4c 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20  WAL to the.  ** 
21180 6a 6f 75 72 6e 61 6c 20 73 69 7a 65 20 6c 69 6d  journal size lim
21190 69 74 2c 20 69 66 20 70 6f 73 73 69 62 6c 65 2e  it, if possible.
211a0 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69 73 43 6f  .  */.  if( isCo
211b0 6d 6d 69 74 20 26 26 20 70 57 61 6c 2d 3e 74 72  mmit && pWal->tr
211c0 75 6e 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 20 26  uncateOnCommit &
211d0 26 20 70 57 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a  & pWal->mxWalSiz
211e0 65 3e 3d 30 20 29 7b 0a 20 20 20 20 69 36 34 20  e>=0 ){.    i64 
211f0 73 7a 20 3d 20 70 57 61 6c 2d 3e 6d 78 57 61 6c  sz = pWal->mxWal
21200 53 69 7a 65 3b 0a 20 20 20 20 69 66 28 20 77 61  Size;.    if( wa
21210 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46 72  lFrameOffset(iFr
21220 61 6d 65 2b 6e 45 78 74 72 61 2b 31 2c 20 73 7a  ame+nExtra+1, sz
21230 50 61 67 65 29 3e 70 57 61 6c 2d 3e 6d 78 57 61  Page)>pWal->mxWa
21240 6c 53 69 7a 65 20 29 7b 0a 20 20 20 20 20 20 73  lSize ){.      s
21250 7a 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73  z = walFrameOffs
21260 65 74 28 69 46 72 61 6d 65 2b 6e 45 78 74 72 61  et(iFrame+nExtra
21270 2b 31 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20 20  +1, szPage);.   
21280 20 7d 0a 20 20 20 20 77 61 6c 4c 69 6d 69 74 53   }.    walLimitS
21290 69 7a 65 28 70 57 61 6c 2c 20 73 7a 29 3b 0a 20  ize(pWal, sz);. 
212a0 20 20 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61 74     pWal->truncat
212b0 65 4f 6e 43 6f 6d 6d 69 74 20 3d 20 30 3b 0a 20  eOnCommit = 0;. 
212c0 20 7d 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20   }..  /* Append 
212d0 64 61 74 61 20 74 6f 20 74 68 65 20 77 61 6c 2d  data to the wal-
212e0 69 6e 64 65 78 2e 20 49 74 20 69 73 20 6e 6f 74  index. It is not
212f0 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20 6c 6f   necessary to lo
21300 63 6b 20 74 68 65 20 0a 20 20 2a 2a 20 77 61 6c  ck the .  ** wal
21310 2d 69 6e 64 65 78 20 74 6f 20 64 6f 20 74 68 69  -index to do thi
21320 73 20 61 73 20 74 68 65 20 53 51 4c 49 54 45 5f  s as the SQLITE_
21330 53 48 4d 5f 57 52 49 54 45 20 6c 6f 63 6b 20 68  SHM_WRITE lock h
21340 65 6c 64 20 6f 6e 20 74 68 65 20 77 61 6c 2d 69  eld on the wal-i
21350 6e 64 65 78 0a 20 20 2a 2a 20 67 75 61 72 61 6e  ndex.  ** guaran
21360 74 65 65 73 20 74 68 61 74 20 74 68 65 72 65 20  tees that there 
21370 61 72 65 20 6e 6f 20 6f 74 68 65 72 20 77 72 69  are no other wri
21380 74 65 72 73 2c 20 61 6e 64 20 6e 6f 20 64 61 74  ters, and no dat
21390 61 20 74 68 61 74 20 6d 61 79 0a 20 20 2a 2a 20  a that may.  ** 
213a0 62 65 20 69 6e 20 75 73 65 20 62 79 20 65 78 69  be in use by exi
213b0 73 74 69 6e 67 20 72 65 61 64 65 72 73 20 69 73  sting readers is
213c0 20 62 65 69 6e 67 20 6f 76 65 72 77 72 69 74 74   being overwritt
213d0 65 6e 2e 0a 20 20 2a 2f 0a 20 20 69 46 72 61 6d  en..  */.  iFram
213e0 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  e = pWal->hdr.mx
213f0 46 72 61 6d 65 3b 0a 20 20 66 6f 72 28 70 3d 70  Frame;.  for(p=p
21400 4c 69 73 74 3b 20 70 20 26 26 20 72 63 3d 3d 53  List; p && rc==S
21410 51 4c 49 54 45 5f 4f 4b 3b 20 70 3d 70 2d 3e 70  QLITE_OK; p=p->p
21420 44 69 72 74 79 29 7b 0a 20 20 20 20 69 66 28 20  Dirty){.    if( 
21430 28 70 2d 3e 66 6c 61 67 73 20 26 20 50 47 48 44  (p->flags & PGHD
21440 52 5f 57 41 4c 5f 41 50 50 45 4e 44 29 3d 3d 30  R_WAL_APPEND)==0
21450 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20   ) continue;.   
21460 20 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 72   iFrame++;.    r
21470 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65  c = walIndexAppe
21480 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c  nd(pWal, iFrame,
21490 20 70 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 20   p->pgno);.  }. 
214a0 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49   while( rc==SQLI
214b0 54 45 5f 4f 4b 20 26 26 20 6e 45 78 74 72 61 3e  TE_OK && nExtra>
214c0 30 20 29 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b  0 ){.    iFrame+
214d0 2b 3b 0a 20 20 20 20 6e 45 78 74 72 61 2d 2d 3b  +;.    nExtra--;
214e0 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64  .    rc = walInd
214f0 65 78 41 70 70 65 6e 64 28 70 57 61 6c 2c 20 69  exAppend(pWal, i
21500 46 72 61 6d 65 2c 20 70 4c 61 73 74 2d 3e 70 67  Frame, pLast->pg
21510 6e 6f 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  no);.  }..  if( 
21520 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
21530 0a 20 20 20 20 2f 2a 20 55 70 64 61 74 65 20 74  .    /* Update t
21540 68 65 20 70 72 69 76 61 74 65 20 63 6f 70 79 20  he private copy 
21550 6f 66 20 74 68 65 20 68 65 61 64 65 72 2e 20 2a  of the header. *
21560 2f 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  /.    pWal->hdr.
21570 73 7a 50 61 67 65 20 3d 20 28 75 31 36 29 28 28  szPage = (u16)((
21580 73 7a 50 61 67 65 26 30 78 66 66 30 30 29 20 7c  szPage&0xff00) |
21590 20 28 73 7a 50 61 67 65 3e 3e 31 36 29 29 3b 0a   (szPage>>16));.
215a0 20 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a      testcase( sz
215b0 50 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20  Page<=32768 );. 
215c0 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50     testcase( szP
215d0 61 67 65 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20  age>=65536 );.  
215e0 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72    pWal->hdr.mxFr
215f0 61 6d 65 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20  ame = iFrame;.  
21600 20 20 69 66 28 20 69 73 43 6f 6d 6d 69 74 20 29    if( isCommit )
21610 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64  {.      pWal->hd
21620 72 2e 69 43 68 61 6e 67 65 2b 2b 3b 0a 20 20 20  r.iChange++;.   
21630 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61     pWal->hdr.nPa
21640 67 65 20 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a  ge = nTruncate;.
21650 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20 49 66 20      }.    /* If 
21660 74 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74  this is a commit
21670 2c 20 75 70 64 61 74 65 20 74 68 65 20 77 61 6c  , update the wal
21680 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f  -index header to
21690 6f 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 69 73  o. */.    if( is
216a0 43 6f 6d 6d 69 74 20 29 7b 0a 20 20 20 20 20 20  Commit ){.      
216b0 77 61 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72  walIndexWriteHdr
216c0 28 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 70 57  (pWal);.      pW
216d0 61 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20  al->iCallback = 
216e0 69 46 72 61 6d 65 3b 0a 20 20 20 20 7d 0a 20 20  iFrame;.    }.  
216f0 7d 0a 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  }..  WALTRACE(("
21700 57 41 4c 25 70 3a 20 66 72 61 6d 65 20 77 72 69  WAL%p: frame wri
21710 74 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20  te %s\n", pWal, 
21720 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20  rc ? "failed" : 
21730 22 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75 72 6e  "ok"));.  return
21740 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54   rc;.}../* .** T
21750 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63  his routine is c
21760 61 6c 6c 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65  alled to impleme
21770 6e 74 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63  nt sqlite3_wal_c
21780 68 65 63 6b 70 6f 69 6e 74 28 29 20 61 6e 64 0a  heckpoint() and.
21790 2a 2a 20 72 65 6c 61 74 65 64 20 69 6e 74 65 72  ** related inter
217a0 66 61 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74  faces..**.** Obt
217b0 61 69 6e 20 61 20 43 48 45 43 4b 50 4f 49 4e 54  ain a CHECKPOINT
217c0 20 6c 6f 63 6b 20 61 6e 64 20 74 68 65 6e 20 62   lock and then b
217d0 61 63 6b 66 69 6c 6c 20 61 73 20 6d 75 63 68 20  ackfill as much 
217e0 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 73 0a 2a  information as.*
217f0 2a 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 57 41  * we can from WA
21800 4c 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  L into the datab
21810 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70 61  ase..**.** If pa
21820 72 61 6d 65 74 65 72 20 78 42 75 73 79 20 69 73  rameter xBusy is
21830 20 6e 6f 74 20 4e 55 4c 4c 2c 20 69 74 20 69 73   not NULL, it is
21840 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20   a pointer to a 
21850 62 75 73 79 2d 68 61 6e 64 6c 65 72 0a 2a 2a 20  busy-handler.** 
21860 63 61 6c 6c 62 61 63 6b 2e 20 49 6e 20 74 68 69  callback. In thi
21870 73 20 63 61 73 65 20 74 68 69 73 20 66 75 6e 63  s case this func
21880 74 69 6f 6e 20 72 75 6e 73 20 61 20 62 6c 6f 63  tion runs a bloc
21890 6b 69 6e 67 20 63 68 65 63 6b 70 6f 69 6e 74 2e  king checkpoint.
218a0 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
218b0 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a 20 20  alCheckpoint(.  
218c0 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20  Wal *pWal,      
218d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
218e0 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65 63 74 69 6f  /* Wal connectio
218f0 6e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a  n */.  sqlite3 *
21900 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  db,             
21910 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 20         /* Check 
21920 74 68 69 73 20 68 61 6e 64 6c 65 27 73 20 69 6e  this handle's in
21930 74 65 72 72 75 70 74 20 66 6c 61 67 20 2a 2f 0a  terrupt flag */.
21940 20 20 69 6e 74 20 65 4d 6f 64 65 2c 20 20 20 20    int eMode,    
21950 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21960 20 20 2f 2a 20 50 41 53 53 49 56 45 2c 20 46 55    /* PASSIVE, FU
21970 4c 4c 2c 20 52 45 53 54 41 52 54 2c 20 6f 72 20  LL, RESTART, or 
21980 54 52 55 4e 43 41 54 45 20 2a 2f 0a 20 20 69 6e  TRUNCATE */.  in
21990 74 20 28 2a 78 42 75 73 79 29 28 76 6f 69 64 2a  t (*xBusy)(void*
219a0 29 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ),            /*
219b0 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63 61 6c   Function to cal
219c0 6c 20 77 68 65 6e 20 62 75 73 79 20 2a 2f 0a 20  l when busy */. 
219d0 20 76 6f 69 64 20 2a 70 42 75 73 79 41 72 67 2c   void *pBusyArg,
219e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
219f0 20 2f 2a 20 43 6f 6e 74 65 78 74 20 61 72 67 75   /* Context argu
21a00 6d 65 6e 74 20 66 6f 72 20 78 42 75 73 79 48 61  ment for xBusyHa
21a10 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74 20 73  ndler */.  int s
21a20 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20  ync_flags,      
21a30 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c             /* Fl
21a40 61 67 73 20 74 6f 20 73 79 6e 63 20 64 62 20 66  ags to sync db f
21a50 69 6c 65 20 77 69 74 68 20 28 6f 72 20 30 29 20  ile with (or 0) 
21a60 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20  */.  int nBuf,  
21a70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21a80 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
21a90 74 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72  temporary buffer
21aa0 20 2a 2f 0a 20 20 75 38 20 2a 7a 42 75 66 2c 20   */.  u8 *zBuf, 
21ab0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21ac0 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61        /* Tempora
21ad0 72 79 20 62 75 66 66 65 72 20 74 6f 20 75 73 65  ry buffer to use
21ae0 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4c 6f 67   */.  int *pnLog
21af0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
21b00 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75        /* OUT: Nu
21b10 6d 62 65 72 20 6f 66 20 66 72 61 6d 65 73 20 69  mber of frames i
21b20 6e 20 57 41 4c 20 2a 2f 0a 20 20 69 6e 74 20 2a  n WAL */.  int *
21b30 70 6e 43 6b 70 74 20 20 20 20 20 20 20 20 20 20  pnCkpt          
21b40 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
21b50 54 3a 20 4e 75 6d 62 65 72 20 6f 66 20 62 61 63  T: Number of bac
21b60 6b 66 69 6c 6c 65 64 20 66 72 61 6d 65 73 20 69  kfilled frames i
21b70 6e 20 57 41 4c 20 2a 2f 0a 29 7b 0a 20 20 69 6e  n WAL */.){.  in
21b80 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
21b90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
21ba0 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
21bb0 20 20 69 6e 74 20 69 73 43 68 61 6e 67 65 64 20    int isChanged 
21bc0 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
21bd0 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61 20 6e    /* True if a n
21be0 65 77 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  ew wal-index hea
21bf0 64 65 72 20 69 73 20 6c 6f 61 64 65 64 20 2a 2f  der is loaded */
21c00 0a 20 20 69 6e 74 20 65 4d 6f 64 65 32 20 3d 20  .  int eMode2 = 
21c10 65 4d 6f 64 65 3b 20 20 20 20 20 20 20 20 20 20  eMode;          
21c20 20 20 20 2f 2a 20 4d 6f 64 65 20 74 6f 20 70 61     /* Mode to pa
21c30 73 73 20 74 6f 20 77 61 6c 43 68 65 63 6b 70 6f  ss to walCheckpo
21c40 69 6e 74 28 29 20 2a 2f 0a 20 20 69 6e 74 20 28  int() */.  int (
21c50 2a 78 42 75 73 79 32 29 28 76 6f 69 64 2a 29 20  *xBusy2)(void*) 
21c60 3d 20 78 42 75 73 79 3b 20 20 20 2f 2a 20 42 75  = xBusy;   /* Bu
21c70 73 79 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 65  sy handler for e
21c80 4d 6f 64 65 32 20 2a 2f 0a 0a 20 20 61 73 73 65  Mode2 */..  asse
21c90 72 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f  rt( pWal->ckptLo
21ca0 63 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  ck==0 );.  asser
21cb0 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  t( pWal->writeLo
21cc0 63 6b 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 45  ck==0 );..  /* E
21cd0 56 49 44 45 4e 43 45 2d 4f 46 3a 20 52 2d 36 32  VIDENCE-OF: R-62
21ce0 39 32 30 2d 34 37 34 35 30 20 54 68 65 20 62 75  920-47450 The bu
21cf0 73 79 2d 68 61 6e 64 6c 65 72 20 63 61 6c 6c 62  sy-handler callb
21d00 61 63 6b 20 69 73 20 6e 65 76 65 72 20 69 6e 76  ack is never inv
21d10 6f 6b 65 64 0a 20 20 2a 2a 20 69 6e 20 74 68 65  oked.  ** in the
21d20 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49   SQLITE_CHECKPOI
21d30 4e 54 5f 50 41 53 53 49 56 45 20 6d 6f 64 65 2e  NT_PASSIVE mode.
21d40 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 65 4d   */.  assert( eM
21d50 6f 64 65 21 3d 53 51 4c 49 54 45 5f 43 48 45 43  ode!=SQLITE_CHEC
21d60 4b 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 7c  KPOINT_PASSIVE |
21d70 7c 20 78 42 75 73 79 3d 3d 30 20 29 3b 0a 0a 20  | xBusy==0 );.. 
21d80 20 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4f   if( pWal->readO
21d90 6e 6c 79 20 29 20 72 65 74 75 72 6e 20 53 51 4c  nly ) return SQL
21da0 49 54 45 5f 52 45 41 44 4f 4e 4c 59 3b 0a 20 20  ITE_READONLY;.  
21db0 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70  WALTRACE(("WAL%p
21dc0 3a 20 63 68 65 63 6b 70 6f 69 6e 74 20 62 65 67  : checkpoint beg
21dd0 69 6e 73 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a  ins\n", pWal));.
21de0 0a 20 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54 41  .  /* IMPLEMENTA
21df0 54 49 4f 4e 2d 4f 46 3a 20 52 2d 36 32 30 32 38  TION-OF: R-62028
21e00 2d 34 37 32 31 32 20 41 6c 6c 20 63 61 6c 6c 73  -47212 All calls
21e10 20 6f 62 74 61 69 6e 20 61 6e 20 65 78 63 6c 75   obtain an exclu
21e20 73 69 76 65 20 0a 20 20 2a 2a 20 22 63 68 65 63  sive .  ** "chec
21e30 6b 70 6f 69 6e 74 22 20 6c 6f 63 6b 20 6f 6e 20  kpoint" lock on 
21e40 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
21e50 65 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 77 61 6c  e. */.  rc = wal
21e60 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  LockExclusive(pW
21e70 61 6c 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43  al, WAL_CKPT_LOC
21e80 4b 2c 20 31 29 3b 0a 20 20 69 66 28 20 72 63 20  K, 1);.  if( rc 
21e90 29 7b 0a 20 20 20 20 2f 2a 20 45 56 49 44 45 4e  ){.    /* EVIDEN
21ea0 43 45 2d 4f 46 3a 20 52 2d 31 30 34 32 31 2d 31  CE-OF: R-10421-1
21eb0 39 37 33 36 20 49 66 20 61 6e 79 20 6f 74 68 65  9736 If any othe
21ec0 72 20 70 72 6f 63 65 73 73 20 69 73 20 72 75 6e  r process is run
21ed0 6e 69 6e 67 20 61 0a 20 20 20 20 2a 2a 20 63 68  ning a.    ** ch
21ee0 65 63 6b 70 6f 69 6e 74 20 6f 70 65 72 61 74 69  eckpoint operati
21ef0 6f 6e 20 61 74 20 74 68 65 20 73 61 6d 65 20 74  on at the same t
21f00 69 6d 65 2c 20 74 68 65 20 6c 6f 63 6b 20 63 61  ime, the lock ca
21f10 6e 6e 6f 74 20 62 65 20 6f 62 74 61 69 6e 65 64  nnot be obtained
21f20 20 61 6e 64 0a 20 20 20 20 2a 2a 20 53 51 4c 49   and.    ** SQLI
21f30 54 45 5f 42 55 53 59 20 69 73 20 72 65 74 75 72  TE_BUSY is retur
21f40 6e 65 64 2e 0a 20 20 20 20 2a 2a 20 45 56 49 44  ned..    ** EVID
21f50 45 4e 43 45 2d 4f 46 3a 20 52 2d 35 33 38 32 30  ENCE-OF: R-53820
21f60 2d 33 33 38 39 37 20 45 76 65 6e 20 69 66 20 74  -33897 Even if t
21f70 68 65 72 65 20 69 73 20 61 20 62 75 73 79 2d 68  here is a busy-h
21f80 61 6e 64 6c 65 72 20 63 6f 6e 66 69 67 75 72 65  andler configure
21f90 64 2c 0a 20 20 20 20 2a 2a 20 69 74 20 77 69 6c  d,.    ** it wil
21fa0 6c 20 6e 6f 74 20 62 65 20 69 6e 76 6f 6b 65 64  l not be invoked
21fb0 20 69 6e 20 74 68 69 73 20 63 61 73 65 2e 0a 20   in this case.. 
21fc0 20 20 20 2a 2f 0a 20 20 20 20 74 65 73 74 63 61     */.    testca
21fd0 73 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42  se( rc==SQLITE_B
21fe0 55 53 59 20 29 3b 0a 20 20 20 20 74 65 73 74 63  USY );.    testc
21ff0 61 73 65 28 20 78 42 75 73 79 21 3d 30 20 29 3b  ase( xBusy!=0 );
22000 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
22010 20 20 7d 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74    }.  pWal->ckpt
22020 4c 6f 63 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20  Lock = 1;..  /* 
22030 49 4d 50 4c 45 4d 45 4e 54 41 54 49 4f 4e 2d 4f  IMPLEMENTATION-O
22040 46 3a 20 52 2d 35 39 37 38 32 2d 33 36 38 31 38  F: R-59782-36818
22050 20 54 68 65 20 53 51 4c 49 54 45 5f 43 48 45 43   The SQLITE_CHEC
22060 4b 50 4f 49 4e 54 5f 46 55 4c 4c 2c 20 52 45 53  KPOINT_FULL, RES
22070 54 41 52 54 20 61 6e 64 0a 20 20 2a 2a 20 54 52  TART and.  ** TR
22080 55 4e 43 41 54 45 20 6d 6f 64 65 73 20 61 6c 73  UNCATE modes als
22090 6f 20 6f 62 74 61 69 6e 20 74 68 65 20 65 78 63  o obtain the exc
220a0 6c 75 73 69 76 65 20 22 77 72 69 74 65 72 22 20  lusive "writer" 
220b0 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 64 61 74 61  lock on the data
220c0 62 61 73 65 0a 20 20 2a 2a 20 66 69 6c 65 2e 0a  base.  ** file..
220d0 20 20 2a 2a 0a 20 20 2a 2a 20 45 56 49 44 45 4e    **.  ** EVIDEN
220e0 43 45 2d 4f 46 3a 20 52 2d 36 30 36 34 32 2d 30  CE-OF: R-60642-0
220f0 34 30 38 32 20 49 66 20 74 68 65 20 77 72 69 74  4082 If the writ
22100 65 72 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62  er lock cannot b
22110 65 20 6f 62 74 61 69 6e 65 64 0a 20 20 2a 2a 20  e obtained.  ** 
22120 69 6d 6d 65 64 69 61 74 65 6c 79 2c 20 61 6e 64  immediately, and
22130 20 61 20 62 75 73 79 2d 68 61 6e 64 6c 65 72 20   a busy-handler 
22140 69 73 20 63 6f 6e 66 69 67 75 72 65 64 2c 20 69  is configured, i
22150 74 20 69 73 20 69 6e 76 6f 6b 65 64 20 61 6e 64  t is invoked and
22160 20 74 68 65 0a 20 20 2a 2a 20 77 72 69 74 65 72   the.  ** writer
22170 20 6c 6f 63 6b 20 72 65 74 72 69 65 64 20 75 6e   lock retried un
22180 74 69 6c 20 65 69 74 68 65 72 20 74 68 65 20 62  til either the b
22190 75 73 79 2d 68 61 6e 64 6c 65 72 20 72 65 74 75  usy-handler retu
221a0 72 6e 73 20 30 20 6f 72 20 74 68 65 0a 20 20 2a  rns 0 or the.  *
221b0 2a 20 6c 6f 63 6b 20 69 73 20 73 75 63 63 65 73  * lock is succes
221c0 73 66 75 6c 6c 79 20 6f 62 74 61 69 6e 65 64 2e  sfully obtained.
221d0 0a 20 20 2a 2f 0a 20 20 69 66 28 20 65 4d 6f 64  .  */.  if( eMod
221e0 65 21 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b 50  e!=SQLITE_CHECKP
221f0 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 29 7b 0a  OINT_PASSIVE ){.
22200 20 20 20 20 72 63 20 3d 20 77 61 6c 42 75 73 79      rc = walBusy
22210 4c 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73 79  Lock(pWal, xBusy
22220 2c 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c 5f  , pBusyArg, WAL_
22230 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  WRITE_LOCK, 1);.
22240 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
22250 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70  TE_OK ){.      p
22260 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d  Wal->writeLock =
22270 20 31 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66   1;.    }else if
22280 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc==SQLITE_BUS
22290 59 20 29 7b 0a 20 20 20 20 20 20 65 4d 6f 64 65  Y ){.      eMode
222a0 32 20 3d 20 53 51 4c 49 54 45 5f 43 48 45 43 4b  2 = SQLITE_CHECK
222b0 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 3b 0a 20  POINT_PASSIVE;. 
222c0 20 20 20 20 20 78 42 75 73 79 32 20 3d 20 30 3b       xBusy2 = 0;
222d0 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
222e0 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 7d  TE_OK;.    }.  }
222f0 0a 0a 20 20 2f 2a 20 52 65 61 64 20 74 68 65 20  ..  /* Read the 
22300 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
22310 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  . */.  if( rc==S
22320 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
22330 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52 65 61  rc = walIndexRea
22340 64 48 64 72 28 70 57 61 6c 2c 20 26 69 73 43 68  dHdr(pWal, &isCh
22350 61 6e 67 65 64 29 3b 0a 20 20 20 20 69 66 28 20  anged);.    if( 
22360 69 73 43 68 61 6e 67 65 64 20 26 26 20 70 57 61  isChanged && pWa
22370 6c 2d 3e 70 44 62 46 64 2d 3e 70 4d 65 74 68 6f  l->pDbFd->pMetho
22380 64 73 2d 3e 69 56 65 72 73 69 6f 6e 3e 3d 33 20  ds->iVersion>=3 
22390 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
223a0 4f 73 55 6e 66 65 74 63 68 28 70 57 61 6c 2d 3e  OsUnfetch(pWal->
223b0 70 44 62 46 64 2c 20 30 2c 20 30 29 3b 0a 20 20  pDbFd, 0, 0);.  
223c0 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f    }.  }..  /* Co
223d0 70 79 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65  py data from the
223e0 20 6c 6f 67 20 74 6f 20 74 68 65 20 64 61 74 61   log to the data
223f0 62 61 73 65 20 66 69 6c 65 2e 20 2a 2f 0a 20 20  base file. */.  
22400 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
22410 4b 20 29 7b 0a 0a 20 20 20 20 69 66 28 20 70 57  K ){..    if( pW
22420 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
22430 26 26 20 77 61 6c 50 61 67 65 73 69 7a 65 28 70  && walPagesize(p
22440 57 61 6c 29 21 3d 6e 42 75 66 20 29 7b 0a 20 20  Wal)!=nBuf ){.  
22450 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
22460 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20  CORRUPT_BKPT;.  
22470 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72    }else{.      r
22480 63 20 3d 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e  c = walCheckpoin
22490 74 28 70 57 61 6c 2c 20 64 62 2c 20 65 4d 6f 64  t(pWal, db, eMod
224a0 65 32 2c 20 78 42 75 73 79 32 2c 20 70 42 75 73  e2, xBusy2, pBus
224b0 79 41 72 67 2c 20 73 79 6e 63 5f 66 6c 61 67 73  yArg, sync_flags
224c0 2c 20 7a 42 75 66 29 3b 0a 20 20 20 20 7d 0a 0a  , zBuf);.    }..
224d0 20 20 20 20 2f 2a 20 49 66 20 6e 6f 20 65 72 72      /* If no err
224e0 6f 72 20 6f 63 63 75 72 72 65 64 2c 20 73 65 74  or occurred, set
224f0 20 74 68 65 20 6f 75 74 70 75 74 20 76 61 72 69   the output vari
22500 61 62 6c 65 73 2e 20 2a 2f 0a 20 20 20 20 69 66  ables. */.    if
22510 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
22520 7c 7c 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  || rc==SQLITE_BU
22530 53 59 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  SY ){.      if( 
22540 70 6e 4c 6f 67 20 29 20 2a 70 6e 4c 6f 67 20 3d  pnLog ) *pnLog =
22550 20 28 69 6e 74 29 70 57 61 6c 2d 3e 68 64 72 2e   (int)pWal->hdr.
22560 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 69  mxFrame;.      i
22570 66 28 20 70 6e 43 6b 70 74 20 29 20 2a 70 6e 43  f( pnCkpt ) *pnC
22580 6b 70 74 20 3d 20 28 69 6e 74 29 28 77 61 6c 43  kpt = (int)(walC
22590 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 2d 3e 6e  kptInfo(pWal)->n
225a0 42 61 63 6b 66 69 6c 6c 29 3b 0a 20 20 20 20 7d  Backfill);.    }
225b0 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 73 43 68  .  }..  if( isCh
225c0 61 6e 67 65 64 20 29 7b 0a 20 20 20 20 2f 2a 20  anged ){.    /* 
225d0 49 66 20 61 20 6e 65 77 20 77 61 6c 2d 69 6e 64  If a new wal-ind
225e0 65 78 20 68 65 61 64 65 72 20 77 61 73 20 6c 6f  ex header was lo
225f0 61 64 65 64 20 62 65 66 6f 72 65 20 74 68 65 20  aded before the 
22600 63 68 65 63 6b 70 6f 69 6e 74 20 77 61 73 20 0a  checkpoint was .
22610 20 20 20 20 2a 2a 20 70 65 72 66 6f 72 6d 65 64      ** performed
22620 2c 20 74 68 65 6e 20 74 68 65 20 70 61 67 65 72  , then the pager
22630 2d 63 61 63 68 65 20 61 73 73 6f 63 69 61 74 65  -cache associate
22640 64 20 77 69 74 68 20 70 57 61 6c 20 69 73 20 6e  d with pWal is n
22650 6f 77 0a 20 20 20 20 2a 2a 20 6f 75 74 20 6f 66  ow.    ** out of
22660 20 64 61 74 65 2e 20 53 6f 20 7a 65 72 6f 20 74   date. So zero t
22670 68 65 20 63 61 63 68 65 64 20 77 61 6c 2d 69 6e  he cached wal-in
22680 64 65 78 20 68 65 61 64 65 72 20 74 6f 20 65 6e  dex header to en
22690 73 75 72 65 20 74 68 61 74 0a 20 20 20 20 2a 2a  sure that.    **
226a0 20 6e 65 78 74 20 74 69 6d 65 20 74 68 65 20 70   next time the p
226b0 61 67 65 72 20 6f 70 65 6e 73 20 61 20 73 6e 61  ager opens a sna
226c0 70 73 68 6f 74 20 6f 6e 20 74 68 69 73 20 64 61  pshot on this da
226d0 74 61 62 61 73 65 20 69 74 20 6b 6e 6f 77 73 20  tabase it knows 
226e0 74 68 61 74 0a 20 20 20 20 2a 2a 20 74 68 65 20  that.    ** the 
226f0 63 61 63 68 65 20 6e 65 65 64 73 20 74 6f 20 62  cache needs to b
22700 65 20 72 65 73 65 74 2e 0a 20 20 20 20 2a 2f 0a  e reset..    */.
22710 20 20 20 20 6d 65 6d 73 65 74 28 26 70 57 61 6c      memset(&pWal
22720 2d 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66  ->hdr, 0, sizeof
22730 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a  (WalIndexHdr));.
22740 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 6c 65 61 73    }..  /* Releas
22750 65 20 74 68 65 20 6c 6f 63 6b 73 2e 20 2a 2f 0a  e the locks. */.
22760 20 20 73 71 6c 69 74 65 33 57 61 6c 45 6e 64 57    sqlite3WalEndW
22770 72 69 74 65 54 72 61 6e 73 61 63 74 69 6f 6e 28  riteTransaction(
22780 70 57 61 6c 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f  pWal);.  walUnlo
22790 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
227a0 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c  , WAL_CKPT_LOCK,
227b0 20 31 29 3b 0a 20 20 70 57 61 6c 2d 3e 63 6b 70   1);.  pWal->ckp
227c0 74 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 57 41 4c  tLock = 0;.  WAL
227d0 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63  TRACE(("WAL%p: c
227e0 68 65 63 6b 70 6f 69 6e 74 20 25 73 5c 6e 22 2c  heckpoint %s\n",
227f0 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69   pWal, rc ? "fai
22800 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
22810 20 72 65 74 75 72 6e 20 28 72 63 3d 3d 53 51 4c   return (rc==SQL
22820 49 54 45 5f 4f 4b 20 26 26 20 65 4d 6f 64 65 21  ITE_OK && eMode!
22830 3d 65 4d 6f 64 65 32 20 3f 20 53 51 4c 49 54 45  =eMode2 ? SQLITE
22840 5f 42 55 53 59 20 3a 20 72 63 29 3b 0a 7d 0a 0a  _BUSY : rc);.}..
22850 2f 2a 20 52 65 74 75 72 6e 20 74 68 65 20 76 61  /* Return the va
22860 6c 75 65 20 74 6f 20 70 61 73 73 20 74 6f 20 61  lue to pass to a
22870 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 68 6f 6f   sqlite3_wal_hoo
22880 6b 20 63 61 6c 6c 62 61 63 6b 2c 20 74 68 65 0a  k callback, the.
22890 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61  ** number of fra
228a0 6d 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20 61  mes in the WAL a
228b0 74 20 74 68 65 20 70 6f 69 6e 74 20 6f 66 20 74  t the point of t
228c0 68 65 20 6c 61 73 74 20 63 6f 6d 6d 69 74 20 73  he last commit s
228d0 69 6e 63 65 0a 2a 2a 20 73 71 6c 69 74 65 33 57  ince.** sqlite3W
228e0 61 6c 43 61 6c 6c 62 61 63 6b 28 29 20 77 61 73  alCallback() was
228f0 20 63 61 6c 6c 65 64 2e 20 20 49 66 20 6e 6f 20   called.  If no 
22900 63 6f 6d 6d 69 74 73 20 68 61 76 65 20 6f 63 63  commits have occ
22910 75 72 72 65 64 20 73 69 6e 63 65 0a 2a 2a 20 74  urred since.** t
22920 68 65 20 6c 61 73 74 20 63 61 6c 6c 2c 20 74 68  he last call, th
22930 65 6e 20 72 65 74 75 72 6e 20 30 2e 0a 2a 2f 0a  en return 0..*/.
22940 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 43 61  int sqlite3WalCa
22950 6c 6c 62 61 63 6b 28 57 61 6c 20 2a 70 57 61 6c  llback(Wal *pWal
22960 29 7b 0a 20 20 75 33 32 20 72 65 74 20 3d 20 30  ){.  u32 ret = 0
22970 3b 0a 20 20 69 66 28 20 70 57 61 6c 20 29 7b 0a  ;.  if( pWal ){.
22980 20 20 20 20 72 65 74 20 3d 20 70 57 61 6c 2d 3e      ret = pWal->
22990 69 43 61 6c 6c 62 61 63 6b 3b 0a 20 20 20 20 70  iCallback;.    p
229a0 57 61 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d  Wal->iCallback =
229b0 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   0;.  }.  return
229c0 20 28 69 6e 74 29 72 65 74 3b 0a 7d 0a 0a 2f 2a   (int)ret;.}../*
229d0 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
229e0 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 63  n is called to c
229f0 68 61 6e 67 65 20 74 68 65 20 57 41 4c 20 73 75  hange the WAL su
22a00 62 73 79 73 74 65 6d 20 69 6e 74 6f 20 6f 72 20  bsystem into or 
22a10 6f 75 74 0a 2a 2a 20 6f 66 20 6c 6f 63 6b 69 6e  out.** of lockin
22a20 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45  g_mode=EXCLUSIVE
22a30 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20 69 73  ..**.** If op is
22a40 20 7a 65 72 6f 2c 20 74 68 65 6e 20 61 74 74 65   zero, then atte
22a50 6d 70 74 20 74 6f 20 63 68 61 6e 67 65 20 66 72  mpt to change fr
22a60 6f 6d 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d  om locking_mode=
22a70 45 58 43 4c 55 53 49 56 45 0a 2a 2a 20 69 6e 74  EXCLUSIVE.** int
22a80 6f 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e  o locking_mode=N
22a90 4f 52 4d 41 4c 2e 20 20 54 68 69 73 20 6d 65 61  ORMAL.  This mea
22aa0 6e 73 20 74 68 61 74 20 77 65 20 6d 75 73 74 20  ns that we must 
22ab0 61 63 71 75 69 72 65 20 61 20 6c 6f 63 6b 0a 2a  acquire a lock.*
22ac0 2a 20 6f 6e 20 74 68 65 20 70 57 61 6c 2d 3e 72  * on the pWal->r
22ad0 65 61 64 4c 6f 63 6b 20 62 79 74 65 2e 20 20 49  eadLock byte.  I
22ae0 66 20 74 68 65 20 57 41 4c 20 69 73 20 61 6c 72  f the WAL is alr
22af0 65 61 64 79 20 69 6e 20 6c 6f 63 6b 69 6e 67 5f  eady in locking_
22b00 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 0a 2a 2a 20 6f  mode=NORMAL.** o
22b10 72 20 69 66 20 74 68 65 20 61 63 71 75 69 73 69  r if the acquisi
22b20 74 69 6f 6e 20 6f 66 20 74 68 65 20 6c 6f 63 6b  tion of the lock
22b30 20 66 61 69 6c 73 2c 20 74 68 65 6e 20 72 65 74   fails, then ret
22b40 75 72 6e 20 30 2e 20 20 49 66 20 74 68 65 0a 2a  urn 0.  If the.*
22b50 2a 20 74 72 61 6e 73 69 74 69 6f 6e 20 6f 75 74  * transition out
22b60 20 6f 66 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f   of exclusive-mo
22b70 64 65 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  de is successful
22b80 2c 20 72 65 74 75 72 6e 20 31 2e 20 20 54 68 69  , return 1.  Thi
22b90 73 0a 2a 2a 20 6f 70 65 72 61 74 69 6f 6e 20 6d  s.** operation m
22ba0 75 73 74 20 6f 63 63 75 72 20 77 68 69 6c 65 20  ust occur while 
22bb0 74 68 65 20 70 61 67 65 72 20 69 73 20 73 74 69  the pager is sti
22bc0 6c 6c 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 65  ll holding the e
22bd0 78 63 6c 75 73 69 76 65 0a 2a 2a 20 6c 6f 63 6b  xclusive.** lock
22be0 20 6f 6e 20 74 68 65 20 6d 61 69 6e 20 64 61 74   on the main dat
22bf0 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a  abase file..**.*
22c00 2a 20 49 66 20 6f 70 20 69 73 20 6f 6e 65 2c 20  * If op is one, 
22c10 74 68 65 6e 20 63 68 61 6e 67 65 20 66 72 6f 6d  then change from
22c20 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f   locking_mode=NO
22c30 52 4d 41 4c 20 69 6e 74 6f 20 0a 2a 2a 20 6c 6f  RMAL into .** lo
22c40 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55  cking_mode=EXCLU
22c50 53 49 56 45 2e 20 20 54 68 69 73 20 6d 65 61 6e  SIVE.  This mean
22c60 73 20 74 68 61 74 20 74 68 65 20 70 57 61 6c 2d  s that the pWal-
22c70 3e 72 65 61 64 4c 6f 63 6b 20 6d 75 73 74 0a 2a  >readLock must.*
22c80 2a 20 62 65 20 72 65 6c 65 61 73 65 64 2e 20 20  * be released.  
22c90 52 65 74 75 72 6e 20 31 20 69 66 20 74 68 65 20  Return 1 if the 
22ca0 74 72 61 6e 73 69 74 69 6f 6e 20 69 73 20 6d 61  transition is ma
22cb0 64 65 20 61 6e 64 20 30 20 69 66 20 74 68 65 0a  de and 0 if the.
22cc0 2a 2a 20 57 41 4c 20 69 73 20 61 6c 72 65 61 64  ** WAL is alread
22cd0 79 20 69 6e 20 65 78 63 6c 75 73 69 76 65 2d 6c  y in exclusive-l
22ce0 6f 63 6b 69 6e 67 20 6d 6f 64 65 20 2d 20 6d 65  ocking mode - me
22cf0 61 6e 69 6e 67 20 74 68 61 74 20 74 68 69 73 0a  aning that this.
22d00 2a 2a 20 72 6f 75 74 69 6e 65 20 69 73 20 61 20  ** routine is a 
22d10 6e 6f 2d 6f 70 2e 20 20 54 68 65 20 70 61 67 65  no-op.  The page
22d20 72 20 6d 75 73 74 20 61 6c 72 65 61 64 79 20 68  r must already h
22d30 6f 6c 64 20 74 68 65 20 65 78 63 6c 75 73 69 76  old the exclusiv
22d40 65 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65  e lock.** on the
22d50 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 66   main database f
22d60 69 6c 65 20 62 65 66 6f 72 65 20 69 6e 76 6f 6b  ile before invok
22d70 69 6e 67 20 74 68 69 73 20 6f 70 65 72 61 74 69  ing this operati
22d80 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20  on..**.** If op 
22d90 69 73 20 6e 65 67 61 74 69 76 65 2c 20 74 68 65  is negative, the
22da0 6e 20 64 6f 20 61 20 64 72 79 2d 72 75 6e 20 6f  n do a dry-run o
22db0 66 20 74 68 65 20 6f 70 3d 3d 31 20 63 61 73 65  f the op==1 case
22dc0 20 62 75 74 20 64 6f 0a 2a 2a 20 6e 6f 74 20 61   but do.** not a
22dd0 63 74 75 61 6c 6c 79 20 63 68 61 6e 67 65 20 61  ctually change a
22de0 6e 79 74 68 69 6e 67 2e 20 54 68 65 20 70 61 67  nything. The pag
22df0 65 72 20 75 73 65 73 20 74 68 69 73 20 74 6f 20  er uses this to 
22e00 73 65 65 20 69 66 20 69 74 0a 2a 2a 20 73 68 6f  see if it.** sho
22e10 75 6c 64 20 61 63 71 75 69 72 65 20 74 68 65 20  uld acquire the 
22e20 64 61 74 61 62 61 73 65 20 65 78 63 6c 75 73 69  database exclusi
22e30 76 65 20 6c 6f 63 6b 20 70 72 69 6f 72 20 74 6f  ve lock prior to
22e40 20 69 6e 76 6f 6b 69 6e 67 0a 2a 2a 20 74 68 65   invoking.** the
22e50 20 6f 70 3d 3d 31 20 63 61 73 65 2e 0a 2a 2f 0a   op==1 case..*/.
22e60 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 45 78  int sqlite3WalEx
22e70 63 6c 75 73 69 76 65 4d 6f 64 65 28 57 61 6c 20  clusiveMode(Wal 
22e80 2a 70 57 61 6c 2c 20 69 6e 74 20 6f 70 29 7b 0a  *pWal, int op){.
22e90 20 20 69 6e 74 20 72 63 3b 0a 20 20 61 73 73 65    int rc;.  asse
22ea0 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c  rt( pWal->writeL
22eb0 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  ock==0 );.  asse
22ec0 72 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  rt( pWal->exclus
22ed0 69 76 65 4d 6f 64 65 21 3d 57 41 4c 5f 48 45 41  iveMode!=WAL_HEA
22ee0 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 7c 7c 20  PMEMORY_MODE || 
22ef0 6f 70 3d 3d 2d 31 20 29 3b 0a 0a 20 20 2f 2a 20  op==-1 );..  /* 
22f00 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69  pWal->readLock i
22f10 73 20 75 73 75 61 6c 6c 79 20 73 65 74 2c 20 62  s usually set, b
22f20 75 74 20 6d 69 67 68 74 20 62 65 20 2d 31 20 69  ut might be -1 i
22f30 66 20 74 68 65 72 65 20 77 61 73 20 61 20 0a 20  f there was a . 
22f40 20 2a 2a 20 70 72 69 6f 72 20 65 72 72 6f 72 20   ** prior error 
22f50 77 68 69 6c 65 20 61 74 74 65 6d 70 74 69 6e 67  while attempting
22f60 20 74 6f 20 61 63 71 75 69 72 65 20 61 72 65 20   to acquire are 
22f70 72 65 61 64 2d 6c 6f 63 6b 2e 20 54 68 69 73 20  read-lock. This 
22f80 63 61 6e 6e 6f 74 20 0a 20 20 2a 2a 20 68 61 70  cannot .  ** hap
22f90 70 65 6e 20 69 66 20 74 68 65 20 63 6f 6e 6e 65  pen if the conne
22fa0 63 74 69 6f 6e 20 69 73 20 61 63 74 75 61 6c 6c  ction is actuall
22fb0 79 20 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d  y in exclusive m
22fc0 6f 64 65 20 28 61 73 20 6e 6f 20 78 53 68 6d 4c  ode (as no xShmL
22fd0 6f 63 6b 0a 20 20 2a 2a 20 6c 6f 63 6b 73 20 61  ock.  ** locks a
22fe0 72 65 20 74 61 6b 65 6e 20 69 6e 20 74 68 69 73  re taken in this
22ff0 20 63 61 73 65 29 2e 20 4e 6f 72 20 73 68 6f 75   case). Nor shou
23000 6c 64 20 74 68 65 20 70 61 67 65 72 20 61 74 74  ld the pager att
23010 65 6d 70 74 20 74 6f 0a 20 20 2a 2a 20 75 70 67  empt to.  ** upg
23020 72 61 64 65 20 74 6f 20 65 78 63 6c 75 73 69 76  rade to exclusiv
23030 65 2d 6d 6f 64 65 20 66 6f 6c 6c 6f 77 69 6e 67  e-mode following
23040 20 73 75 63 68 20 61 6e 20 65 72 72 6f 72 2e 0a   such an error..
23050 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
23060 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30  Wal->readLock>=0
23070 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72   || pWal->lockEr
23080 72 6f 72 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ror );.  assert(
23090 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e   pWal->readLock>
230a0 3d 30 20 7c 7c 20 28 6f 70 3c 3d 30 20 26 26 20  =0 || (op<=0 && 
230b0 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
230c0 6f 64 65 3d 3d 30 29 20 29 3b 0a 0a 20 20 69 66  ode==0) );..  if
230d0 28 20 6f 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69  ( op==0 ){.    i
230e0 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69  f( pWal->exclusi
230f0 76 65 4d 6f 64 65 21 3d 57 41 4c 5f 4e 4f 52 4d  veMode!=WAL_NORM
23100 41 4c 5f 4d 4f 44 45 20 29 7b 0a 20 20 20 20 20  AL_MODE ){.     
23110 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
23120 4d 6f 64 65 20 3d 20 57 41 4c 5f 4e 4f 52 4d 41  Mode = WAL_NORMA
23130 4c 5f 4d 4f 44 45 3b 0a 20 20 20 20 20 20 69 66  L_MODE;.      if
23140 28 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28  ( walLockShared(
23150 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  pWal, WAL_READ_L
23160 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  OCK(pWal->readLo
23170 63 6b 29 29 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ck))!=SQLITE_OK 
23180 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d  ){.        pWal-
23190 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d  >exclusiveMode =
231a0 20 57 41 4c 5f 45 58 43 4c 55 53 49 56 45 5f 4d   WAL_EXCLUSIVE_M
231b0 4f 44 45 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ODE;.      }.   
231c0 20 20 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78     rc = pWal->ex
231d0 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c  clusiveMode==WAL
231e0 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 3b 0a 20 20  _NORMAL_MODE;.  
231f0 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f    }else{.      /
23200 2a 20 41 6c 72 65 61 64 79 20 69 6e 20 6c 6f 63  * Already in loc
23210 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c  king_mode=NORMAL
23220 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 30   */.      rc = 0
23230 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20  ;.    }.  }else 
23240 69 66 28 20 6f 70 3e 30 20 29 7b 0a 20 20 20 20  if( op>0 ){.    
23250 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 65 78  assert( pWal->ex
23260 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c  clusiveMode==WAL
23270 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 20 29 3b 0a  _NORMAL_MODE );.
23280 20 20 20 20 61 73 73 65 72 74 28 20 70 57 61 6c      assert( pWal
23290 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b  ->readLock>=0 );
232a0 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68  .    walUnlockSh
232b0 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
232c0 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72  EAD_LOCK(pWal->r
232d0 65 61 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70  eadLock));.    p
232e0 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
232f0 64 65 20 3d 20 57 41 4c 5f 45 58 43 4c 55 53 49  de = WAL_EXCLUSI
23300 56 45 5f 4d 4f 44 45 3b 0a 20 20 20 20 72 63 20  VE_MODE;.    rc 
23310 3d 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  = 1;.  }else{.  
23320 20 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63    rc = pWal->exc
23330 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f  lusiveMode==WAL_
23340 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 3b 0a 20 20 7d  NORMAL_MODE;.  }
23350 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
23360 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ./* .** Return t
23370 72 75 65 20 69 66 20 74 68 65 20 61 72 67 75 6d  rue if the argum
23380 65 6e 74 20 69 73 20 6e 6f 6e 2d 4e 55 4c 4c 20  ent is non-NULL 
23390 61 6e 64 20 74 68 65 20 57 41 4c 20 6d 6f 64 75  and the WAL modu
233a0 6c 65 20 69 73 20 75 73 69 6e 67 0a 2a 2a 20 68  le is using.** h
233b0 65 61 70 2d 6d 65 6d 6f 72 79 20 66 6f 72 20 74  eap-memory for t
233c0 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 4f 74  he wal-index. Ot
233d0 68 65 72 77 69 73 65 2c 20 69 66 20 74 68 65 20  herwise, if the 
233e0 61 72 67 75 6d 65 6e 74 20 69 73 20 4e 55 4c 4c  argument is NULL
233f0 20 6f 72 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6d   or the.** WAL m
23400 6f 64 75 6c 65 20 69 73 20 75 73 69 6e 67 20 73  odule is using s
23410 68 61 72 65 64 2d 6d 65 6d 6f 72 79 2c 20 72 65  hared-memory, re
23420 74 75 72 6e 20 66 61 6c 73 65 2e 20 0a 2a 2f 0a  turn false. .*/.
23430 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 48 65  int sqlite3WalHe
23440 61 70 4d 65 6d 6f 72 79 28 57 61 6c 20 2a 70 57  apMemory(Wal *pW
23450 61 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 70  al){.  return (p
23460 57 61 6c 20 26 26 20 70 57 61 6c 2d 3e 65 78 63  Wal && pWal->exc
23470 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f  lusiveMode==WAL_
23480 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20  HEAPMEMORY_MODE 
23490 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c  );.}..#ifdef SQL
234a0 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e 41 50 53  ITE_ENABLE_SNAPS
234b0 48 4f 54 0a 2f 2a 20 43 72 65 61 74 65 20 61 20  HOT./* Create a 
234c0 73 6e 61 70 73 68 6f 74 20 6f 62 6a 65 63 74 2e  snapshot object.
234d0 20 20 54 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66    The content of
234e0 20 61 20 73 6e 61 70 73 68 6f 74 20 69 73 20 6f   a snapshot is o
234f0 70 61 71 75 65 20 74 6f 0a 2a 2a 20 65 76 65 72  paque to.** ever
23500 79 20 6f 74 68 65 72 20 73 75 62 73 79 73 74 65  y other subsyste
23510 6d 2c 20 73 6f 20 74 68 65 20 57 41 4c 20 6d 6f  m, so the WAL mo
23520 64 75 6c 65 20 63 61 6e 20 70 75 74 20 77 68 61  dule can put wha
23530 74 65 76 65 72 20 69 74 20 6e 65 65 64 73 0a 2a  tever it needs.*
23540 2a 20 69 6e 20 74 68 65 20 6f 62 6a 65 63 74 2e  * in the object.
23550 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
23560 61 6c 53 6e 61 70 73 68 6f 74 47 65 74 28 57 61  alSnapshotGet(Wa
23570 6c 20 2a 70 57 61 6c 2c 20 73 71 6c 69 74 65 33  l *pWal, sqlite3
23580 5f 73 6e 61 70 73 68 6f 74 20 2a 2a 70 70 53 6e  _snapshot **ppSn
23590 61 70 73 68 6f 74 29 7b 0a 20 20 69 6e 74 20 72  apshot){.  int r
235a0 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
235b0 20 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 70 52   WalIndexHdr *pR
235c0 65 74 3b 0a 20 20 73 74 61 74 69 63 20 63 6f 6e  et;.  static con
235d0 73 74 20 75 33 32 20 61 5a 65 72 6f 5b 34 5d 20  st u32 aZero[4] 
235e0 3d 20 7b 20 30 2c 20 30 2c 20 30 2c 20 30 20 7d  = { 0, 0, 0, 0 }
235f0 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  ;..  assert( pWa
23600 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 26  l->readLock>=0 &
23610 26 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  & pWal->writeLoc
23620 6b 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 6d  k==0 );..  if( m
23630 65 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72  emcmp(&pWal->hdr
23640 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 2c  .aFrameCksum[0],
23650 61 5a 65 72 6f 2c 31 36 29 3d 3d 30 20 29 7b 0a  aZero,16)==0 ){.
23660 20 20 20 20 2a 70 70 53 6e 61 70 73 68 6f 74 20      *ppSnapshot 
23670 3d 20 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  = 0;.    return 
23680 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
23690 7d 0a 20 20 70 52 65 74 20 3d 20 28 57 61 6c 49  }.  pRet = (WalI
236a0 6e 64 65 78 48 64 72 2a 29 73 71 6c 69 74 65 33  ndexHdr*)sqlite3
236b0 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 57  _malloc(sizeof(W
236c0 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 20 20  alIndexHdr));.  
236d0 69 66 28 20 70 52 65 74 3d 3d 30 20 29 7b 0a 20  if( pRet==0 ){. 
236e0 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
236f0 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20 7d 65 6c  OMEM_BKPT;.  }el
23700 73 65 7b 0a 20 20 20 20 6d 65 6d 63 70 79 28 70  se{.    memcpy(p
23710 52 65 74 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c  Ret, &pWal->hdr,
23720 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
23730 48 64 72 29 29 3b 0a 20 20 20 20 2a 70 70 53 6e  Hdr));.    *ppSn
23740 61 70 73 68 6f 74 20 3d 20 28 73 71 6c 69 74 65  apshot = (sqlite
23750 33 5f 73 6e 61 70 73 68 6f 74 2a 29 70 52 65 74  3_snapshot*)pRet
23760 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
23770 72 63 3b 0a 7d 0a 0a 2f 2a 20 54 72 79 20 74 6f  rc;.}../* Try to
23780 20 6f 70 65 6e 20 6f 6e 20 70 53 6e 61 70 73 68   open on pSnapsh
23790 6f 74 20 77 68 65 6e 20 74 68 65 20 6e 65 78 74  ot when the next
237a0 20 72 65 61 64 2d 74 72 61 6e 73 61 63 74 69 6f   read-transactio
237b0 6e 20 73 74 61 72 74 73 0a 2a 2f 0a 76 6f 69 64  n starts.*/.void
237c0 20 73 71 6c 69 74 65 33 57 61 6c 53 6e 61 70 73   sqlite3WalSnaps
237d0 68 6f 74 4f 70 65 6e 28 57 61 6c 20 2a 70 57 61  hotOpen(Wal *pWa
237e0 6c 2c 20 73 71 6c 69 74 65 33 5f 73 6e 61 70 73  l, sqlite3_snaps
237f0 68 6f 74 20 2a 70 53 6e 61 70 73 68 6f 74 29 7b  hot *pSnapshot){
23800 0a 20 20 70 57 61 6c 2d 3e 70 53 6e 61 70 73 68  .  pWal->pSnapsh
23810 6f 74 20 3d 20 28 57 61 6c 49 6e 64 65 78 48 64  ot = (WalIndexHd
23820 72 2a 29 70 53 6e 61 70 73 68 6f 74 3b 0a 7d 0a  r*)pSnapshot;.}.
23830 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 61  ./* .** Return a
23840 20 2b 76 65 20 76 61 6c 75 65 20 69 66 20 73 6e   +ve value if sn
23850 61 70 73 68 6f 74 20 70 31 20 69 73 20 6e 65 77  apshot p1 is new
23860 65 72 20 74 68 61 6e 20 70 32 2e 20 41 20 2d 76  er than p2. A -v
23870 65 20 76 61 6c 75 65 20 69 66 0a 2a 2a 20 70 31  e value if.** p1
23880 20 69 73 20 6f 6c 64 65 72 20 74 68 61 6e 20 70   is older than p
23890 32 20 61 6e 64 20 7a 65 72 6f 20 69 66 20 70 31  2 and zero if p1
238a0 20 61 6e 64 20 70 32 20 61 72 65 20 74 68 65 20   and p2 are the 
238b0 73 61 6d 65 20 73 6e 61 70 73 68 6f 74 2e 0a 2a  same snapshot..*
238c0 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 73 6e  /.int sqlite3_sn
238d0 61 70 73 68 6f 74 5f 63 6d 70 28 73 71 6c 69 74  apshot_cmp(sqlit
238e0 65 33 5f 73 6e 61 70 73 68 6f 74 20 2a 70 31 2c  e3_snapshot *p1,
238f0 20 73 71 6c 69 74 65 33 5f 73 6e 61 70 73 68 6f   sqlite3_snapsho
23900 74 20 2a 70 32 29 7b 0a 20 20 57 61 6c 49 6e 64  t *p2){.  WalInd
23910 65 78 48 64 72 20 2a 70 48 64 72 31 20 3d 20 28  exHdr *pHdr1 = (
23920 57 61 6c 49 6e 64 65 78 48 64 72 2a 29 70 31 3b  WalIndexHdr*)p1;
23930 0a 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20 2a  .  WalIndexHdr *
23940 70 48 64 72 32 20 3d 20 28 57 61 6c 49 6e 64 65  pHdr2 = (WalInde
23950 78 48 64 72 2a 29 70 32 3b 0a 0a 20 20 2f 2a 20  xHdr*)p2;..  /* 
23960 61 53 61 6c 74 5b 30 5d 20 69 73 20 61 20 63 6f  aSalt[0] is a co
23970 70 79 20 6f 66 20 74 68 65 20 76 61 6c 75 65 20  py of the value 
23980 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20 77 61  stored in the wa
23990 6c 20 66 69 6c 65 20 68 65 61 64 65 72 2e 20 49  l file header. I
239a0 74 0a 20 20 2a 2a 20 69 73 20 69 6e 63 72 65 6d  t.  ** is increm
239b0 65 6e 74 65 64 20 65 61 63 68 20 74 69 6d 65 20  ented each time 
239c0 74 68 65 20 77 61 6c 20 66 69 6c 65 20 69 73 20  the wal file is 
239d0 72 65 73 74 61 72 74 65 64 2e 20 20 2a 2f 0a 20  restarted.  */. 
239e0 20 69 66 28 20 70 48 64 72 31 2d 3e 61 53 61 6c   if( pHdr1->aSal
239f0 74 5b 30 5d 3c 70 48 64 72 32 2d 3e 61 53 61 6c  t[0]<pHdr2->aSal
23a00 74 5b 30 5d 20 29 20 72 65 74 75 72 6e 20 2d 31  t[0] ) return -1
23a10 3b 0a 20 20 69 66 28 20 70 48 64 72 31 2d 3e 61  ;.  if( pHdr1->a
23a20 53 61 6c 74 5b 30 5d 3e 70 48 64 72 32 2d 3e 61  Salt[0]>pHdr2->a
23a30 53 61 6c 74 5b 30 5d 20 29 20 72 65 74 75 72 6e  Salt[0] ) return
23a40 20 2b 31 3b 0a 20 20 69 66 28 20 70 48 64 72 31   +1;.  if( pHdr1
23a50 2d 3e 6d 78 46 72 61 6d 65 3c 70 48 64 72 32 2d  ->mxFrame<pHdr2-
23a60 3e 6d 78 46 72 61 6d 65 20 29 20 72 65 74 75 72  >mxFrame ) retur
23a70 6e 20 2d 31 3b 0a 20 20 69 66 28 20 70 48 64 72  n -1;.  if( pHdr
23a80 31 2d 3e 6d 78 46 72 61 6d 65 3e 70 48 64 72 32  1->mxFrame>pHdr2
23a90 2d 3e 6d 78 46 72 61 6d 65 20 29 20 72 65 74 75  ->mxFrame ) retu
23aa0 72 6e 20 2b 31 3b 0a 20 20 72 65 74 75 72 6e 20  rn +1;.  return 
23ab0 30 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53  0;.}.#endif /* S
23ac0 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e 41  QLITE_ENABLE_SNA
23ad0 50 53 48 4f 54 20 2a 2f 0a 0a 23 69 66 64 65 66  PSHOT */..#ifdef
23ae0 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 5a   SQLITE_ENABLE_Z
23af0 49 50 56 46 53 0a 2f 2a 0a 2a 2a 20 49 66 20 74  IPVFS./*.** If t
23b00 68 65 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e  he argument is n
23b10 6f 74 20 4e 55 4c 4c 2c 20 69 74 20 70 6f 69 6e  ot NULL, it poin
23b20 74 73 20 74 6f 20 61 20 57 61 6c 20 6f 62 6a 65  ts to a Wal obje
23b30 63 74 20 74 68 61 74 20 68 6f 6c 64 73 20 61 0a  ct that holds a.
23b40 2a 2a 20 72 65 61 64 2d 6c 6f 63 6b 2e 20 54 68  ** read-lock. Th
23b50 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75  is function retu
23b60 72 6e 73 20 74 68 65 20 64 61 74 61 62 61 73 65  rns the database
23b70 20 70 61 67 65 2d 73 69 7a 65 20 69 66 20 69 74   page-size if it
23b80 20 69 73 20 6b 6e 6f 77 6e 2c 0a 2a 2a 20 6f 72   is known,.** or
23b90 20 7a 65 72 6f 20 69 66 20 69 74 20 69 73 20 6e   zero if it is n
23ba0 6f 74 20 28 6f 72 20 69 66 20 70 57 61 6c 20 69  ot (or if pWal i
23bb0 73 20 4e 55 4c 4c 29 2e 0a 2a 2f 0a 69 6e 74 20  s NULL)..*/.int 
23bc0 73 71 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73  sqlite3WalFrames
23bd0 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ize(Wal *pWal){.
23be0 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 3d 3d    assert( pWal==
23bf0 30 20 7c 7c 20 70 57 61 6c 2d 3e 72 65 61 64 4c  0 || pWal->readL
23c00 6f 63 6b 3e 3d 30 20 29 3b 0a 20 20 72 65 74 75  ock>=0 );.  retu
23c10 72 6e 20 28 70 57 61 6c 20 3f 20 70 57 61 6c 2d  rn (pWal ? pWal-
23c20 3e 73 7a 50 61 67 65 20 3a 20 30 29 3b 0a 7d 0a  >szPage : 0);.}.
23c30 23 65 6e 64 69 66 0a 0a 2f 2a 20 52 65 74 75 72  #endif../* Retur
23c40 6e 20 74 68 65 20 73 71 6c 69 74 65 33 5f 66 69  n the sqlite3_fi
23c50 6c 65 20 6f 62 6a 65 63 74 20 66 6f 72 20 74 68  le object for th
23c60 65 20 57 41 4c 20 66 69 6c 65 0a 2a 2f 0a 73 71  e WAL file.*/.sq
23c70 6c 69 74 65 33 5f 66 69 6c 65 20 2a 73 71 6c 69  lite3_file *sqli
23c80 74 65 33 57 61 6c 46 69 6c 65 28 57 61 6c 20 2a  te3WalFile(Wal *
23c90 70 57 61 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20  pWal){.  return 
23ca0 70 57 61 6c 2d 3e 70 57 61 6c 46 64 3b 0a 7d 0a  pWal->pWalFd;.}.
23cb0 0a 23 65 6e 64 69 66 20 2f 2a 20 23 69 66 6e 64  .#endif /* #ifnd
23cc0 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 57  ef SQLITE_OMIT_W
23cd0 41 4c 20 2a 2f 0a                                AL */.