/ Hex Artifact Content
Login

Artifact 94b5fed2df988fb12f5bf17256e2840e56957a85:


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 54 68 65 20 77 61 6c  y..**.** The wal
18c0: 2d 69 6e 64 65 78 20 69 73 20 74 72 61 6e 73 69  -index is transi
18d0: 65 6e 74 2e 20 20 41 66 74 65 72 20 61 20 63 72  ent.  After a cr
18e0: 61 73 68 2c 20 74 68 65 20 77 61 6c 2d 69 6e 64  ash, the wal-ind
18f0: 65 78 20 63 61 6e 20 28 61 6e 64 20 73 68 6f 75  ex can (and shou
1900: 6c 64 0a 2a 2a 20 62 65 29 20 72 65 63 6f 6e 73  ld.** be) recons
1910: 74 72 75 63 74 65 64 20 66 72 6f 6d 20 74 68 65  tructed from the
1920: 20 6f 72 69 67 69 6e 61 6c 20 57 41 4c 20 66 69   original WAL fi
1930: 6c 65 2e 20 20 49 6e 20 66 61 63 74 2c 20 74 68  le.  In fact, th
1940: 65 20 56 46 53 20 69 73 20 72 65 71 75 69 72 65  e VFS is require
1950: 64 0a 2a 2a 20 74 6f 20 65 69 74 68 65 72 20 74  d.** to either t
1960: 72 75 6e 63 61 74 65 20 6f 72 20 7a 65 72 6f 20  runcate or zero 
1970: 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 74 68  the header of th
1980: 65 20 77 61 6c 2d 69 6e 64 65 78 20 77 68 65 6e  e wal-index when
1990: 20 74 68 65 20 6c 61 73 74 0a 2a 2a 20 63 6f 6e   the last.** con
19a0: 6e 65 63 74 69 6f 6e 20 74 6f 20 69 74 20 63 6c  nection to it cl
19b0: 6f 73 65 73 2e 20 20 42 65 63 61 75 73 65 20 74  oses.  Because t
19c0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
19d0: 74 72 61 6e 73 69 65 6e 74 2c 20 69 74 20 63 61  transient, it ca
19e0: 6e 0a 2a 2a 20 75 73 65 20 61 6e 20 61 72 63 68  n.** use an arch
19f0: 69 74 65 63 74 75 72 65 2d 73 70 65 63 69 66 69  itecture-specifi
1a00: 63 20 66 6f 72 6d 61 74 3b 20 69 74 20 64 6f 65  c format; it doe
1a10: 73 20 6e 6f 74 20 68 61 76 65 20 74 6f 20 62 65  s not have to be
1a20: 20 63 72 6f 73 73 2d 70 6c 61 74 66 6f 72 6d 2e   cross-platform.
1a30: 0a 2a 2a 20 48 65 6e 63 65 2c 20 75 6e 6c 69 6b  .** Hence, unlik
1a40: 65 20 74 68 65 20 64 61 74 61 62 61 73 65 20 61  e the database a
1a50: 6e 64 20 57 41 4c 20 66 69 6c 65 20 66 6f 72 6d  nd WAL file form
1a60: 61 74 73 20 77 68 69 63 68 20 73 74 6f 72 65 20  ats which store 
1a70: 61 6c 6c 20 76 61 6c 75 65 73 0a 2a 2a 20 61 73  all values.** as
1a80: 20 62 69 67 20 65 6e 64 69 61 6e 2c 20 74 68 65   big endian, the
1a90: 20 77 61 6c 2d 69 6e 64 65 78 20 63 61 6e 20 73   wal-index can s
1aa0: 74 6f 72 65 20 6d 75 6c 74 69 2d 62 79 74 65 20  tore multi-byte 
1ab0: 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 6e 61  values in the na
1ac0: 74 69 76 65 0a 2a 2a 20 62 79 74 65 20 6f 72 64  tive.** byte ord
1ad0: 65 72 20 6f 66 20 74 68 65 20 68 6f 73 74 20 63  er of the host c
1ae0: 6f 6d 70 75 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54  omputer..**.** T
1af0: 68 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74 68  he purpose of th
1b00: 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 74  e wal-index is t
1b10: 6f 20 61 6e 73 77 65 72 20 74 68 69 73 20 71 75  o answer this qu
1b20: 65 73 74 69 6f 6e 20 71 75 69 63 6b 6c 79 3a 20  estion quickly: 
1b30: 20 47 69 76 65 6e 0a 2a 2a 20 61 20 70 61 67 65   Given.** a page
1b40: 20 6e 75 6d 62 65 72 20 50 20 61 6e 64 20 61 20   number P and a 
1b50: 6d 61 78 69 6d 75 6d 20 66 72 61 6d 65 20 69 6e  maximum frame in
1b60: 64 65 78 20 4d 2c 20 72 65 74 75 72 6e 20 74 68  dex M, return th
1b70: 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 0a  e index of the .
1b80: 2a 2a 20 6c 61 73 74 20 66 72 61 6d 65 20 69 6e  ** last frame in
1b90: 20 74 68 65 20 77 61 6c 20 62 65 66 6f 72 65 20   the wal before 
1ba0: 66 72 61 6d 65 20 4d 20 66 6f 72 20 70 61 67 65  frame M for page
1bb0: 20 50 20 69 6e 20 74 68 65 20 57 41 4c 2c 20 6f   P in the WAL, o
1bc0: 72 20 72 65 74 75 72 6e 0a 2a 2a 20 4e 55 4c 4c  r return.** NULL
1bd0: 20 69 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f   if there are no
1be0: 20 66 72 61 6d 65 73 20 66 6f 72 20 70 61 67 65   frames for page
1bf0: 20 50 20 69 6e 20 74 68 65 20 57 41 4c 20 70 72   P in the WAL pr
1c00: 69 6f 72 20 74 6f 20 4d 2e 0a 2a 2a 0a 2a 2a 20  ior to M..**.** 
1c10: 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f  The wal-index co
1c20: 6e 73 69 73 74 73 20 6f 66 20 61 20 68 65 61 64  nsists of a head
1c30: 65 72 20 72 65 67 69 6f 6e 2c 20 66 6f 6c 6c 6f  er region, follo
1c40: 77 65 64 20 62 79 20 61 6e 20 6f 6e 65 20 6f 72  wed by an one or
1c50: 0a 2a 2a 20 6d 6f 72 65 20 69 6e 64 65 78 20 62  .** more index b
1c60: 6c 6f 63 6b 73 2e 20 20 0a 2a 2a 0a 2a 2a 20 54  locks.  .**.** T
1c70: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
1c80: 64 65 72 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  der contains the
1c90: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
1ca0: 20 66 72 61 6d 65 73 20 77 69 74 68 69 6e 20 74   frames within t
1cb0: 68 65 20 57 41 4c 0a 2a 2a 20 69 6e 20 74 68 65  he WAL.** in the
1cc0: 20 6d 78 46 72 61 6d 65 20 66 69 65 6c 64 2e 0a   mxFrame field..
1cd0: 2a 2a 0a 2a 2a 20 45 61 63 68 20 69 6e 64 65 78  **.** Each index
1ce0: 20 62 6c 6f 63 6b 20 65 78 63 65 70 74 20 66 6f   block except fo
1cf0: 72 20 74 68 65 20 66 69 72 73 74 20 63 6f 6e 74  r the first cont
1d00: 61 69 6e 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  ains information
1d10: 20 6f 6e 20 0a 2a 2a 20 48 41 53 48 54 41 42 4c   on .** HASHTABL
1d20: 45 5f 4e 50 41 47 45 20 66 72 61 6d 65 73 2e 20  E_NPAGE frames. 
1d30: 54 68 65 20 66 69 72 73 74 20 69 6e 64 65 78 20  The first index 
1d40: 62 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20 69  block contains i
1d50: 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f 6e 0a 2a 2a  nformation on.**
1d60: 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45   HASHTABLE_NPAGE
1d70: 5f 4f 4e 45 20 66 72 61 6d 65 73 2e 20 54 68 65  _ONE frames. The
1d80: 20 76 61 6c 75 65 73 20 6f 66 20 48 41 53 48 54   values of HASHT
1d90: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20 61  ABLE_NPAGE_ONE a
1da0: 6e 64 20 0a 2a 2a 20 48 41 53 48 54 41 42 4c 45  nd .** HASHTABLE
1db0: 5f 4e 50 41 47 45 20 61 72 65 20 73 65 6c 65 63  _NPAGE are selec
1dc0: 74 65 64 20 73 6f 20 74 68 61 74 20 74 6f 67 65  ted so that toge
1dd0: 74 68 65 72 20 74 68 65 20 77 61 6c 2d 69 6e 64  ther the wal-ind
1de0: 65 78 20 68 65 61 64 65 72 20 61 6e 64 0a 2a 2a  ex header and.**
1df0: 20 66 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f   first index blo
1e00: 63 6b 20 61 72 65 20 74 68 65 20 73 61 6d 65 20  ck are the same 
1e10: 73 69 7a 65 20 61 73 20 61 6c 6c 20 6f 74 68 65  size as all othe
1e20: 72 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73 20 69  r index blocks i
1e30: 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64  n the.** wal-ind
1e40: 65 78 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 69  ex..**.** Each i
1e50: 6e 64 65 78 20 62 6c 6f 63 6b 20 63 6f 6e 74 61  ndex block conta
1e60: 69 6e 73 20 74 77 6f 20 73 65 63 74 69 6f 6e 73  ins two sections
1e70: 2c 20 61 20 70 61 67 65 2d 6d 61 70 70 69 6e 67  , a page-mapping
1e80: 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74   that contains t
1e90: 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20 70  he.** database p
1ea0: 61 67 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63  age number assoc
1eb0: 69 61 74 65 64 20 77 69 74 68 20 65 61 63 68 20  iated with each 
1ec0: 77 61 6c 20 66 72 61 6d 65 2c 20 61 6e 64 20 61  wal frame, and a
1ed0: 20 68 61 73 68 2d 74 61 62 6c 65 20 0a 2a 2a 20   hash-table .** 
1ee0: 74 68 61 74 20 61 6c 6c 6f 77 73 20 72 65 61 64  that allows read
1ef0: 65 72 73 20 74 6f 20 71 75 65 72 79 20 61 6e 20  ers to query an 
1f00: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 66 6f 72 20  index block for 
1f10: 61 20 73 70 65 63 69 66 69 63 20 70 61 67 65 20  a specific page 
1f20: 6e 75 6d 62 65 72 2e 0a 2a 2a 20 54 68 65 20 70  number..** The p
1f30: 61 67 65 2d 6d 61 70 70 69 6e 67 20 69 73 20 61  age-mapping is a
1f40: 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53 48 54  n array of HASHT
1f50: 41 42 4c 45 5f 4e 50 41 47 45 20 28 6f 72 20 48  ABLE_NPAGE (or H
1f60: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
1f70: 4e 45 0a 2a 2a 20 66 6f 72 20 74 68 65 20 66 69  NE.** for the fi
1f80: 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 29  rst index block)
1f90: 20 33 32 2d 62 69 74 20 70 61 67 65 20 6e 75 6d   32-bit page num
1fa0: 62 65 72 73 2e 20 54 68 65 20 66 69 72 73 74 20  bers. The first 
1fb0: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 0a 2a 2a  entry in the .**
1fc0: 20 66 69 72 73 74 20 69 6e 64 65 78 2d 62 6c 6f   first index-blo
1fd0: 63 6b 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  ck contains the 
1fe0: 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6e 75  database page nu
1ff0: 6d 62 65 72 20 63 6f 72 72 65 73 70 6f 6e 64 69  mber correspondi
2000: 6e 67 20 74 6f 20 74 68 65 0a 2a 2a 20 66 69 72  ng to the.** fir
2010: 73 74 20 66 72 61 6d 65 20 69 6e 20 74 68 65 20  st frame in the 
2020: 57 41 4c 20 66 69 6c 65 2e 20 54 68 65 20 66 69  WAL file. The fi
2030: 72 73 74 20 65 6e 74 72 79 20 69 6e 20 74 68 65  rst entry in the
2040: 20 73 65 63 6f 6e 64 20 69 6e 64 65 78 20 62 6c   second index bl
2050: 6f 63 6b 0a 2a 2a 20 69 6e 20 74 68 65 20 57 41  ock.** in the WA
2060: 4c 20 66 69 6c 65 20 63 6f 72 72 65 73 70 6f 6e  L file correspon
2070: 64 73 20 74 6f 20 74 68 65 20 28 48 41 53 48 54  ds to the (HASHT
2080: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 31  ABLE_NPAGE_ONE+1
2090: 29 74 68 20 66 72 61 6d 65 20 69 6e 0a 2a 2a 20  )th frame in.** 
20a0: 74 68 65 20 6c 6f 67 2c 20 61 6e 64 20 73 6f 20  the log, and so 
20b0: 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c 61  on..**.** The la
20c0: 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 69  st index block i
20d0: 6e 20 61 20 77 61 6c 2d 69 6e 64 65 78 20 75 73  n a wal-index us
20e0: 75 61 6c 6c 79 20 63 6f 6e 74 61 69 6e 73 20 6c  ually contains l
20f0: 65 73 73 20 74 68 61 6e 20 74 68 65 20 66 75 6c  ess than the ful
2100: 6c 0a 2a 2a 20 63 6f 6d 70 6c 65 6d 65 6e 74 20  l.** complement 
2110: 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  of HASHTABLE_NPA
2120: 47 45 20 28 6f 72 20 48 41 53 48 54 41 42 4c 45  GE (or HASHTABLE
2130: 5f 4e 50 41 47 45 5f 4f 4e 45 29 20 70 61 67 65  _NPAGE_ONE) page
2140: 2d 6e 75 6d 62 65 72 73 2c 0a 2a 2a 20 64 65 70  -numbers,.** dep
2150: 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20 63 6f  ending on the co
2160: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 57 41  ntents of the WA
2170: 4c 20 66 69 6c 65 2e 20 54 68 69 73 20 64 6f 65  L file. This doe
2180: 73 20 6e 6f 74 20 63 68 61 6e 67 65 20 74 68 65  s not change the
2190: 0a 2a 2a 20 61 6c 6c 6f 63 61 74 65 64 20 73 69  .** allocated si
21a0: 7a 65 20 6f 66 20 74 68 65 20 70 61 67 65 2d 6d  ze of the page-m
21b0: 61 70 70 69 6e 67 20 61 72 72 61 79 20 2d 20 74  apping array - t
21c0: 68 65 20 70 61 67 65 2d 6d 61 70 70 69 6e 67 20  he page-mapping 
21d0: 61 72 72 61 79 20 6d 65 72 65 6c 79 0a 2a 2a 20  array merely.** 
21e0: 63 6f 6e 74 61 69 6e 73 20 75 6e 75 73 65 64 20  contains unused 
21f0: 65 6e 74 72 69 65 73 2e 0a 2a 2a 0a 2a 2a 20 45  entries..**.** E
2200: 76 65 6e 20 77 69 74 68 6f 75 74 20 75 73 69 6e  ven without usin
2210: 67 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  g the hash table
2220: 2c 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d 65  , the last frame
2230: 20 66 6f 72 20 70 61 67 65 20 50 0a 2a 2a 20 63   for page P.** c
2240: 61 6e 20 62 65 20 66 6f 75 6e 64 20 62 79 20 73  an be found by s
2250: 63 61 6e 6e 69 6e 67 20 74 68 65 20 70 61 67 65  canning the page
2260: 2d 6d 61 70 70 69 6e 67 20 73 65 63 74 69 6f 6e  -mapping section
2270: 73 20 6f 66 20 65 61 63 68 20 69 6e 64 65 78 20  s of each index 
2280: 62 6c 6f 63 6b 0a 2a 2a 20 73 74 61 72 74 69 6e  block.** startin
2290: 67 20 77 69 74 68 20 74 68 65 20 6c 61 73 74 20  g with the last 
22a0: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 61 6e 64 20  index block and 
22b0: 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20 74 68  moving toward th
22c0: 65 20 66 69 72 73 74 2c 20 61 6e 64 0a 2a 2a 20  e first, and.** 
22d0: 77 69 74 68 69 6e 20 65 61 63 68 20 69 6e 64 65  within each inde
22e0: 78 20 62 6c 6f 63 6b 2c 20 73 74 61 72 74 69 6e  x block, startin
22f0: 67 20 61 74 20 74 68 65 20 65 6e 64 20 61 6e 64  g at the end and
2300: 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20 74   moving toward t
2310: 68 65 0a 2a 2a 20 62 65 67 69 6e 6e 69 6e 67 2e  he.** beginning.
2320: 20 20 54 68 65 20 66 69 72 73 74 20 65 6e 74 72    The first entr
2330: 79 20 74 68 61 74 20 65 71 75 61 6c 73 20 50 20  y that equals P 
2340: 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20 74  corresponds to t
2350: 68 65 20 66 72 61 6d 65 0a 2a 2a 20 68 6f 6c 64  he frame.** hold
2360: 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74 20  ing the content 
2370: 66 6f 72 20 74 68 61 74 20 70 61 67 65 2e 0a 2a  for that page..*
2380: 2a 0a 2a 2a 20 54 68 65 20 68 61 73 68 20 74 61  *.** The hash ta
2390: 62 6c 65 20 63 6f 6e 73 69 73 74 73 20 6f 66 20  ble consists of 
23a0: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20  HASHTABLE_NSLOT 
23b0: 31 36 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20  16-bit unsigned 
23c0: 69 6e 74 65 67 65 72 73 2e 0a 2a 2a 20 48 41 53  integers..** HAS
23d0: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 3d 20 32  HTABLE_NSLOT = 2
23e0: 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  *HASHTABLE_NPAGE
23f0: 2c 20 61 6e 64 20 74 68 65 72 65 20 69 73 20 6f  , and there is o
2400: 6e 65 20 65 6e 74 72 79 20 69 6e 20 74 68 65 0a  ne entry in the.
2410: 2a 2a 20 68 61 73 68 20 74 61 62 6c 65 20 66 6f  ** hash table fo
2420: 72 20 65 61 63 68 20 70 61 67 65 20 6e 75 6d 62  r each page numb
2430: 65 72 20 69 6e 20 74 68 65 20 6d 61 70 70 69 6e  er in the mappin
2440: 67 20 73 65 63 74 69 6f 6e 2c 20 73 6f 20 74 68  g section, so th
2450: 65 20 68 61 73 68 20 0a 2a 2a 20 74 61 62 6c 65  e hash .** table
2460: 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20 74   is never more t
2470: 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2e 20 20  han half full.  
2480: 54 68 65 20 65 78 70 65 63 74 65 64 20 6e 75 6d  The expected num
2490: 62 65 72 20 6f 66 20 63 6f 6c 6c 69 73 69 6f 6e  ber of collision
24a0: 73 20 0a 2a 2a 20 70 72 69 6f 72 20 74 6f 20 66  s .** prior to f
24b0: 69 6e 64 69 6e 67 20 61 20 6d 61 74 63 68 20 69  inding a match i
24c0: 73 20 31 2e 20 20 45 61 63 68 20 65 6e 74 72 79  s 1.  Each entry
24d0: 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61 62   of the hash tab
24e0: 6c 65 20 69 73 20 61 6e 0a 2a 2a 20 31 2d 62 61  le is an.** 1-ba
24f0: 73 65 64 20 69 6e 64 65 78 20 6f 66 20 61 6e 20  sed index of an 
2500: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61 70  entry in the map
2510: 70 69 6e 67 20 73 65 63 74 69 6f 6e 20 6f 66 20  ping section of 
2520: 74 68 65 20 73 61 6d 65 0a 2a 2a 20 69 6e 64 65  the same.** inde
2530: 78 20 62 6c 6f 63 6b 2e 20 20 20 4c 65 74 20 4b  x block.   Let K
2540: 20 62 65 20 74 68 65 20 31 2d 62 61 73 65 64 20   be the 1-based 
2550: 69 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 72  index of the lar
2560: 67 65 73 74 20 65 6e 74 72 79 20 69 6e 0a 2a 2a  gest entry in.**
2570: 20 74 68 65 20 6d 61 70 70 69 6e 67 20 73 65 63   the mapping sec
2580: 74 69 6f 6e 2e 20 20 28 46 6f 72 20 69 6e 64 65  tion.  (For inde
2590: 78 20 62 6c 6f 63 6b 73 20 6f 74 68 65 72 20 74  x blocks other t
25a0: 68 61 6e 20 74 68 65 20 6c 61 73 74 2c 20 4b 20  han the last, K 
25b0: 77 69 6c 6c 0a 2a 2a 20 61 6c 77 61 79 73 20 62  will.** always b
25c0: 65 20 65 78 61 63 74 6c 79 20 48 41 53 48 54 41  e exactly HASHTA
25d0: 42 4c 45 5f 4e 50 41 47 45 20 28 34 30 39 36 29  BLE_NPAGE (4096)
25e0: 20 61 6e 64 20 66 6f 72 20 74 68 65 20 6c 61 73   and for the las
25f0: 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 0a 2a 2a  t index block.**
2600: 20 4b 20 77 69 6c 6c 20 62 65 20 28 6d 78 46 72   K will be (mxFr
2610: 61 6d 65 25 48 41 53 48 54 41 42 4c 45 5f 4e 50  ame%HASHTABLE_NP
2620: 41 47 45 29 2e 29 20 20 55 6e 75 73 65 64 20 73  AGE).)  Unused s
2630: 6c 6f 74 73 20 6f 66 20 74 68 65 20 68 61 73 68  lots of the hash
2640: 20 74 61 62 6c 65 0a 2a 2a 20 63 6f 6e 74 61 69   table.** contai
2650: 6e 20 61 20 76 61 6c 75 65 20 6f 66 20 30 2e 0a  n a value of 0..
2660: 2a 2a 0a 2a 2a 20 54 6f 20 6c 6f 6f 6b 20 66 6f  **.** To look fo
2670: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
2680: 68 61 73 68 20 74 61 62 6c 65 2c 20 66 69 72 73  hash table, firs
2690: 74 20 63 6f 6d 70 75 74 65 20 61 20 68 61 73 68  t compute a hash
26a0: 20 69 4b 65 79 20 6f 6e 0a 2a 2a 20 50 20 61 73   iKey on.** P as
26b0: 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20   follows:.**.** 
26c0: 20 20 20 20 20 69 4b 65 79 20 3d 20 28 50 20 2a       iKey = (P *
26d0: 20 33 38 33 29 20 25 20 48 41 53 48 54 41 42 4c   383) % HASHTABL
26e0: 45 5f 4e 53 4c 4f 54 0a 2a 2a 0a 2a 2a 20 54 68  E_NSLOT.**.** Th
26f0: 65 6e 20 73 74 61 72 74 20 73 63 61 6e 6e 69 6e  en start scannin
2700: 67 20 65 6e 74 72 69 65 73 20 6f 66 20 74 68 65  g entries of the
2710: 20 68 61 73 68 20 74 61 62 6c 65 2c 20 73 74 61   hash table, sta
2720: 72 74 69 6e 67 20 77 69 74 68 20 69 4b 65 79 0a  rting with iKey.
2730: 2a 2a 20 28 77 72 61 70 70 69 6e 67 20 61 72 6f  ** (wrapping aro
2740: 75 6e 64 20 74 6f 20 74 68 65 20 62 65 67 69 6e  und to the begin
2750: 6e 69 6e 67 20 77 68 65 6e 20 74 68 65 20 65 6e  ning when the en
2760: 64 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61  d of the hash ta
2770: 62 6c 65 20 69 73 0a 2a 2a 20 72 65 61 63 68 65  ble is.** reache
2780: 64 29 20 75 6e 74 69 6c 20 61 6e 20 75 6e 75 73  d) until an unus
2790: 65 64 20 68 61 73 68 20 73 6c 6f 74 20 69 73 20  ed hash slot is 
27a0: 66 6f 75 6e 64 2e 20 4c 65 74 20 74 68 65 20 66  found. Let the f
27b0: 69 72 73 74 20 75 6e 75 73 65 64 20 73 6c 6f 74  irst unused slot
27c0: 0a 2a 2a 20 62 65 20 61 74 20 69 6e 64 65 78 20  .** be at index 
27d0: 69 55 6e 75 73 65 64 2e 20 20 28 69 55 6e 75 73  iUnused.  (iUnus
27e0: 65 64 20 6d 69 67 68 74 20 62 65 20 6c 65 73 73  ed might be less
27f0: 20 74 68 61 6e 20 69 4b 65 79 20 69 66 20 74 68   than iKey if th
2800: 65 72 65 20 77 61 73 0a 2a 2a 20 77 72 61 70 2d  ere was.** wrap-
2810: 61 72 6f 75 6e 64 2e 29 20 42 65 63 61 75 73 65  around.) Because
2820: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
2830: 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20 74 68  is never more th
2840: 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2c 0a 2a 2a  an half full,.**
2850: 20 74 68 65 20 73 65 61 72 63 68 20 69 73 20 67   the search is g
2860: 75 61 72 61 6e 74 65 65 64 20 74 6f 20 65 76 65  uaranteed to eve
2870: 6e 74 75 61 6c 6c 79 20 68 69 74 20 61 6e 20 75  ntually hit an u
2880: 6e 75 73 65 64 20 65 6e 74 72 79 2e 20 20 4c 65  nused entry.  Le
2890: 74 20 0a 2a 2a 20 69 4d 61 78 20 62 65 20 74 68  t .** iMax be th
28a0: 65 20 76 61 6c 75 65 20 62 65 74 77 65 65 6e 20  e value between 
28b0: 69 4b 65 79 20 61 6e 64 20 69 55 6e 75 73 65 64  iKey and iUnused
28c0: 2c 20 63 6c 6f 73 65 73 74 20 74 6f 20 69 55 6e  , closest to iUn
28d0: 75 73 65 64 2c 0a 2a 2a 20 77 68 65 72 65 20 61  used,.** where a
28e0: 48 61 73 68 5b 69 4d 61 78 5d 3d 3d 50 2e 20 20  Hash[iMax]==P.  
28f0: 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 69  If there is no i
2900: 4d 61 78 20 65 6e 74 72 79 20 28 69 66 20 74 68  Max entry (if th
2910: 65 72 65 20 65 78 69 73 74 73 0a 2a 2a 20 6e 6f  ere exists.** no
2920: 20 68 61 73 68 20 73 6c 6f 74 20 73 75 63 68 20   hash slot such 
2930: 74 68 61 74 20 61 48 61 73 68 5b 69 5d 3d 3d 70  that aHash[i]==p
2940: 29 20 74 68 65 6e 20 70 61 67 65 20 50 20 69 73  ) then page P is
2950: 20 6e 6f 74 20 69 6e 20 74 68 65 0a 2a 2a 20 63   not in the.** c
2960: 75 72 72 65 6e 74 20 69 6e 64 65 78 20 62 6c 6f  urrent index blo
2970: 63 6b 2e 20 20 4f 74 68 65 72 77 69 73 65 20 74  ck.  Otherwise t
2980: 68 65 20 69 4d 61 78 2d 74 68 20 6d 61 70 70 69  he iMax-th mappi
2990: 6e 67 20 65 6e 74 72 79 20 6f 66 20 74 68 65 0a  ng entry of the.
29a0: 2a 2a 20 63 75 72 72 65 6e 74 20 69 6e 64 65 78  ** current index
29b0: 20 62 6c 6f 63 6b 20 63 6f 72 72 65 73 70 6f 6e   block correspon
29c0: 64 73 20 74 6f 20 74 68 65 20 6c 61 73 74 20 65  ds to the last e
29d0: 6e 74 72 79 20 74 68 61 74 20 72 65 66 65 72 65  ntry that refere
29e0: 6e 63 65 73 20 0a 2a 2a 20 70 61 67 65 20 50 2e  nces .** page P.
29f0: 0a 2a 2a 0a 2a 2a 20 41 20 68 61 73 68 20 73 65  .**.** A hash se
2a00: 61 72 63 68 20 62 65 67 69 6e 73 20 77 69 74 68  arch begins with
2a10: 20 74 68 65 20 6c 61 73 74 20 69 6e 64 65 78 20   the last index 
2a20: 62 6c 6f 63 6b 20 61 6e 64 20 6d 6f 76 65 73 20  block and moves 
2a30: 74 6f 77 61 72 64 20 74 68 65 0a 2a 2a 20 66 69  toward the.** fi
2a40: 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 2c  rst index block,
2a50: 20 6c 6f 6f 6b 69 6e 67 20 66 6f 72 20 65 6e 74   looking for ent
2a60: 72 69 65 73 20 63 6f 72 72 65 73 70 6f 6e 64 69  ries correspondi
2a70: 6e 67 20 74 6f 20 70 61 67 65 20 50 2e 20 20 4f  ng to page P.  O
2a80: 6e 0a 2a 2a 20 61 76 65 72 61 67 65 2c 20 6f 6e  n.** average, on
2a90: 6c 79 20 74 77 6f 20 6f 72 20 74 68 72 65 65 20  ly two or three 
2aa0: 73 6c 6f 74 73 20 69 6e 20 65 61 63 68 20 69 6e  slots in each in
2ab0: 64 65 78 20 62 6c 6f 63 6b 20 6e 65 65 64 20 74  dex block need t
2ac0: 6f 20 62 65 0a 2a 2a 20 65 78 61 6d 69 6e 65 64  o be.** examined
2ad0: 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 65 69 74   in order to eit
2ae0: 68 65 72 20 66 69 6e 64 20 74 68 65 20 6c 61 73  her find the las
2af0: 74 20 65 6e 74 72 79 20 66 6f 72 20 70 61 67 65  t entry for page
2b00: 20 50 2c 20 6f 72 20 74 6f 0a 2a 2a 20 65 73 74   P, or to.** est
2b10: 61 62 6c 69 73 68 20 74 68 61 74 20 6e 6f 20 73  ablish that no s
2b20: 75 63 68 20 65 6e 74 72 79 20 65 78 69 73 74 73  uch entry exists
2b30: 20 69 6e 20 74 68 65 20 62 6c 6f 63 6b 2e 20 20   in the block.  
2b40: 45 61 63 68 20 69 6e 64 65 78 20 62 6c 6f 63 6b  Each index block
2b50: 0a 2a 2a 20 68 6f 6c 64 73 20 6f 76 65 72 20 34  .** holds over 4
2b60: 30 30 30 20 65 6e 74 72 69 65 73 2e 20 20 53 6f  000 entries.  So
2b70: 20 74 77 6f 20 6f 72 20 74 68 72 65 65 20 69 6e   two or three in
2b80: 64 65 78 20 62 6c 6f 63 6b 73 20 61 72 65 20 73  dex blocks are s
2b90: 75 66 66 69 63 69 65 6e 74 0a 2a 2a 20 74 6f 20  ufficient.** to 
2ba0: 63 6f 76 65 72 20 61 20 74 79 70 69 63 61 6c 20  cover a typical 
2bb0: 31 30 20 6d 65 67 61 62 79 74 65 20 57 41 4c 20  10 megabyte WAL 
2bc0: 66 69 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20 31  file, assuming 1
2bd0: 4b 20 70 61 67 65 73 2e 20 20 38 20 6f 72 20 31  K pages.  8 or 1
2be0: 30 0a 2a 2a 20 63 6f 6d 70 61 72 69 73 6f 6e 73  0.** comparisons
2bf0: 20 28 6f 6e 20 61 76 65 72 61 67 65 29 20 73 75   (on average) su
2c00: 66 66 69 63 65 20 74 6f 20 65 69 74 68 65 72 20  ffice to either 
2c10: 6c 6f 63 61 74 65 20 61 20 66 72 61 6d 65 20 69  locate a frame i
2c20: 6e 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6f 72 20  n the.** WAL or 
2c30: 74 6f 20 65 73 74 61 62 6c 69 73 68 20 74 68 61  to establish tha
2c40: 74 20 74 68 65 20 66 72 61 6d 65 20 64 6f 65 73  t the frame does
2c50: 20 6e 6f 74 20 65 78 69 73 74 20 69 6e 20 74 68   not exist in th
2c60: 65 20 57 41 4c 2e 20 20 54 68 69 73 0a 2a 2a 20  e WAL.  This.** 
2c70: 69 73 20 6d 75 63 68 20 66 61 73 74 65 72 20 74  is much faster t
2c80: 68 61 6e 20 73 63 61 6e 6e 69 6e 67 20 74 68 65  han scanning the
2c90: 20 65 6e 74 69 72 65 20 31 30 4d 42 20 57 41 4c   entire 10MB WAL
2ca0: 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61  ..**.** Note tha
2cb0: 74 20 65 6e 74 72 69 65 73 20 61 72 65 20 61 64  t entries are ad
2cc0: 64 65 64 20 69 6e 20 6f 72 64 65 72 20 6f 66 20  ded in order of 
2cd0: 69 6e 63 72 65 61 73 69 6e 67 20 4b 2e 20 20 48  increasing K.  H
2ce0: 65 6e 63 65 2c 20 6f 6e 65 0a 2a 2a 20 72 65 61  ence, one.** rea
2cf0: 64 65 72 20 6d 69 67 68 74 20 62 65 20 75 73 69  der might be usi
2d00: 6e 67 20 73 6f 6d 65 20 76 61 6c 75 65 20 4b 30  ng some value K0
2d10: 20 61 6e 64 20 61 20 73 65 63 6f 6e 64 20 72 65   and a second re
2d20: 61 64 65 72 20 74 68 61 74 20 73 74 61 72 74 65  ader that starte
2d30: 64 0a 2a 2a 20 61 74 20 61 20 6c 61 74 65 72 20  d.** at a later 
2d40: 74 69 6d 65 20 28 61 66 74 65 72 20 61 64 64 69  time (after addi
2d50: 74 69 6f 6e 61 6c 20 74 72 61 6e 73 61 63 74 69  tional transacti
2d60: 6f 6e 73 20 77 65 72 65 20 61 64 64 65 64 20 74  ons were added t
2d70: 6f 20 74 68 65 20 57 41 4c 0a 2a 2a 20 61 6e 64  o the WAL.** and
2d80: 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   to the wal-inde
2d90: 78 29 20 6d 69 67 68 74 20 62 65 20 75 73 69 6e  x) might be usin
2da0: 67 20 61 20 64 69 66 66 65 72 65 6e 74 20 76 61  g a different va
2db0: 6c 75 65 20 4b 31 2c 20 77 68 65 72 65 20 4b 31  lue K1, where K1
2dc0: 3e 4b 30 2e 0a 2a 2a 20 42 6f 74 68 20 72 65 61  >K0..** Both rea
2dd0: 64 65 72 73 20 63 61 6e 20 75 73 65 20 74 68 65  ders can use the
2de0: 20 73 61 6d 65 20 68 61 73 68 20 74 61 62 6c 65   same hash table
2df0: 20 61 6e 64 20 6d 61 70 70 69 6e 67 20 73 65 63   and mapping sec
2e00: 74 69 6f 6e 20 74 6f 20 67 65 74 0a 2a 2a 20 74  tion to get.** t
2e10: 68 65 20 63 6f 72 72 65 63 74 20 72 65 73 75 6c  he correct resul
2e20: 74 2e 20 20 54 68 65 72 65 20 6d 61 79 20 62 65  t.  There may be
2e30: 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20   entries in the 
2e40: 68 61 73 68 20 74 61 62 6c 65 20 77 69 74 68 0a  hash table with.
2e50: 2a 2a 20 4b 3e 4b 30 20 62 75 74 20 74 6f 20 74  ** K>K0 but to t
2e60: 68 65 20 66 69 72 73 74 20 72 65 61 64 65 72 2c  he first reader,
2e70: 20 74 68 6f 73 65 20 65 6e 74 72 69 65 73 20 77   those entries w
2e80: 69 6c 6c 20 61 70 70 65 61 72 20 74 6f 20 62 65  ill appear to be
2e90: 20 75 6e 75 73 65 64 0a 2a 2a 20 73 6c 6f 74 73   unused.** slots
2ea0: 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62   in the hash tab
2eb0: 6c 65 20 61 6e 64 20 73 6f 20 74 68 65 20 66 69  le and so the fi
2ec0: 72 73 74 20 72 65 61 64 65 72 20 77 69 6c 6c 20  rst reader will 
2ed0: 67 65 74 20 61 6e 20 61 6e 73 77 65 72 20 61 73  get an answer as
2ee0: 0a 2a 2a 20 69 66 20 6e 6f 20 76 61 6c 75 65 73  .** if no values
2ef0: 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 4b 30   greater than K0
2f00: 20 68 61 64 20 65 76 65 72 20 62 65 65 6e 20 69   had ever been i
2f10: 6e 73 65 72 74 65 64 20 69 6e 74 6f 20 74 68 65  nserted into the
2f20: 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20 69   hash table.** i
2f30: 6e 20 74 68 65 20 66 69 72 73 74 20 70 6c 61 63  n the first plac
2f40: 65 20 2d 20 77 68 69 63 68 20 69 73 20 77 68 61  e - which is wha
2f50: 74 20 72 65 61 64 65 72 20 6f 6e 65 20 77 61 6e  t reader one wan
2f60: 74 73 2e 20 20 4d 65 61 6e 77 68 69 6c 65 2c 20  ts.  Meanwhile, 
2f70: 74 68 65 0a 2a 2a 20 73 65 63 6f 6e 64 20 72 65  the.** second re
2f80: 61 64 65 72 20 75 73 69 6e 67 20 4b 31 20 77 69  ader using K1 wi
2f90: 6c 6c 20 73 65 65 20 61 64 64 69 74 69 6f 6e 61  ll see additiona
2fa0: 6c 20 76 61 6c 75 65 73 20 74 68 61 74 20 77 65  l values that we
2fb0: 72 65 20 69 6e 73 65 72 74 65 64 0a 2a 2a 20 6c  re inserted.** l
2fc0: 61 74 65 72 2c 20 77 68 69 63 68 20 69 73 20 65  ater, which is e
2fd0: 78 61 63 74 6c 79 20 77 68 61 74 20 72 65 61 64  xactly what read
2fe0: 65 72 20 74 77 6f 20 77 61 6e 74 73 2e 20 20 0a  er two wants.  .
2ff0: 2a 2a 0a 2a 2a 20 57 68 65 6e 20 61 20 72 6f 6c  **.** When a rol
3000: 6c 62 61 63 6b 20 6f 63 63 75 72 73 2c 20 74 68  lback occurs, th
3010: 65 20 76 61 6c 75 65 20 6f 66 20 4b 20 69 73 20  e value of K is 
3020: 64 65 63 72 65 61 73 65 64 2e 20 48 61 73 68 20  decreased. Hash 
3030: 74 61 62 6c 65 20 65 6e 74 72 69 65 73 0a 2a 2a  table entries.**
3040: 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64   that correspond
3050: 20 74 6f 20 66 72 61 6d 65 73 20 67 72 65 61 74   to frames great
3060: 65 72 20 74 68 61 6e 20 74 68 65 20 6e 65 77 20  er than the new 
3070: 4b 20 76 61 6c 75 65 20 61 72 65 20 72 65 6d 6f  K value are remo
3080: 76 65 64 0a 2a 2a 20 66 72 6f 6d 20 74 68 65 20  ved.** from the 
3090: 68 61 73 68 20 74 61 62 6c 65 20 61 74 20 74 68  hash table at th
30a0: 69 73 20 70 6f 69 6e 74 2e 0a 2a 2f 0a 23 69 66  is point..*/.#if
30b0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
30c0: 5f 57 41 4c 0a 0a 23 69 6e 63 6c 75 64 65 20 22  _WAL..#include "
30d0: 77 61 6c 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 54 72  wal.h"../*.** Tr
30e0: 61 63 65 20 6f 75 74 70 75 74 20 6d 61 63 72 6f  ace output macro
30f0: 73 0a 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64  s.*/.#if defined
3100: 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26 26  (SQLITE_TEST) &&
3110: 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
3120: 44 45 42 55 47 29 0a 69 6e 74 20 73 71 6c 69 74  DEBUG).int sqlit
3130: 65 33 57 61 6c 54 72 61 63 65 20 3d 20 30 3b 0a  e3WalTrace = 0;.
3140: 23 20 64 65 66 69 6e 65 20 57 41 4c 54 52 41 43  # define WALTRAC
3150: 45 28 58 29 20 20 69 66 28 73 71 6c 69 74 65 33  E(X)  if(sqlite3
3160: 57 61 6c 54 72 61 63 65 29 20 73 71 6c 69 74 65  WalTrace) sqlite
3170: 33 44 65 62 75 67 50 72 69 6e 74 66 20 58 0a 23  3DebugPrintf X.#
3180: 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 57 41  else.# define WA
3190: 4c 54 52 41 43 45 28 58 29 0a 23 65 6e 64 69 66  LTRACE(X).#endif
31a0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 78 69  ../*.** The maxi
31b0: 6d 75 6d 20 28 61 6e 64 20 6f 6e 6c 79 29 20 76  mum (and only) v
31c0: 65 72 73 69 6f 6e 73 20 6f 66 20 74 68 65 20 77  ersions of the w
31d0: 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78  al and wal-index
31e0: 20 66 6f 72 6d 61 74 73 0a 2a 2a 20 74 68 61 74   formats.** that
31f0: 20 6d 61 79 20 62 65 20 69 6e 74 65 72 70 72 65   may be interpre
3200: 74 65 64 20 62 79 20 74 68 69 73 20 76 65 72 73  ted by this vers
3210: 69 6f 6e 20 6f 66 20 53 51 4c 69 74 65 2e 0a 2a  ion of SQLite..*
3220: 2a 0a 2a 2a 20 49 66 20 61 20 63 6c 69 65 6e 74  *.** If a client
3230: 20 62 65 67 69 6e 73 20 72 65 63 6f 76 65 72 69   begins recoveri
3240: 6e 67 20 61 20 57 41 4c 20 66 69 6c 65 20 61 6e  ng a WAL file an
3250: 64 20 66 69 6e 64 73 20 74 68 61 74 20 28 61 29  d finds that (a)
3260: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 0a 2a 2a   the checksum.**
3270: 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 77   values in the w
3280: 61 6c 2d 68 65 61 64 65 72 20 61 72 65 20 63 6f  al-header are co
3290: 72 72 65 63 74 20 61 6e 64 20 28 62 29 20 74 68  rrect and (b) th
32a0: 65 20 76 65 72 73 69 6f 6e 20 66 69 65 6c 64 20  e version field 
32b0: 69 73 20 6e 6f 74 0a 2a 2a 20 57 41 4c 5f 4d 41  is not.** WAL_MA
32c0: 58 5f 56 45 52 53 49 4f 4e 2c 20 72 65 63 6f 76  X_VERSION, recov
32d0: 65 72 79 20 66 61 69 6c 73 20 61 6e 64 20 53 51  ery fails and SQ
32e0: 4c 69 74 65 20 72 65 74 75 72 6e 73 20 53 51 4c  Lite returns SQL
32f0: 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2e 0a 2a 2a  ITE_CANTOPEN..**
3300: 0a 2a 2a 20 53 69 6d 69 6c 61 72 6c 79 2c 20 69  .** Similarly, i
3310: 66 20 61 20 63 6c 69 65 6e 74 20 73 75 63 63 65  f a client succe
3320: 73 73 66 75 6c 6c 79 20 72 65 61 64 73 20 61 20  ssfully reads a 
3330: 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
3340: 20 28 69 2e 65 2e 20 74 68 65 20 0a 2a 2a 20 63   (i.e. the .** c
3350: 68 65 63 6b 73 75 6d 20 74 65 73 74 20 69 73 20  hecksum test is 
3360: 73 75 63 63 65 73 73 66 75 6c 29 20 61 6e 64 20  successful) and 
3370: 66 69 6e 64 73 20 74 68 61 74 20 74 68 65 20 76  finds that the v
3380: 65 72 73 69 6f 6e 20 66 69 65 6c 64 20 69 73 20  ersion field is 
3390: 6e 6f 74 0a 2a 2a 20 57 41 4c 49 4e 44 45 58 5f  not.** WALINDEX_
33a0: 4d 41 58 5f 56 45 52 53 49 4f 4e 2c 20 74 68 65  MAX_VERSION, the
33b0: 6e 20 6e 6f 20 72 65 61 64 2d 74 72 61 6e 73 61  n no read-transa
33c0: 63 74 69 6f 6e 20 69 73 20 6f 70 65 6e 65 64 20  ction is opened 
33d0: 61 6e 64 20 53 51 4c 69 74 65 0a 2a 2a 20 72 65  and SQLite.** re
33e0: 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 43 41 4e  turns SQLITE_CAN
33f0: 54 4f 50 45 4e 2e 0a 2a 2f 0a 23 64 65 66 69 6e  TOPEN..*/.#defin
3400: 65 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49 4f  e WAL_MAX_VERSIO
3410: 4e 20 20 20 20 20 20 33 30 30 37 30 30 30 0a 23  N      3007000.#
3420: 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58 5f  define WALINDEX_
3430: 4d 41 58 5f 56 45 52 53 49 4f 4e 20 33 30 30 37  MAX_VERSION 3007
3440: 30 30 30 0a 0a 2f 2a 0a 2a 2a 20 49 6e 64 69 63  000../*.** Indic
3450: 65 73 20 6f 66 20 76 61 72 69 6f 75 73 20 6c 6f  es of various lo
3460: 63 6b 69 6e 67 20 62 79 74 65 73 2e 20 20 20 57  cking bytes.   W
3470: 41 4c 5f 4e 52 45 41 44 45 52 20 69 73 20 74 68  AL_NREADER is th
3480: 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 61  e number.** of a
3490: 76 61 69 6c 61 62 6c 65 20 72 65 61 64 65 72 20  vailable reader 
34a0: 6c 6f 63 6b 73 20 61 6e 64 20 73 68 6f 75 6c 64  locks and should
34b0: 20 62 65 20 61 74 20 6c 65 61 73 74 20 33 2e 0a   be at least 3..
34c0: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 57  */.#define WAL_W
34d0: 52 49 54 45 5f 4c 4f 43 4b 20 20 20 20 20 20 20  RITE_LOCK       
34e0: 20 20 30 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f    0.#define WAL_
34f0: 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 20 20  ALL_BUT_WRITE   
3500: 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41 4c     1.#define WAL
3510: 5f 43 4b 50 54 5f 4c 4f 43 4b 20 20 20 20 20 20  _CKPT_LOCK      
3520: 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41      1.#define WA
3530: 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20 20  L_RECOVER_LOCK  
3540: 20 20 20 20 20 32 0a 23 64 65 66 69 6e 65 20 57       2.#define W
3550: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 49 29 20  AL_READ_LOCK(I) 
3560: 20 20 20 20 20 20 28 33 2b 28 49 29 29 0a 23 64        (3+(I)).#d
3570: 65 66 69 6e 65 20 57 41 4c 5f 4e 52 45 41 44 45  efine WAL_NREADE
3580: 52 20 20 20 20 20 20 20 20 20 20 20 20 28 53 51  R            (SQ
3590: 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 2d 33  LITE_SHM_NLOCK-3
35a0: 29 0a 0a 0a 2f 2a 20 4f 62 6a 65 63 74 20 64 65  ).../* Object de
35b0: 63 6c 61 72 61 74 69 6f 6e 73 20 2a 2f 0a 74 79  clarations */.ty
35c0: 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61 6c  pedef struct Wal
35d0: 49 6e 64 65 78 48 64 72 20 57 61 6c 49 6e 64 65  IndexHdr WalInde
35e0: 78 48 64 72 3b 0a 74 79 70 65 64 65 66 20 73 74  xHdr;.typedef st
35f0: 72 75 63 74 20 57 61 6c 49 74 65 72 61 74 6f 72  ruct WalIterator
3600: 20 57 61 6c 49 74 65 72 61 74 6f 72 3b 0a 74 79   WalIterator;.ty
3610: 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61 6c  pedef struct Wal
3620: 43 6b 70 74 49 6e 66 6f 20 57 61 6c 43 6b 70 74  CkptInfo WalCkpt
3630: 49 6e 66 6f 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68  Info;.../*.** Th
3640: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65  e following obje
3650: 63 74 20 68 6f 6c 64 73 20 61 20 63 6f 70 79 20  ct holds a copy 
3660: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
3670: 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74 2e   header content.
3680: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63 74 75 61  .**.** The actua
3690: 6c 20 68 65 61 64 65 72 20 69 6e 20 74 68 65 20  l header in the 
36a0: 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69 73  wal-index consis
36b0: 74 73 20 6f 66 20 74 77 6f 20 63 6f 70 69 65 73  ts of two copies
36c0: 20 6f 66 20 74 68 69 73 0a 2a 2a 20 6f 62 6a 65   of this.** obje
36d0: 63 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 7a  ct..**.** The sz
36e0: 50 61 67 65 20 76 61 6c 75 65 20 63 61 6e 20 62  Page value can b
36f0: 65 20 61 6e 79 20 70 6f 77 65 72 20 6f 66 20 32  e any power of 2
3700: 20 62 65 74 77 65 65 6e 20 35 31 32 20 61 6e 64   between 512 and
3710: 20 33 32 37 36 38 2c 20 69 6e 63 6c 75 73 69 76   32768, inclusiv
3720: 65 2e 0a 2a 2a 20 4f 72 20 69 74 20 63 61 6e 20  e..** Or it can 
3730: 62 65 20 31 20 74 6f 20 72 65 70 72 65 73 65 6e  be 1 to represen
3740: 74 20 61 20 36 35 35 33 36 2d 62 79 74 65 20 70  t a 65536-byte p
3750: 61 67 65 2e 20 20 54 68 65 20 6c 61 74 74 65 72  age.  The latter
3760: 20 63 61 73 65 20 77 61 73 0a 2a 2a 20 61 64 64   case was.** add
3770: 65 64 20 69 6e 20 33 2e 37 2e 31 20 77 68 65 6e  ed in 3.7.1 when
3780: 20 73 75 70 70 6f 72 74 20 66 6f 72 20 36 34 4b   support for 64K
3790: 20 70 61 67 65 73 20 77 61 73 20 61 64 64 65 64   pages was added
37a0: 2e 20 20 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61  .  .*/.struct Wa
37b0: 6c 49 6e 64 65 78 48 64 72 20 7b 0a 20 20 75 33  lIndexHdr {.  u3
37c0: 32 20 69 56 65 72 73 69 6f 6e 3b 20 20 20 20 20  2 iVersion;     
37d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
37e0: 20 57 61 6c 2d 69 6e 64 65 78 20 76 65 72 73 69   Wal-index versi
37f0: 6f 6e 20 2a 2f 0a 20 20 75 33 32 20 75 6e 75 73  on */.  u32 unus
3800: 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ed;             
3810: 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 75 73 65          /* Unuse
3820: 64 20 28 70 61 64 64 69 6e 67 29 20 66 69 65 6c  d (padding) fiel
3830: 64 20 2a 2f 0a 20 20 75 33 32 20 69 43 68 61 6e  d */.  u32 iChan
3840: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
3850: 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65         /* Counte
3860: 72 20 69 6e 63 72 65 6d 65 6e 74 65 64 20 65 61  r incremented ea
3870: 63 68 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a  ch transaction *
3880: 2f 0a 20 20 75 38 20 69 73 49 6e 69 74 3b 20 20  /.  u8 isInit;  
3890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38a0: 20 20 20 20 2f 2a 20 31 20 77 68 65 6e 20 69 6e      /* 1 when in
38b0: 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 75  itialized */.  u
38c0: 38 20 62 69 67 45 6e 64 43 6b 73 75 6d 3b 20 20  8 bigEndCksum;  
38d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
38e0: 2a 20 54 72 75 65 20 69 66 20 63 68 65 63 6b 73  * True if checks
38f0: 75 6d 73 20 69 6e 20 57 41 4c 20 61 72 65 20 62  ums in WAL are b
3900: 69 67 2d 65 6e 64 69 61 6e 20 2a 2f 0a 20 20 75  ig-endian */.  u
3910: 31 36 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20  16 szPage;      
3920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3930: 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20  * Database page 
3940: 73 69 7a 65 20 69 6e 20 62 79 74 65 73 2e 20 31  size in bytes. 1
3950: 3d 3d 36 34 4b 20 2a 2f 0a 20 20 75 33 32 20 6d  ==64K */.  u32 m
3960: 78 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20  xFrame;         
3970: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
3980: 64 65 78 20 6f 66 20 6c 61 73 74 20 76 61 6c 69  dex of last vali
3990: 64 20 66 72 61 6d 65 20 69 6e 20 74 68 65 20 57  d frame in the W
39a0: 41 4c 20 2a 2f 0a 20 20 75 33 32 20 6e 50 61 67  AL */.  u32 nPag
39b0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
39c0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
39d0: 6f 66 20 64 61 74 61 62 61 73 65 20 69 6e 20 70  of database in p
39e0: 61 67 65 73 20 2a 2f 0a 20 20 75 33 32 20 61 46  ages */.  u32 aF
39f0: 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  rameCksum[2];   
3a00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65            /* Che
3a10: 63 6b 73 75 6d 20 6f 66 20 6c 61 73 74 20 66 72  cksum of last fr
3a20: 61 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20  ame in log */.  
3a30: 75 33 32 20 61 53 61 6c 74 5b 32 5d 3b 20 20 20  u32 aSalt[2];   
3a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a50: 2f 2a 20 54 77 6f 20 73 61 6c 74 20 76 61 6c 75  /* Two salt valu
3a60: 65 73 20 63 6f 70 69 65 64 20 66 72 6f 6d 20 57  es copied from W
3a70: 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 75  AL header */.  u
3a80: 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  32 aCksum[2];   
3a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3aa0: 2a 20 43 68 65 63 6b 73 75 6d 20 6f 76 65 72 20  * Checksum over 
3ab0: 61 6c 6c 20 70 72 69 6f 72 20 66 69 65 6c 64 73  all prior fields
3ac0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20   */.};../*.** A 
3ad0: 63 6f 70 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c  copy of the foll
3ae0: 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 6f 63 63  owing object occ
3af0: 75 72 73 20 69 6e 20 74 68 65 20 77 61 6c 2d 69  urs in the wal-i
3b00: 6e 64 65 78 20 69 6d 6d 65 64 69 61 74 65 6c 79  ndex immediately
3b10: 0a 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68  .** following th
3b20: 65 20 73 65 63 6f 6e 64 20 63 6f 70 79 20 6f 66  e second copy of
3b30: 20 74 68 65 20 57 61 6c 49 6e 64 65 78 48 64 72   the WalIndexHdr
3b40: 2e 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20 73  .  This object s
3b50: 74 6f 72 65 73 0a 2a 2a 20 69 6e 66 6f 72 6d 61  tores.** informa
3b60: 74 69 6f 6e 20 75 73 65 64 20 62 79 20 63 68 65  tion used by che
3b70: 63 6b 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20 6e  ckpoint..**.** n
3b80: 42 61 63 6b 66 69 6c 6c 20 69 73 20 74 68 65 20  Backfill is the 
3b90: 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d 65 73  number of frames
3ba0: 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68 61 74   in the WAL that
3bb0: 20 68 61 76 65 20 62 65 65 6e 20 77 72 69 74 74   have been writt
3bc0: 65 6e 0a 2a 2a 20 62 61 63 6b 20 69 6e 74 6f 20  en.** back into 
3bd0: 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 28 57  the database. (W
3be0: 65 20 63 61 6c 6c 20 74 68 65 20 61 63 74 20 6f  e call the act o
3bf0: 66 20 6d 6f 76 69 6e 67 20 63 6f 6e 74 65 6e 74  f moving content
3c00: 20 66 72 6f 6d 20 57 41 4c 20 74 6f 0a 2a 2a 20   from WAL to.** 
3c10: 64 61 74 61 62 61 73 65 20 22 62 61 63 6b 66 69  database "backfi
3c20: 6c 6c 69 6e 67 22 2e 29 20 20 54 68 65 20 6e 42  lling".)  The nB
3c30: 61 63 6b 66 69 6c 6c 20 6e 75 6d 62 65 72 20 69  ackfill number i
3c40: 73 20 6e 65 76 65 72 20 67 72 65 61 74 65 72 20  s never greater 
3c50: 74 68 61 6e 0a 2a 2a 20 57 61 6c 49 6e 64 65 78  than.** WalIndex
3c60: 48 64 72 2e 6d 78 46 72 61 6d 65 2e 20 20 6e 42  Hdr.mxFrame.  nB
3c70: 61 63 6b 66 69 6c 6c 20 63 61 6e 20 6f 6e 6c 79  ackfill can only
3c80: 20 62 65 20 69 6e 63 72 65 61 73 65 64 20 62 79   be increased by
3c90: 20 74 68 72 65 61 64 73 0a 2a 2a 20 68 6f 6c 64   threads.** hold
3ca0: 69 6e 67 20 74 68 65 20 57 41 4c 5f 43 4b 50 54  ing the WAL_CKPT
3cb0: 5f 4c 4f 43 4b 20 6c 6f 63 6b 20 28 77 68 69 63  _LOCK lock (whic
3cc0: 68 20 69 6e 63 6c 75 64 65 73 20 61 20 72 65 63  h includes a rec
3cd0: 6f 76 65 72 79 20 74 68 72 65 61 64 29 2e 0a 2a  overy thread)..*
3ce0: 2a 20 48 6f 77 65 76 65 72 2c 20 61 20 57 41 4c  * However, a WAL
3cf0: 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 74 68 72 65  _WRITE_LOCK thre
3d00: 61 64 20 63 61 6e 20 6d 6f 76 65 20 74 68 65 20  ad can move the 
3d10: 76 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b 66 69  value of nBackfi
3d20: 6c 6c 20 66 72 6f 6d 0a 2a 2a 20 6d 78 46 72 61  ll from.** mxFra
3d30: 6d 65 20 62 61 63 6b 20 74 6f 20 7a 65 72 6f 20  me back to zero 
3d40: 77 68 65 6e 20 74 68 65 20 57 41 4c 20 69 73 20  when the WAL is 
3d50: 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  reset..**.** The
3d60: 72 65 20 69 73 20 6f 6e 65 20 65 6e 74 72 79 20  re is one entry 
3d70: 69 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 66  in aReadMark[] f
3d80: 6f 72 20 65 61 63 68 20 72 65 61 64 65 72 20 6c  or each reader l
3d90: 6f 63 6b 2e 20 20 49 66 20 61 20 72 65 61 64 65  ock.  If a reade
3da0: 72 0a 2a 2a 20 68 6f 6c 64 73 20 72 65 61 64 2d  r.** holds read-
3db0: 6c 6f 63 6b 20 4b 2c 20 74 68 65 6e 20 74 68 65  lock K, then the
3dc0: 20 76 61 6c 75 65 20 69 6e 20 61 52 65 61 64 4d   value in aReadM
3dd0: 61 72 6b 5b 4b 5d 20 69 73 20 6e 6f 20 67 72 65  ark[K] is no gre
3de0: 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 74 68 65  ater than.** the
3df0: 20 6d 78 46 72 61 6d 65 20 66 6f 72 20 74 68 61   mxFrame for tha
3e00: 74 20 72 65 61 64 65 72 2e 20 20 54 68 65 20 76  t reader.  The v
3e10: 61 6c 75 65 20 52 45 41 44 4d 41 52 4b 5f 4e 4f  alue READMARK_NO
3e20: 54 5f 55 53 45 44 20 28 30 78 66 66 66 66 66 66  T_USED (0xffffff
3e30: 66 66 29 0a 2a 2a 20 66 6f 72 20 61 6e 79 20 61  ff).** for any a
3e40: 52 65 61 64 4d 61 72 6b 5b 5d 20 6d 65 61 6e 73  ReadMark[] means
3e50: 20 74 68 61 74 20 65 6e 74 72 79 20 69 73 20 75   that entry is u
3e60: 6e 75 73 65 64 2e 20 20 61 52 65 61 64 4d 61 72  nused.  aReadMar
3e70: 6b 5b 30 5d 20 69 73 20 0a 2a 2a 20 61 20 73 70  k[0] is .** a sp
3e80: 65 63 69 61 6c 20 63 61 73 65 3b 20 69 74 73 20  ecial case; its 
3e90: 76 61 6c 75 65 20 69 73 20 6e 65 76 65 72 20 75  value is never u
3ea0: 73 65 64 20 61 6e 64 20 69 74 20 65 78 69 73 74  sed and it exist
3eb0: 73 20 61 73 20 61 20 70 6c 61 63 65 2d 68 6f 6c  s as a place-hol
3ec0: 64 65 72 0a 2a 2a 20 74 6f 20 61 76 6f 69 64 20  der.** to avoid 
3ed0: 68 61 76 69 6e 67 20 74 6f 20 6f 66 66 73 65 74  having to offset
3ee0: 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 69 6e 64   aReadMark[] ind
3ef0: 65 78 73 20 62 79 20 6f 6e 65 2e 20 20 52 65 61  exs by one.  Rea
3f00: 64 65 72 73 20 68 6f 6c 64 69 6e 67 0a 2a 2a 20  ders holding.** 
3f10: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29  WAL_READ_LOCK(0)
3f20: 20 61 6c 77 61 79 73 20 69 67 6e 6f 72 65 20 74   always ignore t
3f30: 68 65 20 65 6e 74 69 72 65 20 57 41 4c 20 61 6e  he entire WAL an
3f40: 64 20 72 65 61 64 20 61 6c 6c 20 63 6f 6e 74 65  d read all conte
3f50: 6e 74 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20 66  nt.** directly f
3f60: 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73 65  rom the database
3f70: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c 75  ..**.** The valu
3f80: 65 20 6f 66 20 61 52 65 61 64 4d 61 72 6b 5b 4b  e of aReadMark[K
3f90: 5d 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63 68  ] may only be ch
3fa0: 61 6e 67 65 64 20 62 79 20 61 20 74 68 72 65 61  anged by a threa
3fb0: 64 20 74 68 61 74 0a 2a 2a 20 69 73 20 68 6f 6c  d that.** is hol
3fc0: 64 69 6e 67 20 61 6e 20 65 78 63 6c 75 73 69 76  ding an exclusiv
3fd0: 65 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52 45  e lock on WAL_RE
3fe0: 41 44 5f 4c 4f 43 4b 28 4b 29 2e 20 20 54 68 75  AD_LOCK(K).  Thu
3ff0: 73 2c 20 74 68 65 20 76 61 6c 75 65 20 6f 66 0a  s, the value of.
4000: 2a 2a 20 61 52 65 61 64 4d 61 72 6b 5b 4b 5d 20  ** aReadMark[K] 
4010: 63 61 6e 6e 6f 74 20 63 68 61 6e 67 65 64 20 77  cannot changed w
4020: 68 69 6c 65 20 74 68 65 72 65 20 69 73 20 61 20  hile there is a 
4030: 72 65 61 64 65 72 20 69 73 20 75 73 69 6e 67 20  reader is using 
4040: 74 68 61 74 20 6d 61 72 6b 0a 2a 2a 20 73 69 6e  that mark.** sin
4050: 63 65 20 74 68 65 20 72 65 61 64 65 72 20 77 69  ce the reader wi
4060: 6c 6c 20 62 65 20 68 6f 6c 64 69 6e 67 20 61 20  ll be holding a 
4070: 73 68 61 72 65 64 20 6c 6f 63 6b 20 6f 6e 20 57  shared lock on W
4080: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 4b 29 2e  AL_READ_LOCK(K).
4090: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b  .**.** The check
40a0: 70 6f 69 6e 74 65 72 20 6d 61 79 20 6f 6e 6c 79  pointer may only
40b0: 20 74 72 61 6e 73 66 65 72 20 66 72 61 6d 65 73   transfer frames
40c0: 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64 61 74   from WAL to dat
40d0: 61 62 61 73 65 20 77 68 65 72 65 0a 2a 2a 20 74  abase where.** t
40e0: 68 65 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 73  he frame numbers
40f0: 20 61 72 65 20 6c 65 73 73 20 74 68 61 6e 20 6f   are less than o
4100: 72 20 65 71 75 61 6c 20 74 6f 20 65 76 65 72 79  r equal to every
4110: 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 74 68 61   aReadMark[] tha
4120: 74 20 69 73 0a 2a 2a 20 69 6e 20 75 73 65 20 28  t is.** in use (
4130: 74 68 61 74 20 69 73 2c 20 65 76 65 72 79 20 61  that is, every a
4140: 52 65 61 64 4d 61 72 6b 5b 6a 5d 20 66 6f 72 20  ReadMark[j] for 
4150: 77 68 69 63 68 20 74 68 65 72 65 20 69 73 20 61  which there is a
4160: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a   corresponding.*
4170: 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  * WAL_READ_LOCK(
4180: 6a 29 29 2e 20 20 4e 65 77 20 72 65 61 64 65 72  j)).  New reader
4190: 73 20 28 75 73 75 61 6c 6c 79 29 20 70 69 63 6b  s (usually) pick
41a0: 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d   the aReadMark[]
41b0: 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 6c 61 72   with the.** lar
41c0: 67 65 73 74 20 76 61 6c 75 65 20 61 6e 64 20 77  gest value and w
41d0: 69 6c 6c 20 69 6e 63 72 65 61 73 65 20 61 6e 20  ill increase an 
41e0: 75 6e 75 73 65 64 20 61 52 65 61 64 4d 61 72 6b  unused aReadMark
41f0: 5b 5d 20 74 6f 20 6d 78 46 72 61 6d 65 20 69 66  [] to mxFrame if
4200: 20 74 68 65 72 65 0a 2a 2a 20 69 73 20 6e 6f 74   there.** is not
4210: 20 61 6c 72 65 61 64 79 20 61 6e 20 61 52 65 61   already an aRea
4220: 64 4d 61 72 6b 5b 5d 20 65 71 75 61 6c 20 74 6f  dMark[] equal to
4230: 20 6d 78 46 72 61 6d 65 2e 20 20 54 68 65 20 65   mxFrame.  The e
4240: 78 63 65 70 74 69 6f 6e 20 74 6f 20 74 68 65 0a  xception to the.
4250: 2a 2a 20 70 72 65 76 69 6f 75 73 20 73 65 6e 74  ** previous sent
4260: 65 6e 63 65 20 69 73 20 77 68 65 6e 20 6e 42 61  ence is when nBa
4270: 63 6b 66 69 6c 6c 20 65 71 75 61 6c 73 20 6d 78  ckfill equals mx
4280: 46 72 61 6d 65 20 28 6d 65 61 6e 69 6e 67 20 74  Frame (meaning t
4290: 68 61 74 20 65 76 65 72 79 74 68 69 6e 67 0a 2a  hat everything.*
42a0: 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 68 61 73  * in the WAL has
42b0: 20 62 65 65 6e 20 62 61 63 6b 66 69 6c 6c 65 64   been backfilled
42c0: 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
42d0: 73 65 29 20 74 68 65 6e 20 6e 65 77 20 72 65 61  se) then new rea
42e0: 64 65 72 73 0a 2a 2a 20 77 69 6c 6c 20 63 68 6f  ders.** will cho
42f0: 6f 73 65 20 61 52 65 61 64 4d 61 72 6b 5b 30 5d  ose aReadMark[0]
4300: 20 77 68 69 63 68 20 68 61 73 20 76 61 6c 75 65   which has value
4310: 20 30 20 61 6e 64 20 68 65 6e 63 65 20 73 75 63   0 and hence suc
4320: 68 20 72 65 61 64 65 72 20 77 69 6c 6c 0a 2a 2a  h reader will.**
4330: 20 67 65 74 20 61 6c 6c 20 74 68 65 69 72 20 61   get all their a
4340: 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72 65 63  ll content direc
4350: 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61 74  tly from the dat
4360: 61 62 61 73 65 20 66 69 6c 65 20 61 6e 64 20 69  abase file and i
4370: 67 6e 6f 72 65 20 0a 2a 2a 20 74 68 65 20 57 41  gnore .** the WA
4380: 4c 2e 0a 2a 2a 0a 2a 2a 20 57 72 69 74 65 72 73  L..**.** Writers
4390: 20 6e 6f 72 6d 61 6c 6c 79 20 61 70 70 65 6e 64   normally append
43a0: 20 6e 65 77 20 66 72 61 6d 65 73 20 74 6f 20 74   new frames to t
43b0: 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 57 41  he end of the WA
43c0: 4c 2e 20 20 48 6f 77 65 76 65 72 2c 0a 2a 2a 20  L.  However,.** 
43d0: 69 66 20 6e 42 61 63 6b 66 69 6c 6c 20 65 71 75  if nBackfill equ
43e0: 61 6c 73 20 6d 78 46 72 61 6d 65 20 28 6d 65 61  als mxFrame (mea
43f0: 6e 69 6e 67 20 74 68 61 74 20 61 6c 6c 20 57 41  ning that all WA
4400: 4c 20 63 6f 6e 74 65 6e 74 20 68 61 73 20 62 65  L content has be
4410: 65 6e 0a 2a 2a 20 77 72 69 74 74 65 6e 20 62 61  en.** written ba
4420: 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ck into the data
4430: 62 61 73 65 29 20 61 6e 64 20 69 66 20 6e 6f 20  base) and if no 
4440: 72 65 61 64 65 72 73 20 61 72 65 20 75 73 69 6e  readers are usin
4450: 67 20 74 68 65 20 57 41 4c 0a 2a 2a 20 28 69 6e  g the WAL.** (in
4460: 20 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 69 66   other words, if
4470: 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 57 41   there are no WA
4480: 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 20 77  L_READ_LOCK(i) w
4490: 68 65 72 65 20 69 3e 30 29 20 74 68 65 6e 0a 2a  here i>0) then.*
44a0: 2a 20 74 68 65 20 77 72 69 74 65 72 20 77 69 6c  * the writer wil
44b0: 6c 20 66 69 72 73 74 20 22 72 65 73 65 74 22 20  l first "reset" 
44c0: 74 68 65 20 57 41 4c 20 62 61 63 6b 20 74 6f 20  the WAL back to 
44d0: 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 61 6e  the beginning an
44e0: 64 20 73 74 61 72 74 0a 2a 2a 20 77 72 69 74 69  d start.** writi
44f0: 6e 67 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20 62  ng new content b
4500: 65 67 69 6e 6e 69 6e 67 20 61 74 20 66 72 61 6d  eginning at fram
4510: 65 20 31 2e 0a 2a 2a 0a 2a 2a 20 57 65 20 61 73  e 1..**.** We as
4520: 73 75 6d 65 20 74 68 61 74 20 33 32 2d 62 69 74  sume that 32-bit
4530: 20 6c 6f 61 64 73 20 61 72 65 20 61 74 6f 6d 69   loads are atomi
4540: 63 20 61 6e 64 20 73 6f 20 6e 6f 20 6c 6f 63 6b  c and so no lock
4550: 73 20 61 72 65 20 6e 65 65 64 65 64 20 69 6e 0a  s are needed in.
4560: 2a 2a 20 6f 72 64 65 72 20 74 6f 20 72 65 61 64  ** order to read
4570: 20 66 72 6f 6d 20 61 6e 79 20 61 52 65 61 64 4d   from any aReadM
4580: 61 72 6b 5b 5d 20 65 6e 74 72 69 65 73 2e 0a 2a  ark[] entries..*
4590: 2f 0a 73 74 72 75 63 74 20 57 61 6c 43 6b 70 74  /.struct WalCkpt
45a0: 49 6e 66 6f 20 7b 0a 20 20 75 33 32 20 6e 42 61  Info {.  u32 nBa
45b0: 63 6b 66 69 6c 6c 3b 20 20 20 20 20 20 20 20 20  ckfill;         
45c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
45d0: 65 72 20 6f 66 20 57 41 4c 20 66 72 61 6d 65 73  er of WAL frames
45e0: 20 62 61 63 6b 66 69 6c 6c 65 64 20 69 6e 74 6f   backfilled into
45f0: 20 44 42 20 2a 2f 0a 20 20 75 33 32 20 61 52 65   DB */.  u32 aRe
4600: 61 64 4d 61 72 6b 5b 57 41 4c 5f 4e 52 45 41 44  adMark[WAL_NREAD
4610: 45 52 5d 3b 20 20 20 20 20 2f 2a 20 52 65 61 64  ER];     /* Read
4620: 65 72 20 6d 61 72 6b 73 20 2a 2f 0a 7d 3b 0a 23  er marks */.};.#
4630: 64 65 66 69 6e 65 20 52 45 41 44 4d 41 52 4b 5f  define READMARK_
4640: 4e 4f 54 5f 55 53 45 44 20 20 30 78 66 66 66 66  NOT_USED  0xffff
4650: 66 66 66 66 0a 0a 0a 2f 2a 20 41 20 62 6c 6f 63  ffff.../* A bloc
4660: 6b 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 4c 4f  k of WALINDEX_LO
4670: 43 4b 5f 52 45 53 45 52 56 45 44 20 62 79 74 65  CK_RESERVED byte
4680: 73 20 62 65 67 69 6e 6e 69 6e 67 20 61 74 0a 2a  s beginning at.*
4690: 2a 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f  * WALINDEX_LOCK_
46a0: 4f 46 46 53 45 54 20 69 73 20 72 65 73 65 72 76  OFFSET is reserv
46b0: 65 64 20 66 6f 72 20 6c 6f 63 6b 73 2e 20 53 69  ed for locks. Si
46c0: 6e 63 65 20 73 6f 6d 65 20 73 79 73 74 65 6d 73  nce some systems
46d0: 0a 2a 2a 20 6f 6e 6c 79 20 73 75 70 70 6f 72 74  .** only support
46e0: 20 6d 61 6e 64 61 74 6f 72 79 20 66 69 6c 65 2d   mandatory file-
46f0: 6c 6f 63 6b 73 2c 20 77 65 20 64 6f 20 6e 6f 74  locks, we do not
4700: 20 72 65 61 64 20 6f 72 20 77 72 69 74 65 20 64   read or write d
4710: 61 74 61 0a 2a 2a 20 66 72 6f 6d 20 74 68 65 20  ata.** from the 
4720: 72 65 67 69 6f 6e 20 6f 66 20 74 68 65 20 66 69  region of the fi
4730: 6c 65 20 6f 6e 20 77 68 69 63 68 20 6c 6f 63 6b  le on which lock
4740: 73 20 61 72 65 20 61 70 70 6c 69 65 64 2e 0a 2a  s are applied..*
4750: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44  /.#define WALIND
4760: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 20  EX_LOCK_OFFSET  
4770: 20 28 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65   (sizeof(WalInde
4780: 78 48 64 72 29 2a 32 20 2b 20 73 69 7a 65 6f 66  xHdr)*2 + sizeof
4790: 28 57 61 6c 43 6b 70 74 49 6e 66 6f 29 29 0a 23  (WalCkptInfo)).#
47a0: 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58 5f  define WALINDEX_
47b0: 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 20 31 36  LOCK_RESERVED 16
47c0: 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45  .#define WALINDE
47d0: 58 5f 48 44 52 5f 53 49 5a 45 20 20 20 20 20 20  X_HDR_SIZE      
47e0: 28 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f  (WALINDEX_LOCK_O
47f0: 46 46 53 45 54 2b 57 41 4c 49 4e 44 45 58 5f 4c  FFSET+WALINDEX_L
4800: 4f 43 4b 5f 52 45 53 45 52 56 45 44 29 0a 0a 2f  OCK_RESERVED)../
4810: 2a 20 53 69 7a 65 20 6f 66 20 68 65 61 64 65 72  * Size of header
4820: 20 62 65 66 6f 72 65 20 65 61 63 68 20 66 72 61   before each fra
4830: 6d 65 20 69 6e 20 77 61 6c 20 2a 2f 0a 23 64 65  me in wal */.#de
4840: 66 69 6e 65 20 57 41 4c 5f 46 52 41 4d 45 5f 48  fine WAL_FRAME_H
4850: 44 52 53 49 5a 45 20 32 34 0a 0a 2f 2a 20 53 69  DRSIZE 24../* Si
4860: 7a 65 20 6f 66 20 77 72 69 74 65 20 61 68 65 61  ze of write ahea
4870: 64 20 6c 6f 67 20 68 65 61 64 65 72 2c 20 69 6e  d log header, in
4880: 63 6c 75 64 69 6e 67 20 63 68 65 63 6b 73 75 6d  cluding checksum
4890: 2e 20 2a 2f 0a 2f 2a 20 23 64 65 66 69 6e 65 20  . */./* #define 
48a0: 57 41 4c 5f 48 44 52 53 49 5a 45 20 32 34 20 2a  WAL_HDRSIZE 24 *
48b0: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48 44  /.#define WAL_HD
48c0: 52 53 49 5a 45 20 33 32 0a 0a 2f 2a 20 57 41 4c  RSIZE 32../* WAL
48d0: 20 6d 61 67 69 63 20 76 61 6c 75 65 2e 20 45 69   magic value. Ei
48e0: 74 68 65 72 20 74 68 69 73 20 76 61 6c 75 65 2c  ther this value,
48f0: 20 6f 72 20 74 68 65 20 73 61 6d 65 20 76 61 6c   or the same val
4900: 75 65 20 77 69 74 68 20 74 68 65 20 6c 65 61 73  ue with the leas
4910: 74 0a 2a 2a 20 73 69 67 6e 69 66 69 63 61 6e 74  t.** significant
4920: 20 62 69 74 20 61 6c 73 6f 20 73 65 74 20 28 57   bit also set (W
4930: 41 4c 5f 4d 41 47 49 43 20 7c 20 30 78 30 30 30  AL_MAGIC | 0x000
4940: 30 30 30 30 31 29 20 69 73 20 73 74 6f 72 65 64  00001) is stored
4950: 20 69 6e 20 33 32 2d 62 69 74 0a 2a 2a 20 62 69   in 32-bit.** bi
4960: 67 2d 65 6e 64 69 61 6e 20 66 6f 72 6d 61 74 20  g-endian format 
4970: 69 6e 20 74 68 65 20 66 69 72 73 74 20 34 20 62  in the first 4 b
4980: 79 74 65 73 20 6f 66 20 61 20 57 41 4c 20 66 69  ytes of a WAL fi
4990: 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  le..**.** If the
49a0: 20 4c 53 42 20 69 73 20 73 65 74 2c 20 74 68 65   LSB is set, the
49b0: 6e 20 74 68 65 20 63 68 65 63 6b 73 75 6d 73 20  n the checksums 
49c0: 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65 20 77  for each frame w
49d0: 69 74 68 69 6e 20 74 68 65 20 57 41 4c 0a 2a 2a  ithin the WAL.**
49e0: 20 66 69 6c 65 20 61 72 65 20 63 61 6c 63 75 6c   file are calcul
49f0: 61 74 65 64 20 62 79 20 74 72 65 61 74 69 6e 67  ated by treating
4a00: 20 61 6c 6c 20 64 61 74 61 20 61 73 20 61 6e 20   all data as an 
4a10: 61 72 72 61 79 20 6f 66 20 33 32 2d 62 69 74 20  array of 32-bit 
4a20: 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 77  .** big-endian w
4a30: 6f 72 64 73 2e 20 4f 74 68 65 72 77 69 73 65 2c  ords. Otherwise,
4a40: 20 74 68 65 79 20 61 72 65 20 63 61 6c 63 75 6c   they are calcul
4a50: 61 74 65 64 20 62 79 20 69 6e 74 65 72 70 72 65  ated by interpre
4a60: 74 69 6e 67 20 0a 2a 2a 20 61 6c 6c 20 64 61 74  ting .** all dat
4a70: 61 20 61 73 20 33 32 2d 62 69 74 20 6c 69 74 74  a as 32-bit litt
4a80: 6c 65 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73 2e  le-endian words.
4a90: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f  .*/.#define WAL_
4aa0: 4d 41 47 49 43 20 30 78 33 37 37 66 30 36 38 32  MAGIC 0x377f0682
4ab0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
4ac0: 68 65 20 6f 66 66 73 65 74 20 6f 66 20 66 72 61  he offset of fra
4ad0: 6d 65 20 69 46 72 61 6d 65 20 69 6e 20 74 68 65  me iFrame in the
4ae0: 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67   write-ahead log
4af0: 20 66 69 6c 65 2c 20 0a 2a 2a 20 61 73 73 75 6d   file, .** assum
4b00: 69 6e 67 20 61 20 64 61 74 61 62 61 73 65 20 70  ing a database p
4b10: 61 67 65 20 73 69 7a 65 20 6f 66 20 73 7a 50 61  age size of szPa
4b20: 67 65 20 62 79 74 65 73 2e 20 54 68 65 20 6f 66  ge bytes. The of
4b30: 66 73 65 74 20 72 65 74 75 72 6e 65 64 0a 2a 2a  fset returned.**
4b40: 20 69 73 20 74 6f 20 74 68 65 20 73 74 61 72 74   is to the start
4b50: 20 6f 66 20 74 68 65 20 77 72 69 74 65 2d 61 68   of the write-ah
4b60: 65 61 64 20 6c 6f 67 20 66 72 61 6d 65 2d 68 65  ead log frame-he
4b70: 61 64 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  ader..*/.#define
4b80: 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28   walFrameOffset(
4b90: 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29 20  iFrame, szPage) 
4ba0: 28 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (               
4bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4bc0: 5c 0a 20 20 57 41 4c 5f 48 44 52 53 49 5a 45 20  \.  WAL_HDRSIZE 
4bd0: 2b 20 28 28 69 46 72 61 6d 65 29 2d 31 29 2a 28  + ((iFrame)-1)*(
4be0: 69 36 34 29 28 28 73 7a 50 61 67 65 29 2b 57 41  i64)((szPage)+WA
4bf0: 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 29  L_FRAME_HDRSIZE)
4c00: 20 20 20 20 20 20 20 20 20 5c 0a 29 0a 0a 2f 2a           \.)../*
4c10: 0a 2a 2a 20 41 6e 20 6f 70 65 6e 20 77 72 69 74  .** An open writ
4c20: 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65  e-ahead log file
4c30: 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64 20   is represented 
4c40: 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f  by an instance o
4c50: 66 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c 6f 77 69  f the.** followi
4c60: 6e 67 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  ng object..*/.st
4c70: 72 75 63 74 20 57 61 6c 20 7b 0a 20 20 73 71 6c  ruct Wal {.  sql
4c80: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 3b 20  ite3_vfs *pVfs; 
4c90: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 56          /* The V
4ca0: 46 53 20 75 73 65 64 20 74 6f 20 63 72 65 61 74  FS used to creat
4cb0: 65 20 70 44 62 46 64 20 2a 2f 0a 20 20 73 71 6c  e pDbFd */.  sql
4cc0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 44 62 46 64  ite3_file *pDbFd
4cd0: 3b 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20  ;       /* File 
4ce0: 68 61 6e 64 6c 65 20 66 6f 72 20 74 68 65 20 64  handle for the d
4cf0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a  atabase file */.
4d00: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
4d10: 70 57 61 6c 46 64 3b 20 20 20 20 20 20 2f 2a 20  pWalFd;      /* 
4d20: 46 69 6c 65 20 68 61 6e 64 6c 65 20 66 6f 72 20  File handle for 
4d30: 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33  WAL file */.  u3
4d40: 32 20 69 43 61 6c 6c 62 61 63 6b 3b 20 20 20 20  2 iCallback;    
4d50: 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75           /* Valu
4d60: 65 20 74 6f 20 70 61 73 73 20 74 6f 20 6c 6f 67  e to pass to log
4d70: 20 63 61 6c 6c 62 61 63 6b 20 28 6f 72 20 30 29   callback (or 0)
4d80: 20 2a 2f 0a 20 20 69 36 34 20 6d 78 57 61 6c 53   */.  i64 mxWalS
4d90: 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ize;            
4da0: 20 2f 2a 20 54 72 75 6e 63 61 74 65 20 57 41 4c   /* Truncate WAL
4db0: 20 74 6f 20 74 68 69 73 20 73 69 7a 65 20 75 70   to this size up
4dc0: 6f 6e 20 72 65 73 65 74 20 2a 2f 0a 20 20 69 6e  on reset */.  in
4dd0: 74 20 6e 57 69 44 61 74 61 3b 20 20 20 20 20 20  t nWiData;      
4de0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
4df0: 20 6f 66 20 61 72 72 61 79 20 61 70 57 69 44 61   of array apWiDa
4e00: 74 61 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 46 69  ta */.  int szFi
4e10: 72 73 74 42 6c 6f 63 6b 3b 20 20 20 20 20 20 20  rstBlock;       
4e20: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 66 69     /* Size of fi
4e30: 72 73 74 20 62 6c 6f 63 6b 20 77 72 69 74 74 65  rst block writte
4e40: 6e 20 74 6f 20 57 41 4c 20 66 69 6c 65 20 2a 2f  n to WAL file */
4e50: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20  .  volatile u32 
4e60: 2a 2a 61 70 57 69 44 61 74 61 3b 20 20 20 2f 2a  **apWiData;   /*
4e70: 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 61 6c 2d   Pointer to wal-
4e80: 69 6e 64 65 78 20 63 6f 6e 74 65 6e 74 20 69 6e  index content in
4e90: 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 75 33 32   memory */.  u32
4ea0: 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20   szPage;        
4eb0: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
4ec0: 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f  ase page size */
4ed0: 0a 20 20 69 31 36 20 72 65 61 64 4c 6f 63 6b 3b  .  i16 readLock;
4ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4ef0: 20 57 68 69 63 68 20 72 65 61 64 20 6c 6f 63 6b   Which read lock
4f00: 20 69 73 20 62 65 69 6e 67 20 68 65 6c 64 2e 20   is being held. 
4f10: 20 2d 31 20 66 6f 72 20 6e 6f 6e 65 20 2a 2f 0a   -1 for none */.
4f20: 20 20 75 38 20 73 79 6e 63 46 6c 61 67 73 3b 20    u8 syncFlags; 
4f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4f40: 46 6c 61 67 73 20 74 6f 20 75 73 65 20 74 6f 20  Flags to use to 
4f50: 73 79 6e 63 20 68 65 61 64 65 72 20 77 72 69 74  sync header writ
4f60: 65 73 20 2a 2f 0a 20 20 75 38 20 65 78 63 6c 75  es */.  u8 exclu
4f70: 73 69 76 65 4d 6f 64 65 3b 20 20 20 20 20 20 20  siveMode;       
4f80: 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69     /* Non-zero i
4f90: 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20  f connection is 
4fa0: 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f 64  in exclusive mod
4fb0: 65 20 2a 2f 0a 20 20 75 38 20 77 72 69 74 65 4c  e */.  u8 writeL
4fc0: 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ock;            
4fd0: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 20    /* True if in 
4fe0: 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74  a write transact
4ff0: 69 6f 6e 20 2a 2f 0a 20 20 75 38 20 63 6b 70 74  ion */.  u8 ckpt
5000: 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Lock;           
5010: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 68      /* True if h
5020: 6f 6c 64 69 6e 67 20 61 20 63 68 65 63 6b 70 6f  olding a checkpo
5030: 69 6e 74 20 6c 6f 63 6b 20 2a 2f 0a 20 20 75 38  int lock */.  u8
5040: 20 72 65 61 64 4f 6e 6c 79 3b 20 20 20 20 20 20   readOnly;      
5050: 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 5f           /* WAL_
5060: 52 44 57 52 2c 20 57 41 4c 5f 52 44 4f 4e 4c 59  RDWR, WAL_RDONLY
5070: 2c 20 6f 72 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  , or WAL_SHM_RDO
5080: 4e 4c 59 20 2a 2f 0a 20 20 75 38 20 74 72 75 6e  NLY */.  u8 trun
5090: 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 3b 20 20 20  cateOnCommit;   
50a0: 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 74      /* True to t
50b0: 72 75 6e 63 61 74 65 20 57 41 4c 20 66 69 6c 65  runcate WAL file
50c0: 20 6f 6e 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20   on commit */.  
50d0: 75 38 20 73 79 6e 63 48 65 61 64 65 72 3b 20 20  u8 syncHeader;  
50e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 73             /* Fs
50f0: 79 6e 63 20 74 68 65 20 57 41 4c 20 68 65 61 64  ync the WAL head
5100: 65 72 20 69 66 20 74 72 75 65 20 2a 2f 0a 20 20  er if true */.  
5110: 75 38 20 70 61 64 54 6f 53 65 63 74 6f 72 42 6f  u8 padToSectorBo
5120: 75 6e 64 61 72 79 3b 20 20 20 20 2f 2a 20 50 61  undary;    /* Pa
5130: 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 20 6f  d transactions o
5140: 75 74 20 74 6f 20 74 68 65 20 6e 65 78 74 20 73  ut to the next s
5150: 65 63 74 6f 72 20 2a 2f 0a 20 20 57 61 6c 49 6e  ector */.  WalIn
5160: 64 65 78 48 64 72 20 68 64 72 3b 20 20 20 20 20  dexHdr hdr;     
5170: 20 20 20 20 20 20 2f 2a 20 57 61 6c 2d 69 6e 64        /* Wal-ind
5180: 65 78 20 68 65 61 64 65 72 20 66 6f 72 20 63 75  ex header for cu
5190: 72 72 65 6e 74 20 74 72 61 6e 73 61 63 74 69 6f  rrent transactio
51a0: 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  n */.  const cha
51b0: 72 20 2a 7a 57 61 6c 4e 61 6d 65 3b 20 20 20 20  r *zWalName;    
51c0: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 57 41 4c    /* Name of WAL
51d0: 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32 20 6e   file */.  u32 n
51e0: 43 6b 70 74 3b 20 20 20 20 20 20 20 20 20 20 20  Ckpt;           
51f0: 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 70 6f        /* Checkpo
5200: 69 6e 74 20 73 65 71 75 65 6e 63 65 20 63 6f 75  int sequence cou
5210: 6e 74 65 72 20 69 6e 20 74 68 65 20 77 61 6c 2d  nter in the wal-
5220: 68 65 61 64 65 72 20 2a 2f 0a 23 69 66 64 65 66  header */.#ifdef
5230: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20   SQLITE_DEBUG.  
5240: 75 38 20 6c 6f 63 6b 45 72 72 6f 72 3b 20 20 20  u8 lockError;   
5250: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
5260: 75 65 20 69 66 20 61 20 6c 6f 63 6b 69 6e 67 20  ue if a locking 
5270: 65 72 72 6f 72 20 68 61 73 20 6f 63 63 75 72 72  error has occurr
5280: 65 64 20 2a 2f 0a 23 65 6e 64 69 66 0a 7d 3b 0a  ed */.#endif.};.
5290: 0a 2f 2a 0a 2a 2a 20 43 61 6e 64 69 64 61 74 65  ./*.** Candidate
52a0: 20 76 61 6c 75 65 73 20 66 6f 72 20 57 61 6c 2e   values for Wal.
52b0: 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 2e 0a 2a  exclusiveMode..*
52c0: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 4e 4f  /.#define WAL_NO
52d0: 52 4d 41 4c 5f 4d 4f 44 45 20 20 20 20 20 30 0a  RMAL_MODE     0.
52e0: 23 64 65 66 69 6e 65 20 57 41 4c 5f 45 58 43 4c  #define WAL_EXCL
52f0: 55 53 49 56 45 5f 4d 4f 44 45 20 20 31 20 20 20  USIVE_MODE  1   
5300: 20 20 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48    .#define WAL_H
5310: 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 32  EAPMEMORY_MODE 2
5320: 0a 0a 2f 2a 0a 2a 2a 20 50 6f 73 73 69 62 6c 65  ../*.** Possible
5330: 20 76 61 6c 75 65 73 20 66 6f 72 20 57 41 4c 2e   values for WAL.
5340: 72 65 61 64 4f 6e 6c 79 0a 2a 2f 0a 23 64 65 66  readOnly.*/.#def
5350: 69 6e 65 20 57 41 4c 5f 52 44 57 52 20 20 20 20  ine WAL_RDWR    
5360: 20 20 20 20 30 20 20 20 20 2f 2a 20 4e 6f 72 6d      0    /* Norm
5370: 61 6c 20 72 65 61 64 2f 77 72 69 74 65 20 63 6f  al read/write co
5380: 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 23 64 65 66  nnection */.#def
5390: 69 6e 65 20 57 41 4c 5f 52 44 4f 4e 4c 59 20 20  ine WAL_RDONLY  
53a0: 20 20 20 20 31 20 20 20 20 2f 2a 20 54 68 65 20      1    /* The 
53b0: 57 41 4c 20 66 69 6c 65 20 69 73 20 72 65 61 64  WAL file is read
53c0: 6f 6e 6c 79 20 2a 2f 0a 23 64 65 66 69 6e 65 20  only */.#define 
53d0: 57 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 20 20  WAL_SHM_RDONLY  
53e0: 32 20 20 20 20 2f 2a 20 54 68 65 20 53 48 4d 20  2    /* The SHM 
53f0: 66 69 6c 65 20 69 73 20 72 65 61 64 6f 6e 6c 79  file is readonly
5400: 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20   */../*.** Each 
5410: 70 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d  page of the wal-
5420: 69 6e 64 65 78 20 6d 61 70 70 69 6e 67 20 63 6f  index mapping co
5430: 6e 74 61 69 6e 73 20 61 20 68 61 73 68 2d 74 61  ntains a hash-ta
5440: 62 6c 65 20 6d 61 64 65 20 75 70 20 6f 66 0a 2a  ble made up of.*
5450: 2a 20 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41  * an array of HA
5460: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 65 6c  SHTABLE_NSLOT el
5470: 65 6d 65 6e 74 73 20 6f 66 20 74 68 65 20 66 6f  ements of the fo
5480: 6c 6c 6f 77 69 6e 67 20 74 79 70 65 2e 0a 2a 2f  llowing type..*/
5490: 0a 74 79 70 65 64 65 66 20 75 31 36 20 68 74 5f  .typedef u16 ht_
54a0: 73 6c 6f 74 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  slot;../*.** Thi
54b0: 73 20 73 74 72 75 63 74 75 72 65 20 69 73 20 75  s structure is u
54c0: 73 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  sed to implement
54d0: 20 61 6e 20 69 74 65 72 61 74 6f 72 20 74 68 61   an iterator tha
54e0: 74 20 6c 6f 6f 70 73 20 74 68 72 6f 75 67 68 0a  t loops through.
54f0: 2a 2a 20 61 6c 6c 20 66 72 61 6d 65 73 20 69 6e  ** all frames in
5500: 20 74 68 65 20 57 41 4c 20 69 6e 20 64 61 74 61   the WAL in data
5510: 62 61 73 65 20 70 61 67 65 20 6f 72 64 65 72 2e  base page order.
5520: 20 57 68 65 72 65 20 74 77 6f 20 6f 72 20 6d 6f   Where two or mo
5530: 72 65 20 66 72 61 6d 65 73 0a 2a 2a 20 63 6f 72  re frames.** cor
5540: 72 65 73 70 6f 6e 64 20 74 6f 20 74 68 65 20 73  respond to the s
5550: 61 6d 65 20 64 61 74 61 62 61 73 65 20 70 61 67  ame database pag
5560: 65 2c 20 74 68 65 20 69 74 65 72 61 74 6f 72 20  e, the iterator 
5570: 76 69 73 69 74 73 20 6f 6e 6c 79 20 74 68 65 20  visits only the 
5580: 0a 2a 2a 20 66 72 61 6d 65 20 6d 6f 73 74 20 72  .** frame most r
5590: 65 63 65 6e 74 6c 79 20 77 72 69 74 74 65 6e 20  ecently written 
55a0: 74 6f 20 74 68 65 20 57 41 4c 20 28 69 6e 20 6f  to the WAL (in o
55b0: 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68 65 20  ther words, the 
55c0: 66 72 61 6d 65 20 77 69 74 68 0a 2a 2a 20 74 68  frame with.** th
55d0: 65 20 6c 61 72 67 65 73 74 20 69 6e 64 65 78 29  e largest index)
55e0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e 74 65  ..**.** The inte
55f0: 72 6e 61 6c 73 20 6f 66 20 74 68 69 73 20 73 74  rnals of this st
5600: 72 75 63 74 75 72 65 20 61 72 65 20 6f 6e 6c 79  ructure are only
5610: 20 61 63 63 65 73 73 65 64 20 62 79 3a 0a 2a 2a   accessed by:.**
5620: 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f  .**   walIterato
5630: 72 49 6e 69 74 28 29 20 2d 20 43 72 65 61 74 65  rInit() - Create
5640: 20 61 20 6e 65 77 20 69 74 65 72 61 74 6f 72 2c   a new iterator,
5650: 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f  .**   walIterato
5660: 72 4e 65 78 74 28 29 20 2d 20 53 74 65 70 20 61  rNext() - Step a
5670: 6e 20 69 74 65 72 61 74 6f 72 2c 0a 2a 2a 20 20  n iterator,.**  
5680: 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65   walIteratorFree
5690: 28 29 20 2d 20 46 72 65 65 20 61 6e 20 69 74 65  () - Free an ite
56a0: 72 61 74 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  rator..**.** Thi
56b0: 73 20 66 75 6e 63 74 69 6f 6e 61 6c 69 74 79 20  s functionality 
56c0: 69 73 20 75 73 65 64 20 62 79 20 74 68 65 20 63  is used by the c
56d0: 68 65 63 6b 70 6f 69 6e 74 20 63 6f 64 65 20 28  heckpoint code (
56e0: 73 65 65 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e  see walCheckpoin
56f0: 74 28 29 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  t())..*/.struct 
5700: 57 61 6c 49 74 65 72 61 74 6f 72 20 7b 0a 20 20  WalIterator {.  
5710: 69 6e 74 20 69 50 72 69 6f 72 3b 20 20 20 20 20  int iPrior;     
5720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5730: 2f 2a 20 4c 61 73 74 20 72 65 73 75 6c 74 20 72  /* Last result r
5740: 65 74 75 72 6e 65 64 20 66 72 6f 6d 20 74 68 65  eturned from the
5750: 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69   iterator */.  i
5760: 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20 20  nt nSegment;    
5770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5780: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72  * Number of entr
5790: 69 65 73 20 69 6e 20 61 53 65 67 6d 65 6e 74 5b  ies in aSegment[
57a0: 5d 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 57 61  ] */.  struct Wa
57b0: 6c 53 65 67 6d 65 6e 74 20 7b 0a 20 20 20 20 69  lSegment {.    i
57c0: 6e 74 20 69 4e 65 78 74 3b 20 20 20 20 20 20 20  nt iNext;       
57d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
57e0: 4e 65 78 74 20 73 6c 6f 74 20 69 6e 20 61 49 6e  Next slot in aIn
57f0: 64 65 78 5b 5d 20 6e 6f 74 20 79 65 74 20 72 65  dex[] not yet re
5800: 74 75 72 6e 65 64 20 2a 2f 0a 20 20 20 20 68 74  turned */.    ht
5810: 5f 73 6c 6f 74 20 2a 61 49 6e 64 65 78 3b 20 20  _slot *aIndex;  
5820: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
5830: 30 2c 20 69 31 2c 20 69 32 2e 2e 2e 20 73 75 63  0, i1, i2... suc
5840: 68 20 74 68 61 74 20 61 50 67 6e 6f 5b 69 4e 5d  h that aPgno[iN]
5850: 20 61 73 63 65 6e 64 20 2a 2f 0a 20 20 20 20 75   ascend */.    u
5860: 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20  32 *aPgno;      
5870: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5880: 41 72 72 61 79 20 6f 66 20 70 61 67 65 20 6e 75  Array of page nu
5890: 6d 62 65 72 73 2e 20 2a 2f 0a 20 20 20 20 69 6e  mbers. */.    in
58a0: 74 20 6e 45 6e 74 72 79 3b 20 20 20 20 20 20 20  t nEntry;       
58b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
58c0: 72 2e 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e  r. of entries in
58d0: 20 61 50 67 6e 6f 5b 5d 20 61 6e 64 20 61 49 6e   aPgno[] and aIn
58e0: 64 65 78 5b 5d 20 2a 2f 0a 20 20 20 20 69 6e 74  dex[] */.    int
58f0: 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20   iZero;         
5900: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
5910: 61 6d 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63  ame number assoc
5920: 69 61 74 65 64 20 77 69 74 68 20 61 50 67 6e 6f  iated with aPgno
5930: 5b 30 5d 20 2a 2f 0a 20 20 7d 20 61 53 65 67 6d  [0] */.  } aSegm
5940: 65 6e 74 5b 31 5d 3b 20 20 20 20 20 20 20 20 20  ent[1];         
5950: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20           /* One 
5960: 66 6f 72 20 65 76 65 72 79 20 33 32 4b 42 20 70  for every 32KB p
5970: 61 67 65 20 69 6e 20 74 68 65 20 77 61 6c 2d 69  age in the wal-i
5980: 6e 64 65 78 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  ndex */.};../*.*
5990: 2a 20 44 65 66 69 6e 65 20 74 68 65 20 70 61 72  * Define the par
59a0: 61 6d 65 74 65 72 73 20 6f 66 20 74 68 65 20 68  ameters of the h
59b0: 61 73 68 20 74 61 62 6c 65 73 20 69 6e 20 74 68  ash tables in th
59c0: 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65  e wal-index file
59d0: 2e 20 54 68 65 72 65 0a 2a 2a 20 69 73 20 61 20  . There.** is a 
59e0: 68 61 73 68 2d 74 61 62 6c 65 20 66 6f 6c 6c 6f  hash-table follo
59f0: 77 69 6e 67 20 65 76 65 72 79 20 48 41 53 48 54  wing every HASHT
5a00: 41 42 4c 45 5f 4e 50 41 47 45 20 70 61 67 65 20  ABLE_NPAGE page 
5a10: 6e 75 6d 62 65 72 73 20 69 6e 20 74 68 65 0a 2a  numbers in the.*
5a20: 2a 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2a 0a  * wal-index..**.
5a30: 2a 2a 20 43 68 61 6e 67 69 6e 67 20 61 6e 79 20  ** Changing any 
5a40: 6f 66 20 74 68 65 73 65 20 63 6f 6e 73 74 61 6e  of these constan
5a50: 74 73 20 77 69 6c 6c 20 61 6c 74 65 72 20 74 68  ts will alter th
5a60: 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 6f 72 6d  e wal-index form
5a70: 61 74 20 61 6e 64 0a 2a 2a 20 63 72 65 61 74 65  at and.** create
5a80: 20 69 6e 63 6f 6d 70 61 74 69 62 69 6c 69 74 69   incompatibiliti
5a90: 65 73 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 48  es..*/.#define H
5aa0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 20  ASHTABLE_NPAGE  
5ab0: 20 20 20 20 34 30 39 36 20 20 20 20 20 20 20 20      4096        
5ac0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 73 74           /* Must
5ad0: 20 62 65 20 70 6f 77 65 72 20 6f 66 20 32 20 2a   be power of 2 *
5ae0: 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48 54 41  /.#define HASHTA
5af0: 42 4c 45 5f 48 41 53 48 5f 31 20 20 20 20 20 33  BLE_HASH_1     3
5b00: 38 33 20 20 20 20 20 20 20 20 20 20 20 20 20 20  83              
5b10: 20 20 20 20 2f 2a 20 53 68 6f 75 6c 64 20 62 65      /* Should be
5b20: 20 70 72 69 6d 65 20 2a 2f 0a 23 64 65 66 69 6e   prime */.#defin
5b30: 65 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f  e HASHTABLE_NSLO
5b40: 54 20 20 20 20 20 20 28 48 41 53 48 54 41 42 4c  T      (HASHTABL
5b50: 45 5f 4e 50 41 47 45 2a 32 29 20 20 2f 2a 20 4d  E_NPAGE*2)  /* M
5b60: 75 73 74 20 62 65 20 61 20 70 6f 77 65 72 20 6f  ust be a power o
5b70: 66 20 32 20 2a 2f 0a 0a 2f 2a 20 0a 2a 2a 20 54  f 2 */../* .** T
5b80: 68 65 20 62 6c 6f 63 6b 20 6f 66 20 70 61 67 65  he block of page
5b90: 20 6e 75 6d 62 65 72 73 20 61 73 73 6f 63 69 61   numbers associa
5ba0: 74 65 64 20 77 69 74 68 20 74 68 65 20 66 69 72  ted with the fir
5bb0: 73 74 20 68 61 73 68 2d 74 61 62 6c 65 20 69 6e  st hash-table in
5bc0: 20 61 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20   a.** wal-index 
5bd0: 69 73 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20  is smaller than 
5be0: 75 73 75 61 6c 2e 20 54 68 69 73 20 69 73 20 73  usual. This is s
5bf0: 6f 20 74 68 61 74 20 74 68 65 72 65 20 69 73 20  o that there is 
5c00: 61 20 63 6f 6d 70 6c 65 74 65 0a 2a 2a 20 68 61  a complete.** ha
5c10: 73 68 2d 74 61 62 6c 65 20 6f 6e 20 65 61 63 68  sh-table on each
5c20: 20 61 6c 69 67 6e 65 64 20 33 32 4b 42 20 70 61   aligned 32KB pa
5c30: 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ge of the wal-in
5c40: 64 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  dex..*/.#define 
5c50: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
5c60: 4f 4e 45 20 20 28 48 41 53 48 54 41 42 4c 45 5f  ONE  (HASHTABLE_
5c70: 4e 50 41 47 45 20 2d 20 28 57 41 4c 49 4e 44 45  NPAGE - (WALINDE
5c80: 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f  X_HDR_SIZE/sizeo
5c90: 66 28 75 33 32 29 29 29 0a 0a 2f 2a 20 54 68 65  f(u32)))../* The
5ca0: 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 64 69   wal-index is di
5cb0: 76 69 64 65 64 20 69 6e 74 6f 20 70 61 67 65 73  vided into pages
5cc0: 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 50 47 53   of WALINDEX_PGS
5cd0: 5a 20 62 79 74 65 73 20 65 61 63 68 2e 20 2a 2f  Z bytes each. */
5ce0: 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45  .#define WALINDE
5cf0: 58 5f 50 47 53 5a 20 20 20 28 20 20 20 20 20 20  X_PGSZ   (      
5d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5d20: 20 20 20 5c 0a 20 20 20 20 73 69 7a 65 6f 66 28     \.    sizeof(
5d30: 68 74 5f 73 6c 6f 74 29 2a 48 41 53 48 54 41 42  ht_slot)*HASHTAB
5d40: 4c 45 5f 4e 53 4c 4f 54 20 2b 20 48 41 53 48 54  LE_NSLOT + HASHT
5d50: 41 42 4c 45 5f 4e 50 41 47 45 2a 73 69 7a 65 6f  ABLE_NPAGE*sizeo
5d60: 66 28 75 33 32 29 20 5c 0a 29 0a 0a 2f 2a 0a 2a  f(u32) \.)../*.*
5d70: 2a 20 4f 62 74 61 69 6e 20 61 20 70 6f 69 6e 74  * Obtain a point
5d80: 65 72 20 74 6f 20 74 68 65 20 69 50 61 67 65 27  er to the iPage'
5d90: 74 68 20 70 61 67 65 20 6f 66 20 74 68 65 20 77  th page of the w
5da0: 61 6c 2d 69 6e 64 65 78 2e 20 54 68 65 20 77 61  al-index. The wa
5db0: 6c 2d 69 6e 64 65 78 0a 2a 2a 20 69 73 20 62 72  l-index.** is br
5dc0: 6f 6b 65 6e 20 69 6e 74 6f 20 70 61 67 65 73 20  oken into pages 
5dd0: 6f 66 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a  of WALINDEX_PGSZ
5de0: 20 62 79 74 65 73 2e 20 57 61 6c 2d 69 6e 64 65   bytes. Wal-inde
5df0: 78 20 70 61 67 65 73 20 61 72 65 0a 2a 2a 20 6e  x pages are.** n
5e00: 75 6d 62 65 72 65 64 20 66 72 6f 6d 20 7a 65 72  umbered from zer
5e10: 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 69 73  o..**.** If this
5e20: 20 63 61 6c 6c 20 69 73 20 73 75 63 63 65 73 73   call is success
5e30: 66 75 6c 2c 20 2a 70 70 50 61 67 65 20 69 73 20  ful, *ppPage is 
5e40: 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  set to point to 
5e50: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a  the wal-index.**
5e60: 20 70 61 67 65 20 61 6e 64 20 53 51 4c 49 54 45   page and SQLITE
5e70: 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 2e  _OK is returned.
5e80: 20 49 66 20 61 6e 20 65 72 72 6f 72 20 28 61 6e   If an error (an
5e90: 20 4f 4f 4d 20 6f 72 20 56 46 53 20 65 72 72 6f   OOM or VFS erro
5ea0: 72 29 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 74 68  r) occurs,.** th
5eb0: 65 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  en an SQLite err
5ec0: 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  or code is retur
5ed0: 6e 65 64 20 61 6e 64 20 2a 70 70 50 61 67 65 20  ned and *ppPage 
5ee0: 69 73 20 73 65 74 20 74 6f 20 30 2e 0a 2a 2f 0a  is set to 0..*/.
5ef0: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e  static int walIn
5f00: 64 65 78 50 61 67 65 28 57 61 6c 20 2a 70 57 61  dexPage(Wal *pWa
5f10: 6c 2c 20 69 6e 74 20 69 50 61 67 65 2c 20 76 6f  l, int iPage, vo
5f20: 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 70 70 50  latile u32 **ppP
5f30: 61 67 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  age){.  int rc =
5f40: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f   SQLITE_OK;..  /
5f50: 2a 20 45 6e 6c 61 72 67 65 20 74 68 65 20 70 57  * Enlarge the pW
5f60: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 5d 20 61  al->apWiData[] a
5f70: 72 72 61 79 20 69 66 20 72 65 71 75 69 72 65 64  rray if required
5f80: 20 2a 2f 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e   */.  if( pWal->
5f90: 6e 57 69 44 61 74 61 3c 3d 69 50 61 67 65 20 29  nWiData<=iPage )
5fa0: 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20  {.    int nByte 
5fb0: 3d 20 73 69 7a 65 6f 66 28 75 33 32 2a 29 2a 28  = sizeof(u32*)*(
5fc0: 69 50 61 67 65 2b 31 29 3b 0a 20 20 20 20 76 6f  iPage+1);.    vo
5fd0: 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 61 70 4e  latile u32 **apN
5fe0: 65 77 3b 0a 20 20 20 20 61 70 4e 65 77 20 3d 20  ew;.    apNew = 
5ff0: 28 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a  (volatile u32 **
6000: 29 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63  )sqlite3_realloc
6010: 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d 3e 61  ((void *)pWal->a
6020: 70 57 69 44 61 74 61 2c 20 6e 42 79 74 65 29 3b  pWiData, nByte);
6030: 0a 20 20 20 20 69 66 28 20 21 61 70 4e 65 77 20  .    if( !apNew 
6040: 29 7b 0a 20 20 20 20 20 20 2a 70 70 50 61 67 65  ){.      *ppPage
6050: 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 65 74 75   = 0;.      retu
6060: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
6070: 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65  .    }.    memse
6080: 74 28 28 76 6f 69 64 2a 29 26 61 70 4e 65 77 5b  t((void*)&apNew[
6090: 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 5d 2c 20  pWal->nWiData], 
60a0: 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20 73 69  0,.           si
60b0: 7a 65 6f 66 28 75 33 32 2a 29 2a 28 69 50 61 67  zeof(u32*)*(iPag
60c0: 65 2b 31 2d 70 57 61 6c 2d 3e 6e 57 69 44 61 74  e+1-pWal->nWiDat
60d0: 61 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 61  a));.    pWal->a
60e0: 70 57 69 44 61 74 61 20 3d 20 61 70 4e 65 77 3b  pWiData = apNew;
60f0: 0a 20 20 20 20 70 57 61 6c 2d 3e 6e 57 69 44 61  .    pWal->nWiDa
6100: 74 61 20 3d 20 69 50 61 67 65 2b 31 3b 0a 20 20  ta = iPage+1;.  
6110: 7d 0a 0a 20 20 2f 2a 20 52 65 71 75 65 73 74 20  }..  /* Request 
6120: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65  a pointer to the
6130: 20 72 65 71 75 69 72 65 64 20 70 61 67 65 20 66   required page f
6140: 72 6f 6d 20 74 68 65 20 56 46 53 20 2a 2f 0a 20  rom the VFS */. 
6150: 20 69 66 28 20 70 57 61 6c 2d 3e 61 70 57 69 44   if( pWal->apWiD
6160: 61 74 61 5b 69 50 61 67 65 5d 3d 3d 30 20 29 7b  ata[iPage]==0 ){
6170: 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 65  .    if( pWal->e
6180: 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41  xclusiveMode==WA
6190: 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44  L_HEAPMEMORY_MOD
61a0: 45 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d  E ){.      pWal-
61b0: 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d  >apWiData[iPage]
61c0: 20 3d 20 28 75 33 32 20 76 6f 6c 61 74 69 6c 65   = (u32 volatile
61d0: 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   *)sqlite3Malloc
61e0: 5a 65 72 6f 28 57 41 4c 49 4e 44 45 58 5f 50 47  Zero(WALINDEX_PG
61f0: 53 5a 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21  SZ);.      if( !
6200: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69  pWal->apWiData[i
6210: 50 61 67 65 5d 20 29 20 72 63 20 3d 20 53 51 4c  Page] ) rc = SQL
6220: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
6230: 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d  else{.      rc =
6240: 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4d 61 70   sqlite3OsShmMap
6250: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 50  (pWal->pDbFd, iP
6260: 61 67 65 2c 20 57 41 4c 49 4e 44 45 58 5f 50 47  age, WALINDEX_PG
6270: 53 5a 2c 20 0a 20 20 20 20 20 20 20 20 20 20 70  SZ, .          p
6280: 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 2c 20  Wal->writeLock, 
6290: 28 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a  (void volatile *
62a0: 2a 29 26 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  *)&pWal->apWiDat
62b0: 61 5b 69 50 61 67 65 5d 0a 20 20 20 20 20 20 29  a[iPage].      )
62c0: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
62d0: 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 20  SQLITE_READONLY 
62e0: 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d  ){.        pWal-
62f0: 3e 72 65 61 64 4f 6e 6c 79 20 7c 3d 20 57 41 4c  >readOnly |= WAL
6300: 5f 53 48 4d 5f 52 44 4f 4e 4c 59 3b 0a 20 20 20  _SHM_RDONLY;.   
6310: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
6320: 5f 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  _OK;.      }.   
6330: 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 50 61 67   }.  }..  *ppPag
6340: 65 20 3d 20 70 57 61 6c 2d 3e 61 70 57 69 44 61  e = pWal->apWiDa
6350: 74 61 5b 69 50 61 67 65 5d 3b 0a 20 20 61 73 73  ta[iPage];.  ass
6360: 65 72 74 28 20 69 50 61 67 65 3d 3d 30 20 7c 7c  ert( iPage==0 ||
6370: 20 2a 70 70 50 61 67 65 20 7c 7c 20 72 63 21 3d   *ppPage || rc!=
6380: 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72  SQLITE_OK );.  r
6390: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
63a0: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  ** Return a poin
63b0: 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c 43 6b  ter to the WalCk
63c0: 70 74 49 6e 66 6f 20 73 74 72 75 63 74 75 72 65  ptInfo structure
63d0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
63e0: 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c  x..*/.static vol
63f0: 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66  atile WalCkptInf
6400: 6f 20 2a 77 61 6c 43 6b 70 74 49 6e 66 6f 28 57  o *walCkptInfo(W
6410: 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73  al *pWal){.  ass
6420: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
6430: 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70  ta>0 && pWal->ap
6440: 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72  WiData[0] );.  r
6450: 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20  eturn (volatile 
6460: 57 61 6c 43 6b 70 74 49 6e 66 6f 2a 29 26 28 70  WalCkptInfo*)&(p
6470: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
6480: 5b 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78  [sizeof(WalIndex
6490: 48 64 72 29 2f 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a  Hdr)/2]);.}../*.
64a0: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  ** Return a poin
64b0: 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c 49 6e  ter to the WalIn
64c0: 64 65 78 48 64 72 20 73 74 72 75 63 74 75 72 65  dexHdr structure
64d0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
64e0: 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c  x..*/.static vol
64f0: 61 74 69 6c 65 20 57 61 6c 49 6e 64 65 78 48 64  atile WalIndexHd
6500: 72 20 2a 77 61 6c 49 6e 64 65 78 48 64 72 28 57  r *walIndexHdr(W
6510: 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73  al *pWal){.  ass
6520: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
6530: 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70  ta>0 && pWal->ap
6540: 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72  WiData[0] );.  r
6550: 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20  eturn (volatile 
6560: 57 61 6c 49 6e 64 65 78 48 64 72 2a 29 70 57 61  WalIndexHdr*)pWa
6570: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 3b 0a  l->apWiData[0];.
6580: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61 72 67  }../*.** The arg
6590: 75 6d 65 6e 74 20 74 6f 20 74 68 69 73 20 6d 61  ument to this ma
65a0: 63 72 6f 20 6d 75 73 74 20 62 65 20 6f 66 20 74  cro must be of t
65b0: 79 70 65 20 75 33 32 2e 20 4f 6e 20 61 20 6c 69  ype u32. On a li
65c0: 74 74 6c 65 2d 65 6e 64 69 61 6e 0a 2a 2a 20 61  ttle-endian.** a
65d0: 72 63 68 69 74 65 63 74 75 72 65 2c 20 69 74 20  rchitecture, it 
65e0: 72 65 74 75 72 6e 73 20 74 68 65 20 75 33 32 20  returns the u32 
65f0: 76 61 6c 75 65 20 74 68 61 74 20 72 65 73 75 6c  value that resul
6600: 74 73 20 66 72 6f 6d 20 69 6e 74 65 72 70 72 65  ts from interpre
6610: 74 69 6e 67 0a 2a 2a 20 74 68 65 20 34 20 62 79  ting.** the 4 by
6620: 74 65 73 20 61 73 20 61 20 62 69 67 2d 65 6e 64  tes as a big-end
6630: 69 61 6e 20 76 61 6c 75 65 2e 20 4f 6e 20 61 20  ian value. On a 
6640: 62 69 67 2d 65 6e 64 69 61 6e 20 61 72 63 68 69  big-endian archi
6650: 74 65 63 74 75 72 65 2c 20 69 74 0a 2a 2a 20 72  tecture, it.** r
6660: 65 74 75 72 6e 73 20 74 68 65 20 76 61 6c 75 65  eturns the value
6670: 20 74 68 61 74 20 77 6f 75 6c 64 20 62 65 20 70   that would be p
6680: 72 6f 64 75 63 65 64 20 62 79 20 69 6e 74 65 70  roduced by intep
6690: 72 65 74 69 6e 67 20 74 68 65 20 34 20 62 79 74  reting the 4 byt
66a0: 65 73 0a 2a 2a 20 6f 66 20 74 68 65 20 69 6e 70  es.** of the inp
66b0: 75 74 20 76 61 6c 75 65 20 61 73 20 61 20 6c 69  ut value as a li
66c0: 74 74 6c 65 2d 65 6e 64 69 61 6e 20 69 6e 74 65  ttle-endian inte
66d0: 67 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  ger..*/.#define 
66e0: 42 59 54 45 53 57 41 50 33 32 28 78 29 20 28 20  BYTESWAP32(x) ( 
66f0: 5c 0a 20 20 20 20 28 28 28 78 29 26 30 78 30 30  \.    (((x)&0x00
6700: 30 30 30 30 46 46 29 3c 3c 32 34 29 20 2b 20 28  0000FF)<<24) + (
6710: 28 28 78 29 26 30 78 30 30 30 30 46 46 30 30 29  ((x)&0x0000FF00)
6720: 3c 3c 38 29 20 20 5c 0a 20 20 2b 20 28 28 28 78  <<8)  \.  + (((x
6730: 29 26 30 78 30 30 46 46 30 30 30 30 29 3e 3e 38  )&0x00FF0000)>>8
6740: 29 20 20 2b 20 28 28 28 78 29 26 30 78 46 46 30  )  + (((x)&0xFF0
6750: 30 30 30 30 30 29 3e 3e 32 34 29 20 5c 0a 29 0a  00000)>>24) \.).
6760: 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20  ./*.** Generate 
6770: 6f 72 20 65 78 74 65 6e 64 20 61 6e 20 38 20 62  or extend an 8 b
6780: 79 74 65 20 63 68 65 63 6b 73 75 6d 20 62 61 73  yte checksum bas
6790: 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 20 69  ed on the data i
67a0: 6e 20 0a 2a 2a 20 61 72 72 61 79 20 61 42 79 74  n .** array aByt
67b0: 65 5b 5d 20 61 6e 64 20 74 68 65 20 69 6e 69 74  e[] and the init
67c0: 69 61 6c 20 76 61 6c 75 65 73 20 6f 66 20 61 49  ial values of aI
67d0: 6e 5b 30 5d 20 61 6e 64 20 61 49 6e 5b 31 5d 20  n[0] and aIn[1] 
67e0: 28 6f 72 0a 2a 2a 20 69 6e 69 74 69 61 6c 20 76  (or.** initial v
67f0: 61 6c 75 65 73 20 6f 66 20 30 20 61 6e 64 20 30  alues of 0 and 0
6800: 20 69 66 20 61 49 6e 3d 3d 4e 55 4c 4c 29 2e 0a   if aIn==NULL)..
6810: 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b 73  **.** The checks
6820: 75 6d 20 69 73 20 77 72 69 74 74 65 6e 20 62 61  um is written ba
6830: 63 6b 20 69 6e 74 6f 20 61 4f 75 74 5b 5d 20 62  ck into aOut[] b
6840: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
6850: 0a 2a 2a 0a 2a 2a 20 6e 42 79 74 65 20 6d 75 73  .**.** nByte mus
6860: 74 20 62 65 20 61 20 70 6f 73 69 74 69 76 65 20  t be a positive 
6870: 6d 75 6c 74 69 70 6c 65 20 6f 66 20 38 2e 0a 2a  multiple of 8..*
6880: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61  /.static void wa
6890: 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28 0a  lChecksumBytes(.
68a0: 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73 75    int nativeCksu
68b0: 6d 2c 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e  m, /* True for n
68c0: 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64 65 72  ative byte-order
68d0: 2c 20 66 61 6c 73 65 20 66 6f 72 20 6e 6f 6e 2d  , false for non-
68e0: 6e 61 74 69 76 65 20 2a 2f 0a 20 20 75 38 20 2a  native */.  u8 *
68f0: 61 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  a,           /* 
6900: 43 6f 6e 74 65 6e 74 20 74 6f 20 62 65 20 63 68  Content to be ch
6910: 65 63 6b 73 75 6d 6d 65 64 20 2a 2f 0a 20 20 69  ecksummed */.  i
6920: 6e 74 20 6e 42 79 74 65 2c 20 20 20 20 20 20 20  nt nByte,       
6930: 2f 2a 20 42 79 74 65 73 20 6f 66 20 63 6f 6e 74  /* Bytes of cont
6940: 65 6e 74 20 69 6e 20 61 5b 5d 2e 20 20 4d 75 73  ent in a[].  Mus
6950: 74 20 62 65 20 61 20 6d 75 6c 74 69 70 6c 65 20  t be a multiple 
6960: 6f 66 20 38 2e 20 2a 2f 0a 20 20 63 6f 6e 73 74  of 8. */.  const
6970: 20 75 33 32 20 2a 61 49 6e 2c 20 20 2f 2a 20 49   u32 *aIn,  /* I
6980: 6e 69 74 69 61 6c 20 63 68 65 63 6b 73 75 6d 20  nitial checksum 
6990: 76 61 6c 75 65 20 69 6e 70 75 74 20 2a 2f 0a 20  value input */. 
69a0: 20 75 33 32 20 2a 61 4f 75 74 20 20 20 20 20 20   u32 *aOut      
69b0: 20 20 2f 2a 20 4f 55 54 3a 20 46 69 6e 61 6c 20    /* OUT: Final 
69c0: 63 68 65 63 6b 73 75 6d 20 76 61 6c 75 65 20 6f  checksum value o
69d0: 75 74 70 75 74 20 2a 2f 0a 29 7b 0a 20 20 75 33  utput */.){.  u3
69e0: 32 20 73 31 2c 20 73 32 3b 0a 20 20 75 33 32 20  2 s1, s2;.  u32 
69f0: 2a 61 44 61 74 61 20 3d 20 28 75 33 32 20 2a 29  *aData = (u32 *)
6a00: 61 3b 0a 20 20 75 33 32 20 2a 61 45 6e 64 20 3d  a;.  u32 *aEnd =
6a10: 20 28 75 33 32 20 2a 29 26 61 5b 6e 42 79 74 65   (u32 *)&a[nByte
6a20: 5d 3b 0a 0a 20 20 69 66 28 20 61 49 6e 20 29 7b  ];..  if( aIn ){
6a30: 0a 20 20 20 20 73 31 20 3d 20 61 49 6e 5b 30 5d  .    s1 = aIn[0]
6a40: 3b 0a 20 20 20 20 73 32 20 3d 20 61 49 6e 5b 31  ;.    s2 = aIn[1
6a50: 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  ];.  }else{.    
6a60: 73 31 20 3d 20 73 32 20 3d 20 30 3b 0a 20 20 7d  s1 = s2 = 0;.  }
6a70: 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 42 79 74  ..  assert( nByt
6a80: 65 3e 3d 38 20 29 3b 0a 20 20 61 73 73 65 72 74  e>=8 );.  assert
6a90: 28 20 28 6e 42 79 74 65 26 30 78 30 30 30 30 30  ( (nByte&0x00000
6aa0: 30 30 37 29 3d 3d 30 20 29 3b 0a 0a 20 20 69 66  007)==0 );..  if
6ab0: 28 20 6e 61 74 69 76 65 43 6b 73 75 6d 20 29 7b  ( nativeCksum ){
6ac0: 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 20  .    do {.      
6ad0: 73 31 20 2b 3d 20 2a 61 44 61 74 61 2b 2b 20 2b  s1 += *aData++ +
6ae0: 20 73 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d   s2;.      s2 +=
6af0: 20 2a 61 44 61 74 61 2b 2b 20 2b 20 73 31 3b 0a   *aData++ + s1;.
6b00: 20 20 20 20 7d 77 68 69 6c 65 28 20 61 44 61 74      }while( aDat
6b10: 61 3c 61 45 6e 64 20 29 3b 0a 20 20 7d 65 6c 73  a<aEnd );.  }els
6b20: 65 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20  e{.    do {.    
6b30: 20 20 73 31 20 2b 3d 20 42 59 54 45 53 57 41 50    s1 += BYTESWAP
6b40: 33 32 28 61 44 61 74 61 5b 30 5d 29 20 2b 20 73  32(aData[0]) + s
6b50: 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d 20 42  2;.      s2 += B
6b60: 59 54 45 53 57 41 50 33 32 28 61 44 61 74 61 5b  YTESWAP32(aData[
6b70: 31 5d 29 20 2b 20 73 31 3b 0a 20 20 20 20 20 20  1]) + s1;.      
6b80: 61 44 61 74 61 20 2b 3d 20 32 3b 0a 20 20 20 20  aData += 2;.    
6b90: 7d 77 68 69 6c 65 28 20 61 44 61 74 61 3c 61 45  }while( aData<aE
6ba0: 6e 64 20 29 3b 0a 20 20 7d 0a 0a 20 20 61 4f 75  nd );.  }..  aOu
6bb0: 74 5b 30 5d 20 3d 20 73 31 3b 0a 20 20 61 4f 75  t[0] = s1;.  aOu
6bc0: 74 5b 31 5d 20 3d 20 73 32 3b 0a 7d 0a 0a 73 74  t[1] = s2;.}..st
6bd0: 61 74 69 63 20 76 6f 69 64 20 77 61 6c 53 68 6d  atic void walShm
6be0: 42 61 72 72 69 65 72 28 57 61 6c 20 2a 70 57 61  Barrier(Wal *pWa
6bf0: 6c 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  l){.  if( pWal->
6c00: 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 21 3d 57  exclusiveMode!=W
6c10: 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f  AL_HEAPMEMORY_MO
6c20: 44 45 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  DE ){.    sqlite
6c30: 33 4f 73 53 68 6d 42 61 72 72 69 65 72 28 70 57  3OsShmBarrier(pW
6c40: 61 6c 2d 3e 70 44 62 46 64 29 3b 0a 20 20 7d 0a  al->pDbFd);.  }.
6c50: 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74  }../*.** Write t
6c60: 68 65 20 68 65 61 64 65 72 20 69 6e 66 6f 72 6d  he header inform
6c70: 61 74 69 6f 6e 20 69 6e 20 70 57 61 6c 2d 3e 68  ation in pWal->h
6c80: 64 72 20 69 6e 74 6f 20 74 68 65 20 77 61 6c 2d  dr into the wal-
6c90: 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  index..**.** The
6ca0: 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20 70 57 61   checksum on pWa
6cb0: 6c 2d 3e 68 64 72 20 69 73 20 75 70 64 61 74 65  l->hdr is update
6cc0: 64 20 62 65 66 6f 72 65 20 69 74 20 69 73 20 77  d before it is w
6cd0: 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69  ritten..*/.stati
6ce0: 63 20 76 6f 69 64 20 77 61 6c 49 6e 64 65 78 57  c void walIndexW
6cf0: 72 69 74 65 48 64 72 28 57 61 6c 20 2a 70 57 61  riteHdr(Wal *pWa
6d00: 6c 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57  l){.  volatile W
6d10: 61 6c 49 6e 64 65 78 48 64 72 20 2a 61 48 64 72  alIndexHdr *aHdr
6d20: 20 3d 20 77 61 6c 49 6e 64 65 78 48 64 72 28 70   = walIndexHdr(p
6d30: 57 61 6c 29 3b 0a 20 20 63 6f 6e 73 74 20 69 6e  Wal);.  const in
6d40: 74 20 6e 43 6b 73 75 6d 20 3d 20 6f 66 66 73 65  t nCksum = offse
6d50: 74 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 2c  tof(WalIndexHdr,
6d60: 20 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 61 73 73   aCksum);..  ass
6d70: 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65  ert( pWal->write
6d80: 4c 6f 63 6b 20 29 3b 0a 20 20 70 57 61 6c 2d 3e  Lock );.  pWal->
6d90: 68 64 72 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a  hdr.isInit = 1;.
6da0: 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56 65 72    pWal->hdr.iVer
6db0: 73 69 6f 6e 20 3d 20 57 41 4c 49 4e 44 45 58 5f  sion = WALINDEX_
6dc0: 4d 41 58 5f 56 45 52 53 49 4f 4e 3b 0a 20 20 77  MAX_VERSION;.  w
6dd0: 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
6de0: 31 2c 20 28 75 38 2a 29 26 70 57 61 6c 2d 3e 68  1, (u8*)&pWal->h
6df0: 64 72 2c 20 6e 43 6b 73 75 6d 2c 20 30 2c 20 70  dr, nCksum, 0, p
6e00: 57 61 6c 2d 3e 68 64 72 2e 61 43 6b 73 75 6d 29  Wal->hdr.aCksum)
6e10: 3b 0a 20 20 6d 65 6d 63 70 79 28 28 76 6f 69 64  ;.  memcpy((void
6e20: 20 2a 29 26 61 48 64 72 5b 31 5d 2c 20 28 76 6f   *)&aHdr[1], (vo
6e30: 69 64 20 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c  id *)&pWal->hdr,
6e40: 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
6e50: 48 64 72 29 29 3b 0a 20 20 77 61 6c 53 68 6d 42  Hdr));.  walShmB
6e60: 61 72 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20  arrier(pWal);.  
6e70: 6d 65 6d 63 70 79 28 28 76 6f 69 64 20 2a 29 26  memcpy((void *)&
6e80: 61 48 64 72 5b 30 5d 2c 20 28 76 6f 69 64 20 2a  aHdr[0], (void *
6e90: 29 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69 7a  )&pWal->hdr, siz
6ea0: 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29  eof(WalIndexHdr)
6eb0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  );.}../*.** This
6ec0: 20 66 75 6e 63 74 69 6f 6e 20 65 6e 63 6f 64 65   function encode
6ed0: 73 20 61 20 73 69 6e 67 6c 65 20 66 72 61 6d 65  s a single frame
6ee0: 20 68 65 61 64 65 72 20 61 6e 64 20 77 72 69 74   header and writ
6ef0: 65 73 20 69 74 20 74 6f 20 61 20 62 75 66 66 65  es it to a buffe
6f00: 72 0a 2a 2a 20 73 75 70 70 6c 69 65 64 20 62 79  r.** supplied by
6f10: 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 41 20 66   the caller. A f
6f20: 72 61 6d 65 2d 68 65 61 64 65 72 20 69 73 20 6d  rame-header is m
6f30: 61 64 65 20 75 70 20 6f 66 20 61 20 73 65 72 69  ade up of a seri
6f40: 65 73 20 6f 66 20 0a 2a 2a 20 34 2d 62 79 74 65  es of .** 4-byte
6f50: 20 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65   big-endian inte
6f60: 67 65 72 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73  gers, as follows
6f70: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 30 3a 20 50  :.**.**     0: P
6f80: 61 67 65 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20  age number..**  
6f90: 20 20 20 34 3a 20 46 6f 72 20 63 6f 6d 6d 69 74     4: For commit
6fa0: 20 72 65 63 6f 72 64 73 2c 20 74 68 65 20 73 69   records, the si
6fb0: 7a 65 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  ze of the databa
6fc0: 73 65 20 69 6d 61 67 65 20 69 6e 20 70 61 67 65  se image in page
6fd0: 73 20 0a 2a 2a 20 20 20 20 20 20 20 20 61 66 74  s .**        aft
6fe0: 65 72 20 74 68 65 20 63 6f 6d 6d 69 74 2e 20 46  er the commit. F
6ff0: 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 72 65 63  or all other rec
7000: 6f 72 64 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20  ords, zero..**  
7010: 20 20 20 38 3a 20 53 61 6c 74 2d 31 20 28 63 6f     8: Salt-1 (co
7020: 70 69 65 64 20 66 72 6f 6d 20 74 68 65 20 77 61  pied from the wa
7030: 6c 2d 68 65 61 64 65 72 29 0a 2a 2a 20 20 20 20  l-header).**    
7040: 31 32 3a 20 53 61 6c 74 2d 32 20 28 63 6f 70 69  12: Salt-2 (copi
7050: 65 64 20 66 72 6f 6d 20 74 68 65 20 77 61 6c 2d  ed from the wal-
7060: 68 65 61 64 65 72 29 0a 2a 2a 20 20 20 20 31 36  header).**    16
7070: 3a 20 43 68 65 63 6b 73 75 6d 2d 31 2e 0a 2a 2a  : Checksum-1..**
7080: 20 20 20 20 32 30 3a 20 43 68 65 63 6b 73 75 6d      20: Checksum
7090: 2d 32 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  -2..*/.static vo
70a0: 69 64 20 77 61 6c 45 6e 63 6f 64 65 46 72 61 6d  id walEncodeFram
70b0: 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20  e(.  Wal *pWal, 
70c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
70d0: 20 20 20 20 20 2f 2a 20 54 68 65 20 77 72 69 74       /* The writ
70e0: 65 2d 61 68 65 61 64 20 6c 6f 67 20 2a 2f 0a 20  e-ahead log */. 
70f0: 20 75 33 32 20 69 50 61 67 65 2c 20 20 20 20 20   u32 iPage,     
7100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7110: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67   /* Database pag
7120: 65 20 6e 75 6d 62 65 72 20 66 6f 72 20 66 72 61  e number for fra
7130: 6d 65 20 2a 2f 0a 20 20 75 33 32 20 6e 54 72 75  me */.  u32 nTru
7140: 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20 20 20  ncate,          
7150: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 64          /* New d
7160: 62 20 73 69 7a 65 20 28 6f 72 20 30 20 66 6f 72  b size (or 0 for
7170: 20 6e 6f 6e 2d 63 6f 6d 6d 69 74 20 66 72 61 6d   non-commit fram
7180: 65 73 29 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61  es) */.  u8 *aDa
7190: 74 61 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ta,             
71a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
71b0: 74 65 72 20 74 6f 20 70 61 67 65 20 64 61 74 61  ter to page data
71c0: 20 2a 2f 0a 20 20 75 38 20 2a 61 46 72 61 6d 65   */.  u8 *aFrame
71d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71e0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 57 72        /* OUT: Wr
71f0: 69 74 65 20 65 6e 63 6f 64 65 64 20 66 72 61 6d  ite encoded fram
7200: 65 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 69  e here */.){.  i
7210: 6e 74 20 6e 61 74 69 76 65 43 6b 73 75 6d 3b 20  nt nativeCksum; 
7220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7230: 2a 20 54 72 75 65 20 66 6f 72 20 6e 61 74 69 76  * True for nativ
7240: 65 20 62 79 74 65 2d 6f 72 64 65 72 20 63 68 65  e byte-order che
7250: 63 6b 73 75 6d 73 20 2a 2f 0a 20 20 75 33 32 20  cksums */.  u32 
7260: 2a 61 43 6b 73 75 6d 20 3d 20 70 57 61 6c 2d 3e  *aCksum = pWal->
7270: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 3b  hdr.aFrameCksum;
7280: 0a 20 20 61 73 73 65 72 74 28 20 57 41 4c 5f 46  .  assert( WAL_F
7290: 52 41 4d 45 5f 48 44 52 53 49 5a 45 3d 3d 32 34  RAME_HDRSIZE==24
72a0: 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74   );.  sqlite3Put
72b0: 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 30 5d  4byte(&aFrame[0]
72c0: 2c 20 69 50 61 67 65 29 3b 0a 20 20 73 71 6c 69  , iPage);.  sqli
72d0: 74 65 33 50 75 74 34 62 79 74 65 28 26 61 46 72  te3Put4byte(&aFr
72e0: 61 6d 65 5b 34 5d 2c 20 6e 54 72 75 6e 63 61 74  ame[4], nTruncat
72f0: 65 29 3b 0a 20 20 6d 65 6d 63 70 79 28 26 61 46  e);.  memcpy(&aF
7300: 72 61 6d 65 5b 38 5d 2c 20 70 57 61 6c 2d 3e 68  rame[8], pWal->h
7310: 64 72 2e 61 53 61 6c 74 2c 20 38 29 3b 0a 0a 20  dr.aSalt, 8);.. 
7320: 20 6e 61 74 69 76 65 43 6b 73 75 6d 20 3d 20 28   nativeCksum = (
7330: 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64  pWal->hdr.bigEnd
7340: 43 6b 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49  Cksum==SQLITE_BI
7350: 47 45 4e 44 49 41 4e 29 3b 0a 20 20 77 61 6c 43  GENDIAN);.  walC
7360: 68 65 63 6b 73 75 6d 42 79 74 65 73 28 6e 61 74  hecksumBytes(nat
7370: 69 76 65 43 6b 73 75 6d 2c 20 61 46 72 61 6d 65  iveCksum, aFrame
7380: 2c 20 38 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b  , 8, aCksum, aCk
7390: 73 75 6d 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b  sum);.  walCheck
73a0: 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43  sumBytes(nativeC
73b0: 6b 73 75 6d 2c 20 61 44 61 74 61 2c 20 70 57 61  ksum, aData, pWa
73c0: 6c 2d 3e 73 7a 50 61 67 65 2c 20 61 43 6b 73 75  l->szPage, aCksu
73d0: 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 73  m, aCksum);..  s
73e0: 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
73f0: 61 46 72 61 6d 65 5b 31 36 5d 2c 20 61 43 6b 73  aFrame[16], aCks
7400: 75 6d 5b 30 5d 29 3b 0a 20 20 73 71 6c 69 74 65  um[0]);.  sqlite
7410: 33 50 75 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Put4byte(&aFram
7420: 65 5b 32 30 5d 2c 20 61 43 6b 73 75 6d 5b 31 5d  e[20], aCksum[1]
7430: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63  );.}../*.** Chec
7440: 6b 20 74 6f 20 73 65 65 20 69 66 20 74 68 65 20  k to see if the 
7450: 66 72 61 6d 65 20 77 69 74 68 20 68 65 61 64 65  frame with heade
7460: 72 20 69 6e 20 61 46 72 61 6d 65 5b 5d 20 61 6e  r in aFrame[] an
7470: 64 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 69 6e 20  d content.** in 
7480: 61 44 61 74 61 5b 5d 20 69 73 20 76 61 6c 69 64  aData[] is valid
7490: 2e 20 20 49 66 20 69 74 20 69 73 20 61 20 76 61  .  If it is a va
74a0: 6c 69 64 20 66 72 61 6d 65 2c 20 66 69 6c 6c 20  lid frame, fill 
74b0: 2a 70 69 50 61 67 65 20 61 6e 64 0a 2a 2a 20 2a  *piPage and.** *
74c0: 70 6e 54 72 75 6e 63 61 74 65 20 61 6e 64 20 72  pnTruncate and r
74d0: 65 74 75 72 6e 20 74 72 75 65 2e 20 20 52 65 74  eturn true.  Ret
74e0: 75 72 6e 20 69 66 20 74 68 65 20 66 72 61 6d 65  urn if the frame
74f0: 20 69 73 20 6e 6f 74 20 76 61 6c 69 64 2e 0a 2a   is not valid..*
7500: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
7510: 44 65 63 6f 64 65 46 72 61 6d 65 28 0a 20 20 57  DecodeFrame(.  W
7520: 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20  al *pWal,       
7530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7540: 2a 20 54 68 65 20 77 72 69 74 65 2d 61 68 65 61  * The write-ahea
7550: 64 20 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 2a  d log */.  u32 *
7560: 70 69 50 61 67 65 2c 20 20 20 20 20 20 20 20 20  piPage,         
7570: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
7580: 54 3a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  T: Database page
7590: 20 6e 75 6d 62 65 72 20 66 6f 72 20 66 72 61 6d   number for fram
75a0: 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70 6e 54 72  e */.  u32 *pnTr
75b0: 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20 20  uncate,         
75c0: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e         /* OUT: N
75d0: 65 77 20 64 62 20 73 69 7a 65 20 28 6f 72 20 30  ew db size (or 0
75e0: 20 69 66 20 6e 6f 74 20 63 6f 6d 6d 69 74 29 20   if not commit) 
75f0: 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74 61 2c 20  */.  u8 *aData, 
7600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7610: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
7620: 74 6f 20 70 61 67 65 20 64 61 74 61 20 28 66 6f  to page data (fo
7630: 72 20 63 68 65 63 6b 73 75 6d 29 20 2a 2f 0a 20  r checksum) */. 
7640: 20 75 38 20 2a 61 46 72 61 6d 65 20 20 20 20 20   u8 *aFrame     
7650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7660: 20 2f 2a 20 46 72 61 6d 65 20 64 61 74 61 20 2a   /* Frame data *
7670: 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 61 74 69 76  /.){.  int nativ
7680: 65 43 6b 73 75 6d 3b 20 20 20 20 20 20 20 20 20  eCksum;         
7690: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 66         /* True f
76a0: 6f 72 20 6e 61 74 69 76 65 20 62 79 74 65 2d 6f  or native byte-o
76b0: 72 64 65 72 20 63 68 65 63 6b 73 75 6d 73 20 2a  rder checksums *
76c0: 2f 0a 20 20 75 33 32 20 2a 61 43 6b 73 75 6d 20  /.  u32 *aCksum 
76d0: 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61  = pWal->hdr.aFra
76e0: 6d 65 43 6b 73 75 6d 3b 0a 20 20 75 33 32 20 70  meCksum;.  u32 p
76f0: 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20  gno;            
7700: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
7710: 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65  ge number of the
7720: 20 66 72 61 6d 65 20 2a 2f 0a 20 20 61 73 73 65   frame */.  asse
7730: 72 74 28 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44  rt( WAL_FRAME_HD
7740: 52 53 49 5a 45 3d 3d 32 34 20 29 3b 0a 0a 20 20  RSIZE==24 );..  
7750: 2f 2a 20 41 20 66 72 61 6d 65 20 69 73 20 6f 6e  /* A frame is on
7760: 6c 79 20 76 61 6c 69 64 20 69 66 20 74 68 65 20  ly valid if the 
7770: 73 61 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74  salt values in t
7780: 68 65 20 66 72 61 6d 65 2d 68 65 61 64 65 72 0a  he frame-header.
7790: 20 20 2a 2a 20 6d 61 74 63 68 20 74 68 65 20 73    ** match the s
77a0: 61 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68  alt values in th
77b0: 65 20 77 61 6c 2d 68 65 61 64 65 72 2e 20 0a 20  e wal-header. . 
77c0: 20 2a 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70   */.  if( memcmp
77d0: 28 26 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c  (&pWal->hdr.aSal
77e0: 74 2c 20 26 61 46 72 61 6d 65 5b 38 5d 2c 20 38  t, &aFrame[8], 8
77f0: 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )!=0 ){.    retu
7800: 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  rn 0;.  }..  /* 
7810: 41 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20  A frame is only 
7820: 76 61 6c 69 64 20 69 66 20 74 68 65 20 70 61 67  valid if the pag
7830: 65 20 6e 75 6d 62 65 72 20 69 73 20 63 72 65 61  e number is crea
7840: 74 65 72 20 74 68 61 6e 20 7a 65 72 6f 2e 0a 20  ter than zero.. 
7850: 20 2a 2f 0a 20 20 70 67 6e 6f 20 3d 20 73 71 6c   */.  pgno = sql
7860: 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61 46  ite3Get4byte(&aF
7870: 72 61 6d 65 5b 30 5d 29 3b 0a 20 20 69 66 28 20  rame[0]);.  if( 
7880: 70 67 6e 6f 3d 3d 30 20 29 7b 0a 20 20 20 20 72  pgno==0 ){.    r
7890: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20  eturn 0;.  }..  
78a0: 2f 2a 20 41 20 66 72 61 6d 65 20 69 73 20 6f 6e  /* A frame is on
78b0: 6c 79 20 76 61 6c 69 64 20 69 66 20 61 20 63 68  ly valid if a ch
78c0: 65 63 6b 73 75 6d 20 6f 66 20 74 68 65 20 57 41  ecksum of the WA
78d0: 4c 20 68 65 61 64 65 72 2c 0a 20 20 2a 2a 20 61  L header,.  ** a
78e0: 6c 6c 20 70 72 69 6f 72 20 66 72 61 6d 73 2c 20  ll prior frams, 
78f0: 74 68 65 20 66 69 72 73 74 20 31 36 20 62 79 74  the first 16 byt
7900: 65 73 20 6f 66 20 74 68 69 73 20 66 72 61 6d 65  es of this frame
7910: 2d 68 65 61 64 65 72 2c 20 0a 20 20 2a 2a 20 61  -header, .  ** a
7920: 6e 64 20 74 68 65 20 66 72 61 6d 65 2d 64 61 74  nd the frame-dat
7930: 61 20 6d 61 74 63 68 65 73 20 74 68 65 20 63 68  a matches the ch
7940: 65 63 6b 73 75 6d 20 69 6e 20 74 68 65 20 6c 61  ecksum in the la
7950: 73 74 20 38 20 0a 20 20 2a 2a 20 62 79 74 65 73  st 8 .  ** bytes
7960: 20 6f 66 20 74 68 69 73 20 66 72 61 6d 65 2d 68   of this frame-h
7970: 65 61 64 65 72 2e 0a 20 20 2a 2f 0a 20 20 6e 61  eader..  */.  na
7980: 74 69 76 65 43 6b 73 75 6d 20 3d 20 28 70 57 61  tiveCksum = (pWa
7990: 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73  l->hdr.bigEndCks
79a0: 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e  um==SQLITE_BIGEN
79b0: 44 49 41 4e 29 3b 0a 20 20 77 61 6c 43 68 65 63  DIAN);.  walChec
79c0: 6b 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65  ksumBytes(native
79d0: 43 6b 73 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38  Cksum, aFrame, 8
79e0: 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d  , aCksum, aCksum
79f0: 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d  );.  walChecksum
7a00: 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75  Bytes(nativeCksu
7a10: 6d 2c 20 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e  m, aData, pWal->
7a20: 73 7a 50 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20  szPage, aCksum, 
7a30: 61 43 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20 61  aCksum);.  if( a
7a40: 43 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65  Cksum[0]!=sqlite
7a50: 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Get4byte(&aFram
7a60: 65 5b 31 36 5d 29 20 0a 20 20 20 7c 7c 20 61 43  e[16]) .   || aC
7a70: 6b 73 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33  ksum[1]!=sqlite3
7a80: 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Get4byte(&aFrame
7a90: 5b 32 30 5d 29 20 0a 20 20 29 7b 0a 20 20 20 20  [20]) .  ){.    
7aa0: 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66 61 69 6c  /* Checksum fail
7ab0: 65 64 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72  ed. */.    retur
7ac0: 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49  n 0;.  }..  /* I
7ad0: 66 20 77 65 20 72 65 61 63 68 20 74 68 69 73 20  f we reach this 
7ae0: 70 6f 69 6e 74 2c 20 74 68 65 20 66 72 61 6d 65  point, the frame
7af0: 20 69 73 20 76 61 6c 69 64 2e 20 20 52 65 74 75   is valid.  Retu
7b00: 72 6e 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62  rn the page numb
7b10: 65 72 0a 20 20 2a 2a 20 61 6e 64 20 74 68 65 20  er.  ** and the 
7b20: 6e 65 77 20 64 61 74 61 62 61 73 65 20 73 69 7a  new database siz
7b30: 65 2e 0a 20 20 2a 2f 0a 20 20 2a 70 69 50 61 67  e..  */.  *piPag
7b40: 65 20 3d 20 70 67 6e 6f 3b 0a 20 20 2a 70 6e 54  e = pgno;.  *pnT
7b50: 72 75 6e 63 61 74 65 20 3d 20 73 71 6c 69 74 65  runcate = sqlite
7b60: 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Get4byte(&aFram
7b70: 65 5b 34 5d 29 3b 0a 20 20 72 65 74 75 72 6e 20  e[4]);.  return 
7b80: 31 3b 0a 7d 0a 0a 0a 23 69 66 20 64 65 66 69 6e  1;.}...#if defin
7b90: 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20  ed(SQLITE_TEST) 
7ba0: 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  && defined(SQLIT
7bb0: 45 5f 44 45 42 55 47 29 0a 2f 2a 0a 2a 2a 20 4e  E_DEBUG)./*.** N
7bc0: 61 6d 65 73 20 6f 66 20 6c 6f 63 6b 73 2e 20 20  ames of locks.  
7bd0: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20  This routine is 
7be0: 75 73 65 64 20 74 6f 20 70 72 6f 76 69 64 65 20  used to provide 
7bf0: 64 65 62 75 67 67 69 6e 67 20 6f 75 74 70 75 74  debugging output
7c00: 20 61 6e 64 20 69 73 20 6e 6f 74 0a 2a 2a 20 61   and is not.** a
7c10: 20 70 61 72 74 20 6f 66 20 61 6e 20 6f 72 64 69   part of an ordi
7c20: 6e 61 72 79 20 62 75 69 6c 64 2e 0a 2a 2f 0a 73  nary build..*/.s
7c30: 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72  tatic const char
7c40: 20 2a 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 69 6e   *walLockName(in
7c50: 74 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66  t lockIdx){.  if
7c60: 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 57  ( lockIdx==WAL_W
7c70: 52 49 54 45 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20  RITE_LOCK ){.   
7c80: 20 72 65 74 75 72 6e 20 22 57 52 49 54 45 2d 4c   return "WRITE-L
7c90: 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66  OCK";.  }else if
7ca0: 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 43  ( lockIdx==WAL_C
7cb0: 4b 50 54 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20  KPT_LOCK ){.    
7cc0: 72 65 74 75 72 6e 20 22 43 4b 50 54 2d 4c 4f 43  return "CKPT-LOC
7cd0: 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20  K";.  }else if( 
7ce0: 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 52 45 43  lockIdx==WAL_REC
7cf0: 4f 56 45 52 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20  OVER_LOCK ){.   
7d00: 20 72 65 74 75 72 6e 20 22 52 45 43 4f 56 45 52   return "RECOVER
7d10: 2d 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 7b  -LOCK";.  }else{
7d20: 0a 20 20 20 20 73 74 61 74 69 63 20 63 68 61 72  .    static char
7d30: 20 7a 4e 61 6d 65 5b 31 35 5d 3b 0a 20 20 20 20   zName[15];.    
7d40: 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66  sqlite3_snprintf
7d50: 28 73 69 7a 65 6f 66 28 7a 4e 61 6d 65 29 2c 20  (sizeof(zName), 
7d60: 7a 4e 61 6d 65 2c 20 22 52 45 41 44 2d 4c 4f 43  zName, "READ-LOC
7d70: 4b 5b 25 64 5d 22 2c 0a 20 20 20 20 20 20 20 20  K[%d]",.        
7d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 63               loc
7d90: 6b 49 64 78 2d 57 41 4c 5f 52 45 41 44 5f 4c 4f  kIdx-WAL_READ_LO
7da0: 43 4b 28 30 29 29 3b 0a 20 20 20 20 72 65 74 75  CK(0));.    retu
7db0: 72 6e 20 7a 4e 61 6d 65 3b 0a 20 20 7d 0a 7d 0a  rn zName;.  }.}.
7dc0: 23 65 6e 64 69 66 20 2f 2a 64 65 66 69 6e 65 64  #endif /*defined
7dd0: 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 7c 7c  (SQLITE_TEST) ||
7de0: 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
7df0: 44 45 42 55 47 29 20 2a 2f 0a 20 20 20 20 0a 0a  DEBUG) */.    ..
7e00: 2f 2a 0a 2a 2a 20 53 65 74 20 6f 72 20 72 65 6c  /*.** Set or rel
7e10: 65 61 73 65 20 6c 6f 63 6b 73 20 6f 6e 20 74 68  ease locks on th
7e20: 65 20 57 41 4c 2e 20 20 4c 6f 63 6b 73 20 61 72  e WAL.  Locks ar
7e30: 65 20 65 69 74 68 65 72 20 73 68 61 72 65 64 20  e either shared 
7e40: 6f 72 20 65 78 63 6c 75 73 69 76 65 2e 0a 2a 2a  or exclusive..**
7e50: 20 41 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62   A lock cannot b
7e60: 65 20 6d 6f 76 65 64 20 64 69 72 65 63 74 6c 79  e moved directly
7e70: 20 62 65 74 77 65 65 6e 20 73 68 61 72 65 64 20   between shared 
7e80: 61 6e 64 20 65 78 63 6c 75 73 69 76 65 20 2d 20  and exclusive - 
7e90: 69 74 20 6d 75 73 74 20 67 6f 0a 2a 2a 20 74 68  it must go.** th
7ea0: 72 6f 75 67 68 20 74 68 65 20 75 6e 6c 6f 63 6b  rough the unlock
7eb0: 65 64 20 73 74 61 74 65 20 66 69 72 73 74 2e 0a  ed state first..
7ec0: 2a 2a 0a 2a 2a 20 49 6e 20 6c 6f 63 6b 69 6e 67  **.** In locking
7ed0: 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2c  _mode=EXCLUSIVE,
7ee0: 20 61 6c 6c 20 6f 66 20 74 68 65 73 65 20 72 6f   all of these ro
7ef0: 75 74 69 6e 65 73 20 62 65 63 6f 6d 65 20 6e 6f  utines become no
7f00: 2d 6f 70 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  -ops..*/.static 
7f10: 69 6e 74 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65  int walLockShare
7f20: 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  d(Wal *pWal, int
7f30: 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 6e 74   lockIdx){.  int
7f40: 20 72 63 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d   rc;.  if( pWal-
7f50: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29  >exclusiveMode )
7f60: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
7f70: 4b 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  K;.  rc = sqlite
7f80: 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d  3OsShmLock(pWal-
7f90: 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c  >pDbFd, lockIdx,
7fa0: 20 31 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20   1,.            
7fb0: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
7fc0: 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51  TE_SHM_LOCK | SQ
7fd0: 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29  LITE_SHM_SHARED)
7fe0: 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
7ff0: 41 4c 25 70 3a 20 61 63 71 75 69 72 65 20 53 48  AL%p: acquire SH
8000: 41 52 45 44 2d 25 73 20 25 73 5c 6e 22 2c 20 70  ARED-%s %s\n", p
8010: 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20 20  Wal,.           
8020: 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63   walLockName(loc
8030: 6b 49 64 78 29 2c 20 72 63 20 3f 20 22 66 61 69  kIdx), rc ? "fai
8040: 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
8050: 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d   VVA_ONLY( pWal-
8060: 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20 28 75 38  >lockError = (u8
8070: 29 28 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  )(rc!=SQLITE_OK 
8080: 26 26 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55  && rc!=SQLITE_BU
8090: 53 59 29 3b 20 29 0a 20 20 72 65 74 75 72 6e 20  SY); ).  return 
80a0: 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  rc;.}.static voi
80b0: 64 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65  d walUnlockShare
80c0: 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  d(Wal *pWal, int
80d0: 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66 28   lockIdx){.  if(
80e0: 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
80f0: 4d 6f 64 65 20 29 20 72 65 74 75 72 6e 3b 0a 20  Mode ) return;. 
8100: 20 28 76 6f 69 64 29 73 71 6c 69 74 65 33 4f 73   (void)sqlite3Os
8110: 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44  ShmLock(pWal->pD
8120: 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 31 2c  bFd, lockIdx, 1,
8130: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
8140: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
8150: 5f 53 48 4d 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51  _SHM_UNLOCK | SQ
8160: 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29  LITE_SHM_SHARED)
8170: 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
8180: 41 4c 25 70 3a 20 72 65 6c 65 61 73 65 20 53 48  AL%p: release SH
8190: 41 52 45 44 2d 25 73 5c 6e 22 2c 20 70 57 61 6c  ARED-%s\n", pWal
81a0: 2c 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f  , walLockName(lo
81b0: 63 6b 49 64 78 29 29 29 3b 0a 7d 0a 73 74 61 74  ckIdx)));.}.stat
81c0: 69 63 20 69 6e 74 20 77 61 6c 4c 6f 63 6b 45 78  ic int walLockEx
81d0: 63 6c 75 73 69 76 65 28 57 61 6c 20 2a 70 57 61  clusive(Wal *pWa
81e0: 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 2c 20  l, int lockIdx, 
81f0: 69 6e 74 20 6e 29 7b 0a 20 20 69 6e 74 20 72 63  int n){.  int rc
8200: 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78  ;.  if( pWal->ex
8210: 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65  clusiveMode ) re
8220: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
8230: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
8240: 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44  ShmLock(pWal->pD
8250: 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c  bFd, lockIdx, n,
8260: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
8270: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
8280: 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49 54  SHM_LOCK | SQLIT
8290: 45 5f 53 48 4d 5f 45 58 43 4c 55 53 49 56 45 29  E_SHM_EXCLUSIVE)
82a0: 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
82b0: 41 4c 25 70 3a 20 61 63 71 75 69 72 65 20 45 58  AL%p: acquire EX
82c0: 43 4c 55 53 49 56 45 2d 25 73 20 63 6e 74 3d 25  CLUSIVE-%s cnt=%
82d0: 64 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20  d %s\n", pWal,. 
82e0: 20 20 20 20 20 20 20 20 20 20 20 77 61 6c 4c 6f             walLo
82f0: 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c  ckName(lockIdx),
8300: 20 6e 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64   n, rc ? "failed
8310: 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 56 56  " : "ok"));.  VV
8320: 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f  A_ONLY( pWal->lo
8330: 63 6b 45 72 72 6f 72 20 3d 20 28 75 38 29 28 72  ckError = (u8)(r
8340: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c!=SQLITE_OK && 
8350: 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 29  rc!=SQLITE_BUSY)
8360: 3b 20 29 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ; ).  return rc;
8370: 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  .}.static void w
8380: 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
8390: 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  e(Wal *pWal, int
83a0: 20 6c 6f 63 6b 49 64 78 2c 20 69 6e 74 20 6e 29   lockIdx, int n)
83b0: 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78  {.  if( pWal->ex
83c0: 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65  clusiveMode ) re
83d0: 74 75 72 6e 3b 0a 20 20 28 76 6f 69 64 29 73 71  turn;.  (void)sq
83e0: 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70  lite3OsShmLock(p
83f0: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b  Wal->pDbFd, lock
8400: 49 64 78 2c 20 6e 2c 0a 20 20 20 20 20 20 20 20  Idx, n,.        
8410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8420: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f   SQLITE_SHM_UNLO
8430: 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f  CK | SQLITE_SHM_
8440: 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20 57 41  EXCLUSIVE);.  WA
8450: 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20  LTRACE(("WAL%p: 
8460: 72 65 6c 65 61 73 65 20 45 58 43 4c 55 53 49 56  release EXCLUSIV
8470: 45 2d 25 73 20 63 6e 74 3d 25 64 5c 6e 22 2c 20  E-%s cnt=%d\n", 
8480: 70 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20  pWal,.          
8490: 20 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c     walLockName(l
84a0: 6f 63 6b 49 64 78 29 2c 20 6e 29 29 3b 0a 7d 0a  ockIdx), n));.}.
84b0: 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61  ./*.** Compute a
84c0: 20 68 61 73 68 20 6f 6e 20 61 20 70 61 67 65 20   hash on a page 
84d0: 6e 75 6d 62 65 72 2e 20 20 54 68 65 20 72 65 73  number.  The res
84e0: 75 6c 74 69 6e 67 20 68 61 73 68 20 76 61 6c 75  ulting hash valu
84f0: 65 20 6d 75 73 74 20 6c 61 6e 64 0a 2a 2a 20 62  e must land.** b
8500: 65 74 77 65 65 6e 20 30 20 61 6e 64 20 28 48 41  etween 0 and (HA
8510: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29  SHTABLE_NSLOT-1)
8520: 2e 20 20 54 68 65 20 77 61 6c 48 61 73 68 4e 65  .  The walHashNe
8530: 78 74 28 29 20 66 75 6e 63 74 69 6f 6e 20 61 64  xt() function ad
8540: 76 61 6e 63 65 73 0a 2a 2a 20 74 68 65 20 68 61  vances.** the ha
8550: 73 68 20 74 6f 20 74 68 65 20 6e 65 78 74 20 76  sh to the next v
8560: 61 6c 75 65 20 69 6e 20 74 68 65 20 65 76 65 6e  alue in the even
8570: 74 20 6f 66 20 61 20 63 6f 6c 6c 69 73 69 6f 6e  t of a collision
8580: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
8590: 77 61 6c 48 61 73 68 28 75 33 32 20 69 50 61 67  walHash(u32 iPag
85a0: 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69 50  e){.  assert( iP
85b0: 61 67 65 3e 30 20 29 3b 0a 20 20 61 73 73 65 72  age>0 );.  asser
85c0: 74 28 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 53  t( (HASHTABLE_NS
85d0: 4c 4f 54 20 26 20 28 48 41 53 48 54 41 42 4c 45  LOT & (HASHTABLE
85e0: 5f 4e 53 4c 4f 54 2d 31 29 29 3d 3d 30 20 29 3b  _NSLOT-1))==0 );
85f0: 0a 20 20 72 65 74 75 72 6e 20 28 69 50 61 67 65  .  return (iPage
8600: 2a 48 41 53 48 54 41 42 4c 45 5f 48 41 53 48 5f  *HASHTABLE_HASH_
8610: 31 29 20 26 20 28 48 41 53 48 54 41 42 4c 45 5f  1) & (HASHTABLE_
8620: 4e 53 4c 4f 54 2d 31 29 3b 0a 7d 0a 73 74 61 74  NSLOT-1);.}.stat
8630: 69 63 20 69 6e 74 20 77 61 6c 4e 65 78 74 48 61  ic int walNextHa
8640: 73 68 28 69 6e 74 20 69 50 72 69 6f 72 48 61 73  sh(int iPriorHas
8650: 68 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 69 50  h){.  return (iP
8660: 72 69 6f 72 48 61 73 68 2b 31 29 26 28 48 41 53  riorHash+1)&(HAS
8670: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 3b  HTABLE_NSLOT-1);
8680: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72  .}../* .** Retur
8690: 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68  n pointers to th
86a0: 65 20 68 61 73 68 20 74 61 62 6c 65 20 61 6e 64  e hash table and
86b0: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72   page number arr
86c0: 61 79 20 73 74 6f 72 65 64 20 6f 6e 0a 2a 2a 20  ay stored on.** 
86d0: 70 61 67 65 20 69 48 61 73 68 20 6f 66 20 74 68  page iHash of th
86e0: 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 54 68 65  e wal-index. The
86f0: 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 62 72   wal-index is br
8700: 6f 6b 65 6e 20 69 6e 74 6f 20 33 32 4b 42 20 70  oken into 32KB p
8710: 61 67 65 73 0a 2a 2a 20 6e 75 6d 62 65 72 65 64  ages.** numbered
8720: 20 73 74 61 72 74 69 6e 67 20 66 72 6f 6d 20 30   starting from 0
8730: 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20 6f 75 74 70  ..**.** Set outp
8740: 75 74 20 76 61 72 69 61 62 6c 65 20 2a 70 61 48  ut variable *paH
8750: 61 73 68 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  ash to point to 
8760: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
8770: 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20 69   hash table.** i
8780: 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  n the wal-index 
8790: 66 69 6c 65 2e 20 53 65 74 20 2a 70 69 5a 65 72  file. Set *piZer
87a0: 6f 20 74 6f 20 6f 6e 65 20 6c 65 73 73 20 74 68  o to one less th
87b0: 61 6e 20 74 68 65 20 66 72 61 6d 65 20 0a 2a 2a  an the frame .**
87c0: 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 66   number of the f
87d0: 69 72 73 74 20 66 72 61 6d 65 20 69 6e 64 65 78  irst frame index
87e0: 65 64 20 62 79 20 74 68 69 73 20 68 61 73 68 20  ed by this hash 
87f0: 74 61 62 6c 65 2e 20 49 66 20 61 0a 2a 2a 20 73  table. If a.** s
8800: 6c 6f 74 20 69 6e 20 74 68 65 20 68 61 73 68 20  lot in the hash 
8810: 74 61 62 6c 65 20 69 73 20 73 65 74 20 74 6f 20  table is set to 
8820: 4e 2c 20 69 74 20 72 65 66 65 72 73 20 74 6f 20  N, it refers to 
8830: 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 0a 2a 2a  frame number .**
8840: 20 28 2a 70 69 5a 65 72 6f 2b 4e 29 20 69 6e 20   (*piZero+N) in 
8850: 74 68 65 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a 20 46  the log..**.** F
8860: 69 6e 61 6c 6c 79 2c 20 73 65 74 20 2a 70 61 50  inally, set *paP
8870: 67 6e 6f 20 73 6f 20 74 68 61 74 20 2a 70 61 50  gno so that *paP
8880: 67 6e 6f 5b 31 5d 20 69 73 20 74 68 65 20 70 61  gno[1] is the pa
8890: 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65  ge number of the
88a0: 0a 2a 2a 20 66 69 72 73 74 20 66 72 61 6d 65 20  .** first frame 
88b0: 69 6e 64 65 78 65 64 20 62 79 20 74 68 65 20 68  indexed by the h
88c0: 61 73 68 20 74 61 62 6c 65 2c 20 66 72 61 6d 65  ash table, frame
88d0: 20 28 2a 70 69 5a 65 72 6f 2b 31 29 2e 0a 2a 2f   (*piZero+1)..*/
88e0: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 48  .static int walH
88f0: 61 73 68 47 65 74 28 0a 20 20 57 61 6c 20 2a 70  ashGet(.  Wal *p
8900: 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Wal,            
8910: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c            /* WAL
8920: 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74   handle */.  int
8930: 20 69 48 61 73 68 2c 20 20 20 20 20 20 20 20 20   iHash,         
8940: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8950: 46 69 6e 64 20 74 68 65 20 69 48 61 73 68 27 74  Find the iHash't
8960: 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 76 6f 6c  h table */.  vol
8970: 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 2a  atile ht_slot **
8980: 70 61 48 61 73 68 2c 20 20 20 20 20 20 2f 2a 20  paHash,      /* 
8990: 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20  OUT: Pointer to 
89a0: 68 61 73 68 20 69 6e 64 65 78 20 2a 2f 0a 20 20  hash index */.  
89b0: 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 70  volatile u32 **p
89c0: 61 50 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20  aPgno,          
89d0: 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20  /* OUT: Pointer 
89e0: 74 6f 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61  to page number a
89f0: 72 72 61 79 20 2a 2f 0a 20 20 75 33 32 20 2a 70  rray */.  u32 *p
8a00: 69 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20 20  iZero           
8a10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
8a20: 3a 20 46 72 61 6d 65 20 61 73 73 6f 63 69 61 74  : Frame associat
8a30: 65 64 20 77 69 74 68 20 2a 70 61 50 67 6e 6f 5b  ed with *paPgno[
8a40: 30 5d 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  0] */.){.  int r
8a50: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
8a60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
8a70: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 76  turn code */.  v
8a80: 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67  olatile u32 *aPg
8a90: 6e 6f 3b 0a 0a 20 20 72 63 20 3d 20 77 61 6c 49  no;..  rc = walI
8aa0: 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20 69  ndexPage(pWal, i
8ab0: 48 61 73 68 2c 20 26 61 50 67 6e 6f 29 3b 0a 20  Hash, &aPgno);. 
8ac0: 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c   assert( rc==SQL
8ad0: 49 54 45 5f 4f 4b 20 7c 7c 20 69 48 61 73 68 3e  ITE_OK || iHash>
8ae0: 30 20 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d  0 );..  if( rc==
8af0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
8b00: 20 75 33 32 20 69 5a 65 72 6f 3b 0a 20 20 20 20   u32 iZero;.    
8b10: 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74  volatile ht_slot
8b20: 20 2a 61 48 61 73 68 3b 0a 0a 20 20 20 20 61 48   *aHash;..    aH
8b30: 61 73 68 20 3d 20 28 76 6f 6c 61 74 69 6c 65 20  ash = (volatile 
8b40: 68 74 5f 73 6c 6f 74 20 2a 29 26 61 50 67 6e 6f  ht_slot *)&aPgno
8b50: 5b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  [HASHTABLE_NPAGE
8b60: 5d 3b 0a 20 20 20 20 69 66 28 20 69 48 61 73 68  ];.    if( iHash
8b70: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 61 50 67  ==0 ){.      aPg
8b80: 6e 6f 20 3d 20 26 61 50 67 6e 6f 5b 57 41 4c 49  no = &aPgno[WALI
8b90: 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69  NDEX_HDR_SIZE/si
8ba0: 7a 65 6f 66 28 75 33 32 29 5d 3b 0a 20 20 20 20  zeof(u32)];.    
8bb0: 20 20 69 5a 65 72 6f 20 3d 20 30 3b 0a 20 20 20    iZero = 0;.   
8bc0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 5a   }else{.      iZ
8bd0: 65 72 6f 20 3d 20 48 41 53 48 54 41 42 4c 45 5f  ero = HASHTABLE_
8be0: 4e 50 41 47 45 5f 4f 4e 45 20 2b 20 28 69 48 61  NPAGE_ONE + (iHa
8bf0: 73 68 2d 31 29 2a 48 41 53 48 54 41 42 4c 45 5f  sh-1)*HASHTABLE_
8c00: 4e 50 41 47 45 3b 0a 20 20 20 20 7d 0a 20 20 0a  NPAGE;.    }.  .
8c10: 20 20 20 20 2a 70 61 50 67 6e 6f 20 3d 20 26 61      *paPgno = &a
8c20: 50 67 6e 6f 5b 2d 31 5d 3b 0a 20 20 20 20 2a 70  Pgno[-1];.    *p
8c30: 61 48 61 73 68 20 3d 20 61 48 61 73 68 3b 0a 20  aHash = aHash;. 
8c40: 20 20 20 2a 70 69 5a 65 72 6f 20 3d 20 69 5a 65     *piZero = iZe
8c50: 72 6f 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ro;.  }.  return
8c60: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65   rc;.}../*.** Re
8c70: 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20  turn the number 
8c80: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
8c90: 20 70 61 67 65 20 74 68 61 74 20 63 6f 6e 74 61   page that conta
8ca0: 69 6e 73 20 74 68 65 20 68 61 73 68 2d 74 61 62  ins the hash-tab
8cb0: 6c 65 0a 2a 2a 20 61 6e 64 20 70 61 67 65 2d 6e  le.** and page-n
8cc0: 75 6d 62 65 72 20 61 72 72 61 79 20 74 68 61 74  umber array that
8cd0: 20 63 6f 6e 74 61 69 6e 20 65 6e 74 72 69 65 73   contain entries
8ce0: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74   corresponding t
8cf0: 6f 20 57 41 4c 20 66 72 61 6d 65 0a 2a 2a 20 69  o WAL frame.** i
8d00: 46 72 61 6d 65 2e 20 54 68 65 20 77 61 6c 2d 69  Frame. The wal-i
8d10: 6e 64 65 78 20 69 73 20 62 72 6f 6b 65 6e 20 75  ndex is broken u
8d20: 70 20 69 6e 74 6f 20 33 32 4b 42 20 70 61 67 65  p into 32KB page
8d30: 73 2e 20 57 61 6c 2d 69 6e 64 65 78 20 70 61 67  s. Wal-index pag
8d40: 65 73 20 0a 2a 2a 20 61 72 65 20 6e 75 6d 62 65  es .** are numbe
8d50: 72 65 64 20 73 74 61 72 74 69 6e 67 20 66 72 6f  red starting fro
8d60: 6d 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  m 0..*/.static i
8d70: 6e 74 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28  nt walFramePage(
8d80: 75 33 32 20 69 46 72 61 6d 65 29 7b 0a 20 20 69  u32 iFrame){.  i
8d90: 6e 74 20 69 48 61 73 68 20 3d 20 28 69 46 72 61  nt iHash = (iFra
8da0: 6d 65 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  me+HASHTABLE_NPA
8db0: 47 45 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  GE-HASHTABLE_NPA
8dc0: 47 45 5f 4f 4e 45 2d 31 29 20 2f 20 48 41 53 48  GE_ONE-1) / HASH
8dd0: 54 41 42 4c 45 5f 4e 50 41 47 45 3b 0a 20 20 61  TABLE_NPAGE;.  a
8de0: 73 73 65 72 74 28 20 28 69 48 61 73 68 3d 3d 30  ssert( (iHash==0
8df0: 20 7c 7c 20 69 46 72 61 6d 65 3e 48 41 53 48 54   || iFrame>HASHT
8e00: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 0a  ABLE_NPAGE_ONE).
8e10: 20 20 20 20 20 20 20 26 26 20 28 69 48 61 73 68         && (iHash
8e20: 3e 3d 31 20 7c 7c 20 69 46 72 61 6d 65 3c 3d 48  >=1 || iFrame<=H
8e30: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
8e40: 4e 45 29 0a 20 20 20 20 20 20 20 26 26 20 28 69  NE).       && (i
8e50: 48 61 73 68 3c 3d 31 20 7c 7c 20 69 46 72 61 6d  Hash<=1 || iFram
8e60: 65 3e 28 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  e>(HASHTABLE_NPA
8e70: 47 45 5f 4f 4e 45 2b 48 41 53 48 54 41 42 4c 45  GE_ONE+HASHTABLE
8e80: 5f 4e 50 41 47 45 29 29 0a 20 20 20 20 20 20 20  _NPAGE)).       
8e90: 26 26 20 28 69 48 61 73 68 3e 3d 32 20 7c 7c 20  && (iHash>=2 || 
8ea0: 69 46 72 61 6d 65 3c 3d 48 41 53 48 54 41 42 4c  iFrame<=HASHTABL
8eb0: 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 48 41 53 48  E_NPAGE_ONE+HASH
8ec0: 54 41 42 4c 45 5f 4e 50 41 47 45 29 0a 20 20 20  TABLE_NPAGE).   
8ed0: 20 20 20 20 26 26 20 28 69 48 61 73 68 3c 3d 32      && (iHash<=2
8ee0: 20 7c 7c 20 69 46 72 61 6d 65 3e 28 48 41 53 48   || iFrame>(HASH
8ef0: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b  TABLE_NPAGE_ONE+
8f00: 32 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  2*HASHTABLE_NPAG
8f10: 45 29 29 0a 20 20 29 3b 0a 20 20 72 65 74 75 72  E)).  );.  retur
8f20: 6e 20 69 48 61 73 68 3b 0a 7d 0a 0a 2f 2a 0a 2a  n iHash;.}../*.*
8f30: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 70 61 67  * Return the pag
8f40: 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63 69 61  e number associa
8f50: 74 65 64 20 77 69 74 68 20 66 72 61 6d 65 20 69  ted with frame i
8f60: 46 72 61 6d 65 20 69 6e 20 74 68 69 73 20 57 41  Frame in this WA
8f70: 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75 33 32  L..*/.static u32
8f80: 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 57 61   walFramePgno(Wa
8f90: 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 69 46 72  l *pWal, u32 iFr
8fa0: 61 6d 65 29 7b 0a 20 20 69 6e 74 20 69 48 61 73  ame){.  int iHas
8fb0: 68 20 3d 20 77 61 6c 46 72 61 6d 65 50 61 67 65  h = walFramePage
8fc0: 28 69 46 72 61 6d 65 29 3b 0a 20 20 69 66 28 20  (iFrame);.  if( 
8fd0: 69 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20  iHash==0 ){.    
8fe0: 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e 61 70 57  return pWal->apW
8ff0: 69 44 61 74 61 5b 30 5d 5b 57 41 4c 49 4e 44 45  iData[0][WALINDE
9000: 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f  X_HDR_SIZE/sizeo
9010: 66 28 75 33 32 29 20 2b 20 69 46 72 61 6d 65 20  f(u32) + iFrame 
9020: 2d 20 31 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75  - 1];.  }.  retu
9030: 72 6e 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  rn pWal->apWiDat
9040: 61 5b 69 48 61 73 68 5d 5b 28 69 46 72 61 6d 65  a[iHash][(iFrame
9050: 2d 31 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  -1-HASHTABLE_NPA
9060: 47 45 5f 4f 4e 45 29 25 48 41 53 48 54 41 42 4c  GE_ONE)%HASHTABL
9070: 45 5f 4e 50 41 47 45 5d 3b 0a 7d 0a 0a 2f 2a 0a  E_NPAGE];.}../*.
9080: 2a 2a 20 52 65 6d 6f 76 65 20 65 6e 74 72 69 65  ** Remove entrie
9090: 73 20 66 72 6f 6d 20 74 68 65 20 68 61 73 68 20  s from the hash 
90a0: 74 61 62 6c 65 20 74 68 61 74 20 70 6f 69 6e 74  table that point
90b0: 20 74 6f 20 57 41 4c 20 73 6c 6f 74 73 20 67 72   to WAL slots gr
90c0: 65 61 74 65 72 0a 2a 2a 20 74 68 61 6e 20 70 57  eater.** than pW
90d0: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e  al->hdr.mxFrame.
90e0: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  .**.** This func
90f0: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 77  tion is called w
9100: 68 65 6e 65 76 65 72 20 70 57 61 6c 2d 3e 68 64  henever pWal->hd
9110: 72 2e 6d 78 46 72 61 6d 65 20 69 73 20 64 65 63  r.mxFrame is dec
9120: 72 65 61 73 65 64 20 64 75 65 0a 2a 2a 20 74 6f  reased due.** to
9130: 20 61 20 72 6f 6c 6c 62 61 63 6b 20 6f 72 20 73   a rollback or s
9140: 61 76 65 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20  avepoint..**.** 
9150: 41 74 20 6d 6f 73 74 20 6f 6e 6c 79 20 74 68 65  At most only the
9160: 20 68 61 73 68 20 74 61 62 6c 65 20 63 6f 6e 74   hash table cont
9170: 61 69 6e 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72  aining pWal->hdr
9180: 2e 6d 78 46 72 61 6d 65 20 6e 65 65 64 73 20 74  .mxFrame needs t
9190: 6f 20 62 65 0a 2a 2a 20 75 70 64 61 74 65 64 2e  o be.** updated.
91a0: 20 20 41 6e 79 20 6c 61 74 65 72 20 68 61 73 68    Any later hash
91b0: 20 74 61 62 6c 65 73 20 77 69 6c 6c 20 62 65 20   tables will be 
91c0: 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 63 6c  automatically cl
91d0: 65 61 72 65 64 20 77 68 65 6e 0a 2a 2a 20 70 57  eared when.** pW
91e0: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
91f0: 61 64 76 61 6e 63 65 73 20 74 6f 20 74 68 65 20  advances to the 
9200: 70 6f 69 6e 74 20 77 68 65 72 65 20 74 68 6f 73  point where thos
9210: 65 20 68 61 73 68 20 74 61 62 6c 65 73 20 61 72  e hash tables ar
9220: 65 0a 2a 2a 20 61 63 74 75 61 6c 6c 79 20 6e 65  e.** actually ne
9230: 65 64 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  eded..*/.static 
9240: 76 6f 69 64 20 77 61 6c 43 6c 65 61 6e 75 70 48  void walCleanupH
9250: 61 73 68 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ash(Wal *pWal){.
9260: 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c    volatile ht_sl
9270: 6f 74 20 2a 61 48 61 73 68 20 3d 20 30 3b 20 20  ot *aHash = 0;  
9280: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
9290: 68 61 73 68 20 74 61 62 6c 65 20 74 6f 20 63 6c  hash table to cl
92a0: 65 61 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c  ear */.  volatil
92b0: 65 20 75 33 32 20 2a 61 50 67 6e 6f 20 3d 20 30  e u32 *aPgno = 0
92c0: 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65  ;        /* Page
92d0: 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 66 6f   number array fo
92e0: 72 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a  r hash table */.
92f0: 20 20 75 33 32 20 69 5a 65 72 6f 20 3d 20 30 3b    u32 iZero = 0;
9300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9310: 20 20 2f 2a 20 66 72 61 6d 65 20 3d 3d 20 28 61    /* frame == (a
9320: 48 61 73 68 5b 78 5d 2b 69 5a 65 72 6f 29 20 2a  Hash[x]+iZero) *
9330: 2f 0a 20 20 69 6e 74 20 69 4c 69 6d 69 74 20 3d  /.  int iLimit =
9340: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
9350: 20 20 20 20 2f 2a 20 5a 65 72 6f 20 76 61 6c 75      /* Zero valu
9360: 65 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  es greater than 
9370: 74 68 69 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  this */.  int nB
9380: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
9390: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
93a0: 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20  ber of bytes to 
93b0: 7a 65 72 6f 20 69 6e 20 61 50 67 6e 6f 5b 5d 20  zero in aPgno[] 
93c0: 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20  */.  int i;     
93d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
93e0: 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
93f0: 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20  iterate through 
9400: 61 48 61 73 68 5b 5d 20 2a 2f 0a 0a 20 20 61 73  aHash[] */..  as
9410: 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74  sert( pWal->writ
9420: 65 4c 6f 63 6b 20 29 3b 0a 20 20 74 65 73 74 63  eLock );.  testc
9430: 61 73 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  ase( pWal->hdr.m
9440: 78 46 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c  xFrame==HASHTABL
9450: 45 5f 4e 50 41 47 45 5f 4f 4e 45 2d 31 20 29 3b  E_NPAGE_ONE-1 );
9460: 0a 20 20 74 65 73 74 63 61 73 65 28 20 70 57 61  .  testcase( pWa
9470: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d  l->hdr.mxFrame==
9480: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
9490: 4f 4e 45 20 29 3b 0a 20 20 74 65 73 74 63 61 73  ONE );.  testcas
94a0: 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  e( pWal->hdr.mxF
94b0: 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45 5f  rame==HASHTABLE_
94c0: 4e 50 41 47 45 5f 4f 4e 45 2b 31 20 29 3b 0a 0a  NPAGE_ONE+1 );..
94d0: 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e    if( pWal->hdr.
94e0: 6d 78 46 72 61 6d 65 3d 3d 30 20 29 20 72 65 74  mxFrame==0 ) ret
94f0: 75 72 6e 3b 0a 0a 20 20 2f 2a 20 4f 62 74 61 69  urn;..  /* Obtai
9500: 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68  n pointers to th
9510: 65 20 68 61 73 68 2d 74 61 62 6c 65 20 61 6e 64  e hash-table and
9520: 20 70 61 67 65 2d 6e 75 6d 62 65 72 20 61 72 72   page-number arr
9530: 61 79 20 63 6f 6e 74 61 69 6e 69 6e 67 20 0a 20  ay containing . 
9540: 20 2a 2a 20 74 68 65 20 65 6e 74 72 79 20 74 68   ** the entry th
9550: 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74  at corresponds t
9560: 6f 20 66 72 61 6d 65 20 70 57 61 6c 2d 3e 68 64  o frame pWal->hd
9570: 72 2e 6d 78 46 72 61 6d 65 2e 20 49 74 20 69 73  r.mxFrame. It is
9580: 20 67 75 61 72 61 6e 74 65 65 64 0a 20 20 2a 2a   guaranteed.  **
9590: 20 74 68 61 74 20 74 68 65 20 70 61 67 65 20 73   that the page s
95a0: 61 69 64 20 68 61 73 68 2d 74 61 62 6c 65 20 61  aid hash-table a
95b0: 6e 64 20 61 72 72 61 79 20 72 65 73 69 64 65 20  nd array reside 
95c0: 6f 6e 20 69 73 20 61 6c 72 65 61 64 79 20 6d 61  on is already ma
95d0: 70 70 65 64 2e 0a 20 20 2a 2f 0a 20 20 61 73 73  pped..  */.  ass
95e0: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
95f0: 74 61 3e 77 61 6c 46 72 61 6d 65 50 61 67 65 28  ta>walFramePage(
9600: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
9610: 65 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  e) );.  assert( 
9620: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 77  pWal->apWiData[w
9630: 61 6c 46 72 61 6d 65 50 61 67 65 28 70 57 61 6c  alFramePage(pWal
9640: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 29 5d 20  ->hdr.mxFrame)] 
9650: 29 3b 0a 20 20 77 61 6c 48 61 73 68 47 65 74 28  );.  walHashGet(
9660: 70 57 61 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61  pWal, walFramePa
9670: 67 65 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ge(pWal->hdr.mxF
9680: 72 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20 26  rame), &aHash, &
9690: 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a  aPgno, &iZero);.
96a0: 0a 20 20 2f 2a 20 5a 65 72 6f 20 61 6c 6c 20 68  .  /* Zero all h
96b0: 61 73 68 2d 74 61 62 6c 65 20 65 6e 74 72 69 65  ash-table entrie
96c0: 73 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  s that correspon
96d0: 64 20 74 6f 20 66 72 61 6d 65 20 6e 75 6d 62 65  d to frame numbe
96e0: 72 73 20 67 72 65 61 74 65 72 0a 20 20 2a 2a 20  rs greater.  ** 
96f0: 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  than pWal->hdr.m
9700: 78 46 72 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69  xFrame..  */.  i
9710: 4c 69 6d 69 74 20 3d 20 70 57 61 6c 2d 3e 68 64  Limit = pWal->hd
9720: 72 2e 6d 78 46 72 61 6d 65 20 2d 20 69 5a 65 72  r.mxFrame - iZer
9730: 6f 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4c 69  o;.  assert( iLi
9740: 6d 69 74 3e 30 20 29 3b 0a 20 20 66 6f 72 28 69  mit>0 );.  for(i
9750: 3d 30 3b 20 69 3c 48 41 53 48 54 41 42 4c 45 5f  =0; i<HASHTABLE_
9760: 4e 53 4c 4f 54 3b 20 69 2b 2b 29 7b 0a 20 20 20  NSLOT; i++){.   
9770: 20 69 66 28 20 61 48 61 73 68 5b 69 5d 3e 69 4c   if( aHash[i]>iL
9780: 69 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 61 48  imit ){.      aH
9790: 61 73 68 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20  ash[i] = 0;.    
97a0: 7d 0a 20 20 7d 0a 20 20 0a 20 20 2f 2a 20 5a 65  }.  }.  .  /* Ze
97b0: 72 6f 20 74 68 65 20 65 6e 74 72 69 65 73 20 69  ro the entries i
97c0: 6e 20 74 68 65 20 61 50 67 6e 6f 20 61 72 72 61  n the aPgno arra
97d0: 79 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  y that correspon
97e0: 64 20 74 6f 20 66 72 61 6d 65 73 20 77 69 74 68  d to frames with
97f0: 0a 20 20 2a 2a 20 66 72 61 6d 65 20 6e 75 6d 62  .  ** frame numb
9800: 65 72 73 20 67 72 65 61 74 65 72 20 74 68 61 6e  ers greater than
9810: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
9820: 6d 65 2e 20 0a 20 20 2a 2f 0a 20 20 6e 42 79 74  me. .  */.  nByt
9830: 65 20 3d 20 28 69 6e 74 29 28 28 63 68 61 72 20  e = (int)((char 
9840: 2a 29 61 48 61 73 68 20 2d 20 28 63 68 61 72 20  *)aHash - (char 
9850: 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d 69 74 2b  *)&aPgno[iLimit+
9860: 31 5d 29 3b 0a 20 20 6d 65 6d 73 65 74 28 28 76  1]);.  memset((v
9870: 6f 69 64 20 2a 29 26 61 50 67 6e 6f 5b 69 4c 69  oid *)&aPgno[iLi
9880: 6d 69 74 2b 31 5d 2c 20 30 2c 20 6e 42 79 74 65  mit+1], 0, nByte
9890: 29 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  );..#ifdef SQLIT
98a0: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
98b0: 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20 56  VE_ASSERT.  /* V
98c0: 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20 65  erify that the e
98d0: 76 65 72 79 20 65 6e 74 72 79 20 69 6e 20 74 68  very entry in th
98e0: 65 20 6d 61 70 70 69 6e 67 20 72 65 67 69 6f 6e  e mapping region
98f0: 20 69 73 20 73 74 69 6c 6c 20 72 65 61 63 68 61   is still reacha
9900: 62 6c 65 0a 20 20 2a 2a 20 76 69 61 20 74 68 65  ble.  ** via the
9910: 20 68 61 73 68 20 74 61 62 6c 65 20 65 76 65 6e   hash table even
9920: 20 61 66 74 65 72 20 74 68 65 20 63 6c 65 61 6e   after the clean
9930: 75 70 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69  up..  */.  if( i
9940: 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20 69 6e 74  Limit ){.    int
9950: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a   i;           /*
9960: 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f   Loop counter */
9970: 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20  .    int iKey;  
9980: 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 6b 65        /* Hash ke
9990: 79 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d 31  y */.    for(i=1
99a0: 3b 20 69 3c 3d 69 4c 69 6d 69 74 3b 20 69 2b 2b  ; i<=iLimit; i++
99b0: 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 4b 65  ){.      for(iKe
99c0: 79 3d 77 61 6c 48 61 73 68 28 61 50 67 6e 6f 5b  y=walHash(aPgno[
99d0: 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  i]); aHash[iKey]
99e0: 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
99f0: 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
9a00: 20 20 20 69 66 28 20 61 48 61 73 68 5b 69 4b 65     if( aHash[iKe
9a10: 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b 3b 0a 20  y]==i ) break;. 
9a20: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73 73       }.      ass
9a30: 65 72 74 28 20 61 48 61 73 68 5b 69 4b 65 79 5d  ert( aHash[iKey]
9a40: 3d 3d 69 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  ==i );.    }.  }
9a50: 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54  .#endif /* SQLIT
9a60: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
9a70: 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a 7d 0a 0a  VE_ASSERT */.}..
9a80: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 6e 20 65 6e  ./*.** Set an en
9a90: 74 72 79 20 69 6e 20 74 68 65 20 77 61 6c 2d 69  try in the wal-i
9aa0: 6e 64 65 78 20 74 68 61 74 20 77 69 6c 6c 20 6d  ndex that will m
9ab0: 61 70 20 64 61 74 61 62 61 73 65 20 70 61 67 65  ap database page
9ac0: 20 6e 75 6d 62 65 72 0a 2a 2a 20 70 50 61 67 65   number.** pPage
9ad0: 20 69 6e 74 6f 20 57 41 4c 20 66 72 61 6d 65 20   into WAL frame 
9ae0: 69 46 72 61 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69  iFrame..*/.stati
9af0: 63 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 41 70  c int walIndexAp
9b00: 70 65 6e 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20  pend(Wal *pWal, 
9b10: 75 33 32 20 69 46 72 61 6d 65 2c 20 75 33 32 20  u32 iFrame, u32 
9b20: 69 50 61 67 65 29 7b 0a 20 20 69 6e 74 20 72 63  iPage){.  int rc
9b30: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
9b40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
9b50: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 75 33  urn code */.  u3
9b60: 32 20 69 5a 65 72 6f 20 3d 20 30 3b 20 20 20 20  2 iZero = 0;    
9b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9b80: 20 4f 6e 65 20 6c 65 73 73 20 74 68 61 6e 20 66   One less than f
9b90: 72 61 6d 65 20 6e 75 6d 62 65 72 20 6f 66 20 61  rame number of a
9ba0: 50 67 6e 6f 5b 31 5d 20 2a 2f 0a 20 20 76 6f 6c  Pgno[1] */.  vol
9bb0: 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f  atile u32 *aPgno
9bc0: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 2f 2a 20   = 0;        /* 
9bd0: 50 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61  Page number arra
9be0: 79 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20  y */.  volatile 
9bf0: 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 20 3d  ht_slot *aHash =
9c00: 20 30 3b 20 20 20 20 2f 2a 20 48 61 73 68 20 74   0;    /* Hash t
9c10: 61 62 6c 65 20 2a 2f 0a 0a 20 20 72 63 20 3d 20  able */..  rc = 
9c20: 77 61 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c  walHashGet(pWal,
9c30: 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69 46   walFramePage(iF
9c40: 72 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20 26  rame), &aHash, &
9c50: 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a  aPgno, &iZero);.
9c60: 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20 74  .  /* Assuming t
9c70: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  he wal-index fil
9c80: 65 20 77 61 73 20 73 75 63 63 65 73 73 66 75 6c  e was successful
9c90: 6c 79 20 6d 61 70 70 65 64 2c 20 70 6f 70 75 6c  ly mapped, popul
9ca0: 61 74 65 20 74 68 65 0a 20 20 2a 2a 20 70 61 67  ate the.  ** pag
9cb0: 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 61  e number array a
9cc0: 6e 64 20 68 61 73 68 20 74 61 62 6c 65 20 65 6e  nd hash table en
9cd0: 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  try..  */.  if( 
9ce0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
9cf0: 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20  .    int iKey;  
9d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9d10: 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65     /* Hash table
9d20: 20 6b 65 79 20 2a 2f 0a 20 20 20 20 69 6e 74 20   key */.    int 
9d30: 69 64 78 3b 20 20 20 20 20 20 20 20 20 20 20 20  idx;            
9d40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
9d50: 75 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 68  ue to write to h
9d60: 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 20 2a  ash-table slot *
9d70: 2f 0a 20 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69  /.    int nColli
9d80: 64 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  de;             
9d90: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
9da0: 20 68 61 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73   hash collisions
9db0: 20 2a 2f 0a 0a 20 20 20 20 69 64 78 20 3d 20 69   */..    idx = i
9dc0: 46 72 61 6d 65 20 2d 20 69 5a 65 72 6f 3b 0a 20  Frame - iZero;. 
9dd0: 20 20 20 61 73 73 65 72 74 28 20 69 64 78 20 3c     assert( idx <
9de0: 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f  = HASHTABLE_NSLO
9df0: 54 2f 32 20 2b 20 31 20 29 3b 0a 20 20 20 20 0a  T/2 + 1 );.    .
9e00: 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69      /* If this i
9e10: 73 20 74 68 65 20 66 69 72 73 74 20 65 6e 74 72  s the first entr
9e20: 79 20 74 6f 20 62 65 20 61 64 64 65 64 20 74 6f  y to be added to
9e30: 20 74 68 69 73 20 68 61 73 68 2d 74 61 62 6c 65   this hash-table
9e40: 2c 20 7a 65 72 6f 20 74 68 65 0a 20 20 20 20 2a  , zero the.    *
9e50: 2a 20 65 6e 74 69 72 65 20 68 61 73 68 20 74 61  * entire hash ta
9e60: 62 6c 65 20 61 6e 64 20 61 50 67 6e 6f 5b 5d 20  ble and aPgno[] 
9e70: 61 72 72 61 79 20 62 65 66 6f 72 65 20 70 72 6f  array before pro
9e80: 63 65 64 69 6e 67 2e 20 0a 20 20 20 20 2a 2f 0a  ceding. .    */.
9e90: 20 20 20 20 69 66 28 20 69 64 78 3d 3d 31 20 29      if( idx==1 )
9ea0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74  {.      int nByt
9eb0: 65 20 3d 20 28 69 6e 74 29 28 28 75 38 20 2a 29  e = (int)((u8 *)
9ec0: 26 61 48 61 73 68 5b 48 41 53 48 54 41 42 4c 45  &aHash[HASHTABLE
9ed0: 5f 4e 53 4c 4f 54 5d 20 2d 20 28 75 38 20 2a 29  _NSLOT] - (u8 *)
9ee0: 26 61 50 67 6e 6f 5b 31 5d 29 3b 0a 20 20 20 20  &aPgno[1]);.    
9ef0: 20 20 6d 65 6d 73 65 74 28 28 76 6f 69 64 2a 29    memset((void*)
9f00: 26 61 50 67 6e 6f 5b 31 5d 2c 20 30 2c 20 6e 42  &aPgno[1], 0, nB
9f10: 79 74 65 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  yte);.    }..   
9f20: 20 2f 2a 20 49 66 20 74 68 65 20 65 6e 74 72 79   /* If the entry
9f30: 20 69 6e 20 61 50 67 6e 6f 5b 5d 20 69 73 20 61   in aPgno[] is a
9f40: 6c 72 65 61 64 79 20 73 65 74 2c 20 74 68 65 6e  lready set, then
9f50: 20 74 68 65 20 70 72 65 76 69 6f 75 73 20 77 72   the previous wr
9f60: 69 74 65 72 0a 20 20 20 20 2a 2a 20 6d 75 73 74  iter.    ** must
9f70: 20 68 61 76 65 20 65 78 69 74 65 64 20 75 6e 65   have exited une
9f80: 78 70 65 63 74 65 64 6c 79 20 69 6e 20 74 68 65  xpectedly in the
9f90: 20 6d 69 64 64 6c 65 20 6f 66 20 61 20 74 72 61   middle of a tra
9fa0: 6e 73 61 63 74 69 6f 6e 20 28 61 66 74 65 72 0a  nsaction (after.
9fb0: 20 20 20 20 2a 2a 20 77 72 69 74 69 6e 67 20 6f      ** writing o
9fc0: 6e 65 20 6f 72 20 6d 6f 72 65 20 64 69 72 74 79  ne or more dirty
9fd0: 20 70 61 67 65 73 20 74 6f 20 74 68 65 20 57 41   pages to the WA
9fe0: 4c 20 74 6f 20 66 72 65 65 20 75 70 20 6d 65 6d  L to free up mem
9ff0: 6f 72 79 29 2e 20 0a 20 20 20 20 2a 2a 20 52 65  ory). .    ** Re
a000: 6d 6f 76 65 20 74 68 65 20 72 65 6d 6e 61 6e 74  move the remnant
a010: 73 20 6f 66 20 74 68 61 74 20 77 72 69 74 65 72  s of that writer
a020: 73 20 75 6e 63 6f 6d 6d 69 74 74 65 64 20 74 72  s uncommitted tr
a030: 61 6e 73 61 63 74 69 6f 6e 20 66 72 6f 6d 20 0a  ansaction from .
a040: 20 20 20 20 2a 2a 20 74 68 65 20 68 61 73 68 2d      ** the hash-
a050: 74 61 62 6c 65 20 62 65 66 6f 72 65 20 77 72 69  table before wri
a060: 74 69 6e 67 20 61 6e 79 20 6e 65 77 20 65 6e 74  ting any new ent
a070: 72 69 65 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  ries..    */.   
a080: 20 69 66 28 20 61 50 67 6e 6f 5b 69 64 78 5d 20   if( aPgno[idx] 
a090: 29 7b 0a 20 20 20 20 20 20 77 61 6c 43 6c 65 61  ){.      walClea
a0a0: 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20  nupHash(pWal);. 
a0b0: 20 20 20 20 20 61 73 73 65 72 74 28 20 21 61 50       assert( !aP
a0c0: 67 6e 6f 5b 69 64 78 5d 20 29 3b 0a 20 20 20 20  gno[idx] );.    
a0d0: 7d 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20  }..    /* Write 
a0e0: 74 68 65 20 61 50 67 6e 6f 5b 5d 20 61 72 72 61  the aPgno[] arra
a0f0: 79 20 65 6e 74 72 79 20 61 6e 64 20 74 68 65 20  y entry and the 
a100: 68 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 2e  hash-table slot.
a110: 20 2a 2f 0a 20 20 20 20 6e 43 6f 6c 6c 69 64 65   */.    nCollide
a120: 20 3d 20 69 64 78 3b 0a 20 20 20 20 66 6f 72 28   = idx;.    for(
a130: 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 69 50 61  iKey=walHash(iPa
a140: 67 65 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  ge); aHash[iKey]
a150: 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
a160: 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
a170: 20 69 66 28 20 28 6e 43 6f 6c 6c 69 64 65 2d 2d   if( (nCollide--
a180: 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  )==0 ) return SQ
a190: 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50  LITE_CORRUPT_BKP
a1a0: 54 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 50 67  T;.    }.    aPg
a1b0: 6e 6f 5b 69 64 78 5d 20 3d 20 69 50 61 67 65 3b  no[idx] = iPage;
a1c0: 0a 20 20 20 20 61 48 61 73 68 5b 69 4b 65 79 5d  .    aHash[iKey]
a1d0: 20 3d 20 28 68 74 5f 73 6c 6f 74 29 69 64 78 3b   = (ht_slot)idx;
a1e0: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
a1f0: 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45  ENABLE_EXPENSIVE
a200: 5f 41 53 53 45 52 54 0a 20 20 20 20 2f 2a 20 56  _ASSERT.    /* V
a210: 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20 6e  erify that the n
a220: 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73  umber of entries
a230: 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62   in the hash tab
a240: 6c 65 20 65 78 61 63 74 6c 79 20 65 71 75 61 6c  le exactly equal
a250: 73 0a 20 20 20 20 2a 2a 20 74 68 65 20 6e 75 6d  s.    ** the num
a260: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69  ber of entries i
a270: 6e 20 74 68 65 20 6d 61 70 70 69 6e 67 20 72 65  n the mapping re
a280: 67 69 6f 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  gion..    */.   
a290: 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 20   {.      int i; 
a2a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f            /* Loo
a2b0: 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20  p counter */.   
a2c0: 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 20 3d 20     int nEntry = 
a2d0: 30 3b 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66  0;  /* Number of
a2e0: 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20   entries in the 
a2f0: 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20  hash table */.  
a300: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48      for(i=0; i<H
a310: 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 20  ASHTABLE_NSLOT; 
a320: 69 2b 2b 29 7b 20 69 66 28 20 61 48 61 73 68 5b  i++){ if( aHash[
a330: 69 5d 20 29 20 6e 45 6e 74 72 79 2b 2b 3b 20 7d  i] ) nEntry++; }
a340: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6e  .      assert( n
a350: 45 6e 74 72 79 3d 3d 69 64 78 20 29 3b 0a 20 20  Entry==idx );.  
a360: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69    }..    /* Veri
a370: 66 79 20 74 68 61 74 20 74 68 65 20 65 76 65 72  fy that the ever
a380: 79 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d  y entry in the m
a390: 61 70 70 69 6e 67 20 72 65 67 69 6f 6e 20 69 73  apping region is
a3a0: 20 72 65 61 63 68 61 62 6c 65 0a 20 20 20 20 2a   reachable.    *
a3b0: 2a 20 76 69 61 20 74 68 65 20 68 61 73 68 20 74  * via the hash t
a3c0: 61 62 6c 65 2e 20 20 54 68 69 73 20 74 75 72 6e  able.  This turn
a3d0: 73 20 6f 75 74 20 74 6f 20 62 65 20 61 20 72 65  s out to be a re
a3e0: 61 6c 6c 79 2c 20 72 65 61 6c 6c 79 20 65 78 70  ally, really exp
a3f0: 65 6e 73 69 76 65 0a 20 20 20 20 2a 2a 20 74 68  ensive.    ** th
a400: 69 6e 67 20 74 6f 20 63 68 65 63 6b 2c 20 73 6f  ing to check, so
a410: 20 6f 6e 6c 79 20 64 6f 20 74 68 69 73 20 6f 63   only do this oc
a420: 63 61 73 69 6f 6e 61 6c 6c 79 20 2d 20 6e 6f 74  casionally - not
a430: 20 6f 6e 20 65 76 65 72 79 0a 20 20 20 20 2a 2a   on every.    **
a440: 20 69 74 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20   iteration..    
a450: 2a 2f 0a 20 20 20 20 69 66 28 20 28 69 64 78 26  */.    if( (idx&
a460: 30 78 33 66 66 29 3d 3d 30 20 29 7b 0a 20 20 20  0x3ff)==0 ){.   
a470: 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20     int i;       
a480: 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e      /* Loop coun
a490: 74 65 72 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72  ter */.      for
a4a0: 28 69 3d 31 3b 20 69 3c 3d 69 64 78 3b 20 69 2b  (i=1; i<=idx; i+
a4b0: 2b 29 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 28  +){.        for(
a4c0: 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 61 50 67  iKey=walHash(aPg
a4d0: 6e 6f 5b 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b  no[i]); aHash[iK
a4e0: 65 79 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78  ey]; iKey=walNex
a4f0: 74 48 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20  tHash(iKey)){.  
a500: 20 20 20 20 20 20 20 20 69 66 28 20 61 48 61 73          if( aHas
a510: 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 20 62 72 65  h[iKey]==i ) bre
a520: 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  ak;.        }.  
a530: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 61 48        assert( aH
a540: 61 73 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 3b 0a  ash[iKey]==i );.
a550: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 23 65        }.    }.#e
a560: 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45  ndif /* SQLITE_E
a570: 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f  NABLE_EXPENSIVE_
a580: 41 53 53 45 52 54 20 2a 2f 0a 20 20 7d 0a 0a 0a  ASSERT */.  }...
a590: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
a5a0: 0a 2f 2a 0a 2a 2a 20 52 65 63 6f 76 65 72 20 74  ./*.** Recover t
a5b0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 62 79 20  he wal-index by 
a5c0: 72 65 61 64 69 6e 67 20 74 68 65 20 77 72 69 74  reading the writ
a5d0: 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65  e-ahead log file
a5e0: 2e 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  . .**.** This ro
a5f0: 75 74 69 6e 65 20 66 69 72 73 74 20 74 72 69 65  utine first trie
a600: 73 20 74 6f 20 65 73 74 61 62 6c 69 73 68 20 61  s to establish a
a610: 6e 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b  n exclusive lock
a620: 20 6f 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69   on the.** wal-i
a630: 6e 64 65 78 20 74 6f 20 70 72 65 76 65 6e 74 20  ndex to prevent 
a640: 6f 74 68 65 72 20 74 68 72 65 61 64 73 2f 70 72  other threads/pr
a650: 6f 63 65 73 73 65 73 20 66 72 6f 6d 20 64 6f 69  ocesses from doi
a660: 6e 67 20 61 6e 79 74 68 69 6e 67 0a 2a 2a 20 77  ng anything.** w
a670: 69 74 68 20 74 68 65 20 57 41 4c 20 6f 72 20 77  ith the WAL or w
a680: 61 6c 2d 69 6e 64 65 78 20 77 68 69 6c 65 20 72  al-index while r
a690: 65 63 6f 76 65 72 79 20 69 73 20 72 75 6e 6e 69  ecovery is runni
a6a0: 6e 67 2e 20 20 54 68 65 0a 2a 2a 20 57 41 4c 5f  ng.  The.** WAL_
a6b0: 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20 69 73 20  RECOVER_LOCK is 
a6c0: 61 6c 73 6f 20 68 65 6c 64 20 73 6f 20 74 68 61  also held so tha
a6d0: 74 20 6f 74 68 65 72 20 74 68 72 65 61 64 73 20  t other threads 
a6e0: 77 69 6c 6c 20 6b 6e 6f 77 0a 2a 2a 20 74 68 61  will know.** tha
a6f0: 74 20 74 68 69 73 20 74 68 72 65 61 64 20 69 73  t this thread is
a700: 20 72 75 6e 6e 69 6e 67 20 72 65 63 6f 76 65 72   running recover
a710: 79 2e 20 20 49 66 20 75 6e 61 62 6c 65 20 74 6f  y.  If unable to
a720: 20 65 73 74 61 62 6c 69 73 68 0a 2a 2a 20 74 68   establish.** th
a730: 65 20 6e 65 63 65 73 73 61 72 79 20 6c 6f 63 6b  e necessary lock
a740: 73 2c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  s, this routine 
a750: 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 42  returns SQLITE_B
a760: 55 53 59 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  USY..*/.static i
a770: 6e 74 20 77 61 6c 49 6e 64 65 78 52 65 63 6f 76  nt walIndexRecov
a780: 65 72 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20  er(Wal *pWal){. 
a790: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
a7a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a7b0: 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20   /* Return Code 
a7c0: 2a 2f 0a 20 20 69 36 34 20 6e 53 69 7a 65 3b 20  */.  i64 nSize; 
a7d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a7e0: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
a7f0: 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33  log file */.  u3
a800: 32 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 32 5d  2 aFrameCksum[2]
a810: 20 3d 20 7b 30 2c 20 30 7d 3b 0a 20 20 69 6e 74   = {0, 0};.  int
a820: 20 69 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20   iLock;         
a830: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
a840: 4c 6f 63 6b 20 6f 66 66 73 65 74 20 74 6f 20 6c  Lock offset to l
a850: 6f 63 6b 20 66 6f 72 20 63 68 65 63 6b 70 6f 69  ock for checkpoi
a860: 6e 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 6f 63  nt */.  int nLoc
a870: 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
a880: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
a890: 72 20 6f 66 20 6c 6f 63 6b 73 20 74 6f 20 68 6f  r of locks to ho
a8a0: 6c 64 20 2a 2f 0a 0a 20 20 2f 2a 20 4f 62 74 61  ld */..  /* Obta
a8b0: 69 6e 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20  in an exclusive 
a8c0: 6c 6f 63 6b 20 6f 6e 20 61 6c 6c 20 62 79 74 65  lock on all byte
a8d0: 20 69 6e 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20   in the locking 
a8e0: 72 61 6e 67 65 20 6e 6f 74 20 61 6c 72 65 61 64  range not alread
a8f0: 79 0a 20 20 2a 2a 20 6c 6f 63 6b 65 64 20 62 79  y.  ** locked by
a900: 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 54 68 65   the caller. The
a910: 20 63 61 6c 6c 65 72 20 69 73 20 67 75 61 72 61   caller is guara
a920: 6e 74 65 65 64 20 74 6f 20 68 61 76 65 20 6c 6f  nteed to have lo
a930: 63 6b 65 64 20 74 68 65 0a 20 20 2a 2a 20 57 41  cked the.  ** WA
a940: 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 62 79 74  L_WRITE_LOCK byt
a950: 65 2c 20 61 6e 64 20 6d 61 79 20 68 61 76 65 20  e, and may have 
a960: 61 6c 73 6f 20 6c 6f 63 6b 65 64 20 74 68 65 20  also locked the 
a970: 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 62 79  WAL_CKPT_LOCK by
a980: 74 65 2e 0a 20 20 2a 2a 20 49 66 20 73 75 63 63  te..  ** If succ
a990: 65 73 73 66 75 6c 2c 20 74 68 65 20 73 61 6d 65  essful, the same
a9a0: 20 62 79 74 65 73 20 74 68 61 74 20 61 72 65 20   bytes that are 
a9b0: 6c 6f 63 6b 65 64 20 68 65 72 65 20 61 72 65 20  locked here are 
a9c0: 75 6e 6c 6f 63 6b 65 64 20 62 65 66 6f 72 65 0a  unlocked before.
a9d0: 20 20 2a 2a 20 74 68 69 73 20 66 75 6e 63 74 69    ** this functi
a9e0: 6f 6e 20 72 65 74 75 72 6e 73 2e 0a 20 20 2a 2f  on returns..  */
a9f0: 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
aa00: 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 31 20 7c 7c 20  >ckptLock==1 || 
aa10: 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d  pWal->ckptLock==
aa20: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 57  0 );.  assert( W
aa30: 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45  AL_ALL_BUT_WRITE
aa40: 3d 3d 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b  ==WAL_WRITE_LOCK
aa50: 2b 31 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  +1 );.  assert( 
aa60: 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 3d 3d 57  WAL_CKPT_LOCK==W
aa70: 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45  AL_ALL_BUT_WRITE
aa80: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57   );.  assert( pW
aa90: 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
aaa0: 0a 20 20 69 4c 6f 63 6b 20 3d 20 57 41 4c 5f 41  .  iLock = WAL_A
aab0: 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 2b 20 70  LL_BUT_WRITE + p
aac0: 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3b 0a 20  Wal->ckptLock;. 
aad0: 20 6e 4c 6f 63 6b 20 3d 20 53 51 4c 49 54 45 5f   nLock = SQLITE_
aae0: 53 48 4d 5f 4e 4c 4f 43 4b 20 2d 20 69 4c 6f 63  SHM_NLOCK - iLoc
aaf0: 6b 3b 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63  k;.  rc = walLoc
ab00: 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
ab10: 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b 0a   iLock, nLock);.
ab20: 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20    if( rc ){.    
ab30: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20  return rc;.  }. 
ab40: 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
ab50: 70 3a 20 72 65 63 6f 76 65 72 79 20 62 65 67 69  p: recovery begi
ab60: 6e 2e 2e 2e 5c 6e 22 2c 20 70 57 61 6c 29 29 3b  n...\n", pWal));
ab70: 0a 0a 20 20 6d 65 6d 73 65 74 28 26 70 57 61 6c  ..  memset(&pWal
ab80: 2d 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66  ->hdr, 0, sizeof
ab90: 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a  (WalIndexHdr));.
aba0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  .  rc = sqlite3O
abb0: 73 46 69 6c 65 53 69 7a 65 28 70 57 61 6c 2d 3e  sFileSize(pWal->
abc0: 70 57 61 6c 46 64 2c 20 26 6e 53 69 7a 65 29 3b  pWalFd, &nSize);
abd0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
abe0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 67 6f 74 6f  E_OK ){.    goto
abf0: 20 72 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b   recovery_error;
ac00: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6e 53 69 7a  .  }..  if( nSiz
ac10: 65 3e 57 41 4c 5f 48 44 52 53 49 5a 45 20 29 7b  e>WAL_HDRSIZE ){
ac20: 0a 20 20 20 20 75 38 20 61 42 75 66 5b 57 41 4c  .    u8 aBuf[WAL
ac30: 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20 20 20 20  _HDRSIZE];      
ac40: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20     /* Buffer to 
ac50: 6c 6f 61 64 20 57 41 4c 20 68 65 61 64 65 72 20  load WAL header 
ac60: 69 6e 74 6f 20 2a 2f 0a 20 20 20 20 75 38 20 2a  into */.    u8 *
ac70: 61 46 72 61 6d 65 20 3d 20 30 3b 20 20 20 20 20  aFrame = 0;     
ac80: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 6c            /* Mal
ac90: 6c 6f 63 27 64 20 62 75 66 66 65 72 20 74 6f 20  loc'd buffer to 
aca0: 6c 6f 61 64 20 65 6e 74 69 72 65 20 66 72 61 6d  load entire fram
acb0: 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20 73 7a 46  e */.    int szF
acc0: 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20  rame;           
acd0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
ace0: 20 6f 66 20 62 79 74 65 73 20 69 6e 20 62 75 66   of bytes in buf
acf0: 66 65 72 20 61 46 72 61 6d 65 5b 5d 20 2a 2f 0a  fer aFrame[] */.
ad00: 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20      u8 *aData;  
ad10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad20: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
ad30: 64 61 74 61 20 70 61 72 74 20 6f 66 20 61 46 72  data part of aFr
ad40: 61 6d 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20  ame buffer */.  
ad50: 20 20 69 6e 74 20 69 46 72 61 6d 65 3b 20 20 20    int iFrame;   
ad60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad70: 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6c 61 73 74  /* Index of last
ad80: 20 66 72 61 6d 65 20 72 65 61 64 20 2a 2f 0a 20   frame read */. 
ad90: 20 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 20     i64 iOffset; 
ada0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
adb0: 20 2f 2a 20 4e 65 78 74 20 6f 66 66 73 65 74 20   /* Next offset 
adc0: 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 6c 6f 67  to read from log
add0: 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 69 6e 74   file */.    int
ade0: 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20   szPage;        
adf0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
ae00: 67 65 20 73 69 7a 65 20 61 63 63 6f 72 64 69 6e  ge size accordin
ae10: 67 20 74 6f 20 74 68 65 20 6c 6f 67 20 2a 2f 0a  g to the log */.
ae20: 20 20 20 20 75 33 32 20 6d 61 67 69 63 3b 20 20      u32 magic;  
ae30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ae40: 20 20 2f 2a 20 4d 61 67 69 63 20 76 61 6c 75 65    /* Magic value
ae50: 20 72 65 61 64 20 66 72 6f 6d 20 57 41 4c 20 68   read from WAL h
ae60: 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 75 33 32  eader */.    u32
ae70: 20 76 65 72 73 69 6f 6e 3b 20 20 20 20 20 20 20   version;       
ae80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
ae90: 67 69 63 20 76 61 6c 75 65 20 72 65 61 64 20 66  gic value read f
aea0: 72 6f 6d 20 57 41 4c 20 68 65 61 64 65 72 20 2a  rom WAL header *
aeb0: 2f 0a 20 20 20 20 69 6e 74 20 69 73 56 61 6c 69  /.    int isVali
aec0: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
aed0: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 74      /* True if t
aee0: 68 69 73 20 66 72 61 6d 65 20 69 73 20 76 61 6c  his frame is val
aef0: 69 64 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 52 65  id */..    /* Re
af00: 61 64 20 69 6e 20 74 68 65 20 57 41 4c 20 68 65  ad in the WAL he
af10: 61 64 65 72 2e 20 2a 2f 0a 20 20 20 20 72 63 20  ader. */.    rc 
af20: 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28  = sqlite3OsRead(
af30: 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 42  pWal->pWalFd, aB
af40: 75 66 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2c  uf, WAL_HDRSIZE,
af50: 20 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21   0);.    if( rc!
af60: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
af70: 20 20 20 20 67 6f 74 6f 20 72 65 63 6f 76 65 72      goto recover
af80: 79 5f 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a 0a  y_error;.    }..
af90: 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 64 61      /* If the da
afa0: 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65  tabase page size
afb0: 20 69 73 20 6e 6f 74 20 61 20 70 6f 77 65 72 20   is not a power 
afc0: 6f 66 20 74 77 6f 2c 20 6f 72 20 69 73 20 67 72  of two, or is gr
afd0: 65 61 74 65 72 20 74 68 61 6e 0a 20 20 20 20 2a  eater than.    *
afe0: 2a 20 53 51 4c 49 54 45 5f 4d 41 58 5f 50 41 47  * SQLITE_MAX_PAG
aff0: 45 5f 53 49 5a 45 2c 20 63 6f 6e 63 6c 75 64 65  E_SIZE, conclude
b000: 20 74 68 61 74 20 74 68 65 20 57 41 4c 20 66 69   that the WAL fi
b010: 6c 65 20 63 6f 6e 74 61 69 6e 73 20 6e 6f 20 76  le contains no v
b020: 61 6c 69 64 20 0a 20 20 20 20 2a 2a 20 64 61 74  alid .    ** dat
b030: 61 2e 20 53 69 6d 69 6c 61 72 6c 79 2c 20 69 66  a. Similarly, if
b040: 20 74 68 65 20 27 6d 61 67 69 63 27 20 76 61 6c   the 'magic' val
b050: 75 65 20 69 73 20 69 6e 76 61 6c 69 64 2c 20 69  ue is invalid, i
b060: 67 6e 6f 72 65 20 74 68 65 20 77 68 6f 6c 65 0a  gnore the whole.
b070: 20 20 20 20 2a 2a 20 57 41 4c 20 66 69 6c 65 2e      ** WAL file.
b080: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d 61 67 69  .    */.    magi
b090: 63 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62  c = sqlite3Get4b
b0a0: 79 74 65 28 26 61 42 75 66 5b 30 5d 29 3b 0a 20  yte(&aBuf[0]);. 
b0b0: 20 20 20 73 7a 50 61 67 65 20 3d 20 73 71 6c 69     szPage = sqli
b0c0: 74 65 33 47 65 74 34 62 79 74 65 28 26 61 42 75  te3Get4byte(&aBu
b0d0: 66 5b 38 5d 29 3b 0a 20 20 20 20 69 66 28 20 28  f[8]);.    if( (
b0e0: 6d 61 67 69 63 26 30 78 46 46 46 46 46 46 46 45  magic&0xFFFFFFFE
b0f0: 29 21 3d 57 41 4c 5f 4d 41 47 49 43 20 0a 20 20  )!=WAL_MAGIC .  
b100: 20 20 20 7c 7c 20 73 7a 50 61 67 65 26 28 73 7a     || szPage&(sz
b110: 50 61 67 65 2d 31 29 20 0a 20 20 20 20 20 7c 7c  Page-1) .     ||
b120: 20 73 7a 50 61 67 65 3e 53 51 4c 49 54 45 5f 4d   szPage>SQLITE_M
b130: 41 58 5f 50 41 47 45 5f 53 49 5a 45 20 0a 20 20  AX_PAGE_SIZE .  
b140: 20 20 20 7c 7c 20 73 7a 50 61 67 65 3c 35 31 32     || szPage<512
b150: 20 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 67   .    ){.      g
b160: 6f 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20  oto finished;.  
b170: 20 20 7d 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64    }.    pWal->hd
b180: 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 20 3d 20  r.bigEndCksum = 
b190: 28 75 38 29 28 6d 61 67 69 63 26 30 78 30 30 30  (u8)(magic&0x000
b1a0: 30 30 30 30 31 29 3b 0a 20 20 20 20 70 57 61 6c  00001);.    pWal
b1b0: 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67  ->szPage = szPag
b1c0: 65 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 6e 43 6b  e;.    pWal->nCk
b1d0: 70 74 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34  pt = sqlite3Get4
b1e0: 62 79 74 65 28 26 61 42 75 66 5b 31 32 5d 29 3b  byte(&aBuf[12]);
b1f0: 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 57 61  .    memcpy(&pWa
b200: 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 26 61  l->hdr.aSalt, &a
b210: 42 75 66 5b 31 36 5d 2c 20 38 29 3b 0a 0a 20 20  Buf[16], 8);..  
b220: 20 20 2f 2a 20 56 65 72 69 66 79 20 74 68 61 74    /* Verify that
b230: 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72 20   the WAL header 
b240: 63 68 65 63 6b 73 75 6d 20 69 73 20 63 6f 72 72  checksum is corr
b250: 65 63 74 20 2a 2f 0a 20 20 20 20 77 61 6c 43 68  ect */.    walCh
b260: 65 63 6b 73 75 6d 42 79 74 65 73 28 70 57 61 6c  ecksumBytes(pWal
b270: 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75  ->hdr.bigEndCksu
b280: 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e 44  m==SQLITE_BIGEND
b290: 49 41 4e 2c 20 0a 20 20 20 20 20 20 20 20 61 42  IAN, .        aB
b2a0: 75 66 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2d  uf, WAL_HDRSIZE-
b2b0: 32 2a 34 2c 20 30 2c 20 70 57 61 6c 2d 3e 68 64  2*4, 0, pWal->hd
b2c0: 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 0a 20 20  r.aFrameCksum.  
b2d0: 20 20 29 3b 0a 20 20 20 20 69 66 28 20 70 57 61    );.    if( pWa
b2e0: 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
b2f0: 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65 33 47 65  um[0]!=sqlite3Ge
b300: 74 34 62 79 74 65 28 26 61 42 75 66 5b 32 34 5d  t4byte(&aBuf[24]
b310: 29 0a 20 20 20 20 20 7c 7c 20 70 57 61 6c 2d 3e  ).     || pWal->
b320: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
b330: 31 5d 21 3d 73 71 6c 69 74 65 33 47 65 74 34 62  1]!=sqlite3Get4b
b340: 79 74 65 28 26 61 42 75 66 5b 32 38 5d 29 0a 20  yte(&aBuf[28]). 
b350: 20 20 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f     ){.      goto
b360: 20 66 69 6e 69 73 68 65 64 3b 0a 20 20 20 20 7d   finished;.    }
b370: 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20  ..    /* Verify 
b380: 74 68 61 74 20 74 68 65 20 76 65 72 73 69 6f 6e  that the version
b390: 20 6e 75 6d 62 65 72 20 6f 6e 20 74 68 65 20 57   number on the W
b3a0: 41 4c 20 66 6f 72 6d 61 74 20 69 73 20 6f 6e 65  AL format is one
b3b0: 20 74 68 61 74 0a 20 20 20 20 2a 2a 20 61 72 65   that.    ** are
b3c0: 20 61 62 6c 65 20 74 6f 20 75 6e 64 65 72 73 74   able to underst
b3d0: 61 6e 64 20 2a 2f 0a 20 20 20 20 76 65 72 73 69  and */.    versi
b3e0: 6f 6e 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34  on = sqlite3Get4
b3f0: 62 79 74 65 28 26 61 42 75 66 5b 34 5d 29 3b 0a  byte(&aBuf[4]);.
b400: 20 20 20 20 69 66 28 20 76 65 72 73 69 6f 6e 21      if( version!
b410: 3d 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49 4f 4e  =WAL_MAX_VERSION
b420: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
b430: 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 5f 42  QLITE_CANTOPEN_B
b440: 4b 50 54 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20  KPT;.      goto 
b450: 66 69 6e 69 73 68 65 64 3b 0a 20 20 20 20 7d 0a  finished;.    }.
b460: 0a 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f 63 20 61  .    /* Malloc a
b470: 20 62 75 66 66 65 72 20 74 6f 20 72 65 61 64 20   buffer to read 
b480: 66 72 61 6d 65 73 20 69 6e 74 6f 2e 20 2a 2f 0a  frames into. */.
b490: 20 20 20 20 73 7a 46 72 61 6d 65 20 3d 20 73 7a      szFrame = sz
b4a0: 50 61 67 65 20 2b 20 57 41 4c 5f 46 52 41 4d 45  Page + WAL_FRAME
b4b0: 5f 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 61 46  _HDRSIZE;.    aF
b4c0: 72 61 6d 65 20 3d 20 28 75 38 20 2a 29 73 71 6c  rame = (u8 *)sql
b4d0: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 7a 46 72  ite3_malloc(szFr
b4e0: 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21 61  ame);.    if( !a
b4f0: 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 20 20 72  Frame ){.      r
b500: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
b510: 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 72 65 63  ;.      goto rec
b520: 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20 20 20  overy_error;.   
b530: 20 7d 0a 20 20 20 20 61 44 61 74 61 20 3d 20 26   }.    aData = &
b540: 61 46 72 61 6d 65 5b 57 41 4c 5f 46 52 41 4d 45  aFrame[WAL_FRAME
b550: 5f 48 44 52 53 49 5a 45 5d 3b 0a 0a 20 20 20 20  _HDRSIZE];..    
b560: 2f 2a 20 52 65 61 64 20 61 6c 6c 20 66 72 61 6d  /* Read all fram
b570: 65 73 20 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20  es from the log 
b580: 66 69 6c 65 2e 20 2a 2f 0a 20 20 20 20 69 46 72  file. */.    iFr
b590: 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72  ame = 0;.    for
b5a0: 28 69 4f 66 66 73 65 74 3d 57 41 4c 5f 48 44 52  (iOffset=WAL_HDR
b5b0: 53 49 5a 45 3b 20 28 69 4f 66 66 73 65 74 2b 73  SIZE; (iOffset+s
b5c0: 7a 46 72 61 6d 65 29 3c 3d 6e 53 69 7a 65 3b 20  zFrame)<=nSize; 
b5d0: 69 4f 66 66 73 65 74 2b 3d 73 7a 46 72 61 6d 65  iOffset+=szFrame
b5e0: 29 7b 0a 20 20 20 20 20 20 75 33 32 20 70 67 6e  ){.      u32 pgn
b5f0: 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o;              
b600: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
b610: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 66 6f 72   page number for
b620: 20 66 72 61 6d 65 20 2a 2f 0a 20 20 20 20 20 20   frame */.      
b630: 75 33 32 20 6e 54 72 75 6e 63 61 74 65 3b 20 20  u32 nTruncate;  
b640: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 64              /* d
b650: 62 73 69 7a 65 20 66 69 65 6c 64 20 66 72 6f 6d  bsize field from
b660: 20 66 72 61 6d 65 20 68 65 61 64 65 72 20 2a 2f   frame header */
b670: 0a 0a 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20  ..      /* Read 
b680: 61 6e 64 20 64 65 63 6f 64 65 20 74 68 65 20 6e  and decode the n
b690: 65 78 74 20 6c 6f 67 20 66 72 61 6d 65 2e 20 2a  ext log frame. *
b6a0: 2f 0a 20 20 20 20 20 20 69 46 72 61 6d 65 2b 2b  /.      iFrame++
b6b0: 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  ;.      rc = sql
b6c0: 69 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d  ite3OsRead(pWal-
b6d0: 3e 70 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c  >pWalFd, aFrame,
b6e0: 20 73 7a 46 72 61 6d 65 2c 20 69 4f 66 66 73 65   szFrame, iOffse
b6f0: 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  t);.      if( rc
b700: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72  !=SQLITE_OK ) br
b710: 65 61 6b 3b 0a 20 20 20 20 20 20 69 73 56 61 6c  eak;.      isVal
b720: 69 64 20 3d 20 77 61 6c 44 65 63 6f 64 65 46 72  id = walDecodeFr
b730: 61 6d 65 28 70 57 61 6c 2c 20 26 70 67 6e 6f 2c  ame(pWal, &pgno,
b740: 20 26 6e 54 72 75 6e 63 61 74 65 2c 20 61 44 61   &nTruncate, aDa
b750: 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20 20  ta, aFrame);.   
b760: 20 20 20 69 66 28 20 21 69 73 56 61 6c 69 64 20     if( !isValid 
b770: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 72  ) break;.      r
b780: 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65  c = walIndexAppe
b790: 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c  nd(pWal, iFrame,
b7a0: 20 70 67 6e 6f 29 3b 0a 20 20 20 20 20 20 69 66   pgno);.      if
b7b0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
b7c0: 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20  ) break;..      
b7d0: 2f 2a 20 49 66 20 6e 54 72 75 6e 63 61 74 65 20  /* If nTruncate 
b7e0: 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 69  is non-zero, thi
b7f0: 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 20 72 65  s is a commit re
b800: 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 20 20 69  cord. */.      i
b810: 66 28 20 6e 54 72 75 6e 63 61 74 65 20 29 7b 0a  f( nTruncate ){.
b820: 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64          pWal->hd
b830: 72 2e 6d 78 46 72 61 6d 65 20 3d 20 69 46 72 61  r.mxFrame = iFra
b840: 6d 65 3b 0a 20 20 20 20 20 20 20 20 70 57 61 6c  me;.        pWal
b850: 2d 3e 68 64 72 2e 6e 50 61 67 65 20 3d 20 6e 54  ->hdr.nPage = nT
b860: 72 75 6e 63 61 74 65 3b 0a 20 20 20 20 20 20 20  runcate;.       
b870: 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67   pWal->hdr.szPag
b880: 65 20 3d 20 28 75 31 36 29 28 28 73 7a 50 61 67  e = (u16)((szPag
b890: 65 26 30 78 66 66 30 30 29 20 7c 20 28 73 7a 50  e&0xff00) | (szP
b8a0: 61 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20 20 20  age>>16));.     
b8b0: 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50     testcase( szP
b8c0: 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20  age<=32768 );.  
b8d0: 20 20 20 20 20 20 74 65 73 74 63 61 73 65 28 20        testcase( 
b8e0: 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20 29 3b  szPage>=65536 );
b8f0: 0a 20 20 20 20 20 20 20 20 61 46 72 61 6d 65 43  .        aFrameC
b900: 6b 73 75 6d 5b 30 5d 20 3d 20 70 57 61 6c 2d 3e  ksum[0] = pWal->
b910: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
b920: 30 5d 3b 0a 20 20 20 20 20 20 20 20 61 46 72 61  0];.        aFra
b930: 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 70 57 61  meCksum[1] = pWa
b940: 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
b950: 75 6d 5b 31 5d 3b 0a 20 20 20 20 20 20 7d 0a 20  um[1];.      }. 
b960: 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65     }..    sqlite
b970: 33 5f 66 72 65 65 28 61 46 72 61 6d 65 29 3b 0a  3_free(aFrame);.
b980: 20 20 7d 0a 0a 66 69 6e 69 73 68 65 64 3a 0a 20    }..finished:. 
b990: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
b9a0: 4f 4b 20 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69  OK ){.    volati
b9b0: 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a  le WalCkptInfo *
b9c0: 70 49 6e 66 6f 3b 0a 20 20 20 20 69 6e 74 20 69  pInfo;.    int i
b9d0: 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  ;.    pWal->hdr.
b9e0: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d  aFrameCksum[0] =
b9f0: 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b   aFrameCksum[0];
ba00: 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61  .    pWal->hdr.a
ba10: 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20  FrameCksum[1] = 
ba20: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a  aFrameCksum[1];.
ba30: 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72 69 74      walIndexWrit
ba40: 65 48 64 72 28 70 57 61 6c 29 3b 0a 0a 20 20 20  eHdr(pWal);..   
ba50: 20 2f 2a 20 52 65 73 65 74 20 74 68 65 20 63 68   /* Reset the ch
ba60: 65 63 6b 70 6f 69 6e 74 2d 68 65 61 64 65 72 2e  eckpoint-header.
ba70: 20 54 68 69 73 20 69 73 20 73 61 66 65 20 62 65   This is safe be
ba80: 63 61 75 73 65 20 74 68 69 73 20 74 68 72 65 61  cause this threa
ba90: 64 20 69 73 20 0a 20 20 20 20 2a 2a 20 63 75 72  d is .    ** cur
baa0: 72 65 6e 74 6c 79 20 68 6f 6c 64 69 6e 67 20 6c  rently holding l
bab0: 6f 63 6b 73 20 74 68 61 74 20 65 78 63 6c 75 64  ocks that exclud
bac0: 65 20 61 6c 6c 20 6f 74 68 65 72 20 72 65 61 64  e all other read
bad0: 65 72 73 2c 20 77 72 69 74 65 72 73 20 61 6e 64  ers, writers and
bae0: 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69  .    ** checkpoi
baf0: 6e 74 65 72 73 2e 0a 20 20 20 20 2a 2f 0a 20 20  nters..    */.  
bb00: 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70    pInfo = walCkp
bb10: 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20  tInfo(pWal);.   
bb20: 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
bb30: 6c 20 3d 20 30 3b 0a 20 20 20 20 70 49 6e 66 6f  l = 0;.    pInfo
bb40: 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20 3d  ->aReadMark[0] =
bb50: 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b   0;.    for(i=1;
bb60: 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
bb70: 69 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61  i++) pInfo->aRea
bb80: 64 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d  dMark[i] = READM
bb90: 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20  ARK_NOT_USED;.  
bba0: 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e    if( pWal->hdr.
bbb0: 6d 78 46 72 61 6d 65 20 29 20 70 49 6e 66 6f 2d  mxFrame ) pInfo-
bbc0: 3e 61 52 65 61 64 4d 61 72 6b 5b 31 5d 20 3d 20  >aReadMark[1] = 
bbd0: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
bbe0: 65 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 6d 6f  e;..    /* If mo
bbf0: 72 65 20 74 68 61 6e 20 6f 6e 65 20 66 72 61 6d  re than one fram
bc00: 65 20 77 61 73 20 72 65 63 6f 76 65 72 65 64 20  e was recovered 
bc10: 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20 66 69 6c  from the log fil
bc20: 65 2c 20 72 65 70 6f 72 74 20 61 6e 0a 20 20 20  e, report an.   
bc30: 20 2a 2a 20 65 76 65 6e 74 20 76 69 61 20 73 71   ** event via sq
bc40: 6c 69 74 65 33 5f 6c 6f 67 28 29 2e 20 54 68 69  lite3_log(). Thi
bc50: 73 20 69 73 20 74 6f 20 68 65 6c 70 20 77 69 74  s is to help wit
bc60: 68 20 69 64 65 6e 74 69 66 79 69 6e 67 20 70 65  h identifying pe
bc70: 72 66 6f 72 6d 61 6e 63 65 0a 20 20 20 20 2a 2a  rformance.    **
bc80: 20 70 72 6f 62 6c 65 6d 73 20 63 61 75 73 65 64   problems caused
bc90: 20 62 79 20 61 70 70 6c 69 63 61 74 69 6f 6e 73   by applications
bca0: 20 72 6f 75 74 69 6e 65 6c 79 20 73 68 75 74 74   routinely shutt
bcb0: 69 6e 67 20 64 6f 77 6e 20 77 69 74 68 6f 75 74  ing down without
bcc0: 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69  .    ** checkpoi
bcd0: 6e 74 69 6e 67 20 74 68 65 20 6c 6f 67 20 66 69  nting the log fi
bce0: 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  le..    */.    i
bcf0: 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61  f( pWal->hdr.nPa
bd00: 67 65 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  ge ){.      sqli
bd10: 74 65 33 5f 6c 6f 67 28 53 51 4c 49 54 45 5f 4f  te3_log(SQLITE_O
bd20: 4b 2c 20 22 52 65 63 6f 76 65 72 65 64 20 25 64  K, "Recovered %d
bd30: 20 66 72 61 6d 65 73 20 66 72 6f 6d 20 57 41 4c   frames from WAL
bd40: 20 66 69 6c 65 20 25 73 22 2c 0a 20 20 20 20 20   file %s",.     
bd50: 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d       pWal->hdr.m
bd60: 78 46 72 61 6d 65 2c 20 70 57 61 6c 2d 3e 7a 57  xFrame, pWal->zW
bd70: 61 6c 4e 61 6d 65 0a 20 20 20 20 20 20 29 3b 0a  alName.      );.
bd80: 20 20 20 20 7d 0a 20 20 7d 0a 0a 72 65 63 6f 76      }.  }..recov
bd90: 65 72 79 5f 65 72 72 6f 72 3a 0a 20 20 57 41 4c  ery_error:.  WAL
bda0: 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 72  TRACE(("WAL%p: r
bdb0: 65 63 6f 76 65 72 79 20 25 73 5c 6e 22 2c 20 70  ecovery %s\n", p
bdc0: 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c 65  Wal, rc ? "faile
bdd0: 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 77  d" : "ok"));.  w
bde0: 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
bdf0: 65 28 70 57 61 6c 2c 20 69 4c 6f 63 6b 2c 20 6e  e(pWal, iLock, n
be00: 4c 6f 63 6b 29 3b 0a 20 20 72 65 74 75 72 6e 20  Lock);.  return 
be10: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f  rc;.}../*.** Clo
be20: 73 65 20 61 6e 20 6f 70 65 6e 20 77 61 6c 2d 69  se an open wal-i
be30: 6e 64 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ndex..*/.static 
be40: 76 6f 69 64 20 77 61 6c 49 6e 64 65 78 43 6c 6f  void walIndexClo
be50: 73 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e  se(Wal *pWal, in
be60: 74 20 69 73 44 65 6c 65 74 65 29 7b 0a 20 20 69  t isDelete){.  i
be70: 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69  f( pWal->exclusi
be80: 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48 45 41 50  veMode==WAL_HEAP
be90: 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29 7b 0a 20  MEMORY_MODE ){. 
bea0: 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 66 6f     int i;.    fo
beb0: 72 28 69 3d 30 3b 20 69 3c 70 57 61 6c 2d 3e 6e  r(i=0; i<pWal->n
bec0: 57 69 44 61 74 61 3b 20 69 2b 2b 29 7b 0a 20 20  WiData; i++){.  
bed0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
bee0: 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d 3e 61  ((void *)pWal->a
bef0: 70 57 69 44 61 74 61 5b 69 5d 29 3b 0a 20 20 20  pWiData[i]);.   
bf00: 20 20 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74     pWal->apWiDat
bf10: 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  a[i] = 0;.    }.
bf20: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c    }else{.    sql
bf30: 69 74 65 33 4f 73 53 68 6d 55 6e 6d 61 70 28 70  ite3OsShmUnmap(p
bf40: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 73 44 65  Wal->pDbFd, isDe
bf50: 6c 65 74 65 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  lete);.  }.}../*
bf60: 20 0a 2a 2a 20 4f 70 65 6e 20 61 20 63 6f 6e 6e   .** Open a conn
bf70: 65 63 74 69 6f 6e 20 74 6f 20 74 68 65 20 57 41  ection to the WA
bf80: 4c 20 66 69 6c 65 20 7a 57 61 6c 4e 61 6d 65 2e  L file zWalName.
bf90: 20 54 68 65 20 64 61 74 61 62 61 73 65 20 66 69   The database fi
bfa0: 6c 65 20 6d 75 73 74 20 0a 2a 2a 20 61 6c 72 65  le must .** alre
bfb0: 61 64 79 20 62 65 20 6f 70 65 6e 65 64 20 6f 6e  ady be opened on
bfc0: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 70 44 62 46   connection pDbF
bfd0: 64 2e 20 54 68 65 20 62 75 66 66 65 72 20 74 68  d. The buffer th
bfe0: 61 74 20 7a 57 61 6c 4e 61 6d 65 20 70 6f 69 6e  at zWalName poin
bff0: 74 73 0a 2a 2a 20 74 6f 20 6d 75 73 74 20 72 65  ts.** to must re
c000: 6d 61 69 6e 20 76 61 6c 69 64 20 66 6f 72 20 74  main valid for t
c010: 68 65 20 6c 69 66 65 74 69 6d 65 20 6f 66 20 74  he lifetime of t
c020: 68 65 20 72 65 74 75 72 6e 65 64 20 57 61 6c 2a  he returned Wal*
c030: 20 68 61 6e 64 6c 65 2e 0a 2a 2a 0a 2a 2a 20 41   handle..**.** A
c040: 20 53 48 41 52 45 44 20 6c 6f 63 6b 20 73 68 6f   SHARED lock sho
c050: 75 6c 64 20 62 65 20 68 65 6c 64 20 6f 6e 20 74  uld be held on t
c060: 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
c070: 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   when this funct
c080: 69 6f 6e 0a 2a 2a 20 69 73 20 63 61 6c 6c 65 64  ion.** is called
c090: 2e 20 54 68 65 20 70 75 72 70 6f 73 65 20 6f 66  . The purpose of
c0a0: 20 74 68 69 73 20 53 48 41 52 45 44 20 6c 6f 63   this SHARED loc
c0b0: 6b 20 69 73 20 74 6f 20 70 72 65 76 65 6e 74 20  k is to prevent 
c0c0: 61 6e 79 20 6f 74 68 65 72 0a 2a 2a 20 63 6c 69  any other.** cli
c0d0: 65 6e 74 20 66 72 6f 6d 20 75 6e 6c 69 6e 6b 69  ent from unlinki
c0e0: 6e 67 20 74 68 65 20 57 41 4c 20 6f 72 20 77 61  ng the WAL or wa
c0f0: 6c 2d 69 6e 64 65 78 20 66 69 6c 65 2e 20 49 66  l-index file. If
c100: 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65 73 73   another process
c110: 0a 2a 2a 20 77 65 72 65 20 74 6f 20 64 6f 20 74  .** were to do t
c120: 68 69 73 20 6a 75 73 74 20 61 66 74 65 72 20 74  his just after t
c130: 68 69 73 20 63 6c 69 65 6e 74 20 6f 70 65 6e 65  his client opene
c140: 64 20 6f 6e 65 20 6f 66 20 74 68 65 73 65 20 66  d one of these f
c150: 69 6c 65 73 2c 20 74 68 65 0a 2a 2a 20 73 79 73  iles, the.** sys
c160: 74 65 6d 20 77 6f 75 6c 64 20 62 65 20 62 61 64  tem would be bad
c170: 6c 79 20 62 72 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a  ly broken..**.**
c180: 20 49 66 20 74 68 65 20 6c 6f 67 20 66 69 6c 65   If the log file
c190: 20 69 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79   is successfully
c1a0: 20 6f 70 65 6e 65 64 2c 20 53 51 4c 49 54 45 5f   opened, SQLITE_
c1b0: 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 61  OK is returned a
c1c0: 6e 64 20 0a 2a 2a 20 2a 70 70 57 61 6c 20 69 73  nd .** *ppWal is
c1d0: 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f   set to point to
c1e0: 20 61 20 6e 65 77 20 57 41 4c 20 68 61 6e 64 6c   a new WAL handl
c1f0: 65 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f  e. If an error o
c200: 63 63 75 72 73 2c 0a 2a 2a 20 61 6e 20 53 51 4c  ccurs,.** an SQL
c210: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
c220: 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 2a  s returned and *
c230: 70 70 57 61 6c 20 69 73 20 6c 65 66 74 20 75 6e  ppWal is left un
c240: 6d 6f 64 69 66 69 65 64 2e 0a 2a 2f 0a 69 6e 74  modified..*/.int
c250: 20 73 71 6c 69 74 65 33 57 61 6c 4f 70 65 6e 28   sqlite3WalOpen(
c260: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
c270: 70 56 66 73 2c 20 20 20 20 20 20 20 20 20 20 20  pVfs,           
c280: 20 20 20 2f 2a 20 76 66 73 20 6d 6f 64 75 6c 65     /* vfs module
c290: 20 74 6f 20 6f 70 65 6e 20 77 61 6c 20 61 6e 64   to open wal and
c2a0: 20 77 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a 20 20   wal-index */.  
c2b0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 44  sqlite3_file *pD
c2c0: 62 46 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  bFd,            
c2d0: 2f 2a 20 54 68 65 20 6f 70 65 6e 20 64 61 74 61  /* The open data
c2e0: 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20 63  base file */.  c
c2f0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 57 61 6c 4e  onst char *zWalN
c300: 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 2f  ame,           /
c310: 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 57 41  * Name of the WA
c320: 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20  L file */.  int 
c330: 62 4e 6f 53 68 6d 2c 20 20 20 20 20 20 20 20 20  bNoShm,         
c340: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
c350: 72 75 65 20 74 6f 20 72 75 6e 20 69 6e 20 68 65  rue to run in he
c360: 61 70 2d 6d 65 6d 6f 72 79 20 6d 6f 64 65 20 2a  ap-memory mode *
c370: 2f 0a 20 20 69 36 34 20 6d 78 57 61 6c 53 69 7a  /.  i64 mxWalSiz
c380: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
c390: 20 20 20 20 2f 2a 20 54 72 75 6e 63 61 74 65 20      /* Truncate 
c3a0: 57 41 4c 20 74 6f 20 74 68 69 73 20 73 69 7a 65  WAL to this size
c3b0: 20 6f 6e 20 72 65 73 65 74 20 2a 2f 0a 20 20 57   on reset */.  W
c3c0: 61 6c 20 2a 2a 70 70 57 61 6c 20 20 20 20 20 20  al **ppWal      
c3d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c3e0: 2a 20 4f 55 54 3a 20 41 6c 6c 6f 63 61 74 65 64  * OUT: Allocated
c3f0: 20 57 61 6c 20 68 61 6e 64 6c 65 20 2a 2f 0a 29   Wal handle */.)
c400: 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  {.  int rc;     
c410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c420: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f      /* Return Co
c430: 64 65 20 2a 2f 0a 20 20 57 61 6c 20 2a 70 52 65  de */.  Wal *pRe
c440: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
c450: 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63          /* Objec
c460: 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 6e  t to allocate an
c470: 64 20 72 65 74 75 72 6e 20 2a 2f 0a 20 20 69 6e  d return */.  in
c480: 74 20 66 6c 61 67 73 3b 20 20 20 20 20 20 20 20  t flags;        
c490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c4a0: 20 46 6c 61 67 73 20 70 61 73 73 65 64 20 74 6f   Flags passed to
c4b0: 20 4f 73 4f 70 65 6e 28 29 20 2a 2f 0a 0a 20 20   OsOpen() */..  
c4c0: 61 73 73 65 72 74 28 20 7a 57 61 6c 4e 61 6d 65  assert( zWalName
c4d0: 20 26 26 20 7a 57 61 6c 4e 61 6d 65 5b 30 5d 20   && zWalName[0] 
c4e0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 44 62  );.  assert( pDb
c4f0: 46 64 20 29 3b 0a 0a 20 20 2f 2a 20 49 6e 20 74  Fd );..  /* In t
c500: 68 65 20 61 6d 61 6c 67 61 6d 61 74 69 6f 6e 2c  he amalgamation,
c510: 20 74 68 65 20 6f 73 5f 75 6e 69 78 2e 63 20 61   the os_unix.c a
c520: 6e 64 20 6f 73 5f 77 69 6e 2e 63 20 73 6f 75 72  nd os_win.c sour
c530: 63 65 20 66 69 6c 65 73 20 63 6f 6d 65 20 62 65  ce files come be
c540: 66 6f 72 65 0a 20 20 2a 2a 20 74 68 69 73 20 73  fore.  ** this s
c550: 6f 75 72 63 65 20 66 69 6c 65 2e 20 20 56 65 72  ource file.  Ver
c560: 69 66 79 20 74 68 61 74 20 74 68 65 20 23 64 65  ify that the #de
c570: 66 69 6e 65 73 20 6f 66 20 74 68 65 20 6c 6f 63  fines of the loc
c580: 6b 69 6e 67 20 62 79 74 65 20 6f 66 66 73 65 74  king byte offset
c590: 73 0a 20 20 2a 2a 20 69 6e 20 6f 73 5f 75 6e 69  s.  ** in os_uni
c5a0: 78 2e 63 20 61 6e 64 20 6f 73 5f 77 69 6e 2e 63  x.c and os_win.c
c5b0: 20 61 67 72 65 65 20 77 69 74 68 20 74 68 65 20   agree with the 
c5c0: 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46  WALINDEX_LOCK_OF
c5d0: 46 53 45 54 20 76 61 6c 75 65 2e 0a 20 20 2a 2f  FSET value..  */
c5e0: 0a 23 69 66 64 65 66 20 57 49 4e 5f 53 48 4d 5f  .#ifdef WIN_SHM_
c5f0: 42 41 53 45 0a 20 20 61 73 73 65 72 74 28 20 57  BASE.  assert( W
c600: 49 4e 5f 53 48 4d 5f 42 41 53 45 3d 3d 57 41 4c  IN_SHM_BASE==WAL
c610: 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45  INDEX_LOCK_OFFSE
c620: 54 20 29 3b 0a 23 65 6e 64 69 66 0a 23 69 66 64  T );.#endif.#ifd
c630: 65 66 20 55 4e 49 58 5f 53 48 4d 5f 42 41 53 45  ef UNIX_SHM_BASE
c640: 0a 20 20 61 73 73 65 72 74 28 20 55 4e 49 58 5f  .  assert( UNIX_
c650: 53 48 4d 5f 42 41 53 45 3d 3d 57 41 4c 49 4e 44  SHM_BASE==WALIND
c660: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 29  EX_LOCK_OFFSET )
c670: 3b 0a 23 65 6e 64 69 66 0a 0a 0a 20 20 2f 2a 20  ;.#endif...  /* 
c680: 41 6c 6c 6f 63 61 74 65 20 61 6e 20 69 6e 73 74  Allocate an inst
c690: 61 6e 63 65 20 6f 66 20 73 74 72 75 63 74 20 57  ance of struct W
c6a0: 61 6c 20 74 6f 20 72 65 74 75 72 6e 2e 20 2a 2f  al to return. */
c6b0: 0a 20 20 2a 70 70 57 61 6c 20 3d 20 30 3b 0a 20  .  *ppWal = 0;. 
c6c0: 20 70 52 65 74 20 3d 20 28 57 61 6c 2a 29 73 71   pRet = (Wal*)sq
c6d0: 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28  lite3MallocZero(
c6e0: 73 69 7a 65 6f 66 28 57 61 6c 29 20 2b 20 70 56  sizeof(Wal) + pV
c6f0: 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a 20  fs->szOsFile);. 
c700: 20 69 66 28 20 21 70 52 65 74 20 29 7b 0a 20 20   if( !pRet ){.  
c710: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
c720: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 70 52  NOMEM;.  }..  pR
c730: 65 74 2d 3e 70 56 66 73 20 3d 20 70 56 66 73 3b  et->pVfs = pVfs;
c740: 0a 20 20 70 52 65 74 2d 3e 70 57 61 6c 46 64 20  .  pRet->pWalFd 
c750: 3d 20 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  = (sqlite3_file 
c760: 2a 29 26 70 52 65 74 5b 31 5d 3b 0a 20 20 70 52  *)&pRet[1];.  pR
c770: 65 74 2d 3e 70 44 62 46 64 20 3d 20 70 44 62 46  et->pDbFd = pDbF
c780: 64 3b 0a 20 20 70 52 65 74 2d 3e 72 65 61 64 4c  d;.  pRet->readL
c790: 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20 70 52 65 74  ock = -1;.  pRet
c7a0: 2d 3e 6d 78 57 61 6c 53 69 7a 65 20 3d 20 6d 78  ->mxWalSize = mx
c7b0: 57 61 6c 53 69 7a 65 3b 0a 20 20 70 52 65 74 2d  WalSize;.  pRet-
c7c0: 3e 7a 57 61 6c 4e 61 6d 65 20 3d 20 7a 57 61 6c  >zWalName = zWal
c7d0: 4e 61 6d 65 3b 0a 20 20 70 52 65 74 2d 3e 73 79  Name;.  pRet->sy
c7e0: 6e 63 48 65 61 64 65 72 20 3d 20 31 3b 0a 20 20  ncHeader = 1;.  
c7f0: 70 52 65 74 2d 3e 70 61 64 54 6f 53 65 63 74 6f  pRet->padToSecto
c800: 72 42 6f 75 6e 64 61 72 79 20 3d 20 31 3b 0a 20  rBoundary = 1;. 
c810: 20 70 52 65 74 2d 3e 65 78 63 6c 75 73 69 76 65   pRet->exclusive
c820: 4d 6f 64 65 20 3d 20 28 62 4e 6f 53 68 6d 20 3f  Mode = (bNoShm ?
c830: 20 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f   WAL_HEAPMEMORY_
c840: 4d 4f 44 45 3a 20 57 41 4c 5f 4e 4f 52 4d 41 4c  MODE: WAL_NORMAL
c850: 5f 4d 4f 44 45 29 3b 0a 0a 20 20 2f 2a 20 4f 70  _MODE);..  /* Op
c860: 65 6e 20 66 69 6c 65 20 68 61 6e 64 6c 65 20 6f  en file handle o
c870: 6e 20 74 68 65 20 77 72 69 74 65 2d 61 68 65 61  n the write-ahea
c880: 64 20 6c 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a 20  d log file. */. 
c890: 20 66 6c 61 67 73 20 3d 20 28 53 51 4c 49 54 45   flags = (SQLITE
c8a0: 5f 4f 50 45 4e 5f 52 45 41 44 57 52 49 54 45 7c  _OPEN_READWRITE|
c8b0: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41  SQLITE_OPEN_CREA
c8c0: 54 45 7c 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 57  TE|SQLITE_OPEN_W
c8d0: 41 4c 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69  AL);.  rc = sqli
c8e0: 74 65 33 4f 73 4f 70 65 6e 28 70 56 66 73 2c 20  te3OsOpen(pVfs, 
c8f0: 7a 57 61 6c 4e 61 6d 65 2c 20 70 52 65 74 2d 3e  zWalName, pRet->
c900: 70 57 61 6c 46 64 2c 20 66 6c 61 67 73 2c 20 26  pWalFd, flags, &
c910: 66 6c 61 67 73 29 3b 0a 20 20 69 66 28 20 72 63  flags);.  if( rc
c920: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 66  ==SQLITE_OK && f
c930: 6c 61 67 73 26 53 51 4c 49 54 45 5f 4f 50 45 4e  lags&SQLITE_OPEN
c940: 5f 52 45 41 44 4f 4e 4c 59 20 29 7b 0a 20 20 20  _READONLY ){.   
c950: 20 70 52 65 74 2d 3e 72 65 61 64 4f 6e 6c 79 20   pRet->readOnly 
c960: 3d 20 57 41 4c 5f 52 44 4f 4e 4c 59 3b 0a 20 20  = WAL_RDONLY;.  
c970: 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  }..  if( rc!=SQL
c980: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 61  ITE_OK ){.    wa
c990: 6c 49 6e 64 65 78 43 6c 6f 73 65 28 70 52 65 74  lIndexClose(pRet
c9a0: 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  , 0);.    sqlite
c9b0: 33 4f 73 43 6c 6f 73 65 28 70 52 65 74 2d 3e 70  3OsClose(pRet->p
c9c0: 57 61 6c 46 64 29 3b 0a 20 20 20 20 73 71 6c 69  WalFd);.    sqli
c9d0: 74 65 33 5f 66 72 65 65 28 70 52 65 74 29 3b 0a  te3_free(pRet);.
c9e0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74    }else{.    int
c9f0: 20 69 44 43 20 3d 20 73 71 6c 69 74 65 33 4f 73   iDC = sqlite3Os
ca00: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
ca10: 73 74 69 63 73 28 70 52 65 74 2d 3e 70 57 61 6c  stics(pRet->pWal
ca20: 46 64 29 3b 0a 20 20 20 20 69 66 28 20 69 44 43  Fd);.    if( iDC
ca30: 20 26 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f   & SQLITE_IOCAP_
ca40: 53 45 51 55 45 4e 54 49 41 4c 20 29 7b 20 70 52  SEQUENTIAL ){ pR
ca50: 65 74 2d 3e 73 79 6e 63 48 65 61 64 65 72 20 3d  et->syncHeader =
ca60: 20 30 3b 20 7d 0a 20 20 20 20 69 66 28 20 69 44   0; }.    if( iD
ca70: 43 20 26 20 53 51 4c 49 54 45 5f 49 4f 43 41 50  C & SQLITE_IOCAP
ca80: 5f 50 4f 57 45 52 53 41 46 45 5f 4f 56 45 52 57  _POWERSAFE_OVERW
ca90: 52 49 54 45 20 29 7b 0a 20 20 20 20 20 20 70 52  RITE ){.      pR
caa0: 65 74 2d 3e 70 61 64 54 6f 53 65 63 74 6f 72 42  et->padToSectorB
cab0: 6f 75 6e 64 61 72 79 20 3d 20 30 3b 0a 20 20 20  oundary = 0;.   
cac0: 20 7d 0a 20 20 20 20 2a 70 70 57 61 6c 20 3d 20   }.    *ppWal = 
cad0: 70 52 65 74 3b 0a 20 20 20 20 57 41 4c 54 52 41  pRet;.    WALTRA
cae0: 43 45 28 28 22 57 41 4c 25 64 3a 20 6f 70 65 6e  CE(("WAL%d: open
caf0: 65 64 5c 6e 22 2c 20 70 52 65 74 29 29 3b 0a 20  ed\n", pRet));. 
cb00: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
cb10: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61 6e 67 65 20  }../*.** Change 
cb20: 74 68 65 20 73 69 7a 65 20 74 6f 20 77 68 69 63  the size to whic
cb30: 68 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20 69  h the WAL file i
cb40: 73 20 74 72 75 63 61 74 65 64 20 6f 6e 20 65 61  s trucated on ea
cb50: 63 68 20 72 65 73 65 74 2e 0a 2a 2f 0a 76 6f 69  ch reset..*/.voi
cb60: 64 20 73 71 6c 69 74 65 33 57 61 6c 4c 69 6d 69  d sqlite3WalLimi
cb70: 74 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 36 34  t(Wal *pWal, i64
cb80: 20 69 4c 69 6d 69 74 29 7b 0a 20 20 69 66 28 20   iLimit){.  if( 
cb90: 70 57 61 6c 20 29 20 70 57 61 6c 2d 3e 6d 78 57  pWal ) pWal->mxW
cba0: 61 6c 53 69 7a 65 20 3d 20 69 4c 69 6d 69 74 3b  alSize = iLimit;
cbb0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 64 20 74  .}../*.** Find t
cbc0: 68 65 20 73 6d 61 6c 6c 65 73 74 20 70 61 67 65  he smallest page
cbd0: 20 6e 75 6d 62 65 72 20 6f 75 74 20 6f 66 20 61   number out of a
cbe0: 6c 6c 20 70 61 67 65 73 20 68 65 6c 64 20 69 6e  ll pages held in
cbf0: 20 74 68 65 20 57 41 4c 20 74 68 61 74 0a 2a 2a   the WAL that.**
cc00: 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 72 65   has not been re
cc10: 74 75 72 6e 65 64 20 62 79 20 61 6e 79 20 70 72  turned by any pr
cc20: 69 6f 72 20 69 6e 76 6f 63 61 74 69 6f 6e 20 6f  ior invocation o
cc30: 66 20 74 68 69 73 20 6d 65 74 68 6f 64 20 6f 6e  f this method on
cc40: 20 74 68 65 0a 2a 2a 20 73 61 6d 65 20 57 61 6c   the.** same Wal
cc50: 49 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 2e  Iterator object.
cc60: 20 20 20 57 72 69 74 65 20 69 6e 74 6f 20 2a 70     Write into *p
cc70: 69 46 72 61 6d 65 20 74 68 65 20 66 72 61 6d 65  iFrame the frame
cc80: 20 69 6e 64 65 78 20 77 68 65 72 65 0a 2a 2a 20   index where.** 
cc90: 74 68 61 74 20 70 61 67 65 20 77 61 73 20 6c 61  that page was la
cca0: 73 74 20 77 72 69 74 74 65 6e 20 69 6e 74 6f 20  st written into 
ccb0: 74 68 65 20 57 41 4c 2e 20 20 57 72 69 74 65 20  the WAL.  Write 
ccc0: 69 6e 74 6f 20 2a 70 69 50 61 67 65 20 74 68 65  into *piPage the
ccd0: 20 70 61 67 65 0a 2a 2a 20 6e 75 6d 62 65 72 2e   page.** number.
cce0: 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 30 20  .**.** Return 0 
ccf0: 6f 6e 20 73 75 63 63 65 73 73 2e 20 20 49 66 20  on success.  If 
cd00: 74 68 65 72 65 20 61 72 65 20 6e 6f 20 70 61 67  there are no pag
cd10: 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20 77 69  es in the WAL wi
cd20: 74 68 20 61 20 70 61 67 65 0a 2a 2a 20 6e 75 6d  th a page.** num
cd30: 62 65 72 20 6c 61 72 67 65 72 20 74 68 61 6e 20  ber larger than 
cd40: 2a 70 69 50 61 67 65 2c 20 74 68 65 6e 20 72 65  *piPage, then re
cd50: 74 75 72 6e 20 31 2e 0a 2a 2f 0a 73 74 61 74 69  turn 1..*/.stati
cd60: 63 20 69 6e 74 20 77 61 6c 49 74 65 72 61 74 6f  c int walIterato
cd70: 72 4e 65 78 74 28 0a 20 20 57 61 6c 49 74 65 72  rNext(.  WalIter
cd80: 61 74 6f 72 20 2a 70 2c 20 20 20 20 20 20 20 20  ator *p,        
cd90: 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74         /* Iterat
cda0: 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 50  or */.  u32 *piP
cdb0: 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  age,            
cdc0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 68        /* OUT: Th
cdd0: 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 66  e page number of
cde0: 20 74 68 65 20 6e 65 78 74 20 70 61 67 65 20 2a   the next page *
cdf0: 2f 0a 20 20 75 33 32 20 2a 70 69 46 72 61 6d 65  /.  u32 *piFrame
ce00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ce10: 20 20 2f 2a 20 4f 55 54 3a 20 57 61 6c 20 66 72    /* OUT: Wal fr
ce20: 61 6d 65 20 69 6e 64 65 78 20 6f 66 20 6e 65 78  ame index of nex
ce30: 74 20 70 61 67 65 20 2a 2f 0a 29 7b 0a 20 20 75  t page */.){.  u
ce40: 33 32 20 69 4d 69 6e 3b 20 20 20 20 20 20 20 20  32 iMin;        
ce50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
ce60: 52 65 73 75 6c 74 20 70 67 6e 6f 20 6d 75 73 74  Result pgno must
ce70: 20 62 65 20 67 72 65 61 74 65 72 20 74 68 61 6e   be greater than
ce80: 20 69 4d 69 6e 20 2a 2f 0a 20 20 75 33 32 20 69   iMin */.  u32 i
ce90: 52 65 74 20 3d 20 30 78 46 46 46 46 46 46 46 46  Ret = 0xFFFFFFFF
cea0: 3b 20 20 20 20 20 20 20 20 2f 2a 20 30 78 66 66  ;        /* 0xff
ceb0: 66 66 66 66 66 66 20 69 73 20 6e 65 76 65 72 20  ffffff is never 
cec0: 61 20 76 61 6c 69 64 20 70 61 67 65 20 6e 75 6d  a valid page num
ced0: 62 65 72 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20  ber */.  int i; 
cee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cef0: 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 6c 6f         /* For lo
cf00: 6f 70 69 6e 67 20 74 68 72 6f 75 67 68 20 73 65  oping through se
cf10: 67 6d 65 6e 74 73 20 2a 2f 0a 0a 20 20 69 4d 69  gments */..  iMi
cf20: 6e 20 3d 20 70 2d 3e 69 50 72 69 6f 72 3b 0a 20  n = p->iPrior;. 
cf30: 20 61 73 73 65 72 74 28 20 69 4d 69 6e 3c 30 78   assert( iMin<0x
cf40: 66 66 66 66 66 66 66 66 20 29 3b 0a 20 20 66 6f  ffffffff );.  fo
cf50: 72 28 69 3d 70 2d 3e 6e 53 65 67 6d 65 6e 74 2d  r(i=p->nSegment-
cf60: 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29 7b 0a 20  1; i>=0; i--){. 
cf70: 20 20 20 73 74 72 75 63 74 20 57 61 6c 53 65 67     struct WalSeg
cf80: 6d 65 6e 74 20 2a 70 53 65 67 6d 65 6e 74 20 3d  ment *pSegment =
cf90: 20 26 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d   &p->aSegment[i]
cfa0: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 70 53 65  ;.    while( pSe
cfb0: 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 3c 70 53 65  gment->iNext<pSe
cfc0: 67 6d 65 6e 74 2d 3e 6e 45 6e 74 72 79 20 29 7b  gment->nEntry ){
cfd0: 0a 20 20 20 20 20 20 75 33 32 20 69 50 67 20 3d  .      u32 iPg =
cfe0: 20 70 53 65 67 6d 65 6e 74 2d 3e 61 50 67 6e 6f   pSegment->aPgno
cff0: 5b 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e 64 65  [pSegment->aInde
d000: 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78  x[pSegment->iNex
d010: 74 5d 5d 3b 0a 20 20 20 20 20 20 69 66 28 20 69  t]];.      if( i
d020: 50 67 3e 69 4d 69 6e 20 29 7b 0a 20 20 20 20 20  Pg>iMin ){.     
d030: 20 20 20 69 66 28 20 69 50 67 3c 69 52 65 74 20     if( iPg<iRet 
d040: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 52 65  ){.          iRe
d050: 74 20 3d 20 69 50 67 3b 0a 20 20 20 20 20 20 20  t = iPg;.       
d060: 20 20 20 2a 70 69 46 72 61 6d 65 20 3d 20 70 53     *piFrame = pS
d070: 65 67 6d 65 6e 74 2d 3e 69 5a 65 72 6f 20 2b 20  egment->iZero + 
d080: 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e 64 65 78  pSegment->aIndex
d090: 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74  [pSegment->iNext
d0a0: 5d 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  ];.        }.   
d0b0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
d0c0: 20 20 7d 0a 20 20 20 20 20 20 70 53 65 67 6d 65    }.      pSegme
d0d0: 6e 74 2d 3e 69 4e 65 78 74 2b 2b 3b 0a 20 20 20  nt->iNext++;.   
d0e0: 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 69 50 61 67   }.  }..  *piPag
d0f0: 65 20 3d 20 70 2d 3e 69 50 72 69 6f 72 20 3d 20  e = p->iPrior = 
d100: 69 52 65 74 3b 0a 20 20 72 65 74 75 72 6e 20 28  iRet;.  return (
d110: 69 52 65 74 3d 3d 30 78 46 46 46 46 46 46 46 46  iRet==0xFFFFFFFF
d120: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  );.}../*.** This
d130: 20 66 75 6e 63 74 69 6f 6e 20 6d 65 72 67 65 73   function merges
d140: 20 74 77 6f 20 73 6f 72 74 65 64 20 6c 69 73 74   two sorted list
d150: 73 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20  s into a single 
d160: 73 6f 72 74 65 64 20 6c 69 73 74 2e 0a 2a 2a 0a  sorted list..**.
d170: 2a 2a 20 61 4c 65 66 74 5b 5d 20 61 6e 64 20 61  ** aLeft[] and a
d180: 52 69 67 68 74 5b 5d 20 61 72 65 20 61 72 72 61  Right[] are arra
d190: 79 73 20 6f 66 20 69 6e 64 69 63 65 73 2e 20 20  ys of indices.  
d1a0: 54 68 65 20 73 6f 72 74 20 6b 65 79 20 69 73 0a  The sort key is.
d1b0: 2a 2a 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66  ** aContent[aLef
d1c0: 74 5b 5d 5d 20 61 6e 64 20 61 43 6f 6e 74 65 6e  t[]] and aConten
d1d0: 74 5b 61 52 69 67 68 74 5b 5d 5d 2e 20 20 55 70  t[aRight[]].  Up
d1e0: 6f 6e 20 65 6e 74 72 79 2c 20 74 68 65 20 66 6f  on entry, the fo
d1f0: 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 69 73 20 67 75  llowing.** is gu
d200: 61 72 61 6e 74 65 65 64 20 66 6f 72 20 61 6c 6c  aranteed for all
d210: 20 4a 3c 4b 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20   J<K:.**.**     
d220: 20 20 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66     aContent[aLef
d230: 74 5b 4a 5d 5d 20 3c 20 61 43 6f 6e 74 65 6e 74  t[J]] < aContent
d240: 5b 61 4c 65 66 74 5b 4b 5d 5d 0a 2a 2a 20 20 20  [aLeft[K]].**   
d250: 20 20 20 20 20 61 43 6f 6e 74 65 6e 74 5b 61 52       aContent[aR
d260: 69 67 68 74 5b 4a 5d 5d 20 3c 20 61 43 6f 6e 74  ight[J]] < aCont
d270: 65 6e 74 5b 61 52 69 67 68 74 5b 4b 5d 5d 0a 2a  ent[aRight[K]].*
d280: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  *.** This routin
d290: 65 20 6f 76 65 72 77 72 69 74 65 73 20 61 52 69  e overwrites aRi
d2a0: 67 68 74 5b 5d 20 77 69 74 68 20 61 20 6e 65 77  ght[] with a new
d2b0: 20 28 70 72 6f 62 61 62 6c 79 20 6c 6f 6e 67 65   (probably longe
d2c0: 72 29 20 73 65 71 75 65 6e 63 65 0a 2a 2a 20 6f  r) sequence.** o
d2d0: 66 20 69 6e 64 69 63 65 73 20 73 75 63 68 20 74  f indices such t
d2e0: 68 61 74 20 74 68 65 20 61 52 69 67 68 74 5b 5d  hat the aRight[]
d2f0: 20 63 6f 6e 74 61 69 6e 73 20 65 76 65 72 79 20   contains every 
d300: 69 6e 64 65 78 20 74 68 61 74 20 61 70 70 65 61  index that appea
d310: 72 73 20 69 6e 0a 2a 2a 20 65 69 74 68 65 72 20  rs in.** either 
d320: 61 4c 65 66 74 5b 5d 20 6f 72 20 74 68 65 20 6f  aLeft[] or the o
d330: 6c 64 20 61 52 69 67 68 74 5b 5d 20 61 6e 64 20  ld aRight[] and 
d340: 73 75 63 68 20 74 68 61 74 20 74 68 65 20 73 65  such that the se
d350: 63 6f 6e 64 20 63 6f 6e 64 69 74 69 6f 6e 0a 2a  cond condition.*
d360: 2a 20 61 62 6f 76 65 20 69 73 20 73 74 69 6c 6c  * above is still
d370: 20 6d 65 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20   met..**.** The 
d380: 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 58  aContent[aLeft[X
d390: 5d 5d 20 76 61 6c 75 65 73 20 77 69 6c 6c 20 62  ]] values will b
d3a0: 65 20 75 6e 69 71 75 65 20 66 6f 72 20 61 6c 6c  e unique for all
d3b0: 20 58 2e 20 20 41 6e 64 20 74 68 65 0a 2a 2a 20   X.  And the.** 
d3c0: 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b  aContent[aRight[
d3d0: 58 5d 5d 20 76 61 6c 75 65 73 20 77 69 6c 6c 20  X]] values will 
d3e0: 62 65 20 75 6e 69 71 75 65 20 74 6f 6f 2e 20 20  be unique too.  
d3f0: 42 75 74 20 74 68 65 72 65 20 6d 69 67 68 74 20  But there might 
d400: 62 65 0a 2a 2a 20 6f 6e 65 20 6f 72 20 6d 6f 72  be.** one or mor
d410: 65 20 63 6f 6d 62 69 6e 61 74 69 6f 6e 73 20 6f  e combinations o
d420: 66 20 58 20 61 6e 64 20 59 20 73 75 63 68 20 74  f X and Y such t
d430: 68 61 74 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 61  hat.**.**      a
d440: 4c 65 66 74 5b 58 5d 21 3d 61 52 69 67 68 74 5b  Left[X]!=aRight[
d450: 59 5d 20 20 26 26 20 20 61 43 6f 6e 74 65 6e 74  Y]  &&  aContent
d460: 5b 61 4c 65 66 74 5b 58 5d 5d 20 3d 3d 20 61 43  [aLeft[X]] == aC
d470: 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b 59 5d  ontent[aRight[Y]
d480: 5d 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 74 68 61  ].**.** When tha
d490: 74 20 68 61 70 70 65 6e 73 2c 20 6f 6d 69 74 20  t happens, omit 
d4a0: 74 68 65 20 61 4c 65 66 74 5b 58 5d 20 61 6e 64  the aLeft[X] and
d4b0: 20 75 73 65 20 74 68 65 20 61 52 69 67 68 74 5b   use the aRight[
d4c0: 59 5d 20 69 6e 64 65 78 2e 0a 2a 2f 0a 73 74 61  Y] index..*/.sta
d4d0: 74 69 63 20 76 6f 69 64 20 77 61 6c 4d 65 72 67  tic void walMerg
d4e0: 65 28 0a 20 20 63 6f 6e 73 74 20 75 33 32 20 2a  e(.  const u32 *
d4f0: 61 43 6f 6e 74 65 6e 74 2c 20 20 20 20 20 20 20  aContent,       
d500: 20 20 20 20 20 2f 2a 20 50 61 67 65 73 20 69 6e       /* Pages in
d510: 20 77 61 6c 20 2d 20 6b 65 79 73 20 66 6f 72 20   wal - keys for 
d520: 74 68 65 20 73 6f 72 74 20 2a 2f 0a 20 20 68 74  the sort */.  ht
d530: 5f 73 6c 6f 74 20 2a 61 4c 65 66 74 2c 20 20 20  _slot *aLeft,   
d540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d550: 20 49 4e 3a 20 4c 65 66 74 20 68 61 6e 64 20 69   IN: Left hand i
d560: 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69  nput list */.  i
d570: 6e 74 20 6e 4c 65 66 74 2c 20 20 20 20 20 20 20  nt nLeft,       
d580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
d590: 2a 20 49 4e 3a 20 45 6c 65 6d 65 6e 74 73 20 69  * IN: Elements i
d5a0: 6e 20 61 72 72 61 79 20 2a 70 61 4c 65 66 74 20  n array *paLeft 
d5b0: 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 2a 70  */.  ht_slot **p
d5c0: 61 52 69 67 68 74 2c 20 20 20 20 20 20 20 20 20  aRight,         
d5d0: 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20       /* IN/OUT: 
d5e0: 52 69 67 68 74 20 68 61 6e 64 20 69 6e 70 75 74  Right hand input
d5f0: 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 2a   list */.  int *
d600: 70 6e 52 69 67 68 74 2c 20 20 20 20 20 20 20 20  pnRight,        
d610: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e             /* IN
d620: 2f 4f 55 54 3a 20 45 6c 65 6d 65 6e 74 73 20 69  /OUT: Elements i
d630: 6e 20 2a 70 61 52 69 67 68 74 20 2a 2f 0a 20 20  n *paRight */.  
d640: 68 74 5f 73 6c 6f 74 20 2a 61 54 6d 70 20 20 20  ht_slot *aTmp   
d650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d660: 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62 75 66  /* Temporary buf
d670: 66 65 72 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  fer */.){.  int 
d680: 69 4c 65 66 74 20 3d 20 30 3b 20 20 20 20 20 20  iLeft = 0;      
d690: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
d6a0: 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e 20  urrent index in 
d6b0: 61 4c 65 66 74 20 2a 2f 0a 20 20 69 6e 74 20 69  aLeft */.  int i
d6c0: 52 69 67 68 74 20 3d 20 30 3b 20 20 20 20 20 20  Right = 0;      
d6d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
d6e0: 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e 20 61  rrent index in a
d6f0: 52 69 67 68 74 20 2a 2f 0a 20 20 69 6e 74 20 69  Right */.  int i
d700: 4f 75 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20  Out = 0;        
d710: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
d720: 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e 20 6f  rrent index in o
d730: 75 74 70 75 74 20 62 75 66 66 65 72 20 2a 2f 0a  utput buffer */.
d740: 20 20 69 6e 74 20 6e 52 69 67 68 74 20 3d 20 2a    int nRight = *
d750: 70 6e 52 69 67 68 74 3b 0a 20 20 68 74 5f 73 6c  pnRight;.  ht_sl
d760: 6f 74 20 2a 61 52 69 67 68 74 20 3d 20 2a 70 61  ot *aRight = *pa
d770: 52 69 67 68 74 3b 0a 0a 20 20 61 73 73 65 72 74  Right;..  assert
d780: 28 20 6e 4c 65 66 74 3e 30 20 26 26 20 6e 52 69  ( nLeft>0 && nRi
d790: 67 68 74 3e 30 20 29 3b 0a 20 20 77 68 69 6c 65  ght>0 );.  while
d7a0: 28 20 69 52 69 67 68 74 3c 6e 52 69 67 68 74 20  ( iRight<nRight 
d7b0: 7c 7c 20 69 4c 65 66 74 3c 6e 4c 65 66 74 20 29  || iLeft<nLeft )
d7c0: 7b 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20 6c 6f  {.    ht_slot lo
d7d0: 67 70 61 67 65 3b 0a 20 20 20 20 50 67 6e 6f 20  gpage;.    Pgno 
d7e0: 64 62 70 61 67 65 3b 0a 0a 20 20 20 20 69 66 28  dbpage;..    if(
d7f0: 20 28 69 4c 65 66 74 3c 6e 4c 65 66 74 29 20 0a   (iLeft<nLeft) .
d800: 20 20 20 20 20 26 26 20 28 69 52 69 67 68 74 3e       && (iRight>
d810: 3d 6e 52 69 67 68 74 20 7c 7c 20 61 43 6f 6e 74  =nRight || aCont
d820: 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74 5d  ent[aLeft[iLeft]
d830: 5d 3c 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68  ]<aContent[aRigh
d840: 74 5b 69 52 69 67 68 74 5d 5d 29 0a 20 20 20 20  t[iRight]]).    
d850: 29 7b 0a 20 20 20 20 20 20 6c 6f 67 70 61 67 65  ){.      logpage
d860: 20 3d 20 61 4c 65 66 74 5b 69 4c 65 66 74 2b 2b   = aLeft[iLeft++
d870: 5d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  ];.    }else{.  
d880: 20 20 20 20 6c 6f 67 70 61 67 65 20 3d 20 61 52      logpage = aR
d890: 69 67 68 74 5b 69 52 69 67 68 74 2b 2b 5d 3b 0a  ight[iRight++];.
d8a0: 20 20 20 20 7d 0a 20 20 20 20 64 62 70 61 67 65      }.    dbpage
d8b0: 20 3d 20 61 43 6f 6e 74 65 6e 74 5b 6c 6f 67 70   = aContent[logp
d8c0: 61 67 65 5d 3b 0a 0a 20 20 20 20 61 54 6d 70 5b  age];..    aTmp[
d8d0: 69 4f 75 74 2b 2b 5d 20 3d 20 6c 6f 67 70 61 67  iOut++] = logpag
d8e0: 65 3b 0a 20 20 20 20 69 66 28 20 69 4c 65 66 74  e;.    if( iLeft
d8f0: 3c 6e 4c 65 66 74 20 26 26 20 61 43 6f 6e 74 65  <nLeft && aConte
d900: 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74 5d 5d  nt[aLeft[iLeft]]
d910: 3d 3d 64 62 70 61 67 65 20 29 20 69 4c 65 66 74  ==dbpage ) iLeft
d920: 2b 2b 3b 0a 0a 20 20 20 20 61 73 73 65 72 74 28  ++;..    assert(
d930: 20 69 4c 65 66 74 3e 3d 6e 4c 65 66 74 20 7c 7c   iLeft>=nLeft ||
d940: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b   aContent[aLeft[
d950: 69 4c 65 66 74 5d 5d 3e 64 62 70 61 67 65 20 29  iLeft]]>dbpage )
d960: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 52  ;.    assert( iR
d970: 69 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c 20  ight>=nRight || 
d980: 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b  aContent[aRight[
d990: 69 52 69 67 68 74 5d 5d 3e 64 62 70 61 67 65 20  iRight]]>dbpage 
d9a0: 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 61 52 69 67  );.  }..  *paRig
d9b0: 68 74 20 3d 20 61 4c 65 66 74 3b 0a 20 20 2a 70  ht = aLeft;.  *p
d9c0: 6e 52 69 67 68 74 20 3d 20 69 4f 75 74 3b 0a 20  nRight = iOut;. 
d9d0: 20 6d 65 6d 63 70 79 28 61 4c 65 66 74 2c 20 61   memcpy(aLeft, a
d9e0: 54 6d 70 2c 20 73 69 7a 65 6f 66 28 61 54 6d 70  Tmp, sizeof(aTmp
d9f0: 5b 30 5d 29 2a 69 4f 75 74 29 3b 0a 7d 0a 0a 2f  [0])*iOut);.}../
da00: 2a 0a 2a 2a 20 53 6f 72 74 20 74 68 65 20 65 6c  *.** Sort the el
da10: 65 6d 65 6e 74 73 20 69 6e 20 6c 69 73 74 20 61  ements in list a
da20: 4c 69 73 74 20 75 73 69 6e 67 20 61 43 6f 6e 74  List using aCont
da30: 65 6e 74 5b 5d 20 61 73 20 74 68 65 20 73 6f 72  ent[] as the sor
da40: 74 20 6b 65 79 2e 0a 2a 2a 20 52 65 6d 6f 76 65  t key..** Remove
da50: 20 65 6c 65 6d 65 6e 74 73 20 77 69 74 68 20 64   elements with d
da60: 75 70 6c 69 63 61 74 65 20 6b 65 79 73 2c 20 70  uplicate keys, p
da70: 72 65 66 65 72 72 69 6e 67 20 74 6f 20 6b 65 65  referring to kee
da80: 70 20 74 68 65 0a 2a 2a 20 6c 61 72 67 65 72 20  p the.** larger 
da90: 61 4c 69 73 74 5b 5d 20 76 61 6c 75 65 73 2e 0a  aList[] values..
daa0: 2a 2a 0a 2a 2a 20 54 68 65 20 61 4c 69 73 74 5b  **.** The aList[
dab0: 5d 20 65 6e 74 72 69 65 73 20 61 72 65 20 69 6e  ] entries are in
dac0: 64 69 63 65 73 20 69 6e 74 6f 20 61 43 6f 6e 74  dices into aCont
dad0: 65 6e 74 5b 5d 2e 20 20 54 68 65 20 76 61 6c 75  ent[].  The valu
dae0: 65 73 20 69 6e 0a 2a 2a 20 61 4c 69 73 74 5b 5d  es in.** aList[]
daf0: 20 61 72 65 20 74 6f 20 62 65 20 73 6f 72 74 65   are to be sorte
db00: 64 20 73 6f 20 74 68 61 74 20 66 6f 72 20 61 6c  d so that for al
db10: 6c 20 4a 3c 4b 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  l J<K:.**.**    
db20: 20 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74    aContent[aList
db30: 5b 4a 5d 5d 20 3c 20 61 43 6f 6e 74 65 6e 74 5b  [J]] < aContent[
db40: 61 4c 69 73 74 5b 4b 5d 5d 0a 2a 2a 0a 2a 2a 20  aList[K]].**.** 
db50: 46 6f 72 20 61 6e 79 20 58 20 61 6e 64 20 59 20  For any X and Y 
db60: 73 75 63 68 20 74 68 61 74 0a 2a 2a 0a 2a 2a 20  such that.**.** 
db70: 20 20 20 20 20 61 43 6f 6e 74 65 6e 74 5b 61 4c       aContent[aL
db80: 69 73 74 5b 58 5d 5d 20 3d 3d 20 61 43 6f 6e 74  ist[X]] == aCont
db90: 65 6e 74 5b 61 4c 69 73 74 5b 59 5d 5d 0a 2a 2a  ent[aList[Y]].**
dba0: 0a 2a 2a 20 4b 65 65 70 20 74 68 65 20 6c 61 72  .** Keep the lar
dbb0: 67 65 72 20 6f 66 20 74 68 65 20 74 77 6f 20 76  ger of the two v
dbc0: 61 6c 75 65 73 20 61 4c 69 73 74 5b 58 5d 20 61  alues aList[X] a
dbd0: 6e 64 20 61 4c 69 73 74 5b 59 5d 20 61 6e 64 20  nd aList[Y] and 
dbe0: 64 69 73 63 61 72 64 0a 2a 2a 20 74 68 65 20 73  discard.** the s
dbf0: 6d 61 6c 6c 65 72 2e 0a 2a 2f 0a 73 74 61 74 69  maller..*/.stati
dc00: 63 20 76 6f 69 64 20 77 61 6c 4d 65 72 67 65 73  c void walMerges
dc10: 6f 72 74 28 0a 20 20 63 6f 6e 73 74 20 75 33 32  ort(.  const u32
dc20: 20 2a 61 43 6f 6e 74 65 6e 74 2c 20 20 20 20 20   *aContent,     
dc30: 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 73 20         /* Pages 
dc40: 69 6e 20 77 61 6c 20 2a 2f 0a 20 20 68 74 5f 73  in wal */.  ht_s
dc50: 6c 6f 74 20 2a 61 42 75 66 66 65 72 2c 20 20 20  lot *aBuffer,   
dc60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
dc70: 75 66 66 65 72 20 6f 66 20 61 74 20 6c 65 61 73  uffer of at leas
dc80: 74 20 2a 70 6e 4c 69 73 74 20 69 74 65 6d 73 20  t *pnList items 
dc90: 74 6f 20 75 73 65 20 2a 2f 0a 20 20 68 74 5f 73  to use */.  ht_s
dca0: 6c 6f 74 20 2a 61 4c 69 73 74 2c 20 20 20 20 20  lot *aList,     
dcb0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
dcc0: 4e 2f 4f 55 54 3a 20 4c 69 73 74 20 74 6f 20 73  N/OUT: List to s
dcd0: 6f 72 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e  ort */.  int *pn
dce0: 4c 69 73 74 20 20 20 20 20 20 20 20 20 20 20 20  List            
dcf0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f           /* IN/O
dd00: 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c  UT: Number of el
dd10: 65 6d 65 6e 74 73 20 69 6e 20 61 4c 69 73 74 5b  ements in aList[
dd20: 5d 20 2a 2f 0a 29 7b 0a 20 20 73 74 72 75 63 74  ] */.){.  struct
dd30: 20 53 75 62 6c 69 73 74 20 7b 0a 20 20 20 20 69   Sublist {.    i
dd40: 6e 74 20 6e 4c 69 73 74 3b 20 20 20 20 20 20 20  nt nList;       
dd50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
dd60: 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e  Number of elemen
dd70: 74 73 20 69 6e 20 61 4c 69 73 74 20 2a 2f 0a 20  ts in aList */. 
dd80: 20 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 69 73     ht_slot *aLis
dd90: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
dda0: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 73   /* Pointer to s
ddb0: 75 62 2d 6c 69 73 74 20 63 6f 6e 74 65 6e 74 20  ub-list content 
ddc0: 2a 2f 0a 20 20 7d 3b 0a 0a 20 20 63 6f 6e 73 74  */.  };..  const
ddd0: 20 69 6e 74 20 6e 4c 69 73 74 20 3d 20 2a 70 6e   int nList = *pn
dde0: 4c 69 73 74 3b 20 20 20 20 20 20 2f 2a 20 53 69  List;      /* Si
ddf0: 7a 65 20 6f 66 20 69 6e 70 75 74 20 6c 69 73 74  ze of input list
de00: 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 65 72 67 65   */.  int nMerge
de10: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
de20: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
de30: 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 6c  of elements in l
de40: 69 73 74 20 61 4d 65 72 67 65 20 2a 2f 0a 20 20  ist aMerge */.  
de50: 68 74 5f 73 6c 6f 74 20 2a 61 4d 65 72 67 65 20  ht_slot *aMerge 
de60: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
de70: 2f 2a 20 4c 69 73 74 20 74 6f 20 62 65 20 6d 65  /* List to be me
de80: 72 67 65 64 20 2a 2f 0a 20 20 69 6e 74 20 69 4c  rged */.  int iL
de90: 69 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ist;            
dea0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
deb0: 65 78 20 69 6e 74 6f 20 69 6e 70 75 74 20 6c 69  ex into input li
dec0: 73 74 20 2a 2f 0a 20 20 69 6e 74 20 69 53 75 62  st */.  int iSub
ded0: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
dee0: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78          /* Index
def0: 20 69 6e 74 6f 20 61 53 75 62 20 61 72 72 61 79   into aSub array
df00: 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 53 75 62   */.  struct Sub
df10: 6c 69 73 74 20 61 53 75 62 5b 31 33 5d 3b 20 20  list aSub[13];  
df20: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
df30: 66 20 73 75 62 2d 6c 69 73 74 73 20 2a 2f 0a 0a  f sub-lists */..
df40: 20 20 6d 65 6d 73 65 74 28 61 53 75 62 2c 20 30    memset(aSub, 0
df50: 2c 20 73 69 7a 65 6f 66 28 61 53 75 62 29 29 3b  , sizeof(aSub));
df60: 0a 20 20 61 73 73 65 72 74 28 20 6e 4c 69 73 74  .  assert( nList
df70: 3c 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  <=HASHTABLE_NPAG
df80: 45 20 26 26 20 6e 4c 69 73 74 3e 30 20 29 3b 0a  E && nList>0 );.
df90: 20 20 61 73 73 65 72 74 28 20 48 41 53 48 54 41    assert( HASHTA
dfa0: 42 4c 45 5f 4e 50 41 47 45 3d 3d 28 31 3c 3c 28  BLE_NPAGE==(1<<(
dfb0: 41 72 72 61 79 53 69 7a 65 28 61 53 75 62 29 2d  ArraySize(aSub)-
dfc0: 31 29 29 20 29 3b 0a 0a 20 20 66 6f 72 28 69 4c  1)) );..  for(iL
dfd0: 69 73 74 3d 30 3b 20 69 4c 69 73 74 3c 6e 4c 69  ist=0; iList<nLi
dfe0: 73 74 3b 20 69 4c 69 73 74 2b 2b 29 7b 0a 20 20  st; iList++){.  
dff0: 20 20 6e 4d 65 72 67 65 20 3d 20 31 3b 0a 20 20    nMerge = 1;.  
e000: 20 20 61 4d 65 72 67 65 20 3d 20 26 61 4c 69 73    aMerge = &aLis
e010: 74 5b 69 4c 69 73 74 5d 3b 0a 20 20 20 20 66 6f  t[iList];.    fo
e020: 72 28 69 53 75 62 3d 30 3b 20 69 4c 69 73 74 20  r(iSub=0; iList 
e030: 26 20 28 31 3c 3c 69 53 75 62 29 3b 20 69 53 75  & (1<<iSub); iSu
e040: 62 2b 2b 29 7b 0a 20 20 20 20 20 20 73 74 72 75  b++){.      stru
e050: 63 74 20 53 75 62 6c 69 73 74 20 2a 70 20 3d 20  ct Sublist *p = 
e060: 26 61 53 75 62 5b 69 53 75 62 5d 3b 0a 20 20 20  &aSub[iSub];.   
e070: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61 4c     assert( p->aL
e080: 69 73 74 20 26 26 20 70 2d 3e 6e 4c 69 73 74 3c  ist && p->nList<
e090: 3d 28 31 3c 3c 69 53 75 62 29 20 29 3b 0a 20 20  =(1<<iSub) );.  
e0a0: 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61      assert( p->a
e0b0: 4c 69 73 74 3d 3d 26 61 4c 69 73 74 5b 69 4c 69  List==&aList[iLi
e0c0: 73 74 26 7e 28 28 32 3c 3c 69 53 75 62 29 2d 31  st&~((2<<iSub)-1
e0d0: 29 5d 20 29 3b 0a 20 20 20 20 20 20 77 61 6c 4d  )] );.      walM
e0e0: 65 72 67 65 28 61 43 6f 6e 74 65 6e 74 2c 20 70  erge(aContent, p
e0f0: 2d 3e 61 4c 69 73 74 2c 20 70 2d 3e 6e 4c 69 73  ->aList, p->nLis
e100: 74 2c 20 26 61 4d 65 72 67 65 2c 20 26 6e 4d 65  t, &aMerge, &nMe
e110: 72 67 65 2c 20 61 42 75 66 66 65 72 29 3b 0a 20  rge, aBuffer);. 
e120: 20 20 20 7d 0a 20 20 20 20 61 53 75 62 5b 69 53     }.    aSub[iS
e130: 75 62 5d 2e 61 4c 69 73 74 20 3d 20 61 4d 65 72  ub].aList = aMer
e140: 67 65 3b 0a 20 20 20 20 61 53 75 62 5b 69 53 75  ge;.    aSub[iSu
e150: 62 5d 2e 6e 4c 69 73 74 20 3d 20 6e 4d 65 72 67  b].nList = nMerg
e160: 65 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69 53  e;.  }..  for(iS
e170: 75 62 2b 2b 3b 20 69 53 75 62 3c 41 72 72 61 79  ub++; iSub<Array
e180: 53 69 7a 65 28 61 53 75 62 29 3b 20 69 53 75 62  Size(aSub); iSub
e190: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 6e 4c 69  ++){.    if( nLi
e1a0: 73 74 20 26 20 28 31 3c 3c 69 53 75 62 29 20 29  st & (1<<iSub) )
e1b0: 7b 0a 20 20 20 20 20 20 73 74 72 75 63 74 20 53  {.      struct S
e1c0: 75 62 6c 69 73 74 20 2a 70 20 3d 20 26 61 53 75  ublist *p = &aSu
e1d0: 62 5b 69 53 75 62 5d 3b 0a 20 20 20 20 20 20 61  b[iSub];.      a
e1e0: 73 73 65 72 74 28 20 70 2d 3e 6e 4c 69 73 74 3c  ssert( p->nList<
e1f0: 3d 28 31 3c 3c 69 53 75 62 29 20 29 3b 0a 20 20  =(1<<iSub) );.  
e200: 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 61      assert( p->a
e210: 4c 69 73 74 3d 3d 26 61 4c 69 73 74 5b 6e 4c 69  List==&aList[nLi
e220: 73 74 26 7e 28 28 32 3c 3c 69 53 75 62 29 2d 31  st&~((2<<iSub)-1
e230: 29 5d 20 29 3b 0a 20 20 20 20 20 20 77 61 6c 4d  )] );.      walM
e240: 65 72 67 65 28 61 43 6f 6e 74 65 6e 74 2c 20 70  erge(aContent, p
e250: 2d 3e 61 4c 69 73 74 2c 20 70 2d 3e 6e 4c 69 73  ->aList, p->nLis
e260: 74 2c 20 26 61 4d 65 72 67 65 2c 20 26 6e 4d 65  t, &aMerge, &nMe
e270: 72 67 65 2c 20 61 42 75 66 66 65 72 29 3b 0a 20  rge, aBuffer);. 
e280: 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65 72     }.  }.  asser
e290: 74 28 20 61 4d 65 72 67 65 3d 3d 61 4c 69 73 74  t( aMerge==aList
e2a0: 20 29 3b 0a 20 20 2a 70 6e 4c 69 73 74 20 3d 20   );.  *pnList = 
e2b0: 6e 4d 65 72 67 65 3b 0a 0a 23 69 66 64 65 66 20  nMerge;..#ifdef 
e2c0: 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 7b  SQLITE_DEBUG.  {
e2d0: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
e2e0: 66 6f 72 28 69 3d 31 3b 20 69 3c 2a 70 6e 4c 69  for(i=1; i<*pnLi
e2f0: 73 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  st; i++){.      
e300: 61 73 73 65 72 74 28 20 61 43 6f 6e 74 65 6e 74  assert( aContent
e310: 5b 61 4c 69 73 74 5b 69 5d 5d 20 3e 20 61 43 6f  [aList[i]] > aCo
e320: 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 69 2d 31 5d  ntent[aList[i-1]
e330: 5d 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 23  ] );.    }.  }.#
e340: 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  endif.}../* .** 
e350: 46 72 65 65 20 61 6e 20 69 74 65 72 61 74 6f 72  Free an iterator
e360: 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20 77 61   allocated by wa
e370: 6c 49 74 65 72 61 74 6f 72 49 6e 69 74 28 29 2e  lIteratorInit().
e380: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
e390: 77 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28  walIteratorFree(
e3a0: 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 29 7b  WalIterator *p){
e3b0: 0a 20 20 73 71 6c 69 74 65 33 53 63 72 61 74 63  .  sqlite3Scratc
e3c0: 68 46 72 65 65 28 70 29 3b 0a 7d 0a 0a 2f 2a 0a  hFree(p);.}../*.
e3d0: 2a 2a 20 43 6f 6e 73 74 72 75 63 74 20 61 20 57  ** Construct a W
e3e0: 61 6c 49 6e 74 65 72 61 74 6f 72 20 6f 62 6a 65  alInterator obje
e3f0: 63 74 20 74 68 61 74 20 63 61 6e 20 62 65 20 75  ct that can be u
e400: 73 65 64 20 74 6f 20 6c 6f 6f 70 20 6f 76 65 72  sed to loop over
e410: 20 61 6c 6c 20 0a 2a 2a 20 70 61 67 65 73 20 69   all .** pages i
e420: 6e 20 74 68 65 20 57 41 4c 20 69 6e 20 61 73 63  n the WAL in asc
e430: 65 6e 64 69 6e 67 20 6f 72 64 65 72 2e 20 54 68  ending order. Th
e440: 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 68 6f  e caller must ho
e450: 6c 64 20 74 68 65 20 63 68 65 63 6b 70 6f 69 6e  ld the checkpoin
e460: 74 0a 2a 2a 20 6c 6f 63 6b 2e 0a 2a 2a 0a 2a 2a  t.** lock..**.**
e470: 20 4f 6e 20 73 75 63 63 65 73 73 2c 20 6d 61 6b   On success, mak
e480: 65 20 2a 70 70 20 70 6f 69 6e 74 20 74 6f 20 74  e *pp point to t
e490: 68 65 20 6e 65 77 6c 79 20 61 6c 6c 6f 63 61 74  he newly allocat
e4a0: 65 64 20 57 61 6c 49 6e 74 65 72 61 74 6f 72 20  ed WalInterator 
e4b0: 6f 62 6a 65 63 74 0a 2a 2a 20 72 65 74 75 72 6e  object.** return
e4c0: 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f 74 68 65   SQLITE_OK. Othe
e4d0: 72 77 69 73 65 2c 20 72 65 74 75 72 6e 20 61 6e  rwise, return an
e4e0: 20 65 72 72 6f 72 20 63 6f 64 65 2e 20 49 66 20   error code. If 
e4f0: 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20  this routine.** 
e500: 72 65 74 75 72 6e 73 20 61 6e 20 65 72 72 6f 72  returns an error
e510: 2c 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 2a  , the value of *
e520: 70 70 20 69 73 20 75 6e 64 65 66 69 6e 65 64 2e  pp is undefined.
e530: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 69  .**.** The calli
e540: 6e 67 20 72 6f 75 74 69 6e 65 20 73 68 6f 75 6c  ng routine shoul
e550: 64 20 69 6e 76 6f 6b 65 20 77 61 6c 49 74 65 72  d invoke walIter
e560: 61 74 6f 72 46 72 65 65 28 29 20 74 6f 20 64 65  atorFree() to de
e570: 73 74 72 6f 79 20 74 68 65 0a 2a 2a 20 57 61 6c  stroy the.** Wal
e580: 49 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 20  Iterator object 
e590: 77 68 65 6e 20 69 74 20 68 61 73 20 66 69 6e 69  when it has fini
e5a0: 73 68 65 64 20 77 69 74 68 20 69 74 2e 0a 2a 2f  shed with it..*/
e5b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49  .static int walI
e5c0: 74 65 72 61 74 6f 72 49 6e 69 74 28 57 61 6c 20  teratorInit(Wal 
e5d0: 2a 70 57 61 6c 2c 20 57 61 6c 49 74 65 72 61 74  *pWal, WalIterat
e5e0: 6f 72 20 2a 2a 70 70 29 7b 0a 20 20 57 61 6c 49  or **pp){.  WalI
e5f0: 74 65 72 61 74 6f 72 20 2a 70 3b 20 20 20 20 20  terator *p;     
e600: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
e610: 65 74 75 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 20  eturn value */. 
e620: 20 69 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20   int nSegment;  
e630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e640: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 65   /* Number of se
e650: 67 6d 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20  gments to merge 
e660: 2a 2f 0a 20 20 75 33 32 20 69 4c 61 73 74 3b 20  */.  u32 iLast; 
e670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e680: 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 66 72 61       /* Last fra
e690: 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20 69  me in log */.  i
e6a0: 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20  nt nByte;       
e6b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e6c0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
e6d0: 73 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f  s to allocate */
e6e0: 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
e6f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e700: 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 76     /* Iterator v
e710: 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 68 74 5f  ariable */.  ht_
e720: 73 6c 6f 74 20 2a 61 54 6d 70 3b 20 20 20 20 20  slot *aTmp;     
e730: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e740: 54 65 6d 70 20 73 70 61 63 65 20 75 73 65 64 20  Temp space used 
e750: 62 79 20 6d 65 72 67 65 2d 73 6f 72 74 20 2a 2f  by merge-sort */
e760: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
e770: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
e780: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64     /* Return Cod
e790: 65 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 69 73 20  e */..  /* This 
e7a0: 72 6f 75 74 69 6e 65 20 6f 6e 6c 79 20 72 75 6e  routine only run
e7b0: 73 20 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67 20  s while holding 
e7c0: 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 6c  the checkpoint l
e7d0: 6f 63 6b 2e 20 41 6e 64 0a 20 20 2a 2a 20 69 74  ock. And.  ** it
e7e0: 20 6f 6e 6c 79 20 72 75 6e 73 20 69 66 20 74 68   only runs if th
e7f0: 65 72 65 20 69 73 20 61 63 74 75 61 6c 6c 79 20  ere is actually 
e800: 63 6f 6e 74 65 6e 74 20 69 6e 20 74 68 65 20 6c  content in the l
e810: 6f 67 20 28 6d 78 46 72 61 6d 65 3e 30 29 2e 0a  og (mxFrame>0)..
e820: 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
e830: 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20 26 26  Wal->ckptLock &&
e840: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
e850: 6d 65 3e 30 20 29 3b 0a 20 20 69 4c 61 73 74 20  me>0 );.  iLast 
e860: 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  = pWal->hdr.mxFr
e870: 61 6d 65 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63  ame;..  /* Alloc
e880: 61 74 65 20 73 70 61 63 65 20 66 6f 72 20 74 68  ate space for th
e890: 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62  e WalIterator ob
e8a0: 6a 65 63 74 2e 20 2a 2f 0a 20 20 6e 53 65 67 6d  ject. */.  nSegm
e8b0: 65 6e 74 20 3d 20 77 61 6c 46 72 61 6d 65 50 61  ent = walFramePa
e8c0: 67 65 28 69 4c 61 73 74 29 20 2b 20 31 3b 0a 20  ge(iLast) + 1;. 
e8d0: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
e8e0: 57 61 6c 49 74 65 72 61 74 6f 72 29 20 0a 20 20  WalIterator) .  
e8f0: 20 20 20 20 20 20 2b 20 28 6e 53 65 67 6d 65 6e        + (nSegmen
e900: 74 2d 31 29 2a 73 69 7a 65 6f 66 28 73 74 72 75  t-1)*sizeof(stru
e910: 63 74 20 57 61 6c 53 65 67 6d 65 6e 74 29 0a 20  ct WalSegment). 
e920: 20 20 20 20 20 20 20 2b 20 69 4c 61 73 74 2a 73         + iLast*s
e930: 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 3b 0a  izeof(ht_slot);.
e940: 20 20 70 20 3d 20 28 57 61 6c 49 74 65 72 61 74    p = (WalIterat
e950: 6f 72 20 2a 29 73 71 6c 69 74 65 33 53 63 72 61  or *)sqlite3Scra
e960: 74 63 68 4d 61 6c 6c 6f 63 28 6e 42 79 74 65 29  tchMalloc(nByte)
e970: 3b 0a 20 20 69 66 28 20 21 70 20 29 7b 0a 20 20  ;.  if( !p ){.  
e980: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
e990: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 6d 65 6d  NOMEM;.  }.  mem
e9a0: 73 65 74 28 70 2c 20 30 2c 20 6e 42 79 74 65 29  set(p, 0, nByte)
e9b0: 3b 0a 20 20 70 2d 3e 6e 53 65 67 6d 65 6e 74 20  ;.  p->nSegment 
e9c0: 3d 20 6e 53 65 67 6d 65 6e 74 3b 0a 0a 20 20 2f  = nSegment;..  /
e9d0: 2a 20 41 6c 6c 6f 63 61 74 65 20 74 65 6d 70 6f  * Allocate tempo
e9e0: 72 61 72 79 20 73 70 61 63 65 20 75 73 65 64 20  rary space used 
e9f0: 62 79 20 74 68 65 20 6d 65 72 67 65 2d 73 6f 72  by the merge-sor
ea00: 74 20 72 6f 75 74 69 6e 65 2e 20 54 68 69 73 20  t routine. This 
ea10: 62 6c 6f 63 6b 0a 20 20 2a 2a 20 6f 66 20 6d 65  block.  ** of me
ea20: 6d 6f 72 79 20 77 69 6c 6c 20 62 65 20 66 72 65  mory will be fre
ea30: 65 64 20 62 65 66 6f 72 65 20 74 68 69 73 20 66  ed before this f
ea40: 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e  unction returns.
ea50: 0a 20 20 2a 2f 0a 20 20 61 54 6d 70 20 3d 20 28  .  */.  aTmp = (
ea60: 68 74 5f 73 6c 6f 74 20 2a 29 73 71 6c 69 74 65  ht_slot *)sqlite
ea70: 33 53 63 72 61 74 63 68 4d 61 6c 6c 6f 63 28 0a  3ScratchMalloc(.
ea80: 20 20 20 20 20 20 73 69 7a 65 6f 66 28 68 74 5f        sizeof(ht_
ea90: 73 6c 6f 74 29 20 2a 20 28 69 4c 61 73 74 3e 48  slot) * (iLast>H
eaa0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3f 48  ASHTABLE_NPAGE?H
eab0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3a 69  ASHTABLE_NPAGE:i
eac0: 4c 61 73 74 29 0a 20 20 29 3b 0a 20 20 69 66 28  Last).  );.  if(
ead0: 20 21 61 54 6d 70 20 29 7b 0a 20 20 20 20 72 63   !aTmp ){.    rc
eae0: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
eaf0: 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69 3d 30 3b  .  }..  for(i=0;
eb00: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
eb10: 26 20 69 3c 6e 53 65 67 6d 65 6e 74 3b 20 69 2b  & i<nSegment; i+
eb20: 2b 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65  +){.    volatile
eb30: 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b   ht_slot *aHash;
eb40: 0a 20 20 20 20 75 33 32 20 69 5a 65 72 6f 3b 0a  .    u32 iZero;.
eb50: 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32      volatile u32
eb60: 20 2a 61 50 67 6e 6f 3b 0a 0a 20 20 20 20 72 63   *aPgno;..    rc
eb70: 20 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70 57   = walHashGet(pW
eb80: 61 6c 2c 20 69 2c 20 26 61 48 61 73 68 2c 20 26  al, i, &aHash, &
eb90: 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a  aPgno, &iZero);.
eba0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
ebb0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69  TE_OK ){.      i
ebc0: 6e 74 20 6a 3b 20 20 20 20 20 20 20 20 20 20 20  nt j;           
ebd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
ebe0: 75 6e 74 65 72 20 76 61 72 69 61 62 6c 65 20 2a  unter variable *
ebf0: 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 45 6e 74  /.      int nEnt
ec00: 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ry;             
ec10: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
ec20: 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 69 73   entries in this
ec30: 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 20 20 20 20   segment */.    
ec40: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 49 6e 64 65    ht_slot *aInde
ec50: 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  x;            /*
ec60: 20 53 6f 72 74 65 64 20 69 6e 64 65 78 20 66 6f   Sorted index fo
ec70: 72 20 74 68 69 73 20 73 65 67 6d 65 6e 74 20 2a  r this segment *
ec80: 2f 0a 0a 20 20 20 20 20 20 61 50 67 6e 6f 2b 2b  /..      aPgno++
ec90: 3b 0a 20 20 20 20 20 20 69 66 28 20 28 69 2b 31  ;.      if( (i+1
eca0: 29 3d 3d 6e 53 65 67 6d 65 6e 74 20 29 7b 0a 20  )==nSegment ){. 
ecb0: 20 20 20 20 20 20 20 6e 45 6e 74 72 79 20 3d 20         nEntry = 
ecc0: 28 69 6e 74 29 28 69 4c 61 73 74 20 2d 20 69 5a  (int)(iLast - iZ
ecd0: 65 72 6f 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  ero);.      }els
ece0: 65 7b 0a 20 20 20 20 20 20 20 20 6e 45 6e 74 72  e{.        nEntr
ecf0: 79 20 3d 20 28 69 6e 74 29 28 28 75 33 32 2a 29  y = (int)((u32*)
ed00: 61 48 61 73 68 20 2d 20 28 75 33 32 2a 29 61 50  aHash - (u32*)aP
ed10: 67 6e 6f 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  gno);.      }.  
ed20: 20 20 20 20 61 49 6e 64 65 78 20 3d 20 26 28 28      aIndex = &((
ed30: 68 74 5f 73 6c 6f 74 20 2a 29 26 70 2d 3e 61 53  ht_slot *)&p->aS
ed40: 65 67 6d 65 6e 74 5b 70 2d 3e 6e 53 65 67 6d 65  egment[p->nSegme
ed50: 6e 74 5d 29 5b 69 5a 65 72 6f 5d 3b 0a 20 20 20  nt])[iZero];.   
ed60: 20 20 20 69 5a 65 72 6f 2b 2b 3b 0a 20 20 0a 20     iZero++;.  . 
ed70: 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c       for(j=0; j<
ed80: 6e 45 6e 74 72 79 3b 20 6a 2b 2b 29 7b 0a 20 20  nEntry; j++){.  
ed90: 20 20 20 20 20 20 61 49 6e 64 65 78 5b 6a 5d 20        aIndex[j] 
eda0: 3d 20 28 68 74 5f 73 6c 6f 74 29 6a 3b 0a 20 20  = (ht_slot)j;.  
edb0: 20 20 20 20 7d 0a 20 20 20 20 20 20 77 61 6c 4d      }.      walM
edc0: 65 72 67 65 73 6f 72 74 28 28 75 33 32 20 2a 29  ergesort((u32 *)
edd0: 61 50 67 6e 6f 2c 20 61 54 6d 70 2c 20 61 49 6e  aPgno, aTmp, aIn
ede0: 64 65 78 2c 20 26 6e 45 6e 74 72 79 29 3b 0a 20  dex, &nEntry);. 
edf0: 20 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74       p->aSegment
ee00: 5b 69 5d 2e 69 5a 65 72 6f 20 3d 20 69 5a 65 72  [i].iZero = iZer
ee10: 6f 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65 67  o;.      p->aSeg
ee20: 6d 65 6e 74 5b 69 5d 2e 6e 45 6e 74 72 79 20 3d  ment[i].nEntry =
ee30: 20 6e 45 6e 74 72 79 3b 0a 20 20 20 20 20 20 70   nEntry;.      p
ee40: 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 61 49  ->aSegment[i].aI
ee50: 6e 64 65 78 20 3d 20 61 49 6e 64 65 78 3b 0a 20  ndex = aIndex;. 
ee60: 20 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74       p->aSegment
ee70: 5b 69 5d 2e 61 50 67 6e 6f 20 3d 20 28 75 33 32  [i].aPgno = (u32
ee80: 20 2a 29 61 50 67 6e 6f 3b 0a 20 20 20 20 7d 0a   *)aPgno;.    }.
ee90: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 53 63 72    }.  sqlite3Scr
eea0: 61 74 63 68 46 72 65 65 28 61 54 6d 70 29 3b 0a  atchFree(aTmp);.
eeb0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
eec0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49  E_OK ){.    walI
eed0: 74 65 72 61 74 6f 72 46 72 65 65 28 70 29 3b 0a  teratorFree(p);.
eee0: 20 20 7d 0a 20 20 2a 70 70 20 3d 20 70 3b 0a 20    }.  *pp = p;. 
eef0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
ef00: 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f 20  *.** Attempt to 
ef10: 6f 62 74 61 69 6e 20 74 68 65 20 65 78 63 6c 75  obtain the exclu
ef20: 73 69 76 65 20 57 41 4c 20 6c 6f 63 6b 20 64 65  sive WAL lock de
ef30: 66 69 6e 65 64 20 62 79 20 70 61 72 61 6d 65 74  fined by paramet
ef40: 65 72 73 20 6c 6f 63 6b 49 64 78 20 61 6e 64 0a  ers lockIdx and.
ef50: 2a 2a 20 6e 2e 20 49 66 20 74 68 65 20 61 74 74  ** n. If the att
ef60: 65 6d 70 74 20 66 61 69 6c 73 20 61 6e 64 20 70  empt fails and p
ef70: 61 72 61 6d 65 74 65 72 20 78 42 75 73 79 20 69  arameter xBusy i
ef80: 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 74 68 65 6e  s not NULL, then
ef90: 20 69 74 20 69 73 20 61 0a 2a 2a 20 62 75 73 79   it is a.** busy
efa0: 2d 68 61 6e 64 6c 65 72 20 66 75 6e 63 74 69 6f  -handler functio
efb0: 6e 2e 20 49 6e 76 6f 6b 65 20 69 74 20 61 6e 64  n. Invoke it and
efc0: 20 72 65 74 72 79 20 74 68 65 20 6c 6f 63 6b 20   retry the lock 
efd0: 75 6e 74 69 6c 20 65 69 74 68 65 72 20 74 68 65  until either the
efe0: 0a 2a 2a 20 6c 6f 63 6b 20 69 73 20 73 75 63 63  .** lock is succ
eff0: 65 73 73 66 75 6c 6c 79 20 6f 62 74 61 69 6e 65  essfully obtaine
f000: 64 20 6f 72 20 74 68 65 20 62 75 73 79 2d 68 61  d or the busy-ha
f010: 6e 64 6c 65 72 20 72 65 74 75 72 6e 73 20 30 2e  ndler returns 0.
f020: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
f030: 61 6c 42 75 73 79 4c 6f 63 6b 28 0a 20 20 57 61  alBusyLock(.  Wa
f040: 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20  l *pWal,        
f050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
f060: 20 57 41 4c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20   WAL connection 
f070: 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 42 75 73 79  */.  int (*xBusy
f080: 29 28 76 6f 69 64 2a 29 2c 20 20 20 20 20 20 20  )(void*),       
f090: 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e       /* Function
f0a0: 20 74 6f 20 63 61 6c 6c 20 77 68 65 6e 20 62 75   to call when bu
f0b0: 73 79 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 42  sy */.  void *pB
f0c0: 75 73 79 41 72 67 2c 20 20 20 20 20 20 20 20 20  usyArg,         
f0d0: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65          /* Conte
f0e0: 78 74 20 61 72 67 75 6d 65 6e 74 20 66 6f 72 20  xt argument for 
f0f0: 78 42 75 73 79 48 61 6e 64 6c 65 72 20 2a 2f 0a  xBusyHandler */.
f100: 20 20 69 6e 74 20 6c 6f 63 6b 49 64 78 2c 20 20    int lockIdx,  
f110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f120: 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 66    /* Offset of f
f130: 69 72 73 74 20 62 79 74 65 20 74 6f 20 6c 6f 63  irst byte to loc
f140: 6b 20 2a 2f 0a 20 20 69 6e 74 20 6e 20 20 20 20  k */.  int n    
f150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f160: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
f170: 20 6f 66 20 62 79 74 65 73 20 74 6f 20 6c 6f 63   of bytes to loc
f180: 6b 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  k */.){.  int rc
f190: 3b 0a 20 20 64 6f 20 7b 0a 20 20 20 20 72 63 20  ;.  do {.    rc 
f1a0: 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69  = walLockExclusi
f1b0: 76 65 28 70 57 61 6c 2c 20 6c 6f 63 6b 49 64 78  ve(pWal, lockIdx
f1c0: 2c 20 6e 29 3b 0a 20 20 7d 77 68 69 6c 65 28 20  , n);.  }while( 
f1d0: 78 42 75 73 79 20 26 26 20 72 63 3d 3d 53 51 4c  xBusy && rc==SQL
f1e0: 49 54 45 5f 42 55 53 59 20 26 26 20 78 42 75 73  ITE_BUSY && xBus
f1f0: 79 28 70 42 75 73 79 41 72 67 29 20 29 3b 0a 20  y(pBusyArg) );. 
f200: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
f210: 2a 0a 2a 2a 20 54 68 65 20 63 61 63 68 65 20 6f  *.** The cache o
f220: 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
f230: 68 65 61 64 65 72 20 6d 75 73 74 20 62 65 20 76  header must be v
f240: 61 6c 69 64 20 74 6f 20 63 61 6c 6c 20 74 68 69  alid to call thi
f250: 73 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2a 20 52  s function..** R
f260: 65 74 75 72 6e 20 74 68 65 20 70 61 67 65 2d 73  eturn the page-s
f270: 69 7a 65 20 69 6e 20 62 79 74 65 73 20 75 73 65  ize in bytes use
f280: 64 20 62 79 20 74 68 65 20 64 61 74 61 62 61 73  d by the databas
f290: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
f2a0: 20 77 61 6c 50 61 67 65 73 69 7a 65 28 57 61 6c   walPagesize(Wal
f2b0: 20 2a 70 57 61 6c 29 7b 0a 20 20 72 65 74 75 72   *pWal){.  retur
f2c0: 6e 20 28 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50  n (pWal->hdr.szP
f2d0: 61 67 65 26 30 78 66 65 30 30 29 20 2b 20 28 28  age&0xfe00) + ((
f2e0: 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65  pWal->hdr.szPage
f2f0: 26 30 78 30 30 30 31 29 3c 3c 31 36 29 3b 0a 7d  &0x0001)<<16);.}
f300: 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 61 73 20  ../*.** Copy as 
f310: 6d 75 63 68 20 63 6f 6e 74 65 6e 74 20 61 73 20  much content as 
f320: 77 65 20 63 61 6e 20 66 72 6f 6d 20 74 68 65 20  we can from the 
f330: 57 41 4c 20 62 61 63 6b 20 69 6e 74 6f 20 74 68  WAL back into th
f340: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 0a  e database file.
f350: 2a 2a 20 69 6e 20 72 65 73 70 6f 6e 73 65 20 74  ** in response t
f360: 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f 77 61 6c  o an sqlite3_wal
f370: 5f 63 68 65 63 6b 70 6f 69 6e 74 28 29 20 72 65  _checkpoint() re
f380: 71 75 65 73 74 20 6f 72 20 74 68 65 20 65 71 75  quest or the equ
f390: 69 76 61 6c 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54  ivalent..**.** T
f3a0: 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20 69 6e 66  he amount of inf
f3b0: 6f 72 6d 61 74 69 6f 6e 20 63 6f 70 69 65 73 20  ormation copies 
f3c0: 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64 61 74 61  from WAL to data
f3d0: 62 61 73 65 20 6d 69 67 68 74 20 62 65 20 6c 69  base might be li
f3e0: 6d 69 74 65 64 0a 2a 2a 20 62 79 20 61 63 74 69  mited.** by acti
f3f0: 76 65 20 72 65 61 64 65 72 73 2e 20 20 54 68 69  ve readers.  Thi
f400: 73 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20 6e  s routine will n
f410: 65 76 65 72 20 6f 76 65 72 77 72 69 74 65 20 61  ever overwrite a
f420: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 0a 2a   database page.*
f430: 2a 20 74 68 61 74 20 61 20 63 6f 6e 63 75 72 72  * that a concurr
f440: 65 6e 74 20 72 65 61 64 65 72 20 6d 69 67 68 74  ent reader might
f450: 20 62 65 20 75 73 69 6e 67 2e 0a 2a 2a 0a 2a 2a   be using..**.**
f460: 20 41 6c 6c 20 49 2f 4f 20 62 61 72 72 69 65 72   All I/O barrier
f470: 20 6f 70 65 72 61 74 69 6f 6e 73 20 28 61 2e 6b   operations (a.k
f480: 2e 61 20 66 73 79 6e 63 73 29 20 6f 63 63 75 72  .a fsyncs) occur
f490: 20 69 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65   in this routine
f4a0: 20 77 68 65 6e 0a 2a 2a 20 53 51 4c 69 74 65 20   when.** SQLite 
f4b0: 69 73 20 69 6e 20 57 41 4c 2d 6d 6f 64 65 20 69  is in WAL-mode i
f4c0: 6e 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 4e 4f  n synchronous=NO
f4d0: 52 4d 41 4c 2e 20 20 54 68 61 74 20 6d 65 61 6e  RMAL.  That mean
f4e0: 73 20 74 68 61 74 20 69 66 20 0a 2a 2a 20 63 68  s that if .** ch
f4f0: 65 63 6b 70 6f 69 6e 74 73 20 61 72 65 20 61 6c  eckpoints are al
f500: 77 61 79 73 20 72 75 6e 20 62 79 20 61 20 62 61  ways run by a ba
f510: 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64 20  ckground thread 
f520: 6f 72 20 62 61 63 6b 67 72 6f 75 6e 64 20 0a 2a  or background .*
f530: 2a 20 70 72 6f 63 65 73 73 2c 20 66 6f 72 65 67  * process, foreg
f540: 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20 77 69  round threads wi
f550: 6c 6c 20 6e 65 76 65 72 20 62 6c 6f 63 6b 20 6f  ll never block o
f560: 6e 20 61 20 6c 65 6e 67 74 68 79 20 66 73 79 6e  n a lengthy fsyn
f570: 63 20 63 61 6c 6c 2e 0a 2a 2a 0a 2a 2a 20 46 73  c call..**.** Fs
f580: 79 6e 63 20 69 73 20 63 61 6c 6c 65 64 20 6f 6e  ync is called on
f590: 20 74 68 65 20 57 41 4c 20 62 65 66 6f 72 65 20   the WAL before 
f5a0: 77 72 69 74 69 6e 67 20 63 6f 6e 74 65 6e 74 20  writing content 
f5b0: 6f 75 74 20 6f 66 20 74 68 65 20 57 41 4c 20 61  out of the WAL a
f5c0: 6e 64 0a 2a 2a 20 69 6e 74 6f 20 74 68 65 20 64  nd.** into the d
f5d0: 61 74 61 62 61 73 65 2e 20 20 54 68 69 73 20 65  atabase.  This e
f5e0: 6e 73 75 72 65 73 20 74 68 61 74 20 69 66 20 74  nsures that if t
f5f0: 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20 69  he new content i
f600: 73 20 70 65 72 73 69 73 74 65 6e 74 0a 2a 2a 20  s persistent.** 
f610: 69 6e 20 74 68 65 20 57 41 4c 20 61 6e 64 20 63  in the WAL and c
f620: 61 6e 20 62 65 20 72 65 63 6f 76 65 72 65 64 20  an be recovered 
f630: 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 70 6f 77 65  following a powe
f640: 72 2d 6c 6f 73 73 20 6f 72 20 68 61 72 64 20 72  r-loss or hard r
f650: 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 46 73 79 6e  eset..**.** Fsyn
f660: 63 20 69 73 20 61 6c 73 6f 20 63 61 6c 6c 65 64  c is also called
f670: 20 6f 6e 20 74 68 65 20 64 61 74 61 62 61 73 65   on the database
f680: 20 66 69 6c 65 20 69 66 20 28 61 6e 64 20 6f 6e   file if (and on
f690: 6c 79 20 69 66 29 20 74 68 65 20 65 6e 74 69 72  ly if) the entir
f6a0: 65 0a 2a 2a 20 57 41 4c 20 63 6f 6e 74 65 6e 74  e.** WAL content
f6b0: 20 69 73 20 63 6f 70 69 65 64 20 69 6e 74 6f 20   is copied into 
f6c0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
f6d0: 65 2e 20 20 54 68 69 73 20 73 65 63 6f 6e 64 20  e.  This second 
f6e0: 66 73 79 6e 63 20 6d 61 6b 65 73 0a 2a 2a 20 69  fsync makes.** i
f6f0: 74 20 73 61 66 65 20 74 6f 20 64 65 6c 65 74 65  t safe to delete
f700: 20 74 68 65 20 57 41 4c 20 73 69 6e 63 65 20 74   the WAL since t
f710: 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20 77  he new content w
f720: 69 6c 6c 20 70 65 72 73 69 73 74 20 69 6e 20 74  ill persist in t
f730: 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20 66  he.** database f
f740: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ile..**.** This 
f750: 72 6f 75 74 69 6e 65 20 75 73 65 73 20 61 6e 64  routine uses and
f760: 20 75 70 64 61 74 65 73 20 74 68 65 20 6e 42 61   updates the nBa
f770: 63 6b 66 69 6c 6c 20 66 69 65 6c 64 20 6f 66 20  ckfill field of 
f780: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
f790: 61 64 65 72 2e 0a 2a 2a 20 54 68 69 73 20 69 73  ader..** This is
f7a0: 20 74 68 65 20 6f 6e 6c 79 20 72 6f 75 74 69 6e   the only routin
f7b0: 65 20 74 68 61 20 77 69 6c 6c 20 69 6e 63 72 65  e tha will incre
f7c0: 61 73 65 20 74 68 65 20 76 61 6c 75 65 20 6f 66  ase the value of
f7d0: 20 6e 42 61 63 6b 66 69 6c 6c 2e 20 20 0a 2a 2a   nBackfill.  .**
f7e0: 20 28 41 20 57 41 4c 20 72 65 73 65 74 20 6f 72   (A WAL reset or
f7f0: 20 72 65 63 6f 76 65 72 79 20 77 69 6c 6c 20 72   recovery will r
f800: 65 76 65 72 74 20 6e 42 61 63 6b 66 69 6c 6c 20  evert nBackfill 
f810: 74 6f 20 7a 65 72 6f 2c 20 62 75 74 20 6e 6f 74  to zero, but not
f820: 20 69 6e 63 72 65 61 73 65 0a 2a 2a 20 69 74 73   increase.** its
f830: 20 76 61 6c 75 65 2e 29 0a 2a 2a 0a 2a 2a 20 54   value.).**.** T
f840: 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 62  he caller must b
f850: 65 20 68 6f 6c 64 69 6e 67 20 73 75 66 66 69 63  e holding suffic
f860: 69 65 6e 74 20 6c 6f 63 6b 73 20 74 6f 20 65 6e  ient locks to en
f870: 73 75 72 65 20 74 68 61 74 20 6e 6f 20 6f 74 68  sure that no oth
f880: 65 72 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74  er.** checkpoint
f890: 20 69 73 20 72 75 6e 6e 69 6e 67 20 28 69 6e 20   is running (in 
f8a0: 61 6e 79 20 6f 74 68 65 72 20 74 68 72 65 61 64  any other thread
f8b0: 20 6f 72 20 70 72 6f 63 65 73 73 29 20 61 74 20   or process) at 
f8c0: 74 68 65 20 73 61 6d 65 0a 2a 2a 20 74 69 6d 65  the same.** time
f8d0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
f8e0: 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a 20  walCheckpoint(. 
f8f0: 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20   Wal *pWal,     
f900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f910: 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65 63 74 69   /* Wal connecti
f920: 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 65 4d 6f 64  on */.  int eMod
f930: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
f940: 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f          /* One o
f950: 66 20 50 41 53 53 49 56 45 2c 20 46 55 4c 4c 20  f PASSIVE, FULL 
f960: 6f 72 20 52 45 53 54 41 52 54 20 2a 2f 0a 20 20  or RESTART */.  
f970: 69 6e 74 20 28 2a 78 42 75 73 79 43 61 6c 6c 29  int (*xBusyCall)
f980: 28 76 6f 69 64 2a 29 2c 20 20 20 20 20 20 20 20  (void*),        
f990: 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63  /* Function to c
f9a0: 61 6c 6c 20 77 68 65 6e 20 62 75 73 79 20 2a 2f  all when busy */
f9b0: 0a 20 20 76 6f 69 64 20 2a 70 42 75 73 79 41 72  .  void *pBusyAr
f9c0: 67 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  g,              
f9d0: 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 61 72     /* Context ar
f9e0: 67 75 6d 65 6e 74 20 66 6f 72 20 78 42 75 73 79  gument for xBusy
f9f0: 48 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74  Handler */.  int
fa00: 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20   sync_flags,    
fa10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
fa20: 46 6c 61 67 73 20 66 6f 72 20 4f 73 53 79 6e 63  Flags for OsSync
fa30: 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20 75  () (or 0) */.  u
fa40: 38 20 2a 7a 42 75 66 20 20 20 20 20 20 20 20 20  8 *zBuf         
fa50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
fa60: 2a 20 54 65 6d 70 6f 72 61 72 79 20 62 75 66 66  * Temporary buff
fa70: 65 72 20 74 6f 20 75 73 65 20 2a 2f 0a 29 7b 0a  er to use */.){.
fa80: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
fa90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
faa0: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
fab0: 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65   */.  int szPage
fac0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
fad0: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
fae0: 65 20 70 61 67 65 2d 73 69 7a 65 20 2a 2f 0a 20  e page-size */. 
faf0: 20 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 49   WalIterator *pI
fb00: 74 65 72 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ter = 0;        
fb10: 20 2f 2a 20 57 61 6c 20 69 74 65 72 61 74 6f 72   /* Wal iterator
fb20: 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 75 33   context */.  u3
fb30: 32 20 69 44 62 70 61 67 65 20 3d 20 30 3b 20 20  2 iDbpage = 0;  
fb40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
fb50: 20 4e 65 78 74 20 64 61 74 61 62 61 73 65 20 70   Next database p
fb60: 61 67 65 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a  age to write */.
fb70: 20 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20 30    u32 iFrame = 0
fb80: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
fb90: 20 20 2f 2a 20 57 61 6c 20 66 72 61 6d 65 20 63    /* Wal frame c
fba0: 6f 6e 74 61 69 6e 69 6e 67 20 64 61 74 61 20 66  ontaining data f
fbb0: 6f 72 20 69 44 62 70 61 67 65 20 2a 2f 0a 20 20  or iDbpage */.  
fbc0: 75 33 32 20 6d 78 53 61 66 65 46 72 61 6d 65 3b  u32 mxSafeFrame;
fbd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fbe0: 2f 2a 20 4d 61 78 20 66 72 61 6d 65 20 74 68 61  /* Max frame tha
fbf0: 74 20 63 61 6e 20 62 65 20 62 61 63 6b 66 69 6c  t can be backfil
fc00: 6c 65 64 20 2a 2f 0a 20 20 75 33 32 20 6d 78 50  led */.  u32 mxP
fc10: 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
fc20: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78 20           /* Max 
fc30: 64 61 74 61 62 61 73 65 20 70 61 67 65 20 74 6f  database page to
fc40: 20 77 72 69 74 65 20 2a 2f 0a 20 20 69 6e 74 20   write */.  int 
fc50: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
fc60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
fc70: 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20  oop counter */. 
fc80: 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70   volatile WalCkp
fc90: 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b 20 20 20  tInfo *pInfo;   
fca0: 20 2f 2a 20 54 68 65 20 63 68 65 63 6b 70 6f 69   /* The checkpoi
fcb0: 6e 74 20 73 74 61 74 75 73 20 69 6e 66 6f 72 6d  nt status inform
fcc0: 61 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 28  ation */.  int (
fcd0: 2a 78 42 75 73 79 29 28 76 6f 69 64 2a 29 20 3d  *xBusy)(void*) =
fce0: 20 30 3b 20 20 20 20 20 20 20 20 2f 2a 20 46 75   0;        /* Fu
fcf0: 6e 63 74 69 6f 6e 20 74 6f 20 63 61 6c 6c 20 77  nction to call w
fd00: 68 65 6e 20 77 61 69 74 69 6e 67 20 66 6f 72 20  hen waiting for 
fd10: 6c 6f 63 6b 73 20 2a 2f 0a 0a 20 20 73 7a 50 61  locks */..  szPa
fd20: 67 65 20 3d 20 77 61 6c 50 61 67 65 73 69 7a 65  ge = walPagesize
fd30: 28 70 57 61 6c 29 3b 0a 20 20 74 65 73 74 63 61  (pWal);.  testca
fd40: 73 65 28 20 73 7a 50 61 67 65 3c 3d 33 32 37 36  se( szPage<=3276
fd50: 38 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28  8 );.  testcase(
fd60: 20 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20 29   szPage>=65536 )
fd70: 3b 0a 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43  ;.  pInfo = walC
fd80: 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20  kptInfo(pWal);. 
fd90: 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63   if( pInfo->nBac
fda0: 6b 66 69 6c 6c 3e 3d 70 57 61 6c 2d 3e 68 64 72  kfill>=pWal->hdr
fdb0: 2e 6d 78 46 72 61 6d 65 20 29 20 72 65 74 75 72  .mxFrame ) retur
fdc0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  n SQLITE_OK;..  
fdd0: 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68 65 20  /* Allocate the 
fde0: 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 72 63  iterator */.  rc
fdf0: 20 3d 20 77 61 6c 49 74 65 72 61 74 6f 72 49 6e   = walIteratorIn
fe00: 69 74 28 70 57 61 6c 2c 20 26 70 49 74 65 72 29  it(pWal, &pIter)
fe10: 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
fe20: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74  TE_OK ){.    ret
fe30: 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 61 73  urn rc;.  }.  as
fe40: 73 65 72 74 28 20 70 49 74 65 72 20 29 3b 0a 0a  sert( pIter );..
fe50: 20 20 69 66 28 20 65 4d 6f 64 65 21 3d 53 51 4c    if( eMode!=SQL
fe60: 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50  ITE_CHECKPOINT_P
fe70: 41 53 53 49 56 45 20 29 20 78 42 75 73 79 20 3d  ASSIVE ) xBusy =
fe80: 20 78 42 75 73 79 43 61 6c 6c 3b 0a 0a 20 20 2f   xBusyCall;..  /
fe90: 2a 20 43 6f 6d 70 75 74 65 20 69 6e 20 6d 78 53  * Compute in mxS
fea0: 61 66 65 46 72 61 6d 65 20 74 68 65 20 69 6e 64  afeFrame the ind
feb0: 65 78 20 6f 66 20 74 68 65 20 6c 61 73 74 20 66  ex of the last f
fec0: 72 61 6d 65 20 6f 66 20 74 68 65 20 57 41 4c 20  rame of the WAL 
fed0: 74 68 61 74 20 69 73 0a 20 20 2a 2a 20 73 61 66  that is.  ** saf
fee0: 65 20 74 6f 20 77 72 69 74 65 20 69 6e 74 6f 20  e to write into 
fef0: 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 20 46  the database.  F
ff00: 72 61 6d 65 73 20 62 65 79 6f 6e 64 20 6d 78 53  rames beyond mxS
ff10: 61 66 65 46 72 61 6d 65 20 6d 69 67 68 74 0a 20  afeFrame might. 
ff20: 20 2a 2a 20 6f 76 65 72 77 72 69 74 65 20 64 61   ** overwrite da
ff30: 74 61 62 61 73 65 20 70 61 67 65 73 20 74 68 61  tabase pages tha
ff40: 74 20 61 72 65 20 69 6e 20 75 73 65 20 62 79 20  t are in use by 
ff50: 61 63 74 69 76 65 20 72 65 61 64 65 72 73 20 61  active readers a
ff60: 6e 64 20 74 68 75 73 0a 20 20 2a 2a 20 63 61 6e  nd thus.  ** can
ff70: 6e 6f 74 20 62 65 20 62 61 63 6b 66 69 6c 6c 65  not be backfille
ff80: 64 20 66 72 6f 6d 20 74 68 65 20 57 41 4c 2e 0a  d from the WAL..
ff90: 20 20 2a 2f 0a 20 20 6d 78 53 61 66 65 46 72 61    */.  mxSafeFra
ffa0: 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  me = pWal->hdr.m
ffb0: 78 46 72 61 6d 65 3b 0a 20 20 6d 78 50 61 67 65  xFrame;.  mxPage
ffc0: 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61   = pWal->hdr.nPa
ffd0: 67 65 3b 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69  ge;.  for(i=1; i
ffe0: 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b  <WAL_NREADER; i+
fff0: 2b 29 7b 0a 20 20 20 20 75 33 32 20 79 20 3d 20  +){.    u32 y = 
10000 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b  pInfo->aReadMark
10010 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 6d 78 53  [i];.    if( mxS
10020 61 66 65 46 72 61 6d 65 3e 79 20 29 7b 0a 20 20  afeFrame>y ){.  
10030 20 20 20 20 61 73 73 65 72 74 28 20 79 3c 3d 70      assert( y<=p
10040 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
10050 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 77   );.      rc = w
10060 61 6c 42 75 73 79 4c 6f 63 6b 28 70 57 61 6c 2c  alBusyLock(pWal,
10070 20 78 42 75 73 79 2c 20 70 42 75 73 79 41 72 67   xBusy, pBusyArg
10080 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
10090 69 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 69 66  i), 1);.      if
100a0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
100b0 29 7b 0a 20 20 20 20 20 20 20 20 70 49 6e 66 6f  ){.        pInfo
100c0 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d  ->aReadMark[i] =
100d0 20 28 69 3d 3d 31 20 3f 20 6d 78 53 61 66 65 46   (i==1 ? mxSafeF
100e0 72 61 6d 65 20 3a 20 52 45 41 44 4d 41 52 4b 5f  rame : READMARK_
100f0 4e 4f 54 5f 55 53 45 44 29 3b 0a 20 20 20 20 20  NOT_USED);.     
10100 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c     walUnlockExcl
10110 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
10120 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29  READ_LOCK(i), 1)
10130 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  ;.      }else if
10140 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc==SQLITE_BUS
10150 59 20 29 7b 0a 20 20 20 20 20 20 20 20 6d 78 53  Y ){.        mxS
10160 61 66 65 46 72 61 6d 65 20 3d 20 79 3b 0a 20 20  afeFrame = y;.  
10170 20 20 20 20 20 20 78 42 75 73 79 20 3d 20 30 3b        xBusy = 0;
10180 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
10190 20 20 20 20 20 20 67 6f 74 6f 20 77 61 6c 63 68        goto walch
101a0 65 63 6b 70 6f 69 6e 74 5f 6f 75 74 3b 0a 20 20  eckpoint_out;.  
101b0 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
101c0 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 42  .  if( pInfo->nB
101d0 61 63 6b 66 69 6c 6c 3c 6d 78 53 61 66 65 46 72  ackfill<mxSafeFr
101e0 61 6d 65 0a 20 20 20 26 26 20 28 72 63 20 3d 20  ame.   && (rc = 
101f0 77 61 6c 42 75 73 79 4c 6f 63 6b 28 70 57 61 6c  walBusyLock(pWal
10200 2c 20 78 42 75 73 79 2c 20 70 42 75 73 79 41 72  , xBusy, pBusyAr
10210 67 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  g, WAL_READ_LOCK
10220 28 30 29 2c 20 31 29 29 3d 3d 53 51 4c 49 54 45  (0), 1))==SQLITE
10230 5f 4f 4b 0a 20 20 29 7b 0a 20 20 20 20 69 36 34  _OK.  ){.    i64
10240 20 6e 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20   nSize;         
10250 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
10260 72 72 65 6e 74 20 73 69 7a 65 20 6f 66 20 64 61  rrent size of da
10270 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20  tabase file */. 
10280 20 20 20 75 33 32 20 6e 42 61 63 6b 66 69 6c 6c     u32 nBackfill
10290 20 3d 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66   = pInfo->nBackf
102a0 69 6c 6c 3b 0a 0a 20 20 20 20 2f 2a 20 53 79 6e  ill;..    /* Syn
102b0 63 20 74 68 65 20 57 41 4c 20 74 6f 20 64 69 73  c the WAL to dis
102c0 6b 20 2a 2f 0a 20 20 20 20 69 66 28 20 73 79 6e  k */.    if( syn
102d0 63 5f 66 6c 61 67 73 20 29 7b 0a 20 20 20 20 20  c_flags ){.     
102e0 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53   rc = sqlite3OsS
102f0 79 6e 63 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ync(pWal->pWalFd
10300 2c 20 73 79 6e 63 5f 66 6c 61 67 73 29 3b 0a 20  , sync_flags);. 
10310 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20     }..    /* If 
10320 74 68 65 20 64 61 74 61 62 61 73 65 20 6d 61 79  the database may
10330 20 67 72 6f 77 20 61 73 20 61 20 72 65 73 75 6c   grow as a resul
10340 74 20 6f 66 20 74 68 69 73 20 63 68 65 63 6b 70  t of this checkp
10350 6f 69 6e 74 2c 20 68 69 6e 74 0a 20 20 20 20 2a  oint, hint.    *
10360 2a 20 61 62 6f 75 74 20 74 68 65 20 65 76 65 6e  * about the even
10370 74 75 61 6c 20 73 69 7a 65 20 6f 66 20 74 68 65  tual size of the
10380 20 64 62 20 66 69 6c 65 20 74 6f 20 74 68 65 20   db file to the 
10390 56 46 53 20 6c 61 79 65 72 2e 0a 20 20 20 20 2a  VFS layer..    *
103a0 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  /.    if( rc==SQ
103b0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
103c0 20 69 36 34 20 6e 52 65 71 20 3d 20 28 28 69 36   i64 nReq = ((i6
103d0 34 29 6d 78 50 61 67 65 20 2a 20 73 7a 50 61 67  4)mxPage * szPag
103e0 65 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  e);.      rc = s
103f0 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a 65  qlite3OsFileSize
10400 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 26 6e  (pWal->pDbFd, &n
10410 53 69 7a 65 29 3b 0a 20 20 20 20 20 20 69 66 28  Size);.      if(
10420 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
10430 26 20 6e 53 69 7a 65 3c 6e 52 65 71 20 29 7b 0a  & nSize<nReq ){.
10440 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f          sqlite3O
10450 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 48 69 6e 74  sFileControlHint
10460 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 53 51  (pWal->pDbFd, SQ
10470 4c 49 54 45 5f 46 43 4e 54 4c 5f 53 49 5a 45 5f  LITE_FCNTL_SIZE_
10480 48 49 4e 54 2c 20 26 6e 52 65 71 29 3b 0a 20 20  HINT, &nReq);.  
10490 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 0a 20 20      }.    }...  
104a0 20 20 2f 2a 20 49 74 65 72 61 74 65 20 74 68 72    /* Iterate thr
104b0 6f 75 67 68 20 74 68 65 20 63 6f 6e 74 65 6e 74  ough the content
104c0 73 20 6f 66 20 74 68 65 20 57 41 4c 2c 20 63 6f  s of the WAL, co
104d0 70 79 69 6e 67 20 64 61 74 61 20 74 6f 20 74 68  pying data to th
104e0 65 20 64 62 20 66 69 6c 65 2e 20 2a 2f 0a 20 20  e db file. */.  
104f0 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c    while( rc==SQL
10500 49 54 45 5f 4f 4b 20 26 26 20 30 3d 3d 77 61 6c  ITE_OK && 0==wal
10510 49 74 65 72 61 74 6f 72 4e 65 78 74 28 70 49 74  IteratorNext(pIt
10520 65 72 2c 20 26 69 44 62 70 61 67 65 2c 20 26 69  er, &iDbpage, &i
10530 46 72 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20  Frame) ){.      
10540 69 36 34 20 69 4f 66 66 73 65 74 3b 0a 20 20 20  i64 iOffset;.   
10550 20 20 20 61 73 73 65 72 74 28 20 77 61 6c 46 72     assert( walFr
10560 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 46  amePgno(pWal, iF
10570 72 61 6d 65 29 3d 3d 69 44 62 70 61 67 65 20 29  rame)==iDbpage )
10580 3b 0a 20 20 20 20 20 20 69 66 28 20 69 46 72 61  ;.      if( iFra
10590 6d 65 3c 3d 6e 42 61 63 6b 66 69 6c 6c 20 7c 7c  me<=nBackfill ||
105a0 20 69 46 72 61 6d 65 3e 6d 78 53 61 66 65 46 72   iFrame>mxSafeFr
105b0 61 6d 65 20 7c 7c 20 69 44 62 70 61 67 65 3e 6d  ame || iDbpage>m
105c0 78 50 61 67 65 20 29 20 63 6f 6e 74 69 6e 75 65  xPage ) continue
105d0 3b 0a 20 20 20 20 20 20 69 4f 66 66 73 65 74 20  ;.      iOffset 
105e0 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74  = walFrameOffset
105f0 28 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29  (iFrame, szPage)
10600 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52   + WAL_FRAME_HDR
10610 53 49 5a 45 3b 0a 20 20 20 20 20 20 2f 2a 20 74  SIZE;.      /* t
10620 65 73 74 63 61 73 65 28 20 49 53 5f 42 49 47 5f  estcase( IS_BIG_
10630 49 4e 54 28 69 4f 66 66 73 65 74 29 20 29 3b 20  INT(iOffset) ); 
10640 2f 2f 20 72 65 71 75 69 72 65 73 20 61 20 34 47  // requires a 4G
10650 69 42 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20  iB WAL file */. 
10660 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
10670 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57  3OsRead(pWal->pW
10680 61 6c 46 64 2c 20 7a 42 75 66 2c 20 73 7a 50 61  alFd, zBuf, szPa
10690 67 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  ge, iOffset);.  
106a0 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
106b0 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20  TE_OK ) break;. 
106c0 20 20 20 20 20 69 4f 66 66 73 65 74 20 3d 20 28       iOffset = (
106d0 69 44 62 70 61 67 65 2d 31 29 2a 28 69 36 34 29  iDbpage-1)*(i64)
106e0 73 7a 50 61 67 65 3b 0a 20 20 20 20 20 20 74 65  szPage;.      te
106f0 73 74 63 61 73 65 28 20 49 53 5f 42 49 47 5f 49  stcase( IS_BIG_I
10700 4e 54 28 69 4f 66 66 73 65 74 29 20 29 3b 0a 20  NT(iOffset) );. 
10710 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
10720 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70  3OsWrite(pWal->p
10730 44 62 46 64 2c 20 7a 42 75 66 2c 20 73 7a 50 61  DbFd, zBuf, szPa
10740 67 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  ge, iOffset);.  
10750 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
10760 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20  TE_OK ) break;. 
10770 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20     }..    /* If 
10780 77 6f 72 6b 20 77 61 73 20 61 63 74 75 61 6c 6c  work was actuall
10790 79 20 61 63 63 6f 6d 70 6c 69 73 68 65 64 2e 2e  y accomplished..
107a0 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d  . */.    if( rc=
107b0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
107c0 20 20 20 20 69 66 28 20 6d 78 53 61 66 65 46 72      if( mxSafeFr
107d0 61 6d 65 3d 3d 77 61 6c 49 6e 64 65 78 48 64 72  ame==walIndexHdr
107e0 28 70 57 61 6c 29 2d 3e 6d 78 46 72 61 6d 65 20  (pWal)->mxFrame 
107f0 29 7b 0a 20 20 20 20 20 20 20 20 69 36 34 20 73  ){.        i64 s
10800 7a 44 62 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  zDb = pWal->hdr.
10810 6e 50 61 67 65 2a 28 69 36 34 29 73 7a 50 61 67  nPage*(i64)szPag
10820 65 3b 0a 20 20 20 20 20 20 20 20 74 65 73 74 63  e;.        testc
10830 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28  ase( IS_BIG_INT(
10840 73 7a 44 62 29 20 29 3b 0a 20 20 20 20 20 20 20  szDb) );.       
10850 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 54   rc = sqlite3OsT
10860 72 75 6e 63 61 74 65 28 70 57 61 6c 2d 3e 70 44  runcate(pWal->pD
10870 62 46 64 2c 20 73 7a 44 62 29 3b 0a 20 20 20 20  bFd, szDb);.    
10880 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
10890 54 45 5f 4f 4b 20 26 26 20 73 79 6e 63 5f 66 6c  TE_OK && sync_fl
108a0 61 67 73 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ags ){.         
108b0 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53   rc = sqlite3OsS
108c0 79 6e 63 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  ync(pWal->pDbFd,
108d0 20 73 79 6e 63 5f 66 6c 61 67 73 29 3b 0a 20 20   sync_flags);.  
108e0 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
108f0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
10900 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
10910 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66     pInfo->nBackf
10920 69 6c 6c 20 3d 20 6d 78 53 61 66 65 46 72 61 6d  ill = mxSafeFram
10930 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  e;.      }.    }
10940 0a 0a 20 20 20 20 2f 2a 20 52 65 6c 65 61 73 65  ..    /* Release
10950 20 74 68 65 20 72 65 61 64 65 72 20 6c 6f 63 6b   the reader lock
10960 20 68 65 6c 64 20 77 68 69 6c 65 20 62 61 63 6b   held while back
10970 66 69 6c 6c 69 6e 67 20 2a 2f 0a 20 20 20 20 77  filling */.    w
10980 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
10990 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
109a0 5f 4c 4f 43 4b 28 30 29 2c 20 31 29 3b 0a 20 20  _LOCK(0), 1);.  
109b0 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
109c0 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20  ITE_BUSY ){.    
109d0 2f 2a 20 52 65 73 65 74 20 74 68 65 20 72 65 74  /* Reset the ret
109e0 75 72 6e 20 63 6f 64 65 20 73 6f 20 61 73 20 6e  urn code so as n
109f0 6f 74 20 74 6f 20 72 65 70 6f 72 74 20 61 20 63  ot to report a c
10a00 68 65 63 6b 70 6f 69 6e 74 20 66 61 69 6c 75 72  heckpoint failur
10a10 65 0a 20 20 20 20 2a 2a 20 6a 75 73 74 20 62 65  e.    ** just be
10a20 63 61 75 73 65 20 74 68 65 72 65 20 61 72 65 20  cause there are 
10a30 61 63 74 69 76 65 20 72 65 61 64 65 72 73 2e 20  active readers. 
10a40 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   */.    rc = SQL
10a50 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 2f  ITE_OK;.  }..  /
10a60 2a 20 49 66 20 74 68 69 73 20 69 73 20 61 6e 20  * If this is an 
10a70 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e  SQLITE_CHECKPOIN
10a80 54 5f 52 45 53 54 41 52 54 20 6f 70 65 72 61 74  T_RESTART operat
10a90 69 6f 6e 2c 20 61 6e 64 20 74 68 65 20 65 6e 74  ion, and the ent
10aa0 69 72 65 20 77 61 6c 0a 20 20 2a 2a 20 66 69 6c  ire wal.  ** fil
10ab0 65 20 68 61 73 20 62 65 65 6e 20 63 6f 70 69 65  e has been copie
10ac0 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  d into the datab
10ad0 61 73 65 20 66 69 6c 65 2c 20 74 68 65 6e 20 62  ase file, then b
10ae0 6c 6f 63 6b 20 75 6e 74 69 6c 20 61 6c 6c 0a 20  lock until all. 
10af0 20 2a 2a 20 72 65 61 64 65 72 73 20 68 61 76 65   ** readers have
10b00 20 66 69 6e 69 73 68 65 64 20 75 73 69 6e 67 20   finished using 
10b10 74 68 65 20 77 61 6c 20 66 69 6c 65 2e 20 54 68  the wal file. Th
10b20 69 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20  is ensures that 
10b30 74 68 65 20 6e 65 78 74 0a 20 20 2a 2a 20 70 72  the next.  ** pr
10b40 6f 63 65 73 73 20 74 6f 20 77 72 69 74 65 20 74  ocess to write t
10b50 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20 72  o the database r
10b60 65 73 74 61 72 74 73 20 74 68 65 20 77 61 6c 20  estarts the wal 
10b70 66 69 6c 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  file..  */.  if(
10b80 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
10b90 26 20 65 4d 6f 64 65 21 3d 53 51 4c 49 54 45 5f  & eMode!=SQLITE_
10ba0 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49  CHECKPOINT_PASSI
10bb0 56 45 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  VE ){.    assert
10bc0 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
10bd0 6b 20 29 3b 0a 20 20 20 20 69 66 28 20 70 49 6e  k );.    if( pIn
10be0 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3c 70 57  fo->nBackfill<pW
10bf0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
10c00 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  ){.      rc = SQ
10c10 4c 49 54 45 5f 42 55 53 59 3b 0a 20 20 20 20 7d  LITE_BUSY;.    }
10c20 65 6c 73 65 20 69 66 28 20 65 4d 6f 64 65 3d 3d  else if( eMode==
10c30 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e  SQLITE_CHECKPOIN
10c40 54 5f 52 45 53 54 41 52 54 20 29 7b 0a 20 20 20  T_RESTART ){.   
10c50 20 20 20 61 73 73 65 72 74 28 20 6d 78 53 61 66     assert( mxSaf
10c60 65 46 72 61 6d 65 3d 3d 70 57 61 6c 2d 3e 68 64  eFrame==pWal->hd
10c70 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20  r.mxFrame );.   
10c80 20 20 20 72 63 20 3d 20 77 61 6c 42 75 73 79 4c     rc = walBusyL
10c90 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73 79 2c  ock(pWal, xBusy,
10ca0 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c 5f 52   pBusyArg, WAL_R
10cb0 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c  EAD_LOCK(1), WAL
10cc0 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20  _NREADER-1);.   
10cd0 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
10ce0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
10cf0 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69  walUnlockExclusi
10d00 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ve(pWal, WAL_REA
10d10 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e  D_LOCK(1), WAL_N
10d20 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20 20 20  READER-1);.     
10d30 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 77   }.    }.  }.. w
10d40 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74  alcheckpoint_out
10d50 3a 0a 20 20 77 61 6c 49 74 65 72 61 74 6f 72 46  :.  walIteratorF
10d60 72 65 65 28 70 49 74 65 72 29 3b 0a 20 20 72 65  ree(pIter);.  re
10d70 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
10d80 2a 20 49 66 20 74 68 65 20 57 41 4c 20 66 69 6c  * If the WAL fil
10d90 65 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 6c  e is currently l
10da0 61 72 67 65 72 20 74 68 61 6e 20 6e 4d 61 78 20  arger than nMax 
10db0 62 79 74 65 73 20 69 6e 20 73 69 7a 65 2c 20 74  bytes in size, t
10dc0 72 75 6e 63 61 74 65 0a 2a 2a 20 69 74 20 74 6f  runcate.** it to
10dd0 20 65 78 61 63 74 6c 79 20 6e 4d 61 78 20 62 79   exactly nMax by
10de0 74 65 73 2e 20 49 66 20 61 6e 20 65 72 72 6f 72  tes. If an error
10df0 20 6f 63 63 75 72 73 20 77 68 69 6c 65 20 64 6f   occurs while do
10e00 69 6e 67 20 73 6f 2c 20 69 67 6e 6f 72 65 20 69  ing so, ignore i
10e10 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t..*/.static voi
10e20 64 20 77 61 6c 4c 69 6d 69 74 53 69 7a 65 28 57  d walLimitSize(W
10e30 61 6c 20 2a 70 57 61 6c 2c 20 69 36 34 20 6e 4d  al *pWal, i64 nM
10e40 61 78 29 7b 0a 20 20 69 36 34 20 73 7a 3b 0a 20  ax){.  i64 sz;. 
10e50 20 69 6e 74 20 72 78 3b 0a 20 20 73 71 6c 69 74   int rx;.  sqlit
10e60 65 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c  e3BeginBenignMal
10e70 6c 6f 63 28 29 3b 0a 20 20 72 78 20 3d 20 73 71  loc();.  rx = sq
10e80 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a 65 28  lite3OsFileSize(
10e90 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 26 73  pWal->pWalFd, &s
10ea0 7a 29 3b 0a 20 20 69 66 28 20 72 78 3d 3d 53 51  z);.  if( rx==SQ
10eb0 4c 49 54 45 5f 4f 4b 20 26 26 20 28 73 7a 20 3e  LITE_OK && (sz >
10ec0 20 6e 4d 61 78 20 29 20 29 7b 0a 20 20 20 20 72   nMax ) ){.    r
10ed0 78 20 3d 20 73 71 6c 69 74 65 33 4f 73 54 72 75  x = sqlite3OsTru
10ee0 6e 63 61 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c  ncate(pWal->pWal
10ef0 46 64 2c 20 6e 4d 61 78 29 3b 0a 20 20 7d 0a 20  Fd, nMax);.  }. 
10f00 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67   sqlite3EndBenig
10f10 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 69 66 28  nMalloc();.  if(
10f20 20 72 78 20 29 7b 0a 20 20 20 20 73 71 6c 69 74   rx ){.    sqlit
10f30 65 33 5f 6c 6f 67 28 72 78 2c 20 22 63 61 6e 6e  e3_log(rx, "cann
10f40 6f 74 20 6c 69 6d 69 74 20 57 41 4c 20 73 69 7a  ot limit WAL siz
10f50 65 3a 20 25 73 22 2c 20 70 57 61 6c 2d 3e 7a 57  e: %s", pWal->zW
10f60 61 6c 4e 61 6d 65 29 3b 0a 20 20 7d 0a 7d 0a 0a  alName);.  }.}..
10f70 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 63 6f  /*.** Close a co
10f80 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 61 20 6c 6f  nnection to a lo
10f90 67 20 66 69 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 73  g file..*/.int s
10fa0 71 6c 69 74 65 33 57 61 6c 43 6c 6f 73 65 28 0a  qlite3WalClose(.
10fb0 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
10fc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10fd0 20 20 2f 2a 20 57 61 6c 20 74 6f 20 63 6c 6f 73    /* Wal to clos
10fe0 65 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f  e */.  int sync_
10ff0 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20 20 20  flags,          
11000 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20         /* Flags 
11010 74 6f 20 70 61 73 73 20 74 6f 20 4f 73 53 79 6e  to pass to OsSyn
11020 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20  c() (or 0) */.  
11030 69 6e 74 20 6e 42 75 66 2c 0a 20 20 75 38 20 2a  int nBuf,.  u8 *
11040 7a 42 75 66 20 20 20 20 20 20 20 20 20 20 20 20  zBuf            
11050 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
11060 75 66 66 65 72 20 6f 66 20 61 74 20 6c 65 61 73  uffer of at leas
11070 74 20 6e 42 75 66 20 62 79 74 65 73 20 2a 2f 0a  t nBuf bytes */.
11080 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
11090 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70  LITE_OK;.  if( p
110a0 57 61 6c 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  Wal ){.    int i
110b0 73 44 65 6c 65 74 65 20 3d 20 30 3b 20 20 20 20  sDelete = 0;    
110c0 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
110d0 20 74 6f 20 75 6e 6c 69 6e 6b 20 77 61 6c 20 61   to unlink wal a
110e0 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  nd wal-index fil
110f0 65 73 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 49 66  es */..    /* If
11100 20 61 6e 20 45 58 43 4c 55 53 49 56 45 20 6c 6f   an EXCLUSIVE lo
11110 63 6b 20 63 61 6e 20 62 65 20 6f 62 74 61 69 6e  ck can be obtain
11120 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 62 61  ed on the databa
11130 73 65 20 66 69 6c 65 20 28 75 73 69 6e 67 20 74  se file (using t
11140 68 65 0a 20 20 20 20 2a 2a 20 6f 72 64 69 6e 61  he.    ** ordina
11150 72 79 2c 20 72 6f 6c 6c 62 61 63 6b 2d 6d 6f 64  ry, rollback-mod
11160 65 20 6c 6f 63 6b 69 6e 67 20 6d 65 74 68 6f 64  e locking method
11170 73 2c 20 74 68 69 73 20 67 75 61 72 61 6e 74 65  s, this guarante
11180 65 73 20 74 68 61 74 20 74 68 65 0a 20 20 20 20  es that the.    
11190 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 61 73  ** connection as
111a0 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68  sociated with th
111b0 69 73 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 74  is log file is t
111c0 68 65 20 6f 6e 6c 79 20 63 6f 6e 6e 65 63 74 69  he only connecti
111d0 6f 6e 20 74 6f 0a 20 20 20 20 2a 2a 20 74 68 65  on to.    ** the
111e0 20 64 61 74 61 62 61 73 65 2e 20 49 6e 20 74 68   database. In th
111f0 69 73 20 63 61 73 65 20 63 68 65 63 6b 70 6f 69  is case checkpoi
11200 6e 74 20 74 68 65 20 64 61 74 61 62 61 73 65 20  nt the database 
11210 61 6e 64 20 75 6e 6c 69 6e 6b 20 62 6f 74 68 0a  and unlink both.
11220 20 20 20 20 2a 2a 20 74 68 65 20 77 61 6c 20 61      ** the wal a
11230 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  nd wal-index fil
11240 65 73 2e 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a  es..    **.    *
11250 2a 20 54 68 65 20 45 58 43 4c 55 53 49 56 45 20  * The EXCLUSIVE 
11260 6c 6f 63 6b 20 69 73 20 6e 6f 74 20 72 65 6c 65  lock is not rele
11270 61 73 65 64 20 62 65 66 6f 72 65 20 72 65 74 75  ased before retu
11280 72 6e 69 6e 67 2e 0a 20 20 20 20 2a 2f 0a 20 20  rning..    */.  
11290 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
112a0 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64  Lock(pWal->pDbFd
112b0 2c 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 5f 45 58  , SQLITE_LOCK_EX
112c0 43 4c 55 53 49 56 45 29 3b 0a 20 20 20 20 69 66  CLUSIVE);.    if
112d0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
112e0 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 57 61  ){.      if( pWa
112f0 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
11300 3d 3d 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44  ==WAL_NORMAL_MOD
11310 45 20 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61  E ){.        pWa
11320 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
11330 20 3d 20 57 41 4c 5f 45 58 43 4c 55 53 49 56 45   = WAL_EXCLUSIVE
11340 5f 4d 4f 44 45 3b 0a 20 20 20 20 20 20 7d 0a 20  _MODE;.      }. 
11350 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
11360 33 57 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a  3WalCheckpoint(.
11370 20 20 20 20 20 20 20 20 20 20 70 57 61 6c 2c 20            pWal, 
11380 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e  SQLITE_CHECKPOIN
11390 54 5f 50 41 53 53 49 56 45 2c 20 30 2c 20 30 2c  T_PASSIVE, 0, 0,
113a0 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20 6e 42 75   sync_flags, nBu
113b0 66 2c 20 7a 42 75 66 2c 20 30 2c 20 30 0a 20 20  f, zBuf, 0, 0.  
113c0 20 20 20 20 29 3b 0a 20 20 20 20 20 20 69 66 28      );.      if(
113d0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
113e0 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 62 50  {.        int bP
113f0 65 72 73 69 73 74 20 3d 20 2d 31 3b 0a 20 20 20  ersist = -1;.   
11400 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73 46 69       sqlite3OsFi
11410 6c 65 43 6f 6e 74 72 6f 6c 48 69 6e 74 28 0a 20  leControlHint(. 
11420 20 20 20 20 20 20 20 20 20 20 20 70 57 61 6c 2d             pWal-
11430 3e 70 44 62 46 64 2c 20 53 51 4c 49 54 45 5f 46  >pDbFd, SQLITE_F
11440 43 4e 54 4c 5f 50 45 52 53 49 53 54 5f 57 41 4c  CNTL_PERSIST_WAL
11450 2c 20 26 62 50 65 72 73 69 73 74 0a 20 20 20 20  , &bPersist.    
11460 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 69      );.        i
11470 66 28 20 62 50 65 72 73 69 73 74 21 3d 31 20 29  f( bPersist!=1 )
11480 7b 0a 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54  {.          /* T
11490 72 79 20 74 6f 20 64 65 6c 65 74 65 20 74 68 65  ry to delete the
114a0 20 57 41 4c 20 66 69 6c 65 20 69 66 20 74 68 65   WAL file if the
114b0 20 63 68 65 63 6b 70 6f 69 6e 74 20 63 6f 6d 70   checkpoint comp
114c0 6c 65 74 65 64 20 61 6e 64 0a 20 20 20 20 20 20  leted and.      
114d0 20 20 20 20 2a 2a 20 66 73 79 6e 65 64 20 28 72      ** fsyned (r
114e0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29 20 61 6e  c==SQLITE_OK) an
114f0 64 20 69 66 20 77 65 20 61 72 65 20 6e 6f 74 20  d if we are not 
11500 69 6e 20 70 65 72 73 69 73 74 65 6e 74 2d 77 61  in persistent-wa
11510 6c 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 6d  l.          ** m
11520 6f 64 65 20 28 21 62 50 65 72 73 69 73 74 29 20  ode (!bPersist) 
11530 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 69 73 44  */.          isD
11540 65 6c 65 74 65 20 3d 20 31 3b 0a 20 20 20 20 20  elete = 1;.     
11550 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 57 61     }else if( pWa
11560 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 3e 3d 30 20  l->mxWalSize>=0 
11570 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ){.          /* 
11580 54 72 79 20 74 6f 20 74 72 75 6e 63 61 74 65 20  Try to truncate 
11590 74 68 65 20 57 41 4c 20 66 69 6c 65 20 74 6f 20  the WAL file to 
115a0 7a 65 72 6f 20 62 79 74 65 73 20 69 66 20 74 68  zero bytes if th
115b0 65 20 63 68 65 63 6b 70 6f 69 6e 74 0a 20 20 20  e checkpoint.   
115c0 20 20 20 20 20 20 20 2a 2a 20 63 6f 6d 70 6c 65         ** comple
115d0 74 65 64 20 61 6e 64 20 66 73 79 6e 63 65 64 20  ted and fsynced 
115e0 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29 20  (rc==SQLITE_OK) 
115f0 61 6e 64 20 77 65 20 61 72 65 20 69 6e 20 70 65  and we are in pe
11600 72 73 69 73 74 65 6e 74 0a 20 20 20 20 20 20 20  rsistent.       
11610 20 20 20 2a 2a 20 57 41 4c 20 6d 6f 64 65 20 28     ** WAL mode (
11620 62 50 65 72 73 69 73 74 29 20 61 6e 64 20 69 66  bPersist) and if
11630 20 74 68 65 20 50 52 41 47 4d 41 20 6a 6f 75 72   the PRAGMA jour
11640 6e 61 6c 5f 73 69 7a 65 5f 6c 69 6d 69 74 20 69  nal_size_limit i
11650 73 20 61 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  s a.          **
11660 20 6e 6f 6e 2d 6e 65 67 61 74 69 76 65 20 76 61   non-negative va
11670 6c 75 65 20 28 70 57 61 6c 2d 3e 6d 78 57 61 6c  lue (pWal->mxWal
11680 53 69 7a 65 3e 3d 30 29 2e 20 20 4e 6f 74 65 20  Size>=0).  Note 
11690 74 68 61 74 20 77 65 20 74 72 75 6e 63 61 74 65  that we truncate
116a0 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 74 6f  .          ** to
116b0 20 7a 65 72 6f 20 62 79 74 65 73 20 61 73 20 74   zero bytes as t
116c0 72 75 6e 63 61 74 69 6e 67 20 74 6f 20 74 68 65  runcating to the
116d0 20 6a 6f 75 72 6e 61 6c 5f 73 69 7a 65 5f 6c 69   journal_size_li
116e0 6d 69 74 20 6d 69 67 68 74 0a 20 20 20 20 20 20  mit might.      
116f0 20 20 20 20 2a 2a 20 6c 65 61 76 65 20 61 20 63      ** leave a c
11700 6f 72 72 75 70 74 20 57 41 4c 20 66 69 6c 65 20  orrupt WAL file 
11710 6f 6e 20 64 69 73 6b 2e 20 2a 2f 0a 20 20 20 20  on disk. */.    
11720 20 20 20 20 20 20 77 61 6c 4c 69 6d 69 74 53 69        walLimitSi
11730 7a 65 28 70 57 61 6c 2c 20 30 29 3b 0a 20 20 20  ze(pWal, 0);.   
11740 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
11750 20 20 20 7d 0a 0a 20 20 20 20 77 61 6c 49 6e 64     }..    walInd
11760 65 78 43 6c 6f 73 65 28 70 57 61 6c 2c 20 69 73  exClose(pWal, is
11770 44 65 6c 65 74 65 29 3b 0a 20 20 20 20 73 71 6c  Delete);.    sql
11780 69 74 65 33 4f 73 43 6c 6f 73 65 28 70 57 61 6c  ite3OsClose(pWal
11790 2d 3e 70 57 61 6c 46 64 29 3b 0a 20 20 20 20 69  ->pWalFd);.    i
117a0 66 28 20 69 73 44 65 6c 65 74 65 20 29 7b 0a 20  f( isDelete ){. 
117b0 20 20 20 20 20 73 71 6c 69 74 65 33 42 65 67 69       sqlite3Begi
117c0 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  nBenignMalloc();
117d0 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73  .      sqlite3Os
117e0 44 65 6c 65 74 65 28 70 57 61 6c 2d 3e 70 56 66  Delete(pWal->pVf
117f0 73 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d  s, pWal->zWalNam
11800 65 2c 20 30 29 3b 0a 20 20 20 20 20 20 73 71 6c  e, 0);.      sql
11810 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c  ite3EndBenignMal
11820 6c 6f 63 28 29 3b 0a 20 20 20 20 7d 0a 20 20 20  loc();.    }.   
11830 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
11840 70 3a 20 63 6c 6f 73 65 64 5c 6e 22 2c 20 70 57  p: closed\n", pW
11850 61 6c 29 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  al));.    sqlite
11860 33 5f 66 72 65 65 28 28 76 6f 69 64 20 2a 29 70  3_free((void *)p
11870 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 29 3b 0a  Wal->apWiData);.
11880 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
11890 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20 20 72 65  (pWal);.  }.  re
118a0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
118b0 2a 20 54 72 79 20 74 6f 20 72 65 61 64 20 74 68  * Try to read th
118c0 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
118d0 65 72 2e 20 20 52 65 74 75 72 6e 20 30 20 6f 6e  er.  Return 0 on
118e0 20 73 75 63 63 65 73 73 20 61 6e 64 20 31 20 69   success and 1 i
118f0 66 0a 2a 2a 20 74 68 65 72 65 20 69 73 20 61 20  f.** there is a 
11900 70 72 6f 62 6c 65 6d 2e 0a 2a 2a 0a 2a 2a 20 54  problem..**.** T
11910 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
11920 69 6e 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79  in shared memory
11930 2e 20 20 41 6e 6f 74 68 65 72 20 74 68 72 65 61  .  Another threa
11940 64 20 6f 72 20 70 72 6f 63 65 73 73 20 6d 69 67  d or process mig
11950 68 74 0a 2a 2a 20 62 65 20 77 72 69 74 69 6e 67  ht.** be writing
11960 20 74 68 65 20 68 65 61 64 65 72 20 61 74 20 74   the header at t
11970 68 65 20 73 61 6d 65 20 74 69 6d 65 20 74 68 69  he same time thi
11980 73 20 70 72 6f 63 65 64 75 72 65 20 69 73 20 74  s procedure is t
11990 72 79 69 6e 67 20 74 6f 0a 2a 2a 20 72 65 61 64  rying to.** read
119a0 20 69 74 2c 20 77 68 69 63 68 20 6d 69 67 68 74   it, which might
119b0 20 72 65 73 75 6c 74 20 69 6e 20 69 6e 63 6f 6e   result in incon
119c0 73 69 73 74 65 6e 63 79 2e 20 20 41 20 64 69 72  sistency.  A dir
119d0 74 79 20 72 65 61 64 20 69 73 20 64 65 74 65 63  ty read is detec
119e0 74 65 64 0a 2a 2a 20 62 79 20 76 65 72 69 66 79  ted.** by verify
119f0 69 6e 67 20 74 68 61 74 20 62 6f 74 68 20 63 6f  ing that both co
11a00 70 69 65 73 20 6f 66 20 74 68 65 20 68 65 61 64  pies of the head
11a10 65 72 20 61 72 65 20 74 68 65 20 73 61 6d 65 20  er are the same 
11a20 61 6e 64 20 61 6c 73 6f 20 62 79 0a 2a 2a 20 61  and also by.** a
11a30 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20 74 68 65   checksum on the
11a40 20 68 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 49   header..**.** I
11a50 66 20 61 6e 64 20 6f 6e 6c 79 20 69 66 20 74 68  f and only if th
11a60 65 20 72 65 61 64 20 69 73 20 63 6f 6e 73 69 73  e read is consis
11a70 74 65 6e 74 20 61 6e 64 20 74 68 65 20 68 65 61  tent and the hea
11a80 64 65 72 20 69 73 20 64 69 66 66 65 72 65 6e 74  der is different
11a90 20 66 72 6f 6d 0a 2a 2a 20 70 57 61 6c 2d 3e 68   from.** pWal->h
11aa0 64 72 2c 20 74 68 65 6e 20 70 57 61 6c 2d 3e 68  dr, then pWal->h
11ab0 64 72 20 69 73 20 75 70 64 61 74 65 64 20 74 6f  dr is updated to
11ac0 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20   the content of 
11ad0 74 68 65 20 6e 65 77 20 68 65 61 64 65 72 0a 2a  the new header.*
11ae0 2a 20 61 6e 64 20 2a 70 43 68 61 6e 67 65 64 20  * and *pChanged 
11af0 69 73 20 73 65 74 20 74 6f 20 31 2e 0a 2a 2a 0a  is set to 1..**.
11b00 2a 2a 20 49 66 20 74 68 65 20 63 68 65 63 6b 73  ** If the checks
11b10 75 6d 20 63 61 6e 6e 6f 74 20 62 65 20 76 65 72  um cannot be ver
11b20 69 66 69 65 64 20 72 65 74 75 72 6e 20 6e 6f 6e  ified return non
11b30 2d 7a 65 72 6f 2e 20 49 66 20 74 68 65 20 68 65  -zero. If the he
11b40 61 64 65 72 0a 2a 2a 20 69 73 20 72 65 61 64 20  ader.** is read 
11b50 73 75 63 63 65 73 73 66 75 6c 6c 79 20 61 6e 64  successfully and
11b60 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 76 65   the checksum ve
11b70 72 69 66 69 65 64 2c 20 72 65 74 75 72 6e 20 7a  rified, return z
11b80 65 72 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ero..*/.static i
11b90 6e 74 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64  nt walIndexTryHd
11ba0 72 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  r(Wal *pWal, int
11bb0 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a 20 20 75   *pChanged){.  u
11bc0 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  32 aCksum[2];   
11bd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
11be0 2a 20 43 68 65 63 6b 73 75 6d 20 6f 6e 20 74 68  * Checksum on th
11bf0 65 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74  e header content
11c00 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65 78 48 64   */.  WalIndexHd
11c10 72 20 68 31 2c 20 68 32 3b 20 20 20 20 20 20 20  r h1, h2;       
11c20 20 20 20 20 20 20 2f 2a 20 54 77 6f 20 63 6f 70        /* Two cop
11c30 69 65 73 20 6f 66 20 74 68 65 20 68 65 61 64 65  ies of the heade
11c40 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 57  r content */.  W
11c50 61 6c 49 6e 64 65 78 48 64 72 20 76 6f 6c 61 74  alIndexHdr volat
11c60 69 6c 65 20 2a 61 48 64 72 3b 20 20 20 20 20 2f  ile *aHdr;     /
11c70 2a 20 48 65 61 64 65 72 20 69 6e 20 73 68 61 72  * Header in shar
11c80 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a 0a 20 20  ed memory */..  
11c90 2f 2a 20 54 68 65 20 66 69 72 73 74 20 70 61 67  /* The first pag
11ca0 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  e of the wal-ind
11cb0 65 78 20 6d 75 73 74 20 62 65 20 6d 61 70 70 65  ex must be mappe
11cc0 64 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74 2e  d at this point.
11cd0 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57   */.  assert( pW
11ce0 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20 26 26  al->nWiData>0 &&
11cf0 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
11d00 30 5d 20 29 3b 0a 0a 20 20 2f 2a 20 52 65 61 64  0] );..  /* Read
11d10 20 74 68 65 20 68 65 61 64 65 72 2e 20 54 68 69   the header. Thi
11d20 73 20 6d 69 67 68 74 20 68 61 70 70 65 6e 20 63  s might happen c
11d30 6f 6e 63 75 72 72 65 6e 74 6c 79 20 77 69 74 68  oncurrently with
11d40 20 61 20 77 72 69 74 65 20 74 6f 20 74 68 65 0a   a write to the.
11d50 20 20 2a 2a 20 73 61 6d 65 20 61 72 65 61 20 6f    ** same area o
11d60 66 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 20  f shared memory 
11d70 6f 6e 20 61 20 64 69 66 66 65 72 65 6e 74 20 43  on a different C
11d80 50 55 20 69 6e 20 61 20 53 4d 50 2c 0a 20 20 2a  PU in a SMP,.  *
11d90 2a 20 6d 65 61 6e 69 6e 67 20 69 74 20 69 73 20  * meaning it is 
11da0 70 6f 73 73 69 62 6c 65 20 74 68 61 74 20 61 6e  possible that an
11db0 20 69 6e 63 6f 6e 73 69 73 74 65 6e 74 20 73 6e   inconsistent sn
11dc0 61 70 73 68 6f 74 20 69 73 20 72 65 61 64 0a 20  apshot is read. 
11dd0 20 2a 2a 20 66 72 6f 6d 20 74 68 65 20 66 69 6c   ** from the fil
11de0 65 2e 20 49 66 20 74 68 69 73 20 68 61 70 70 65  e. If this happe
11df0 6e 73 2c 20 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a  ns, return non-z
11e00 65 72 6f 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54  ero..  **.  ** T
11e10 68 65 72 65 20 61 72 65 20 74 77 6f 20 63 6f 70  here are two cop
11e20 69 65 73 20 6f 66 20 74 68 65 20 68 65 61 64 65  ies of the heade
11e30 72 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e 69  r at the beginni
11e40 6e 67 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ng of the wal-in
11e50 64 65 78 2e 0a 20 20 2a 2a 20 57 68 65 6e 20 72  dex..  ** When r
11e60 65 61 64 69 6e 67 2c 20 72 65 61 64 20 5b 30 5d  eading, read [0]
11e70 20 66 69 72 73 74 20 74 68 65 6e 20 5b 31 5d 2e   first then [1].
11e80 20 20 57 72 69 74 65 73 20 61 72 65 20 69 6e 20    Writes are in 
11e90 74 68 65 20 72 65 76 65 72 73 65 20 6f 72 64 65  the reverse orde
11ea0 72 2e 0a 20 20 2a 2a 20 4d 65 6d 6f 72 79 20 62  r..  ** Memory b
11eb0 61 72 72 69 65 72 73 20 61 72 65 20 75 73 65 64  arriers are used
11ec0 20 74 6f 20 70 72 65 76 65 6e 74 20 74 68 65 20   to prevent the 
11ed0 63 6f 6d 70 69 6c 65 72 20 6f 72 20 74 68 65 20  compiler or the 
11ee0 68 61 72 64 77 61 72 65 20 66 72 6f 6d 0a 20 20  hardware from.  
11ef0 2a 2a 20 72 65 6f 72 64 65 72 69 6e 67 20 74 68  ** reordering th
11f00 65 20 72 65 61 64 73 20 61 6e 64 20 77 72 69 74  e reads and writ
11f10 65 73 2e 0a 20 20 2a 2f 0a 20 20 61 48 64 72 20  es..  */.  aHdr 
11f20 3d 20 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57  = walIndexHdr(pW
11f30 61 6c 29 3b 0a 20 20 6d 65 6d 63 70 79 28 26 68  al);.  memcpy(&h
11f40 31 2c 20 28 76 6f 69 64 20 2a 29 26 61 48 64 72  1, (void *)&aHdr
11f50 5b 30 5d 2c 20 73 69 7a 65 6f 66 28 68 31 29 29  [0], sizeof(h1))
11f60 3b 0a 20 20 77 61 6c 53 68 6d 42 61 72 72 69 65  ;.  walShmBarrie
11f70 72 28 70 57 61 6c 29 3b 0a 20 20 6d 65 6d 63 70  r(pWal);.  memcp
11f80 79 28 26 68 32 2c 20 28 76 6f 69 64 20 2a 29 26  y(&h2, (void *)&
11f90 61 48 64 72 5b 31 5d 2c 20 73 69 7a 65 6f 66 28  aHdr[1], sizeof(
11fa0 68 32 29 29 3b 0a 0a 20 20 69 66 28 20 6d 65 6d  h2));..  if( mem
11fb0 63 6d 70 28 26 68 31 2c 20 26 68 32 2c 20 73 69  cmp(&h1, &h2, si
11fc0 7a 65 6f 66 28 68 31 29 29 21 3d 30 20 29 7b 0a  zeof(h1))!=0 ){.
11fd0 20 20 20 20 72 65 74 75 72 6e 20 31 3b 20 20 20      return 1;   
11fe0 2f 2a 20 44 69 72 74 79 20 72 65 61 64 20 2a 2f  /* Dirty read */
11ff0 0a 20 20 7d 20 20 0a 20 20 69 66 28 20 68 31 2e  .  }  .  if( h1.
12000 69 73 49 6e 69 74 3d 3d 30 20 29 7b 0a 20 20 20  isInit==0 ){.   
12010 20 72 65 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20   return 1;   /* 
12020 4d 61 6c 66 6f 72 6d 65 64 20 68 65 61 64 65 72  Malformed header
12030 20 2d 20 70 72 6f 62 61 62 6c 79 20 61 6c 6c 20   - probably all 
12040 7a 65 72 6f 73 20 2a 2f 0a 20 20 7d 0a 20 20 77  zeros */.  }.  w
12050 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
12060 31 2c 20 28 75 38 2a 29 26 68 31 2c 20 73 69 7a  1, (u8*)&h1, siz
12070 65 6f 66 28 68 31 29 2d 73 69 7a 65 6f 66 28 68  eof(h1)-sizeof(h
12080 31 2e 61 43 6b 73 75 6d 29 2c 20 30 2c 20 61 43  1.aCksum), 0, aC
12090 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20 61 43 6b  ksum);.  if( aCk
120a0 73 75 6d 5b 30 5d 21 3d 68 31 2e 61 43 6b 73 75  sum[0]!=h1.aCksu
120b0 6d 5b 30 5d 20 7c 7c 20 61 43 6b 73 75 6d 5b 31  m[0] || aCksum[1
120c0 5d 21 3d 68 31 2e 61 43 6b 73 75 6d 5b 31 5d 20  ]!=h1.aCksum[1] 
120d0 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b  ){.    return 1;
120e0 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 64     /* Checksum d
120f0 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68 20 2a 2f  oes not match */
12100 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6d 65 6d 63  .  }..  if( memc
12110 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 26  mp(&pWal->hdr, &
12120 68 31 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  h1, sizeof(WalIn
12130 64 65 78 48 64 72 29 29 20 29 7b 0a 20 20 20 20  dexHdr)) ){.    
12140 2a 70 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20  *pChanged = 1;. 
12150 20 20 20 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d     memcpy(&pWal-
12160 3e 68 64 72 2c 20 26 68 31 2c 20 73 69 7a 65 6f  >hdr, &h1, sizeo
12170 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b  f(WalIndexHdr));
12180 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50 61 67  .    pWal->szPag
12190 65 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72 2e 73  e = (pWal->hdr.s
121a0 7a 50 61 67 65 26 30 78 66 65 30 30 29 20 2b 20  zPage&0xfe00) + 
121b0 28 28 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61  ((pWal->hdr.szPa
121c0 67 65 26 30 78 30 30 30 31 29 3c 3c 31 36 29 3b  ge&0x0001)<<16);
121d0 0a 20 20 20 20 74 65 73 74 63 61 73 65 28 20 70  .    testcase( p
121e0 57 61 6c 2d 3e 73 7a 50 61 67 65 3c 3d 33 32 37  Wal->szPage<=327
121f0 36 38 20 29 3b 0a 20 20 20 20 74 65 73 74 63 61  68 );.    testca
12200 73 65 28 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65  se( pWal->szPage
12210 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 7d 0a 0a  >=65536 );.  }..
12220 20 20 2f 2a 20 54 68 65 20 68 65 61 64 65 72 20    /* The header 
12230 77 61 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79  was successfully
12240 20 72 65 61 64 2e 20 52 65 74 75 72 6e 20 7a 65   read. Return ze
12250 72 6f 2e 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20  ro. */.  return 
12260 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64  0;.}../*.** Read
12270 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
12280 65 61 64 65 72 20 66 72 6f 6d 20 74 68 65 20 77  eader from the w
12290 61 6c 2d 69 6e 64 65 78 20 61 6e 64 20 69 6e 74  al-index and int
122a0 6f 20 70 57 61 6c 2d 3e 68 64 72 2e 0a 2a 2a 20  o pWal->hdr..** 
122b0 49 66 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65  If the wal-heade
122c0 72 20 61 70 70 65 61 72 73 20 74 6f 20 62 65 20  r appears to be 
122d0 63 6f 72 72 75 70 74 2c 20 74 72 79 20 74 6f 20  corrupt, try to 
122e0 72 65 63 6f 6e 73 74 72 75 63 74 20 74 68 65 0a  reconstruct the.
122f0 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 66 72 6f  ** wal-index fro
12300 6d 20 74 68 65 20 57 41 4c 20 62 65 66 6f 72 65  m the WAL before
12310 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2a 0a 2a   returning..**.*
12320 2a 20 53 65 74 20 2a 70 43 68 61 6e 67 65 64 20  * Set *pChanged 
12330 74 6f 20 31 20 69 66 20 74 68 65 20 77 61 6c 2d  to 1 if the wal-
12340 69 6e 64 65 78 20 68 65 61 64 65 72 20 76 61 6c  index header val
12350 75 65 20 69 6e 20 70 57 61 6c 2d 3e 68 64 72 20  ue in pWal->hdr 
12360 69 73 0a 2a 2a 20 63 68 61 6e 67 65 64 20 62 79  is.** changed by
12370 20 74 68 69 73 20 6f 70 65 72 74 69 6f 6e 2e 20   this opertion. 
12380 20 49 66 20 70 57 61 6c 2d 3e 68 64 72 20 69 73   If pWal->hdr is
12390 20 75 6e 63 68 61 6e 67 65 64 2c 20 73 65 74 20   unchanged, set 
123a0 2a 70 43 68 61 6e 67 65 64 0a 2a 2a 20 74 6f 20  *pChanged.** to 
123b0 30 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  0..**.** If the 
123c0 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
123d0 20 69 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79   is successfully
123e0 20 72 65 61 64 2c 20 72 65 74 75 72 6e 20 53 51   read, return SQ
123f0 4c 49 54 45 5f 4f 4b 2e 20 0a 2a 2a 20 4f 74 68  LITE_OK. .** Oth
12400 65 72 77 69 73 65 20 61 6e 20 53 51 4c 69 74 65  erwise an SQLite
12410 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f 0a   error code..*/.
12420 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e  static int walIn
12430 64 65 78 52 65 61 64 48 64 72 28 57 61 6c 20 2a  dexReadHdr(Wal *
12440 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e  pWal, int *pChan
12450 67 65 64 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  ged){.  int rc; 
12460 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12470 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
12480 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
12490 62 61 64 48 64 72 3b 20 20 20 20 20 20 20 20 20  badHdr;         
124a0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
124b0 72 75 65 20 69 66 20 61 20 68 65 61 64 65 72 20  rue if a header 
124c0 72 65 61 64 20 66 61 69 6c 65 64 20 2a 2f 0a 20  read failed */. 
124d0 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 70   volatile u32 *p
124e0 61 67 65 30 3b 20 20 20 20 20 20 20 20 20 20 20  age0;           
124f0 20 2f 2a 20 43 68 75 6e 6b 20 6f 66 20 77 61 6c   /* Chunk of wal
12500 2d 69 6e 64 65 78 20 63 6f 6e 74 61 69 6e 69 6e  -index containin
12510 67 20 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20 2f  g header */..  /
12520 2a 20 45 6e 73 75 72 65 20 74 68 61 74 20 70 61  * Ensure that pa
12530 67 65 20 30 20 6f 66 20 74 68 65 20 77 61 6c 2d  ge 0 of the wal-
12540 69 6e 64 65 78 20 28 74 68 65 20 70 61 67 65 20  index (the page 
12550 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74 68  that contains th
12560 65 20 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65  e .  ** wal-inde
12570 78 20 68 65 61 64 65 72 29 20 69 73 20 6d 61 70  x header) is map
12580 70 65 64 2e 20 52 65 74 75 72 6e 20 65 61 72 6c  ped. Return earl
12590 79 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  y if an error oc
125a0 63 75 72 73 20 68 65 72 65 2e 0a 20 20 2a 2f 0a  curs here..  */.
125b0 20 20 61 73 73 65 72 74 28 20 70 43 68 61 6e 67    assert( pChang
125c0 65 64 20 29 3b 0a 20 20 72 63 20 3d 20 77 61 6c  ed );.  rc = wal
125d0 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20  IndexPage(pWal, 
125e0 30 2c 20 26 70 61 67 65 30 29 3b 0a 20 20 69 66  0, &page0);.  if
125f0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
12600 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  ){.    return rc
12610 3b 0a 20 20 7d 3b 0a 20 20 61 73 73 65 72 74 28  ;.  };.  assert(
12620 20 70 61 67 65 30 20 7c 7c 20 70 57 61 6c 2d 3e   page0 || pWal->
12630 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a  writeLock==0 );.
12640 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72  .  /* If the fir
12650 73 74 20 70 61 67 65 20 6f 66 20 74 68 65 20 77  st page of the w
12660 61 6c 2d 69 6e 64 65 78 20 68 61 73 20 62 65 65  al-index has bee
12670 6e 20 6d 61 70 70 65 64 2c 20 74 72 79 20 74 6f  n mapped, try to
12680 20 72 65 61 64 20 74 68 65 0a 20 20 2a 2a 20 77   read the.  ** w
12690 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
126a0 69 6d 6d 65 64 69 61 74 65 6c 79 2c 20 77 69 74  immediately, wit
126b0 68 6f 75 74 20 68 6f 6c 64 69 6e 67 20 61 6e 79  hout holding any
126c0 20 6c 6f 63 6b 2e 20 54 68 69 73 20 75 73 75 61   lock. This usua
126d0 6c 6c 79 0a 20 20 2a 2a 20 77 6f 72 6b 73 2c 20  lly.  ** works, 
126e0 62 75 74 20 6d 61 79 20 66 61 69 6c 20 69 66 20  but may fail if 
126f0 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
12700 61 64 65 72 20 69 73 20 63 6f 72 72 75 70 74 20  ader is corrupt 
12710 6f 72 20 63 75 72 72 65 6e 74 6c 79 20 0a 20 20  or currently .  
12720 2a 2a 20 62 65 69 6e 67 20 6d 6f 64 69 66 69 65  ** being modifie
12730 64 20 62 79 20 61 6e 6f 74 68 65 72 20 74 68 72  d by another thr
12740 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 2e 0a  ead or process..
12750 20 20 2a 2f 0a 20 20 62 61 64 48 64 72 20 3d 20    */.  badHdr = 
12760 28 70 61 67 65 30 20 3f 20 77 61 6c 49 6e 64 65  (page0 ? walInde
12770 78 54 72 79 48 64 72 28 70 57 61 6c 2c 20 70 43  xTryHdr(pWal, pC
12780 68 61 6e 67 65 64 29 20 3a 20 31 29 3b 0a 0a 20  hanged) : 1);.. 
12790 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72 73 74   /* If the first
127a0 20 61 74 74 65 6d 70 74 20 66 61 69 6c 65 64 2c   attempt failed,
127b0 20 69 74 20 6d 69 67 68 74 20 68 61 76 65 20 62   it might have b
127c0 65 65 6e 20 64 75 65 20 74 6f 20 61 20 72 61 63  een due to a rac
127d0 65 0a 20 20 2a 2a 20 77 69 74 68 20 61 20 77 72  e.  ** with a wr
127e0 69 74 65 72 2e 20 20 53 6f 20 67 65 74 20 61 20  iter.  So get a 
127f0 57 52 49 54 45 20 6c 6f 63 6b 20 61 6e 64 20 74  WRITE lock and t
12800 72 79 20 61 67 61 69 6e 2e 0a 20 20 2a 2f 0a 20  ry again..  */. 
12810 20 61 73 73 65 72 74 28 20 62 61 64 48 64 72 3d   assert( badHdr=
12820 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 77 72 69 74  =0 || pWal->writ
12830 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 69 66  eLock==0 );.  if
12840 28 20 62 61 64 48 64 72 20 29 7b 0a 20 20 20 20  ( badHdr ){.    
12850 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4f 6e  if( pWal->readOn
12860 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  ly & WAL_SHM_RDO
12870 4e 4c 59 20 29 7b 0a 20 20 20 20 20 20 69 66 28  NLY ){.      if(
12880 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20   SQLITE_OK==(rc 
12890 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28  = walLockShared(
128a0 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f  pWal, WAL_WRITE_
128b0 4c 4f 43 4b 29 29 20 29 7b 0a 20 20 20 20 20 20  LOCK)) ){.      
128c0 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65    walUnlockShare
128d0 64 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54  d(pWal, WAL_WRIT
128e0 45 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 20 20 20  E_LOCK);.       
128f0 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 52 45 41   rc = SQLITE_REA
12900 44 4f 4e 4c 59 5f 52 45 43 4f 56 45 52 59 3b 0a  DONLY_RECOVERY;.
12910 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
12920 65 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d  e if( SQLITE_OK=
12930 3d 28 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78  =(rc = walLockEx
12940 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
12950 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29  L_WRITE_LOCK, 1)
12960 29 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d  ) ){.      pWal-
12970 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 31 3b 0a  >writeLock = 1;.
12980 20 20 20 20 20 20 69 66 28 20 53 51 4c 49 54 45        if( SQLITE
12990 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c 49 6e  _OK==(rc = walIn
129a0 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20 30 2c  dexPage(pWal, 0,
129b0 20 26 70 61 67 65 30 29 29 20 29 7b 0a 20 20 20   &page0)) ){.   
129c0 20 20 20 20 20 62 61 64 48 64 72 20 3d 20 77 61       badHdr = wa
129d0 6c 49 6e 64 65 78 54 72 79 48 64 72 28 70 57 61  lIndexTryHdr(pWa
129e0 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b 0a 20 20  l, pChanged);.  
129f0 20 20 20 20 20 20 69 66 28 20 62 61 64 48 64 72        if( badHdr
12a00 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2f 2a   ){.          /*
12a10 20 49 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   If the wal-inde
12a20 78 20 68 65 61 64 65 72 20 69 73 20 73 74 69 6c  x header is stil
12a30 6c 20 6d 61 6c 66 6f 72 6d 65 64 20 65 76 65 6e  l malformed even
12a40 20 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67 0a 20   while holding. 
12a50 20 20 20 20 20 20 20 20 20 2a 2a 20 61 20 57 52           ** a WR
12a60 49 54 45 20 6c 6f 63 6b 2c 20 69 74 20 63 61 6e  ITE lock, it can
12a70 20 6f 6e 6c 79 20 6d 65 61 6e 20 74 68 61 74 20   only mean that 
12a80 74 68 65 20 68 65 61 64 65 72 20 69 73 20 63 6f  the header is co
12a90 72 72 75 70 74 65 64 20 61 6e 64 0a 20 20 20 20  rrupted and.    
12aa0 20 20 20 20 20 20 2a 2a 20 6e 65 65 64 73 20 74        ** needs t
12ab0 6f 20 62 65 20 72 65 63 6f 6e 73 74 72 75 63 74  o be reconstruct
12ac0 65 64 2e 20 20 53 6f 20 72 75 6e 20 72 65 63 6f  ed.  So run reco
12ad0 76 65 72 79 20 74 6f 20 64 6f 20 65 78 61 63 74  very to do exact
12ae0 6c 79 20 74 68 61 74 2e 0a 20 20 20 20 20 20 20  ly that..       
12af0 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20     */.          
12b00 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52 65 63  rc = walIndexRec
12b10 6f 76 65 72 28 70 57 61 6c 29 3b 0a 20 20 20 20  over(pWal);.    
12b20 20 20 20 20 20 20 2a 70 43 68 61 6e 67 65 64 20        *pChanged 
12b30 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  = 1;.        }. 
12b40 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 57 61       }.      pWa
12b50 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30  l->writeLock = 0
12b60 3b 0a 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63  ;.      walUnloc
12b70 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
12b80 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c   WAL_WRITE_LOCK,
12b90 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a   1);.    }.  }..
12ba0 20 20 2f 2a 20 49 66 20 74 68 65 20 68 65 61 64    /* If the head
12bb0 65 72 20 69 73 20 72 65 61 64 20 73 75 63 63 65  er is read succe
12bc0 73 73 66 75 6c 6c 79 2c 20 63 68 65 63 6b 20 74  ssfully, check t
12bd0 68 65 20 76 65 72 73 69 6f 6e 20 6e 75 6d 62 65  he version numbe
12be0 72 20 74 6f 20 6d 61 6b 65 0a 20 20 2a 2a 20 73  r to make.  ** s
12bf0 75 72 65 20 74 68 65 20 77 61 6c 2d 69 6e 64 65  ure the wal-inde
12c00 78 20 77 61 73 20 6e 6f 74 20 63 6f 6e 73 74 72  x was not constr
12c10 75 63 74 65 64 20 77 69 74 68 20 73 6f 6d 65 20  ucted with some 
12c20 66 75 74 75 72 65 20 66 6f 72 6d 61 74 20 74 68  future format th
12c30 61 74 0a 20 20 2a 2a 20 74 68 69 73 20 76 65 72  at.  ** this ver
12c40 73 69 6f 6e 20 6f 66 20 53 51 4c 69 74 65 20 63  sion of SQLite c
12c50 61 6e 6e 6f 74 20 75 6e 64 65 72 73 74 61 6e 64  annot understand
12c60 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 62 61 64  ..  */.  if( bad
12c70 48 64 72 3d 3d 30 20 26 26 20 70 57 61 6c 2d 3e  Hdr==0 && pWal->
12c80 68 64 72 2e 69 56 65 72 73 69 6f 6e 21 3d 57 41  hdr.iVersion!=WA
12c90 4c 49 4e 44 45 58 5f 4d 41 58 5f 56 45 52 53 49  LINDEX_MAX_VERSI
12ca0 4f 4e 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  ON ){.    rc = S
12cb0 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 5f 42  QLITE_CANTOPEN_B
12cc0 4b 50 54 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  KPT;.  }..  retu
12cd0 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
12ce0 54 68 69 73 20 69 73 20 74 68 65 20 76 61 6c 75  This is the valu
12cf0 65 20 74 68 61 74 20 77 61 6c 54 72 79 42 65 67  e that walTryBeg
12d00 69 6e 52 65 61 64 20 72 65 74 75 72 6e 73 20 77  inRead returns w
12d10 68 65 6e 20 69 74 20 6e 65 65 64 73 20 74 6f 0a  hen it needs to.
12d20 2a 2a 20 62 65 20 72 65 74 72 69 65 64 2e 0a 2a  ** be retried..*
12d30 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 52 45  /.#define WAL_RE
12d40 54 52 59 20 20 28 2d 31 29 0a 0a 2f 2a 0a 2a 2a  TRY  (-1)../*.**
12d50 20 41 74 74 65 6d 70 74 20 74 6f 20 73 74 61 72   Attempt to star
12d60 74 20 61 20 72 65 61 64 20 74 72 61 6e 73 61 63  t a read transac
12d70 74 69 6f 6e 2e 20 20 54 68 69 73 20 6d 69 67 68  tion.  This migh
12d80 74 20 66 61 69 6c 20 64 75 65 20 74 6f 20 61 20  t fail due to a 
12d90 72 61 63 65 20 6f 72 0a 2a 2a 20 6f 74 68 65 72  race or.** other
12da0 20 74 72 61 6e 73 69 65 6e 74 20 63 6f 6e 64 69   transient condi
12db0 74 69 6f 6e 2e 20 20 57 68 65 6e 20 74 68 61 74  tion.  When that
12dc0 20 68 61 70 70 65 6e 73 2c 20 69 74 20 72 65 74   happens, it ret
12dd0 75 72 6e 73 20 57 41 4c 5f 52 45 54 52 59 20 74  urns WAL_RETRY t
12de0 6f 0a 2a 2a 20 69 6e 64 69 63 61 74 65 20 74 6f  o.** indicate to
12df0 20 74 68 65 20 63 61 6c 6c 65 72 20 74 68 61 74   the caller that
12e00 20 69 74 20 69 73 20 73 61 66 65 20 74 6f 20 72   it is safe to r
12e10 65 74 72 79 20 69 6d 6d 65 64 69 61 74 65 6c 79  etry immediately
12e20 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63 65  ..**.** On succe
12e30 73 73 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  ss return SQLITE
12e40 5f 4f 4b 2e 20 20 4f 6e 20 61 20 70 65 72 6d 61  _OK.  On a perma
12e50 6e 65 6e 74 20 66 61 69 6c 75 72 65 20 28 73 75  nent failure (su
12e60 63 68 20 61 6e 0a 2a 2a 20 49 2f 4f 20 65 72 72  ch an.** I/O err
12e70 6f 72 20 6f 72 20 61 6e 20 53 51 4c 49 54 45 5f  or or an SQLITE_
12e80 42 55 53 59 20 62 65 63 61 75 73 65 20 61 6e 6f  BUSY because ano
12e90 74 68 65 72 20 70 72 6f 63 65 73 73 20 69 73 20  ther process is 
12ea0 72 75 6e 6e 69 6e 67 0a 2a 2a 20 72 65 63 6f 76  running.** recov
12eb0 65 72 79 29 20 72 65 74 75 72 6e 20 61 20 70 6f  ery) return a po
12ec0 73 69 74 69 76 65 20 65 72 72 6f 72 20 63 6f 64  sitive error cod
12ed0 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 75 73 65  e..**.** The use
12ee0 57 61 6c 20 70 61 72 61 6d 65 74 65 72 20 69 73  Wal parameter is
12ef0 20 74 72 75 65 20 74 6f 20 66 6f 72 63 65 20 74   true to force t
12f00 68 65 20 75 73 65 20 6f 66 20 74 68 65 20 57 41  he use of the WA
12f10 4c 20 61 6e 64 20 64 69 73 61 62 6c 65 0a 2a 2a  L and disable.**
12f20 20 74 68 65 20 63 61 73 65 20 77 68 65 72 65 20   the case where 
12f30 74 68 65 20 57 41 4c 20 69 73 20 62 79 70 61 73  the WAL is bypas
12f40 73 65 64 20 62 65 63 61 75 73 65 20 69 74 20 68  sed because it h
12f50 61 73 20 62 65 65 6e 20 63 6f 6d 70 6c 65 74 65  as been complete
12f60 6c 79 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74  ly.** checkpoint
12f70 65 64 2e 20 20 49 66 20 75 73 65 57 61 6c 3d 3d  ed.  If useWal==
12f80 30 20 74 68 65 6e 20 74 68 69 73 20 72 6f 75 74  0 then this rout
12f90 69 6e 65 20 63 61 6c 6c 73 20 77 61 6c 49 6e 64  ine calls walInd
12fa0 65 78 52 65 61 64 48 64 72 28 29 20 0a 2a 2a 20  exReadHdr() .** 
12fb0 74 6f 20 6d 61 6b 65 20 61 20 63 6f 70 79 20 6f  to make a copy o
12fc0 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
12fd0 68 65 61 64 65 72 20 69 6e 74 6f 20 70 57 61 6c  header into pWal
12fe0 2d 3e 68 64 72 2e 20 20 49 66 20 74 68 65 20 0a  ->hdr.  If the .
12ff0 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  ** wal-index hea
13000 64 65 72 20 68 61 73 20 63 68 61 6e 67 65 64 2c  der has changed,
13010 20 2a 70 43 68 61 6e 67 65 64 20 69 73 20 73 65   *pChanged is se
13020 74 20 74 6f 20 31 20 28 61 73 20 61 6e 20 69 6e  t to 1 (as an in
13030 64 69 63 61 74 69 6f 6e 20 0a 2a 2a 20 74 6f 20  dication .** to 
13040 74 68 65 20 63 61 6c 6c 65 72 20 74 68 61 74 20  the caller that 
13050 74 68 65 20 6c 6f 63 61 6c 20 70 61 67 65 74 20  the local paget 
13060 63 61 63 68 65 20 69 73 20 6f 62 73 6f 6c 65 74  cache is obsolet
13070 65 20 61 6e 64 20 6e 65 65 64 73 20 74 6f 20 62  e and needs to b
13080 65 20 0a 2a 2a 20 66 6c 75 73 68 65 64 2e 29 20  e .** flushed.) 
13090 20 57 68 65 6e 20 75 73 65 57 61 6c 3d 3d 31 2c   When useWal==1,
130a0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
130b0 65 61 64 65 72 20 69 73 20 61 73 73 75 6d 65 64  eader is assumed
130c0 20 74 6f 20 61 6c 72 65 61 64 79 0a 2a 2a 20 62   to already.** b
130d0 65 20 6c 6f 61 64 65 64 20 61 6e 64 20 74 68 65  e loaded and the
130e0 20 70 43 68 61 6e 67 65 64 20 70 61 72 61 6d 65   pChanged parame
130f0 74 65 72 20 69 73 20 75 6e 75 73 65 64 2e 0a 2a  ter is unused..*
13100 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 65 72 20  *.** The caller 
13110 6d 75 73 74 20 73 65 74 20 74 68 65 20 63 6e 74  must set the cnt
13120 20 70 61 72 61 6d 65 74 65 72 20 74 6f 20 74 68   parameter to th
13130 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 72 69 6f  e number of prio
13140 72 20 63 61 6c 6c 73 20 74 6f 0a 2a 2a 20 74 68  r calls to.** th
13150 69 73 20 72 6f 75 74 69 6e 65 20 64 75 72 69 6e  is routine durin
13160 67 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 65  g the current re
13170 61 64 20 61 74 74 65 6d 70 74 20 74 68 61 74 20  ad attempt that 
13180 72 65 74 75 72 6e 65 64 20 57 41 4c 5f 52 45 54  returned WAL_RET
13190 52 59 2e 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74  RY..** This rout
131a0 69 6e 65 20 77 69 6c 6c 20 73 74 61 72 74 20 74  ine will start t
131b0 61 6b 69 6e 67 20 6d 6f 72 65 20 61 67 67 72 65  aking more aggre
131c0 73 73 69 76 65 20 6d 65 61 73 75 72 65 73 20 74  ssive measures t
131d0 6f 20 63 6c 65 61 72 20 74 68 65 0a 2a 2a 20 72  o clear the.** r
131e0 61 63 65 20 63 6f 6e 64 69 74 69 6f 6e 73 20 61  ace conditions a
131f0 66 74 65 72 20 6d 75 6c 74 69 70 6c 65 20 57 41  fter multiple WA
13200 4c 5f 52 45 54 52 59 20 72 65 74 75 72 6e 73 2c  L_RETRY returns,
13210 20 61 6e 64 20 61 66 74 65 72 20 61 6e 20 65 78   and after an ex
13220 63 65 73 73 69 76 65 0a 2a 2a 20 6e 75 6d 62 65  cessive.** numbe
13230 72 20 6f 66 20 65 72 72 6f 72 73 20 77 69 6c 6c  r of errors will
13240 20 75 6c 74 69 6d 61 74 65 6c 79 20 72 65 74 75   ultimately retu
13250 72 6e 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43  rn SQLITE_PROTOC
13260 4f 4c 2e 20 20 54 68 65 0a 2a 2a 20 53 51 4c 49  OL.  The.** SQLI
13270 54 45 5f 50 52 4f 54 4f 43 4f 4c 20 72 65 74 75  TE_PROTOCOL retu
13280 72 6e 20 69 6e 64 69 63 61 74 65 73 20 74 68 61  rn indicates tha
13290 74 20 73 6f 6d 65 20 6f 74 68 65 72 20 70 72 6f  t some other pro
132a0 63 65 73 73 20 68 61 73 20 67 6f 6e 65 20 72 6f  cess has gone ro
132b0 67 75 65 0a 2a 2a 20 61 6e 64 20 69 73 20 6e 6f  gue.** and is no
132c0 74 20 68 6f 6e 6f 72 69 6e 67 20 74 68 65 20 6c  t honoring the l
132d0 6f 63 6b 69 6e 67 20 70 72 6f 74 6f 63 6f 6c 2e  ocking protocol.
132e0 20 20 54 68 65 72 65 20 69 73 20 61 20 76 61 6e    There is a van
132f0 69 73 68 69 6e 67 6c 79 20 73 6d 61 6c 6c 0a 2a  ishingly small.*
13300 2a 20 63 68 61 6e 63 65 20 74 68 61 74 20 53 51  * chance that SQ
13310 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 20 63 6f  LITE_PROTOCOL co
13320 75 6c 64 20 62 65 20 72 65 74 75 72 6e 65 64 20  uld be returned 
13330 62 65 63 61 75 73 65 20 6f 66 20 61 20 72 75 6e  because of a run
13340 20 6f 66 20 72 65 61 6c 6c 79 0a 2a 2a 20 62 61   of really.** ba
13350 64 20 6c 75 63 6b 20 77 68 65 6e 20 74 68 65 72  d luck when ther
13360 65 20 69 73 20 6c 6f 74 73 20 6f 66 20 63 6f 6e  e is lots of con
13370 74 65 6e 74 69 6f 6e 20 66 6f 72 20 74 68 65 20  tention for the 
13380 77 61 6c 2d 69 6e 64 65 78 2c 20 62 75 74 20 74  wal-index, but t
13390 68 61 74 0a 2a 2a 20 70 6f 73 73 69 62 69 6c 69  hat.** possibili
133a0 74 79 20 69 73 20 73 6f 20 73 6d 61 6c 6c 20 74  ty is so small t
133b0 68 61 74 20 69 74 20 63 61 6e 20 62 65 20 73 61  hat it can be sa
133c0 66 65 6c 79 20 6e 65 67 6c 65 63 74 65 64 2c 20  fely neglected, 
133d0 77 65 20 62 65 6c 69 65 76 65 2e 0a 2a 2a 0a 2a  we believe..**.*
133e0 2a 20 4f 6e 20 73 75 63 63 65 73 73 2c 20 74 68  * On success, th
133f0 69 73 20 72 6f 75 74 69 6e 65 20 6f 62 74 61 69  is routine obtai
13400 6e 73 20 61 20 72 65 61 64 20 6c 6f 63 6b 20 6f  ns a read lock o
13410 6e 20 0a 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c  n .** WAL_READ_L
13420 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  OCK(pWal->readLo
13430 63 6b 29 2e 20 20 54 68 65 20 70 57 61 6c 2d 3e  ck).  The pWal->
13440 72 65 61 64 4c 6f 63 6b 20 69 6e 74 65 67 65 72  readLock integer
13450 20 69 73 0a 2a 2a 20 69 6e 20 74 68 65 20 72 61   is.** in the ra
13460 6e 67 65 20 30 20 3c 3d 20 70 57 61 6c 2d 3e 72  nge 0 <= pWal->r
13470 65 61 64 4c 6f 63 6b 20 3c 20 57 41 4c 5f 4e 52  eadLock < WAL_NR
13480 45 41 44 45 52 2e 20 20 49 66 20 70 57 61 6c 2d  EADER.  If pWal-
13490 3e 72 65 61 64 4c 6f 63 6b 3d 3d 28 2d 31 29 0a  >readLock==(-1).
134a0 2a 2a 20 74 68 61 74 20 6d 65 61 6e 73 20 74 68  ** that means th
134b0 65 20 57 61 6c 20 64 6f 65 73 20 6e 6f 74 20 68  e Wal does not h
134c0 6f 6c 64 20 61 6e 79 20 72 65 61 64 20 6c 6f 63  old any read loc
134d0 6b 2e 20 20 54 68 65 20 72 65 61 64 65 72 20 6d  k.  The reader m
134e0 75 73 74 20 6e 6f 74 0a 2a 2a 20 61 63 63 65 73  ust not.** acces
134f0 73 20 61 6e 79 20 64 61 74 61 62 61 73 65 20 70  s any database p
13500 61 67 65 20 74 68 61 74 20 69 73 20 6d 6f 64 69  age that is modi
13510 66 69 65 64 20 62 79 20 61 20 57 41 4c 20 66 72  fied by a WAL fr
13520 61 6d 65 20 75 70 20 74 6f 20 61 6e 64 0a 2a 2a  ame up to and.**
13530 20 69 6e 63 6c 75 64 69 6e 67 20 66 72 61 6d 65   including frame
13540 20 6e 75 6d 62 65 72 20 61 52 65 61 64 4d 61 72   number aReadMar
13550 6b 5b 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  k[pWal->readLock
13560 5d 2e 20 20 54 68 65 20 72 65 61 64 65 72 20 77  ].  The reader w
13570 69 6c 6c 0a 2a 2a 20 75 73 65 20 57 41 4c 20 66  ill.** use WAL f
13580 72 61 6d 65 73 20 75 70 20 74 6f 20 61 6e 64 20  rames up to and 
13590 69 6e 63 6c 75 64 69 6e 67 20 70 57 61 6c 2d 3e  including pWal->
135a0 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 66 20 70  hdr.mxFrame if p
135b0 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 30 0a  Wal->readLock>0.
135c0 2a 2a 20 4f 72 20 69 66 20 70 57 61 6c 2d 3e 72  ** Or if pWal->r
135d0 65 61 64 4c 6f 63 6b 3d 3d 30 2c 20 74 68 65 6e  eadLock==0, then
135e0 20 74 68 65 20 72 65 61 64 65 72 20 77 69 6c 6c   the reader will
135f0 20 69 67 6e 6f 72 65 20 74 68 65 20 57 41 4c 0a   ignore the WAL.
13600 2a 2a 20 63 6f 6d 70 6c 65 74 65 6c 79 20 61 6e  ** completely an
13610 64 20 67 65 74 20 61 6c 6c 20 63 6f 6e 74 65 6e  d get all conten
13620 74 20 64 69 72 65 63 74 6c 79 20 66 72 6f 6d 20  t directly from 
13630 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
13640 65 2e 0a 2a 2a 20 49 66 20 74 68 65 20 75 73 65  e..** If the use
13650 57 61 6c 20 70 61 72 61 6d 65 74 65 72 20 69 73  Wal parameter is
13660 20 31 20 74 68 65 6e 20 74 68 65 20 57 41 4c 20   1 then the WAL 
13670 77 69 6c 6c 20 6e 65 76 65 72 20 62 65 20 69 67  will never be ig
13680 6e 6f 72 65 64 20 61 6e 64 0a 2a 2a 20 74 68 69  nored and.** thi
13690 73 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20 61  s routine will a
136a0 6c 77 61 79 73 20 73 65 74 20 70 57 61 6c 2d 3e  lways set pWal->
136b0 72 65 61 64 4c 6f 63 6b 3e 30 20 6f 6e 20 73 75  readLock>0 on su
136c0 63 63 65 73 73 2e 0a 2a 2a 20 57 68 65 6e 20 74  ccess..** When t
136d0 68 65 20 72 65 61 64 20 74 72 61 6e 73 61 63 74  he read transact
136e0 69 6f 6e 20 69 73 20 63 6f 6d 70 6c 65 74 65 64  ion is completed
136f0 2c 20 74 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  , the caller mus
13700 74 20 72 65 6c 65 61 73 65 20 74 68 65 0a 2a 2a  t release the.**
13710 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52 45 41   lock on WAL_REA
13720 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61  D_LOCK(pWal->rea
13730 64 4c 6f 63 6b 29 20 61 6e 64 20 73 65 74 20 70  dLock) and set p
13740 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 74 6f  Wal->readLock to
13750 20 2d 31 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20   -1..**.** This 
13760 72 6f 75 74 69 6e 65 20 75 73 65 73 20 74 68 65  routine uses the
13770 20 6e 42 61 63 6b 66 69 6c 6c 20 61 6e 64 20 61   nBackfill and a
13780 52 65 61 64 4d 61 72 6b 5b 5d 20 66 69 65 6c 64  ReadMark[] field
13790 73 20 6f 66 20 74 68 65 20 68 65 61 64 65 72 0a  s of the header.
137a0 2a 2a 20 74 6f 20 73 65 6c 65 63 74 20 61 20 70  ** to select a p
137b0 61 72 74 69 63 75 6c 61 72 20 57 41 4c 5f 52 45  articular WAL_RE
137c0 41 44 5f 4c 4f 43 4b 28 29 20 74 68 61 74 20 73  AD_LOCK() that s
137d0 74 72 69 76 65 73 20 74 6f 20 6c 65 74 20 74 68  trives to let th
137e0 65 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 20  e.** checkpoint 
137f0 70 72 6f 63 65 73 73 20 64 6f 20 61 73 20 6d 75  process do as mu
13800 63 68 20 77 6f 72 6b 20 61 73 20 70 6f 73 73 69  ch work as possi
13810 62 6c 65 2e 20 20 54 68 69 73 20 72 6f 75 74 69  ble.  This routi
13820 6e 65 20 6d 69 67 68 74 0a 2a 2a 20 75 70 64 61  ne might.** upda
13830 74 65 20 76 61 6c 75 65 73 20 6f 66 20 74 68 65  te values of the
13840 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 61 72 72   aReadMark[] arr
13850 61 79 20 69 6e 20 74 68 65 20 68 65 61 64 65 72  ay in the header
13860 2c 20 62 75 74 20 69 66 20 69 74 20 64 6f 65 73  , but if it does
13870 0a 2a 2a 20 73 6f 20 69 74 20 74 61 6b 65 73 20  .** so it takes 
13880 63 61 72 65 20 74 6f 20 68 6f 6c 64 20 61 6e 20  care to hold an 
13890 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f  exclusive lock o
138a0 6e 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e 64  n the correspond
138b0 69 6e 67 0a 2a 2a 20 57 41 4c 5f 52 45 41 44 5f  ing.** WAL_READ_
138c0 4c 4f 43 4b 28 29 20 77 68 69 6c 65 20 63 68 61  LOCK() while cha
138d0 6e 67 69 6e 67 20 76 61 6c 75 65 73 2e 0a 2a 2f  nging values..*/
138e0 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 54  .static int walT
138f0 72 79 42 65 67 69 6e 52 65 61 64 28 57 61 6c 20  ryBeginRead(Wal 
13900 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61  *pWal, int *pCha
13910 6e 67 65 64 2c 20 69 6e 74 20 75 73 65 57 61 6c  nged, int useWal
13920 2c 20 69 6e 74 20 63 6e 74 29 7b 0a 20 20 76 6f  , int cnt){.  vo
13930 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e  latile WalCkptIn
13940 66 6f 20 2a 70 49 6e 66 6f 3b 20 20 20 20 2f 2a  fo *pInfo;    /*
13950 20 43 68 65 63 6b 70 6f 69 6e 74 20 69 6e 66 6f   Checkpoint info
13960 72 6d 61 74 69 6f 6e 20 69 6e 20 77 61 6c 2d 69  rmation in wal-i
13970 6e 64 65 78 20 2a 2f 0a 20 20 75 33 32 20 6d 78  ndex */.  u32 mx
13980 52 65 61 64 4d 61 72 6b 3b 20 20 20 20 20 20 20  ReadMark;       
13990 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 72            /* Lar
139a0 67 65 73 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d  gest aReadMark[]
139b0 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20   value */.  int 
139c0 6d 78 49 3b 20 20 20 20 20 20 20 20 20 20 20 20  mxI;            
139d0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
139e0 6e 64 65 78 20 6f 66 20 6c 61 72 67 65 73 74 20  ndex of largest 
139f0 61 52 65 61 64 4d 61 72 6b 5b 5d 20 76 61 6c 75  aReadMark[] valu
13a00 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  e */.  int i;   
13a10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13a20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63         /* Loop c
13a30 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 69 6e 74 20  ounter */.  int 
13a40 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  rc = SQLITE_OK; 
13a50 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
13a60 65 74 75 72 6e 20 63 6f 64 65 20 20 2a 2f 0a 0a  eturn code  */..
13a70 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
13a80 72 65 61 64 4c 6f 63 6b 3c 30 20 29 3b 20 20 20  readLock<0 );   
13a90 20 20 2f 2a 20 4e 6f 74 20 63 75 72 72 65 6e 74    /* Not current
13aa0 6c 79 20 6c 6f 63 6b 65 64 20 2a 2f 0a 0a 20 20  ly locked */..  
13ab0 2f 2a 20 54 61 6b 65 20 73 74 65 70 73 20 74 6f  /* Take steps to
13ac0 20 61 76 6f 69 64 20 73 70 69 6e 6e 69 6e 67 20   avoid spinning 
13ad0 66 6f 72 65 76 65 72 20 69 66 20 74 68 65 72 65  forever if there
13ae0 20 69 73 20 61 20 70 72 6f 74 6f 63 6f 6c 20 65   is a protocol e
13af0 72 72 6f 72 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20  rror..  **.  ** 
13b00 43 69 72 63 75 6d 73 74 61 6e 63 65 73 20 74 68  Circumstances th
13b10 61 74 20 63 61 75 73 65 20 61 20 52 45 54 52 59  at cause a RETRY
13b20 20 73 68 6f 75 6c 64 20 6f 6e 6c 79 20 6c 61 73   should only las
13b30 74 20 66 6f 72 20 74 68 65 20 62 72 69 65 66 65  t for the briefe
13b40 73 74 0a 20 20 2a 2a 20 69 6e 73 74 61 6e 63 65  st.  ** instance
13b50 73 20 6f 66 20 74 69 6d 65 2e 20 20 4e 6f 20 49  s of time.  No I
13b60 2f 4f 20 6f 72 20 6f 74 68 65 72 20 73 79 73 74  /O or other syst
13b70 65 6d 20 63 61 6c 6c 73 20 61 72 65 20 64 6f 6e  em calls are don
13b80 65 20 77 68 69 6c 65 20 74 68 65 0a 20 20 2a 2a  e while the.  **
13b90 20 6c 6f 63 6b 73 20 61 72 65 20 68 65 6c 64 2c   locks are held,
13ba0 20 73 6f 20 74 68 65 20 6c 6f 63 6b 73 20 73 68   so the locks sh
13bb0 6f 75 6c 64 20 6e 6f 74 20 62 65 20 68 65 6c 64  ould not be held
13bc0 20 66 6f 72 20 76 65 72 79 20 6c 6f 6e 67 2e 20   for very long. 
13bd0 42 75 74 20 0a 20 20 2a 2a 20 69 66 20 77 65 20  But .  ** if we 
13be0 61 72 65 20 75 6e 6c 75 63 6b 79 2c 20 61 6e 6f  are unlucky, ano
13bf0 74 68 65 72 20 70 72 6f 63 65 73 73 20 74 68 61  ther process tha
13c00 74 20 69 73 20 68 6f 6c 64 69 6e 67 20 61 20 6c  t is holding a l
13c10 6f 63 6b 20 6d 69 67 68 74 20 67 65 74 0a 20 20  ock might get.  
13c20 2a 2a 20 70 61 67 65 64 20 6f 75 74 20 6f 72 20  ** paged out or 
13c30 74 61 6b 65 20 61 20 70 61 67 65 2d 66 61 75 6c  take a page-faul
13c40 74 20 74 68 61 74 20 69 73 20 74 69 6d 65 2d 63  t that is time-c
13c50 6f 6e 73 75 6d 69 6e 67 20 74 6f 20 72 65 73 6f  onsuming to reso
13c60 6c 76 65 2c 20 0a 20 20 2a 2a 20 64 75 72 69 6e  lve, .  ** durin
13c70 67 20 74 68 65 20 66 65 77 20 6e 61 6e 6f 73 65  g the few nanose
13c80 63 6f 6e 64 73 20 74 68 61 74 20 69 74 20 69 73  conds that it is
13c90 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 6c 6f 63   holding the loc
13ca0 6b 2e 20 20 49 6e 20 74 68 61 74 20 63 61 73 65  k.  In that case
13cb0 2c 0a 20 20 2a 2a 20 69 74 20 6d 69 67 68 74 20  ,.  ** it might 
13cc0 74 61 6b 65 20 6c 6f 6e 67 65 72 20 74 68 61 6e  take longer than
13cd0 20 6e 6f 72 6d 61 6c 20 66 6f 72 20 74 68 65 20   normal for the 
13ce0 6c 6f 63 6b 20 74 6f 20 66 72 65 65 2e 0a 20 20  lock to free..  
13cf0 2a 2a 0a 20 20 2a 2a 20 41 66 74 65 72 20 35 20  **.  ** After 5 
13d00 52 45 54 52 59 73 2c 20 77 65 20 62 65 67 69 6e  RETRYs, we begin
13d10 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33   calling sqlite3
13d20 4f 73 53 6c 65 65 70 28 29 2e 20 20 54 68 65 20  OsSleep().  The 
13d30 66 69 72 73 74 20 66 65 77 0a 20 20 2a 2a 20 63  first few.  ** c
13d40 61 6c 6c 73 20 74 6f 20 73 71 6c 69 74 65 33 4f  alls to sqlite3O
13d50 73 53 6c 65 65 70 28 29 20 68 61 76 65 20 61 20  sSleep() have a 
13d60 64 65 6c 61 79 20 6f 66 20 31 20 6d 69 63 72 6f  delay of 1 micro
13d70 73 65 63 6f 6e 64 2e 20 20 52 65 61 6c 6c 79 20  second.  Really 
13d80 74 68 69 73 0a 20 20 2a 2a 20 69 73 20 6d 6f 72  this.  ** is mor
13d90 65 20 6f 66 20 61 20 73 63 68 65 64 75 6c 65 72  e of a scheduler
13da0 20 79 69 65 6c 64 20 74 68 61 6e 20 61 6e 20 61   yield than an a
13db0 63 74 75 61 6c 20 64 65 6c 61 79 2e 20 20 42 75  ctual delay.  Bu
13dc0 74 20 6f 6e 20 74 68 65 20 31 30 74 68 0a 20 20  t on the 10th.  
13dd0 2a 2a 20 61 6e 20 73 75 62 73 65 71 75 65 6e 74  ** an subsequent
13de0 20 72 65 74 72 69 65 73 2c 20 74 68 65 20 64 65   retries, the de
13df0 6c 61 79 73 20 73 74 61 72 74 20 62 65 63 6f 6d  lays start becom
13e00 69 6e 67 20 6c 6f 6e 67 65 72 20 61 6e 64 20 6c  ing longer and l
13e10 6f 6e 67 65 72 2c 20 0a 20 20 2a 2a 20 73 6f 20  onger, .  ** so 
13e20 74 68 61 74 20 6f 6e 20 74 68 65 20 31 30 30 74  that on the 100t
13e30 68 20 28 61 6e 64 20 6c 61 73 74 29 20 52 45 54  h (and last) RET
13e40 52 59 20 77 65 20 64 65 6c 61 79 20 66 6f 72 20  RY we delay for 
13e50 32 31 20 6d 69 6c 6c 69 73 65 63 6f 6e 64 73 2e  21 milliseconds.
13e60 0a 20 20 2a 2a 20 54 68 65 20 74 6f 74 61 6c 20  .  ** The total 
13e70 64 65 6c 61 79 20 74 69 6d 65 20 62 65 66 6f 72  delay time befor
13e80 65 20 67 69 76 69 6e 67 20 75 70 20 69 73 20 6c  e giving up is l
13e90 65 73 73 20 74 68 61 6e 20 31 20 73 65 63 6f 6e  ess than 1 secon
13ea0 64 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 63 6e  d..  */.  if( cn
13eb0 74 3e 35 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e  t>5 ){.    int n
13ec0 44 65 6c 61 79 20 3d 20 31 3b 20 20 20 20 20 20  Delay = 1;      
13ed0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13ee0 2f 2a 20 50 61 75 73 65 20 74 69 6d 65 20 69 6e  /* Pause time in
13ef0 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73 20 2a 2f   microseconds */
13f00 0a 20 20 20 20 69 66 28 20 63 6e 74 3e 31 30 30  .    if( cnt>100
13f10 20 29 7b 0a 20 20 20 20 20 20 56 56 41 5f 4f 4e   ){.      VVA_ON
13f20 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72  LY( pWal->lockEr
13f30 72 6f 72 20 3d 20 31 3b 20 29 0a 20 20 20 20 20  ror = 1; ).     
13f40 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 50   return SQLITE_P
13f50 52 4f 54 4f 43 4f 4c 3b 0a 20 20 20 20 7d 0a 20  ROTOCOL;.    }. 
13f60 20 20 20 69 66 28 20 63 6e 74 3e 3d 31 30 20 29     if( cnt>=10 )
13f70 20 6e 44 65 6c 61 79 20 3d 20 28 63 6e 74 2d 39   nDelay = (cnt-9
13f80 29 2a 32 33 38 3b 20 20 2f 2a 20 4d 61 78 20 64  )*238;  /* Max d
13f90 65 6c 61 79 20 32 31 6d 73 2e 20 54 6f 74 61 6c  elay 21ms. Total
13fa0 20 64 65 6c 61 79 20 39 39 36 6d 73 20 2a 2f 0a   delay 996ms */.
13fb0 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53 6c 65      sqlite3OsSle
13fc0 65 70 28 70 57 61 6c 2d 3e 70 56 66 73 2c 20 6e  ep(pWal->pVfs, n
13fd0 44 65 6c 61 79 29 3b 0a 20 20 7d 0a 0a 20 20 69  Delay);.  }..  i
13fe0 66 28 20 21 75 73 65 57 61 6c 20 29 7b 0a 20 20  f( !useWal ){.  
13ff0 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52    rc = walIndexR
14000 65 61 64 48 64 72 28 70 57 61 6c 2c 20 70 43 68  eadHdr(pWal, pCh
14010 61 6e 67 65 64 29 3b 0a 20 20 20 20 69 66 28 20  anged);.    if( 
14020 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc==SQLITE_BUSY 
14030 29 7b 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 74  ){.      /* If t
14040 68 65 72 65 20 69 73 20 6e 6f 74 20 61 20 72 65  here is not a re
14050 63 6f 76 65 72 79 20 72 75 6e 6e 69 6e 67 20 69  covery running i
14060 6e 20 61 6e 6f 74 68 65 72 20 74 68 72 65 61 64  n another thread
14070 20 6f 72 20 70 72 6f 63 65 73 73 0a 20 20 20 20   or process.    
14080 20 20 2a 2a 20 74 68 65 6e 20 63 6f 6e 76 65 72    ** then conver
14090 74 20 42 55 53 59 20 65 72 72 6f 72 73 20 74 6f  t BUSY errors to
140a0 20 57 41 4c 5f 52 45 54 52 59 2e 20 20 49 66 20   WAL_RETRY.  If 
140b0 72 65 63 6f 76 65 72 79 20 69 73 20 6b 6e 6f 77  recovery is know
140c0 6e 20 74 6f 0a 20 20 20 20 20 20 2a 2a 20 62 65  n to.      ** be
140d0 20 72 75 6e 6e 69 6e 67 2c 20 63 6f 6e 76 65 72   running, conver
140e0 74 20 42 55 53 59 20 74 6f 20 42 55 53 59 5f 52  t BUSY to BUSY_R
140f0 45 43 4f 56 45 52 59 2e 20 20 54 68 65 72 65 20  ECOVERY.  There 
14100 69 73 20 61 20 72 61 63 65 20 68 65 72 65 0a 20  is a race here. 
14110 20 20 20 20 20 2a 2a 20 77 68 69 63 68 20 6d 69       ** which mi
14120 67 68 74 20 63 61 75 73 65 20 57 41 4c 5f 52 45  ght cause WAL_RE
14130 54 52 59 20 74 6f 20 62 65 20 72 65 74 75 72 6e  TRY to be return
14140 65 64 20 65 76 65 6e 20 69 66 20 42 55 53 59 5f  ed even if BUSY_
14150 52 45 43 4f 56 45 52 59 0a 20 20 20 20 20 20 2a  RECOVERY.      *
14160 2a 20 77 6f 75 6c 64 20 62 65 20 74 65 63 68 6e  * would be techn
14170 69 63 61 6c 6c 79 20 63 6f 72 72 65 63 74 2e 20  ically correct. 
14180 20 42 75 74 20 74 68 65 20 72 61 63 65 20 69 73   But the race is
14190 20 62 65 6e 69 67 6e 20 73 69 6e 63 65 20 77 69   benign since wi
141a0 74 68 0a 20 20 20 20 20 20 2a 2a 20 57 41 4c 5f  th.      ** WAL_
141b0 52 45 54 52 59 20 74 68 69 73 20 72 6f 75 74 69  RETRY this routi
141c0 6e 65 20 77 69 6c 6c 20 62 65 20 63 61 6c 6c 65  ne will be calle
141d0 64 20 61 67 61 69 6e 20 61 6e 64 20 77 69 6c 6c  d again and will
141e0 20 70 72 6f 62 61 62 6c 79 20 62 65 0a 20 20 20   probably be.   
141f0 20 20 20 2a 2a 20 72 69 67 68 74 20 6f 6e 20 74     ** right on t
14200 68 65 20 73 65 63 6f 6e 64 20 69 74 65 72 61 74  he second iterat
14210 69 6f 6e 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20  ion..      */.  
14220 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 61 70      if( pWal->ap
14230 57 69 44 61 74 61 5b 30 5d 3d 3d 30 20 29 7b 0a  WiData[0]==0 ){.
14240 20 20 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20          /* This 
14250 62 72 61 6e 63 68 20 69 73 20 74 61 6b 65 6e 20  branch is taken 
14260 77 68 65 6e 20 74 68 65 20 78 53 68 6d 4d 61 70  when the xShmMap
14270 28 29 20 6d 65 74 68 6f 64 20 72 65 74 75 72 6e  () method return
14280 73 20 53 51 4c 49 54 45 5f 42 55 53 59 2e 0a 20  s SQLITE_BUSY.. 
14290 20 20 20 20 20 20 20 2a 2a 20 57 65 20 61 73 73         ** We ass
142a0 75 6d 65 20 74 68 69 73 20 69 73 20 61 20 74 72  ume this is a tr
142b0 61 6e 73 69 65 6e 74 20 63 6f 6e 64 69 74 69 6f  ansient conditio
142c0 6e 2c 20 73 6f 20 72 65 74 75 72 6e 20 57 41 4c  n, so return WAL
142d0 5f 52 45 54 52 59 2e 20 54 68 65 0a 20 20 20 20  _RETRY. The.    
142e0 20 20 20 20 2a 2a 20 78 53 68 6d 4d 61 70 28 29      ** xShmMap()
142f0 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   implementation 
14300 75 73 65 64 20 62 79 20 74 68 65 20 64 65 66 61  used by the defa
14310 75 6c 74 20 75 6e 69 78 20 61 6e 64 20 77 69 6e  ult unix and win
14320 33 32 20 56 46 53 20 0a 20 20 20 20 20 20 20 20  32 VFS .        
14330 2a 2a 20 6d 6f 64 75 6c 65 73 20 6d 61 79 20 72  ** modules may r
14340 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 42 55 53  eturn SQLITE_BUS
14350 59 20 64 75 65 20 74 6f 20 61 20 72 61 63 65 20  Y due to a race 
14360 63 6f 6e 64 69 74 69 6f 6e 20 69 6e 20 74 68 65  condition in the
14370 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 63 6f 64   .        ** cod
14380 65 20 74 68 61 74 20 64 65 74 65 72 6d 69 6e 65  e that determine
14390 73 20 77 68 65 74 68 65 72 20 6f 72 20 6e 6f 74  s whether or not
143a0 20 74 68 65 20 73 68 61 72 65 64 2d 6d 65 6d 6f   the shared-memo
143b0 72 79 20 72 65 67 69 6f 6e 20 0a 20 20 20 20 20  ry region .     
143c0 20 20 20 2a 2a 20 6d 75 73 74 20 62 65 20 7a 65     ** must be ze
143d0 72 6f 65 64 20 62 65 66 6f 72 65 20 74 68 65 20  roed before the 
143e0 72 65 71 75 65 73 74 65 64 20 70 61 67 65 20 69  requested page i
143f0 73 20 72 65 74 75 72 6e 65 64 2e 0a 20 20 20 20  s returned..    
14400 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 72      */.        r
14410 63 20 3d 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20  c = WAL_RETRY;. 
14420 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 53       }else if( S
14430 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20  QLITE_OK==(rc = 
14440 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57  walLockShared(pW
14450 61 6c 2c 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f  al, WAL_RECOVER_
14460 4c 4f 43 4b 29 29 20 29 7b 0a 20 20 20 20 20 20  LOCK)) ){.      
14470 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65    walUnlockShare
14480 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 43 4f  d(pWal, WAL_RECO
14490 56 45 52 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 20  VER_LOCK);.     
144a0 20 20 20 72 63 20 3d 20 57 41 4c 5f 52 45 54 52     rc = WAL_RETR
144b0 59 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69  Y;.      }else i
144c0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  f( rc==SQLITE_BU
144d0 53 59 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  SY ){.        rc
144e0 20 3d 20 53 51 4c 49 54 45 5f 42 55 53 59 5f 52   = SQLITE_BUSY_R
144f0 45 43 4f 56 45 52 59 3b 0a 20 20 20 20 20 20 7d  ECOVERY;.      }
14500 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72  .    }.    if( r
14510 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
14520 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
14530 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70 49  .    }.  }..  pI
14540 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66  nfo = walCkptInf
14550 6f 28 70 57 61 6c 29 3b 0a 20 20 69 66 28 20 21  o(pWal);.  if( !
14560 75 73 65 57 61 6c 20 26 26 20 70 49 6e 66 6f 2d  useWal && pInfo-
14570 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70 57 61 6c  >nBackfill==pWal
14580 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 7b  ->hdr.mxFrame ){
14590 0a 20 20 20 20 2f 2a 20 54 68 65 20 57 41 4c 20  .    /* The WAL 
145a0 68 61 73 20 62 65 65 6e 20 63 6f 6d 70 6c 65 74  has been complet
145b0 65 6c 79 20 62 61 63 6b 66 69 6c 6c 65 64 20 28  ely backfilled (
145c0 6f 72 20 69 74 20 69 73 20 65 6d 70 74 79 29 2e  or it is empty).
145d0 0a 20 20 20 20 2a 2a 20 61 6e 64 20 63 61 6e 20  .    ** and can 
145e0 62 65 20 73 61 66 65 6c 79 20 69 67 6e 6f 72 65  be safely ignore
145f0 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 72 63  d..    */.    rc
14600 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64   = walLockShared
14610 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f  (pWal, WAL_READ_
14620 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20 20 77 61  LOCK(0));.    wa
14630 6c 53 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c  lShmBarrier(pWal
14640 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  );.    if( rc==S
14650 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
14660 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 28 76 6f    if( memcmp((vo
14670 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72  id *)walIndexHdr
14680 28 70 57 61 6c 29 2c 20 26 70 57 61 6c 2d 3e 68  (pWal), &pWal->h
14690 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  dr, sizeof(WalIn
146a0 64 65 78 48 64 72 29 29 20 29 7b 0a 20 20 20 20  dexHdr)) ){.    
146b0 20 20 20 20 2f 2a 20 49 74 20 69 73 20 6e 6f 74      /* It is not
146c0 20 73 61 66 65 20 74 6f 20 61 6c 6c 6f 77 20 74   safe to allow t
146d0 68 65 20 72 65 61 64 65 72 20 74 6f 20 63 6f 6e  he reader to con
146e0 74 69 6e 75 65 20 68 65 72 65 20 69 66 20 66 72  tinue here if fr
146f0 61 6d 65 73 0a 20 20 20 20 20 20 20 20 2a 2a 20  ames.        ** 
14700 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 61 70  may have been ap
14710 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 6c 6f  pended to the lo
14720 67 20 62 65 66 6f 72 65 20 52 45 41 44 5f 4c 4f  g before READ_LO
14730 43 4b 28 30 29 20 77 61 73 20 6f 62 74 61 69 6e  CK(0) was obtain
14740 65 64 2e 0a 20 20 20 20 20 20 20 20 2a 2a 20 57  ed..        ** W
14750 68 65 6e 20 68 6f 6c 64 69 6e 67 20 52 45 41 44  hen holding READ
14760 5f 4c 4f 43 4b 28 30 29 2c 20 74 68 65 20 72 65  _LOCK(0), the re
14770 61 64 65 72 20 69 67 6e 6f 72 65 73 20 74 68 65  ader ignores the
14780 20 65 6e 74 69 72 65 20 6c 6f 67 20 66 69 6c 65   entire log file
14790 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20 77 68 69  ,.        ** whi
147a0 63 68 20 69 6d 70 6c 69 65 73 20 74 68 61 74 20  ch implies that 
147b0 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
147c0 65 20 63 6f 6e 74 61 69 6e 73 20 61 20 74 72 75  e contains a tru
147d0 73 74 77 6f 72 74 68 79 0a 20 20 20 20 20 20 20  stworthy.       
147e0 20 2a 2a 20 73 6e 61 70 73 68 6f 54 2e 20 53 69   ** snapshoT. Si
147f0 6e 63 65 20 68 6f 6c 64 69 6e 67 20 52 45 41 44  nce holding READ
14800 5f 4c 4f 43 4b 28 30 29 20 70 72 65 76 65 6e 74  _LOCK(0) prevent
14810 73 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 20 66  s a checkpoint f
14820 72 6f 6d 0a 20 20 20 20 20 20 20 20 2a 2a 20 68  rom.        ** h
14830 61 70 70 65 6e 69 6e 67 2c 20 74 68 69 73 20 69  appening, this i
14840 73 20 75 73 75 61 6c 6c 79 20 63 6f 72 72 65 63  s usually correc
14850 74 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20  t..        **.  
14860 20 20 20 20 20 20 2a 2a 20 48 6f 77 65 76 65 72        ** However
14870 2c 20 69 66 20 66 72 61 6d 65 73 20 68 61 76 65  , if frames have
14880 20 62 65 65 6e 20 61 70 70 65 6e 64 65 64 20 74   been appended t
14890 6f 20 74 68 65 20 6c 6f 67 20 28 6f 72 20 69 66  o the log (or if
148a0 20 74 68 65 20 6c 6f 67 20 0a 20 20 20 20 20 20   the log .      
148b0 20 20 2a 2a 20 69 73 20 77 72 61 70 70 65 64 20    ** is wrapped 
148c0 61 6e 64 20 77 72 69 74 74 65 6e 20 66 6f 72 20  and written for 
148d0 74 68 61 74 20 6d 61 74 74 65 72 29 20 62 65 66  that matter) bef
148e0 6f 72 65 20 74 68 65 20 52 45 41 44 5f 4c 4f 43  ore the READ_LOC
148f0 4b 28 30 29 0a 20 20 20 20 20 20 20 20 2a 2a 20  K(0).        ** 
14900 69 73 20 6f 62 74 61 69 6e 65 64 2c 20 74 68 61  is obtained, tha
14910 74 20 69 73 20 6e 6f 74 20 6e 65 63 65 73 73 61  t is not necessa
14920 72 69 6c 79 20 74 72 75 65 2e 20 41 20 63 68 65  rily true. A che
14930 63 6b 70 6f 69 6e 74 65 72 20 6d 61 79 0a 20 20  ckpointer may.  
14940 20 20 20 20 20 20 2a 2a 20 68 61 76 65 20 73 74        ** have st
14950 61 72 74 65 64 20 74 6f 20 62 61 63 6b 66 69 6c  arted to backfil
14960 6c 20 74 68 65 20 61 70 70 65 6e 64 65 64 20 66  l the appended f
14970 72 61 6d 65 73 20 62 75 74 20 63 72 61 73 68 65  rames but crashe
14980 64 20 62 65 66 6f 72 65 0a 20 20 20 20 20 20 20  d before.       
14990 20 2a 2a 20 69 74 20 66 69 6e 69 73 68 65 64 2e   ** it finished.
149a0 20 4c 65 61 76 69 6e 67 20 61 20 63 6f 72 72 75   Leaving a corru
149b0 70 74 20 69 6d 61 67 65 20 69 6e 20 74 68 65 20  pt image in the 
149c0 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 20  database file.. 
149d0 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20         */.      
149e0 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65    walUnlockShare
149f0 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  d(pWal, WAL_READ
14a00 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20 20 20  _LOCK(0));.     
14a10 20 20 20 72 65 74 75 72 6e 20 57 41 4c 5f 52 45     return WAL_RE
14a20 54 52 59 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  TRY;.      }.   
14a30 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63     pWal->readLoc
14a40 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 65 74  k = 0;.      ret
14a50 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  urn SQLITE_OK;. 
14a60 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 21     }else if( rc!
14a70 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a  =SQLITE_BUSY ){.
14a80 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
14a90 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
14aa0 20 49 66 20 77 65 20 67 65 74 20 74 68 69 73 20   If we get this 
14ab0 66 61 72 2c 20 69 74 20 6d 65 61 6e 73 20 74 68  far, it means th
14ac0 61 74 20 74 68 65 20 72 65 61 64 65 72 20 77 69  at the reader wi
14ad0 6c 6c 20 77 61 6e 74 20 74 6f 20 75 73 65 0a 20  ll want to use. 
14ae0 20 2a 2a 20 74 68 65 20 57 41 4c 20 74 6f 20 67   ** the WAL to g
14af0 65 74 20 61 74 20 63 6f 6e 74 65 6e 74 20 66 72  et at content fr
14b00 6f 6d 20 72 65 63 65 6e 74 20 63 6f 6d 6d 69 74  om recent commit
14b10 73 2e 20 20 54 68 65 20 6a 6f 62 20 6e 6f 77 20  s.  The job now 
14b20 69 73 0a 20 20 2a 2a 20 74 6f 20 73 65 6c 65 63  is.  ** to selec
14b30 74 20 6f 6e 65 20 6f 66 20 74 68 65 20 61 52 65  t one of the aRe
14b40 61 64 4d 61 72 6b 5b 5d 20 65 6e 74 72 69 65 73  adMark[] entries
14b50 20 74 68 61 74 20 69 73 20 63 6c 6f 73 65 73 74   that is closest
14b60 20 74 6f 0a 20 20 2a 2a 20 62 75 74 20 6e 6f 74   to.  ** but not
14b70 20 65 78 63 65 65 64 69 6e 67 20 70 57 61 6c 2d   exceeding pWal-
14b80 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 61 6e 64  >hdr.mxFrame and
14b90 20 6c 6f 63 6b 20 74 68 61 74 20 65 6e 74 72 79   lock that entry
14ba0 2e 0a 20 20 2a 2f 0a 20 20 6d 78 52 65 61 64 4d  ..  */.  mxReadM
14bb0 61 72 6b 20 3d 20 30 3b 0a 20 20 6d 78 49 20 3d  ark = 0;.  mxI =
14bc0 20 30 3b 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69   0;.  for(i=1; i
14bd0 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b  <WAL_NREADER; i+
14be0 2b 29 7b 0a 20 20 20 20 75 33 32 20 74 68 69 73  +){.    u32 this
14bf0 4d 61 72 6b 20 3d 20 70 49 6e 66 6f 2d 3e 61 52  Mark = pInfo->aR
14c00 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20 20 20 20  eadMark[i];.    
14c10 69 66 28 20 6d 78 52 65 61 64 4d 61 72 6b 3c 3d  if( mxReadMark<=
14c20 74 68 69 73 4d 61 72 6b 20 26 26 20 74 68 69 73  thisMark && this
14c30 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e  Mark<=pWal->hdr.
14c40 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 20  mxFrame ){.     
14c50 20 61 73 73 65 72 74 28 20 74 68 69 73 4d 61 72   assert( thisMar
14c60 6b 21 3d 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f  k!=READMARK_NOT_
14c70 55 53 45 44 20 29 3b 0a 20 20 20 20 20 20 6d 78  USED );.      mx
14c80 52 65 61 64 4d 61 72 6b 20 3d 20 74 68 69 73 4d  ReadMark = thisM
14c90 61 72 6b 3b 0a 20 20 20 20 20 20 6d 78 49 20 3d  ark;.      mxI =
14ca0 20 69 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20   i;.    }.  }.  
14cb0 2f 2a 20 54 68 65 72 65 20 77 61 73 20 6f 6e 63  /* There was onc
14cc0 65 20 61 6e 20 22 69 66 22 20 68 65 72 65 2e 20  e an "if" here. 
14cd0 54 68 65 20 65 78 74 72 61 20 22 7b 22 20 69 73  The extra "{" is
14ce0 20 74 6f 20 70 72 65 73 65 72 76 65 20 69 6e 64   to preserve ind
14cf0 65 6e 74 61 74 69 6f 6e 2e 20 2a 2f 0a 20 20 7b  entation. */.  {
14d00 0a 20 20 20 20 69 66 28 20 28 70 57 61 6c 2d 3e  .    if( (pWal->
14d10 72 65 61 64 4f 6e 6c 79 20 26 20 57 41 4c 5f 53  readOnly & WAL_S
14d20 48 4d 5f 52 44 4f 4e 4c 59 29 3d 3d 30 0a 20 20  HM_RDONLY)==0.  
14d30 20 20 20 26 26 20 28 6d 78 52 65 61 64 4d 61 72     && (mxReadMar
14d40 6b 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  k<pWal->hdr.mxFr
14d50 61 6d 65 20 7c 7c 20 6d 78 49 3d 3d 30 29 0a 20  ame || mxI==0). 
14d60 20 20 20 29 7b 0a 20 20 20 20 20 20 66 6f 72 28     ){.      for(
14d70 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44  i=1; i<WAL_NREAD
14d80 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ER; i++){.      
14d90 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78    rc = walLockEx
14da0 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
14db0 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20  L_READ_LOCK(i), 
14dc0 31 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  1);.        if( 
14dd0 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
14de0 0a 20 20 20 20 20 20 20 20 20 20 6d 78 52 65 61  .          mxRea
14df0 64 4d 61 72 6b 20 3d 20 70 49 6e 66 6f 2d 3e 61  dMark = pInfo->a
14e00 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 70 57  ReadMark[i] = pW
14e10 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b  al->hdr.mxFrame;
14e20 0a 20 20 20 20 20 20 20 20 20 20 6d 78 49 20 3d  .          mxI =
14e30 20 69 3b 0a 20 20 20 20 20 20 20 20 20 20 77 61   i;.          wa
14e40 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65  lUnlockExclusive
14e50 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f  (pWal, WAL_READ_
14e60 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20  LOCK(i), 1);.   
14e70 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
14e80 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
14e90 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc!=SQLITE_BUSY 
14ea0 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65 74  ){.          ret
14eb0 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 20 20  urn rc;.        
14ec0 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  }.      }.    }.
14ed0 20 20 20 20 69 66 28 20 6d 78 49 3d 3d 30 20 29      if( mxI==0 )
14ee0 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  {.      assert( 
14ef0 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc==SQLITE_BUSY 
14f00 7c 7c 20 28 70 57 61 6c 2d 3e 72 65 61 64 4f 6e  || (pWal->readOn
14f10 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  ly & WAL_SHM_RDO
14f20 4e 4c 59 29 21 3d 30 20 29 3b 0a 20 20 20 20 20  NLY)!=0 );.     
14f30 20 72 65 74 75 72 6e 20 72 63 3d 3d 53 51 4c 49   return rc==SQLI
14f40 54 45 5f 42 55 53 59 20 3f 20 57 41 4c 5f 52 45  TE_BUSY ? WAL_RE
14f50 54 52 59 20 3a 20 53 51 4c 49 54 45 5f 52 45 41  TRY : SQLITE_REA
14f60 44 4f 4e 4c 59 5f 43 41 4e 54 4c 4f 43 4b 3b 0a  DONLY_CANTLOCK;.
14f70 20 20 20 20 7d 0a 0a 20 20 20 20 72 63 20 3d 20      }..    rc = 
14f80 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57  walLockShared(pW
14f90 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  al, WAL_READ_LOC
14fa0 4b 28 6d 78 49 29 29 3b 0a 20 20 20 20 69 66 28  K(mxI));.    if(
14fb0 20 72 63 20 29 7b 0a 20 20 20 20 20 20 72 65 74   rc ){.      ret
14fc0 75 72 6e 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42  urn rc==SQLITE_B
14fd0 55 53 59 20 3f 20 57 41 4c 5f 52 45 54 52 59 20  USY ? WAL_RETRY 
14fe0 3a 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20  : rc;.    }.    
14ff0 2f 2a 20 4e 6f 77 20 74 68 61 74 20 74 68 65 20  /* Now that the 
15000 72 65 61 64 2d 6c 6f 63 6b 20 68 61 73 20 62 65  read-lock has be
15010 65 6e 20 6f 62 74 61 69 6e 65 64 2c 20 63 68 65  en obtained, che
15020 63 6b 20 74 68 61 74 20 6e 65 69 74 68 65 72 20  ck that neither 
15030 74 68 65 0a 20 20 20 20 2a 2a 20 76 61 6c 75 65  the.    ** value
15040 20 69 6e 20 74 68 65 20 61 52 65 61 64 4d 61 72   in the aReadMar
15050 6b 5b 5d 20 61 72 72 61 79 20 6f 72 20 74 68 65  k[] array or the
15060 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
15070 20 77 61 6c 2d 69 6e 64 65 78 0a 20 20 20 20 2a   wal-index.    *
15080 2a 20 68 65 61 64 65 72 20 68 61 76 65 20 63 68  * header have ch
15090 61 6e 67 65 64 2e 0a 20 20 20 20 2a 2a 0a 20 20  anged..    **.  
150a0 20 20 2a 2a 20 49 74 20 69 73 20 6e 65 63 65 73    ** It is neces
150b0 73 61 72 79 20 74 6f 20 63 68 65 63 6b 20 74 68  sary to check th
150c0 61 74 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  at the wal-index
150d0 20 68 65 61 64 65 72 20 64 69 64 20 6e 6f 74 20   header did not 
150e0 63 68 61 6e 67 65 0a 20 20 20 20 2a 2a 20 62 65  change.    ** be
150f0 74 77 65 65 6e 20 74 68 65 20 74 69 6d 65 20 69  tween the time i
15100 74 20 77 61 73 20 72 65 61 64 20 61 6e 64 20 77  t was read and w
15110 68 65 6e 20 74 68 65 20 73 68 61 72 65 64 2d 6c  hen the shared-l
15120 6f 63 6b 20 77 61 73 20 6f 62 74 61 69 6e 65 64  ock was obtained
15130 0a 20 20 20 20 2a 2a 20 6f 6e 20 57 41 4c 5f 52  .    ** on WAL_R
15140 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 20 77 61  EAD_LOCK(mxI) wa
15150 73 20 6f 62 74 61 69 6e 65 64 20 74 6f 20 61 63  s obtained to ac
15160 63 6f 75 6e 74 20 66 6f 72 20 74 68 65 20 70 6f  count for the po
15170 73 73 69 62 69 6c 69 74 79 0a 20 20 20 20 2a 2a  ssibility.    **
15180 20 74 68 61 74 20 74 68 65 20 6c 6f 67 20 66 69   that the log fi
15190 6c 65 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e  le may have been
151a0 20 77 72 61 70 70 65 64 20 62 79 20 61 20 77 72   wrapped by a wr
151b0 69 74 65 72 2c 20 6f 72 20 74 68 61 74 20 66 72  iter, or that fr
151c0 61 6d 65 73 0a 20 20 20 20 2a 2a 20 74 68 61 74  ames.    ** that
151d0 20 6f 63 63 75 72 20 6c 61 74 65 72 20 69 6e 20   occur later in 
151e0 74 68 65 20 6c 6f 67 20 74 68 61 6e 20 70 57 61  the log than pWa
151f0 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 6d  l->hdr.mxFrame m
15200 61 79 20 68 61 76 65 20 62 65 65 6e 0a 20 20 20  ay have been.   
15210 20 2a 2a 20 63 6f 70 69 65 64 20 69 6e 74 6f 20   ** copied into 
15220 74 68 65 20 64 61 74 61 62 61 73 65 20 62 79 20  the database by 
15230 61 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 2e 20  a checkpointer. 
15240 49 66 20 65 69 74 68 65 72 20 6f 66 20 74 68 65  If either of the
15250 73 65 20 74 68 69 6e 67 73 0a 20 20 20 20 2a 2a  se things.    **
15260 20 68 61 70 70 65 6e 65 64 2c 20 74 68 65 6e 20   happened, then 
15270 72 65 61 64 69 6e 67 20 74 68 65 20 64 61 74 61  reading the data
15280 62 61 73 65 20 77 69 74 68 20 74 68 65 20 63 75  base with the cu
15290 72 72 65 6e 74 20 76 61 6c 75 65 20 6f 66 0a 20  rrent value of. 
152a0 20 20 20 2a 2a 20 70 57 61 6c 2d 3e 68 64 72 2e     ** pWal->hdr.
152b0 6d 78 46 72 61 6d 65 20 72 69 73 6b 73 20 72 65  mxFrame risks re
152c0 61 64 69 6e 67 20 61 20 63 6f 72 72 75 70 74 65  ading a corrupte
152d0 64 20 73 6e 61 70 73 68 6f 74 2e 20 53 6f 2c 20  d snapshot. So, 
152e0 72 65 74 72 79 0a 20 20 20 20 2a 2a 20 69 6e 73  retry.    ** ins
152f0 74 65 61 64 2e 0a 20 20 20 20 2a 2a 0a 20 20 20  tead..    **.   
15300 20 2a 2a 20 54 68 69 73 20 64 6f 65 73 20 6e 6f   ** This does no
15310 74 20 67 75 61 72 61 6e 74 65 65 20 74 68 61 74  t guarantee that
15320 20 74 68 65 20 63 6f 70 79 20 6f 66 20 74 68 65   the copy of the
15330 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
15340 72 20 69 73 20 75 70 20 74 6f 0a 20 20 20 20 2a  r is up to.    *
15350 2a 20 64 61 74 65 20 62 65 66 6f 72 65 20 70 72  * date before pr
15360 6f 63 65 65 64 69 6e 67 2e 20 54 68 61 74 20 77  oceeding. That w
15370 6f 75 6c 64 20 6e 6f 74 20 62 65 20 70 6f 73 73  ould not be poss
15380 69 62 6c 65 20 77 69 74 68 6f 75 74 20 73 6f 6d  ible without som
15390 65 68 6f 77 0a 20 20 20 20 2a 2a 20 62 6c 6f 63  ehow.    ** bloc
153a0 6b 69 6e 67 20 77 72 69 74 65 72 73 2e 20 49 74  king writers. It
153b0 20 6f 6e 6c 79 20 67 75 61 72 61 6e 74 65 65 73   only guarantees
153c0 20 74 68 61 74 20 61 20 64 61 6e 67 65 72 6f 75   that a dangerou
153d0 73 20 63 68 65 63 6b 70 6f 69 6e 74 20 6f 72 20  s checkpoint or 
153e0 0a 20 20 20 20 2a 2a 20 6c 6f 67 2d 77 72 61 70  .    ** log-wrap
153f0 20 28 65 69 74 68 65 72 20 6f 66 20 77 68 69 63   (either of whic
15400 68 20 77 6f 75 6c 64 20 72 65 71 75 69 72 65 20  h would require 
15410 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63  an exclusive loc
15420 6b 20 6f 6e 0a 20 20 20 20 2a 2a 20 57 41 4c 5f  k on.    ** WAL_
15430 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 20  READ_LOCK(mxI)) 
15440 68 61 73 20 6e 6f 74 20 6f 63 63 75 72 72 65 64  has not occurred
15450 20 73 69 6e 63 65 20 74 68 65 20 73 6e 61 70 73   since the snaps
15460 68 6f 74 20 77 61 73 20 76 61 6c 69 64 2e 0a 20  hot was valid.. 
15470 20 20 20 2a 2f 0a 20 20 20 20 77 61 6c 53 68 6d     */.    walShm
15480 42 61 72 72 69 65 72 28 70 57 61 6c 29 3b 0a 20  Barrier(pWal);. 
15490 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 61 52     if( pInfo->aR
154a0 65 61 64 4d 61 72 6b 5b 6d 78 49 5d 21 3d 6d 78  eadMark[mxI]!=mx
154b0 52 65 61 64 4d 61 72 6b 0a 20 20 20 20 20 7c 7c  ReadMark.     ||
154c0 20 6d 65 6d 63 6d 70 28 28 76 6f 69 64 20 2a 29   memcmp((void *)
154d0 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c  walIndexHdr(pWal
154e0 29 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73  ), &pWal->hdr, s
154f0 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64  izeof(WalIndexHd
15500 72 29 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20  r)).    ){.     
15510 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64   walUnlockShared
15520 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f  (pWal, WAL_READ_
15530 4c 4f 43 4b 28 6d 78 49 29 29 3b 0a 20 20 20 20  LOCK(mxI));.    
15540 20 20 72 65 74 75 72 6e 20 57 41 4c 5f 52 45 54    return WAL_RET
15550 52 59 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  RY;.    }else{. 
15560 20 20 20 20 20 61 73 73 65 72 74 28 20 6d 78 52       assert( mxR
15570 65 61 64 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e 68  eadMark<=pWal->h
15580 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20  dr.mxFrame );.  
15590 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f      pWal->readLo
155a0 63 6b 20 3d 20 28 69 31 36 29 6d 78 49 3b 0a 20  ck = (i16)mxI;. 
155b0 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
155c0 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42  n rc;.}../*.** B
155d0 65 67 69 6e 20 61 20 72 65 61 64 20 74 72 61 6e  egin a read tran
155e0 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20 64  saction on the d
155f0 61 74 61 62 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 54  atabase..**.** T
15600 68 69 73 20 72 6f 75 74 69 6e 65 20 75 73 65 64  his routine used
15610 20 74 6f 20 62 65 20 63 61 6c 6c 65 64 20 73 71   to be called sq
15620 6c 69 74 65 33 4f 70 65 6e 53 6e 61 70 73 68 6f  lite3OpenSnapsho
15630 74 28 29 20 61 6e 64 20 77 69 74 68 20 67 6f 6f  t() and with goo
15640 64 20 72 65 61 73 6f 6e 3a 0a 2a 2a 20 69 74 20  d reason:.** it 
15650 74 61 6b 65 73 20 61 20 73 6e 61 70 73 68 6f 74  takes a snapshot
15660 20 6f 66 20 74 68 65 20 73 74 61 74 65 20 6f 66   of the state of
15670 20 74 68 65 20 57 41 4c 20 61 6e 64 20 77 61 6c   the WAL and wal
15680 2d 69 6e 64 65 78 20 66 6f 72 20 74 68 65 20 63  -index for the c
15690 75 72 72 65 6e 74 0a 2a 2a 20 69 6e 73 74 61 6e  urrent.** instan
156a0 74 20 69 6e 20 74 69 6d 65 2e 20 20 54 68 65 20  t in time.  The 
156b0 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 20 77  current thread w
156c0 69 6c 6c 20 63 6f 6e 74 69 6e 75 65 20 74 6f 20  ill continue to 
156d0 75 73 65 20 74 68 69 73 20 73 6e 61 70 73 68 6f  use this snapsho
156e0 74 2e 0a 2a 2a 20 4f 74 68 65 72 20 74 68 72 65  t..** Other thre
156f0 61 64 73 20 6d 69 67 68 74 20 61 70 70 65 6e 64  ads might append
15700 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20 74 6f 20   new content to 
15710 74 68 65 20 57 41 4c 20 61 6e 64 20 77 61 6c 2d  the WAL and wal-
15720 69 6e 64 65 78 20 62 75 74 0a 2a 2a 20 74 68 61  index but.** tha
15730 74 20 65 78 74 72 61 20 63 6f 6e 74 65 6e 74 20  t extra content 
15740 69 73 20 69 67 6e 6f 72 65 64 20 62 79 20 74 68  is ignored by th
15750 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64  e current thread
15760 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 64  ..**.** If the d
15770 61 74 61 62 61 73 65 20 63 6f 6e 74 65 6e 74 73  atabase contents
15780 20 68 61 76 65 20 63 68 61 6e 67 65 73 20 73 69   have changes si
15790 6e 63 65 20 74 68 65 20 70 72 65 76 69 6f 75 73  nce the previous
157a0 20 72 65 61 64 0a 2a 2a 20 74 72 61 6e 73 61 63   read.** transac
157b0 74 69 6f 6e 2c 20 74 68 65 6e 20 2a 70 43 68 61  tion, then *pCha
157c0 6e 67 65 64 20 69 73 20 73 65 74 20 74 6f 20 31  nged is set to 1
157d0 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
157e0 67 2e 20 20 54 68 65 0a 2a 2a 20 50 61 67 65 72  g.  The.** Pager
157f0 20 6c 61 79 65 72 20 77 69 6c 6c 20 75 73 65 20   layer will use 
15800 74 68 69 73 20 74 6f 20 6b 6e 6f 77 20 74 68 61  this to know tha
15810 74 20 69 73 20 63 61 63 68 65 20 69 73 20 73 74  t is cache is st
15820 61 6c 65 20 61 6e 64 0a 2a 2a 20 6e 65 65 64 73  ale and.** needs
15830 20 74 6f 20 62 65 20 66 6c 75 73 68 65 64 2e 0a   to be flushed..
15840 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
15850 6c 42 65 67 69 6e 52 65 61 64 54 72 61 6e 73 61  lBeginReadTransa
15860 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 2c  ction(Wal *pWal,
15870 20 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 29 7b   int *pChanged){
15880 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
15890 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
158a0 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
158b0 65 20 2a 2f 0a 20 20 69 6e 74 20 63 6e 74 20 3d  e */.  int cnt =
158c0 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
158d0 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
158e0 20 6f 66 20 54 72 79 42 65 67 69 6e 52 65 61 64   of TryBeginRead
158f0 20 61 74 74 65 6d 70 74 73 20 2a 2f 0a 0a 20 20   attempts */..  
15900 64 6f 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c  do{.    rc = wal
15910 54 72 79 42 65 67 69 6e 52 65 61 64 28 70 57 61  TryBeginRead(pWa
15920 6c 2c 20 70 43 68 61 6e 67 65 64 2c 20 30 2c 20  l, pChanged, 0, 
15930 2b 2b 63 6e 74 29 3b 0a 20 20 7d 77 68 69 6c 65  ++cnt);.  }while
15940 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54 52 59 20  ( rc==WAL_RETRY 
15950 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 28  );.  testcase( (
15960 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49 54 45  rc&0xff)==SQLITE
15970 5f 42 55 53 59 20 29 3b 0a 20 20 74 65 73 74 63  _BUSY );.  testc
15980 61 73 65 28 20 28 72 63 26 30 78 66 66 29 3d 3d  ase( (rc&0xff)==
15990 53 51 4c 49 54 45 5f 49 4f 45 52 52 20 29 3b 0a  SQLITE_IOERR );.
159a0 20 20 74 65 73 74 63 61 73 65 28 20 72 63 3d 3d    testcase( rc==
159b0 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 20  SQLITE_PROTOCOL 
159c0 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 72  );.  testcase( r
159d0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c==SQLITE_OK );.
159e0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
159f0 2f 2a 0a 2a 2a 20 46 69 6e 69 73 68 20 77 69 74  /*.** Finish wit
15a00 68 20 61 20 72 65 61 64 20 74 72 61 6e 73 61 63  h a read transac
15a10 74 69 6f 6e 2e 20 20 41 6c 6c 20 74 68 69 73 20  tion.  All this 
15a20 64 6f 65 73 20 69 73 20 72 65 6c 65 61 73 65 20  does is release 
15a30 74 68 65 0a 2a 2a 20 72 65 61 64 2d 6c 6f 63 6b  the.** read-lock
15a40 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
15a50 33 57 61 6c 45 6e 64 52 65 61 64 54 72 61 6e 73  3WalEndReadTrans
15a60 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c  action(Wal *pWal
15a70 29 7b 0a 20 20 73 71 6c 69 74 65 33 57 61 6c 45  ){.  sqlite3WalE
15a80 6e 64 57 72 69 74 65 54 72 61 6e 73 61 63 74 69  ndWriteTransacti
15a90 6f 6e 28 70 57 61 6c 29 3b 0a 20 20 69 66 28 20  on(pWal);.  if( 
15aa0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
15ab0 30 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f  0 ){.    walUnlo
15ac0 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
15ad0 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61  AL_READ_LOCK(pWa
15ae0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 3b 0a 20  l->readLock));. 
15af0 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63     pWal->readLoc
15b00 6b 20 3d 20 2d 31 3b 0a 20 20 7d 0a 7d 0a 0a 2f  k = -1;.  }.}../
15b10 2a 0a 2a 2a 20 53 65 61 72 63 68 20 74 68 65 20  *.** Search the 
15b20 77 61 6c 20 66 69 6c 65 20 66 6f 72 20 70 61 67  wal file for pag
15b30 65 20 70 67 6e 6f 2e 20 49 66 20 66 6f 75 6e 64  e pgno. If found
15b40 2c 20 73 65 74 20 2a 70 69 52 65 61 64 20 74 6f  , set *piRead to
15b50 20 74 68 65 20 66 72 61 6d 65 20 74 68 61 74 0a   the frame that.
15b60 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  ** contains the 
15b70 70 61 67 65 2e 20 4f 74 68 65 72 77 69 73 65 2c  page. Otherwise,
15b80 20 69 66 20 70 67 6e 6f 20 69 73 20 6e 6f 74 20   if pgno is not 
15b90 69 6e 20 74 68 65 20 77 61 6c 20 66 69 6c 65 2c  in the wal file,
15ba0 20 73 65 74 20 2a 70 69 52 65 61 64 0a 2a 2a 20   set *piRead.** 
15bb0 74 6f 20 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20 52  to zero..**.** R
15bc0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20  eturn SQLITE_OK 
15bd0 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f  if successful, o
15be0 72 20 61 6e 20 65 72 72 6f 72 20 63 6f 64 65 20  r an error code 
15bf0 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  if an error occu
15c00 72 73 2e 20 49 66 20 61 6e 0a 2a 2a 20 65 72 72  rs. If an.** err
15c10 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c 20 74  or does occur, t
15c20 68 65 20 66 69 6e 61 6c 20 76 61 6c 75 65 20 6f  he final value o
15c30 66 20 2a 70 69 52 65 61 64 20 69 73 20 75 6e 64  f *piRead is und
15c40 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73  efined..*/.int s
15c50 71 6c 69 74 65 33 57 61 6c 46 69 6e 64 46 72 61  qlite3WalFindFra
15c60 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c  me(.  Wal *pWal,
15c70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15c80 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 68 61 6e        /* WAL han
15c90 64 6c 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70 67  dle */.  Pgno pg
15ca0 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  no,             
15cb0 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
15cc0 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72  base page number
15cd0 20 74 6f 20 72 65 61 64 20 64 61 74 61 20 66 6f   to read data fo
15ce0 72 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 52 65  r */.  u32 *piRe
15cf0 61 64 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ad              
15d00 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 46         /* OUT: F
15d10 72 61 6d 65 20 6e 75 6d 62 65 72 20 28 6f 72 20  rame number (or 
15d20 7a 65 72 6f 29 20 2a 2f 0a 29 7b 0a 20 20 75 33  zero) */.){.  u3
15d30 32 20 69 52 65 61 64 20 3d 20 30 3b 20 20 20 20  2 iRead = 0;    
15d40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
15d50 20 49 66 20 21 3d 30 2c 20 57 41 4c 20 66 72 61   If !=0, WAL fra
15d60 6d 65 20 74 6f 20 72 65 74 75 72 6e 20 64 61 74  me to return dat
15d70 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 75 33 32 20  a from */.  u32 
15d80 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d 3e 68 64  iLast = pWal->hd
15d90 72 2e 6d 78 46 72 61 6d 65 3b 20 20 2f 2a 20 4c  r.mxFrame;  /* L
15da0 61 73 74 20 70 61 67 65 20 69 6e 20 57 41 4c 20  ast page in WAL 
15db0 66 6f 72 20 74 68 69 73 20 72 65 61 64 65 72 20  for this reader 
15dc0 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73 68 3b 20  */.  int iHash; 
15dd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15de0 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
15df0 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20 4e 20 68  loop through N h
15e00 61 73 68 20 74 61 62 6c 65 73 20 2a 2f 0a 0a 20  ash tables */.. 
15e10 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65   /* This routine
15e20 20 69 73 20 6f 6e 6c 79 20 62 65 20 63 61 6c 6c   is only be call
15e30 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 61  ed from within a
15e40 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
15e50 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  n. */.  assert( 
15e60 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
15e70 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45  0 || pWal->lockE
15e80 72 72 6f 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66  rror );..  /* If
15e90 20 74 68 65 20 22 6c 61 73 74 20 70 61 67 65 22   the "last page"
15ea0 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20 77 61   field of the wa
15eb0 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 73  l-index header s
15ec0 6e 61 70 73 68 6f 74 20 69 73 20 30 2c 20 74 68  napshot is 0, th
15ed0 65 6e 0a 20 20 2a 2a 20 6e 6f 20 64 61 74 61 20  en.  ** no data 
15ee0 77 69 6c 6c 20 62 65 20 72 65 61 64 20 66 72 6f  will be read fro
15ef0 6d 20 74 68 65 20 77 61 6c 20 75 6e 64 65 72 20  m the wal under 
15f00 61 6e 79 20 63 69 72 63 75 6d 73 74 61 6e 63 65  any circumstance
15f10 73 2e 20 52 65 74 75 72 6e 20 65 61 72 6c 79 0a  s. Return early.
15f20 20 20 2a 2a 20 69 6e 20 74 68 69 73 20 63 61 73    ** in this cas
15f30 65 20 61 73 20 61 6e 20 6f 70 74 69 6d 69 7a 61  e as an optimiza
15f40 74 69 6f 6e 2e 20 20 4c 69 6b 65 77 69 73 65 2c  tion.  Likewise,
15f50 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f   if pWal->readLo
15f60 63 6b 3d 3d 30 2c 20 0a 20 20 2a 2a 20 74 68 65  ck==0, .  ** the
15f70 6e 20 74 68 65 20 57 41 4c 20 69 73 20 69 67 6e  n the WAL is ign
15f80 6f 72 65 64 20 62 79 20 74 68 65 20 72 65 61 64  ored by the read
15f90 65 72 20 73 6f 20 72 65 74 75 72 6e 20 65 61 72  er so return ear
15fa0 6c 79 2c 20 61 73 20 69 66 20 74 68 65 20 0a 20  ly, as if the . 
15fb0 20 2a 2a 20 57 41 4c 20 77 65 72 65 20 65 6d 70   ** WAL were emp
15fc0 74 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69  ty..  */.  if( i
15fd0 4c 61 73 74 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d  Last==0 || pWal-
15fe0 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20 29 7b 0a  >readLock==0 ){.
15ff0 20 20 20 20 2a 70 69 52 65 61 64 20 3d 20 30 3b      *piRead = 0;
16000 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
16010 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  TE_OK;.  }..  /*
16020 20 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68   Search the hash
16030 20 74 61 62 6c 65 20 6f 72 20 74 61 62 6c 65 73   table or tables
16040 20 66 6f 72 20 61 6e 20 65 6e 74 72 79 20 6d 61   for an entry ma
16050 74 63 68 69 6e 67 20 70 61 67 65 20 6e 75 6d 62  tching page numb
16060 65 72 0a 20 20 2a 2a 20 70 67 6e 6f 2e 20 45 61  er.  ** pgno. Ea
16070 63 68 20 69 74 65 72 61 74 69 6f 6e 20 6f 66 20  ch iteration of 
16080 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 66 6f  the following fo
16090 72 28 29 20 6c 6f 6f 70 20 73 65 61 72 63 68 65  r() loop searche
160a0 73 20 6f 6e 65 0a 20 20 2a 2a 20 68 61 73 68 20  s one.  ** hash 
160b0 74 61 62 6c 65 20 28 65 61 63 68 20 68 61 73 68  table (each hash
160c0 20 74 61 62 6c 65 20 69 6e 64 65 78 65 73 20 75   table indexes u
160d0 70 20 74 6f 20 48 41 53 48 54 41 42 4c 45 5f 4e  p to HASHTABLE_N
160e0 50 41 47 45 20 66 72 61 6d 65 73 29 2e 0a 20 20  PAGE frames)..  
160f0 2a 2a 0a 20 20 2a 2a 20 54 68 69 73 20 63 6f 64  **.  ** This cod
16100 65 20 6d 69 67 68 74 20 72 75 6e 20 63 6f 6e 63  e might run conc
16110 75 72 72 65 6e 74 6c 79 20 74 6f 20 74 68 65 20  urrently to the 
16120 63 6f 64 65 20 69 6e 20 77 61 6c 49 6e 64 65 78  code in walIndex
16130 41 70 70 65 6e 64 28 29 0a 20 20 2a 2a 20 74 68  Append().  ** th
16140 61 74 20 61 64 64 73 20 65 6e 74 72 69 65 73 20  at adds entries 
16150 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  to the wal-index
16160 20 28 61 6e 64 20 70 6f 73 73 69 62 6c 79 20 74   (and possibly t
16170 6f 20 74 68 69 73 20 68 61 73 68 20 0a 20 20 2a  o this hash .  *
16180 2a 20 74 61 62 6c 65 29 2e 20 54 68 69 73 20 6d  * table). This m
16190 65 61 6e 73 20 74 68 65 20 76 61 6c 75 65 20 6a  eans the value j
161a0 75 73 74 20 72 65 61 64 20 66 72 6f 6d 20 74 68  ust read from th
161b0 65 20 68 61 73 68 20 0a 20 20 2a 2a 20 73 6c 6f  e hash .  ** slo
161c0 74 20 28 61 48 61 73 68 5b 69 4b 65 79 5d 29 20  t (aHash[iKey]) 
161d0 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 61 64  may have been ad
161e0 64 65 64 20 62 65 66 6f 72 65 20 6f 72 20 61 66  ded before or af
161f0 74 65 72 20 74 68 65 20 0a 20 20 2a 2a 20 63 75  ter the .  ** cu
16200 72 72 65 6e 74 20 72 65 61 64 20 74 72 61 6e 73  rrent read trans
16210 61 63 74 69 6f 6e 20 77 61 73 20 6f 70 65 6e 65  action was opene
16220 64 2e 20 56 61 6c 75 65 73 20 61 64 64 65 64 20  d. Values added 
16230 61 66 74 65 72 20 74 68 65 0a 20 20 2a 2a 20 72  after the.  ** r
16240 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
16250 77 61 73 20 6f 70 65 6e 65 64 20 6d 61 79 20 68  was opened may h
16260 61 76 65 20 62 65 65 6e 20 77 72 69 74 74 65 6e  ave been written
16270 20 69 6e 63 6f 72 72 65 63 74 6c 79 20 2d 0a 20   incorrectly -. 
16280 20 2a 2a 20 69 2e 65 2e 20 74 68 65 73 65 20 73   ** i.e. these s
16290 6c 6f 74 73 20 6d 61 79 20 63 6f 6e 74 61 69 6e  lots may contain
162a0 20 67 61 72 62 61 67 65 20 64 61 74 61 2e 20 48   garbage data. H
162b0 6f 77 65 76 65 72 2c 20 77 65 20 61 73 73 75 6d  owever, we assum
162c0 65 0a 20 20 2a 2a 20 74 68 61 74 20 61 6e 79 20  e.  ** that any 
162d0 73 6c 6f 74 73 20 77 72 69 74 74 65 6e 20 62 65  slots written be
162e0 66 6f 72 65 20 74 68 65 20 63 75 72 72 65 6e 74  fore the current
162f0 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
16300 6e 20 77 61 73 0a 20 20 2a 2a 20 6f 70 65 6e 65  n was.  ** opene
16310 64 20 72 65 6d 61 69 6e 20 75 6e 6d 6f 64 69 66  d remain unmodif
16320 69 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 46  ied..  **.  ** F
16330 6f 72 20 74 68 65 20 72 65 61 73 6f 6e 73 20 61  or the reasons a
16340 62 6f 76 65 2c 20 74 68 65 20 69 66 28 2e 2e 2e  bove, the if(...
16350 29 20 63 6f 6e 64 69 74 69 6f 6e 20 66 65 61 74  ) condition feat
16360 75 72 65 64 20 69 6e 20 74 68 65 20 69 6e 6e 65  ured in the inne
16370 72 0a 20 20 2a 2a 20 6c 6f 6f 70 20 6f 66 20 74  r.  ** loop of t
16380 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62 6c 6f  he following blo
16390 63 6b 20 69 73 20 6d 6f 72 65 20 73 74 72 69 6e  ck is more strin
163a0 67 65 6e 74 20 74 68 61 74 20 77 6f 75 6c 64 20  gent that would 
163b0 62 65 20 72 65 71 75 69 72 65 64 20 0a 20 20 2a  be required .  *
163c0 2a 20 69 66 20 77 65 20 68 61 64 20 65 78 63 6c  * if we had excl
163d0 75 73 69 76 65 20 61 63 63 65 73 73 20 74 6f 20  usive access to 
163e0 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65 3a 0a  the hash-table:.
163f0 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 28 61 50 67    **.  **   (aPg
16400 6e 6f 5b 69 46 72 61 6d 65 5d 3d 3d 70 67 6e 6f  no[iFrame]==pgno
16410 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69  ): .  **     Thi
16420 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74  s condition filt
16430 65 72 73 20 6f 75 74 20 6e 6f 72 6d 61 6c 20 68  ers out normal h
16440 61 73 68 2d 74 61 62 6c 65 20 63 6f 6c 6c 69 73  ash-table collis
16450 69 6f 6e 73 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20  ions..  **.  ** 
16460 20 20 28 69 46 72 61 6d 65 3c 3d 69 4c 61 73 74    (iFrame<=iLast
16470 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69  ): .  **     Thi
16480 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74  s condition filt
16490 65 72 73 20 6f 75 74 20 65 6e 74 72 69 65 73 20  ers out entries 
164a0 74 68 61 74 20 77 65 72 65 20 61 64 64 65 64 20  that were added 
164b0 74 6f 20 74 68 65 20 68 61 73 68 0a 20 20 2a 2a  to the hash.  **
164c0 20 20 20 20 20 74 61 62 6c 65 20 61 66 74 65 72       table after
164d0 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 65 61   the current rea
164e0 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e 20 68 61  d-transaction ha
164f0 64 20 73 74 61 72 74 65 64 2e 0a 20 20 2a 2f 0a  d started..  */.
16500 20 20 66 6f 72 28 69 48 61 73 68 3d 77 61 6c 46    for(iHash=walF
16510 72 61 6d 65 50 61 67 65 28 69 4c 61 73 74 29 3b  ramePage(iLast);
16520 20 69 48 61 73 68 3e 3d 30 20 26 26 20 69 52 65   iHash>=0 && iRe
16530 61 64 3d 3d 30 3b 20 69 48 61 73 68 2d 2d 29 7b  ad==0; iHash--){
16540 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 68 74  .    volatile ht
16550 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b 20 20 20  _slot *aHash;   
16560 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
16570 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20   hash table */. 
16580 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20     volatile u32 
16590 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20 20 20 20  *aPgno;         
165a0 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 61   /* Pointer to a
165b0 72 72 61 79 20 6f 66 20 70 61 67 65 20 6e 75 6d  rray of page num
165c0 62 65 72 73 20 2a 2f 0a 20 20 20 20 75 33 32 20  bers */.    u32 
165d0 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20 20  iZero;          
165e0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72 61            /* Fra
165f0 6d 65 20 6e 75 6d 62 65 72 20 63 6f 72 72 65 73  me number corres
16600 70 6f 6e 64 69 6e 67 20 74 6f 20 61 50 67 6e 6f  ponding to aPgno
16610 5b 30 5d 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69  [0] */.    int i
16620 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  Key;            
16630 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68           /* Hash
16640 20 73 6c 6f 74 20 69 6e 64 65 78 20 2a 2f 0a 20   slot index */. 
16650 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69 64 65 3b     int nCollide;
16660 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16670 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 68 61   /* Number of ha
16680 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73 20 72 65  sh collisions re
16690 6d 61 69 6e 69 6e 67 20 2a 2f 0a 20 20 20 20 69  maining */.    i
166a0 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
166b0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
166c0 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 0a 20  Error code */.. 
166d0 20 20 20 72 63 20 3d 20 77 61 6c 48 61 73 68 47     rc = walHashG
166e0 65 74 28 70 57 61 6c 2c 20 69 48 61 73 68 2c 20  et(pWal, iHash, 
166f0 26 61 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20  &aHash, &aPgno, 
16700 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20 69 66 28  &iZero);.    if(
16710 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
16720 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72  {.      return r
16730 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e 43 6f  c;.    }.    nCo
16740 6c 6c 69 64 65 20 3d 20 48 41 53 48 54 41 42 4c  llide = HASHTABL
16750 45 5f 4e 53 4c 4f 54 3b 0a 20 20 20 20 66 6f 72  E_NSLOT;.    for
16760 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 70 67  (iKey=walHash(pg
16770 6e 6f 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  no); aHash[iKey]
16780 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
16790 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
167a0 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20 61 48   u32 iFrame = aH
167b0 61 73 68 5b 69 4b 65 79 5d 20 2b 20 69 5a 65 72  ash[iKey] + iZer
167c0 6f 3b 0a 20 20 20 20 20 20 69 66 28 20 69 46 72  o;.      if( iFr
167d0 61 6d 65 3c 3d 69 4c 61 73 74 20 26 26 20 61 50  ame<=iLast && aP
167e0 67 6e 6f 5b 61 48 61 73 68 5b 69 4b 65 79 5d 5d  gno[aHash[iKey]]
167f0 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20  ==pgno ){.      
16800 20 20 2f 2a 20 61 73 73 65 72 74 28 20 69 46 72    /* assert( iFr
16810 61 6d 65 3e 69 52 65 61 64 20 29 3b 20 2d 2d 20  ame>iRead ); -- 
16820 6e 6f 74 20 74 72 75 65 20 69 66 20 74 68 65 72  not true if ther
16830 65 20 69 73 20 63 6f 72 72 75 70 74 69 6f 6e 20  e is corruption 
16840 2a 2f 0a 20 20 20 20 20 20 20 20 69 52 65 61 64  */.        iRead
16850 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20 20 20   = iFrame;.     
16860 20 7d 0a 20 20 20 20 20 20 69 66 28 20 28 6e 43   }.      if( (nC
16870 6f 6c 6c 69 64 65 2d 2d 29 3d 3d 30 20 29 7b 0a  ollide--)==0 ){.
16880 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 53          return S
16890 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b  QLITE_CORRUPT_BK
168a0 50 54 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  PT;.      }.    
168b0 7d 0a 20 20 7d 0a 0a 23 69 66 64 65 66 20 53 51  }.  }..#ifdef SQ
168c0 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45  LITE_ENABLE_EXPE
168d0 4e 53 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f  NSIVE_ASSERT.  /
168e0 2a 20 49 66 20 65 78 70 65 6e 73 69 76 65 20 61  * If expensive a
168f0 73 73 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e  ssert() statemen
16900 74 73 20 61 72 65 20 61 76 61 69 6c 61 62 6c 65  ts are available
16910 2c 20 64 6f 20 61 20 6c 69 6e 65 61 72 20 73 65  , do a linear se
16920 61 72 63 68 0a 20 20 2a 2a 20 6f 66 20 74 68 65  arch.  ** of the
16930 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20   wal-index file 
16940 63 6f 6e 74 65 6e 74 2e 20 4d 61 6b 65 20 73 75  content. Make su
16950 72 65 20 74 68 65 20 72 65 73 75 6c 74 73 20 61  re the results a
16960 67 72 65 65 20 77 69 74 68 20 74 68 65 0a 20 20  gree with the.  
16970 2a 2a 20 72 65 73 75 6c 74 20 6f 62 74 61 69 6e  ** result obtain
16980 65 64 20 75 73 69 6e 67 20 74 68 65 20 68 61 73  ed using the has
16990 68 20 69 6e 64 65 78 65 73 20 61 62 6f 76 65 2e  h indexes above.
169a0 20 20 2a 2f 0a 20 20 7b 0a 20 20 20 20 75 33 32    */.  {.    u32
169b0 20 69 52 65 61 64 32 20 3d 20 30 3b 0a 20 20 20   iRead2 = 0;.   
169c0 20 75 33 32 20 69 54 65 73 74 3b 0a 20 20 20 20   u32 iTest;.    
169d0 66 6f 72 28 69 54 65 73 74 3d 69 4c 61 73 74 3b  for(iTest=iLast;
169e0 20 69 54 65 73 74 3e 30 3b 20 69 54 65 73 74 2d   iTest>0; iTest-
169f0 2d 29 7b 0a 20 20 20 20 20 20 69 66 28 20 77 61  -){.      if( wa
16a00 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c  lFramePgno(pWal,
16a10 20 69 54 65 73 74 29 3d 3d 70 67 6e 6f 20 29 7b   iTest)==pgno ){
16a20 0a 20 20 20 20 20 20 20 20 69 52 65 61 64 32 20  .        iRead2 
16a30 3d 20 69 54 65 73 74 3b 0a 20 20 20 20 20 20 20  = iTest;.       
16a40 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
16a50 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74      }.    assert
16a60 28 20 69 52 65 61 64 3d 3d 69 52 65 61 64 32 20  ( iRead==iRead2 
16a70 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20  );.  }.#endif.. 
16a80 20 2a 70 69 52 65 61 64 20 3d 20 69 52 65 61 64   *piRead = iRead
16a90 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
16aa0 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  E_OK;.}../*.** R
16ab0 65 61 64 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ead the contents
16ac0 20 6f 66 20 66 72 61 6d 65 20 69 52 65 61 64 20   of frame iRead 
16ad0 66 72 6f 6d 20 74 68 65 20 77 61 6c 20 66 69 6c  from the wal fil
16ae0 65 20 69 6e 74 6f 20 62 75 66 66 65 72 20 70 4f  e into buffer pO
16af0 75 74 0a 2a 2a 20 28 77 68 69 63 68 20 69 73 20  ut.** (which is 
16b00 6e 4f 75 74 20 62 79 74 65 73 20 69 6e 20 73 69  nOut bytes in si
16b10 7a 65 29 2e 20 52 65 74 75 72 6e 20 53 51 4c 49  ze). Return SQLI
16b20 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73  TE_OK if success
16b30 66 75 6c 2c 20 6f 72 20 61 6e 0a 2a 2a 20 65 72  ful, or an.** er
16b40 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77 69  ror code otherwi
16b50 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  se..*/.int sqlit
16b60 65 33 57 61 6c 52 65 61 64 46 72 61 6d 65 28 0a  e3WalReadFrame(.
16b70 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
16b80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16b90 20 20 2f 2a 20 57 41 4c 20 68 61 6e 64 6c 65 20    /* WAL handle 
16ba0 2a 2f 0a 20 20 75 33 32 20 69 52 65 61 64 2c 20  */.  u32 iRead, 
16bb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16bc0 20 20 20 20 20 2f 2a 20 46 72 61 6d 65 20 74 6f       /* Frame to
16bd0 20 72 65 61 64 20 2a 2f 0a 20 20 69 6e 74 20 6e   read */.  int n
16be0 4f 75 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  Out,            
16bf0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
16c00 7a 65 20 6f 66 20 62 75 66 66 65 72 20 70 4f 75  ze of buffer pOu
16c10 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  t in bytes */.  
16c20 75 38 20 2a 70 4f 75 74 20 20 20 20 20 20 20 20  u8 *pOut        
16c30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16c40 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 77 72 69  /* Buffer to wri
16c50 74 65 20 70 61 67 65 20 64 61 74 61 20 74 6f 20  te page data to 
16c60 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 73 7a 3b 0a  */.){.  int sz;.
16c70 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 0a 20    i64 iOffset;. 
16c80 20 73 7a 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e   sz = pWal->hdr.
16c90 73 7a 50 61 67 65 3b 0a 20 20 73 7a 20 3d 20 28  szPage;.  sz = (
16ca0 73 7a 26 30 78 66 65 30 30 29 20 2b 20 28 28 73  sz&0xfe00) + ((s
16cb0 7a 26 30 78 30 30 30 31 29 3c 3c 31 36 29 3b 0a  z&0x0001)<<16);.
16cc0 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 3c 3d    testcase( sz<=
16cd0 33 32 37 36 38 20 29 3b 0a 20 20 74 65 73 74 63  32768 );.  testc
16ce0 61 73 65 28 20 73 7a 3e 3d 36 35 35 33 36 20 29  ase( sz>=65536 )
16cf0 3b 0a 20 20 69 4f 66 66 73 65 74 20 3d 20 77 61  ;.  iOffset = wa
16d00 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 52 65  lFrameOffset(iRe
16d10 61 64 2c 20 73 7a 29 20 2b 20 57 41 4c 5f 46 52  ad, sz) + WAL_FR
16d20 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20 20 2f  AME_HDRSIZE;.  /
16d30 2a 20 74 65 73 74 63 61 73 65 28 20 49 53 5f 42  * testcase( IS_B
16d40 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20  IG_INT(iOffset) 
16d50 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73 20 61  ); // requires a
16d60 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20 20 72   4GiB WAL */.  r
16d70 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52  eturn sqlite3OsR
16d80 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ead(pWal->pWalFd
16d90 2c 20 70 4f 75 74 2c 20 28 6e 4f 75 74 3e 73 7a  , pOut, (nOut>sz
16da0 20 3f 20 73 7a 20 3a 20 6e 4f 75 74 29 2c 20 69   ? sz : nOut), i
16db0 4f 66 66 73 65 74 29 3b 0a 7d 0a 0a 2f 2a 20 0a  Offset);.}../* .
16dc0 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73 69  ** Return the si
16dd0 7a 65 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  ze of the databa
16de0 73 65 20 69 6e 20 70 61 67 65 73 20 28 6f 72 20  se in pages (or 
16df0 7a 65 72 6f 2c 20 69 66 20 75 6e 6b 6e 6f 77 6e  zero, if unknown
16e00 29 2e 0a 2a 2f 0a 50 67 6e 6f 20 73 71 6c 69 74  )..*/.Pgno sqlit
16e10 65 33 57 61 6c 44 62 73 69 7a 65 28 57 61 6c 20  e3WalDbsize(Wal 
16e20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28 20 70 57  *pWal){.  if( pW
16e30 61 6c 20 26 26 20 41 4c 57 41 59 53 28 70 57 61  al && ALWAYS(pWa
16e40 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 29 20  l->readLock>=0) 
16e50 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 57  ){.    return pW
16e60 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 3b 0a 20  al->hdr.nPage;. 
16e70 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d   }.  return 0;.}
16e80 0a 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 66  .../* .** This f
16e90 75 6e 63 74 69 6f 6e 20 73 74 61 72 74 73 20 61  unction starts a
16ea0 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69   write transacti
16eb0 6f 6e 20 6f 6e 20 74 68 65 20 57 41 4c 2e 0a 2a  on on the WAL..*
16ec0 2a 0a 2a 2a 20 41 20 72 65 61 64 20 74 72 61 6e  *.** A read tran
16ed0 73 61 63 74 69 6f 6e 20 6d 75 73 74 20 68 61 76  saction must hav
16ee0 65 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 73  e already been s
16ef0 74 61 72 74 65 64 20 62 79 20 61 20 70 72 69 6f  tarted by a prio
16f00 72 20 63 61 6c 6c 0a 2a 2a 20 74 6f 20 73 71 6c  r call.** to sql
16f10 69 74 65 33 57 61 6c 42 65 67 69 6e 52 65 61 64  ite3WalBeginRead
16f20 54 72 61 6e 73 61 63 74 69 6f 6e 28 29 2e 0a 2a  Transaction()..*
16f30 2a 0a 2a 2a 20 49 66 20 61 6e 6f 74 68 65 72 20  *.** If another 
16f40 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73  thread or proces
16f50 73 20 68 61 73 20 77 72 69 74 74 65 6e 20 69 6e  s has written in
16f60 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20  to the database 
16f70 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 72 65 61  since.** the rea
16f80 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61  d transaction wa
16f90 73 20 73 74 61 72 74 65 64 2c 20 74 68 65 6e 20  s started, then 
16fa0 69 74 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62  it is not possib
16fb0 6c 65 20 66 6f 72 20 74 68 69 73 0a 2a 2a 20 74  le for this.** t
16fc0 68 72 65 61 64 20 74 6f 20 77 72 69 74 65 20 61  hread to write a
16fd0 73 20 64 6f 69 6e 67 20 73 6f 20 77 6f 75 6c 64  s doing so would
16fe0 20 63 61 75 73 65 20 61 20 66 6f 72 6b 2e 20 20   cause a fork.  
16ff0 53 6f 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a  So this routine.
17000 2a 2a 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  ** returns SQLIT
17010 45 5f 42 55 53 59 20 69 6e 20 74 68 61 74 20 63  E_BUSY in that c
17020 61 73 65 20 61 6e 64 20 6e 6f 20 77 72 69 74 65  ase and no write
17030 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20   transaction is 
17040 73 74 61 72 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 54  started..**.** T
17050 68 65 72 65 20 63 61 6e 20 6f 6e 6c 79 20 62 65  here can only be
17060 20 61 20 73 69 6e 67 6c 65 20 77 72 69 74 65 72   a single writer
17070 20 61 63 74 69 76 65 20 61 74 20 61 20 74 69 6d   active at a tim
17080 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
17090 33 57 61 6c 42 65 67 69 6e 57 72 69 74 65 54 72  3WalBeginWriteTr
170a0 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70  ansaction(Wal *p
170b0 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  Wal){.  int rc;.
170c0 0a 20 20 2f 2a 20 43 61 6e 6e 6f 74 20 73 74 61  .  /* Cannot sta
170d0 72 74 20 61 20 77 72 69 74 65 20 74 72 61 6e 73  rt a write trans
170e0 61 63 74 69 6f 6e 20 77 69 74 68 6f 75 74 20 66  action without f
170f0 69 72 73 74 20 68 6f 6c 64 69 6e 67 20 61 20 72  irst holding a r
17100 65 61 64 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63  ead.  ** transac
17110 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72  tion. */.  asser
17120 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  t( pWal->readLoc
17130 6b 3e 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 70  k>=0 );..  if( p
17140 57 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 29 7b  Wal->readOnly ){
17150 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
17160 54 45 5f 52 45 41 44 4f 4e 4c 59 3b 0a 20 20 7d  TE_READONLY;.  }
17170 0a 0a 20 20 2f 2a 20 4f 6e 6c 79 20 6f 6e 65 20  ..  /* Only one 
17180 77 72 69 74 65 72 20 61 6c 6c 6f 77 65 64 20 61  writer allowed a
17190 74 20 61 20 74 69 6d 65 2e 20 20 47 65 74 20 74  t a time.  Get t
171a0 68 65 20 77 72 69 74 65 20 6c 6f 63 6b 2e 20 20  he write lock.  
171b0 52 65 74 75 72 6e 0a 20 20 2a 2a 20 53 51 4c 49  Return.  ** SQLI
171c0 54 45 5f 42 55 53 59 20 69 66 20 75 6e 61 62 6c  TE_BUSY if unabl
171d0 65 2e 0a 20 20 2a 2f 0a 20 20 72 63 20 3d 20 77  e..  */.  rc = w
171e0 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  alLockExclusive(
171f0 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f  pWal, WAL_WRITE_
17200 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 69 66 28 20  LOCK, 1);.  if( 
17210 72 63 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  rc ){.    return
17220 20 72 63 3b 0a 20 20 7d 0a 20 20 70 57 61 6c 2d   rc;.  }.  pWal-
17230 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 31 3b 0a  >writeLock = 1;.
17240 0a 20 20 2f 2a 20 49 66 20 61 6e 6f 74 68 65 72  .  /* If another
17250 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 73 20   connection has 
17260 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20 64  written to the d
17270 61 74 61 62 61 73 65 20 66 69 6c 65 20 73 69 6e  atabase file sin
17280 63 65 20 74 68 65 0a 20 20 2a 2a 20 74 69 6d 65  ce the.  ** time
17290 20 74 68 65 20 72 65 61 64 20 74 72 61 6e 73 61   the read transa
172a0 63 74 69 6f 6e 20 6f 6e 20 74 68 69 73 20 63 6f  ction on this co
172b0 6e 6e 65 63 74 69 6f 6e 20 77 61 73 20 73 74 61  nnection was sta
172c0 72 74 65 64 2c 20 74 68 65 6e 0a 20 20 2a 2a 20  rted, then.  ** 
172d0 74 68 65 20 77 72 69 74 65 20 69 73 20 64 69 73  the write is dis
172e0 61 6c 6c 6f 77 65 64 2e 0a 20 20 2a 2f 0a 20 20  allowed..  */.  
172f0 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c  if( memcmp(&pWal
17300 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20 2a 29 77  ->hdr, (void *)w
17310 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29  alIndexHdr(pWal)
17320 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65  , sizeof(WalInde
17330 78 48 64 72 29 29 21 3d 30 20 29 7b 0a 20 20 20  xHdr))!=0 ){.   
17340 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
17350 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52  ive(pWal, WAL_WR
17360 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20  ITE_LOCK, 1);.  
17370 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63    pWal->writeLoc
17380 6b 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20  k = 0;.    rc = 
17390 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a 20 20 7d  SQLITE_BUSY;.  }
173a0 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
173b0 0a 0a 2f 2a 0a 2a 2a 20 45 6e 64 20 61 20 77 72  ../*.** End a wr
173c0 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e  ite transaction.
173d0 20 20 54 68 65 20 63 6f 6d 6d 69 74 20 68 61 73    The commit has
173e0 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 64 6f   already been do
173f0 6e 65 2e 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75  ne.  This.** rou
17400 74 69 6e 65 20 6d 65 72 65 6c 79 20 72 65 6c 65  tine merely rele
17410 61 73 65 73 20 74 68 65 20 6c 6f 63 6b 2e 0a 2a  ases the lock..*
17420 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c  /.int sqlite3Wal
17430 45 6e 64 57 72 69 74 65 54 72 61 6e 73 61 63 74  EndWriteTransact
17440 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ion(Wal *pWal){.
17450 20 20 69 66 28 20 70 57 61 6c 2d 3e 77 72 69 74    if( pWal->writ
17460 65 4c 6f 63 6b 20 29 7b 0a 20 20 20 20 77 61 6c  eLock ){.    wal
17470 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  UnlockExclusive(
17480 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f  pWal, WAL_WRITE_
17490 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 20 20 70 57  LOCK, 1);.    pW
174a0 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20  al->writeLock = 
174b0 30 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 74 72 75  0;.    pWal->tru
174c0 6e 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 20 3d 20  ncateOnCommit = 
174d0 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  0;.  }.  return 
174e0 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
174f0 0a 2a 2a 20 49 66 20 61 6e 79 20 64 61 74 61 20  .** If any data 
17500 68 61 73 20 62 65 65 6e 20 77 72 69 74 74 65 6e  has been written
17510 20 28 62 75 74 20 6e 6f 74 20 63 6f 6d 6d 69 74   (but not commit
17520 74 65 64 29 20 74 6f 20 74 68 65 20 6c 6f 67 20  ted) to the log 
17530 66 69 6c 65 2c 20 74 68 69 73 0a 2a 2a 20 66 75  file, this.** fu
17540 6e 63 74 69 6f 6e 20 6d 6f 76 65 73 20 74 68 65  nction moves the
17550 20 77 72 69 74 65 2d 70 6f 69 6e 74 65 72 20 62   write-pointer b
17560 61 63 6b 20 74 6f 20 74 68 65 20 73 74 61 72 74  ack to the start
17570 20 6f 66 20 74 68 65 20 74 72 61 6e 73 61 63 74   of the transact
17580 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41 64 64 69 74  ion..**.** Addit
17590 69 6f 6e 61 6c 6c 79 2c 20 74 68 65 20 63 61 6c  ionally, the cal
175a0 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20 69  lback function i
175b0 73 20 69 6e 76 6f 6b 65 64 20 66 6f 72 20 65 61  s invoked for ea
175c0 63 68 20 66 72 61 6d 65 20 77 72 69 74 74 65 6e  ch frame written
175d0 0a 2a 2a 20 74 6f 20 74 68 65 20 57 41 4c 20 73  .** to the WAL s
175e0 69 6e 63 65 20 74 68 65 20 73 74 61 72 74 20 6f  ince the start o
175f0 66 20 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f  f the transactio
17600 6e 2e 20 49 66 20 74 68 65 20 63 61 6c 6c 62 61  n. If the callba
17610 63 6b 20 72 65 74 75 72 6e 73 0a 2a 2a 20 6f 74  ck returns.** ot
17620 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45 5f  her than SQLITE_
17630 4f 4b 2c 20 69 74 20 69 73 20 6e 6f 74 20 69 6e  OK, it is not in
17640 76 6f 6b 65 64 20 61 67 61 69 6e 20 61 6e 64 20  voked again and 
17650 74 68 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  the error code i
17660 73 0a 2a 2a 20 72 65 74 75 72 6e 65 64 20 74 6f  s.** returned to
17670 20 74 68 65 20 63 61 6c 6c 65 72 2e 0a 2a 2a 0a   the caller..**.
17680 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66  ** Otherwise, if
17690 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 66 75   the callback fu
176a0 6e 63 74 69 6f 6e 20 64 6f 65 73 20 6e 6f 74 20  nction does not 
176b0 72 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72 2c  return an error,
176c0 20 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f   this.** functio
176d0 6e 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45  n returns SQLITE
176e0 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  _OK..*/.int sqli
176f0 74 65 33 57 61 6c 55 6e 64 6f 28 57 61 6c 20 2a  te3WalUndo(Wal *
17700 70 57 61 6c 2c 20 69 6e 74 20 28 2a 78 55 6e 64  pWal, int (*xUnd
17710 6f 29 28 76 6f 69 64 20 2a 2c 20 50 67 6e 6f 29  o)(void *, Pgno)
17720 2c 20 76 6f 69 64 20 2a 70 55 6e 64 6f 43 74 78  , void *pUndoCtx
17730 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
17740 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 41  LITE_OK;.  if( A
17750 4c 57 41 59 53 28 70 57 61 6c 2d 3e 77 72 69 74  LWAYS(pWal->writ
17760 65 4c 6f 63 6b 29 20 29 7b 0a 20 20 20 20 50 67  eLock) ){.    Pg
17770 6e 6f 20 69 4d 61 78 20 3d 20 70 57 61 6c 2d 3e  no iMax = pWal->
17780 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20  hdr.mxFrame;.   
17790 20 50 67 6e 6f 20 69 46 72 61 6d 65 3b 0a 20 20   Pgno iFrame;.  
177a0 0a 20 20 20 20 2f 2a 20 52 65 73 74 6f 72 65 20  .    /* Restore 
177b0 74 68 65 20 63 6c 69 65 6e 74 73 20 63 61 63 68  the clients cach
177c0 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  e of the wal-ind
177d0 65 78 20 68 65 61 64 65 72 20 74 6f 20 74 68 65  ex header to the
177e0 20 73 74 61 74 65 20 69 74 0a 20 20 20 20 2a 2a   state it.    **
177f0 20 77 61 73 20 69 6e 20 62 65 66 6f 72 65 20 74   was in before t
17800 68 65 20 63 6c 69 65 6e 74 20 62 65 67 61 6e 20  he client began 
17810 77 72 69 74 69 6e 67 20 74 6f 20 74 68 65 20 64  writing to the d
17820 61 74 61 62 61 73 65 2e 20 0a 20 20 20 20 2a 2f  atabase. .    */
17830 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 57 61  .    memcpy(&pWa
17840 6c 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20 2a 29  l->hdr, (void *)
17850 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c  walIndexHdr(pWal
17860 29 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64  ), sizeof(WalInd
17870 65 78 48 64 72 29 29 3b 0a 0a 20 20 20 20 66 6f  exHdr));..    fo
17880 72 28 69 46 72 61 6d 65 3d 70 57 61 6c 2d 3e 68  r(iFrame=pWal->h
17890 64 72 2e 6d 78 46 72 61 6d 65 2b 31 3b 20 0a 20  dr.mxFrame+1; . 
178a0 20 20 20 20 20 20 20 41 4c 57 41 59 53 28 72 63         ALWAYS(rc
178b0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29 20 26 26 20  ==SQLITE_OK) && 
178c0 69 46 72 61 6d 65 3c 3d 69 4d 61 78 3b 20 0a 20  iFrame<=iMax; . 
178d0 20 20 20 20 20 20 20 69 46 72 61 6d 65 2b 2b 0a         iFrame++.
178e0 20 20 20 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20      ){.      /* 
178f0 54 68 69 73 20 63 61 6c 6c 20 63 61 6e 6e 6f 74  This call cannot
17900 20 66 61 69 6c 2e 20 55 6e 6c 65 73 73 20 74 68   fail. Unless th
17910 65 20 70 61 67 65 20 66 6f 72 20 77 68 69 63 68  e page for which
17920 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72   the page number
17930 0a 20 20 20 20 20 20 2a 2a 20 69 73 20 70 61 73  .      ** is pas
17940 73 65 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e  sed as the secon
17950 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20 28 61  d argument is (a
17960 29 20 69 6e 20 74 68 65 20 63 61 63 68 65 20 61  ) in the cache a
17970 6e 64 20 0a 20 20 20 20 20 20 2a 2a 20 28 62 29  nd .      ** (b)
17980 20 68 61 73 20 61 6e 20 6f 75 74 73 74 61 6e 64   has an outstand
17990 69 6e 67 20 72 65 66 65 72 65 6e 63 65 2c 20 74  ing reference, t
179a0 68 65 6e 20 78 55 6e 64 6f 20 69 73 20 65 69 74  hen xUndo is eit
179b0 68 65 72 20 61 20 6e 6f 2d 6f 70 0a 20 20 20 20  her a no-op.    
179c0 20 20 2a 2a 20 28 69 66 20 28 61 29 20 69 73 20    ** (if (a) is 
179d0 66 61 6c 73 65 29 20 6f 72 20 73 69 6d 70 6c 79  false) or simply
179e0 20 65 78 70 65 6c 73 20 74 68 65 20 70 61 67 65   expels the page
179f0 20 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65 20   from the cache 
17a00 28 69 66 20 28 62 29 0a 20 20 20 20 20 20 2a 2a  (if (b).      **
17a10 20 69 73 20 66 61 6c 73 65 29 2e 0a 20 20 20 20   is false)..    
17a20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 49 66    **.      ** If
17a30 20 74 68 65 20 75 70 70 65 72 20 6c 61 79 65 72   the upper layer
17a40 20 69 73 20 64 6f 69 6e 67 20 61 20 72 6f 6c 6c   is doing a roll
17a50 62 61 63 6b 2c 20 69 74 20 69 73 20 67 75 61 72  back, it is guar
17a60 61 6e 74 65 65 64 20 74 68 61 74 20 74 68 65 72  anteed that ther
17a70 65 0a 20 20 20 20 20 20 2a 2a 20 61 72 65 20 6e  e.      ** are n
17a80 6f 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 72 65  o outstanding re
17a90 66 65 72 65 6e 63 65 73 20 74 6f 20 61 6e 79 20  ferences to any 
17aa0 70 61 67 65 20 6f 74 68 65 72 20 74 68 61 6e 20  page other than 
17ab0 70 61 67 65 20 31 2e 20 41 6e 64 0a 20 20 20 20  page 1. And.    
17ac0 20 20 2a 2a 20 70 61 67 65 20 31 20 69 73 20 6e    ** page 1 is n
17ad0 65 76 65 72 20 77 72 69 74 74 65 6e 20 74 6f 20  ever written to 
17ae0 74 68 65 20 6c 6f 67 20 75 6e 74 69 6c 20 74 68  the log until th
17af0 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73  e transaction is
17b00 0a 20 20 20 20 20 20 2a 2a 20 63 6f 6d 6d 69 74  .      ** commit
17b10 74 65 64 2e 20 41 73 20 61 20 72 65 73 75 6c 74  ted. As a result
17b20 2c 20 74 68 65 20 63 61 6c 6c 20 74 6f 20 78 55  , the call to xU
17b30 6e 64 6f 20 6d 61 79 20 6e 6f 74 20 66 61 69 6c  ndo may not fail
17b40 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20  ..      */.     
17b50 20 61 73 73 65 72 74 28 20 77 61 6c 46 72 61 6d   assert( walFram
17b60 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 46 72 61  ePgno(pWal, iFra
17b70 6d 65 29 21 3d 31 20 29 3b 0a 20 20 20 20 20 20  me)!=1 );.      
17b80 72 63 20 3d 20 78 55 6e 64 6f 28 70 55 6e 64 6f  rc = xUndo(pUndo
17b90 43 74 78 2c 20 77 61 6c 46 72 61 6d 65 50 67 6e  Ctx, walFramePgn
17ba0 6f 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 29  o(pWal, iFrame))
17bb0 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
17bc0 69 4d 61 78 21 3d 70 57 61 6c 2d 3e 68 64 72 2e  iMax!=pWal->hdr.
17bd0 6d 78 46 72 61 6d 65 20 29 20 77 61 6c 43 6c 65  mxFrame ) walCle
17be0 61 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a  anupHash(pWal);.
17bf0 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20 72 63    }.  assert( rc
17c00 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20  ==SQLITE_OK );. 
17c10 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
17c20 2a 20 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 61  * .** Argument a
17c30 57 61 6c 44 61 74 61 20 6d 75 73 74 20 70 6f 69  WalData must poi
17c40 6e 74 20 74 6f 20 61 6e 20 61 72 72 61 79 20 6f  nt to an array o
17c50 66 20 57 41 4c 5f 53 41 56 45 50 4f 49 4e 54 5f  f WAL_SAVEPOINT_
17c60 4e 44 41 54 41 20 75 33 32 20 0a 2a 2a 20 76 61  NDATA u32 .** va
17c70 6c 75 65 73 2e 20 54 68 69 73 20 66 75 6e 63 74  lues. This funct
17c80 69 6f 6e 20 70 6f 70 75 6c 61 74 65 73 20 74 68  ion populates th
17c90 65 20 61 72 72 61 79 20 77 69 74 68 20 76 61 6c  e array with val
17ca0 75 65 73 20 72 65 71 75 69 72 65 64 20 74 6f 20  ues required to 
17cb0 0a 2a 2a 20 22 72 6f 6c 6c 62 61 63 6b 22 20 74  .** "rollback" t
17cc0 68 65 20 77 72 69 74 65 20 70 6f 73 69 74 69 6f  he write positio
17cd0 6e 20 6f 66 20 74 68 65 20 57 41 4c 20 68 61 6e  n of the WAL han
17ce0 64 6c 65 20 62 61 63 6b 20 74 6f 20 74 68 65 20  dle back to the 
17cf0 63 75 72 72 65 6e 74 20 0a 2a 2a 20 70 6f 69 6e  current .** poin
17d00 74 20 69 6e 20 74 68 65 20 65 76 65 6e 74 20 6f  t in the event o
17d10 66 20 61 20 73 61 76 65 70 6f 69 6e 74 20 72 6f  f a savepoint ro
17d20 6c 6c 62 61 63 6b 20 28 76 69 61 20 57 61 6c 53  llback (via WalS
17d30 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28 29 29 2e  avepointUndo()).
17d40 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
17d50 57 61 6c 53 61 76 65 70 6f 69 6e 74 28 57 61 6c  WalSavepoint(Wal
17d60 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a 61 57 61   *pWal, u32 *aWa
17d70 6c 44 61 74 61 29 7b 0a 20 20 61 73 73 65 72 74  lData){.  assert
17d80 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
17d90 6b 20 29 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b  k );.  aWalData[
17da0 30 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  0] = pWal->hdr.m
17db0 78 46 72 61 6d 65 3b 0a 20 20 61 57 61 6c 44 61  xFrame;.  aWalDa
17dc0 74 61 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64  ta[1] = pWal->hd
17dd0 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d  r.aFrameCksum[0]
17de0 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 32 5d 20  ;.  aWalData[2] 
17df0 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61  = pWal->hdr.aFra
17e00 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 61 57  meCksum[1];.  aW
17e10 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70 57 61 6c  alData[3] = pWal
17e20 2d 3e 6e 43 6b 70 74 3b 0a 7d 0a 0a 2f 2a 20 0a  ->nCkpt;.}../* .
17e30 2a 2a 20 4d 6f 76 65 20 74 68 65 20 77 72 69 74  ** Move the writ
17e40 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66 20 74 68  e position of th
17e50 65 20 57 41 4c 20 62 61 63 6b 20 74 6f 20 74 68  e WAL back to th
17e60 65 20 70 6f 69 6e 74 20 69 64 65 6e 74 69 66 69  e point identifi
17e70 65 64 20 62 79 0a 2a 2a 20 74 68 65 20 76 61 6c  ed by.** the val
17e80 75 65 73 20 69 6e 20 74 68 65 20 61 57 61 6c 44  ues in the aWalD
17e90 61 74 61 5b 5d 20 61 72 72 61 79 2e 20 61 57 61  ata[] array. aWa
17ea0 6c 44 61 74 61 20 6d 75 73 74 20 70 6f 69 6e 74  lData must point
17eb0 20 74 6f 20 61 6e 20 61 72 72 61 79 0a 2a 2a 20   to an array.** 
17ec0 6f 66 20 57 41 4c 5f 53 41 56 45 50 4f 49 4e 54  of WAL_SAVEPOINT
17ed0 5f 4e 44 41 54 41 20 75 33 32 20 76 61 6c 75 65  _NDATA u32 value
17ee0 73 20 74 68 61 74 20 68 61 73 20 62 65 65 6e 20  s that has been 
17ef0 70 72 65 76 69 6f 75 73 6c 79 20 70 6f 70 75 6c  previously popul
17f00 61 74 65 64 0a 2a 2a 20 62 79 20 61 20 63 61 6c  ated.** by a cal
17f10 6c 20 74 6f 20 57 61 6c 53 61 76 65 70 6f 69 6e  l to WalSavepoin
17f20 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  t()..*/.int sqli
17f30 74 65 33 57 61 6c 53 61 76 65 70 6f 69 6e 74 55  te3WalSavepointU
17f40 6e 64 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75  ndo(Wal *pWal, u
17f50 33 32 20 2a 61 57 61 6c 44 61 74 61 29 7b 0a 20  32 *aWalData){. 
17f60 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
17f70 5f 4f 4b 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  _OK;..  assert( 
17f80 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
17f90 29 3b 0a 20 20 61 73 73 65 72 74 28 20 61 57 61  );.  assert( aWa
17fa0 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e  lData[3]!=pWal->
17fb0 6e 43 6b 70 74 20 7c 7c 20 61 57 61 6c 44 61 74  nCkpt || aWalDat
17fc0 61 5b 30 5d 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e  a[0]<=pWal->hdr.
17fd0 6d 78 46 72 61 6d 65 20 29 3b 0a 0a 20 20 69 66  mxFrame );..  if
17fe0 28 20 61 57 61 6c 44 61 74 61 5b 33 5d 21 3d 70  ( aWalData[3]!=p
17ff0 57 61 6c 2d 3e 6e 43 6b 70 74 20 29 7b 0a 20 20  Wal->nCkpt ){.  
18000 20 20 2f 2a 20 54 68 69 73 20 73 61 76 65 70 6f    /* This savepo
18010 69 6e 74 20 77 61 73 20 6f 70 65 6e 65 64 20 69  int was opened i
18020 6d 6d 65 64 69 61 74 65 6c 79 20 61 66 74 65 72  mmediately after
18030 20 74 68 65 20 77 72 69 74 65 2d 74 72 61 6e 73   the write-trans
18040 61 63 74 69 6f 6e 0a 20 20 20 20 2a 2a 20 77 61  action.    ** wa
18050 73 20 73 74 61 72 74 65 64 2e 20 52 69 67 68 74  s started. Right
18060 20 61 66 74 65 72 20 74 68 61 74 2c 20 74 68 65   after that, the
18070 20 77 72 69 74 65 72 20 64 65 63 69 64 65 64 20   writer decided 
18080 74 6f 20 77 72 61 70 20 61 72 6f 75 6e 64 0a 20  to wrap around. 
18090 20 20 20 2a 2a 20 74 6f 20 74 68 65 20 73 74 61     ** to the sta
180a0 72 74 20 6f 66 20 74 68 65 20 6c 6f 67 2e 20 55  rt of the log. U
180b0 70 64 61 74 65 20 74 68 65 20 73 61 76 65 70 6f  pdate the savepo
180c0 69 6e 74 20 76 61 6c 75 65 73 20 74 6f 20 6d 61  int values to ma
180d0 74 63 68 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  tch..    */.    
180e0 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d 20 30 3b  aWalData[0] = 0;
180f0 0a 20 20 20 20 61 57 61 6c 44 61 74 61 5b 33 5d  .    aWalData[3]
18100 20 3d 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 3b 0a   = pWal->nCkpt;.
18110 20 20 7d 0a 0a 20 20 69 66 28 20 61 57 61 6c 44    }..  if( aWalD
18120 61 74 61 5b 30 5d 3c 70 57 61 6c 2d 3e 68 64 72  ata[0]<pWal->hdr
18130 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20  .mxFrame ){.    
18140 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
18150 65 20 3d 20 61 57 61 6c 44 61 74 61 5b 30 5d 3b  e = aWalData[0];
18160 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61  .    pWal->hdr.a
18170 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d 20  FrameCksum[0] = 
18180 61 57 61 6c 44 61 74 61 5b 31 5d 3b 0a 20 20 20  aWalData[1];.   
18190 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
181a0 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 61 57 61 6c  eCksum[1] = aWal
181b0 44 61 74 61 5b 32 5d 3b 0a 20 20 20 20 77 61 6c  Data[2];.    wal
181c0 43 6c 65 61 6e 75 70 48 61 73 68 28 70 57 61 6c  CleanupHash(pWal
181d0 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
181e0 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 54   rc;.}.../*.** T
181f0 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
18200 63 61 6c 6c 65 64 20 6a 75 73 74 20 62 65 66 6f  called just befo
18210 72 65 20 77 72 69 74 69 6e 67 20 61 20 73 65 74  re writing a set
18220 20 6f 66 20 66 72 61 6d 65 73 20 74 6f 20 74 68   of frames to th
18230 65 20 6c 6f 67 0a 2a 2a 20 66 69 6c 65 20 28 73  e log.** file (s
18240 65 65 20 73 71 6c 69 74 65 33 57 61 6c 46 72 61  ee sqlite3WalFra
18250 6d 65 73 28 29 29 2e 20 49 74 20 63 68 65 63 6b  mes()). It check
18260 73 20 74 6f 20 73 65 65 20 69 66 2c 20 69 6e 73  s to see if, ins
18270 74 65 61 64 20 6f 66 20 61 70 70 65 6e 64 69 6e  tead of appendin
18280 67 0a 2a 2a 20 74 6f 20 74 68 65 20 63 75 72 72  g.** to the curr
18290 65 6e 74 20 6c 6f 67 20 66 69 6c 65 2c 20 69 74  ent log file, it
182a0 20 69 73 20 70 6f 73 73 69 62 6c 65 20 74 6f 20   is possible to 
182b0 6f 76 65 72 77 72 69 74 65 20 74 68 65 20 73 74  overwrite the st
182c0 61 72 74 20 6f 66 20 74 68 65 0a 2a 2a 20 65 78  art of the.** ex
182d0 69 73 74 69 6e 67 20 6c 6f 67 20 66 69 6c 65 20  isting log file 
182e0 77 69 74 68 20 74 68 65 20 6e 65 77 20 66 72 61  with the new fra
182f0 6d 65 73 20 28 69 2e 65 2e 20 22 72 65 73 65 74  mes (i.e. "reset
18300 22 20 74 68 65 20 6c 6f 67 29 2e 20 49 66 20 73  " the log). If s
18310 6f 2c 0a 2a 2a 20 69 74 20 73 65 74 73 20 70 57  o,.** it sets pW
18320 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
18330 74 6f 20 30 2e 20 4f 74 68 65 72 77 69 73 65 2c  to 0. Otherwise,
18340 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
18350 6d 65 20 69 73 20 6c 65 66 74 0a 2a 2a 20 75 6e  me is left.** un
18360 63 68 61 6e 67 65 64 2e 0a 2a 2a 0a 2a 2a 20 53  changed..**.** S
18370 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
18380 72 6e 65 64 20 69 66 20 6e 6f 20 65 72 72 6f 72  rned if no error
18390 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 20   is encountered 
183a0 28 72 65 67 61 72 64 6c 65 73 73 20 6f 66 20 77  (regardless of w
183b0 68 65 74 68 65 72 0a 2a 2a 20 6f 72 20 6e 6f 74  hether.** or not
183c0 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
183d0 6d 65 20 69 73 20 6d 6f 64 69 66 69 65 64 29 2e  me is modified).
183e0 20 41 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   An SQLite error
183f0 20 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65   code is returne
18400 64 0a 2a 2a 20 69 66 20 61 6e 20 65 72 72 6f 72  d.** if an error
18410 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74   occurs..*/.stat
18420 69 63 20 69 6e 74 20 77 61 6c 52 65 73 74 61 72  ic int walRestar
18430 74 4c 6f 67 28 57 61 6c 20 2a 70 57 61 6c 29 7b  tLog(Wal *pWal){
18440 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
18450 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 63 6e 74  TE_OK;.  int cnt
18460 3b 0a 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 72  ;..  if( pWal->r
18470 65 61 64 4c 6f 63 6b 3d 3d 30 20 29 7b 0a 20 20  eadLock==0 ){.  
18480 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b    volatile WalCk
18490 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 20 3d 20  ptInfo *pInfo = 
184a0 77 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c  walCkptInfo(pWal
184b0 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
184c0 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3d  Info->nBackfill=
184d0 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  =pWal->hdr.mxFra
184e0 6d 65 20 29 3b 0a 20 20 20 20 69 66 28 20 70 49  me );.    if( pI
184f0 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3e 30  nfo->nBackfill>0
18500 20 29 7b 0a 20 20 20 20 20 20 75 33 32 20 73 61   ){.      u32 sa
18510 6c 74 31 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  lt1;.      sqlit
18520 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 34 2c  e3_randomness(4,
18530 20 26 73 61 6c 74 31 29 3b 0a 20 20 20 20 20 20   &salt1);.      
18540 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
18550 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
18560 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41  READ_LOCK(1), WA
18570 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20 20  L_NREADER-1);.  
18580 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
18590 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
185a0 20 2f 2a 20 49 66 20 61 6c 6c 20 72 65 61 64 65   /* If all reade
185b0 72 73 20 61 72 65 20 75 73 69 6e 67 20 57 41 4c  rs are using WAL
185c0 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20 28 69  _READ_LOCK(0) (i
185d0 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 20 69 66  n other words if
185e0 20 6e 6f 0a 20 20 20 20 20 20 20 20 2a 2a 20 72   no.        ** r
185f0 65 61 64 65 72 73 20 61 72 65 20 63 75 72 72 65  eaders are curre
18600 6e 74 6c 79 20 75 73 69 6e 67 20 74 68 65 20 57  ntly using the W
18610 41 4c 29 2c 20 74 68 65 6e 20 74 68 65 20 74 72  AL), then the tr
18620 61 6e 73 61 63 74 69 6f 6e 73 0a 20 20 20 20 20  ansactions.     
18630 20 20 20 2a 2a 20 66 72 61 6d 65 73 20 77 69 6c     ** frames wil
18640 6c 20 6f 76 65 72 77 72 69 74 65 20 74 68 65 20  l overwrite the 
18650 73 74 61 72 74 20 6f 66 20 74 68 65 20 65 78 69  start of the exi
18660 73 74 69 6e 67 20 6c 6f 67 2e 20 55 70 64 61 74  sting log. Updat
18670 65 20 74 68 65 0a 20 20 20 20 20 20 20 20 2a 2a  e the.        **
18680 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
18690 72 20 74 6f 20 72 65 66 6c 65 63 74 20 74 68 69  r to reflect thi
186a0 73 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20  s..        **.  
186b0 20 20 20 20 20 20 2a 2a 20 49 6e 20 74 68 65 6f        ** In theo
186c0 72 79 20 69 74 20 77 6f 75 6c 64 20 62 65 20 4f  ry it would be O
186d0 6b 20 74 6f 20 75 70 64 61 74 65 20 74 68 65 20  k to update the 
186e0 63 61 63 68 65 20 6f 66 20 74 68 65 20 68 65 61  cache of the hea
186f0 64 65 72 20 6f 6e 6c 79 0a 20 20 20 20 20 20 20  der only.       
18700 20 2a 2a 20 61 74 20 74 68 69 73 20 70 6f 69 6e   ** at this poin
18710 74 2e 20 42 75 74 20 75 70 64 61 74 69 6e 67 20  t. But updating 
18720 74 68 65 20 61 63 74 75 61 6c 20 77 61 6c 2d 69  the actual wal-i
18730 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20 61  ndex header is a
18740 6c 73 6f 0a 20 20 20 20 20 20 20 20 2a 2a 20 73  lso.        ** s
18750 61 66 65 20 61 6e 64 20 6d 65 61 6e 73 20 74 68  afe and means th
18760 65 72 65 20 69 73 20 6e 6f 20 73 70 65 63 69 61  ere is no specia
18770 6c 20 63 61 73 65 20 66 6f 72 20 73 71 6c 69 74  l case for sqlit
18780 65 33 57 61 6c 55 6e 64 6f 28 29 0a 20 20 20 20  e3WalUndo().    
18790 20 20 20 20 2a 2a 20 74 6f 20 68 61 6e 64 6c 65      ** to handle
187a0 20 69 66 20 74 68 69 73 20 74 72 61 6e 73 61 63   if this transac
187b0 74 69 6f 6e 20 69 73 20 72 6f 6c 6c 65 64 20 62  tion is rolled b
187c0 61 63 6b 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a  ack..        */.
187d0 20 20 20 20 20 20 20 20 69 6e 74 20 69 3b 20 20          int i;  
187e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
187f0 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65    /* Loop counte
18800 72 20 2a 2f 0a 20 20 20 20 20 20 20 20 75 33 32  r */.        u32
18810 20 2a 61 53 61 6c 74 20 3d 20 70 57 61 6c 2d 3e   *aSalt = pWal->
18820 68 64 72 2e 61 53 61 6c 74 3b 20 20 20 20 20 20  hdr.aSalt;      
18830 20 2f 2a 20 42 69 67 2d 65 6e 64 69 61 6e 20 73   /* Big-endian s
18840 61 6c 74 20 76 61 6c 75 65 73 20 2a 2f 0a 0a 20  alt values */.. 
18850 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 6e 43 6b         pWal->nCk
18860 70 74 2b 2b 3b 0a 20 20 20 20 20 20 20 20 70 57  pt++;.        pW
18870 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
18880 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 73 71 6c  = 0;.        sql
18890 69 74 65 33 50 75 74 34 62 79 74 65 28 28 75 38  ite3Put4byte((u8
188a0 2a 29 26 61 53 61 6c 74 5b 30 5d 2c 20 31 20 2b  *)&aSalt[0], 1 +
188b0 20 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65   sqlite3Get4byte
188c0 28 28 75 38 2a 29 26 61 53 61 6c 74 5b 30 5d 29  ((u8*)&aSalt[0])
188d0 29 3b 0a 20 20 20 20 20 20 20 20 61 53 61 6c 74  );.        aSalt
188e0 5b 31 5d 20 3d 20 73 61 6c 74 31 3b 0a 20 20 20  [1] = salt1;.   
188f0 20 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72 69       walIndexWri
18900 74 65 48 64 72 28 70 57 61 6c 29 3b 0a 20 20 20  teHdr(pWal);.   
18910 20 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63       pInfo->nBac
18920 6b 66 69 6c 6c 20 3d 20 30 3b 0a 20 20 20 20 20  kfill = 0;.     
18930 20 20 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d     pInfo->aReadM
18940 61 72 6b 5b 31 5d 20 3d 20 30 3b 0a 20 20 20 20  ark[1] = 0;.    
18950 20 20 20 20 66 6f 72 28 69 3d 32 3b 20 69 3c 57      for(i=2; i<W
18960 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29  AL_NREADER; i++)
18970 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
18980 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41 52 4b 5f  k[i] = READMARK_
18990 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 20 20 20 20  NOT_USED;.      
189a0 20 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d    assert( pInfo-
189b0 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 3d 3d 30  >aReadMark[0]==0
189c0 20 29 3b 0a 20 20 20 20 20 20 20 20 77 61 6c 55   );.        walU
189d0 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  nlockExclusive(p
189e0 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
189f0 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44  CK(1), WAL_NREAD
18a00 45 52 2d 31 29 3b 0a 20 20 20 20 20 20 7d 65 6c  ER-1);.      }el
18a10 73 65 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  se if( rc!=SQLIT
18a20 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20  E_BUSY ){.      
18a30 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20    return rc;.   
18a40 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 77     }.    }.    w
18a50 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70  alUnlockShared(p
18a60 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
18a70 43 4b 28 30 29 29 3b 0a 20 20 20 20 70 57 61 6c  CK(0));.    pWal
18a80 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31 3b  ->readLock = -1;
18a90 0a 20 20 20 20 63 6e 74 20 3d 20 30 3b 0a 20 20  .    cnt = 0;.  
18aa0 20 20 64 6f 7b 0a 20 20 20 20 20 20 69 6e 74 20    do{.      int 
18ab0 6e 6f 74 55 73 65 64 3b 0a 20 20 20 20 20 20 72  notUsed;.      r
18ac0 63 20 3d 20 77 61 6c 54 72 79 42 65 67 69 6e 52  c = walTryBeginR
18ad0 65 61 64 28 70 57 61 6c 2c 20 26 6e 6f 74 55 73  ead(pWal, &notUs
18ae0 65 64 2c 20 31 2c 20 2b 2b 63 6e 74 29 3b 0a 20  ed, 1, ++cnt);. 
18af0 20 20 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d 57     }while( rc==W
18b00 41 4c 5f 52 45 54 52 59 20 29 3b 0a 20 20 20 20  AL_RETRY );.    
18b10 61 73 73 65 72 74 28 20 28 72 63 26 30 78 66 66  assert( (rc&0xff
18b20 29 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29  )!=SQLITE_BUSY )
18b30 3b 20 2f 2a 20 42 55 53 59 20 6e 6f 74 20 70 6f  ; /* BUSY not po
18b40 73 73 69 62 6c 65 20 77 68 65 6e 20 75 73 65 57  ssible when useW
18b50 61 6c 3d 3d 31 20 2a 2f 0a 20 20 20 20 74 65 73  al==1 */.    tes
18b60 74 63 61 73 65 28 20 28 72 63 26 30 78 66 66 29  tcase( (rc&0xff)
18b70 3d 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 20 29  ==SQLITE_IOERR )
18b80 3b 0a 20 20 20 20 74 65 73 74 63 61 73 65 28 20  ;.    testcase( 
18b90 72 63 3d 3d 53 51 4c 49 54 45 5f 50 52 4f 54 4f  rc==SQLITE_PROTO
18ba0 43 4f 4c 20 29 3b 0a 20 20 20 20 74 65 73 74 63  COL );.    testc
18bb0 61 73 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ase( rc==SQLITE_
18bc0 4f 4b 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  OK );.  }.  retu
18bd0 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
18be0 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75  Information abou
18bf0 74 20 74 68 65 20 63 75 72 72 65 6e 74 20 73 74  t the current st
18c00 61 74 65 20 6f 66 20 74 68 65 20 57 41 4c 20 66  ate of the WAL f
18c10 69 6c 65 20 61 6e 64 20 77 68 65 72 65 0a 2a 2a  ile and where.**
18c20 20 74 68 65 20 6e 65 78 74 20 66 73 79 6e 63 20   the next fsync 
18c30 73 68 6f 75 6c 64 20 6f 63 63 75 72 20 2d 20 70  should occur - p
18c40 61 73 73 65 64 20 66 72 6f 6d 20 73 71 6c 69 74  assed from sqlit
18c50 65 33 57 61 6c 46 72 61 6d 65 73 28 29 20 69 6e  e3WalFrames() in
18c60 74 6f 0a 2a 2a 20 77 61 6c 57 72 69 74 65 54 6f  to.** walWriteTo
18c70 4c 6f 67 28 29 2e 0a 2a 2f 0a 74 79 70 65 64 65  Log()..*/.typede
18c80 66 20 73 74 72 75 63 74 20 57 61 6c 57 72 69 74  f struct WalWrit
18c90 65 72 20 7b 0a 20 20 57 61 6c 20 2a 70 57 61 6c  er {.  Wal *pWal
18ca0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
18cb0 20 20 20 20 2f 2a 20 54 68 65 20 63 6f 6d 70 6c      /* The compl
18cc0 65 74 65 20 57 41 4c 20 69 6e 66 6f 72 6d 61 74  ete WAL informat
18cd0 69 6f 6e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ion */.  sqlite3
18ce0 5f 66 69 6c 65 20 2a 70 46 64 3b 20 20 20 20 20  _file *pFd;     
18cf0 20 20 20 20 20 20 2f 2a 20 54 68 65 20 57 41 4c        /* The WAL
18d00 20 66 69 6c 65 20 74 6f 20 77 68 69 63 68 20 77   file to which w
18d10 65 20 77 72 69 74 65 20 2a 2f 0a 20 20 73 71 6c  e write */.  sql
18d20 69 74 65 33 5f 69 6e 74 36 34 20 69 53 79 6e 63  ite3_int64 iSync
18d30 50 6f 69 6e 74 3b 20 20 20 20 2f 2a 20 46 73 79  Point;    /* Fsy
18d40 6e 63 20 61 74 20 74 68 69 73 20 6f 66 66 73 65  nc at this offse
18d50 74 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 46  t */.  int syncF
18d60 6c 61 67 73 3b 20 20 20 20 20 20 20 20 20 20 20  lags;           
18d70 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 66 6f 72      /* Flags for
18d80 20 74 68 65 20 66 73 79 6e 63 20 2a 2f 0a 20 20   the fsync */.  
18d90 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20 20  int szPage;     
18da0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
18db0 53 69 7a 65 20 6f 66 20 6f 6e 65 20 70 61 67 65  Size of one page
18dc0 20 2a 2f 0a 7d 20 57 61 6c 57 72 69 74 65 72 3b   */.} WalWriter;
18dd0 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 69 41  ../*.** Write iA
18de0 6d 74 20 62 79 74 65 73 20 6f 66 20 63 6f 6e 74  mt bytes of cont
18df0 65 6e 74 20 69 6e 74 6f 20 74 68 65 20 57 41 4c  ent into the WAL
18e00 20 66 69 6c 65 20 62 65 67 69 6e 6e 69 6e 67 20   file beginning 
18e10 61 74 20 69 4f 66 66 73 65 74 2e 0a 2a 2a 20 44  at iOffset..** D
18e20 6f 20 61 20 73 79 6e 63 20 77 68 65 6e 20 63 72  o a sync when cr
18e30 6f 73 73 69 6e 67 20 74 68 65 20 70 2d 3e 69 53  ossing the p->iS
18e40 79 6e 63 50 6f 69 6e 74 20 62 6f 75 6e 64 61 72  yncPoint boundar
18e50 79 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74 68 65  y..**.** In othe
18e60 72 20 77 6f 72 64 73 2c 20 69 66 20 69 53 79 6e  r words, if iSyn
18e70 63 50 6f 69 6e 74 20 69 73 20 69 6e 20 62 65 74  cPoint is in bet
18e80 77 65 65 6e 20 69 4f 66 66 73 65 74 20 61 6e 64  ween iOffset and
18e90 20 69 4f 66 66 73 65 74 2b 69 41 6d 74 2c 0a 2a   iOffset+iAmt,.*
18ea0 2a 20 66 69 72 73 74 20 77 72 69 74 65 20 74 68  * first write th
18eb0 65 20 70 61 72 74 20 62 65 66 6f 72 65 20 69 53  e part before iS
18ec0 79 6e 63 50 6f 69 6e 74 2c 20 74 68 65 6e 20 73  yncPoint, then s
18ed0 79 6e 63 2c 20 74 68 65 6e 20 77 72 69 74 65 20  ync, then write 
18ee0 74 68 65 0a 2a 2a 20 72 65 73 74 2e 0a 2a 2f 0a  the.** rest..*/.
18ef0 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 57 72  static int walWr
18f00 69 74 65 54 6f 4c 6f 67 28 0a 20 20 57 61 6c 57  iteToLog(.  WalW
18f10 72 69 74 65 72 20 2a 70 2c 20 20 20 20 20 20 20  riter *p,       
18f20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 74 6f         /* WAL to
18f30 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20 20 76   write to */.  v
18f40 6f 69 64 20 2a 70 43 6f 6e 74 65 6e 74 2c 20 20  oid *pContent,  
18f50 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e            /* Con
18f60 74 65 6e 74 20 74 6f 20 62 65 20 77 72 69 74 74  tent to be writt
18f70 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 41 6d 74  en */.  int iAmt
18f80 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
18f90 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
18fa0 62 79 74 65 73 20 74 6f 20 77 72 69 74 65 20 2a  bytes to write *
18fb0 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  /.  sqlite3_int6
18fc0 34 20 69 4f 66 66 73 65 74 20 20 20 20 20 20 2f  4 iOffset      /
18fd0 2a 20 53 74 61 72 74 20 77 72 69 74 69 6e 67 20  * Start writing 
18fe0 61 74 20 74 68 69 73 20 6f 66 66 73 65 74 20 2a  at this offset *
18ff0 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  /.){.  int rc;. 
19000 20 69 66 28 20 69 4f 66 66 73 65 74 3c 70 2d 3e   if( iOffset<p->
19010 69 53 79 6e 63 50 6f 69 6e 74 20 26 26 20 69 4f  iSyncPoint && iO
19020 66 66 73 65 74 2b 69 41 6d 74 3e 3d 70 2d 3e 69  ffset+iAmt>=p->i
19030 53 79 6e 63 50 6f 69 6e 74 20 29 7b 0a 20 20 20  SyncPoint ){.   
19040 20 69 6e 74 20 69 46 69 72 73 74 41 6d 74 20 3d   int iFirstAmt =
19050 20 28 69 6e 74 29 28 70 2d 3e 69 53 79 6e 63 50   (int)(p->iSyncP
19060 6f 69 6e 74 20 2d 20 69 4f 66 66 73 65 74 29 3b  oint - iOffset);
19070 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
19080 33 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 64 2c  3OsWrite(p->pFd,
19090 20 70 43 6f 6e 74 65 6e 74 2c 20 69 46 69 72 73   pContent, iFirs
190a0 74 41 6d 74 2c 20 69 4f 66 66 73 65 74 29 3b 0a  tAmt, iOffset);.
190b0 20 20 20 20 69 66 28 20 72 63 20 29 20 72 65 74      if( rc ) ret
190c0 75 72 6e 20 72 63 3b 0a 20 20 20 20 69 4f 66 66  urn rc;.    iOff
190d0 73 65 74 20 2b 3d 20 69 46 69 72 73 74 41 6d 74  set += iFirstAmt
190e0 3b 0a 20 20 20 20 69 41 6d 74 20 2d 3d 20 69 46  ;.    iAmt -= iF
190f0 69 72 73 74 41 6d 74 3b 0a 20 20 20 20 70 43 6f  irstAmt;.    pCo
19100 6e 74 65 6e 74 20 3d 20 28 76 6f 69 64 2a 29 28  ntent = (void*)(
19110 69 46 69 72 73 74 41 6d 74 20 2b 20 28 63 68 61  iFirstAmt + (cha
19120 72 2a 29 70 43 6f 6e 74 65 6e 74 29 3b 0a 20 20  r*)pContent);.  
19130 20 20 61 73 73 65 72 74 28 20 70 2d 3e 73 79 6e    assert( p->syn
19140 63 46 6c 61 67 73 20 26 20 28 53 51 4c 49 54 45  cFlags & (SQLITE
19150 5f 53 59 4e 43 5f 4e 4f 52 4d 41 4c 7c 53 51 4c  _SYNC_NORMAL|SQL
19160 49 54 45 5f 53 59 4e 43 5f 46 55 4c 4c 29 20 29  ITE_SYNC_FULL) )
19170 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
19180 65 33 4f 73 53 79 6e 63 28 70 2d 3e 70 46 64 2c  e3OsSync(p->pFd,
19190 20 70 2d 3e 73 79 6e 63 46 6c 61 67 73 29 3b 0a   p->syncFlags);.
191a0 20 20 20 20 69 66 28 20 69 41 6d 74 3d 3d 30 20      if( iAmt==0 
191b0 7c 7c 20 72 63 20 29 20 72 65 74 75 72 6e 20 72  || rc ) return r
191c0 63 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71  c;.  }.  rc = sq
191d0 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e  lite3OsWrite(p->
191e0 70 46 64 2c 20 70 43 6f 6e 74 65 6e 74 2c 20 69  pFd, pContent, i
191f0 41 6d 74 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20  Amt, iOffset);. 
19200 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
19210 2a 0a 2a 2a 20 57 72 69 74 65 20 6f 75 74 20 61  *.** Write out a
19220 20 73 69 6e 67 6c 65 20 66 72 61 6d 65 20 6f 66   single frame of
19230 20 74 68 65 20 57 41 4c 0a 2a 2f 0a 73 74 61 74   the WAL.*/.stat
19240 69 63 20 69 6e 74 20 77 61 6c 57 72 69 74 65 4f  ic int walWriteO
19250 6e 65 46 72 61 6d 65 28 0a 20 20 57 61 6c 57 72  neFrame(.  WalWr
19260 69 74 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20  iter *p,        
19270 20 20 20 20 20 20 20 2f 2a 20 57 68 65 72 65 20         /* Where 
19280 74 6f 20 77 72 69 74 65 20 74 68 65 20 66 72 61  to write the fra
19290 6d 65 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70  me */.  PgHdr *p
192a0 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20  Page,           
192b0 20 20 20 20 2f 2a 20 54 68 65 20 70 61 67 65 20      /* The page 
192c0 6f 66 20 74 68 65 20 66 72 61 6d 65 20 74 6f 20  of the frame to 
192d0 62 65 20 77 72 69 74 74 65 6e 20 2a 2f 0a 20 20  be written */.  
192e0 69 6e 74 20 6e 54 72 75 6e 63 61 74 65 2c 20 20  int nTruncate,  
192f0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
19300 68 65 20 63 6f 6d 6d 69 74 20 66 6c 61 67 2e 20  he commit flag. 
19310 20 55 73 75 61 6c 6c 79 20 30 2e 20 20 3e 30 20   Usually 0.  >0 
19320 66 6f 72 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20  for commit */.  
19330 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f  sqlite3_int64 iO
19340 66 66 73 65 74 20 20 20 20 20 20 20 2f 2a 20 42  ffset       /* B
19350 79 74 65 20 6f 66 66 73 65 74 20 61 74 20 77 68  yte offset at wh
19360 69 63 68 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a  ich to write */.
19370 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  ){.  int rc;    
19380 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19390 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 63       /* Result c
193a0 6f 64 65 20 66 72 6f 6d 20 73 75 62 66 75 6e 63  ode from subfunc
193b0 74 69 6f 6e 73 20 2a 2f 0a 20 20 76 6f 69 64 20  tions */.  void 
193c0 2a 70 44 61 74 61 3b 20 20 20 20 20 20 20 20 20  *pData;         
193d0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
193e0 74 61 20 61 63 74 75 61 6c 6c 79 20 77 72 69 74  ta actually writ
193f0 74 65 6e 20 2a 2f 0a 20 20 75 38 20 61 46 72 61  ten */.  u8 aFra
19400 6d 65 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52  me[WAL_FRAME_HDR
19410 53 49 5a 45 5d 3b 20 20 20 2f 2a 20 42 75 66 66  SIZE];   /* Buff
19420 65 72 20 74 6f 20 61 73 73 65 6d 62 6c 65 20 66  er to assemble f
19430 72 61 6d 65 2d 68 65 61 64 65 72 20 69 6e 20 2a  rame-header in *
19440 2f 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51  /.#if defined(SQ
19450 4c 49 54 45 5f 48 41 53 5f 43 4f 44 45 43 29 0a  LITE_HAS_CODEC).
19460 20 20 69 66 28 20 28 70 44 61 74 61 20 3d 20 73    if( (pData = s
19470 71 6c 69 74 65 33 50 61 67 65 72 43 6f 64 65 63  qlite3PagerCodec
19480 28 70 50 61 67 65 29 29 3d 3d 30 20 29 20 72 65  (pPage))==0 ) re
19490 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
194a0 4d 3b 0a 23 65 6c 73 65 0a 20 20 70 44 61 74 61  M;.#else.  pData
194b0 20 3d 20 70 50 61 67 65 2d 3e 70 44 61 74 61 3b   = pPage->pData;
194c0 0a 23 65 6e 64 69 66 0a 20 20 77 61 6c 45 6e 63  .#endif.  walEnc
194d0 6f 64 65 46 72 61 6d 65 28 70 2d 3e 70 57 61 6c  odeFrame(p->pWal
194e0 2c 20 70 50 61 67 65 2d 3e 70 67 6e 6f 2c 20 6e  , pPage->pgno, n
194f0 54 72 75 6e 63 61 74 65 2c 20 70 44 61 74 61 2c  Truncate, pData,
19500 20 61 46 72 61 6d 65 29 3b 0a 20 20 72 63 20 3d   aFrame);.  rc =
19510 20 77 61 6c 57 72 69 74 65 54 6f 4c 6f 67 28 70   walWriteToLog(p
19520 2c 20 61 46 72 61 6d 65 2c 20 73 69 7a 65 6f 66  , aFrame, sizeof
19530 28 61 46 72 61 6d 65 29 2c 20 69 4f 66 66 73 65  (aFrame), iOffse
19540 74 29 3b 0a 20 20 69 66 28 20 72 63 20 29 20 72  t);.  if( rc ) r
19550 65 74 75 72 6e 20 72 63 3b 0a 20 20 2f 2a 20 57  eturn rc;.  /* W
19560 72 69 74 65 20 74 68 65 20 70 61 67 65 20 64 61  rite the page da
19570 74 61 20 2a 2f 0a 20 20 72 63 20 3d 20 77 61 6c  ta */.  rc = wal
19580 57 72 69 74 65 54 6f 4c 6f 67 28 70 2c 20 70 44  WriteToLog(p, pD
19590 61 74 61 2c 20 70 2d 3e 73 7a 50 61 67 65 2c 20  ata, p->szPage, 
195a0 69 4f 66 66 73 65 74 2b 73 69 7a 65 6f 66 28 61  iOffset+sizeof(a
195b0 46 72 61 6d 65 29 29 3b 0a 20 20 72 65 74 75 72  Frame));.  retur
195c0 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  n rc;.}../* .** 
195d0 57 72 69 74 65 20 61 20 73 65 74 20 6f 66 20 66  Write a set of f
195e0 72 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67  rames to the log
195f0 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  . The caller mus
19600 74 20 68 6f 6c 64 20 74 68 65 20 77 72 69 74 65  t hold the write
19610 2d 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20  -lock.** on the 
19620 6c 6f 67 20 66 69 6c 65 20 28 6f 62 74 61 69 6e  log file (obtain
19630 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33  ed using sqlite3
19640 57 61 6c 42 65 67 69 6e 57 72 69 74 65 54 72 61  WalBeginWriteTra
19650 6e 73 61 63 74 69 6f 6e 28 29 29 2e 0a 2a 2f 0a  nsaction())..*/.
19660 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 46 72  int sqlite3WalFr
19670 61 6d 65 73 28 0a 20 20 57 61 6c 20 2a 70 57 61  ames(.  Wal *pWa
19680 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
19690 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 68          /* Wal h
196a0 61 6e 64 6c 65 20 74 6f 20 77 72 69 74 65 20 74  andle to write t
196b0 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67  o */.  int szPag
196c0 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
196d0 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
196e0 73 65 20 70 61 67 65 2d 73 69 7a 65 20 69 6e 20  se page-size in 
196f0 62 79 74 65 73 20 2a 2f 0a 20 20 50 67 48 64 72  bytes */.  PgHdr
19700 20 2a 70 4c 69 73 74 2c 20 20 20 20 20 20 20 20   *pList,        
19710 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69             /* Li
19720 73 74 20 6f 66 20 64 69 72 74 79 20 70 61 67 65  st of dirty page
19730 73 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20  s to write */.  
19740 50 67 6e 6f 20 6e 54 72 75 6e 63 61 74 65 2c 20  Pgno nTruncate, 
19750 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19760 2f 2a 20 44 61 74 61 62 61 73 65 20 73 69 7a 65  /* Database size
19770 20 61 66 74 65 72 20 74 68 69 73 20 63 6f 6d 6d   after this comm
19780 69 74 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43 6f  it */.  int isCo
19790 6d 6d 69 74 2c 20 20 20 20 20 20 20 20 20 20 20  mmit,           
197a0 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
197b0 69 66 20 74 68 69 73 20 69 73 20 61 20 63 6f 6d  if this is a com
197c0 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e  mit */.  int syn
197d0 63 5f 66 6c 61 67 73 20 20 20 20 20 20 20 20 20  c_flags         
197e0 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67           /* Flag
197f0 73 20 74 6f 20 70 61 73 73 20 74 6f 20 4f 73 53  s to pass to OsS
19800 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a  ync() (or 0) */.
19810 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  ){.  int rc;    
19820 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19830 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
19840 63 61 74 63 68 20 72 65 74 75 72 6e 20 63 6f 64  catch return cod
19850 65 73 20 2a 2f 0a 20 20 75 33 32 20 69 46 72 61  es */.  u32 iFra
19860 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  me;             
19870 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
19880 66 72 61 6d 65 20 61 64 64 72 65 73 73 20 2a 2f  frame address */
19890 0a 20 20 50 67 48 64 72 20 2a 70 3b 20 20 20 20  .  PgHdr *p;    
198a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
198b0 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74     /* Iterator t
198c0 6f 20 72 75 6e 20 74 68 72 6f 75 67 68 20 70 4c  o run through pL
198d0 69 73 74 20 77 69 74 68 2e 20 2a 2f 0a 20 20 50  ist with. */.  P
198e0 67 48 64 72 20 2a 70 4c 61 73 74 20 3d 20 30 3b  gHdr *pLast = 0;
198f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
19900 2a 20 4c 61 73 74 20 66 72 61 6d 65 20 69 6e 20  * Last frame in 
19910 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 45  list */.  int nE
19920 78 74 72 61 20 3d 20 30 3b 20 20 20 20 20 20 20  xtra = 0;       
19930 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
19940 62 65 72 20 6f 66 20 65 78 74 72 61 20 63 6f 70  ber of extra cop
19950 69 65 73 20 6f 66 20 6c 61 73 74 20 70 61 67 65  ies of last page
19960 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 46 72 61 6d   */.  int szFram
19970 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
19980 20 20 20 20 20 20 2f 2a 20 54 68 65 20 73 69 7a        /* The siz
19990 65 20 6f 66 20 61 20 73 69 6e 67 6c 65 20 66 72  e of a single fr
199a0 61 6d 65 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66  ame */.  i64 iOf
199b0 66 73 65 74 3b 20 20 20 20 20 20 20 20 20 20 20  fset;           
199c0 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
199d0 20 62 79 74 65 20 74 6f 20 77 72 69 74 65 20 69   byte to write i
199e0 6e 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20  n WAL file */.  
199f0 57 61 6c 57 72 69 74 65 72 20 77 3b 20 20 20 20  WalWriter w;    
19a00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19a10 2f 2a 20 54 68 65 20 77 72 69 74 65 72 20 2a 2f  /* The writer */
19a20 0a 0a 20 20 61 73 73 65 72 74 28 20 70 4c 69 73  ..  assert( pLis
19a30 74 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  t );.  assert( p
19a40 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29  Wal->writeLock )
19a50 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 69 73 20  ;..  /* If this 
19a60 66 72 61 6d 65 20 73 65 74 20 63 6f 6d 70 6c 65  frame set comple
19a70 74 65 73 20 61 20 74 72 61 6e 73 61 63 74 69 6f  tes a transactio
19a80 6e 2c 20 74 68 65 6e 20 6e 54 72 75 6e 63 61 74  n, then nTruncat
19a90 65 3e 30 2e 20 20 49 66 0a 20 20 2a 2a 20 6e 54  e>0.  If.  ** nT
19aa0 72 75 6e 63 61 74 65 3d 3d 30 20 74 68 65 6e 20  runcate==0 then 
19ab0 74 68 69 73 20 66 72 61 6d 65 20 73 65 74 20 64  this frame set d
19ac0 6f 65 73 20 6e 6f 74 20 63 6f 6d 70 6c 65 74 65  oes not complete
19ad0 20 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e   the transaction
19ae0 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 28  . */.  assert( (
19af0 69 73 43 6f 6d 6d 69 74 21 3d 30 29 3d 3d 28 6e  isCommit!=0)==(n
19b00 54 72 75 6e 63 61 74 65 21 3d 30 29 20 29 3b 0a  Truncate!=0) );.
19b10 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c  .#if defined(SQL
19b20 49 54 45 5f 54 45 53 54 29 20 26 26 20 64 65 66  ITE_TEST) && def
19b30 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42 55  ined(SQLITE_DEBU
19b40 47 29 0a 20 20 7b 20 69 6e 74 20 63 6e 74 3b 20  G).  { int cnt; 
19b50 66 6f 72 28 63 6e 74 3d 30 2c 20 70 3d 70 4c 69  for(cnt=0, p=pLi
19b60 73 74 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72  st; p; p=p->pDir
19b70 74 79 2c 20 63 6e 74 2b 2b 29 7b 7d 0a 20 20 20  ty, cnt++){}.   
19b80 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
19b90 70 3a 20 66 72 61 6d 65 20 77 72 69 74 65 20 62  p: frame write b
19ba0 65 67 69 6e 2e 20 25 64 20 66 72 61 6d 65 73 2e  egin. %d frames.
19bb0 20 6d 78 46 72 61 6d 65 3d 25 64 2e 20 25 73 5c   mxFrame=%d. %s\
19bc0 6e 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  n",.            
19bd0 20 20 70 57 61 6c 2c 20 63 6e 74 2c 20 70 57 61    pWal, cnt, pWa
19be0 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2c 20  l->hdr.mxFrame, 
19bf0 69 73 43 6f 6d 6d 69 74 20 3f 20 22 43 6f 6d 6d  isCommit ? "Comm
19c00 69 74 22 20 3a 20 22 53 70 69 6c 6c 22 29 29 3b  it" : "Spill"));
19c10 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2f  .  }.#endif..  /
19c20 2a 20 53 65 65 20 69 66 20 69 74 20 69 73 20 70  * See if it is p
19c30 6f 73 73 69 62 6c 65 20 74 6f 20 77 72 69 74 65  ossible to write
19c40 20 74 68 65 73 65 20 66 72 61 6d 65 73 20 69 6e   these frames in
19c50 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  to the start of 
19c60 74 68 65 0a 20 20 2a 2a 20 6c 6f 67 20 66 69 6c  the.  ** log fil
19c70 65 2c 20 69 6e 73 74 65 61 64 20 6f 66 20 61 70  e, instead of ap
19c80 70 65 6e 64 69 6e 67 20 74 6f 20 69 74 20 61 74  pending to it at
19c90 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
19ca0 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 53  me..  */.  if( S
19cb0 51 4c 49 54 45 5f 4f 4b 21 3d 28 72 63 20 3d 20  QLITE_OK!=(rc = 
19cc0 77 61 6c 52 65 73 74 61 72 74 4c 6f 67 28 70 57  walRestartLog(pW
19cd0 61 6c 29 29 20 29 7b 0a 20 20 20 20 72 65 74 75  al)) ){.    retu
19ce0 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  rn rc;.  }..  /*
19cf0 20 49 66 20 74 68 69 73 20 69 73 20 74 68 65 20   If this is the 
19d00 66 69 72 73 74 20 66 72 61 6d 65 20 77 72 69 74  first frame writ
19d10 74 65 6e 20 69 6e 74 6f 20 74 68 65 20 6c 6f 67  ten into the log
19d20 2c 20 77 72 69 74 65 20 74 68 65 20 57 41 4c 0a  , write the WAL.
19d30 20 20 2a 2a 20 68 65 61 64 65 72 20 74 6f 20 74    ** header to t
19d40 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  he start of the 
19d50 57 41 4c 20 66 69 6c 65 2e 20 53 65 65 20 63 6f  WAL file. See co
19d60 6d 6d 65 6e 74 73 20 61 74 20 74 68 65 20 74 6f  mments at the to
19d70 70 20 6f 66 0a 20 20 2a 2a 20 74 68 69 73 20 73  p of.  ** this s
19d80 6f 75 72 63 65 20 66 69 6c 65 20 66 6f 72 20 61  ource file for a
19d90 20 64 65 73 63 72 69 70 74 69 6f 6e 20 6f 66 20   description of 
19da0 74 68 65 20 57 41 4c 20 68 65 61 64 65 72 20 66  the WAL header f
19db0 6f 72 6d 61 74 2e 0a 20 20 2a 2f 0a 20 20 69 46  ormat..  */.  iF
19dc0 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72  rame = pWal->hdr
19dd0 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 69 66 28 20  .mxFrame;.  if( 
19de0 69 46 72 61 6d 65 3d 3d 30 20 29 7b 0a 20 20 20  iFrame==0 ){.   
19df0 20 75 38 20 61 57 61 6c 48 64 72 5b 57 41 4c 5f   u8 aWalHdr[WAL_
19e00 48 44 52 53 49 5a 45 5d 3b 20 20 20 20 20 20 2f  HDRSIZE];      /
19e10 2a 20 42 75 66 66 65 72 20 74 6f 20 61 73 73 65  * Buffer to asse
19e20 6d 62 6c 65 20 77 61 6c 2d 68 65 61 64 65 72 20  mble wal-header 
19e30 69 6e 20 2a 2f 0a 20 20 20 20 75 33 32 20 61 43  in */.    u32 aC
19e40 6b 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20  ksum[2];        
19e50 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b          /* Check
19e60 73 75 6d 20 66 6f 72 20 77 61 6c 2d 68 65 61 64  sum for wal-head
19e70 65 72 20 2a 2f 0a 0a 20 20 20 20 73 71 6c 69 74  er */..    sqlit
19e80 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c  e3Put4byte(&aWal
19e90 48 64 72 5b 30 5d 2c 20 28 57 41 4c 5f 4d 41 47  Hdr[0], (WAL_MAG
19ea0 49 43 20 7c 20 53 51 4c 49 54 45 5f 42 49 47 45  IC | SQLITE_BIGE
19eb0 4e 44 49 41 4e 29 29 3b 0a 20 20 20 20 73 71 6c  NDIAN));.    sql
19ec0 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57  ite3Put4byte(&aW
19ed0 61 6c 48 64 72 5b 34 5d 2c 20 57 41 4c 5f 4d 41  alHdr[4], WAL_MA
19ee0 58 5f 56 45 52 53 49 4f 4e 29 3b 0a 20 20 20 20  X_VERSION);.    
19ef0 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28  sqlite3Put4byte(
19f00 26 61 57 61 6c 48 64 72 5b 38 5d 2c 20 73 7a 50  &aWalHdr[8], szP
19f10 61 67 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  age);.    sqlite
19f20 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c 48  3Put4byte(&aWalH
19f30 64 72 5b 31 32 5d 2c 20 70 57 61 6c 2d 3e 6e 43  dr[12], pWal->nC
19f40 6b 70 74 29 3b 0a 20 20 20 20 69 66 28 20 70 57  kpt);.    if( pW
19f50 61 6c 2d 3e 6e 43 6b 70 74 3d 3d 30 20 29 20 73  al->nCkpt==0 ) s
19f60 71 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73  qlite3_randomnes
19f70 73 28 38 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61  s(8, pWal->hdr.a
19f80 53 61 6c 74 29 3b 0a 20 20 20 20 6d 65 6d 63 70  Salt);.    memcp
19f90 79 28 26 61 57 61 6c 48 64 72 5b 31 36 5d 2c 20  y(&aWalHdr[16], 
19fa0 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c  pWal->hdr.aSalt,
19fb0 20 38 29 3b 0a 20 20 20 20 77 61 6c 43 68 65 63   8);.    walChec
19fc0 6b 73 75 6d 42 79 74 65 73 28 31 2c 20 61 57 61  ksumBytes(1, aWa
19fd0 6c 48 64 72 2c 20 57 41 4c 5f 48 44 52 53 49 5a  lHdr, WAL_HDRSIZ
19fe0 45 2d 32 2a 34 2c 20 30 2c 20 61 43 6b 73 75 6d  E-2*4, 0, aCksum
19ff0 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75  );.    sqlite3Pu
1a000 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b  t4byte(&aWalHdr[
1a010 32 34 5d 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b  24], aCksum[0]);
1a020 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34  .    sqlite3Put4
1a030 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32 38  byte(&aWalHdr[28
1a040 5d 2c 20 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 20  ], aCksum[1]);. 
1a050 20 20 20 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a     .    pWal->sz
1a060 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20  Page = szPage;. 
1a070 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67     pWal->hdr.big
1a080 45 6e 64 43 6b 73 75 6d 20 3d 20 53 51 4c 49 54  EndCksum = SQLIT
1a090 45 5f 42 49 47 45 4e 44 49 41 4e 3b 0a 20 20 20  E_BIGENDIAN;.   
1a0a0 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
1a0b0 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 43 6b 73  eCksum[0] = aCks
1a0c0 75 6d 5b 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d  um[0];.    pWal-
1a0d0 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
1a0e0 5b 31 5d 20 3d 20 61 43 6b 73 75 6d 5b 31 5d 3b  [1] = aCksum[1];
1a0f0 0a 20 20 20 20 70 57 61 6c 2d 3e 74 72 75 6e 63  .    pWal->trunc
1a100 61 74 65 4f 6e 43 6f 6d 6d 69 74 20 3d 20 31 3b  ateOnCommit = 1;
1a110 0a 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ..    rc = sqlit
1a120 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e  e3OsWrite(pWal->
1a130 70 57 61 6c 46 64 2c 20 61 57 61 6c 48 64 72 2c  pWalFd, aWalHdr,
1a140 20 73 69 7a 65 6f 66 28 61 57 61 6c 48 64 72 29   sizeof(aWalHdr)
1a150 2c 20 30 29 3b 0a 20 20 20 20 57 41 4c 54 52 41  , 0);.    WALTRA
1a160 43 45 28 28 22 57 41 4c 25 70 3a 20 77 61 6c 2d  CE(("WAL%p: wal-
1a170 68 65 61 64 65 72 20 77 72 69 74 65 20 25 73 5c  header write %s\
1a180 6e 22 2c 20 70 57 61 6c 2c 20 72 63 20 3f 20 22  n", pWal, rc ? "
1a190 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29  failed" : "ok"))
1a1a0 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
1a1b0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
1a1c0 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
1a1d0 7d 0a 0a 20 20 20 20 2f 2a 20 53 79 6e 63 20 74  }..    /* Sync t
1a1e0 68 65 20 68 65 61 64 65 72 20 28 75 6e 6c 65 73  he header (unles
1a1f0 73 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 53  s SQLITE_IOCAP_S
1a200 45 51 55 45 4e 54 49 41 4c 20 69 73 20 74 72 75  EQUENTIAL is tru
1a210 65 20 6f 72 20 75 6e 6c 65 73 73 0a 20 20 20 20  e or unless.    
1a220 2a 2a 20 61 6c 6c 20 73 79 6e 63 69 6e 67 20 69  ** all syncing i
1a230 73 20 74 75 72 6e 65 64 20 6f 66 66 20 62 79 20  s turned off by 
1a240 50 52 41 47 4d 41 20 73 79 6e 63 68 72 6f 6e 6f  PRAGMA synchrono
1a250 75 73 3d 4f 46 46 29 2e 20 20 4f 74 68 65 72 77  us=OFF).  Otherw
1a260 69 73 65 0a 20 20 20 20 2a 2a 20 61 6e 20 6f 75  ise.    ** an ou
1a270 74 2d 6f 66 2d 6f 72 64 65 72 20 77 72 69 74 65  t-of-order write
1a280 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 57 41 4c   following a WAL
1a290 20 72 65 73 74 61 72 74 20 63 6f 75 6c 64 20 72   restart could r
1a2a0 65 73 75 6c 74 20 69 6e 0a 20 20 20 20 2a 2a 20  esult in.    ** 
1a2b0 64 61 74 61 62 61 73 65 20 63 6f 72 72 75 70 74  database corrupt
1a2c0 69 6f 6e 2e 20 20 53 65 65 20 74 68 65 20 74 69  ion.  See the ti
1a2d0 63 6b 65 74 3a 0a 20 20 20 20 2a 2a 0a 20 20 20  cket:.    **.   
1a2e0 20 2a 2a 20 20 20 20 20 68 74 74 70 3a 2f 2f 6c   **     http://l
1a2f0 6f 63 61 6c 68 6f 73 74 3a 35 39 31 2f 73 71 6c  ocalhost:591/sql
1a300 69 74 65 2f 69 6e 66 6f 2f 66 66 35 62 65 37 33  ite/info/ff5be73
1a310 64 65 65 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  dee.    */.    i
1a320 66 28 20 70 57 61 6c 2d 3e 73 79 6e 63 48 65 61  f( pWal->syncHea
1a330 64 65 72 20 26 26 20 73 79 6e 63 5f 66 6c 61 67  der && sync_flag
1a340 73 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  s ){.      rc = 
1a350 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 70 57  sqlite3OsSync(pW
1a360 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 73 79 6e 63  al->pWalFd, sync
1a370 5f 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f  _flags & SQLITE_
1a380 53 59 4e 43 5f 4d 41 53 4b 29 3b 0a 20 20 20 20  SYNC_MASK);.    
1a390 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72    if( rc ) retur
1a3a0 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  n rc;.    }.  }.
1a3b0 20 20 61 73 73 65 72 74 28 20 28 69 6e 74 29 70    assert( (int)p
1a3c0 57 61 6c 2d 3e 73 7a 50 61 67 65 3d 3d 73 7a 50  Wal->szPage==szP
1a3d0 61 67 65 20 29 3b 0a 0a 20 20 2f 2a 20 53 65 74  age );..  /* Set
1a3e0 75 70 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6e  up information n
1a3f0 65 65 64 65 64 20 74 6f 20 77 72 69 74 65 20 66  eeded to write f
1a400 72 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20 57  rames into the W
1a410 41 4c 20 2a 2f 0a 20 20 77 2e 70 57 61 6c 20 3d  AL */.  w.pWal =
1a420 20 70 57 61 6c 3b 0a 20 20 77 2e 70 46 64 20 3d   pWal;.  w.pFd =
1a430 20 70 57 61 6c 2d 3e 70 57 61 6c 46 64 3b 0a 20   pWal->pWalFd;. 
1a440 20 77 2e 69 53 79 6e 63 50 6f 69 6e 74 20 3d 20   w.iSyncPoint = 
1a450 30 3b 0a 20 20 77 2e 73 79 6e 63 46 6c 61 67 73  0;.  w.syncFlags
1a460 20 3d 20 73 79 6e 63 5f 66 6c 61 67 73 3b 0a 20   = sync_flags;. 
1a470 20 77 2e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61   w.szPage = szPa
1a480 67 65 3b 0a 20 20 69 4f 66 66 73 65 74 20 3d 20  ge;.  iOffset = 
1a490 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69  walFrameOffset(i
1a4a0 46 72 61 6d 65 2b 31 2c 20 73 7a 50 61 67 65 29  Frame+1, szPage)
1a4b0 3b 0a 20 20 73 7a 46 72 61 6d 65 20 3d 20 73 7a  ;.  szFrame = sz
1a4c0 50 61 67 65 20 2b 20 57 41 4c 5f 46 52 41 4d 45  Page + WAL_FRAME
1a4d0 5f 48 44 52 53 49 5a 45 3b 0a 0a 20 20 2f 2a 20  _HDRSIZE;..  /* 
1a4e0 57 72 69 74 65 20 61 6c 6c 20 66 72 61 6d 65 73  Write all frames
1a4f0 20 69 6e 74 6f 20 74 68 65 20 6c 6f 67 20 66 69   into the log fi
1a500 6c 65 20 65 78 61 63 74 6c 79 20 6f 6e 63 65 20  le exactly once 
1a510 2a 2f 0a 20 20 66 6f 72 28 70 3d 70 4c 69 73 74  */.  for(p=pList
1a520 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79  ; p; p=p->pDirty
1a530 29 7b 0a 20 20 20 20 69 6e 74 20 6e 44 62 53 69  ){.    int nDbSi
1a540 7a 65 3b 20 20 20 2f 2a 20 30 20 6e 6f 72 6d 61  ze;   /* 0 norma
1a550 6c 6c 79 2e 20 20 50 6f 73 69 74 69 76 65 20 3d  lly.  Positive =
1a560 3d 20 63 6f 6d 6d 69 74 20 66 6c 61 67 20 2a 2f  = commit flag */
1a570 0a 20 20 20 20 69 46 72 61 6d 65 2b 2b 3b 0a 20  .    iFrame++;. 
1a580 20 20 20 61 73 73 65 72 74 28 20 69 4f 66 66 73     assert( iOffs
1a590 65 74 3d 3d 77 61 6c 46 72 61 6d 65 4f 66 66 73  et==walFrameOffs
1a5a0 65 74 28 69 46 72 61 6d 65 2c 20 73 7a 50 61 67  et(iFrame, szPag
1a5b0 65 29 20 29 3b 0a 20 20 20 20 6e 44 62 53 69 7a  e) );.    nDbSiz
1a5c0 65 20 3d 20 28 69 73 43 6f 6d 6d 69 74 20 26 26  e = (isCommit &&
1a5d0 20 70 2d 3e 70 44 69 72 74 79 3d 3d 30 29 20 3f   p->pDirty==0) ?
1a5e0 20 6e 54 72 75 6e 63 61 74 65 20 3a 20 30 3b 0a   nTruncate : 0;.
1a5f0 20 20 20 20 72 63 20 3d 20 77 61 6c 57 72 69 74      rc = walWrit
1a600 65 4f 6e 65 46 72 61 6d 65 28 26 77 2c 20 70 2c  eOneFrame(&w, p,
1a610 20 6e 44 62 53 69 7a 65 2c 20 69 4f 66 66 73 65   nDbSize, iOffse
1a620 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63 20 29  t);.    if( rc )
1a630 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
1a640 70 4c 61 73 74 20 3d 20 70 3b 0a 20 20 20 20 69  pLast = p;.    i
1a650 4f 66 66 73 65 74 20 2b 3d 20 73 7a 46 72 61 6d  Offset += szFram
1a660 65 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20  e;.  }..  /* If 
1a670 74 68 69 73 20 69 73 20 74 68 65 20 65 6e 64 20  this is the end 
1a680 6f 66 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e  of a transaction
1a690 2c 20 74 68 65 6e 20 77 65 20 6d 69 67 68 74 20  , then we might 
1a6a0 6e 65 65 64 20 74 6f 20 70 61 64 0a 20 20 2a 2a  need to pad.  **
1a6b0 20 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e   the transaction
1a6c0 20 61 6e 64 2f 6f 72 20 73 79 6e 63 20 74 68 65   and/or sync the
1a6d0 20 57 41 4c 20 66 69 6c 65 2e 0a 20 20 2a 2a 0a   WAL file..  **.
1a6e0 20 20 2a 2a 20 50 61 64 64 69 6e 67 20 61 6e 64    ** Padding and
1a6f0 20 73 79 6e 63 69 6e 67 20 6f 6e 6c 79 20 6f 63   syncing only oc
1a700 63 75 72 20 69 66 20 74 68 69 73 20 73 65 74 20  cur if this set 
1a710 6f 66 20 66 72 61 6d 65 73 20 63 6f 6d 70 6c 65  of frames comple
1a720 74 65 20 61 0a 20 20 2a 2a 20 74 72 61 6e 73 61  te a.  ** transa
1a730 63 74 69 6f 6e 20 61 6e 64 20 69 66 20 50 52 41  ction and if PRA
1a740 47 4d 41 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d  GMA synchronous=
1a750 46 55 4c 4c 2e 20 20 49 66 20 73 79 6e 63 68 72  FULL.  If synchr
1a760 6f 6e 6f 75 73 3d 3d 4e 4f 52 4d 41 4c 0a 20 20  onous==NORMAL.  
1a770 2a 2a 20 6f 72 20 73 79 6e 63 68 6f 6e 6f 75 73  ** or synchonous
1a780 3d 3d 4f 46 46 2c 20 74 68 65 6e 20 6e 6f 20 70  ==OFF, then no p
1a790 61 64 64 69 6e 67 20 6f 72 20 73 79 6e 63 69 6e  adding or syncin
1a7a0 67 20 61 72 65 20 6e 65 65 64 65 64 2e 0a 20 20  g are needed..  
1a7b0 2a 2a 0a 20 20 2a 2a 20 49 66 20 53 51 4c 49 54  **.  ** If SQLIT
1a7c0 45 5f 49 4f 43 41 50 5f 50 4f 57 45 52 53 41 46  E_IOCAP_POWERSAF
1a7d0 45 5f 4f 56 45 52 57 52 49 54 45 20 69 73 20 64  E_OVERWRITE is d
1a7e0 65 66 69 6e 65 64 2c 20 74 68 65 6e 20 70 61 64  efined, then pad
1a7f0 64 69 6e 67 20 69 73 20 6e 6f 74 0a 20 20 2a 2a  ding is not.  **
1a800 20 6e 65 65 64 65 64 20 61 6e 64 20 6f 6e 6c 79   needed and only
1a810 20 74 68 65 20 73 79 6e 63 20 69 73 20 64 6f 6e   the sync is don
1a820 65 2e 20 20 49 66 20 70 61 64 64 69 6e 67 20 69  e.  If padding i
1a830 73 20 6e 65 65 64 65 64 2c 20 74 68 65 6e 20 74  s needed, then t
1a840 68 65 0a 20 20 2a 2a 20 66 69 6e 61 6c 20 66 72  he.  ** final fr
1a850 61 6d 65 20 69 73 20 72 65 70 65 61 74 65 64 20  ame is repeated 
1a860 28 77 69 74 68 20 69 74 73 20 63 6f 6d 6d 69 74  (with its commit
1a870 20 6d 61 72 6b 29 20 75 6e 74 69 6c 20 74 68 65   mark) until the
1a880 20 6e 65 78 74 20 73 65 63 74 6f 72 0a 20 20 2a   next sector.  *
1a890 2a 20 62 6f 75 6e 64 61 72 79 20 69 73 20 63 72  * boundary is cr
1a8a0 6f 73 73 65 64 2e 20 20 4f 6e 6c 79 20 74 68 65  ossed.  Only the
1a8b0 20 70 61 72 74 20 6f 66 20 74 68 65 20 57 41 4c   part of the WAL
1a8c0 20 70 72 69 6f 72 20 74 6f 20 74 68 65 20 6c 61   prior to the la
1a8d0 73 74 0a 20 20 2a 2a 20 73 65 63 74 6f 72 20 62  st.  ** sector b
1a8e0 6f 75 6e 64 61 72 79 20 69 73 20 73 79 6e 63 65  oundary is synce
1a8f0 64 3b 20 74 68 65 20 70 61 72 74 20 6f 66 20 74  d; the part of t
1a900 68 65 20 6c 61 73 74 20 66 72 61 6d 65 20 74 68  he last frame th
1a910 61 74 20 65 78 74 65 6e 64 73 0a 20 20 2a 2a 20  at extends.  ** 
1a920 70 61 73 74 20 74 68 65 20 73 65 63 74 6f 72 20  past the sector 
1a930 62 6f 75 6e 64 61 72 79 20 69 73 20 77 72 69 74  boundary is writ
1a940 74 65 6e 20 61 66 74 65 72 20 74 68 65 20 73 79  ten after the sy
1a950 6e 63 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69  nc..  */.  if( i
1a960 73 43 6f 6d 6d 69 74 20 26 26 20 28 73 79 6e 63  sCommit && (sync
1a970 5f 66 6c 61 67 73 20 26 20 57 41 4c 5f 53 59 4e  _flags & WAL_SYN
1a980 43 5f 54 52 41 4e 53 41 43 54 49 4f 4e 53 29 21  C_TRANSACTIONS)!
1a990 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57  =0 ){.    if( pW
1a9a0 61 6c 2d 3e 70 61 64 54 6f 53 65 63 74 6f 72 42  al->padToSectorB
1a9b0 6f 75 6e 64 61 72 79 20 29 7b 0a 20 20 20 20 20  oundary ){.     
1a9c0 20 69 6e 74 20 73 65 63 74 6f 72 53 69 7a 65 20   int sectorSize 
1a9d0 3d 20 73 71 6c 69 74 65 33 53 65 63 74 6f 72 53  = sqlite3SectorS
1a9e0 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ize(pWal->pWalFd
1a9f0 29 3b 0a 20 20 20 20 20 20 77 2e 69 53 79 6e 63  );.      w.iSync
1aa00 50 6f 69 6e 74 20 3d 20 28 28 69 4f 66 66 73 65  Point = ((iOffse
1aa10 74 2b 73 65 63 74 6f 72 53 69 7a 65 2d 31 29 2f  t+sectorSize-1)/
1aa20 73 65 63 74 6f 72 53 69 7a 65 29 2a 73 65 63 74  sectorSize)*sect
1aa30 6f 72 53 69 7a 65 3b 0a 20 20 20 20 20 20 77 68  orSize;.      wh
1aa40 69 6c 65 28 20 69 4f 66 66 73 65 74 3c 77 2e 69  ile( iOffset<w.i
1aa50 53 79 6e 63 50 6f 69 6e 74 20 29 7b 0a 20 20 20  SyncPoint ){.   
1aa60 20 20 20 20 20 72 63 20 3d 20 77 61 6c 57 72 69       rc = walWri
1aa70 74 65 4f 6e 65 46 72 61 6d 65 28 26 77 2c 20 70  teOneFrame(&w, p
1aa80 4c 61 73 74 2c 20 6e 54 72 75 6e 63 61 74 65 2c  Last, nTruncate,
1aa90 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20   iOffset);.     
1aaa0 20 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75     if( rc ) retu
1aab0 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 20 20 69  rn rc;.        i
1aac0 4f 66 66 73 65 74 20 2b 3d 20 73 7a 46 72 61 6d  Offset += szFram
1aad0 65 3b 0a 20 20 20 20 20 20 20 20 6e 45 78 74 72  e;.        nExtr
1aae0 61 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  a++;.      }.   
1aaf0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
1ab00 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63   = sqlite3OsSync
1ab10 28 77 2e 70 46 64 2c 20 73 79 6e 63 5f 66 6c 61  (w.pFd, sync_fla
1ab20 67 73 20 26 20 53 51 4c 49 54 45 5f 53 59 4e 43  gs & SQLITE_SYNC
1ab30 5f 4d 41 53 4b 29 3b 0a 20 20 20 20 7d 0a 20 20  _MASK);.    }.  
1ab40 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 69 73 20  }..  /* If this 
1ab50 66 72 61 6d 65 20 73 65 74 20 63 6f 6d 70 6c 65  frame set comple
1ab60 74 65 73 20 74 68 65 20 66 69 72 73 74 20 74 72  tes the first tr
1ab70 61 6e 73 61 63 74 69 6f 6e 20 69 6e 20 74 68 65  ansaction in the
1ab80 20 57 41 4c 20 61 6e 64 0a 20 20 2a 2a 20 69 66   WAL and.  ** if
1ab90 20 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f   PRAGMA journal_
1aba0 73 69 7a 65 5f 6c 69 6d 69 74 20 69 73 20 73 65  size_limit is se
1abb0 74 2c 20 74 68 65 6e 20 74 72 75 6e 63 61 74 65  t, then truncate
1abc0 20 74 68 65 20 57 41 4c 20 74 6f 20 74 68 65 0a   the WAL to the.
1abd0 20 20 2a 2a 20 6a 6f 75 72 6e 61 6c 20 73 69 7a    ** journal siz
1abe0 65 20 6c 69 6d 69 74 2c 20 69 66 20 70 6f 73 73  e limit, if poss
1abf0 69 62 6c 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  ible..  */.  if(
1ac00 20 69 73 43 6f 6d 6d 69 74 20 26 26 20 70 57 61   isCommit && pWa
1ac10 6c 2d 3e 74 72 75 6e 63 61 74 65 4f 6e 43 6f 6d  l->truncateOnCom
1ac20 6d 69 74 20 26 26 20 70 57 61 6c 2d 3e 6d 78 57  mit && pWal->mxW
1ac30 61 6c 53 69 7a 65 3e 3d 30 20 29 7b 0a 20 20 20  alSize>=0 ){.   
1ac40 20 69 36 34 20 73 7a 20 3d 20 70 57 61 6c 2d 3e   i64 sz = pWal->
1ac50 6d 78 57 61 6c 53 69 7a 65 3b 0a 20 20 20 20 69  mxWalSize;.    i
1ac60 66 28 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65  f( walFrameOffse
1ac70 74 28 69 46 72 61 6d 65 2b 6e 45 78 74 72 61 2b  t(iFrame+nExtra+
1ac80 31 2c 20 73 7a 50 61 67 65 29 3e 70 57 61 6c 2d  1, szPage)>pWal-
1ac90 3e 6d 78 57 61 6c 53 69 7a 65 20 29 7b 0a 20 20  >mxWalSize ){.  
1aca0 20 20 20 20 73 7a 20 3d 20 77 61 6c 46 72 61 6d      sz = walFram
1acb0 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2b 6e  eOffset(iFrame+n
1acc0 45 78 74 72 61 2b 31 2c 20 73 7a 50 61 67 65 29  Extra+1, szPage)
1acd0 3b 0a 20 20 20 20 7d 0a 20 20 20 20 77 61 6c 4c  ;.    }.    walL
1ace0 69 6d 69 74 53 69 7a 65 28 70 57 61 6c 2c 20 73  imitSize(pWal, s
1acf0 7a 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 74 72  z);.    pWal->tr
1ad00 75 6e 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 20 3d  uncateOnCommit =
1ad10 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 70   0;.  }..  /* Ap
1ad20 70 65 6e 64 20 64 61 74 61 20 74 6f 20 74 68 65  pend data to the
1ad30 20 77 61 6c 2d 69 6e 64 65 78 2e 20 49 74 20 69   wal-index. It i
1ad40 73 20 6e 6f 74 20 6e 65 63 65 73 73 61 72 79 20  s not necessary 
1ad50 74 6f 20 6c 6f 63 6b 20 74 68 65 20 0a 20 20 2a  to lock the .  *
1ad60 2a 20 77 61 6c 2d 69 6e 64 65 78 20 74 6f 20 64  * wal-index to d
1ad70 6f 20 74 68 69 73 20 61 73 20 74 68 65 20 53 51  o this as the SQ
1ad80 4c 49 54 45 5f 53 48 4d 5f 57 52 49 54 45 20 6c  LITE_SHM_WRITE l
1ad90 6f 63 6b 20 68 65 6c 64 20 6f 6e 20 74 68 65 20  ock held on the 
1ada0 77 61 6c 2d 69 6e 64 65 78 0a 20 20 2a 2a 20 67  wal-index.  ** g
1adb0 75 61 72 61 6e 74 65 65 73 20 74 68 61 74 20 74  uarantees that t
1adc0 68 65 72 65 20 61 72 65 20 6e 6f 20 6f 74 68 65  here are no othe
1add0 72 20 77 72 69 74 65 72 73 2c 20 61 6e 64 20 6e  r writers, and n
1ade0 6f 20 64 61 74 61 20 74 68 61 74 20 6d 61 79 0a  o data that may.
1adf0 20 20 2a 2a 20 62 65 20 69 6e 20 75 73 65 20 62    ** be in use b
1ae00 79 20 65 78 69 73 74 69 6e 67 20 72 65 61 64 65  y existing reade
1ae10 72 73 20 69 73 20 62 65 69 6e 67 20 6f 76 65 72  rs is being over
1ae20 77 72 69 74 74 65 6e 2e 0a 20 20 2a 2f 0a 20 20  written..  */.  
1ae30 69 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68  iFrame = pWal->h
1ae40 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 66 6f  dr.mxFrame;.  fo
1ae50 72 28 70 3d 70 4c 69 73 74 3b 20 70 20 26 26 20  r(p=pList; p && 
1ae60 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 70  rc==SQLITE_OK; p
1ae70 3d 70 2d 3e 70 44 69 72 74 79 29 7b 0a 20 20 20  =p->pDirty){.   
1ae80 20 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 72   iFrame++;.    r
1ae90 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65  c = walIndexAppe
1aea0 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c  nd(pWal, iFrame,
1aeb0 20 70 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 20   p->pgno);.  }. 
1aec0 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49   while( rc==SQLI
1aed0 54 45 5f 4f 4b 20 26 26 20 6e 45 78 74 72 61 3e  TE_OK && nExtra>
1aee0 30 20 29 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b  0 ){.    iFrame+
1aef0 2b 3b 0a 20 20 20 20 6e 45 78 74 72 61 2d 2d 3b  +;.    nExtra--;
1af00 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64  .    rc = walInd
1af10 65 78 41 70 70 65 6e 64 28 70 57 61 6c 2c 20 69  exAppend(pWal, i
1af20 46 72 61 6d 65 2c 20 70 4c 61 73 74 2d 3e 70 67  Frame, pLast->pg
1af30 6e 6f 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  no);.  }..  if( 
1af40 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1af50 0a 20 20 20 20 2f 2a 20 55 70 64 61 74 65 20 74  .    /* Update t
1af60 68 65 20 70 72 69 76 61 74 65 20 63 6f 70 79 20  he private copy 
1af70 6f 66 20 74 68 65 20 68 65 61 64 65 72 2e 20 2a  of the header. *
1af80 2f 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  /.    pWal->hdr.
1af90 73 7a 50 61 67 65 20 3d 20 28 75 31 36 29 28 28  szPage = (u16)((
1afa0 73 7a 50 61 67 65 26 30 78 66 66 30 30 29 20 7c  szPage&0xff00) |
1afb0 20 28 73 7a 50 61 67 65 3e 3e 31 36 29 29 3b 0a   (szPage>>16));.
1afc0 20 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a      testcase( sz
1afd0 50 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20  Page<=32768 );. 
1afe0 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50     testcase( szP
1aff0 61 67 65 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20  age>=65536 );.  
1b000 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72    pWal->hdr.mxFr
1b010 61 6d 65 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20  ame = iFrame;.  
1b020 20 20 69 66 28 20 69 73 43 6f 6d 6d 69 74 20 29    if( isCommit )
1b030 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64  {.      pWal->hd
1b040 72 2e 69 43 68 61 6e 67 65 2b 2b 3b 0a 20 20 20  r.iChange++;.   
1b050 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61     pWal->hdr.nPa
1b060 67 65 20 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a  ge = nTruncate;.
1b070 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20 49 66 20      }.    /* If 
1b080 74 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74  this is a commit
1b090 2c 20 75 70 64 61 74 65 20 74 68 65 20 77 61 6c  , update the wal
1b0a0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f  -index header to
1b0b0 6f 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 69 73  o. */.    if( is
1b0c0 43 6f 6d 6d 69 74 20 29 7b 0a 20 20 20 20 20 20  Commit ){.      
1b0d0 77 61 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72  walIndexWriteHdr
1b0e0 28 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 70 57  (pWal);.      pW
1b0f0 61 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20  al->iCallback = 
1b100 69 46 72 61 6d 65 3b 0a 20 20 20 20 7d 0a 20 20  iFrame;.    }.  
1b110 7d 0a 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  }..  WALTRACE(("
1b120 57 41 4c 25 70 3a 20 66 72 61 6d 65 20 77 72 69  WAL%p: frame wri
1b130 74 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20  te %s\n", pWal, 
1b140 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20  rc ? "failed" : 
1b150 22 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75 72 6e  "ok"));.  return
1b160 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54   rc;.}../* .** T
1b170 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63  his routine is c
1b180 61 6c 6c 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65  alled to impleme
1b190 6e 74 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63  nt sqlite3_wal_c
1b1a0 68 65 63 6b 70 6f 69 6e 74 28 29 20 61 6e 64 0a  heckpoint() and.
1b1b0 2a 2a 20 72 65 6c 61 74 65 64 20 69 6e 74 65 72  ** related inter
1b1c0 66 61 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74  faces..**.** Obt
1b1d0 61 69 6e 20 61 20 43 48 45 43 4b 50 4f 49 4e 54  ain a CHECKPOINT
1b1e0 20 6c 6f 63 6b 20 61 6e 64 20 74 68 65 6e 20 62   lock and then b
1b1f0 61 63 6b 66 69 6c 6c 20 61 73 20 6d 75 63 68 20  ackfill as much 
1b200 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 73 0a 2a  information as.*
1b210 2a 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 57 41  * we can from WA
1b220 4c 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  L into the datab
1b230 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70 61  ase..**.** If pa
1b240 72 61 6d 65 74 65 72 20 78 42 75 73 79 20 69 73  rameter xBusy is
1b250 20 6e 6f 74 20 4e 55 4c 4c 2c 20 69 74 20 69 73   not NULL, it is
1b260 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20   a pointer to a 
1b270 62 75 73 79 2d 68 61 6e 64 6c 65 72 0a 2a 2a 20  busy-handler.** 
1b280 63 61 6c 6c 62 61 63 6b 2e 20 49 6e 20 74 68 69  callback. In thi
1b290 73 20 63 61 73 65 20 74 68 69 73 20 66 75 6e 63  s case this func
1b2a0 74 69 6f 6e 20 72 75 6e 73 20 61 20 62 6c 6f 63  tion runs a bloc
1b2b0 6b 69 6e 67 20 63 68 65 63 6b 70 6f 69 6e 74 2e  king checkpoint.
1b2c0 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
1b2d0 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a 20 20  alCheckpoint(.  
1b2e0 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20  Wal *pWal,      
1b2f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b300 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65 63 74 69 6f  /* Wal connectio
1b310 6e 20 2a 2f 0a 20 20 69 6e 74 20 65 4d 6f 64 65  n */.  int eMode
1b320 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1b330 20 20 20 20 20 20 20 2f 2a 20 50 41 53 53 49 56         /* PASSIV
1b340 45 2c 20 46 55 4c 4c 20 6f 72 20 52 45 53 54 41  E, FULL or RESTA
1b350 52 54 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 42  RT */.  int (*xB
1b360 75 73 79 29 28 76 6f 69 64 2a 29 2c 20 20 20 20  usy)(void*),    
1b370 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74          /* Funct
1b380 69 6f 6e 20 74 6f 20 63 61 6c 6c 20 77 68 65 6e  ion to call when
1b390 20 62 75 73 79 20 2a 2f 0a 20 20 76 6f 69 64 20   busy */.  void 
1b3a0 2a 70 42 75 73 79 41 72 67 2c 20 20 20 20 20 20  *pBusyArg,      
1b3b0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
1b3c0 6e 74 65 78 74 20 61 72 67 75 6d 65 6e 74 20 66  ntext argument f
1b3d0 6f 72 20 78 42 75 73 79 48 61 6e 64 6c 65 72 20  or xBusyHandler 
1b3e0 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c  */.  int sync_fl
1b3f0 61 67 73 2c 20 20 20 20 20 20 20 20 20 20 20 20  ags,            
1b400 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f       /* Flags to
1b410 20 73 79 6e 63 20 64 62 20 66 69 6c 65 20 77 69   sync db file wi
1b420 74 68 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20 69  th (or 0) */.  i
1b430 6e 74 20 6e 42 75 66 2c 20 20 20 20 20 20 20 20  nt nBuf,        
1b440 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b450 2a 20 53 69 7a 65 20 6f 66 20 74 65 6d 70 6f 72  * Size of tempor
1b460 61 72 79 20 62 75 66 66 65 72 20 2a 2f 0a 20 20  ary buffer */.  
1b470 75 38 20 2a 7a 42 75 66 2c 20 20 20 20 20 20 20  u8 *zBuf,       
1b480 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b490 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62 75 66  /* Temporary buf
1b4a0 66 65 72 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20  fer to use */.  
1b4b0 69 6e 74 20 2a 70 6e 4c 6f 67 2c 20 20 20 20 20  int *pnLog,     
1b4c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b4d0 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f  /* OUT: Number o
1b4e0 66 20 66 72 61 6d 65 73 20 69 6e 20 57 41 4c 20  f frames in WAL 
1b4f0 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 43 6b 70 74  */.  int *pnCkpt
1b500 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b510 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d       /* OUT: Num
1b520 62 65 72 20 6f 66 20 62 61 63 6b 66 69 6c 6c 65  ber of backfille
1b530 64 20 66 72 61 6d 65 73 20 69 6e 20 57 41 4c 20  d frames in WAL 
1b540 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  */.){.  int rc; 
1b550 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b560 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
1b570 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
1b580 69 73 43 68 61 6e 67 65 64 20 3d 20 30 3b 20 20  isChanged = 0;  
1b590 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1b5a0 72 75 65 20 69 66 20 61 20 6e 65 77 20 77 61 6c  rue if a new wal
1b5b0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73  -index header is
1b5c0 20 6c 6f 61 64 65 64 20 2a 2f 0a 20 20 69 6e 74   loaded */.  int
1b5d0 20 65 4d 6f 64 65 32 20 3d 20 65 4d 6f 64 65 3b   eMode2 = eMode;
1b5e0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1b5f0 4d 6f 64 65 20 74 6f 20 70 61 73 73 20 74 6f 20  Mode to pass to 
1b600 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 29 20  walCheckpoint() 
1b610 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57  */..  assert( pW
1b620 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 30 20  al->ckptLock==0 
1b630 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  );.  assert( pWa
1b640 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20  l->writeLock==0 
1b650 29 3b 0a 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  );..  if( pWal->
1b660 72 65 61 64 4f 6e 6c 79 20 29 20 72 65 74 75 72  readOnly ) retur
1b670 6e 20 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c  n SQLITE_READONL
1b680 59 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  Y;.  WALTRACE(("
1b690 57 41 4c 25 70 3a 20 63 68 65 63 6b 70 6f 69 6e  WAL%p: checkpoin
1b6a0 74 20 62 65 67 69 6e 73 5c 6e 22 2c 20 70 57 61  t begins\n", pWa
1b6b0 6c 29 29 3b 0a 20 20 72 63 20 3d 20 77 61 6c 4c  l));.  rc = walL
1b6c0 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
1b6d0 6c 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b  l, WAL_CKPT_LOCK
1b6e0 2c 20 31 29 3b 0a 20 20 69 66 28 20 72 63 20 29  , 1);.  if( rc )
1b6f0 7b 0a 20 20 20 20 2f 2a 20 55 73 75 61 6c 6c 79  {.    /* Usually
1b700 20 74 68 69 73 20 69 73 20 53 51 4c 49 54 45 5f   this is SQLITE_
1b710 42 55 53 59 20 6d 65 61 6e 69 6e 67 20 74 68 61  BUSY meaning tha
1b720 74 20 61 6e 6f 74 68 65 72 20 74 68 72 65 61 64  t another thread
1b730 20 6f 72 20 70 72 6f 63 65 73 73 0a 20 20 20 20   or process.    
1b740 2a 2a 20 69 73 20 61 6c 72 65 61 64 79 20 72 75  ** is already ru
1b750 6e 6e 69 6e 67 20 61 20 63 68 65 63 6b 70 6f 69  nning a checkpoi
1b760 6e 74 2c 20 6f 72 20 6d 61 79 62 65 20 61 20 72  nt, or maybe a r
1b770 65 63 6f 76 65 72 79 2e 20 20 42 75 74 20 69 74  ecovery.  But it
1b780 20 6d 69 67 68 74 0a 20 20 20 20 2a 2a 20 61 6c   might.    ** al
1b790 73 6f 20 62 65 20 53 51 4c 49 54 45 5f 49 4f 45  so be SQLITE_IOE
1b7a0 52 52 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72  RR. */.    retur
1b7b0 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70 57 61 6c  n rc;.  }.  pWal
1b7c0 2d 3e 63 6b 70 74 4c 6f 63 6b 20 3d 20 31 3b 0a  ->ckptLock = 1;.
1b7d0 0a 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73  .  /* If this is
1b7e0 20 61 20 62 6c 6f 63 6b 69 6e 67 2d 63 68 65 63   a blocking-chec
1b7f0 6b 70 6f 69 6e 74 2c 20 74 68 65 6e 20 6f 62 74  kpoint, then obt
1b800 61 69 6e 20 74 68 65 20 77 72 69 74 65 2d 6c 6f  ain the write-lo
1b810 63 6b 20 61 73 20 77 65 6c 6c 0a 20 20 2a 2a 20  ck as well.  ** 
1b820 74 6f 20 70 72 65 76 65 6e 74 20 61 6e 79 20 77  to prevent any w
1b830 72 69 74 65 72 73 20 66 72 6f 6d 20 72 75 6e 6e  riters from runn
1b840 69 6e 67 20 77 68 69 6c 65 20 74 68 65 20 63 68  ing while the ch
1b850 65 63 6b 70 6f 69 6e 74 20 69 73 20 75 6e 64 65  eckpoint is unde
1b860 72 77 61 79 2e 0a 20 20 2a 2a 20 54 68 69 73 20  rway..  ** This 
1b870 68 61 73 20 74 6f 20 62 65 20 64 6f 6e 65 20 62  has to be done b
1b880 65 66 6f 72 65 20 74 68 65 20 63 61 6c 6c 20 74  efore the call t
1b890 6f 20 77 61 6c 49 6e 64 65 78 52 65 61 64 48 64  o walIndexReadHd
1b8a0 72 28 29 20 62 65 6c 6f 77 2e 0a 20 20 2a 2a 0a  r() below..  **.
1b8b0 20 20 2a 2a 20 49 66 20 74 68 65 20 77 72 69 74    ** If the writ
1b8c0 65 72 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62  er lock cannot b
1b8d0 65 20 6f 62 74 61 69 6e 65 64 2c 20 74 68 65 6e  e obtained, then
1b8e0 20 61 20 70 61 73 73 69 76 65 20 63 68 65 63 6b   a passive check
1b8f0 70 6f 69 6e 74 20 69 73 0a 20 20 2a 2a 20 72 75  point is.  ** ru
1b900 6e 20 69 6e 73 74 65 61 64 2e 20 53 69 6e 63 65  n instead. Since
1b910 20 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 65   the checkpointe
1b920 72 20 69 73 20 6e 6f 74 20 68 6f 6c 64 69 6e 67  r is not holding
1b930 20 74 68 65 20 77 72 69 74 65 72 20 6c 6f 63 6b   the writer lock
1b940 2c 0a 20 20 2a 2a 20 74 68 65 72 65 20 69 73 20  ,.  ** there is 
1b950 6e 6f 20 70 6f 69 6e 74 20 69 6e 20 62 6c 6f 63  no point in bloc
1b960 6b 69 6e 67 20 77 61 69 74 69 6e 67 20 66 6f 72  king waiting for
1b970 20 61 6e 79 20 72 65 61 64 65 72 73 2e 20 41 73   any readers. As
1b980 73 75 6d 69 6e 67 20 6e 6f 20 0a 20 20 2a 2a 20  suming no .  ** 
1b990 6f 74 68 65 72 20 65 72 72 6f 72 20 6f 63 63 75  other error occu
1b9a0 72 73 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f  rs, this functio
1b9b0 6e 20 77 69 6c 6c 20 72 65 74 75 72 6e 20 53 51  n will return SQ
1b9c0 4c 49 54 45 5f 42 55 53 59 20 74 6f 20 74 68 65  LITE_BUSY to the
1b9d0 20 63 61 6c 6c 65 72 2e 0a 20 20 2a 2f 0a 20 20   caller..  */.  
1b9e0 69 66 28 20 65 4d 6f 64 65 21 3d 53 51 4c 49 54  if( eMode!=SQLIT
1b9f0 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53  E_CHECKPOINT_PAS
1ba00 53 49 56 45 20 29 7b 0a 20 20 20 20 72 63 20 3d  SIVE ){.    rc =
1ba10 20 77 61 6c 42 75 73 79 4c 6f 63 6b 28 70 57 61   walBusyLock(pWa
1ba20 6c 2c 20 78 42 75 73 79 2c 20 70 42 75 73 79 41  l, xBusy, pBusyA
1ba30 72 67 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f  rg, WAL_WRITE_LO
1ba40 43 4b 2c 20 31 29 3b 0a 20 20 20 20 69 66 28 20  CK, 1);.    if( 
1ba50 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1ba60 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 77 72 69  .      pWal->wri
1ba70 74 65 4c 6f 63 6b 20 3d 20 31 3b 0a 20 20 20 20  teLock = 1;.    
1ba80 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51  }else if( rc==SQ
1ba90 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
1baa0 20 20 20 65 4d 6f 64 65 32 20 3d 20 53 51 4c 49     eMode2 = SQLI
1bab0 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41  TE_CHECKPOINT_PA
1bac0 53 53 49 56 45 3b 0a 20 20 20 20 20 20 72 63 20  SSIVE;.      rc 
1bad0 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20  = SQLITE_OK;.   
1bae0 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 61   }.  }..  /* Rea
1baf0 64 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  d the wal-index 
1bb00 68 65 61 64 65 72 2e 20 2a 2f 0a 20 20 69 66 28  header. */.  if(
1bb10 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
1bb20 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e  {.    rc = walIn
1bb30 64 65 78 52 65 61 64 48 64 72 28 70 57 61 6c 2c  dexReadHdr(pWal,
1bb40 20 26 69 73 43 68 61 6e 67 65 64 29 3b 0a 20 20   &isChanged);.  
1bb50 20 20 69 66 28 20 69 73 43 68 61 6e 67 65 64 20    if( isChanged 
1bb60 26 26 20 70 57 61 6c 2d 3e 70 44 62 46 64 2d 3e  && pWal->pDbFd->
1bb70 70 4d 65 74 68 6f 64 73 2d 3e 69 56 65 72 73 69  pMethods->iVersi
1bb80 6f 6e 3e 3d 33 20 29 7b 0a 20 20 20 20 20 20 73  on>=3 ){.      s
1bb90 71 6c 69 74 65 33 4f 73 55 6e 66 65 74 63 68 28  qlite3OsUnfetch(
1bba0 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 30 2c 20  pWal->pDbFd, 0, 
1bbb0 30 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  0);.    }.  }.. 
1bbc0 20 2f 2a 20 43 6f 70 79 20 64 61 74 61 20 66 72   /* Copy data fr
1bbd0 6f 6d 20 74 68 65 20 6c 6f 67 20 74 6f 20 74 68  om the log to th
1bbe0 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e  e database file.
1bbf0 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   */.  if( rc==SQ
1bc00 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  LITE_OK ){.    i
1bc10 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  f( pWal->hdr.mxF
1bc20 72 61 6d 65 20 26 26 20 77 61 6c 50 61 67 65 73  rame && walPages
1bc30 69 7a 65 28 70 57 61 6c 29 21 3d 6e 42 75 66 20  ize(pWal)!=nBuf 
1bc40 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  ){.      rc = SQ
1bc50 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50  LITE_CORRUPT_BKP
1bc60 54 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  T;.    }else{.  
1bc70 20 20 20 20 72 63 20 3d 20 77 61 6c 43 68 65 63      rc = walChec
1bc80 6b 70 6f 69 6e 74 28 70 57 61 6c 2c 20 65 4d 6f  kpoint(pWal, eMo
1bc90 64 65 32 2c 20 78 42 75 73 79 2c 20 70 42 75 73  de2, xBusy, pBus
1bca0 79 41 72 67 2c 20 73 79 6e 63 5f 66 6c 61 67 73  yArg, sync_flags
1bcb0 2c 20 7a 42 75 66 29 3b 0a 20 20 20 20 7d 0a 0a  , zBuf);.    }..
1bcc0 20 20 20 20 2f 2a 20 49 66 20 6e 6f 20 65 72 72      /* If no err
1bcd0 6f 72 20 6f 63 63 75 72 72 65 64 2c 20 73 65 74  or occurred, set
1bce0 20 74 68 65 20 6f 75 74 70 75 74 20 76 61 72 69   the output vari
1bcf0 61 62 6c 65 73 2e 20 2a 2f 0a 20 20 20 20 69 66  ables. */.    if
1bd00 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1bd10 7c 7c 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  || rc==SQLITE_BU
1bd20 53 59 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  SY ){.      if( 
1bd30 70 6e 4c 6f 67 20 29 20 2a 70 6e 4c 6f 67 20 3d  pnLog ) *pnLog =
1bd40 20 28 69 6e 74 29 70 57 61 6c 2d 3e 68 64 72 2e   (int)pWal->hdr.
1bd50 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 69  mxFrame;.      i
1bd60 66 28 20 70 6e 43 6b 70 74 20 29 20 2a 70 6e 43  f( pnCkpt ) *pnC
1bd70 6b 70 74 20 3d 20 28 69 6e 74 29 28 77 61 6c 43  kpt = (int)(walC
1bd80 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 2d 3e 6e  kptInfo(pWal)->n
1bd90 42 61 63 6b 66 69 6c 6c 29 3b 0a 20 20 20 20 7d  Backfill);.    }
1bda0 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 73 43 68  .  }..  if( isCh
1bdb0 61 6e 67 65 64 20 29 7b 0a 20 20 20 20 2f 2a 20  anged ){.    /* 
1bdc0 49 66 20 61 20 6e 65 77 20 77 61 6c 2d 69 6e 64  If a new wal-ind
1bdd0 65 78 20 68 65 61 64 65 72 20 77 61 73 20 6c 6f  ex header was lo
1bde0 61 64 65 64 20 62 65 66 6f 72 65 20 74 68 65 20  aded before the 
1bdf0 63 68 65 63 6b 70 6f 69 6e 74 20 77 61 73 20 0a  checkpoint was .
1be00 20 20 20 20 2a 2a 20 70 65 72 66 6f 72 6d 65 64      ** performed
1be10 2c 20 74 68 65 6e 20 74 68 65 20 70 61 67 65 72  , then the pager
1be20 2d 63 61 63 68 65 20 61 73 73 6f 63 69 61 74 65  -cache associate
1be30 64 20 77 69 74 68 20 70 57 61 6c 20 69 73 20 6e  d with pWal is n
1be40 6f 77 0a 20 20 20 20 2a 2a 20 6f 75 74 20 6f 66  ow.    ** out of
1be50 20 64 61 74 65 2e 20 53 6f 20 7a 65 72 6f 20 74   date. So zero t
1be60 68 65 20 63 61 63 68 65 64 20 77 61 6c 2d 69 6e  he cached wal-in
1be70 64 65 78 20 68 65 61 64 65 72 20 74 6f 20 65 6e  dex header to en
1be80 73 75 72 65 20 74 68 61 74 0a 20 20 20 20 2a 2a  sure that.    **
1be90 20 6e 65 78 74 20 74 69 6d 65 20 74 68 65 20 70   next time the p
1bea0 61 67 65 72 20 6f 70 65 6e 73 20 61 20 73 6e 61  ager opens a sna
1beb0 70 73 68 6f 74 20 6f 6e 20 74 68 69 73 20 64 61  pshot on this da
1bec0 74 61 62 61 73 65 20 69 74 20 6b 6e 6f 77 73 20  tabase it knows 
1bed0 74 68 61 74 0a 20 20 20 20 2a 2a 20 74 68 65 20  that.    ** the 
1bee0 63 61 63 68 65 20 6e 65 65 64 73 20 74 6f 20 62  cache needs to b
1bef0 65 20 72 65 73 65 74 2e 0a 20 20 20 20 2a 2f 0a  e reset..    */.
1bf00 20 20 20 20 6d 65 6d 73 65 74 28 26 70 57 61 6c      memset(&pWal
1bf10 2d 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66  ->hdr, 0, sizeof
1bf20 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a  (WalIndexHdr));.
1bf30 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 6c 65 61 73    }..  /* Releas
1bf40 65 20 74 68 65 20 6c 6f 63 6b 73 2e 20 2a 2f 0a  e the locks. */.
1bf50 20 20 73 71 6c 69 74 65 33 57 61 6c 45 6e 64 57    sqlite3WalEndW
1bf60 72 69 74 65 54 72 61 6e 73 61 63 74 69 6f 6e 28  riteTransaction(
1bf70 70 57 61 6c 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f  pWal);.  walUnlo
1bf80 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
1bf90 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c  , WAL_CKPT_LOCK,
1bfa0 20 31 29 3b 0a 20 20 70 57 61 6c 2d 3e 63 6b 70   1);.  pWal->ckp
1bfb0 74 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 57 41 4c  tLock = 0;.  WAL
1bfc0 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63  TRACE(("WAL%p: c
1bfd0 68 65 63 6b 70 6f 69 6e 74 20 25 73 5c 6e 22 2c  heckpoint %s\n",
1bfe0 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69   pWal, rc ? "fai
1bff0 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
1c000 20 72 65 74 75 72 6e 20 28 72 63 3d 3d 53 51 4c   return (rc==SQL
1c010 49 54 45 5f 4f 4b 20 26 26 20 65 4d 6f 64 65 21  ITE_OK && eMode!
1c020 3d 65 4d 6f 64 65 32 20 3f 20 53 51 4c 49 54 45  =eMode2 ? SQLITE
1c030 5f 42 55 53 59 20 3a 20 72 63 29 3b 0a 7d 0a 0a  _BUSY : rc);.}..
1c040 2f 2a 20 52 65 74 75 72 6e 20 74 68 65 20 76 61  /* Return the va
1c050 6c 75 65 20 74 6f 20 70 61 73 73 20 74 6f 20 61  lue to pass to a
1c060 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 68 6f 6f   sqlite3_wal_hoo
1c070 6b 20 63 61 6c 6c 62 61 63 6b 2c 20 74 68 65 0a  k callback, the.
1c080 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61  ** number of fra
1c090 6d 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20 61  mes in the WAL a
1c0a0 74 20 74 68 65 20 70 6f 69 6e 74 20 6f 66 20 74  t the point of t
1c0b0 68 65 20 6c 61 73 74 20 63 6f 6d 6d 69 74 20 73  he last commit s
1c0c0 69 6e 63 65 0a 2a 2a 20 73 71 6c 69 74 65 33 57  ince.** sqlite3W
1c0d0 61 6c 43 61 6c 6c 62 61 63 6b 28 29 20 77 61 73  alCallback() was
1c0e0 20 63 61 6c 6c 65 64 2e 20 20 49 66 20 6e 6f 20   called.  If no 
1c0f0 63 6f 6d 6d 69 74 73 20 68 61 76 65 20 6f 63 63  commits have occ
1c100 75 72 72 65 64 20 73 69 6e 63 65 0a 2a 2a 20 74  urred since.** t
1c110 68 65 20 6c 61 73 74 20 63 61 6c 6c 2c 20 74 68  he last call, th
1c120 65 6e 20 72 65 74 75 72 6e 20 30 2e 0a 2a 2f 0a  en return 0..*/.
1c130 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 43 61  int sqlite3WalCa
1c140 6c 6c 62 61 63 6b 28 57 61 6c 20 2a 70 57 61 6c  llback(Wal *pWal
1c150 29 7b 0a 20 20 75 33 32 20 72 65 74 20 3d 20 30  ){.  u32 ret = 0
1c160 3b 0a 20 20 69 66 28 20 70 57 61 6c 20 29 7b 0a  ;.  if( pWal ){.
1c170 20 20 20 20 72 65 74 20 3d 20 70 57 61 6c 2d 3e      ret = pWal->
1c180 69 43 61 6c 6c 62 61 63 6b 3b 0a 20 20 20 20 70  iCallback;.    p
1c190 57 61 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d  Wal->iCallback =
1c1a0 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   0;.  }.  return
1c1b0 20 28 69 6e 74 29 72 65 74 3b 0a 7d 0a 0a 2f 2a   (int)ret;.}../*
1c1c0 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
1c1d0 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 63  n is called to c
1c1e0 68 61 6e 67 65 20 74 68 65 20 57 41 4c 20 73 75  hange the WAL su
1c1f0 62 73 79 73 74 65 6d 20 69 6e 74 6f 20 6f 72 20  bsystem into or 
1c200 6f 75 74 0a 2a 2a 20 6f 66 20 6c 6f 63 6b 69 6e  out.** of lockin
1c210 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45  g_mode=EXCLUSIVE
1c220 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20 69 73  ..**.** If op is
1c230 20 7a 65 72 6f 2c 20 74 68 65 6e 20 61 74 74 65   zero, then atte
1c240 6d 70 74 20 74 6f 20 63 68 61 6e 67 65 20 66 72  mpt to change fr
1c250 6f 6d 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d  om locking_mode=
1c260 45 58 43 4c 55 53 49 56 45 0a 2a 2a 20 69 6e 74  EXCLUSIVE.** int
1c270 6f 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e  o locking_mode=N
1c280 4f 52 4d 41 4c 2e 20 20 54 68 69 73 20 6d 65 61  ORMAL.  This mea
1c290 6e 73 20 74 68 61 74 20 77 65 20 6d 75 73 74 20  ns that we must 
1c2a0 61 63 71 75 69 72 65 20 61 20 6c 6f 63 6b 0a 2a  acquire a lock.*
1c2b0 2a 20 6f 6e 20 74 68 65 20 70 57 61 6c 2d 3e 72  * on the pWal->r
1c2c0 65 61 64 4c 6f 63 6b 20 62 79 74 65 2e 20 20 49  eadLock byte.  I
1c2d0 66 20 74 68 65 20 57 41 4c 20 69 73 20 61 6c 72  f the WAL is alr
1c2e0 65 61 64 79 20 69 6e 20 6c 6f 63 6b 69 6e 67 5f  eady in locking_
1c2f0 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 0a 2a 2a 20 6f  mode=NORMAL.** o
1c300 72 20 69 66 20 74 68 65 20 61 63 71 75 69 73 69  r if the acquisi
1c310 74 69 6f 6e 20 6f 66 20 74 68 65 20 6c 6f 63 6b  tion of the lock
1c320 20 66 61 69 6c 73 2c 20 74 68 65 6e 20 72 65 74   fails, then ret
1c330 75 72 6e 20 30 2e 20 20 49 66 20 74 68 65 0a 2a  urn 0.  If the.*
1c340 2a 20 74 72 61 6e 73 69 74 69 6f 6e 20 6f 75 74  * transition out
1c350 20 6f 66 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f   of exclusive-mo
1c360 64 65 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  de is successful
1c370 2c 20 72 65 74 75 72 6e 20 31 2e 20 20 54 68 69  , return 1.  Thi
1c380 73 0a 2a 2a 20 6f 70 65 72 61 74 69 6f 6e 20 6d  s.** operation m
1c390 75 73 74 20 6f 63 63 75 72 20 77 68 69 6c 65 20  ust occur while 
1c3a0 74 68 65 20 70 61 67 65 72 20 69 73 20 73 74 69  the pager is sti
1c3b0 6c 6c 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 65  ll holding the e
1c3c0 78 63 6c 75 73 69 76 65 0a 2a 2a 20 6c 6f 63 6b  xclusive.** lock
1c3d0 20 6f 6e 20 74 68 65 20 6d 61 69 6e 20 64 61 74   on the main dat
1c3e0 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a  abase file..**.*
1c3f0 2a 20 49 66 20 6f 70 20 69 73 20 6f 6e 65 2c 20  * If op is one, 
1c400 74 68 65 6e 20 63 68 61 6e 67 65 20 66 72 6f 6d  then change from
1c410 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f   locking_mode=NO
1c420 52 4d 41 4c 20 69 6e 74 6f 20 0a 2a 2a 20 6c 6f  RMAL into .** lo
1c430 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55  cking_mode=EXCLU
1c440 53 49 56 45 2e 20 20 54 68 69 73 20 6d 65 61 6e  SIVE.  This mean
1c450 73 20 74 68 61 74 20 74 68 65 20 70 57 61 6c 2d  s that the pWal-
1c460 3e 72 65 61 64 4c 6f 63 6b 20 6d 75 73 74 0a 2a  >readLock must.*
1c470 2a 20 62 65 20 72 65 6c 65 61 73 65 64 2e 20 20  * be released.  
1c480 52 65 74 75 72 6e 20 31 20 69 66 20 74 68 65 20  Return 1 if the 
1c490 74 72 61 6e 73 69 74 69 6f 6e 20 69 73 20 6d 61  transition is ma
1c4a0 64 65 20 61 6e 64 20 30 20 69 66 20 74 68 65 0a  de and 0 if the.
1c4b0 2a 2a 20 57 41 4c 20 69 73 20 61 6c 72 65 61 64  ** WAL is alread
1c4c0 79 20 69 6e 20 65 78 63 6c 75 73 69 76 65 2d 6c  y in exclusive-l
1c4d0 6f 63 6b 69 6e 67 20 6d 6f 64 65 20 2d 20 6d 65  ocking mode - me
1c4e0 61 6e 69 6e 67 20 74 68 61 74 20 74 68 69 73 0a  aning that this.
1c4f0 2a 2a 20 72 6f 75 74 69 6e 65 20 69 73 20 61 20  ** routine is a 
1c500 6e 6f 2d 6f 70 2e 20 20 54 68 65 20 70 61 67 65  no-op.  The page
1c510 72 20 6d 75 73 74 20 61 6c 72 65 61 64 79 20 68  r must already h
1c520 6f 6c 64 20 74 68 65 20 65 78 63 6c 75 73 69 76  old the exclusiv
1c530 65 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65  e lock.** on the
1c540 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 66   main database f
1c550 69 6c 65 20 62 65 66 6f 72 65 20 69 6e 76 6f 6b  ile before invok
1c560 69 6e 67 20 74 68 69 73 20 6f 70 65 72 61 74 69  ing this operati
1c570 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20  on..**.** If op 
1c580 69 73 20 6e 65 67 61 74 69 76 65 2c 20 74 68 65  is negative, the
1c590 6e 20 64 6f 20 61 20 64 72 79 2d 72 75 6e 20 6f  n do a dry-run o
1c5a0 66 20 74 68 65 20 6f 70 3d 3d 31 20 63 61 73 65  f the op==1 case
1c5b0 20 62 75 74 20 64 6f 0a 2a 2a 20 6e 6f 74 20 61   but do.** not a
1c5c0 63 74 75 61 6c 6c 79 20 63 68 61 6e 67 65 20 61  ctually change a
1c5d0 6e 79 74 68 69 6e 67 2e 20 54 68 65 20 70 61 67  nything. The pag
1c5e0 65 72 20 75 73 65 73 20 74 68 69 73 20 74 6f 20  er uses this to 
1c5f0 73 65 65 20 69 66 20 69 74 0a 2a 2a 20 73 68 6f  see if it.** sho
1c600 75 6c 64 20 61 63 71 75 69 72 65 20 74 68 65 20  uld acquire the 
1c610 64 61 74 61 62 61 73 65 20 65 78 63 6c 75 73 69  database exclusi
1c620 76 65 20 6c 6f 63 6b 20 70 72 69 6f 72 20 74 6f  ve lock prior to
1c630 20 69 6e 76 6f 6b 69 6e 67 0a 2a 2a 20 74 68 65   invoking.** the
1c640 20 6f 70 3d 3d 31 20 63 61 73 65 2e 0a 2a 2f 0a   op==1 case..*/.
1c650 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 45 78  int sqlite3WalEx
1c660 63 6c 75 73 69 76 65 4d 6f 64 65 28 57 61 6c 20  clusiveMode(Wal 
1c670 2a 70 57 61 6c 2c 20 69 6e 74 20 6f 70 29 7b 0a  *pWal, int op){.
1c680 20 20 69 6e 74 20 72 63 3b 0a 20 20 61 73 73 65    int rc;.  asse
1c690 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c  rt( pWal->writeL
1c6a0 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  ock==0 );.  asse
1c6b0 72 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  rt( pWal->exclus
1c6c0 69 76 65 4d 6f 64 65 21 3d 57 41 4c 5f 48 45 41  iveMode!=WAL_HEA
1c6d0 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 7c 7c 20  PMEMORY_MODE || 
1c6e0 6f 70 3d 3d 2d 31 20 29 3b 0a 0a 20 20 2f 2a 20  op==-1 );..  /* 
1c6f0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69  pWal->readLock i
1c700 73 20 75 73 75 61 6c 6c 79 20 73 65 74 2c 20 62  s usually set, b
1c710 75 74 20 6d 69 67 68 74 20 62 65 20 2d 31 20 69  ut might be -1 i
1c720 66 20 74 68 65 72 65 20 77 61 73 20 61 20 0a 20  f there was a . 
1c730 20 2a 2a 20 70 72 69 6f 72 20 65 72 72 6f 72 20   ** prior error 
1c740 77 68 69 6c 65 20 61 74 74 65 6d 70 74 69 6e 67  while attempting
1c750 20 74 6f 20 61 63 71 75 69 72 65 20 61 72 65 20   to acquire are 
1c760 72 65 61 64 2d 6c 6f 63 6b 2e 20 54 68 69 73 20  read-lock. This 
1c770 63 61 6e 6e 6f 74 20 0a 20 20 2a 2a 20 68 61 70  cannot .  ** hap
1c780 70 65 6e 20 69 66 20 74 68 65 20 63 6f 6e 6e 65  pen if the conne
1c790 63 74 69 6f 6e 20 69 73 20 61 63 74 75 61 6c 6c  ction is actuall
1c7a0 79 20 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d  y in exclusive m
1c7b0 6f 64 65 20 28 61 73 20 6e 6f 20 78 53 68 6d 4c  ode (as no xShmL
1c7c0 6f 63 6b 0a 20 20 2a 2a 20 6c 6f 63 6b 73 20 61  ock.  ** locks a
1c7d0 72 65 20 74 61 6b 65 6e 20 69 6e 20 74 68 69 73  re taken in this
1c7e0 20 63 61 73 65 29 2e 20 4e 6f 72 20 73 68 6f 75   case). Nor shou
1c7f0 6c 64 20 74 68 65 20 70 61 67 65 72 20 61 74 74  ld the pager att
1c800 65 6d 70 74 20 74 6f 0a 20 20 2a 2a 20 75 70 67  empt to.  ** upg
1c810 72 61 64 65 20 74 6f 20 65 78 63 6c 75 73 69 76  rade to exclusiv
1c820 65 2d 6d 6f 64 65 20 66 6f 6c 6c 6f 77 69 6e 67  e-mode following
1c830 20 73 75 63 68 20 61 6e 20 65 72 72 6f 72 2e 0a   such an error..
1c840 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
1c850 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30  Wal->readLock>=0
1c860 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72   || pWal->lockEr
1c870 72 6f 72 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ror );.  assert(
1c880 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e   pWal->readLock>
1c890 3d 30 20 7c 7c 20 28 6f 70 3c 3d 30 20 26 26 20  =0 || (op<=0 && 
1c8a0 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
1c8b0 6f 64 65 3d 3d 30 29 20 29 3b 0a 0a 20 20 69 66  ode==0) );..  if
1c8c0 28 20 6f 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69  ( op==0 ){.    i
1c8d0 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69  f( pWal->exclusi
1c8e0 76 65 4d 6f 64 65 20 29 7b 0a 20 20 20 20 20 20  veMode ){.      
1c8f0 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
1c900 6f 64 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 69  ode = 0;.      i
1c910 66 28 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64  f( walLockShared
1c920 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f  (pWal, WAL_READ_
1c930 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c  LOCK(pWal->readL
1c940 6f 63 6b 29 29 21 3d 53 51 4c 49 54 45 5f 4f 4b  ock))!=SQLITE_OK
1c950 20 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c   ){.        pWal
1c960 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20  ->exclusiveMode 
1c970 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 1;.      }.   
1c980 20 20 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78     rc = pWal->ex
1c990 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a  clusiveMode==0;.
1c9a0 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
1c9b0 20 2f 2a 20 41 6c 72 65 61 64 79 20 69 6e 20 6c   /* Already in l
1c9c0 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d  ocking_mode=NORM
1c9d0 41 4c 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d  AL */.      rc =
1c9e0 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73   0;.    }.  }els
1c9f0 65 20 69 66 28 20 6f 70 3e 30 20 29 7b 0a 20 20  e if( op>0 ){.  
1ca00 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
1ca10 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30  exclusiveMode==0
1ca20 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
1ca30 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
1ca40 30 20 29 3b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f  0 );.    walUnlo
1ca50 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
1ca60 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61  AL_READ_LOCK(pWa
1ca70 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 3b 0a 20  l->readLock));. 
1ca80 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69     pWal->exclusi
1ca90 76 65 4d 6f 64 65 20 3d 20 31 3b 0a 20 20 20 20  veMode = 1;.    
1caa0 72 63 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65 7b  rc = 1;.  }else{
1cab0 0a 20 20 20 20 72 63 20 3d 20 70 57 61 6c 2d 3e  .    rc = pWal->
1cac0 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30  exclusiveMode==0
1cad0 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
1cae0 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74  c;.}../* .** Ret
1caf0 75 72 6e 20 74 72 75 65 20 69 66 20 74 68 65 20  urn true if the 
1cb00 61 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f 6e 2d  argument is non-
1cb10 4e 55 4c 4c 20 61 6e 64 20 74 68 65 20 57 41 4c  NULL and the WAL
1cb20 20 6d 6f 64 75 6c 65 20 69 73 20 75 73 69 6e 67   module is using
1cb30 0a 2a 2a 20 68 65 61 70 2d 6d 65 6d 6f 72 79 20  .** heap-memory 
1cb40 66 6f 72 20 74 68 65 20 77 61 6c 2d 69 6e 64 65  for the wal-inde
1cb50 78 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66  x. Otherwise, if
1cb60 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20 69 73   the argument is
1cb70 20 4e 55 4c 4c 20 6f 72 20 74 68 65 0a 2a 2a 20   NULL or the.** 
1cb80 57 41 4c 20 6d 6f 64 75 6c 65 20 69 73 20 75 73  WAL module is us
1cb90 69 6e 67 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72  ing shared-memor
1cba0 79 2c 20 72 65 74 75 72 6e 20 66 61 6c 73 65 2e  y, return false.
1cbb0 20 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33   .*/.int sqlite3
1cbc0 57 61 6c 48 65 61 70 4d 65 6d 6f 72 79 28 57 61  WalHeapMemory(Wa
1cbd0 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 72 65 74 75  l *pWal){.  retu
1cbe0 72 6e 20 28 70 57 61 6c 20 26 26 20 70 57 61 6c  rn (pWal && pWal
1cbf0 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d  ->exclusiveMode=
1cc00 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f  =WAL_HEAPMEMORY_
1cc10 4d 4f 44 45 20 29 3b 0a 7d 0a 0a 23 69 66 64 65  MODE );.}..#ifde
1cc20 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
1cc30 5a 49 50 56 46 53 0a 2f 2a 0a 2a 2a 20 49 66 20  ZIPVFS./*.** If 
1cc40 74 68 65 20 61 72 67 75 6d 65 6e 74 20 69 73 20  the argument is 
1cc50 6e 6f 74 20 4e 55 4c 4c 2c 20 69 74 20 70 6f 69  not NULL, it poi
1cc60 6e 74 73 20 74 6f 20 61 20 57 61 6c 20 6f 62 6a  nts to a Wal obj
1cc70 65 63 74 20 74 68 61 74 20 68 6f 6c 64 73 20 61  ect that holds a
1cc80 0a 2a 2a 20 72 65 61 64 2d 6c 6f 63 6b 2e 20 54  .** read-lock. T
1cc90 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74  his function ret
1cca0 75 72 6e 73 20 74 68 65 20 64 61 74 61 62 61 73  urns the databas
1ccb0 65 20 70 61 67 65 2d 73 69 7a 65 20 69 66 20 69  e page-size if i
1ccc0 74 20 69 73 20 6b 6e 6f 77 6e 2c 0a 2a 2a 20 6f  t is known,.** o
1ccd0 72 20 7a 65 72 6f 20 69 66 20 69 74 20 69 73 20  r zero if it is 
1cce0 6e 6f 74 20 28 6f 72 20 69 66 20 70 57 61 6c 20  not (or if pWal 
1ccf0 69 73 20 4e 55 4c 4c 29 2e 0a 2a 2f 0a 69 6e 74  is NULL)..*/.int
1cd00 20 73 71 6c 69 74 65 33 57 61 6c 46 72 61 6d 65   sqlite3WalFrame
1cd10 73 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c 29 7b  size(Wal *pWal){
1cd20 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 3d  .  assert( pWal=
1cd30 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 72 65 61 64  =0 || pWal->read
1cd40 4c 6f 63 6b 3e 3d 30 20 29 3b 0a 20 20 72 65 74  Lock>=0 );.  ret
1cd50 75 72 6e 20 28 70 57 61 6c 20 3f 20 70 57 61 6c  urn (pWal ? pWal
1cd60 2d 3e 73 7a 50 61 67 65 20 3a 20 30 29 3b 0a 7d  ->szPage : 0);.}
1cd70 0a 23 65 6e 64 69 66 0a 0a 23 65 6e 64 69 66 20  .#endif..#endif 
1cd80 2f 2a 20 23 69 66 6e 64 65 66 20 53 51 4c 49 54  /* #ifndef SQLIT
1cd90 45 5f 4f 4d 49 54 5f 57 41 4c 20 2a 2f 0a        E_OMIT_WAL */.