/ Hex Artifact Content
Login

Artifact 436bfceb141b9423c45119e68e444358ee0ed35d:


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 4e  te3_log(SQLITE_N
bd20: 4f 54 49 43 45 5f 52 45 43 4f 56 45 52 5f 57 41  OTICE_RECOVER_WA
bd30: 4c 2c 0a 20 20 20 20 20 20 20 20 20 20 22 72 65  L,.          "re
bd40: 63 6f 76 65 72 65 64 20 25 64 20 66 72 61 6d 65  covered %d frame
bd50: 73 20 66 72 6f 6d 20 57 41 4c 20 66 69 6c 65 20  s from WAL file 
bd60: 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20 20 70  %s",.          p
bd70: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
bd80: 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65  , pWal->zWalName
bd90: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a  .      );.    }.
bda0: 20 20 7d 0a 0a 72 65 63 6f 76 65 72 79 5f 65 72    }..recovery_er
bdb0: 72 6f 72 3a 0a 20 20 57 41 4c 54 52 41 43 45 28  ror:.  WALTRACE(
bdc0: 28 22 57 41 4c 25 70 3a 20 72 65 63 6f 76 65 72  ("WAL%p: recover
bdd0: 79 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  y %s\n", pWal, r
bde0: 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
bdf0: 6f 6b 22 29 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f  ok"));.  walUnlo
be00: 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
be10: 2c 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b  , iLock, nLock);
be20: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
be30: 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20  ./*.** Close an 
be40: 6f 70 65 6e 20 77 61 6c 2d 69 6e 64 65 78 2e 0a  open wal-index..
be50: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
be60: 61 6c 49 6e 64 65 78 43 6c 6f 73 65 28 57 61 6c  alIndexClose(Wal
be70: 20 2a 70 57 61 6c 2c 20 69 6e 74 20 69 73 44 65   *pWal, int isDe
be80: 6c 65 74 65 29 7b 0a 20 20 69 66 28 20 70 57 61  lete){.  if( pWa
be90: 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
bea0: 3d 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59  ==WAL_HEAPMEMORY
beb0: 5f 4d 4f 44 45 20 29 7b 0a 20 20 20 20 69 6e 74  _MODE ){.    int
bec0: 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b   i;.    for(i=0;
bed0: 20 69 3c 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61   i<pWal->nWiData
bee0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 71  ; i++){.      sq
bef0: 6c 69 74 65 33 5f 66 72 65 65 28 28 76 6f 69 64  lite3_free((void
bf00: 20 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44 61 74   *)pWal->apWiDat
bf10: 61 5b 69 5d 29 3b 0a 20 20 20 20 20 20 70 57 61  a[i]);.      pWa
bf20: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 5d 20 3d  l->apWiData[i] =
bf30: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73   0;.    }.  }els
bf40: 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  e{.    sqlite3Os
bf50: 53 68 6d 55 6e 6d 61 70 28 70 57 61 6c 2d 3e 70  ShmUnmap(pWal->p
bf60: 44 62 46 64 2c 20 69 73 44 65 6c 65 74 65 29 3b  DbFd, isDelete);
bf70: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4f  .  }.}../* .** O
bf80: 70 65 6e 20 61 20 63 6f 6e 6e 65 63 74 69 6f 6e  pen a connection
bf90: 20 74 6f 20 74 68 65 20 57 41 4c 20 66 69 6c 65   to the WAL file
bfa0: 20 7a 57 61 6c 4e 61 6d 65 2e 20 54 68 65 20 64   zWalName. The d
bfb0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 6d 75 73  atabase file mus
bfc0: 74 20 0a 2a 2a 20 61 6c 72 65 61 64 79 20 62 65  t .** already be
bfd0: 20 6f 70 65 6e 65 64 20 6f 6e 20 63 6f 6e 6e 65   opened on conne
bfe0: 63 74 69 6f 6e 20 70 44 62 46 64 2e 20 54 68 65  ction pDbFd. The
bff0: 20 62 75 66 66 65 72 20 74 68 61 74 20 7a 57 61   buffer that zWa
c000: 6c 4e 61 6d 65 20 70 6f 69 6e 74 73 0a 2a 2a 20  lName points.** 
c010: 74 6f 20 6d 75 73 74 20 72 65 6d 61 69 6e 20 76  to must remain v
c020: 61 6c 69 64 20 66 6f 72 20 74 68 65 20 6c 69 66  alid for the lif
c030: 65 74 69 6d 65 20 6f 66 20 74 68 65 20 72 65 74  etime of the ret
c040: 75 72 6e 65 64 20 57 61 6c 2a 20 68 61 6e 64 6c  urned Wal* handl
c050: 65 2e 0a 2a 2a 0a 2a 2a 20 41 20 53 48 41 52 45  e..**.** A SHARE
c060: 44 20 6c 6f 63 6b 20 73 68 6f 75 6c 64 20 62 65  D lock should be
c070: 20 68 65 6c 64 20 6f 6e 20 74 68 65 20 64 61 74   held on the dat
c080: 61 62 61 73 65 20 66 69 6c 65 20 77 68 65 6e 20  abase file when 
c090: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a  this function.**
c0a0: 20 69 73 20 63 61 6c 6c 65 64 2e 20 54 68 65 20   is called. The 
c0b0: 70 75 72 70 6f 73 65 20 6f 66 20 74 68 69 73 20  purpose of this 
c0c0: 53 48 41 52 45 44 20 6c 6f 63 6b 20 69 73 20 74  SHARED lock is t
c0d0: 6f 20 70 72 65 76 65 6e 74 20 61 6e 79 20 6f 74  o prevent any ot
c0e0: 68 65 72 0a 2a 2a 20 63 6c 69 65 6e 74 20 66 72  her.** client fr
c0f0: 6f 6d 20 75 6e 6c 69 6e 6b 69 6e 67 20 74 68 65  om unlinking the
c100: 20 57 41 4c 20 6f 72 20 77 61 6c 2d 69 6e 64 65   WAL or wal-inde
c110: 78 20 66 69 6c 65 2e 20 49 66 20 61 6e 6f 74 68  x file. If anoth
c120: 65 72 20 70 72 6f 63 65 73 73 0a 2a 2a 20 77 65  er process.** we
c130: 72 65 20 74 6f 20 64 6f 20 74 68 69 73 20 6a 75  re to do this ju
c140: 73 74 20 61 66 74 65 72 20 74 68 69 73 20 63 6c  st after this cl
c150: 69 65 6e 74 20 6f 70 65 6e 65 64 20 6f 6e 65 20  ient opened one 
c160: 6f 66 20 74 68 65 73 65 20 66 69 6c 65 73 2c 20  of these files, 
c170: 74 68 65 0a 2a 2a 20 73 79 73 74 65 6d 20 77 6f  the.** system wo
c180: 75 6c 64 20 62 65 20 62 61 64 6c 79 20 62 72 6f  uld be badly bro
c190: 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ken..**.** If th
c1a0: 65 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 73 75  e log file is su
c1b0: 63 63 65 73 73 66 75 6c 6c 79 20 6f 70 65 6e 65  ccessfully opene
c1c0: 64 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20  d, SQLITE_OK is 
c1d0: 72 65 74 75 72 6e 65 64 20 61 6e 64 20 0a 2a 2a  returned and .**
c1e0: 20 2a 70 70 57 61 6c 20 69 73 20 73 65 74 20 74   *ppWal is set t
c1f0: 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20 6e 65 77  o point to a new
c200: 20 57 41 4c 20 68 61 6e 64 6c 65 2e 20 49 66 20   WAL handle. If 
c210: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  an error occurs,
c220: 0a 2a 2a 20 61 6e 20 53 51 4c 69 74 65 20 65 72  .** an SQLite er
c230: 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75  ror code is retu
c240: 72 6e 65 64 20 61 6e 64 20 2a 70 70 57 61 6c 20  rned and *ppWal 
c250: 69 73 20 6c 65 66 74 20 75 6e 6d 6f 64 69 66 69  is left unmodifi
c260: 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ed..*/.int sqlit
c270: 65 33 57 61 6c 4f 70 65 6e 28 0a 20 20 73 71 6c  e3WalOpen(.  sql
c280: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
c290: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c2a0: 76 66 73 20 6d 6f 64 75 6c 65 20 74 6f 20 6f 70  vfs module to op
c2b0: 65 6e 20 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69  en wal and wal-i
c2c0: 6e 64 65 78 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ndex */.  sqlite
c2d0: 33 5f 66 69 6c 65 20 2a 70 44 62 46 64 2c 20 20  3_file *pDbFd,  
c2e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
c2f0: 20 6f 70 65 6e 20 64 61 74 61 62 61 73 65 20 66   open database f
c300: 69 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ile */.  const c
c310: 68 61 72 20 2a 7a 57 61 6c 4e 61 6d 65 2c 20 20  har *zWalName,  
c320: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
c330: 20 6f 66 20 74 68 65 20 57 41 4c 20 66 69 6c 65   of the WAL file
c340: 20 2a 2f 0a 20 20 69 6e 74 20 62 4e 6f 53 68 6d   */.  int bNoShm
c350: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
c360: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f        /* True to
c370: 20 72 75 6e 20 69 6e 20 68 65 61 70 2d 6d 65 6d   run in heap-mem
c380: 6f 72 79 20 6d 6f 64 65 20 2a 2f 0a 20 20 69 36  ory mode */.  i6
c390: 34 20 6d 78 57 61 6c 53 69 7a 65 2c 20 20 20 20  4 mxWalSize,    
c3a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c3b0: 20 54 72 75 6e 63 61 74 65 20 57 41 4c 20 74 6f   Truncate WAL to
c3c0: 20 74 68 69 73 20 73 69 7a 65 20 6f 6e 20 72 65   this size on re
c3d0: 73 65 74 20 2a 2f 0a 20 20 57 61 6c 20 2a 2a 70  set */.  Wal **p
c3e0: 70 57 61 6c 20 20 20 20 20 20 20 20 20 20 20 20  pWal            
c3f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
c400: 20 41 6c 6c 6f 63 61 74 65 64 20 57 61 6c 20 68   Allocated Wal h
c410: 61 6e 64 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e  andle */.){.  in
c420: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
c430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c440: 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a   Return Code */.
c450: 20 20 57 61 6c 20 2a 70 52 65 74 3b 20 20 20 20    Wal *pRet;    
c460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c470: 20 20 2f 2a 20 4f 62 6a 65 63 74 20 74 6f 20 61    /* Object to a
c480: 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65 74 75  llocate and retu
c490: 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67  rn */.  int flag
c4a0: 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s;              
c4b0: 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73          /* Flags
c4c0: 20 70 61 73 73 65 64 20 74 6f 20 4f 73 4f 70 65   passed to OsOpe
c4d0: 6e 28 29 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  n() */..  assert
c4e0: 28 20 7a 57 61 6c 4e 61 6d 65 20 26 26 20 7a 57  ( zWalName && zW
c4f0: 61 6c 4e 61 6d 65 5b 30 5d 20 29 3b 0a 20 20 61  alName[0] );.  a
c500: 73 73 65 72 74 28 20 70 44 62 46 64 20 29 3b 0a  ssert( pDbFd );.
c510: 0a 20 20 2f 2a 20 49 6e 20 74 68 65 20 61 6d 61  .  /* In the ama
c520: 6c 67 61 6d 61 74 69 6f 6e 2c 20 74 68 65 20 6f  lgamation, the o
c530: 73 5f 75 6e 69 78 2e 63 20 61 6e 64 20 6f 73 5f  s_unix.c and os_
c540: 77 69 6e 2e 63 20 73 6f 75 72 63 65 20 66 69 6c  win.c source fil
c550: 65 73 20 63 6f 6d 65 20 62 65 66 6f 72 65 0a 20  es come before. 
c560: 20 2a 2a 20 74 68 69 73 20 73 6f 75 72 63 65 20   ** this source 
c570: 66 69 6c 65 2e 20 20 56 65 72 69 66 79 20 74 68  file.  Verify th
c580: 61 74 20 74 68 65 20 23 64 65 66 69 6e 65 73 20  at the #defines 
c590: 6f 66 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 62  of the locking b
c5a0: 79 74 65 20 6f 66 66 73 65 74 73 0a 20 20 2a 2a  yte offsets.  **
c5b0: 20 69 6e 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e   in os_unix.c an
c5c0: 64 20 6f 73 5f 77 69 6e 2e 63 20 61 67 72 65 65  d os_win.c agree
c5d0: 20 77 69 74 68 20 74 68 65 20 57 41 4c 49 4e 44   with the WALIND
c5e0: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 76  EX_LOCK_OFFSET v
c5f0: 61 6c 75 65 2e 0a 20 20 2a 2f 0a 23 69 66 64 65  alue..  */.#ifde
c600: 66 20 57 49 4e 5f 53 48 4d 5f 42 41 53 45 0a 20  f WIN_SHM_BASE. 
c610: 20 61 73 73 65 72 74 28 20 57 49 4e 5f 53 48 4d   assert( WIN_SHM
c620: 5f 42 41 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f  _BASE==WALINDEX_
c630: 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23  LOCK_OFFSET );.#
c640: 65 6e 64 69 66 0a 23 69 66 64 65 66 20 55 4e 49  endif.#ifdef UNI
c650: 58 5f 53 48 4d 5f 42 41 53 45 0a 20 20 61 73 73  X_SHM_BASE.  ass
c660: 65 72 74 28 20 55 4e 49 58 5f 53 48 4d 5f 42 41  ert( UNIX_SHM_BA
c670: 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f 43  SE==WALINDEX_LOC
c680: 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65 6e 64  K_OFFSET );.#end
c690: 69 66 0a 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61  if...  /* Alloca
c6a0: 74 65 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f  te an instance o
c6b0: 66 20 73 74 72 75 63 74 20 57 61 6c 20 74 6f 20  f struct Wal to 
c6c0: 72 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 2a 70 70  return. */.  *pp
c6d0: 57 61 6c 20 3d 20 30 3b 0a 20 20 70 52 65 74 20  Wal = 0;.  pRet 
c6e0: 3d 20 28 57 61 6c 2a 29 73 71 6c 69 74 65 33 4d  = (Wal*)sqlite3M
c6f0: 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66  allocZero(sizeof
c700: 28 57 61 6c 29 20 2b 20 70 56 66 73 2d 3e 73 7a  (Wal) + pVfs->sz
c710: 4f 73 46 69 6c 65 29 3b 0a 20 20 69 66 28 20 21  OsFile);.  if( !
c720: 70 52 65 74 20 29 7b 0a 20 20 20 20 72 65 74 75  pRet ){.    retu
c730: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
c740: 0a 20 20 7d 0a 0a 20 20 70 52 65 74 2d 3e 70 56  .  }..  pRet->pV
c750: 66 73 20 3d 20 70 56 66 73 3b 0a 20 20 70 52 65  fs = pVfs;.  pRe
c760: 74 2d 3e 70 57 61 6c 46 64 20 3d 20 28 73 71 6c  t->pWalFd = (sql
c770: 69 74 65 33 5f 66 69 6c 65 20 2a 29 26 70 52 65  ite3_file *)&pRe
c780: 74 5b 31 5d 3b 0a 20 20 70 52 65 74 2d 3e 70 44  t[1];.  pRet->pD
c790: 62 46 64 20 3d 20 70 44 62 46 64 3b 0a 20 20 70  bFd = pDbFd;.  p
c7a0: 52 65 74 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20  Ret->readLock = 
c7b0: 2d 31 3b 0a 20 20 70 52 65 74 2d 3e 6d 78 57 61  -1;.  pRet->mxWa
c7c0: 6c 53 69 7a 65 20 3d 20 6d 78 57 61 6c 53 69 7a  lSize = mxWalSiz
c7d0: 65 3b 0a 20 20 70 52 65 74 2d 3e 7a 57 61 6c 4e  e;.  pRet->zWalN
c7e0: 61 6d 65 20 3d 20 7a 57 61 6c 4e 61 6d 65 3b 0a  ame = zWalName;.
c7f0: 20 20 70 52 65 74 2d 3e 73 79 6e 63 48 65 61 64    pRet->syncHead
c800: 65 72 20 3d 20 31 3b 0a 20 20 70 52 65 74 2d 3e  er = 1;.  pRet->
c810: 70 61 64 54 6f 53 65 63 74 6f 72 42 6f 75 6e 64  padToSectorBound
c820: 61 72 79 20 3d 20 31 3b 0a 20 20 70 52 65 74 2d  ary = 1;.  pRet-
c830: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d  >exclusiveMode =
c840: 20 28 62 4e 6f 53 68 6d 20 3f 20 57 41 4c 5f 48   (bNoShm ? WAL_H
c850: 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 3a 20  EAPMEMORY_MODE: 
c860: 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 29  WAL_NORMAL_MODE)
c870: 3b 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 66 69 6c  ;..  /* Open fil
c880: 65 20 68 61 6e 64 6c 65 20 6f 6e 20 74 68 65 20  e handle on the 
c890: 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20  write-ahead log 
c8a0: 66 69 6c 65 2e 20 2a 2f 0a 20 20 66 6c 61 67 73  file. */.  flags
c8b0: 20 3d 20 28 53 51 4c 49 54 45 5f 4f 50 45 4e 5f   = (SQLITE_OPEN_
c8c0: 52 45 41 44 57 52 49 54 45 7c 53 51 4c 49 54 45  READWRITE|SQLITE
c8d0: 5f 4f 50 45 4e 5f 43 52 45 41 54 45 7c 53 51 4c  _OPEN_CREATE|SQL
c8e0: 49 54 45 5f 4f 50 45 4e 5f 57 41 4c 29 3b 0a 20  ITE_OPEN_WAL);. 
c8f0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 4f   rc = sqlite3OsO
c900: 70 65 6e 28 70 56 66 73 2c 20 7a 57 61 6c 4e 61  pen(pVfs, zWalNa
c910: 6d 65 2c 20 70 52 65 74 2d 3e 70 57 61 6c 46 64  me, pRet->pWalFd
c920: 2c 20 66 6c 61 67 73 2c 20 26 66 6c 61 67 73 29  , flags, &flags)
c930: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
c940: 54 45 5f 4f 4b 20 26 26 20 66 6c 61 67 73 26 53  TE_OK && flags&S
c950: 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 4f  QLITE_OPEN_READO
c960: 4e 4c 59 20 29 7b 0a 20 20 20 20 70 52 65 74 2d  NLY ){.    pRet-
c970: 3e 72 65 61 64 4f 6e 6c 79 20 3d 20 57 41 4c 5f  >readOnly = WAL_
c980: 52 44 4f 4e 4c 59 3b 0a 20 20 7d 0a 0a 20 20 69  RDONLY;.  }..  i
c990: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
c9a0: 20 29 7b 0a 20 20 20 20 77 61 6c 49 6e 64 65 78   ){.    walIndex
c9b0: 43 6c 6f 73 65 28 70 52 65 74 2c 20 30 29 3b 0a  Close(pRet, 0);.
c9c0: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f      sqlite3OsClo
c9d0: 73 65 28 70 52 65 74 2d 3e 70 57 61 6c 46 64 29  se(pRet->pWalFd)
c9e0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
c9f0: 65 65 28 70 52 65 74 29 3b 0a 20 20 7d 65 6c 73  ee(pRet);.  }els
ca00: 65 7b 0a 20 20 20 20 69 6e 74 20 69 44 43 20 3d  e{.    int iDC =
ca10: 20 73 71 6c 69 74 65 33 4f 73 44 65 76 69 63 65   sqlite3OsDevice
ca20: 43 68 61 72 61 63 74 65 72 69 73 74 69 63 73 28  Characteristics(
ca30: 70 52 65 74 2d 3e 70 57 61 6c 46 64 29 3b 0a 20  pRet->pWalFd);. 
ca40: 20 20 20 69 66 28 20 69 44 43 20 26 20 53 51 4c     if( iDC & SQL
ca50: 49 54 45 5f 49 4f 43 41 50 5f 53 45 51 55 45 4e  ITE_IOCAP_SEQUEN
ca60: 54 49 41 4c 20 29 7b 20 70 52 65 74 2d 3e 73 79  TIAL ){ pRet->sy
ca70: 6e 63 48 65 61 64 65 72 20 3d 20 30 3b 20 7d 0a  ncHeader = 0; }.
ca80: 20 20 20 20 69 66 28 20 69 44 43 20 26 20 53 51      if( iDC & SQ
ca90: 4c 49 54 45 5f 49 4f 43 41 50 5f 50 4f 57 45 52  LITE_IOCAP_POWER
caa0: 53 41 46 45 5f 4f 56 45 52 57 52 49 54 45 20 29  SAFE_OVERWRITE )
cab0: 7b 0a 20 20 20 20 20 20 70 52 65 74 2d 3e 70 61  {.      pRet->pa
cac0: 64 54 6f 53 65 63 74 6f 72 42 6f 75 6e 64 61 72  dToSectorBoundar
cad0: 79 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20  y = 0;.    }.   
cae0: 20 2a 70 70 57 61 6c 20 3d 20 70 52 65 74 3b 0a   *ppWal = pRet;.
caf0: 20 20 20 20 57 41 4c 54 52 41 43 45 28 28 22 57      WALTRACE(("W
cb00: 41 4c 25 64 3a 20 6f 70 65 6e 65 64 5c 6e 22 2c  AL%d: opened\n",
cb10: 20 70 52 65 74 29 29 3b 0a 20 20 7d 0a 20 20 72   pRet));.  }.  r
cb20: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
cb30: 2a 2a 20 43 68 61 6e 67 65 20 74 68 65 20 73 69  ** Change the si
cb40: 7a 65 20 74 6f 20 77 68 69 63 68 20 74 68 65 20  ze to which the 
cb50: 57 41 4c 20 66 69 6c 65 20 69 73 20 74 72 75 63  WAL file is truc
cb60: 61 74 65 64 20 6f 6e 20 65 61 63 68 20 72 65 73  ated on each res
cb70: 65 74 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  et..*/.void sqli
cb80: 74 65 33 57 61 6c 4c 69 6d 69 74 28 57 61 6c 20  te3WalLimit(Wal 
cb90: 2a 70 57 61 6c 2c 20 69 36 34 20 69 4c 69 6d 69  *pWal, i64 iLimi
cba0: 74 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 20 29  t){.  if( pWal )
cbb0: 20 70 57 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65   pWal->mxWalSize
cbc0: 20 3d 20 69 4c 69 6d 69 74 3b 0a 7d 0a 0a 2f 2a   = iLimit;.}../*
cbd0: 0a 2a 2a 20 46 69 6e 64 20 74 68 65 20 73 6d 61  .** Find the sma
cbe0: 6c 6c 65 73 74 20 70 61 67 65 20 6e 75 6d 62 65  llest page numbe
cbf0: 72 20 6f 75 74 20 6f 66 20 61 6c 6c 20 70 61 67  r out of all pag
cc00: 65 73 20 68 65 6c 64 20 69 6e 20 74 68 65 20 57  es held in the W
cc10: 41 4c 20 74 68 61 74 0a 2a 2a 20 68 61 73 20 6e  AL that.** has n
cc20: 6f 74 20 62 65 65 6e 20 72 65 74 75 72 6e 65 64  ot been returned
cc30: 20 62 79 20 61 6e 79 20 70 72 69 6f 72 20 69 6e   by any prior in
cc40: 76 6f 63 61 74 69 6f 6e 20 6f 66 20 74 68 69 73  vocation of this
cc50: 20 6d 65 74 68 6f 64 20 6f 6e 20 74 68 65 0a 2a   method on the.*
cc60: 2a 20 73 61 6d 65 20 57 61 6c 49 74 65 72 61 74  * same WalIterat
cc70: 6f 72 20 6f 62 6a 65 63 74 2e 20 20 20 57 72 69  or object.   Wri
cc80: 74 65 20 69 6e 74 6f 20 2a 70 69 46 72 61 6d 65  te into *piFrame
cc90: 20 74 68 65 20 66 72 61 6d 65 20 69 6e 64 65 78   the frame index
cca0: 20 77 68 65 72 65 0a 2a 2a 20 74 68 61 74 20 70   where.** that p
ccb0: 61 67 65 20 77 61 73 20 6c 61 73 74 20 77 72 69  age was last wri
ccc0: 74 74 65 6e 20 69 6e 74 6f 20 74 68 65 20 57 41  tten into the WA
ccd0: 4c 2e 20 20 57 72 69 74 65 20 69 6e 74 6f 20 2a  L.  Write into *
cce0: 70 69 50 61 67 65 20 74 68 65 20 70 61 67 65 0a  piPage the page.
ccf0: 2a 2a 20 6e 75 6d 62 65 72 2e 0a 2a 2a 0a 2a 2a  ** number..**.**
cd00: 20 52 65 74 75 72 6e 20 30 20 6f 6e 20 73 75 63   Return 0 on suc
cd10: 63 65 73 73 2e 20 20 49 66 20 74 68 65 72 65 20  cess.  If there 
cd20: 61 72 65 20 6e 6f 20 70 61 67 65 73 20 69 6e 20  are no pages in 
cd30: 74 68 65 20 57 41 4c 20 77 69 74 68 20 61 20 70  the WAL with a p
cd40: 61 67 65 0a 2a 2a 20 6e 75 6d 62 65 72 20 6c 61  age.** number la
cd50: 72 67 65 72 20 74 68 61 6e 20 2a 70 69 50 61 67  rger than *piPag
cd60: 65 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20 31  e, then return 1
cd70: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
cd80: 77 61 6c 49 74 65 72 61 74 6f 72 4e 65 78 74 28  walIteratorNext(
cd90: 0a 20 20 57 61 6c 49 74 65 72 61 74 6f 72 20 2a  .  WalIterator *
cda0: 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p,              
cdb0: 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 2a 2f 0a   /* Iterator */.
cdc0: 20 20 75 33 32 20 2a 70 69 50 61 67 65 2c 20 20    u32 *piPage,  
cdd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cde0: 2f 2a 20 4f 55 54 3a 20 54 68 65 20 70 61 67 65  /* OUT: The page
cdf0: 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 6e   number of the n
ce00: 65 78 74 20 70 61 67 65 20 2a 2f 0a 20 20 75 33  ext page */.  u3
ce10: 32 20 2a 70 69 46 72 61 6d 65 20 20 20 20 20 20  2 *piFrame      
ce20: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
ce30: 55 54 3a 20 57 61 6c 20 66 72 61 6d 65 20 69 6e  UT: Wal frame in
ce40: 64 65 78 20 6f 66 20 6e 65 78 74 20 70 61 67 65  dex of next page
ce50: 20 2a 2f 0a 29 7b 0a 20 20 75 33 32 20 69 4d 69   */.){.  u32 iMi
ce60: 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n;              
ce70: 20 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74         /* Result
ce80: 20 70 67 6e 6f 20 6d 75 73 74 20 62 65 20 67 72   pgno must be gr
ce90: 65 61 74 65 72 20 74 68 61 6e 20 69 4d 69 6e 20  eater than iMin 
cea0: 2a 2f 0a 20 20 75 33 32 20 69 52 65 74 20 3d 20  */.  u32 iRet = 
ceb0: 30 78 46 46 46 46 46 46 46 46 3b 20 20 20 20 20  0xFFFFFFFF;     
cec0: 20 20 20 2f 2a 20 30 78 66 66 66 66 66 66 66 66     /* 0xffffffff
ced0: 20 69 73 20 6e 65 76 65 72 20 61 20 76 61 6c 69   is never a vali
cee0: 64 20 70 61 67 65 20 6e 75 6d 62 65 72 20 2a 2f  d page number */
cef0: 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
cf00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cf10: 20 2f 2a 20 46 6f 72 20 6c 6f 6f 70 69 6e 67 20   /* For looping 
cf20: 74 68 72 6f 75 67 68 20 73 65 67 6d 65 6e 74 73  through segments
cf30: 20 2a 2f 0a 0a 20 20 69 4d 69 6e 20 3d 20 70 2d   */..  iMin = p-
cf40: 3e 69 50 72 69 6f 72 3b 0a 20 20 61 73 73 65 72  >iPrior;.  asser
cf50: 74 28 20 69 4d 69 6e 3c 30 78 66 66 66 66 66 66  t( iMin<0xffffff
cf60: 66 66 20 29 3b 0a 20 20 66 6f 72 28 69 3d 70 2d  ff );.  for(i=p-
cf70: 3e 6e 53 65 67 6d 65 6e 74 2d 31 3b 20 69 3e 3d  >nSegment-1; i>=
cf80: 30 3b 20 69 2d 2d 29 7b 0a 20 20 20 20 73 74 72  0; i--){.    str
cf90: 75 63 74 20 57 61 6c 53 65 67 6d 65 6e 74 20 2a  uct WalSegment *
cfa0: 70 53 65 67 6d 65 6e 74 20 3d 20 26 70 2d 3e 61  pSegment = &p->a
cfb0: 53 65 67 6d 65 6e 74 5b 69 5d 3b 0a 20 20 20 20  Segment[i];.    
cfc0: 77 68 69 6c 65 28 20 70 53 65 67 6d 65 6e 74 2d  while( pSegment-
cfd0: 3e 69 4e 65 78 74 3c 70 53 65 67 6d 65 6e 74 2d  >iNext<pSegment-
cfe0: 3e 6e 45 6e 74 72 79 20 29 7b 0a 20 20 20 20 20  >nEntry ){.     
cff0: 20 75 33 32 20 69 50 67 20 3d 20 70 53 65 67 6d   u32 iPg = pSegm
d000: 65 6e 74 2d 3e 61 50 67 6e 6f 5b 70 53 65 67 6d  ent->aPgno[pSegm
d010: 65 6e 74 2d 3e 61 49 6e 64 65 78 5b 70 53 65 67  ent->aIndex[pSeg
d020: 6d 65 6e 74 2d 3e 69 4e 65 78 74 5d 5d 3b 0a 20  ment->iNext]];. 
d030: 20 20 20 20 20 69 66 28 20 69 50 67 3e 69 4d 69       if( iPg>iMi
d040: 6e 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  n ){.        if(
d050: 20 69 50 67 3c 69 52 65 74 20 29 7b 0a 20 20 20   iPg<iRet ){.   
d060: 20 20 20 20 20 20 20 69 52 65 74 20 3d 20 69 50         iRet = iP
d070: 67 3b 0a 20 20 20 20 20 20 20 20 20 20 2a 70 69  g;.          *pi
d080: 46 72 61 6d 65 20 3d 20 70 53 65 67 6d 65 6e 74  Frame = pSegment
d090: 2d 3e 69 5a 65 72 6f 20 2b 20 70 53 65 67 6d 65  ->iZero + pSegme
d0a0: 6e 74 2d 3e 61 49 6e 64 65 78 5b 70 53 65 67 6d  nt->aIndex[pSegm
d0b0: 65 6e 74 2d 3e 69 4e 65 78 74 5d 3b 0a 20 20 20  ent->iNext];.   
d0c0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 62       }.        b
d0d0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
d0e0: 20 20 20 20 70 53 65 67 6d 65 6e 74 2d 3e 69 4e      pSegment->iN
d0f0: 65 78 74 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d  ext++;.    }.  }
d100: 0a 0a 20 20 2a 70 69 50 61 67 65 20 3d 20 70 2d  ..  *piPage = p-
d110: 3e 69 50 72 69 6f 72 20 3d 20 69 52 65 74 3b 0a  >iPrior = iRet;.
d120: 20 20 72 65 74 75 72 6e 20 28 69 52 65 74 3d 3d    return (iRet==
d130: 30 78 46 46 46 46 46 46 46 46 29 3b 0a 7d 0a 0a  0xFFFFFFFF);.}..
d140: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
d150: 69 6f 6e 20 6d 65 72 67 65 73 20 74 77 6f 20 73  ion merges two s
d160: 6f 72 74 65 64 20 6c 69 73 74 73 20 69 6e 74 6f  orted lists into
d170: 20 61 20 73 69 6e 67 6c 65 20 73 6f 72 74 65 64   a single sorted
d180: 20 6c 69 73 74 2e 0a 2a 2a 0a 2a 2a 20 61 4c 65   list..**.** aLe
d190: 66 74 5b 5d 20 61 6e 64 20 61 52 69 67 68 74 5b  ft[] and aRight[
d1a0: 5d 20 61 72 65 20 61 72 72 61 79 73 20 6f 66 20  ] are arrays of 
d1b0: 69 6e 64 69 63 65 73 2e 20 20 54 68 65 20 73 6f  indices.  The so
d1c0: 72 74 20 6b 65 79 20 69 73 0a 2a 2a 20 61 43 6f  rt key is.** aCo
d1d0: 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 5d 5d 20 61  ntent[aLeft[]] a
d1e0: 6e 64 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67  nd aContent[aRig
d1f0: 68 74 5b 5d 5d 2e 20 20 55 70 6f 6e 20 65 6e 74  ht[]].  Upon ent
d200: 72 79 2c 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e  ry, the followin
d210: 67 0a 2a 2a 20 69 73 20 67 75 61 72 61 6e 74 65  g.** is guarante
d220: 65 64 20 66 6f 72 20 61 6c 6c 20 4a 3c 4b 3a 0a  ed for all J<K:.
d230: 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 20 61 43 6f  **.**        aCo
d240: 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 4a 5d 5d 20  ntent[aLeft[J]] 
d250: 3c 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74  < aContent[aLeft
d260: 5b 4b 5d 5d 0a 2a 2a 20 20 20 20 20 20 20 20 61  [K]].**        a
d270: 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b 4a  Content[aRight[J
d280: 5d 5d 20 3c 20 61 43 6f 6e 74 65 6e 74 5b 61 52  ]] < aContent[aR
d290: 69 67 68 74 5b 4b 5d 5d 0a 2a 2a 0a 2a 2a 20 54  ight[K]].**.** T
d2a0: 68 69 73 20 72 6f 75 74 69 6e 65 20 6f 76 65 72  his routine over
d2b0: 77 72 69 74 65 73 20 61 52 69 67 68 74 5b 5d 20  writes aRight[] 
d2c0: 77 69 74 68 20 61 20 6e 65 77 20 28 70 72 6f 62  with a new (prob
d2d0: 61 62 6c 79 20 6c 6f 6e 67 65 72 29 20 73 65 71  ably longer) seq
d2e0: 75 65 6e 63 65 0a 2a 2a 20 6f 66 20 69 6e 64 69  uence.** of indi
d2f0: 63 65 73 20 73 75 63 68 20 74 68 61 74 20 74 68  ces such that th
d300: 65 20 61 52 69 67 68 74 5b 5d 20 63 6f 6e 74 61  e aRight[] conta
d310: 69 6e 73 20 65 76 65 72 79 20 69 6e 64 65 78 20  ins every index 
d320: 74 68 61 74 20 61 70 70 65 61 72 73 20 69 6e 0a  that appears in.
d330: 2a 2a 20 65 69 74 68 65 72 20 61 4c 65 66 74 5b  ** either aLeft[
d340: 5d 20 6f 72 20 74 68 65 20 6f 6c 64 20 61 52 69  ] or the old aRi
d350: 67 68 74 5b 5d 20 61 6e 64 20 73 75 63 68 20 74  ght[] and such t
d360: 68 61 74 20 74 68 65 20 73 65 63 6f 6e 64 20 63  hat the second c
d370: 6f 6e 64 69 74 69 6f 6e 0a 2a 2a 20 61 62 6f 76  ondition.** abov
d380: 65 20 69 73 20 73 74 69 6c 6c 20 6d 65 74 2e 0a  e is still met..
d390: 2a 2a 0a 2a 2a 20 54 68 65 20 61 43 6f 6e 74 65  **.** The aConte
d3a0: 6e 74 5b 61 4c 65 66 74 5b 58 5d 5d 20 76 61 6c  nt[aLeft[X]] val
d3b0: 75 65 73 20 77 69 6c 6c 20 62 65 20 75 6e 69 71  ues will be uniq
d3c0: 75 65 20 66 6f 72 20 61 6c 6c 20 58 2e 20 20 41  ue for all X.  A
d3d0: 6e 64 20 74 68 65 0a 2a 2a 20 61 43 6f 6e 74 65  nd the.** aConte
d3e0: 6e 74 5b 61 52 69 67 68 74 5b 58 5d 5d 20 76 61  nt[aRight[X]] va
d3f0: 6c 75 65 73 20 77 69 6c 6c 20 62 65 20 75 6e 69  lues will be uni
d400: 71 75 65 20 74 6f 6f 2e 20 20 42 75 74 20 74 68  que too.  But th
d410: 65 72 65 20 6d 69 67 68 74 20 62 65 0a 2a 2a 20  ere might be.** 
d420: 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 63 6f 6d 62  one or more comb
d430: 69 6e 61 74 69 6f 6e 73 20 6f 66 20 58 20 61 6e  inations of X an
d440: 64 20 59 20 73 75 63 68 20 74 68 61 74 0a 2a 2a  d Y such that.**
d450: 0a 2a 2a 20 20 20 20 20 20 61 4c 65 66 74 5b 58  .**      aLeft[X
d460: 5d 21 3d 61 52 69 67 68 74 5b 59 5d 20 20 26 26  ]!=aRight[Y]  &&
d470: 20 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74    aContent[aLeft
d480: 5b 58 5d 5d 20 3d 3d 20 61 43 6f 6e 74 65 6e 74  [X]] == aContent
d490: 5b 61 52 69 67 68 74 5b 59 5d 5d 0a 2a 2a 0a 2a  [aRight[Y]].**.*
d4a0: 2a 20 57 68 65 6e 20 74 68 61 74 20 68 61 70 70  * When that happ
d4b0: 65 6e 73 2c 20 6f 6d 69 74 20 74 68 65 20 61 4c  ens, omit the aL
d4c0: 65 66 74 5b 58 5d 20 61 6e 64 20 75 73 65 20 74  eft[X] and use t
d4d0: 68 65 20 61 52 69 67 68 74 5b 59 5d 20 69 6e 64  he aRight[Y] ind
d4e0: 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ex..*/.static vo
d4f0: 69 64 20 77 61 6c 4d 65 72 67 65 28 0a 20 20 63  id walMerge(.  c
d500: 6f 6e 73 74 20 75 33 32 20 2a 61 43 6f 6e 74 65  onst u32 *aConte
d510: 6e 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  nt,            /
d520: 2a 20 50 61 67 65 73 20 69 6e 20 77 61 6c 20 2d  * Pages in wal -
d530: 20 6b 65 79 73 20 66 6f 72 20 74 68 65 20 73 6f   keys for the so
d540: 72 74 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20  rt */.  ht_slot 
d550: 2a 61 4c 65 66 74 2c 20 20 20 20 20 20 20 20 20  *aLeft,         
d560: 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 3a 20 4c          /* IN: L
d570: 65 66 74 20 68 61 6e 64 20 69 6e 70 75 74 20 6c  eft hand input l
d580: 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 65  ist */.  int nLe
d590: 66 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ft,             
d5a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 3a 20           /* IN: 
d5b0: 45 6c 65 6d 65 6e 74 73 20 69 6e 20 61 72 72 61  Elements in arra
d5c0: 79 20 2a 70 61 4c 65 66 74 20 2a 2f 0a 20 20 68  y *paLeft */.  h
d5d0: 74 5f 73 6c 6f 74 20 2a 2a 70 61 52 69 67 68 74  t_slot **paRight
d5e0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
d5f0: 2a 20 49 4e 2f 4f 55 54 3a 20 52 69 67 68 74 20  * IN/OUT: Right 
d600: 68 61 6e 64 20 69 6e 70 75 74 20 6c 69 73 74 20  hand input list 
d610: 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 69 67 68  */.  int *pnRigh
d620: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
d630: 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20       /* IN/OUT: 
d640: 45 6c 65 6d 65 6e 74 73 20 69 6e 20 2a 70 61 52  Elements in *paR
d650: 69 67 68 74 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f  ight */.  ht_slo
d660: 74 20 2a 61 54 6d 70 20 20 20 20 20 20 20 20 20  t *aTmp         
d670: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 65 6d            /* Tem
d680: 70 6f 72 61 72 79 20 62 75 66 66 65 72 20 2a 2f  porary buffer */
d690: 0a 29 7b 0a 20 20 69 6e 74 20 69 4c 65 66 74 20  .){.  int iLeft 
d6a0: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
d6b0: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
d6c0: 20 69 6e 64 65 78 20 69 6e 20 61 4c 65 66 74 20   index in aLeft 
d6d0: 2a 2f 0a 20 20 69 6e 74 20 69 52 69 67 68 74 20  */.  int iRight 
d6e0: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
d6f0: 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20       /* Current 
d700: 69 6e 64 65 78 20 69 6e 20 61 52 69 67 68 74 20  index in aRight 
d710: 2a 2f 0a 20 20 69 6e 74 20 69 4f 75 74 20 3d 20  */.  int iOut = 
d720: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
d730: 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20       /* Current 
d740: 69 6e 64 65 78 20 69 6e 20 6f 75 74 70 75 74 20  index in output 
d750: 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20  buffer */.  int 
d760: 6e 52 69 67 68 74 20 3d 20 2a 70 6e 52 69 67 68  nRight = *pnRigh
d770: 74 3b 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 52  t;.  ht_slot *aR
d780: 69 67 68 74 20 3d 20 2a 70 61 52 69 67 68 74 3b  ight = *paRight;
d790: 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 4c 65 66  ..  assert( nLef
d7a0: 74 3e 30 20 26 26 20 6e 52 69 67 68 74 3e 30 20  t>0 && nRight>0 
d7b0: 29 3b 0a 20 20 77 68 69 6c 65 28 20 69 52 69 67  );.  while( iRig
d7c0: 68 74 3c 6e 52 69 67 68 74 20 7c 7c 20 69 4c 65  ht<nRight || iLe
d7d0: 66 74 3c 6e 4c 65 66 74 20 29 7b 0a 20 20 20 20  ft<nLeft ){.    
d7e0: 68 74 5f 73 6c 6f 74 20 6c 6f 67 70 61 67 65 3b  ht_slot logpage;
d7f0: 0a 20 20 20 20 50 67 6e 6f 20 64 62 70 61 67 65  .    Pgno dbpage
d800: 3b 0a 0a 20 20 20 20 69 66 28 20 28 69 4c 65 66  ;..    if( (iLef
d810: 74 3c 6e 4c 65 66 74 29 20 0a 20 20 20 20 20 26  t<nLeft) .     &
d820: 26 20 28 69 52 69 67 68 74 3e 3d 6e 52 69 67 68  & (iRight>=nRigh
d830: 74 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61 4c  t || aContent[aL
d840: 65 66 74 5b 69 4c 65 66 74 5d 5d 3c 61 43 6f 6e  eft[iLeft]]<aCon
d850: 74 65 6e 74 5b 61 52 69 67 68 74 5b 69 52 69 67  tent[aRight[iRig
d860: 68 74 5d 5d 29 0a 20 20 20 20 29 7b 0a 20 20 20  ht]]).    ){.   
d870: 20 20 20 6c 6f 67 70 61 67 65 20 3d 20 61 4c 65     logpage = aLe
d880: 66 74 5b 69 4c 65 66 74 2b 2b 5d 3b 0a 20 20 20  ft[iLeft++];.   
d890: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6c 6f   }else{.      lo
d8a0: 67 70 61 67 65 20 3d 20 61 52 69 67 68 74 5b 69  gpage = aRight[i
d8b0: 52 69 67 68 74 2b 2b 5d 3b 0a 20 20 20 20 7d 0a  Right++];.    }.
d8c0: 20 20 20 20 64 62 70 61 67 65 20 3d 20 61 43 6f      dbpage = aCo
d8d0: 6e 74 65 6e 74 5b 6c 6f 67 70 61 67 65 5d 3b 0a  ntent[logpage];.
d8e0: 0a 20 20 20 20 61 54 6d 70 5b 69 4f 75 74 2b 2b  .    aTmp[iOut++
d8f0: 5d 20 3d 20 6c 6f 67 70 61 67 65 3b 0a 20 20 20  ] = logpage;.   
d900: 20 69 66 28 20 69 4c 65 66 74 3c 6e 4c 65 66 74   if( iLeft<nLeft
d910: 20 26 26 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65   && aContent[aLe
d920: 66 74 5b 69 4c 65 66 74 5d 5d 3d 3d 64 62 70 61  ft[iLeft]]==dbpa
d930: 67 65 20 29 20 69 4c 65 66 74 2b 2b 3b 0a 0a 20  ge ) iLeft++;.. 
d940: 20 20 20 61 73 73 65 72 74 28 20 69 4c 65 66 74     assert( iLeft
d950: 3e 3d 6e 4c 65 66 74 20 7c 7c 20 61 43 6f 6e 74  >=nLeft || aCont
d960: 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74 5d  ent[aLeft[iLeft]
d970: 5d 3e 64 62 70 61 67 65 20 29 3b 0a 20 20 20 20  ]>dbpage );.    
d980: 61 73 73 65 72 74 28 20 69 52 69 67 68 74 3e 3d  assert( iRight>=
d990: 6e 52 69 67 68 74 20 7c 7c 20 61 43 6f 6e 74 65  nRight || aConte
d9a0: 6e 74 5b 61 52 69 67 68 74 5b 69 52 69 67 68 74  nt[aRight[iRight
d9b0: 5d 5d 3e 64 62 70 61 67 65 20 29 3b 0a 20 20 7d  ]]>dbpage );.  }
d9c0: 0a 0a 20 20 2a 70 61 52 69 67 68 74 20 3d 20 61  ..  *paRight = a
d9d0: 4c 65 66 74 3b 0a 20 20 2a 70 6e 52 69 67 68 74  Left;.  *pnRight
d9e0: 20 3d 20 69 4f 75 74 3b 0a 20 20 6d 65 6d 63 70   = iOut;.  memcp
d9f0: 79 28 61 4c 65 66 74 2c 20 61 54 6d 70 2c 20 73  y(aLeft, aTmp, s
da00: 69 7a 65 6f 66 28 61 54 6d 70 5b 30 5d 29 2a 69  izeof(aTmp[0])*i
da10: 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  Out);.}../*.** S
da20: 6f 72 74 20 74 68 65 20 65 6c 65 6d 65 6e 74 73  ort the elements
da30: 20 69 6e 20 6c 69 73 74 20 61 4c 69 73 74 20 75   in list aList u
da40: 73 69 6e 67 20 61 43 6f 6e 74 65 6e 74 5b 5d 20  sing aContent[] 
da50: 61 73 20 74 68 65 20 73 6f 72 74 20 6b 65 79 2e  as the sort key.
da60: 0a 2a 2a 20 52 65 6d 6f 76 65 20 65 6c 65 6d 65  .** Remove eleme
da70: 6e 74 73 20 77 69 74 68 20 64 75 70 6c 69 63 61  nts with duplica
da80: 74 65 20 6b 65 79 73 2c 20 70 72 65 66 65 72 72  te keys, preferr
da90: 69 6e 67 20 74 6f 20 6b 65 65 70 20 74 68 65 0a  ing to keep the.
daa0: 2a 2a 20 6c 61 72 67 65 72 20 61 4c 69 73 74 5b  ** larger aList[
dab0: 5d 20 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20  ] values..**.** 
dac0: 54 68 65 20 61 4c 69 73 74 5b 5d 20 65 6e 74 72  The aList[] entr
dad0: 69 65 73 20 61 72 65 20 69 6e 64 69 63 65 73 20  ies are indices 
dae0: 69 6e 74 6f 20 61 43 6f 6e 74 65 6e 74 5b 5d 2e  into aContent[].
daf0: 20 20 54 68 65 20 76 61 6c 75 65 73 20 69 6e 0a    The values in.
db00: 2a 2a 20 61 4c 69 73 74 5b 5d 20 61 72 65 20 74  ** aList[] are t
db10: 6f 20 62 65 20 73 6f 72 74 65 64 20 73 6f 20 74  o be sorted so t
db20: 68 61 74 20 66 6f 72 20 61 6c 6c 20 4a 3c 4b 3a  hat for all J<K:
db30: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 61 43 6f 6e  .**.**      aCon
db40: 74 65 6e 74 5b 61 4c 69 73 74 5b 4a 5d 5d 20 3c  tent[aList[J]] <
db50: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b   aContent[aList[
db60: 4b 5d 5d 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 61 6e  K]].**.** For an
db70: 79 20 58 20 61 6e 64 20 59 20 73 75 63 68 20 74  y X and Y such t
db80: 68 61 74 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 61  hat.**.**      a
db90: 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 58 5d  Content[aList[X]
dba0: 5d 20 3d 3d 20 61 43 6f 6e 74 65 6e 74 5b 61 4c  ] == aContent[aL
dbb0: 69 73 74 5b 59 5d 5d 0a 2a 2a 0a 2a 2a 20 4b 65  ist[Y]].**.** Ke
dbc0: 65 70 20 74 68 65 20 6c 61 72 67 65 72 20 6f 66  ep the larger of
dbd0: 20 74 68 65 20 74 77 6f 20 76 61 6c 75 65 73 20   the two values 
dbe0: 61 4c 69 73 74 5b 58 5d 20 61 6e 64 20 61 4c 69  aList[X] and aLi
dbf0: 73 74 5b 59 5d 20 61 6e 64 20 64 69 73 63 61 72  st[Y] and discar
dc00: 64 0a 2a 2a 20 74 68 65 20 73 6d 61 6c 6c 65 72  d.** the smaller
dc10: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
dc20: 20 77 61 6c 4d 65 72 67 65 73 6f 72 74 28 0a 20   walMergesort(. 
dc30: 20 63 6f 6e 73 74 20 75 33 32 20 2a 61 43 6f 6e   const u32 *aCon
dc40: 74 65 6e 74 2c 20 20 20 20 20 20 20 20 20 20 20  tent,           
dc50: 20 2f 2a 20 50 61 67 65 73 20 69 6e 20 77 61 6c   /* Pages in wal
dc60: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61   */.  ht_slot *a
dc70: 42 75 66 66 65 72 2c 20 20 20 20 20 20 20 20 20  Buffer,         
dc80: 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
dc90: 6f 66 20 61 74 20 6c 65 61 73 74 20 2a 70 6e 4c  of at least *pnL
dca0: 69 73 74 20 69 74 65 6d 73 20 74 6f 20 75 73 65  ist items to use
dcb0: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61   */.  ht_slot *a
dcc0: 4c 69 73 74 2c 20 20 20 20 20 20 20 20 20 20 20  List,           
dcd0: 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a        /* IN/OUT:
dce0: 20 4c 69 73 74 20 74 6f 20 73 6f 72 74 20 2a 2f   List to sort */
dcf0: 0a 20 20 69 6e 74 20 2a 70 6e 4c 69 73 74 20 20  .  int *pnList  
dd00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dd10: 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4e 75     /* IN/OUT: Nu
dd20: 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73  mber of elements
dd30: 20 69 6e 20 61 4c 69 73 74 5b 5d 20 2a 2f 0a 29   in aList[] */.)
dd40: 7b 0a 20 20 73 74 72 75 63 74 20 53 75 62 6c 69  {.  struct Subli
dd50: 73 74 20 7b 0a 20 20 20 20 69 6e 74 20 6e 4c 69  st {.    int nLi
dd60: 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  st;             
dd70: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
dd80: 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20   of elements in 
dd90: 61 4c 69 73 74 20 2a 2f 0a 20 20 20 20 68 74 5f  aList */.    ht_
dda0: 73 6c 6f 74 20 2a 61 4c 69 73 74 3b 20 20 20 20  slot *aList;    
ddb0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f             /* Po
ddc0: 69 6e 74 65 72 20 74 6f 20 73 75 62 2d 6c 69 73  inter to sub-lis
ddd0: 74 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 7d  t content */.  }
dde0: 3b 0a 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20 6e  ;..  const int n
ddf0: 4c 69 73 74 20 3d 20 2a 70 6e 4c 69 73 74 3b 20  List = *pnList; 
de00: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
de10: 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20  input list */.  
de20: 69 6e 74 20 6e 4d 65 72 67 65 20 3d 20 30 3b 20  int nMerge = 0; 
de30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
de40: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65  /* Number of ele
de50: 6d 65 6e 74 73 20 69 6e 20 6c 69 73 74 20 61 4d  ments in list aM
de60: 65 72 67 65 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f  erge */.  ht_slo
de70: 74 20 2a 61 4d 65 72 67 65 20 3d 20 30 3b 20 20  t *aMerge = 0;  
de80: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73            /* Lis
de90: 74 20 74 6f 20 62 65 20 6d 65 72 67 65 64 20 2a  t to be merged *
dea0: 2f 0a 20 20 69 6e 74 20 69 4c 69 73 74 3b 20 20  /.  int iList;  
deb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dec0: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 69 6e 74      /* Index int
ded0: 6f 20 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a  o input list */.
dee0: 20 20 69 6e 74 20 69 53 75 62 20 3d 20 30 3b 20    int iSub = 0; 
def0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
df00: 20 20 2f 2a 20 49 6e 64 65 78 20 69 6e 74 6f 20    /* Index into 
df10: 61 53 75 62 20 61 72 72 61 79 20 2a 2f 0a 20 20  aSub array */.  
df20: 73 74 72 75 63 74 20 53 75 62 6c 69 73 74 20 61  struct Sublist a
df30: 53 75 62 5b 31 33 5d 3b 20 20 20 20 20 20 20 20  Sub[13];        
df40: 2f 2a 20 41 72 72 61 79 20 6f 66 20 73 75 62 2d  /* Array of sub-
df50: 6c 69 73 74 73 20 2a 2f 0a 0a 20 20 6d 65 6d 73  lists */..  mems
df60: 65 74 28 61 53 75 62 2c 20 30 2c 20 73 69 7a 65  et(aSub, 0, size
df70: 6f 66 28 61 53 75 62 29 29 3b 0a 20 20 61 73 73  of(aSub));.  ass
df80: 65 72 74 28 20 6e 4c 69 73 74 3c 3d 48 41 53 48  ert( nList<=HASH
df90: 54 41 42 4c 45 5f 4e 50 41 47 45 20 26 26 20 6e  TABLE_NPAGE && n
dfa0: 4c 69 73 74 3e 30 20 29 3b 0a 20 20 61 73 73 65  List>0 );.  asse
dfb0: 72 74 28 20 48 41 53 48 54 41 42 4c 45 5f 4e 50  rt( HASHTABLE_NP
dfc0: 41 47 45 3d 3d 28 31 3c 3c 28 41 72 72 61 79 53  AGE==(1<<(ArrayS
dfd0: 69 7a 65 28 61 53 75 62 29 2d 31 29 29 20 29 3b  ize(aSub)-1)) );
dfe0: 0a 0a 20 20 66 6f 72 28 69 4c 69 73 74 3d 30 3b  ..  for(iList=0;
dff0: 20 69 4c 69 73 74 3c 6e 4c 69 73 74 3b 20 69 4c   iList<nList; iL
e000: 69 73 74 2b 2b 29 7b 0a 20 20 20 20 6e 4d 65 72  ist++){.    nMer
e010: 67 65 20 3d 20 31 3b 0a 20 20 20 20 61 4d 65 72  ge = 1;.    aMer
e020: 67 65 20 3d 20 26 61 4c 69 73 74 5b 69 4c 69 73  ge = &aList[iLis
e030: 74 5d 3b 0a 20 20 20 20 66 6f 72 28 69 53 75 62  t];.    for(iSub
e040: 3d 30 3b 20 69 4c 69 73 74 20 26 20 28 31 3c 3c  =0; iList & (1<<
e050: 69 53 75 62 29 3b 20 69 53 75 62 2b 2b 29 7b 0a  iSub); iSub++){.
e060: 20 20 20 20 20 20 73 74 72 75 63 74 20 53 75 62        struct Sub
e070: 6c 69 73 74 20 2a 70 20 3d 20 26 61 53 75 62 5b  list *p = &aSub[
e080: 69 53 75 62 5d 3b 0a 20 20 20 20 20 20 61 73 73  iSub];.      ass
e090: 65 72 74 28 20 70 2d 3e 61 4c 69 73 74 20 26 26  ert( p->aList &&
e0a0: 20 70 2d 3e 6e 4c 69 73 74 3c 3d 28 31 3c 3c 69   p->nList<=(1<<i
e0b0: 53 75 62 29 20 29 3b 0a 20 20 20 20 20 20 61 73  Sub) );.      as
e0c0: 73 65 72 74 28 20 70 2d 3e 61 4c 69 73 74 3d 3d  sert( p->aList==
e0d0: 26 61 4c 69 73 74 5b 69 4c 69 73 74 26 7e 28 28  &aList[iList&~((
e0e0: 32 3c 3c 69 53 75 62 29 2d 31 29 5d 20 29 3b 0a  2<<iSub)-1)] );.
e0f0: 20 20 20 20 20 20 77 61 6c 4d 65 72 67 65 28 61        walMerge(a
e100: 43 6f 6e 74 65 6e 74 2c 20 70 2d 3e 61 4c 69 73  Content, p->aLis
e110: 74 2c 20 70 2d 3e 6e 4c 69 73 74 2c 20 26 61 4d  t, p->nList, &aM
e120: 65 72 67 65 2c 20 26 6e 4d 65 72 67 65 2c 20 61  erge, &nMerge, a
e130: 42 75 66 66 65 72 29 3b 0a 20 20 20 20 7d 0a 20  Buffer);.    }. 
e140: 20 20 20 61 53 75 62 5b 69 53 75 62 5d 2e 61 4c     aSub[iSub].aL
e150: 69 73 74 20 3d 20 61 4d 65 72 67 65 3b 0a 20 20  ist = aMerge;.  
e160: 20 20 61 53 75 62 5b 69 53 75 62 5d 2e 6e 4c 69    aSub[iSub].nLi
e170: 73 74 20 3d 20 6e 4d 65 72 67 65 3b 0a 20 20 7d  st = nMerge;.  }
e180: 0a 0a 20 20 66 6f 72 28 69 53 75 62 2b 2b 3b 20  ..  for(iSub++; 
e190: 69 53 75 62 3c 41 72 72 61 79 53 69 7a 65 28 61  iSub<ArraySize(a
e1a0: 53 75 62 29 3b 20 69 53 75 62 2b 2b 29 7b 0a 20  Sub); iSub++){. 
e1b0: 20 20 20 69 66 28 20 6e 4c 69 73 74 20 26 20 28     if( nList & (
e1c0: 31 3c 3c 69 53 75 62 29 20 29 7b 0a 20 20 20 20  1<<iSub) ){.    
e1d0: 20 20 73 74 72 75 63 74 20 53 75 62 6c 69 73 74    struct Sublist
e1e0: 20 2a 70 20 3d 20 26 61 53 75 62 5b 69 53 75 62   *p = &aSub[iSub
e1f0: 5d 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  ];.      assert(
e200: 20 70 2d 3e 6e 4c 69 73 74 3c 3d 28 31 3c 3c 69   p->nList<=(1<<i
e210: 53 75 62 29 20 29 3b 0a 20 20 20 20 20 20 61 73  Sub) );.      as
e220: 73 65 72 74 28 20 70 2d 3e 61 4c 69 73 74 3d 3d  sert( p->aList==
e230: 26 61 4c 69 73 74 5b 6e 4c 69 73 74 26 7e 28 28  &aList[nList&~((
e240: 32 3c 3c 69 53 75 62 29 2d 31 29 5d 20 29 3b 0a  2<<iSub)-1)] );.
e250: 20 20 20 20 20 20 77 61 6c 4d 65 72 67 65 28 61        walMerge(a
e260: 43 6f 6e 74 65 6e 74 2c 20 70 2d 3e 61 4c 69 73  Content, p->aLis
e270: 74 2c 20 70 2d 3e 6e 4c 69 73 74 2c 20 26 61 4d  t, p->nList, &aM
e280: 65 72 67 65 2c 20 26 6e 4d 65 72 67 65 2c 20 61  erge, &nMerge, a
e290: 42 75 66 66 65 72 29 3b 0a 20 20 20 20 7d 0a 20  Buffer);.    }. 
e2a0: 20 7d 0a 20 20 61 73 73 65 72 74 28 20 61 4d 65   }.  assert( aMe
e2b0: 72 67 65 3d 3d 61 4c 69 73 74 20 29 3b 0a 20 20  rge==aList );.  
e2c0: 2a 70 6e 4c 69 73 74 20 3d 20 6e 4d 65 72 67 65  *pnList = nMerge
e2d0: 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  ;..#ifdef SQLITE
e2e0: 5f 44 45 42 55 47 0a 20 20 7b 0a 20 20 20 20 69  _DEBUG.  {.    i
e2f0: 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d  nt i;.    for(i=
e300: 31 3b 20 69 3c 2a 70 6e 4c 69 73 74 3b 20 69 2b  1; i<*pnList; i+
e310: 2b 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74  +){.      assert
e320: 28 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74  ( aContent[aList
e330: 5b 69 5d 5d 20 3e 20 61 43 6f 6e 74 65 6e 74 5b  [i]] > aContent[
e340: 61 4c 69 73 74 5b 69 2d 31 5d 5d 20 29 3b 0a 20  aList[i-1]] );. 
e350: 20 20 20 7d 0a 20 20 7d 0a 23 65 6e 64 69 66 0a     }.  }.#endif.
e360: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 46 72 65 65 20 61  }../* .** Free a
e370: 6e 20 69 74 65 72 61 74 6f 72 20 61 6c 6c 6f 63  n iterator alloc
e380: 61 74 65 64 20 62 79 20 77 61 6c 49 74 65 72 61  ated by walItera
e390: 74 6f 72 49 6e 69 74 28 29 2e 0a 2a 2f 0a 73 74  torInit()..*/.st
e3a0: 61 74 69 63 20 76 6f 69 64 20 77 61 6c 49 74 65  atic void walIte
e3b0: 72 61 74 6f 72 46 72 65 65 28 57 61 6c 49 74 65  ratorFree(WalIte
e3c0: 72 61 74 6f 72 20 2a 70 29 7b 0a 20 20 73 71 6c  rator *p){.  sql
e3d0: 69 74 65 33 53 63 72 61 74 63 68 46 72 65 65 28  ite3ScratchFree(
e3e0: 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e  p);.}../*.** Con
e3f0: 73 74 72 75 63 74 20 61 20 57 61 6c 49 6e 74 65  struct a WalInte
e400: 72 61 74 6f 72 20 6f 62 6a 65 63 74 20 74 68 61  rator object tha
e410: 74 20 63 61 6e 20 62 65 20 75 73 65 64 20 74 6f  t can be used to
e420: 20 6c 6f 6f 70 20 6f 76 65 72 20 61 6c 6c 20 0a   loop over all .
e430: 2a 2a 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  ** pages in the 
e440: 57 41 4c 20 69 6e 20 61 73 63 65 6e 64 69 6e 67  WAL in ascending
e450: 20 6f 72 64 65 72 2e 20 54 68 65 20 63 61 6c 6c   order. The call
e460: 65 72 20 6d 75 73 74 20 68 6f 6c 64 20 74 68 65  er must hold the
e470: 20 63 68 65 63 6b 70 6f 69 6e 74 0a 2a 2a 20 6c   checkpoint.** l
e480: 6f 63 6b 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75  ock..**.** On su
e490: 63 63 65 73 73 2c 20 6d 61 6b 65 20 2a 70 70 20  ccess, make *pp 
e4a0: 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 6e 65 77  point to the new
e4b0: 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 57 61 6c  ly allocated Wal
e4c0: 49 6e 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74  Interator object
e4d0: 0a 2a 2a 20 72 65 74 75 72 6e 20 53 51 4c 49 54  .** return SQLIT
e4e0: 45 5f 4f 4b 2e 20 4f 74 68 65 72 77 69 73 65 2c  E_OK. Otherwise,
e4f0: 20 72 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72   return an error
e500: 20 63 6f 64 65 2e 20 49 66 20 74 68 69 73 20 72   code. If this r
e510: 6f 75 74 69 6e 65 0a 2a 2a 20 72 65 74 75 72 6e  outine.** return
e520: 73 20 61 6e 20 65 72 72 6f 72 2c 20 74 68 65 20  s an error, the 
e530: 76 61 6c 75 65 20 6f 66 20 2a 70 70 20 69 73 20  value of *pp is 
e540: 75 6e 64 65 66 69 6e 65 64 2e 0a 2a 2a 0a 2a 2a  undefined..**.**
e550: 20 54 68 65 20 63 61 6c 6c 69 6e 67 20 72 6f 75   The calling rou
e560: 74 69 6e 65 20 73 68 6f 75 6c 64 20 69 6e 76 6f  tine should invo
e570: 6b 65 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72  ke walIteratorFr
e580: 65 65 28 29 20 74 6f 20 64 65 73 74 72 6f 79 20  ee() to destroy 
e590: 74 68 65 0a 2a 2a 20 57 61 6c 49 74 65 72 61 74  the.** WalIterat
e5a0: 6f 72 20 6f 62 6a 65 63 74 20 77 68 65 6e 20 69  or object when i
e5b0: 74 20 68 61 73 20 66 69 6e 69 73 68 65 64 20 77  t has finished w
e5c0: 69 74 68 20 69 74 2e 0a 2a 2f 0a 73 74 61 74 69  ith it..*/.stati
e5d0: 63 20 69 6e 74 20 77 61 6c 49 74 65 72 61 74 6f  c int walIterato
e5e0: 72 49 6e 69 74 28 57 61 6c 20 2a 70 57 61 6c 2c  rInit(Wal *pWal,
e5f0: 20 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 2a 70   WalIterator **p
e600: 70 29 7b 0a 20 20 57 61 6c 49 74 65 72 61 74 6f  p){.  WalIterato
e610: 72 20 2a 70 3b 20 20 20 20 20 20 20 20 20 20 20  r *p;           
e620: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
e630: 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20 6e  value */.  int n
e640: 53 65 67 6d 65 6e 74 3b 20 20 20 20 20 20 20 20  Segment;        
e650: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
e660: 6d 62 65 72 20 6f 66 20 73 65 67 6d 65 6e 74 73  mber of segments
e670: 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20 75   to merge */.  u
e680: 33 32 20 69 4c 61 73 74 3b 20 20 20 20 20 20 20  32 iLast;       
e690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e6a0: 2a 20 4c 61 73 74 20 66 72 61 6d 65 20 69 6e 20  * Last frame in 
e6b0: 6c 6f 67 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79  log */.  int nBy
e6c0: 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  te;             
e6d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
e6e0: 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20 61  er of bytes to a
e6f0: 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 69 6e 74  llocate */.  int
e700: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
e710: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e720: 49 74 65 72 61 74 6f 72 20 76 61 72 69 61 62 6c  Iterator variabl
e730: 65 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a  e */.  ht_slot *
e740: 61 54 6d 70 3b 20 20 20 20 20 20 20 20 20 20 20  aTmp;           
e750: 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 20 73         /* Temp s
e760: 70 61 63 65 20 75 73 65 64 20 62 79 20 6d 65 72  pace used by mer
e770: 67 65 2d 73 6f 72 74 20 2a 2f 0a 20 20 69 6e 74  ge-sort */.  int
e780: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
e790: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e7a0: 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 0a  Return Code */..
e7b0: 20 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69 6e    /* This routin
e7c0: 65 20 6f 6e 6c 79 20 72 75 6e 73 20 77 68 69 6c  e only runs whil
e7d0: 65 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 63 68  e holding the ch
e7e0: 65 63 6b 70 6f 69 6e 74 20 6c 6f 63 6b 2e 20 41  eckpoint lock. A
e7f0: 6e 64 0a 20 20 2a 2a 20 69 74 20 6f 6e 6c 79 20  nd.  ** it only 
e800: 72 75 6e 73 20 69 66 20 74 68 65 72 65 20 69 73  runs if there is
e810: 20 61 63 74 75 61 6c 6c 79 20 63 6f 6e 74 65 6e   actually conten
e820: 74 20 69 6e 20 74 68 65 20 6c 6f 67 20 28 6d 78  t in the log (mx
e830: 46 72 61 6d 65 3e 30 29 2e 0a 20 20 2a 2f 0a 20  Frame>0)..  */. 
e840: 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 63   assert( pWal->c
e850: 6b 70 74 4c 6f 63 6b 20 26 26 20 70 57 61 6c 2d  kptLock && pWal-
e860: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3e 30 20 29  >hdr.mxFrame>0 )
e870: 3b 0a 20 20 69 4c 61 73 74 20 3d 20 70 57 61 6c  ;.  iLast = pWal
e880: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 0a  ->hdr.mxFrame;..
e890: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70    /* Allocate sp
e8a0: 61 63 65 20 66 6f 72 20 74 68 65 20 57 61 6c 49  ace for the WalI
e8b0: 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 2e 20  terator object. 
e8c0: 2a 2f 0a 20 20 6e 53 65 67 6d 65 6e 74 20 3d 20  */.  nSegment = 
e8d0: 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69 4c 61  walFramePage(iLa
e8e0: 73 74 29 20 2b 20 31 3b 0a 20 20 6e 42 79 74 65  st) + 1;.  nByte
e8f0: 20 3d 20 73 69 7a 65 6f 66 28 57 61 6c 49 74 65   = sizeof(WalIte
e900: 72 61 74 6f 72 29 20 0a 20 20 20 20 20 20 20 20  rator) .        
e910: 2b 20 28 6e 53 65 67 6d 65 6e 74 2d 31 29 2a 73  + (nSegment-1)*s
e920: 69 7a 65 6f 66 28 73 74 72 75 63 74 20 57 61 6c  izeof(struct Wal
e930: 53 65 67 6d 65 6e 74 29 0a 20 20 20 20 20 20 20  Segment).       
e940: 20 2b 20 69 4c 61 73 74 2a 73 69 7a 65 6f 66 28   + iLast*sizeof(
e950: 68 74 5f 73 6c 6f 74 29 3b 0a 20 20 70 20 3d 20  ht_slot);.  p = 
e960: 28 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 29 73  (WalIterator *)s
e970: 71 6c 69 74 65 33 53 63 72 61 74 63 68 4d 61 6c  qlite3ScratchMal
e980: 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 69 66  loc(nByte);.  if
e990: 28 20 21 70 20 29 7b 0a 20 20 20 20 72 65 74 75  ( !p ){.    retu
e9a0: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
e9b0: 0a 20 20 7d 0a 20 20 6d 65 6d 73 65 74 28 70 2c  .  }.  memset(p,
e9c0: 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 70 2d   0, nByte);.  p-
e9d0: 3e 6e 53 65 67 6d 65 6e 74 20 3d 20 6e 53 65 67  >nSegment = nSeg
e9e0: 6d 65 6e 74 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f  ment;..  /* Allo
e9f0: 63 61 74 65 20 74 65 6d 70 6f 72 61 72 79 20 73  cate temporary s
ea00: 70 61 63 65 20 75 73 65 64 20 62 79 20 74 68 65  pace used by the
ea10: 20 6d 65 72 67 65 2d 73 6f 72 74 20 72 6f 75 74   merge-sort rout
ea20: 69 6e 65 2e 20 54 68 69 73 20 62 6c 6f 63 6b 0a  ine. This block.
ea30: 20 20 2a 2a 20 6f 66 20 6d 65 6d 6f 72 79 20 77    ** of memory w
ea40: 69 6c 6c 20 62 65 20 66 72 65 65 64 20 62 65 66  ill be freed bef
ea50: 6f 72 65 20 74 68 69 73 20 66 75 6e 63 74 69 6f  ore this functio
ea60: 6e 20 72 65 74 75 72 6e 73 2e 0a 20 20 2a 2f 0a  n returns..  */.
ea70: 20 20 61 54 6d 70 20 3d 20 28 68 74 5f 73 6c 6f    aTmp = (ht_slo
ea80: 74 20 2a 29 73 71 6c 69 74 65 33 53 63 72 61 74  t *)sqlite3Scrat
ea90: 63 68 4d 61 6c 6c 6f 63 28 0a 20 20 20 20 20 20  chMalloc(.      
eaa0: 73 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 20  sizeof(ht_slot) 
eab0: 2a 20 28 69 4c 61 73 74 3e 48 41 53 48 54 41 42  * (iLast>HASHTAB
eac0: 4c 45 5f 4e 50 41 47 45 3f 48 41 53 48 54 41 42  LE_NPAGE?HASHTAB
ead0: 4c 45 5f 4e 50 41 47 45 3a 69 4c 61 73 74 29 0a  LE_NPAGE:iLast).
eae0: 20 20 29 3b 0a 20 20 69 66 28 20 21 61 54 6d 70    );.  if( !aTmp
eaf0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
eb00: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a  ITE_NOMEM;.  }..
eb10: 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53    for(i=0; rc==S
eb20: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e 53  QLITE_OK && i<nS
eb30: 65 67 6d 65 6e 74 3b 20 69 2b 2b 29 7b 0a 20 20  egment; i++){.  
eb40: 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c    volatile ht_sl
eb50: 6f 74 20 2a 61 48 61 73 68 3b 0a 20 20 20 20 75  ot *aHash;.    u
eb60: 33 32 20 69 5a 65 72 6f 3b 0a 20 20 20 20 76 6f  32 iZero;.    vo
eb70: 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e  latile u32 *aPgn
eb80: 6f 3b 0a 0a 20 20 20 20 72 63 20 3d 20 77 61 6c  o;..    rc = wal
eb90: 48 61 73 68 47 65 74 28 70 57 61 6c 2c 20 69 2c  HashGet(pWal, i,
eba0: 20 26 61 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c   &aHash, &aPgno,
ebb0: 20 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20 69 66   &iZero);.    if
ebc0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
ebd0: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6a 3b 20  ){.      int j; 
ebe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ebf0: 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20       /* Counter 
ec00: 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 20 20  variable */.    
ec10: 20 20 69 6e 74 20 6e 45 6e 74 72 79 3b 20 20 20    int nEntry;   
ec20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
ec30: 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69   Number of entri
ec40: 65 73 20 69 6e 20 74 68 69 73 20 73 65 67 6d 65  es in this segme
ec50: 6e 74 20 2a 2f 0a 20 20 20 20 20 20 68 74 5f 73  nt */.      ht_s
ec60: 6c 6f 74 20 2a 61 49 6e 64 65 78 3b 20 20 20 20  lot *aIndex;    
ec70: 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65          /* Sorte
ec80: 64 20 69 6e 64 65 78 20 66 6f 72 20 74 68 69 73  d index for this
ec90: 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 0a 20 20 20   segment */..   
eca0: 20 20 20 61 50 67 6e 6f 2b 2b 3b 0a 20 20 20 20     aPgno++;.    
ecb0: 20 20 69 66 28 20 28 69 2b 31 29 3d 3d 6e 53 65    if( (i+1)==nSe
ecc0: 67 6d 65 6e 74 20 29 7b 0a 20 20 20 20 20 20 20  gment ){.       
ecd0: 20 6e 45 6e 74 72 79 20 3d 20 28 69 6e 74 29 28   nEntry = (int)(
ece0: 69 4c 61 73 74 20 2d 20 69 5a 65 72 6f 29 3b 0a  iLast - iZero);.
ecf0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
ed00: 20 20 20 20 20 6e 45 6e 74 72 79 20 3d 20 28 69       nEntry = (i
ed10: 6e 74 29 28 28 75 33 32 2a 29 61 48 61 73 68 20  nt)((u32*)aHash 
ed20: 2d 20 28 75 33 32 2a 29 61 50 67 6e 6f 29 3b 0a  - (u32*)aPgno);.
ed30: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61 49        }.      aI
ed40: 6e 64 65 78 20 3d 20 26 28 28 68 74 5f 73 6c 6f  ndex = &((ht_slo
ed50: 74 20 2a 29 26 70 2d 3e 61 53 65 67 6d 65 6e 74  t *)&p->aSegment
ed60: 5b 70 2d 3e 6e 53 65 67 6d 65 6e 74 5d 29 5b 69  [p->nSegment])[i
ed70: 5a 65 72 6f 5d 3b 0a 20 20 20 20 20 20 69 5a 65  Zero];.      iZe
ed80: 72 6f 2b 2b 3b 0a 20 20 0a 20 20 20 20 20 20 66  ro++;.  .      f
ed90: 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 45 6e 74 72 79  or(j=0; j<nEntry
eda0: 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; j++){.        
edb0: 61 49 6e 64 65 78 5b 6a 5d 20 3d 20 28 68 74 5f  aIndex[j] = (ht_
edc0: 73 6c 6f 74 29 6a 3b 0a 20 20 20 20 20 20 7d 0a  slot)j;.      }.
edd0: 20 20 20 20 20 20 77 61 6c 4d 65 72 67 65 73 6f        walMergeso
ede0: 72 74 28 28 75 33 32 20 2a 29 61 50 67 6e 6f 2c  rt((u32 *)aPgno,
edf0: 20 61 54 6d 70 2c 20 61 49 6e 64 65 78 2c 20 26   aTmp, aIndex, &
ee00: 6e 45 6e 74 72 79 29 3b 0a 20 20 20 20 20 20 70  nEntry);.      p
ee10: 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 69 5a  ->aSegment[i].iZ
ee20: 65 72 6f 20 3d 20 69 5a 65 72 6f 3b 0a 20 20 20  ero = iZero;.   
ee30: 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69     p->aSegment[i
ee40: 5d 2e 6e 45 6e 74 72 79 20 3d 20 6e 45 6e 74 72  ].nEntry = nEntr
ee50: 79 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65 67  y;.      p->aSeg
ee60: 6d 65 6e 74 5b 69 5d 2e 61 49 6e 64 65 78 20 3d  ment[i].aIndex =
ee70: 20 61 49 6e 64 65 78 3b 0a 20 20 20 20 20 20 70   aIndex;.      p
ee80: 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 61 50  ->aSegment[i].aP
ee90: 67 6e 6f 20 3d 20 28 75 33 32 20 2a 29 61 50 67  gno = (u32 *)aPg
eea0: 6e 6f 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  no;.    }.  }.  
eeb0: 73 71 6c 69 74 65 33 53 63 72 61 74 63 68 46 72  sqlite3ScratchFr
eec0: 65 65 28 61 54 6d 70 29 3b 0a 0a 20 20 69 66 28  ee(aTmp);..  if(
eed0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
eee0: 7b 0a 20 20 20 20 77 61 6c 49 74 65 72 61 74 6f  {.    walIterato
eef0: 72 46 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20  rFree(p);.  }.  
ef00: 2a 70 70 20 3d 20 70 3b 0a 20 20 72 65 74 75 72  *pp = p;.  retur
ef10: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
ef20: 74 74 65 6d 70 74 20 74 6f 20 6f 62 74 61 69 6e  ttempt to obtain
ef30: 20 74 68 65 20 65 78 63 6c 75 73 69 76 65 20 57   the exclusive W
ef40: 41 4c 20 6c 6f 63 6b 20 64 65 66 69 6e 65 64 20  AL lock defined 
ef50: 62 79 20 70 61 72 61 6d 65 74 65 72 73 20 6c 6f  by parameters lo
ef60: 63 6b 49 64 78 20 61 6e 64 0a 2a 2a 20 6e 2e 20  ckIdx and.** n. 
ef70: 49 66 20 74 68 65 20 61 74 74 65 6d 70 74 20 66  If the attempt f
ef80: 61 69 6c 73 20 61 6e 64 20 70 61 72 61 6d 65 74  ails and paramet
ef90: 65 72 20 78 42 75 73 79 20 69 73 20 6e 6f 74 20  er xBusy is not 
efa0: 4e 55 4c 4c 2c 20 74 68 65 6e 20 69 74 20 69 73  NULL, then it is
efb0: 20 61 0a 2a 2a 20 62 75 73 79 2d 68 61 6e 64 6c   a.** busy-handl
efc0: 65 72 20 66 75 6e 63 74 69 6f 6e 2e 20 49 6e 76  er function. Inv
efd0: 6f 6b 65 20 69 74 20 61 6e 64 20 72 65 74 72 79  oke it and retry
efe0: 20 74 68 65 20 6c 6f 63 6b 20 75 6e 74 69 6c 20   the lock until 
eff0: 65 69 74 68 65 72 20 74 68 65 0a 2a 2a 20 6c 6f  either the.** lo
f000: 63 6b 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  ck is successful
f010: 6c 79 20 6f 62 74 61 69 6e 65 64 20 6f 72 20 74  ly obtained or t
f020: 68 65 20 62 75 73 79 2d 68 61 6e 64 6c 65 72 20  he busy-handler 
f030: 72 65 74 75 72 6e 73 20 30 2e 0a 2a 2f 0a 73 74  returns 0..*/.st
f040: 61 74 69 63 20 69 6e 74 20 77 61 6c 42 75 73 79  atic int walBusy
f050: 4c 6f 63 6b 28 0a 20 20 57 61 6c 20 2a 70 57 61  Lock(.  Wal *pWa
f060: 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
f070: 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 63          /* WAL c
f080: 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 69  onnection */.  i
f090: 6e 74 20 28 2a 78 42 75 73 79 29 28 76 6f 69 64  nt (*xBusy)(void
f0a0: 2a 29 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  *),            /
f0b0: 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63 61  * Function to ca
f0c0: 6c 6c 20 77 68 65 6e 20 62 75 73 79 20 2a 2f 0a  ll when busy */.
f0d0: 20 20 76 6f 69 64 20 2a 70 42 75 73 79 41 72 67    void *pBusyArg
f0e0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
f0f0: 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 61 72 67    /* Context arg
f100: 75 6d 65 6e 74 20 66 6f 72 20 78 42 75 73 79 48  ument for xBusyH
f110: 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74 20  andler */.  int 
f120: 6c 6f 63 6b 49 64 78 2c 20 20 20 20 20 20 20 20  lockIdx,        
f130: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
f140: 66 66 73 65 74 20 6f 66 20 66 69 72 73 74 20 62  ffset of first b
f150: 79 74 65 20 74 6f 20 6c 6f 63 6b 20 2a 2f 0a 20  yte to lock */. 
f160: 20 69 6e 74 20 6e 20 20 20 20 20 20 20 20 20 20   int n          
f170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f180: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
f190: 74 65 73 20 74 6f 20 6c 6f 63 6b 20 2a 2f 0a 29  tes to lock */.)
f1a0: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 64 6f  {.  int rc;.  do
f1b0: 20 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 4c   {.    rc = walL
f1c0: 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
f1d0: 6c 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 29 3b 0a  l, lockIdx, n);.
f1e0: 20 20 7d 77 68 69 6c 65 28 20 78 42 75 73 79 20    }while( xBusy 
f1f0: 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  && rc==SQLITE_BU
f200: 53 59 20 26 26 20 78 42 75 73 79 28 70 42 75 73  SY && xBusy(pBus
f210: 79 41 72 67 29 20 29 3b 0a 20 20 72 65 74 75 72  yArg) );.  retur
f220: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  n rc;.}../*.** T
f230: 68 65 20 63 61 63 68 65 20 6f 66 20 74 68 65 20  he cache of the 
f240: 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
f250: 20 6d 75 73 74 20 62 65 20 76 61 6c 69 64 20 74   must be valid t
f260: 6f 20 63 61 6c 6c 20 74 68 69 73 20 66 75 6e 63  o call this func
f270: 74 69 6f 6e 2e 0a 2a 2a 20 52 65 74 75 72 6e 20  tion..** Return 
f280: 74 68 65 20 70 61 67 65 2d 73 69 7a 65 20 69 6e  the page-size in
f290: 20 62 79 74 65 73 20 75 73 65 64 20 62 79 20 74   bytes used by t
f2a0: 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2f 0a  he database..*/.
f2b0: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 50 61  static int walPa
f2c0: 67 65 73 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c  gesize(Wal *pWal
f2d0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 70 57 61  ){.  return (pWa
f2e0: 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26 30 78  l->hdr.szPage&0x
f2f0: 66 65 30 30 29 20 2b 20 28 28 70 57 61 6c 2d 3e  fe00) + ((pWal->
f300: 68 64 72 2e 73 7a 50 61 67 65 26 30 78 30 30 30  hdr.szPage&0x000
f310: 31 29 3c 3c 31 36 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  1)<<16);.}../*.*
f320: 2a 20 43 6f 70 79 20 61 73 20 6d 75 63 68 20 63  * Copy as much c
f330: 6f 6e 74 65 6e 74 20 61 73 20 77 65 20 63 61 6e  ontent as we can
f340: 20 66 72 6f 6d 20 74 68 65 20 57 41 4c 20 62 61   from the WAL ba
f350: 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ck into the data
f360: 62 61 73 65 20 66 69 6c 65 0a 2a 2a 20 69 6e 20  base file.** in 
f370: 72 65 73 70 6f 6e 73 65 20 74 6f 20 61 6e 20 73  response to an s
f380: 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68 65 63 6b  qlite3_wal_check
f390: 70 6f 69 6e 74 28 29 20 72 65 71 75 65 73 74 20  point() request 
f3a0: 6f 72 20 74 68 65 20 65 71 75 69 76 61 6c 65 6e  or the equivalen
f3b0: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 6d 6f  t..**.** The amo
f3c0: 75 6e 74 20 6f 66 20 69 6e 66 6f 72 6d 61 74 69  unt of informati
f3d0: 6f 6e 20 63 6f 70 69 65 73 20 66 72 6f 6d 20 57  on copies from W
f3e0: 41 4c 20 74 6f 20 64 61 74 61 62 61 73 65 20 6d  AL to database m
f3f0: 69 67 68 74 20 62 65 20 6c 69 6d 69 74 65 64 0a  ight be limited.
f400: 2a 2a 20 62 79 20 61 63 74 69 76 65 20 72 65 61  ** by active rea
f410: 64 65 72 73 2e 20 20 54 68 69 73 20 72 6f 75 74  ders.  This rout
f420: 69 6e 65 20 77 69 6c 6c 20 6e 65 76 65 72 20 6f  ine will never o
f430: 76 65 72 77 72 69 74 65 20 61 20 64 61 74 61 62  verwrite a datab
f440: 61 73 65 20 70 61 67 65 0a 2a 2a 20 74 68 61 74  ase page.** that
f450: 20 61 20 63 6f 6e 63 75 72 72 65 6e 74 20 72 65   a concurrent re
f460: 61 64 65 72 20 6d 69 67 68 74 20 62 65 20 75 73  ader might be us
f470: 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 20 49  ing..**.** All I
f480: 2f 4f 20 62 61 72 72 69 65 72 20 6f 70 65 72 61  /O barrier opera
f490: 74 69 6f 6e 73 20 28 61 2e 6b 2e 61 20 66 73 79  tions (a.k.a fsy
f4a0: 6e 63 73 29 20 6f 63 63 75 72 20 69 6e 20 74 68  ncs) occur in th
f4b0: 69 73 20 72 6f 75 74 69 6e 65 20 77 68 65 6e 0a  is routine when.
f4c0: 2a 2a 20 53 51 4c 69 74 65 20 69 73 20 69 6e 20  ** SQLite is in 
f4d0: 57 41 4c 2d 6d 6f 64 65 20 69 6e 20 73 79 6e 63  WAL-mode in sync
f4e0: 68 72 6f 6e 6f 75 73 3d 4e 4f 52 4d 41 4c 2e 20  hronous=NORMAL. 
f4f0: 20 54 68 61 74 20 6d 65 61 6e 73 20 74 68 61 74   That means that
f500: 20 69 66 20 0a 2a 2a 20 63 68 65 63 6b 70 6f 69   if .** checkpoi
f510: 6e 74 73 20 61 72 65 20 61 6c 77 61 79 73 20 72  nts are always r
f520: 75 6e 20 62 79 20 61 20 62 61 63 6b 67 72 6f 75  un by a backgrou
f530: 6e 64 20 74 68 72 65 61 64 20 6f 72 20 62 61 63  nd thread or bac
f540: 6b 67 72 6f 75 6e 64 20 0a 2a 2a 20 70 72 6f 63  kground .** proc
f550: 65 73 73 2c 20 66 6f 72 65 67 72 6f 75 6e 64 20  ess, foreground 
f560: 74 68 72 65 61 64 73 20 77 69 6c 6c 20 6e 65 76  threads will nev
f570: 65 72 20 62 6c 6f 63 6b 20 6f 6e 20 61 20 6c 65  er block on a le
f580: 6e 67 74 68 79 20 66 73 79 6e 63 20 63 61 6c 6c  ngthy fsync call
f590: 2e 0a 2a 2a 0a 2a 2a 20 46 73 79 6e 63 20 69 73  ..**.** Fsync is
f5a0: 20 63 61 6c 6c 65 64 20 6f 6e 20 74 68 65 20 57   called on the W
f5b0: 41 4c 20 62 65 66 6f 72 65 20 77 72 69 74 69 6e  AL before writin
f5c0: 67 20 63 6f 6e 74 65 6e 74 20 6f 75 74 20 6f 66  g content out of
f5d0: 20 74 68 65 20 57 41 4c 20 61 6e 64 0a 2a 2a 20   the WAL and.** 
f5e0: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
f5f0: 65 2e 20 20 54 68 69 73 20 65 6e 73 75 72 65 73  e.  This ensures
f600: 20 74 68 61 74 20 69 66 20 74 68 65 20 6e 65 77   that if the new
f610: 20 63 6f 6e 74 65 6e 74 20 69 73 20 70 65 72 73   content is pers
f620: 69 73 74 65 6e 74 0a 2a 2a 20 69 6e 20 74 68 65  istent.** in the
f630: 20 57 41 4c 20 61 6e 64 20 63 61 6e 20 62 65 20   WAL and can be 
f640: 72 65 63 6f 76 65 72 65 64 20 66 6f 6c 6c 6f 77  recovered follow
f650: 69 6e 67 20 61 20 70 6f 77 65 72 2d 6c 6f 73 73  ing a power-loss
f660: 20 6f 72 20 68 61 72 64 20 72 65 73 65 74 2e 0a   or hard reset..
f670: 2a 2a 0a 2a 2a 20 46 73 79 6e 63 20 69 73 20 61  **.** Fsync is a
f680: 6c 73 6f 20 63 61 6c 6c 65 64 20 6f 6e 20 74 68  lso called on th
f690: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  e database file 
f6a0: 69 66 20 28 61 6e 64 20 6f 6e 6c 79 20 69 66 29  if (and only if)
f6b0: 20 74 68 65 20 65 6e 74 69 72 65 0a 2a 2a 20 57   the entire.** W
f6c0: 41 4c 20 63 6f 6e 74 65 6e 74 20 69 73 20 63 6f  AL content is co
f6d0: 70 69 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61  pied into the da
f6e0: 74 61 62 61 73 65 20 66 69 6c 65 2e 20 20 54 68  tabase file.  Th
f6f0: 69 73 20 73 65 63 6f 6e 64 20 66 73 79 6e 63 20  is second fsync 
f700: 6d 61 6b 65 73 0a 2a 2a 20 69 74 20 73 61 66 65  makes.** it safe
f710: 20 74 6f 20 64 65 6c 65 74 65 20 74 68 65 20 57   to delete the W
f720: 41 4c 20 73 69 6e 63 65 20 74 68 65 20 6e 65 77  AL since the new
f730: 20 63 6f 6e 74 65 6e 74 20 77 69 6c 6c 20 70 65   content will pe
f740: 72 73 69 73 74 20 69 6e 20 74 68 65 0a 2a 2a 20  rsist in the.** 
f750: 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a  database file..*
f760: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  *.** This routin
f770: 65 20 75 73 65 73 20 61 6e 64 20 75 70 64 61 74  e uses and updat
f780: 65 73 20 74 68 65 20 6e 42 61 63 6b 66 69 6c 6c  es the nBackfill
f790: 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20 77 61   field of the wa
f7a0: 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 2e 0a  l-index header..
f7b0: 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 6f  ** This is the o
f7c0: 6e 6c 79 20 72 6f 75 74 69 6e 65 20 74 68 61 20  nly routine tha 
f7d0: 77 69 6c 6c 20 69 6e 63 72 65 61 73 65 20 74 68  will increase th
f7e0: 65 20 76 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b  e value of nBack
f7f0: 66 69 6c 6c 2e 20 20 0a 2a 2a 20 28 41 20 57 41  fill.  .** (A WA
f800: 4c 20 72 65 73 65 74 20 6f 72 20 72 65 63 6f 76  L reset or recov
f810: 65 72 79 20 77 69 6c 6c 20 72 65 76 65 72 74 20  ery will revert 
f820: 6e 42 61 63 6b 66 69 6c 6c 20 74 6f 20 7a 65 72  nBackfill to zer
f830: 6f 2c 20 62 75 74 20 6e 6f 74 20 69 6e 63 72 65  o, but not incre
f840: 61 73 65 0a 2a 2a 20 69 74 73 20 76 61 6c 75 65  ase.** its value
f850: 2e 29 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c  .).**.** The cal
f860: 6c 65 72 20 6d 75 73 74 20 62 65 20 68 6f 6c 64  ler must be hold
f870: 69 6e 67 20 73 75 66 66 69 63 69 65 6e 74 20 6c  ing sufficient l
f880: 6f 63 6b 73 20 74 6f 20 65 6e 73 75 72 65 20 74  ocks to ensure t
f890: 68 61 74 20 6e 6f 20 6f 74 68 65 72 0a 2a 2a 20  hat no other.** 
f8a0: 63 68 65 63 6b 70 6f 69 6e 74 20 69 73 20 72 75  checkpoint is ru
f8b0: 6e 6e 69 6e 67 20 28 69 6e 20 61 6e 79 20 6f 74  nning (in any ot
f8c0: 68 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72  her thread or pr
f8d0: 6f 63 65 73 73 29 20 61 74 20 74 68 65 20 73 61  ocess) at the sa
f8e0: 6d 65 0a 2a 2a 20 74 69 6d 65 2e 0a 2a 2f 0a 73  me.** time..*/.s
f8f0: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 43 68 65  tatic int walChe
f900: 63 6b 70 6f 69 6e 74 28 0a 20 20 57 61 6c 20 2a  ckpoint(.  Wal *
f910: 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  pWal,           
f920: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61             /* Wa
f930: 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a  l connection */.
f940: 20 20 69 6e 74 20 65 4d 6f 64 65 2c 20 20 20 20    int eMode,    
f950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f960: 20 20 2f 2a 20 4f 6e 65 20 6f 66 20 50 41 53 53    /* One of PASS
f970: 49 56 45 2c 20 46 55 4c 4c 20 6f 72 20 52 45 53  IVE, FULL or RES
f980: 54 41 52 54 20 2a 2f 0a 20 20 69 6e 74 20 28 2a  TART */.  int (*
f990: 78 42 75 73 79 43 61 6c 6c 29 28 76 6f 69 64 2a  xBusyCall)(void*
f9a0: 29 2c 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e  ),        /* Fun
f9b0: 63 74 69 6f 6e 20 74 6f 20 63 61 6c 6c 20 77 68  ction to call wh
f9c0: 65 6e 20 62 75 73 79 20 2a 2f 0a 20 20 76 6f 69  en busy */.  voi
f9d0: 64 20 2a 70 42 75 73 79 41 72 67 2c 20 20 20 20  d *pBusyArg,    
f9e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
f9f0: 43 6f 6e 74 65 78 74 20 61 72 67 75 6d 65 6e 74  Context argument
fa00: 20 66 6f 72 20 78 42 75 73 79 48 61 6e 64 6c 65   for xBusyHandle
fa10: 72 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f  r */.  int sync_
fa20: 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20 20 20  flags,          
fa30: 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20         /* Flags 
fa40: 66 6f 72 20 4f 73 53 79 6e 63 28 29 20 28 6f 72  for OsSync() (or
fa50: 20 30 29 20 2a 2f 0a 20 20 75 38 20 2a 7a 42 75   0) */.  u8 *zBu
fa60: 66 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f               
fa70: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70           /* Temp
fa80: 6f 72 61 72 79 20 62 75 66 66 65 72 20 74 6f 20  orary buffer to 
fa90: 75 73 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  use */.){.  int 
faa0: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
fab0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
fac0: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
fad0: 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20 20  int szPage;     
fae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
faf0: 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  /* Database page
fb00: 2d 73 69 7a 65 20 2a 2f 0a 20 20 57 61 6c 49 74  -size */.  WalIt
fb10: 65 72 61 74 6f 72 20 2a 70 49 74 65 72 20 3d 20  erator *pIter = 
fb20: 30 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61  0;         /* Wa
fb30: 6c 20 69 74 65 72 61 74 6f 72 20 63 6f 6e 74 65  l iterator conte
fb40: 78 74 20 2a 2f 0a 20 20 75 33 32 20 69 44 62 70  xt */.  u32 iDbp
fb50: 61 67 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20  age = 0;        
fb60: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
fb70: 64 61 74 61 62 61 73 65 20 70 61 67 65 20 74 6f  database page to
fb80: 20 77 72 69 74 65 20 2a 2f 0a 20 20 75 33 32 20   write */.  u32 
fb90: 69 46 72 61 6d 65 20 3d 20 30 3b 20 20 20 20 20  iFrame = 0;     
fba0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
fbb0: 61 6c 20 66 72 61 6d 65 20 63 6f 6e 74 61 69 6e  al frame contain
fbc0: 69 6e 67 20 64 61 74 61 20 66 6f 72 20 69 44 62  ing data for iDb
fbd0: 70 61 67 65 20 2a 2f 0a 20 20 75 33 32 20 6d 78  page */.  u32 mx
fbe0: 53 61 66 65 46 72 61 6d 65 3b 20 20 20 20 20 20  SafeFrame;      
fbf0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78            /* Max
fc00: 20 66 72 61 6d 65 20 74 68 61 74 20 63 61 6e 20   frame that can 
fc10: 62 65 20 62 61 63 6b 66 69 6c 6c 65 64 20 2a 2f  be backfilled */
fc20: 0a 20 20 75 33 32 20 6d 78 50 61 67 65 3b 20 20  .  u32 mxPage;  
fc30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fc40: 20 20 20 2f 2a 20 4d 61 78 20 64 61 74 61 62 61     /* Max databa
fc50: 73 65 20 70 61 67 65 20 74 6f 20 77 72 69 74 65  se page to write
fc60: 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20   */.  int i;    
fc70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fc80: 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f        /* Loop co
fc90: 75 6e 74 65 72 20 2a 2f 0a 20 20 76 6f 6c 61 74  unter */.  volat
fca0: 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20  ile WalCkptInfo 
fcb0: 2a 70 49 6e 66 6f 3b 20 20 20 20 2f 2a 20 54 68  *pInfo;    /* Th
fcc0: 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 73 74 61  e checkpoint sta
fcd0: 74 75 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  tus information 
fce0: 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 42 75 73 79  */.  int (*xBusy
fcf0: 29 28 76 6f 69 64 2a 29 20 3d 20 30 3b 20 20 20  )(void*) = 0;   
fd00: 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e       /* Function
fd10: 20 74 6f 20 63 61 6c 6c 20 77 68 65 6e 20 77 61   to call when wa
fd20: 69 74 69 6e 67 20 66 6f 72 20 6c 6f 63 6b 73 20  iting for locks 
fd30: 2a 2f 0a 0a 20 20 73 7a 50 61 67 65 20 3d 20 77  */..  szPage = w
fd40: 61 6c 50 61 67 65 73 69 7a 65 28 70 57 61 6c 29  alPagesize(pWal)
fd50: 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 73 7a  ;.  testcase( sz
fd60: 50 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20  Page<=32768 );. 
fd70: 20 74 65 73 74 63 61 73 65 28 20 73 7a 50 61 67   testcase( szPag
fd80: 65 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 70 49  e>=65536 );.  pI
fd90: 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66  nfo = walCkptInf
fda0: 6f 28 70 57 61 6c 29 3b 0a 20 20 69 66 28 20 70  o(pWal);.  if( p
fdb0: 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3e  Info->nBackfill>
fdc0: 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  =pWal->hdr.mxFra
fdd0: 6d 65 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  me ) return SQLI
fde0: 54 45 5f 4f 4b 3b 0a 0a 20 20 2f 2a 20 41 6c 6c  TE_OK;..  /* All
fdf0: 6f 63 61 74 65 20 74 68 65 20 69 74 65 72 61 74  ocate the iterat
fe00: 6f 72 20 2a 2f 0a 20 20 72 63 20 3d 20 77 61 6c  or */.  rc = wal
fe10: 49 74 65 72 61 74 6f 72 49 6e 69 74 28 70 57 61  IteratorInit(pWa
fe20: 6c 2c 20 26 70 49 74 65 72 29 3b 0a 20 20 69 66  l, &pIter);.  if
fe30: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
fe40: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  ){.    return rc
fe50: 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20  ;.  }.  assert( 
fe60: 70 49 74 65 72 20 29 3b 0a 0a 20 20 69 66 28 20  pIter );..  if( 
fe70: 65 4d 6f 64 65 21 3d 53 51 4c 49 54 45 5f 43 48  eMode!=SQLITE_CH
fe80: 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49 56 45  ECKPOINT_PASSIVE
fe90: 20 29 20 78 42 75 73 79 20 3d 20 78 42 75 73 79   ) xBusy = xBusy
fea0: 43 61 6c 6c 3b 0a 0a 20 20 2f 2a 20 43 6f 6d 70  Call;..  /* Comp
feb0: 75 74 65 20 69 6e 20 6d 78 53 61 66 65 46 72 61  ute in mxSafeFra
fec0: 6d 65 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20  me the index of 
fed0: 74 68 65 20 6c 61 73 74 20 66 72 61 6d 65 20 6f  the last frame o
fee0: 66 20 74 68 65 20 57 41 4c 20 74 68 61 74 20 69  f the WAL that i
fef0: 73 0a 20 20 2a 2a 20 73 61 66 65 20 74 6f 20 77  s.  ** safe to w
ff00: 72 69 74 65 20 69 6e 74 6f 20 74 68 65 20 64 61  rite into the da
ff10: 74 61 62 61 73 65 2e 20 20 46 72 61 6d 65 73 20  tabase.  Frames 
ff20: 62 65 79 6f 6e 64 20 6d 78 53 61 66 65 46 72 61  beyond mxSafeFra
ff30: 6d 65 20 6d 69 67 68 74 0a 20 20 2a 2a 20 6f 76  me might.  ** ov
ff40: 65 72 77 72 69 74 65 20 64 61 74 61 62 61 73 65  erwrite database
ff50: 20 70 61 67 65 73 20 74 68 61 74 20 61 72 65 20   pages that are 
ff60: 69 6e 20 75 73 65 20 62 79 20 61 63 74 69 76 65  in use by active
ff70: 20 72 65 61 64 65 72 73 20 61 6e 64 20 74 68 75   readers and thu
ff80: 73 0a 20 20 2a 2a 20 63 61 6e 6e 6f 74 20 62 65  s.  ** cannot be
ff90: 20 62 61 63 6b 66 69 6c 6c 65 64 20 66 72 6f 6d   backfilled from
ffa0: 20 74 68 65 20 57 41 4c 2e 0a 20 20 2a 2f 0a 20   the WAL..  */. 
ffb0: 20 6d 78 53 61 66 65 46 72 61 6d 65 20 3d 20 70   mxSafeFrame = p
ffc0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
ffd0: 3b 0a 20 20 6d 78 50 61 67 65 20 3d 20 70 57 61  ;.  mxPage = pWa
ffe0: 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 3b 0a 20 20  l->hdr.nPage;.  
fff0: 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e  for(i=1; i<WAL_N
10000 52 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20  READER; i++){.  
10010 20 20 75 33 32 20 79 20 3d 20 70 49 6e 66 6f 2d    u32 y = pInfo-
10020 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20  >aReadMark[i];. 
10030 20 20 20 69 66 28 20 6d 78 53 61 66 65 46 72 61     if( mxSafeFra
10040 6d 65 3e 79 20 29 7b 0a 20 20 20 20 20 20 61 73  me>y ){.      as
10050 73 65 72 74 28 20 79 3c 3d 70 57 61 6c 2d 3e 68  sert( y<=pWal->h
10060 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20  dr.mxFrame );.  
10070 20 20 20 20 72 63 20 3d 20 77 61 6c 42 75 73 79      rc = walBusy
10080 4c 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73 79  Lock(pWal, xBusy
10090 2c 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c 5f  , pBusyArg, WAL_
100a0 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29  READ_LOCK(i), 1)
100b0 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
100c0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
100d0 20 20 20 20 20 70 49 6e 66 6f 2d 3e 61 52 65 61       pInfo->aRea
100e0 64 4d 61 72 6b 5b 69 5d 20 3d 20 28 69 3d 3d 31  dMark[i] = (i==1
100f0 20 3f 20 6d 78 53 61 66 65 46 72 61 6d 65 20 3a   ? mxSafeFrame :
10100 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53   READMARK_NOT_US
10110 45 44 29 3b 0a 20 20 20 20 20 20 20 20 77 61 6c  ED);.        wal
10120 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  UnlockExclusive(
10130 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  pWal, WAL_READ_L
10140 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20 20  OCK(i), 1);.    
10150 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d    }else if( rc==
10160 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20  SQLITE_BUSY ){. 
10170 20 20 20 20 20 20 20 6d 78 53 61 66 65 46 72 61         mxSafeFra
10180 6d 65 20 3d 20 79 3b 0a 20 20 20 20 20 20 20 20  me = y;.        
10190 78 42 75 73 79 20 3d 20 30 3b 0a 20 20 20 20 20  xBusy = 0;.     
101a0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
101b0 67 6f 74 6f 20 77 61 6c 63 68 65 63 6b 70 6f 69  goto walcheckpoi
101c0 6e 74 5f 6f 75 74 3b 0a 20 20 20 20 20 20 7d 0a  nt_out;.      }.
101d0 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28      }.  }..  if(
101e0 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
101f0 6c 3c 6d 78 53 61 66 65 46 72 61 6d 65 0a 20 20  l<mxSafeFrame.  
10200 20 26 26 20 28 72 63 20 3d 20 77 61 6c 42 75 73   && (rc = walBus
10210 79 4c 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73  yLock(pWal, xBus
10220 79 2c 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c  y, pBusyArg, WAL
10230 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 31  _READ_LOCK(0), 1
10240 29 29 3d 3d 53 51 4c 49 54 45 5f 4f 4b 0a 20 20  ))==SQLITE_OK.  
10250 29 7b 0a 20 20 20 20 69 36 34 20 6e 53 69 7a 65  ){.    i64 nSize
10260 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
10270 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20       /* Current 
10280 73 69 7a 65 20 6f 66 20 64 61 74 61 62 61 73 65  size of database
10290 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 75 33 32   file */.    u32
102a0 20 6e 42 61 63 6b 66 69 6c 6c 20 3d 20 70 49 6e   nBackfill = pIn
102b0 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3b 0a 0a  fo->nBackfill;..
102c0 20 20 20 20 2f 2a 20 53 79 6e 63 20 74 68 65 20      /* Sync the 
102d0 57 41 4c 20 74 6f 20 64 69 73 6b 20 2a 2f 0a 20  WAL to disk */. 
102e0 20 20 20 69 66 28 20 73 79 6e 63 5f 66 6c 61 67     if( sync_flag
102f0 73 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  s ){.      rc = 
10300 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 70 57  sqlite3OsSync(pW
10310 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 73 79 6e 63  al->pWalFd, sync
10320 5f 66 6c 61 67 73 29 3b 0a 20 20 20 20 7d 0a 0a  _flags);.    }..
10330 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 64 61      /* If the da
10340 74 61 62 61 73 65 20 6d 61 79 20 67 72 6f 77 20  tabase may grow 
10350 61 73 20 61 20 72 65 73 75 6c 74 20 6f 66 20 74  as a result of t
10360 68 69 73 20 63 68 65 63 6b 70 6f 69 6e 74 2c 20  his checkpoint, 
10370 68 69 6e 74 0a 20 20 20 20 2a 2a 20 61 62 6f 75  hint.    ** abou
10380 74 20 74 68 65 20 65 76 65 6e 74 75 61 6c 20 73  t the eventual s
10390 69 7a 65 20 6f 66 20 74 68 65 20 64 62 20 66 69  ize of the db fi
103a0 6c 65 20 74 6f 20 74 68 65 20 56 46 53 20 6c 61  le to the VFS la
103b0 79 65 72 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  yer..    */.    
103c0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
103d0 4b 20 29 7b 0a 20 20 20 20 20 20 69 36 34 20 6e  K ){.      i64 n
103e0 52 65 71 20 3d 20 28 28 69 36 34 29 6d 78 50 61  Req = ((i64)mxPa
103f0 67 65 20 2a 20 73 7a 50 61 67 65 29 3b 0a 20 20  ge * szPage);.  
10400 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
10410 4f 73 46 69 6c 65 53 69 7a 65 28 70 57 61 6c 2d  OsFileSize(pWal-
10420 3e 70 44 62 46 64 2c 20 26 6e 53 69 7a 65 29 3b  >pDbFd, &nSize);
10430 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
10440 51 4c 49 54 45 5f 4f 4b 20 26 26 20 6e 53 69 7a  QLITE_OK && nSiz
10450 65 3c 6e 52 65 71 20 29 7b 0a 20 20 20 20 20 20  e<nReq ){.      
10460 20 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 43    sqlite3OsFileC
10470 6f 6e 74 72 6f 6c 48 69 6e 74 28 70 57 61 6c 2d  ontrolHint(pWal-
10480 3e 70 44 62 46 64 2c 20 53 51 4c 49 54 45 5f 46  >pDbFd, SQLITE_F
10490 43 4e 54 4c 5f 53 49 5a 45 5f 48 49 4e 54 2c 20  CNTL_SIZE_HINT, 
104a0 26 6e 52 65 71 29 3b 0a 20 20 20 20 20 20 7d 0a  &nReq);.      }.
104b0 20 20 20 20 7d 0a 0a 0a 20 20 20 20 2f 2a 20 49      }...    /* I
104c0 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 74  terate through t
104d0 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
104e0 68 65 20 57 41 4c 2c 20 63 6f 70 79 69 6e 67 20  he WAL, copying 
104f0 64 61 74 61 20 74 6f 20 74 68 65 20 64 62 20 66  data to the db f
10500 69 6c 65 2e 20 2a 2f 0a 20 20 20 20 77 68 69 6c  ile. */.    whil
10510 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  e( rc==SQLITE_OK
10520 20 26 26 20 30 3d 3d 77 61 6c 49 74 65 72 61 74   && 0==walIterat
10530 6f 72 4e 65 78 74 28 70 49 74 65 72 2c 20 26 69  orNext(pIter, &i
10540 44 62 70 61 67 65 2c 20 26 69 46 72 61 6d 65 29  Dbpage, &iFrame)
10550 20 29 7b 0a 20 20 20 20 20 20 69 36 34 20 69 4f   ){.      i64 iO
10560 66 66 73 65 74 3b 0a 20 20 20 20 20 20 61 73 73  ffset;.      ass
10570 65 72 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e  ert( walFramePgn
10580 6f 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 3d  o(pWal, iFrame)=
10590 3d 69 44 62 70 61 67 65 20 29 3b 0a 20 20 20 20  =iDbpage );.    
105a0 20 20 69 66 28 20 69 46 72 61 6d 65 3c 3d 6e 42    if( iFrame<=nB
105b0 61 63 6b 66 69 6c 6c 20 7c 7c 20 69 46 72 61 6d  ackfill || iFram
105c0 65 3e 6d 78 53 61 66 65 46 72 61 6d 65 20 7c 7c  e>mxSafeFrame ||
105d0 20 69 44 62 70 61 67 65 3e 6d 78 50 61 67 65 20   iDbpage>mxPage 
105e0 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20  ) continue;.    
105f0 20 20 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46    iOffset = walF
10600 72 61 6d 65 4f 66 66 73 65 74 28 69 46 72 61 6d  rameOffset(iFram
10610 65 2c 20 73 7a 50 61 67 65 29 20 2b 20 57 41 4c  e, szPage) + WAL
10620 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a  _FRAME_HDRSIZE;.
10630 20 20 20 20 20 20 2f 2a 20 74 65 73 74 63 61 73        /* testcas
10640 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28 69 4f  e( IS_BIG_INT(iO
10650 66 66 73 65 74 29 20 29 3b 20 2f 2f 20 72 65 71  ffset) ); // req
10660 75 69 72 65 73 20 61 20 34 47 69 42 20 57 41 4c  uires a 4GiB WAL
10670 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 20 20 72   file */.      r
10680 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61  c = sqlite3OsRea
10690 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20  d(pWal->pWalFd, 
106a0 7a 42 75 66 2c 20 73 7a 50 61 67 65 2c 20 69 4f  zBuf, szPage, iO
106b0 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 69 66  ffset);.      if
106c0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
106d0 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 69  ) break;.      i
106e0 4f 66 66 73 65 74 20 3d 20 28 69 44 62 70 61 67  Offset = (iDbpag
106f0 65 2d 31 29 2a 28 69 36 34 29 73 7a 50 61 67 65  e-1)*(i64)szPage
10700 3b 0a 20 20 20 20 20 20 74 65 73 74 63 61 73 65  ;.      testcase
10710 28 20 49 53 5f 42 49 47 5f 49 4e 54 28 69 4f 66  ( IS_BIG_INT(iOf
10720 66 73 65 74 29 20 29 3b 0a 20 20 20 20 20 20 72  fset) );.      r
10730 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69  c = sqlite3OsWri
10740 74 65 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20  te(pWal->pDbFd, 
10750 7a 42 75 66 2c 20 73 7a 50 61 67 65 2c 20 69 4f  zBuf, szPage, iO
10760 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 69 66  ffset);.      if
10770 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
10780 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a  ) break;.    }..
10790 20 20 20 20 2f 2a 20 49 66 20 77 6f 72 6b 20 77      /* If work w
107a0 61 73 20 61 63 74 75 61 6c 6c 79 20 61 63 63 6f  as actually acco
107b0 6d 70 6c 69 73 68 65 64 2e 2e 2e 20 2a 2f 0a 20  mplished... */. 
107c0 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
107d0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 66  E_OK ){.      if
107e0 28 20 6d 78 53 61 66 65 46 72 61 6d 65 3d 3d 77  ( mxSafeFrame==w
107f0 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29  alIndexHdr(pWal)
10800 2d 3e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20  ->mxFrame ){.   
10810 20 20 20 20 20 69 36 34 20 73 7a 44 62 20 3d 20       i64 szDb = 
10820 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 2a  pWal->hdr.nPage*
10830 28 69 36 34 29 73 7a 50 61 67 65 3b 0a 20 20 20  (i64)szPage;.   
10840 20 20 20 20 20 74 65 73 74 63 61 73 65 28 20 49       testcase( I
10850 53 5f 42 49 47 5f 49 4e 54 28 73 7a 44 62 29 20  S_BIG_INT(szDb) 
10860 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  );.        rc = 
10870 73 71 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74  sqlite3OsTruncat
10880 65 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 73  e(pWal->pDbFd, s
10890 7a 44 62 29 3b 0a 20 20 20 20 20 20 20 20 69 66  zDb);.        if
108a0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
108b0 26 26 20 73 79 6e 63 5f 66 6c 61 67 73 20 29 7b  && sync_flags ){
108c0 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
108d0 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 70 57  sqlite3OsSync(pW
108e0 61 6c 2d 3e 70 44 62 46 64 2c 20 73 79 6e 63 5f  al->pDbFd, sync_
108f0 66 6c 61 67 73 29 3b 0a 20 20 20 20 20 20 20 20  flags);.        
10900 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
10910 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
10920 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49 6e  K ){.        pIn
10930 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 20 3d 20  fo->nBackfill = 
10940 6d 78 53 61 66 65 46 72 61 6d 65 3b 0a 20 20 20  mxSafeFrame;.   
10950 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20     }.    }..    
10960 2f 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20 72  /* Release the r
10970 65 61 64 65 72 20 6c 6f 63 6b 20 68 65 6c 64 20  eader lock held 
10980 77 68 69 6c 65 20 62 61 63 6b 66 69 6c 6c 69 6e  while backfillin
10990 67 20 2a 2f 0a 20 20 20 20 77 61 6c 55 6e 6c 6f  g */.    walUnlo
109a0 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
109b0 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
109c0 30 29 2c 20 31 29 3b 0a 20 20 7d 0a 0a 20 20 69  0), 1);.  }..  i
109d0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  f( rc==SQLITE_BU
109e0 53 59 20 29 7b 0a 20 20 20 20 2f 2a 20 52 65 73  SY ){.    /* Res
109f0 65 74 20 74 68 65 20 72 65 74 75 72 6e 20 63 6f  et the return co
10a00 64 65 20 73 6f 20 61 73 20 6e 6f 74 20 74 6f 20  de so as not to 
10a10 72 65 70 6f 72 74 20 61 20 63 68 65 63 6b 70 6f  report a checkpo
10a20 69 6e 74 20 66 61 69 6c 75 72 65 0a 20 20 20 20  int failure.    
10a30 2a 2a 20 6a 75 73 74 20 62 65 63 61 75 73 65 20  ** just because 
10a40 74 68 65 72 65 20 61 72 65 20 61 63 74 69 76 65  there are active
10a50 20 72 65 61 64 65 72 73 2e 20 20 2a 2f 0a 20 20   readers.  */.  
10a60 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b    rc = SQLITE_OK
10a70 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74  ;.  }..  /* If t
10a80 68 69 73 20 69 73 20 61 6e 20 53 51 4c 49 54 45  his is an SQLITE
10a90 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 52 45 53 54  _CHECKPOINT_REST
10aa0 41 52 54 20 6f 70 65 72 61 74 69 6f 6e 2c 20 61  ART operation, a
10ab0 6e 64 20 74 68 65 20 65 6e 74 69 72 65 20 77 61  nd the entire wa
10ac0 6c 0a 20 20 2a 2a 20 66 69 6c 65 20 68 61 73 20  l.  ** file has 
10ad0 62 65 65 6e 20 63 6f 70 69 65 64 20 69 6e 74 6f  been copied into
10ae0 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
10af0 6c 65 2c 20 74 68 65 6e 20 62 6c 6f 63 6b 20 75  le, then block u
10b00 6e 74 69 6c 20 61 6c 6c 0a 20 20 2a 2a 20 72 65  ntil all.  ** re
10b10 61 64 65 72 73 20 68 61 76 65 20 66 69 6e 69 73  aders have finis
10b20 68 65 64 20 75 73 69 6e 67 20 74 68 65 20 77 61  hed using the wa
10b30 6c 20 66 69 6c 65 2e 20 54 68 69 73 20 65 6e 73  l file. This ens
10b40 75 72 65 73 20 74 68 61 74 20 74 68 65 20 6e 65  ures that the ne
10b50 78 74 0a 20 20 2a 2a 20 70 72 6f 63 65 73 73 20  xt.  ** process 
10b60 74 6f 20 77 72 69 74 65 20 74 6f 20 74 68 65 20  to write to the 
10b70 64 61 74 61 62 61 73 65 20 72 65 73 74 61 72 74  database restart
10b80 73 20 74 68 65 20 77 61 6c 20 66 69 6c 65 2e 0a  s the wal file..
10b90 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53    */.  if( rc==S
10ba0 51 4c 49 54 45 5f 4f 4b 20 26 26 20 65 4d 6f 64  QLITE_OK && eMod
10bb0 65 21 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b 50  e!=SQLITE_CHECKP
10bc0 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 29 7b 0a  OINT_PASSIVE ){.
10bd0 20 20 20 20 61 73 73 65 72 74 28 20 70 57 61 6c      assert( pWal
10be0 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20  ->writeLock );. 
10bf0 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 42     if( pInfo->nB
10c00 61 63 6b 66 69 6c 6c 3c 70 57 61 6c 2d 3e 68 64  ackfill<pWal->hd
10c10 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20  r.mxFrame ){.   
10c20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42     rc = SQLITE_B
10c30 55 53 59 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  USY;.    }else i
10c40 66 28 20 65 4d 6f 64 65 3d 3d 53 51 4c 49 54 45  f( eMode==SQLITE
10c50 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 52 45 53 54  _CHECKPOINT_REST
10c60 41 52 54 20 29 7b 0a 20 20 20 20 20 20 61 73 73  ART ){.      ass
10c70 65 72 74 28 20 6d 78 53 61 66 65 46 72 61 6d 65  ert( mxSafeFrame
10c80 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  ==pWal->hdr.mxFr
10c90 61 6d 65 20 29 3b 0a 20 20 20 20 20 20 72 63 20  ame );.      rc 
10ca0 3d 20 77 61 6c 42 75 73 79 4c 6f 63 6b 28 70 57  = walBusyLock(pW
10cb0 61 6c 2c 20 78 42 75 73 79 2c 20 70 42 75 73 79  al, xBusy, pBusy
10cc0 41 72 67 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Arg, WAL_READ_LO
10cd0 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44  CK(1), WAL_NREAD
10ce0 45 52 2d 31 29 3b 0a 20 20 20 20 20 20 69 66 28  ER-1);.      if(
10cf0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
10d00 7b 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c  {.        walUnl
10d10 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
10d20 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  l, WAL_READ_LOCK
10d30 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52  (1), WAL_NREADER
10d40 2d 31 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  -1);.      }.   
10d50 20 7d 0a 20 20 7d 0a 0a 20 77 61 6c 63 68 65 63   }.  }.. walchec
10d60 6b 70 6f 69 6e 74 5f 6f 75 74 3a 0a 20 20 77 61  kpoint_out:.  wa
10d70 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28 70 49  lIteratorFree(pI
10d80 74 65 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  ter);.  return r
10d90 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74  c;.}../*.** If t
10da0 68 65 20 57 41 4c 20 66 69 6c 65 20 69 73 20 63  he WAL file is c
10db0 75 72 72 65 6e 74 6c 79 20 6c 61 72 67 65 72 20  urrently larger 
10dc0 74 68 61 6e 20 6e 4d 61 78 20 62 79 74 65 73 20  than nMax bytes 
10dd0 69 6e 20 73 69 7a 65 2c 20 74 72 75 6e 63 61 74  in size, truncat
10de0 65 0a 2a 2a 20 69 74 20 74 6f 20 65 78 61 63 74  e.** it to exact
10df0 6c 79 20 6e 4d 61 78 20 62 79 74 65 73 2e 20 49  ly nMax bytes. I
10e00 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
10e10 73 20 77 68 69 6c 65 20 64 6f 69 6e 67 20 73 6f  s while doing so
10e20 2c 20 69 67 6e 6f 72 65 20 69 74 2e 0a 2a 2f 0a  , ignore it..*/.
10e30 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 4c  static void walL
10e40 69 6d 69 74 53 69 7a 65 28 57 61 6c 20 2a 70 57  imitSize(Wal *pW
10e50 61 6c 2c 20 69 36 34 20 6e 4d 61 78 29 7b 0a 20  al, i64 nMax){. 
10e60 20 69 36 34 20 73 7a 3b 0a 20 20 69 6e 74 20 72   i64 sz;.  int r
10e70 78 3b 0a 20 20 73 71 6c 69 74 65 33 42 65 67 69  x;.  sqlite3Begi
10e80 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  nBenignMalloc();
10e90 0a 20 20 72 78 20 3d 20 73 71 6c 69 74 65 33 4f  .  rx = sqlite3O
10ea0 73 46 69 6c 65 53 69 7a 65 28 70 57 61 6c 2d 3e  sFileSize(pWal->
10eb0 70 57 61 6c 46 64 2c 20 26 73 7a 29 3b 0a 20 20  pWalFd, &sz);.  
10ec0 69 66 28 20 72 78 3d 3d 53 51 4c 49 54 45 5f 4f  if( rx==SQLITE_O
10ed0 4b 20 26 26 20 28 73 7a 20 3e 20 6e 4d 61 78 20  K && (sz > nMax 
10ee0 29 20 29 7b 0a 20 20 20 20 72 78 20 3d 20 73 71  ) ){.    rx = sq
10ef0 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28  lite3OsTruncate(
10f00 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 6e 4d  pWal->pWalFd, nM
10f10 61 78 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74  ax);.  }.  sqlit
10f20 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f  e3EndBenignMallo
10f30 63 28 29 3b 0a 20 20 69 66 28 20 72 78 20 29 7b  c();.  if( rx ){
10f40 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67  .    sqlite3_log
10f50 28 72 78 2c 20 22 63 61 6e 6e 6f 74 20 6c 69 6d  (rx, "cannot lim
10f60 69 74 20 57 41 4c 20 73 69 7a 65 3a 20 25 73 22  it WAL size: %s"
10f70 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65  , pWal->zWalName
10f80 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
10f90 43 6c 6f 73 65 20 61 20 63 6f 6e 6e 65 63 74 69  Close a connecti
10fa0 6f 6e 20 74 6f 20 61 20 6c 6f 67 20 66 69 6c 65  on to a log file
10fb0 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
10fc0 57 61 6c 43 6c 6f 73 65 28 0a 20 20 57 61 6c 20  WalClose(.  Wal 
10fd0 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20  *pWal,          
10fe0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
10ff0 61 6c 20 74 6f 20 63 6c 6f 73 65 20 2a 2f 0a 20  al to close */. 
11000 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67 73 2c   int sync_flags,
11010 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11020 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20 70 61 73   /* Flags to pas
11030 73 20 74 6f 20 4f 73 53 79 6e 63 28 29 20 28 6f  s to OsSync() (o
11040 72 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  r 0) */.  int nB
11050 75 66 2c 0a 20 20 75 38 20 2a 7a 42 75 66 20 20  uf,.  u8 *zBuf  
11060 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11070 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
11080 6f 66 20 61 74 20 6c 65 61 73 74 20 6e 42 75 66  of at least nBuf
11090 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 69   bytes */.){.  i
110a0 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
110b0 4b 3b 0a 20 20 69 66 28 20 70 57 61 6c 20 29 7b  K;.  if( pWal ){
110c0 0a 20 20 20 20 69 6e 74 20 69 73 44 65 6c 65 74  .    int isDelet
110d0 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  e = 0;          
110e0 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 75 6e     /* True to un
110f0 6c 69 6e 6b 20 77 61 6c 20 61 6e 64 20 77 61 6c  link wal and wal
11100 2d 69 6e 64 65 78 20 66 69 6c 65 73 20 2a 2f 0a  -index files */.
11110 0a 20 20 20 20 2f 2a 20 49 66 20 61 6e 20 45 58  .    /* If an EX
11120 43 4c 55 53 49 56 45 20 6c 6f 63 6b 20 63 61 6e  CLUSIVE lock can
11130 20 62 65 20 6f 62 74 61 69 6e 65 64 20 6f 6e 20   be obtained on 
11140 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
11150 65 20 28 75 73 69 6e 67 20 74 68 65 0a 20 20 20  e (using the.   
11160 20 2a 2a 20 6f 72 64 69 6e 61 72 79 2c 20 72 6f   ** ordinary, ro
11170 6c 6c 62 61 63 6b 2d 6d 6f 64 65 20 6c 6f 63 6b  llback-mode lock
11180 69 6e 67 20 6d 65 74 68 6f 64 73 2c 20 74 68 69  ing methods, thi
11190 73 20 67 75 61 72 61 6e 74 65 65 73 20 74 68 61  s guarantees tha
111a0 74 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 6f 6e  t the.    ** con
111b0 6e 65 63 74 69 6f 6e 20 61 73 73 6f 63 69 61 74  nection associat
111c0 65 64 20 77 69 74 68 20 74 68 69 73 20 6c 6f 67  ed with this log
111d0 20 66 69 6c 65 20 69 73 20 74 68 65 20 6f 6e 6c   file is the onl
111e0 79 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 0a  y connection to.
111f0 20 20 20 20 2a 2a 20 74 68 65 20 64 61 74 61 62      ** the datab
11200 61 73 65 2e 20 49 6e 20 74 68 69 73 20 63 61 73  ase. In this cas
11210 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 74 68 65  e checkpoint the
11220 20 64 61 74 61 62 61 73 65 20 61 6e 64 20 75 6e   database and un
11230 6c 69 6e 6b 20 62 6f 74 68 0a 20 20 20 20 2a 2a  link both.    **
11240 20 74 68 65 20 77 61 6c 20 61 6e 64 20 77 61 6c   the wal and wal
11250 2d 69 6e 64 65 78 20 66 69 6c 65 73 2e 0a 20 20  -index files..  
11260 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68 65 20    **.    ** The 
11270 45 58 43 4c 55 53 49 56 45 20 6c 6f 63 6b 20 69  EXCLUSIVE lock i
11280 73 20 6e 6f 74 20 72 65 6c 65 61 73 65 64 20 62  s not released b
11290 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
112a0 0a 20 20 20 20 2a 2f 0a 20 20 20 20 72 63 20 3d  .    */.    rc =
112b0 20 73 71 6c 69 74 65 33 4f 73 4c 6f 63 6b 28 70   sqlite3OsLock(p
112c0 57 61 6c 2d 3e 70 44 62 46 64 2c 20 53 51 4c 49  Wal->pDbFd, SQLI
112d0 54 45 5f 4c 4f 43 4b 5f 45 58 43 4c 55 53 49 56  TE_LOCK_EXCLUSIV
112e0 45 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  E);.    if( rc==
112f0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
11300 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63     if( pWal->exc
11310 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f  lusiveMode==WAL_
11320 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 20 29 7b 0a 20  NORMAL_MODE ){. 
11330 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 65 78 63         pWal->exc
11340 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 57 41 4c  lusiveMode = WAL
11350 5f 45 58 43 4c 55 53 49 56 45 5f 4d 4f 44 45 3b  _EXCLUSIVE_MODE;
11360 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72  .      }.      r
11370 63 20 3d 20 73 71 6c 69 74 65 33 57 61 6c 43 68  c = sqlite3WalCh
11380 65 63 6b 70 6f 69 6e 74 28 0a 20 20 20 20 20 20  eckpoint(.      
11390 20 20 20 20 70 57 61 6c 2c 20 53 51 4c 49 54 45      pWal, SQLITE
113a0 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53  _CHECKPOINT_PASS
113b0 49 56 45 2c 20 30 2c 20 30 2c 20 73 79 6e 63 5f  IVE, 0, 0, sync_
113c0 66 6c 61 67 73 2c 20 6e 42 75 66 2c 20 7a 42 75  flags, nBuf, zBu
113d0 66 2c 20 30 2c 20 30 0a 20 20 20 20 20 20 29 3b  f, 0, 0.      );
113e0 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
113f0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
11400 20 20 20 20 69 6e 74 20 62 50 65 72 73 69 73 74      int bPersist
11410 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20 20 20 73   = -1;.        s
11420 71 6c 69 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74  qlite3OsFileCont
11430 72 6f 6c 48 69 6e 74 28 0a 20 20 20 20 20 20 20  rolHint(.       
11440 20 20 20 20 20 70 57 61 6c 2d 3e 70 44 62 46 64       pWal->pDbFd
11450 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 50  , SQLITE_FCNTL_P
11460 45 52 53 49 53 54 5f 57 41 4c 2c 20 26 62 50 65  ERSIST_WAL, &bPe
11470 72 73 69 73 74 0a 20 20 20 20 20 20 20 20 29 3b  rsist.        );
11480 0a 20 20 20 20 20 20 20 20 69 66 28 20 62 50 65  .        if( bPe
11490 72 73 69 73 74 21 3d 31 20 29 7b 0a 20 20 20 20  rsist!=1 ){.    
114a0 20 20 20 20 20 20 2f 2a 20 54 72 79 20 74 6f 20        /* Try to 
114b0 64 65 6c 65 74 65 20 74 68 65 20 57 41 4c 20 66  delete the WAL f
114c0 69 6c 65 20 69 66 20 74 68 65 20 63 68 65 63 6b  ile if the check
114d0 70 6f 69 6e 74 20 63 6f 6d 70 6c 65 74 65 64 20  point completed 
114e0 61 6e 64 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  and.          **
114f0 20 66 73 79 6e 65 64 20 28 72 63 3d 3d 53 51 4c   fsyned (rc==SQL
11500 49 54 45 5f 4f 4b 29 20 61 6e 64 20 69 66 20 77  ITE_OK) and if w
11510 65 20 61 72 65 20 6e 6f 74 20 69 6e 20 70 65 72  e are not in per
11520 73 69 73 74 65 6e 74 2d 77 61 6c 0a 20 20 20 20  sistent-wal.    
11530 20 20 20 20 20 20 2a 2a 20 6d 6f 64 65 20 28 21        ** mode (!
11540 62 50 65 72 73 69 73 74 29 20 2a 2f 0a 20 20 20  bPersist) */.   
11550 20 20 20 20 20 20 20 69 73 44 65 6c 65 74 65 20         isDelete 
11560 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  = 1;.        }el
11570 73 65 20 69 66 28 20 70 57 61 6c 2d 3e 6d 78 57  se if( pWal->mxW
11580 61 6c 53 69 7a 65 3e 3d 30 20 29 7b 0a 20 20 20  alSize>=0 ){.   
11590 20 20 20 20 20 20 20 2f 2a 20 54 72 79 20 74 6f         /* Try to
115a0 20 74 72 75 6e 63 61 74 65 20 74 68 65 20 57 41   truncate the WA
115b0 4c 20 66 69 6c 65 20 74 6f 20 7a 65 72 6f 20 62  L file to zero b
115c0 79 74 65 73 20 69 66 20 74 68 65 20 63 68 65 63  ytes if the chec
115d0 6b 70 6f 69 6e 74 0a 20 20 20 20 20 20 20 20 20  kpoint.         
115e0 20 2a 2a 20 63 6f 6d 70 6c 65 74 65 64 20 61 6e   ** completed an
115f0 64 20 66 73 79 6e 63 65 64 20 28 72 63 3d 3d 53  d fsynced (rc==S
11600 51 4c 49 54 45 5f 4f 4b 29 20 61 6e 64 20 77 65  QLITE_OK) and we
11610 20 61 72 65 20 69 6e 20 70 65 72 73 69 73 74 65   are in persiste
11620 6e 74 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20  nt.          ** 
11630 57 41 4c 20 6d 6f 64 65 20 28 62 50 65 72 73 69  WAL mode (bPersi
11640 73 74 29 20 61 6e 64 20 69 66 20 74 68 65 20 50  st) and if the P
11650 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 73 69  RAGMA journal_si
11660 7a 65 5f 6c 69 6d 69 74 20 69 73 20 61 0a 20 20  ze_limit is a.  
11670 20 20 20 20 20 20 20 20 2a 2a 20 6e 6f 6e 2d 6e          ** non-n
11680 65 67 61 74 69 76 65 20 76 61 6c 75 65 20 28 70  egative value (p
11690 57 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 3e 3d  Wal->mxWalSize>=
116a0 30 29 2e 20 20 4e 6f 74 65 20 74 68 61 74 20 77  0).  Note that w
116b0 65 20 74 72 75 6e 63 61 74 65 0a 20 20 20 20 20  e truncate.     
116c0 20 20 20 20 20 2a 2a 20 74 6f 20 7a 65 72 6f 20       ** to zero 
116d0 62 79 74 65 73 20 61 73 20 74 72 75 6e 63 61 74  bytes as truncat
116e0 69 6e 67 20 74 6f 20 74 68 65 20 6a 6f 75 72 6e  ing to the journ
116f0 61 6c 5f 73 69 7a 65 5f 6c 69 6d 69 74 20 6d 69  al_size_limit mi
11700 67 68 74 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  ght.          **
11710 20 6c 65 61 76 65 20 61 20 63 6f 72 72 75 70 74   leave a corrupt
11720 20 57 41 4c 20 66 69 6c 65 20 6f 6e 20 64 69 73   WAL file on dis
11730 6b 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  k. */.          
11740 77 61 6c 4c 69 6d 69 74 53 69 7a 65 28 70 57 61  walLimitSize(pWa
11750 6c 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 7d  l, 0);.        }
11760 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
11770 20 20 20 20 77 61 6c 49 6e 64 65 78 43 6c 6f 73      walIndexClos
11780 65 28 70 57 61 6c 2c 20 69 73 44 65 6c 65 74 65  e(pWal, isDelete
11790 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  );.    sqlite3Os
117a0 43 6c 6f 73 65 28 70 57 61 6c 2d 3e 70 57 61 6c  Close(pWal->pWal
117b0 46 64 29 3b 0a 20 20 20 20 69 66 28 20 69 73 44  Fd);.    if( isD
117c0 65 6c 65 74 65 20 29 7b 0a 20 20 20 20 20 20 73  elete ){.      s
117d0 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67  qlite3BeginBenig
117e0 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 20 20 20  nMalloc();.     
117f0 20 73 71 6c 69 74 65 33 4f 73 44 65 6c 65 74 65   sqlite3OsDelete
11800 28 70 57 61 6c 2d 3e 70 56 66 73 2c 20 70 57 61  (pWal->pVfs, pWa
11810 6c 2d 3e 7a 57 61 6c 4e 61 6d 65 2c 20 30 29 3b  l->zWalName, 0);
11820 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 45 6e  .      sqlite3En
11830 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  dBenignMalloc();
11840 0a 20 20 20 20 7d 0a 20 20 20 20 57 41 4c 54 52  .    }.    WALTR
11850 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63 6c 6f  ACE(("WAL%p: clo
11860 73 65 64 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a  sed\n", pWal));.
11870 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
11880 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d 3e 61  ((void *)pWal->a
11890 70 57 69 44 61 74 61 29 3b 0a 20 20 20 20 73 71  pWiData);.    sq
118a0 6c 69 74 65 33 5f 66 72 65 65 28 70 57 61 6c 29  lite3_free(pWal)
118b0 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
118c0 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20  c;.}../*.** Try 
118d0 74 6f 20 72 65 61 64 20 74 68 65 20 77 61 6c 2d  to read the wal-
118e0 69 6e 64 65 78 20 68 65 61 64 65 72 2e 20 20 52  index header.  R
118f0 65 74 75 72 6e 20 30 20 6f 6e 20 73 75 63 63 65  eturn 0 on succe
11900 73 73 20 61 6e 64 20 31 20 69 66 0a 2a 2a 20 74  ss and 1 if.** t
11910 68 65 72 65 20 69 73 20 61 20 70 72 6f 62 6c 65  here is a proble
11920 6d 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61 6c  m..**.** The wal
11930 2d 69 6e 64 65 78 20 69 73 20 69 6e 20 73 68 61  -index is in sha
11940 72 65 64 20 6d 65 6d 6f 72 79 2e 20 20 41 6e 6f  red memory.  Ano
11950 74 68 65 72 20 74 68 72 65 61 64 20 6f 72 20 70  ther thread or p
11960 72 6f 63 65 73 73 20 6d 69 67 68 74 0a 2a 2a 20  rocess might.** 
11970 62 65 20 77 72 69 74 69 6e 67 20 74 68 65 20 68  be writing the h
11980 65 61 64 65 72 20 61 74 20 74 68 65 20 73 61 6d  eader at the sam
11990 65 20 74 69 6d 65 20 74 68 69 73 20 70 72 6f 63  e time this proc
119a0 65 64 75 72 65 20 69 73 20 74 72 79 69 6e 67 20  edure is trying 
119b0 74 6f 0a 2a 2a 20 72 65 61 64 20 69 74 2c 20 77  to.** read it, w
119c0 68 69 63 68 20 6d 69 67 68 74 20 72 65 73 75 6c  hich might resul
119d0 74 20 69 6e 20 69 6e 63 6f 6e 73 69 73 74 65 6e  t in inconsisten
119e0 63 79 2e 20 20 41 20 64 69 72 74 79 20 72 65 61  cy.  A dirty rea
119f0 64 20 69 73 20 64 65 74 65 63 74 65 64 0a 2a 2a  d is detected.**
11a00 20 62 79 20 76 65 72 69 66 79 69 6e 67 20 74 68   by verifying th
11a10 61 74 20 62 6f 74 68 20 63 6f 70 69 65 73 20 6f  at both copies o
11a20 66 20 74 68 65 20 68 65 61 64 65 72 20 61 72 65  f the header are
11a30 20 74 68 65 20 73 61 6d 65 20 61 6e 64 20 61 6c   the same and al
11a40 73 6f 20 62 79 0a 2a 2a 20 61 20 63 68 65 63 6b  so by.** a check
11a50 73 75 6d 20 6f 6e 20 74 68 65 20 68 65 61 64 65  sum on the heade
11a60 72 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 64 20  r..**.** If and 
11a70 6f 6e 6c 79 20 69 66 20 74 68 65 20 72 65 61 64  only if the read
11a80 20 69 73 20 63 6f 6e 73 69 73 74 65 6e 74 20 61   is consistent a
11a90 6e 64 20 74 68 65 20 68 65 61 64 65 72 20 69 73  nd the header is
11aa0 20 64 69 66 66 65 72 65 6e 74 20 66 72 6f 6d 0a   different from.
11ab0 2a 2a 20 70 57 61 6c 2d 3e 68 64 72 2c 20 74 68  ** pWal->hdr, th
11ac0 65 6e 20 70 57 61 6c 2d 3e 68 64 72 20 69 73 20  en pWal->hdr is 
11ad0 75 70 64 61 74 65 64 20 74 6f 20 74 68 65 20 63  updated to the c
11ae0 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65 20 6e 65  ontent of the ne
11af0 77 20 68 65 61 64 65 72 0a 2a 2a 20 61 6e 64 20  w header.** and 
11b00 2a 70 43 68 61 6e 67 65 64 20 69 73 20 73 65 74  *pChanged is set
11b10 20 74 6f 20 31 2e 0a 2a 2a 0a 2a 2a 20 49 66 20   to 1..**.** If 
11b20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 63 61 6e  the checksum can
11b30 6e 6f 74 20 62 65 20 76 65 72 69 66 69 65 64 20  not be verified 
11b40 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e  return non-zero.
11b50 20 49 66 20 74 68 65 20 68 65 61 64 65 72 0a 2a   If the header.*
11b60 2a 20 69 73 20 72 65 61 64 20 73 75 63 63 65 73  * is read succes
11b70 73 66 75 6c 6c 79 20 61 6e 64 20 74 68 65 20 63  sfully and the c
11b80 68 65 63 6b 73 75 6d 20 76 65 72 69 66 69 65 64  hecksum verified
11b90 2c 20 72 65 74 75 72 6e 20 7a 65 72 6f 2e 0a 2a  , return zero..*
11ba0 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
11bb0 49 6e 64 65 78 54 72 79 48 64 72 28 57 61 6c 20  IndexTryHdr(Wal 
11bc0 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61  *pWal, int *pCha
11bd0 6e 67 65 64 29 7b 0a 20 20 75 33 32 20 61 43 6b  nged){.  u32 aCk
11be0 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20  sum[2];         
11bf0 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63           /* Chec
11c00 6b 73 75 6d 20 6f 6e 20 74 68 65 20 68 65 61 64  ksum on the head
11c10 65 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20  er content */.  
11c20 57 61 6c 49 6e 64 65 78 48 64 72 20 68 31 2c 20  WalIndexHdr h1, 
11c30 68 32 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  h2;             
11c40 2f 2a 20 54 77 6f 20 63 6f 70 69 65 73 20 6f 66  /* Two copies of
11c50 20 74 68 65 20 68 65 61 64 65 72 20 63 6f 6e 74   the header cont
11c60 65 6e 74 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65  ent */.  WalInde
11c70 78 48 64 72 20 76 6f 6c 61 74 69 6c 65 20 2a 61  xHdr volatile *a
11c80 48 64 72 3b 20 20 20 20 20 2f 2a 20 48 65 61 64  Hdr;     /* Head
11c90 65 72 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d  er in shared mem
11ca0 6f 72 79 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 65  ory */..  /* The
11cb0 20 66 69 72 73 74 20 70 61 67 65 20 6f 66 20 74   first page of t
11cc0 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 6d 75 73  he wal-index mus
11cd0 74 20 62 65 20 6d 61 70 70 65 64 20 61 74 20 74  t be mapped at t
11ce0 68 69 73 20 70 6f 69 6e 74 2e 20 2a 2f 0a 20 20  his point. */.  
11cf0 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57  assert( pWal->nW
11d00 69 44 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d  iData>0 && pWal-
11d10 3e 61 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a  >apWiData[0] );.
11d20 0a 20 20 2f 2a 20 52 65 61 64 20 74 68 65 20 68  .  /* Read the h
11d30 65 61 64 65 72 2e 20 54 68 69 73 20 6d 69 67 68  eader. This migh
11d40 74 20 68 61 70 70 65 6e 20 63 6f 6e 63 75 72 72  t happen concurr
11d50 65 6e 74 6c 79 20 77 69 74 68 20 61 20 77 72 69  ently with a wri
11d60 74 65 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20 73  te to the.  ** s
11d70 61 6d 65 20 61 72 65 61 20 6f 66 20 73 68 61 72  ame area of shar
11d80 65 64 20 6d 65 6d 6f 72 79 20 6f 6e 20 61 20 64  ed memory on a d
11d90 69 66 66 65 72 65 6e 74 20 43 50 55 20 69 6e 20  ifferent CPU in 
11da0 61 20 53 4d 50 2c 0a 20 20 2a 2a 20 6d 65 61 6e  a SMP,.  ** mean
11db0 69 6e 67 20 69 74 20 69 73 20 70 6f 73 73 69 62  ing it is possib
11dc0 6c 65 20 74 68 61 74 20 61 6e 20 69 6e 63 6f 6e  le that an incon
11dd0 73 69 73 74 65 6e 74 20 73 6e 61 70 73 68 6f 74  sistent snapshot
11de0 20 69 73 20 72 65 61 64 0a 20 20 2a 2a 20 66 72   is read.  ** fr
11df0 6f 6d 20 74 68 65 20 66 69 6c 65 2e 20 49 66 20  om the file. If 
11e00 74 68 69 73 20 68 61 70 70 65 6e 73 2c 20 72 65  this happens, re
11e10 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 20  turn non-zero.. 
11e20 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 72 65 20 61   **.  ** There a
11e30 72 65 20 74 77 6f 20 63 6f 70 69 65 73 20 6f 66  re two copies of
11e40 20 74 68 65 20 68 65 61 64 65 72 20 61 74 20 74   the header at t
11e50 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20  he beginning of 
11e60 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 20  the wal-index.. 
11e70 20 2a 2a 20 57 68 65 6e 20 72 65 61 64 69 6e 67   ** When reading
11e80 2c 20 72 65 61 64 20 5b 30 5d 20 66 69 72 73 74  , read [0] first
11e90 20 74 68 65 6e 20 5b 31 5d 2e 20 20 57 72 69 74   then [1].  Writ
11ea0 65 73 20 61 72 65 20 69 6e 20 74 68 65 20 72 65  es are in the re
11eb0 76 65 72 73 65 20 6f 72 64 65 72 2e 0a 20 20 2a  verse order..  *
11ec0 2a 20 4d 65 6d 6f 72 79 20 62 61 72 72 69 65 72  * Memory barrier
11ed0 73 20 61 72 65 20 75 73 65 64 20 74 6f 20 70 72  s are used to pr
11ee0 65 76 65 6e 74 20 74 68 65 20 63 6f 6d 70 69 6c  event the compil
11ef0 65 72 20 6f 72 20 74 68 65 20 68 61 72 64 77 61  er or the hardwa
11f00 72 65 20 66 72 6f 6d 0a 20 20 2a 2a 20 72 65 6f  re from.  ** reo
11f10 72 64 65 72 69 6e 67 20 74 68 65 20 72 65 61 64  rdering the read
11f20 73 20 61 6e 64 20 77 72 69 74 65 73 2e 0a 20 20  s and writes..  
11f30 2a 2f 0a 20 20 61 48 64 72 20 3d 20 77 61 6c 49  */.  aHdr = walI
11f40 6e 64 65 78 48 64 72 28 70 57 61 6c 29 3b 0a 20  ndexHdr(pWal);. 
11f50 20 6d 65 6d 63 70 79 28 26 68 31 2c 20 28 76 6f   memcpy(&h1, (vo
11f60 69 64 20 2a 29 26 61 48 64 72 5b 30 5d 2c 20 73  id *)&aHdr[0], s
11f70 69 7a 65 6f 66 28 68 31 29 29 3b 0a 20 20 77 61  izeof(h1));.  wa
11f80 6c 53 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c  lShmBarrier(pWal
11f90 29 3b 0a 20 20 6d 65 6d 63 70 79 28 26 68 32 2c  );.  memcpy(&h2,
11fa0 20 28 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 31   (void *)&aHdr[1
11fb0 5d 2c 20 73 69 7a 65 6f 66 28 68 32 29 29 3b 0a  ], sizeof(h2));.
11fc0 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 68  .  if( memcmp(&h
11fd0 31 2c 20 26 68 32 2c 20 73 69 7a 65 6f 66 28 68  1, &h2, sizeof(h
11fe0 31 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65  1))!=0 ){.    re
11ff0 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20 44 69 72  turn 1;   /* Dir
12000 74 79 20 72 65 61 64 20 2a 2f 0a 20 20 7d 20 20  ty read */.  }  
12010 0a 20 20 69 66 28 20 68 31 2e 69 73 49 6e 69 74  .  if( h1.isInit
12020 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  ==0 ){.    retur
12030 6e 20 31 3b 20 20 20 2f 2a 20 4d 61 6c 66 6f 72  n 1;   /* Malfor
12040 6d 65 64 20 68 65 61 64 65 72 20 2d 20 70 72 6f  med header - pro
12050 62 61 62 6c 79 20 61 6c 6c 20 7a 65 72 6f 73 20  bably all zeros 
12060 2a 2f 0a 20 20 7d 0a 20 20 77 61 6c 43 68 65 63  */.  }.  walChec
12070 6b 73 75 6d 42 79 74 65 73 28 31 2c 20 28 75 38  ksumBytes(1, (u8
12080 2a 29 26 68 31 2c 20 73 69 7a 65 6f 66 28 68 31  *)&h1, sizeof(h1
12090 29 2d 73 69 7a 65 6f 66 28 68 31 2e 61 43 6b 73  )-sizeof(h1.aCks
120a0 75 6d 29 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b  um), 0, aCksum);
120b0 0a 20 20 69 66 28 20 61 43 6b 73 75 6d 5b 30 5d  .  if( aCksum[0]
120c0 21 3d 68 31 2e 61 43 6b 73 75 6d 5b 30 5d 20 7c  !=h1.aCksum[0] |
120d0 7c 20 61 43 6b 73 75 6d 5b 31 5d 21 3d 68 31 2e  | aCksum[1]!=h1.
120e0 61 43 6b 73 75 6d 5b 31 5d 20 29 7b 0a 20 20 20  aCksum[1] ){.   
120f0 20 72 65 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20   return 1;   /* 
12100 43 68 65 63 6b 73 75 6d 20 64 6f 65 73 20 6e 6f  Checksum does no
12110 74 20 6d 61 74 63 68 20 2a 2f 0a 20 20 7d 0a 0a  t match */.  }..
12120 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57    if( memcmp(&pW
12130 61 6c 2d 3e 68 64 72 2c 20 26 68 31 2c 20 73 69  al->hdr, &h1, si
12140 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
12150 29 29 20 29 7b 0a 20 20 20 20 2a 70 43 68 61 6e  )) ){.    *pChan
12160 67 65 64 20 3d 20 31 3b 0a 20 20 20 20 6d 65 6d  ged = 1;.    mem
12170 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20  cpy(&pWal->hdr, 
12180 26 68 31 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49  &h1, sizeof(WalI
12190 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 20 20 70  ndexHdr));.    p
121a0 57 61 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 28 70  Wal->szPage = (p
121b0 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26  Wal->hdr.szPage&
121c0 30 78 66 65 30 30 29 20 2b 20 28 28 70 57 61 6c  0xfe00) + ((pWal
121d0 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26 30 78 30  ->hdr.szPage&0x0
121e0 30 30 31 29 3c 3c 31 36 29 3b 0a 20 20 20 20 74  001)<<16);.    t
121f0 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d 3e 73  estcase( pWal->s
12200 7a 50 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a  zPage<=32768 );.
12210 20 20 20 20 74 65 73 74 63 61 73 65 28 20 70 57      testcase( pW
12220 61 6c 2d 3e 73 7a 50 61 67 65 3e 3d 36 35 35 33  al->szPage>=6553
12230 36 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54  6 );.  }..  /* T
12240 68 65 20 68 65 61 64 65 72 20 77 61 73 20 73 75  he header was su
12250 63 63 65 73 73 66 75 6c 6c 79 20 72 65 61 64 2e  ccessfully read.
12260 20 52 65 74 75 72 6e 20 7a 65 72 6f 2e 20 2a 2f   Return zero. */
12270 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
12280 2f 2a 0a 2a 2a 20 52 65 61 64 20 74 68 65 20 77  /*.** Read the w
12290 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
122a0 66 72 6f 6d 20 74 68 65 20 77 61 6c 2d 69 6e 64  from the wal-ind
122b0 65 78 20 61 6e 64 20 69 6e 74 6f 20 70 57 61 6c  ex and into pWal
122c0 2d 3e 68 64 72 2e 0a 2a 2a 20 49 66 20 74 68 65  ->hdr..** If the
122d0 20 77 61 6c 2d 68 65 61 64 65 72 20 61 70 70 65   wal-header appe
122e0 61 72 73 20 74 6f 20 62 65 20 63 6f 72 72 75 70  ars to be corrup
122f0 74 2c 20 74 72 79 20 74 6f 20 72 65 63 6f 6e 73  t, try to recons
12300 74 72 75 63 74 20 74 68 65 0a 2a 2a 20 77 61 6c  truct the.** wal
12310 2d 69 6e 64 65 78 20 66 72 6f 6d 20 74 68 65 20  -index from the 
12320 57 41 4c 20 62 65 66 6f 72 65 20 72 65 74 75 72  WAL before retur
12330 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20  ning..**.** Set 
12340 2a 70 43 68 61 6e 67 65 64 20 74 6f 20 31 20 69  *pChanged to 1 i
12350 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
12360 68 65 61 64 65 72 20 76 61 6c 75 65 20 69 6e 20  header value in 
12370 70 57 61 6c 2d 3e 68 64 72 20 69 73 0a 2a 2a 20  pWal->hdr is.** 
12380 63 68 61 6e 67 65 64 20 62 79 20 74 68 69 73 20  changed by this 
12390 6f 70 65 72 74 69 6f 6e 2e 20 20 49 66 20 70 57  opertion.  If pW
123a0 61 6c 2d 3e 68 64 72 20 69 73 20 75 6e 63 68 61  al->hdr is uncha
123b0 6e 67 65 64 2c 20 73 65 74 20 2a 70 43 68 61 6e  nged, set *pChan
123c0 67 65 64 0a 2a 2a 20 74 6f 20 30 2e 0a 2a 2a 0a  ged.** to 0..**.
123d0 2a 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 69 6e  ** If the wal-in
123e0 64 65 78 20 68 65 61 64 65 72 20 69 73 20 73 75  dex header is su
123f0 63 63 65 73 73 66 75 6c 6c 79 20 72 65 61 64 2c  ccessfully read,
12400 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
12410 4b 2e 20 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  K. .** Otherwise
12420 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
12430 20 63 6f 64 65 2e 0a 2a 2f 0a 73 74 61 74 69 63   code..*/.static
12440 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 52 65 61   int walIndexRea
12450 64 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 2c 20  dHdr(Wal *pWal, 
12460 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a  int *pChanged){.
12470 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
12480 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12490 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
124a0 20 2a 2f 0a 20 20 69 6e 74 20 62 61 64 48 64 72   */.  int badHdr
124b0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
124c0 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
124d0 20 61 20 68 65 61 64 65 72 20 72 65 61 64 20 66   a header read f
124e0 61 69 6c 65 64 20 2a 2f 0a 20 20 76 6f 6c 61 74  ailed */.  volat
124f0 69 6c 65 20 75 33 32 20 2a 70 61 67 65 30 3b 20  ile u32 *page0; 
12500 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68             /* Ch
12510 75 6e 6b 20 6f 66 20 77 61 6c 2d 69 6e 64 65 78  unk of wal-index
12520 20 63 6f 6e 74 61 69 6e 69 6e 67 20 68 65 61 64   containing head
12530 65 72 20 2a 2f 0a 0a 20 20 2f 2a 20 45 6e 73 75  er */..  /* Ensu
12540 72 65 20 74 68 61 74 20 70 61 67 65 20 30 20 6f  re that page 0 o
12550 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
12560 28 74 68 65 20 70 61 67 65 20 74 68 61 74 20 63  (the page that c
12570 6f 6e 74 61 69 6e 73 20 74 68 65 20 0a 20 20 2a  ontains the .  *
12580 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  * wal-index head
12590 65 72 29 20 69 73 20 6d 61 70 70 65 64 2e 20 52  er) is mapped. R
125a0 65 74 75 72 6e 20 65 61 72 6c 79 20 69 66 20 61  eturn early if a
125b0 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 20 68  n error occurs h
125c0 65 72 65 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65  ere..  */.  asse
125d0 72 74 28 20 70 43 68 61 6e 67 65 64 20 29 3b 0a  rt( pChanged );.
125e0 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 50    rc = walIndexP
125f0 61 67 65 28 70 57 61 6c 2c 20 30 2c 20 26 70 61  age(pWal, 0, &pa
12600 67 65 30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  ge0);.  if( rc!=
12610 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
12620 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 3b   return rc;.  };
12630 0a 20 20 61 73 73 65 72 74 28 20 70 61 67 65 30  .  assert( page0
12640 20 7c 7c 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c   || pWal->writeL
12650 6f 63 6b 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20  ock==0 );..  /* 
12660 49 66 20 74 68 65 20 66 69 72 73 74 20 70 61 67  If the first pag
12670 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  e of the wal-ind
12680 65 78 20 68 61 73 20 62 65 65 6e 20 6d 61 70 70  ex has been mapp
12690 65 64 2c 20 74 72 79 20 74 6f 20 72 65 61 64 20  ed, try to read 
126a0 74 68 65 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64  the.  ** wal-ind
126b0 65 78 20 68 65 61 64 65 72 20 69 6d 6d 65 64 69  ex header immedi
126c0 61 74 65 6c 79 2c 20 77 69 74 68 6f 75 74 20 68  ately, without h
126d0 6f 6c 64 69 6e 67 20 61 6e 79 20 6c 6f 63 6b 2e  olding any lock.
126e0 20 54 68 69 73 20 75 73 75 61 6c 6c 79 0a 20 20   This usually.  
126f0 2a 2a 20 77 6f 72 6b 73 2c 20 62 75 74 20 6d 61  ** works, but ma
12700 79 20 66 61 69 6c 20 69 66 20 74 68 65 20 77 61  y fail if the wa
12710 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69  l-index header i
12720 73 20 63 6f 72 72 75 70 74 20 6f 72 20 63 75 72  s corrupt or cur
12730 72 65 6e 74 6c 79 20 0a 20 20 2a 2a 20 62 65 69  rently .  ** bei
12740 6e 67 20 6d 6f 64 69 66 69 65 64 20 62 79 20 61  ng modified by a
12750 6e 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f 72  nother thread or
12760 20 70 72 6f 63 65 73 73 2e 0a 20 20 2a 2f 0a 20   process..  */. 
12770 20 62 61 64 48 64 72 20 3d 20 28 70 61 67 65 30   badHdr = (page0
12780 20 3f 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64   ? walIndexTryHd
12790 72 28 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64  r(pWal, pChanged
127a0 29 20 3a 20 31 29 3b 0a 0a 20 20 2f 2a 20 49 66  ) : 1);..  /* If
127b0 20 74 68 65 20 66 69 72 73 74 20 61 74 74 65 6d   the first attem
127c0 70 74 20 66 61 69 6c 65 64 2c 20 69 74 20 6d 69  pt failed, it mi
127d0 67 68 74 20 68 61 76 65 20 62 65 65 6e 20 64 75  ght have been du
127e0 65 20 74 6f 20 61 20 72 61 63 65 0a 20 20 2a 2a  e to a race.  **
127f0 20 77 69 74 68 20 61 20 77 72 69 74 65 72 2e 20   with a writer. 
12800 20 53 6f 20 67 65 74 20 61 20 57 52 49 54 45 20   So get a WRITE 
12810 6c 6f 63 6b 20 61 6e 64 20 74 72 79 20 61 67 61  lock and try aga
12820 69 6e 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72  in..  */.  asser
12830 74 28 20 62 61 64 48 64 72 3d 3d 30 20 7c 7c 20  t( badHdr==0 || 
12840 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d  pWal->writeLock=
12850 3d 30 20 29 3b 0a 20 20 69 66 28 20 62 61 64 48  =0 );.  if( badH
12860 64 72 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57  dr ){.    if( pW
12870 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57  al->readOnly & W
12880 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 20 29 7b  AL_SHM_RDONLY ){
12890 0a 20 20 20 20 20 20 69 66 28 20 53 51 4c 49 54  .      if( SQLIT
128a0 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c 4c  E_OK==(rc = walL
128b0 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20  ockShared(pWal, 
128c0 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 29 29  WAL_WRITE_LOCK))
128d0 20 29 7b 0a 20 20 20 20 20 20 20 20 77 61 6c 55   ){.        walU
128e0 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
128f0 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b  , WAL_WRITE_LOCK
12900 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  );.        rc = 
12910 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 5f  SQLITE_READONLY_
12920 52 45 43 4f 56 45 52 59 3b 0a 20 20 20 20 20 20  RECOVERY;.      
12930 7d 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  }.    }else if( 
12940 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d  SQLITE_OK==(rc =
12950 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76   walLockExclusiv
12960 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54  e(pWal, WAL_WRIT
12970 45 5f 4c 4f 43 4b 2c 20 31 29 29 20 29 7b 0a 20  E_LOCK, 1)) ){. 
12980 20 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65       pWal->write
12990 4c 6f 63 6b 20 3d 20 31 3b 0a 20 20 20 20 20 20  Lock = 1;.      
129a0 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28  if( SQLITE_OK==(
129b0 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 50 61 67  rc = walIndexPag
129c0 65 28 70 57 61 6c 2c 20 30 2c 20 26 70 61 67 65  e(pWal, 0, &page
129d0 30 29 29 20 29 7b 0a 20 20 20 20 20 20 20 20 62  0)) ){.        b
129e0 61 64 48 64 72 20 3d 20 77 61 6c 49 6e 64 65 78  adHdr = walIndex
129f0 54 72 79 48 64 72 28 70 57 61 6c 2c 20 70 43 68  TryHdr(pWal, pCh
12a00 61 6e 67 65 64 29 3b 0a 20 20 20 20 20 20 20 20  anged);.        
12a10 69 66 28 20 62 61 64 48 64 72 20 29 7b 0a 20 20  if( badHdr ){.  
12a20 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68          /* If th
12a30 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
12a40 65 72 20 69 73 20 73 74 69 6c 6c 20 6d 61 6c 66  er is still malf
12a50 6f 72 6d 65 64 20 65 76 65 6e 20 77 68 69 6c 65  ormed even while
12a60 20 68 6f 6c 64 69 6e 67 0a 20 20 20 20 20 20 20   holding.       
12a70 20 20 20 2a 2a 20 61 20 57 52 49 54 45 20 6c 6f     ** a WRITE lo
12a80 63 6b 2c 20 69 74 20 63 61 6e 20 6f 6e 6c 79 20  ck, it can only 
12a90 6d 65 61 6e 20 74 68 61 74 20 74 68 65 20 68 65  mean that the he
12aa0 61 64 65 72 20 69 73 20 63 6f 72 72 75 70 74 65  ader is corrupte
12ab0 64 20 61 6e 64 0a 20 20 20 20 20 20 20 20 20 20  d and.          
12ac0 2a 2a 20 6e 65 65 64 73 20 74 6f 20 62 65 20 72  ** needs to be r
12ad0 65 63 6f 6e 73 74 72 75 63 74 65 64 2e 20 20 53  econstructed.  S
12ae0 6f 20 72 75 6e 20 72 65 63 6f 76 65 72 79 20 74  o run recovery t
12af0 6f 20 64 6f 20 65 78 61 63 74 6c 79 20 74 68 61  o do exactly tha
12b00 74 2e 0a 20 20 20 20 20 20 20 20 20 20 2a 2f 0a  t..          */.
12b10 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 77            rc = w
12b20 61 6c 49 6e 64 65 78 52 65 63 6f 76 65 72 28 70  alIndexRecover(p
12b30 57 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Wal);.          
12b40 2a 70 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20  *pChanged = 1;. 
12b50 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
12b60 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 77 72 69  .      pWal->wri
12b70 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20  teLock = 0;.    
12b80 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75    walUnlockExclu
12b90 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57  sive(pWal, WAL_W
12ba0 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  RITE_LOCK, 1);. 
12bb0 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49     }.  }..  /* I
12bc0 66 20 74 68 65 20 68 65 61 64 65 72 20 69 73 20  f the header is 
12bd0 72 65 61 64 20 73 75 63 63 65 73 73 66 75 6c 6c  read successfull
12be0 79 2c 20 63 68 65 63 6b 20 74 68 65 20 76 65 72  y, check the ver
12bf0 73 69 6f 6e 20 6e 75 6d 62 65 72 20 74 6f 20 6d  sion number to m
12c00 61 6b 65 0a 20 20 2a 2a 20 73 75 72 65 20 74 68  ake.  ** sure th
12c10 65 20 77 61 6c 2d 69 6e 64 65 78 20 77 61 73 20  e wal-index was 
12c20 6e 6f 74 20 63 6f 6e 73 74 72 75 63 74 65 64 20  not constructed 
12c30 77 69 74 68 20 73 6f 6d 65 20 66 75 74 75 72 65  with some future
12c40 20 66 6f 72 6d 61 74 20 74 68 61 74 0a 20 20 2a   format that.  *
12c50 2a 20 74 68 69 73 20 76 65 72 73 69 6f 6e 20 6f  * this version o
12c60 66 20 53 51 4c 69 74 65 20 63 61 6e 6e 6f 74 20  f SQLite cannot 
12c70 75 6e 64 65 72 73 74 61 6e 64 2e 0a 20 20 2a 2f  understand..  */
12c80 0a 20 20 69 66 28 20 62 61 64 48 64 72 3d 3d 30  .  if( badHdr==0
12c90 20 26 26 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56   && pWal->hdr.iV
12ca0 65 72 73 69 6f 6e 21 3d 57 41 4c 49 4e 44 45 58  ersion!=WALINDEX
12cb0 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 20 29 7b 0a  _MAX_VERSION ){.
12cc0 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
12cd0 43 41 4e 54 4f 50 45 4e 5f 42 4b 50 54 3b 0a 20  CANTOPEN_BKPT;. 
12ce0 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
12cf0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69  .}../*.** This i
12d00 73 20 74 68 65 20 76 61 6c 75 65 20 74 68 61 74  s the value that
12d10 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64   walTryBeginRead
12d20 20 72 65 74 75 72 6e 73 20 77 68 65 6e 20 69 74   returns when it
12d30 20 6e 65 65 64 73 20 74 6f 0a 2a 2a 20 62 65 20   needs to.** be 
12d40 72 65 74 72 69 65 64 2e 0a 2a 2f 0a 23 64 65 66  retried..*/.#def
12d50 69 6e 65 20 57 41 4c 5f 52 45 54 52 59 20 20 28  ine WAL_RETRY  (
12d60 2d 31 29 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d  -1)../*.** Attem
12d70 70 74 20 74 6f 20 73 74 61 72 74 20 61 20 72 65  pt to start a re
12d80 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20  ad transaction. 
12d90 20 54 68 69 73 20 6d 69 67 68 74 20 66 61 69 6c   This might fail
12da0 20 64 75 65 20 74 6f 20 61 20 72 61 63 65 20 6f   due to a race o
12db0 72 0a 2a 2a 20 6f 74 68 65 72 20 74 72 61 6e 73  r.** other trans
12dc0 69 65 6e 74 20 63 6f 6e 64 69 74 69 6f 6e 2e 20  ient condition. 
12dd0 20 57 68 65 6e 20 74 68 61 74 20 68 61 70 70 65   When that happe
12de0 6e 73 2c 20 69 74 20 72 65 74 75 72 6e 73 20 57  ns, it returns W
12df0 41 4c 5f 52 45 54 52 59 20 74 6f 0a 2a 2a 20 69  AL_RETRY to.** i
12e00 6e 64 69 63 61 74 65 20 74 6f 20 74 68 65 20 63  ndicate to the c
12e10 61 6c 6c 65 72 20 74 68 61 74 20 69 74 20 69 73  aller that it is
12e20 20 73 61 66 65 20 74 6f 20 72 65 74 72 79 20 69   safe to retry i
12e30 6d 6d 65 64 69 61 74 65 6c 79 2e 0a 2a 2a 0a 2a  mmediately..**.*
12e40 2a 20 4f 6e 20 73 75 63 63 65 73 73 20 72 65 74  * On success ret
12e50 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 20  urn SQLITE_OK.  
12e60 4f 6e 20 61 20 70 65 72 6d 61 6e 65 6e 74 20 66  On a permanent f
12e70 61 69 6c 75 72 65 20 28 73 75 63 68 20 61 6e 0a  ailure (such an.
12e80 2a 2a 20 49 2f 4f 20 65 72 72 6f 72 20 6f 72 20  ** I/O error or 
12e90 61 6e 20 53 51 4c 49 54 45 5f 42 55 53 59 20 62  an SQLITE_BUSY b
12ea0 65 63 61 75 73 65 20 61 6e 6f 74 68 65 72 20 70  ecause another p
12eb0 72 6f 63 65 73 73 20 69 73 20 72 75 6e 6e 69 6e  rocess is runnin
12ec0 67 0a 2a 2a 20 72 65 63 6f 76 65 72 79 29 20 72  g.** recovery) r
12ed0 65 74 75 72 6e 20 61 20 70 6f 73 69 74 69 76 65  eturn a positive
12ee0 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a   error code..**.
12ef0 2a 2a 20 54 68 65 20 75 73 65 57 61 6c 20 70 61  ** The useWal pa
12f00 72 61 6d 65 74 65 72 20 69 73 20 74 72 75 65 20  rameter is true 
12f10 74 6f 20 66 6f 72 63 65 20 74 68 65 20 75 73 65  to force the use
12f20 20 6f 66 20 74 68 65 20 57 41 4c 20 61 6e 64 20   of the WAL and 
12f30 64 69 73 61 62 6c 65 0a 2a 2a 20 74 68 65 20 63  disable.** the c
12f40 61 73 65 20 77 68 65 72 65 20 74 68 65 20 57 41  ase where the WA
12f50 4c 20 69 73 20 62 79 70 61 73 73 65 64 20 62 65  L is bypassed be
12f60 63 61 75 73 65 20 69 74 20 68 61 73 20 62 65 65  cause it has bee
12f70 6e 20 63 6f 6d 70 6c 65 74 65 6c 79 0a 2a 2a 20  n completely.** 
12f80 63 68 65 63 6b 70 6f 69 6e 74 65 64 2e 20 20 49  checkpointed.  I
12f90 66 20 75 73 65 57 61 6c 3d 3d 30 20 74 68 65 6e  f useWal==0 then
12fa0 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 63 61   this routine ca
12fb0 6c 6c 73 20 77 61 6c 49 6e 64 65 78 52 65 61 64  lls walIndexRead
12fc0 48 64 72 28 29 20 0a 2a 2a 20 74 6f 20 6d 61 6b  Hdr() .** to mak
12fd0 65 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20  e a copy of the 
12fe0 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
12ff0 20 69 6e 74 6f 20 70 57 61 6c 2d 3e 68 64 72 2e   into pWal->hdr.
13000 20 20 49 66 20 74 68 65 20 0a 2a 2a 20 77 61 6c    If the .** wal
13010 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 68 61  -index header ha
13020 73 20 63 68 61 6e 67 65 64 2c 20 2a 70 43 68 61  s changed, *pCha
13030 6e 67 65 64 20 69 73 20 73 65 74 20 74 6f 20 31  nged is set to 1
13040 20 28 61 73 20 61 6e 20 69 6e 64 69 63 61 74 69   (as an indicati
13050 6f 6e 20 0a 2a 2a 20 74 6f 20 74 68 65 20 63 61  on .** to the ca
13060 6c 6c 65 72 20 74 68 61 74 20 74 68 65 20 6c 6f  ller that the lo
13070 63 61 6c 20 70 61 67 65 74 20 63 61 63 68 65 20  cal paget cache 
13080 69 73 20 6f 62 73 6f 6c 65 74 65 20 61 6e 64 20  is obsolete and 
13090 6e 65 65 64 73 20 74 6f 20 62 65 20 0a 2a 2a 20  needs to be .** 
130a0 66 6c 75 73 68 65 64 2e 29 20 20 57 68 65 6e 20  flushed.)  When 
130b0 75 73 65 57 61 6c 3d 3d 31 2c 20 74 68 65 20 77  useWal==1, the w
130c0 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
130d0 69 73 20 61 73 73 75 6d 65 64 20 74 6f 20 61 6c  is assumed to al
130e0 72 65 61 64 79 0a 2a 2a 20 62 65 20 6c 6f 61 64  ready.** be load
130f0 65 64 20 61 6e 64 20 74 68 65 20 70 43 68 61 6e  ed and the pChan
13100 67 65 64 20 70 61 72 61 6d 65 74 65 72 20 69 73  ged parameter is
13110 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 54   unused..**.** T
13120 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 73  he caller must s
13130 65 74 20 74 68 65 20 63 6e 74 20 70 61 72 61 6d  et the cnt param
13140 65 74 65 72 20 74 6f 20 74 68 65 20 6e 75 6d 62  eter to the numb
13150 65 72 20 6f 66 20 70 72 69 6f 72 20 63 61 6c 6c  er of prior call
13160 73 20 74 6f 0a 2a 2a 20 74 68 69 73 20 72 6f 75  s to.** this rou
13170 74 69 6e 65 20 64 75 72 69 6e 67 20 74 68 65 20  tine during the 
13180 63 75 72 72 65 6e 74 20 72 65 61 64 20 61 74 74  current read att
13190 65 6d 70 74 20 74 68 61 74 20 72 65 74 75 72 6e  empt that return
131a0 65 64 20 57 41 4c 5f 52 45 54 52 59 2e 0a 2a 2a  ed WAL_RETRY..**
131b0 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69   This routine wi
131c0 6c 6c 20 73 74 61 72 74 20 74 61 6b 69 6e 67 20  ll start taking 
131d0 6d 6f 72 65 20 61 67 67 72 65 73 73 69 76 65 20  more aggressive 
131e0 6d 65 61 73 75 72 65 73 20 74 6f 20 63 6c 65 61  measures to clea
131f0 72 20 74 68 65 0a 2a 2a 20 72 61 63 65 20 63 6f  r the.** race co
13200 6e 64 69 74 69 6f 6e 73 20 61 66 74 65 72 20 6d  nditions after m
13210 75 6c 74 69 70 6c 65 20 57 41 4c 5f 52 45 54 52  ultiple WAL_RETR
13220 59 20 72 65 74 75 72 6e 73 2c 20 61 6e 64 20 61  Y returns, and a
13230 66 74 65 72 20 61 6e 20 65 78 63 65 73 73 69 76  fter an excessiv
13240 65 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 65  e.** number of e
13250 72 72 6f 72 73 20 77 69 6c 6c 20 75 6c 74 69 6d  rrors will ultim
13260 61 74 65 6c 79 20 72 65 74 75 72 6e 20 53 51 4c  ately return SQL
13270 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 2e 20 20 54  ITE_PROTOCOL.  T
13280 68 65 0a 2a 2a 20 53 51 4c 49 54 45 5f 50 52 4f  he.** SQLITE_PRO
13290 54 4f 43 4f 4c 20 72 65 74 75 72 6e 20 69 6e 64  TOCOL return ind
132a0 69 63 61 74 65 73 20 74 68 61 74 20 73 6f 6d 65  icates that some
132b0 20 6f 74 68 65 72 20 70 72 6f 63 65 73 73 20 68   other process h
132c0 61 73 20 67 6f 6e 65 20 72 6f 67 75 65 0a 2a 2a  as gone rogue.**
132d0 20 61 6e 64 20 69 73 20 6e 6f 74 20 68 6f 6e 6f   and is not hono
132e0 72 69 6e 67 20 74 68 65 20 6c 6f 63 6b 69 6e 67  ring the locking
132f0 20 70 72 6f 74 6f 63 6f 6c 2e 20 20 54 68 65 72   protocol.  Ther
13300 65 20 69 73 20 61 20 76 61 6e 69 73 68 69 6e 67  e is a vanishing
13310 6c 79 20 73 6d 61 6c 6c 0a 2a 2a 20 63 68 61 6e  ly small.** chan
13320 63 65 20 74 68 61 74 20 53 51 4c 49 54 45 5f 50  ce that SQLITE_P
13330 52 4f 54 4f 43 4f 4c 20 63 6f 75 6c 64 20 62 65  ROTOCOL could be
13340 20 72 65 74 75 72 6e 65 64 20 62 65 63 61 75 73   returned becaus
13350 65 20 6f 66 20 61 20 72 75 6e 20 6f 66 20 72 65  e of a run of re
13360 61 6c 6c 79 0a 2a 2a 20 62 61 64 20 6c 75 63 6b  ally.** bad luck
13370 20 77 68 65 6e 20 74 68 65 72 65 20 69 73 20 6c   when there is l
13380 6f 74 73 20 6f 66 20 63 6f 6e 74 65 6e 74 69 6f  ots of contentio
13390 6e 20 66 6f 72 20 74 68 65 20 77 61 6c 2d 69 6e  n for the wal-in
133a0 64 65 78 2c 20 62 75 74 20 74 68 61 74 0a 2a 2a  dex, but that.**
133b0 20 70 6f 73 73 69 62 69 6c 69 74 79 20 69 73 20   possibility is 
133c0 73 6f 20 73 6d 61 6c 6c 20 74 68 61 74 20 69 74  so small that it
133d0 20 63 61 6e 20 62 65 20 73 61 66 65 6c 79 20 6e   can be safely n
133e0 65 67 6c 65 63 74 65 64 2c 20 77 65 20 62 65 6c  eglected, we bel
133f0 69 65 76 65 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73  ieve..**.** On s
13400 75 63 63 65 73 73 2c 20 74 68 69 73 20 72 6f 75  uccess, this rou
13410 74 69 6e 65 20 6f 62 74 61 69 6e 73 20 61 20 72  tine obtains a r
13420 65 61 64 20 6c 6f 63 6b 20 6f 6e 20 0a 2a 2a 20  ead lock on .** 
13430 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57  WAL_READ_LOCK(pW
13440 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 2e 20 20  al->readLock).  
13450 54 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  The pWal->readLo
13460 63 6b 20 69 6e 74 65 67 65 72 20 69 73 0a 2a 2a  ck integer is.**
13470 20 69 6e 20 74 68 65 20 72 61 6e 67 65 20 30 20   in the range 0 
13480 3c 3d 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  <= pWal->readLoc
13490 6b 20 3c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2e  k < WAL_NREADER.
134a0 20 20 49 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c    If pWal->readL
134b0 6f 63 6b 3d 3d 28 2d 31 29 0a 2a 2a 20 74 68 61  ock==(-1).** tha
134c0 74 20 6d 65 61 6e 73 20 74 68 65 20 57 61 6c 20  t means the Wal 
134d0 64 6f 65 73 20 6e 6f 74 20 68 6f 6c 64 20 61 6e  does not hold an
134e0 79 20 72 65 61 64 20 6c 6f 63 6b 2e 20 20 54 68  y read lock.  Th
134f0 65 20 72 65 61 64 65 72 20 6d 75 73 74 20 6e 6f  e reader must no
13500 74 0a 2a 2a 20 61 63 63 65 73 73 20 61 6e 79 20  t.** access any 
13510 64 61 74 61 62 61 73 65 20 70 61 67 65 20 74 68  database page th
13520 61 74 20 69 73 20 6d 6f 64 69 66 69 65 64 20 62  at is modified b
13530 79 20 61 20 57 41 4c 20 66 72 61 6d 65 20 75 70  y a WAL frame up
13540 20 74 6f 20 61 6e 64 0a 2a 2a 20 69 6e 63 6c 75   to and.** inclu
13550 64 69 6e 67 20 66 72 61 6d 65 20 6e 75 6d 62 65  ding frame numbe
13560 72 20 61 52 65 61 64 4d 61 72 6b 5b 70 57 61 6c  r aReadMark[pWal
13570 2d 3e 72 65 61 64 4c 6f 63 6b 5d 2e 20 20 54 68  ->readLock].  Th
13580 65 20 72 65 61 64 65 72 20 77 69 6c 6c 0a 2a 2a  e reader will.**
13590 20 75 73 65 20 57 41 4c 20 66 72 61 6d 65 73 20   use WAL frames 
135a0 75 70 20 74 6f 20 61 6e 64 20 69 6e 63 6c 75 64  up to and includ
135b0 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  ing pWal->hdr.mx
135c0 46 72 61 6d 65 20 69 66 20 70 57 61 6c 2d 3e 72  Frame if pWal->r
135d0 65 61 64 4c 6f 63 6b 3e 30 0a 2a 2a 20 4f 72 20  eadLock>0.** Or 
135e0 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  if pWal->readLoc
135f0 6b 3d 3d 30 2c 20 74 68 65 6e 20 74 68 65 20 72  k==0, then the r
13600 65 61 64 65 72 20 77 69 6c 6c 20 69 67 6e 6f 72  eader will ignor
13610 65 20 74 68 65 20 57 41 4c 0a 2a 2a 20 63 6f 6d  e the WAL.** com
13620 70 6c 65 74 65 6c 79 20 61 6e 64 20 67 65 74 20  pletely and get 
13630 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72 65  all content dire
13640 63 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61  ctly from the da
13650 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 20  tabase file..** 
13660 49 66 20 74 68 65 20 75 73 65 57 61 6c 20 70 61  If the useWal pa
13670 72 61 6d 65 74 65 72 20 69 73 20 31 20 74 68 65  rameter is 1 the
13680 6e 20 74 68 65 20 57 41 4c 20 77 69 6c 6c 20 6e  n the WAL will n
13690 65 76 65 72 20 62 65 20 69 67 6e 6f 72 65 64 20  ever be ignored 
136a0 61 6e 64 0a 2a 2a 20 74 68 69 73 20 72 6f 75 74  and.** this rout
136b0 69 6e 65 20 77 69 6c 6c 20 61 6c 77 61 79 73 20  ine will always 
136c0 73 65 74 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  set pWal->readLo
136d0 63 6b 3e 30 20 6f 6e 20 73 75 63 63 65 73 73 2e  ck>0 on success.
136e0 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 72 65 61  .** When the rea
136f0 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73  d transaction is
13700 20 63 6f 6d 70 6c 65 74 65 64 2c 20 74 68 65 20   completed, the 
13710 63 61 6c 6c 65 72 20 6d 75 73 74 20 72 65 6c 65  caller must rele
13720 61 73 65 20 74 68 65 0a 2a 2a 20 6c 6f 63 6b 20  ase the.** lock 
13730 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  on WAL_READ_LOCK
13740 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29  (pWal->readLock)
13750 20 61 6e 64 20 73 65 74 20 70 57 61 6c 2d 3e 72   and set pWal->r
13760 65 61 64 4c 6f 63 6b 20 74 6f 20 2d 31 2e 0a 2a  eadLock to -1..*
13770 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  *.** This routin
13780 65 20 75 73 65 73 20 74 68 65 20 6e 42 61 63 6b  e uses the nBack
13790 66 69 6c 6c 20 61 6e 64 20 61 52 65 61 64 4d 61  fill and aReadMa
137a0 72 6b 5b 5d 20 66 69 65 6c 64 73 20 6f 66 20 74  rk[] fields of t
137b0 68 65 20 68 65 61 64 65 72 0a 2a 2a 20 74 6f 20  he header.** to 
137c0 73 65 6c 65 63 74 20 61 20 70 61 72 74 69 63 75  select a particu
137d0 6c 61 72 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  lar WAL_READ_LOC
137e0 4b 28 29 20 74 68 61 74 20 73 74 72 69 76 65 73  K() that strives
137f0 20 74 6f 20 6c 65 74 20 74 68 65 0a 2a 2a 20 63   to let the.** c
13800 68 65 63 6b 70 6f 69 6e 74 20 70 72 6f 63 65 73  heckpoint proces
13810 73 20 64 6f 20 61 73 20 6d 75 63 68 20 77 6f 72  s do as much wor
13820 6b 20 61 73 20 70 6f 73 73 69 62 6c 65 2e 20 20  k as possible.  
13830 54 68 69 73 20 72 6f 75 74 69 6e 65 20 6d 69 67  This routine mig
13840 68 74 0a 2a 2a 20 75 70 64 61 74 65 20 76 61 6c  ht.** update val
13850 75 65 73 20 6f 66 20 74 68 65 20 61 52 65 61 64  ues of the aRead
13860 4d 61 72 6b 5b 5d 20 61 72 72 61 79 20 69 6e 20  Mark[] array in 
13870 74 68 65 20 68 65 61 64 65 72 2c 20 62 75 74 20  the header, but 
13880 69 66 20 69 74 20 64 6f 65 73 0a 2a 2a 20 73 6f  if it does.** so
13890 20 69 74 20 74 61 6b 65 73 20 63 61 72 65 20 74   it takes care t
138a0 6f 20 68 6f 6c 64 20 61 6e 20 65 78 63 6c 75 73  o hold an exclus
138b0 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 74 68 65 20  ive lock on the 
138c0 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a  corresponding.**
138d0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 29   WAL_READ_LOCK()
138e0 20 77 68 69 6c 65 20 63 68 61 6e 67 69 6e 67 20   while changing 
138f0 76 61 6c 75 65 73 2e 0a 2a 2f 0a 73 74 61 74 69  values..*/.stati
13900 63 20 69 6e 74 20 77 61 6c 54 72 79 42 65 67 69  c int walTryBegi
13910 6e 52 65 61 64 28 57 61 6c 20 2a 70 57 61 6c 2c  nRead(Wal *pWal,
13920 20 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 2c 20   int *pChanged, 
13930 69 6e 74 20 75 73 65 57 61 6c 2c 20 69 6e 74 20  int useWal, int 
13940 63 6e 74 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65  cnt){.  volatile
13950 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49   WalCkptInfo *pI
13960 6e 66 6f 3b 20 20 20 20 2f 2a 20 43 68 65 63 6b  nfo;    /* Check
13970 70 6f 69 6e 74 20 69 6e 66 6f 72 6d 61 74 69 6f  point informatio
13980 6e 20 69 6e 20 77 61 6c 2d 69 6e 64 65 78 20 2a  n in wal-index *
13990 2f 0a 20 20 75 33 32 20 6d 78 52 65 61 64 4d 61  /.  u32 mxReadMa
139a0 72 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rk;             
139b0 20 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 61      /* Largest a
139c0 52 65 61 64 4d 61 72 6b 5b 5d 20 76 61 6c 75 65  ReadMark[] value
139d0 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 49 3b 20 20   */.  int mxI;  
139e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
139f0 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f        /* Index o
13a00 66 20 6c 61 72 67 65 73 74 20 61 52 65 61 64 4d  f largest aReadM
13a10 61 72 6b 5b 5d 20 76 61 6c 75 65 20 2a 2f 0a 20  ark[] value */. 
13a20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
13a30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13a40 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72   /* Loop counter
13a50 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   */.  int rc = S
13a60 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
13a70 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
13a80 63 6f 64 65 20 20 2a 2f 0a 0a 20 20 61 73 73 65  code  */..  asse
13a90 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  rt( pWal->readLo
13aa0 63 6b 3c 30 20 29 3b 20 20 20 20 20 2f 2a 20 4e  ck<0 );     /* N
13ab0 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 6c 6f 63  ot currently loc
13ac0 6b 65 64 20 2a 2f 0a 0a 20 20 2f 2a 20 54 61 6b  ked */..  /* Tak
13ad0 65 20 73 74 65 70 73 20 74 6f 20 61 76 6f 69 64  e steps to avoid
13ae0 20 73 70 69 6e 6e 69 6e 67 20 66 6f 72 65 76 65   spinning foreve
13af0 72 20 69 66 20 74 68 65 72 65 20 69 73 20 61 20  r if there is a 
13b00 70 72 6f 74 6f 63 6f 6c 20 65 72 72 6f 72 2e 0a  protocol error..
13b10 20 20 2a 2a 0a 20 20 2a 2a 20 43 69 72 63 75 6d    **.  ** Circum
13b20 73 74 61 6e 63 65 73 20 74 68 61 74 20 63 61 75  stances that cau
13b30 73 65 20 61 20 52 45 54 52 59 20 73 68 6f 75 6c  se a RETRY shoul
13b40 64 20 6f 6e 6c 79 20 6c 61 73 74 20 66 6f 72 20  d only last for 
13b50 74 68 65 20 62 72 69 65 66 65 73 74 0a 20 20 2a  the briefest.  *
13b60 2a 20 69 6e 73 74 61 6e 63 65 73 20 6f 66 20 74  * instances of t
13b70 69 6d 65 2e 20 20 4e 6f 20 49 2f 4f 20 6f 72 20  ime.  No I/O or 
13b80 6f 74 68 65 72 20 73 79 73 74 65 6d 20 63 61 6c  other system cal
13b90 6c 73 20 61 72 65 20 64 6f 6e 65 20 77 68 69 6c  ls are done whil
13ba0 65 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 63 6b 73  e the.  ** locks
13bb0 20 61 72 65 20 68 65 6c 64 2c 20 73 6f 20 74 68   are held, so th
13bc0 65 20 6c 6f 63 6b 73 20 73 68 6f 75 6c 64 20 6e  e locks should n
13bd0 6f 74 20 62 65 20 68 65 6c 64 20 66 6f 72 20 76  ot be held for v
13be0 65 72 79 20 6c 6f 6e 67 2e 20 42 75 74 20 0a 20  ery long. But . 
13bf0 20 2a 2a 20 69 66 20 77 65 20 61 72 65 20 75 6e   ** if we are un
13c00 6c 75 63 6b 79 2c 20 61 6e 6f 74 68 65 72 20 70  lucky, another p
13c10 72 6f 63 65 73 73 20 74 68 61 74 20 69 73 20 68  rocess that is h
13c20 6f 6c 64 69 6e 67 20 61 20 6c 6f 63 6b 20 6d 69  olding a lock mi
13c30 67 68 74 20 67 65 74 0a 20 20 2a 2a 20 70 61 67  ght get.  ** pag
13c40 65 64 20 6f 75 74 20 6f 72 20 74 61 6b 65 20 61  ed out or take a
13c50 20 70 61 67 65 2d 66 61 75 6c 74 20 74 68 61 74   page-fault that
13c60 20 69 73 20 74 69 6d 65 2d 63 6f 6e 73 75 6d 69   is time-consumi
13c70 6e 67 20 74 6f 20 72 65 73 6f 6c 76 65 2c 20 0a  ng to resolve, .
13c80 20 20 2a 2a 20 64 75 72 69 6e 67 20 74 68 65 20    ** during the 
13c90 66 65 77 20 6e 61 6e 6f 73 65 63 6f 6e 64 73 20  few nanoseconds 
13ca0 74 68 61 74 20 69 74 20 69 73 20 68 6f 6c 64 69  that it is holdi
13cb0 6e 67 20 74 68 65 20 6c 6f 63 6b 2e 20 20 49 6e  ng the lock.  In
13cc0 20 74 68 61 74 20 63 61 73 65 2c 0a 20 20 2a 2a   that case,.  **
13cd0 20 69 74 20 6d 69 67 68 74 20 74 61 6b 65 20 6c   it might take l
13ce0 6f 6e 67 65 72 20 74 68 61 6e 20 6e 6f 72 6d 61  onger than norma
13cf0 6c 20 66 6f 72 20 74 68 65 20 6c 6f 63 6b 20 74  l for the lock t
13d00 6f 20 66 72 65 65 2e 0a 20 20 2a 2a 0a 20 20 2a  o free..  **.  *
13d10 2a 20 41 66 74 65 72 20 35 20 52 45 54 52 59 73  * After 5 RETRYs
13d20 2c 20 77 65 20 62 65 67 69 6e 20 63 61 6c 6c 69  , we begin calli
13d30 6e 67 20 73 71 6c 69 74 65 33 4f 73 53 6c 65 65  ng sqlite3OsSlee
13d40 70 28 29 2e 20 20 54 68 65 20 66 69 72 73 74 20  p().  The first 
13d50 66 65 77 0a 20 20 2a 2a 20 63 61 6c 6c 73 20 74  few.  ** calls t
13d60 6f 20 73 71 6c 69 74 65 33 4f 73 53 6c 65 65 70  o sqlite3OsSleep
13d70 28 29 20 68 61 76 65 20 61 20 64 65 6c 61 79 20  () have a delay 
13d80 6f 66 20 31 20 6d 69 63 72 6f 73 65 63 6f 6e 64  of 1 microsecond
13d90 2e 20 20 52 65 61 6c 6c 79 20 74 68 69 73 0a 20  .  Really this. 
13da0 20 2a 2a 20 69 73 20 6d 6f 72 65 20 6f 66 20 61   ** is more of a
13db0 20 73 63 68 65 64 75 6c 65 72 20 79 69 65 6c 64   scheduler yield
13dc0 20 74 68 61 6e 20 61 6e 20 61 63 74 75 61 6c 20   than an actual 
13dd0 64 65 6c 61 79 2e 20 20 42 75 74 20 6f 6e 20 74  delay.  But on t
13de0 68 65 20 31 30 74 68 0a 20 20 2a 2a 20 61 6e 20  he 10th.  ** an 
13df0 73 75 62 73 65 71 75 65 6e 74 20 72 65 74 72 69  subsequent retri
13e00 65 73 2c 20 74 68 65 20 64 65 6c 61 79 73 20 73  es, the delays s
13e10 74 61 72 74 20 62 65 63 6f 6d 69 6e 67 20 6c 6f  tart becoming lo
13e20 6e 67 65 72 20 61 6e 64 20 6c 6f 6e 67 65 72 2c  nger and longer,
13e30 20 0a 20 20 2a 2a 20 73 6f 20 74 68 61 74 20 6f   .  ** so that o
13e40 6e 20 74 68 65 20 31 30 30 74 68 20 28 61 6e 64  n the 100th (and
13e50 20 6c 61 73 74 29 20 52 45 54 52 59 20 77 65 20   last) RETRY we 
13e60 64 65 6c 61 79 20 66 6f 72 20 32 31 20 6d 69 6c  delay for 21 mil
13e70 6c 69 73 65 63 6f 6e 64 73 2e 0a 20 20 2a 2a 20  liseconds..  ** 
13e80 54 68 65 20 74 6f 74 61 6c 20 64 65 6c 61 79 20  The total delay 
13e90 74 69 6d 65 20 62 65 66 6f 72 65 20 67 69 76 69  time before givi
13ea0 6e 67 20 75 70 20 69 73 20 6c 65 73 73 20 74 68  ng up is less th
13eb0 61 6e 20 31 20 73 65 63 6f 6e 64 2e 0a 20 20 2a  an 1 second..  *
13ec0 2f 0a 20 20 69 66 28 20 63 6e 74 3e 35 20 29 7b  /.  if( cnt>5 ){
13ed0 0a 20 20 20 20 69 6e 74 20 6e 44 65 6c 61 79 20  .    int nDelay 
13ee0 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 1;            
13ef0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 75            /* Pau
13f00 73 65 20 74 69 6d 65 20 69 6e 20 6d 69 63 72 6f  se time in micro
13f10 73 65 63 6f 6e 64 73 20 2a 2f 0a 20 20 20 20 69  seconds */.    i
13f20 66 28 20 63 6e 74 3e 31 30 30 20 29 7b 0a 20 20  f( cnt>100 ){.  
13f30 20 20 20 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57      VVA_ONLY( pW
13f40 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20  al->lockError = 
13f50 31 3b 20 29 0a 20 20 20 20 20 20 72 65 74 75 72  1; ).      retur
13f60 6e 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f  n SQLITE_PROTOCO
13f70 4c 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  L;.    }.    if(
13f80 20 63 6e 74 3e 3d 31 30 20 29 20 6e 44 65 6c 61   cnt>=10 ) nDela
13f90 79 20 3d 20 28 63 6e 74 2d 39 29 2a 32 33 38 3b  y = (cnt-9)*238;
13fa0 20 20 2f 2a 20 4d 61 78 20 64 65 6c 61 79 20 32    /* Max delay 2
13fb0 31 6d 73 2e 20 54 6f 74 61 6c 20 64 65 6c 61 79  1ms. Total delay
13fc0 20 39 39 36 6d 73 20 2a 2f 0a 20 20 20 20 73 71   996ms */.    sq
13fd0 6c 69 74 65 33 4f 73 53 6c 65 65 70 28 70 57 61  lite3OsSleep(pWa
13fe0 6c 2d 3e 70 56 66 73 2c 20 6e 44 65 6c 61 79 29  l->pVfs, nDelay)
13ff0 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21 75 73  ;.  }..  if( !us
14000 65 57 61 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d  eWal ){.    rc =
14010 20 77 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72   walIndexReadHdr
14020 28 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 29  (pWal, pChanged)
14030 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
14040 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
14050 20 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69     /* If there i
14060 73 20 6e 6f 74 20 61 20 72 65 63 6f 76 65 72 79  s not a recovery
14070 20 72 75 6e 6e 69 6e 67 20 69 6e 20 61 6e 6f 74   running in anot
14080 68 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72  her thread or pr
14090 6f 63 65 73 73 0a 20 20 20 20 20 20 2a 2a 20 74  ocess.      ** t
140a0 68 65 6e 20 63 6f 6e 76 65 72 74 20 42 55 53 59  hen convert BUSY
140b0 20 65 72 72 6f 72 73 20 74 6f 20 57 41 4c 5f 52   errors to WAL_R
140c0 45 54 52 59 2e 20 20 49 66 20 72 65 63 6f 76 65  ETRY.  If recove
140d0 72 79 20 69 73 20 6b 6e 6f 77 6e 20 74 6f 0a 20  ry is known to. 
140e0 20 20 20 20 20 2a 2a 20 62 65 20 72 75 6e 6e 69       ** be runni
140f0 6e 67 2c 20 63 6f 6e 76 65 72 74 20 42 55 53 59  ng, convert BUSY
14100 20 74 6f 20 42 55 53 59 5f 52 45 43 4f 56 45 52   to BUSY_RECOVER
14110 59 2e 20 20 54 68 65 72 65 20 69 73 20 61 20 72  Y.  There is a r
14120 61 63 65 20 68 65 72 65 0a 20 20 20 20 20 20 2a  ace here.      *
14130 2a 20 77 68 69 63 68 20 6d 69 67 68 74 20 63 61  * which might ca
14140 75 73 65 20 57 41 4c 5f 52 45 54 52 59 20 74 6f  use WAL_RETRY to
14150 20 62 65 20 72 65 74 75 72 6e 65 64 20 65 76 65   be returned eve
14160 6e 20 69 66 20 42 55 53 59 5f 52 45 43 4f 56 45  n if BUSY_RECOVE
14170 52 59 0a 20 20 20 20 20 20 2a 2a 20 77 6f 75 6c  RY.      ** woul
14180 64 20 62 65 20 74 65 63 68 6e 69 63 61 6c 6c 79  d be technically
14190 20 63 6f 72 72 65 63 74 2e 20 20 42 75 74 20 74   correct.  But t
141a0 68 65 20 72 61 63 65 20 69 73 20 62 65 6e 69 67  he race is benig
141b0 6e 20 73 69 6e 63 65 20 77 69 74 68 0a 20 20 20  n since with.   
141c0 20 20 20 2a 2a 20 57 41 4c 5f 52 45 54 52 59 20     ** WAL_RETRY 
141d0 74 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c  this routine wil
141e0 6c 20 62 65 20 63 61 6c 6c 65 64 20 61 67 61 69  l be called agai
141f0 6e 20 61 6e 64 20 77 69 6c 6c 20 70 72 6f 62 61  n and will proba
14200 62 6c 79 20 62 65 0a 20 20 20 20 20 20 2a 2a 20  bly be.      ** 
14210 72 69 67 68 74 20 6f 6e 20 74 68 65 20 73 65 63  right on the sec
14220 6f 6e 64 20 69 74 65 72 61 74 69 6f 6e 2e 0a 20  ond iteration.. 
14230 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 69 66       */.      if
14240 28 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61  ( pWal->apWiData
14250 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  [0]==0 ){.      
14260 20 20 2f 2a 20 54 68 69 73 20 62 72 61 6e 63 68    /* This branch
14270 20 69 73 20 74 61 6b 65 6e 20 77 68 65 6e 20 74   is taken when t
14280 68 65 20 78 53 68 6d 4d 61 70 28 29 20 6d 65 74  he xShmMap() met
14290 68 6f 64 20 72 65 74 75 72 6e 73 20 53 51 4c 49  hod returns SQLI
142a0 54 45 5f 42 55 53 59 2e 0a 20 20 20 20 20 20 20  TE_BUSY..       
142b0 20 2a 2a 20 57 65 20 61 73 73 75 6d 65 20 74 68   ** We assume th
142c0 69 73 20 69 73 20 61 20 74 72 61 6e 73 69 65 6e  is is a transien
142d0 74 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 73 6f 20  t condition, so 
142e0 72 65 74 75 72 6e 20 57 41 4c 5f 52 45 54 52 59  return WAL_RETRY
142f0 2e 20 54 68 65 0a 20 20 20 20 20 20 20 20 2a 2a  . The.        **
14300 20 78 53 68 6d 4d 61 70 28 29 20 69 6d 70 6c 65   xShmMap() imple
14310 6d 65 6e 74 61 74 69 6f 6e 20 75 73 65 64 20 62  mentation used b
14320 79 20 74 68 65 20 64 65 66 61 75 6c 74 20 75 6e  y the default un
14330 69 78 20 61 6e 64 20 77 69 6e 33 32 20 56 46 53  ix and win32 VFS
14340 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 6d 6f 64   .        ** mod
14350 75 6c 65 73 20 6d 61 79 20 72 65 74 75 72 6e 20  ules may return 
14360 53 51 4c 49 54 45 5f 42 55 53 59 20 64 75 65 20  SQLITE_BUSY due 
14370 74 6f 20 61 20 72 61 63 65 20 63 6f 6e 64 69 74  to a race condit
14380 69 6f 6e 20 69 6e 20 74 68 65 20 0a 20 20 20 20  ion in the .    
14390 20 20 20 20 2a 2a 20 63 6f 64 65 20 74 68 61 74      ** code that
143a0 20 64 65 74 65 72 6d 69 6e 65 73 20 77 68 65 74   determines whet
143b0 68 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 73  her or not the s
143c0 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20 72 65 67  hared-memory reg
143d0 69 6f 6e 20 0a 20 20 20 20 20 20 20 20 2a 2a 20  ion .        ** 
143e0 6d 75 73 74 20 62 65 20 7a 65 72 6f 65 64 20 62  must be zeroed b
143f0 65 66 6f 72 65 20 74 68 65 20 72 65 71 75 65 73  efore the reques
14400 74 65 64 20 70 61 67 65 20 69 73 20 72 65 74 75  ted page is retu
14410 72 6e 65 64 2e 0a 20 20 20 20 20 20 20 20 2a 2f  rned..        */
14420 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 57 41  .        rc = WA
14430 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d  L_RETRY;.      }
14440 65 6c 73 65 20 69 66 28 20 53 51 4c 49 54 45 5f  else if( SQLITE_
14450 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c 4c 6f 63  OK==(rc = walLoc
14460 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
14470 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 29 29  L_RECOVER_LOCK))
14480 20 29 7b 0a 20 20 20 20 20 20 20 20 77 61 6c 55   ){.        walU
14490 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
144a0 2c 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f  , WAL_RECOVER_LO
144b0 43 4b 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20  CK);.        rc 
144c0 3d 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20  = WAL_RETRY;.   
144d0 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d     }else if( rc=
144e0 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a  =SQLITE_BUSY ){.
144f0 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
14500 49 54 45 5f 42 55 53 59 5f 52 45 43 4f 56 45 52  ITE_BUSY_RECOVER
14510 59 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  Y;.      }.    }
14520 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
14530 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
14540 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
14550 0a 20 20 7d 0a 0a 20 20 70 49 6e 66 6f 20 3d 20  .  }..  pInfo = 
14560 77 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c  walCkptInfo(pWal
14570 29 3b 0a 20 20 69 66 28 20 21 75 73 65 57 61 6c  );.  if( !useWal
14580 20 26 26 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b   && pInfo->nBack
14590 66 69 6c 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e  fill==pWal->hdr.
145a0 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 2f  mxFrame ){.    /
145b0 2a 20 54 68 65 20 57 41 4c 20 68 61 73 20 62 65  * The WAL has be
145c0 65 6e 20 63 6f 6d 70 6c 65 74 65 6c 79 20 62 61  en completely ba
145d0 63 6b 66 69 6c 6c 65 64 20 28 6f 72 20 69 74 20  ckfilled (or it 
145e0 69 73 20 65 6d 70 74 79 29 2e 0a 20 20 20 20 2a  is empty)..    *
145f0 2a 20 61 6e 64 20 63 61 6e 20 62 65 20 73 61 66  * and can be saf
14600 65 6c 79 20 69 67 6e 6f 72 65 64 2e 0a 20 20 20  ely ignored..   
14610 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 77 61 6c   */.    rc = wal
14620 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  LockShared(pWal,
14630 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
14640 29 29 3b 0a 20 20 20 20 77 61 6c 53 68 6d 42 61  ));.    walShmBa
14650 72 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20 20  rrier(pWal);.   
14660 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
14670 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  OK ){.      if( 
14680 6d 65 6d 63 6d 70 28 28 76 6f 69 64 20 2a 29 77  memcmp((void *)w
14690 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29  alIndexHdr(pWal)
146a0 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69  , &pWal->hdr, si
146b0 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
146c0 29 29 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a  )) ){.        /*
146d0 20 49 74 20 69 73 20 6e 6f 74 20 73 61 66 65 20   It is not safe 
146e0 74 6f 20 61 6c 6c 6f 77 20 74 68 65 20 72 65 61  to allow the rea
146f0 64 65 72 20 74 6f 20 63 6f 6e 74 69 6e 75 65 20  der to continue 
14700 68 65 72 65 20 69 66 20 66 72 61 6d 65 73 0a 20  here if frames. 
14710 20 20 20 20 20 20 20 2a 2a 20 6d 61 79 20 68 61         ** may ha
14720 76 65 20 62 65 65 6e 20 61 70 70 65 6e 64 65 64  ve been appended
14730 20 74 6f 20 74 68 65 20 6c 6f 67 20 62 65 66 6f   to the log befo
14740 72 65 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20  re READ_LOCK(0) 
14750 77 61 73 20 6f 62 74 61 69 6e 65 64 2e 0a 20 20  was obtained..  
14760 20 20 20 20 20 20 2a 2a 20 57 68 65 6e 20 68 6f        ** When ho
14770 6c 64 69 6e 67 20 52 45 41 44 5f 4c 4f 43 4b 28  lding READ_LOCK(
14780 30 29 2c 20 74 68 65 20 72 65 61 64 65 72 20 69  0), the reader i
14790 67 6e 6f 72 65 73 20 74 68 65 20 65 6e 74 69 72  gnores the entir
147a0 65 20 6c 6f 67 20 66 69 6c 65 2c 0a 20 20 20 20  e log file,.    
147b0 20 20 20 20 2a 2a 20 77 68 69 63 68 20 69 6d 70      ** which imp
147c0 6c 69 65 73 20 74 68 61 74 20 74 68 65 20 64 61  lies that the da
147d0 74 61 62 61 73 65 20 66 69 6c 65 20 63 6f 6e 74  tabase file cont
147e0 61 69 6e 73 20 61 20 74 72 75 73 74 77 6f 72 74  ains a trustwort
147f0 68 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 6e  hy.        ** sn
14800 61 70 73 68 6f 54 2e 20 53 69 6e 63 65 20 68 6f  apshoT. Since ho
14810 6c 64 69 6e 67 20 52 45 41 44 5f 4c 4f 43 4b 28  lding READ_LOCK(
14820 30 29 20 70 72 65 76 65 6e 74 73 20 61 20 63 68  0) prevents a ch
14830 65 63 6b 70 6f 69 6e 74 20 66 72 6f 6d 0a 20 20  eckpoint from.  
14840 20 20 20 20 20 20 2a 2a 20 68 61 70 70 65 6e 69        ** happeni
14850 6e 67 2c 20 74 68 69 73 20 69 73 20 75 73 75 61  ng, this is usua
14860 6c 6c 79 20 63 6f 72 72 65 63 74 2e 0a 20 20 20  lly correct..   
14870 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20       **.        
14880 2a 2a 20 48 6f 77 65 76 65 72 2c 20 69 66 20 66  ** However, if f
14890 72 61 6d 65 73 20 68 61 76 65 20 62 65 65 6e 20  rames have been 
148a0 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20  appended to the 
148b0 6c 6f 67 20 28 6f 72 20 69 66 20 74 68 65 20 6c  log (or if the l
148c0 6f 67 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 69  og .        ** i
148d0 73 20 77 72 61 70 70 65 64 20 61 6e 64 20 77 72  s wrapped and wr
148e0 69 74 74 65 6e 20 66 6f 72 20 74 68 61 74 20 6d  itten for that m
148f0 61 74 74 65 72 29 20 62 65 66 6f 72 65 20 74 68  atter) before th
14900 65 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29 0a 20  e READ_LOCK(0). 
14910 20 20 20 20 20 20 20 2a 2a 20 69 73 20 6f 62 74         ** is obt
14920 61 69 6e 65 64 2c 20 74 68 61 74 20 69 73 20 6e  ained, that is n
14930 6f 74 20 6e 65 63 65 73 73 61 72 69 6c 79 20 74  ot necessarily t
14940 72 75 65 2e 20 41 20 63 68 65 63 6b 70 6f 69 6e  rue. A checkpoin
14950 74 65 72 20 6d 61 79 0a 20 20 20 20 20 20 20 20  ter may.        
14960 2a 2a 20 68 61 76 65 20 73 74 61 72 74 65 64 20  ** have started 
14970 74 6f 20 62 61 63 6b 66 69 6c 6c 20 74 68 65 20  to backfill the 
14980 61 70 70 65 6e 64 65 64 20 66 72 61 6d 65 73 20  appended frames 
14990 62 75 74 20 63 72 61 73 68 65 64 20 62 65 66 6f  but crashed befo
149a0 72 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 69 74  re.        ** it
149b0 20 66 69 6e 69 73 68 65 64 2e 20 4c 65 61 76 69   finished. Leavi
149c0 6e 67 20 61 20 63 6f 72 72 75 70 74 20 69 6d 61  ng a corrupt ima
149d0 67 65 20 69 6e 20 74 68 65 20 64 61 74 61 62 61  ge in the databa
149e0 73 65 20 66 69 6c 65 2e 0a 20 20 20 20 20 20 20  se file..       
149f0 20 2a 2f 0a 20 20 20 20 20 20 20 20 77 61 6c 55   */.        walU
14a00 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
14a10 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
14a20 30 29 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74  0));.        ret
14a30 75 72 6e 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20  urn WAL_RETRY;. 
14a40 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 57 61       }.      pWa
14a50 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 30 3b  l->readLock = 0;
14a60 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
14a70 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 65 6c  LITE_OK;.    }el
14a80 73 65 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  se if( rc!=SQLIT
14a90 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20  E_BUSY ){.      
14aa0 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
14ab0 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 77 65  .  }..  /* If we
14ac0 20 67 65 74 20 74 68 69 73 20 66 61 72 2c 20 69   get this far, i
14ad0 74 20 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65  t means that the
14ae0 20 72 65 61 64 65 72 20 77 69 6c 6c 20 77 61 6e   reader will wan
14af0 74 20 74 6f 20 75 73 65 0a 20 20 2a 2a 20 74 68  t to use.  ** th
14b00 65 20 57 41 4c 20 74 6f 20 67 65 74 20 61 74 20  e WAL to get at 
14b10 63 6f 6e 74 65 6e 74 20 66 72 6f 6d 20 72 65 63  content from rec
14b20 65 6e 74 20 63 6f 6d 6d 69 74 73 2e 20 20 54 68  ent commits.  Th
14b30 65 20 6a 6f 62 20 6e 6f 77 20 69 73 0a 20 20 2a  e job now is.  *
14b40 2a 20 74 6f 20 73 65 6c 65 63 74 20 6f 6e 65 20  * to select one 
14b50 6f 66 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b  of the aReadMark
14b60 5b 5d 20 65 6e 74 72 69 65 73 20 74 68 61 74 20  [] entries that 
14b70 69 73 20 63 6c 6f 73 65 73 74 20 74 6f 0a 20 20  is closest to.  
14b80 2a 2a 20 62 75 74 20 6e 6f 74 20 65 78 63 65 65  ** but not excee
14b90 64 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  ding pWal->hdr.m
14ba0 78 46 72 61 6d 65 20 61 6e 64 20 6c 6f 63 6b 20  xFrame and lock 
14bb0 74 68 61 74 20 65 6e 74 72 79 2e 0a 20 20 2a 2f  that entry..  */
14bc0 0a 20 20 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20  .  mxReadMark = 
14bd0 30 3b 0a 20 20 6d 78 49 20 3d 20 30 3b 0a 20 20  0;.  mxI = 0;.  
14be0 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e  for(i=1; i<WAL_N
14bf0 52 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20  READER; i++){.  
14c00 20 20 75 33 32 20 74 68 69 73 4d 61 72 6b 20 3d    u32 thisMark =
14c10 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
14c20 6b 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 6d 78  k[i];.    if( mx
14c30 52 65 61 64 4d 61 72 6b 3c 3d 74 68 69 73 4d 61  ReadMark<=thisMa
14c40 72 6b 20 26 26 20 74 68 69 73 4d 61 72 6b 3c 3d  rk && thisMark<=
14c50 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
14c60 65 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72  e ){.      asser
14c70 74 28 20 74 68 69 73 4d 61 72 6b 21 3d 52 45 41  t( thisMark!=REA
14c80 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 20 29  DMARK_NOT_USED )
14c90 3b 0a 20 20 20 20 20 20 6d 78 52 65 61 64 4d 61  ;.      mxReadMa
14ca0 72 6b 20 3d 20 74 68 69 73 4d 61 72 6b 3b 0a 20  rk = thisMark;. 
14cb0 20 20 20 20 20 6d 78 49 20 3d 20 69 3b 0a 20 20       mxI = i;.  
14cc0 20 20 7d 0a 20 20 7d 0a 20 20 2f 2a 20 54 68 65    }.  }.  /* The
14cd0 72 65 20 77 61 73 20 6f 6e 63 65 20 61 6e 20 22  re was once an "
14ce0 69 66 22 20 68 65 72 65 2e 20 54 68 65 20 65 78  if" here. The ex
14cf0 74 72 61 20 22 7b 22 20 69 73 20 74 6f 20 70 72  tra "{" is to pr
14d00 65 73 65 72 76 65 20 69 6e 64 65 6e 74 61 74 69  eserve indentati
14d10 6f 6e 2e 20 2a 2f 0a 20 20 7b 0a 20 20 20 20 69  on. */.  {.    i
14d20 66 28 20 28 70 57 61 6c 2d 3e 72 65 61 64 4f 6e  f( (pWal->readOn
14d30 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  ly & WAL_SHM_RDO
14d40 4e 4c 59 29 3d 3d 30 0a 20 20 20 20 20 26 26 20  NLY)==0.     && 
14d50 28 6d 78 52 65 61 64 4d 61 72 6b 3c 70 57 61 6c  (mxReadMark<pWal
14d60 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 7c 7c  ->hdr.mxFrame ||
14d70 20 6d 78 49 3d 3d 30 29 0a 20 20 20 20 29 7b 0a   mxI==0).    ){.
14d80 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69        for(i=1; i
14d90 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b  <WAL_NREADER; i+
14da0 2b 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  +){.        rc =
14db0 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76   walLockExclusiv
14dc0 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
14dd0 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20  _LOCK(i), 1);.  
14de0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
14df0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
14e00 20 20 20 20 20 6d 78 52 65 61 64 4d 61 72 6b 20       mxReadMark 
14e10 3d 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61  = pInfo->aReadMa
14e20 72 6b 5b 69 5d 20 3d 20 70 57 61 6c 2d 3e 68 64  rk[i] = pWal->hd
14e30 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 20  r.mxFrame;.     
14e40 20 20 20 20 20 6d 78 49 20 3d 20 69 3b 0a 20 20       mxI = i;.  
14e50 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63          walUnloc
14e60 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
14e70 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69   WAL_READ_LOCK(i
14e80 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20 20  ), 1);.         
14e90 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
14ea0 7d 65 6c 73 65 20 69 66 28 20 72 63 21 3d 53 51  }else if( rc!=SQ
14eb0 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
14ec0 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63         return rc
14ed0 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
14ee0 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
14ef0 28 20 6d 78 49 3d 3d 30 20 29 7b 0a 20 20 20 20  ( mxI==0 ){.    
14f00 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
14f10 4c 49 54 45 5f 42 55 53 59 20 7c 7c 20 28 70 57  LITE_BUSY || (pW
14f20 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57  al->readOnly & W
14f30 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 29 21 3d  AL_SHM_RDONLY)!=
14f40 30 20 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72  0 );.      retur
14f50 6e 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  n rc==SQLITE_BUS
14f60 59 20 3f 20 57 41 4c 5f 52 45 54 52 59 20 3a 20  Y ? WAL_RETRY : 
14f70 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 5f  SQLITE_READONLY_
14f80 43 41 4e 54 4c 4f 43 4b 3b 0a 20 20 20 20 7d 0a  CANTLOCK;.    }.
14f90 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63  .    rc = walLoc
14fa0 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
14fb0 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29  L_READ_LOCK(mxI)
14fc0 29 3b 0a 20 20 20 20 69 66 28 20 72 63 20 29 7b  );.    if( rc ){
14fd0 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63  .      return rc
14fe0 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 3f 20  ==SQLITE_BUSY ? 
14ff0 57 41 4c 5f 52 45 54 52 59 20 3a 20 72 63 3b 0a  WAL_RETRY : rc;.
15000 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20 4e 6f 77      }.    /* Now
15010 20 74 68 61 74 20 74 68 65 20 72 65 61 64 2d 6c   that the read-l
15020 6f 63 6b 20 68 61 73 20 62 65 65 6e 20 6f 62 74  ock has been obt
15030 61 69 6e 65 64 2c 20 63 68 65 63 6b 20 74 68 61  ained, check tha
15040 74 20 6e 65 69 74 68 65 72 20 74 68 65 0a 20 20  t neither the.  
15050 20 20 2a 2a 20 76 61 6c 75 65 20 69 6e 20 74 68    ** value in th
15060 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 61 72  e aReadMark[] ar
15070 72 61 79 20 6f 72 20 74 68 65 20 63 6f 6e 74 65  ray or the conte
15080 6e 74 73 20 6f 66 20 74 68 65 20 77 61 6c 2d 69  nts of the wal-i
15090 6e 64 65 78 0a 20 20 20 20 2a 2a 20 68 65 61 64  ndex.    ** head
150a0 65 72 20 68 61 76 65 20 63 68 61 6e 67 65 64 2e  er have changed.
150b0 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 49  .    **.    ** I
150c0 74 20 69 73 20 6e 65 63 65 73 73 61 72 79 20 74  t is necessary t
150d0 6f 20 63 68 65 63 6b 20 74 68 61 74 20 74 68 65  o check that the
150e0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
150f0 72 20 64 69 64 20 6e 6f 74 20 63 68 61 6e 67 65  r did not change
15100 0a 20 20 20 20 2a 2a 20 62 65 74 77 65 65 6e 20  .    ** between 
15110 74 68 65 20 74 69 6d 65 20 69 74 20 77 61 73 20  the time it was 
15120 72 65 61 64 20 61 6e 64 20 77 68 65 6e 20 74 68  read and when th
15130 65 20 73 68 61 72 65 64 2d 6c 6f 63 6b 20 77 61  e shared-lock wa
15140 73 20 6f 62 74 61 69 6e 65 64 0a 20 20 20 20 2a  s obtained.    *
15150 2a 20 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  * on WAL_READ_LO
15160 43 4b 28 6d 78 49 29 20 77 61 73 20 6f 62 74 61  CK(mxI) was obta
15170 69 6e 65 64 20 74 6f 20 61 63 63 6f 75 6e 74 20  ined to account 
15180 66 6f 72 20 74 68 65 20 70 6f 73 73 69 62 69 6c  for the possibil
15190 69 74 79 0a 20 20 20 20 2a 2a 20 74 68 61 74 20  ity.    ** that 
151a0 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 6d 61 79  the log file may
151b0 20 68 61 76 65 20 62 65 65 6e 20 77 72 61 70 70   have been wrapp
151c0 65 64 20 62 79 20 61 20 77 72 69 74 65 72 2c 20  ed by a writer, 
151d0 6f 72 20 74 68 61 74 20 66 72 61 6d 65 73 0a 20  or that frames. 
151e0 20 20 20 2a 2a 20 74 68 61 74 20 6f 63 63 75 72     ** that occur
151f0 20 6c 61 74 65 72 20 69 6e 20 74 68 65 20 6c 6f   later in the lo
15200 67 20 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72  g than pWal->hdr
15210 2e 6d 78 46 72 61 6d 65 20 6d 61 79 20 68 61 76  .mxFrame may hav
15220 65 20 62 65 65 6e 0a 20 20 20 20 2a 2a 20 63 6f  e been.    ** co
15230 70 69 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61  pied into the da
15240 74 61 62 61 73 65 20 62 79 20 61 20 63 68 65 63  tabase by a chec
15250 6b 70 6f 69 6e 74 65 72 2e 20 49 66 20 65 69 74  kpointer. If eit
15260 68 65 72 20 6f 66 20 74 68 65 73 65 20 74 68 69  her of these thi
15270 6e 67 73 0a 20 20 20 20 2a 2a 20 68 61 70 70 65  ngs.    ** happe
15280 6e 65 64 2c 20 74 68 65 6e 20 72 65 61 64 69 6e  ned, then readin
15290 67 20 74 68 65 20 64 61 74 61 62 61 73 65 20 77  g the database w
152a0 69 74 68 20 74 68 65 20 63 75 72 72 65 6e 74 20  ith the current 
152b0 76 61 6c 75 65 20 6f 66 0a 20 20 20 20 2a 2a 20  value of.    ** 
152c0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
152d0 65 20 72 69 73 6b 73 20 72 65 61 64 69 6e 67 20  e risks reading 
152e0 61 20 63 6f 72 72 75 70 74 65 64 20 73 6e 61 70  a corrupted snap
152f0 73 68 6f 74 2e 20 53 6f 2c 20 72 65 74 72 79 0a  shot. So, retry.
15300 20 20 20 20 2a 2a 20 69 6e 73 74 65 61 64 2e 0a      ** instead..
15310 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68      **.    ** Th
15320 69 73 20 64 6f 65 73 20 6e 6f 74 20 67 75 61 72  is does not guar
15330 61 6e 74 65 65 20 74 68 61 74 20 74 68 65 20 63  antee that the c
15340 6f 70 79 20 6f 66 20 74 68 65 20 77 61 6c 2d 69  opy of the wal-i
15350 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20 75  ndex header is u
15360 70 20 74 6f 0a 20 20 20 20 2a 2a 20 64 61 74 65  p to.    ** date
15370 20 62 65 66 6f 72 65 20 70 72 6f 63 65 65 64 69   before proceedi
15380 6e 67 2e 20 54 68 61 74 20 77 6f 75 6c 64 20 6e  ng. That would n
15390 6f 74 20 62 65 20 70 6f 73 73 69 62 6c 65 20 77  ot be possible w
153a0 69 74 68 6f 75 74 20 73 6f 6d 65 68 6f 77 0a 20  ithout somehow. 
153b0 20 20 20 2a 2a 20 62 6c 6f 63 6b 69 6e 67 20 77     ** blocking w
153c0 72 69 74 65 72 73 2e 20 49 74 20 6f 6e 6c 79 20  riters. It only 
153d0 67 75 61 72 61 6e 74 65 65 73 20 74 68 61 74 20  guarantees that 
153e0 61 20 64 61 6e 67 65 72 6f 75 73 20 63 68 65 63  a dangerous chec
153f0 6b 70 6f 69 6e 74 20 6f 72 20 0a 20 20 20 20 2a  kpoint or .    *
15400 2a 20 6c 6f 67 2d 77 72 61 70 20 28 65 69 74 68  * log-wrap (eith
15410 65 72 20 6f 66 20 77 68 69 63 68 20 77 6f 75 6c  er of which woul
15420 64 20 72 65 71 75 69 72 65 20 61 6e 20 65 78 63  d require an exc
15430 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 0a 20  lusive lock on. 
15440 20 20 20 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c     ** WAL_READ_L
15450 4f 43 4b 28 6d 78 49 29 29 20 68 61 73 20 6e 6f  OCK(mxI)) has no
15460 74 20 6f 63 63 75 72 72 65 64 20 73 69 6e 63 65  t occurred since
15470 20 74 68 65 20 73 6e 61 70 73 68 6f 74 20 77 61   the snapshot wa
15480 73 20 76 61 6c 69 64 2e 0a 20 20 20 20 2a 2f 0a  s valid..    */.
15490 20 20 20 20 77 61 6c 53 68 6d 42 61 72 72 69 65      walShmBarrie
154a0 72 28 70 57 61 6c 29 3b 0a 20 20 20 20 69 66 28  r(pWal);.    if(
154b0 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
154c0 6b 5b 6d 78 49 5d 21 3d 6d 78 52 65 61 64 4d 61  k[mxI]!=mxReadMa
154d0 72 6b 0a 20 20 20 20 20 7c 7c 20 6d 65 6d 63 6d  rk.     || memcm
154e0 70 28 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64  p((void *)walInd
154f0 65 78 48 64 72 28 70 57 61 6c 29 2c 20 26 70 57  exHdr(pWal), &pW
15500 61 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28  al->hdr, sizeof(
15510 57 61 6c 49 6e 64 65 78 48 64 72 29 29 0a 20 20  WalIndexHdr)).  
15520 20 20 29 7b 0a 20 20 20 20 20 20 77 61 6c 55 6e    ){.      walUn
15530 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  lockShared(pWal,
15540 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d   WAL_READ_LOCK(m
15550 78 49 29 29 3b 0a 20 20 20 20 20 20 72 65 74 75  xI));.      retu
15560 72 6e 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20  rn WAL_RETRY;.  
15570 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 61    }else{.      a
15580 73 73 65 72 74 28 20 6d 78 52 65 61 64 4d 61 72  ssert( mxReadMar
15590 6b 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  k<=pWal->hdr.mxF
155a0 72 61 6d 65 20 29 3b 0a 20 20 20 20 20 20 70 57  rame );.      pW
155b0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 28  al->readLock = (
155c0 69 31 36 29 6d 78 49 3b 0a 20 20 20 20 7d 0a 20  i16)mxI;.    }. 
155d0 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
155e0 7d 0a 0a 2f 2a 0a 2a 2a 20 42 65 67 69 6e 20 61  }../*.** Begin a
155f0 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
15600 6e 20 6f 6e 20 74 68 65 20 64 61 74 61 62 61 73  n on the databas
15610 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  e..**.** This ro
15620 75 74 69 6e 65 20 75 73 65 64 20 74 6f 20 62 65  utine used to be
15630 20 63 61 6c 6c 65 64 20 73 71 6c 69 74 65 33 4f   called sqlite3O
15640 70 65 6e 53 6e 61 70 73 68 6f 74 28 29 20 61 6e  penSnapshot() an
15650 64 20 77 69 74 68 20 67 6f 6f 64 20 72 65 61 73  d with good reas
15660 6f 6e 3a 0a 2a 2a 20 69 74 20 74 61 6b 65 73 20  on:.** it takes 
15670 61 20 73 6e 61 70 73 68 6f 74 20 6f 66 20 74 68  a snapshot of th
15680 65 20 73 74 61 74 65 20 6f 66 20 74 68 65 20 57  e state of the W
15690 41 4c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78  AL and wal-index
156a0 20 66 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74   for the current
156b0 0a 2a 2a 20 69 6e 73 74 61 6e 74 20 69 6e 20 74  .** instant in t
156c0 69 6d 65 2e 20 20 54 68 65 20 63 75 72 72 65 6e  ime.  The curren
156d0 74 20 74 68 72 65 61 64 20 77 69 6c 6c 20 63 6f  t thread will co
156e0 6e 74 69 6e 75 65 20 74 6f 20 75 73 65 20 74 68  ntinue to use th
156f0 69 73 20 73 6e 61 70 73 68 6f 74 2e 0a 2a 2a 20  is snapshot..** 
15700 4f 74 68 65 72 20 74 68 72 65 61 64 73 20 6d 69  Other threads mi
15710 67 68 74 20 61 70 70 65 6e 64 20 6e 65 77 20 63  ght append new c
15720 6f 6e 74 65 6e 74 20 74 6f 20 74 68 65 20 57 41  ontent to the WA
15730 4c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20  L and wal-index 
15740 62 75 74 0a 2a 2a 20 74 68 61 74 20 65 78 74 72  but.** that extr
15750 61 20 63 6f 6e 74 65 6e 74 20 69 73 20 69 67 6e  a content is ign
15760 6f 72 65 64 20 62 79 20 74 68 65 20 63 75 72 72  ored by the curr
15770 65 6e 74 20 74 68 72 65 61 64 2e 0a 2a 2a 0a 2a  ent thread..**.*
15780 2a 20 49 66 20 74 68 65 20 64 61 74 61 62 61 73  * If the databas
15790 65 20 63 6f 6e 74 65 6e 74 73 20 68 61 76 65 20  e contents have 
157a0 63 68 61 6e 67 65 73 20 73 69 6e 63 65 20 74 68  changes since th
157b0 65 20 70 72 65 76 69 6f 75 73 20 72 65 61 64 0a  e previous read.
157c0 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20  ** transaction, 
157d0 74 68 65 6e 20 2a 70 43 68 61 6e 67 65 64 20 69  then *pChanged i
157e0 73 20 73 65 74 20 74 6f 20 31 20 62 65 66 6f 72  s set to 1 befor
157f0 65 20 72 65 74 75 72 6e 69 6e 67 2e 20 20 54 68  e returning.  Th
15800 65 0a 2a 2a 20 50 61 67 65 72 20 6c 61 79 65 72  e.** Pager layer
15810 20 77 69 6c 6c 20 75 73 65 20 74 68 69 73 20 74   will use this t
15820 6f 20 6b 6e 6f 77 20 74 68 61 74 20 69 73 20 63  o know that is c
15830 61 63 68 65 20 69 73 20 73 74 61 6c 65 20 61 6e  ache is stale an
15840 64 0a 2a 2a 20 6e 65 65 64 73 20 74 6f 20 62 65  d.** needs to be
15850 20 66 6c 75 73 68 65 64 2e 0a 2a 2f 0a 69 6e 74   flushed..*/.int
15860 20 73 71 6c 69 74 65 33 57 61 6c 42 65 67 69 6e   sqlite3WalBegin
15870 52 65 61 64 54 72 61 6e 73 61 63 74 69 6f 6e 28  ReadTransaction(
15880 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a  Wal *pWal, int *
15890 70 43 68 61 6e 67 65 64 29 7b 0a 20 20 69 6e 74  pChanged){.  int
158a0 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
158b0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
158c0 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
158d0 20 69 6e 74 20 63 6e 74 20 3d 20 30 3b 20 20 20   int cnt = 0;   
158e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
158f0 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 54 72   /* Number of Tr
15900 79 42 65 67 69 6e 52 65 61 64 20 61 74 74 65 6d  yBeginRead attem
15910 70 74 73 20 2a 2f 0a 0a 20 20 64 6f 7b 0a 20 20  pts */..  do{.  
15920 20 20 72 63 20 3d 20 77 61 6c 54 72 79 42 65 67    rc = walTryBeg
15930 69 6e 52 65 61 64 28 70 57 61 6c 2c 20 70 43 68  inRead(pWal, pCh
15940 61 6e 67 65 64 2c 20 30 2c 20 2b 2b 63 6e 74 29  anged, 0, ++cnt)
15950 3b 0a 20 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d  ;.  }while( rc==
15960 57 41 4c 5f 52 45 54 52 59 20 29 3b 0a 20 20 74  WAL_RETRY );.  t
15970 65 73 74 63 61 73 65 28 20 28 72 63 26 30 78 66  estcase( (rc&0xf
15980 66 29 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  f)==SQLITE_BUSY 
15990 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 28  );.  testcase( (
159a0 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49 54 45  rc&0xff)==SQLITE
159b0 5f 49 4f 45 52 52 20 29 3b 0a 20 20 74 65 73 74  _IOERR );.  test
159c0 63 61 73 65 28 20 72 63 3d 3d 53 51 4c 49 54 45  case( rc==SQLITE
159d0 5f 50 52 4f 54 4f 43 4f 4c 20 29 3b 0a 20 20 74  _PROTOCOL );.  t
159e0 65 73 74 63 61 73 65 28 20 72 63 3d 3d 53 51 4c  estcase( rc==SQL
159f0 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74 75  ITE_OK );.  retu
15a00 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
15a10 46 69 6e 69 73 68 20 77 69 74 68 20 61 20 72 65  Finish with a re
15a20 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20  ad transaction. 
15a30 20 41 6c 6c 20 74 68 69 73 20 64 6f 65 73 20 69   All this does i
15a40 73 20 72 65 6c 65 61 73 65 20 74 68 65 0a 2a 2a  s release the.**
15a50 20 72 65 61 64 2d 6c 6f 63 6b 2e 0a 2a 2f 0a 76   read-lock..*/.v
15a60 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 45 6e  oid sqlite3WalEn
15a70 64 52 65 61 64 54 72 61 6e 73 61 63 74 69 6f 6e  dReadTransaction
15a80 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 73  (Wal *pWal){.  s
15a90 71 6c 69 74 65 33 57 61 6c 45 6e 64 57 72 69 74  qlite3WalEndWrit
15aa0 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 70 57 61  eTransaction(pWa
15ab0 6c 29 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  l);.  if( pWal->
15ac0 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 7b 0a 20  readLock>=0 ){. 
15ad0 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72     walUnlockShar
15ae0 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ed(pWal, WAL_REA
15af0 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61  D_LOCK(pWal->rea
15b00 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70 57 61  dLock));.    pWa
15b10 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31  l->readLock = -1
15b20 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  ;.  }.}../*.** S
15b30 65 61 72 63 68 20 74 68 65 20 77 61 6c 20 66 69  earch the wal fi
15b40 6c 65 20 66 6f 72 20 70 61 67 65 20 70 67 6e 6f  le for page pgno
15b50 2e 20 49 66 20 66 6f 75 6e 64 2c 20 73 65 74 20  . If found, set 
15b60 2a 70 69 52 65 61 64 20 74 6f 20 74 68 65 20 66  *piRead to the f
15b70 72 61 6d 65 20 74 68 61 74 0a 2a 2a 20 63 6f 6e  rame that.** con
15b80 74 61 69 6e 73 20 74 68 65 20 70 61 67 65 2e 20  tains the page. 
15b90 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20 70 67  Otherwise, if pg
15ba0 6e 6f 20 69 73 20 6e 6f 74 20 69 6e 20 74 68 65  no is not in the
15bb0 20 77 61 6c 20 66 69 6c 65 2c 20 73 65 74 20 2a   wal file, set *
15bc0 70 69 52 65 61 64 0a 2a 2a 20 74 6f 20 7a 65 72  piRead.** to zer
15bd0 6f 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  o..**.** Return 
15be0 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63  SQLITE_OK if suc
15bf0 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 65  cessful, or an e
15c00 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 20  rror code if an 
15c10 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20 49 66  error occurs. If
15c20 20 61 6e 0a 2a 2a 20 65 72 72 6f 72 20 64 6f 65   an.** error doe
15c30 73 20 6f 63 63 75 72 2c 20 74 68 65 20 66 69 6e  s occur, the fin
15c40 61 6c 20 76 61 6c 75 65 20 6f 66 20 2a 70 69 52  al value of *piR
15c50 65 61 64 20 69 73 20 75 6e 64 65 66 69 6e 65 64  ead is undefined
15c60 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
15c70 57 61 6c 46 69 6e 64 46 72 61 6d 65 28 0a 20 20  WalFindFrame(.  
15c80 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20  Wal *pWal,      
15c90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15ca0 2f 2a 20 57 41 4c 20 68 61 6e 64 6c 65 20 2a 2f  /* WAL handle */
15cb0 0a 20 20 50 67 6e 6f 20 70 67 6e 6f 2c 20 20 20  .  Pgno pgno,   
15cc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15cd0 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 70     /* Database p
15ce0 61 67 65 20 6e 75 6d 62 65 72 20 74 6f 20 72 65  age number to re
15cf0 61 64 20 64 61 74 61 20 66 6f 72 20 2a 2f 0a 20  ad data for */. 
15d00 20 75 33 32 20 2a 70 69 52 65 61 64 20 20 20 20   u32 *piRead    
15d10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15d20 20 2f 2a 20 4f 55 54 3a 20 46 72 61 6d 65 20 6e   /* OUT: Frame n
15d30 75 6d 62 65 72 20 28 6f 72 20 7a 65 72 6f 29 20  umber (or zero) 
15d40 2a 2f 0a 29 7b 0a 20 20 75 33 32 20 69 52 65 61  */.){.  u32 iRea
15d50 64 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  d = 0;          
15d60 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 21 3d          /* If !=
15d70 30 2c 20 57 41 4c 20 66 72 61 6d 65 20 74 6f 20  0, WAL frame to 
15d80 72 65 74 75 72 6e 20 64 61 74 61 20 66 72 6f 6d  return data from
15d90 20 2a 2f 0a 20 20 75 33 32 20 69 4c 61 73 74 20   */.  u32 iLast 
15da0 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  = pWal->hdr.mxFr
15db0 61 6d 65 3b 20 20 2f 2a 20 4c 61 73 74 20 70 61  ame;  /* Last pa
15dc0 67 65 20 69 6e 20 57 41 4c 20 66 6f 72 20 74 68  ge in WAL for th
15dd0 69 73 20 72 65 61 64 65 72 20 2a 2f 0a 20 20 69  is reader */.  i
15de0 6e 74 20 69 48 61 73 68 3b 20 20 20 20 20 20 20  nt iHash;       
15df0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
15e00 2a 20 55 73 65 64 20 74 6f 20 6c 6f 6f 70 20 74  * Used to loop t
15e10 68 72 6f 75 67 68 20 4e 20 68 61 73 68 20 74 61  hrough N hash ta
15e20 62 6c 65 73 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68  bles */..  /* Th
15e30 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 6f 6e  is routine is on
15e40 6c 79 20 62 65 20 63 61 6c 6c 65 64 20 66 72 6f  ly be called fro
15e50 6d 20 77 69 74 68 69 6e 20 61 20 72 65 61 64 20  m within a read 
15e60 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 2a 2f 0a  transaction. */.
15e70 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
15e80 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70  readLock>=0 || p
15e90 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 29  Wal->lockError )
15ea0 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 22  ;..  /* If the "
15eb0 6c 61 73 74 20 70 61 67 65 22 20 66 69 65 6c 64  last page" field
15ec0 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
15ed0 78 20 68 65 61 64 65 72 20 73 6e 61 70 73 68 6f  x header snapsho
15ee0 74 20 69 73 20 30 2c 20 74 68 65 6e 0a 20 20 2a  t is 0, then.  *
15ef0 2a 20 6e 6f 20 64 61 74 61 20 77 69 6c 6c 20 62  * no data will b
15f00 65 20 72 65 61 64 20 66 72 6f 6d 20 74 68 65 20  e read from the 
15f10 77 61 6c 20 75 6e 64 65 72 20 61 6e 79 20 63 69  wal under any ci
15f20 72 63 75 6d 73 74 61 6e 63 65 73 2e 20 52 65 74  rcumstances. Ret
15f30 75 72 6e 20 65 61 72 6c 79 0a 20 20 2a 2a 20 69  urn early.  ** i
15f40 6e 20 74 68 69 73 20 63 61 73 65 20 61 73 20 61  n this case as a
15f50 6e 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e 2e 20  n optimization. 
15f60 20 4c 69 6b 65 77 69 73 65 2c 20 69 66 20 70 57   Likewise, if pW
15f70 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 2c  al->readLock==0,
15f80 20 0a 20 20 2a 2a 20 74 68 65 6e 20 74 68 65 20   .  ** then the 
15f90 57 41 4c 20 69 73 20 69 67 6e 6f 72 65 64 20 62  WAL is ignored b
15fa0 79 20 74 68 65 20 72 65 61 64 65 72 20 73 6f 20  y the reader so 
15fb0 72 65 74 75 72 6e 20 65 61 72 6c 79 2c 20 61 73  return early, as
15fc0 20 69 66 20 74 68 65 20 0a 20 20 2a 2a 20 57 41   if the .  ** WA
15fd0 4c 20 77 65 72 65 20 65 6d 70 74 79 2e 0a 20 20  L were empty..  
15fe0 2a 2f 0a 20 20 69 66 28 20 69 4c 61 73 74 3d 3d  */.  if( iLast==
15ff0 30 20 7c 7c 20 70 57 61 6c 2d 3e 72 65 61 64 4c  0 || pWal->readL
16000 6f 63 6b 3d 3d 30 20 29 7b 0a 20 20 20 20 2a 70  ock==0 ){.    *p
16010 69 52 65 61 64 20 3d 20 30 3b 0a 20 20 20 20 72  iRead = 0;.    r
16020 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
16030 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 65 61 72 63  .  }..  /* Searc
16040 68 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  h the hash table
16050 20 6f 72 20 74 61 62 6c 65 73 20 66 6f 72 20 61   or tables for a
16060 6e 20 65 6e 74 72 79 20 6d 61 74 63 68 69 6e 67  n entry matching
16070 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 20 20 2a   page number.  *
16080 2a 20 70 67 6e 6f 2e 20 45 61 63 68 20 69 74 65  * pgno. Each ite
16090 72 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 66 6f  ration of the fo
160a0 6c 6c 6f 77 69 6e 67 20 66 6f 72 28 29 20 6c 6f  llowing for() lo
160b0 6f 70 20 73 65 61 72 63 68 65 73 20 6f 6e 65 0a  op searches one.
160c0 20 20 2a 2a 20 68 61 73 68 20 74 61 62 6c 65 20    ** hash table 
160d0 28 65 61 63 68 20 68 61 73 68 20 74 61 62 6c 65  (each hash table
160e0 20 69 6e 64 65 78 65 73 20 75 70 20 74 6f 20 48   indexes up to H
160f0 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 66  ASHTABLE_NPAGE f
16100 72 61 6d 65 73 29 2e 0a 20 20 2a 2a 0a 20 20 2a  rames)..  **.  *
16110 2a 20 54 68 69 73 20 63 6f 64 65 20 6d 69 67 68  * This code migh
16120 74 20 72 75 6e 20 63 6f 6e 63 75 72 72 65 6e 74  t run concurrent
16130 6c 79 20 74 6f 20 74 68 65 20 63 6f 64 65 20 69  ly to the code i
16140 6e 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64  n walIndexAppend
16150 28 29 0a 20 20 2a 2a 20 74 68 61 74 20 61 64 64  ().  ** that add
16160 73 20 65 6e 74 72 69 65 73 20 74 6f 20 74 68 65  s entries to the
16170 20 77 61 6c 2d 69 6e 64 65 78 20 28 61 6e 64 20   wal-index (and 
16180 70 6f 73 73 69 62 6c 79 20 74 6f 20 74 68 69 73  possibly to this
16190 20 68 61 73 68 20 0a 20 20 2a 2a 20 74 61 62 6c   hash .  ** tabl
161a0 65 29 2e 20 54 68 69 73 20 6d 65 61 6e 73 20 74  e). This means t
161b0 68 65 20 76 61 6c 75 65 20 6a 75 73 74 20 72 65  he value just re
161c0 61 64 20 66 72 6f 6d 20 74 68 65 20 68 61 73 68  ad from the hash
161d0 20 0a 20 20 2a 2a 20 73 6c 6f 74 20 28 61 48 61   .  ** slot (aHa
161e0 73 68 5b 69 4b 65 79 5d 29 20 6d 61 79 20 68 61  sh[iKey]) may ha
161f0 76 65 20 62 65 65 6e 20 61 64 64 65 64 20 62 65  ve been added be
16200 66 6f 72 65 20 6f 72 20 61 66 74 65 72 20 74 68  fore or after th
16210 65 20 0a 20 20 2a 2a 20 63 75 72 72 65 6e 74 20  e .  ** current 
16220 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
16230 20 77 61 73 20 6f 70 65 6e 65 64 2e 20 56 61 6c   was opened. Val
16240 75 65 73 20 61 64 64 65 64 20 61 66 74 65 72 20  ues added after 
16250 74 68 65 0a 20 20 2a 2a 20 72 65 61 64 20 74 72  the.  ** read tr
16260 61 6e 73 61 63 74 69 6f 6e 20 77 61 73 20 6f 70  ansaction was op
16270 65 6e 65 64 20 6d 61 79 20 68 61 76 65 20 62 65  ened may have be
16280 65 6e 20 77 72 69 74 74 65 6e 20 69 6e 63 6f 72  en written incor
16290 72 65 63 74 6c 79 20 2d 0a 20 20 2a 2a 20 69 2e  rectly -.  ** i.
162a0 65 2e 20 74 68 65 73 65 20 73 6c 6f 74 73 20 6d  e. these slots m
162b0 61 79 20 63 6f 6e 74 61 69 6e 20 67 61 72 62 61  ay contain garba
162c0 67 65 20 64 61 74 61 2e 20 48 6f 77 65 76 65 72  ge data. However
162d0 2c 20 77 65 20 61 73 73 75 6d 65 0a 20 20 2a 2a  , we assume.  **
162e0 20 74 68 61 74 20 61 6e 79 20 73 6c 6f 74 73 20   that any slots 
162f0 77 72 69 74 74 65 6e 20 62 65 66 6f 72 65 20 74  written before t
16300 68 65 20 63 75 72 72 65 6e 74 20 72 65 61 64 20  he current read 
16310 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61 73 0a  transaction was.
16320 20 20 2a 2a 20 6f 70 65 6e 65 64 20 72 65 6d 61    ** opened rema
16330 69 6e 20 75 6e 6d 6f 64 69 66 69 65 64 2e 0a 20  in unmodified.. 
16340 20 2a 2a 0a 20 20 2a 2a 20 46 6f 72 20 74 68 65   **.  ** For the
16350 20 72 65 61 73 6f 6e 73 20 61 62 6f 76 65 2c 20   reasons above, 
16360 74 68 65 20 69 66 28 2e 2e 2e 29 20 63 6f 6e 64  the if(...) cond
16370 69 74 69 6f 6e 20 66 65 61 74 75 72 65 64 20 69  ition featured i
16380 6e 20 74 68 65 20 69 6e 6e 65 72 0a 20 20 2a 2a  n the inner.  **
16390 20 6c 6f 6f 70 20 6f 66 20 74 68 65 20 66 6f 6c   loop of the fol
163a0 6c 6f 77 69 6e 67 20 62 6c 6f 63 6b 20 69 73 20  lowing block is 
163b0 6d 6f 72 65 20 73 74 72 69 6e 67 65 6e 74 20 74  more stringent t
163c0 68 61 74 20 77 6f 75 6c 64 20 62 65 20 72 65 71  hat would be req
163d0 75 69 72 65 64 20 0a 20 20 2a 2a 20 69 66 20 77  uired .  ** if w
163e0 65 20 68 61 64 20 65 78 63 6c 75 73 69 76 65 20  e had exclusive 
163f0 61 63 63 65 73 73 20 74 6f 20 74 68 65 20 68 61  access to the ha
16400 73 68 2d 74 61 62 6c 65 3a 0a 20 20 2a 2a 0a 20  sh-table:.  **. 
16410 20 2a 2a 20 20 20 28 61 50 67 6e 6f 5b 69 46 72   **   (aPgno[iFr
16420 61 6d 65 5d 3d 3d 70 67 6e 6f 29 3a 20 0a 20 20  ame]==pgno): .  
16430 2a 2a 20 20 20 20 20 54 68 69 73 20 63 6f 6e 64  **     This cond
16440 69 74 69 6f 6e 20 66 69 6c 74 65 72 73 20 6f 75  ition filters ou
16450 74 20 6e 6f 72 6d 61 6c 20 68 61 73 68 2d 74 61  t normal hash-ta
16460 62 6c 65 20 63 6f 6c 6c 69 73 69 6f 6e 73 2e 0a  ble collisions..
16470 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 28 69 46 72    **.  **   (iFr
16480 61 6d 65 3c 3d 69 4c 61 73 74 29 3a 20 0a 20 20  ame<=iLast): .  
16490 2a 2a 20 20 20 20 20 54 68 69 73 20 63 6f 6e 64  **     This cond
164a0 69 74 69 6f 6e 20 66 69 6c 74 65 72 73 20 6f 75  ition filters ou
164b0 74 20 65 6e 74 72 69 65 73 20 74 68 61 74 20 77  t entries that w
164c0 65 72 65 20 61 64 64 65 64 20 74 6f 20 74 68 65  ere added to the
164d0 20 68 61 73 68 0a 20 20 2a 2a 20 20 20 20 20 74   hash.  **     t
164e0 61 62 6c 65 20 61 66 74 65 72 20 74 68 65 20 63  able after the c
164f0 75 72 72 65 6e 74 20 72 65 61 64 2d 74 72 61 6e  urrent read-tran
16500 73 61 63 74 69 6f 6e 20 68 61 64 20 73 74 61 72  saction had star
16510 74 65 64 2e 0a 20 20 2a 2f 0a 20 20 66 6f 72 28  ted..  */.  for(
16520 69 48 61 73 68 3d 77 61 6c 46 72 61 6d 65 50 61  iHash=walFramePa
16530 67 65 28 69 4c 61 73 74 29 3b 20 69 48 61 73 68  ge(iLast); iHash
16540 3e 3d 30 20 26 26 20 69 52 65 61 64 3d 3d 30 3b  >=0 && iRead==0;
16550 20 69 48 61 73 68 2d 2d 29 7b 0a 20 20 20 20 76   iHash--){.    v
16560 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20  olatile ht_slot 
16570 2a 61 48 61 73 68 3b 20 20 20 20 20 20 2f 2a 20  *aHash;      /* 
16580 50 6f 69 6e 74 65 72 20 74 6f 20 68 61 73 68 20  Pointer to hash 
16590 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 76 6f 6c  table */.    vol
165a0 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f  atile u32 *aPgno
165b0 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f  ;          /* Po
165c0 69 6e 74 65 72 20 74 6f 20 61 72 72 61 79 20 6f  inter to array o
165d0 66 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20 2a  f page numbers *
165e0 2f 0a 20 20 20 20 75 33 32 20 69 5a 65 72 6f 3b  /.    u32 iZero;
165f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16600 20 20 20 20 2f 2a 20 46 72 61 6d 65 20 6e 75 6d      /* Frame num
16610 62 65 72 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e  ber correspondin
16620 67 20 74 6f 20 61 50 67 6e 6f 5b 30 5d 20 2a 2f  g to aPgno[0] */
16630 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20  .    int iKey;  
16640 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16650 20 20 20 2f 2a 20 48 61 73 68 20 73 6c 6f 74 20     /* Hash slot 
16660 69 6e 64 65 78 20 2a 2f 0a 20 20 20 20 69 6e 74  index */.    int
16670 20 6e 43 6f 6c 6c 69 64 65 3b 20 20 20 20 20 20   nCollide;      
16680 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
16690 6d 62 65 72 20 6f 66 20 68 61 73 68 20 63 6f 6c  mber of hash col
166a0 6c 69 73 69 6f 6e 73 20 72 65 6d 61 69 6e 69 6e  lisions remainin
166b0 67 20 2a 2f 0a 20 20 20 20 69 6e 74 20 72 63 3b  g */.    int rc;
166c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
166d0 20 20 20 20 20 20 20 2f 2a 20 45 72 72 6f 72 20         /* Error 
166e0 63 6f 64 65 20 2a 2f 0a 0a 20 20 20 20 72 63 20  code */..    rc 
166f0 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70 57 61  = walHashGet(pWa
16700 6c 2c 20 69 48 61 73 68 2c 20 26 61 48 61 73 68  l, iHash, &aHash
16710 2c 20 26 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f  , &aPgno, &iZero
16720 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
16730 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
16740 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20    return rc;.   
16750 20 7d 0a 20 20 20 20 6e 43 6f 6c 6c 69 64 65 20   }.    nCollide 
16760 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f  = HASHTABLE_NSLO
16770 54 3b 0a 20 20 20 20 66 6f 72 28 69 4b 65 79 3d  T;.    for(iKey=
16780 77 61 6c 48 61 73 68 28 70 67 6e 6f 29 3b 20 61  walHash(pgno); a
16790 48 61 73 68 5b 69 4b 65 79 5d 3b 20 69 4b 65 79  Hash[iKey]; iKey
167a0 3d 77 61 6c 4e 65 78 74 48 61 73 68 28 69 4b 65  =walNextHash(iKe
167b0 79 29 29 7b 0a 20 20 20 20 20 20 75 33 32 20 69  y)){.      u32 i
167c0 46 72 61 6d 65 20 3d 20 61 48 61 73 68 5b 69 4b  Frame = aHash[iK
167d0 65 79 5d 20 2b 20 69 5a 65 72 6f 3b 0a 20 20 20  ey] + iZero;.   
167e0 20 20 20 69 66 28 20 69 46 72 61 6d 65 3c 3d 69     if( iFrame<=i
167f0 4c 61 73 74 20 26 26 20 61 50 67 6e 6f 5b 61 48  Last && aPgno[aH
16800 61 73 68 5b 69 4b 65 79 5d 5d 3d 3d 70 67 6e 6f  ash[iKey]]==pgno
16810 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 61   ){.        /* a
16820 73 73 65 72 74 28 20 69 46 72 61 6d 65 3e 69 52  ssert( iFrame>iR
16830 65 61 64 20 29 3b 20 2d 2d 20 6e 6f 74 20 74 72  ead ); -- not tr
16840 75 65 20 69 66 20 74 68 65 72 65 20 69 73 20 63  ue if there is c
16850 6f 72 72 75 70 74 69 6f 6e 20 2a 2f 0a 20 20 20  orruption */.   
16860 20 20 20 20 20 69 52 65 61 64 20 3d 20 69 46 72       iRead = iFr
16870 61 6d 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ame;.      }.   
16880 20 20 20 69 66 28 20 28 6e 43 6f 6c 6c 69 64 65     if( (nCollide
16890 2d 2d 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  --)==0 ){.      
168a0 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
168b0 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20  CORRUPT_BKPT;.  
168c0 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
168d0 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45  .#ifdef SQLITE_E
168e0 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f  NABLE_EXPENSIVE_
168f0 41 53 53 45 52 54 0a 20 20 2f 2a 20 49 66 20 65  ASSERT.  /* If e
16900 78 70 65 6e 73 69 76 65 20 61 73 73 65 72 74 28  xpensive assert(
16910 29 20 73 74 61 74 65 6d 65 6e 74 73 20 61 72 65  ) statements are
16920 20 61 76 61 69 6c 61 62 6c 65 2c 20 64 6f 20 61   available, do a
16930 20 6c 69 6e 65 61 72 20 73 65 61 72 63 68 0a 20   linear search. 
16940 20 2a 2a 20 6f 66 20 74 68 65 20 77 61 6c 2d 69   ** of the wal-i
16950 6e 64 65 78 20 66 69 6c 65 20 63 6f 6e 74 65 6e  ndex file conten
16960 74 2e 20 4d 61 6b 65 20 73 75 72 65 20 74 68 65  t. Make sure the
16970 20 72 65 73 75 6c 74 73 20 61 67 72 65 65 20 77   results agree w
16980 69 74 68 20 74 68 65 0a 20 20 2a 2a 20 72 65 73  ith the.  ** res
16990 75 6c 74 20 6f 62 74 61 69 6e 65 64 20 75 73 69  ult obtained usi
169a0 6e 67 20 74 68 65 20 68 61 73 68 20 69 6e 64 65  ng the hash inde
169b0 78 65 73 20 61 62 6f 76 65 2e 20 20 2a 2f 0a 20  xes above.  */. 
169c0 20 7b 0a 20 20 20 20 75 33 32 20 69 52 65 61 64   {.    u32 iRead
169d0 32 20 3d 20 30 3b 0a 20 20 20 20 75 33 32 20 69  2 = 0;.    u32 i
169e0 54 65 73 74 3b 0a 20 20 20 20 66 6f 72 28 69 54  Test;.    for(iT
169f0 65 73 74 3d 69 4c 61 73 74 3b 20 69 54 65 73 74  est=iLast; iTest
16a00 3e 30 3b 20 69 54 65 73 74 2d 2d 29 7b 0a 20 20  >0; iTest--){.  
16a10 20 20 20 20 69 66 28 20 77 61 6c 46 72 61 6d 65      if( walFrame
16a20 50 67 6e 6f 28 70 57 61 6c 2c 20 69 54 65 73 74  Pgno(pWal, iTest
16a30 29 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20  )==pgno ){.     
16a40 20 20 20 69 52 65 61 64 32 20 3d 20 69 54 65 73     iRead2 = iTes
16a50 74 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  t;.        break
16a60 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
16a70 20 20 20 20 61 73 73 65 72 74 28 20 69 52 65 61      assert( iRea
16a80 64 3d 3d 69 52 65 61 64 32 20 29 3b 0a 20 20 7d  d==iRead2 );.  }
16a90 0a 23 65 6e 64 69 66 0a 0a 20 20 2a 70 69 52 65  .#endif..  *piRe
16aa0 61 64 20 3d 20 69 52 65 61 64 3b 0a 20 20 72 65  ad = iRead;.  re
16ab0 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
16ac0 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 74 68  }../*.** Read th
16ad0 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 66 72  e contents of fr
16ae0 61 6d 65 20 69 52 65 61 64 20 66 72 6f 6d 20 74  ame iRead from t
16af0 68 65 20 77 61 6c 20 66 69 6c 65 20 69 6e 74 6f  he wal file into
16b00 20 62 75 66 66 65 72 20 70 4f 75 74 0a 2a 2a 20   buffer pOut.** 
16b10 28 77 68 69 63 68 20 69 73 20 6e 4f 75 74 20 62  (which is nOut b
16b20 79 74 65 73 20 69 6e 20 73 69 7a 65 29 2e 20 52  ytes in size). R
16b30 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20  eturn SQLITE_OK 
16b40 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f  if successful, o
16b50 72 20 61 6e 0a 2a 2a 20 65 72 72 6f 72 20 63 6f  r an.** error co
16b60 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f  de otherwise..*/
16b70 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 52  .int sqlite3WalR
16b80 65 61 64 46 72 61 6d 65 28 0a 20 20 57 61 6c 20  eadFrame(.  Wal 
16b90 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20  *pWal,          
16ba0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
16bb0 41 4c 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 75  AL handle */.  u
16bc0 33 32 20 69 52 65 61 64 2c 20 20 20 20 20 20 20  32 iRead,       
16bd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
16be0 2a 20 46 72 61 6d 65 20 74 6f 20 72 65 61 64 20  * Frame to read 
16bf0 2a 2f 0a 20 20 69 6e 74 20 6e 4f 75 74 2c 20 20  */.  int nOut,  
16c00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16c10 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
16c20 62 75 66 66 65 72 20 70 4f 75 74 20 69 6e 20 62  buffer pOut in b
16c30 79 74 65 73 20 2a 2f 0a 20 20 75 38 20 2a 70 4f  ytes */.  u8 *pO
16c40 75 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ut              
16c50 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66            /* Buf
16c60 66 65 72 20 74 6f 20 77 72 69 74 65 20 70 61 67  fer to write pag
16c70 65 20 64 61 74 61 20 74 6f 20 2a 2f 0a 29 7b 0a  e data to */.){.
16c80 20 20 69 6e 74 20 73 7a 3b 0a 20 20 69 36 34 20    int sz;.  i64 
16c90 69 4f 66 66 73 65 74 3b 0a 20 20 73 7a 20 3d 20  iOffset;.  sz = 
16ca0 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65  pWal->hdr.szPage
16cb0 3b 0a 20 20 73 7a 20 3d 20 28 73 7a 26 30 78 66  ;.  sz = (sz&0xf
16cc0 65 30 30 29 20 2b 20 28 28 73 7a 26 30 78 30 30  e00) + ((sz&0x00
16cd0 30 31 29 3c 3c 31 36 29 3b 0a 20 20 74 65 73 74  01)<<16);.  test
16ce0 63 61 73 65 28 20 73 7a 3c 3d 33 32 37 36 38 20  case( sz<=32768 
16cf0 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 73  );.  testcase( s
16d00 7a 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 69 4f  z>=65536 );.  iO
16d10 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61 6d 65  ffset = walFrame
16d20 4f 66 66 73 65 74 28 69 52 65 61 64 2c 20 73 7a  Offset(iRead, sz
16d30 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44  ) + WAL_FRAME_HD
16d40 52 53 49 5a 45 3b 0a 20 20 2f 2a 20 74 65 73 74  RSIZE;.  /* test
16d50 63 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54  case( IS_BIG_INT
16d60 28 69 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f 20  (iOffset) ); // 
16d70 72 65 71 75 69 72 65 73 20 61 20 34 47 69 42 20  requires a 4GiB 
16d80 57 41 4c 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20  WAL */.  return 
16d90 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57  sqlite3OsRead(pW
16da0 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 70 4f 75 74  al->pWalFd, pOut
16db0 2c 20 28 6e 4f 75 74 3e 73 7a 20 3f 20 73 7a 20  , (nOut>sz ? sz 
16dc0 3a 20 6e 4f 75 74 29 2c 20 69 4f 66 66 73 65 74  : nOut), iOffset
16dd0 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74  );.}../* .** Ret
16de0 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20  urn the size of 
16df0 74 68 65 20 64 61 74 61 62 61 73 65 20 69 6e 20  the database in 
16e00 70 61 67 65 73 20 28 6f 72 20 7a 65 72 6f 2c 20  pages (or zero, 
16e10 69 66 20 75 6e 6b 6e 6f 77 6e 29 2e 0a 2a 2f 0a  if unknown)..*/.
16e20 50 67 6e 6f 20 73 71 6c 69 74 65 33 57 61 6c 44  Pgno sqlite3WalD
16e30 62 73 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c 29  bsize(Wal *pWal)
16e40 7b 0a 20 20 69 66 28 20 70 57 61 6c 20 26 26 20  {.  if( pWal && 
16e50 41 4c 57 41 59 53 28 70 57 61 6c 2d 3e 72 65 61  ALWAYS(pWal->rea
16e60 64 4c 6f 63 6b 3e 3d 30 29 20 29 7b 0a 20 20 20  dLock>=0) ){.   
16e70 20 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e 68 64   return pWal->hd
16e80 72 2e 6e 50 61 67 65 3b 0a 20 20 7d 0a 20 20 72  r.nPage;.  }.  r
16e90 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 0a 2f 2a 20  eturn 0;.}.../* 
16ea0 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
16eb0 6e 20 73 74 61 72 74 73 20 61 20 77 72 69 74 65  n starts a write
16ec0 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20   transaction on 
16ed0 74 68 65 20 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20 41  the WAL..**.** A
16ee0 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
16ef0 6e 20 6d 75 73 74 20 68 61 76 65 20 61 6c 72 65  n must have alre
16f00 61 64 79 20 62 65 65 6e 20 73 74 61 72 74 65 64  ady been started
16f10 20 62 79 20 61 20 70 72 69 6f 72 20 63 61 6c 6c   by a prior call
16f20 0a 2a 2a 20 74 6f 20 73 71 6c 69 74 65 33 57 61  .** to sqlite3Wa
16f30 6c 42 65 67 69 6e 52 65 61 64 54 72 61 6e 73 61  lBeginReadTransa
16f40 63 74 69 6f 6e 28 29 2e 0a 2a 2a 0a 2a 2a 20 49  ction()..**.** I
16f50 66 20 61 6e 6f 74 68 65 72 20 74 68 72 65 61 64  f another thread
16f60 20 6f 72 20 70 72 6f 63 65 73 73 20 68 61 73 20   or process has 
16f70 77 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65  written into the
16f80 20 64 61 74 61 62 61 73 65 20 73 69 6e 63 65 0a   database since.
16f90 2a 2a 20 74 68 65 20 72 65 61 64 20 74 72 61 6e  ** the read tran
16fa0 73 61 63 74 69 6f 6e 20 77 61 73 20 73 74 61 72  saction was star
16fb0 74 65 64 2c 20 74 68 65 6e 20 69 74 20 69 73 20  ted, then it is 
16fc0 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20 66 6f 72  not possible for
16fd0 20 74 68 69 73 0a 2a 2a 20 74 68 72 65 61 64 20   this.** thread 
16fe0 74 6f 20 77 72 69 74 65 20 61 73 20 64 6f 69 6e  to write as doin
16ff0 67 20 73 6f 20 77 6f 75 6c 64 20 63 61 75 73 65  g so would cause
17000 20 61 20 66 6f 72 6b 2e 20 20 53 6f 20 74 68 69   a fork.  So thi
17010 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65 74  s routine.** ret
17020 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53 59  urns SQLITE_BUSY
17030 20 69 6e 20 74 68 61 74 20 63 61 73 65 20 61 6e   in that case an
17040 64 20 6e 6f 20 77 72 69 74 65 20 74 72 61 6e 73  d no write trans
17050 61 63 74 69 6f 6e 20 69 73 20 73 74 61 72 74 65  action is starte
17060 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 63  d..**.** There c
17070 61 6e 20 6f 6e 6c 79 20 62 65 20 61 20 73 69 6e  an only be a sin
17080 67 6c 65 20 77 72 69 74 65 72 20 61 63 74 69 76  gle writer activ
17090 65 20 61 74 20 61 20 74 69 6d 65 2e 0a 2a 2f 0a  e at a time..*/.
170a0 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 42 65  int sqlite3WalBe
170b0 67 69 6e 57 72 69 74 65 54 72 61 6e 73 61 63 74  ginWriteTransact
170c0 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ion(Wal *pWal){.
170d0 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 2f 2a 20    int rc;..  /* 
170e0 43 61 6e 6e 6f 74 20 73 74 61 72 74 20 61 20 77  Cannot start a w
170f0 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  rite transaction
17100 20 77 69 74 68 6f 75 74 20 66 69 72 73 74 20 68   without first h
17110 6f 6c 64 69 6e 67 20 61 20 72 65 61 64 0a 20 20  olding a read.  
17120 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20  ** transaction. 
17130 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  */.  assert( pWa
17140 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29  l->readLock>=0 )
17150 3b 0a 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 72  ;..  if( pWal->r
17160 65 61 64 4f 6e 6c 79 20 29 7b 0a 20 20 20 20 72  eadOnly ){.    r
17170 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 52 45 41  eturn SQLITE_REA
17180 44 4f 4e 4c 59 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  DONLY;.  }..  /*
17190 20 4f 6e 6c 79 20 6f 6e 65 20 77 72 69 74 65 72   Only one writer
171a0 20 61 6c 6c 6f 77 65 64 20 61 74 20 61 20 74 69   allowed at a ti
171b0 6d 65 2e 20 20 47 65 74 20 74 68 65 20 77 72 69  me.  Get the wri
171c0 74 65 20 6c 6f 63 6b 2e 20 20 52 65 74 75 72 6e  te lock.  Return
171d0 0a 20 20 2a 2a 20 53 51 4c 49 54 45 5f 42 55 53  .  ** SQLITE_BUS
171e0 59 20 69 66 20 75 6e 61 62 6c 65 2e 0a 20 20 2a  Y if unable..  *
171f0 2f 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b  /.  rc = walLock
17200 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
17210 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20  WAL_WRITE_LOCK, 
17220 31 29 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a  1);.  if( rc ){.
17230 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
17240 20 7d 0a 20 20 70 57 61 6c 2d 3e 77 72 69 74 65   }.  pWal->write
17250 4c 6f 63 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20  Lock = 1;..  /* 
17260 49 66 20 61 6e 6f 74 68 65 72 20 63 6f 6e 6e 65  If another conne
17270 63 74 69 6f 6e 20 68 61 73 20 77 72 69 74 74 65  ction has writte
17280 6e 20 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  n to the databas
17290 65 20 66 69 6c 65 20 73 69 6e 63 65 20 74 68 65  e file since the
172a0 0a 20 20 2a 2a 20 74 69 6d 65 20 74 68 65 20 72  .  ** time the r
172b0 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
172c0 6f 6e 20 74 68 69 73 20 63 6f 6e 6e 65 63 74 69  on this connecti
172d0 6f 6e 20 77 61 73 20 73 74 61 72 74 65 64 2c 20  on was started, 
172e0 74 68 65 6e 0a 20 20 2a 2a 20 74 68 65 20 77 72  then.  ** the wr
172f0 69 74 65 20 69 73 20 64 69 73 61 6c 6c 6f 77 65  ite is disallowe
17300 64 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 6d 65  d..  */.  if( me
17310 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72 2c  mcmp(&pWal->hdr,
17320 20 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65   (void *)walInde
17330 78 48 64 72 28 70 57 61 6c 29 2c 20 73 69 7a 65  xHdr(pWal), size
17340 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
17350 21 3d 30 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e  !=0 ){.    walUn
17360 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  lockExclusive(pW
17370 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f  al, WAL_WRITE_LO
17380 43 4b 2c 20 31 29 3b 0a 20 20 20 20 70 57 61 6c  CK, 1);.    pWal
17390 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b  ->writeLock = 0;
173a0 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
173b0 5f 42 55 53 59 3b 0a 20 20 7d 0a 0a 20 20 72 65  _BUSY;.  }..  re
173c0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
173d0 2a 20 45 6e 64 20 61 20 77 72 69 74 65 20 74 72  * End a write tr
173e0 61 6e 73 61 63 74 69 6f 6e 2e 20 20 54 68 65 20  ansaction.  The 
173f0 63 6f 6d 6d 69 74 20 68 61 73 20 61 6c 72 65 61  commit has alrea
17400 64 79 20 62 65 65 6e 20 64 6f 6e 65 2e 20 20 54  dy been done.  T
17410 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 6d  his.** routine m
17420 65 72 65 6c 79 20 72 65 6c 65 61 73 65 73 20 74  erely releases t
17430 68 65 20 6c 6f 63 6b 2e 0a 2a 2f 0a 69 6e 74 20  he lock..*/.int 
17440 73 71 6c 69 74 65 33 57 61 6c 45 6e 64 57 72 69  sqlite3WalEndWri
17450 74 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 57 61  teTransaction(Wa
17460 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28 20  l *pWal){.  if( 
17470 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
17480 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b  ){.    walUnlock
17490 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
174a0 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20  WAL_WRITE_LOCK, 
174b0 31 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72  1);.    pWal->wr
174c0 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20  iteLock = 0;.   
174d0 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61 74 65 4f   pWal->truncateO
174e0 6e 43 6f 6d 6d 69 74 20 3d 20 30 3b 0a 20 20 7d  nCommit = 0;.  }
174f0 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
17500 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66  _OK;.}../*.** If
17510 20 61 6e 79 20 64 61 74 61 20 68 61 73 20 62 65   any data has be
17520 65 6e 20 77 72 69 74 74 65 6e 20 28 62 75 74 20  en written (but 
17530 6e 6f 74 20 63 6f 6d 6d 69 74 74 65 64 29 20 74  not committed) t
17540 6f 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2c 20  o the log file, 
17550 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e  this.** function
17560 20 6d 6f 76 65 73 20 74 68 65 20 77 72 69 74 65   moves the write
17570 2d 70 6f 69 6e 74 65 72 20 62 61 63 6b 20 74 6f  -pointer back to
17580 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
17590 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a  e transaction..*
175a0 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c 6c  *.** Additionall
175b0 79 2c 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20  y, the callback 
175c0 66 75 6e 63 74 69 6f 6e 20 69 73 20 69 6e 76 6f  function is invo
175d0 6b 65 64 20 66 6f 72 20 65 61 63 68 20 66 72 61  ked for each fra
175e0 6d 65 20 77 72 69 74 74 65 6e 0a 2a 2a 20 74 6f  me written.** to
175f0 20 74 68 65 20 57 41 4c 20 73 69 6e 63 65 20 74   the WAL since t
17600 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  he start of the 
17610 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 49 66 20  transaction. If 
17620 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 72 65 74  the callback ret
17630 75 72 6e 73 0a 2a 2a 20 6f 74 68 65 72 20 74 68  urns.** other th
17640 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 69 74  an SQLITE_OK, it
17650 20 69 73 20 6e 6f 74 20 69 6e 76 6f 6b 65 64 20   is not invoked 
17660 61 67 61 69 6e 20 61 6e 64 20 74 68 65 20 65 72  again and the er
17670 72 6f 72 20 63 6f 64 65 20 69 73 0a 2a 2a 20 72  ror code is.** r
17680 65 74 75 72 6e 65 64 20 74 6f 20 74 68 65 20 63  eturned to the c
17690 61 6c 6c 65 72 2e 0a 2a 2a 0a 2a 2a 20 4f 74 68  aller..**.** Oth
176a0 65 72 77 69 73 65 2c 20 69 66 20 74 68 65 20 63  erwise, if the c
176b0 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e  allback function
176c0 20 64 6f 65 73 20 6e 6f 74 20 72 65 74 75 72 6e   does not return
176d0 20 61 6e 20 65 72 72 6f 72 2c 20 74 68 69 73 0a   an error, this.
176e0 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75  ** function retu
176f0 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a  rns SQLITE_OK..*
17700 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c  /.int sqlite3Wal
17710 55 6e 64 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Undo(Wal *pWal, 
17720 69 6e 74 20 28 2a 78 55 6e 64 6f 29 28 76 6f 69  int (*xUndo)(voi
17730 64 20 2a 2c 20 50 67 6e 6f 29 2c 20 76 6f 69 64  d *, Pgno), void
17740 20 2a 70 55 6e 64 6f 43 74 78 29 7b 0a 20 20 69   *pUndoCtx){.  i
17750 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
17760 4b 3b 0a 20 20 69 66 28 20 41 4c 57 41 59 53 28  K;.  if( ALWAYS(
17770 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 29  pWal->writeLock)
17780 20 29 7b 0a 20 20 20 20 50 67 6e 6f 20 69 4d 61   ){.    Pgno iMa
17790 78 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  x = pWal->hdr.mx
177a0 46 72 61 6d 65 3b 0a 20 20 20 20 50 67 6e 6f 20  Frame;.    Pgno 
177b0 69 46 72 61 6d 65 3b 0a 20 20 0a 20 20 20 20 2f  iFrame;.  .    /
177c0 2a 20 52 65 73 74 6f 72 65 20 74 68 65 20 63 6c  * Restore the cl
177d0 69 65 6e 74 73 20 63 61 63 68 65 20 6f 66 20 74  ients cache of t
177e0 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
177f0 64 65 72 20 74 6f 20 74 68 65 20 73 74 61 74 65  der to the state
17800 20 69 74 0a 20 20 20 20 2a 2a 20 77 61 73 20 69   it.    ** was i
17810 6e 20 62 65 66 6f 72 65 20 74 68 65 20 63 6c 69  n before the cli
17820 65 6e 74 20 62 65 67 61 6e 20 77 72 69 74 69 6e  ent began writin
17830 67 20 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  g to the databas
17840 65 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d  e. .    */.    m
17850 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72  emcpy(&pWal->hdr
17860 2c 20 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64  , (void *)walInd
17870 65 78 48 64 72 28 70 57 61 6c 29 2c 20 73 69 7a  exHdr(pWal), siz
17880 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29  eof(WalIndexHdr)
17890 29 3b 0a 0a 20 20 20 20 66 6f 72 28 69 46 72 61  );..    for(iFra
178a0 6d 65 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  me=pWal->hdr.mxF
178b0 72 61 6d 65 2b 31 3b 20 0a 20 20 20 20 20 20 20  rame+1; .       
178c0 20 41 4c 57 41 59 53 28 72 63 3d 3d 53 51 4c 49   ALWAYS(rc==SQLI
178d0 54 45 5f 4f 4b 29 20 26 26 20 69 46 72 61 6d 65  TE_OK) && iFrame
178e0 3c 3d 69 4d 61 78 3b 20 0a 20 20 20 20 20 20 20  <=iMax; .       
178f0 20 69 46 72 61 6d 65 2b 2b 0a 20 20 20 20 29 7b   iFrame++.    ){
17900 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20 63  .      /* This c
17910 61 6c 6c 20 63 61 6e 6e 6f 74 20 66 61 69 6c 2e  all cannot fail.
17920 20 55 6e 6c 65 73 73 20 74 68 65 20 70 61 67 65   Unless the page
17930 20 66 6f 72 20 77 68 69 63 68 20 74 68 65 20 70   for which the p
17940 61 67 65 20 6e 75 6d 62 65 72 0a 20 20 20 20 20  age number.     
17950 20 2a 2a 20 69 73 20 70 61 73 73 65 64 20 61 73   ** is passed as
17960 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75   the second argu
17970 6d 65 6e 74 20 69 73 20 28 61 29 20 69 6e 20 74  ment is (a) in t
17980 68 65 20 63 61 63 68 65 20 61 6e 64 20 0a 20 20  he cache and .  
17990 20 20 20 20 2a 2a 20 28 62 29 20 68 61 73 20 61      ** (b) has a
179a0 6e 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 72 65  n outstanding re
179b0 66 65 72 65 6e 63 65 2c 20 74 68 65 6e 20 78 55  ference, then xU
179c0 6e 64 6f 20 69 73 20 65 69 74 68 65 72 20 61 20  ndo is either a 
179d0 6e 6f 2d 6f 70 0a 20 20 20 20 20 20 2a 2a 20 28  no-op.      ** (
179e0 69 66 20 28 61 29 20 69 73 20 66 61 6c 73 65 29  if (a) is false)
179f0 20 6f 72 20 73 69 6d 70 6c 79 20 65 78 70 65 6c   or simply expel
17a00 73 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20  s the page from 
17a10 74 68 65 20 63 61 63 68 65 20 28 69 66 20 28 62  the cache (if (b
17a20 29 0a 20 20 20 20 20 20 2a 2a 20 69 73 20 66 61  ).      ** is fa
17a30 6c 73 65 29 2e 0a 20 20 20 20 20 20 2a 2a 0a 20  lse)..      **. 
17a40 20 20 20 20 20 2a 2a 20 49 66 20 74 68 65 20 75       ** If the u
17a50 70 70 65 72 20 6c 61 79 65 72 20 69 73 20 64 6f  pper layer is do
17a60 69 6e 67 20 61 20 72 6f 6c 6c 62 61 63 6b 2c 20  ing a rollback, 
17a70 69 74 20 69 73 20 67 75 61 72 61 6e 74 65 65 64  it is guaranteed
17a80 20 74 68 61 74 20 74 68 65 72 65 0a 20 20 20 20   that there.    
17a90 20 20 2a 2a 20 61 72 65 20 6e 6f 20 6f 75 74 73    ** are no outs
17aa0 74 61 6e 64 69 6e 67 20 72 65 66 65 72 65 6e 63  tanding referenc
17ab0 65 73 20 74 6f 20 61 6e 79 20 70 61 67 65 20 6f  es to any page o
17ac0 74 68 65 72 20 74 68 61 6e 20 70 61 67 65 20 31  ther than page 1
17ad0 2e 20 41 6e 64 0a 20 20 20 20 20 20 2a 2a 20 70  . And.      ** p
17ae0 61 67 65 20 31 20 69 73 20 6e 65 76 65 72 20 77  age 1 is never w
17af0 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20 6c 6f  ritten to the lo
17b00 67 20 75 6e 74 69 6c 20 74 68 65 20 74 72 61 6e  g until the tran
17b10 73 61 63 74 69 6f 6e 20 69 73 0a 20 20 20 20 20  saction is.     
17b20 20 2a 2a 20 63 6f 6d 6d 69 74 74 65 64 2e 20 41   ** committed. A
17b30 73 20 61 20 72 65 73 75 6c 74 2c 20 74 68 65 20  s a result, the 
17b40 63 61 6c 6c 20 74 6f 20 78 55 6e 64 6f 20 6d 61  call to xUndo ma
17b50 79 20 6e 6f 74 20 66 61 69 6c 2e 0a 20 20 20 20  y not fail..    
17b60 20 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72    */.      asser
17b70 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28  t( walFramePgno(
17b80 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 21 3d 31  pWal, iFrame)!=1
17b90 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 78   );.      rc = x
17ba0 55 6e 64 6f 28 70 55 6e 64 6f 43 74 78 2c 20 77  Undo(pUndoCtx, w
17bb0 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c  alFramePgno(pWal
17bc0 2c 20 69 46 72 61 6d 65 29 29 3b 0a 20 20 20 20  , iFrame));.    
17bd0 7d 0a 20 20 20 20 69 66 28 20 69 4d 61 78 21 3d  }.    if( iMax!=
17be0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
17bf0 65 20 29 20 77 61 6c 43 6c 65 61 6e 75 70 48 61  e ) walCleanupHa
17c00 73 68 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20 20  sh(pWal);.  }.  
17c10 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49  assert( rc==SQLI
17c20 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74 75 72  TE_OK );.  retur
17c30 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  n rc;.}../* .** 
17c40 41 72 67 75 6d 65 6e 74 20 61 57 61 6c 44 61 74  Argument aWalDat
17c50 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f 20  a must point to 
17c60 61 6e 20 61 72 72 61 79 20 6f 66 20 57 41 4c 5f  an array of WAL_
17c70 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54 41 20  SAVEPOINT_NDATA 
17c80 75 33 32 20 0a 2a 2a 20 76 61 6c 75 65 73 2e 20  u32 .** values. 
17c90 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 70 6f  This function po
17ca0 70 75 6c 61 74 65 73 20 74 68 65 20 61 72 72 61  pulates the arra
17cb0 79 20 77 69 74 68 20 76 61 6c 75 65 73 20 72 65  y with values re
17cc0 71 75 69 72 65 64 20 74 6f 20 0a 2a 2a 20 22 72  quired to .** "r
17cd0 6f 6c 6c 62 61 63 6b 22 20 74 68 65 20 77 72 69  ollback" the wri
17ce0 74 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66 20 74  te position of t
17cf0 68 65 20 57 41 4c 20 68 61 6e 64 6c 65 20 62 61  he WAL handle ba
17d00 63 6b 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e  ck to the curren
17d10 74 20 0a 2a 2a 20 70 6f 69 6e 74 20 69 6e 20 74  t .** point in t
17d20 68 65 20 65 76 65 6e 74 20 6f 66 20 61 20 73 61  he event of a sa
17d30 76 65 70 6f 69 6e 74 20 72 6f 6c 6c 62 61 63 6b  vepoint rollback
17d40 20 28 76 69 61 20 57 61 6c 53 61 76 65 70 6f 69   (via WalSavepoi
17d50 6e 74 55 6e 64 6f 28 29 29 2e 0a 2a 2f 0a 76 6f  ntUndo())..*/.vo
17d60 69 64 20 73 71 6c 69 74 65 33 57 61 6c 53 61 76  id sqlite3WalSav
17d70 65 70 6f 69 6e 74 28 57 61 6c 20 2a 70 57 61 6c  epoint(Wal *pWal
17d80 2c 20 75 33 32 20 2a 61 57 61 6c 44 61 74 61 29  , u32 *aWalData)
17d90 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  {.  assert( pWal
17da0 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20  ->writeLock );. 
17db0 20 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d 20 70   aWalData[0] = p
17dc0 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
17dd0 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 31 5d 20  ;.  aWalData[1] 
17de0 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61  = pWal->hdr.aFra
17df0 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 61 57  meCksum[0];.  aW
17e00 61 6c 44 61 74 61 5b 32 5d 20 3d 20 70 57 61 6c  alData[2] = pWal
17e10 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
17e20 6d 5b 31 5d 3b 0a 20 20 61 57 61 6c 44 61 74 61  m[1];.  aWalData
17e30 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e 6e 43 6b 70  [3] = pWal->nCkp
17e40 74 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4d 6f 76  t;.}../* .** Mov
17e50 65 20 74 68 65 20 77 72 69 74 65 20 70 6f 73 69  e the write posi
17e60 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41 4c 20  tion of the WAL 
17e70 62 61 63 6b 20 74 6f 20 74 68 65 20 70 6f 69 6e  back to the poin
17e80 74 20 69 64 65 6e 74 69 66 69 65 64 20 62 79 0a  t identified by.
17e90 2a 2a 20 74 68 65 20 76 61 6c 75 65 73 20 69 6e  ** the values in
17ea0 20 74 68 65 20 61 57 61 6c 44 61 74 61 5b 5d 20   the aWalData[] 
17eb0 61 72 72 61 79 2e 20 61 57 61 6c 44 61 74 61 20  array. aWalData 
17ec0 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f 20 61 6e  must point to an
17ed0 20 61 72 72 61 79 0a 2a 2a 20 6f 66 20 57 41 4c   array.** of WAL
17ee0 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54 41  _SAVEPOINT_NDATA
17ef0 20 75 33 32 20 76 61 6c 75 65 73 20 74 68 61 74   u32 values that
17f00 20 68 61 73 20 62 65 65 6e 20 70 72 65 76 69 6f   has been previo
17f10 75 73 6c 79 20 70 6f 70 75 6c 61 74 65 64 0a 2a  usly populated.*
17f20 2a 20 62 79 20 61 20 63 61 6c 6c 20 74 6f 20 57  * by a call to W
17f30 61 6c 53 61 76 65 70 6f 69 6e 74 28 29 2e 0a 2a  alSavepoint()..*
17f40 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c  /.int sqlite3Wal
17f50 53 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28 57 61  SavepointUndo(Wa
17f60 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a 61 57  l *pWal, u32 *aW
17f70 61 6c 44 61 74 61 29 7b 0a 20 20 69 6e 74 20 72  alData){.  int r
17f80 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
17f90 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
17fa0 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 61  writeLock );.  a
17fb0 73 73 65 72 74 28 20 61 57 61 6c 44 61 74 61 5b  ssert( aWalData[
17fc0 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43 6b 70 74 20  3]!=pWal->nCkpt 
17fd0 7c 7c 20 61 57 61 6c 44 61 74 61 5b 30 5d 3c 3d  || aWalData[0]<=
17fe0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
17ff0 65 20 29 3b 0a 0a 20 20 69 66 28 20 61 57 61 6c  e );..  if( aWal
18000 44 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e  Data[3]!=pWal->n
18010 43 6b 70 74 20 29 7b 0a 20 20 20 20 2f 2a 20 54  Ckpt ){.    /* T
18020 68 69 73 20 73 61 76 65 70 6f 69 6e 74 20 77 61  his savepoint wa
18030 73 20 6f 70 65 6e 65 64 20 69 6d 6d 65 64 69 61  s opened immedia
18040 74 65 6c 79 20 61 66 74 65 72 20 74 68 65 20 77  tely after the w
18050 72 69 74 65 2d 74 72 61 6e 73 61 63 74 69 6f 6e  rite-transaction
18060 0a 20 20 20 20 2a 2a 20 77 61 73 20 73 74 61 72  .    ** was star
18070 74 65 64 2e 20 52 69 67 68 74 20 61 66 74 65 72  ted. Right after
18080 20 74 68 61 74 2c 20 74 68 65 20 77 72 69 74 65   that, the write
18090 72 20 64 65 63 69 64 65 64 20 74 6f 20 77 72 61  r decided to wra
180a0 70 20 61 72 6f 75 6e 64 0a 20 20 20 20 2a 2a 20  p around.    ** 
180b0 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  to the start of 
180c0 74 68 65 20 6c 6f 67 2e 20 55 70 64 61 74 65 20  the log. Update 
180d0 74 68 65 20 73 61 76 65 70 6f 69 6e 74 20 76 61  the savepoint va
180e0 6c 75 65 73 20 74 6f 20 6d 61 74 63 68 2e 0a 20  lues to match.. 
180f0 20 20 20 2a 2f 0a 20 20 20 20 61 57 61 6c 44 61     */.    aWalDa
18100 74 61 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20 61  ta[0] = 0;.    a
18110 57 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70 57 61  WalData[3] = pWa
18120 6c 2d 3e 6e 43 6b 70 74 3b 0a 20 20 7d 0a 0a 20  l->nCkpt;.  }.. 
18130 20 69 66 28 20 61 57 61 6c 44 61 74 61 5b 30 5d   if( aWalData[0]
18140 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  <pWal->hdr.mxFra
18150 6d 65 20 29 7b 0a 20 20 20 20 70 57 61 6c 2d 3e  me ){.    pWal->
18160 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20 61 57  hdr.mxFrame = aW
18170 61 6c 44 61 74 61 5b 30 5d 3b 0a 20 20 20 20 70  alData[0];.    p
18180 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
18190 6b 73 75 6d 5b 30 5d 20 3d 20 61 57 61 6c 44 61  ksum[0] = aWalDa
181a0 74 61 5b 31 5d 3b 0a 20 20 20 20 70 57 61 6c 2d  ta[1];.    pWal-
181b0 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
181c0 5b 31 5d 20 3d 20 61 57 61 6c 44 61 74 61 5b 32  [1] = aWalData[2
181d0 5d 3b 0a 20 20 20 20 77 61 6c 43 6c 65 61 6e 75  ];.    walCleanu
181e0 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 7d  pHash(pWal);.  }
181f0 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
18200 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  .../*.** This fu
18210 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
18220 20 6a 75 73 74 20 62 65 66 6f 72 65 20 77 72 69   just before wri
18230 74 69 6e 67 20 61 20 73 65 74 20 6f 66 20 66 72  ting a set of fr
18240 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67 0a  ames to the log.
18250 2a 2a 20 66 69 6c 65 20 28 73 65 65 20 73 71 6c  ** file (see sql
18260 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28 29 29  ite3WalFrames())
18270 2e 20 49 74 20 63 68 65 63 6b 73 20 74 6f 20 73  . It checks to s
18280 65 65 20 69 66 2c 20 69 6e 73 74 65 61 64 20 6f  ee if, instead o
18290 66 20 61 70 70 65 6e 64 69 6e 67 0a 2a 2a 20 74  f appending.** t
182a0 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c 6f  o the current lo
182b0 67 20 66 69 6c 65 2c 20 69 74 20 69 73 20 70 6f  g file, it is po
182c0 73 73 69 62 6c 65 20 74 6f 20 6f 76 65 72 77 72  ssible to overwr
182d0 69 74 65 20 74 68 65 20 73 74 61 72 74 20 6f 66  ite the start of
182e0 20 74 68 65 0a 2a 2a 20 65 78 69 73 74 69 6e 67   the.** existing
182f0 20 6c 6f 67 20 66 69 6c 65 20 77 69 74 68 20 74   log file with t
18300 68 65 20 6e 65 77 20 66 72 61 6d 65 73 20 28 69  he new frames (i
18310 2e 65 2e 20 22 72 65 73 65 74 22 20 74 68 65 20  .e. "reset" the 
18320 6c 6f 67 29 2e 20 49 66 20 73 6f 2c 0a 2a 2a 20  log). If so,.** 
18330 69 74 20 73 65 74 73 20 70 57 61 6c 2d 3e 68 64  it sets pWal->hd
18340 72 2e 6d 78 46 72 61 6d 65 20 74 6f 20 30 2e 20  r.mxFrame to 0. 
18350 4f 74 68 65 72 77 69 73 65 2c 20 70 57 61 6c 2d  Otherwise, pWal-
18360 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20  >hdr.mxFrame is 
18370 6c 65 66 74 0a 2a 2a 20 75 6e 63 68 61 6e 67 65  left.** unchange
18380 64 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f  d..**.** SQLITE_
18390 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 69  OK is returned i
183a0 66 20 6e 6f 20 65 72 72 6f 72 20 69 73 20 65 6e  f no error is en
183b0 63 6f 75 6e 74 65 72 65 64 20 28 72 65 67 61 72  countered (regar
183c0 64 6c 65 73 73 20 6f 66 20 77 68 65 74 68 65 72  dless of whether
183d0 0a 2a 2a 20 6f 72 20 6e 6f 74 20 70 57 61 6c 2d  .** or not pWal-
183e0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20  >hdr.mxFrame is 
183f0 6d 6f 64 69 66 69 65 64 29 2e 20 41 6e 20 53 51  modified). An SQ
18400 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20  Lite error code 
18410 69 73 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69  is returned.** i
18420 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
18430 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
18440 20 77 61 6c 52 65 73 74 61 72 74 4c 6f 67 28 57   walRestartLog(W
18450 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74  al *pWal){.  int
18460 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
18470 0a 20 20 69 6e 74 20 63 6e 74 3b 0a 0a 20 20 69  .  int cnt;..  i
18480 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  f( pWal->readLoc
18490 6b 3d 3d 30 20 29 7b 0a 20 20 20 20 76 6f 6c 61  k==0 ){.    vola
184a0 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f  tile WalCkptInfo
184b0 20 2a 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70   *pInfo = walCkp
184c0 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20  tInfo(pWal);.   
184d0 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e   assert( pInfo->
184e0 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70 57 61 6c 2d  nBackfill==pWal-
184f0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a  >hdr.mxFrame );.
18500 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e      if( pInfo->n
18510 42 61 63 6b 66 69 6c 6c 3e 30 20 29 7b 0a 20 20  Backfill>0 ){.  
18520 20 20 20 20 75 33 32 20 73 61 6c 74 31 3b 0a 20      u32 salt1;. 
18530 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 61 6e       sqlite3_ran
18540 64 6f 6d 6e 65 73 73 28 34 2c 20 26 73 61 6c 74  domness(4, &salt
18550 31 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 77  1);.      rc = w
18560 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  alLockExclusive(
18570 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  pWal, WAL_READ_L
18580 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41  OCK(1), WAL_NREA
18590 44 45 52 2d 31 29 3b 0a 20 20 20 20 20 20 69 66  DER-1);.      if
185a0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
185b0 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49 66  ){.        /* If
185c0 20 61 6c 6c 20 72 65 61 64 65 72 73 20 61 72 65   all readers are
185d0 20 75 73 69 6e 67 20 57 41 4c 5f 52 45 41 44 5f   using WAL_READ_
185e0 4c 4f 43 4b 28 30 29 20 28 69 6e 20 6f 74 68 65  LOCK(0) (in othe
185f0 72 20 77 6f 72 64 73 20 69 66 20 6e 6f 0a 20 20  r words if no.  
18600 20 20 20 20 20 20 2a 2a 20 72 65 61 64 65 72 73        ** readers
18610 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20 75   are currently u
18620 73 69 6e 67 20 74 68 65 20 57 41 4c 29 2c 20 74  sing the WAL), t
18630 68 65 6e 20 74 68 65 20 74 72 61 6e 73 61 63 74  hen the transact
18640 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 2a 2a 20  ions.        ** 
18650 66 72 61 6d 65 73 20 77 69 6c 6c 20 6f 76 65 72  frames will over
18660 77 72 69 74 65 20 74 68 65 20 73 74 61 72 74 20  write the start 
18670 6f 66 20 74 68 65 20 65 78 69 73 74 69 6e 67 20  of the existing 
18680 6c 6f 67 2e 20 55 70 64 61 74 65 20 74 68 65 0a  log. Update the.
18690 20 20 20 20 20 20 20 20 2a 2a 20 77 61 6c 2d 69          ** wal-i
186a0 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f 20 72  ndex header to r
186b0 65 66 6c 65 63 74 20 74 68 69 73 2e 0a 20 20 20  eflect this..   
186c0 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20       **.        
186d0 2a 2a 20 49 6e 20 74 68 65 6f 72 79 20 69 74 20  ** In theory it 
186e0 77 6f 75 6c 64 20 62 65 20 4f 6b 20 74 6f 20 75  would be Ok to u
186f0 70 64 61 74 65 20 74 68 65 20 63 61 63 68 65 20  pdate the cache 
18700 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 6f 6e  of the header on
18710 6c 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 74  ly.        ** at
18720 20 74 68 69 73 20 70 6f 69 6e 74 2e 20 42 75 74   this point. But
18730 20 75 70 64 61 74 69 6e 67 20 74 68 65 20 61 63   updating the ac
18740 74 75 61 6c 20 77 61 6c 2d 69 6e 64 65 78 20 68  tual wal-index h
18750 65 61 64 65 72 20 69 73 20 61 6c 73 6f 0a 20 20  eader is also.  
18760 20 20 20 20 20 20 2a 2a 20 73 61 66 65 20 61 6e        ** safe an
18770 64 20 6d 65 61 6e 73 20 74 68 65 72 65 20 69 73  d means there is
18780 20 6e 6f 20 73 70 65 63 69 61 6c 20 63 61 73 65   no special case
18790 20 66 6f 72 20 73 71 6c 69 74 65 33 57 61 6c 55   for sqlite3WalU
187a0 6e 64 6f 28 29 0a 20 20 20 20 20 20 20 20 2a 2a  ndo().        **
187b0 20 74 6f 20 68 61 6e 64 6c 65 20 69 66 20 74 68   to handle if th
187c0 69 73 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69  is transaction i
187d0 73 20 72 6f 6c 6c 65 64 20 62 61 63 6b 2e 0a 20  s rolled back.. 
187e0 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20         */.      
187f0 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
18800 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
18810 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20  oop counter */. 
18820 20 20 20 20 20 20 20 75 33 32 20 2a 61 53 61 6c         u32 *aSal
18830 74 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53  t = pWal->hdr.aS
18840 61 6c 74 3b 20 20 20 20 20 20 20 2f 2a 20 42 69  alt;       /* Bi
18850 67 2d 65 6e 64 69 61 6e 20 73 61 6c 74 20 76 61  g-endian salt va
18860 6c 75 65 73 20 2a 2f 0a 0a 20 20 20 20 20 20 20  lues */..       
18870 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 2b 2b 3b 0a   pWal->nCkpt++;.
18880 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64          pWal->hd
18890 72 2e 6d 78 46 72 61 6d 65 20 3d 20 30 3b 0a 20  r.mxFrame = 0;. 
188a0 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 50 75         sqlite3Pu
188b0 74 34 62 79 74 65 28 28 75 38 2a 29 26 61 53 61  t4byte((u8*)&aSa
188c0 6c 74 5b 30 5d 2c 20 31 20 2b 20 73 71 6c 69 74  lt[0], 1 + sqlit
188d0 65 33 47 65 74 34 62 79 74 65 28 28 75 38 2a 29  e3Get4byte((u8*)
188e0 26 61 53 61 6c 74 5b 30 5d 29 29 3b 0a 20 20 20  &aSalt[0]));.   
188f0 20 20 20 20 20 61 53 61 6c 74 5b 31 5d 20 3d 20       aSalt[1] = 
18900 73 61 6c 74 31 3b 0a 20 20 20 20 20 20 20 20 77  salt1;.        w
18910 61 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72 28  alIndexWriteHdr(
18920 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 70  pWal);.        p
18930 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 20  Info->nBackfill 
18940 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 70 49 6e  = 0;.        pIn
18950 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 31 5d  fo->aReadMark[1]
18960 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 66 6f   = 0;.        fo
18970 72 28 69 3d 32 3b 20 69 3c 57 41 4c 5f 4e 52 45  r(i=2; i<WAL_NRE
18980 41 44 45 52 3b 20 69 2b 2b 29 20 70 49 6e 66 6f  ADER; i++) pInfo
18990 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d  ->aReadMark[i] =
189a0 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53   READMARK_NOT_US
189b0 45 44 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65  ED;.        asse
189c0 72 74 28 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64  rt( pInfo->aRead
189d0 4d 61 72 6b 5b 30 5d 3d 3d 30 20 29 3b 0a 20 20  Mark[0]==0 );.  
189e0 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45        walUnlockE
189f0 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
18a00 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c  AL_READ_LOCK(1),
18a10 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b   WAL_NREADER-1);
18a20 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
18a30 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc!=SQLITE_BUSY
18a40 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75   ){.        retu
18a50 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20  rn rc;.      }. 
18a60 20 20 20 7d 0a 20 20 20 20 77 61 6c 55 6e 6c 6f     }.    walUnlo
18a70 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
18a80 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29  AL_READ_LOCK(0))
18a90 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64  ;.    pWal->read
18aa0 4c 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20 20 20 63  Lock = -1;.    c
18ab0 6e 74 20 3d 20 30 3b 0a 20 20 20 20 64 6f 7b 0a  nt = 0;.    do{.
18ac0 20 20 20 20 20 20 69 6e 74 20 6e 6f 74 55 73 65        int notUse
18ad0 64 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61  d;.      rc = wa
18ae0 6c 54 72 79 42 65 67 69 6e 52 65 61 64 28 70 57  lTryBeginRead(pW
18af0 61 6c 2c 20 26 6e 6f 74 55 73 65 64 2c 20 31 2c  al, &notUsed, 1,
18b00 20 2b 2b 63 6e 74 29 3b 0a 20 20 20 20 7d 77 68   ++cnt);.    }wh
18b10 69 6c 65 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54  ile( rc==WAL_RET
18b20 52 59 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  RY );.    assert
18b30 28 20 28 72 63 26 30 78 66 66 29 21 3d 53 51 4c  ( (rc&0xff)!=SQL
18b40 49 54 45 5f 42 55 53 59 20 29 3b 20 2f 2a 20 42  ITE_BUSY ); /* B
18b50 55 53 59 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65  USY not possible
18b60 20 77 68 65 6e 20 75 73 65 57 61 6c 3d 3d 31 20   when useWal==1 
18b70 2a 2f 0a 20 20 20 20 74 65 73 74 63 61 73 65 28  */.    testcase(
18b80 20 28 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49   (rc&0xff)==SQLI
18b90 54 45 5f 49 4f 45 52 52 20 29 3b 0a 20 20 20 20  TE_IOERR );.    
18ba0 74 65 73 74 63 61 73 65 28 20 72 63 3d 3d 53 51  testcase( rc==SQ
18bb0 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 20 29 3b  LITE_PROTOCOL );
18bc0 0a 20 20 20 20 74 65 73 74 63 61 73 65 28 20 72  .    testcase( r
18bd0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c==SQLITE_OK );.
18be0 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
18bf0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 66 6f 72 6d  .}../*.** Inform
18c00 61 74 69 6f 6e 20 61 62 6f 75 74 20 74 68 65 20  ation about the 
18c10 63 75 72 72 65 6e 74 20 73 74 61 74 65 20 6f 66  current state of
18c20 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20 61 6e   the WAL file an
18c30 64 20 77 68 65 72 65 0a 2a 2a 20 74 68 65 20 6e  d where.** the n
18c40 65 78 74 20 66 73 79 6e 63 20 73 68 6f 75 6c 64  ext fsync should
18c50 20 6f 63 63 75 72 20 2d 20 70 61 73 73 65 64 20   occur - passed 
18c60 66 72 6f 6d 20 73 71 6c 69 74 65 33 57 61 6c 46  from sqlite3WalF
18c70 72 61 6d 65 73 28 29 20 69 6e 74 6f 0a 2a 2a 20  rames() into.** 
18c80 77 61 6c 57 72 69 74 65 54 6f 4c 6f 67 28 29 2e  walWriteToLog().
18c90 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75  .*/.typedef stru
18ca0 63 74 20 57 61 6c 57 72 69 74 65 72 20 7b 0a 20  ct WalWriter {. 
18cb0 20 57 61 6c 20 2a 70 57 61 6c 3b 20 20 20 20 20   Wal *pWal;     
18cc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
18cd0 20 54 68 65 20 63 6f 6d 70 6c 65 74 65 20 57 41   The complete WA
18ce0 4c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 2a 2f  L information */
18cf0 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
18d00 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20 20 20  *pFd;           
18d10 2f 2a 20 54 68 65 20 57 41 4c 20 66 69 6c 65 20  /* The WAL file 
18d20 74 6f 20 77 68 69 63 68 20 77 65 20 77 72 69 74  to which we writ
18d30 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69  e */.  sqlite3_i
18d40 6e 74 36 34 20 69 53 79 6e 63 50 6f 69 6e 74 3b  nt64 iSyncPoint;
18d50 20 20 20 20 2f 2a 20 46 73 79 6e 63 20 61 74 20      /* Fsync at 
18d60 74 68 69 73 20 6f 66 66 73 65 74 20 2a 2f 0a 20  this offset */. 
18d70 20 69 6e 74 20 73 79 6e 63 46 6c 61 67 73 3b 20   int syncFlags; 
18d80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
18d90 20 46 6c 61 67 73 20 66 6f 72 20 74 68 65 20 66   Flags for the f
18da0 73 79 6e 63 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  sync */.  int sz
18db0 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  Page;           
18dc0 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
18dd0 66 20 6f 6e 65 20 70 61 67 65 20 2a 2f 0a 7d 20  f one page */.} 
18de0 57 61 6c 57 72 69 74 65 72 3b 0a 0a 2f 2a 0a 2a  WalWriter;../*.*
18df0 2a 20 57 72 69 74 65 20 69 41 6d 74 20 62 79 74  * Write iAmt byt
18e00 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74 20 69 6e  es of content in
18e10 74 6f 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20  to the WAL file 
18e20 62 65 67 69 6e 6e 69 6e 67 20 61 74 20 69 4f 66  beginning at iOf
18e30 66 73 65 74 2e 0a 2a 2a 20 44 6f 20 61 20 73 79  fset..** Do a sy
18e40 6e 63 20 77 68 65 6e 20 63 72 6f 73 73 69 6e 67  nc when crossing
18e50 20 74 68 65 20 70 2d 3e 69 53 79 6e 63 50 6f 69   the p->iSyncPoi
18e60 6e 74 20 62 6f 75 6e 64 61 72 79 2e 0a 2a 2a 0a  nt boundary..**.
18e70 2a 2a 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64  ** In other word
18e80 73 2c 20 69 66 20 69 53 79 6e 63 50 6f 69 6e 74  s, if iSyncPoint
18e90 20 69 73 20 69 6e 20 62 65 74 77 65 65 6e 20 69   is in between i
18ea0 4f 66 66 73 65 74 20 61 6e 64 20 69 4f 66 66 73  Offset and iOffs
18eb0 65 74 2b 69 41 6d 74 2c 0a 2a 2a 20 66 69 72 73  et+iAmt,.** firs
18ec0 74 20 77 72 69 74 65 20 74 68 65 20 70 61 72 74  t write the part
18ed0 20 62 65 66 6f 72 65 20 69 53 79 6e 63 50 6f 69   before iSyncPoi
18ee0 6e 74 2c 20 74 68 65 6e 20 73 79 6e 63 2c 20 74  nt, then sync, t
18ef0 68 65 6e 20 77 72 69 74 65 20 74 68 65 0a 2a 2a  hen write the.**
18f00 20 72 65 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63   rest..*/.static
18f10 20 69 6e 74 20 77 61 6c 57 72 69 74 65 54 6f 4c   int walWriteToL
18f20 6f 67 28 0a 20 20 57 61 6c 57 72 69 74 65 72 20  og(.  WalWriter 
18f30 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  *p,             
18f40 20 2f 2a 20 57 41 4c 20 74 6f 20 77 72 69 74 65   /* WAL to write
18f50 20 74 6f 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70   to */.  void *p
18f60 43 6f 6e 74 65 6e 74 2c 20 20 20 20 20 20 20 20  Content,        
18f70 20 20 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 74      /* Content t
18f80 6f 20 62 65 20 77 72 69 74 74 65 6e 20 2a 2f 0a  o be written */.
18f90 20 20 69 6e 74 20 69 41 6d 74 2c 20 20 20 20 20    int iAmt,     
18fa0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
18fb0 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
18fc0 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 73 71  to write */.  sq
18fd0 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 66  lite3_int64 iOff
18fe0 73 65 74 20 20 20 20 20 20 2f 2a 20 53 74 61 72  set      /* Star
18ff0 74 20 77 72 69 74 69 6e 67 20 61 74 20 74 68 69  t writing at thi
19000 73 20 6f 66 66 73 65 74 20 2a 2f 0a 29 7b 0a 20  s offset */.){. 
19010 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 69   int rc;.  if( i
19020 4f 66 66 73 65 74 3c 70 2d 3e 69 53 79 6e 63 50  Offset<p->iSyncP
19030 6f 69 6e 74 20 26 26 20 69 4f 66 66 73 65 74 2b  oint && iOffset+
19040 69 41 6d 74 3e 3d 70 2d 3e 69 53 79 6e 63 50 6f  iAmt>=p->iSyncPo
19050 69 6e 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  int ){.    int i
19060 46 69 72 73 74 41 6d 74 20 3d 20 28 69 6e 74 29  FirstAmt = (int)
19070 28 70 2d 3e 69 53 79 6e 63 50 6f 69 6e 74 20 2d  (p->iSyncPoint -
19080 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 72   iOffset);.    r
19090 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69  c = sqlite3OsWri
190a0 74 65 28 70 2d 3e 70 46 64 2c 20 70 43 6f 6e 74  te(p->pFd, pCont
190b0 65 6e 74 2c 20 69 46 69 72 73 74 41 6d 74 2c 20  ent, iFirstAmt, 
190c0 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 69 66  iOffset);.    if
190d0 28 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63  ( rc ) return rc
190e0 3b 0a 20 20 20 20 69 4f 66 66 73 65 74 20 2b 3d  ;.    iOffset +=
190f0 20 69 46 69 72 73 74 41 6d 74 3b 0a 20 20 20 20   iFirstAmt;.    
19100 69 41 6d 74 20 2d 3d 20 69 46 69 72 73 74 41 6d  iAmt -= iFirstAm
19110 74 3b 0a 20 20 20 20 70 43 6f 6e 74 65 6e 74 20  t;.    pContent 
19120 3d 20 28 76 6f 69 64 2a 29 28 69 46 69 72 73 74  = (void*)(iFirst
19130 41 6d 74 20 2b 20 28 63 68 61 72 2a 29 70 43 6f  Amt + (char*)pCo
19140 6e 74 65 6e 74 29 3b 0a 20 20 20 20 61 73 73 65  ntent);.    asse
19150 72 74 28 20 70 2d 3e 73 79 6e 63 46 6c 61 67 73  rt( p->syncFlags
19160 20 26 20 28 53 51 4c 49 54 45 5f 53 59 4e 43 5f   & (SQLITE_SYNC_
19170 4e 4f 52 4d 41 4c 7c 53 51 4c 49 54 45 5f 53 59  NORMAL|SQLITE_SY
19180 4e 43 5f 46 55 4c 4c 29 20 29 3b 0a 20 20 20 20  NC_FULL) );.    
19190 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79  rc = sqlite3OsSy
191a0 6e 63 28 70 2d 3e 70 46 64 2c 20 70 2d 3e 73 79  nc(p->pFd, p->sy
191b0 6e 63 46 6c 61 67 73 29 3b 0a 20 20 20 20 69 66  ncFlags);.    if
191c0 28 20 69 41 6d 74 3d 3d 30 20 7c 7c 20 72 63 20  ( iAmt==0 || rc 
191d0 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d  ) return rc;.  }
191e0 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  .  rc = sqlite3O
191f0 73 57 72 69 74 65 28 70 2d 3e 70 46 64 2c 20 70  sWrite(p->pFd, p
19200 43 6f 6e 74 65 6e 74 2c 20 69 41 6d 74 2c 20 69  Content, iAmt, i
19210 4f 66 66 73 65 74 29 3b 0a 20 20 72 65 74 75 72  Offset);.  retur
19220 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  n rc;.}../*.** W
19230 72 69 74 65 20 6f 75 74 20 61 20 73 69 6e 67 6c  rite out a singl
19240 65 20 66 72 61 6d 65 20 6f 66 20 74 68 65 20 57  e frame of the W
19250 41 4c 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  AL.*/.static int
19260 20 77 61 6c 57 72 69 74 65 4f 6e 65 46 72 61 6d   walWriteOneFram
19270 65 28 0a 20 20 57 61 6c 57 72 69 74 65 72 20 2a  e(.  WalWriter *
19280 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p,              
19290 20 2f 2a 20 57 68 65 72 65 20 74 6f 20 77 72 69   /* Where to wri
192a0 74 65 20 74 68 65 20 66 72 61 6d 65 20 2a 2f 0a  te the frame */.
192b0 20 20 50 67 48 64 72 20 2a 70 50 61 67 65 2c 20    PgHdr *pPage, 
192c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
192d0 20 54 68 65 20 70 61 67 65 20 6f 66 20 74 68 65   The page of the
192e0 20 66 72 61 6d 65 20 74 6f 20 62 65 20 77 72 69   frame to be wri
192f0 74 74 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 6e 54  tten */.  int nT
19300 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20  runcate,        
19310 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63 6f 6d        /* The com
19320 6d 69 74 20 66 6c 61 67 2e 20 20 55 73 75 61 6c  mit flag.  Usual
19330 6c 79 20 30 2e 20 20 3e 30 20 66 6f 72 20 63 6f  ly 0.  >0 for co
19340 6d 6d 69 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65  mmit */.  sqlite
19350 33 5f 69 6e 74 36 34 20 69 4f 66 66 73 65 74 20  3_int64 iOffset 
19360 20 20 20 20 20 20 2f 2a 20 42 79 74 65 20 6f 66        /* Byte of
19370 66 73 65 74 20 61 74 20 77 68 69 63 68 20 74 6f  fset at which to
19380 20 77 72 69 74 65 20 2a 2f 0a 29 7b 0a 20 20 69   write */.){.  i
19390 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
193a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
193b0 2a 20 52 65 73 75 6c 74 20 63 6f 64 65 20 66 72  * Result code fr
193c0 6f 6d 20 73 75 62 66 75 6e 63 74 69 6f 6e 73 20  om subfunctions 
193d0 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 44 61 74 61  */.  void *pData
193e0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
193f0 20 20 20 20 20 2f 2a 20 44 61 74 61 20 61 63 74       /* Data act
19400 75 61 6c 6c 79 20 77 72 69 74 74 65 6e 20 2a 2f  ually written */
19410 0a 20 20 75 38 20 61 46 72 61 6d 65 5b 57 41 4c  .  u8 aFrame[WAL
19420 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 5d 3b  _FRAME_HDRSIZE];
19430 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20     /* Buffer to 
19440 61 73 73 65 6d 62 6c 65 20 66 72 61 6d 65 2d 68  assemble frame-h
19450 65 61 64 65 72 20 69 6e 20 2a 2f 0a 23 69 66 20  eader in */.#if 
19460 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 48  defined(SQLITE_H
19470 41 53 5f 43 4f 44 45 43 29 0a 20 20 69 66 28 20  AS_CODEC).  if( 
19480 28 70 44 61 74 61 20 3d 20 73 71 6c 69 74 65 33  (pData = sqlite3
19490 50 61 67 65 72 43 6f 64 65 63 28 70 50 61 67 65  PagerCodec(pPage
194a0 29 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  ))==0 ) return S
194b0 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 23 65 6c  QLITE_NOMEM;.#el
194c0 73 65 0a 20 20 70 44 61 74 61 20 3d 20 70 50 61  se.  pData = pPa
194d0 67 65 2d 3e 70 44 61 74 61 3b 0a 23 65 6e 64 69  ge->pData;.#endi
194e0 66 0a 20 20 77 61 6c 45 6e 63 6f 64 65 46 72 61  f.  walEncodeFra
194f0 6d 65 28 70 2d 3e 70 57 61 6c 2c 20 70 50 61 67  me(p->pWal, pPag
19500 65 2d 3e 70 67 6e 6f 2c 20 6e 54 72 75 6e 63 61  e->pgno, nTrunca
19510 74 65 2c 20 70 44 61 74 61 2c 20 61 46 72 61 6d  te, pData, aFram
19520 65 29 3b 0a 20 20 72 63 20 3d 20 77 61 6c 57 72  e);.  rc = walWr
19530 69 74 65 54 6f 4c 6f 67 28 70 2c 20 61 46 72 61  iteToLog(p, aFra
19540 6d 65 2c 20 73 69 7a 65 6f 66 28 61 46 72 61 6d  me, sizeof(aFram
19550 65 29 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  e), iOffset);.  
19560 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e 20  if( rc ) return 
19570 72 63 3b 0a 20 20 2f 2a 20 57 72 69 74 65 20 74  rc;.  /* Write t
19580 68 65 20 70 61 67 65 20 64 61 74 61 20 2a 2f 0a  he page data */.
19590 20 20 72 63 20 3d 20 77 61 6c 57 72 69 74 65 54    rc = walWriteT
195a0 6f 4c 6f 67 28 70 2c 20 70 44 61 74 61 2c 20 70  oLog(p, pData, p
195b0 2d 3e 73 7a 50 61 67 65 2c 20 69 4f 66 66 73 65  ->szPage, iOffse
195c0 74 2b 73 69 7a 65 6f 66 28 61 46 72 61 6d 65 29  t+sizeof(aFrame)
195d0 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
195e0 7d 0a 0a 2f 2a 20 0a 2a 2a 20 57 72 69 74 65 20  }../* .** Write 
195f0 61 20 73 65 74 20 6f 66 20 66 72 61 6d 65 73 20  a set of frames 
19600 74 6f 20 74 68 65 20 6c 6f 67 2e 20 54 68 65 20  to the log. The 
19610 63 61 6c 6c 65 72 20 6d 75 73 74 20 68 6f 6c 64  caller must hold
19620 20 74 68 65 20 77 72 69 74 65 2d 6c 6f 63 6b 0a   the write-lock.
19630 2a 2a 20 6f 6e 20 74 68 65 20 6c 6f 67 20 66 69  ** on the log fi
19640 6c 65 20 28 6f 62 74 61 69 6e 65 64 20 75 73 69  le (obtained usi
19650 6e 67 20 73 71 6c 69 74 65 33 57 61 6c 42 65 67  ng sqlite3WalBeg
19660 69 6e 57 72 69 74 65 54 72 61 6e 73 61 63 74 69  inWriteTransacti
19670 6f 6e 28 29 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71  on())..*/.int sq
19680 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28 0a  lite3WalFrames(.
19690 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
196a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
196b0 20 20 2f 2a 20 57 61 6c 20 68 61 6e 64 6c 65 20    /* Wal handle 
196c0 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20  to write to */. 
196d0 20 69 6e 74 20 73 7a 50 61 67 65 2c 20 20 20 20   int szPage,    
196e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
196f0 20 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67   /* Database pag
19700 65 2d 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20  e-size in bytes 
19710 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 4c 69 73  */.  PgHdr *pLis
19720 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
19730 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20       /* List of 
19740 64 69 72 74 79 20 70 61 67 65 73 20 74 6f 20 77  dirty pages to w
19750 72 69 74 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 6e  rite */.  Pgno n
19760 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20  Truncate,       
19770 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
19780 61 62 61 73 65 20 73 69 7a 65 20 61 66 74 65 72  abase size after
19790 20 74 68 69 73 20 63 6f 6d 6d 69 74 20 2a 2f 0a   this commit */.
197a0 20 20 69 6e 74 20 69 73 43 6f 6d 6d 69 74 2c 20    int isCommit, 
197b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
197c0 20 20 2f 2a 20 54 72 75 65 20 69 66 20 74 68 69    /* True if thi
197d0 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 20 2a 2f  s is a commit */
197e0 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67  .  int sync_flag
197f0 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s               
19800 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20 70     /* Flags to p
19810 61 73 73 20 74 6f 20 4f 73 53 79 6e 63 28 29 20  ass to OsSync() 
19820 28 6f 72 20 30 29 20 2a 2f 0a 29 7b 0a 20 20 69  (or 0) */.){.  i
19830 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
19840 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
19850 2a 20 55 73 65 64 20 74 6f 20 63 61 74 63 68 20  * Used to catch 
19860 72 65 74 75 72 6e 20 63 6f 64 65 73 20 2a 2f 0a  return codes */.
19870 20 20 75 33 32 20 69 46 72 61 6d 65 3b 20 20 20    u32 iFrame;   
19880 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19890 20 20 2f 2a 20 4e 65 78 74 20 66 72 61 6d 65 20    /* Next frame 
198a0 61 64 64 72 65 73 73 20 2a 2f 0a 20 20 50 67 48  address */.  PgH
198b0 64 72 20 2a 70 3b 20 20 20 20 20 20 20 20 20 20  dr *p;          
198c0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
198d0 49 74 65 72 61 74 6f 72 20 74 6f 20 72 75 6e 20  Iterator to run 
198e0 74 68 72 6f 75 67 68 20 70 4c 69 73 74 20 77 69  through pList wi
198f0 74 68 2e 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a  th. */.  PgHdr *
19900 70 4c 61 73 74 20 3d 20 30 3b 20 20 20 20 20 20  pLast = 0;      
19910 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73 74           /* Last
19920 20 66 72 61 6d 65 20 69 6e 20 6c 69 73 74 20 2a   frame in list *
19930 2f 0a 20 20 69 6e 74 20 6e 45 78 74 72 61 20 3d  /.  int nExtra =
19940 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
19950 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
19960 20 65 78 74 72 61 20 63 6f 70 69 65 73 20 6f 66   extra copies of
19970 20 6c 61 73 74 20 70 61 67 65 20 2a 2f 0a 20 20   last page */.  
19980 69 6e 74 20 73 7a 46 72 61 6d 65 3b 20 20 20 20  int szFrame;    
19990 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
199a0 2f 2a 20 54 68 65 20 73 69 7a 65 20 6f 66 20 61  /* The size of a
199b0 20 73 69 6e 67 6c 65 20 66 72 61 6d 65 20 2a 2f   single frame */
199c0 0a 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 20  .  i64 iOffset; 
199d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
199e0 20 20 20 2f 2a 20 4e 65 78 74 20 62 79 74 65 20     /* Next byte 
199f0 74 6f 20 77 72 69 74 65 20 69 6e 20 57 41 4c 20  to write in WAL 
19a00 66 69 6c 65 20 2a 2f 0a 20 20 57 61 6c 57 72 69  file */.  WalWri
19a10 74 65 72 20 77 3b 20 20 20 20 20 20 20 20 20 20  ter w;          
19a20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
19a30 20 77 72 69 74 65 72 20 2a 2f 0a 0a 20 20 61 73   writer */..  as
19a40 73 65 72 74 28 20 70 4c 69 73 74 20 29 3b 0a 20  sert( pList );. 
19a50 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77   assert( pWal->w
19a60 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 0a 20 20 2f  riteLock );..  /
19a70 2a 20 49 66 20 74 68 69 73 20 66 72 61 6d 65 20  * If this frame 
19a80 73 65 74 20 63 6f 6d 70 6c 65 74 65 73 20 61 20  set completes a 
19a90 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20 74 68 65  transaction, the
19aa0 6e 20 6e 54 72 75 6e 63 61 74 65 3e 30 2e 20 20  n nTruncate>0.  
19ab0 49 66 0a 20 20 2a 2a 20 6e 54 72 75 6e 63 61 74  If.  ** nTruncat
19ac0 65 3d 3d 30 20 74 68 65 6e 20 74 68 69 73 20 66  e==0 then this f
19ad0 72 61 6d 65 20 73 65 74 20 64 6f 65 73 20 6e 6f  rame set does no
19ae0 74 20 63 6f 6d 70 6c 65 74 65 20 74 68 65 20 74  t complete the t
19af0 72 61 6e 73 61 63 74 69 6f 6e 2e 20 2a 2f 0a 20  ransaction. */. 
19b00 20 61 73 73 65 72 74 28 20 28 69 73 43 6f 6d 6d   assert( (isComm
19b10 69 74 21 3d 30 29 3d 3d 28 6e 54 72 75 6e 63 61  it!=0)==(nTrunca
19b20 74 65 21 3d 30 29 20 29 3b 0a 0a 23 69 66 20 64  te!=0) );..#if d
19b30 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54 45  efined(SQLITE_TE
19b40 53 54 29 20 26 26 20 64 65 66 69 6e 65 64 28 53  ST) && defined(S
19b50 51 4c 49 54 45 5f 44 45 42 55 47 29 0a 20 20 7b  QLITE_DEBUG).  {
19b60 20 69 6e 74 20 63 6e 74 3b 20 66 6f 72 28 63 6e   int cnt; for(cn
19b70 74 3d 30 2c 20 70 3d 70 4c 69 73 74 3b 20 70 3b  t=0, p=pList; p;
19b80 20 70 3d 70 2d 3e 70 44 69 72 74 79 2c 20 63 6e   p=p->pDirty, cn
19b90 74 2b 2b 29 7b 7d 0a 20 20 20 20 57 41 4c 54 52  t++){}.    WALTR
19ba0 41 43 45 28 28 22 57 41 4c 25 70 3a 20 66 72 61  ACE(("WAL%p: fra
19bb0 6d 65 20 77 72 69 74 65 20 62 65 67 69 6e 2e 20  me write begin. 
19bc0 25 64 20 66 72 61 6d 65 73 2e 20 6d 78 46 72 61  %d frames. mxFra
19bd0 6d 65 3d 25 64 2e 20 25 73 5c 6e 22 2c 0a 20 20  me=%d. %s\n",.  
19be0 20 20 20 20 20 20 20 20 20 20 20 20 70 57 61 6c              pWal
19bf0 2c 20 63 6e 74 2c 20 70 57 61 6c 2d 3e 68 64 72  , cnt, pWal->hdr
19c00 2e 6d 78 46 72 61 6d 65 2c 20 69 73 43 6f 6d 6d  .mxFrame, isComm
19c10 69 74 20 3f 20 22 43 6f 6d 6d 69 74 22 20 3a 20  it ? "Commit" : 
19c20 22 53 70 69 6c 6c 22 29 29 3b 0a 20 20 7d 0a 23  "Spill"));.  }.#
19c30 65 6e 64 69 66 0a 0a 20 20 2f 2a 20 53 65 65 20  endif..  /* See 
19c40 69 66 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c  if it is possibl
19c50 65 20 74 6f 20 77 72 69 74 65 20 74 68 65 73 65  e to write these
19c60 20 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68 65   frames into the
19c70 20 73 74 61 72 74 20 6f 66 20 74 68 65 0a 20 20   start of the.  
19c80 2a 2a 20 6c 6f 67 20 66 69 6c 65 2c 20 69 6e 73  ** log file, ins
19c90 74 65 61 64 20 6f 66 20 61 70 70 65 6e 64 69 6e  tead of appendin
19ca0 67 20 74 6f 20 69 74 20 61 74 20 70 57 61 6c 2d  g to it at pWal-
19cb0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a 20 20  >hdr.mxFrame..  
19cc0 2a 2f 0a 20 20 69 66 28 20 53 51 4c 49 54 45 5f  */.  if( SQLITE_
19cd0 4f 4b 21 3d 28 72 63 20 3d 20 77 61 6c 52 65 73  OK!=(rc = walRes
19ce0 74 61 72 74 4c 6f 67 28 70 57 61 6c 29 29 20 29  tartLog(pWal)) )
19cf0 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  {.    return rc;
19d00 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68  .  }..  /* If th
19d10 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20  is is the first 
19d20 66 72 61 6d 65 20 77 72 69 74 74 65 6e 20 69 6e  frame written in
19d30 74 6f 20 74 68 65 20 6c 6f 67 2c 20 77 72 69 74  to the log, writ
19d40 65 20 74 68 65 20 57 41 4c 0a 20 20 2a 2a 20 68  e the WAL.  ** h
19d50 65 61 64 65 72 20 74 6f 20 74 68 65 20 73 74 61  eader to the sta
19d60 72 74 20 6f 66 20 74 68 65 20 57 41 4c 20 66 69  rt of the WAL fi
19d70 6c 65 2e 20 53 65 65 20 63 6f 6d 6d 65 6e 74 73  le. See comments
19d80 20 61 74 20 74 68 65 20 74 6f 70 20 6f 66 0a 20   at the top of. 
19d90 20 2a 2a 20 74 68 69 73 20 73 6f 75 72 63 65 20   ** this source 
19da0 66 69 6c 65 20 66 6f 72 20 61 20 64 65 73 63 72  file for a descr
19db0 69 70 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41  iption of the WA
19dc0 4c 20 68 65 61 64 65 72 20 66 6f 72 6d 61 74 2e  L header format.
19dd0 0a 20 20 2a 2f 0a 20 20 69 46 72 61 6d 65 20 3d  .  */.  iFrame =
19de0 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
19df0 6d 65 3b 0a 20 20 69 66 28 20 69 46 72 61 6d 65  me;.  if( iFrame
19e00 3d 3d 30 20 29 7b 0a 20 20 20 20 75 38 20 61 57  ==0 ){.    u8 aW
19e10 61 6c 48 64 72 5b 57 41 4c 5f 48 44 52 53 49 5a  alHdr[WAL_HDRSIZ
19e20 45 5d 3b 20 20 20 20 20 20 2f 2a 20 42 75 66 66  E];      /* Buff
19e30 65 72 20 74 6f 20 61 73 73 65 6d 62 6c 65 20 77  er to assemble w
19e40 61 6c 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f 0a  al-header in */.
19e50 20 20 20 20 75 33 32 20 61 43 6b 73 75 6d 5b 32      u32 aCksum[2
19e60 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ];              
19e70 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66 6f    /* Checksum fo
19e80 72 20 77 61 6c 2d 68 65 61 64 65 72 20 2a 2f 0a  r wal-header */.
19e90 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34  .    sqlite3Put4
19ea0 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 30 5d  byte(&aWalHdr[0]
19eb0 2c 20 28 57 41 4c 5f 4d 41 47 49 43 20 7c 20 53  , (WAL_MAGIC | S
19ec0 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e 29  QLITE_BIGENDIAN)
19ed0 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75  );.    sqlite3Pu
19ee0 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b  t4byte(&aWalHdr[
19ef0 34 5d 2c 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53  4], WAL_MAX_VERS
19f00 49 4f 4e 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  ION);.    sqlite
19f10 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c 48  3Put4byte(&aWalH
19f20 64 72 5b 38 5d 2c 20 73 7a 50 61 67 65 29 3b 0a  dr[8], szPage);.
19f30 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62      sqlite3Put4b
19f40 79 74 65 28 26 61 57 61 6c 48 64 72 5b 31 32 5d  yte(&aWalHdr[12]
19f50 2c 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 29 3b 0a  , pWal->nCkpt);.
19f60 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 6e 43      if( pWal->nC
19f70 6b 70 74 3d 3d 30 20 29 20 73 71 6c 69 74 65 33  kpt==0 ) sqlite3
19f80 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 38 2c 20 70  _randomness(8, p
19f90 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 29 3b  Wal->hdr.aSalt);
19fa0 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 61 57 61  .    memcpy(&aWa
19fb0 6c 48 64 72 5b 31 36 5d 2c 20 70 57 61 6c 2d 3e  lHdr[16], pWal->
19fc0 68 64 72 2e 61 53 61 6c 74 2c 20 38 29 3b 0a 20  hdr.aSalt, 8);. 
19fd0 20 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79     walChecksumBy
19fe0 74 65 73 28 31 2c 20 61 57 61 6c 48 64 72 2c 20  tes(1, aWalHdr, 
19ff0 57 41 4c 5f 48 44 52 53 49 5a 45 2d 32 2a 34 2c  WAL_HDRSIZE-2*4,
1a000 20 30 2c 20 61 43 6b 73 75 6d 29 3b 0a 20 20 20   0, aCksum);.   
1a010 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65   sqlite3Put4byte
1a020 28 26 61 57 61 6c 48 64 72 5b 32 34 5d 2c 20 61  (&aWalHdr[24], a
1a030 43 6b 73 75 6d 5b 30 5d 29 3b 0a 20 20 20 20 73  Cksum[0]);.    s
1a040 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
1a050 61 57 61 6c 48 64 72 5b 32 38 5d 2c 20 61 43 6b  aWalHdr[28], aCk
1a060 73 75 6d 5b 31 5d 29 3b 0a 20 20 20 20 0a 20 20  sum[1]);.    .  
1a070 20 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 20 3d    pWal->szPage =
1a080 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 70 57 61   szPage;.    pWa
1a090 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73  l->hdr.bigEndCks
1a0a0 75 6d 20 3d 20 53 51 4c 49 54 45 5f 42 49 47 45  um = SQLITE_BIGE
1a0b0 4e 44 49 41 4e 3b 0a 20 20 20 20 70 57 61 6c 2d  NDIAN;.    pWal-
1a0c0 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
1a0d0 5b 30 5d 20 3d 20 61 43 6b 73 75 6d 5b 30 5d 3b  [0] = aCksum[0];
1a0e0 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61  .    pWal->hdr.a
1a0f0 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20  FrameCksum[1] = 
1a100 61 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 20 20 70  aCksum[1];.    p
1a110 57 61 6c 2d 3e 74 72 75 6e 63 61 74 65 4f 6e 43  Wal->truncateOnC
1a120 6f 6d 6d 69 74 20 3d 20 31 3b 0a 0a 20 20 20 20  ommit = 1;..    
1a130 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72  rc = sqlite3OsWr
1a140 69 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ite(pWal->pWalFd
1a150 2c 20 61 57 61 6c 48 64 72 2c 20 73 69 7a 65 6f  , aWalHdr, sizeo
1a160 66 28 61 57 61 6c 48 64 72 29 2c 20 30 29 3b 0a  f(aWalHdr), 0);.
1a170 20 20 20 20 57 41 4c 54 52 41 43 45 28 28 22 57      WALTRACE(("W
1a180 41 4c 25 70 3a 20 77 61 6c 2d 68 65 61 64 65 72  AL%p: wal-header
1a190 20 77 72 69 74 65 20 25 73 5c 6e 22 2c 20 70 57   write %s\n", pW
1a1a0 61 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64  al, rc ? "failed
1a1b0 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 20 20  " : "ok"));.    
1a1c0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
1a1d0 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  K ){.      retur
1a1e0 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  n rc;.    }..   
1a1f0 20 2f 2a 20 53 79 6e 63 20 74 68 65 20 68 65 61   /* Sync the hea
1a200 64 65 72 20 28 75 6e 6c 65 73 73 20 53 51 4c 49  der (unless SQLI
1a210 54 45 5f 49 4f 43 41 50 5f 53 45 51 55 45 4e 54  TE_IOCAP_SEQUENT
1a220 49 41 4c 20 69 73 20 74 72 75 65 20 6f 72 20 75  IAL is true or u
1a230 6e 6c 65 73 73 0a 20 20 20 20 2a 2a 20 61 6c 6c  nless.    ** all
1a240 20 73 79 6e 63 69 6e 67 20 69 73 20 74 75 72 6e   syncing is turn
1a250 65 64 20 6f 66 66 20 62 79 20 50 52 41 47 4d 41  ed off by PRAGMA
1a260 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 4f 46 46   synchronous=OFF
1a270 29 2e 20 20 4f 74 68 65 72 77 69 73 65 0a 20 20  ).  Otherwise.  
1a280 20 20 2a 2a 20 61 6e 20 6f 75 74 2d 6f 66 2d 6f    ** an out-of-o
1a290 72 64 65 72 20 77 72 69 74 65 20 66 6f 6c 6c 6f  rder write follo
1a2a0 77 69 6e 67 20 61 20 57 41 4c 20 72 65 73 74 61  wing a WAL resta
1a2b0 72 74 20 63 6f 75 6c 64 20 72 65 73 75 6c 74 20  rt could result 
1a2c0 69 6e 0a 20 20 20 20 2a 2a 20 64 61 74 61 62 61  in.    ** databa
1a2d0 73 65 20 63 6f 72 72 75 70 74 69 6f 6e 2e 20 20  se corruption.  
1a2e0 53 65 65 20 74 68 65 20 74 69 63 6b 65 74 3a 0a  See the ticket:.
1a2f0 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 20 20      **.    **   
1a300 20 20 68 74 74 70 3a 2f 2f 6c 6f 63 61 6c 68 6f    http://localho
1a310 73 74 3a 35 39 31 2f 73 71 6c 69 74 65 2f 69 6e  st:591/sqlite/in
1a320 66 6f 2f 66 66 35 62 65 37 33 64 65 65 0a 20 20  fo/ff5be73dee.  
1a330 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 57 61    */.    if( pWa
1a340 6c 2d 3e 73 79 6e 63 48 65 61 64 65 72 20 26 26  l->syncHeader &&
1a350 20 73 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a 20   sync_flags ){. 
1a360 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
1a370 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57  3OsSync(pWal->pW
1a380 61 6c 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73  alFd, sync_flags
1a390 20 26 20 53 51 4c 49 54 45 5f 53 59 4e 43 5f 4d   & SQLITE_SYNC_M
1a3a0 41 53 4b 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ASK);.      if( 
1a3b0 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  rc ) return rc;.
1a3c0 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65      }.  }.  asse
1a3d0 72 74 28 20 28 69 6e 74 29 70 57 61 6c 2d 3e 73  rt( (int)pWal->s
1a3e0 7a 50 61 67 65 3d 3d 73 7a 50 61 67 65 20 29 3b  zPage==szPage );
1a3f0 0a 0a 20 20 2f 2a 20 53 65 74 75 70 20 69 6e 66  ..  /* Setup inf
1a400 6f 72 6d 61 74 69 6f 6e 20 6e 65 65 64 65 64 20  ormation needed 
1a410 74 6f 20 77 72 69 74 65 20 66 72 61 6d 65 73 20  to write frames 
1a420 69 6e 74 6f 20 74 68 65 20 57 41 4c 20 2a 2f 0a  into the WAL */.
1a430 20 20 77 2e 70 57 61 6c 20 3d 20 70 57 61 6c 3b    w.pWal = pWal;
1a440 0a 20 20 77 2e 70 46 64 20 3d 20 70 57 61 6c 2d  .  w.pFd = pWal-
1a450 3e 70 57 61 6c 46 64 3b 0a 20 20 77 2e 69 53 79  >pWalFd;.  w.iSy
1a460 6e 63 50 6f 69 6e 74 20 3d 20 30 3b 0a 20 20 77  ncPoint = 0;.  w
1a470 2e 73 79 6e 63 46 6c 61 67 73 20 3d 20 73 79 6e  .syncFlags = syn
1a480 63 5f 66 6c 61 67 73 3b 0a 20 20 77 2e 73 7a 50  c_flags;.  w.szP
1a490 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20  age = szPage;.  
1a4a0 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61  iOffset = walFra
1a4b0 6d 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2b  meOffset(iFrame+
1a4c0 31 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20 73 7a  1, szPage);.  sz
1a4d0 46 72 61 6d 65 20 3d 20 73 7a 50 61 67 65 20 2b  Frame = szPage +
1a4e0 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49   WAL_FRAME_HDRSI
1a4f0 5a 45 3b 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20  ZE;..  /* Write 
1a500 61 6c 6c 20 66 72 61 6d 65 73 20 69 6e 74 6f 20  all frames into 
1a510 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 65 78 61  the log file exa
1a520 63 74 6c 79 20 6f 6e 63 65 20 2a 2f 0a 20 20 66  ctly once */.  f
1a530 6f 72 28 70 3d 70 4c 69 73 74 3b 20 70 3b 20 70  or(p=pList; p; p
1a540 3d 70 2d 3e 70 44 69 72 74 79 29 7b 0a 20 20 20  =p->pDirty){.   
1a550 20 69 6e 74 20 6e 44 62 53 69 7a 65 3b 20 20 20   int nDbSize;   
1a560 2f 2a 20 30 20 6e 6f 72 6d 61 6c 6c 79 2e 20 20  /* 0 normally.  
1a570 50 6f 73 69 74 69 76 65 20 3d 3d 20 63 6f 6d 6d  Positive == comm
1a580 69 74 20 66 6c 61 67 20 2a 2f 0a 20 20 20 20 69  it flag */.    i
1a590 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 61 73 73  Frame++;.    ass
1a5a0 65 72 74 28 20 69 4f 66 66 73 65 74 3d 3d 77 61  ert( iOffset==wa
1a5b0 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46 72  lFrameOffset(iFr
1a5c0 61 6d 65 2c 20 73 7a 50 61 67 65 29 20 29 3b 0a  ame, szPage) );.
1a5d0 20 20 20 20 6e 44 62 53 69 7a 65 20 3d 20 28 69      nDbSize = (i
1a5e0 73 43 6f 6d 6d 69 74 20 26 26 20 70 2d 3e 70 44  sCommit && p->pD
1a5f0 69 72 74 79 3d 3d 30 29 20 3f 20 6e 54 72 75 6e  irty==0) ? nTrun
1a600 63 61 74 65 20 3a 20 30 3b 0a 20 20 20 20 72 63  cate : 0;.    rc
1a610 20 3d 20 77 61 6c 57 72 69 74 65 4f 6e 65 46 72   = walWriteOneFr
1a620 61 6d 65 28 26 77 2c 20 70 2c 20 6e 44 62 53 69  ame(&w, p, nDbSi
1a630 7a 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  ze, iOffset);.  
1a640 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72    if( rc ) retur
1a650 6e 20 72 63 3b 0a 20 20 20 20 70 4c 61 73 74 20  n rc;.    pLast 
1a660 3d 20 70 3b 0a 20 20 20 20 69 4f 66 66 73 65 74  = p;.    iOffset
1a670 20 2b 3d 20 73 7a 46 72 61 6d 65 3b 0a 20 20 7d   += szFrame;.  }
1a680 0a 0a 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69  ..  /* If this i
1a690 73 20 74 68 65 20 65 6e 64 20 6f 66 20 61 20 74  s the end of a t
1a6a0 72 61 6e 73 61 63 74 69 6f 6e 2c 20 74 68 65 6e  ransaction, then
1a6b0 20 77 65 20 6d 69 67 68 74 20 6e 65 65 64 20 74   we might need t
1a6c0 6f 20 70 61 64 0a 20 20 2a 2a 20 74 68 65 20 74  o pad.  ** the t
1a6d0 72 61 6e 73 61 63 74 69 6f 6e 20 61 6e 64 2f 6f  ransaction and/o
1a6e0 72 20 73 79 6e 63 20 74 68 65 20 57 41 4c 20 66  r sync the WAL f
1a6f0 69 6c 65 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 50  ile..  **.  ** P
1a700 61 64 64 69 6e 67 20 61 6e 64 20 73 79 6e 63 69  adding and synci
1a710 6e 67 20 6f 6e 6c 79 20 6f 63 63 75 72 20 69 66  ng only occur if
1a720 20 74 68 69 73 20 73 65 74 20 6f 66 20 66 72 61   this set of fra
1a730 6d 65 73 20 63 6f 6d 70 6c 65 74 65 20 61 0a 20  mes complete a. 
1a740 20 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 20   ** transaction 
1a750 61 6e 64 20 69 66 20 50 52 41 47 4d 41 20 73 79  and if PRAGMA sy
1a760 6e 63 68 72 6f 6e 6f 75 73 3d 46 55 4c 4c 2e 20  nchronous=FULL. 
1a770 20 49 66 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d   If synchronous=
1a780 3d 4e 4f 52 4d 41 4c 0a 20 20 2a 2a 20 6f 72 20  =NORMAL.  ** or 
1a790 73 79 6e 63 68 6f 6e 6f 75 73 3d 3d 4f 46 46 2c  synchonous==OFF,
1a7a0 20 74 68 65 6e 20 6e 6f 20 70 61 64 64 69 6e 67   then no padding
1a7b0 20 6f 72 20 73 79 6e 63 69 6e 67 20 61 72 65 20   or syncing are 
1a7c0 6e 65 65 64 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a  needed..  **.  *
1a7d0 2a 20 49 66 20 53 51 4c 49 54 45 5f 49 4f 43 41  * If SQLITE_IOCA
1a7e0 50 5f 50 4f 57 45 52 53 41 46 45 5f 4f 56 45 52  P_POWERSAFE_OVER
1a7f0 57 52 49 54 45 20 69 73 20 64 65 66 69 6e 65 64  WRITE is defined
1a800 2c 20 74 68 65 6e 20 70 61 64 64 69 6e 67 20 69  , then padding i
1a810 73 20 6e 6f 74 0a 20 20 2a 2a 20 6e 65 65 64 65  s not.  ** neede
1a820 64 20 61 6e 64 20 6f 6e 6c 79 20 74 68 65 20 73  d and only the s
1a830 79 6e 63 20 69 73 20 64 6f 6e 65 2e 20 20 49 66  ync is done.  If
1a840 20 70 61 64 64 69 6e 67 20 69 73 20 6e 65 65 64   padding is need
1a850 65 64 2c 20 74 68 65 6e 20 74 68 65 0a 20 20 2a  ed, then the.  *
1a860 2a 20 66 69 6e 61 6c 20 66 72 61 6d 65 20 69 73  * final frame is
1a870 20 72 65 70 65 61 74 65 64 20 28 77 69 74 68 20   repeated (with 
1a880 69 74 73 20 63 6f 6d 6d 69 74 20 6d 61 72 6b 29  its commit mark)
1a890 20 75 6e 74 69 6c 20 74 68 65 20 6e 65 78 74 20   until the next 
1a8a0 73 65 63 74 6f 72 0a 20 20 2a 2a 20 62 6f 75 6e  sector.  ** boun
1a8b0 64 61 72 79 20 69 73 20 63 72 6f 73 73 65 64 2e  dary is crossed.
1a8c0 20 20 4f 6e 6c 79 20 74 68 65 20 70 61 72 74 20    Only the part 
1a8d0 6f 66 20 74 68 65 20 57 41 4c 20 70 72 69 6f 72  of the WAL prior
1a8e0 20 74 6f 20 74 68 65 20 6c 61 73 74 0a 20 20 2a   to the last.  *
1a8f0 2a 20 73 65 63 74 6f 72 20 62 6f 75 6e 64 61 72  * sector boundar
1a900 79 20 69 73 20 73 79 6e 63 65 64 3b 20 74 68 65  y is synced; the
1a910 20 70 61 72 74 20 6f 66 20 74 68 65 20 6c 61 73   part of the las
1a920 74 20 66 72 61 6d 65 20 74 68 61 74 20 65 78 74  t frame that ext
1a930 65 6e 64 73 0a 20 20 2a 2a 20 70 61 73 74 20 74  ends.  ** past t
1a940 68 65 20 73 65 63 74 6f 72 20 62 6f 75 6e 64 61  he sector bounda
1a950 72 79 20 69 73 20 77 72 69 74 74 65 6e 20 61 66  ry is written af
1a960 74 65 72 20 74 68 65 20 73 79 6e 63 2e 0a 20 20  ter the sync..  
1a970 2a 2f 0a 20 20 69 66 28 20 69 73 43 6f 6d 6d 69  */.  if( isCommi
1a980 74 20 26 26 20 28 73 79 6e 63 5f 66 6c 61 67 73  t && (sync_flags
1a990 20 26 20 57 41 4c 5f 53 59 4e 43 5f 54 52 41 4e   & WAL_SYNC_TRAN
1a9a0 53 41 43 54 49 4f 4e 53 29 21 3d 30 20 29 7b 0a  SACTIONS)!=0 ){.
1a9b0 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 70 61      if( pWal->pa
1a9c0 64 54 6f 53 65 63 74 6f 72 42 6f 75 6e 64 61 72  dToSectorBoundar
1a9d0 79 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 73  y ){.      int s
1a9e0 65 63 74 6f 72 53 69 7a 65 20 3d 20 73 71 6c 69  ectorSize = sqli
1a9f0 74 65 33 53 65 63 74 6f 72 53 69 7a 65 28 70 57  te3SectorSize(pW
1aa00 61 6c 2d 3e 70 57 61 6c 46 64 29 3b 0a 20 20 20  al->pWalFd);.   
1aa10 20 20 20 77 2e 69 53 79 6e 63 50 6f 69 6e 74 20     w.iSyncPoint 
1aa20 3d 20 28 28 69 4f 66 66 73 65 74 2b 73 65 63 74  = ((iOffset+sect
1aa30 6f 72 53 69 7a 65 2d 31 29 2f 73 65 63 74 6f 72  orSize-1)/sector
1aa40 53 69 7a 65 29 2a 73 65 63 74 6f 72 53 69 7a 65  Size)*sectorSize
1aa50 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 69  ;.      while( i
1aa60 4f 66 66 73 65 74 3c 77 2e 69 53 79 6e 63 50 6f  Offset<w.iSyncPo
1aa70 69 6e 74 20 29 7b 0a 20 20 20 20 20 20 20 20 72  int ){.        r
1aa80 63 20 3d 20 77 61 6c 57 72 69 74 65 4f 6e 65 46  c = walWriteOneF
1aa90 72 61 6d 65 28 26 77 2c 20 70 4c 61 73 74 2c 20  rame(&w, pLast, 
1aaa0 6e 54 72 75 6e 63 61 74 65 2c 20 69 4f 66 66 73  nTruncate, iOffs
1aab0 65 74 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  et);.        if(
1aac0 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b   rc ) return rc;
1aad0 0a 20 20 20 20 20 20 20 20 69 4f 66 66 73 65 74  .        iOffset
1aae0 20 2b 3d 20 73 7a 46 72 61 6d 65 3b 0a 20 20 20   += szFrame;.   
1aaf0 20 20 20 20 20 6e 45 78 74 72 61 2b 2b 3b 0a 20       nExtra++;. 
1ab00 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65       }.    }else
1ab10 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  {.      rc = sql
1ab20 69 74 65 33 4f 73 53 79 6e 63 28 77 2e 70 46 64  ite3OsSync(w.pFd
1ab30 2c 20 73 79 6e 63 5f 66 6c 61 67 73 20 26 20 53  , sync_flags & S
1ab40 51 4c 49 54 45 5f 53 59 4e 43 5f 4d 41 53 4b 29  QLITE_SYNC_MASK)
1ab50 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
1ab60 2a 20 49 66 20 74 68 69 73 20 66 72 61 6d 65 20  * If this frame 
1ab70 73 65 74 20 63 6f 6d 70 6c 65 74 65 73 20 74 68  set completes th
1ab80 65 20 66 69 72 73 74 20 74 72 61 6e 73 61 63 74  e first transact
1ab90 69 6f 6e 20 69 6e 20 74 68 65 20 57 41 4c 20 61  ion in the WAL a
1aba0 6e 64 0a 20 20 2a 2a 20 69 66 20 50 52 41 47 4d  nd.  ** if PRAGM
1abb0 41 20 6a 6f 75 72 6e 61 6c 5f 73 69 7a 65 5f 6c  A journal_size_l
1abc0 69 6d 69 74 20 69 73 20 73 65 74 2c 20 74 68 65  imit is set, the
1abd0 6e 20 74 72 75 6e 63 61 74 65 20 74 68 65 20 57  n truncate the W
1abe0 41 4c 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20 6a  AL to the.  ** j
1abf0 6f 75 72 6e 61 6c 20 73 69 7a 65 20 6c 69 6d 69  ournal size limi
1ac00 74 2c 20 69 66 20 70 6f 73 73 69 62 6c 65 2e 0a  t, if possible..
1ac10 20 20 2a 2f 0a 20 20 69 66 28 20 69 73 43 6f 6d    */.  if( isCom
1ac20 6d 69 74 20 26 26 20 70 57 61 6c 2d 3e 74 72 75  mit && pWal->tru
1ac30 6e 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 20 26 26  ncateOnCommit &&
1ac40 20 70 57 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65   pWal->mxWalSize
1ac50 3e 3d 30 20 29 7b 0a 20 20 20 20 69 36 34 20 73  >=0 ){.    i64 s
1ac60 7a 20 3d 20 70 57 61 6c 2d 3e 6d 78 57 61 6c 53  z = pWal->mxWalS
1ac70 69 7a 65 3b 0a 20 20 20 20 69 66 28 20 77 61 6c  ize;.    if( wal
1ac80 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46 72 61  FrameOffset(iFra
1ac90 6d 65 2b 6e 45 78 74 72 61 2b 31 2c 20 73 7a 50  me+nExtra+1, szP
1aca0 61 67 65 29 3e 70 57 61 6c 2d 3e 6d 78 57 61 6c  age)>pWal->mxWal
1acb0 53 69 7a 65 20 29 7b 0a 20 20 20 20 20 20 73 7a  Size ){.      sz
1acc0 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65   = walFrameOffse
1acd0 74 28 69 46 72 61 6d 65 2b 6e 45 78 74 72 61 2b  t(iFrame+nExtra+
1ace0 31 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20 20 20  1, szPage);.    
1acf0 7d 0a 20 20 20 20 77 61 6c 4c 69 6d 69 74 53 69  }.    walLimitSi
1ad00 7a 65 28 70 57 61 6c 2c 20 73 7a 29 3b 0a 20 20  ze(pWal, sz);.  
1ad10 20 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61 74 65    pWal->truncate
1ad20 4f 6e 43 6f 6d 6d 69 74 20 3d 20 30 3b 0a 20 20  OnCommit = 0;.  
1ad30 7d 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 64  }..  /* Append d
1ad40 61 74 61 20 74 6f 20 74 68 65 20 77 61 6c 2d 69  ata to the wal-i
1ad50 6e 64 65 78 2e 20 49 74 20 69 73 20 6e 6f 74 20  ndex. It is not 
1ad60 6e 65 63 65 73 73 61 72 79 20 74 6f 20 6c 6f 63  necessary to loc
1ad70 6b 20 74 68 65 20 0a 20 20 2a 2a 20 77 61 6c 2d  k the .  ** wal-
1ad80 69 6e 64 65 78 20 74 6f 20 64 6f 20 74 68 69 73  index to do this
1ad90 20 61 73 20 74 68 65 20 53 51 4c 49 54 45 5f 53   as the SQLITE_S
1ada0 48 4d 5f 57 52 49 54 45 20 6c 6f 63 6b 20 68 65  HM_WRITE lock he
1adb0 6c 64 20 6f 6e 20 74 68 65 20 77 61 6c 2d 69 6e  ld on the wal-in
1adc0 64 65 78 0a 20 20 2a 2a 20 67 75 61 72 61 6e 74  dex.  ** guarant
1add0 65 65 73 20 74 68 61 74 20 74 68 65 72 65 20 61  ees that there a
1ade0 72 65 20 6e 6f 20 6f 74 68 65 72 20 77 72 69 74  re no other writ
1adf0 65 72 73 2c 20 61 6e 64 20 6e 6f 20 64 61 74 61  ers, and no data
1ae00 20 74 68 61 74 20 6d 61 79 0a 20 20 2a 2a 20 62   that may.  ** b
1ae10 65 20 69 6e 20 75 73 65 20 62 79 20 65 78 69 73  e in use by exis
1ae20 74 69 6e 67 20 72 65 61 64 65 72 73 20 69 73 20  ting readers is 
1ae30 62 65 69 6e 67 20 6f 76 65 72 77 72 69 74 74 65  being overwritte
1ae40 6e 2e 0a 20 20 2a 2f 0a 20 20 69 46 72 61 6d 65  n..  */.  iFrame
1ae50 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46   = pWal->hdr.mxF
1ae60 72 61 6d 65 3b 0a 20 20 66 6f 72 28 70 3d 70 4c  rame;.  for(p=pL
1ae70 69 73 74 3b 20 70 20 26 26 20 72 63 3d 3d 53 51  ist; p && rc==SQ
1ae80 4c 49 54 45 5f 4f 4b 3b 20 70 3d 70 2d 3e 70 44  LITE_OK; p=p->pD
1ae90 69 72 74 79 29 7b 0a 20 20 20 20 69 46 72 61 6d  irty){.    iFram
1aea0 65 2b 2b 3b 0a 20 20 20 20 72 63 20 3d 20 77 61  e++;.    rc = wa
1aeb0 6c 49 6e 64 65 78 41 70 70 65 6e 64 28 70 57 61  lIndexAppend(pWa
1aec0 6c 2c 20 69 46 72 61 6d 65 2c 20 70 2d 3e 70 67  l, iFrame, p->pg
1aed0 6e 6f 29 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65  no);.  }.  while
1aee0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1aef0 26 26 20 6e 45 78 74 72 61 3e 30 20 29 7b 0a 20  && nExtra>0 ){. 
1af00 20 20 20 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20     iFrame++;.   
1af10 20 6e 45 78 74 72 61 2d 2d 3b 0a 20 20 20 20 72   nExtra--;.    r
1af20 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65  c = walIndexAppe
1af30 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c  nd(pWal, iFrame,
1af40 20 70 4c 61 73 74 2d 3e 70 67 6e 6f 29 3b 0a 20   pLast->pgno);. 
1af50 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
1af60 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2f  LITE_OK ){.    /
1af70 2a 20 55 70 64 61 74 65 20 74 68 65 20 70 72 69  * Update the pri
1af80 76 61 74 65 20 63 6f 70 79 20 6f 66 20 74 68 65  vate copy of the
1af90 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20 20 20 20   header. */.    
1afa0 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65  pWal->hdr.szPage
1afb0 20 3d 20 28 75 31 36 29 28 28 73 7a 50 61 67 65   = (u16)((szPage
1afc0 26 30 78 66 66 30 30 29 20 7c 20 28 73 7a 50 61  &0xff00) | (szPa
1afd0 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20 20 74 65  ge>>16));.    te
1afe0 73 74 63 61 73 65 28 20 73 7a 50 61 67 65 3c 3d  stcase( szPage<=
1aff0 33 32 37 36 38 20 29 3b 0a 20 20 20 20 74 65 73  32768 );.    tes
1b000 74 63 61 73 65 28 20 73 7a 50 61 67 65 3e 3d 36  tcase( szPage>=6
1b010 35 35 33 36 20 29 3b 0a 20 20 20 20 70 57 61 6c  5536 );.    pWal
1b020 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20  ->hdr.mxFrame = 
1b030 69 46 72 61 6d 65 3b 0a 20 20 20 20 69 66 28 20  iFrame;.    if( 
1b040 69 73 43 6f 6d 6d 69 74 20 29 7b 0a 20 20 20 20  isCommit ){.    
1b050 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69 43 68 61    pWal->hdr.iCha
1b060 6e 67 65 2b 2b 3b 0a 20 20 20 20 20 20 70 57 61  nge++;.      pWa
1b070 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20 3d 20 6e  l->hdr.nPage = n
1b080 54 72 75 6e 63 61 74 65 3b 0a 20 20 20 20 7d 0a  Truncate;.    }.
1b090 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69      /* If this i
1b0a0 73 20 61 20 63 6f 6d 6d 69 74 2c 20 75 70 64 61  s a commit, upda
1b0b0 74 65 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  te the wal-index
1b0c0 20 68 65 61 64 65 72 20 74 6f 6f 2e 20 2a 2f 0a   header too. */.
1b0d0 20 20 20 20 69 66 28 20 69 73 43 6f 6d 6d 69 74      if( isCommit
1b0e0 20 29 7b 0a 20 20 20 20 20 20 77 61 6c 49 6e 64   ){.      walInd
1b0f0 65 78 57 72 69 74 65 48 64 72 28 70 57 61 6c 29  exWriteHdr(pWal)
1b100 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 69 43  ;.      pWal->iC
1b110 61 6c 6c 62 61 63 6b 20 3d 20 69 46 72 61 6d 65  allback = iFrame
1b120 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 57  ;.    }.  }..  W
1b130 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
1b140 20 66 72 61 6d 65 20 77 72 69 74 65 20 25 73 5c   frame write %s\
1b150 6e 22 2c 20 70 57 61 6c 2c 20 72 63 20 3f 20 22  n", pWal, rc ? "
1b160 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29  failed" : "ok"))
1b170 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
1b180 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 72 6f  ../* .** This ro
1b190 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65 64 20  utine is called 
1b1a0 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 73 71 6c  to implement sql
1b1b0 69 74 65 33 5f 77 61 6c 5f 63 68 65 63 6b 70 6f  ite3_wal_checkpo
1b1c0 69 6e 74 28 29 20 61 6e 64 0a 2a 2a 20 72 65 6c  int() and.** rel
1b1d0 61 74 65 64 20 69 6e 74 65 72 66 61 63 65 73 2e  ated interfaces.
1b1e0 0a 2a 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20 61 20  .**.** Obtain a 
1b1f0 43 48 45 43 4b 50 4f 49 4e 54 20 6c 6f 63 6b 20  CHECKPOINT lock 
1b200 61 6e 64 20 74 68 65 6e 20 62 61 63 6b 66 69 6c  and then backfil
1b210 6c 20 61 73 20 6d 75 63 68 20 69 6e 66 6f 72 6d  l as much inform
1b220 61 74 69 6f 6e 20 61 73 0a 2a 2a 20 77 65 20 63  ation as.** we c
1b230 61 6e 20 66 72 6f 6d 20 57 41 4c 20 69 6e 74 6f  an from WAL into
1b240 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a   the database..*
1b250 2a 0a 2a 2a 20 49 66 20 70 61 72 61 6d 65 74 65  *.** If paramete
1b260 72 20 78 42 75 73 79 20 69 73 20 6e 6f 74 20 4e  r xBusy is not N
1b270 55 4c 4c 2c 20 69 74 20 69 73 20 61 20 70 6f 69  ULL, it is a poi
1b280 6e 74 65 72 20 74 6f 20 61 20 62 75 73 79 2d 68  nter to a busy-h
1b290 61 6e 64 6c 65 72 0a 2a 2a 20 63 61 6c 6c 62 61  andler.** callba
1b2a0 63 6b 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65  ck. In this case
1b2b0 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72   this function r
1b2c0 75 6e 73 20 61 20 62 6c 6f 63 6b 69 6e 67 20 63  uns a blocking c
1b2d0 68 65 63 6b 70 6f 69 6e 74 2e 0a 2a 2f 0a 69 6e  heckpoint..*/.in
1b2e0 74 20 73 71 6c 69 74 65 33 57 61 6c 43 68 65 63  t sqlite3WalChec
1b2f0 6b 70 6f 69 6e 74 28 0a 20 20 57 61 6c 20 2a 70  kpoint(.  Wal *p
1b300 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Wal,            
1b310 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c            /* Wal
1b320 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20   connection */. 
1b330 20 69 6e 74 20 65 4d 6f 64 65 2c 20 20 20 20 20   int eMode,     
1b340 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b350 20 2f 2a 20 50 41 53 53 49 56 45 2c 20 46 55 4c   /* PASSIVE, FUL
1b360 4c 20 6f 72 20 52 45 53 54 41 52 54 20 2a 2f 0a  L or RESTART */.
1b370 20 20 69 6e 74 20 28 2a 78 42 75 73 79 29 28 76    int (*xBusy)(v
1b380 6f 69 64 2a 29 2c 20 20 20 20 20 20 20 20 20 20  oid*),          
1b390 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f    /* Function to
1b3a0 20 63 61 6c 6c 20 77 68 65 6e 20 62 75 73 79 20   call when busy 
1b3b0 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 42 75 73 79  */.  void *pBusy
1b3c0 41 72 67 2c 20 20 20 20 20 20 20 20 20 20 20 20  Arg,            
1b3d0 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20       /* Context 
1b3e0 61 72 67 75 6d 65 6e 74 20 66 6f 72 20 78 42 75  argument for xBu
1b3f0 73 79 48 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69  syHandler */.  i
1b400 6e 74 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20 20  nt sync_flags,  
1b410 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b420 2a 20 46 6c 61 67 73 20 74 6f 20 73 79 6e 63 20  * Flags to sync 
1b430 64 62 20 66 69 6c 65 20 77 69 74 68 20 28 6f 72  db file with (or
1b440 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75   0) */.  int nBu
1b450 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f,              
1b460 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
1b470 20 6f 66 20 74 65 6d 70 6f 72 61 72 79 20 62 75   of temporary bu
1b480 66 66 65 72 20 2a 2f 0a 20 20 75 38 20 2a 7a 42  ffer */.  u8 *zB
1b490 75 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  uf,             
1b4a0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 65 6d            /* Tem
1b4b0 70 6f 72 61 72 79 20 62 75 66 66 65 72 20 74 6f  porary buffer to
1b4c0 20 75 73 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70   use */.  int *p
1b4d0 6e 4c 6f 67 2c 20 20 20 20 20 20 20 20 20 20 20  nLog,           
1b4e0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
1b4f0 3a 20 4e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d  : Number of fram
1b500 65 73 20 69 6e 20 57 41 4c 20 2a 2f 0a 20 20 69  es in WAL */.  i
1b510 6e 74 20 2a 70 6e 43 6b 70 74 20 20 20 20 20 20  nt *pnCkpt      
1b520 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b530 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66  * OUT: Number of
1b540 20 62 61 63 6b 66 69 6c 6c 65 64 20 66 72 61 6d   backfilled fram
1b550 65 73 20 69 6e 20 57 41 4c 20 2a 2f 0a 29 7b 0a  es in WAL */.){.
1b560 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
1b570 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b580 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
1b590 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43 68 61 6e   */.  int isChan
1b5a0 67 65 64 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ged = 0;        
1b5b0 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
1b5c0 20 61 20 6e 65 77 20 77 61 6c 2d 69 6e 64 65 78   a new wal-index
1b5d0 20 68 65 61 64 65 72 20 69 73 20 6c 6f 61 64 65   header is loade
1b5e0 64 20 2a 2f 0a 20 20 69 6e 74 20 65 4d 6f 64 65  d */.  int eMode
1b5f0 32 20 3d 20 65 4d 6f 64 65 3b 20 20 20 20 20 20  2 = eMode;      
1b600 20 20 20 20 20 20 20 2f 2a 20 4d 6f 64 65 20 74         /* Mode t
1b610 6f 20 70 61 73 73 20 74 6f 20 77 61 6c 43 68 65  o pass to walChe
1b620 63 6b 70 6f 69 6e 74 28 29 20 2a 2f 0a 0a 20 20  ckpoint() */..  
1b630 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 63 6b  assert( pWal->ck
1b640 70 74 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 61  ptLock==0 );.  a
1b650 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69  ssert( pWal->wri
1b660 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 0a 20 20  teLock==0 );..  
1b670 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4f 6e  if( pWal->readOn
1b680 6c 79 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  ly ) return SQLI
1b690 54 45 5f 52 45 41 44 4f 4e 4c 59 3b 0a 20 20 57  TE_READONLY;.  W
1b6a0 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
1b6b0 20 63 68 65 63 6b 70 6f 69 6e 74 20 62 65 67 69   checkpoint begi
1b6c0 6e 73 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 20  ns\n", pWal));. 
1b6d0 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63   rc = walLockExc
1b6e0 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
1b6f0 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  _CKPT_LOCK, 1);.
1b700 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20    if( rc ){.    
1b710 2f 2a 20 55 73 75 61 6c 6c 79 20 74 68 69 73 20  /* Usually this 
1b720 69 73 20 53 51 4c 49 54 45 5f 42 55 53 59 20 6d  is SQLITE_BUSY m
1b730 65 61 6e 69 6e 67 20 74 68 61 74 20 61 6e 6f 74  eaning that anot
1b740 68 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72  her thread or pr
1b750 6f 63 65 73 73 0a 20 20 20 20 2a 2a 20 69 73 20  ocess.    ** is 
1b760 61 6c 72 65 61 64 79 20 72 75 6e 6e 69 6e 67 20  already running 
1b770 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c 20 6f 72  a checkpoint, or
1b780 20 6d 61 79 62 65 20 61 20 72 65 63 6f 76 65 72   maybe a recover
1b790 79 2e 20 20 42 75 74 20 69 74 20 6d 69 67 68 74  y.  But it might
1b7a0 0a 20 20 20 20 2a 2a 20 61 6c 73 6f 20 62 65 20  .    ** also be 
1b7b0 53 51 4c 49 54 45 5f 49 4f 45 52 52 2e 20 2a 2f  SQLITE_IOERR. */
1b7c0 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
1b7d0 20 20 7d 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74    }.  pWal->ckpt
1b7e0 4c 6f 63 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20  Lock = 1;..  /* 
1b7f0 49 66 20 74 68 69 73 20 69 73 20 61 20 62 6c 6f  If this is a blo
1b800 63 6b 69 6e 67 2d 63 68 65 63 6b 70 6f 69 6e 74  cking-checkpoint
1b810 2c 20 74 68 65 6e 20 6f 62 74 61 69 6e 20 74 68  , then obtain th
1b820 65 20 77 72 69 74 65 2d 6c 6f 63 6b 20 61 73 20  e write-lock as 
1b830 77 65 6c 6c 0a 20 20 2a 2a 20 74 6f 20 70 72 65  well.  ** to pre
1b840 76 65 6e 74 20 61 6e 79 20 77 72 69 74 65 72 73  vent any writers
1b850 20 66 72 6f 6d 20 72 75 6e 6e 69 6e 67 20 77 68   from running wh
1b860 69 6c 65 20 74 68 65 20 63 68 65 63 6b 70 6f 69  ile the checkpoi
1b870 6e 74 20 69 73 20 75 6e 64 65 72 77 61 79 2e 0a  nt is underway..
1b880 20 20 2a 2a 20 54 68 69 73 20 68 61 73 20 74 6f    ** This has to
1b890 20 62 65 20 64 6f 6e 65 20 62 65 66 6f 72 65 20   be done before 
1b8a0 74 68 65 20 63 61 6c 6c 20 74 6f 20 77 61 6c 49  the call to walI
1b8b0 6e 64 65 78 52 65 61 64 48 64 72 28 29 20 62 65  ndexReadHdr() be
1b8c0 6c 6f 77 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49  low..  **.  ** I
1b8d0 66 20 74 68 65 20 77 72 69 74 65 72 20 6c 6f 63  f the writer loc
1b8e0 6b 20 63 61 6e 6e 6f 74 20 62 65 20 6f 62 74 61  k cannot be obta
1b8f0 69 6e 65 64 2c 20 74 68 65 6e 20 61 20 70 61 73  ined, then a pas
1b900 73 69 76 65 20 63 68 65 63 6b 70 6f 69 6e 74 20  sive checkpoint 
1b910 69 73 0a 20 20 2a 2a 20 72 75 6e 20 69 6e 73 74  is.  ** run inst
1b920 65 61 64 2e 20 53 69 6e 63 65 20 74 68 65 20 63  ead. Since the c
1b930 68 65 63 6b 70 6f 69 6e 74 65 72 20 69 73 20 6e  heckpointer is n
1b940 6f 74 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 77  ot holding the w
1b950 72 69 74 65 72 20 6c 6f 63 6b 2c 0a 20 20 2a 2a  riter lock,.  **
1b960 20 74 68 65 72 65 20 69 73 20 6e 6f 20 70 6f 69   there is no poi
1b970 6e 74 20 69 6e 20 62 6c 6f 63 6b 69 6e 67 20 77  nt in blocking w
1b980 61 69 74 69 6e 67 20 66 6f 72 20 61 6e 79 20 72  aiting for any r
1b990 65 61 64 65 72 73 2e 20 41 73 73 75 6d 69 6e 67  eaders. Assuming
1b9a0 20 6e 6f 20 0a 20 20 2a 2a 20 6f 74 68 65 72 20   no .  ** other 
1b9b0 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 74 68  error occurs, th
1b9c0 69 73 20 66 75 6e 63 74 69 6f 6e 20 77 69 6c 6c  is function will
1b9d0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 42   return SQLITE_B
1b9e0 55 53 59 20 74 6f 20 74 68 65 20 63 61 6c 6c 65  USY to the calle
1b9f0 72 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 65 4d  r..  */.  if( eM
1ba00 6f 64 65 21 3d 53 51 4c 49 54 45 5f 43 48 45 43  ode!=SQLITE_CHEC
1ba10 4b 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 29  KPOINT_PASSIVE )
1ba20 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 42 75  {.    rc = walBu
1ba30 73 79 4c 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75  syLock(pWal, xBu
1ba40 73 79 2c 20 70 42 75 73 79 41 72 67 2c 20 57 41  sy, pBusyArg, WA
1ba50 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29  L_WRITE_LOCK, 1)
1ba60 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
1ba70 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
1ba80 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
1ba90 20 3d 20 31 3b 0a 20 20 20 20 7d 65 6c 73 65 20   = 1;.    }else 
1baa0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42  if( rc==SQLITE_B
1bab0 55 53 59 20 29 7b 0a 20 20 20 20 20 20 65 4d 6f  USY ){.      eMo
1bac0 64 65 32 20 3d 20 53 51 4c 49 54 45 5f 43 48 45  de2 = SQLITE_CHE
1bad0 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 3b  CKPOINT_PASSIVE;
1bae0 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
1baf0 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 7d  TE_OK;.    }.  }
1bb00 0a 0a 20 20 2f 2a 20 52 65 61 64 20 74 68 65 20  ..  /* Read the 
1bb10 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
1bb20 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  . */.  if( rc==S
1bb30 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1bb40 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52 65 61  rc = walIndexRea
1bb50 64 48 64 72 28 70 57 61 6c 2c 20 26 69 73 43 68  dHdr(pWal, &isCh
1bb60 61 6e 67 65 64 29 3b 0a 20 20 20 20 69 66 28 20  anged);.    if( 
1bb70 69 73 43 68 61 6e 67 65 64 20 26 26 20 70 57 61  isChanged && pWa
1bb80 6c 2d 3e 70 44 62 46 64 2d 3e 70 4d 65 74 68 6f  l->pDbFd->pMetho
1bb90 64 73 2d 3e 69 56 65 72 73 69 6f 6e 3e 3d 33 20  ds->iVersion>=3 
1bba0 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
1bbb0 4f 73 55 6e 66 65 74 63 68 28 70 57 61 6c 2d 3e  OsUnfetch(pWal->
1bbc0 70 44 62 46 64 2c 20 30 2c 20 30 29 3b 0a 20 20  pDbFd, 0, 0);.  
1bbd0 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f    }.  }..  /* Co
1bbe0 70 79 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65  py data from the
1bbf0 20 6c 6f 67 20 74 6f 20 74 68 65 20 64 61 74 61   log to the data
1bc00 62 61 73 65 20 66 69 6c 65 2e 20 2a 2f 0a 20 20  base file. */.  
1bc10 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
1bc20 4b 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57 61  K ){.    if( pWa
1bc30 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 26  l->hdr.mxFrame &
1bc40 26 20 77 61 6c 50 61 67 65 73 69 7a 65 28 70 57  & walPagesize(pW
1bc50 61 6c 29 21 3d 6e 42 75 66 20 29 7b 0a 20 20 20  al)!=nBuf ){.   
1bc60 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43     rc = SQLITE_C
1bc70 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20  ORRUPT_BKPT;.   
1bc80 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
1bc90 20 3d 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74   = walCheckpoint
1bca0 28 70 57 61 6c 2c 20 65 4d 6f 64 65 32 2c 20 78  (pWal, eMode2, x
1bcb0 42 75 73 79 2c 20 70 42 75 73 79 41 72 67 2c 20  Busy, pBusyArg, 
1bcc0 73 79 6e 63 5f 66 6c 61 67 73 2c 20 7a 42 75 66  sync_flags, zBuf
1bcd0 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
1bce0 20 49 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63   If no error occ
1bcf0 75 72 72 65 64 2c 20 73 65 74 20 74 68 65 20 6f  urred, set the o
1bd00 75 74 70 75 74 20 76 61 72 69 61 62 6c 65 73 2e  utput variables.
1bd10 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d   */.    if( rc==
1bd20 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 72 63 3d  SQLITE_OK || rc=
1bd30 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a  =SQLITE_BUSY ){.
1bd40 20 20 20 20 20 20 69 66 28 20 70 6e 4c 6f 67 20        if( pnLog 
1bd50 29 20 2a 70 6e 4c 6f 67 20 3d 20 28 69 6e 74 29  ) *pnLog = (int)
1bd60 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
1bd70 65 3b 0a 20 20 20 20 20 20 69 66 28 20 70 6e 43  e;.      if( pnC
1bd80 6b 70 74 20 29 20 2a 70 6e 43 6b 70 74 20 3d 20  kpt ) *pnCkpt = 
1bd90 28 69 6e 74 29 28 77 61 6c 43 6b 70 74 49 6e 66  (int)(walCkptInf
1bda0 6f 28 70 57 61 6c 29 2d 3e 6e 42 61 63 6b 66 69  o(pWal)->nBackfi
1bdb0 6c 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ll);.    }.  }..
1bdc0 20 20 69 66 28 20 69 73 43 68 61 6e 67 65 64 20    if( isChanged 
1bdd0 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 61 20 6e  ){.    /* If a n
1bde0 65 77 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  ew wal-index hea
1bdf0 64 65 72 20 77 61 73 20 6c 6f 61 64 65 64 20 62  der was loaded b
1be00 65 66 6f 72 65 20 74 68 65 20 63 68 65 63 6b 70  efore the checkp
1be10 6f 69 6e 74 20 77 61 73 20 0a 20 20 20 20 2a 2a  oint was .    **
1be20 20 70 65 72 66 6f 72 6d 65 64 2c 20 74 68 65 6e   performed, then
1be30 20 74 68 65 20 70 61 67 65 72 2d 63 61 63 68 65   the pager-cache
1be40 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
1be50 20 70 57 61 6c 20 69 73 20 6e 6f 77 0a 20 20 20   pWal is now.   
1be60 20 2a 2a 20 6f 75 74 20 6f 66 20 64 61 74 65 2e   ** out of date.
1be70 20 53 6f 20 7a 65 72 6f 20 74 68 65 20 63 61 63   So zero the cac
1be80 68 65 64 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  hed wal-index he
1be90 61 64 65 72 20 74 6f 20 65 6e 73 75 72 65 20 74  ader to ensure t
1bea0 68 61 74 0a 20 20 20 20 2a 2a 20 6e 65 78 74 20  hat.    ** next 
1beb0 74 69 6d 65 20 74 68 65 20 70 61 67 65 72 20 6f  time the pager o
1bec0 70 65 6e 73 20 61 20 73 6e 61 70 73 68 6f 74 20  pens a snapshot 
1bed0 6f 6e 20 74 68 69 73 20 64 61 74 61 62 61 73 65  on this database
1bee0 20 69 74 20 6b 6e 6f 77 73 20 74 68 61 74 0a 20   it knows that. 
1bef0 20 20 20 2a 2a 20 74 68 65 20 63 61 63 68 65 20     ** the cache 
1bf00 6e 65 65 64 73 20 74 6f 20 62 65 20 72 65 73 65  needs to be rese
1bf10 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d 65  t..    */.    me
1bf20 6d 73 65 74 28 26 70 57 61 6c 2d 3e 68 64 72 2c  mset(&pWal->hdr,
1bf30 20 30 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e   0, sizeof(WalIn
1bf40 64 65 78 48 64 72 29 29 3b 0a 20 20 7d 0a 0a 20  dexHdr));.  }.. 
1bf50 20 2f 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20   /* Release the 
1bf60 6c 6f 63 6b 73 2e 20 2a 2f 0a 20 20 73 71 6c 69  locks. */.  sqli
1bf70 74 65 33 57 61 6c 45 6e 64 57 72 69 74 65 54 72  te3WalEndWriteTr
1bf80 61 6e 73 61 63 74 69 6f 6e 28 70 57 61 6c 29 3b  ansaction(pWal);
1bf90 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c  .  walUnlockExcl
1bfa0 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
1bfb0 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  CKPT_LOCK, 1);. 
1bfc0 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20   pWal->ckptLock 
1bfd0 3d 20 30 3b 0a 20 20 57 41 4c 54 52 41 43 45 28  = 0;.  WALTRACE(
1bfe0 28 22 57 41 4c 25 70 3a 20 63 68 65 63 6b 70 6f  ("WAL%p: checkpo
1bff0 69 6e 74 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c  int %s\n", pWal,
1c000 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a   rc ? "failed" :
1c010 20 22 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75 72   "ok"));.  retur
1c020 6e 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  n (rc==SQLITE_OK
1c030 20 26 26 20 65 4d 6f 64 65 21 3d 65 4d 6f 64 65   && eMode!=eMode
1c040 32 20 3f 20 53 51 4c 49 54 45 5f 42 55 53 59 20  2 ? SQLITE_BUSY 
1c050 3a 20 72 63 29 3b 0a 7d 0a 0a 2f 2a 20 52 65 74  : rc);.}../* Ret
1c060 75 72 6e 20 74 68 65 20 76 61 6c 75 65 20 74 6f  urn the value to
1c070 20 70 61 73 73 20 74 6f 20 61 20 73 71 6c 69 74   pass to a sqlit
1c080 65 33 5f 77 61 6c 5f 68 6f 6f 6b 20 63 61 6c 6c  e3_wal_hook call
1c090 62 61 63 6b 2c 20 74 68 65 0a 2a 2a 20 6e 75 6d  back, the.** num
1c0a0 62 65 72 20 6f 66 20 66 72 61 6d 65 73 20 69 6e  ber of frames in
1c0b0 20 74 68 65 20 57 41 4c 20 61 74 20 74 68 65 20   the WAL at the 
1c0c0 70 6f 69 6e 74 20 6f 66 20 74 68 65 20 6c 61 73  point of the las
1c0d0 74 20 63 6f 6d 6d 69 74 20 73 69 6e 63 65 0a 2a  t commit since.*
1c0e0 2a 20 73 71 6c 69 74 65 33 57 61 6c 43 61 6c 6c  * sqlite3WalCall
1c0f0 62 61 63 6b 28 29 20 77 61 73 20 63 61 6c 6c 65  back() was calle
1c100 64 2e 20 20 49 66 20 6e 6f 20 63 6f 6d 6d 69 74  d.  If no commit
1c110 73 20 68 61 76 65 20 6f 63 63 75 72 72 65 64 20  s have occurred 
1c120 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 6c 61 73  since.** the las
1c130 74 20 63 61 6c 6c 2c 20 74 68 65 6e 20 72 65 74  t call, then ret
1c140 75 72 6e 20 30 2e 0a 2a 2f 0a 69 6e 74 20 73 71  urn 0..*/.int sq
1c150 6c 69 74 65 33 57 61 6c 43 61 6c 6c 62 61 63 6b  lite3WalCallback
1c160 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 75  (Wal *pWal){.  u
1c170 33 32 20 72 65 74 20 3d 20 30 3b 0a 20 20 69 66  32 ret = 0;.  if
1c180 28 20 70 57 61 6c 20 29 7b 0a 20 20 20 20 72 65  ( pWal ){.    re
1c190 74 20 3d 20 70 57 61 6c 2d 3e 69 43 61 6c 6c 62  t = pWal->iCallb
1c1a0 61 63 6b 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 69  ack;.    pWal->i
1c1b0 43 61 6c 6c 62 61 63 6b 20 3d 20 30 3b 0a 20 20  Callback = 0;.  
1c1c0 7d 0a 20 20 72 65 74 75 72 6e 20 28 69 6e 74 29  }.  return (int)
1c1d0 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  ret;.}../*.** Th
1c1e0 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
1c1f0 61 6c 6c 65 64 20 74 6f 20 63 68 61 6e 67 65 20  alled to change 
1c200 74 68 65 20 57 41 4c 20 73 75 62 73 79 73 74 65  the WAL subsyste
1c210 6d 20 69 6e 74 6f 20 6f 72 20 6f 75 74 0a 2a 2a  m into or out.**
1c220 20 6f 66 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65   of locking_mode
1c230 3d 45 58 43 4c 55 53 49 56 45 2e 0a 2a 2a 0a 2a  =EXCLUSIVE..**.*
1c240 2a 20 49 66 20 6f 70 20 69 73 20 7a 65 72 6f 2c  * If op is zero,
1c250 20 74 68 65 6e 20 61 74 74 65 6d 70 74 20 74 6f   then attempt to
1c260 20 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63   change from loc
1c270 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53  king_mode=EXCLUS
1c280 49 56 45 0a 2a 2a 20 69 6e 74 6f 20 6c 6f 63 6b  IVE.** into lock
1c290 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 2e  ing_mode=NORMAL.
1c2a0 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68 61    This means tha
1c2b0 74 20 77 65 20 6d 75 73 74 20 61 63 71 75 69 72  t we must acquir
1c2c0 65 20 61 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74  e a lock.** on t
1c2d0 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  he pWal->readLoc
1c2e0 6b 20 62 79 74 65 2e 20 20 49 66 20 74 68 65 20  k byte.  If the 
1c2f0 57 41 4c 20 69 73 20 61 6c 72 65 61 64 79 20 69  WAL is already i
1c300 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e  n locking_mode=N
1c310 4f 52 4d 41 4c 0a 2a 2a 20 6f 72 20 69 66 20 74  ORMAL.** or if t
1c320 68 65 20 61 63 71 75 69 73 69 74 69 6f 6e 20 6f  he acquisition o
1c330 66 20 74 68 65 20 6c 6f 63 6b 20 66 61 69 6c 73  f the lock fails
1c340 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20 30 2e  , then return 0.
1c350 20 20 49 66 20 74 68 65 0a 2a 2a 20 74 72 61 6e    If the.** tran
1c360 73 69 74 69 6f 6e 20 6f 75 74 20 6f 66 20 65 78  sition out of ex
1c370 63 6c 75 73 69 76 65 2d 6d 6f 64 65 20 69 73 20  clusive-mode is 
1c380 73 75 63 63 65 73 73 66 75 6c 2c 20 72 65 74 75  successful, retu
1c390 72 6e 20 31 2e 20 20 54 68 69 73 0a 2a 2a 20 6f  rn 1.  This.** o
1c3a0 70 65 72 61 74 69 6f 6e 20 6d 75 73 74 20 6f 63  peration must oc
1c3b0 63 75 72 20 77 68 69 6c 65 20 74 68 65 20 70 61  cur while the pa
1c3c0 67 65 72 20 69 73 20 73 74 69 6c 6c 20 68 6f 6c  ger is still hol
1c3d0 64 69 6e 67 20 74 68 65 20 65 78 63 6c 75 73 69  ding the exclusi
1c3e0 76 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20 74 68  ve.** lock on th
1c3f0 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20  e main database 
1c400 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f  file..**.** If o
1c410 70 20 69 73 20 6f 6e 65 2c 20 74 68 65 6e 20 63  p is one, then c
1c420 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63 6b 69  hange from locki
1c430 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 69  ng_mode=NORMAL i
1c440 6e 74 6f 20 0a 2a 2a 20 6c 6f 63 6b 69 6e 67 5f  nto .** locking_
1c450 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2e 20  mode=EXCLUSIVE. 
1c460 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68 61 74   This means that
1c470 20 74 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c   the pWal->readL
1c480 6f 63 6b 20 6d 75 73 74 0a 2a 2a 20 62 65 20 72  ock must.** be r
1c490 65 6c 65 61 73 65 64 2e 20 20 52 65 74 75 72 6e  eleased.  Return
1c4a0 20 31 20 69 66 20 74 68 65 20 74 72 61 6e 73 69   1 if the transi
1c4b0 74 69 6f 6e 20 69 73 20 6d 61 64 65 20 61 6e 64  tion is made and
1c4c0 20 30 20 69 66 20 74 68 65 0a 2a 2a 20 57 41 4c   0 if the.** WAL
1c4d0 20 69 73 20 61 6c 72 65 61 64 79 20 69 6e 20 65   is already in e
1c4e0 78 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69 6e 67  xclusive-locking
1c4f0 20 6d 6f 64 65 20 2d 20 6d 65 61 6e 69 6e 67 20   mode - meaning 
1c500 74 68 61 74 20 74 68 69 73 0a 2a 2a 20 72 6f 75  that this.** rou
1c510 74 69 6e 65 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  tine is a no-op.
1c520 20 20 54 68 65 20 70 61 67 65 72 20 6d 75 73 74    The pager must
1c530 20 61 6c 72 65 61 64 79 20 68 6f 6c 64 20 74 68   already hold th
1c540 65 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b  e exclusive lock
1c550 0a 2a 2a 20 6f 6e 20 74 68 65 20 6d 61 69 6e 20  .** on the main 
1c560 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 62 65  database file be
1c570 66 6f 72 65 20 69 6e 76 6f 6b 69 6e 67 20 74 68  fore invoking th
1c580 69 73 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 2a 2a  is operation..**
1c590 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20 6e 65 67  .** If op is neg
1c5a0 61 74 69 76 65 2c 20 74 68 65 6e 20 64 6f 20 61  ative, then do a
1c5b0 20 64 72 79 2d 72 75 6e 20 6f 66 20 74 68 65 20   dry-run of the 
1c5c0 6f 70 3d 3d 31 20 63 61 73 65 20 62 75 74 20 64  op==1 case but d
1c5d0 6f 0a 2a 2a 20 6e 6f 74 20 61 63 74 75 61 6c 6c  o.** not actuall
1c5e0 79 20 63 68 61 6e 67 65 20 61 6e 79 74 68 69 6e  y change anythin
1c5f0 67 2e 20 54 68 65 20 70 61 67 65 72 20 75 73 65  g. The pager use
1c600 73 20 74 68 69 73 20 74 6f 20 73 65 65 20 69 66  s this to see if
1c610 20 69 74 0a 2a 2a 20 73 68 6f 75 6c 64 20 61 63   it.** should ac
1c620 71 75 69 72 65 20 74 68 65 20 64 61 74 61 62 61  quire the databa
1c630 73 65 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63  se exclusive loc
1c640 6b 20 70 72 69 6f 72 20 74 6f 20 69 6e 76 6f 6b  k prior to invok
1c650 69 6e 67 0a 2a 2a 20 74 68 65 20 6f 70 3d 3d 31  ing.** the op==1
1c660 20 63 61 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71   case..*/.int sq
1c670 6c 69 74 65 33 57 61 6c 45 78 63 6c 75 73 69 76  lite3WalExclusiv
1c680 65 4d 6f 64 65 28 57 61 6c 20 2a 70 57 61 6c 2c  eMode(Wal *pWal,
1c690 20 69 6e 74 20 6f 70 29 7b 0a 20 20 69 6e 74 20   int op){.  int 
1c6a0 72 63 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57  rc;.  assert( pW
1c6b0 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30  al->writeLock==0
1c6c0 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57   );.  assert( pW
1c6d0 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  al->exclusiveMod
1c6e0 65 21 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52  e!=WAL_HEAPMEMOR
1c6f0 59 5f 4d 4f 44 45 20 7c 7c 20 6f 70 3d 3d 2d 31  Y_MODE || op==-1
1c700 20 29 3b 0a 0a 20 20 2f 2a 20 70 57 61 6c 2d 3e   );..  /* pWal->
1c710 72 65 61 64 4c 6f 63 6b 20 69 73 20 75 73 75 61  readLock is usua
1c720 6c 6c 79 20 73 65 74 2c 20 62 75 74 20 6d 69 67  lly set, but mig
1c730 68 74 20 62 65 20 2d 31 20 69 66 20 74 68 65 72  ht be -1 if ther
1c740 65 20 77 61 73 20 61 20 0a 20 20 2a 2a 20 70 72  e was a .  ** pr
1c750 69 6f 72 20 65 72 72 6f 72 20 77 68 69 6c 65 20  ior error while 
1c760 61 74 74 65 6d 70 74 69 6e 67 20 74 6f 20 61 63  attempting to ac
1c770 71 75 69 72 65 20 61 72 65 20 72 65 61 64 2d 6c  quire are read-l
1c780 6f 63 6b 2e 20 54 68 69 73 20 63 61 6e 6e 6f 74  ock. This cannot
1c790 20 0a 20 20 2a 2a 20 68 61 70 70 65 6e 20 69 66   .  ** happen if
1c7a0 20 74 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20   the connection 
1c7b0 69 73 20 61 63 74 75 61 6c 6c 79 20 69 6e 20 65  is actually in e
1c7c0 78 63 6c 75 73 69 76 65 20 6d 6f 64 65 20 28 61  xclusive mode (a
1c7d0 73 20 6e 6f 20 78 53 68 6d 4c 6f 63 6b 0a 20 20  s no xShmLock.  
1c7e0 2a 2a 20 6c 6f 63 6b 73 20 61 72 65 20 74 61 6b  ** locks are tak
1c7f0 65 6e 20 69 6e 20 74 68 69 73 20 63 61 73 65 29  en in this case)
1c800 2e 20 4e 6f 72 20 73 68 6f 75 6c 64 20 74 68 65  . Nor should the
1c810 20 70 61 67 65 72 20 61 74 74 65 6d 70 74 20 74   pager attempt t
1c820 6f 0a 20 20 2a 2a 20 75 70 67 72 61 64 65 20 74  o.  ** upgrade t
1c830 6f 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f 64 65  o exclusive-mode
1c840 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 75 63 68 20   following such 
1c850 61 6e 20 65 72 72 6f 72 2e 0a 20 20 2a 2f 0a 20  an error..  */. 
1c860 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72   assert( pWal->r
1c870 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70 57  eadLock>=0 || pW
1c880 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 29 3b  al->lockError );
1c890 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
1c8a0 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20  >readLock>=0 || 
1c8b0 28 6f 70 3c 3d 30 20 26 26 20 70 57 61 6c 2d 3e  (op<=0 && pWal->
1c8c0 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30  exclusiveMode==0
1c8d0 29 20 29 3b 0a 0a 20 20 69 66 28 20 6f 70 3d 3d  ) );..  if( op==
1c8e0 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57 61  0 ){.    if( pWa
1c8f0 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
1c900 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e   ){.      pWal->
1c910 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20  exclusiveMode = 
1c920 30 3b 0a 20 20 20 20 20 20 69 66 28 20 77 61 6c  0;.      if( wal
1c930 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  LockShared(pWal,
1c940 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70   WAL_READ_LOCK(p
1c950 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 21  Wal->readLock))!
1c960 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
1c970 20 20 20 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c        pWal->excl
1c980 75 73 69 76 65 4d 6f 64 65 20 3d 20 31 3b 0a 20  usiveMode = 1;. 
1c990 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 63 20       }.      rc 
1c9a0 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76  = pWal->exclusiv
1c9b0 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 20 20 7d 65  eMode==0;.    }e
1c9c0 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20 41 6c  lse{.      /* Al
1c9d0 72 65 61 64 79 20 69 6e 20 6c 6f 63 6b 69 6e 67  ready in locking
1c9e0 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 2a 2f 0a  _mode=NORMAL */.
1c9f0 20 20 20 20 20 20 72 63 20 3d 20 30 3b 0a 20 20        rc = 0;.  
1ca00 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20    }.  }else if( 
1ca10 6f 70 3e 30 20 29 7b 0a 20 20 20 20 61 73 73 65  op>0 ){.    asse
1ca20 72 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  rt( pWal->exclus
1ca30 69 76 65 4d 6f 64 65 3d 3d 30 20 29 3b 0a 20 20  iveMode==0 );.  
1ca40 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
1ca50 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b 0a 20  readLock>=0 );. 
1ca60 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72     walUnlockShar
1ca70 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ed(pWal, WAL_REA
1ca80 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61  D_LOCK(pWal->rea
1ca90 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70 57 61  dLock));.    pWa
1caa0 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
1cab0 20 3d 20 31 3b 0a 20 20 20 20 72 63 20 3d 20 31   = 1;.    rc = 1
1cac0 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72  ;.  }else{.    r
1cad0 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  c = pWal->exclus
1cae0 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 7d 0a  iveMode==0;.  }.
1caf0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
1cb00 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72  /* .** Return tr
1cb10 75 65 20 69 66 20 74 68 65 20 61 72 67 75 6d 65  ue if the argume
1cb20 6e 74 20 69 73 20 6e 6f 6e 2d 4e 55 4c 4c 20 61  nt is non-NULL a
1cb30 6e 64 20 74 68 65 20 57 41 4c 20 6d 6f 64 75 6c  nd the WAL modul
1cb40 65 20 69 73 20 75 73 69 6e 67 0a 2a 2a 20 68 65  e is using.** he
1cb50 61 70 2d 6d 65 6d 6f 72 79 20 66 6f 72 20 74 68  ap-memory for th
1cb60 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 4f 74 68  e wal-index. Oth
1cb70 65 72 77 69 73 65 2c 20 69 66 20 74 68 65 20 61  erwise, if the a
1cb80 72 67 75 6d 65 6e 74 20 69 73 20 4e 55 4c 4c 20  rgument is NULL 
1cb90 6f 72 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6d 6f  or the.** WAL mo
1cba0 64 75 6c 65 20 69 73 20 75 73 69 6e 67 20 73 68  dule is using sh
1cbb0 61 72 65 64 2d 6d 65 6d 6f 72 79 2c 20 72 65 74  ared-memory, ret
1cbc0 75 72 6e 20 66 61 6c 73 65 2e 20 0a 2a 2f 0a 69  urn false. .*/.i
1cbd0 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 48 65 61  nt sqlite3WalHea
1cbe0 70 4d 65 6d 6f 72 79 28 57 61 6c 20 2a 70 57 61  pMemory(Wal *pWa
1cbf0 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 70 57  l){.  return (pW
1cc00 61 6c 20 26 26 20 70 57 61 6c 2d 3e 65 78 63 6c  al && pWal->excl
1cc10 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48  usiveMode==WAL_H
1cc20 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29  EAPMEMORY_MODE )
1cc30 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49  ;.}..#ifdef SQLI
1cc40 54 45 5f 45 4e 41 42 4c 45 5f 5a 49 50 56 46 53  TE_ENABLE_ZIPVFS
1cc50 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 20 61 72  ./*.** If the ar
1cc60 67 75 6d 65 6e 74 20 69 73 20 6e 6f 74 20 4e 55  gument is not NU
1cc70 4c 4c 2c 20 69 74 20 70 6f 69 6e 74 73 20 74 6f  LL, it points to
1cc80 20 61 20 57 61 6c 20 6f 62 6a 65 63 74 20 74 68   a Wal object th
1cc90 61 74 20 68 6f 6c 64 73 20 61 0a 2a 2a 20 72 65  at holds a.** re
1cca0 61 64 2d 6c 6f 63 6b 2e 20 54 68 69 73 20 66 75  ad-lock. This fu
1ccb0 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 74  nction returns t
1ccc0 68 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65  he database page
1ccd0 2d 73 69 7a 65 20 69 66 20 69 74 20 69 73 20 6b  -size if it is k
1cce0 6e 6f 77 6e 2c 0a 2a 2a 20 6f 72 20 7a 65 72 6f  nown,.** or zero
1ccf0 20 69 66 20 69 74 20 69 73 20 6e 6f 74 20 28 6f   if it is not (o
1cd00 72 20 69 66 20 70 57 61 6c 20 69 73 20 4e 55 4c  r if pWal is NUL
1cd10 4c 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  L)..*/.int sqlit
1cd20 65 33 57 61 6c 46 72 61 6d 65 73 69 7a 65 28 57  e3WalFramesize(W
1cd30 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73  al *pWal){.  ass
1cd40 65 72 74 28 20 70 57 61 6c 3d 3d 30 20 7c 7c 20  ert( pWal==0 || 
1cd50 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
1cd60 30 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 70  0 );.  return (p
1cd70 57 61 6c 20 3f 20 70 57 61 6c 2d 3e 73 7a 50 61  Wal ? pWal->szPa
1cd80 67 65 20 3a 20 30 29 3b 0a 7d 0a 23 65 6e 64 69  ge : 0);.}.#endi
1cd90 66 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 23 69 66  f..#endif /* #if
1cda0 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
1cdb0 5f 57 41 4c 20 2a 2f 0a                          _WAL */.