/ Hex Artifact Content
Login

Artifact 839db09792fead5052bb35e533fa485e134913d547d05b5f42e537b73e63f07a:


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 20   be at least 3. 
34c0: 20 54 68 65 20 64 65 66 61 75 6c 74 0a 2a 2a 20   The default.** 
34d0: 69 73 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c  is SQLITE_SHM_NL
34e0: 4f 43 4b 3d 3d 38 20 61 6e 64 20 20 57 41 4c 5f  OCK==8 and  WAL_
34f0: 4e 52 45 41 44 45 52 3d 3d 35 2e 0a 2a 2f 0a 23  NREADER==5..*/.#
3500: 64 65 66 69 6e 65 20 57 41 4c 5f 57 52 49 54 45  define WAL_WRITE
3510: 5f 4c 4f 43 4b 20 20 20 20 20 20 20 20 20 30 0a  _LOCK         0.
3520: 23 64 65 66 69 6e 65 20 57 41 4c 5f 41 4c 4c 5f  #define WAL_ALL_
3530: 42 55 54 5f 57 52 49 54 45 20 20 20 20 20 20 31  BUT_WRITE      1
3540: 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 43 4b 50  .#define WAL_CKP
3550: 54 5f 4c 4f 43 4b 20 20 20 20 20 20 20 20 20 20  T_LOCK          
3560: 31 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 52 45  1.#define WAL_RE
3570: 43 4f 56 45 52 5f 4c 4f 43 4b 20 20 20 20 20 20  COVER_LOCK      
3580: 20 32 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 52   2.#define WAL_R
3590: 45 41 44 5f 4c 4f 43 4b 28 49 29 20 20 20 20 20  EAD_LOCK(I)     
35a0: 20 20 28 33 2b 28 49 29 29 0a 23 64 65 66 69 6e    (3+(I)).#defin
35b0: 65 20 57 41 4c 5f 4e 52 45 41 44 45 52 20 20 20  e WAL_NREADER   
35c0: 20 20 20 20 20 20 20 20 20 28 53 51 4c 49 54 45           (SQLITE
35d0: 5f 53 48 4d 5f 4e 4c 4f 43 4b 2d 33 29 0a 0a 0a  _SHM_NLOCK-3)...
35e0: 2f 2a 20 4f 62 6a 65 63 74 20 64 65 63 6c 61 72  /* Object declar
35f0: 61 74 69 6f 6e 73 20 2a 2f 0a 74 79 70 65 64 65  ations */.typede
3600: 66 20 73 74 72 75 63 74 20 57 61 6c 49 6e 64 65  f struct WalInde
3610: 78 48 64 72 20 57 61 6c 49 6e 64 65 78 48 64 72  xHdr WalIndexHdr
3620: 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ;.typedef struct
3630: 20 57 61 6c 49 74 65 72 61 74 6f 72 20 57 61 6c   WalIterator Wal
3640: 49 74 65 72 61 74 6f 72 3b 0a 74 79 70 65 64 65  Iterator;.typede
3650: 66 20 73 74 72 75 63 74 20 57 61 6c 43 6b 70 74  f struct WalCkpt
3660: 49 6e 66 6f 20 57 61 6c 43 6b 70 74 49 6e 66 6f  Info WalCkptInfo
3670: 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 66 6f  ;.../*.** The fo
3680: 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 68  llowing object h
3690: 6f 6c 64 73 20 61 20 63 6f 70 79 20 6f 66 20 74  olds a copy of t
36a0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
36b0: 64 65 72 20 63 6f 6e 74 65 6e 74 2e 0a 2a 2a 0a  der content..**.
36c0: 2a 2a 20 54 68 65 20 61 63 74 75 61 6c 20 68 65  ** The actual he
36d0: 61 64 65 72 20 69 6e 20 74 68 65 20 77 61 6c 2d  ader in the wal-
36e0: 69 6e 64 65 78 20 63 6f 6e 73 69 73 74 73 20 6f  index consists o
36f0: 66 20 74 77 6f 20 63 6f 70 69 65 73 20 6f 66 20  f two copies of 
3700: 74 68 69 73 0a 2a 2a 20 6f 62 6a 65 63 74 20 66  this.** object f
3710: 6f 6c 6c 6f 77 65 64 20 62 79 20 6f 6e 65 20 69  ollowed by one i
3720: 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 57  nstance of the W
3730: 61 6c 43 6b 70 74 49 6e 66 6f 20 6f 62 6a 65 63  alCkptInfo objec
3740: 74 2e 0a 2a 2a 20 46 6f 72 20 61 6c 6c 20 76 65  t..** For all ve
3750: 72 73 69 6f 6e 73 20 6f 66 20 53 51 4c 69 74 65  rsions of SQLite
3760: 20 74 68 72 6f 75 67 68 20 33 2e 31 30 2e 30 20   through 3.10.0 
3770: 61 6e 64 20 70 72 6f 62 61 62 6c 79 20 62 65 79  and probably bey
3780: 6f 6e 64 2c 0a 2a 2a 20 74 68 65 20 6c 6f 63 6b  ond,.** the lock
3790: 69 6e 67 20 62 79 74 65 73 20 28 57 61 6c 43 6b  ing bytes (WalCk
37a0: 70 74 49 6e 66 6f 2e 61 4c 6f 63 6b 29 20 73 74  ptInfo.aLock) st
37b0: 61 72 74 20 61 74 20 6f 66 66 73 65 74 20 31 32  art at offset 12
37c0: 30 20 61 6e 64 0a 2a 2a 20 74 68 65 20 74 6f 74  0 and.** the tot
37d0: 61 6c 20 68 65 61 64 65 72 20 73 69 7a 65 20 69  al header size i
37e0: 73 20 31 33 36 20 62 79 74 65 73 2e 0a 2a 2a 0a  s 136 bytes..**.
37f0: 2a 2a 20 54 68 65 20 73 7a 50 61 67 65 20 76 61  ** The szPage va
3800: 6c 75 65 20 63 61 6e 20 62 65 20 61 6e 79 20 70  lue can be any p
3810: 6f 77 65 72 20 6f 66 20 32 20 62 65 74 77 65 65  ower of 2 betwee
3820: 6e 20 35 31 32 20 61 6e 64 20 33 32 37 36 38 2c  n 512 and 32768,
3830: 20 69 6e 63 6c 75 73 69 76 65 2e 0a 2a 2a 20 4f   inclusive..** O
3840: 72 20 69 74 20 63 61 6e 20 62 65 20 31 20 74 6f  r it can be 1 to
3850: 20 72 65 70 72 65 73 65 6e 74 20 61 20 36 35 35   represent a 655
3860: 33 36 2d 62 79 74 65 20 70 61 67 65 2e 20 20 54  36-byte page.  T
3870: 68 65 20 6c 61 74 74 65 72 20 63 61 73 65 20 77  he latter case w
3880: 61 73 0a 2a 2a 20 61 64 64 65 64 20 69 6e 20 33  as.** added in 3
3890: 2e 37 2e 31 20 77 68 65 6e 20 73 75 70 70 6f 72  .7.1 when suppor
38a0: 74 20 66 6f 72 20 36 34 4b 20 70 61 67 65 73 20  t for 64K pages 
38b0: 77 61 73 20 61 64 64 65 64 2e 20 20 0a 2a 2f 0a  was added.  .*/.
38c0: 73 74 72 75 63 74 20 57 61 6c 49 6e 64 65 78 48  struct WalIndexH
38d0: 64 72 20 7b 0a 20 20 75 33 32 20 69 56 65 72 73  dr {.  u32 iVers
38e0: 69 6f 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20  ion;            
38f0: 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 2d 69 6e         /* Wal-in
3900: 64 65 78 20 76 65 72 73 69 6f 6e 20 2a 2f 0a 20  dex version */. 
3910: 20 75 33 32 20 75 6e 75 73 65 64 3b 20 20 20 20   u32 unused;    
3920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3930: 20 2f 2a 20 55 6e 75 73 65 64 20 28 70 61 64 64   /* Unused (padd
3940: 69 6e 67 29 20 66 69 65 6c 64 20 2a 2f 0a 20 20  ing) field */.  
3950: 75 33 32 20 69 43 68 61 6e 67 65 3b 20 20 20 20  u32 iChange;    
3960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3970: 2f 2a 20 43 6f 75 6e 74 65 72 20 69 6e 63 72 65  /* Counter incre
3980: 6d 65 6e 74 65 64 20 65 61 63 68 20 74 72 61 6e  mented each tran
3990: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 75 38 20  saction */.  u8 
39a0: 69 73 49 6e 69 74 3b 20 20 20 20 20 20 20 20 20  isInit;         
39b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
39c0: 31 20 77 68 65 6e 20 69 6e 69 74 69 61 6c 69 7a  1 when initializ
39d0: 65 64 20 2a 2f 0a 20 20 75 38 20 62 69 67 45 6e  ed */.  u8 bigEn
39e0: 64 43 6b 73 75 6d 3b 20 20 20 20 20 20 20 20 20  dCksum;         
39f0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
3a00: 69 66 20 63 68 65 63 6b 73 75 6d 73 20 69 6e 20  if checksums in 
3a10: 57 41 4c 20 61 72 65 20 62 69 67 2d 65 6e 64 69  WAL are big-endi
3a20: 61 6e 20 2a 2f 0a 20 20 75 31 36 20 73 7a 50 61  an */.  u16 szPa
3a30: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
3a40: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
3a50: 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 69 6e  ase page size in
3a60: 20 62 79 74 65 73 2e 20 31 3d 3d 36 34 4b 20 2a   bytes. 1==64K *
3a70: 2f 0a 20 20 75 33 32 20 6d 78 46 72 61 6d 65 3b  /.  u32 mxFrame;
3a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a90: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20      /* Index of 
3aa0: 6c 61 73 74 20 76 61 6c 69 64 20 66 72 61 6d 65  last valid frame
3ab0: 20 69 6e 20 74 68 65 20 57 41 4c 20 2a 2f 0a 20   in the WAL */. 
3ac0: 20 75 33 32 20 6e 50 61 67 65 3b 20 20 20 20 20   u32 nPage;     
3ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3ae0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 64 61 74 61   /* Size of data
3af0: 62 61 73 65 20 69 6e 20 70 61 67 65 73 20 2a 2f  base in pages */
3b00: 0a 20 20 75 33 32 20 61 46 72 61 6d 65 43 6b 73  .  u32 aFrameCks
3b10: 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  um[2];          
3b20: 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 6f     /* Checksum o
3b30: 66 20 6c 61 73 74 20 66 72 61 6d 65 20 69 6e 20  f last frame in 
3b40: 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 61 53 61  log */.  u32 aSa
3b50: 6c 74 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  lt[2];          
3b60: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 77 6f 20           /* Two 
3b70: 73 61 6c 74 20 76 61 6c 75 65 73 20 63 6f 70 69  salt values copi
3b80: 65 64 20 66 72 6f 6d 20 57 41 4c 20 68 65 61 64  ed from WAL head
3b90: 65 72 20 2a 2f 0a 20 20 75 33 32 20 61 43 6b 73  er */.  u32 aCks
3ba0: 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  um[2];          
3bb0: 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b          /* Check
3bc0: 73 75 6d 20 6f 76 65 72 20 61 6c 6c 20 70 72 69  sum over all pri
3bd0: 6f 72 20 66 69 65 6c 64 73 20 2a 2f 0a 7d 3b 0a  or fields */.};.
3be0: 0a 2f 2a 0a 2a 2a 20 41 20 63 6f 70 79 20 6f 66  ./*.** A copy of
3bf0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f   the following o
3c00: 62 6a 65 63 74 20 6f 63 63 75 72 73 20 69 6e 20  bject occurs in 
3c10: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 6d  the wal-index im
3c20: 6d 65 64 69 61 74 65 6c 79 0a 2a 2a 20 66 6f 6c  mediately.** fol
3c30: 6c 6f 77 69 6e 67 20 74 68 65 20 73 65 63 6f 6e  lowing the secon
3c40: 64 20 63 6f 70 79 20 6f 66 20 74 68 65 20 57 61  d copy of the Wa
3c50: 6c 49 6e 64 65 78 48 64 72 2e 20 20 54 68 69 73  lIndexHdr.  This
3c60: 20 6f 62 6a 65 63 74 20 73 74 6f 72 65 73 0a 2a   object stores.*
3c70: 2a 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73  * information us
3c80: 65 64 20 62 79 20 63 68 65 63 6b 70 6f 69 6e 74  ed by checkpoint
3c90: 2e 0a 2a 2a 0a 2a 2a 20 6e 42 61 63 6b 66 69 6c  ..**.** nBackfil
3ca0: 6c 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  l is the number 
3cb0: 6f 66 20 66 72 61 6d 65 73 20 69 6e 20 74 68 65  of frames in the
3cc0: 20 57 41 4c 20 74 68 61 74 20 68 61 76 65 20 62   WAL that have b
3cd0: 65 65 6e 20 77 72 69 74 74 65 6e 0a 2a 2a 20 62  een written.** b
3ce0: 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74  ack into the dat
3cf0: 61 62 61 73 65 2e 20 28 57 65 20 63 61 6c 6c 20  abase. (We call 
3d00: 74 68 65 20 61 63 74 20 6f 66 20 6d 6f 76 69 6e  the act of movin
3d10: 67 20 63 6f 6e 74 65 6e 74 20 66 72 6f 6d 20 57  g content from W
3d20: 41 4c 20 74 6f 0a 2a 2a 20 64 61 74 61 62 61 73  AL to.** databas
3d30: 65 20 22 62 61 63 6b 66 69 6c 6c 69 6e 67 22 2e  e "backfilling".
3d40: 29 20 20 54 68 65 20 6e 42 61 63 6b 66 69 6c 6c  )  The nBackfill
3d50: 20 6e 75 6d 62 65 72 20 69 73 20 6e 65 76 65 72   number is never
3d60: 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a   greater than.**
3d70: 20 57 61 6c 49 6e 64 65 78 48 64 72 2e 6d 78 46   WalIndexHdr.mxF
3d80: 72 61 6d 65 2e 20 20 6e 42 61 63 6b 66 69 6c 6c  rame.  nBackfill
3d90: 20 63 61 6e 20 6f 6e 6c 79 20 62 65 20 69 6e 63   can only be inc
3da0: 72 65 61 73 65 64 20 62 79 20 74 68 72 65 61 64  reased by thread
3db0: 73 0a 2a 2a 20 68 6f 6c 64 69 6e 67 20 74 68 65  s.** holding the
3dc0: 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 6c   WAL_CKPT_LOCK l
3dd0: 6f 63 6b 20 28 77 68 69 63 68 20 69 6e 63 6c 75  ock (which inclu
3de0: 64 65 73 20 61 20 72 65 63 6f 76 65 72 79 20 74  des a recovery t
3df0: 68 72 65 61 64 29 2e 0a 2a 2a 20 48 6f 77 65 76  hread)..** Howev
3e00: 65 72 2c 20 61 20 57 41 4c 5f 57 52 49 54 45 5f  er, a WAL_WRITE_
3e10: 4c 4f 43 4b 20 74 68 72 65 61 64 20 63 61 6e 20  LOCK thread can 
3e20: 6d 6f 76 65 20 74 68 65 20 76 61 6c 75 65 20 6f  move the value o
3e30: 66 20 6e 42 61 63 6b 66 69 6c 6c 20 66 72 6f 6d  f nBackfill from
3e40: 0a 2a 2a 20 6d 78 46 72 61 6d 65 20 62 61 63 6b  .** mxFrame back
3e50: 20 74 6f 20 7a 65 72 6f 20 77 68 65 6e 20 74 68   to zero when th
3e60: 65 20 57 41 4c 20 69 73 20 72 65 73 65 74 2e 0a  e WAL is reset..
3e70: 2a 2a 0a 2a 2a 20 6e 42 61 63 6b 66 69 6c 6c 41  **.** nBackfillA
3e80: 74 74 65 6d 70 74 65 64 20 69 73 20 74 68 65 20  ttempted is the 
3e90: 6c 61 72 67 65 73 74 20 76 61 6c 75 65 20 6f 66  largest value of
3ea0: 20 6e 42 61 63 6b 66 69 6c 6c 20 74 68 61 74 20   nBackfill that 
3eb0: 61 20 63 68 65 63 6b 70 6f 69 6e 74 0a 2a 2a 20  a checkpoint.** 
3ec0: 68 61 73 20 61 74 74 65 6d 70 74 65 64 20 74 6f  has attempted to
3ed0: 20 61 63 68 69 65 76 65 2e 20 20 4e 6f 72 6d 61   achieve.  Norma
3ee0: 6c 6c 79 20 6e 42 61 63 6b 66 69 6c 6c 3d 3d 6e  lly nBackfill==n
3ef0: 42 61 63 6b 66 69 6c 6c 41 74 65 6d 70 74 65 64  BackfillAtempted
3f00: 2c 20 68 6f 77 65 76 65 72 0a 2a 2a 20 74 68 65  , however.** the
3f10: 20 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70   nBackfillAttemp
3f20: 74 65 64 20 69 73 20 73 65 74 20 62 65 66 6f 72  ted is set befor
3f30: 65 20 61 6e 79 20 62 61 63 6b 66 69 6c 6c 69 6e  e any backfillin
3f40: 67 20 69 73 20 64 6f 6e 65 20 61 6e 64 20 74 68  g is done and th
3f50: 65 0a 2a 2a 20 6e 42 61 63 6b 66 69 6c 6c 20 69  e.** nBackfill i
3f60: 73 20 6f 6e 6c 79 20 73 65 74 20 61 66 74 65 72  s only set after
3f70: 20 61 6c 6c 20 62 61 63 6b 66 69 6c 6c 69 6e 67   all backfilling
3f80: 20 63 6f 6d 70 6c 65 74 65 73 2e 20 20 53 6f 20   completes.  So 
3f90: 69 66 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 0a  if a checkpoint.
3fa0: 2a 2a 20 63 72 61 73 68 65 73 2c 20 6e 42 61 63  ** crashes, nBac
3fb0: 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 6d  kfillAttempted m
3fc0: 69 67 68 74 20 62 65 20 6c 61 72 67 65 72 20 74  ight be larger t
3fd0: 68 61 6e 20 6e 42 61 63 6b 66 69 6c 6c 2e 20 20  han nBackfill.  
3fe0: 54 68 65 0a 2a 2a 20 57 61 6c 49 6e 64 65 78 48  The.** WalIndexH
3ff0: 64 72 2e 6d 78 46 72 61 6d 65 20 6d 75 73 74 20  dr.mxFrame must 
4000: 6e 65 76 65 72 20 62 65 20 6c 65 73 73 20 74 68  never be less th
4010: 61 6e 20 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65  an nBackfillAtte
4020: 6d 70 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  mpted..**.** The
4030: 20 61 4c 6f 63 6b 5b 5d 20 66 69 65 6c 64 20 69   aLock[] field i
4040: 73 20 61 20 73 65 74 20 6f 66 20 62 79 74 65 73  s a set of bytes
4050: 20 75 73 65 64 20 66 6f 72 20 6c 6f 63 6b 69 6e   used for lockin
4060: 67 2e 20 20 54 68 65 73 65 20 62 79 74 65 73 20  g.  These bytes 
4070: 73 68 6f 75 6c 64 0a 2a 2a 20 6e 65 76 65 72 20  should.** never 
4080: 62 65 20 72 65 61 64 20 6f 72 20 77 72 69 74 74  be read or writt
4090: 65 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20  en..**.** There 
40a0: 69 73 20 6f 6e 65 20 65 6e 74 72 79 20 69 6e 20  is one entry in 
40b0: 61 52 65 61 64 4d 61 72 6b 5b 5d 20 66 6f 72 20  aReadMark[] for 
40c0: 65 61 63 68 20 72 65 61 64 65 72 20 6c 6f 63 6b  each reader lock
40d0: 2e 20 20 49 66 20 61 20 72 65 61 64 65 72 0a 2a  .  If a reader.*
40e0: 2a 20 68 6f 6c 64 73 20 72 65 61 64 2d 6c 6f 63  * holds read-loc
40f0: 6b 20 4b 2c 20 74 68 65 6e 20 74 68 65 20 76 61  k K, then the va
4100: 6c 75 65 20 69 6e 20 61 52 65 61 64 4d 61 72 6b  lue in aReadMark
4110: 5b 4b 5d 20 69 73 20 6e 6f 20 67 72 65 61 74 65  [K] is no greate
4120: 72 20 74 68 61 6e 0a 2a 2a 20 74 68 65 20 6d 78  r than.** the mx
4130: 46 72 61 6d 65 20 66 6f 72 20 74 68 61 74 20 72  Frame for that r
4140: 65 61 64 65 72 2e 20 20 54 68 65 20 76 61 6c 75  eader.  The valu
4150: 65 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55  e READMARK_NOT_U
4160: 53 45 44 20 28 30 78 66 66 66 66 66 66 66 66 29  SED (0xffffffff)
4170: 0a 2a 2a 20 66 6f 72 20 61 6e 79 20 61 52 65 61  .** for any aRea
4180: 64 4d 61 72 6b 5b 5d 20 6d 65 61 6e 73 20 74 68  dMark[] means th
4190: 61 74 20 65 6e 74 72 79 20 69 73 20 75 6e 75 73  at entry is unus
41a0: 65 64 2e 20 20 61 52 65 61 64 4d 61 72 6b 5b 30  ed.  aReadMark[0
41b0: 5d 20 69 73 20 0a 2a 2a 20 61 20 73 70 65 63 69  ] is .** a speci
41c0: 61 6c 20 63 61 73 65 3b 20 69 74 73 20 76 61 6c  al case; its val
41d0: 75 65 20 69 73 20 6e 65 76 65 72 20 75 73 65 64  ue is never used
41e0: 20 61 6e 64 20 69 74 20 65 78 69 73 74 73 20 61   and it exists a
41f0: 73 20 61 20 70 6c 61 63 65 2d 68 6f 6c 64 65 72  s a place-holder
4200: 0a 2a 2a 20 74 6f 20 61 76 6f 69 64 20 68 61 76  .** to avoid hav
4210: 69 6e 67 20 74 6f 20 6f 66 66 73 65 74 20 61 52  ing to offset aR
4220: 65 61 64 4d 61 72 6b 5b 5d 20 69 6e 64 65 78 73  eadMark[] indexs
4230: 20 62 79 20 6f 6e 65 2e 20 20 52 65 61 64 65 72   by one.  Reader
4240: 73 20 68 6f 6c 64 69 6e 67 0a 2a 2a 20 57 41 4c  s holding.** WAL
4250: 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20 61 6c  _READ_LOCK(0) al
4260: 77 61 79 73 20 69 67 6e 6f 72 65 20 74 68 65 20  ways ignore the 
4270: 65 6e 74 69 72 65 20 57 41 4c 20 61 6e 64 20 72  entire WAL and r
4280: 65 61 64 20 61 6c 6c 20 63 6f 6e 74 65 6e 74 0a  ead all content.
4290: 2a 2a 20 64 69 72 65 63 74 6c 79 20 66 72 6f 6d  ** directly from
42a0: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a   the database..*
42b0: 2a 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65 20 6f  *.** The value o
42c0: 66 20 61 52 65 61 64 4d 61 72 6b 5b 4b 5d 20 6d  f aReadMark[K] m
42d0: 61 79 20 6f 6e 6c 79 20 62 65 20 63 68 61 6e 67  ay only be chang
42e0: 65 64 20 62 79 20 61 20 74 68 72 65 61 64 20 74  ed by a thread t
42f0: 68 61 74 0a 2a 2a 20 69 73 20 68 6f 6c 64 69 6e  hat.** is holdin
4300: 67 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c  g an exclusive l
4310: 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52 45 41 44 5f  ock on WAL_READ_
4320: 4c 4f 43 4b 28 4b 29 2e 20 20 54 68 75 73 2c 20  LOCK(K).  Thus, 
4330: 74 68 65 20 76 61 6c 75 65 20 6f 66 0a 2a 2a 20  the value of.** 
4340: 61 52 65 61 64 4d 61 72 6b 5b 4b 5d 20 63 61 6e  aReadMark[K] can
4350: 6e 6f 74 20 63 68 61 6e 67 65 64 20 77 68 69 6c  not changed whil
4360: 65 20 74 68 65 72 65 20 69 73 20 61 20 72 65 61  e there is a rea
4370: 64 65 72 20 69 73 20 75 73 69 6e 67 20 74 68 61  der is using tha
4380: 74 20 6d 61 72 6b 0a 2a 2a 20 73 69 6e 63 65 20  t mark.** since 
4390: 74 68 65 20 72 65 61 64 65 72 20 77 69 6c 6c 20  the reader will 
43a0: 62 65 20 68 6f 6c 64 69 6e 67 20 61 20 73 68 61  be holding a sha
43b0: 72 65 64 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f  red lock on WAL_
43c0: 52 45 41 44 5f 4c 4f 43 4b 28 4b 29 2e 0a 2a 2a  READ_LOCK(K)..**
43d0: 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b 70 6f 69  .** The checkpoi
43e0: 6e 74 65 72 20 6d 61 79 20 6f 6e 6c 79 20 74 72  nter may only tr
43f0: 61 6e 73 66 65 72 20 66 72 61 6d 65 73 20 66 72  ansfer frames fr
4400: 6f 6d 20 57 41 4c 20 74 6f 20 64 61 74 61 62 61  om WAL to databa
4410: 73 65 20 77 68 65 72 65 0a 2a 2a 20 74 68 65 20  se where.** the 
4420: 66 72 61 6d 65 20 6e 75 6d 62 65 72 73 20 61 72  frame numbers ar
4430: 65 20 6c 65 73 73 20 74 68 61 6e 20 6f 72 20 65  e less than or e
4440: 71 75 61 6c 20 74 6f 20 65 76 65 72 79 20 61 52  qual to every aR
4450: 65 61 64 4d 61 72 6b 5b 5d 20 74 68 61 74 20 69  eadMark[] that i
4460: 73 0a 2a 2a 20 69 6e 20 75 73 65 20 28 74 68 61  s.** in use (tha
4470: 74 20 69 73 2c 20 65 76 65 72 79 20 61 52 65 61  t is, every aRea
4480: 64 4d 61 72 6b 5b 6a 5d 20 66 6f 72 20 77 68 69  dMark[j] for whi
4490: 63 68 20 74 68 65 72 65 20 69 73 20 61 20 63 6f  ch there is a co
44a0: 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20 57  rresponding.** W
44b0: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6a 29 29  AL_READ_LOCK(j))
44c0: 2e 20 20 4e 65 77 20 72 65 61 64 65 72 73 20 28  .  New readers (
44d0: 75 73 75 61 6c 6c 79 29 20 70 69 63 6b 20 74 68  usually) pick th
44e0: 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 77 69  e aReadMark[] wi
44f0: 74 68 20 74 68 65 0a 2a 2a 20 6c 61 72 67 65 73  th the.** larges
4500: 74 20 76 61 6c 75 65 20 61 6e 64 20 77 69 6c 6c  t value and will
4510: 20 69 6e 63 72 65 61 73 65 20 61 6e 20 75 6e 75   increase an unu
4520: 73 65 64 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20  sed aReadMark[] 
4530: 74 6f 20 6d 78 46 72 61 6d 65 20 69 66 20 74 68  to mxFrame if th
4540: 65 72 65 0a 2a 2a 20 69 73 20 6e 6f 74 20 61 6c  ere.** is not al
4550: 72 65 61 64 79 20 61 6e 20 61 52 65 61 64 4d 61  ready an aReadMa
4560: 72 6b 5b 5d 20 65 71 75 61 6c 20 74 6f 20 6d 78  rk[] equal to mx
4570: 46 72 61 6d 65 2e 20 20 54 68 65 20 65 78 63 65  Frame.  The exce
4580: 70 74 69 6f 6e 20 74 6f 20 74 68 65 0a 2a 2a 20  ption to the.** 
4590: 70 72 65 76 69 6f 75 73 20 73 65 6e 74 65 6e 63  previous sentenc
45a0: 65 20 69 73 20 77 68 65 6e 20 6e 42 61 63 6b 66  e is when nBackf
45b0: 69 6c 6c 20 65 71 75 61 6c 73 20 6d 78 46 72 61  ill equals mxFra
45c0: 6d 65 20 28 6d 65 61 6e 69 6e 67 20 74 68 61 74  me (meaning that
45d0: 20 65 76 65 72 79 74 68 69 6e 67 0a 2a 2a 20 69   everything.** i
45e0: 6e 20 74 68 65 20 57 41 4c 20 68 61 73 20 62 65  n the WAL has be
45f0: 65 6e 20 62 61 63 6b 66 69 6c 6c 65 64 20 69 6e  en backfilled in
4600: 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 29  to the database)
4610: 20 74 68 65 6e 20 6e 65 77 20 72 65 61 64 65 72   then new reader
4620: 73 0a 2a 2a 20 77 69 6c 6c 20 63 68 6f 6f 73 65  s.** will choose
4630: 20 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20 77 68   aReadMark[0] wh
4640: 69 63 68 20 68 61 73 20 76 61 6c 75 65 20 30 20  ich has value 0 
4650: 61 6e 64 20 68 65 6e 63 65 20 73 75 63 68 20 72  and hence such r
4660: 65 61 64 65 72 20 77 69 6c 6c 0a 2a 2a 20 67 65  eader will.** ge
4670: 74 20 61 6c 6c 20 74 68 65 69 72 20 61 6c 6c 20  t all their all 
4680: 63 6f 6e 74 65 6e 74 20 64 69 72 65 63 74 6c 79  content directly
4690: 20 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61   from the databa
46a0: 73 65 20 66 69 6c 65 20 61 6e 64 20 69 67 6e 6f  se file and igno
46b0: 72 65 20 0a 2a 2a 20 74 68 65 20 57 41 4c 2e 0a  re .** the WAL..
46c0: 2a 2a 0a 2a 2a 20 57 72 69 74 65 72 73 20 6e 6f  **.** Writers no
46d0: 72 6d 61 6c 6c 79 20 61 70 70 65 6e 64 20 6e 65  rmally append ne
46e0: 77 20 66 72 61 6d 65 73 20 74 6f 20 74 68 65 20  w frames to the 
46f0: 65 6e 64 20 6f 66 20 74 68 65 20 57 41 4c 2e 20  end of the WAL. 
4700: 20 48 6f 77 65 76 65 72 2c 0a 2a 2a 20 69 66 20   However,.** if 
4710: 6e 42 61 63 6b 66 69 6c 6c 20 65 71 75 61 6c 73  nBackfill equals
4720: 20 6d 78 46 72 61 6d 65 20 28 6d 65 61 6e 69 6e   mxFrame (meanin
4730: 67 20 74 68 61 74 20 61 6c 6c 20 57 41 4c 20 63  g that all WAL c
4740: 6f 6e 74 65 6e 74 20 68 61 73 20 62 65 65 6e 0a  ontent has been.
4750: 2a 2a 20 77 72 69 74 74 65 6e 20 62 61 63 6b 20  ** written back 
4760: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
4770: 65 29 20 61 6e 64 20 69 66 20 6e 6f 20 72 65 61  e) and if no rea
4780: 64 65 72 73 20 61 72 65 20 75 73 69 6e 67 20 74  ders are using t
4790: 68 65 20 57 41 4c 0a 2a 2a 20 28 69 6e 20 6f 74  he WAL.** (in ot
47a0: 68 65 72 20 77 6f 72 64 73 2c 20 69 66 20 74 68  her words, if th
47b0: 65 72 65 20 61 72 65 20 6e 6f 20 57 41 4c 5f 52  ere are no WAL_R
47c0: 45 41 44 5f 4c 4f 43 4b 28 69 29 20 77 68 65 72  EAD_LOCK(i) wher
47d0: 65 20 69 3e 30 29 20 74 68 65 6e 0a 2a 2a 20 74  e i>0) then.** t
47e0: 68 65 20 77 72 69 74 65 72 20 77 69 6c 6c 20 66  he writer will f
47f0: 69 72 73 74 20 22 72 65 73 65 74 22 20 74 68 65  irst "reset" the
4800: 20 57 41 4c 20 62 61 63 6b 20 74 6f 20 74 68 65   WAL back to the
4810: 20 62 65 67 69 6e 6e 69 6e 67 20 61 6e 64 20 73   beginning and s
4820: 74 61 72 74 0a 2a 2a 20 77 72 69 74 69 6e 67 20  tart.** writing 
4830: 6e 65 77 20 63 6f 6e 74 65 6e 74 20 62 65 67 69  new content begi
4840: 6e 6e 69 6e 67 20 61 74 20 66 72 61 6d 65 20 31  nning at frame 1
4850: 2e 0a 2a 2a 0a 2a 2a 20 57 65 20 61 73 73 75 6d  ..**.** We assum
4860: 65 20 74 68 61 74 20 33 32 2d 62 69 74 20 6c 6f  e that 32-bit lo
4870: 61 64 73 20 61 72 65 20 61 74 6f 6d 69 63 20 61  ads are atomic a
4880: 6e 64 20 73 6f 20 6e 6f 20 6c 6f 63 6b 73 20 61  nd so no locks a
4890: 72 65 20 6e 65 65 64 65 64 20 69 6e 0a 2a 2a 20  re needed in.** 
48a0: 6f 72 64 65 72 20 74 6f 20 72 65 61 64 20 66 72  order to read fr
48b0: 6f 6d 20 61 6e 79 20 61 52 65 61 64 4d 61 72 6b  om any aReadMark
48c0: 5b 5d 20 65 6e 74 72 69 65 73 2e 0a 2a 2f 0a 73  [] entries..*/.s
48d0: 74 72 75 63 74 20 57 61 6c 43 6b 70 74 49 6e 66  truct WalCkptInf
48e0: 6f 20 7b 0a 20 20 75 33 32 20 6e 42 61 63 6b 66  o {.  u32 nBackf
48f0: 69 6c 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  ill;            
4900: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
4910: 6f 66 20 57 41 4c 20 66 72 61 6d 65 73 20 62 61  of WAL frames ba
4920: 63 6b 66 69 6c 6c 65 64 20 69 6e 74 6f 20 44 42  ckfilled into DB
4930: 20 2a 2f 0a 20 20 75 33 32 20 61 52 65 61 64 4d   */.  u32 aReadM
4940: 61 72 6b 5b 57 41 4c 5f 4e 52 45 41 44 45 52 5d  ark[WAL_NREADER]
4950: 3b 20 20 20 20 20 2f 2a 20 52 65 61 64 65 72 20  ;     /* Reader 
4960: 6d 61 72 6b 73 20 2a 2f 0a 20 20 75 38 20 61 4c  marks */.  u8 aL
4970: 6f 63 6b 5b 53 51 4c 49 54 45 5f 53 48 4d 5f 4e  ock[SQLITE_SHM_N
4980: 4c 4f 43 4b 5d 3b 20 20 20 20 20 2f 2a 20 52 65  LOCK];     /* Re
4990: 73 65 72 76 65 64 20 73 70 61 63 65 20 66 6f 72  served space for
49a0: 20 6c 6f 63 6b 73 20 2a 2f 0a 20 20 75 33 32 20   locks */.  u32 
49b0: 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74  nBackfillAttempt
49c0: 65 64 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 57  ed;         /* W
49d0: 41 4c 20 66 72 61 6d 65 73 20 70 65 72 68 61 70  AL frames perhap
49e0: 73 20 77 72 69 74 74 65 6e 2c 20 6f 72 20 6d 61  s written, or ma
49f0: 79 62 65 20 6e 6f 74 20 2a 2f 0a 20 20 75 33 32  ybe not */.  u32
4a00: 20 6e 6f 74 55 73 65 64 30 3b 20 20 20 20 20 20   notUsed0;      
4a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4a20: 41 76 61 69 6c 61 62 6c 65 20 66 6f 72 20 66 75  Available for fu
4a30: 74 75 72 65 20 65 6e 68 61 6e 63 65 6d 65 6e 74  ture enhancement
4a40: 73 20 2a 2f 0a 7d 3b 0a 23 64 65 66 69 6e 65 20  s */.};.#define 
4a50: 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45  READMARK_NOT_USE
4a60: 44 20 20 30 78 66 66 66 66 66 66 66 66 0a 0a 0a  D  0xffffffff...
4a70: 2f 2a 20 41 20 62 6c 6f 63 6b 20 6f 66 20 57 41  /* A block of WA
4a80: 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 52 45 53 45  LINDEX_LOCK_RESE
4a90: 52 56 45 44 20 62 79 74 65 73 20 62 65 67 69 6e  RVED bytes begin
4aa0: 6e 69 6e 67 20 61 74 0a 2a 2a 20 57 41 4c 49 4e  ning at.** WALIN
4ab0: 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20  DEX_LOCK_OFFSET 
4ac0: 69 73 20 72 65 73 65 72 76 65 64 20 66 6f 72 20  is reserved for 
4ad0: 6c 6f 63 6b 73 2e 20 53 69 6e 63 65 20 73 6f 6d  locks. Since som
4ae0: 65 20 73 79 73 74 65 6d 73 0a 2a 2a 20 6f 6e 6c  e systems.** onl
4af0: 79 20 73 75 70 70 6f 72 74 20 6d 61 6e 64 61 74  y support mandat
4b00: 6f 72 79 20 66 69 6c 65 2d 6c 6f 63 6b 73 2c 20  ory file-locks, 
4b10: 77 65 20 64 6f 20 6e 6f 74 20 72 65 61 64 20 6f  we do not read o
4b20: 72 20 77 72 69 74 65 20 64 61 74 61 0a 2a 2a 20  r write data.** 
4b30: 66 72 6f 6d 20 74 68 65 20 72 65 67 69 6f 6e 20  from the region 
4b40: 6f 66 20 74 68 65 20 66 69 6c 65 20 6f 6e 20 77  of the file on w
4b50: 68 69 63 68 20 6c 6f 63 6b 73 20 61 72 65 20 61  hich locks are a
4b60: 70 70 6c 69 65 64 2e 0a 2a 2f 0a 23 64 65 66 69  pplied..*/.#defi
4b70: 6e 65 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b  ne WALINDEX_LOCK
4b80: 5f 4f 46 46 53 45 54 20 28 73 69 7a 65 6f 66 28  _OFFSET (sizeof(
4b90: 57 61 6c 49 6e 64 65 78 48 64 72 29 2a 32 2b 6f  WalIndexHdr)*2+o
4ba0: 66 66 73 65 74 6f 66 28 57 61 6c 43 6b 70 74 49  ffsetof(WalCkptI
4bb0: 6e 66 6f 2c 61 4c 6f 63 6b 29 29 0a 23 64 65 66  nfo,aLock)).#def
4bc0: 69 6e 65 20 57 41 4c 49 4e 44 45 58 5f 48 44 52  ine WALINDEX_HDR
4bd0: 5f 53 49 5a 45 20 20 20 20 28 73 69 7a 65 6f 66  _SIZE    (sizeof
4be0: 28 57 61 6c 49 6e 64 65 78 48 64 72 29 2a 32 2b  (WalIndexHdr)*2+
4bf0: 73 69 7a 65 6f 66 28 57 61 6c 43 6b 70 74 49 6e  sizeof(WalCkptIn
4c00: 66 6f 29 29 0a 0a 2f 2a 20 53 69 7a 65 20 6f 66  fo))../* Size of
4c10: 20 68 65 61 64 65 72 20 62 65 66 6f 72 65 20 65   header before e
4c20: 61 63 68 20 66 72 61 6d 65 20 69 6e 20 77 61 6c  ach frame in wal
4c30: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f   */.#define WAL_
4c40: 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 20 32 34  FRAME_HDRSIZE 24
4c50: 0a 0a 2f 2a 20 53 69 7a 65 20 6f 66 20 77 72 69  ../* Size of wri
4c60: 74 65 20 61 68 65 61 64 20 6c 6f 67 20 68 65 61  te ahead log hea
4c70: 64 65 72 2c 20 69 6e 63 6c 75 64 69 6e 67 20 63  der, including c
4c80: 68 65 63 6b 73 75 6d 2e 20 2a 2f 0a 2f 2a 20 23  hecksum. */./* #
4c90: 64 65 66 69 6e 65 20 57 41 4c 5f 48 44 52 53 49  define WAL_HDRSI
4ca0: 5a 45 20 32 34 20 2a 2f 0a 23 64 65 66 69 6e 65  ZE 24 */.#define
4cb0: 20 57 41 4c 5f 48 44 52 53 49 5a 45 20 33 32 0a   WAL_HDRSIZE 32.
4cc0: 0a 2f 2a 20 57 41 4c 20 6d 61 67 69 63 20 76 61  ./* WAL magic va
4cd0: 6c 75 65 2e 20 45 69 74 68 65 72 20 74 68 69 73  lue. Either this
4ce0: 20 76 61 6c 75 65 2c 20 6f 72 20 74 68 65 20 73   value, or the s
4cf0: 61 6d 65 20 76 61 6c 75 65 20 77 69 74 68 20 74  ame value with t
4d00: 68 65 20 6c 65 61 73 74 0a 2a 2a 20 73 69 67 6e  he least.** sign
4d10: 69 66 69 63 61 6e 74 20 62 69 74 20 61 6c 73 6f  ificant bit also
4d20: 20 73 65 74 20 28 57 41 4c 5f 4d 41 47 49 43 20   set (WAL_MAGIC 
4d30: 7c 20 30 78 30 30 30 30 30 30 30 31 29 20 69 73  | 0x00000001) is
4d40: 20 73 74 6f 72 65 64 20 69 6e 20 33 32 2d 62 69   stored in 32-bi
4d50: 74 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20  t.** big-endian 
4d60: 66 6f 72 6d 61 74 20 69 6e 20 74 68 65 20 66 69  format in the fi
4d70: 72 73 74 20 34 20 62 79 74 65 73 20 6f 66 20 61  rst 4 bytes of a
4d80: 20 57 41 4c 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a   WAL file..**.**
4d90: 20 49 66 20 74 68 65 20 4c 53 42 20 69 73 20 73   If the LSB is s
4da0: 65 74 2c 20 74 68 65 6e 20 74 68 65 20 63 68 65  et, then the che
4db0: 63 6b 73 75 6d 73 20 66 6f 72 20 65 61 63 68 20  cksums for each 
4dc0: 66 72 61 6d 65 20 77 69 74 68 69 6e 20 74 68 65  frame within the
4dd0: 20 57 41 4c 0a 2a 2a 20 66 69 6c 65 20 61 72 65   WAL.** file are
4de0: 20 63 61 6c 63 75 6c 61 74 65 64 20 62 79 20 74   calculated by t
4df0: 72 65 61 74 69 6e 67 20 61 6c 6c 20 64 61 74 61  reating all data
4e00: 20 61 73 20 61 6e 20 61 72 72 61 79 20 6f 66 20   as an array of 
4e10: 33 32 2d 62 69 74 20 0a 2a 2a 20 62 69 67 2d 65  32-bit .** big-e
4e20: 6e 64 69 61 6e 20 77 6f 72 64 73 2e 20 4f 74 68  ndian words. Oth
4e30: 65 72 77 69 73 65 2c 20 74 68 65 79 20 61 72 65  erwise, they are
4e40: 20 63 61 6c 63 75 6c 61 74 65 64 20 62 79 20 69   calculated by i
4e50: 6e 74 65 72 70 72 65 74 69 6e 67 20 0a 2a 2a 20  nterpreting .** 
4e60: 61 6c 6c 20 64 61 74 61 20 61 73 20 33 32 2d 62  all data as 32-b
4e70: 69 74 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61 6e  it little-endian
4e80: 20 77 6f 72 64 73 2e 0a 2a 2f 0a 23 64 65 66 69   words..*/.#defi
4e90: 6e 65 20 57 41 4c 5f 4d 41 47 49 43 20 30 78 33  ne WAL_MAGIC 0x3
4ea0: 37 37 66 30 36 38 32 0a 0a 2f 2a 0a 2a 2a 20 52  77f0682../*.** R
4eb0: 65 74 75 72 6e 20 74 68 65 20 6f 66 66 73 65 74  eturn the offset
4ec0: 20 6f 66 20 66 72 61 6d 65 20 69 46 72 61 6d 65   of frame iFrame
4ed0: 20 69 6e 20 74 68 65 20 77 72 69 74 65 2d 61 68   in the write-ah
4ee0: 65 61 64 20 6c 6f 67 20 66 69 6c 65 2c 20 0a 2a  ead log file, .*
4ef0: 2a 20 61 73 73 75 6d 69 6e 67 20 61 20 64 61 74  * assuming a dat
4f00: 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65 20  abase page size 
4f10: 6f 66 20 73 7a 50 61 67 65 20 62 79 74 65 73 2e  of szPage bytes.
4f20: 20 54 68 65 20 6f 66 66 73 65 74 20 72 65 74 75   The offset retu
4f30: 72 6e 65 64 0a 2a 2a 20 69 73 20 74 6f 20 74 68  rned.** is to th
4f40: 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 77  e start of the w
4f50: 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66  rite-ahead log f
4f60: 72 61 6d 65 2d 68 65 61 64 65 72 2e 0a 2a 2f 0a  rame-header..*/.
4f70: 23 64 65 66 69 6e 65 20 77 61 6c 46 72 61 6d 65  #define walFrame
4f80: 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2c 20 73  Offset(iFrame, s
4f90: 7a 50 61 67 65 29 20 28 20 20 20 20 20 20 20 20  zPage) (        
4fa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4fb0: 20 20 20 20 20 20 20 5c 0a 20 20 57 41 4c 5f 48         \.  WAL_H
4fc0: 44 52 53 49 5a 45 20 2b 20 28 28 69 46 72 61 6d  DRSIZE + ((iFram
4fd0: 65 29 2d 31 29 2a 28 69 36 34 29 28 28 73 7a 50  e)-1)*(i64)((szP
4fe0: 61 67 65 29 2b 57 41 4c 5f 46 52 41 4d 45 5f 48  age)+WAL_FRAME_H
4ff0: 44 52 53 49 5a 45 29 20 20 20 20 20 20 20 20 20  DRSIZE)         
5000: 5c 0a 29 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 6f 70  \.)../*.** An op
5010: 65 6e 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c  en write-ahead l
5020: 6f 67 20 66 69 6c 65 20 69 73 20 72 65 70 72 65  og file is repre
5030: 73 65 6e 74 65 64 20 62 79 20 61 6e 20 69 6e 73  sented by an ins
5040: 74 61 6e 63 65 20 6f 66 20 74 68 65 0a 2a 2a 20  tance of the.** 
5050: 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74  following object
5060: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61 6c 20  ..*/.struct Wal 
5070: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20  {.  sqlite3_vfs 
5080: 2a 70 56 66 73 3b 20 20 20 20 20 20 20 20 20 2f  *pVfs;         /
5090: 2a 20 54 68 65 20 56 46 53 20 75 73 65 64 20 74  * The VFS used t
50a0: 6f 20 63 72 65 61 74 65 20 70 44 62 46 64 20 2a  o create pDbFd *
50b0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  /.  sqlite3_file
50c0: 20 2a 70 44 62 46 64 3b 20 20 20 20 20 20 20 2f   *pDbFd;       /
50d0: 2a 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 66 6f  * File handle fo
50e0: 72 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  r the database f
50f0: 69 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ile */.  sqlite3
5100: 5f 66 69 6c 65 20 2a 70 57 61 6c 46 64 3b 20 20  _file *pWalFd;  
5110: 20 20 20 20 2f 2a 20 46 69 6c 65 20 68 61 6e 64      /* File hand
5120: 6c 65 20 66 6f 72 20 57 41 4c 20 66 69 6c 65 20  le for WAL file 
5130: 2a 2f 0a 20 20 75 33 32 20 69 43 61 6c 6c 62 61  */.  u32 iCallba
5140: 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ck;             
5150: 2f 2a 20 56 61 6c 75 65 20 74 6f 20 70 61 73 73  /* Value to pass
5160: 20 74 6f 20 6c 6f 67 20 63 61 6c 6c 62 61 63 6b   to log callback
5170: 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20 69 36 34   (or 0) */.  i64
5180: 20 6d 78 57 61 6c 53 69 7a 65 3b 20 20 20 20 20   mxWalSize;     
5190: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 6e 63          /* Trunc
51a0: 61 74 65 20 57 41 4c 20 74 6f 20 74 68 69 73 20  ate WAL to this 
51b0: 73 69 7a 65 20 75 70 6f 6e 20 72 65 73 65 74 20  size upon reset 
51c0: 2a 2f 0a 20 20 69 6e 74 20 6e 57 69 44 61 74 61  */.  int nWiData
51d0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
51e0: 2f 2a 20 53 69 7a 65 20 6f 66 20 61 72 72 61 79  /* Size of array
51f0: 20 61 70 57 69 44 61 74 61 20 2a 2f 0a 20 20 69   apWiData */.  i
5200: 6e 74 20 73 7a 46 69 72 73 74 42 6c 6f 63 6b 3b  nt szFirstBlock;
5210: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
5220: 65 20 6f 66 20 66 69 72 73 74 20 62 6c 6f 63 6b  e of first block
5230: 20 77 72 69 74 74 65 6e 20 74 6f 20 57 41 4c 20   written to WAL 
5240: 66 69 6c 65 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  file */.  volati
5250: 6c 65 20 75 33 32 20 2a 2a 61 70 57 69 44 61 74  le u32 **apWiDat
5260: 61 3b 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20  a;   /* Pointer 
5270: 74 6f 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e  to wal-index con
5280: 74 65 6e 74 20 69 6e 20 6d 65 6d 6f 72 79 20 2a  tent in memory *
5290: 2f 0a 20 20 75 33 32 20 73 7a 50 61 67 65 3b 20  /.  u32 szPage; 
52a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
52b0: 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20  * Database page 
52c0: 73 69 7a 65 20 2a 2f 0a 20 20 69 31 36 20 72 65  size */.  i16 re
52d0: 61 64 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20  adLock;         
52e0: 20 20 20 20 20 2f 2a 20 57 68 69 63 68 20 72 65       /* Which re
52f0: 61 64 20 6c 6f 63 6b 20 69 73 20 62 65 69 6e 67  ad lock is being
5300: 20 68 65 6c 64 2e 20 20 2d 31 20 66 6f 72 20 6e   held.  -1 for n
5310: 6f 6e 65 20 2a 2f 0a 20 20 75 38 20 73 79 6e 63  one */.  u8 sync
5320: 46 6c 61 67 73 3b 20 20 20 20 20 20 20 20 20 20  Flags;          
5330: 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20      /* Flags to 
5340: 75 73 65 20 74 6f 20 73 79 6e 63 20 68 65 61 64  use to sync head
5350: 65 72 20 77 72 69 74 65 73 20 2a 2f 0a 20 20 75  er writes */.  u
5360: 38 20 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3b  8 exclusiveMode;
5370: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 6e            /* Non
5380: 2d 7a 65 72 6f 20 69 66 20 63 6f 6e 6e 65 63 74  -zero if connect
5390: 69 6f 6e 20 69 73 20 69 6e 20 65 78 63 6c 75 73  ion is in exclus
53a0: 69 76 65 20 6d 6f 64 65 20 2a 2f 0a 20 20 75 38  ive mode */.  u8
53b0: 20 77 72 69 74 65 4c 6f 63 6b 3b 20 20 20 20 20   writeLock;     
53c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
53d0: 20 69 66 20 69 6e 20 61 20 77 72 69 74 65 20 74   if in a write t
53e0: 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20  ransaction */.  
53f0: 75 38 20 63 6b 70 74 4c 6f 63 6b 3b 20 20 20 20  u8 ckptLock;    
5400: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
5410: 75 65 20 69 66 20 68 6f 6c 64 69 6e 67 20 61 20  ue if holding a 
5420: 63 68 65 63 6b 70 6f 69 6e 74 20 6c 6f 63 6b 20  checkpoint lock 
5430: 2a 2f 0a 20 20 75 38 20 72 65 61 64 4f 6e 6c 79  */.  u8 readOnly
5440: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
5450: 2f 2a 20 57 41 4c 5f 52 44 57 52 2c 20 57 41 4c  /* WAL_RDWR, WAL
5460: 5f 52 44 4f 4e 4c 59 2c 20 6f 72 20 57 41 4c 5f  _RDONLY, or WAL_
5470: 53 48 4d 5f 52 44 4f 4e 4c 59 20 2a 2f 0a 20 20  SHM_RDONLY */.  
5480: 75 38 20 74 72 75 6e 63 61 74 65 4f 6e 43 6f 6d  u8 truncateOnCom
5490: 6d 69 74 3b 20 20 20 20 20 20 20 2f 2a 20 54 72  mit;       /* Tr
54a0: 75 65 20 74 6f 20 74 72 75 6e 63 61 74 65 20 57  ue to truncate W
54b0: 41 4c 20 66 69 6c 65 20 6f 6e 20 63 6f 6d 6d 69  AL file on commi
54c0: 74 20 2a 2f 0a 20 20 75 38 20 73 79 6e 63 48 65  t */.  u8 syncHe
54d0: 61 64 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ader;           
54e0: 20 20 2f 2a 20 46 73 79 6e 63 20 74 68 65 20 57    /* Fsync the W
54f0: 41 4c 20 68 65 61 64 65 72 20 69 66 20 74 72 75  AL header if tru
5500: 65 20 2a 2f 0a 20 20 75 38 20 70 61 64 54 6f 53  e */.  u8 padToS
5510: 65 63 74 6f 72 42 6f 75 6e 64 61 72 79 3b 20 20  ectorBoundary;  
5520: 20 20 2f 2a 20 50 61 64 20 74 72 61 6e 73 61 63    /* Pad transac
5530: 74 69 6f 6e 73 20 6f 75 74 20 74 6f 20 74 68 65  tions out to the
5540: 20 6e 65 78 74 20 73 65 63 74 6f 72 20 2a 2f 0a   next sector */.
5550: 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20 68 64    WalIndexHdr hd
5560: 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  r;           /* 
5570: 57 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  Wal-index header
5580: 20 66 6f 72 20 63 75 72 72 65 6e 74 20 74 72 61   for current tra
5590: 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 75 33  nsaction */.  u3
55a0: 32 20 6d 69 6e 46 72 61 6d 65 3b 20 20 20 20 20  2 minFrame;     
55b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 67 6e 6f           /* Igno
55c0: 72 65 20 77 61 6c 20 66 72 61 6d 65 73 20 62 65  re wal frames be
55d0: 66 6f 72 65 20 74 68 69 73 20 6f 6e 65 20 2a 2f  fore this one */
55e0: 0a 20 20 75 33 32 20 69 52 65 43 6b 73 75 6d 3b  .  u32 iReCksum;
55f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5600: 20 4f 6e 20 63 6f 6d 6d 69 74 2c 20 72 65 63 61   On commit, reca
5610: 6c 63 75 6c 61 74 65 20 63 68 65 63 6b 73 75 6d  lculate checksum
5620: 73 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f 0a 20  s from here */. 
5630: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 57 61   const char *zWa
5640: 6c 4e 61 6d 65 3b 20 20 20 20 20 20 2f 2a 20 4e  lName;      /* N
5650: 61 6d 65 20 6f 66 20 57 41 4c 20 66 69 6c 65 20  ame of WAL file 
5660: 2a 2f 0a 20 20 75 33 32 20 6e 43 6b 70 74 3b 20  */.  u32 nCkpt; 
5670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5680: 2f 2a 20 43 68 65 63 6b 70 6f 69 6e 74 20 73 65  /* Checkpoint se
5690: 71 75 65 6e 63 65 20 63 6f 75 6e 74 65 72 20 69  quence counter i
56a0: 6e 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  n the wal-header
56b0: 20 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c 49 54   */.#ifdef SQLIT
56c0: 45 5f 44 45 42 55 47 0a 20 20 75 38 20 6c 6f 63  E_DEBUG.  u8 loc
56d0: 6b 45 72 72 6f 72 3b 20 20 20 20 20 20 20 20 20  kError;         
56e0: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
56f0: 61 20 6c 6f 63 6b 69 6e 67 20 65 72 72 6f 72 20  a locking error 
5700: 68 61 73 20 6f 63 63 75 72 72 65 64 20 2a 2f 0a  has occurred */.
5710: 23 65 6e 64 69 66 0a 23 69 66 64 65 66 20 53 51  #endif.#ifdef SQ
5720: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e 41 50  LITE_ENABLE_SNAP
5730: 53 48 4f 54 0a 20 20 57 61 6c 49 6e 64 65 78 48  SHOT.  WalIndexH
5740: 64 72 20 2a 70 53 6e 61 70 73 68 6f 74 3b 20 20  dr *pSnapshot;  
5750: 20 20 2f 2a 20 53 74 61 72 74 20 74 72 61 6e 73    /* Start trans
5760: 61 63 74 69 6f 6e 20 68 65 72 65 20 69 66 20 6e  action here if n
5770: 6f 74 20 4e 55 4c 4c 20 2a 2f 0a 23 65 6e 64 69  ot NULL */.#endi
5780: 66 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 43 61 6e 64  f.};../*.** Cand
5790: 69 64 61 74 65 20 76 61 6c 75 65 73 20 66 6f 72  idate values for
57a0: 20 57 61 6c 2e 65 78 63 6c 75 73 69 76 65 4d 6f   Wal.exclusiveMo
57b0: 64 65 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57  de..*/.#define W
57c0: 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 20 20  AL_NORMAL_MODE  
57d0: 20 20 20 30 0a 23 64 65 66 69 6e 65 20 57 41 4c     0.#define WAL
57e0: 5f 45 58 43 4c 55 53 49 56 45 5f 4d 4f 44 45 20  _EXCLUSIVE_MODE 
57f0: 20 31 20 20 20 20 20 0a 23 64 65 66 69 6e 65 20   1     .#define 
5800: 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d  WAL_HEAPMEMORY_M
5810: 4f 44 45 20 32 0a 0a 2f 2a 0a 2a 2a 20 50 6f 73  ODE 2../*.** Pos
5820: 73 69 62 6c 65 20 76 61 6c 75 65 73 20 66 6f 72  sible values for
5830: 20 57 41 4c 2e 72 65 61 64 4f 6e 6c 79 0a 2a 2f   WAL.readOnly.*/
5840: 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 52 44 57  .#define WAL_RDW
5850: 52 20 20 20 20 20 20 20 20 30 20 20 20 20 2f 2a  R        0    /*
5860: 20 4e 6f 72 6d 61 6c 20 72 65 61 64 2f 77 72 69   Normal read/wri
5870: 74 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f  te connection */
5880: 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 52 44 4f  .#define WAL_RDO
5890: 4e 4c 59 20 20 20 20 20 20 31 20 20 20 20 2f 2a  NLY      1    /*
58a0: 20 54 68 65 20 57 41 4c 20 66 69 6c 65 20 69 73   The WAL file is
58b0: 20 72 65 61 64 6f 6e 6c 79 20 2a 2f 0a 23 64 65   readonly */.#de
58c0: 66 69 6e 65 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  fine WAL_SHM_RDO
58d0: 4e 4c 59 20 20 32 20 20 20 20 2f 2a 20 54 68 65  NLY  2    /* The
58e0: 20 53 48 4d 20 66 69 6c 65 20 69 73 20 72 65 61   SHM file is rea
58f0: 64 6f 6e 6c 79 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  donly */../*.** 
5900: 45 61 63 68 20 70 61 67 65 20 6f 66 20 74 68 65  Each page of the
5910: 20 77 61 6c 2d 69 6e 64 65 78 20 6d 61 70 70 69   wal-index mappi
5920: 6e 67 20 63 6f 6e 74 61 69 6e 73 20 61 20 68 61  ng contains a ha
5930: 73 68 2d 74 61 62 6c 65 20 6d 61 64 65 20 75 70  sh-table made up
5940: 20 6f 66 0a 2a 2a 20 61 6e 20 61 72 72 61 79 20   of.** an array 
5950: 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c  of HASHTABLE_NSL
5960: 4f 54 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 74  OT elements of t
5970: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70  he following typ
5980: 65 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 75 31  e..*/.typedef u1
5990: 36 20 68 74 5f 73 6c 6f 74 3b 0a 0a 2f 2a 0a 2a  6 ht_slot;../*.*
59a0: 2a 20 54 68 69 73 20 73 74 72 75 63 74 75 72 65  * This structure
59b0: 20 69 73 20 75 73 65 64 20 74 6f 20 69 6d 70 6c   is used to impl
59c0: 65 6d 65 6e 74 20 61 6e 20 69 74 65 72 61 74 6f  ement an iterato
59d0: 72 20 74 68 61 74 20 6c 6f 6f 70 73 20 74 68 72  r that loops thr
59e0: 6f 75 67 68 0a 2a 2a 20 61 6c 6c 20 66 72 61 6d  ough.** all fram
59f0: 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20 69 6e  es in the WAL in
5a00: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6f   database page o
5a10: 72 64 65 72 2e 20 57 68 65 72 65 20 74 77 6f 20  rder. Where two 
5a20: 6f 72 20 6d 6f 72 65 20 66 72 61 6d 65 73 0a 2a  or more frames.*
5a30: 2a 20 63 6f 72 72 65 73 70 6f 6e 64 20 74 6f 20  * correspond to 
5a40: 74 68 65 20 73 61 6d 65 20 64 61 74 61 62 61 73  the same databas
5a50: 65 20 70 61 67 65 2c 20 74 68 65 20 69 74 65 72  e page, the iter
5a60: 61 74 6f 72 20 76 69 73 69 74 73 20 6f 6e 6c 79  ator visits only
5a70: 20 74 68 65 20 0a 2a 2a 20 66 72 61 6d 65 20 6d   the .** frame m
5a80: 6f 73 74 20 72 65 63 65 6e 74 6c 79 20 77 72 69  ost recently wri
5a90: 74 74 65 6e 20 74 6f 20 74 68 65 20 57 41 4c 20  tten to the WAL 
5aa0: 28 69 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c  (in other words,
5ab0: 20 74 68 65 20 66 72 61 6d 65 20 77 69 74 68 0a   the frame with.
5ac0: 2a 2a 20 74 68 65 20 6c 61 72 67 65 73 74 20 69  ** the largest i
5ad0: 6e 64 65 78 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  ndex)..**.** The
5ae0: 20 69 6e 74 65 72 6e 61 6c 73 20 6f 66 20 74 68   internals of th
5af0: 69 73 20 73 74 72 75 63 74 75 72 65 20 61 72 65  is structure are
5b00: 20 6f 6e 6c 79 20 61 63 63 65 73 73 65 64 20 62   only accessed b
5b10: 79 3a 0a 2a 2a 0a 2a 2a 20 20 20 77 61 6c 49 74  y:.**.**   walIt
5b20: 65 72 61 74 6f 72 49 6e 69 74 28 29 20 2d 20 43  eratorInit() - C
5b30: 72 65 61 74 65 20 61 20 6e 65 77 20 69 74 65 72  reate a new iter
5b40: 61 74 6f 72 2c 0a 2a 2a 20 20 20 77 61 6c 49 74  ator,.**   walIt
5b50: 65 72 61 74 6f 72 4e 65 78 74 28 29 20 2d 20 53  eratorNext() - S
5b60: 74 65 70 20 61 6e 20 69 74 65 72 61 74 6f 72 2c  tep an iterator,
5b70: 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f  .**   walIterato
5b80: 72 46 72 65 65 28 29 20 2d 20 46 72 65 65 20 61  rFree() - Free a
5b90: 6e 20 69 74 65 72 61 74 6f 72 2e 0a 2a 2a 0a 2a  n iterator..**.*
5ba0: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 61  * This functiona
5bb0: 6c 69 74 79 20 69 73 20 75 73 65 64 20 62 79 20  lity is used by 
5bc0: 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 63  the checkpoint c
5bd0: 6f 64 65 20 28 73 65 65 20 77 61 6c 43 68 65 63  ode (see walChec
5be0: 6b 70 6f 69 6e 74 28 29 29 2e 0a 2a 2f 0a 73 74  kpoint())..*/.st
5bf0: 72 75 63 74 20 57 61 6c 49 74 65 72 61 74 6f 72  ruct WalIterator
5c00: 20 7b 0a 20 20 69 6e 74 20 69 50 72 69 6f 72 3b   {.  int iPrior;
5c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5c20: 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 72 65 73       /* Last res
5c30: 75 6c 74 20 72 65 74 75 72 6e 65 64 20 66 72 6f  ult returned fro
5c40: 6d 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 2a  m the iterator *
5c50: 2f 0a 20 20 69 6e 74 20 6e 53 65 67 6d 65 6e 74  /.  int nSegment
5c60: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
5c70: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
5c80: 20 65 6e 74 72 69 65 73 20 69 6e 20 61 53 65 67   entries in aSeg
5c90: 6d 65 6e 74 5b 5d 20 2a 2f 0a 20 20 73 74 72 75  ment[] */.  stru
5ca0: 63 74 20 57 61 6c 53 65 67 6d 65 6e 74 20 7b 0a  ct WalSegment {.
5cb0: 20 20 20 20 69 6e 74 20 69 4e 65 78 74 3b 20 20      int iNext;  
5cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5cd0: 20 20 2f 2a 20 4e 65 78 74 20 73 6c 6f 74 20 69    /* Next slot i
5ce0: 6e 20 61 49 6e 64 65 78 5b 5d 20 6e 6f 74 20 79  n aIndex[] not y
5cf0: 65 74 20 72 65 74 75 72 6e 65 64 20 2a 2f 0a 20  et returned */. 
5d00: 20 20 20 68 74 5f 73 6c 6f 74 20 2a 61 49 6e 64     ht_slot *aInd
5d10: 65 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ex;             
5d20: 20 2f 2a 20 69 30 2c 20 69 31 2c 20 69 32 2e 2e   /* i0, i1, i2..
5d30: 2e 20 73 75 63 68 20 74 68 61 74 20 61 50 67 6e  . such that aPgn
5d40: 6f 5b 69 4e 5d 20 61 73 63 65 6e 64 20 2a 2f 0a  o[iN] ascend */.
5d50: 20 20 20 20 75 33 32 20 2a 61 50 67 6e 6f 3b 20      u32 *aPgno; 
5d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5d70: 20 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 70 61    /* Array of pa
5d80: 67 65 20 6e 75 6d 62 65 72 73 2e 20 2a 2f 0a 20  ge numbers. */. 
5d90: 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 3b 20 20     int nEntry;  
5da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5db0: 20 2f 2a 20 4e 72 2e 20 6f 66 20 65 6e 74 72 69   /* Nr. of entri
5dc0: 65 73 20 69 6e 20 61 50 67 6e 6f 5b 5d 20 61 6e  es in aPgno[] an
5dd0: 64 20 61 49 6e 64 65 78 5b 5d 20 2a 2f 0a 20 20  d aIndex[] */.  
5de0: 20 20 69 6e 74 20 69 5a 65 72 6f 3b 20 20 20 20    int iZero;    
5df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e00: 2f 2a 20 46 72 61 6d 65 20 6e 75 6d 62 65 72 20  /* Frame number 
5e10: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20  associated with 
5e20: 61 50 67 6e 6f 5b 30 5d 20 2a 2f 0a 20 20 7d 20  aPgno[0] */.  } 
5e30: 61 53 65 67 6d 65 6e 74 5b 31 5d 3b 20 20 20 20  aSegment[1];    
5e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5e50: 20 4f 6e 65 20 66 6f 72 20 65 76 65 72 79 20 33   One for every 3
5e60: 32 4b 42 20 70 61 67 65 20 69 6e 20 74 68 65 20  2KB page in the 
5e70: 77 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a 7d 3b 0a  wal-index */.};.
5e80: 0a 2f 2a 0a 2a 2a 20 44 65 66 69 6e 65 20 74 68  ./*.** Define th
5e90: 65 20 70 61 72 61 6d 65 74 65 72 73 20 6f 66 20  e parameters of 
5ea0: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 73 20  the hash tables 
5eb0: 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  in the wal-index
5ec0: 20 66 69 6c 65 2e 20 54 68 65 72 65 0a 2a 2a 20   file. There.** 
5ed0: 69 73 20 61 20 68 61 73 68 2d 74 61 62 6c 65 20  is a hash-table 
5ee0: 66 6f 6c 6c 6f 77 69 6e 67 20 65 76 65 72 79 20  following every 
5ef0: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20  HASHTABLE_NPAGE 
5f00: 70 61 67 65 20 6e 75 6d 62 65 72 73 20 69 6e 20  page numbers in 
5f10: 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78  the.** wal-index
5f20: 2e 0a 2a 2a 0a 2a 2a 20 43 68 61 6e 67 69 6e 67  ..**.** Changing
5f30: 20 61 6e 79 20 6f 66 20 74 68 65 73 65 20 63 6f   any of these co
5f40: 6e 73 74 61 6e 74 73 20 77 69 6c 6c 20 61 6c 74  nstants will alt
5f50: 65 72 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  er the wal-index
5f60: 20 66 6f 72 6d 61 74 20 61 6e 64 0a 2a 2a 20 63   format and.** c
5f70: 72 65 61 74 65 20 69 6e 63 6f 6d 70 61 74 69 62  reate incompatib
5f80: 69 6c 69 74 69 65 73 2e 0a 2a 2f 0a 23 64 65 66  ilities..*/.#def
5f90: 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f 4e 50  ine HASHTABLE_NP
5fa0: 41 47 45 20 20 20 20 20 20 34 30 39 36 20 20 20  AGE      4096   
5fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5fc0: 20 4d 75 73 74 20 62 65 20 70 6f 77 65 72 20 6f   Must be power o
5fd0: 66 20 32 20 2a 2f 0a 23 64 65 66 69 6e 65 20 48  f 2 */.#define H
5fe0: 41 53 48 54 41 42 4c 45 5f 48 41 53 48 5f 31 20  ASHTABLE_HASH_1 
5ff0: 20 20 20 20 33 38 33 20 20 20 20 20 20 20 20 20      383         
6000: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 68 6f 75           /* Shou
6010: 6c 64 20 62 65 20 70 72 69 6d 65 20 2a 2f 0a 23  ld be prime */.#
6020: 64 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45  define HASHTABLE
6030: 5f 4e 53 4c 4f 54 20 20 20 20 20 20 28 48 41 53  _NSLOT      (HAS
6040: 48 54 41 42 4c 45 5f 4e 50 41 47 45 2a 32 29 20  HTABLE_NPAGE*2) 
6050: 20 2f 2a 20 4d 75 73 74 20 62 65 20 61 20 70 6f   /* Must be a po
6060: 77 65 72 20 6f 66 20 32 20 2a 2f 0a 0a 2f 2a 20  wer of 2 */../* 
6070: 0a 2a 2a 20 54 68 65 20 62 6c 6f 63 6b 20 6f 66  .** The block of
6080: 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20 61 73   page numbers as
6090: 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68  sociated with th
60a0: 65 20 66 69 72 73 74 20 68 61 73 68 2d 74 61 62  e first hash-tab
60b0: 6c 65 20 69 6e 20 61 0a 2a 2a 20 77 61 6c 2d 69  le in a.** wal-i
60c0: 6e 64 65 78 20 69 73 20 73 6d 61 6c 6c 65 72 20  ndex is smaller 
60d0: 74 68 61 6e 20 75 73 75 61 6c 2e 20 54 68 69 73  than usual. This
60e0: 20 69 73 20 73 6f 20 74 68 61 74 20 74 68 65 72   is so that ther
60f0: 65 20 69 73 20 61 20 63 6f 6d 70 6c 65 74 65 0a  e is a complete.
6100: 2a 2a 20 68 61 73 68 2d 74 61 62 6c 65 20 6f 6e  ** hash-table on
6110: 20 65 61 63 68 20 61 6c 69 67 6e 65 64 20 33 32   each aligned 32
6120: 4b 42 20 70 61 67 65 20 6f 66 20 74 68 65 20 77  KB page of the w
6130: 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 23 64 65  al-index..*/.#de
6140: 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f 4e  fine HASHTABLE_N
6150: 50 41 47 45 5f 4f 4e 45 20 20 28 48 41 53 48 54  PAGE_ONE  (HASHT
6160: 41 42 4c 45 5f 4e 50 41 47 45 20 2d 20 28 57 41  ABLE_NPAGE - (WA
6170: 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45 2f  LINDEX_HDR_SIZE/
6180: 73 69 7a 65 6f 66 28 75 33 32 29 29 29 0a 0a 2f  sizeof(u32)))../
6190: 2a 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  * The wal-index 
61a0: 69 73 20 64 69 76 69 64 65 64 20 69 6e 74 6f 20  is divided into 
61b0: 70 61 67 65 73 20 6f 66 20 57 41 4c 49 4e 44 45  pages of WALINDE
61c0: 58 5f 50 47 53 5a 20 62 79 74 65 73 20 65 61 63  X_PGSZ bytes eac
61d0: 68 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41  h. */.#define WA
61e0: 4c 49 4e 44 45 58 5f 50 47 53 5a 20 20 20 28 20  LINDEX_PGSZ   ( 
61f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6210: 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20 73 69          \.    si
6220: 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 2a 48 41  zeof(ht_slot)*HA
6230: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 2b 20  SHTABLE_NSLOT + 
6240: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 2a  HASHTABLE_NPAGE*
6250: 73 69 7a 65 6f 66 28 75 33 32 29 20 5c 0a 29 0a  sizeof(u32) \.).
6260: 0a 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20 61 20  ./*.** Obtain a 
6270: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 69  pointer to the i
6280: 50 61 67 65 27 74 68 20 70 61 67 65 20 6f 66 20  Page'th page of 
6290: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 54  the wal-index. T
62a0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a 20  he wal-index.** 
62b0: 69 73 20 62 72 6f 6b 65 6e 20 69 6e 74 6f 20 70  is broken into p
62c0: 61 67 65 73 20 6f 66 20 57 41 4c 49 4e 44 45 58  ages of WALINDEX
62d0: 5f 50 47 53 5a 20 62 79 74 65 73 2e 20 57 61 6c  _PGSZ bytes. Wal
62e0: 2d 69 6e 64 65 78 20 70 61 67 65 73 20 61 72 65  -index pages are
62f0: 0a 2a 2a 20 6e 75 6d 62 65 72 65 64 20 66 72 6f  .** numbered fro
6300: 6d 20 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66  m zero..**.** If
6310: 20 74 68 69 73 20 63 61 6c 6c 20 69 73 20 73 75   this call is su
6320: 63 63 65 73 73 66 75 6c 2c 20 2a 70 70 50 61 67  ccessful, *ppPag
6330: 65 20 69 73 20 73 65 74 20 74 6f 20 70 6f 69 6e  e is set to poin
6340: 74 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64  t to the wal-ind
6350: 65 78 0a 2a 2a 20 70 61 67 65 20 61 6e 64 20 53  ex.** page and S
6360: 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
6370: 72 6e 65 64 2e 20 49 66 20 61 6e 20 65 72 72 6f  rned. If an erro
6380: 72 20 28 61 6e 20 4f 4f 4d 20 6f 72 20 56 46 53  r (an OOM or VFS
6390: 20 65 72 72 6f 72 29 20 6f 63 63 75 72 73 2c 0a   error) occurs,.
63a0: 2a 2a 20 74 68 65 6e 20 61 6e 20 53 51 4c 69 74  ** then an SQLit
63b0: 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20  e error code is 
63c0: 72 65 74 75 72 6e 65 64 20 61 6e 64 20 2a 70 70  returned and *pp
63d0: 50 61 67 65 20 69 73 20 73 65 74 20 74 6f 20 30  Page is set to 0
63e0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
63f0: 77 61 6c 49 6e 64 65 78 50 61 67 65 28 57 61 6c  walIndexPage(Wal
6400: 20 2a 70 57 61 6c 2c 20 69 6e 74 20 69 50 61 67   *pWal, int iPag
6410: 65 2c 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20  e, volatile u32 
6420: 2a 2a 70 70 50 61 67 65 29 7b 0a 20 20 69 6e 74  **ppPage){.  int
6430: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
6440: 0a 0a 20 20 2f 2a 20 45 6e 6c 61 72 67 65 20 74  ..  /* Enlarge t
6450: 68 65 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  he pWal->apWiDat
6460: 61 5b 5d 20 61 72 72 61 79 20 69 66 20 72 65 71  a[] array if req
6470: 75 69 72 65 64 20 2a 2f 0a 20 20 69 66 28 20 70  uired */.  if( p
6480: 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3c 3d 69 50  Wal->nWiData<=iP
6490: 61 67 65 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e  age ){.    int n
64a0: 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 75 33  Byte = sizeof(u3
64b0: 32 2a 29 2a 28 69 50 61 67 65 2b 31 29 3b 0a 20  2*)*(iPage+1);. 
64c0: 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20     volatile u32 
64d0: 2a 2a 61 70 4e 65 77 3b 0a 20 20 20 20 61 70 4e  **apNew;.    apN
64e0: 65 77 20 3d 20 28 76 6f 6c 61 74 69 6c 65 20 75  ew = (volatile u
64f0: 33 32 20 2a 2a 29 73 71 6c 69 74 65 33 5f 72 65  32 **)sqlite3_re
6500: 61 6c 6c 6f 63 36 34 28 28 76 6f 69 64 20 2a 29  alloc64((void *)
6510: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 2c 20  pWal->apWiData, 
6520: 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20  nByte);.    if( 
6530: 21 61 70 4e 65 77 20 29 7b 0a 20 20 20 20 20 20  !apNew ){.      
6540: 2a 70 70 50 61 67 65 20 3d 20 30 3b 0a 20 20 20  *ppPage = 0;.   
6550: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
6560: 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20 20  _NOMEM_BKPT;.   
6570: 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74 28 28 76   }.    memset((v
6580: 6f 69 64 2a 29 26 61 70 4e 65 77 5b 70 57 61 6c  oid*)&apNew[pWal
6590: 2d 3e 6e 57 69 44 61 74 61 5d 2c 20 30 2c 0a 20  ->nWiData], 0,. 
65a0: 20 20 20 20 20 20 20 20 20 20 73 69 7a 65 6f 66            sizeof
65b0: 28 75 33 32 2a 29 2a 28 69 50 61 67 65 2b 31 2d  (u32*)*(iPage+1-
65c0: 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 29 29 3b  pWal->nWiData));
65d0: 0a 20 20 20 20 70 57 61 6c 2d 3e 61 70 57 69 44  .    pWal->apWiD
65e0: 61 74 61 20 3d 20 61 70 4e 65 77 3b 0a 20 20 20  ata = apNew;.   
65f0: 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 20 3d   pWal->nWiData =
6600: 20 69 50 61 67 65 2b 31 3b 0a 20 20 7d 0a 0a 20   iPage+1;.  }.. 
6610: 20 2f 2a 20 52 65 71 75 65 73 74 20 61 20 70 6f   /* Request a po
6620: 69 6e 74 65 72 20 74 6f 20 74 68 65 20 72 65 71  inter to the req
6630: 75 69 72 65 64 20 70 61 67 65 20 66 72 6f 6d 20  uired page from 
6640: 74 68 65 20 56 46 53 20 2a 2f 0a 20 20 69 66 28  the VFS */.  if(
6650: 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
6660: 69 50 61 67 65 5d 3d 3d 30 20 29 7b 0a 20 20 20  iPage]==0 ){.   
6670: 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75   if( pWal->exclu
6680: 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48 45  siveMode==WAL_HE
6690: 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29 7b  APMEMORY_MODE ){
66a0: 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 61 70 57  .      pWal->apW
66b0: 69 44 61 74 61 5b 69 50 61 67 65 5d 20 3d 20 28  iData[iPage] = (
66c0: 75 33 32 20 76 6f 6c 61 74 69 6c 65 20 2a 29 73  u32 volatile *)s
66d0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f  qlite3MallocZero
66e0: 28 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a 29 3b  (WALINDEX_PGSZ);
66f0: 0a 20 20 20 20 20 20 69 66 28 20 21 70 57 61 6c  .      if( !pWal
6700: 2d 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65  ->apWiData[iPage
6710: 5d 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  ] ) rc = SQLITE_
6720: 4e 4f 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20 20 20  NOMEM_BKPT;.    
6730: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20  }else{.      rc 
6740: 3d 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4d 61  = sqlite3OsShmMa
6750: 70 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69  p(pWal->pDbFd, i
6760: 50 61 67 65 2c 20 57 41 4c 49 4e 44 45 58 5f 50  Page, WALINDEX_P
6770: 47 53 5a 2c 20 0a 20 20 20 20 20 20 20 20 20 20  GSZ, .          
6780: 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 2c  pWal->writeLock,
6790: 20 28 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20   (void volatile 
67a0: 2a 2a 29 26 70 57 61 6c 2d 3e 61 70 57 69 44 61  **)&pWal->apWiDa
67b0: 74 61 5b 69 50 61 67 65 5d 0a 20 20 20 20 20 20  ta[iPage].      
67c0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
67d0: 3d 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59  =SQLITE_READONLY
67e0: 20 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c   ){.        pWal
67f0: 2d 3e 72 65 61 64 4f 6e 6c 79 20 7c 3d 20 57 41  ->readOnly |= WA
6800: 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 3b 0a 20 20  L_SHM_RDONLY;.  
6810: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
6820: 45 5f 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  E_OK;.      }.  
6830: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 50 61    }.  }..  *ppPa
6840: 67 65 20 3d 20 70 57 61 6c 2d 3e 61 70 57 69 44  ge = pWal->apWiD
6850: 61 74 61 5b 69 50 61 67 65 5d 3b 0a 20 20 61 73  ata[iPage];.  as
6860: 73 65 72 74 28 20 69 50 61 67 65 3d 3d 30 20 7c  sert( iPage==0 |
6870: 7c 20 2a 70 70 50 61 67 65 20 7c 7c 20 72 63 21  | *ppPage || rc!
6880: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
6890: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
68a0: 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69  .** Return a poi
68b0: 6e 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c 43  nter to the WalC
68c0: 6b 70 74 49 6e 66 6f 20 73 74 72 75 63 74 75 72  kptInfo structur
68d0: 65 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64  e in the wal-ind
68e0: 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ex..*/.static vo
68f0: 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e  latile WalCkptIn
6900: 66 6f 20 2a 77 61 6c 43 6b 70 74 49 6e 66 6f 28  fo *walCkptInfo(
6910: 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73  Wal *pWal){.  as
6920: 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44  sert( pWal->nWiD
6930: 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61  ata>0 && pWal->a
6940: 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20  pWiData[0] );.  
6950: 72 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65  return (volatile
6960: 20 57 61 6c 43 6b 70 74 49 6e 66 6f 2a 29 26 28   WalCkptInfo*)&(
6970: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30  pWal->apWiData[0
6980: 5d 5b 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65  ][sizeof(WalInde
6990: 78 48 64 72 29 2f 32 5d 29 3b 0a 7d 0a 0a 2f 2a  xHdr)/2]);.}../*
69a0: 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69  .** Return a poi
69b0: 6e 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c 49  nter to the WalI
69c0: 6e 64 65 78 48 64 72 20 73 74 72 75 63 74 75 72  ndexHdr structur
69d0: 65 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64  e in the wal-ind
69e0: 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ex..*/.static vo
69f0: 6c 61 74 69 6c 65 20 57 61 6c 49 6e 64 65 78 48  latile WalIndexH
6a00: 64 72 20 2a 77 61 6c 49 6e 64 65 78 48 64 72 28  dr *walIndexHdr(
6a10: 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73  Wal *pWal){.  as
6a20: 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44  sert( pWal->nWiD
6a30: 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61  ata>0 && pWal->a
6a40: 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20  pWiData[0] );.  
6a50: 72 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65  return (volatile
6a60: 20 57 61 6c 49 6e 64 65 78 48 64 72 2a 29 70 57   WalIndexHdr*)pW
6a70: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 3b  al->apWiData[0];
6a80: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61 72  .}../*.** The ar
6a90: 67 75 6d 65 6e 74 20 74 6f 20 74 68 69 73 20 6d  gument to this m
6aa0: 61 63 72 6f 20 6d 75 73 74 20 62 65 20 6f 66 20  acro must be of 
6ab0: 74 79 70 65 20 75 33 32 2e 20 4f 6e 20 61 20 6c  type u32. On a l
6ac0: 69 74 74 6c 65 2d 65 6e 64 69 61 6e 0a 2a 2a 20  ittle-endian.** 
6ad0: 61 72 63 68 69 74 65 63 74 75 72 65 2c 20 69 74  architecture, it
6ae0: 20 72 65 74 75 72 6e 73 20 74 68 65 20 75 33 32   returns the u32
6af0: 20 76 61 6c 75 65 20 74 68 61 74 20 72 65 73 75   value that resu
6b00: 6c 74 73 20 66 72 6f 6d 20 69 6e 74 65 72 70 72  lts from interpr
6b10: 65 74 69 6e 67 0a 2a 2a 20 74 68 65 20 34 20 62  eting.** the 4 b
6b20: 79 74 65 73 20 61 73 20 61 20 62 69 67 2d 65 6e  ytes as a big-en
6b30: 64 69 61 6e 20 76 61 6c 75 65 2e 20 4f 6e 20 61  dian value. On a
6b40: 20 62 69 67 2d 65 6e 64 69 61 6e 20 61 72 63 68   big-endian arch
6b50: 69 74 65 63 74 75 72 65 2c 20 69 74 0a 2a 2a 20  itecture, it.** 
6b60: 72 65 74 75 72 6e 73 20 74 68 65 20 76 61 6c 75  returns the valu
6b70: 65 20 74 68 61 74 20 77 6f 75 6c 64 20 62 65 20  e that would be 
6b80: 70 72 6f 64 75 63 65 64 20 62 79 20 69 6e 74 65  produced by inte
6b90: 72 70 72 65 74 69 6e 67 20 74 68 65 20 34 20 62  rpreting the 4 b
6ba0: 79 74 65 73 0a 2a 2a 20 6f 66 20 74 68 65 20 69  ytes.** of the i
6bb0: 6e 70 75 74 20 76 61 6c 75 65 20 61 73 20 61 20  nput value as a 
6bc0: 6c 69 74 74 6c 65 2d 65 6e 64 69 61 6e 20 69 6e  little-endian in
6bd0: 74 65 67 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e  teger..*/.#defin
6be0: 65 20 42 59 54 45 53 57 41 50 33 32 28 78 29 20  e BYTESWAP32(x) 
6bf0: 28 20 5c 0a 20 20 20 20 28 28 28 78 29 26 30 78  ( \.    (((x)&0x
6c00: 30 30 30 30 30 30 46 46 29 3c 3c 32 34 29 20 2b  000000FF)<<24) +
6c10: 20 28 28 28 78 29 26 30 78 30 30 30 30 46 46 30   (((x)&0x0000FF0
6c20: 30 29 3c 3c 38 29 20 20 5c 0a 20 20 2b 20 28 28  0)<<8)  \.  + ((
6c30: 28 78 29 26 30 78 30 30 46 46 30 30 30 30 29 3e  (x)&0x00FF0000)>
6c40: 3e 38 29 20 20 2b 20 28 28 28 78 29 26 30 78 46  >8)  + (((x)&0xF
6c50: 46 30 30 30 30 30 30 29 3e 3e 32 34 29 20 5c 0a  F000000)>>24) \.
6c60: 29 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74  )../*.** Generat
6c70: 65 20 6f 72 20 65 78 74 65 6e 64 20 61 6e 20 38  e or extend an 8
6c80: 20 62 79 74 65 20 63 68 65 63 6b 73 75 6d 20 62   byte checksum b
6c90: 61 73 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61  ased on the data
6ca0: 20 69 6e 20 0a 2a 2a 20 61 72 72 61 79 20 61 42   in .** array aB
6cb0: 79 74 65 5b 5d 20 61 6e 64 20 74 68 65 20 69 6e  yte[] and the in
6cc0: 69 74 69 61 6c 20 76 61 6c 75 65 73 20 6f 66 20  itial values of 
6cd0: 61 49 6e 5b 30 5d 20 61 6e 64 20 61 49 6e 5b 31  aIn[0] and aIn[1
6ce0: 5d 20 28 6f 72 0a 2a 2a 20 69 6e 69 74 69 61 6c  ] (or.** initial
6cf0: 20 76 61 6c 75 65 73 20 6f 66 20 30 20 61 6e 64   values of 0 and
6d00: 20 30 20 69 66 20 61 49 6e 3d 3d 4e 55 4c 4c 29   0 if aIn==NULL)
6d10: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63  ..**.** The chec
6d20: 6b 73 75 6d 20 69 73 20 77 72 69 74 74 65 6e 20  ksum is written 
6d30: 62 61 63 6b 20 69 6e 74 6f 20 61 4f 75 74 5b 5d  back into aOut[]
6d40: 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
6d50: 67 2e 0a 2a 2a 0a 2a 2a 20 6e 42 79 74 65 20 6d  g..**.** nByte m
6d60: 75 73 74 20 62 65 20 61 20 70 6f 73 69 74 69 76  ust be a positiv
6d70: 65 20 6d 75 6c 74 69 70 6c 65 20 6f 66 20 38 2e  e multiple of 8.
6d80: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
6d90: 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73  walChecksumBytes
6da0: 28 0a 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b  (.  int nativeCk
6db0: 73 75 6d 2c 20 2f 2a 20 54 72 75 65 20 66 6f 72  sum, /* True for
6dc0: 20 6e 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64   native byte-ord
6dd0: 65 72 2c 20 66 61 6c 73 65 20 66 6f 72 20 6e 6f  er, false for no
6de0: 6e 2d 6e 61 74 69 76 65 20 2a 2f 0a 20 20 75 38  n-native */.  u8
6df0: 20 2a 61 2c 20 20 20 20 20 20 20 20 20 20 20 2f   *a,           /
6e00: 2a 20 43 6f 6e 74 65 6e 74 20 74 6f 20 62 65 20  * Content to be 
6e10: 63 68 65 63 6b 73 75 6d 6d 65 64 20 2a 2f 0a 20  checksummed */. 
6e20: 20 69 6e 74 20 6e 42 79 74 65 2c 20 20 20 20 20   int nByte,     
6e30: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 63 6f    /* Bytes of co
6e40: 6e 74 65 6e 74 20 69 6e 20 61 5b 5d 2e 20 20 4d  ntent in a[].  M
6e50: 75 73 74 20 62 65 20 61 20 6d 75 6c 74 69 70 6c  ust be a multipl
6e60: 65 20 6f 66 20 38 2e 20 2a 2f 0a 20 20 63 6f 6e  e of 8. */.  con
6e70: 73 74 20 75 33 32 20 2a 61 49 6e 2c 20 20 2f 2a  st u32 *aIn,  /*
6e80: 20 49 6e 69 74 69 61 6c 20 63 68 65 63 6b 73 75   Initial checksu
6e90: 6d 20 76 61 6c 75 65 20 69 6e 70 75 74 20 2a 2f  m value input */
6ea0: 0a 20 20 75 33 32 20 2a 61 4f 75 74 20 20 20 20  .  u32 *aOut    
6eb0: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 46 69 6e 61      /* OUT: Fina
6ec0: 6c 20 63 68 65 63 6b 73 75 6d 20 76 61 6c 75 65  l checksum value
6ed0: 20 6f 75 74 70 75 74 20 2a 2f 0a 29 7b 0a 20 20   output */.){.  
6ee0: 75 33 32 20 73 31 2c 20 73 32 3b 0a 20 20 75 33  u32 s1, s2;.  u3
6ef0: 32 20 2a 61 44 61 74 61 20 3d 20 28 75 33 32 20  2 *aData = (u32 
6f00: 2a 29 61 3b 0a 20 20 75 33 32 20 2a 61 45 6e 64  *)a;.  u32 *aEnd
6f10: 20 3d 20 28 75 33 32 20 2a 29 26 61 5b 6e 42 79   = (u32 *)&a[nBy
6f20: 74 65 5d 3b 0a 0a 20 20 69 66 28 20 61 49 6e 20  te];..  if( aIn 
6f30: 29 7b 0a 20 20 20 20 73 31 20 3d 20 61 49 6e 5b  ){.    s1 = aIn[
6f40: 30 5d 3b 0a 20 20 20 20 73 32 20 3d 20 61 49 6e  0];.    s2 = aIn
6f50: 5b 31 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  [1];.  }else{.  
6f60: 20 20 73 31 20 3d 20 73 32 20 3d 20 30 3b 0a 20    s1 = s2 = 0;. 
6f70: 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 42   }..  assert( nB
6f80: 79 74 65 3e 3d 38 20 29 3b 0a 20 20 61 73 73 65  yte>=8 );.  asse
6f90: 72 74 28 20 28 6e 42 79 74 65 26 30 78 30 30 30  rt( (nByte&0x000
6fa0: 30 30 30 30 37 29 3d 3d 30 20 29 3b 0a 0a 20 20  00007)==0 );..  
6fb0: 69 66 28 20 6e 61 74 69 76 65 43 6b 73 75 6d 20  if( nativeCksum 
6fc0: 29 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20  ){.    do {.    
6fd0: 20 20 73 31 20 2b 3d 20 2a 61 44 61 74 61 2b 2b    s1 += *aData++
6fe0: 20 2b 20 73 32 3b 0a 20 20 20 20 20 20 73 32 20   + s2;.      s2 
6ff0: 2b 3d 20 2a 61 44 61 74 61 2b 2b 20 2b 20 73 31  += *aData++ + s1
7000: 3b 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 61 44  ;.    }while( aD
7010: 61 74 61 3c 61 45 6e 64 20 29 3b 0a 20 20 7d 65  ata<aEnd );.  }e
7020: 6c 73 65 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20  lse{.    do {.  
7030: 20 20 20 20 73 31 20 2b 3d 20 42 59 54 45 53 57      s1 += BYTESW
7040: 41 50 33 32 28 61 44 61 74 61 5b 30 5d 29 20 2b  AP32(aData[0]) +
7050: 20 73 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d   s2;.      s2 +=
7060: 20 42 59 54 45 53 57 41 50 33 32 28 61 44 61 74   BYTESWAP32(aDat
7070: 61 5b 31 5d 29 20 2b 20 73 31 3b 0a 20 20 20 20  a[1]) + s1;.    
7080: 20 20 61 44 61 74 61 20 2b 3d 20 32 3b 0a 20 20    aData += 2;.  
7090: 20 20 7d 77 68 69 6c 65 28 20 61 44 61 74 61 3c    }while( aData<
70a0: 61 45 6e 64 20 29 3b 0a 20 20 7d 0a 0a 20 20 61  aEnd );.  }..  a
70b0: 4f 75 74 5b 30 5d 20 3d 20 73 31 3b 0a 20 20 61  Out[0] = s1;.  a
70c0: 4f 75 74 5b 31 5d 20 3d 20 73 32 3b 0a 7d 0a 0a  Out[1] = s2;.}..
70d0: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 53  static void walS
70e0: 68 6d 42 61 72 72 69 65 72 28 57 61 6c 20 2a 70  hmBarrier(Wal *p
70f0: 57 61 6c 29 7b 0a 20 20 69 66 28 20 70 57 61 6c  Wal){.  if( pWal
7100: 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 21  ->exclusiveMode!
7110: 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f  =WAL_HEAPMEMORY_
7120: 4d 4f 44 45 20 29 7b 0a 20 20 20 20 73 71 6c 69  MODE ){.    sqli
7130: 74 65 33 4f 73 53 68 6d 42 61 72 72 69 65 72 28  te3OsShmBarrier(
7140: 70 57 61 6c 2d 3e 70 44 62 46 64 29 3b 0a 20 20  pWal->pDbFd);.  
7150: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65  }.}../*.** Write
7160: 20 74 68 65 20 68 65 61 64 65 72 20 69 6e 66 6f   the header info
7170: 72 6d 61 74 69 6f 6e 20 69 6e 20 70 57 61 6c 2d  rmation in pWal-
7180: 3e 68 64 72 20 69 6e 74 6f 20 74 68 65 20 77 61  >hdr into the wa
7190: 6c 2d 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 54  l-index..**.** T
71a0: 68 65 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20 70  he checksum on p
71b0: 57 61 6c 2d 3e 68 64 72 20 69 73 20 75 70 64 61  Wal->hdr is upda
71c0: 74 65 64 20 62 65 66 6f 72 65 20 69 74 20 69 73  ted before it is
71d0: 20 77 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 61   written..*/.sta
71e0: 74 69 63 20 76 6f 69 64 20 77 61 6c 49 6e 64 65  tic void walInde
71f0: 78 57 72 69 74 65 48 64 72 28 57 61 6c 20 2a 70  xWriteHdr(Wal *p
7200: 57 61 6c 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65  Wal){.  volatile
7210: 20 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 61 48   WalIndexHdr *aH
7220: 64 72 20 3d 20 77 61 6c 49 6e 64 65 78 48 64 72  dr = walIndexHdr
7230: 28 70 57 61 6c 29 3b 0a 20 20 63 6f 6e 73 74 20  (pWal);.  const 
7240: 69 6e 74 20 6e 43 6b 73 75 6d 20 3d 20 6f 66 66  int nCksum = off
7250: 73 65 74 6f 66 28 57 61 6c 49 6e 64 65 78 48 64  setof(WalIndexHd
7260: 72 2c 20 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 61  r, aCksum);..  a
7270: 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69  ssert( pWal->wri
7280: 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 70 57 61 6c  teLock );.  pWal
7290: 2d 3e 68 64 72 2e 69 73 49 6e 69 74 20 3d 20 31  ->hdr.isInit = 1
72a0: 3b 0a 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56  ;.  pWal->hdr.iV
72b0: 65 72 73 69 6f 6e 20 3d 20 57 41 4c 49 4e 44 45  ersion = WALINDE
72c0: 58 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 3b 0a 20  X_MAX_VERSION;. 
72d0: 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65   walChecksumByte
72e0: 73 28 31 2c 20 28 75 38 2a 29 26 70 57 61 6c 2d  s(1, (u8*)&pWal-
72f0: 3e 68 64 72 2c 20 6e 43 6b 73 75 6d 2c 20 30 2c  >hdr, nCksum, 0,
7300: 20 70 57 61 6c 2d 3e 68 64 72 2e 61 43 6b 73 75   pWal->hdr.aCksu
7310: 6d 29 3b 0a 20 20 6d 65 6d 63 70 79 28 28 76 6f  m);.  memcpy((vo
7320: 69 64 2a 29 26 61 48 64 72 5b 31 5d 2c 20 28 63  id*)&aHdr[1], (c
7330: 6f 6e 73 74 20 76 6f 69 64 2a 29 26 70 57 61 6c  onst void*)&pWal
7340: 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61  ->hdr, sizeof(Wa
7350: 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 77  lIndexHdr));.  w
7360: 61 6c 53 68 6d 42 61 72 72 69 65 72 28 70 57 61  alShmBarrier(pWa
7370: 6c 29 3b 0a 20 20 6d 65 6d 63 70 79 28 28 76 6f  l);.  memcpy((vo
7380: 69 64 2a 29 26 61 48 64 72 5b 30 5d 2c 20 28 63  id*)&aHdr[0], (c
7390: 6f 6e 73 74 20 76 6f 69 64 2a 29 26 70 57 61 6c  onst void*)&pWal
73a0: 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61  ->hdr, sizeof(Wa
73b0: 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 7d 0a 0a  lIndexHdr));.}..
73c0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
73d0: 69 6f 6e 20 65 6e 63 6f 64 65 73 20 61 20 73 69  ion encodes a si
73e0: 6e 67 6c 65 20 66 72 61 6d 65 20 68 65 61 64 65  ngle frame heade
73f0: 72 20 61 6e 64 20 77 72 69 74 65 73 20 69 74 20  r and writes it 
7400: 74 6f 20 61 20 62 75 66 66 65 72 0a 2a 2a 20 73  to a buffer.** s
7410: 75 70 70 6c 69 65 64 20 62 79 20 74 68 65 20 63  upplied by the c
7420: 61 6c 6c 65 72 2e 20 41 20 66 72 61 6d 65 2d 68  aller. A frame-h
7430: 65 61 64 65 72 20 69 73 20 6d 61 64 65 20 75 70  eader is made up
7440: 20 6f 66 20 61 20 73 65 72 69 65 73 20 6f 66 20   of a series of 
7450: 0a 2a 2a 20 34 2d 62 79 74 65 20 62 69 67 2d 65  .** 4-byte big-e
7460: 6e 64 69 61 6e 20 69 6e 74 65 67 65 72 73 2c 20  ndian integers, 
7470: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a  as follows:.**.*
7480: 2a 20 20 20 20 20 30 3a 20 50 61 67 65 20 6e 75  *     0: Page nu
7490: 6d 62 65 72 2e 0a 2a 2a 20 20 20 20 20 34 3a 20  mber..**     4: 
74a0: 46 6f 72 20 63 6f 6d 6d 69 74 20 72 65 63 6f 72  For commit recor
74b0: 64 73 2c 20 74 68 65 20 73 69 7a 65 20 6f 66 20  ds, the size of 
74c0: 74 68 65 20 64 61 74 61 62 61 73 65 20 69 6d 61  the database ima
74d0: 67 65 20 69 6e 20 70 61 67 65 73 20 0a 2a 2a 20  ge in pages .** 
74e0: 20 20 20 20 20 20 20 61 66 74 65 72 20 74 68 65         after the
74f0: 20 63 6f 6d 6d 69 74 2e 20 46 6f 72 20 61 6c 6c   commit. For all
7500: 20 6f 74 68 65 72 20 72 65 63 6f 72 64 73 2c 20   other records, 
7510: 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20 20 38 3a 20  zero..**     8: 
7520: 53 61 6c 74 2d 31 20 28 63 6f 70 69 65 64 20 66  Salt-1 (copied f
7530: 72 6f 6d 20 74 68 65 20 77 61 6c 2d 68 65 61 64  rom the wal-head
7540: 65 72 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61  er).**    12: Sa
7550: 6c 74 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f  lt-2 (copied fro
7560: 6d 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  m the wal-header
7570: 29 0a 2a 2a 20 20 20 20 31 36 3a 20 43 68 65 63  ).**    16: Chec
7580: 6b 73 75 6d 2d 31 2e 0a 2a 2a 20 20 20 20 32 30  ksum-1..**    20
7590: 3a 20 43 68 65 63 6b 73 75 6d 2d 32 2e 0a 2a 2f  : Checksum-2..*/
75a0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
75b0: 45 6e 63 6f 64 65 46 72 61 6d 65 28 0a 20 20 57  EncodeFrame(.  W
75c0: 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20  al *pWal,       
75d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
75e0: 2a 20 54 68 65 20 77 72 69 74 65 2d 61 68 65 61  * The write-ahea
75f0: 64 20 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 69  d log */.  u32 i
7600: 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20  Page,           
7610: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
7620: 74 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62  tabase page numb
7630: 65 72 20 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a  er for frame */.
7640: 20 20 75 33 32 20 6e 54 72 75 6e 63 61 74 65 2c    u32 nTruncate,
7650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7660: 20 20 2f 2a 20 4e 65 77 20 64 62 20 73 69 7a 65    /* New db size
7670: 20 28 6f 72 20 30 20 66 6f 72 20 6e 6f 6e 2d 63   (or 0 for non-c
7680: 6f 6d 6d 69 74 20 66 72 61 6d 65 73 29 20 2a 2f  ommit frames) */
7690: 0a 20 20 75 38 20 2a 61 44 61 74 61 2c 20 20 20  .  u8 *aData,   
76a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
76b0: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
76c0: 20 70 61 67 65 20 64 61 74 61 20 2a 2f 0a 20 20   page data */.  
76d0: 75 38 20 2a 61 46 72 61 6d 65 20 20 20 20 20 20  u8 *aFrame      
76e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
76f0: 2f 2a 20 4f 55 54 3a 20 57 72 69 74 65 20 65 6e  /* OUT: Write en
7700: 63 6f 64 65 64 20 66 72 61 6d 65 20 68 65 72 65  coded frame here
7710: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 61 74   */.){.  int nat
7720: 69 76 65 43 6b 73 75 6d 3b 20 20 20 20 20 20 20  iveCksum;       
7730: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
7740: 20 66 6f 72 20 6e 61 74 69 76 65 20 62 79 74 65   for native byte
7750: 2d 6f 72 64 65 72 20 63 68 65 63 6b 73 75 6d 73  -order checksums
7760: 20 2a 2f 0a 20 20 75 33 32 20 2a 61 43 6b 73 75   */.  u32 *aCksu
7770: 6d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46  m = pWal->hdr.aF
7780: 72 61 6d 65 43 6b 73 75 6d 3b 0a 20 20 61 73 73  rameCksum;.  ass
7790: 65 72 74 28 20 57 41 4c 5f 46 52 41 4d 45 5f 48  ert( WAL_FRAME_H
77a0: 44 52 53 49 5a 45 3d 3d 32 34 20 29 3b 0a 20 20  DRSIZE==24 );.  
77b0: 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28  sqlite3Put4byte(
77c0: 26 61 46 72 61 6d 65 5b 30 5d 2c 20 69 50 61 67  &aFrame[0], iPag
77d0: 65 29 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74  e);.  sqlite3Put
77e0: 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 34 5d  4byte(&aFrame[4]
77f0: 2c 20 6e 54 72 75 6e 63 61 74 65 29 3b 0a 20 20  , nTruncate);.  
7800: 69 66 28 20 70 57 61 6c 2d 3e 69 52 65 43 6b 73  if( pWal->iReCks
7810: 75 6d 3d 3d 30 20 29 7b 0a 20 20 20 20 6d 65 6d  um==0 ){.    mem
7820: 63 70 79 28 26 61 46 72 61 6d 65 5b 38 5d 2c 20  cpy(&aFrame[8], 
7830: 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c  pWal->hdr.aSalt,
7840: 20 38 29 3b 0a 0a 20 20 20 20 6e 61 74 69 76 65   8);..    native
7850: 43 6b 73 75 6d 20 3d 20 28 70 57 61 6c 2d 3e 68  Cksum = (pWal->h
7860: 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d 3d  dr.bigEndCksum==
7870: 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e  SQLITE_BIGENDIAN
7880: 29 3b 0a 20 20 20 20 77 61 6c 43 68 65 63 6b 73  );.    walChecks
7890: 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b  umBytes(nativeCk
78a0: 73 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38 2c 20  sum, aFrame, 8, 
78b0: 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b  aCksum, aCksum);
78c0: 0a 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75 6d  .    walChecksum
78d0: 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75  Bytes(nativeCksu
78e0: 6d 2c 20 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e  m, aData, pWal->
78f0: 73 7a 50 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20  szPage, aCksum, 
7900: 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 20 20 73 71  aCksum);..    sq
7910: 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61  lite3Put4byte(&a
7920: 46 72 61 6d 65 5b 31 36 5d 2c 20 61 43 6b 73 75  Frame[16], aCksu
7930: 6d 5b 30 5d 29 3b 0a 20 20 20 20 73 71 6c 69 74  m[0]);.    sqlit
7940: 65 33 50 75 74 34 62 79 74 65 28 26 61 46 72 61  e3Put4byte(&aFra
7950: 6d 65 5b 32 30 5d 2c 20 61 43 6b 73 75 6d 5b 31  me[20], aCksum[1
7960: 5d 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ]);.  }else{.   
7970: 20 6d 65 6d 73 65 74 28 26 61 46 72 61 6d 65 5b   memset(&aFrame[
7980: 38 5d 2c 20 30 2c 20 31 36 29 3b 0a 20 20 7d 0a  8], 0, 16);.  }.
7990: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74  }../*.** Check t
79a0: 6f 20 73 65 65 20 69 66 20 74 68 65 20 66 72 61  o see if the fra
79b0: 6d 65 20 77 69 74 68 20 68 65 61 64 65 72 20 69  me with header i
79c0: 6e 20 61 46 72 61 6d 65 5b 5d 20 61 6e 64 20 63  n aFrame[] and c
79d0: 6f 6e 74 65 6e 74 0a 2a 2a 20 69 6e 20 61 44 61  ontent.** in aDa
79e0: 74 61 5b 5d 20 69 73 20 76 61 6c 69 64 2e 20 20  ta[] is valid.  
79f0: 49 66 20 69 74 20 69 73 20 61 20 76 61 6c 69 64  If it is a valid
7a00: 20 66 72 61 6d 65 2c 20 66 69 6c 6c 20 2a 70 69   frame, fill *pi
7a10: 50 61 67 65 20 61 6e 64 0a 2a 2a 20 2a 70 6e 54  Page and.** *pnT
7a20: 72 75 6e 63 61 74 65 20 61 6e 64 20 72 65 74 75  runcate and retu
7a30: 72 6e 20 74 72 75 65 2e 20 20 52 65 74 75 72 6e  rn true.  Return
7a40: 20 69 66 20 74 68 65 20 66 72 61 6d 65 20 69 73   if the frame is
7a50: 20 6e 6f 74 20 76 61 6c 69 64 2e 0a 2a 2f 0a 73   not valid..*/.s
7a60: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 44 65 63  tatic int walDec
7a70: 6f 64 65 46 72 61 6d 65 28 0a 20 20 57 61 6c 20  odeFrame(.  Wal 
7a80: 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20  *pWal,          
7a90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
7aa0: 68 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c  he write-ahead l
7ab0: 6f 67 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 50  og */.  u32 *piP
7ac0: 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  age,            
7ad0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
7ae0: 44 61 74 61 62 61 73 65 20 70 61 67 65 20 6e 75  Database page nu
7af0: 6d 62 65 72 20 66 6f 72 20 66 72 61 6d 65 20 2a  mber for frame *
7b00: 2f 0a 20 20 75 33 32 20 2a 70 6e 54 72 75 6e 63  /.  u32 *pnTrunc
7b10: 61 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ate,            
7b20: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20      /* OUT: New 
7b30: 64 62 20 73 69 7a 65 20 28 6f 72 20 30 20 69 66  db size (or 0 if
7b40: 20 6e 6f 74 20 63 6f 6d 6d 69 74 29 20 2a 2f 0a   not commit) */.
7b50: 20 20 75 38 20 2a 61 44 61 74 61 2c 20 20 20 20    u8 *aData,    
7b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b70: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
7b80: 70 61 67 65 20 64 61 74 61 20 28 66 6f 72 20 63  page data (for c
7b90: 68 65 63 6b 73 75 6d 29 20 2a 2f 0a 20 20 75 38  hecksum) */.  u8
7ba0: 20 2a 61 46 72 61 6d 65 20 20 20 20 20 20 20 20   *aFrame        
7bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7bc0: 20 46 72 61 6d 65 20 64 61 74 61 20 2a 2f 0a 29   Frame data */.)
7bd0: 7b 0a 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b  {.  int nativeCk
7be0: 73 75 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20  sum;            
7bf0: 20 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20      /* True for 
7c00: 6e 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64 65  native byte-orde
7c10: 72 20 63 68 65 63 6b 73 75 6d 73 20 2a 2f 0a 20  r checksums */. 
7c20: 20 75 33 32 20 2a 61 43 6b 73 75 6d 20 3d 20 70   u32 *aCksum = p
7c30: 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
7c40: 6b 73 75 6d 3b 0a 20 20 75 33 32 20 70 67 6e 6f  ksum;.  u32 pgno
7c50: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
7c60: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20          /* Page 
7c70: 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 66 72  number of the fr
7c80: 61 6d 65 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  ame */.  assert(
7c90: 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49   WAL_FRAME_HDRSI
7ca0: 5a 45 3d 3d 32 34 20 29 3b 0a 0a 20 20 2f 2a 20  ZE==24 );..  /* 
7cb0: 41 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20  A frame is only 
7cc0: 76 61 6c 69 64 20 69 66 20 74 68 65 20 73 61 6c  valid if the sal
7cd0: 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20  t values in the 
7ce0: 66 72 61 6d 65 2d 68 65 61 64 65 72 0a 20 20 2a  frame-header.  *
7cf0: 2a 20 6d 61 74 63 68 20 74 68 65 20 73 61 6c 74  * match the salt
7d00: 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 77   values in the w
7d10: 61 6c 2d 68 65 61 64 65 72 2e 20 0a 20 20 2a 2f  al-header. .  */
7d20: 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 70  .  if( memcmp(&p
7d30: 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20  Wal->hdr.aSalt, 
7d40: 26 61 46 72 61 6d 65 5b 38 5d 2c 20 38 29 21 3d  &aFrame[8], 8)!=
7d50: 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  0 ){.    return 
7d60: 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 20 66  0;.  }..  /* A f
7d70: 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c  rame is only val
7d80: 69 64 20 69 66 20 74 68 65 20 70 61 67 65 20 6e  id if the page n
7d90: 75 6d 62 65 72 20 69 73 20 63 72 65 61 74 65 72  umber is creater
7da0: 20 74 68 61 6e 20 7a 65 72 6f 2e 0a 20 20 2a 2f   than zero..  */
7db0: 0a 20 20 70 67 6e 6f 20 3d 20 73 71 6c 69 74 65  .  pgno = sqlite
7dc0: 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Get4byte(&aFram
7dd0: 65 5b 30 5d 29 3b 0a 20 20 69 66 28 20 70 67 6e  e[0]);.  if( pgn
7de0: 6f 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  o==0 ){.    retu
7df0: 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  rn 0;.  }..  /* 
7e00: 41 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20  A frame is only 
7e10: 76 61 6c 69 64 20 69 66 20 61 20 63 68 65 63 6b  valid if a check
7e20: 73 75 6d 20 6f 66 20 74 68 65 20 57 41 4c 20 68  sum of the WAL h
7e30: 65 61 64 65 72 2c 0a 20 20 2a 2a 20 61 6c 6c 20  eader,.  ** all 
7e40: 70 72 69 6f 72 20 66 72 61 6d 73 2c 20 74 68 65  prior frams, the
7e50: 20 66 69 72 73 74 20 31 36 20 62 79 74 65 73 20   first 16 bytes 
7e60: 6f 66 20 74 68 69 73 20 66 72 61 6d 65 2d 68 65  of this frame-he
7e70: 61 64 65 72 2c 20 0a 20 20 2a 2a 20 61 6e 64 20  ader, .  ** and 
7e80: 74 68 65 20 66 72 61 6d 65 2d 64 61 74 61 20 6d  the frame-data m
7e90: 61 74 63 68 65 73 20 74 68 65 20 63 68 65 63 6b  atches the check
7ea0: 73 75 6d 20 69 6e 20 74 68 65 20 6c 61 73 74 20  sum in the last 
7eb0: 38 20 0a 20 20 2a 2a 20 62 79 74 65 73 20 6f 66  8 .  ** bytes of
7ec0: 20 74 68 69 73 20 66 72 61 6d 65 2d 68 65 61 64   this frame-head
7ed0: 65 72 2e 0a 20 20 2a 2f 0a 20 20 6e 61 74 69 76  er..  */.  nativ
7ee0: 65 43 6b 73 75 6d 20 3d 20 28 70 57 61 6c 2d 3e  eCksum = (pWal->
7ef0: 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d  hdr.bigEndCksum=
7f00: 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41  =SQLITE_BIGENDIA
7f10: 4e 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75  N);.  walChecksu
7f20: 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73  mBytes(nativeCks
7f30: 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38 2c 20 61  um, aFrame, 8, a
7f40: 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a  Cksum, aCksum);.
7f50: 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74    walChecksumByt
7f60: 65 73 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20  es(nativeCksum, 
7f70: 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e 73 7a 50  aData, pWal->szP
7f80: 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b  age, aCksum, aCk
7f90: 73 75 6d 29 3b 0a 20 20 69 66 28 20 61 43 6b 73  sum);.  if( aCks
7fa0: 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65 33 47 65  um[0]!=sqlite3Ge
7fb0: 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 31  t4byte(&aFrame[1
7fc0: 36 5d 29 20 0a 20 20 20 7c 7c 20 61 43 6b 73 75  6]) .   || aCksu
7fd0: 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33 47 65 74  m[1]!=sqlite3Get
7fe0: 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 32 30  4byte(&aFrame[20
7ff0: 5d 29 20 0a 20 20 29 7b 0a 20 20 20 20 2f 2a 20  ]) .  ){.    /* 
8000: 43 68 65 63 6b 73 75 6d 20 66 61 69 6c 65 64 2e  Checksum failed.
8010: 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 30   */.    return 0
8020: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 77  ;.  }..  /* If w
8030: 65 20 72 65 61 63 68 20 74 68 69 73 20 70 6f 69  e reach this poi
8040: 6e 74 2c 20 74 68 65 20 66 72 61 6d 65 20 69 73  nt, the frame is
8050: 20 76 61 6c 69 64 2e 20 20 52 65 74 75 72 6e 20   valid.  Return 
8060: 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 0a  the page number.
8070: 20 20 2a 2a 20 61 6e 64 20 74 68 65 20 6e 65 77    ** and the new
8080: 20 64 61 74 61 62 61 73 65 20 73 69 7a 65 2e 0a   database size..
8090: 20 20 2a 2f 0a 20 20 2a 70 69 50 61 67 65 20 3d    */.  *piPage =
80a0: 20 70 67 6e 6f 3b 0a 20 20 2a 70 6e 54 72 75 6e   pgno;.  *pnTrun
80b0: 63 61 74 65 20 3d 20 73 71 6c 69 74 65 33 47 65  cate = sqlite3Ge
80c0: 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 34  t4byte(&aFrame[4
80d0: 5d 29 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a  ]);.  return 1;.
80e0: 7d 0a 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28  }...#if defined(
80f0: 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26 26 20  SQLITE_TEST) && 
8100: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44  defined(SQLITE_D
8110: 45 42 55 47 29 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65  EBUG)./*.** Name
8120: 73 20 6f 66 20 6c 6f 63 6b 73 2e 20 20 54 68 69  s of locks.  Thi
8130: 73 20 72 6f 75 74 69 6e 65 20 69 73 20 75 73 65  s routine is use
8140: 64 20 74 6f 20 70 72 6f 76 69 64 65 20 64 65 62  d to provide deb
8150: 75 67 67 69 6e 67 20 6f 75 74 70 75 74 20 61 6e  ugging output an
8160: 64 20 69 73 20 6e 6f 74 0a 2a 2a 20 61 20 70 61  d is not.** a pa
8170: 72 74 20 6f 66 20 61 6e 20 6f 72 64 69 6e 61 72  rt of an ordinar
8180: 79 20 62 75 69 6c 64 2e 0a 2a 2f 0a 73 74 61 74  y build..*/.stat
8190: 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 77  ic const char *w
81a0: 61 6c 4c 6f 63 6b 4e 61 6d 65 28 69 6e 74 20 6c  alLockName(int l
81b0: 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66 28 20 6c  ockIdx){.  if( l
81c0: 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 57 52 49 54  ockIdx==WAL_WRIT
81d0: 45 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 72 65  E_LOCK ){.    re
81e0: 74 75 72 6e 20 22 57 52 49 54 45 2d 4c 4f 43 4b  turn "WRITE-LOCK
81f0: 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 6c  ";.  }else if( l
8200: 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 43 4b 50 54  ockIdx==WAL_CKPT
8210: 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 72 65 74  _LOCK ){.    ret
8220: 75 72 6e 20 22 43 4b 50 54 2d 4c 4f 43 4b 22 3b  urn "CKPT-LOCK";
8230: 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 6c 6f 63  .  }else if( loc
8240: 6b 49 64 78 3d 3d 57 41 4c 5f 52 45 43 4f 56 45  kIdx==WAL_RECOVE
8250: 52 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 72 65  R_LOCK ){.    re
8260: 74 75 72 6e 20 22 52 45 43 4f 56 45 52 2d 4c 4f  turn "RECOVER-LO
8270: 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  CK";.  }else{.  
8280: 20 20 73 74 61 74 69 63 20 63 68 61 72 20 7a 4e    static char zN
8290: 61 6d 65 5b 31 35 5d 3b 0a 20 20 20 20 73 71 6c  ame[15];.    sql
82a0: 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 73 69  ite3_snprintf(si
82b0: 7a 65 6f 66 28 7a 4e 61 6d 65 29 2c 20 7a 4e 61  zeof(zName), zNa
82c0: 6d 65 2c 20 22 52 45 41 44 2d 4c 4f 43 4b 5b 25  me, "READ-LOCK[%
82d0: 64 5d 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20  d]",.           
82e0: 20 20 20 20 20 20 20 20 20 20 6c 6f 63 6b 49 64            lockId
82f0: 78 2d 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  x-WAL_READ_LOCK(
8300: 30 29 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  0));.    return 
8310: 7a 4e 61 6d 65 3b 0a 20 20 7d 0a 7d 0a 23 65 6e  zName;.  }.}.#en
8320: 64 69 66 20 2f 2a 64 65 66 69 6e 65 64 28 53 51  dif /*defined(SQ
8330: 4c 49 54 45 5f 54 45 53 54 29 20 7c 7c 20 64 65  LITE_TEST) || de
8340: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42  fined(SQLITE_DEB
8350: 55 47 29 20 2a 2f 0a 20 20 20 20 0a 0a 2f 2a 0a  UG) */.    ../*.
8360: 2a 2a 20 53 65 74 20 6f 72 20 72 65 6c 65 61 73  ** Set or releas
8370: 65 20 6c 6f 63 6b 73 20 6f 6e 20 74 68 65 20 57  e locks on the W
8380: 41 4c 2e 20 20 4c 6f 63 6b 73 20 61 72 65 20 65  AL.  Locks are e
8390: 69 74 68 65 72 20 73 68 61 72 65 64 20 6f 72 20  ither shared or 
83a0: 65 78 63 6c 75 73 69 76 65 2e 0a 2a 2a 20 41 20  exclusive..** A 
83b0: 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62 65 20 6d  lock cannot be m
83c0: 6f 76 65 64 20 64 69 72 65 63 74 6c 79 20 62 65  oved directly be
83d0: 74 77 65 65 6e 20 73 68 61 72 65 64 20 61 6e 64  tween shared and
83e0: 20 65 78 63 6c 75 73 69 76 65 20 2d 20 69 74 20   exclusive - it 
83f0: 6d 75 73 74 20 67 6f 0a 2a 2a 20 74 68 72 6f 75  must go.** throu
8400: 67 68 20 74 68 65 20 75 6e 6c 6f 63 6b 65 64 20  gh the unlocked 
8410: 73 74 61 74 65 20 66 69 72 73 74 2e 0a 2a 2a 0a  state first..**.
8420: 2a 2a 20 49 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f  ** In locking_mo
8430: 64 65 3d 45 58 43 4c 55 53 49 56 45 2c 20 61 6c  de=EXCLUSIVE, al
8440: 6c 20 6f 66 20 74 68 65 73 65 20 72 6f 75 74 69  l of these routi
8450: 6e 65 73 20 62 65 63 6f 6d 65 20 6e 6f 2d 6f 70  nes become no-op
8460: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
8470: 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 57   walLockShared(W
8480: 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f  al *pWal, int lo
8490: 63 6b 49 64 78 29 7b 0a 20 20 69 6e 74 20 72 63  ckIdx){.  int rc
84a0: 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78  ;.  if( pWal->ex
84b0: 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65  clusiveMode ) re
84c0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
84d0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
84e0: 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44  ShmLock(pWal->pD
84f0: 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 31 2c  bFd, lockIdx, 1,
8500: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
8510: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
8520: 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49 54  SHM_LOCK | SQLIT
8530: 45 5f 53 48 4d 5f 53 48 41 52 45 44 29 3b 0a 20  E_SHM_SHARED);. 
8540: 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
8550: 70 3a 20 61 63 71 75 69 72 65 20 53 48 41 52 45  p: acquire SHARE
8560: 44 2d 25 73 20 25 73 5c 6e 22 2c 20 70 57 61 6c  D-%s %s\n", pWal
8570: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 77 61  ,.            wa
8580: 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64  lLockName(lockId
8590: 78 29 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64  x), rc ? "failed
85a0: 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 56 56  " : "ok"));.  VV
85b0: 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f  A_ONLY( pWal->lo
85c0: 63 6b 45 72 72 6f 72 20 3d 20 28 75 38 29 28 72  ckError = (u8)(r
85d0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c!=SQLITE_OK && 
85e0: 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 29  rc!=SQLITE_BUSY)
85f0: 3b 20 29 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ; ).  return rc;
8600: 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  .}.static void w
8610: 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 57  alUnlockShared(W
8620: 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f  al *pWal, int lo
8630: 63 6b 49 64 78 29 7b 0a 20 20 69 66 28 20 70 57  ckIdx){.  if( pW
8640: 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  al->exclusiveMod
8650: 65 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 28 76  e ) return;.  (v
8660: 6f 69 64 29 73 71 6c 69 74 65 33 4f 73 53 68 6d  oid)sqlite3OsShm
8670: 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64  Lock(pWal->pDbFd
8680: 2c 20 6c 6f 63 6b 49 64 78 2c 20 31 2c 0a 20 20  , lockIdx, 1,.  
8690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
86a0: 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53 48         SQLITE_SH
86b0: 4d 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51 4c 49 54  M_UNLOCK | SQLIT
86c0: 45 5f 53 48 4d 5f 53 48 41 52 45 44 29 3b 0a 20  E_SHM_SHARED);. 
86d0: 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
86e0: 70 3a 20 72 65 6c 65 61 73 65 20 53 48 41 52 45  p: release SHARE
86f0: 44 2d 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 77  D-%s\n", pWal, w
8700: 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49  alLockName(lockI
8710: 64 78 29 29 29 3b 0a 7d 0a 73 74 61 74 69 63 20  dx)));.}.static 
8720: 69 6e 74 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75  int walLockExclu
8730: 73 69 76 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20  sive(Wal *pWal, 
8740: 69 6e 74 20 6c 6f 63 6b 49 64 78 2c 20 69 6e 74  int lockIdx, int
8750: 20 6e 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20   n){.  int rc;. 
8760: 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75   if( pWal->exclu
8770: 73 69 76 65 4d 6f 64 65 20 29 20 72 65 74 75 72  siveMode ) retur
8780: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72  n SQLITE_OK;.  r
8790: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 68 6d  c = sqlite3OsShm
87a0: 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64  Lock(pWal->pDbFd
87b0: 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c 0a 20 20  , lockIdx, n,.  
87c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
87d0: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53 48 4d        SQLITE_SHM
87e0: 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53  _LOCK | SQLITE_S
87f0: 48 4d 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20  HM_EXCLUSIVE);. 
8800: 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
8810: 70 3a 20 61 63 71 75 69 72 65 20 45 58 43 4c 55  p: acquire EXCLU
8820: 53 49 56 45 2d 25 73 20 63 6e 74 3d 25 64 20 25  SIVE-%s cnt=%d %
8830: 73 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20 20 20 20  s\n", pWal,.    
8840: 20 20 20 20 20 20 20 20 77 61 6c 4c 6f 63 6b 4e          walLockN
8850: 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c 20 6e 2c  ame(lockIdx), n,
8860: 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a   rc ? "failed" :
8870: 20 22 6f 6b 22 29 29 3b 0a 20 20 56 56 41 5f 4f   "ok"));.  VVA_O
8880: 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45  NLY( pWal->lockE
8890: 72 72 6f 72 20 3d 20 28 75 38 29 28 72 63 21 3d  rror = (u8)(rc!=
88a0: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72 63 21  SQLITE_OK && rc!
88b0: 3d 53 51 4c 49 54 45 5f 42 55 53 59 29 3b 20 29  =SQLITE_BUSY); )
88c0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
88d0: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 55  static void walU
88e0: 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 57  nlockExclusive(W
88f0: 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f  al *pWal, int lo
8900: 63 6b 49 64 78 2c 20 69 6e 74 20 6e 29 7b 0a 20  ckIdx, int n){. 
8910: 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75   if( pWal->exclu
8920: 73 69 76 65 4d 6f 64 65 20 29 20 72 65 74 75 72  siveMode ) retur
8930: 6e 3b 0a 20 20 28 76 6f 69 64 29 73 71 6c 69 74  n;.  (void)sqlit
8940: 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c  e3OsShmLock(pWal
8950: 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78  ->pDbFd, lockIdx
8960: 2c 20 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20  , n,.           
8970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
8980: 4c 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f 43 4b 20  LITE_SHM_UNLOCK 
8990: 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f 45 58 43  | SQLITE_SHM_EXC
89a0: 4c 55 53 49 56 45 29 3b 0a 20 20 57 41 4c 54 52  LUSIVE);.  WALTR
89b0: 41 43 45 28 28 22 57 41 4c 25 70 3a 20 72 65 6c  ACE(("WAL%p: rel
89c0: 65 61 73 65 20 45 58 43 4c 55 53 49 56 45 2d 25  ease EXCLUSIVE-%
89d0: 73 20 63 6e 74 3d 25 64 5c 6e 22 2c 20 70 57 61  s cnt=%d\n", pWa
89e0: 6c 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  l,.             
89f0: 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b  walLockName(lock
8a00: 49 64 78 29 2c 20 6e 29 29 3b 0a 7d 0a 0a 2f 2a  Idx), n));.}../*
8a10: 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20 68 61  .** Compute a ha
8a20: 73 68 20 6f 6e 20 61 20 70 61 67 65 20 6e 75 6d  sh on a page num
8a30: 62 65 72 2e 20 20 54 68 65 20 72 65 73 75 6c 74  ber.  The result
8a40: 69 6e 67 20 68 61 73 68 20 76 61 6c 75 65 20 6d  ing hash value m
8a50: 75 73 74 20 6c 61 6e 64 0a 2a 2a 20 62 65 74 77  ust land.** betw
8a60: 65 65 6e 20 30 20 61 6e 64 20 28 48 41 53 48 54  een 0 and (HASHT
8a70: 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 2e 20 20  ABLE_NSLOT-1).  
8a80: 54 68 65 20 77 61 6c 48 61 73 68 4e 65 78 74 28  The walHashNext(
8a90: 29 20 66 75 6e 63 74 69 6f 6e 20 61 64 76 61 6e  ) function advan
8aa0: 63 65 73 0a 2a 2a 20 74 68 65 20 68 61 73 68 20  ces.** the hash 
8ab0: 74 6f 20 74 68 65 20 6e 65 78 74 20 76 61 6c 75  to the next valu
8ac0: 65 20 69 6e 20 74 68 65 20 65 76 65 6e 74 20 6f  e in the event o
8ad0: 66 20 61 20 63 6f 6c 6c 69 73 69 6f 6e 2e 0a 2a  f a collision..*
8ae0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
8af0: 48 61 73 68 28 75 33 32 20 69 50 61 67 65 29 7b  Hash(u32 iPage){
8b00: 0a 20 20 61 73 73 65 72 74 28 20 69 50 61 67 65  .  assert( iPage
8b10: 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  >0 );.  assert( 
8b20: 28 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54  (HASHTABLE_NSLOT
8b30: 20 26 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 53   & (HASHTABLE_NS
8b40: 4c 4f 54 2d 31 29 29 3d 3d 30 20 29 3b 0a 20 20  LOT-1))==0 );.  
8b50: 72 65 74 75 72 6e 20 28 69 50 61 67 65 2a 48 41  return (iPage*HA
8b60: 53 48 54 41 42 4c 45 5f 48 41 53 48 5f 31 29 20  SHTABLE_HASH_1) 
8b70: 26 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c  & (HASHTABLE_NSL
8b80: 4f 54 2d 31 29 3b 0a 7d 0a 73 74 61 74 69 63 20  OT-1);.}.static 
8b90: 69 6e 74 20 77 61 6c 4e 65 78 74 48 61 73 68 28  int walNextHash(
8ba0: 69 6e 74 20 69 50 72 69 6f 72 48 61 73 68 29 7b  int iPriorHash){
8bb0: 0a 20 20 72 65 74 75 72 6e 20 28 69 50 72 69 6f  .  return (iPrio
8bc0: 72 48 61 73 68 2b 31 29 26 28 48 41 53 48 54 41  rHash+1)&(HASHTA
8bd0: 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 3b 0a 7d 0a  BLE_NSLOT-1);.}.
8be0: 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 70  ./* .** Return p
8bf0: 6f 69 6e 74 65 72 73 20 74 6f 20 74 68 65 20 68  ointers to the h
8c00: 61 73 68 20 74 61 62 6c 65 20 61 6e 64 20 70 61  ash table and pa
8c10: 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20  ge number array 
8c20: 73 74 6f 72 65 64 20 6f 6e 0a 2a 2a 20 70 61 67  stored on.** pag
8c30: 65 20 69 48 61 73 68 20 6f 66 20 74 68 65 20 77  e iHash of the w
8c40: 61 6c 2d 69 6e 64 65 78 2e 20 54 68 65 20 77 61  al-index. The wa
8c50: 6c 2d 69 6e 64 65 78 20 69 73 20 62 72 6f 6b 65  l-index is broke
8c60: 6e 20 69 6e 74 6f 20 33 32 4b 42 20 70 61 67 65  n into 32KB page
8c70: 73 0a 2a 2a 20 6e 75 6d 62 65 72 65 64 20 73 74  s.** numbered st
8c80: 61 72 74 69 6e 67 20 66 72 6f 6d 20 30 2e 0a 2a  arting from 0..*
8c90: 2a 0a 2a 2a 20 53 65 74 20 6f 75 74 70 75 74 20  *.** Set output 
8ca0: 76 61 72 69 61 62 6c 65 20 2a 70 61 48 61 73 68  variable *paHash
8cb0: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   to point to the
8cc0: 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 68 61   start of the ha
8cd0: 73 68 20 74 61 62 6c 65 0a 2a 2a 20 69 6e 20 74  sh table.** in t
8ce0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  he wal-index fil
8cf0: 65 2e 20 53 65 74 20 2a 70 69 5a 65 72 6f 20 74  e. Set *piZero t
8d00: 6f 20 6f 6e 65 20 6c 65 73 73 20 74 68 61 6e 20  o one less than 
8d10: 74 68 65 20 66 72 61 6d 65 20 0a 2a 2a 20 6e 75  the frame .** nu
8d20: 6d 62 65 72 20 6f 66 20 74 68 65 20 66 69 72 73  mber of the firs
8d30: 74 20 66 72 61 6d 65 20 69 6e 64 65 78 65 64 20  t frame indexed 
8d40: 62 79 20 74 68 69 73 20 68 61 73 68 20 74 61 62  by this hash tab
8d50: 6c 65 2e 20 49 66 20 61 0a 2a 2a 20 73 6c 6f 74  le. If a.** slot
8d60: 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62   in the hash tab
8d70: 6c 65 20 69 73 20 73 65 74 20 74 6f 20 4e 2c 20  le is set to N, 
8d80: 69 74 20 72 65 66 65 72 73 20 74 6f 20 66 72 61  it refers to fra
8d90: 6d 65 20 6e 75 6d 62 65 72 20 0a 2a 2a 20 28 2a  me number .** (*
8da0: 70 69 5a 65 72 6f 2b 4e 29 20 69 6e 20 74 68 65  piZero+N) in the
8db0: 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a 20 46 69 6e 61   log..**.** Fina
8dc0: 6c 6c 79 2c 20 73 65 74 20 2a 70 61 50 67 6e 6f  lly, set *paPgno
8dd0: 20 73 6f 20 74 68 61 74 20 2a 70 61 50 67 6e 6f   so that *paPgno
8de0: 5b 31 5d 20 69 73 20 74 68 65 20 70 61 67 65 20  [1] is the page 
8df0: 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 0a 2a 2a  number of the.**
8e00: 20 66 69 72 73 74 20 66 72 61 6d 65 20 69 6e 64   first frame ind
8e10: 65 78 65 64 20 62 79 20 74 68 65 20 68 61 73 68  exed by the hash
8e20: 20 74 61 62 6c 65 2c 20 66 72 61 6d 65 20 28 2a   table, frame (*
8e30: 70 69 5a 65 72 6f 2b 31 29 2e 0a 2a 2f 0a 73 74  piZero+1)..*/.st
8e40: 61 74 69 63 20 69 6e 74 20 77 61 6c 48 61 73 68  atic int walHash
8e50: 47 65 74 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c  Get(.  Wal *pWal
8e60: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8e70: 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 68 61         /* WAL ha
8e80: 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 69 48  ndle */.  int iH
8e90: 61 73 68 2c 20 20 20 20 20 20 20 20 20 20 20 20  ash,            
8ea0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6e            /* Fin
8eb0: 64 20 74 68 65 20 69 48 61 73 68 27 74 68 20 74  d the iHash'th t
8ec0: 61 62 6c 65 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  able */.  volati
8ed0: 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 2a 70 61 48  le ht_slot **paH
8ee0: 61 73 68 2c 20 20 20 20 20 20 2f 2a 20 4f 55 54  ash,      /* OUT
8ef0: 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20 68 61 73  : Pointer to has
8f00: 68 20 69 6e 64 65 78 20 2a 2f 0a 20 20 76 6f 6c  h index */.  vol
8f10: 61 74 69 6c 65 20 75 33 32 20 2a 2a 70 61 50 67  atile u32 **paPg
8f20: 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  no,          /* 
8f30: 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20  OUT: Pointer to 
8f40: 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61  page number arra
8f50: 79 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 5a 65  y */.  u32 *piZe
8f60: 72 6f 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ro              
8f70: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 46         /* OUT: F
8f80: 72 61 6d 65 20 61 73 73 6f 63 69 61 74 65 64 20  rame associated 
8f90: 77 69 74 68 20 2a 70 61 50 67 6e 6f 5b 30 5d 20  with *paPgno[0] 
8fa0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  */.){.  int rc; 
8fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8fc0: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
8fd0: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 76 6f 6c 61  n code */.  vola
8fe0: 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 3b  tile u32 *aPgno;
8ff0: 0a 0a 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65  ..  rc = walInde
9000: 78 50 61 67 65 28 70 57 61 6c 2c 20 69 48 61 73  xPage(pWal, iHas
9010: 68 2c 20 26 61 50 67 6e 6f 29 3b 0a 20 20 61 73  h, &aPgno);.  as
9020: 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45  sert( rc==SQLITE
9030: 5f 4f 4b 20 7c 7c 20 69 48 61 73 68 3e 30 20 29  _OK || iHash>0 )
9040: 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  ;..  if( rc==SQL
9050: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 75 33  ITE_OK ){.    u3
9060: 32 20 69 5a 65 72 6f 3b 0a 20 20 20 20 76 6f 6c  2 iZero;.    vol
9070: 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 61  atile ht_slot *a
9080: 48 61 73 68 3b 0a 0a 20 20 20 20 61 48 61 73 68  Hash;..    aHash
9090: 20 3d 20 28 76 6f 6c 61 74 69 6c 65 20 68 74 5f   = (volatile ht_
90a0: 73 6c 6f 74 20 2a 29 26 61 50 67 6e 6f 5b 48 41  slot *)&aPgno[HA
90b0: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5d 3b 0a  SHTABLE_NPAGE];.
90c0: 20 20 20 20 69 66 28 20 69 48 61 73 68 3d 3d 30      if( iHash==0
90d0: 20 29 7b 0a 20 20 20 20 20 20 61 50 67 6e 6f 20   ){.      aPgno 
90e0: 3d 20 26 61 50 67 6e 6f 5b 57 41 4c 49 4e 44 45  = &aPgno[WALINDE
90f0: 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f  X_HDR_SIZE/sizeo
9100: 66 28 75 33 32 29 5d 3b 0a 20 20 20 20 20 20 69  f(u32)];.      i
9110: 5a 65 72 6f 20 3d 20 30 3b 0a 20 20 20 20 7d 65  Zero = 0;.    }e
9120: 6c 73 65 7b 0a 20 20 20 20 20 20 69 5a 65 72 6f  lse{.      iZero
9130: 20 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41   = HASHTABLE_NPA
9140: 47 45 5f 4f 4e 45 20 2b 20 28 69 48 61 73 68 2d  GE_ONE + (iHash-
9150: 31 29 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  1)*HASHTABLE_NPA
9160: 47 45 3b 0a 20 20 20 20 7d 0a 20 20 0a 20 20 20  GE;.    }.  .   
9170: 20 2a 70 61 50 67 6e 6f 20 3d 20 26 61 50 67 6e   *paPgno = &aPgn
9180: 6f 5b 2d 31 5d 3b 0a 20 20 20 20 2a 70 61 48 61  o[-1];.    *paHa
9190: 73 68 20 3d 20 61 48 61 73 68 3b 0a 20 20 20 20  sh = aHash;.    
91a0: 2a 70 69 5a 65 72 6f 20 3d 20 69 5a 65 72 6f 3b  *piZero = iZero;
91b0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
91c0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
91d0: 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  n the number of 
91e0: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 70 61  the wal-index pa
91f0: 67 65 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73  ge that contains
9200: 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65 0a   the hash-table.
9210: 2a 2a 20 61 6e 64 20 70 61 67 65 2d 6e 75 6d 62  ** and page-numb
9220: 65 72 20 61 72 72 61 79 20 74 68 61 74 20 63 6f  er array that co
9230: 6e 74 61 69 6e 20 65 6e 74 72 69 65 73 20 63 6f  ntain entries co
9240: 72 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 57  rresponding to W
9250: 41 4c 20 66 72 61 6d 65 0a 2a 2a 20 69 46 72 61  AL frame.** iFra
9260: 6d 65 2e 20 54 68 65 20 77 61 6c 2d 69 6e 64 65  me. The wal-inde
9270: 78 20 69 73 20 62 72 6f 6b 65 6e 20 75 70 20 69  x is broken up i
9280: 6e 74 6f 20 33 32 4b 42 20 70 61 67 65 73 2e 20  nto 32KB pages. 
9290: 57 61 6c 2d 69 6e 64 65 78 20 70 61 67 65 73 20  Wal-index pages 
92a0: 0a 2a 2a 20 61 72 65 20 6e 75 6d 62 65 72 65 64  .** are numbered
92b0: 20 73 74 61 72 74 69 6e 67 20 66 72 6f 6d 20 30   starting from 0
92c0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
92d0: 77 61 6c 46 72 61 6d 65 50 61 67 65 28 75 33 32  walFramePage(u32
92e0: 20 69 46 72 61 6d 65 29 7b 0a 20 20 69 6e 74 20   iFrame){.  int 
92f0: 69 48 61 73 68 20 3d 20 28 69 46 72 61 6d 65 2b  iHash = (iFrame+
9300: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 2d  HASHTABLE_NPAGE-
9310: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
9320: 4f 4e 45 2d 31 29 20 2f 20 48 41 53 48 54 41 42  ONE-1) / HASHTAB
9330: 4c 45 5f 4e 50 41 47 45 3b 0a 20 20 61 73 73 65  LE_NPAGE;.  asse
9340: 72 74 28 20 28 69 48 61 73 68 3d 3d 30 20 7c 7c  rt( (iHash==0 ||
9350: 20 69 46 72 61 6d 65 3e 48 41 53 48 54 41 42 4c   iFrame>HASHTABL
9360: 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 0a 20 20 20  E_NPAGE_ONE).   
9370: 20 20 20 20 26 26 20 28 69 48 61 73 68 3e 3d 31      && (iHash>=1
9380: 20 7c 7c 20 69 46 72 61 6d 65 3c 3d 48 41 53 48   || iFrame<=HASH
9390: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29  TABLE_NPAGE_ONE)
93a0: 0a 20 20 20 20 20 20 20 26 26 20 28 69 48 61 73  .       && (iHas
93b0: 68 3c 3d 31 20 7c 7c 20 69 46 72 61 6d 65 3e 28  h<=1 || iFrame>(
93c0: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
93d0: 4f 4e 45 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50  ONE+HASHTABLE_NP
93e0: 41 47 45 29 29 0a 20 20 20 20 20 20 20 26 26 20  AGE)).       && 
93f0: 28 69 48 61 73 68 3e 3d 32 20 7c 7c 20 69 46 72  (iHash>=2 || iFr
9400: 61 6d 65 3c 3d 48 41 53 48 54 41 42 4c 45 5f 4e  ame<=HASHTABLE_N
9410: 50 41 47 45 5f 4f 4e 45 2b 48 41 53 48 54 41 42  PAGE_ONE+HASHTAB
9420: 4c 45 5f 4e 50 41 47 45 29 0a 20 20 20 20 20 20  LE_NPAGE).      
9430: 20 26 26 20 28 69 48 61 73 68 3c 3d 32 20 7c 7c   && (iHash<=2 ||
9440: 20 69 46 72 61 6d 65 3e 28 48 41 53 48 54 41 42   iFrame>(HASHTAB
9450: 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 32 2a 48  LE_NPAGE_ONE+2*H
9460: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 29 29  ASHTABLE_NPAGE))
9470: 0a 20 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 69  .  );.  return i
9480: 48 61 73 68 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  Hash;.}../*.** R
9490: 65 74 75 72 6e 20 74 68 65 20 70 61 67 65 20 6e  eturn the page n
94a0: 75 6d 62 65 72 20 61 73 73 6f 63 69 61 74 65 64  umber associated
94b0: 20 77 69 74 68 20 66 72 61 6d 65 20 69 46 72 61   with frame iFra
94c0: 6d 65 20 69 6e 20 74 68 69 73 20 57 41 4c 2e 0a  me in this WAL..
94d0: 2a 2f 0a 73 74 61 74 69 63 20 75 33 32 20 77 61  */.static u32 wa
94e0: 6c 46 72 61 6d 65 50 67 6e 6f 28 57 61 6c 20 2a  lFramePgno(Wal *
94f0: 70 57 61 6c 2c 20 75 33 32 20 69 46 72 61 6d 65  pWal, u32 iFrame
9500: 29 7b 0a 20 20 69 6e 74 20 69 48 61 73 68 20 3d  ){.  int iHash =
9510: 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69 46   walFramePage(iF
9520: 72 61 6d 65 29 3b 0a 20 20 69 66 28 20 69 48 61  rame);.  if( iHa
9530: 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  sh==0 ){.    ret
9540: 75 72 6e 20 70 57 61 6c 2d 3e 61 70 57 69 44 61  urn pWal->apWiDa
9550: 74 61 5b 30 5d 5b 57 41 4c 49 4e 44 45 58 5f 48  ta[0][WALINDEX_H
9560: 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f 66 28 75  DR_SIZE/sizeof(u
9570: 33 32 29 20 2b 20 69 46 72 61 6d 65 20 2d 20 31  32) + iFrame - 1
9580: 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  ];.  }.  return 
9590: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69  pWal->apWiData[i
95a0: 48 61 73 68 5d 5b 28 69 46 72 61 6d 65 2d 31 2d  Hash][(iFrame-1-
95b0: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
95c0: 4f 4e 45 29 25 48 41 53 48 54 41 42 4c 45 5f 4e  ONE)%HASHTABLE_N
95d0: 50 41 47 45 5d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  PAGE];.}../*.** 
95e0: 52 65 6d 6f 76 65 20 65 6e 74 72 69 65 73 20 66  Remove entries f
95f0: 72 6f 6d 20 74 68 65 20 68 61 73 68 20 74 61 62  rom the hash tab
9600: 6c 65 20 74 68 61 74 20 70 6f 69 6e 74 20 74 6f  le that point to
9610: 20 57 41 4c 20 73 6c 6f 74 73 20 67 72 65 61 74   WAL slots great
9620: 65 72 0a 2a 2a 20 74 68 61 6e 20 70 57 61 6c 2d  er.** than pWal-
9630: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a 2a 2a  >hdr.mxFrame..**
9640: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
9650: 6e 20 69 73 20 63 61 6c 6c 65 64 20 77 68 65 6e  n is called when
9660: 65 76 65 72 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  ever pWal->hdr.m
9670: 78 46 72 61 6d 65 20 69 73 20 64 65 63 72 65 61  xFrame is decrea
9680: 73 65 64 20 64 75 65 0a 2a 2a 20 74 6f 20 61 20  sed due.** to a 
9690: 72 6f 6c 6c 62 61 63 6b 20 6f 72 20 73 61 76 65  rollback or save
96a0: 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20 41 74 20  point..**.** At 
96b0: 6d 6f 73 74 20 6f 6e 6c 79 20 74 68 65 20 68 61  most only the ha
96c0: 73 68 20 74 61 62 6c 65 20 63 6f 6e 74 61 69 6e  sh table contain
96d0: 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  ing pWal->hdr.mx
96e0: 46 72 61 6d 65 20 6e 65 65 64 73 20 74 6f 20 62  Frame needs to b
96f0: 65 0a 2a 2a 20 75 70 64 61 74 65 64 2e 20 20 41  e.** updated.  A
9700: 6e 79 20 6c 61 74 65 72 20 68 61 73 68 20 74 61  ny later hash ta
9710: 62 6c 65 73 20 77 69 6c 6c 20 62 65 20 61 75 74  bles will be aut
9720: 6f 6d 61 74 69 63 61 6c 6c 79 20 63 6c 65 61 72  omatically clear
9730: 65 64 20 77 68 65 6e 0a 2a 2a 20 70 57 61 6c 2d  ed when.** pWal-
9740: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 61 64 76  >hdr.mxFrame adv
9750: 61 6e 63 65 73 20 74 6f 20 74 68 65 20 70 6f 69  ances to the poi
9760: 6e 74 20 77 68 65 72 65 20 74 68 6f 73 65 20 68  nt where those h
9770: 61 73 68 20 74 61 62 6c 65 73 20 61 72 65 0a 2a  ash tables are.*
9780: 2a 20 61 63 74 75 61 6c 6c 79 20 6e 65 65 64 65  * actually neede
9790: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d..*/.static voi
97a0: 64 20 77 61 6c 43 6c 65 61 6e 75 70 48 61 73 68  d walCleanupHash
97b0: 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 76  (Wal *pWal){.  v
97c0: 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20  olatile ht_slot 
97d0: 2a 61 48 61 73 68 20 3d 20 30 3b 20 20 20 20 2f  *aHash = 0;    /
97e0: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 68 61 73  * Pointer to has
97f0: 68 20 74 61 62 6c 65 20 74 6f 20 63 6c 65 61 72  h table to clear
9800: 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75   */.  volatile u
9810: 33 32 20 2a 61 50 67 6e 6f 20 3d 20 30 3b 20 20  32 *aPgno = 0;  
9820: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75        /* Page nu
9830: 6d 62 65 72 20 61 72 72 61 79 20 66 6f 72 20 68  mber array for h
9840: 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 75  ash table */.  u
9850: 33 32 20 69 5a 65 72 6f 20 3d 20 30 3b 20 20 20  32 iZero = 0;   
9860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9870: 2a 20 66 72 61 6d 65 20 3d 3d 20 28 61 48 61 73  * frame == (aHas
9880: 68 5b 78 5d 2b 69 5a 65 72 6f 29 20 2a 2f 0a 20  h[x]+iZero) */. 
9890: 20 69 6e 74 20 69 4c 69 6d 69 74 20 3d 20 30 3b   int iLimit = 0;
98a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
98b0: 20 2f 2a 20 5a 65 72 6f 20 76 61 6c 75 65 73 20   /* Zero values 
98c0: 67 72 65 61 74 65 72 20 74 68 61 6e 20 74 68 69  greater than thi
98d0: 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65  s */.  int nByte
98e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
98f0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
9900: 20 6f 66 20 62 79 74 65 73 20 74 6f 20 7a 65 72   of bytes to zer
9910: 6f 20 69 6e 20 61 50 67 6e 6f 5b 5d 20 2a 2f 0a  o in aPgno[] */.
9920: 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
9930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9940: 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74 65    /* Used to ite
9950: 72 61 74 65 20 74 68 72 6f 75 67 68 20 61 48 61  rate through aHa
9960: 73 68 5b 5d 20 2a 2f 0a 0a 20 20 61 73 73 65 72  sh[] */..  asser
9970: 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  t( pWal->writeLo
9980: 63 6b 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65  ck );.  testcase
9990: 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  ( pWal->hdr.mxFr
99a0: 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45 5f 4e  ame==HASHTABLE_N
99b0: 50 41 47 45 5f 4f 4e 45 2d 31 20 29 3b 0a 20 20  PAGE_ONE-1 );.  
99c0: 74 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d 3e  testcase( pWal->
99d0: 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 48 41 53  hdr.mxFrame==HAS
99e0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45  HTABLE_NPAGE_ONE
99f0: 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20   );.  testcase( 
9a00: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
9a10: 65 3d 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  e==HASHTABLE_NPA
9a20: 47 45 5f 4f 4e 45 2b 31 20 29 3b 0a 0a 20 20 69  GE_ONE+1 );..  i
9a30: 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  f( pWal->hdr.mxF
9a40: 72 61 6d 65 3d 3d 30 20 29 20 72 65 74 75 72 6e  rame==0 ) return
9a50: 3b 0a 0a 20 20 2f 2a 20 4f 62 74 61 69 6e 20 70  ;..  /* Obtain p
9a60: 6f 69 6e 74 65 72 73 20 74 6f 20 74 68 65 20 68  ointers to the h
9a70: 61 73 68 2d 74 61 62 6c 65 20 61 6e 64 20 70 61  ash-table and pa
9a80: 67 65 2d 6e 75 6d 62 65 72 20 61 72 72 61 79 20  ge-number array 
9a90: 63 6f 6e 74 61 69 6e 69 6e 67 20 0a 20 20 2a 2a  containing .  **
9aa0: 20 74 68 65 20 65 6e 74 72 79 20 74 68 61 74 20   the entry that 
9ab0: 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20 66  corresponds to f
9ac0: 72 61 6d 65 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  rame pWal->hdr.m
9ad0: 78 46 72 61 6d 65 2e 20 49 74 20 69 73 20 67 75  xFrame. It is gu
9ae0: 61 72 61 6e 74 65 65 64 0a 20 20 2a 2a 20 74 68  aranteed.  ** th
9af0: 61 74 20 74 68 65 20 70 61 67 65 20 73 61 69 64  at the page said
9b00: 20 68 61 73 68 2d 74 61 62 6c 65 20 61 6e 64 20   hash-table and 
9b10: 61 72 72 61 79 20 72 65 73 69 64 65 20 6f 6e 20  array reside on 
9b20: 69 73 20 61 6c 72 65 61 64 79 20 6d 61 70 70 65  is already mappe
9b30: 64 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74  d..  */.  assert
9b40: 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e  ( pWal->nWiData>
9b50: 77 61 6c 46 72 61 6d 65 50 61 67 65 28 70 57 61  walFramePage(pWa
9b60: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 29 20  l->hdr.mxFrame) 
9b70: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  );.  assert( pWa
9b80: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 77 61 6c 46  l->apWiData[walF
9b90: 72 61 6d 65 50 61 67 65 28 70 57 61 6c 2d 3e 68  ramePage(pWal->h
9ba0: 64 72 2e 6d 78 46 72 61 6d 65 29 5d 20 29 3b 0a  dr.mxFrame)] );.
9bb0: 20 20 77 61 6c 48 61 73 68 47 65 74 28 70 57 61    walHashGet(pWa
9bc0: 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28  l, walFramePage(
9bd0: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
9be0: 65 29 2c 20 26 61 48 61 73 68 2c 20 26 61 50 67  e), &aHash, &aPg
9bf0: 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 0a 20 20  no, &iZero);..  
9c00: 2f 2a 20 5a 65 72 6f 20 61 6c 6c 20 68 61 73 68  /* Zero all hash
9c10: 2d 74 61 62 6c 65 20 65 6e 74 72 69 65 73 20 74  -table entries t
9c20: 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 20 74  hat correspond t
9c30: 6f 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 73 20  o frame numbers 
9c40: 67 72 65 61 74 65 72 0a 20 20 2a 2a 20 74 68 61  greater.  ** tha
9c50: 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  n pWal->hdr.mxFr
9c60: 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 4c 69 6d  ame..  */.  iLim
9c70: 69 74 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  it = pWal->hdr.m
9c80: 78 46 72 61 6d 65 20 2d 20 69 5a 65 72 6f 3b 0a  xFrame - iZero;.
9c90: 20 20 61 73 73 65 72 74 28 20 69 4c 69 6d 69 74    assert( iLimit
9ca0: 3e 30 20 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  >0 );.  for(i=0;
9cb0: 20 69 3c 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c   i<HASHTABLE_NSL
9cc0: 4f 54 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66  OT; i++){.    if
9cd0: 28 20 61 48 61 73 68 5b 69 5d 3e 69 4c 69 6d 69  ( aHash[i]>iLimi
9ce0: 74 20 29 7b 0a 20 20 20 20 20 20 61 48 61 73 68  t ){.      aHash
9cf0: 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20  [i] = 0;.    }. 
9d00: 20 7d 0a 20 20 0a 20 20 2f 2a 20 5a 65 72 6f 20   }.  .  /* Zero 
9d10: 74 68 65 20 65 6e 74 72 69 65 73 20 69 6e 20 74  the entries in t
9d20: 68 65 20 61 50 67 6e 6f 20 61 72 72 61 79 20 74  he aPgno array t
9d30: 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 20 74  hat correspond t
9d40: 6f 20 66 72 61 6d 65 73 20 77 69 74 68 0a 20 20  o frames with.  
9d50: 2a 2a 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 73  ** frame numbers
9d60: 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 70 57   greater than pW
9d70: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e  al->hdr.mxFrame.
9d80: 20 0a 20 20 2a 2f 0a 20 20 6e 42 79 74 65 20 3d   .  */.  nByte =
9d90: 20 28 69 6e 74 29 28 28 63 68 61 72 20 2a 29 61   (int)((char *)a
9da0: 48 61 73 68 20 2d 20 28 63 68 61 72 20 2a 29 26  Hash - (char *)&
9db0: 61 50 67 6e 6f 5b 69 4c 69 6d 69 74 2b 31 5d 29  aPgno[iLimit+1])
9dc0: 3b 0a 20 20 6d 65 6d 73 65 74 28 28 76 6f 69 64  ;.  memset((void
9dd0: 20 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d 69 74   *)&aPgno[iLimit
9de0: 2b 31 5d 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a  +1], 0, nByte);.
9df0: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45  .#ifdef SQLITE_E
9e00: 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f  NABLE_EXPENSIVE_
9e10: 41 53 53 45 52 54 0a 20 20 2f 2a 20 56 65 72 69  ASSERT.  /* Veri
9e20: 66 79 20 74 68 61 74 20 74 68 65 20 65 76 65 72  fy that the ever
9e30: 79 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d  y entry in the m
9e40: 61 70 70 69 6e 67 20 72 65 67 69 6f 6e 20 69 73  apping region is
9e50: 20 73 74 69 6c 6c 20 72 65 61 63 68 61 62 6c 65   still reachable
9e60: 0a 20 20 2a 2a 20 76 69 61 20 74 68 65 20 68 61  .  ** via the ha
9e70: 73 68 20 74 61 62 6c 65 20 65 76 65 6e 20 61 66  sh table even af
9e80: 74 65 72 20 74 68 65 20 63 6c 65 61 6e 75 70 2e  ter the cleanup.
9e90: 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69 4c 69 6d  .  */.  if( iLim
9ea0: 69 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 6a 3b  it ){.    int j;
9eb0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f             /* Lo
9ec0: 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20  op counter */.  
9ed0: 20 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20    int iKey;     
9ee0: 20 20 20 2f 2a 20 48 61 73 68 20 6b 65 79 20 2a     /* Hash key *
9ef0: 2f 0a 20 20 20 20 66 6f 72 28 6a 3d 31 3b 20 6a  /.    for(j=1; j
9f00: 3c 3d 69 4c 69 6d 69 74 3b 20 6a 2b 2b 29 7b 0a  <=iLimit; j++){.
9f10: 20 20 20 20 20 20 66 6f 72 28 69 4b 65 79 3d 77        for(iKey=w
9f20: 61 6c 48 61 73 68 28 61 50 67 6e 6f 5b 6a 5d 29  alHash(aPgno[j])
9f30: 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20 69  ; aHash[iKey]; i
9f40: 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68 28  Key=walNextHash(
9f50: 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 20 20  iKey)){.        
9f60: 69 66 28 20 61 48 61 73 68 5b 69 4b 65 79 5d 3d  if( aHash[iKey]=
9f70: 3d 6a 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  =j ) break;.    
9f80: 20 20 7d 0a 20 20 20 20 20 20 61 73 73 65 72 74    }.      assert
9f90: 28 20 61 48 61 73 68 5b 69 4b 65 79 5d 3d 3d 6a  ( aHash[iKey]==j
9fa0: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 23 65   );.    }.  }.#e
9fb0: 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45  ndif /* SQLITE_E
9fc0: 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f  NABLE_EXPENSIVE_
9fd0: 41 53 53 45 52 54 20 2a 2f 0a 7d 0a 0a 0a 2f 2a  ASSERT */.}.../*
9fe0: 0a 2a 2a 20 53 65 74 20 61 6e 20 65 6e 74 72 79  .** Set an entry
9ff0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
a000: 78 20 74 68 61 74 20 77 69 6c 6c 20 6d 61 70 20  x that will map 
a010: 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6e 75  database page nu
a020: 6d 62 65 72 0a 2a 2a 20 70 50 61 67 65 20 69 6e  mber.** pPage in
a030: 74 6f 20 57 41 4c 20 66 72 61 6d 65 20 69 46 72  to WAL frame iFr
a040: 61 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ame..*/.static i
a050: 6e 74 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e  nt walIndexAppen
a060: 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32  d(Wal *pWal, u32
a070: 20 69 46 72 61 6d 65 2c 20 75 33 32 20 69 50 61   iFrame, u32 iPa
a080: 67 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20  ge){.  int rc;  
a090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a0a0: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
a0b0: 20 63 6f 64 65 20 2a 2f 0a 20 20 75 33 32 20 69   code */.  u32 i
a0c0: 5a 65 72 6f 20 3d 20 30 3b 20 20 20 20 20 20 20  Zero = 0;       
a0d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e             /* On
a0e0: 65 20 6c 65 73 73 20 74 68 61 6e 20 66 72 61 6d  e less than fram
a0f0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 61 50 67 6e  e number of aPgn
a100: 6f 5b 31 5d 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  o[1] */.  volati
a110: 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 20 3d 20  le u32 *aPgno = 
a120: 30 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67  0;        /* Pag
a130: 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 2a  e number array *
a140: 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f  /.  volatile ht_
a150: 73 6c 6f 74 20 2a 61 48 61 73 68 20 3d 20 30 3b  slot *aHash = 0;
a160: 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c      /* Hash tabl
a170: 65 20 2a 2f 0a 0a 20 20 72 63 20 3d 20 77 61 6c  e */..  rc = wal
a180: 48 61 73 68 47 65 74 28 70 57 61 6c 2c 20 77 61  HashGet(pWal, wa
a190: 6c 46 72 61 6d 65 50 61 67 65 28 69 46 72 61 6d  lFramePage(iFram
a1a0: 65 29 2c 20 26 61 48 61 73 68 2c 20 26 61 50 67  e), &aHash, &aPg
a1b0: 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 0a 20 20  no, &iZero);..  
a1c0: 2f 2a 20 41 73 73 75 6d 69 6e 67 20 74 68 65 20  /* Assuming the 
a1d0: 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20 77  wal-index file w
a1e0: 61 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20  as successfully 
a1f0: 6d 61 70 70 65 64 2c 20 70 6f 70 75 6c 61 74 65  mapped, populate
a200: 20 74 68 65 0a 20 20 2a 2a 20 70 61 67 65 20 6e   the.  ** page n
a210: 75 6d 62 65 72 20 61 72 72 61 79 20 61 6e 64 20  umber array and 
a220: 68 61 73 68 20 74 61 62 6c 65 20 65 6e 74 72 79  hash table entry
a230: 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  ..  */.  if( rc=
a240: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
a250: 20 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20    int iKey;     
a260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a270: 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 6b 65  /* Hash table ke
a280: 79 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 64 78  y */.    int idx
a290: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
a2a0: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
a2b0: 74 6f 20 77 72 69 74 65 20 74 6f 20 68 61 73 68  to write to hash
a2c0: 2d 74 61 62 6c 65 20 73 6c 6f 74 20 2a 2f 0a 20  -table slot */. 
a2d0: 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69 64 65 3b     int nCollide;
a2e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a2f0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 68 61   /* Number of ha
a300: 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73 20 2a 2f  sh collisions */
a310: 0a 0a 20 20 20 20 69 64 78 20 3d 20 69 46 72 61  ..    idx = iFra
a320: 6d 65 20 2d 20 69 5a 65 72 6f 3b 0a 20 20 20 20  me - iZero;.    
a330: 61 73 73 65 72 74 28 20 69 64 78 20 3c 3d 20 48  assert( idx <= H
a340: 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2f 32  ASHTABLE_NSLOT/2
a350: 20 2b 20 31 20 29 3b 0a 20 20 20 20 0a 20 20 20   + 1 );.    .   
a360: 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20 74   /* If this is t
a370: 68 65 20 66 69 72 73 74 20 65 6e 74 72 79 20 74  he first entry t
a380: 6f 20 62 65 20 61 64 64 65 64 20 74 6f 20 74 68  o be added to th
a390: 69 73 20 68 61 73 68 2d 74 61 62 6c 65 2c 20 7a  is hash-table, z
a3a0: 65 72 6f 20 74 68 65 0a 20 20 20 20 2a 2a 20 65  ero the.    ** e
a3b0: 6e 74 69 72 65 20 68 61 73 68 20 74 61 62 6c 65  ntire hash table
a3c0: 20 61 6e 64 20 61 50 67 6e 6f 5b 5d 20 61 72 72   and aPgno[] arr
a3d0: 61 79 20 62 65 66 6f 72 65 20 70 72 6f 63 65 65  ay before procee
a3e0: 64 69 6e 67 2e 20 0a 20 20 20 20 2a 2f 0a 20 20  ding. .    */.  
a3f0: 20 20 69 66 28 20 69 64 78 3d 3d 31 20 29 7b 0a    if( idx==1 ){.
a400: 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20        int nByte 
a410: 3d 20 28 69 6e 74 29 28 28 75 38 20 2a 29 26 61  = (int)((u8 *)&a
a420: 48 61 73 68 5b 48 41 53 48 54 41 42 4c 45 5f 4e  Hash[HASHTABLE_N
a430: 53 4c 4f 54 5d 20 2d 20 28 75 38 20 2a 29 26 61  SLOT] - (u8 *)&a
a440: 50 67 6e 6f 5b 31 5d 29 3b 0a 20 20 20 20 20 20  Pgno[1]);.      
a450: 6d 65 6d 73 65 74 28 28 76 6f 69 64 2a 29 26 61  memset((void*)&a
a460: 50 67 6e 6f 5b 31 5d 2c 20 30 2c 20 6e 42 79 74  Pgno[1], 0, nByt
a470: 65 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  e);.    }..    /
a480: 2a 20 49 66 20 74 68 65 20 65 6e 74 72 79 20 69  * If the entry i
a490: 6e 20 61 50 67 6e 6f 5b 5d 20 69 73 20 61 6c 72  n aPgno[] is alr
a4a0: 65 61 64 79 20 73 65 74 2c 20 74 68 65 6e 20 74  eady set, then t
a4b0: 68 65 20 70 72 65 76 69 6f 75 73 20 77 72 69 74  he previous writ
a4c0: 65 72 0a 20 20 20 20 2a 2a 20 6d 75 73 74 20 68  er.    ** must h
a4d0: 61 76 65 20 65 78 69 74 65 64 20 75 6e 65 78 70  ave exited unexp
a4e0: 65 63 74 65 64 6c 79 20 69 6e 20 74 68 65 20 6d  ectedly in the m
a4f0: 69 64 64 6c 65 20 6f 66 20 61 20 74 72 61 6e 73  iddle of a trans
a500: 61 63 74 69 6f 6e 20 28 61 66 74 65 72 0a 20 20  action (after.  
a510: 20 20 2a 2a 20 77 72 69 74 69 6e 67 20 6f 6e 65    ** writing one
a520: 20 6f 72 20 6d 6f 72 65 20 64 69 72 74 79 20 70   or more dirty p
a530: 61 67 65 73 20 74 6f 20 74 68 65 20 57 41 4c 20  ages to the WAL 
a540: 74 6f 20 66 72 65 65 20 75 70 20 6d 65 6d 6f 72  to free up memor
a550: 79 29 2e 20 0a 20 20 20 20 2a 2a 20 52 65 6d 6f  y). .    ** Remo
a560: 76 65 20 74 68 65 20 72 65 6d 6e 61 6e 74 73 20  ve the remnants 
a570: 6f 66 20 74 68 61 74 20 77 72 69 74 65 72 73 20  of that writers 
a580: 75 6e 63 6f 6d 6d 69 74 74 65 64 20 74 72 61 6e  uncommitted tran
a590: 73 61 63 74 69 6f 6e 20 66 72 6f 6d 20 0a 20 20  saction from .  
a5a0: 20 20 2a 2a 20 74 68 65 20 68 61 73 68 2d 74 61    ** the hash-ta
a5b0: 62 6c 65 20 62 65 66 6f 72 65 20 77 72 69 74 69  ble before writi
a5c0: 6e 67 20 61 6e 79 20 6e 65 77 20 65 6e 74 72 69  ng any new entri
a5d0: 65 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  es..    */.    i
a5e0: 66 28 20 61 50 67 6e 6f 5b 69 64 78 5d 20 29 7b  f( aPgno[idx] ){
a5f0: 0a 20 20 20 20 20 20 77 61 6c 43 6c 65 61 6e 75  .      walCleanu
a600: 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 20  pHash(pWal);.   
a610: 20 20 20 61 73 73 65 72 74 28 20 21 61 50 67 6e     assert( !aPgn
a620: 6f 5b 69 64 78 5d 20 29 3b 0a 20 20 20 20 7d 0a  o[idx] );.    }.
a630: 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68  .    /* Write th
a640: 65 20 61 50 67 6e 6f 5b 5d 20 61 72 72 61 79 20  e aPgno[] array 
a650: 65 6e 74 72 79 20 61 6e 64 20 74 68 65 20 68 61  entry and the ha
a660: 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 2e 20 2a  sh-table slot. *
a670: 2f 0a 20 20 20 20 6e 43 6f 6c 6c 69 64 65 20 3d  /.    nCollide =
a680: 20 69 64 78 3b 0a 20 20 20 20 66 6f 72 28 69 4b   idx;.    for(iK
a690: 65 79 3d 77 61 6c 48 61 73 68 28 69 50 61 67 65  ey=walHash(iPage
a6a0: 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20  ); aHash[iKey]; 
a6b0: 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68  iKey=walNextHash
a6c0: 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 69  (iKey)){.      i
a6d0: 66 28 20 28 6e 43 6f 6c 6c 69 64 65 2d 2d 29 3d  f( (nCollide--)=
a6e0: 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
a6f0: 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b  TE_CORRUPT_BKPT;
a700: 0a 20 20 20 20 7d 0a 20 20 20 20 61 50 67 6e 6f  .    }.    aPgno
a710: 5b 69 64 78 5d 20 3d 20 69 50 61 67 65 3b 0a 20  [idx] = iPage;. 
a720: 20 20 20 61 48 61 73 68 5b 69 4b 65 79 5d 20 3d     aHash[iKey] =
a730: 20 28 68 74 5f 73 6c 6f 74 29 69 64 78 3b 0a 0a   (ht_slot)idx;..
a740: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
a750: 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41  ABLE_EXPENSIVE_A
a760: 53 53 45 52 54 0a 20 20 20 20 2f 2a 20 56 65 72  SSERT.    /* Ver
a770: 69 66 79 20 74 68 61 74 20 74 68 65 20 6e 75 6d  ify that the num
a780: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69  ber of entries i
a790: 6e 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  n the hash table
a7a0: 20 65 78 61 63 74 6c 79 20 65 71 75 61 6c 73 0a   exactly equals.
a7b0: 20 20 20 20 2a 2a 20 74 68 65 20 6e 75 6d 62 65      ** the numbe
a7c0: 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20  r of entries in 
a7d0: 74 68 65 20 6d 61 70 70 69 6e 67 20 72 65 67 69  the mapping regi
a7e0: 6f 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7b  on..    */.    {
a7f0: 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 20 20 20  .      int i;   
a800: 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20          /* Loop 
a810: 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20 20 20  counter */.     
a820: 20 69 6e 74 20 6e 45 6e 74 72 79 20 3d 20 30 3b   int nEntry = 0;
a830: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65    /* Number of e
a840: 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20 68 61  ntries in the ha
a850: 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20  sh table */.    
a860: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48 41 53    for(i=0; i<HAS
a870: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 20 69 2b  HTABLE_NSLOT; i+
a880: 2b 29 7b 20 69 66 28 20 61 48 61 73 68 5b 69 5d  +){ if( aHash[i]
a890: 20 29 20 6e 45 6e 74 72 79 2b 2b 3b 20 7d 0a 20   ) nEntry++; }. 
a8a0: 20 20 20 20 20 61 73 73 65 72 74 28 20 6e 45 6e       assert( nEn
a8b0: 74 72 79 3d 3d 69 64 78 20 29 3b 0a 20 20 20 20  try==idx );.    
a8c0: 7d 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69 66 79  }..    /* Verify
a8d0: 20 74 68 61 74 20 74 68 65 20 65 76 65 72 79 20   that the every 
a8e0: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61 70  entry in the map
a8f0: 70 69 6e 67 20 72 65 67 69 6f 6e 20 69 73 20 72  ping region is r
a900: 65 61 63 68 61 62 6c 65 0a 20 20 20 20 2a 2a 20  eachable.    ** 
a910: 76 69 61 20 74 68 65 20 68 61 73 68 20 74 61 62  via the hash tab
a920: 6c 65 2e 20 20 54 68 69 73 20 74 75 72 6e 73 20  le.  This turns 
a930: 6f 75 74 20 74 6f 20 62 65 20 61 20 72 65 61 6c  out to be a real
a940: 6c 79 2c 20 72 65 61 6c 6c 79 20 65 78 70 65 6e  ly, really expen
a950: 73 69 76 65 0a 20 20 20 20 2a 2a 20 74 68 69 6e  sive.    ** thin
a960: 67 20 74 6f 20 63 68 65 63 6b 2c 20 73 6f 20 6f  g to check, so o
a970: 6e 6c 79 20 64 6f 20 74 68 69 73 20 6f 63 63 61  nly do this occa
a980: 73 69 6f 6e 61 6c 6c 79 20 2d 20 6e 6f 74 20 6f  sionally - not o
a990: 6e 20 65 76 65 72 79 0a 20 20 20 20 2a 2a 20 69  n every.    ** i
a9a0: 74 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20 2a 2f  teration..    */
a9b0: 0a 20 20 20 20 69 66 28 20 28 69 64 78 26 30 78  .    if( (idx&0x
a9c0: 33 66 66 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  3ff)==0 ){.     
a9d0: 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
a9e0: 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65    /* Loop counte
a9f0: 72 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28 69  r */.      for(i
aa00: 3d 31 3b 20 69 3c 3d 69 64 78 3b 20 69 2b 2b 29  =1; i<=idx; i++)
aa10: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 4b  {.        for(iK
aa20: 65 79 3d 77 61 6c 48 61 73 68 28 61 50 67 6e 6f  ey=walHash(aPgno
aa30: 5b 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b 65 79  [i]); aHash[iKey
aa40: 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48  ]; iKey=walNextH
aa50: 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20  ash(iKey)){.    
aa60: 20 20 20 20 20 20 69 66 28 20 61 48 61 73 68 5b        if( aHash[
aa70: 69 4b 65 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b  iKey]==i ) break
aa80: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
aa90: 20 20 20 20 61 73 73 65 72 74 28 20 61 48 61 73      assert( aHas
aaa0: 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 3b 0a 20 20  h[iKey]==i );.  
aab0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 23 65 6e 64      }.    }.#end
aac0: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
aad0: 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53  BLE_EXPENSIVE_AS
aae0: 53 45 52 54 20 2a 2f 0a 20 20 7d 0a 0a 0a 20 20  SERT */.  }...  
aaf0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f  return rc;.}.../
ab00: 2a 0a 2a 2a 20 52 65 63 6f 76 65 72 20 74 68 65  *.** Recover the
ab10: 20 77 61 6c 2d 69 6e 64 65 78 20 62 79 20 72 65   wal-index by re
ab20: 61 64 69 6e 67 20 74 68 65 20 77 72 69 74 65 2d  ading the write-
ab30: 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65 2e 20  ahead log file. 
ab40: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74  .**.** This rout
ab50: 69 6e 65 20 66 69 72 73 74 20 74 72 69 65 73 20  ine first tries 
ab60: 74 6f 20 65 73 74 61 62 6c 69 73 68 20 61 6e 20  to establish an 
ab70: 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f  exclusive lock o
ab80: 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64  n the.** wal-ind
ab90: 65 78 20 74 6f 20 70 72 65 76 65 6e 74 20 6f 74  ex to prevent ot
aba0: 68 65 72 20 74 68 72 65 61 64 73 2f 70 72 6f 63  her threads/proc
abb0: 65 73 73 65 73 20 66 72 6f 6d 20 64 6f 69 6e 67  esses from doing
abc0: 20 61 6e 79 74 68 69 6e 67 0a 2a 2a 20 77 69 74   anything.** wit
abd0: 68 20 74 68 65 20 57 41 4c 20 6f 72 20 77 61 6c  h the WAL or wal
abe0: 2d 69 6e 64 65 78 20 77 68 69 6c 65 20 72 65 63  -index while rec
abf0: 6f 76 65 72 79 20 69 73 20 72 75 6e 6e 69 6e 67  overy is running
ac00: 2e 20 20 54 68 65 0a 2a 2a 20 57 41 4c 5f 52 45  .  The.** WAL_RE
ac10: 43 4f 56 45 52 5f 4c 4f 43 4b 20 69 73 20 61 6c  COVER_LOCK is al
ac20: 73 6f 20 68 65 6c 64 20 73 6f 20 74 68 61 74 20  so held so that 
ac30: 6f 74 68 65 72 20 74 68 72 65 61 64 73 20 77 69  other threads wi
ac40: 6c 6c 20 6b 6e 6f 77 0a 2a 2a 20 74 68 61 74 20  ll know.** that 
ac50: 74 68 69 73 20 74 68 72 65 61 64 20 69 73 20 72  this thread is r
ac60: 75 6e 6e 69 6e 67 20 72 65 63 6f 76 65 72 79 2e  unning recovery.
ac70: 20 20 49 66 20 75 6e 61 62 6c 65 20 74 6f 20 65    If unable to e
ac80: 73 74 61 62 6c 69 73 68 0a 2a 2a 20 74 68 65 20  stablish.** the 
ac90: 6e 65 63 65 73 73 61 72 79 20 6c 6f 63 6b 73 2c  necessary locks,
aca0: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65   this routine re
acb0: 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53  turns SQLITE_BUS
acc0: 59 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  Y..*/.static int
acd0: 20 77 61 6c 49 6e 64 65 78 52 65 63 6f 76 65 72   walIndexRecover
ace0: 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69  (Wal *pWal){.  i
acf0: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
ad00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
ad10: 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f  * Return Code */
ad20: 0a 20 20 69 36 34 20 6e 53 69 7a 65 3b 20 20 20  .  i64 nSize;   
ad30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad40: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 6c 6f     /* Size of lo
ad50: 67 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32 20  g file */.  u32 
ad60: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 20 3d  aFrameCksum[2] =
ad70: 20 7b 30 2c 20 30 7d 3b 0a 20 20 69 6e 74 20 69   {0, 0};.  int i
ad80: 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Lock;           
ad90: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f             /* Lo
ada0: 63 6b 20 6f 66 66 73 65 74 20 74 6f 20 6c 6f 63  ck offset to loc
adb0: 6b 20 66 6f 72 20 63 68 65 63 6b 70 6f 69 6e 74  k for checkpoint
adc0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 6f 63 6b 3b   */.  int nLock;
add0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ade0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
adf0: 6f 66 20 6c 6f 63 6b 73 20 74 6f 20 68 6f 6c 64  of locks to hold
ae00: 20 2a 2f 0a 0a 20 20 2f 2a 20 4f 62 74 61 69 6e   */..  /* Obtain
ae10: 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c 6f   an exclusive lo
ae20: 63 6b 20 6f 6e 20 61 6c 6c 20 62 79 74 65 20 69  ck on all byte i
ae30: 6e 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 72 61  n the locking ra
ae40: 6e 67 65 20 6e 6f 74 20 61 6c 72 65 61 64 79 0a  nge not already.
ae50: 20 20 2a 2a 20 6c 6f 63 6b 65 64 20 62 79 20 74    ** locked by t
ae60: 68 65 20 63 61 6c 6c 65 72 2e 20 54 68 65 20 63  he caller. The c
ae70: 61 6c 6c 65 72 20 69 73 20 67 75 61 72 61 6e 74  aller is guarant
ae80: 65 65 64 20 74 6f 20 68 61 76 65 20 6c 6f 63 6b  eed to have lock
ae90: 65 64 20 74 68 65 0a 20 20 2a 2a 20 57 41 4c 5f  ed the.  ** WAL_
aea0: 57 52 49 54 45 5f 4c 4f 43 4b 20 62 79 74 65 2c  WRITE_LOCK byte,
aeb0: 20 61 6e 64 20 6d 61 79 20 68 61 76 65 20 61 6c   and may have al
aec0: 73 6f 20 6c 6f 63 6b 65 64 20 74 68 65 20 57 41  so locked the WA
aed0: 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 62 79 74 65  L_CKPT_LOCK byte
aee0: 2e 0a 20 20 2a 2a 20 49 66 20 73 75 63 63 65 73  ..  ** If succes
aef0: 73 66 75 6c 2c 20 74 68 65 20 73 61 6d 65 20 62  sful, the same b
af00: 79 74 65 73 20 74 68 61 74 20 61 72 65 20 6c 6f  ytes that are lo
af10: 63 6b 65 64 20 68 65 72 65 20 61 72 65 20 75 6e  cked here are un
af20: 6c 6f 63 6b 65 64 20 62 65 66 6f 72 65 0a 20 20  locked before.  
af30: 2a 2a 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** this function
af40: 20 72 65 74 75 72 6e 73 2e 0a 20 20 2a 2f 0a 20   returns..  */. 
af50: 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 63   assert( pWal->c
af60: 6b 70 74 4c 6f 63 6b 3d 3d 31 20 7c 7c 20 70 57  kptLock==1 || pW
af70: 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 30 20  al->ckptLock==0 
af80: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 57 41 4c  );.  assert( WAL
af90: 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 3d 3d  _ALL_BUT_WRITE==
afa0: 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2b 31  WAL_WRITE_LOCK+1
afb0: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 57 41   );.  assert( WA
afc0: 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 3d 3d 57 41 4c  L_CKPT_LOCK==WAL
afd0: 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 29  _ALL_BUT_WRITE )
afe0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ;.  assert( pWal
aff0: 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20  ->writeLock );. 
b000: 20 69 4c 6f 63 6b 20 3d 20 57 41 4c 5f 41 4c 4c   iLock = WAL_ALL
b010: 5f 42 55 54 5f 57 52 49 54 45 20 2b 20 70 57 61  _BUT_WRITE + pWa
b020: 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3b 0a 20 20 6e  l->ckptLock;.  n
b030: 4c 6f 63 6b 20 3d 20 53 51 4c 49 54 45 5f 53 48  Lock = SQLITE_SH
b040: 4d 5f 4e 4c 4f 43 4b 20 2d 20 69 4c 6f 63 6b 3b  M_NLOCK - iLock;
b050: 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45  .  rc = walLockE
b060: 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 69  xclusive(pWal, i
b070: 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b 0a 20 20  Lock, nLock);.  
b080: 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 72 65  if( rc ){.    re
b090: 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 57  turn rc;.  }.  W
b0a0: 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
b0b0: 20 72 65 63 6f 76 65 72 79 20 62 65 67 69 6e 2e   recovery begin.
b0c0: 2e 2e 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 0a  ..\n", pWal));..
b0d0: 20 20 6d 65 6d 73 65 74 28 26 70 57 61 6c 2d 3e    memset(&pWal->
b0e0: 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 57  hdr, 0, sizeof(W
b0f0: 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 0a 20  alIndexHdr));.. 
b100: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 46   rc = sqlite3OsF
b110: 69 6c 65 53 69 7a 65 28 70 57 61 6c 2d 3e 70 57  ileSize(pWal->pW
b120: 61 6c 46 64 2c 20 26 6e 53 69 7a 65 29 3b 0a 20  alFd, &nSize);. 
b130: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
b140: 4f 4b 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20 72  OK ){.    goto r
b150: 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20  ecovery_error;. 
b160: 20 7d 0a 0a 20 20 69 66 28 20 6e 53 69 7a 65 3e   }..  if( nSize>
b170: 57 41 4c 5f 48 44 52 53 49 5a 45 20 29 7b 0a 20  WAL_HDRSIZE ){. 
b180: 20 20 20 75 38 20 61 42 75 66 5b 57 41 4c 5f 48     u8 aBuf[WAL_H
b190: 44 52 53 49 5a 45 5d 3b 20 20 20 20 20 20 20 20  DRSIZE];        
b1a0: 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 6c 6f   /* Buffer to lo
b1b0: 61 64 20 57 41 4c 20 68 65 61 64 65 72 20 69 6e  ad WAL header in
b1c0: 74 6f 20 2a 2f 0a 20 20 20 20 75 38 20 2a 61 46  to */.    u8 *aF
b1d0: 72 61 6d 65 20 3d 20 30 3b 20 20 20 20 20 20 20  rame = 0;       
b1e0: 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f          /* Mallo
b1f0: 63 27 64 20 62 75 66 66 65 72 20 74 6f 20 6c 6f  c'd buffer to lo
b200: 61 64 20 65 6e 74 69 72 65 20 66 72 61 6d 65 20  ad entire frame 
b210: 2a 2f 0a 20 20 20 20 69 6e 74 20 73 7a 46 72 61  */.    int szFra
b220: 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  me;             
b230: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
b240: 66 20 62 79 74 65 73 20 69 6e 20 62 75 66 66 65  f bytes in buffe
b250: 72 20 61 46 72 61 6d 65 5b 5d 20 2a 2f 0a 20 20  r aFrame[] */.  
b260: 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20 20 20    u8 *aData;    
b270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b280: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 64 61  /* Pointer to da
b290: 74 61 20 70 61 72 74 20 6f 66 20 61 46 72 61 6d  ta part of aFram
b2a0: 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 20 20  e buffer */.    
b2b0: 69 6e 74 20 69 46 72 61 6d 65 3b 20 20 20 20 20  int iFrame;     
b2c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
b2d0: 20 49 6e 64 65 78 20 6f 66 20 6c 61 73 74 20 66   Index of last f
b2e0: 72 61 6d 65 20 72 65 61 64 20 2a 2f 0a 20 20 20  rame read */.   
b2f0: 20 69 36 34 20 69 4f 66 66 73 65 74 3b 20 20 20   i64 iOffset;   
b300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
b310: 2a 20 4e 65 78 74 20 6f 66 66 73 65 74 20 74 6f  * Next offset to
b320: 20 72 65 61 64 20 66 72 6f 6d 20 6c 6f 67 20 66   read from log f
b330: 69 6c 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20 73  ile */.    int s
b340: 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  zPage;          
b350: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65           /* Page
b360: 20 73 69 7a 65 20 61 63 63 6f 72 64 69 6e 67 20   size according 
b370: 74 6f 20 74 68 65 20 6c 6f 67 20 2a 2f 0a 20 20  to the log */.  
b380: 20 20 75 33 32 20 6d 61 67 69 63 3b 20 20 20 20    u32 magic;    
b390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b3a0: 2f 2a 20 4d 61 67 69 63 20 76 61 6c 75 65 20 72  /* Magic value r
b3b0: 65 61 64 20 66 72 6f 6d 20 57 41 4c 20 68 65 61  ead from WAL hea
b3c0: 64 65 72 20 2a 2f 0a 20 20 20 20 75 33 32 20 76  der */.    u32 v
b3d0: 65 72 73 69 6f 6e 3b 20 20 20 20 20 20 20 20 20  ersion;         
b3e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 67 69           /* Magi
b3f0: 63 20 76 61 6c 75 65 20 72 65 61 64 20 66 72 6f  c value read fro
b400: 6d 20 57 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a  m WAL header */.
b410: 20 20 20 20 69 6e 74 20 69 73 56 61 6c 69 64 3b      int isValid;
b420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b430: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 74 68 69    /* True if thi
b440: 73 20 66 72 61 6d 65 20 69 73 20 76 61 6c 69 64  s frame is valid
b450: 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64   */..    /* Read
b460: 20 69 6e 20 74 68 65 20 57 41 4c 20 68 65 61 64   in the WAL head
b470: 65 72 2e 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20  er. */.    rc = 
b480: 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57  sqlite3OsRead(pW
b490: 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 42 75 66  al->pWalFd, aBuf
b4a0: 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2c 20 30  , WAL_HDRSIZE, 0
b4b0: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
b4c0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
b4d0: 20 20 67 6f 74 6f 20 72 65 63 6f 76 65 72 79 5f    goto recovery_
b4e0: 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a 0a 20 20  error;.    }..  
b4f0: 20 20 2f 2a 20 49 66 20 74 68 65 20 64 61 74 61    /* If the data
b500: 62 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 69  base page size i
b510: 73 20 6e 6f 74 20 61 20 70 6f 77 65 72 20 6f 66  s not a power of
b520: 20 74 77 6f 2c 20 6f 72 20 69 73 20 67 72 65 61   two, or is grea
b530: 74 65 72 20 74 68 61 6e 0a 20 20 20 20 2a 2a 20  ter than.    ** 
b540: 53 51 4c 49 54 45 5f 4d 41 58 5f 50 41 47 45 5f  SQLITE_MAX_PAGE_
b550: 53 49 5a 45 2c 20 63 6f 6e 63 6c 75 64 65 20 74  SIZE, conclude t
b560: 68 61 74 20 74 68 65 20 57 41 4c 20 66 69 6c 65  hat the WAL file
b570: 20 63 6f 6e 74 61 69 6e 73 20 6e 6f 20 76 61 6c   contains no val
b580: 69 64 20 0a 20 20 20 20 2a 2a 20 64 61 74 61 2e  id .    ** data.
b590: 20 53 69 6d 69 6c 61 72 6c 79 2c 20 69 66 20 74   Similarly, if t
b5a0: 68 65 20 27 6d 61 67 69 63 27 20 76 61 6c 75 65  he 'magic' value
b5b0: 20 69 73 20 69 6e 76 61 6c 69 64 2c 20 69 67 6e   is invalid, ign
b5c0: 6f 72 65 20 74 68 65 20 77 68 6f 6c 65 0a 20 20  ore the whole.  
b5d0: 20 20 2a 2a 20 57 41 4c 20 66 69 6c 65 2e 0a 20    ** WAL file.. 
b5e0: 20 20 20 2a 2f 0a 20 20 20 20 6d 61 67 69 63 20     */.    magic 
b5f0: 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62 79 74  = sqlite3Get4byt
b600: 65 28 26 61 42 75 66 5b 30 5d 29 3b 0a 20 20 20  e(&aBuf[0]);.   
b610: 20 73 7a 50 61 67 65 20 3d 20 73 71 6c 69 74 65   szPage = sqlite
b620: 33 47 65 74 34 62 79 74 65 28 26 61 42 75 66 5b  3Get4byte(&aBuf[
b630: 38 5d 29 3b 0a 20 20 20 20 69 66 28 20 28 6d 61  8]);.    if( (ma
b640: 67 69 63 26 30 78 46 46 46 46 46 46 46 45 29 21  gic&0xFFFFFFFE)!
b650: 3d 57 41 4c 5f 4d 41 47 49 43 20 0a 20 20 20 20  =WAL_MAGIC .    
b660: 20 7c 7c 20 73 7a 50 61 67 65 26 28 73 7a 50 61   || szPage&(szPa
b670: 67 65 2d 31 29 20 0a 20 20 20 20 20 7c 7c 20 73  ge-1) .     || s
b680: 7a 50 61 67 65 3e 53 51 4c 49 54 45 5f 4d 41 58  zPage>SQLITE_MAX
b690: 5f 50 41 47 45 5f 53 49 5a 45 20 0a 20 20 20 20  _PAGE_SIZE .    
b6a0: 20 7c 7c 20 73 7a 50 61 67 65 3c 35 31 32 20 0a   || szPage<512 .
b6b0: 20 20 20 20 29 7b 0a 20 20 20 20 20 20 67 6f 74      ){.      got
b6c0: 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20 20 20  o finished;.    
b6d0: 7d 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  }.    pWal->hdr.
b6e0: 62 69 67 45 6e 64 43 6b 73 75 6d 20 3d 20 28 75  bigEndCksum = (u
b6f0: 38 29 28 6d 61 67 69 63 26 30 78 30 30 30 30 30  8)(magic&0x00000
b700: 30 30 31 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  001);.    pWal->
b710: 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b  szPage = szPage;
b720: 0a 20 20 20 20 70 57 61 6c 2d 3e 6e 43 6b 70 74  .    pWal->nCkpt
b730: 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62 79   = sqlite3Get4by
b740: 74 65 28 26 61 42 75 66 5b 31 32 5d 29 3b 0a 20  te(&aBuf[12]);. 
b750: 20 20 20 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d     memcpy(&pWal-
b760: 3e 68 64 72 2e 61 53 61 6c 74 2c 20 26 61 42 75  >hdr.aSalt, &aBu
b770: 66 5b 31 36 5d 2c 20 38 29 3b 0a 0a 20 20 20 20  f[16], 8);..    
b780: 2f 2a 20 56 65 72 69 66 79 20 74 68 61 74 20 74  /* Verify that t
b790: 68 65 20 57 41 4c 20 68 65 61 64 65 72 20 63 68  he WAL header ch
b7a0: 65 63 6b 73 75 6d 20 69 73 20 63 6f 72 72 65 63  ecksum is correc
b7b0: 74 20 2a 2f 0a 20 20 20 20 77 61 6c 43 68 65 63  t */.    walChec
b7c0: 6b 73 75 6d 42 79 74 65 73 28 70 57 61 6c 2d 3e  ksumBytes(pWal->
b7d0: 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d  hdr.bigEndCksum=
b7e0: 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41  =SQLITE_BIGENDIA
b7f0: 4e 2c 20 0a 20 20 20 20 20 20 20 20 61 42 75 66  N, .        aBuf
b800: 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2d 32 2a  , WAL_HDRSIZE-2*
b810: 34 2c 20 30 2c 20 70 57 61 6c 2d 3e 68 64 72 2e  4, 0, pWal->hdr.
b820: 61 46 72 61 6d 65 43 6b 73 75 6d 0a 20 20 20 20  aFrameCksum.    
b830: 29 3b 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d  );.    if( pWal-
b840: 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
b850: 5b 30 5d 21 3d 73 71 6c 69 74 65 33 47 65 74 34  [0]!=sqlite3Get4
b860: 62 79 74 65 28 26 61 42 75 66 5b 32 34 5d 29 0a  byte(&aBuf[24]).
b870: 20 20 20 20 20 7c 7c 20 70 57 61 6c 2d 3e 68 64       || pWal->hd
b880: 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d  r.aFrameCksum[1]
b890: 21 3d 73 71 6c 69 74 65 33 47 65 74 34 62 79 74  !=sqlite3Get4byt
b8a0: 65 28 26 61 42 75 66 5b 32 38 5d 29 0a 20 20 20  e(&aBuf[28]).   
b8b0: 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 66   ){.      goto f
b8c0: 69 6e 69 73 68 65 64 3b 0a 20 20 20 20 7d 0a 0a  inished;.    }..
b8d0: 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20 74 68      /* Verify th
b8e0: 61 74 20 74 68 65 20 76 65 72 73 69 6f 6e 20 6e  at the version n
b8f0: 75 6d 62 65 72 20 6f 6e 20 74 68 65 20 57 41 4c  umber on the WAL
b900: 20 66 6f 72 6d 61 74 20 69 73 20 6f 6e 65 20 74   format is one t
b910: 68 61 74 0a 20 20 20 20 2a 2a 20 61 72 65 20 61  hat.    ** are a
b920: 62 6c 65 20 74 6f 20 75 6e 64 65 72 73 74 61 6e  ble to understan
b930: 64 20 2a 2f 0a 20 20 20 20 76 65 72 73 69 6f 6e  d */.    version
b940: 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62 79   = sqlite3Get4by
b950: 74 65 28 26 61 42 75 66 5b 34 5d 29 3b 0a 20 20  te(&aBuf[4]);.  
b960: 20 20 69 66 28 20 76 65 72 73 69 6f 6e 21 3d 57    if( version!=W
b970: 41 4c 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 20 29  AL_MAX_VERSION )
b980: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
b990: 49 54 45 5f 43 41 4e 54 4f 50 45 4e 5f 42 4b 50  ITE_CANTOPEN_BKP
b9a0: 54 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 66 69  T;.      goto fi
b9b0: 6e 69 73 68 65 64 3b 0a 20 20 20 20 7d 0a 0a 20  nished;.    }.. 
b9c0: 20 20 20 2f 2a 20 4d 61 6c 6c 6f 63 20 61 20 62     /* Malloc a b
b9d0: 75 66 66 65 72 20 74 6f 20 72 65 61 64 20 66 72  uffer to read fr
b9e0: 61 6d 65 73 20 69 6e 74 6f 2e 20 2a 2f 0a 20 20  ames into. */.  
b9f0: 20 20 73 7a 46 72 61 6d 65 20 3d 20 73 7a 50 61    szFrame = szPa
ba00: 67 65 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48  ge + WAL_FRAME_H
ba10: 44 52 53 49 5a 45 3b 0a 20 20 20 20 61 46 72 61  DRSIZE;.    aFra
ba20: 6d 65 20 3d 20 28 75 38 20 2a 29 73 71 6c 69 74  me = (u8 *)sqlit
ba30: 65 33 5f 6d 61 6c 6c 6f 63 36 34 28 73 7a 46 72  e3_malloc64(szFr
ba40: 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21 61  ame);.    if( !a
ba50: 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 20 20 72  Frame ){.      r
ba60: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
ba70: 5f 42 4b 50 54 3b 0a 20 20 20 20 20 20 67 6f 74  _BKPT;.      got
ba80: 6f 20 72 65 63 6f 76 65 72 79 5f 65 72 72 6f 72  o recovery_error
ba90: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 44 61 74  ;.    }.    aDat
baa0: 61 20 3d 20 26 61 46 72 61 6d 65 5b 57 41 4c 5f  a = &aFrame[WAL_
bab0: 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 5d 3b 0a  FRAME_HDRSIZE];.
bac0: 0a 20 20 20 20 2f 2a 20 52 65 61 64 20 61 6c 6c  .    /* Read all
bad0: 20 66 72 61 6d 65 73 20 66 72 6f 6d 20 74 68 65   frames from the
bae0: 20 6c 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20   log file. */.  
baf0: 20 20 69 46 72 61 6d 65 20 3d 20 30 3b 0a 20 20    iFrame = 0;.  
bb00: 20 20 66 6f 72 28 69 4f 66 66 73 65 74 3d 57 41    for(iOffset=WA
bb10: 4c 5f 48 44 52 53 49 5a 45 3b 20 28 69 4f 66 66  L_HDRSIZE; (iOff
bb20: 73 65 74 2b 73 7a 46 72 61 6d 65 29 3c 3d 6e 53  set+szFrame)<=nS
bb30: 69 7a 65 3b 20 69 4f 66 66 73 65 74 2b 3d 73 7a  ize; iOffset+=sz
bb40: 46 72 61 6d 65 29 7b 0a 20 20 20 20 20 20 75 33  Frame){.      u3
bb50: 32 20 70 67 6e 6f 3b 20 20 20 20 20 20 20 20 20  2 pgno;         
bb60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
bb70: 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65  abase page numbe
bb80: 72 20 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20  r for frame */. 
bb90: 20 20 20 20 20 75 33 32 20 6e 54 72 75 6e 63 61       u32 nTrunca
bba0: 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  te;             
bbb0: 20 2f 2a 20 64 62 73 69 7a 65 20 66 69 65 6c 64   /* dbsize field
bbc0: 20 66 72 6f 6d 20 66 72 61 6d 65 20 68 65 61 64   from frame head
bbd0: 65 72 20 2a 2f 0a 0a 20 20 20 20 20 20 2f 2a 20  er */..      /* 
bbe0: 52 65 61 64 20 61 6e 64 20 64 65 63 6f 64 65 20  Read and decode 
bbf0: 74 68 65 20 6e 65 78 74 20 6c 6f 67 20 66 72 61  the next log fra
bc00: 6d 65 2e 20 2a 2f 0a 20 20 20 20 20 20 69 46 72  me. */.      iFr
bc10: 61 6d 65 2b 2b 3b 0a 20 20 20 20 20 20 72 63 20  ame++;.      rc 
bc20: 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28  = sqlite3OsRead(
bc30: 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 46  pWal->pWalFd, aF
bc40: 72 61 6d 65 2c 20 73 7a 46 72 61 6d 65 2c 20 69  rame, szFrame, i
bc50: 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 69  Offset);.      i
bc60: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
bc70: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20   ) break;.      
bc80: 69 73 56 61 6c 69 64 20 3d 20 77 61 6c 44 65 63  isValid = walDec
bc90: 6f 64 65 46 72 61 6d 65 28 70 57 61 6c 2c 20 26  odeFrame(pWal, &
bca0: 70 67 6e 6f 2c 20 26 6e 54 72 75 6e 63 61 74 65  pgno, &nTruncate
bcb0: 2c 20 61 44 61 74 61 2c 20 61 46 72 61 6d 65 29  , aData, aFrame)
bcc0: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 69 73 56  ;.      if( !isV
bcd0: 61 6c 69 64 20 29 20 62 72 65 61 6b 3b 0a 20 20  alid ) break;.  
bce0: 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65      rc = walInde
bcf0: 78 41 70 70 65 6e 64 28 70 57 61 6c 2c 20 69 46  xAppend(pWal, iF
bd00: 72 61 6d 65 2c 20 70 67 6e 6f 29 3b 0a 20 20 20  rame, pgno);.   
bd10: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
bd20: 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a 20  E_OK ) break;.. 
bd30: 20 20 20 20 20 2f 2a 20 49 66 20 6e 54 72 75 6e       /* If nTrun
bd40: 63 61 74 65 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f  cate is non-zero
bd50: 2c 20 74 68 69 73 20 69 73 20 61 20 63 6f 6d 6d  , this is a comm
bd60: 69 74 20 72 65 63 6f 72 64 2e 20 2a 2f 0a 20 20  it record. */.  
bd70: 20 20 20 20 69 66 28 20 6e 54 72 75 6e 63 61 74      if( nTruncat
bd80: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61  e ){.        pWa
bd90: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d  l->hdr.mxFrame =
bda0: 20 69 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 20   iFrame;.       
bdb0: 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65   pWal->hdr.nPage
bdc0: 20 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a 20 20   = nTruncate;.  
bdd0: 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e        pWal->hdr.
bde0: 73 7a 50 61 67 65 20 3d 20 28 75 31 36 29 28 28  szPage = (u16)((
bdf0: 73 7a 50 61 67 65 26 30 78 66 66 30 30 29 20 7c  szPage&0xff00) |
be00: 20 28 73 7a 50 61 67 65 3e 3e 31 36 29 29 3b 0a   (szPage>>16));.
be10: 20 20 20 20 20 20 20 20 74 65 73 74 63 61 73 65          testcase
be20: 28 20 73 7a 50 61 67 65 3c 3d 33 32 37 36 38 20  ( szPage<=32768 
be30: 29 3b 0a 20 20 20 20 20 20 20 20 74 65 73 74 63  );.        testc
be40: 61 73 65 28 20 73 7a 50 61 67 65 3e 3d 36 35 35  ase( szPage>=655
be50: 33 36 20 29 3b 0a 20 20 20 20 20 20 20 20 61 46  36 );.        aF
be60: 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 70  rameCksum[0] = p
be70: 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
be80: 6b 73 75 6d 5b 30 5d 3b 0a 20 20 20 20 20 20 20  ksum[0];.       
be90: 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20   aFrameCksum[1] 
bea0: 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61  = pWal->hdr.aFra
beb0: 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 20 20  meCksum[1];.    
bec0: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73    }.    }..    s
bed0: 71 6c 69 74 65 33 5f 66 72 65 65 28 61 46 72 61  qlite3_free(aFra
bee0: 6d 65 29 3b 0a 20 20 7d 0a 0a 66 69 6e 69 73 68  me);.  }..finish
bef0: 65 64 3a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  ed:.  if( rc==SQ
bf00: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76  LITE_OK ){.    v
bf10: 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49  olatile WalCkptI
bf20: 6e 66 6f 20 2a 70 49 6e 66 6f 3b 0a 20 20 20 20  nfo *pInfo;.    
bf30: 69 6e 74 20 69 3b 0a 20 20 20 20 70 57 61 6c 2d  int i;.    pWal-
bf40: 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
bf50: 5b 30 5d 20 3d 20 61 46 72 61 6d 65 43 6b 73 75  [0] = aFrameCksu
bf60: 6d 5b 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  m[0];.    pWal->
bf70: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
bf80: 31 5d 20 3d 20 61 46 72 61 6d 65 43 6b 73 75 6d  1] = aFrameCksum
bf90: 5b 31 5d 3b 0a 20 20 20 20 77 61 6c 49 6e 64 65  [1];.    walInde
bfa0: 78 57 72 69 74 65 48 64 72 28 70 57 61 6c 29 3b  xWriteHdr(pWal);
bfb0: 0a 0a 20 20 20 20 2f 2a 20 52 65 73 65 74 20 74  ..    /* Reset t
bfc0: 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 2d 68 65  he checkpoint-he
bfd0: 61 64 65 72 2e 20 54 68 69 73 20 69 73 20 73 61  ader. This is sa
bfe0: 66 65 20 62 65 63 61 75 73 65 20 74 68 69 73 20  fe because this 
bff0: 74 68 72 65 61 64 20 69 73 20 0a 20 20 20 20 2a  thread is .    *
c000: 2a 20 63 75 72 72 65 6e 74 6c 79 20 68 6f 6c 64  * currently hold
c010: 69 6e 67 20 6c 6f 63 6b 73 20 74 68 61 74 20 65  ing locks that e
c020: 78 63 6c 75 64 65 20 61 6c 6c 20 6f 74 68 65 72  xclude all other
c030: 20 72 65 61 64 65 72 73 2c 20 77 72 69 74 65 72   readers, writer
c040: 73 20 61 6e 64 0a 20 20 20 20 2a 2a 20 63 68 65  s and.    ** che
c050: 63 6b 70 6f 69 6e 74 65 72 73 2e 0a 20 20 20 20  ckpointers..    
c060: 2a 2f 0a 20 20 20 20 70 49 6e 66 6f 20 3d 20 77  */.    pInfo = w
c070: 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29  alCkptInfo(pWal)
c080: 3b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61  ;.    pInfo->nBa
c090: 63 6b 66 69 6c 6c 20 3d 20 30 3b 0a 20 20 20 20  ckfill = 0;.    
c0a0: 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
c0b0: 41 74 74 65 6d 70 74 65 64 20 3d 20 70 57 61 6c  Attempted = pWal
c0c0: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20  ->hdr.mxFrame;. 
c0d0: 20 20 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d     pInfo->aReadM
c0e0: 61 72 6b 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20  ark[0] = 0;.    
c0f0: 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e  for(i=1; i<WAL_N
c100: 52 45 41 44 45 52 3b 20 69 2b 2b 29 20 70 49 6e  READER; i++) pIn
c110: 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d  fo->aReadMark[i]
c120: 20 3d 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f   = READMARK_NOT_
c130: 55 53 45 44 3b 0a 20 20 20 20 69 66 28 20 70 57  USED;.    if( pW
c140: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
c150: 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61  ) pInfo->aReadMa
c160: 72 6b 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64  rk[1] = pWal->hd
c170: 72 2e 6d 78 46 72 61 6d 65 3b 0a 0a 20 20 20 20  r.mxFrame;..    
c180: 2f 2a 20 49 66 20 6d 6f 72 65 20 74 68 61 6e 20  /* If more than 
c190: 6f 6e 65 20 66 72 61 6d 65 20 77 61 73 20 72 65  one frame was re
c1a0: 63 6f 76 65 72 65 64 20 66 72 6f 6d 20 74 68 65  covered from the
c1b0: 20 6c 6f 67 20 66 69 6c 65 2c 20 72 65 70 6f 72   log file, repor
c1c0: 74 20 61 6e 0a 20 20 20 20 2a 2a 20 65 76 65 6e  t an.    ** even
c1d0: 74 20 76 69 61 20 73 71 6c 69 74 65 33 5f 6c 6f  t via sqlite3_lo
c1e0: 67 28 29 2e 20 54 68 69 73 20 69 73 20 74 6f 20  g(). This is to 
c1f0: 68 65 6c 70 20 77 69 74 68 20 69 64 65 6e 74 69  help with identi
c200: 66 79 69 6e 67 20 70 65 72 66 6f 72 6d 61 6e 63  fying performanc
c210: 65 0a 20 20 20 20 2a 2a 20 70 72 6f 62 6c 65 6d  e.    ** problem
c220: 73 20 63 61 75 73 65 64 20 62 79 20 61 70 70 6c  s caused by appl
c230: 69 63 61 74 69 6f 6e 73 20 72 6f 75 74 69 6e 65  ications routine
c240: 6c 79 20 73 68 75 74 74 69 6e 67 20 64 6f 77 6e  ly shutting down
c250: 20 77 69 74 68 6f 75 74 0a 20 20 20 20 2a 2a 20   without.    ** 
c260: 63 68 65 63 6b 70 6f 69 6e 74 69 6e 67 20 74 68  checkpointing th
c270: 65 20 6c 6f 67 20 66 69 6c 65 2e 0a 20 20 20 20  e log file..    
c280: 2a 2f 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d  */.    if( pWal-
c290: 3e 68 64 72 2e 6e 50 61 67 65 20 29 7b 0a 20 20  >hdr.nPage ){.  
c2a0: 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28      sqlite3_log(
c2b0: 53 51 4c 49 54 45 5f 4e 4f 54 49 43 45 5f 52 45  SQLITE_NOTICE_RE
c2c0: 43 4f 56 45 52 5f 57 41 4c 2c 0a 20 20 20 20 20  COVER_WAL,.     
c2d0: 20 20 20 20 20 22 72 65 63 6f 76 65 72 65 64 20       "recovered 
c2e0: 25 64 20 66 72 61 6d 65 73 20 66 72 6f 6d 20 57  %d frames from W
c2f0: 41 4c 20 66 69 6c 65 20 25 73 22 2c 0a 20 20 20  AL file %s",.   
c300: 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72         pWal->hdr
c310: 2e 6d 78 46 72 61 6d 65 2c 20 70 57 61 6c 2d 3e  .mxFrame, pWal->
c320: 7a 57 61 6c 4e 61 6d 65 0a 20 20 20 20 20 20 29  zWalName.      )
c330: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 72 65 63  ;.    }.  }..rec
c340: 6f 76 65 72 79 5f 65 72 72 6f 72 3a 0a 20 20 57  overy_error:.  W
c350: 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
c360: 20 72 65 63 6f 76 65 72 79 20 25 73 5c 6e 22 2c   recovery %s\n",
c370: 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69   pWal, rc ? "fai
c380: 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
c390: 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
c3a0: 69 76 65 28 70 57 61 6c 2c 20 69 4c 6f 63 6b 2c  ive(pWal, iLock,
c3b0: 20 6e 4c 6f 63 6b 29 3b 0a 20 20 72 65 74 75 72   nLock);.  retur
c3c0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  n rc;.}../*.** C
c3d0: 6c 6f 73 65 20 61 6e 20 6f 70 65 6e 20 77 61 6c  lose an open wal
c3e0: 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 73 74 61 74 69  -index..*/.stati
c3f0: 63 20 76 6f 69 64 20 77 61 6c 49 6e 64 65 78 43  c void walIndexC
c400: 6c 6f 73 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20  lose(Wal *pWal, 
c410: 69 6e 74 20 69 73 44 65 6c 65 74 65 29 7b 0a 20  int isDelete){. 
c420: 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75   if( pWal->exclu
c430: 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48 45  siveMode==WAL_HE
c440: 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29 7b  APMEMORY_MODE ){
c450: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
c460: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 57 61 6c 2d  for(i=0; i<pWal-
c470: 3e 6e 57 69 44 61 74 61 3b 20 69 2b 2b 29 7b 0a  >nWiData; i++){.
c480: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
c490: 65 65 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d  ee((void *)pWal-
c4a0: 3e 61 70 57 69 44 61 74 61 5b 69 5d 29 3b 0a 20  >apWiData[i]);. 
c4b0: 20 20 20 20 20 70 57 61 6c 2d 3e 61 70 57 69 44       pWal->apWiD
c4c0: 61 74 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20  ata[i] = 0;.    
c4d0: 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73  }.  }else{.    s
c4e0: 71 6c 69 74 65 33 4f 73 53 68 6d 55 6e 6d 61 70  qlite3OsShmUnmap
c4f0: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 73  (pWal->pDbFd, is
c500: 44 65 6c 65 74 65 29 3b 0a 20 20 7d 0a 7d 0a 0a  Delete);.  }.}..
c510: 2f 2a 20 0a 2a 2a 20 4f 70 65 6e 20 61 20 63 6f  /* .** Open a co
c520: 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 74 68 65 20  nnection to the 
c530: 57 41 4c 20 66 69 6c 65 20 7a 57 61 6c 4e 61 6d  WAL file zWalNam
c540: 65 2e 20 54 68 65 20 64 61 74 61 62 61 73 65 20  e. The database 
c550: 66 69 6c 65 20 6d 75 73 74 20 0a 2a 2a 20 61 6c  file must .** al
c560: 72 65 61 64 79 20 62 65 20 6f 70 65 6e 65 64 20  ready be opened 
c570: 6f 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 70 44  on connection pD
c580: 62 46 64 2e 20 54 68 65 20 62 75 66 66 65 72 20  bFd. The buffer 
c590: 74 68 61 74 20 7a 57 61 6c 4e 61 6d 65 20 70 6f  that zWalName po
c5a0: 69 6e 74 73 0a 2a 2a 20 74 6f 20 6d 75 73 74 20  ints.** to must 
c5b0: 72 65 6d 61 69 6e 20 76 61 6c 69 64 20 66 6f 72  remain valid for
c5c0: 20 74 68 65 20 6c 69 66 65 74 69 6d 65 20 6f 66   the lifetime of
c5d0: 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 57 61   the returned Wa
c5e0: 6c 2a 20 68 61 6e 64 6c 65 2e 0a 2a 2a 0a 2a 2a  l* handle..**.**
c5f0: 20 41 20 53 48 41 52 45 44 20 6c 6f 63 6b 20 73   A SHARED lock s
c600: 68 6f 75 6c 64 20 62 65 20 68 65 6c 64 20 6f 6e  hould be held on
c610: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
c620: 6c 65 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e  le when this fun
c630: 63 74 69 6f 6e 0a 2a 2a 20 69 73 20 63 61 6c 6c  ction.** is call
c640: 65 64 2e 20 54 68 65 20 70 75 72 70 6f 73 65 20  ed. The purpose 
c650: 6f 66 20 74 68 69 73 20 53 48 41 52 45 44 20 6c  of this SHARED l
c660: 6f 63 6b 20 69 73 20 74 6f 20 70 72 65 76 65 6e  ock is to preven
c670: 74 20 61 6e 79 20 6f 74 68 65 72 0a 2a 2a 20 63  t any other.** c
c680: 6c 69 65 6e 74 20 66 72 6f 6d 20 75 6e 6c 69 6e  lient from unlin
c690: 6b 69 6e 67 20 74 68 65 20 57 41 4c 20 6f 72 20  king the WAL or 
c6a0: 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 2e 20  wal-index file. 
c6b0: 49 66 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65  If another proce
c6c0: 73 73 0a 2a 2a 20 77 65 72 65 20 74 6f 20 64 6f  ss.** were to do
c6d0: 20 74 68 69 73 20 6a 75 73 74 20 61 66 74 65 72   this just after
c6e0: 20 74 68 69 73 20 63 6c 69 65 6e 74 20 6f 70 65   this client ope
c6f0: 6e 65 64 20 6f 6e 65 20 6f 66 20 74 68 65 73 65  ned one of these
c700: 20 66 69 6c 65 73 2c 20 74 68 65 0a 2a 2a 20 73   files, the.** s
c710: 79 73 74 65 6d 20 77 6f 75 6c 64 20 62 65 20 62  ystem would be b
c720: 61 64 6c 79 20 62 72 6f 6b 65 6e 2e 0a 2a 2a 0a  adly broken..**.
c730: 2a 2a 20 49 66 20 74 68 65 20 6c 6f 67 20 66 69  ** If the log fi
c740: 6c 65 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  le is successful
c750: 6c 79 20 6f 70 65 6e 65 64 2c 20 53 51 4c 49 54  ly opened, SQLIT
c760: 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
c770: 20 61 6e 64 20 0a 2a 2a 20 2a 70 70 57 61 6c 20   and .** *ppWal 
c780: 69 73 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20  is set to point 
c790: 74 6f 20 61 20 6e 65 77 20 57 41 4c 20 68 61 6e  to a new WAL han
c7a0: 64 6c 65 2e 20 49 66 20 61 6e 20 65 72 72 6f 72  dle. If an error
c7b0: 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 61 6e 20 53   occurs,.** an S
c7c0: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
c7d0: 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64   is returned and
c7e0: 20 2a 70 70 57 61 6c 20 69 73 20 6c 65 66 74 20   *ppWal is left 
c7f0: 75 6e 6d 6f 64 69 66 69 65 64 2e 0a 2a 2f 0a 69  unmodified..*/.i
c800: 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 4f 70 65  nt sqlite3WalOpe
c810: 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  n(.  sqlite3_vfs
c820: 20 2a 70 56 66 73 2c 20 20 20 20 20 20 20 20 20   *pVfs,         
c830: 20 20 20 20 20 2f 2a 20 76 66 73 20 6d 6f 64 75       /* vfs modu
c840: 6c 65 20 74 6f 20 6f 70 65 6e 20 77 61 6c 20 61  le to open wal a
c850: 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a  nd wal-index */.
c860: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
c870: 70 44 62 46 64 2c 20 20 20 20 20 20 20 20 20 20  pDbFd,          
c880: 20 20 2f 2a 20 54 68 65 20 6f 70 65 6e 20 64 61    /* The open da
c890: 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20  tabase file */. 
c8a0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 57 61   const char *zWa
c8b0: 6c 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20  lName,          
c8c0: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20   /* Name of the 
c8d0: 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e  WAL file */.  in
c8e0: 74 20 62 4e 6f 53 68 6d 2c 20 20 20 20 20 20 20  t bNoShm,       
c8f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c900: 20 54 72 75 65 20 74 6f 20 72 75 6e 20 69 6e 20   True to run in 
c910: 68 65 61 70 2d 6d 65 6d 6f 72 79 20 6d 6f 64 65  heap-memory mode
c920: 20 2a 2f 0a 20 20 69 36 34 20 6d 78 57 61 6c 53   */.  i64 mxWalS
c930: 69 7a 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ize,            
c940: 20 20 20 20 20 20 2f 2a 20 54 72 75 6e 63 61 74        /* Truncat
c950: 65 20 57 41 4c 20 74 6f 20 74 68 69 73 20 73 69  e WAL to this si
c960: 7a 65 20 6f 6e 20 72 65 73 65 74 20 2a 2f 0a 20  ze on reset */. 
c970: 20 57 61 6c 20 2a 2a 70 70 57 61 6c 20 20 20 20   Wal **ppWal    
c980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c990: 20 2f 2a 20 4f 55 54 3a 20 41 6c 6c 6f 63 61 74   /* OUT: Allocat
c9a0: 65 64 20 57 61 6c 20 68 61 6e 64 6c 65 20 2a 2f  ed Wal handle */
c9b0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  .){.  int rc;   
c9c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c9d0: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
c9e0: 43 6f 64 65 20 2a 2f 0a 20 20 57 61 6c 20 2a 70  Code */.  Wal *p
c9f0: 52 65 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  Ret;            
ca00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a            /* Obj
ca10: 65 63 74 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  ect to allocate 
ca20: 61 6e 64 20 72 65 74 75 72 6e 20 2a 2f 0a 20 20  and return */.  
ca30: 69 6e 74 20 66 6c 61 67 73 3b 20 20 20 20 20 20  int flags;      
ca40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ca50: 2f 2a 20 46 6c 61 67 73 20 70 61 73 73 65 64 20  /* Flags passed 
ca60: 74 6f 20 4f 73 4f 70 65 6e 28 29 20 2a 2f 0a 0a  to OsOpen() */..
ca70: 20 20 61 73 73 65 72 74 28 20 7a 57 61 6c 4e 61    assert( zWalNa
ca80: 6d 65 20 26 26 20 7a 57 61 6c 4e 61 6d 65 5b 30  me && zWalName[0
ca90: 5d 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ] );.  assert( p
caa0: 44 62 46 64 20 29 3b 0a 0a 20 20 2f 2a 20 49 6e  DbFd );..  /* In
cab0: 20 74 68 65 20 61 6d 61 6c 67 61 6d 61 74 69 6f   the amalgamatio
cac0: 6e 2c 20 74 68 65 20 6f 73 5f 75 6e 69 78 2e 63  n, the os_unix.c
cad0: 20 61 6e 64 20 6f 73 5f 77 69 6e 2e 63 20 73 6f   and os_win.c so
cae0: 75 72 63 65 20 66 69 6c 65 73 20 63 6f 6d 65 20  urce files come 
caf0: 62 65 66 6f 72 65 0a 20 20 2a 2a 20 74 68 69 73  before.  ** this
cb00: 20 73 6f 75 72 63 65 20 66 69 6c 65 2e 20 20 56   source file.  V
cb10: 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20 23  erify that the #
cb20: 64 65 66 69 6e 65 73 20 6f 66 20 74 68 65 20 6c  defines of the l
cb30: 6f 63 6b 69 6e 67 20 62 79 74 65 20 6f 66 66 73  ocking byte offs
cb40: 65 74 73 0a 20 20 2a 2a 20 69 6e 20 6f 73 5f 75  ets.  ** in os_u
cb50: 6e 69 78 2e 63 20 61 6e 64 20 6f 73 5f 77 69 6e  nix.c and os_win
cb60: 2e 63 20 61 67 72 65 65 20 77 69 74 68 20 74 68  .c agree with th
cb70: 65 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f  e WALINDEX_LOCK_
cb80: 4f 46 46 53 45 54 20 76 61 6c 75 65 2e 0a 20 20  OFFSET value..  
cb90: 2a 2a 20 46 6f 72 20 74 68 61 74 20 6d 61 74 74  ** For that matt
cba0: 65 72 2c 20 69 66 20 74 68 65 20 6c 6f 63 6b 20  er, if the lock 
cbb0: 6f 66 66 73 65 74 20 65 76 65 72 20 63 68 61 6e  offset ever chan
cbc0: 67 65 73 20 66 72 6f 6d 20 69 74 73 20 69 6e 69  ges from its ini
cbd0: 74 69 61 6c 20 64 65 73 69 67 6e 0a 20 20 2a 2a  tial design.  **
cbe0: 20 76 61 6c 75 65 20 6f 66 20 31 32 30 2c 20 77   value of 120, w
cbf0: 65 20 6e 65 65 64 20 74 6f 20 6b 6e 6f 77 20 74  e need to know t
cc00: 68 61 74 20 73 6f 20 74 68 65 72 65 20 69 73 20  hat so there is 
cc10: 61 6e 20 61 73 73 65 72 74 28 29 20 74 6f 20 63  an assert() to c
cc20: 68 65 63 6b 20 69 74 2e 0a 20 20 2a 2f 0a 20 20  heck it..  */.  
cc30: 61 73 73 65 72 74 28 20 31 32 30 3d 3d 57 41 4c  assert( 120==WAL
cc40: 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45  INDEX_LOCK_OFFSE
cc50: 54 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 31  T );.  assert( 1
cc60: 33 36 3d 3d 57 41 4c 49 4e 44 45 58 5f 48 44 52  36==WALINDEX_HDR
cc70: 5f 53 49 5a 45 20 29 3b 0a 23 69 66 64 65 66 20  _SIZE );.#ifdef 
cc80: 57 49 4e 5f 53 48 4d 5f 42 41 53 45 0a 20 20 61  WIN_SHM_BASE.  a
cc90: 73 73 65 72 74 28 20 57 49 4e 5f 53 48 4d 5f 42  ssert( WIN_SHM_B
cca0: 41 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f  ASE==WALINDEX_LO
ccb0: 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65 6e  CK_OFFSET );.#en
ccc0: 64 69 66 0a 23 69 66 64 65 66 20 55 4e 49 58 5f  dif.#ifdef UNIX_
ccd0: 53 48 4d 5f 42 41 53 45 0a 20 20 61 73 73 65 72  SHM_BASE.  asser
cce0: 74 28 20 55 4e 49 58 5f 53 48 4d 5f 42 41 53 45  t( UNIX_SHM_BASE
ccf0: 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f  ==WALINDEX_LOCK_
cd00: 4f 46 46 53 45 54 20 29 3b 0a 23 65 6e 64 69 66  OFFSET );.#endif
cd10: 0a 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65  ...  /* Allocate
cd20: 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   an instance of 
cd30: 73 74 72 75 63 74 20 57 61 6c 20 74 6f 20 72 65  struct Wal to re
cd40: 74 75 72 6e 2e 20 2a 2f 0a 20 20 2a 70 70 57 61  turn. */.  *ppWa
cd50: 6c 20 3d 20 30 3b 0a 20 20 70 52 65 74 20 3d 20  l = 0;.  pRet = 
cd60: 28 57 61 6c 2a 29 73 71 6c 69 74 65 33 4d 61 6c  (Wal*)sqlite3Mal
cd70: 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 57  locZero(sizeof(W
cd80: 61 6c 29 20 2b 20 70 56 66 73 2d 3e 73 7a 4f 73  al) + pVfs->szOs
cd90: 46 69 6c 65 29 3b 0a 20 20 69 66 28 20 21 70 52  File);.  if( !pR
cda0: 65 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  et ){.    return
cdb0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b   SQLITE_NOMEM_BK
cdc0: 50 54 3b 0a 20 20 7d 0a 0a 20 20 70 52 65 74 2d  PT;.  }..  pRet-
cdd0: 3e 70 56 66 73 20 3d 20 70 56 66 73 3b 0a 20 20  >pVfs = pVfs;.  
cde0: 70 52 65 74 2d 3e 70 57 61 6c 46 64 20 3d 20 28  pRet->pWalFd = (
cdf0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 29 26  sqlite3_file *)&
ce00: 70 52 65 74 5b 31 5d 3b 0a 20 20 70 52 65 74 2d  pRet[1];.  pRet-
ce10: 3e 70 44 62 46 64 20 3d 20 70 44 62 46 64 3b 0a  >pDbFd = pDbFd;.
ce20: 20 20 70 52 65 74 2d 3e 72 65 61 64 4c 6f 63 6b    pRet->readLock
ce30: 20 3d 20 2d 31 3b 0a 20 20 70 52 65 74 2d 3e 6d   = -1;.  pRet->m
ce40: 78 57 61 6c 53 69 7a 65 20 3d 20 6d 78 57 61 6c  xWalSize = mxWal
ce50: 53 69 7a 65 3b 0a 20 20 70 52 65 74 2d 3e 7a 57  Size;.  pRet->zW
ce60: 61 6c 4e 61 6d 65 20 3d 20 7a 57 61 6c 4e 61 6d  alName = zWalNam
ce70: 65 3b 0a 20 20 70 52 65 74 2d 3e 73 79 6e 63 48  e;.  pRet->syncH
ce80: 65 61 64 65 72 20 3d 20 31 3b 0a 20 20 70 52 65  eader = 1;.  pRe
ce90: 74 2d 3e 70 61 64 54 6f 53 65 63 74 6f 72 42 6f  t->padToSectorBo
cea0: 75 6e 64 61 72 79 20 3d 20 31 3b 0a 20 20 70 52  undary = 1;.  pR
ceb0: 65 74 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  et->exclusiveMod
cec0: 65 20 3d 20 28 62 4e 6f 53 68 6d 20 3f 20 57 41  e = (bNoShm ? WA
ced0: 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44  L_HEAPMEMORY_MOD
cee0: 45 3a 20 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f  E: WAL_NORMAL_MO
cef0: 44 45 29 3b 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20  DE);..  /* Open 
cf00: 66 69 6c 65 20 68 61 6e 64 6c 65 20 6f 6e 20 74  file handle on t
cf10: 68 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c  he write-ahead l
cf20: 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 66 6c  og file. */.  fl
cf30: 61 67 73 20 3d 20 28 53 51 4c 49 54 45 5f 4f 50  ags = (SQLITE_OP
cf40: 45 4e 5f 52 45 41 44 57 52 49 54 45 7c 53 51 4c  EN_READWRITE|SQL
cf50: 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54 45 7c  ITE_OPEN_CREATE|
cf60: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 57 41 4c 29  SQLITE_OPEN_WAL)
cf70: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
cf80: 4f 73 4f 70 65 6e 28 70 56 66 73 2c 20 7a 57 61  OsOpen(pVfs, zWa
cf90: 6c 4e 61 6d 65 2c 20 70 52 65 74 2d 3e 70 57 61  lName, pRet->pWa
cfa0: 6c 46 64 2c 20 66 6c 61 67 73 2c 20 26 66 6c 61  lFd, flags, &fla
cfb0: 67 73 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  gs);.  if( rc==S
cfc0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 66 6c 61 67  QLITE_OK && flag
cfd0: 73 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45  s&SQLITE_OPEN_RE
cfe0: 41 44 4f 4e 4c 59 20 29 7b 0a 20 20 20 20 70 52  ADONLY ){.    pR
cff0: 65 74 2d 3e 72 65 61 64 4f 6e 6c 79 20 3d 20 57  et->readOnly = W
d000: 41 4c 5f 52 44 4f 4e 4c 59 3b 0a 20 20 7d 0a 0a  AL_RDONLY;.  }..
d010: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
d020: 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49 6e  _OK ){.    walIn
d030: 64 65 78 43 6c 6f 73 65 28 70 52 65 74 2c 20 30  dexClose(pRet, 0
d040: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  );.    sqlite3Os
d050: 43 6c 6f 73 65 28 70 52 65 74 2d 3e 70 57 61 6c  Close(pRet->pWal
d060: 46 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  Fd);.    sqlite3
d070: 5f 66 72 65 65 28 70 52 65 74 29 3b 0a 20 20 7d  _free(pRet);.  }
d080: 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 69 44  else{.    int iD
d090: 43 20 3d 20 73 71 6c 69 74 65 33 4f 73 44 65 76  C = sqlite3OsDev
d0a0: 69 63 65 43 68 61 72 61 63 74 65 72 69 73 74 69  iceCharacteristi
d0b0: 63 73 28 70 44 62 46 64 29 3b 0a 20 20 20 20 69  cs(pDbFd);.    i
d0c0: 66 28 20 69 44 43 20 26 20 53 51 4c 49 54 45 5f  f( iDC & SQLITE_
d0d0: 49 4f 43 41 50 5f 53 45 51 55 45 4e 54 49 41 4c  IOCAP_SEQUENTIAL
d0e0: 20 29 7b 20 70 52 65 74 2d 3e 73 79 6e 63 48 65   ){ pRet->syncHe
d0f0: 61 64 65 72 20 3d 20 30 3b 20 7d 0a 20 20 20 20  ader = 0; }.    
d100: 69 66 28 20 69 44 43 20 26 20 53 51 4c 49 54 45  if( iDC & SQLITE
d110: 5f 49 4f 43 41 50 5f 50 4f 57 45 52 53 41 46 45  _IOCAP_POWERSAFE
d120: 5f 4f 56 45 52 57 52 49 54 45 20 29 7b 0a 20 20  _OVERWRITE ){.  
d130: 20 20 20 20 70 52 65 74 2d 3e 70 61 64 54 6f 53      pRet->padToS
d140: 65 63 74 6f 72 42 6f 75 6e 64 61 72 79 20 3d 20  ectorBoundary = 
d150: 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 70  0;.    }.    *pp
d160: 57 61 6c 20 3d 20 70 52 65 74 3b 0a 20 20 20 20  Wal = pRet;.    
d170: 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 64  WALTRACE(("WAL%d
d180: 3a 20 6f 70 65 6e 65 64 5c 6e 22 2c 20 70 52 65  : opened\n", pRe
d190: 74 29 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  t));.  }.  retur
d1a0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  n rc;.}../*.** C
d1b0: 68 61 6e 67 65 20 74 68 65 20 73 69 7a 65 20 74  hange the size t
d1c0: 6f 20 77 68 69 63 68 20 74 68 65 20 57 41 4c 20  o which the WAL 
d1d0: 66 69 6c 65 20 69 73 20 74 72 75 63 61 74 65 64  file is trucated
d1e0: 20 6f 6e 20 65 61 63 68 20 72 65 73 65 74 2e 0a   on each reset..
d1f0: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 57  */.void sqlite3W
d200: 61 6c 4c 69 6d 69 74 28 57 61 6c 20 2a 70 57 61  alLimit(Wal *pWa
d210: 6c 2c 20 69 36 34 20 69 4c 69 6d 69 74 29 7b 0a  l, i64 iLimit){.
d220: 20 20 69 66 28 20 70 57 61 6c 20 29 20 70 57 61    if( pWal ) pWa
d230: 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 20 3d 20 69  l->mxWalSize = i
d240: 4c 69 6d 69 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Limit;.}../*.** 
d250: 46 69 6e 64 20 74 68 65 20 73 6d 61 6c 6c 65 73  Find the smalles
d260: 74 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 75  t page number ou
d270: 74 20 6f 66 20 61 6c 6c 20 70 61 67 65 73 20 68  t of all pages h
d280: 65 6c 64 20 69 6e 20 74 68 65 20 57 41 4c 20 74  eld in the WAL t
d290: 68 61 74 0a 2a 2a 20 68 61 73 20 6e 6f 74 20 62  hat.** has not b
d2a0: 65 65 6e 20 72 65 74 75 72 6e 65 64 20 62 79 20  een returned by 
d2b0: 61 6e 79 20 70 72 69 6f 72 20 69 6e 76 6f 63 61  any prior invoca
d2c0: 74 69 6f 6e 20 6f 66 20 74 68 69 73 20 6d 65 74  tion of this met
d2d0: 68 6f 64 20 6f 6e 20 74 68 65 0a 2a 2a 20 73 61  hod on the.** sa
d2e0: 6d 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f  me WalIterator o
d2f0: 62 6a 65 63 74 2e 20 20 20 57 72 69 74 65 20 69  bject.   Write i
d300: 6e 74 6f 20 2a 70 69 46 72 61 6d 65 20 74 68 65  nto *piFrame the
d310: 20 66 72 61 6d 65 20 69 6e 64 65 78 20 77 68 65   frame index whe
d320: 72 65 0a 2a 2a 20 74 68 61 74 20 70 61 67 65 20  re.** that page 
d330: 77 61 73 20 6c 61 73 74 20 77 72 69 74 74 65 6e  was last written
d340: 20 69 6e 74 6f 20 74 68 65 20 57 41 4c 2e 20 20   into the WAL.  
d350: 57 72 69 74 65 20 69 6e 74 6f 20 2a 70 69 50 61  Write into *piPa
d360: 67 65 20 74 68 65 20 70 61 67 65 0a 2a 2a 20 6e  ge the page.** n
d370: 75 6d 62 65 72 2e 0a 2a 2a 0a 2a 2a 20 52 65 74  umber..**.** Ret
d380: 75 72 6e 20 30 20 6f 6e 20 73 75 63 63 65 73 73  urn 0 on success
d390: 2e 20 20 49 66 20 74 68 65 72 65 20 61 72 65 20  .  If there are 
d3a0: 6e 6f 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  no pages in the 
d3b0: 57 41 4c 20 77 69 74 68 20 61 20 70 61 67 65 0a  WAL with a page.
d3c0: 2a 2a 20 6e 75 6d 62 65 72 20 6c 61 72 67 65 72  ** number larger
d3d0: 20 74 68 61 6e 20 2a 70 69 50 61 67 65 2c 20 74   than *piPage, t
d3e0: 68 65 6e 20 72 65 74 75 72 6e 20 31 2e 0a 2a 2f  hen return 1..*/
d3f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49  .static int walI
d400: 74 65 72 61 74 6f 72 4e 65 78 74 28 0a 20 20 57  teratorNext(.  W
d410: 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 2c 20 20  alIterator *p,  
d420: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
d430: 49 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 75 33  Iterator */.  u3
d440: 32 20 2a 70 69 50 61 67 65 2c 20 20 20 20 20 20  2 *piPage,      
d450: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
d460: 55 54 3a 20 54 68 65 20 70 61 67 65 20 6e 75 6d  UT: The page num
d470: 62 65 72 20 6f 66 20 74 68 65 20 6e 65 78 74 20  ber of the next 
d480: 70 61 67 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70  page */.  u32 *p
d490: 69 46 72 61 6d 65 20 20 20 20 20 20 20 20 20 20  iFrame          
d4a0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
d4b0: 57 61 6c 20 66 72 61 6d 65 20 69 6e 64 65 78 20  Wal frame index 
d4c0: 6f 66 20 6e 65 78 74 20 70 61 67 65 20 2a 2f 0a  of next page */.
d4d0: 29 7b 0a 20 20 75 33 32 20 69 4d 69 6e 3b 20 20  ){.  u32 iMin;  
d4e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d4f0: 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 70 67 6e     /* Result pgn
d500: 6f 20 6d 75 73 74 20 62 65 20 67 72 65 61 74 65  o must be greate
d510: 72 20 74 68 61 6e 20 69 4d 69 6e 20 2a 2f 0a 20  r than iMin */. 
d520: 20 75 33 32 20 69 52 65 74 20 3d 20 30 78 46 46   u32 iRet = 0xFF
d530: 46 46 46 46 46 46 3b 20 20 20 20 20 20 20 20 2f  FFFFFF;        /
d540: 2a 20 30 78 66 66 66 66 66 66 66 66 20 69 73 20  * 0xffffffff is 
d550: 6e 65 76 65 72 20 61 20 76 61 6c 69 64 20 70 61  never a valid pa
d560: 67 65 20 6e 75 6d 62 65 72 20 2a 2f 0a 20 20 69  ge number */.  i
d570: 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20  nt i;           
d580: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
d590: 46 6f 72 20 6c 6f 6f 70 69 6e 67 20 74 68 72 6f  For looping thro
d5a0: 75 67 68 20 73 65 67 6d 65 6e 74 73 20 2a 2f 0a  ugh segments */.
d5b0: 0a 20 20 69 4d 69 6e 20 3d 20 70 2d 3e 69 50 72  .  iMin = p->iPr
d5c0: 69 6f 72 3b 0a 20 20 61 73 73 65 72 74 28 20 69  ior;.  assert( i
d5d0: 4d 69 6e 3c 30 78 66 66 66 66 66 66 66 66 20 29  Min<0xffffffff )
d5e0: 3b 0a 20 20 66 6f 72 28 69 3d 70 2d 3e 6e 53 65  ;.  for(i=p->nSe
d5f0: 67 6d 65 6e 74 2d 31 3b 20 69 3e 3d 30 3b 20 69  gment-1; i>=0; i
d600: 2d 2d 29 7b 0a 20 20 20 20 73 74 72 75 63 74 20  --){.    struct 
d610: 57 61 6c 53 65 67 6d 65 6e 74 20 2a 70 53 65 67  WalSegment *pSeg
d620: 6d 65 6e 74 20 3d 20 26 70 2d 3e 61 53 65 67 6d  ment = &p->aSegm
d630: 65 6e 74 5b 69 5d 3b 0a 20 20 20 20 77 68 69 6c  ent[i];.    whil
d640: 65 28 20 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65  e( pSegment->iNe
d650: 78 74 3c 70 53 65 67 6d 65 6e 74 2d 3e 6e 45 6e  xt<pSegment->nEn
d660: 74 72 79 20 29 7b 0a 20 20 20 20 20 20 75 33 32  try ){.      u32
d670: 20 69 50 67 20 3d 20 70 53 65 67 6d 65 6e 74 2d   iPg = pSegment-
d680: 3e 61 50 67 6e 6f 5b 70 53 65 67 6d 65 6e 74 2d  >aPgno[pSegment-
d690: 3e 61 49 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74  >aIndex[pSegment
d6a0: 2d 3e 69 4e 65 78 74 5d 5d 3b 0a 20 20 20 20 20  ->iNext]];.     
d6b0: 20 69 66 28 20 69 50 67 3e 69 4d 69 6e 20 29 7b   if( iPg>iMin ){
d6c0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 50 67  .        if( iPg
d6d0: 3c 69 52 65 74 20 29 7b 0a 20 20 20 20 20 20 20  <iRet ){.       
d6e0: 20 20 20 69 52 65 74 20 3d 20 69 50 67 3b 0a 20     iRet = iPg;. 
d6f0: 20 20 20 20 20 20 20 20 20 2a 70 69 46 72 61 6d           *piFram
d700: 65 20 3d 20 70 53 65 67 6d 65 6e 74 2d 3e 69 5a  e = pSegment->iZ
d710: 65 72 6f 20 2b 20 70 53 65 67 6d 65 6e 74 2d 3e  ero + pSegment->
d720: 61 49 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d  aIndex[pSegment-
d730: 3e 69 4e 65 78 74 5d 3b 0a 20 20 20 20 20 20 20  >iNext];.       
d740: 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b   }.        break
d750: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
d760: 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 2b  pSegment->iNext+
d770: 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  +;.    }.  }..  
d780: 2a 70 69 50 61 67 65 20 3d 20 70 2d 3e 69 50 72  *piPage = p->iPr
d790: 69 6f 72 20 3d 20 69 52 65 74 3b 0a 20 20 72 65  ior = iRet;.  re
d7a0: 74 75 72 6e 20 28 69 52 65 74 3d 3d 30 78 46 46  turn (iRet==0xFF
d7b0: 46 46 46 46 46 46 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  FFFFFF);.}../*.*
d7c0: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
d7d0: 6d 65 72 67 65 73 20 74 77 6f 20 73 6f 72 74 65  merges two sorte
d7e0: 64 20 6c 69 73 74 73 20 69 6e 74 6f 20 61 20 73  d lists into a s
d7f0: 69 6e 67 6c 65 20 73 6f 72 74 65 64 20 6c 69 73  ingle sorted lis
d800: 74 2e 0a 2a 2a 0a 2a 2a 20 61 4c 65 66 74 5b 5d  t..**.** aLeft[]
d810: 20 61 6e 64 20 61 52 69 67 68 74 5b 5d 20 61 72   and aRight[] ar
d820: 65 20 61 72 72 61 79 73 20 6f 66 20 69 6e 64 69  e arrays of indi
d830: 63 65 73 2e 20 20 54 68 65 20 73 6f 72 74 20 6b  ces.  The sort k
d840: 65 79 20 69 73 0a 2a 2a 20 61 43 6f 6e 74 65 6e  ey is.** aConten
d850: 74 5b 61 4c 65 66 74 5b 5d 5d 20 61 6e 64 20 61  t[aLeft[]] and a
d860: 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b 5d  Content[aRight[]
d870: 5d 2e 20 20 55 70 6f 6e 20 65 6e 74 72 79 2c 20  ].  Upon entry, 
d880: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a  the following.**
d890: 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 66   is guaranteed f
d8a0: 6f 72 20 61 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a 2a  or all J<K:.**.*
d8b0: 2a 20 20 20 20 20 20 20 20 61 43 6f 6e 74 65 6e  *        aConten
d8c0: 74 5b 61 4c 65 66 74 5b 4a 5d 5d 20 3c 20 61 43  t[aLeft[J]] < aC
d8d0: 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 4b 5d 5d  ontent[aLeft[K]]
d8e0: 0a 2a 2a 20 20 20 20 20 20 20 20 61 43 6f 6e 74  .**        aCont
d8f0: 65 6e 74 5b 61 52 69 67 68 74 5b 4a 5d 5d 20 3c  ent[aRight[J]] <
d900: 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74   aContent[aRight
d910: 5b 4b 5d 5d 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  [K]].**.** This 
d920: 72 6f 75 74 69 6e 65 20 6f 76 65 72 77 72 69 74  routine overwrit
d930: 65 73 20 61 52 69 67 68 74 5b 5d 20 77 69 74 68  es aRight[] with
d940: 20 61 20 6e 65 77 20 28 70 72 6f 62 61 62 6c 79   a new (probably
d950: 20 6c 6f 6e 67 65 72 29 20 73 65 71 75 65 6e 63   longer) sequenc
d960: 65 0a 2a 2a 20 6f 66 20 69 6e 64 69 63 65 73 20  e.** of indices 
d970: 73 75 63 68 20 74 68 61 74 20 74 68 65 20 61 52  such that the aR
d980: 69 67 68 74 5b 5d 20 63 6f 6e 74 61 69 6e 73 20  ight[] contains 
d990: 65 76 65 72 79 20 69 6e 64 65 78 20 74 68 61 74  every index that
d9a0: 20 61 70 70 65 61 72 73 20 69 6e 0a 2a 2a 20 65   appears in.** e
d9b0: 69 74 68 65 72 20 61 4c 65 66 74 5b 5d 20 6f 72  ither aLeft[] or
d9c0: 20 74 68 65 20 6f 6c 64 20 61 52 69 67 68 74 5b   the old aRight[
d9d0: 5d 20 61 6e 64 20 73 75 63 68 20 74 68 61 74 20  ] and such that 
d9e0: 74 68 65 20 73 65 63 6f 6e 64 20 63 6f 6e 64 69  the second condi
d9f0: 74 69 6f 6e 0a 2a 2a 20 61 62 6f 76 65 20 69 73  tion.** above is
da00: 20 73 74 69 6c 6c 20 6d 65 74 2e 0a 2a 2a 0a 2a   still met..**.*
da10: 2a 20 54 68 65 20 61 43 6f 6e 74 65 6e 74 5b 61  * The aContent[a
da20: 4c 65 66 74 5b 58 5d 5d 20 76 61 6c 75 65 73 20  Left[X]] values 
da30: 77 69 6c 6c 20 62 65 20 75 6e 69 71 75 65 20 66  will be unique f
da40: 6f 72 20 61 6c 6c 20 58 2e 20 20 41 6e 64 20 74  or all X.  And t
da50: 68 65 0a 2a 2a 20 61 43 6f 6e 74 65 6e 74 5b 61  he.** aContent[a
da60: 52 69 67 68 74 5b 58 5d 5d 20 76 61 6c 75 65 73  Right[X]] values
da70: 20 77 69 6c 6c 20 62 65 20 75 6e 69 71 75 65 20   will be unique 
da80: 74 6f 6f 2e 20 20 42 75 74 20 74 68 65 72 65 20  too.  But there 
da90: 6d 69 67 68 74 20 62 65 0a 2a 2a 20 6f 6e 65 20  might be.** one 
daa0: 6f 72 20 6d 6f 72 65 20 63 6f 6d 62 69 6e 61 74  or more combinat
dab0: 69 6f 6e 73 20 6f 66 20 58 20 61 6e 64 20 59 20  ions of X and Y 
dac0: 73 75 63 68 20 74 68 61 74 0a 2a 2a 0a 2a 2a 20  such that.**.** 
dad0: 20 20 20 20 20 61 4c 65 66 74 5b 58 5d 21 3d 61       aLeft[X]!=a
dae0: 52 69 67 68 74 5b 59 5d 20 20 26 26 20 20 61 43  Right[Y]  &&  aC
daf0: 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 58 5d 5d  ontent[aLeft[X]]
db00: 20 3d 3d 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69   == aContent[aRi
db10: 67 68 74 5b 59 5d 5d 0a 2a 2a 0a 2a 2a 20 57 68  ght[Y]].**.** Wh
db20: 65 6e 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c  en that happens,
db30: 20 6f 6d 69 74 20 74 68 65 20 61 4c 65 66 74 5b   omit the aLeft[
db40: 58 5d 20 61 6e 64 20 75 73 65 20 74 68 65 20 61  X] and use the a
db50: 52 69 67 68 74 5b 59 5d 20 69 6e 64 65 78 2e 0a  Right[Y] index..
db60: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
db70: 61 6c 4d 65 72 67 65 28 0a 20 20 63 6f 6e 73 74  alMerge(.  const
db80: 20 75 33 32 20 2a 61 43 6f 6e 74 65 6e 74 2c 20   u32 *aContent, 
db90: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
dba0: 67 65 73 20 69 6e 20 77 61 6c 20 2d 20 6b 65 79  ges in wal - key
dbb0: 73 20 66 6f 72 20 74 68 65 20 73 6f 72 74 20 2a  s for the sort *
dbc0: 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 65  /.  ht_slot *aLe
dbd0: 66 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ft,             
dbe0: 20 20 20 20 2f 2a 20 49 4e 3a 20 4c 65 66 74 20      /* IN: Left 
dbf0: 68 61 6e 64 20 69 6e 70 75 74 20 6c 69 73 74 20  hand input list 
dc00: 2a 2f 0a 20 20 69 6e 74 20 6e 4c 65 66 74 2c 20  */.  int nLeft, 
dc10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dc20: 20 20 20 20 20 2f 2a 20 49 4e 3a 20 45 6c 65 6d       /* IN: Elem
dc30: 65 6e 74 73 20 69 6e 20 61 72 72 61 79 20 2a 70  ents in array *p
dc40: 61 4c 65 66 74 20 2a 2f 0a 20 20 68 74 5f 73 6c  aLeft */.  ht_sl
dc50: 6f 74 20 2a 2a 70 61 52 69 67 68 74 2c 20 20 20  ot **paRight,   
dc60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e             /* IN
dc70: 2f 4f 55 54 3a 20 52 69 67 68 74 20 68 61 6e 64  /OUT: Right hand
dc80: 20 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20   input list */. 
dc90: 20 69 6e 74 20 2a 70 6e 52 69 67 68 74 2c 20 20   int *pnRight,  
dca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dcb0: 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45 6c 65 6d   /* IN/OUT: Elem
dcc0: 65 6e 74 73 20 69 6e 20 2a 70 61 52 69 67 68 74  ents in *paRight
dcd0: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61   */.  ht_slot *a
dce0: 54 6d 70 20 20 20 20 20 20 20 20 20 20 20 20 20  Tmp             
dcf0: 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61        /* Tempora
dd00: 72 79 20 62 75 66 66 65 72 20 2a 2f 0a 29 7b 0a  ry buffer */.){.
dd10: 20 20 69 6e 74 20 69 4c 65 66 74 20 3d 20 30 3b    int iLeft = 0;
dd20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dd30: 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64    /* Current ind
dd40: 65 78 20 69 6e 20 61 4c 65 66 74 20 2a 2f 0a 20  ex in aLeft */. 
dd50: 20 69 6e 74 20 69 52 69 67 68 74 20 3d 20 30 3b   int iRight = 0;
dd60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dd70: 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65   /* Current inde
dd80: 78 20 69 6e 20 61 52 69 67 68 74 20 2a 2f 0a 20  x in aRight */. 
dd90: 20 69 6e 74 20 69 4f 75 74 20 3d 20 30 3b 20 20   int iOut = 0;  
dda0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ddb0: 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65   /* Current inde
ddc0: 78 20 69 6e 20 6f 75 74 70 75 74 20 62 75 66 66  x in output buff
ddd0: 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 69 67  er */.  int nRig
dde0: 68 74 20 3d 20 2a 70 6e 52 69 67 68 74 3b 0a 20  ht = *pnRight;. 
ddf0: 20 68 74 5f 73 6c 6f 74 20 2a 61 52 69 67 68 74   ht_slot *aRight
de00: 20 3d 20 2a 70 61 52 69 67 68 74 3b 0a 0a 20 20   = *paRight;..  
de10: 61 73 73 65 72 74 28 20 6e 4c 65 66 74 3e 30 20  assert( nLeft>0 
de20: 26 26 20 6e 52 69 67 68 74 3e 30 20 29 3b 0a 20  && nRight>0 );. 
de30: 20 77 68 69 6c 65 28 20 69 52 69 67 68 74 3c 6e   while( iRight<n
de40: 52 69 67 68 74 20 7c 7c 20 69 4c 65 66 74 3c 6e  Right || iLeft<n
de50: 4c 65 66 74 20 29 7b 0a 20 20 20 20 68 74 5f 73  Left ){.    ht_s
de60: 6c 6f 74 20 6c 6f 67 70 61 67 65 3b 0a 20 20 20  lot logpage;.   
de70: 20 50 67 6e 6f 20 64 62 70 61 67 65 3b 0a 0a 20   Pgno dbpage;.. 
de80: 20 20 20 69 66 28 20 28 69 4c 65 66 74 3c 6e 4c     if( (iLeft<nL
de90: 65 66 74 29 20 0a 20 20 20 20 20 26 26 20 28 69  eft) .     && (i
dea0: 52 69 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c  Right>=nRight ||
deb0: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b   aContent[aLeft[
dec0: 69 4c 65 66 74 5d 5d 3c 61 43 6f 6e 74 65 6e 74  iLeft]]<aContent
ded0: 5b 61 52 69 67 68 74 5b 69 52 69 67 68 74 5d 5d  [aRight[iRight]]
dee0: 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 6c  ).    ){.      l
def0: 6f 67 70 61 67 65 20 3d 20 61 4c 65 66 74 5b 69  ogpage = aLeft[i
df00: 4c 65 66 74 2b 2b 5d 3b 0a 20 20 20 20 7d 65 6c  Left++];.    }el
df10: 73 65 7b 0a 20 20 20 20 20 20 6c 6f 67 70 61 67  se{.      logpag
df20: 65 20 3d 20 61 52 69 67 68 74 5b 69 52 69 67 68  e = aRight[iRigh
df30: 74 2b 2b 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20  t++];.    }.    
df40: 64 62 70 61 67 65 20 3d 20 61 43 6f 6e 74 65 6e  dbpage = aConten
df50: 74 5b 6c 6f 67 70 61 67 65 5d 3b 0a 0a 20 20 20  t[logpage];..   
df60: 20 61 54 6d 70 5b 69 4f 75 74 2b 2b 5d 20 3d 20   aTmp[iOut++] = 
df70: 6c 6f 67 70 61 67 65 3b 0a 20 20 20 20 69 66 28  logpage;.    if(
df80: 20 69 4c 65 66 74 3c 6e 4c 65 66 74 20 26 26 20   iLeft<nLeft && 
df90: 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69  aContent[aLeft[i
dfa0: 4c 65 66 74 5d 5d 3d 3d 64 62 70 61 67 65 20 29  Left]]==dbpage )
dfb0: 20 69 4c 65 66 74 2b 2b 3b 0a 0a 20 20 20 20 61   iLeft++;..    a
dfc0: 73 73 65 72 74 28 20 69 4c 65 66 74 3e 3d 6e 4c  ssert( iLeft>=nL
dfd0: 65 66 74 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b  eft || aContent[
dfe0: 61 4c 65 66 74 5b 69 4c 65 66 74 5d 5d 3e 64 62  aLeft[iLeft]]>db
dff0: 70 61 67 65 20 29 3b 0a 20 20 20 20 61 73 73 65  page );.    asse
e000: 72 74 28 20 69 52 69 67 68 74 3e 3d 6e 52 69 67  rt( iRight>=nRig
e010: 68 74 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61  ht || aContent[a
e020: 52 69 67 68 74 5b 69 52 69 67 68 74 5d 5d 3e 64  Right[iRight]]>d
e030: 62 70 61 67 65 20 29 3b 0a 20 20 7d 0a 0a 20 20  bpage );.  }..  
e040: 2a 70 61 52 69 67 68 74 20 3d 20 61 4c 65 66 74  *paRight = aLeft
e050: 3b 0a 20 20 2a 70 6e 52 69 67 68 74 20 3d 20 69  ;.  *pnRight = i
e060: 4f 75 74 3b 0a 20 20 6d 65 6d 63 70 79 28 61 4c  Out;.  memcpy(aL
e070: 65 66 74 2c 20 61 54 6d 70 2c 20 73 69 7a 65 6f  eft, aTmp, sizeo
e080: 66 28 61 54 6d 70 5b 30 5d 29 2a 69 4f 75 74 29  f(aTmp[0])*iOut)
e090: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20  ;.}../*.** Sort 
e0a0: 74 68 65 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20  the elements in 
e0b0: 6c 69 73 74 20 61 4c 69 73 74 20 75 73 69 6e 67  list aList using
e0c0: 20 61 43 6f 6e 74 65 6e 74 5b 5d 20 61 73 20 74   aContent[] as t
e0d0: 68 65 20 73 6f 72 74 20 6b 65 79 2e 0a 2a 2a 20  he sort key..** 
e0e0: 52 65 6d 6f 76 65 20 65 6c 65 6d 65 6e 74 73 20  Remove elements 
e0f0: 77 69 74 68 20 64 75 70 6c 69 63 61 74 65 20 6b  with duplicate k
e100: 65 79 73 2c 20 70 72 65 66 65 72 72 69 6e 67 20  eys, preferring 
e110: 74 6f 20 6b 65 65 70 20 74 68 65 0a 2a 2a 20 6c  to keep the.** l
e120: 61 72 67 65 72 20 61 4c 69 73 74 5b 5d 20 76 61  arger aList[] va
e130: 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  lues..**.** The 
e140: 61 4c 69 73 74 5b 5d 20 65 6e 74 72 69 65 73 20  aList[] entries 
e150: 61 72 65 20 69 6e 64 69 63 65 73 20 69 6e 74 6f  are indices into
e160: 20 61 43 6f 6e 74 65 6e 74 5b 5d 2e 20 20 54 68   aContent[].  Th
e170: 65 20 76 61 6c 75 65 73 20 69 6e 0a 2a 2a 20 61  e values in.** a
e180: 4c 69 73 74 5b 5d 20 61 72 65 20 74 6f 20 62 65  List[] are to be
e190: 20 73 6f 72 74 65 64 20 73 6f 20 74 68 61 74 20   sorted so that 
e1a0: 66 6f 72 20 61 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a  for all J<K:.**.
e1b0: 2a 2a 20 20 20 20 20 20 61 43 6f 6e 74 65 6e 74  **      aContent
e1c0: 5b 61 4c 69 73 74 5b 4a 5d 5d 20 3c 20 61 43 6f  [aList[J]] < aCo
e1d0: 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 4b 5d 5d 0a  ntent[aList[K]].
e1e0: 2a 2a 0a 2a 2a 20 46 6f 72 20 61 6e 79 20 58 20  **.** For any X 
e1f0: 61 6e 64 20 59 20 73 75 63 68 20 74 68 61 74 0a  and Y such that.
e200: 2a 2a 0a 2a 2a 20 20 20 20 20 20 61 43 6f 6e 74  **.**      aCont
e210: 65 6e 74 5b 61 4c 69 73 74 5b 58 5d 5d 20 3d 3d  ent[aList[X]] ==
e220: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b   aContent[aList[
e230: 59 5d 5d 0a 2a 2a 0a 2a 2a 20 4b 65 65 70 20 74  Y]].**.** Keep t
e240: 68 65 20 6c 61 72 67 65 72 20 6f 66 20 74 68 65  he larger of the
e250: 20 74 77 6f 20 76 61 6c 75 65 73 20 61 4c 69 73   two values aLis
e260: 74 5b 58 5d 20 61 6e 64 20 61 4c 69 73 74 5b 59  t[X] and aList[Y
e270: 5d 20 61 6e 64 20 64 69 73 63 61 72 64 0a 2a 2a  ] and discard.**
e280: 20 74 68 65 20 73 6d 61 6c 6c 65 72 2e 0a 2a 2f   the smaller..*/
e290: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
e2a0: 4d 65 72 67 65 73 6f 72 74 28 0a 20 20 63 6f 6e  Mergesort(.  con
e2b0: 73 74 20 75 33 32 20 2a 61 43 6f 6e 74 65 6e 74  st u32 *aContent
e2c0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
e2d0: 50 61 67 65 73 20 69 6e 20 77 61 6c 20 2a 2f 0a  Pages in wal */.
e2e0: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 42 75 66 66    ht_slot *aBuff
e2f0: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
e300: 20 20 2f 2a 20 42 75 66 66 65 72 20 6f 66 20 61    /* Buffer of a
e310: 74 20 6c 65 61 73 74 20 2a 70 6e 4c 69 73 74 20  t least *pnList 
e320: 69 74 65 6d 73 20 74 6f 20 75 73 65 20 2a 2f 0a  items to use */.
e330: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 69 73 74    ht_slot *aList
e340: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
e350: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4c 69 73    /* IN/OUT: Lis
e360: 74 20 74 6f 20 73 6f 72 74 20 2a 2f 0a 20 20 69  t to sort */.  i
e370: 6e 74 20 2a 70 6e 4c 69 73 74 20 20 20 20 20 20  nt *pnList      
e380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e390: 2a 20 49 4e 2f 4f 55 54 3a 20 4e 75 6d 62 65 72  * IN/OUT: Number
e3a0: 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20   of elements in 
e3b0: 61 4c 69 73 74 5b 5d 20 2a 2f 0a 29 7b 0a 20 20  aList[] */.){.  
e3c0: 73 74 72 75 63 74 20 53 75 62 6c 69 73 74 20 7b  struct Sublist {
e3d0: 0a 20 20 20 20 69 6e 74 20 6e 4c 69 73 74 3b 20  .    int nList; 
e3e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e3f0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
e400: 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 4c 69 73  elements in aLis
e410: 74 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74  t */.    ht_slot
e420: 20 2a 61 4c 69 73 74 3b 20 20 20 20 20 20 20 20   *aList;        
e430: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
e440: 72 20 74 6f 20 73 75 62 2d 6c 69 73 74 20 63 6f  r to sub-list co
e450: 6e 74 65 6e 74 20 2a 2f 0a 20 20 7d 3b 0a 0a 20  ntent */.  };.. 
e460: 20 63 6f 6e 73 74 20 69 6e 74 20 6e 4c 69 73 74   const int nList
e470: 20 3d 20 2a 70 6e 4c 69 73 74 3b 20 20 20 20 20   = *pnList;     
e480: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 69 6e 70 75   /* Size of inpu
e490: 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20  t list */.  int 
e4a0: 6e 4d 65 72 67 65 20 3d 20 30 3b 20 20 20 20 20  nMerge = 0;     
e4b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
e4c0: 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74  umber of element
e4d0: 73 20 69 6e 20 6c 69 73 74 20 61 4d 65 72 67 65  s in list aMerge
e4e0: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61   */.  ht_slot *a
e4f0: 4d 65 72 67 65 20 3d 20 30 3b 20 20 20 20 20 20  Merge = 0;      
e500: 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 74 6f        /* List to
e510: 20 62 65 20 6d 65 72 67 65 64 20 2a 2f 0a 20 20   be merged */.  
e520: 69 6e 74 20 69 4c 69 73 74 3b 20 20 20 20 20 20  int iList;      
e530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e540: 2f 2a 20 49 6e 64 65 78 20 69 6e 74 6f 20 69 6e  /* Index into in
e550: 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 75 33  put list */.  u3
e560: 32 20 69 53 75 62 20 3d 20 30 3b 20 20 20 20 20  2 iSub = 0;     
e570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
e580: 20 49 6e 64 65 78 20 69 6e 74 6f 20 61 53 75 62   Index into aSub
e590: 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 74 72 75   array */.  stru
e5a0: 63 74 20 53 75 62 6c 69 73 74 20 61 53 75 62 5b  ct Sublist aSub[
e5b0: 31 33 5d 3b 20 20 20 20 20 20 20 20 2f 2a 20 41  13];        /* A
e5c0: 72 72 61 79 20 6f 66 20 73 75 62 2d 6c 69 73 74  rray of sub-list
e5d0: 73 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65 74 28 61  s */..  memset(a
e5e0: 53 75 62 2c 20 30 2c 20 73 69 7a 65 6f 66 28 61  Sub, 0, sizeof(a
e5f0: 53 75 62 29 29 3b 0a 20 20 61 73 73 65 72 74 28  Sub));.  assert(
e600: 20 6e 4c 69 73 74 3c 3d 48 41 53 48 54 41 42 4c   nList<=HASHTABL
e610: 45 5f 4e 50 41 47 45 20 26 26 20 6e 4c 69 73 74  E_NPAGE && nList
e620: 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  >0 );.  assert( 
e630: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3d  HASHTABLE_NPAGE=
e640: 3d 28 31 3c 3c 28 41 72 72 61 79 53 69 7a 65 28  =(1<<(ArraySize(
e650: 61 53 75 62 29 2d 31 29 29 20 29 3b 0a 0a 20 20  aSub)-1)) );..  
e660: 66 6f 72 28 69 4c 69 73 74 3d 30 3b 20 69 4c 69  for(iList=0; iLi
e670: 73 74 3c 6e 4c 69 73 74 3b 20 69 4c 69 73 74 2b  st<nList; iList+
e680: 2b 29 7b 0a 20 20 20 20 6e 4d 65 72 67 65 20 3d  +){.    nMerge =
e690: 20 31 3b 0a 20 20 20 20 61 4d 65 72 67 65 20 3d   1;.    aMerge =
e6a0: 20 26 61 4c 69 73 74 5b 69 4c 69 73 74 5d 3b 0a   &aList[iList];.
e6b0: 20 20 20 20 66 6f 72 28 69 53 75 62 3d 30 3b 20      for(iSub=0; 
e6c0: 69 4c 69 73 74 20 26 20 28 31 3c 3c 69 53 75 62  iList & (1<<iSub
e6d0: 29 3b 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20  ); iSub++){.    
e6e0: 20 20 73 74 72 75 63 74 20 53 75 62 6c 69 73 74    struct Sublist
e6f0: 20 2a 70 3b 0a 20 20 20 20 20 20 61 73 73 65 72   *p;.      asser
e700: 74 28 20 69 53 75 62 3c 41 72 72 61 79 53 69 7a  t( iSub<ArraySiz
e710: 65 28 61 53 75 62 29 20 29 3b 0a 20 20 20 20 20  e(aSub) );.     
e720: 20 70 20 3d 20 26 61 53 75 62 5b 69 53 75 62 5d   p = &aSub[iSub]
e730: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
e740: 70 2d 3e 61 4c 69 73 74 20 26 26 20 70 2d 3e 6e  p->aList && p->n
e750: 4c 69 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29 20  List<=(1<<iSub) 
e760: 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
e770: 20 70 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69 73   p->aList==&aLis
e780: 74 5b 69 4c 69 73 74 26 7e 28 28 32 3c 3c 69 53  t[iList&~((2<<iS
e790: 75 62 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20 20  ub)-1)] );.     
e7a0: 20 77 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74 65   walMerge(aConte
e7b0: 6e 74 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70 2d  nt, p->aList, p-
e7c0: 3e 6e 4c 69 73 74 2c 20 26 61 4d 65 72 67 65 2c  >nList, &aMerge,
e7d0: 20 26 6e 4d 65 72 67 65 2c 20 61 42 75 66 66 65   &nMerge, aBuffe
e7e0: 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 53  r);.    }.    aS
e7f0: 75 62 5b 69 53 75 62 5d 2e 61 4c 69 73 74 20 3d  ub[iSub].aList =
e800: 20 61 4d 65 72 67 65 3b 0a 20 20 20 20 61 53 75   aMerge;.    aSu
e810: 62 5b 69 53 75 62 5d 2e 6e 4c 69 73 74 20 3d 20  b[iSub].nList = 
e820: 6e 4d 65 72 67 65 3b 0a 20 20 7d 0a 0a 20 20 66  nMerge;.  }..  f
e830: 6f 72 28 69 53 75 62 2b 2b 3b 20 69 53 75 62 3c  or(iSub++; iSub<
e840: 41 72 72 61 79 53 69 7a 65 28 61 53 75 62 29 3b  ArraySize(aSub);
e850: 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20 69 66   iSub++){.    if
e860: 28 20 6e 4c 69 73 74 20 26 20 28 31 3c 3c 69 53  ( nList & (1<<iS
e870: 75 62 29 20 29 7b 0a 20 20 20 20 20 20 73 74 72  ub) ){.      str
e880: 75 63 74 20 53 75 62 6c 69 73 74 20 2a 70 3b 0a  uct Sublist *p;.
e890: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 53        assert( iS
e8a0: 75 62 3c 41 72 72 61 79 53 69 7a 65 28 61 53 75  ub<ArraySize(aSu
e8b0: 62 29 20 29 3b 0a 20 20 20 20 20 20 70 20 3d 20  b) );.      p = 
e8c0: 26 61 53 75 62 5b 69 53 75 62 5d 3b 0a 20 20 20  &aSub[iSub];.   
e8d0: 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 4c     assert( p->nL
e8e0: 69 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29 20 29  ist<=(1<<iSub) )
e8f0: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
e900: 70 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69 73 74  p->aList==&aList
e910: 5b 6e 4c 69 73 74 26 7e 28 28 32 3c 3c 69 53 75  [nList&~((2<<iSu
e920: 62 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20 20 20  b)-1)] );.      
e930: 77 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74 65 6e  walMerge(aConten
e940: 74 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70 2d 3e  t, p->aList, p->
e950: 6e 4c 69 73 74 2c 20 26 61 4d 65 72 67 65 2c 20  nList, &aMerge, 
e960: 26 6e 4d 65 72 67 65 2c 20 61 42 75 66 66 65 72  &nMerge, aBuffer
e970: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61  );.    }.  }.  a
e980: 73 73 65 72 74 28 20 61 4d 65 72 67 65 3d 3d 61  ssert( aMerge==a
e990: 4c 69 73 74 20 29 3b 0a 20 20 2a 70 6e 4c 69 73  List );.  *pnLis
e9a0: 74 20 3d 20 6e 4d 65 72 67 65 3b 0a 0a 23 69 66  t = nMerge;..#if
e9b0: 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47  def SQLITE_DEBUG
e9c0: 0a 20 20 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a  .  {.    int i;.
e9d0: 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 2a      for(i=1; i<*
e9e0: 70 6e 4c 69 73 74 3b 20 69 2b 2b 29 7b 0a 20 20  pnList; i++){.  
e9f0: 20 20 20 20 61 73 73 65 72 74 28 20 61 43 6f 6e      assert( aCon
ea00: 74 65 6e 74 5b 61 4c 69 73 74 5b 69 5d 5d 20 3e  tent[aList[i]] >
ea10: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b   aContent[aList[
ea20: 69 2d 31 5d 5d 20 29 3b 0a 20 20 20 20 7d 0a 20  i-1]] );.    }. 
ea30: 20 7d 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 20   }.#endif.}../* 
ea40: 0a 2a 2a 20 46 72 65 65 20 61 6e 20 69 74 65 72  .** Free an iter
ea50: 61 74 6f 72 20 61 6c 6c 6f 63 61 74 65 64 20 62  ator allocated b
ea60: 79 20 77 61 6c 49 74 65 72 61 74 6f 72 49 6e 69  y walIteratorIni
ea70: 74 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  t()..*/.static v
ea80: 6f 69 64 20 77 61 6c 49 74 65 72 61 74 6f 72 46  oid walIteratorF
ea90: 72 65 65 28 57 61 6c 49 74 65 72 61 74 6f 72 20  ree(WalIterator 
eaa0: 2a 70 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  *p){.  sqlite3_f
eab0: 72 65 65 28 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ree(p);.}../*.**
eac0: 20 43 6f 6e 73 74 72 75 63 74 20 61 20 57 61 6c   Construct a Wal
ead0: 49 6e 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74  Interator object
eae0: 20 74 68 61 74 20 63 61 6e 20 62 65 20 75 73 65   that can be use
eaf0: 64 20 74 6f 20 6c 6f 6f 70 20 6f 76 65 72 20 61  d to loop over a
eb00: 6c 6c 20 0a 2a 2a 20 70 61 67 65 73 20 69 6e 20  ll .** pages in 
eb10: 74 68 65 20 57 41 4c 20 69 6e 20 61 73 63 65 6e  the WAL in ascen
eb20: 64 69 6e 67 20 6f 72 64 65 72 2e 20 54 68 65 20  ding order. The 
eb30: 63 61 6c 6c 65 72 20 6d 75 73 74 20 68 6f 6c 64  caller must hold
eb40: 20 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 0a   the checkpoint.
eb50: 2a 2a 20 6c 6f 63 6b 2e 0a 2a 2a 0a 2a 2a 20 4f  ** lock..**.** O
eb60: 6e 20 73 75 63 63 65 73 73 2c 20 6d 61 6b 65 20  n success, make 
eb70: 2a 70 70 20 70 6f 69 6e 74 20 74 6f 20 74 68 65  *pp point to the
eb80: 20 6e 65 77 6c 79 20 61 6c 6c 6f 63 61 74 65 64   newly allocated
eb90: 20 57 61 6c 49 6e 74 65 72 61 74 6f 72 20 6f 62   WalInterator ob
eba0: 6a 65 63 74 0a 2a 2a 20 72 65 74 75 72 6e 20 53  ject.** return S
ebb0: 51 4c 49 54 45 5f 4f 4b 2e 20 4f 74 68 65 72 77  QLITE_OK. Otherw
ebc0: 69 73 65 2c 20 72 65 74 75 72 6e 20 61 6e 20 65  ise, return an e
ebd0: 72 72 6f 72 20 63 6f 64 65 2e 20 49 66 20 74 68  rror code. If th
ebe0: 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65  is routine.** re
ebf0: 74 75 72 6e 73 20 61 6e 20 65 72 72 6f 72 2c 20  turns an error, 
ec00: 74 68 65 20 76 61 6c 75 65 20 6f 66 20 2a 70 70  the value of *pp
ec10: 20 69 73 20 75 6e 64 65 66 69 6e 65 64 2e 0a 2a   is undefined..*
ec20: 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 69 6e 67  *.** The calling
ec30: 20 72 6f 75 74 69 6e 65 20 73 68 6f 75 6c 64 20   routine should 
ec40: 69 6e 76 6f 6b 65 20 77 61 6c 49 74 65 72 61 74  invoke walIterat
ec50: 6f 72 46 72 65 65 28 29 20 74 6f 20 64 65 73 74  orFree() to dest
ec60: 72 6f 79 20 74 68 65 0a 2a 2a 20 57 61 6c 49 74  roy the.** WalIt
ec70: 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 20 77 68  erator object wh
ec80: 65 6e 20 69 74 20 68 61 73 20 66 69 6e 69 73 68  en it has finish
ec90: 65 64 20 77 69 74 68 20 69 74 2e 0a 2a 2f 0a 73  ed with it..*/.s
eca0: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 74 65  tatic int walIte
ecb0: 72 61 74 6f 72 49 6e 69 74 28 57 61 6c 20 2a 70  ratorInit(Wal *p
ecc0: 57 61 6c 2c 20 57 61 6c 49 74 65 72 61 74 6f 72  Wal, WalIterator
ecd0: 20 2a 2a 70 70 29 7b 0a 20 20 57 61 6c 49 74 65   **pp){.  WalIte
ece0: 72 61 74 6f 72 20 2a 70 3b 20 20 20 20 20 20 20  rator *p;       
ecf0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
ed00: 75 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69  urn value */.  i
ed10: 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20 20  nt nSegment;    
ed20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
ed30: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 65 67 6d  * Number of segm
ed40: 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20 2a 2f  ents to merge */
ed50: 0a 20 20 75 33 32 20 69 4c 61 73 74 3b 20 20 20  .  u32 iLast;   
ed60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ed70: 20 20 20 2f 2a 20 4c 61 73 74 20 66 72 61 6d 65     /* Last frame
ed80: 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20 69 6e 74   in log */.  int
ed90: 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20   nByte;         
eda0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
edb0: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
edc0: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20  to allocate */. 
edd0: 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
ede0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
edf0: 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 76 61 72   /* Iterator var
ee00: 69 61 62 6c 65 20 2a 2f 0a 20 20 68 74 5f 73 6c  iable */.  ht_sl
ee10: 6f 74 20 2a 61 54 6d 70 3b 20 20 20 20 20 20 20  ot *aTmp;       
ee20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 65             /* Te
ee30: 6d 70 20 73 70 61 63 65 20 75 73 65 64 20 62 79  mp space used by
ee40: 20 6d 65 72 67 65 2d 73 6f 72 74 20 2a 2f 0a 20   merge-sort */. 
ee50: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
ee60: 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
ee70: 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20   /* Return Code 
ee80: 2a 2f 0a 0a 20 20 2f 2a 20 54 68 69 73 20 72 6f  */..  /* This ro
ee90: 75 74 69 6e 65 20 6f 6e 6c 79 20 72 75 6e 73 20  utine only runs 
eea0: 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67 20 74 68  while holding th
eeb0: 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 6c 6f 63  e checkpoint loc
eec0: 6b 2e 20 41 6e 64 0a 20 20 2a 2a 20 69 74 20 6f  k. And.  ** it o
eed0: 6e 6c 79 20 72 75 6e 73 20 69 66 20 74 68 65 72  nly runs if ther
eee0: 65 20 69 73 20 61 63 74 75 61 6c 6c 79 20 63 6f  e is actually co
eef0: 6e 74 65 6e 74 20 69 6e 20 74 68 65 20 6c 6f 67  ntent in the log
ef00: 20 28 6d 78 46 72 61 6d 65 3e 30 29 2e 0a 20 20   (mxFrame>0)..  
ef10: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  */.  assert( pWa
ef20: 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20 26 26 20 70  l->ckptLock && p
ef30: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
ef40: 3e 30 20 29 3b 0a 20 20 69 4c 61 73 74 20 3d 20  >0 );.  iLast = 
ef50: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
ef60: 65 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  e;..  /* Allocat
ef70: 65 20 73 70 61 63 65 20 66 6f 72 20 74 68 65 20  e space for the 
ef80: 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65  WalIterator obje
ef90: 63 74 2e 20 2a 2f 0a 20 20 6e 53 65 67 6d 65 6e  ct. */.  nSegmen
efa0: 74 20 3d 20 77 61 6c 46 72 61 6d 65 50 61 67 65  t = walFramePage
efb0: 28 69 4c 61 73 74 29 20 2b 20 31 3b 0a 20 20 6e  (iLast) + 1;.  n
efc0: 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 57 61  Byte = sizeof(Wa
efd0: 6c 49 74 65 72 61 74 6f 72 29 20 0a 20 20 20 20  lIterator) .    
efe0: 20 20 20 20 2b 20 28 6e 53 65 67 6d 65 6e 74 2d      + (nSegment-
eff0: 31 29 2a 73 69 7a 65 6f 66 28 73 74 72 75 63 74  1)*sizeof(struct
f000: 20 57 61 6c 53 65 67 6d 65 6e 74 29 0a 20 20 20   WalSegment).   
f010: 20 20 20 20 20 2b 20 69 4c 61 73 74 2a 73 69 7a       + iLast*siz
f020: 65 6f 66 28 68 74 5f 73 6c 6f 74 29 3b 0a 20 20  eof(ht_slot);.  
f030: 70 20 3d 20 28 57 61 6c 49 74 65 72 61 74 6f 72  p = (WalIterator
f040: 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   *)sqlite3_mallo
f050: 63 36 34 28 6e 42 79 74 65 29 3b 0a 20 20 69 66  c64(nByte);.  if
f060: 28 20 21 70 20 29 7b 0a 20 20 20 20 72 65 74 75  ( !p ){.    retu
f070: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f  rn SQLITE_NOMEM_
f080: 42 4b 50 54 3b 0a 20 20 7d 0a 20 20 6d 65 6d 73  BKPT;.  }.  mems
f090: 65 74 28 70 2c 20 30 2c 20 6e 42 79 74 65 29 3b  et(p, 0, nByte);
f0a0: 0a 20 20 70 2d 3e 6e 53 65 67 6d 65 6e 74 20 3d  .  p->nSegment =
f0b0: 20 6e 53 65 67 6d 65 6e 74 3b 0a 0a 20 20 2f 2a   nSegment;..  /*
f0c0: 20 41 6c 6c 6f 63 61 74 65 20 74 65 6d 70 6f 72   Allocate tempor
f0d0: 61 72 79 20 73 70 61 63 65 20 75 73 65 64 20 62  ary space used b
f0e0: 79 20 74 68 65 20 6d 65 72 67 65 2d 73 6f 72 74  y the merge-sort
f0f0: 20 72 6f 75 74 69 6e 65 2e 20 54 68 69 73 20 62   routine. This b
f100: 6c 6f 63 6b 0a 20 20 2a 2a 20 6f 66 20 6d 65 6d  lock.  ** of mem
f110: 6f 72 79 20 77 69 6c 6c 20 62 65 20 66 72 65 65  ory will be free
f120: 64 20 62 65 66 6f 72 65 20 74 68 69 73 20 66 75  d before this fu
f130: 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e 0a  nction returns..
f140: 20 20 2a 2f 0a 20 20 61 54 6d 70 20 3d 20 28 68    */.  aTmp = (h
f150: 74 5f 73 6c 6f 74 20 2a 29 73 71 6c 69 74 65 33  t_slot *)sqlite3
f160: 5f 6d 61 6c 6c 6f 63 36 34 28 0a 20 20 20 20 20  _malloc64(.     
f170: 20 73 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29   sizeof(ht_slot)
f180: 20 2a 20 28 69 4c 61 73 74 3e 48 41 53 48 54 41   * (iLast>HASHTA
f190: 42 4c 45 5f 4e 50 41 47 45 3f 48 41 53 48 54 41  BLE_NPAGE?HASHTA
f1a0: 42 4c 45 5f 4e 50 41 47 45 3a 69 4c 61 73 74 29  BLE_NPAGE:iLast)
f1b0: 0a 20 20 29 3b 0a 20 20 69 66 28 20 21 61 54 6d  .  );.  if( !aTm
f1c0: 70 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  p ){.    rc = SQ
f1d0: 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b  LITE_NOMEM_BKPT;
f1e0: 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69 3d 30 3b  .  }..  for(i=0;
f1f0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
f200: 26 20 69 3c 6e 53 65 67 6d 65 6e 74 3b 20 69 2b  & i<nSegment; i+
f210: 2b 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65  +){.    volatile
f220: 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b   ht_slot *aHash;
f230: 0a 20 20 20 20 75 33 32 20 69 5a 65 72 6f 3b 0a  .    u32 iZero;.
f240: 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32      volatile u32
f250: 20 2a 61 50 67 6e 6f 3b 0a 0a 20 20 20 20 72 63   *aPgno;..    rc
f260: 20 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70 57   = walHashGet(pW
f270: 61 6c 2c 20 69 2c 20 26 61 48 61 73 68 2c 20 26  al, i, &aHash, &
f280: 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a  aPgno, &iZero);.
f290: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
f2a0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69  TE_OK ){.      i
f2b0: 6e 74 20 6a 3b 20 20 20 20 20 20 20 20 20 20 20  nt j;           
f2c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
f2d0: 75 6e 74 65 72 20 76 61 72 69 61 62 6c 65 20 2a  unter variable *
f2e0: 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 45 6e 74  /.      int nEnt
f2f0: 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ry;             
f300: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
f310: 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 69 73   entries in this
f320: 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 20 20 20 20   segment */.    
f330: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 49 6e 64 65    ht_slot *aInde
f340: 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  x;            /*
f350: 20 53 6f 72 74 65 64 20 69 6e 64 65 78 20 66 6f   Sorted index fo
f360: 72 20 74 68 69 73 20 73 65 67 6d 65 6e 74 20 2a  r this segment *
f370: 2f 0a 0a 20 20 20 20 20 20 61 50 67 6e 6f 2b 2b  /..      aPgno++
f380: 3b 0a 20 20 20 20 20 20 69 66 28 20 28 69 2b 31  ;.      if( (i+1
f390: 29 3d 3d 6e 53 65 67 6d 65 6e 74 20 29 7b 0a 20  )==nSegment ){. 
f3a0: 20 20 20 20 20 20 20 6e 45 6e 74 72 79 20 3d 20         nEntry = 
f3b0: 28 69 6e 74 29 28 69 4c 61 73 74 20 2d 20 69 5a  (int)(iLast - iZ
f3c0: 65 72 6f 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  ero);.      }els
f3d0: 65 7b 0a 20 20 20 20 20 20 20 20 6e 45 6e 74 72  e{.        nEntr
f3e0: 79 20 3d 20 28 69 6e 74 29 28 28 75 33 32 2a 29  y = (int)((u32*)
f3f0: 61 48 61 73 68 20 2d 20 28 75 33 32 2a 29 61 50  aHash - (u32*)aP
f400: 67 6e 6f 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  gno);.      }.  
f410: 20 20 20 20 61 49 6e 64 65 78 20 3d 20 26 28 28      aIndex = &((
f420: 68 74 5f 73 6c 6f 74 20 2a 29 26 70 2d 3e 61 53  ht_slot *)&p->aS
f430: 65 67 6d 65 6e 74 5b 70 2d 3e 6e 53 65 67 6d 65  egment[p->nSegme
f440: 6e 74 5d 29 5b 69 5a 65 72 6f 5d 3b 0a 20 20 20  nt])[iZero];.   
f450: 20 20 20 69 5a 65 72 6f 2b 2b 3b 0a 20 20 0a 20     iZero++;.  . 
f460: 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c       for(j=0; j<
f470: 6e 45 6e 74 72 79 3b 20 6a 2b 2b 29 7b 0a 20 20  nEntry; j++){.  
f480: 20 20 20 20 20 20 61 49 6e 64 65 78 5b 6a 5d 20        aIndex[j] 
f490: 3d 20 28 68 74 5f 73 6c 6f 74 29 6a 3b 0a 20 20  = (ht_slot)j;.  
f4a0: 20 20 20 20 7d 0a 20 20 20 20 20 20 77 61 6c 4d      }.      walM
f4b0: 65 72 67 65 73 6f 72 74 28 28 75 33 32 20 2a 29  ergesort((u32 *)
f4c0: 61 50 67 6e 6f 2c 20 61 54 6d 70 2c 20 61 49 6e  aPgno, aTmp, aIn
f4d0: 64 65 78 2c 20 26 6e 45 6e 74 72 79 29 3b 0a 20  dex, &nEntry);. 
f4e0: 20 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74       p->aSegment
f4f0: 5b 69 5d 2e 69 5a 65 72 6f 20 3d 20 69 5a 65 72  [i].iZero = iZer
f500: 6f 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65 67  o;.      p->aSeg
f510: 6d 65 6e 74 5b 69 5d 2e 6e 45 6e 74 72 79 20 3d  ment[i].nEntry =
f520: 20 6e 45 6e 74 72 79 3b 0a 20 20 20 20 20 20 70   nEntry;.      p
f530: 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 61 49  ->aSegment[i].aI
f540: 6e 64 65 78 20 3d 20 61 49 6e 64 65 78 3b 0a 20  ndex = aIndex;. 
f550: 20 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74       p->aSegment
f560: 5b 69 5d 2e 61 50 67 6e 6f 20 3d 20 28 75 33 32  [i].aPgno = (u32
f570: 20 2a 29 61 50 67 6e 6f 3b 0a 20 20 20 20 7d 0a   *)aPgno;.    }.
f580: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72    }.  sqlite3_fr
f590: 65 65 28 61 54 6d 70 29 3b 0a 0a 20 20 69 66 28  ee(aTmp);..  if(
f5a0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
f5b0: 7b 0a 20 20 20 20 77 61 6c 49 74 65 72 61 74 6f  {.    walIterato
f5c0: 72 46 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20  rFree(p);.  }.  
f5d0: 2a 70 70 20 3d 20 70 3b 0a 20 20 72 65 74 75 72  *pp = p;.  retur
f5e0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  n rc;.}../*.** A
f5f0: 74 74 65 6d 70 74 20 74 6f 20 6f 62 74 61 69 6e  ttempt to obtain
f600: 20 74 68 65 20 65 78 63 6c 75 73 69 76 65 20 57   the exclusive W
f610: 41 4c 20 6c 6f 63 6b 20 64 65 66 69 6e 65 64 20  AL lock defined 
f620: 62 79 20 70 61 72 61 6d 65 74 65 72 73 20 6c 6f  by parameters lo
f630: 63 6b 49 64 78 20 61 6e 64 0a 2a 2a 20 6e 2e 20  ckIdx and.** n. 
f640: 49 66 20 74 68 65 20 61 74 74 65 6d 70 74 20 66  If the attempt f
f650: 61 69 6c 73 20 61 6e 64 20 70 61 72 61 6d 65 74  ails and paramet
f660: 65 72 20 78 42 75 73 79 20 69 73 20 6e 6f 74 20  er xBusy is not 
f670: 4e 55 4c 4c 2c 20 74 68 65 6e 20 69 74 20 69 73  NULL, then it is
f680: 20 61 0a 2a 2a 20 62 75 73 79 2d 68 61 6e 64 6c   a.** busy-handl
f690: 65 72 20 66 75 6e 63 74 69 6f 6e 2e 20 49 6e 76  er function. Inv
f6a0: 6f 6b 65 20 69 74 20 61 6e 64 20 72 65 74 72 79  oke it and retry
f6b0: 20 74 68 65 20 6c 6f 63 6b 20 75 6e 74 69 6c 20   the lock until 
f6c0: 65 69 74 68 65 72 20 74 68 65 0a 2a 2a 20 6c 6f  either the.** lo
f6d0: 63 6b 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  ck is successful
f6e0: 6c 79 20 6f 62 74 61 69 6e 65 64 20 6f 72 20 74  ly obtained or t
f6f0: 68 65 20 62 75 73 79 2d 68 61 6e 64 6c 65 72 20  he busy-handler 
f700: 72 65 74 75 72 6e 73 20 30 2e 0a 2a 2f 0a 73 74  returns 0..*/.st
f710: 61 74 69 63 20 69 6e 74 20 77 61 6c 42 75 73 79  atic int walBusy
f720: 4c 6f 63 6b 28 0a 20 20 57 61 6c 20 2a 70 57 61  Lock(.  Wal *pWa
f730: 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
f740: 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 63          /* WAL c
f750: 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 69  onnection */.  i
f760: 6e 74 20 28 2a 78 42 75 73 79 29 28 76 6f 69 64  nt (*xBusy)(void
f770: 2a 29 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  *),            /
f780: 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63 61  * Function to ca
f790: 6c 6c 20 77 68 65 6e 20 62 75 73 79 20 2a 2f 0a  ll when busy */.
f7a0: 20 20 76 6f 69 64 20 2a 70 42 75 73 79 41 72 67    void *pBusyArg
f7b0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
f7c0: 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 61 72 67    /* Context arg
f7d0: 75 6d 65 6e 74 20 66 6f 72 20 78 42 75 73 79 48  ument for xBusyH
f7e0: 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74 20  andler */.  int 
f7f0: 6c 6f 63 6b 49 64 78 2c 20 20 20 20 20 20 20 20  lockIdx,        
f800: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
f810: 66 66 73 65 74 20 6f 66 20 66 69 72 73 74 20 62  ffset of first b
f820: 79 74 65 20 74 6f 20 6c 6f 63 6b 20 2a 2f 0a 20  yte to lock */. 
f830: 20 69 6e 74 20 6e 20 20 20 20 20 20 20 20 20 20   int n          
f840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f850: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
f860: 74 65 73 20 74 6f 20 6c 6f 63 6b 20 2a 2f 0a 29  tes to lock */.)
f870: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 64 6f  {.  int rc;.  do
f880: 20 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 4c   {.    rc = walL
f890: 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
f8a0: 6c 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 29 3b 0a  l, lockIdx, n);.
f8b0: 20 20 7d 77 68 69 6c 65 28 20 78 42 75 73 79 20    }while( xBusy 
f8c0: 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  && rc==SQLITE_BU
f8d0: 53 59 20 26 26 20 78 42 75 73 79 28 70 42 75 73  SY && xBusy(pBus
f8e0: 79 41 72 67 29 20 29 3b 0a 20 20 72 65 74 75 72  yArg) );.  retur
f8f0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  n rc;.}../*.** T
f900: 68 65 20 63 61 63 68 65 20 6f 66 20 74 68 65 20  he cache of the 
f910: 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
f920: 20 6d 75 73 74 20 62 65 20 76 61 6c 69 64 20 74   must be valid t
f930: 6f 20 63 61 6c 6c 20 74 68 69 73 20 66 75 6e 63  o call this func
f940: 74 69 6f 6e 2e 0a 2a 2a 20 52 65 74 75 72 6e 20  tion..** Return 
f950: 74 68 65 20 70 61 67 65 2d 73 69 7a 65 20 69 6e  the page-size in
f960: 20 62 79 74 65 73 20 75 73 65 64 20 62 79 20 74   bytes used by t
f970: 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2f 0a  he database..*/.
f980: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 50 61  static int walPa
f990: 67 65 73 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c  gesize(Wal *pWal
f9a0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 70 57 61  ){.  return (pWa
f9b0: 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26 30 78  l->hdr.szPage&0x
f9c0: 66 65 30 30 29 20 2b 20 28 28 70 57 61 6c 2d 3e  fe00) + ((pWal->
f9d0: 68 64 72 2e 73 7a 50 61 67 65 26 30 78 30 30 30  hdr.szPage&0x000
f9e0: 31 29 3c 3c 31 36 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  1)<<16);.}../*.*
f9f0: 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  * The following 
fa00: 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 77 68  is guaranteed wh
fa10: 65 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  en this function
fa20: 20 69 73 20 63 61 6c 6c 65 64 3a 0a 2a 2a 0a 2a   is called:.**.*
fa30: 2a 20 20 20 61 29 20 74 68 65 20 57 52 49 54 45  *   a) the WRITE
fa40: 52 20 6c 6f 63 6b 20 69 73 20 68 65 6c 64 2c 0a  R lock is held,.
fa50: 2a 2a 20 20 20 62 29 20 74 68 65 20 65 6e 74 69  **   b) the enti
fa60: 72 65 20 6c 6f 67 20 66 69 6c 65 20 68 61 73 20  re log file has 
fa70: 62 65 65 6e 20 63 68 65 63 6b 70 6f 69 6e 74 65  been checkpointe
fa80: 64 2c 20 61 6e 64 0a 2a 2a 20 20 20 63 29 20 61  d, and.**   c) a
fa90: 6e 79 20 65 78 69 73 74 69 6e 67 20 72 65 61 64  ny existing read
faa0: 65 72 73 20 61 72 65 20 72 65 61 64 69 6e 67 20  ers are reading 
fab0: 65 78 63 6c 75 73 69 76 65 6c 79 20 66 72 6f 6d  exclusively from
fac0: 20 74 68 65 20 64 61 74 61 62 61 73 65 0a 2a 2a   the database.**
fad0: 20 20 20 20 20 20 66 69 6c 65 20 2d 20 74 68 65        file - the
fae0: 72 65 20 61 72 65 20 6e 6f 20 72 65 61 64 65 72  re are no reader
faf0: 73 20 74 68 61 74 20 6d 61 79 20 61 74 74 65 6d  s that may attem
fb00: 70 74 20 74 6f 20 72 65 61 64 20 61 20 66 72 61  pt to read a fra
fb10: 6d 65 20 66 72 6f 6d 0a 2a 2a 20 20 20 20 20 20  me from.**      
fb20: 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 0a 2a 2a  the log file..**
fb30: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
fb40: 6e 20 75 70 64 61 74 65 73 20 74 68 65 20 73 68  n updates the sh
fb50: 61 72 65 64 2d 6d 65 6d 6f 72 79 20 73 74 72 75  ared-memory stru
fb60: 63 74 75 72 65 73 20 73 6f 20 74 68 61 74 20 74  ctures so that t
fb70: 68 65 20 6e 65 78 74 0a 2a 2a 20 63 6c 69 65 6e  he next.** clien
fb80: 74 20 74 6f 20 77 72 69 74 65 20 74 6f 20 74 68  t to write to th
fb90: 65 20 64 61 74 61 62 61 73 65 20 28 77 68 69 63  e database (whic
fba0: 68 20 6d 61 79 20 62 65 20 74 68 69 73 20 6f 6e  h may be this on
fbb0: 65 29 20 64 6f 65 73 20 73 6f 20 62 79 0a 2a 2a  e) does so by.**
fbc0: 20 77 72 69 74 69 6e 67 20 66 72 61 6d 65 73 20   writing frames 
fbd0: 69 6e 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f  into the start o
fbe0: 66 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 0a  f the log file..
fbf0: 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c 75 65 20  **.** The value 
fc00: 6f 66 20 70 61 72 61 6d 65 74 65 72 20 73 61 6c  of parameter sal
fc10: 74 31 20 69 73 20 75 73 65 64 20 61 73 20 74 68  t1 is used as th
fc20: 65 20 61 53 61 6c 74 5b 31 5d 20 76 61 6c 75 65  e aSalt[1] value
fc30: 20 69 6e 20 74 68 65 20 0a 2a 2a 20 6e 65 77 20   in the .** new 
fc40: 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
fc50: 2e 20 49 74 20 73 68 6f 75 6c 64 20 62 65 20 70  . It should be p
fc60: 61 73 73 65 64 20 61 20 70 73 65 75 64 6f 2d 72  assed a pseudo-r
fc70: 61 6e 64 6f 6d 20 76 61 6c 75 65 20 28 69 2e 65  andom value (i.e
fc80: 2e 20 0a 2a 2a 20 6f 6e 65 20 6f 62 74 61 69 6e  . .** one obtain
fc90: 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 5f  ed from sqlite3_
fca0: 72 61 6e 64 6f 6d 6e 65 73 73 28 29 29 2e 0a 2a  randomness())..*
fcb0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61  /.static void wa
fcc0: 6c 52 65 73 74 61 72 74 48 64 72 28 57 61 6c 20  lRestartHdr(Wal 
fcd0: 2a 70 57 61 6c 2c 20 75 33 32 20 73 61 6c 74 31  *pWal, u32 salt1
fce0: 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57 61  ){.  volatile Wa
fcf0: 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f  lCkptInfo *pInfo
fd00: 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f 28 70   = walCkptInfo(p
fd10: 57 61 6c 29 3b 0a 20 20 69 6e 74 20 69 3b 20 20  Wal);.  int i;  
fd20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fd30: 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20          /* Loop 
fd40: 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 75 33 32  counter */.  u32
fd50: 20 2a 61 53 61 6c 74 20 3d 20 70 57 61 6c 2d 3e   *aSalt = pWal->
fd60: 68 64 72 2e 61 53 61 6c 74 3b 20 20 20 2f 2a 20  hdr.aSalt;   /* 
fd70: 42 69 67 2d 65 6e 64 69 61 6e 20 73 61 6c 74 20  Big-endian salt 
fd80: 76 61 6c 75 65 73 20 2a 2f 0a 20 20 70 57 61 6c  values */.  pWal
fd90: 2d 3e 6e 43 6b 70 74 2b 2b 3b 0a 20 20 70 57 61  ->nCkpt++;.  pWa
fda0: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d  l->hdr.mxFrame =
fdb0: 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74   0;.  sqlite3Put
fdc0: 34 62 79 74 65 28 28 75 38 2a 29 26 61 53 61 6c  4byte((u8*)&aSal
fdd0: 74 5b 30 5d 2c 20 31 20 2b 20 73 71 6c 69 74 65  t[0], 1 + sqlite
fde0: 33 47 65 74 34 62 79 74 65 28 28 75 38 2a 29 26  3Get4byte((u8*)&
fdf0: 61 53 61 6c 74 5b 30 5d 29 29 3b 0a 20 20 6d 65  aSalt[0]));.  me
fe00: 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2e  mcpy(&pWal->hdr.
fe10: 61 53 61 6c 74 5b 31 5d 2c 20 26 73 61 6c 74 31  aSalt[1], &salt1
fe20: 2c 20 34 29 3b 0a 20 20 77 61 6c 49 6e 64 65 78  , 4);.  walIndex
fe30: 57 72 69 74 65 48 64 72 28 70 57 61 6c 29 3b 0a  WriteHdr(pWal);.
fe40: 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69    pInfo->nBackfi
fe50: 6c 6c 20 3d 20 30 3b 0a 20 20 70 49 6e 66 6f 2d  ll = 0;.  pInfo-
fe60: 3e 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70  >nBackfillAttemp
fe70: 74 65 64 20 3d 20 30 3b 0a 20 20 70 49 6e 66 6f  ted = 0;.  pInfo
fe80: 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 31 5d 20 3d  ->aReadMark[1] =
fe90: 20 30 3b 0a 20 20 66 6f 72 28 69 3d 32 3b 20 69   0;.  for(i=2; i
fea0: 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b  <WAL_NREADER; i+
feb0: 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d  +) pInfo->aReadM
fec0: 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41 52  ark[i] = READMAR
fed0: 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 61 73  K_NOT_USED;.  as
fee0: 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e 61 52 65  sert( pInfo->aRe
fef0: 61 64 4d 61 72 6b 5b 30 5d 3d 3d 30 20 29 3b 0a  adMark[0]==0 );.
ff00: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 61 73  }../*.** Copy as
ff10: 20 6d 75 63 68 20 63 6f 6e 74 65 6e 74 20 61 73   much content as
ff20: 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 74 68 65   we can from the
ff30: 20 57 41 4c 20 62 61 63 6b 20 69 6e 74 6f 20 74   WAL back into t
ff40: 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
ff50: 0a 2a 2a 20 69 6e 20 72 65 73 70 6f 6e 73 65 20  .** in response 
ff60: 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f 77 61  to an sqlite3_wa
ff70: 6c 5f 63 68 65 63 6b 70 6f 69 6e 74 28 29 20 72  l_checkpoint() r
ff80: 65 71 75 65 73 74 20 6f 72 20 74 68 65 20 65 71  equest or the eq
ff90: 75 69 76 61 6c 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20  uivalent..**.** 
ffa0: 54 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20 69 6e  The amount of in
ffb0: 66 6f 72 6d 61 74 69 6f 6e 20 63 6f 70 69 65 73  formation copies
ffc0: 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64 61 74   from WAL to dat
ffd0: 61 62 61 73 65 20 6d 69 67 68 74 20 62 65 20 6c  abase might be l
ffe0: 69 6d 69 74 65 64 0a 2a 2a 20 62 79 20 61 63 74  imited.** by act
fff0: 69 76 65 20 72 65 61 64 65 72 73 2e 20 20 54 68  ive readers.  Th
10000 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20  is routine will 
10010 6e 65 76 65 72 20 6f 76 65 72 77 72 69 74 65 20  never overwrite 
10020 61 20 64 61 74 61 62 61 73 65 20 70 61 67 65 0a  a database page.
10030 2a 2a 20 74 68 61 74 20 61 20 63 6f 6e 63 75 72  ** that a concur
10040 72 65 6e 74 20 72 65 61 64 65 72 20 6d 69 67 68  rent reader migh
10050 74 20 62 65 20 75 73 69 6e 67 2e 0a 2a 2a 0a 2a  t be using..**.*
10060 2a 20 41 6c 6c 20 49 2f 4f 20 62 61 72 72 69 65  * All I/O barrie
10070 72 20 6f 70 65 72 61 74 69 6f 6e 73 20 28 61 2e  r operations (a.
10080 6b 2e 61 20 66 73 79 6e 63 73 29 20 6f 63 63 75  k.a fsyncs) occu
10090 72 20 69 6e 20 74 68 69 73 20 72 6f 75 74 69 6e  r in this routin
100a0 65 20 77 68 65 6e 0a 2a 2a 20 53 51 4c 69 74 65  e when.** SQLite
100b0 20 69 73 20 69 6e 20 57 41 4c 2d 6d 6f 64 65 20   is in WAL-mode 
100c0 69 6e 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 4e  in synchronous=N
100d0 4f 52 4d 41 4c 2e 20 20 54 68 61 74 20 6d 65 61  ORMAL.  That mea
100e0 6e 73 20 74 68 61 74 20 69 66 20 0a 2a 2a 20 63  ns that if .** c
100f0 68 65 63 6b 70 6f 69 6e 74 73 20 61 72 65 20 61  heckpoints are a
10100 6c 77 61 79 73 20 72 75 6e 20 62 79 20 61 20 62  lways run by a b
10110 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64  ackground thread
10120 20 6f 72 20 62 61 63 6b 67 72 6f 75 6e 64 20 0a   or background .
10130 2a 2a 20 70 72 6f 63 65 73 73 2c 20 66 6f 72 65  ** process, fore
10140 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20 77  ground threads w
10150 69 6c 6c 20 6e 65 76 65 72 20 62 6c 6f 63 6b 20  ill never block 
10160 6f 6e 20 61 20 6c 65 6e 67 74 68 79 20 66 73 79  on a lengthy fsy
10170 6e 63 20 63 61 6c 6c 2e 0a 2a 2a 0a 2a 2a 20 46  nc call..**.** F
10180 73 79 6e 63 20 69 73 20 63 61 6c 6c 65 64 20 6f  sync is called o
10190 6e 20 74 68 65 20 57 41 4c 20 62 65 66 6f 72 65  n the WAL before
101a0 20 77 72 69 74 69 6e 67 20 63 6f 6e 74 65 6e 74   writing content
101b0 20 6f 75 74 20 6f 66 20 74 68 65 20 57 41 4c 20   out of the WAL 
101c0 61 6e 64 0a 2a 2a 20 69 6e 74 6f 20 74 68 65 20  and.** into the 
101d0 64 61 74 61 62 61 73 65 2e 20 20 54 68 69 73 20  database.  This 
101e0 65 6e 73 75 72 65 73 20 74 68 61 74 20 69 66 20  ensures that if 
101f0 74 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20  the new content 
10200 69 73 20 70 65 72 73 69 73 74 65 6e 74 0a 2a 2a  is persistent.**
10210 20 69 6e 20 74 68 65 20 57 41 4c 20 61 6e 64 20   in the WAL and 
10220 63 61 6e 20 62 65 20 72 65 63 6f 76 65 72 65 64  can be recovered
10230 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 70 6f 77   following a pow
10240 65 72 2d 6c 6f 73 73 20 6f 72 20 68 61 72 64 20  er-loss or hard 
10250 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 46 73 79  reset..**.** Fsy
10260 6e 63 20 69 73 20 61 6c 73 6f 20 63 61 6c 6c 65  nc is also calle
10270 64 20 6f 6e 20 74 68 65 20 64 61 74 61 62 61 73  d on the databas
10280 65 20 66 69 6c 65 20 69 66 20 28 61 6e 64 20 6f  e file if (and o
10290 6e 6c 79 20 69 66 29 20 74 68 65 20 65 6e 74 69  nly if) the enti
102a0 72 65 0a 2a 2a 20 57 41 4c 20 63 6f 6e 74 65 6e  re.** WAL conten
102b0 74 20 69 73 20 63 6f 70 69 65 64 20 69 6e 74 6f  t is copied into
102c0 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
102d0 6c 65 2e 20 20 54 68 69 73 20 73 65 63 6f 6e 64  le.  This second
102e0 20 66 73 79 6e 63 20 6d 61 6b 65 73 0a 2a 2a 20   fsync makes.** 
102f0 69 74 20 73 61 66 65 20 74 6f 20 64 65 6c 65 74  it safe to delet
10300 65 20 74 68 65 20 57 41 4c 20 73 69 6e 63 65 20  e the WAL since 
10310 74 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20  the new content 
10320 77 69 6c 6c 20 70 65 72 73 69 73 74 20 69 6e 20  will persist in 
10330 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20  the.** database 
10340 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  file..**.** This
10350 20 72 6f 75 74 69 6e 65 20 75 73 65 73 20 61 6e   routine uses an
10360 64 20 75 70 64 61 74 65 73 20 74 68 65 20 6e 42  d updates the nB
10370 61 63 6b 66 69 6c 6c 20 66 69 65 6c 64 20 6f 66  ackfill field of
10380 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
10390 65 61 64 65 72 2e 0a 2a 2a 20 54 68 69 73 20 69  eader..** This i
103a0 73 20 74 68 65 20 6f 6e 6c 79 20 72 6f 75 74 69  s the only routi
103b0 6e 65 20 74 68 61 74 20 77 69 6c 6c 20 69 6e 63  ne that will inc
103c0 72 65 61 73 65 20 74 68 65 20 76 61 6c 75 65 20  rease the value 
103d0 6f 66 20 6e 42 61 63 6b 66 69 6c 6c 2e 20 20 0a  of nBackfill.  .
103e0 2a 2a 20 28 41 20 57 41 4c 20 72 65 73 65 74 20  ** (A WAL reset 
103f0 6f 72 20 72 65 63 6f 76 65 72 79 20 77 69 6c 6c  or recovery will
10400 20 72 65 76 65 72 74 20 6e 42 61 63 6b 66 69 6c   revert nBackfil
10410 6c 20 74 6f 20 7a 65 72 6f 2c 20 62 75 74 20 6e  l to zero, but n
10420 6f 74 20 69 6e 63 72 65 61 73 65 0a 2a 2a 20 69  ot increase.** i
10430 74 73 20 76 61 6c 75 65 2e 29 0a 2a 2a 0a 2a 2a  ts value.).**.**
10440 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74   The caller must
10450 20 62 65 20 68 6f 6c 64 69 6e 67 20 73 75 66 66   be holding suff
10460 69 63 69 65 6e 74 20 6c 6f 63 6b 73 20 74 6f 20  icient locks to 
10470 65 6e 73 75 72 65 20 74 68 61 74 20 6e 6f 20 6f  ensure that no o
10480 74 68 65 72 0a 2a 2a 20 63 68 65 63 6b 70 6f 69  ther.** checkpoi
10490 6e 74 20 69 73 20 72 75 6e 6e 69 6e 67 20 28 69  nt is running (i
104a0 6e 20 61 6e 79 20 6f 74 68 65 72 20 74 68 72 65  n any other thre
104b0 61 64 20 6f 72 20 70 72 6f 63 65 73 73 29 20 61  ad or process) a
104c0 74 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20 74 69  t the same.** ti
104d0 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  me..*/.static in
104e0 74 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28  t walCheckpoint(
104f0 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20  .  Wal *pWal,   
10500 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10510 20 20 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65 63     /* Wal connec
10520 74 69 6f 6e 20 2a 2f 0a 20 20 73 71 6c 69 74 65  tion */.  sqlite
10530 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20  3 *db,          
10540 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65            /* Che
10550 63 6b 20 66 6f 72 20 69 6e 74 65 72 72 75 70 74  ck for interrupt
10560 73 20 6f 6e 20 74 68 69 73 20 68 61 6e 64 6c 65  s on this handle
10570 20 2a 2f 0a 20 20 69 6e 74 20 65 4d 6f 64 65 2c   */.  int eMode,
10580 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10590 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 66 20        /* One of 
105a0 50 41 53 53 49 56 45 2c 20 46 55 4c 4c 20 6f 72  PASSIVE, FULL or
105b0 20 52 45 53 54 41 52 54 20 2a 2f 0a 20 20 69 6e   RESTART */.  in
105c0 74 20 28 2a 78 42 75 73 79 29 28 76 6f 69 64 2a  t (*xBusy)(void*
105d0 29 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ),            /*
105e0 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63 61 6c   Function to cal
105f0 6c 20 77 68 65 6e 20 62 75 73 79 20 2a 2f 0a 20  l when busy */. 
10600 20 76 6f 69 64 20 2a 70 42 75 73 79 41 72 67 2c   void *pBusyArg,
10610 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10620 20 2f 2a 20 43 6f 6e 74 65 78 74 20 61 72 67 75   /* Context argu
10630 6d 65 6e 74 20 66 6f 72 20 78 42 75 73 79 48 61  ment for xBusyHa
10640 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74 20 73  ndler */.  int s
10650 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20  ync_flags,      
10660 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c             /* Fl
10670 61 67 73 20 66 6f 72 20 4f 73 53 79 6e 63 28 29  ags for OsSync()
10680 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20 75 38 20   (or 0) */.  u8 
10690 2a 7a 42 75 66 20 20 20 20 20 20 20 20 20 20 20  *zBuf           
106a0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
106b0 54 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72  Temporary buffer
106c0 20 74 6f 20 75 73 65 20 2a 2f 0a 29 7b 0a 20 20   to use */.){.  
106d0 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
106e0 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
106f0 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
10700 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 3b 20  /.  int szPage; 
10710 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10720 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
10730 70 61 67 65 2d 73 69 7a 65 20 2a 2f 0a 20 20 57  page-size */.  W
10740 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 49 74 65  alIterator *pIte
10750 72 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 2f  r = 0;         /
10760 2a 20 57 61 6c 20 69 74 65 72 61 74 6f 72 20 63  * Wal iterator c
10770 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 75 33 32 20  ontext */.  u32 
10780 69 44 62 70 61 67 65 20 3d 20 30 3b 20 20 20 20  iDbpage = 0;    
10790 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
107a0 65 78 74 20 64 61 74 61 62 61 73 65 20 70 61 67  ext database pag
107b0 65 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20  e to write */.  
107c0 75 33 32 20 69 46 72 61 6d 65 20 3d 20 30 3b 20  u32 iFrame = 0; 
107d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
107e0 2f 2a 20 57 61 6c 20 66 72 61 6d 65 20 63 6f 6e  /* Wal frame con
107f0 74 61 69 6e 69 6e 67 20 64 61 74 61 20 66 6f 72  taining data for
10800 20 69 44 62 70 61 67 65 20 2a 2f 0a 20 20 75 33   iDbpage */.  u3
10810 32 20 6d 78 53 61 66 65 46 72 61 6d 65 3b 20 20  2 mxSafeFrame;  
10820 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
10830 20 4d 61 78 20 66 72 61 6d 65 20 74 68 61 74 20   Max frame that 
10840 63 61 6e 20 62 65 20 62 61 63 6b 66 69 6c 6c 65  can be backfille
10850 64 20 2a 2f 0a 20 20 75 33 32 20 6d 78 50 61 67  d */.  u32 mxPag
10860 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
10870 20 20 20 20 20 20 20 2f 2a 20 4d 61 78 20 64 61         /* Max da
10880 74 61 62 61 73 65 20 70 61 67 65 20 74 6f 20 77  tabase page to w
10890 72 69 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b  rite */.  int i;
108a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
108b0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f            /* Loo
108c0 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 76  p counter */.  v
108d0 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49  olatile WalCkptI
108e0 6e 66 6f 20 2a 70 49 6e 66 6f 3b 20 20 20 20 2f  nfo *pInfo;    /
108f0 2a 20 54 68 65 20 63 68 65 63 6b 70 6f 69 6e 74  * The checkpoint
10900 20 73 74 61 74 75 73 20 69 6e 66 6f 72 6d 61 74   status informat
10910 69 6f 6e 20 2a 2f 0a 0a 20 20 73 7a 50 61 67 65  ion */..  szPage
10920 20 3d 20 77 61 6c 50 61 67 65 73 69 7a 65 28 70   = walPagesize(p
10930 57 61 6c 29 3b 0a 20 20 74 65 73 74 63 61 73 65  Wal);.  testcase
10940 28 20 73 7a 50 61 67 65 3c 3d 33 32 37 36 38 20  ( szPage<=32768 
10950 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 73  );.  testcase( s
10960 7a 50 61 67 65 3e 3d 36 35 35 33 36 20 29 3b 0a  zPage>=65536 );.
10970 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70    pInfo = walCkp
10980 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 69  tInfo(pWal);.  i
10990 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66  f( pInfo->nBackf
109a0 69 6c 6c 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  ill<pWal->hdr.mx
109b0 46 72 61 6d 65 20 29 7b 0a 0a 20 20 20 20 2f 2a  Frame ){..    /*
109c0 20 41 6c 6c 6f 63 61 74 65 20 74 68 65 20 69 74   Allocate the it
109d0 65 72 61 74 6f 72 20 2a 2f 0a 20 20 20 20 72 63  erator */.    rc
109e0 20 3d 20 77 61 6c 49 74 65 72 61 74 6f 72 49 6e   = walIteratorIn
109f0 69 74 28 70 57 61 6c 2c 20 26 70 49 74 65 72 29  it(pWal, &pIter)
10a00 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
10a10 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
10a20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
10a30 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 49  }.    assert( pI
10a40 74 65 72 20 29 3b 0a 0a 20 20 20 20 2f 2a 20 45  ter );..    /* E
10a50 56 49 44 45 4e 43 45 2d 4f 46 3a 20 52 2d 36 32  VIDENCE-OF: R-62
10a60 39 32 30 2d 34 37 34 35 30 20 54 68 65 20 62 75  920-47450 The bu
10a70 73 79 2d 68 61 6e 64 6c 65 72 20 63 61 6c 6c 62  sy-handler callb
10a80 61 63 6b 20 69 73 20 6e 65 76 65 72 20 69 6e 76  ack is never inv
10a90 6f 6b 65 64 0a 20 20 20 20 2a 2a 20 69 6e 20 74  oked.    ** in t
10aa0 68 65 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 50  he SQLITE_CHECKP
10ab0 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 6d 6f 64  OINT_PASSIVE mod
10ac0 65 2e 20 2a 2f 0a 20 20 20 20 61 73 73 65 72 74  e. */.    assert
10ad0 28 20 65 4d 6f 64 65 21 3d 53 51 4c 49 54 45 5f  ( eMode!=SQLITE_
10ae0 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49  CHECKPOINT_PASSI
10af0 56 45 20 7c 7c 20 78 42 75 73 79 3d 3d 30 20 29  VE || xBusy==0 )
10b00 3b 0a 0a 20 20 20 20 2f 2a 20 43 6f 6d 70 75 74  ;..    /* Comput
10b10 65 20 69 6e 20 6d 78 53 61 66 65 46 72 61 6d 65  e in mxSafeFrame
10b20 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68   the index of th
10b30 65 20 6c 61 73 74 20 66 72 61 6d 65 20 6f 66 20  e last frame of 
10b40 74 68 65 20 57 41 4c 20 74 68 61 74 20 69 73 0a  the WAL that is.
10b50 20 20 20 20 2a 2a 20 73 61 66 65 20 74 6f 20 77      ** safe to w
10b60 72 69 74 65 20 69 6e 74 6f 20 74 68 65 20 64 61  rite into the da
10b70 74 61 62 61 73 65 2e 20 20 46 72 61 6d 65 73 20  tabase.  Frames 
10b80 62 65 79 6f 6e 64 20 6d 78 53 61 66 65 46 72 61  beyond mxSafeFra
10b90 6d 65 20 6d 69 67 68 74 0a 20 20 20 20 2a 2a 20  me might.    ** 
10ba0 6f 76 65 72 77 72 69 74 65 20 64 61 74 61 62 61  overwrite databa
10bb0 73 65 20 70 61 67 65 73 20 74 68 61 74 20 61 72  se pages that ar
10bc0 65 20 69 6e 20 75 73 65 20 62 79 20 61 63 74 69  e in use by acti
10bd0 76 65 20 72 65 61 64 65 72 73 20 61 6e 64 20 74  ve readers and t
10be0 68 75 73 0a 20 20 20 20 2a 2a 20 63 61 6e 6e 6f  hus.    ** canno
10bf0 74 20 62 65 20 62 61 63 6b 66 69 6c 6c 65 64 20  t be backfilled 
10c00 66 72 6f 6d 20 74 68 65 20 57 41 4c 2e 0a 20 20  from the WAL..  
10c10 20 20 2a 2f 0a 20 20 20 20 6d 78 53 61 66 65 46    */.    mxSafeF
10c20 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72  rame = pWal->hdr
10c30 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 6d 78  .mxFrame;.    mx
10c40 50 61 67 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72  Page = pWal->hdr
10c50 2e 6e 50 61 67 65 3b 0a 20 20 20 20 66 6f 72 28  .nPage;.    for(
10c60 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44  i=1; i<WAL_NREAD
10c70 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ER; i++){.      
10c80 2f 2a 20 54 68 72 65 61 64 2d 73 61 6e 69 74 69  /* Thread-saniti
10c90 7a 65 72 20 72 65 70 6f 72 74 73 20 74 68 61 74  zer reports that
10ca0 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69   the following i
10cb0 73 20 61 6e 20 75 6e 73 61 66 65 20 72 65 61 64  s an unsafe read
10cc0 2c 0a 20 20 20 20 20 20 2a 2a 20 61 73 20 73 6f  ,.      ** as so
10cd0 6d 65 20 6f 74 68 65 72 20 74 68 72 65 61 64 20  me other thread 
10ce0 6d 61 79 20 62 65 20 69 6e 20 74 68 65 20 70 72  may be in the pr
10cf0 6f 63 65 73 73 20 6f 66 20 75 70 64 61 74 69 6e  ocess of updatin
10d00 67 20 74 68 65 20 76 61 6c 75 65 0a 20 20 20 20  g the value.    
10d10 20 20 2a 2a 20 6f 66 20 74 68 65 20 61 52 65 61    ** of the aRea
10d20 64 4d 61 72 6b 5b 5d 20 73 6c 6f 74 2e 20 54 68  dMark[] slot. Th
10d30 65 20 61 73 73 75 6d 70 74 69 6f 6e 20 68 65 72  e assumption her
10d40 65 20 69 73 20 74 68 61 74 20 69 66 20 74 68 61  e is that if tha
10d50 74 20 69 73 0a 20 20 20 20 20 20 2a 2a 20 68 61  t is.      ** ha
10d60 70 70 65 6e 69 6e 67 2c 20 74 68 65 20 6f 74 68  ppening, the oth
10d70 65 72 20 63 6c 69 65 6e 74 20 6d 61 79 20 6f 6e  er client may on
10d80 6c 79 20 62 65 20 69 6e 63 72 65 61 73 69 6e 67  ly be increasing
10d90 20 74 68 65 20 76 61 6c 75 65 2c 0a 20 20 20 20   the value,.    
10da0 20 20 2a 2a 20 6e 6f 74 20 64 65 63 72 65 61 73    ** not decreas
10db0 69 6e 67 20 69 74 2e 20 53 6f 20 61 73 73 75 6d  ing it. So assum
10dc0 69 6e 67 20 65 69 74 68 65 72 20 74 68 61 74 20  ing either that 
10dd0 65 69 74 68 65 72 20 74 68 65 20 22 6f 6c 64 22  either the "old"
10de0 20 6f 72 0a 20 20 20 20 20 20 2a 2a 20 22 6e 65   or.      ** "ne
10df0 77 22 20 76 65 72 73 69 6f 6e 20 6f 66 20 74 68  w" version of th
10e00 65 20 76 61 6c 75 65 20 69 73 20 72 65 61 64 2c  e value is read,
10e10 20 61 6e 64 20 6e 6f 74 20 73 6f 6d 65 20 61 72   and not some ar
10e20 62 69 74 72 61 72 79 20 76 61 6c 75 65 0a 20 20  bitrary value.  
10e30 20 20 20 20 2a 2a 20 74 68 61 74 20 77 6f 75 6c      ** that woul
10e40 64 20 6e 65 76 65 72 20 62 65 20 77 72 69 74 74  d never be writt
10e50 65 6e 20 62 79 20 61 20 72 65 61 6c 20 63 6c 69  en by a real cli
10e60 65 6e 74 2c 20 74 68 69 6e 67 73 20 61 72 65 20  ent, things are 
10e70 73 74 69 6c 6c 20 0a 20 20 20 20 20 20 2a 2a 20  still .      ** 
10e80 73 61 66 65 2e 20 20 2a 2f 0a 20 20 20 20 20 20  safe.  */.      
10e90 75 33 32 20 79 20 3d 20 70 49 6e 66 6f 2d 3e 61  u32 y = pInfo->a
10ea0 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20 20 20  ReadMark[i];.   
10eb0 20 20 20 69 66 28 20 6d 78 53 61 66 65 46 72 61     if( mxSafeFra
10ec0 6d 65 3e 79 20 29 7b 0a 20 20 20 20 20 20 20 20  me>y ){.        
10ed0 61 73 73 65 72 74 28 20 79 3c 3d 70 57 61 6c 2d  assert( y<=pWal-
10ee0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a  >hdr.mxFrame );.
10ef0 20 20 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c          rc = wal
10f00 42 75 73 79 4c 6f 63 6b 28 70 57 61 6c 2c 20 78  BusyLock(pWal, x
10f10 42 75 73 79 2c 20 70 42 75 73 79 41 72 67 2c 20  Busy, pBusyArg, 
10f20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29  WAL_READ_LOCK(i)
10f30 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20 69 66  , 1);.        if
10f40 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
10f50 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 49 6e  ){.          pIn
10f60 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d  fo->aReadMark[i]
10f70 20 3d 20 28 69 3d 3d 31 20 3f 20 6d 78 53 61 66   = (i==1 ? mxSaf
10f80 65 46 72 61 6d 65 20 3a 20 52 45 41 44 4d 41 52  eFrame : READMAR
10f90 4b 5f 4e 4f 54 5f 55 53 45 44 29 3b 0a 20 20 20  K_NOT_USED);.   
10fa0 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b         walUnlock
10fb0 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
10fc0 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29  WAL_READ_LOCK(i)
10fd0 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20 7d 65  , 1);.        }e
10fe0 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  lse if( rc==SQLI
10ff0 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20  TE_BUSY ){.     
11000 20 20 20 20 20 6d 78 53 61 66 65 46 72 61 6d 65       mxSafeFrame
11010 20 3d 20 79 3b 0a 20 20 20 20 20 20 20 20 20 20   = y;.          
11020 78 42 75 73 79 20 3d 20 30 3b 0a 20 20 20 20 20  xBusy = 0;.     
11030 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
11040 20 20 20 20 67 6f 74 6f 20 77 61 6c 63 68 65 63      goto walchec
11050 6b 70 6f 69 6e 74 5f 6f 75 74 3b 0a 20 20 20 20  kpoint_out;.    
11060 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
11070 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 70 49 6e    }..    if( pIn
11080 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3c 6d 78  fo->nBackfill<mx
11090 53 61 66 65 46 72 61 6d 65 0a 20 20 20 20 20 26  SafeFrame.     &
110a0 26 20 28 72 63 20 3d 20 77 61 6c 42 75 73 79 4c  & (rc = walBusyL
110b0 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73 79 2c  ock(pWal, xBusy,
110c0 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c 5f 52   pBusyArg, WAL_R
110d0 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 31 29 29 3d  EAD_LOCK(0),1))=
110e0 3d 53 51 4c 49 54 45 5f 4f 4b 0a 20 20 20 20 29  =SQLITE_OK.    )
110f0 7b 0a 20 20 20 20 20 20 69 36 34 20 6e 53 69 7a  {.      i64 nSiz
11100 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
11110 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
11120 20 73 69 7a 65 20 6f 66 20 64 61 74 61 62 61 73   size of databas
11130 65 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 20 20  e file */.      
11140 75 33 32 20 6e 42 61 63 6b 66 69 6c 6c 20 3d 20  u32 nBackfill = 
11150 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
11160 3b 0a 0a 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e  ;..      pInfo->
11170 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74  nBackfillAttempt
11180 65 64 20 3d 20 6d 78 53 61 66 65 46 72 61 6d 65  ed = mxSafeFrame
11190 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 53 79 6e 63  ;..      /* Sync
111a0 20 74 68 65 20 57 41 4c 20 74 6f 20 64 69 73 6b   the WAL to disk
111b0 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 73   */.      rc = s
111c0 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 70 57 61  qlite3OsSync(pWa
111d0 6c 2d 3e 70 57 61 6c 46 64 2c 20 43 4b 50 54 5f  l->pWalFd, CKPT_
111e0 53 59 4e 43 5f 46 4c 41 47 53 28 73 79 6e 63 5f  SYNC_FLAGS(sync_
111f0 66 6c 61 67 73 29 29 3b 0a 0a 20 20 20 20 20 20  flags));..      
11200 2f 2a 20 49 66 20 74 68 65 20 64 61 74 61 62 61  /* If the databa
11210 73 65 20 6d 61 79 20 67 72 6f 77 20 61 73 20 61  se may grow as a
11220 20 72 65 73 75 6c 74 20 6f 66 20 74 68 69 73 20   result of this 
11230 63 68 65 63 6b 70 6f 69 6e 74 2c 20 68 69 6e 74  checkpoint, hint
11240 0a 20 20 20 20 20 20 2a 2a 20 61 62 6f 75 74 20  .      ** about 
11250 74 68 65 20 65 76 65 6e 74 75 61 6c 20 73 69 7a  the eventual siz
11260 65 20 6f 66 20 74 68 65 20 64 62 20 66 69 6c 65  e of the db file
11270 20 74 6f 20 74 68 65 20 56 46 53 20 6c 61 79 65   to the VFS laye
11280 72 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  r..      */.    
11290 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
112a0 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69  _OK ){.        i
112b0 36 34 20 6e 52 65 71 20 3d 20 28 28 69 36 34 29  64 nReq = ((i64)
112c0 6d 78 50 61 67 65 20 2a 20 73 7a 50 61 67 65 29  mxPage * szPage)
112d0 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73  ;.        rc = s
112e0 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a 65  qlite3OsFileSize
112f0 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 26 6e  (pWal->pDbFd, &n
11300 53 69 7a 65 29 3b 0a 20 20 20 20 20 20 20 20 69  Size);.        i
11310 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
11320 20 26 26 20 6e 53 69 7a 65 3c 6e 52 65 71 20 29   && nSize<nReq )
11330 7b 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c 69  {.          sqli
11340 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72 6f 6c  te3OsFileControl
11350 48 69 6e 74 28 70 57 61 6c 2d 3e 70 44 62 46 64  Hint(pWal->pDbFd
11360 2c 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 53  , SQLITE_FCNTL_S
11370 49 5a 45 5f 48 49 4e 54 2c 20 26 6e 52 65 71 29  IZE_HINT, &nReq)
11380 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
11390 20 20 7d 0a 0a 0a 20 20 20 20 20 20 2f 2a 20 49    }...      /* I
113a0 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 74  terate through t
113b0 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
113c0 68 65 20 57 41 4c 2c 20 63 6f 70 79 69 6e 67 20  he WAL, copying 
113d0 64 61 74 61 20 74 6f 20 74 68 65 20 64 62 20 66  data to the db f
113e0 69 6c 65 20 2a 2f 0a 20 20 20 20 20 20 77 68 69  ile */.      whi
113f0 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  le( rc==SQLITE_O
11400 4b 20 26 26 20 30 3d 3d 77 61 6c 49 74 65 72 61  K && 0==walItera
11410 74 6f 72 4e 65 78 74 28 70 49 74 65 72 2c 20 26  torNext(pIter, &
11420 69 44 62 70 61 67 65 2c 20 26 69 46 72 61 6d 65  iDbpage, &iFrame
11430 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69 36 34  ) ){.        i64
11440 20 69 4f 66 66 73 65 74 3b 0a 20 20 20 20 20 20   iOffset;.      
11450 20 20 61 73 73 65 72 74 28 20 77 61 6c 46 72 61    assert( walFra
11460 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 46 72  mePgno(pWal, iFr
11470 61 6d 65 29 3d 3d 69 44 62 70 61 67 65 20 29 3b  ame)==iDbpage );
11480 0a 20 20 20 20 20 20 20 20 69 66 28 20 64 62 2d  .        if( db-
11490 3e 75 31 2e 69 73 49 6e 74 65 72 72 75 70 74 65  >u1.isInterrupte
114a0 64 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72  d ){.          r
114b0 63 20 3d 20 64 62 2d 3e 6d 61 6c 6c 6f 63 46 61  c = db->mallocFa
114c0 69 6c 65 64 20 3f 20 53 51 4c 49 54 45 5f 4e 4f  iled ? SQLITE_NO
114d0 4d 45 4d 5f 42 4b 50 54 20 3a 20 53 51 4c 49 54  MEM_BKPT : SQLIT
114e0 45 5f 49 4e 54 45 52 52 55 50 54 3b 0a 20 20 20  E_INTERRUPT;.   
114f0 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
11500 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
11510 69 66 28 20 69 46 72 61 6d 65 3c 3d 6e 42 61 63  if( iFrame<=nBac
11520 6b 66 69 6c 6c 20 7c 7c 20 69 46 72 61 6d 65 3e  kfill || iFrame>
11530 6d 78 53 61 66 65 46 72 61 6d 65 20 7c 7c 20 69  mxSafeFrame || i
11540 44 62 70 61 67 65 3e 6d 78 50 61 67 65 20 29 7b  Dbpage>mxPage ){
11550 0a 20 20 20 20 20 20 20 20 20 20 63 6f 6e 74 69  .          conti
11560 6e 75 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  nue;.        }. 
11570 20 20 20 20 20 20 20 69 4f 66 66 73 65 74 20 3d         iOffset =
11580 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28   walFrameOffset(
11590 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29 20  iFrame, szPage) 
115a0 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  + WAL_FRAME_HDRS
115b0 49 5a 45 3b 0a 20 20 20 20 20 20 20 20 2f 2a 20  IZE;.        /* 
115c0 74 65 73 74 63 61 73 65 28 20 49 53 5f 42 49 47  testcase( IS_BIG
115d0 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20 29 3b  _INT(iOffset) );
115e0 20 2f 2f 20 72 65 71 75 69 72 65 73 20 61 20 34   // requires a 4
115f0 47 69 42 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a  GiB WAL file */.
11600 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c          rc = sql
11610 69 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d  ite3OsRead(pWal-
11620 3e 70 57 61 6c 46 64 2c 20 7a 42 75 66 2c 20 73  >pWalFd, zBuf, s
11630 7a 50 61 67 65 2c 20 69 4f 66 66 73 65 74 29 3b  zPage, iOffset);
11640 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 21  .        if( rc!
11650 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65  =SQLITE_OK ) bre
11660 61 6b 3b 0a 20 20 20 20 20 20 20 20 69 4f 66 66  ak;.        iOff
11670 73 65 74 20 3d 20 28 69 44 62 70 61 67 65 2d 31  set = (iDbpage-1
11680 29 2a 28 69 36 34 29 73 7a 50 61 67 65 3b 0a 20  )*(i64)szPage;. 
11690 20 20 20 20 20 20 20 74 65 73 74 63 61 73 65 28         testcase(
116a0 20 49 53 5f 42 49 47 5f 49 4e 54 28 69 4f 66 66   IS_BIG_INT(iOff
116b0 73 65 74 29 20 29 3b 0a 20 20 20 20 20 20 20 20  set) );.        
116c0 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72  rc = sqlite3OsWr
116d0 69 74 65 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  ite(pWal->pDbFd,
116e0 20 7a 42 75 66 2c 20 73 7a 50 61 67 65 2c 20 69   zBuf, szPage, i
116f0 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 20  Offset);.       
11700 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
11710 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  OK ) break;.    
11720 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66    }..      /* If
11730 20 77 6f 72 6b 20 77 61 73 20 61 63 74 75 61 6c   work was actual
11740 6c 79 20 61 63 63 6f 6d 70 6c 69 73 68 65 64 2e  ly accomplished.
11750 2e 2e 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20  .. */.      if( 
11760 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
11770 0a 20 20 20 20 20 20 20 20 69 66 28 20 6d 78 53  .        if( mxS
11780 61 66 65 46 72 61 6d 65 3d 3d 77 61 6c 49 6e 64  afeFrame==walInd
11790 65 78 48 64 72 28 70 57 61 6c 29 2d 3e 6d 78 46  exHdr(pWal)->mxF
117a0 72 61 6d 65 20 29 7b 0a 20 20 20 20 20 20 20 20  rame ){.        
117b0 20 20 69 36 34 20 73 7a 44 62 20 3d 20 70 57 61    i64 szDb = pWa
117c0 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 2a 28 69 36  l->hdr.nPage*(i6
117d0 34 29 73 7a 50 61 67 65 3b 0a 20 20 20 20 20 20  4)szPage;.      
117e0 20 20 20 20 74 65 73 74 63 61 73 65 28 20 49 53      testcase( IS
117f0 5f 42 49 47 5f 49 4e 54 28 73 7a 44 62 29 20 29  _BIG_INT(szDb) )
11800 3b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d  ;.          rc =
11810 20 73 71 6c 69 74 65 33 4f 73 54 72 75 6e 63 61   sqlite3OsTrunca
11820 74 65 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20  te(pWal->pDbFd, 
11830 73 7a 44 62 29 3b 0a 20 20 20 20 20 20 20 20 20  szDb);.         
11840 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
11850 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  OK ){.          
11860 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
11870 53 79 6e 63 28 70 57 61 6c 2d 3e 70 44 62 46 64  Sync(pWal->pDbFd
11880 2c 20 43 4b 50 54 5f 53 59 4e 43 5f 46 4c 41 47  , CKPT_SYNC_FLAG
11890 53 28 73 79 6e 63 5f 66 6c 61 67 73 29 29 3b 0a  S(sync_flags));.
118a0 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
118b0 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66      }.        if
118c0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
118d0 29 7b 0a 20 20 20 20 20 20 20 20 20 20 70 49 6e  ){.          pIn
118e0 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 20 3d 20  fo->nBackfill = 
118f0 6d 78 53 61 66 65 46 72 61 6d 65 3b 0a 20 20 20  mxSafeFrame;.   
11900 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 0a       }.      }..
11910 20 20 20 20 20 20 2f 2a 20 52 65 6c 65 61 73 65        /* Release
11920 20 74 68 65 20 72 65 61 64 65 72 20 6c 6f 63 6b   the reader lock
11930 20 68 65 6c 64 20 77 68 69 6c 65 20 62 61 63 6b   held while back
11940 66 69 6c 6c 69 6e 67 20 2a 2f 0a 20 20 20 20 20  filling */.     
11950 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
11960 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  ive(pWal, WAL_RE
11970 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 31 29 3b 0a  AD_LOCK(0), 1);.
11980 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72      }..    if( r
11990 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29  c==SQLITE_BUSY )
119a0 7b 0a 20 20 20 20 20 20 2f 2a 20 52 65 73 65 74  {.      /* Reset
119b0 20 74 68 65 20 72 65 74 75 72 6e 20 63 6f 64 65   the return code
119c0 20 73 6f 20 61 73 20 6e 6f 74 20 74 6f 20 72 65   so as not to re
119d0 70 6f 72 74 20 61 20 63 68 65 63 6b 70 6f 69 6e  port a checkpoin
119e0 74 20 66 61 69 6c 75 72 65 0a 20 20 20 20 20 20  t failure.      
119f0 2a 2a 20 6a 75 73 74 20 62 65 63 61 75 73 65 20  ** just because 
11a00 74 68 65 72 65 20 61 72 65 20 61 63 74 69 76 65  there are active
11a10 20 72 65 61 64 65 72 73 2e 20 20 2a 2f 0a 20 20   readers.  */.  
11a20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
11a30 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  OK;.    }.  }.. 
11a40 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20 61   /* If this is a
11a50 6e 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f  n SQLITE_CHECKPO
11a60 49 4e 54 5f 52 45 53 54 41 52 54 20 6f 72 20 54  INT_RESTART or T
11a70 52 55 4e 43 41 54 45 20 6f 70 65 72 61 74 69 6f  RUNCATE operatio
11a80 6e 2c 20 61 6e 64 20 74 68 65 0a 20 20 2a 2a 20  n, and the.  ** 
11a90 65 6e 74 69 72 65 20 77 61 6c 20 66 69 6c 65 20  entire wal file 
11aa0 68 61 73 20 62 65 65 6e 20 63 6f 70 69 65 64 20  has been copied 
11ab0 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
11ac0 65 20 66 69 6c 65 2c 20 74 68 65 6e 20 62 6c 6f  e file, then blo
11ad0 63 6b 20 0a 20 20 2a 2a 20 75 6e 74 69 6c 20 61  ck .  ** until a
11ae0 6c 6c 20 72 65 61 64 65 72 73 20 68 61 76 65 20  ll readers have 
11af0 66 69 6e 69 73 68 65 64 20 75 73 69 6e 67 20 74  finished using t
11b00 68 65 20 77 61 6c 20 66 69 6c 65 2e 20 54 68 69  he wal file. Thi
11b10 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20 0a  s ensures that .
11b20 20 20 2a 2a 20 74 68 65 20 6e 65 78 74 20 70 72    ** the next pr
11b30 6f 63 65 73 73 20 74 6f 20 77 72 69 74 65 20 74  ocess to write t
11b40 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20 72  o the database r
11b50 65 73 74 61 72 74 73 20 74 68 65 20 77 61 6c 20  estarts the wal 
11b60 66 69 6c 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  file..  */.  if(
11b70 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
11b80 26 20 65 4d 6f 64 65 21 3d 53 51 4c 49 54 45 5f  & eMode!=SQLITE_
11b90 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49  CHECKPOINT_PASSI
11ba0 56 45 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  VE ){.    assert
11bb0 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
11bc0 6b 20 29 3b 0a 20 20 20 20 69 66 28 20 70 49 6e  k );.    if( pIn
11bd0 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3c 70 57  fo->nBackfill<pW
11be0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
11bf0 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  ){.      rc = SQ
11c00 4c 49 54 45 5f 42 55 53 59 3b 0a 20 20 20 20 7d  LITE_BUSY;.    }
11c10 65 6c 73 65 20 69 66 28 20 65 4d 6f 64 65 3e 3d  else if( eMode>=
11c20 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e  SQLITE_CHECKPOIN
11c30 54 5f 52 45 53 54 41 52 54 20 29 7b 0a 20 20 20  T_RESTART ){.   
11c40 20 20 20 75 33 32 20 73 61 6c 74 31 3b 0a 20 20     u32 salt1;.  
11c50 20 20 20 20 73 71 6c 69 74 65 33 5f 72 61 6e 64      sqlite3_rand
11c60 6f 6d 6e 65 73 73 28 34 2c 20 26 73 61 6c 74 31  omness(4, &salt1
11c70 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
11c80 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
11c90 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  l==pWal->hdr.mxF
11ca0 72 61 6d 65 20 29 3b 0a 20 20 20 20 20 20 72 63  rame );.      rc
11cb0 20 3d 20 77 61 6c 42 75 73 79 4c 6f 63 6b 28 70   = walBusyLock(p
11cc0 57 61 6c 2c 20 78 42 75 73 79 2c 20 70 42 75 73  Wal, xBusy, pBus
11cd0 79 41 72 67 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  yArg, WAL_READ_L
11ce0 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41  OCK(1), WAL_NREA
11cf0 44 45 52 2d 31 29 3b 0a 20 20 20 20 20 20 69 66  DER-1);.      if
11d00 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
11d10 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65  ){.        if( e
11d20 4d 6f 64 65 3d 3d 53 51 4c 49 54 45 5f 43 48 45  Mode==SQLITE_CHE
11d30 43 4b 50 4f 49 4e 54 5f 54 52 55 4e 43 41 54 45  CKPOINT_TRUNCATE
11d40 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2f 2a   ){.          /*
11d50 20 49 4d 50 4c 45 4d 45 4e 54 41 54 49 4f 4e 2d   IMPLEMENTATION-
11d60 4f 46 3a 20 52 2d 34 34 36 39 39 2d 35 37 31 34  OF: R-44699-5714
11d70 30 20 54 68 69 73 20 6d 6f 64 65 20 77 6f 72 6b  0 This mode work
11d80 73 20 74 68 65 20 73 61 6d 65 20 77 61 79 20 61  s the same way a
11d90 73 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 53  s.          ** S
11da0 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54  QLITE_CHECKPOINT
11db0 5f 52 45 53 54 41 52 54 20 77 69 74 68 20 74 68  _RESTART with th
11dc0 65 20 61 64 64 69 74 69 6f 6e 20 74 68 61 74 20  e addition that 
11dd0 69 74 20 61 6c 73 6f 0a 20 20 20 20 20 20 20 20  it also.        
11de0 20 20 2a 2a 20 74 72 75 6e 63 61 74 65 73 20 74    ** truncates t
11df0 68 65 20 6c 6f 67 20 66 69 6c 65 20 74 6f 20 7a  he log file to z
11e00 65 72 6f 20 62 79 74 65 73 20 6a 75 73 74 20 70  ero bytes just p
11e10 72 69 6f 72 20 74 6f 20 61 0a 20 20 20 20 20 20  rior to a.      
11e20 20 20 20 20 2a 2a 20 73 75 63 63 65 73 73 66 75      ** successfu
11e30 6c 20 72 65 74 75 72 6e 2e 0a 20 20 20 20 20 20  l return..      
11e40 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 20      **.         
11e50 20 2a 2a 20 49 6e 20 74 68 65 6f 72 79 2c 20 69   ** In theory, i
11e60 74 20 6d 69 67 68 74 20 62 65 20 73 61 66 65 20  t might be safe 
11e70 74 6f 20 64 6f 20 74 68 69 73 20 77 69 74 68 6f  to do this witho
11e80 75 74 20 75 70 64 61 74 69 6e 67 20 74 68 65 0a  ut updating the.
11e90 20 20 20 20 20 20 20 20 20 20 2a 2a 20 77 61 6c            ** wal
11ea0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 6e  -index header in
11eb0 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 2c 20   shared memory, 
11ec0 61 73 20 61 6c 6c 20 73 75 62 73 65 71 75 65 6e  as all subsequen
11ed0 74 20 72 65 61 64 65 72 20 6f 72 0a 20 20 20 20  t reader or.    
11ee0 20 20 20 20 20 20 2a 2a 20 77 72 69 74 65 72 20        ** writer 
11ef0 63 6c 69 65 6e 74 73 20 73 68 6f 75 6c 64 20 73  clients should s
11f00 65 65 20 74 68 61 74 20 74 68 65 20 65 6e 74 69  ee that the enti
11f10 72 65 20 6c 6f 67 20 66 69 6c 65 20 68 61 73 20  re log file has 
11f20 62 65 65 6e 0a 20 20 20 20 20 20 20 20 20 20 2a  been.          *
11f30 2a 20 63 68 65 63 6b 70 6f 69 6e 74 65 64 20 61  * checkpointed a
11f40 6e 64 20 62 65 68 61 76 65 20 61 63 63 6f 72 64  nd behave accord
11f50 69 6e 67 6c 79 2e 20 54 68 69 73 20 73 65 65 6d  ingly. This seem
11f60 73 20 75 6e 73 61 66 65 20 74 68 6f 75 67 68 2c  s unsafe though,
11f70 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 61 73  .          ** as
11f80 20 69 74 20 77 6f 75 6c 64 20 6c 65 61 76 65 20   it would leave 
11f90 74 68 65 20 73 79 73 74 65 6d 20 69 6e 20 61 20  the system in a 
11fa0 73 74 61 74 65 20 77 68 65 72 65 20 74 68 65 20  state where the 
11fb0 63 6f 6e 74 65 6e 74 73 20 6f 66 0a 20 20 20 20  contents of.    
11fc0 20 20 20 20 20 20 2a 2a 20 74 68 65 20 77 61 6c        ** the wal
11fd0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 64 6f  -index header do
11fe0 20 6e 6f 74 20 6d 61 74 63 68 20 74 68 65 20 63   not match the c
11ff0 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 0a  ontents of the .
12000 20 20 20 20 20 20 20 20 20 20 2a 2a 20 66 69 6c            ** fil
12010 65 2d 73 79 73 74 65 6d 2e 20 54 6f 20 61 76 6f  e-system. To avo
12020 69 64 20 74 68 69 73 2c 20 75 70 64 61 74 65 20  id this, update 
12030 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
12040 61 64 65 72 20 74 6f 0a 20 20 20 20 20 20 20 20  ader to.        
12050 20 20 2a 2a 20 69 6e 64 69 63 61 74 65 20 74 68    ** indicate th
12060 61 74 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 20  at the log file 
12070 63 6f 6e 74 61 69 6e 73 20 7a 65 72 6f 20 76 61  contains zero va
12080 6c 69 64 20 66 72 61 6d 65 73 2e 20 20 2a 2f 0a  lid frames.  */.
12090 20 20 20 20 20 20 20 20 20 20 77 61 6c 52 65 73            walRes
120a0 74 61 72 74 48 64 72 28 70 57 61 6c 2c 20 73 61  tartHdr(pWal, sa
120b0 6c 74 31 29 3b 0a 20 20 20 20 20 20 20 20 20 20  lt1);.          
120c0 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 54 72  rc = sqlite3OsTr
120d0 75 6e 63 61 74 65 28 70 57 61 6c 2d 3e 70 57 61  uncate(pWal->pWa
120e0 6c 46 64 2c 20 30 29 3b 0a 20 20 20 20 20 20 20  lFd, 0);.       
120f0 20 7d 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e   }.        walUn
12100 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  lockExclusive(pW
12110 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  al, WAL_READ_LOC
12120 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45  K(1), WAL_NREADE
12130 52 2d 31 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  R-1);.      }.  
12140 20 20 7d 0a 20 20 7d 0a 0a 20 77 61 6c 63 68 65    }.  }.. walche
12150 63 6b 70 6f 69 6e 74 5f 6f 75 74 3a 0a 20 20 77  ckpoint_out:.  w
12160 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28 70  alIteratorFree(p
12170 49 74 65 72 29 3b 0a 20 20 72 65 74 75 72 6e 20  Iter);.  return 
12180 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20  rc;.}../*.** If 
12190 74 68 65 20 57 41 4c 20 66 69 6c 65 20 69 73 20  the WAL file is 
121a0 63 75 72 72 65 6e 74 6c 79 20 6c 61 72 67 65 72  currently larger
121b0 20 74 68 61 6e 20 6e 4d 61 78 20 62 79 74 65 73   than nMax bytes
121c0 20 69 6e 20 73 69 7a 65 2c 20 74 72 75 6e 63 61   in size, trunca
121d0 74 65 0a 2a 2a 20 69 74 20 74 6f 20 65 78 61 63  te.** it to exac
121e0 74 6c 79 20 6e 4d 61 78 20 62 79 74 65 73 2e 20  tly nMax bytes. 
121f0 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  If an error occu
12200 72 73 20 77 68 69 6c 65 20 64 6f 69 6e 67 20 73  rs while doing s
12210 6f 2c 20 69 67 6e 6f 72 65 20 69 74 2e 0a 2a 2f  o, ignore it..*/
12220 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
12230 4c 69 6d 69 74 53 69 7a 65 28 57 61 6c 20 2a 70  LimitSize(Wal *p
12240 57 61 6c 2c 20 69 36 34 20 6e 4d 61 78 29 7b 0a  Wal, i64 nMax){.
12250 20 20 69 36 34 20 73 7a 3b 0a 20 20 69 6e 74 20    i64 sz;.  int 
12260 72 78 3b 0a 20 20 73 71 6c 69 74 65 33 42 65 67  rx;.  sqlite3Beg
12270 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29  inBenignMalloc()
12280 3b 0a 20 20 72 78 20 3d 20 73 71 6c 69 74 65 33  ;.  rx = sqlite3
12290 4f 73 46 69 6c 65 53 69 7a 65 28 70 57 61 6c 2d  OsFileSize(pWal-
122a0 3e 70 57 61 6c 46 64 2c 20 26 73 7a 29 3b 0a 20  >pWalFd, &sz);. 
122b0 20 69 66 28 20 72 78 3d 3d 53 51 4c 49 54 45 5f   if( rx==SQLITE_
122c0 4f 4b 20 26 26 20 28 73 7a 20 3e 20 6e 4d 61 78  OK && (sz > nMax
122d0 20 29 20 29 7b 0a 20 20 20 20 72 78 20 3d 20 73   ) ){.    rx = s
122e0 71 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74 65  qlite3OsTruncate
122f0 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 6e  (pWal->pWalFd, n
12300 4d 61 78 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69  Max);.  }.  sqli
12310 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c  te3EndBenignMall
12320 6f 63 28 29 3b 0a 20 20 69 66 28 20 72 78 20 29  oc();.  if( rx )
12330 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f  {.    sqlite3_lo
12340 67 28 72 78 2c 20 22 63 61 6e 6e 6f 74 20 6c 69  g(rx, "cannot li
12350 6d 69 74 20 57 41 4c 20 73 69 7a 65 3a 20 25 73  mit WAL size: %s
12360 22 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d  ", pWal->zWalNam
12370 65 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  e);.  }.}../*.**
12380 20 43 6c 6f 73 65 20 61 20 63 6f 6e 6e 65 63 74   Close a connect
12390 69 6f 6e 20 74 6f 20 61 20 6c 6f 67 20 66 69 6c  ion to a log fil
123a0 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
123b0 33 57 61 6c 43 6c 6f 73 65 28 0a 20 20 57 61 6c  3WalClose(.  Wal
123c0 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20   *pWal,         
123d0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
123e0 57 61 6c 20 74 6f 20 63 6c 6f 73 65 20 2a 2f 0a  Wal to close */.
123f0 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20    sqlite3 *db,  
12400 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12410 20 20 2f 2a 20 46 6f 72 20 69 6e 74 65 72 72 75    /* For interru
12420 70 74 20 66 6c 61 67 20 2a 2f 0a 20 20 69 6e 74  pt flag */.  int
12430 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20   sync_flags,    
12440 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12450 46 6c 61 67 73 20 74 6f 20 70 61 73 73 20 74 6f  Flags to pass to
12460 20 4f 73 53 79 6e 63 28 29 20 28 6f 72 20 30 29   OsSync() (or 0)
12470 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 2c 0a   */.  int nBuf,.
12480 20 20 75 38 20 2a 7a 42 75 66 20 20 20 20 20 20    u8 *zBuf      
12490 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
124a0 20 20 2f 2a 20 42 75 66 66 65 72 20 6f 66 20 61    /* Buffer of a
124b0 74 20 6c 65 61 73 74 20 6e 42 75 66 20 62 79 74  t least nBuf byt
124c0 65 73 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  es */.){.  int r
124d0 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
124e0 20 69 66 28 20 70 57 61 6c 20 29 7b 0a 20 20 20   if( pWal ){.   
124f0 20 69 6e 74 20 69 73 44 65 6c 65 74 65 20 3d 20   int isDelete = 
12500 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  0;             /
12510 2a 20 54 72 75 65 20 74 6f 20 75 6e 6c 69 6e 6b  * True to unlink
12520 20 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64   wal and wal-ind
12530 65 78 20 66 69 6c 65 73 20 2a 2f 0a 0a 20 20 20  ex files */..   
12540 20 2f 2a 20 49 66 20 61 6e 20 45 58 43 4c 55 53   /* If an EXCLUS
12550 49 56 45 20 6c 6f 63 6b 20 63 61 6e 20 62 65 20  IVE lock can be 
12560 6f 62 74 61 69 6e 65 64 20 6f 6e 20 74 68 65 20  obtained on the 
12570 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 28 75  database file (u
12580 73 69 6e 67 20 74 68 65 0a 20 20 20 20 2a 2a 20  sing the.    ** 
12590 6f 72 64 69 6e 61 72 79 2c 20 72 6f 6c 6c 62 61  ordinary, rollba
125a0 63 6b 2d 6d 6f 64 65 20 6c 6f 63 6b 69 6e 67 20  ck-mode locking 
125b0 6d 65 74 68 6f 64 73 2c 20 74 68 69 73 20 67 75  methods, this gu
125c0 61 72 61 6e 74 65 65 73 20 74 68 61 74 20 74 68  arantees that th
125d0 65 0a 20 20 20 20 2a 2a 20 63 6f 6e 6e 65 63 74  e.    ** connect
125e0 69 6f 6e 20 61 73 73 6f 63 69 61 74 65 64 20 77  ion associated w
125f0 69 74 68 20 74 68 69 73 20 6c 6f 67 20 66 69 6c  ith this log fil
12600 65 20 69 73 20 74 68 65 20 6f 6e 6c 79 20 63 6f  e is the only co
12610 6e 6e 65 63 74 69 6f 6e 20 74 6f 0a 20 20 20 20  nnection to.    
12620 2a 2a 20 74 68 65 20 64 61 74 61 62 61 73 65 2e  ** the database.
12630 20 49 6e 20 74 68 69 73 20 63 61 73 65 20 63 68   In this case ch
12640 65 63 6b 70 6f 69 6e 74 20 74 68 65 20 64 61 74  eckpoint the dat
12650 61 62 61 73 65 20 61 6e 64 20 75 6e 6c 69 6e 6b  abase and unlink
12660 20 62 6f 74 68 0a 20 20 20 20 2a 2a 20 74 68 65   both.    ** the
12670 20 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64   wal and wal-ind
12680 65 78 20 66 69 6c 65 73 2e 0a 20 20 20 20 2a 2a  ex files..    **
12690 0a 20 20 20 20 2a 2a 20 54 68 65 20 45 58 43 4c  .    ** The EXCL
126a0 55 53 49 56 45 20 6c 6f 63 6b 20 69 73 20 6e 6f  USIVE lock is no
126b0 74 20 72 65 6c 65 61 73 65 64 20 62 65 66 6f 72  t released befor
126c0 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 20 20 20  e returning..   
126d0 20 2a 2f 0a 20 20 20 20 69 66 28 20 7a 42 75 66   */.    if( zBuf
126e0 21 3d 30 0a 20 20 20 20 20 26 26 20 53 51 4c 49  !=0.     && SQLI
126f0 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 73 71 6c  TE_OK==(rc = sql
12700 69 74 65 33 4f 73 4c 6f 63 6b 28 70 57 61 6c 2d  ite3OsLock(pWal-
12710 3e 70 44 62 46 64 2c 20 53 51 4c 49 54 45 5f 4c  >pDbFd, SQLITE_L
12720 4f 43 4b 5f 45 58 43 4c 55 53 49 56 45 29 29 0a  OCK_EXCLUSIVE)).
12730 20 20 20 20 29 7b 0a 20 20 20 20 20 20 69 66 28      ){.      if(
12740 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
12750 4d 6f 64 65 3d 3d 57 41 4c 5f 4e 4f 52 4d 41 4c  Mode==WAL_NORMAL
12760 5f 4d 4f 44 45 20 29 7b 0a 20 20 20 20 20 20 20  _MODE ){.       
12770 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
12780 4d 6f 64 65 20 3d 20 57 41 4c 5f 45 58 43 4c 55  Mode = WAL_EXCLU
12790 53 49 56 45 5f 4d 4f 44 45 3b 0a 20 20 20 20 20  SIVE_MODE;.     
127a0 20 7d 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71   }.      rc = sq
127b0 6c 69 74 65 33 57 61 6c 43 68 65 63 6b 70 6f 69  lite3WalCheckpoi
127c0 6e 74 28 70 57 61 6c 2c 20 64 62 2c 20 0a 20 20  nt(pWal, db, .  
127d0 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 43          SQLITE_C
127e0 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49 56  HECKPOINT_PASSIV
127f0 45 2c 20 30 2c 20 30 2c 20 73 79 6e 63 5f 66 6c  E, 0, 0, sync_fl
12800 61 67 73 2c 20 6e 42 75 66 2c 20 7a 42 75 66 2c  ags, nBuf, zBuf,
12810 20 30 2c 20 30 0a 20 20 20 20 20 20 29 3b 0a 20   0, 0.      );. 
12820 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
12830 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
12840 20 20 69 6e 74 20 62 50 65 72 73 69 73 74 20 3d    int bPersist =
12850 20 2d 31 3b 0a 20 20 20 20 20 20 20 20 73 71 6c   -1;.        sql
12860 69 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72 6f  ite3OsFileContro
12870 6c 48 69 6e 74 28 0a 20 20 20 20 20 20 20 20 20  lHint(.         
12880 20 20 20 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20     pWal->pDbFd, 
12890 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 50 45 52  SQLITE_FCNTL_PER
128a0 53 49 53 54 5f 57 41 4c 2c 20 26 62 50 65 72 73  SIST_WAL, &bPers
128b0 69 73 74 0a 20 20 20 20 20 20 20 20 29 3b 0a 20  ist.        );. 
128c0 20 20 20 20 20 20 20 69 66 28 20 62 50 65 72 73         if( bPers
128d0 69 73 74 21 3d 31 20 29 7b 0a 20 20 20 20 20 20  ist!=1 ){.      
128e0 20 20 20 20 2f 2a 20 54 72 79 20 74 6f 20 64 65      /* Try to de
128f0 6c 65 74 65 20 74 68 65 20 57 41 4c 20 66 69 6c  lete the WAL fil
12900 65 20 69 66 20 74 68 65 20 63 68 65 63 6b 70 6f  e if the checkpo
12910 69 6e 74 20 63 6f 6d 70 6c 65 74 65 64 20 61 6e  int completed an
12920 64 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 66  d.          ** f
12930 73 79 6e 65 64 20 28 72 63 3d 3d 53 51 4c 49 54  syned (rc==SQLIT
12940 45 5f 4f 4b 29 20 61 6e 64 20 69 66 20 77 65 20  E_OK) and if we 
12950 61 72 65 20 6e 6f 74 20 69 6e 20 70 65 72 73 69  are not in persi
12960 73 74 65 6e 74 2d 77 61 6c 0a 20 20 20 20 20 20  stent-wal.      
12970 20 20 20 20 2a 2a 20 6d 6f 64 65 20 28 21 62 50      ** mode (!bP
12980 65 72 73 69 73 74 29 20 2a 2f 0a 20 20 20 20 20  ersist) */.     
12990 20 20 20 20 20 69 73 44 65 6c 65 74 65 20 3d 20       isDelete = 
129a0 31 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  1;.        }else
129b0 20 69 66 28 20 70 57 61 6c 2d 3e 6d 78 57 61 6c   if( pWal->mxWal
129c0 53 69 7a 65 3e 3d 30 20 29 7b 0a 20 20 20 20 20  Size>=0 ){.     
129d0 20 20 20 20 20 2f 2a 20 54 72 79 20 74 6f 20 74       /* Try to t
129e0 72 75 6e 63 61 74 65 20 74 68 65 20 57 41 4c 20  runcate the WAL 
129f0 66 69 6c 65 20 74 6f 20 7a 65 72 6f 20 62 79 74  file to zero byt
12a00 65 73 20 69 66 20 74 68 65 20 63 68 65 63 6b 70  es if the checkp
12a10 6f 69 6e 74 0a 20 20 20 20 20 20 20 20 20 20 2a  oint.          *
12a20 2a 20 63 6f 6d 70 6c 65 74 65 64 20 61 6e 64 20  * completed and 
12a30 66 73 79 6e 63 65 64 20 28 72 63 3d 3d 53 51 4c  fsynced (rc==SQL
12a40 49 54 45 5f 4f 4b 29 20 61 6e 64 20 77 65 20 61  ITE_OK) and we a
12a50 72 65 20 69 6e 20 70 65 72 73 69 73 74 65 6e 74  re in persistent
12a60 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 57 41  .          ** WA
12a70 4c 20 6d 6f 64 65 20 28 62 50 65 72 73 69 73 74  L mode (bPersist
12a80 29 20 61 6e 64 20 69 66 20 74 68 65 20 50 52 41  ) and if the PRA
12a90 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 73 69 7a 65  GMA journal_size
12aa0 5f 6c 69 6d 69 74 20 69 73 20 61 0a 20 20 20 20  _limit is a.    
12ab0 20 20 20 20 20 20 2a 2a 20 6e 6f 6e 2d 6e 65 67        ** non-neg
12ac0 61 74 69 76 65 20 76 61 6c 75 65 20 28 70 57 61  ative value (pWa
12ad0 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 3e 3d 30 29  l->mxWalSize>=0)
12ae0 2e 20 20 4e 6f 74 65 20 74 68 61 74 20 77 65 20  .  Note that we 
12af0 74 72 75 6e 63 61 74 65 0a 20 20 20 20 20 20 20  truncate.       
12b00 20 20 20 2a 2a 20 74 6f 20 7a 65 72 6f 20 62 79     ** to zero by
12b10 74 65 73 20 61 73 20 74 72 75 6e 63 61 74 69 6e  tes as truncatin
12b20 67 20 74 6f 20 74 68 65 20 6a 6f 75 72 6e 61 6c  g to the journal
12b30 5f 73 69 7a 65 5f 6c 69 6d 69 74 20 6d 69 67 68  _size_limit migh
12b40 74 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 6c  t.          ** l
12b50 65 61 76 65 20 61 20 63 6f 72 72 75 70 74 20 57  eave a corrupt W
12b60 41 4c 20 66 69 6c 65 20 6f 6e 20 64 69 73 6b 2e  AL file on disk.
12b70 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 77 61   */.          wa
12b80 6c 4c 69 6d 69 74 53 69 7a 65 28 70 57 61 6c 2c  lLimitSize(pWal,
12b90 20 30 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20   0);.        }. 
12ba0 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
12bb0 20 20 77 61 6c 49 6e 64 65 78 43 6c 6f 73 65 28    walIndexClose(
12bc0 70 57 61 6c 2c 20 69 73 44 65 6c 65 74 65 29 3b  pWal, isDelete);
12bd0 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c  .    sqlite3OsCl
12be0 6f 73 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ose(pWal->pWalFd
12bf0 29 3b 0a 20 20 20 20 69 66 28 20 69 73 44 65 6c  );.    if( isDel
12c00 65 74 65 20 29 7b 0a 20 20 20 20 20 20 73 71 6c  ete ){.      sql
12c10 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d  ite3BeginBenignM
12c20 61 6c 6c 6f 63 28 29 3b 0a 20 20 20 20 20 20 73  alloc();.      s
12c30 71 6c 69 74 65 33 4f 73 44 65 6c 65 74 65 28 70  qlite3OsDelete(p
12c40 57 61 6c 2d 3e 70 56 66 73 2c 20 70 57 61 6c 2d  Wal->pVfs, pWal-
12c50 3e 7a 57 61 6c 4e 61 6d 65 2c 20 30 29 3b 0a 20  >zWalName, 0);. 
12c60 20 20 20 20 20 73 71 6c 69 74 65 33 45 6e 64 42       sqlite3EndB
12c70 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20  enignMalloc();. 
12c80 20 20 20 7d 0a 20 20 20 20 57 41 4c 54 52 41 43     }.    WALTRAC
12c90 45 28 28 22 57 41 4c 25 70 3a 20 63 6c 6f 73 65  E(("WAL%p: close
12ca0 64 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 20 20  d\n", pWal));.  
12cb0 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 28    sqlite3_free((
12cc0 76 6f 69 64 20 2a 29 70 57 61 6c 2d 3e 61 70 57  void *)pWal->apW
12cd0 69 44 61 74 61 29 3b 0a 20 20 20 20 73 71 6c 69  iData);.    sqli
12ce0 74 65 33 5f 66 72 65 65 28 70 57 61 6c 29 3b 0a  te3_free(pWal);.
12cf0 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
12d00 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74 6f  .}../*.** Try to
12d10 20 72 65 61 64 20 74 68 65 20 77 61 6c 2d 69 6e   read the wal-in
12d20 64 65 78 20 68 65 61 64 65 72 2e 20 20 52 65 74  dex header.  Ret
12d30 75 72 6e 20 30 20 6f 6e 20 73 75 63 63 65 73 73  urn 0 on success
12d40 20 61 6e 64 20 31 20 69 66 0a 2a 2a 20 74 68 65   and 1 if.** the
12d50 72 65 20 69 73 20 61 20 70 72 6f 62 6c 65 6d 2e  re is a problem.
12d60 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61 6c 2d 69  .**.** The wal-i
12d70 6e 64 65 78 20 69 73 20 69 6e 20 73 68 61 72 65  ndex is in share
12d80 64 20 6d 65 6d 6f 72 79 2e 20 20 41 6e 6f 74 68  d memory.  Anoth
12d90 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f  er thread or pro
12da0 63 65 73 73 20 6d 69 67 68 74 0a 2a 2a 20 62 65  cess might.** be
12db0 20 77 72 69 74 69 6e 67 20 74 68 65 20 68 65 61   writing the hea
12dc0 64 65 72 20 61 74 20 74 68 65 20 73 61 6d 65 20  der at the same 
12dd0 74 69 6d 65 20 74 68 69 73 20 70 72 6f 63 65 64  time this proced
12de0 75 72 65 20 69 73 20 74 72 79 69 6e 67 20 74 6f  ure is trying to
12df0 0a 2a 2a 20 72 65 61 64 20 69 74 2c 20 77 68 69  .** read it, whi
12e00 63 68 20 6d 69 67 68 74 20 72 65 73 75 6c 74 20  ch might result 
12e10 69 6e 20 69 6e 63 6f 6e 73 69 73 74 65 6e 63 79  in inconsistency
12e20 2e 20 20 41 20 64 69 72 74 79 20 72 65 61 64 20  .  A dirty read 
12e30 69 73 20 64 65 74 65 63 74 65 64 0a 2a 2a 20 62  is detected.** b
12e40 79 20 76 65 72 69 66 79 69 6e 67 20 74 68 61 74  y verifying that
12e50 20 62 6f 74 68 20 63 6f 70 69 65 73 20 6f 66 20   both copies of 
12e60 74 68 65 20 68 65 61 64 65 72 20 61 72 65 20 74  the header are t
12e70 68 65 20 73 61 6d 65 20 61 6e 64 20 61 6c 73 6f  he same and also
12e80 20 62 79 0a 2a 2a 20 61 20 63 68 65 63 6b 73 75   by.** a checksu
12e90 6d 20 6f 6e 20 74 68 65 20 68 65 61 64 65 72 2e  m on the header.
12ea0 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 64 20 6f 6e  .**.** If and on
12eb0 6c 79 20 69 66 20 74 68 65 20 72 65 61 64 20 69  ly if the read i
12ec0 73 20 63 6f 6e 73 69 73 74 65 6e 74 20 61 6e 64  s consistent and
12ed0 20 74 68 65 20 68 65 61 64 65 72 20 69 73 20 64   the header is d
12ee0 69 66 66 65 72 65 6e 74 20 66 72 6f 6d 0a 2a 2a  ifferent from.**
12ef0 20 70 57 61 6c 2d 3e 68 64 72 2c 20 74 68 65 6e   pWal->hdr, then
12f00 20 70 57 61 6c 2d 3e 68 64 72 20 69 73 20 75 70   pWal->hdr is up
12f10 64 61 74 65 64 20 74 6f 20 74 68 65 20 63 6f 6e  dated to the con
12f20 74 65 6e 74 20 6f 66 20 74 68 65 20 6e 65 77 20  tent of the new 
12f30 68 65 61 64 65 72 0a 2a 2a 20 61 6e 64 20 2a 70  header.** and *p
12f40 43 68 61 6e 67 65 64 20 69 73 20 73 65 74 20 74  Changed is set t
12f50 6f 20 31 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  o 1..**.** If th
12f60 65 20 63 68 65 63 6b 73 75 6d 20 63 61 6e 6e 6f  e checksum canno
12f70 74 20 62 65 20 76 65 72 69 66 69 65 64 20 72 65  t be verified re
12f80 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 20 49  turn non-zero. I
12f90 66 20 74 68 65 20 68 65 61 64 65 72 0a 2a 2a 20  f the header.** 
12fa0 69 73 20 72 65 61 64 20 73 75 63 63 65 73 73 66  is read successf
12fb0 75 6c 6c 79 20 61 6e 64 20 74 68 65 20 63 68 65  ully and the che
12fc0 63 6b 73 75 6d 20 76 65 72 69 66 69 65 64 2c 20  cksum verified, 
12fd0 72 65 74 75 72 6e 20 7a 65 72 6f 2e 0a 2a 2f 0a  return zero..*/.
12fe0 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e  static int walIn
12ff0 64 65 78 54 72 79 48 64 72 28 57 61 6c 20 2a 70  dexTryHdr(Wal *p
13000 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e 67  Wal, int *pChang
13010 65 64 29 7b 0a 20 20 75 33 32 20 61 43 6b 73 75  ed){.  u32 aCksu
13020 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20 20  m[2];           
13030 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 73         /* Checks
13040 75 6d 20 6f 6e 20 74 68 65 20 68 65 61 64 65 72  um on the header
13050 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 57 61   content */.  Wa
13060 6c 49 6e 64 65 78 48 64 72 20 68 31 2c 20 68 32  lIndexHdr h1, h2
13070 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
13080 20 54 77 6f 20 63 6f 70 69 65 73 20 6f 66 20 74   Two copies of t
13090 68 65 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e  he header conten
130a0 74 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65 78 48  t */.  WalIndexH
130b0 64 72 20 76 6f 6c 61 74 69 6c 65 20 2a 61 48 64  dr volatile *aHd
130c0 72 3b 20 20 20 20 20 2f 2a 20 48 65 61 64 65 72  r;     /* Header
130d0 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d 6f 72   in shared memor
130e0 79 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 65 20 66  y */..  /* The f
130f0 69 72 73 74 20 70 61 67 65 20 6f 66 20 74 68 65  irst page of the
13100 20 77 61 6c 2d 69 6e 64 65 78 20 6d 75 73 74 20   wal-index must 
13110 62 65 20 6d 61 70 70 65 64 20 61 74 20 74 68 69  be mapped at thi
13120 73 20 70 6f 69 6e 74 2e 20 2a 2f 0a 20 20 61 73  s point. */.  as
13130 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44  sert( pWal->nWiD
13140 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61  ata>0 && pWal->a
13150 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 0a 20  pWiData[0] );.. 
13160 20 2f 2a 20 52 65 61 64 20 74 68 65 20 68 65 61   /* Read the hea
13170 64 65 72 2e 20 54 68 69 73 20 6d 69 67 68 74 20  der. This might 
13180 68 61 70 70 65 6e 20 63 6f 6e 63 75 72 72 65 6e  happen concurren
13190 74 6c 79 20 77 69 74 68 20 61 20 77 72 69 74 65  tly with a write
131a0 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20 73 61 6d   to the.  ** sam
131b0 65 20 61 72 65 61 20 6f 66 20 73 68 61 72 65 64  e area of shared
131c0 20 6d 65 6d 6f 72 79 20 6f 6e 20 61 20 64 69 66   memory on a dif
131d0 66 65 72 65 6e 74 20 43 50 55 20 69 6e 20 61 20  ferent CPU in a 
131e0 53 4d 50 2c 0a 20 20 2a 2a 20 6d 65 61 6e 69 6e  SMP,.  ** meanin
131f0 67 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c 65  g it is possible
13200 20 74 68 61 74 20 61 6e 20 69 6e 63 6f 6e 73 69   that an inconsi
13210 73 74 65 6e 74 20 73 6e 61 70 73 68 6f 74 20 69  stent snapshot i
13220 73 20 72 65 61 64 0a 20 20 2a 2a 20 66 72 6f 6d  s read.  ** from
13230 20 74 68 65 20 66 69 6c 65 2e 20 49 66 20 74 68   the file. If th
13240 69 73 20 68 61 70 70 65 6e 73 2c 20 72 65 74 75  is happens, retu
13250 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 20 20 2a  rn non-zero..  *
13260 2a 0a 20 20 2a 2a 20 54 68 65 72 65 20 61 72 65  *.  ** There are
13270 20 74 77 6f 20 63 6f 70 69 65 73 20 6f 66 20 74   two copies of t
13280 68 65 20 68 65 61 64 65 72 20 61 74 20 74 68 65  he header at the
13290 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68   beginning of th
132a0 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 20 20 2a  e wal-index..  *
132b0 2a 20 57 68 65 6e 20 72 65 61 64 69 6e 67 2c 20  * When reading, 
132c0 72 65 61 64 20 5b 30 5d 20 66 69 72 73 74 20 74  read [0] first t
132d0 68 65 6e 20 5b 31 5d 2e 20 20 57 72 69 74 65 73  hen [1].  Writes
132e0 20 61 72 65 20 69 6e 20 74 68 65 20 72 65 76 65   are in the reve
132f0 72 73 65 20 6f 72 64 65 72 2e 0a 20 20 2a 2a 20  rse order..  ** 
13300 4d 65 6d 6f 72 79 20 62 61 72 72 69 65 72 73 20  Memory barriers 
13310 61 72 65 20 75 73 65 64 20 74 6f 20 70 72 65 76  are used to prev
13320 65 6e 74 20 74 68 65 20 63 6f 6d 70 69 6c 65 72  ent the compiler
13330 20 6f 72 20 74 68 65 20 68 61 72 64 77 61 72 65   or the hardware
13340 20 66 72 6f 6d 0a 20 20 2a 2a 20 72 65 6f 72 64   from.  ** reord
13350 65 72 69 6e 67 20 74 68 65 20 72 65 61 64 73 20  ering the reads 
13360 61 6e 64 20 77 72 69 74 65 73 2e 0a 20 20 2a 2f  and writes..  */
13370 0a 20 20 61 48 64 72 20 3d 20 77 61 6c 49 6e 64  .  aHdr = walInd
13380 65 78 48 64 72 28 70 57 61 6c 29 3b 0a 20 20 6d  exHdr(pWal);.  m
13390 65 6d 63 70 79 28 26 68 31 2c 20 28 76 6f 69 64  emcpy(&h1, (void
133a0 20 2a 29 26 61 48 64 72 5b 30 5d 2c 20 73 69 7a   *)&aHdr[0], siz
133b0 65 6f 66 28 68 31 29 29 3b 0a 20 20 77 61 6c 53  eof(h1));.  walS
133c0 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c 29 3b  hmBarrier(pWal);
133d0 0a 20 20 6d 65 6d 63 70 79 28 26 68 32 2c 20 28  .  memcpy(&h2, (
133e0 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 31 5d 2c  void *)&aHdr[1],
133f0 20 73 69 7a 65 6f 66 28 68 32 29 29 3b 0a 0a 20   sizeof(h2));.. 
13400 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 68 31 2c   if( memcmp(&h1,
13410 20 26 68 32 2c 20 73 69 7a 65 6f 66 28 68 31 29   &h2, sizeof(h1)
13420 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )!=0 ){.    retu
13430 72 6e 20 31 3b 20 20 20 2f 2a 20 44 69 72 74 79  rn 1;   /* Dirty
13440 20 72 65 61 64 20 2a 2f 0a 20 20 7d 20 20 0a 20   read */.  }  . 
13450 20 69 66 28 20 68 31 2e 69 73 49 6e 69 74 3d 3d   if( h1.isInit==
13460 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  0 ){.    return 
13470 31 3b 20 20 20 2f 2a 20 4d 61 6c 66 6f 72 6d 65  1;   /* Malforme
13480 64 20 68 65 61 64 65 72 20 2d 20 70 72 6f 62 61  d header - proba
13490 62 6c 79 20 61 6c 6c 20 7a 65 72 6f 73 20 2a 2f  bly all zeros */
134a0 0a 20 20 7d 0a 20 20 77 61 6c 43 68 65 63 6b 73  .  }.  walChecks
134b0 75 6d 42 79 74 65 73 28 31 2c 20 28 75 38 2a 29  umBytes(1, (u8*)
134c0 26 68 31 2c 20 73 69 7a 65 6f 66 28 68 31 29 2d  &h1, sizeof(h1)-
134d0 73 69 7a 65 6f 66 28 68 31 2e 61 43 6b 73 75 6d  sizeof(h1.aCksum
134e0 29 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b 0a 20  ), 0, aCksum);. 
134f0 20 69 66 28 20 61 43 6b 73 75 6d 5b 30 5d 21 3d   if( aCksum[0]!=
13500 68 31 2e 61 43 6b 73 75 6d 5b 30 5d 20 7c 7c 20  h1.aCksum[0] || 
13510 61 43 6b 73 75 6d 5b 31 5d 21 3d 68 31 2e 61 43  aCksum[1]!=h1.aC
13520 6b 73 75 6d 5b 31 5d 20 29 7b 0a 20 20 20 20 72  ksum[1] ){.    r
13530 65 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20 43 68  eturn 1;   /* Ch
13540 65 63 6b 73 75 6d 20 64 6f 65 73 20 6e 6f 74 20  ecksum does not 
13550 6d 61 74 63 68 20 2a 2f 0a 20 20 7d 0a 0a 20 20  match */.  }..  
13560 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c  if( memcmp(&pWal
13570 2d 3e 68 64 72 2c 20 26 68 31 2c 20 73 69 7a 65  ->hdr, &h1, size
13580 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
13590 20 29 7b 0a 20 20 20 20 2a 70 43 68 61 6e 67 65   ){.    *pChange
135a0 64 20 3d 20 31 3b 0a 20 20 20 20 6d 65 6d 63 70  d = 1;.    memcp
135b0 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 26 68  y(&pWal->hdr, &h
135c0 31 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64  1, sizeof(WalInd
135d0 65 78 48 64 72 29 29 3b 0a 20 20 20 20 70 57 61  exHdr));.    pWa
135e0 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 28 70 57 61  l->szPage = (pWa
135f0 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26 30 78  l->hdr.szPage&0x
13600 66 65 30 30 29 20 2b 20 28 28 70 57 61 6c 2d 3e  fe00) + ((pWal->
13610 68 64 72 2e 73 7a 50 61 67 65 26 30 78 30 30 30  hdr.szPage&0x000
13620 31 29 3c 3c 31 36 29 3b 0a 20 20 20 20 74 65 73  1)<<16);.    tes
13630 74 63 61 73 65 28 20 70 57 61 6c 2d 3e 73 7a 50  tcase( pWal->szP
13640 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20  age<=32768 );.  
13650 20 20 74 65 73 74 63 61 73 65 28 20 70 57 61 6c    testcase( pWal
13660 2d 3e 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20  ->szPage>=65536 
13670 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 68 65  );.  }..  /* The
13680 20 68 65 61 64 65 72 20 77 61 73 20 73 75 63 63   header was succ
13690 65 73 73 66 75 6c 6c 79 20 72 65 61 64 2e 20 52  essfully read. R
136a0 65 74 75 72 6e 20 7a 65 72 6f 2e 20 2a 2f 0a 20  eturn zero. */. 
136b0 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a   return 0;.}../*
136c0 0a 2a 2a 20 52 65 61 64 20 74 68 65 20 77 61 6c  .** Read the wal
136d0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 66 72  -index header fr
136e0 6f 6d 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  om the wal-index
136f0 20 61 6e 64 20 69 6e 74 6f 20 70 57 61 6c 2d 3e   and into pWal->
13700 68 64 72 2e 0a 2a 2a 20 49 66 20 74 68 65 20 77  hdr..** If the w
13710 61 6c 2d 68 65 61 64 65 72 20 61 70 70 65 61 72  al-header appear
13720 73 20 74 6f 20 62 65 20 63 6f 72 72 75 70 74 2c  s to be corrupt,
13730 20 74 72 79 20 74 6f 20 72 65 63 6f 6e 73 74 72   try to reconstr
13740 75 63 74 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69  uct the.** wal-i
13750 6e 64 65 78 20 66 72 6f 6d 20 74 68 65 20 57 41  ndex from the WA
13760 4c 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69  L before returni
13770 6e 67 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20 2a 70  ng..**.** Set *p
13780 43 68 61 6e 67 65 64 20 74 6f 20 31 20 69 66 20  Changed to 1 if 
13790 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
137a0 61 64 65 72 20 76 61 6c 75 65 20 69 6e 20 70 57  ader value in pW
137b0 61 6c 2d 3e 68 64 72 20 69 73 0a 2a 2a 20 63 68  al->hdr is.** ch
137c0 61 6e 67 65 64 20 62 79 20 74 68 69 73 20 6f 70  anged by this op
137d0 65 72 61 74 69 6f 6e 2e 20 20 49 66 20 70 57 61  eration.  If pWa
137e0 6c 2d 3e 68 64 72 20 69 73 20 75 6e 63 68 61 6e  l->hdr is unchan
137f0 67 65 64 2c 20 73 65 74 20 2a 70 43 68 61 6e 67  ged, set *pChang
13800 65 64 0a 2a 2a 20 74 6f 20 30 2e 0a 2a 2a 0a 2a  ed.** to 0..**.*
13810 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  * If the wal-ind
13820 65 78 20 68 65 61 64 65 72 20 69 73 20 73 75 63  ex header is suc
13830 63 65 73 73 66 75 6c 6c 79 20 72 65 61 64 2c 20  cessfully read, 
13840 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
13850 2e 20 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 20  . .** Otherwise 
13860 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
13870 63 6f 64 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  code..*/.static 
13880 69 6e 74 20 77 61 6c 49 6e 64 65 78 52 65 61 64  int walIndexRead
13890 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69  Hdr(Wal *pWal, i
138a0 6e 74 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a 20  nt *pChanged){. 
138b0 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
138c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
138d0 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
138e0 2a 2f 0a 20 20 69 6e 74 20 62 61 64 48 64 72 3b  */.  int badHdr;
138f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13900 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
13910 61 20 68 65 61 64 65 72 20 72 65 61 64 20 66 61  a header read fa
13920 69 6c 65 64 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  iled */.  volati
13930 6c 65 20 75 33 32 20 2a 70 61 67 65 30 3b 20 20  le u32 *page0;  
13940 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 75            /* Chu
13950 6e 6b 20 6f 66 20 77 61 6c 2d 69 6e 64 65 78 20  nk of wal-index 
13960 63 6f 6e 74 61 69 6e 69 6e 67 20 68 65 61 64 65  containing heade
13970 72 20 2a 2f 0a 0a 20 20 2f 2a 20 45 6e 73 75 72  r */..  /* Ensur
13980 65 20 74 68 61 74 20 70 61 67 65 20 30 20 6f 66  e that page 0 of
13990 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 28   the wal-index (
139a0 74 68 65 20 70 61 67 65 20 74 68 61 74 20 63 6f  the page that co
139b0 6e 74 61 69 6e 73 20 74 68 65 20 0a 20 20 2a 2a  ntains the .  **
139c0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
139d0 72 29 20 69 73 20 6d 61 70 70 65 64 2e 20 52 65  r) is mapped. Re
139e0 74 75 72 6e 20 65 61 72 6c 79 20 69 66 20 61 6e  turn early if an
139f0 20 65 72 72 6f 72 20 6f 63 63 75 72 73 20 68 65   error occurs he
13a00 72 65 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72  re..  */.  asser
13a10 74 28 20 70 43 68 61 6e 67 65 64 20 29 3b 0a 20  t( pChanged );. 
13a20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 50 61   rc = walIndexPa
13a30 67 65 28 70 57 61 6c 2c 20 30 2c 20 26 70 61 67  ge(pWal, 0, &pag
13a40 65 30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  e0);.  if( rc!=S
13a50 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
13a60 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 3b 0a  return rc;.  };.
13a70 20 20 61 73 73 65 72 74 28 20 70 61 67 65 30 20    assert( page0 
13a80 7c 7c 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  || pWal->writeLo
13a90 63 6b 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 49  ck==0 );..  /* I
13aa0 66 20 74 68 65 20 66 69 72 73 74 20 70 61 67 65  f the first page
13ab0 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
13ac0 78 20 68 61 73 20 62 65 65 6e 20 6d 61 70 70 65  x has been mappe
13ad0 64 2c 20 74 72 79 20 74 6f 20 72 65 61 64 20 74  d, try to read t
13ae0 68 65 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65  he.  ** wal-inde
13af0 78 20 68 65 61 64 65 72 20 69 6d 6d 65 64 69 61  x header immedia
13b00 74 65 6c 79 2c 20 77 69 74 68 6f 75 74 20 68 6f  tely, without ho
13b10 6c 64 69 6e 67 20 61 6e 79 20 6c 6f 63 6b 2e 20  lding any lock. 
13b20 54 68 69 73 20 75 73 75 61 6c 6c 79 0a 20 20 2a  This usually.  *
13b30 2a 20 77 6f 72 6b 73 2c 20 62 75 74 20 6d 61 79  * works, but may
13b40 20 66 61 69 6c 20 69 66 20 74 68 65 20 77 61 6c   fail if the wal
13b50 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73  -index header is
13b60 20 63 6f 72 72 75 70 74 20 6f 72 20 63 75 72 72   corrupt or curr
13b70 65 6e 74 6c 79 20 0a 20 20 2a 2a 20 62 65 69 6e  ently .  ** bein
13b80 67 20 6d 6f 64 69 66 69 65 64 20 62 79 20 61 6e  g modified by an
13b90 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f 72 20  other thread or 
13ba0 70 72 6f 63 65 73 73 2e 0a 20 20 2a 2f 0a 20 20  process..  */.  
13bb0 62 61 64 48 64 72 20 3d 20 28 70 61 67 65 30 20  badHdr = (page0 
13bc0 3f 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64 72  ? walIndexTryHdr
13bd0 28 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 29  (pWal, pChanged)
13be0 20 3a 20 31 29 3b 0a 0a 20 20 2f 2a 20 49 66 20   : 1);..  /* If 
13bf0 74 68 65 20 66 69 72 73 74 20 61 74 74 65 6d 70  the first attemp
13c00 74 20 66 61 69 6c 65 64 2c 20 69 74 20 6d 69 67  t failed, it mig
13c10 68 74 20 68 61 76 65 20 62 65 65 6e 20 64 75 65  ht have been due
13c20 20 74 6f 20 61 20 72 61 63 65 0a 20 20 2a 2a 20   to a race.  ** 
13c30 77 69 74 68 20 61 20 77 72 69 74 65 72 2e 20 20  with a writer.  
13c40 53 6f 20 67 65 74 20 61 20 57 52 49 54 45 20 6c  So get a WRITE l
13c50 6f 63 6b 20 61 6e 64 20 74 72 79 20 61 67 61 69  ock and try agai
13c60 6e 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74  n..  */.  assert
13c70 28 20 62 61 64 48 64 72 3d 3d 30 20 7c 7c 20 70  ( badHdr==0 || p
13c80 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d  Wal->writeLock==
13c90 30 20 29 3b 0a 20 20 69 66 28 20 62 61 64 48 64  0 );.  if( badHd
13ca0 72 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57 61  r ){.    if( pWa
13cb0 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57 41  l->readOnly & WA
13cc0 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 20 29 7b 0a  L_SHM_RDONLY ){.
13cd0 20 20 20 20 20 20 69 66 28 20 53 51 4c 49 54 45        if( SQLITE
13ce0 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c 4c 6f  _OK==(rc = walLo
13cf0 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
13d00 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 29 29 20  AL_WRITE_LOCK)) 
13d10 29 7b 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e  ){.        walUn
13d20 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  lockShared(pWal,
13d30 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 29   WAL_WRITE_LOCK)
13d40 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53  ;.        rc = S
13d50 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 5f 52  QLITE_READONLY_R
13d60 45 43 4f 56 45 52 59 3b 0a 20 20 20 20 20 20 7d  ECOVERY;.      }
13d70 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 53  .    }else if( S
13d80 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20  QLITE_OK==(rc = 
13d90 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65  walLockExclusive
13da0 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45  (pWal, WAL_WRITE
13db0 5f 4c 4f 43 4b 2c 20 31 29 29 20 29 7b 0a 20 20  _LOCK, 1)) ){.  
13dc0 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c      pWal->writeL
13dd0 6f 63 6b 20 3d 20 31 3b 0a 20 20 20 20 20 20 69  ock = 1;.      i
13de0 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72  f( SQLITE_OK==(r
13df0 63 20 3d 20 77 61 6c 49 6e 64 65 78 50 61 67 65  c = walIndexPage
13e00 28 70 57 61 6c 2c 20 30 2c 20 26 70 61 67 65 30  (pWal, 0, &page0
13e10 29 29 20 29 7b 0a 20 20 20 20 20 20 20 20 62 61  )) ){.        ba
13e20 64 48 64 72 20 3d 20 77 61 6c 49 6e 64 65 78 54  dHdr = walIndexT
13e30 72 79 48 64 72 28 70 57 61 6c 2c 20 70 43 68 61  ryHdr(pWal, pCha
13e40 6e 67 65 64 29 3b 0a 20 20 20 20 20 20 20 20 69  nged);.        i
13e50 66 28 20 62 61 64 48 64 72 20 29 7b 0a 20 20 20  f( badHdr ){.   
13e60 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65         /* If the
13e70 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
13e80 72 20 69 73 20 73 74 69 6c 6c 20 6d 61 6c 66 6f  r is still malfo
13e90 72 6d 65 64 20 65 76 65 6e 20 77 68 69 6c 65 20  rmed even while 
13ea0 68 6f 6c 64 69 6e 67 0a 20 20 20 20 20 20 20 20  holding.        
13eb0 20 20 2a 2a 20 61 20 57 52 49 54 45 20 6c 6f 63    ** a WRITE loc
13ec0 6b 2c 20 69 74 20 63 61 6e 20 6f 6e 6c 79 20 6d  k, it can only m
13ed0 65 61 6e 20 74 68 61 74 20 74 68 65 20 68 65 61  ean that the hea
13ee0 64 65 72 20 69 73 20 63 6f 72 72 75 70 74 65 64  der is corrupted
13ef0 20 61 6e 64 0a 20 20 20 20 20 20 20 20 20 20 2a   and.          *
13f00 2a 20 6e 65 65 64 73 20 74 6f 20 62 65 20 72 65  * needs to be re
13f10 63 6f 6e 73 74 72 75 63 74 65 64 2e 20 20 53 6f  constructed.  So
13f20 20 72 75 6e 20 72 65 63 6f 76 65 72 79 20 74 6f   run recovery to
13f30 20 64 6f 20 65 78 61 63 74 6c 79 20 74 68 61 74   do exactly that
13f40 2e 0a 20 20 20 20 20 20 20 20 20 20 2a 2f 0a 20  ..          */. 
13f50 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 77 61           rc = wa
13f60 6c 49 6e 64 65 78 52 65 63 6f 76 65 72 28 70 57  lIndexRecover(pW
13f70 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20 2a  al);.          *
13f80 70 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20  pChanged = 1;.  
13f90 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
13fa0 20 20 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74        pWal->writ
13fb0 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 20  eLock = 0;.     
13fc0 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
13fd0 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52  ive(pWal, WAL_WR
13fe0 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20  ITE_LOCK, 1);.  
13ff0 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66    }.  }..  /* If
14000 20 74 68 65 20 68 65 61 64 65 72 20 69 73 20 72   the header is r
14010 65 61 64 20 73 75 63 63 65 73 73 66 75 6c 6c 79  ead successfully
14020 2c 20 63 68 65 63 6b 20 74 68 65 20 76 65 72 73  , check the vers
14030 69 6f 6e 20 6e 75 6d 62 65 72 20 74 6f 20 6d 61  ion number to ma
14040 6b 65 0a 20 20 2a 2a 20 73 75 72 65 20 74 68 65  ke.  ** sure the
14050 20 77 61 6c 2d 69 6e 64 65 78 20 77 61 73 20 6e   wal-index was n
14060 6f 74 20 63 6f 6e 73 74 72 75 63 74 65 64 20 77  ot constructed w
14070 69 74 68 20 73 6f 6d 65 20 66 75 74 75 72 65 20  ith some future 
14080 66 6f 72 6d 61 74 20 74 68 61 74 0a 20 20 2a 2a  format that.  **
14090 20 74 68 69 73 20 76 65 72 73 69 6f 6e 20 6f 66   this version of
140a0 20 53 51 4c 69 74 65 20 63 61 6e 6e 6f 74 20 75   SQLite cannot u
140b0 6e 64 65 72 73 74 61 6e 64 2e 0a 20 20 2a 2f 0a  nderstand..  */.
140c0 20 20 69 66 28 20 62 61 64 48 64 72 3d 3d 30 20    if( badHdr==0 
140d0 26 26 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56 65  && pWal->hdr.iVe
140e0 72 73 69 6f 6e 21 3d 57 41 4c 49 4e 44 45 58 5f  rsion!=WALINDEX_
140f0 4d 41 58 5f 56 45 52 53 49 4f 4e 20 29 7b 0a 20  MAX_VERSION ){. 
14100 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43     rc = SQLITE_C
14110 41 4e 54 4f 50 45 4e 5f 42 4b 50 54 3b 0a 20 20  ANTOPEN_BKPT;.  
14120 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
14130 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73  }../*.** This is
14140 20 74 68 65 20 76 61 6c 75 65 20 74 68 61 74 20   the value that 
14150 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64 20  walTryBeginRead 
14160 72 65 74 75 72 6e 73 20 77 68 65 6e 20 69 74 20  returns when it 
14170 6e 65 65 64 73 20 74 6f 0a 2a 2a 20 62 65 20 72  needs to.** be r
14180 65 74 72 69 65 64 2e 0a 2a 2f 0a 23 64 65 66 69  etried..*/.#defi
14190 6e 65 20 57 41 4c 5f 52 45 54 52 59 20 20 28 2d  ne WAL_RETRY  (-
141a0 31 29 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70  1)../*.** Attemp
141b0 74 20 74 6f 20 73 74 61 72 74 20 61 20 72 65 61  t to start a rea
141c0 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 20  d transaction.  
141d0 54 68 69 73 20 6d 69 67 68 74 20 66 61 69 6c 20  This might fail 
141e0 64 75 65 20 74 6f 20 61 20 72 61 63 65 20 6f 72  due to a race or
141f0 0a 2a 2a 20 6f 74 68 65 72 20 74 72 61 6e 73 69  .** other transi
14200 65 6e 74 20 63 6f 6e 64 69 74 69 6f 6e 2e 20 20  ent condition.  
14210 57 68 65 6e 20 74 68 61 74 20 68 61 70 70 65 6e  When that happen
14220 73 2c 20 69 74 20 72 65 74 75 72 6e 73 20 57 41  s, it returns WA
14230 4c 5f 52 45 54 52 59 20 74 6f 0a 2a 2a 20 69 6e  L_RETRY to.** in
14240 64 69 63 61 74 65 20 74 6f 20 74 68 65 20 63 61  dicate to the ca
14250 6c 6c 65 72 20 74 68 61 74 20 69 74 20 69 73 20  ller that it is 
14260 73 61 66 65 20 74 6f 20 72 65 74 72 79 20 69 6d  safe to retry im
14270 6d 65 64 69 61 74 65 6c 79 2e 0a 2a 2a 0a 2a 2a  mediately..**.**
14280 20 4f 6e 20 73 75 63 63 65 73 73 20 72 65 74 75   On success retu
14290 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 20 4f  rn SQLITE_OK.  O
142a0 6e 20 61 20 70 65 72 6d 61 6e 65 6e 74 20 66 61  n a permanent fa
142b0 69 6c 75 72 65 20 28 73 75 63 68 20 61 6e 0a 2a  ilure (such an.*
142c0 2a 20 49 2f 4f 20 65 72 72 6f 72 20 6f 72 20 61  * I/O error or a
142d0 6e 20 53 51 4c 49 54 45 5f 42 55 53 59 20 62 65  n SQLITE_BUSY be
142e0 63 61 75 73 65 20 61 6e 6f 74 68 65 72 20 70 72  cause another pr
142f0 6f 63 65 73 73 20 69 73 20 72 75 6e 6e 69 6e 67  ocess is running
14300 0a 2a 2a 20 72 65 63 6f 76 65 72 79 29 20 72 65  .** recovery) re
14310 74 75 72 6e 20 61 20 70 6f 73 69 74 69 76 65 20  turn a positive 
14320 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a  error code..**.*
14330 2a 20 54 68 65 20 75 73 65 57 61 6c 20 70 61 72  * The useWal par
14340 61 6d 65 74 65 72 20 69 73 20 74 72 75 65 20 74  ameter is true t
14350 6f 20 66 6f 72 63 65 20 74 68 65 20 75 73 65 20  o force the use 
14360 6f 66 20 74 68 65 20 57 41 4c 20 61 6e 64 20 64  of the WAL and d
14370 69 73 61 62 6c 65 0a 2a 2a 20 74 68 65 20 63 61  isable.** the ca
14380 73 65 20 77 68 65 72 65 20 74 68 65 20 57 41 4c  se where the WAL
14390 20 69 73 20 62 79 70 61 73 73 65 64 20 62 65 63   is bypassed bec
143a0 61 75 73 65 20 69 74 20 68 61 73 20 62 65 65 6e  ause it has been
143b0 20 63 6f 6d 70 6c 65 74 65 6c 79 0a 2a 2a 20 63   completely.** c
143c0 68 65 63 6b 70 6f 69 6e 74 65 64 2e 20 20 49 66  heckpointed.  If
143d0 20 75 73 65 57 61 6c 3d 3d 30 20 74 68 65 6e 20   useWal==0 then 
143e0 74 68 69 73 20 72 6f 75 74 69 6e 65 20 63 61 6c  this routine cal
143f0 6c 73 20 77 61 6c 49 6e 64 65 78 52 65 61 64 48  ls walIndexReadH
14400 64 72 28 29 20 0a 2a 2a 20 74 6f 20 6d 61 6b 65  dr() .** to make
14410 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 77   a copy of the w
14420 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
14430 69 6e 74 6f 20 70 57 61 6c 2d 3e 68 64 72 2e 20  into pWal->hdr. 
14440 20 49 66 20 74 68 65 20 0a 2a 2a 20 77 61 6c 2d   If the .** wal-
14450 69 6e 64 65 78 20 68 65 61 64 65 72 20 68 61 73  index header has
14460 20 63 68 61 6e 67 65 64 2c 20 2a 70 43 68 61 6e   changed, *pChan
14470 67 65 64 20 69 73 20 73 65 74 20 74 6f 20 31 20  ged is set to 1 
14480 28 61 73 20 61 6e 20 69 6e 64 69 63 61 74 69 6f  (as an indicatio
14490 6e 20 0a 2a 2a 20 74 6f 20 74 68 65 20 63 61 6c  n .** to the cal
144a0 6c 65 72 20 74 68 61 74 20 74 68 65 20 6c 6f 63  ler that the loc
144b0 61 6c 20 70 61 67 65 74 20 63 61 63 68 65 20 69  al paget cache i
144c0 73 20 6f 62 73 6f 6c 65 74 65 20 61 6e 64 20 6e  s obsolete and n
144d0 65 65 64 73 20 74 6f 20 62 65 20 0a 2a 2a 20 66  eeds to be .** f
144e0 6c 75 73 68 65 64 2e 29 20 20 57 68 65 6e 20 75  lushed.)  When u
144f0 73 65 57 61 6c 3d 3d 31 2c 20 74 68 65 20 77 61  seWal==1, the wa
14500 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69  l-index header i
14510 73 20 61 73 73 75 6d 65 64 20 74 6f 20 61 6c 72  s assumed to alr
14520 65 61 64 79 0a 2a 2a 20 62 65 20 6c 6f 61 64 65  eady.** be loade
14530 64 20 61 6e 64 20 74 68 65 20 70 43 68 61 6e 67  d and the pChang
14540 65 64 20 70 61 72 61 6d 65 74 65 72 20 69 73 20  ed parameter is 
14550 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68  unused..**.** Th
14560 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 73 65  e caller must se
14570 74 20 74 68 65 20 63 6e 74 20 70 61 72 61 6d 65  t the cnt parame
14580 74 65 72 20 74 6f 20 74 68 65 20 6e 75 6d 62 65  ter to the numbe
14590 72 20 6f 66 20 70 72 69 6f 72 20 63 61 6c 6c 73  r of prior calls
145a0 20 74 6f 0a 2a 2a 20 74 68 69 73 20 72 6f 75 74   to.** this rout
145b0 69 6e 65 20 64 75 72 69 6e 67 20 74 68 65 20 63  ine during the c
145c0 75 72 72 65 6e 74 20 72 65 61 64 20 61 74 74 65  urrent read atte
145d0 6d 70 74 20 74 68 61 74 20 72 65 74 75 72 6e 65  mpt that returne
145e0 64 20 57 41 4c 5f 52 45 54 52 59 2e 0a 2a 2a 20  d WAL_RETRY..** 
145f0 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c  This routine wil
14600 6c 20 73 74 61 72 74 20 74 61 6b 69 6e 67 20 6d  l start taking m
14610 6f 72 65 20 61 67 67 72 65 73 73 69 76 65 20 6d  ore aggressive m
14620 65 61 73 75 72 65 73 20 74 6f 20 63 6c 65 61 72  easures to clear
14630 20 74 68 65 0a 2a 2a 20 72 61 63 65 20 63 6f 6e   the.** race con
14640 64 69 74 69 6f 6e 73 20 61 66 74 65 72 20 6d 75  ditions after mu
14650 6c 74 69 70 6c 65 20 57 41 4c 5f 52 45 54 52 59  ltiple WAL_RETRY
14660 20 72 65 74 75 72 6e 73 2c 20 61 6e 64 20 61 66   returns, and af
14670 74 65 72 20 61 6e 20 65 78 63 65 73 73 69 76 65  ter an excessive
14680 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 65 72  .** number of er
14690 72 6f 72 73 20 77 69 6c 6c 20 75 6c 74 69 6d 61  rors will ultima
146a0 74 65 6c 79 20 72 65 74 75 72 6e 20 53 51 4c 49  tely return SQLI
146b0 54 45 5f 50 52 4f 54 4f 43 4f 4c 2e 20 20 54 68  TE_PROTOCOL.  Th
146c0 65 0a 2a 2a 20 53 51 4c 49 54 45 5f 50 52 4f 54  e.** SQLITE_PROT
146d0 4f 43 4f 4c 20 72 65 74 75 72 6e 20 69 6e 64 69  OCOL return indi
146e0 63 61 74 65 73 20 74 68 61 74 20 73 6f 6d 65 20  cates that some 
146f0 6f 74 68 65 72 20 70 72 6f 63 65 73 73 20 68 61  other process ha
14700 73 20 67 6f 6e 65 20 72 6f 67 75 65 0a 2a 2a 20  s gone rogue.** 
14710 61 6e 64 20 69 73 20 6e 6f 74 20 68 6f 6e 6f 72  and is not honor
14720 69 6e 67 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20  ing the locking 
14730 70 72 6f 74 6f 63 6f 6c 2e 20 20 54 68 65 72 65  protocol.  There
14740 20 69 73 20 61 20 76 61 6e 69 73 68 69 6e 67 6c   is a vanishingl
14750 79 20 73 6d 61 6c 6c 0a 2a 2a 20 63 68 61 6e 63  y small.** chanc
14760 65 20 74 68 61 74 20 53 51 4c 49 54 45 5f 50 52  e that SQLITE_PR
14770 4f 54 4f 43 4f 4c 20 63 6f 75 6c 64 20 62 65 20  OTOCOL could be 
14780 72 65 74 75 72 6e 65 64 20 62 65 63 61 75 73 65  returned because
14790 20 6f 66 20 61 20 72 75 6e 20 6f 66 20 72 65 61   of a run of rea
147a0 6c 6c 79 0a 2a 2a 20 62 61 64 20 6c 75 63 6b 20  lly.** bad luck 
147b0 77 68 65 6e 20 74 68 65 72 65 20 69 73 20 6c 6f  when there is lo
147c0 74 73 20 6f 66 20 63 6f 6e 74 65 6e 74 69 6f 6e  ts of contention
147d0 20 66 6f 72 20 74 68 65 20 77 61 6c 2d 69 6e 64   for the wal-ind
147e0 65 78 2c 20 62 75 74 20 74 68 61 74 0a 2a 2a 20  ex, but that.** 
147f0 70 6f 73 73 69 62 69 6c 69 74 79 20 69 73 20 73  possibility is s
14800 6f 20 73 6d 61 6c 6c 20 74 68 61 74 20 69 74 20  o small that it 
14810 63 61 6e 20 62 65 20 73 61 66 65 6c 79 20 6e 65  can be safely ne
14820 67 6c 65 63 74 65 64 2c 20 77 65 20 62 65 6c 69  glected, we beli
14830 65 76 65 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75  eve..**.** On su
14840 63 63 65 73 73 2c 20 74 68 69 73 20 72 6f 75 74  ccess, this rout
14850 69 6e 65 20 6f 62 74 61 69 6e 73 20 61 20 72 65  ine obtains a re
14860 61 64 20 6c 6f 63 6b 20 6f 6e 20 0a 2a 2a 20 57  ad lock on .** W
14870 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61  AL_READ_LOCK(pWa
14880 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 2e 20 20 54  l->readLock).  T
14890 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  he pWal->readLoc
148a0 6b 20 69 6e 74 65 67 65 72 20 69 73 0a 2a 2a 20  k integer is.** 
148b0 69 6e 20 74 68 65 20 72 61 6e 67 65 20 30 20 3c  in the range 0 <
148c0 3d 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  = pWal->readLock
148d0 20 3c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2e 20   < WAL_NREADER. 
148e0 20 49 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f   If pWal->readLo
148f0 63 6b 3d 3d 28 2d 31 29 0a 2a 2a 20 74 68 61 74  ck==(-1).** that
14900 20 6d 65 61 6e 73 20 74 68 65 20 57 61 6c 20 64   means the Wal d
14910 6f 65 73 20 6e 6f 74 20 68 6f 6c 64 20 61 6e 79  oes not hold any
14920 20 72 65 61 64 20 6c 6f 63 6b 2e 20 20 54 68 65   read lock.  The
14930 20 72 65 61 64 65 72 20 6d 75 73 74 20 6e 6f 74   reader must not
14940 0a 2a 2a 20 61 63 63 65 73 73 20 61 6e 79 20 64  .** access any d
14950 61 74 61 62 61 73 65 20 70 61 67 65 20 74 68 61  atabase page tha
14960 74 20 69 73 20 6d 6f 64 69 66 69 65 64 20 62 79  t is modified by
14970 20 61 20 57 41 4c 20 66 72 61 6d 65 20 75 70 20   a WAL frame up 
14980 74 6f 20 61 6e 64 0a 2a 2a 20 69 6e 63 6c 75 64  to and.** includ
14990 69 6e 67 20 66 72 61 6d 65 20 6e 75 6d 62 65 72  ing frame number
149a0 20 61 52 65 61 64 4d 61 72 6b 5b 70 57 61 6c 2d   aReadMark[pWal-
149b0 3e 72 65 61 64 4c 6f 63 6b 5d 2e 20 20 54 68 65  >readLock].  The
149c0 20 72 65 61 64 65 72 20 77 69 6c 6c 0a 2a 2a 20   reader will.** 
149d0 75 73 65 20 57 41 4c 20 66 72 61 6d 65 73 20 75  use WAL frames u
149e0 70 20 74 6f 20 61 6e 64 20 69 6e 63 6c 75 64 69  p to and includi
149f0 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ng pWal->hdr.mxF
14a00 72 61 6d 65 20 69 66 20 70 57 61 6c 2d 3e 72 65  rame if pWal->re
14a10 61 64 4c 6f 63 6b 3e 30 0a 2a 2a 20 4f 72 20 69  adLock>0.** Or i
14a20 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  f pWal->readLock
14a30 3d 3d 30 2c 20 74 68 65 6e 20 74 68 65 20 72 65  ==0, then the re
14a40 61 64 65 72 20 77 69 6c 6c 20 69 67 6e 6f 72 65  ader will ignore
14a50 20 74 68 65 20 57 41 4c 0a 2a 2a 20 63 6f 6d 70   the WAL.** comp
14a60 6c 65 74 65 6c 79 20 61 6e 64 20 67 65 74 20 61  letely and get a
14a70 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72 65 63  ll content direc
14a80 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61 74  tly from the dat
14a90 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 20 49  abase file..** I
14aa0 66 20 74 68 65 20 75 73 65 57 61 6c 20 70 61 72  f the useWal par
14ab0 61 6d 65 74 65 72 20 69 73 20 31 20 74 68 65 6e  ameter is 1 then
14ac0 20 74 68 65 20 57 41 4c 20 77 69 6c 6c 20 6e 65   the WAL will ne
14ad0 76 65 72 20 62 65 20 69 67 6e 6f 72 65 64 20 61  ver be ignored a
14ae0 6e 64 0a 2a 2a 20 74 68 69 73 20 72 6f 75 74 69  nd.** this routi
14af0 6e 65 20 77 69 6c 6c 20 61 6c 77 61 79 73 20 73  ne will always s
14b00 65 74 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  et pWal->readLoc
14b10 6b 3e 30 20 6f 6e 20 73 75 63 63 65 73 73 2e 0a  k>0 on success..
14b20 2a 2a 20 57 68 65 6e 20 74 68 65 20 72 65 61 64  ** When the read
14b30 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20   transaction is 
14b40 63 6f 6d 70 6c 65 74 65 64 2c 20 74 68 65 20 63  completed, the c
14b50 61 6c 6c 65 72 20 6d 75 73 74 20 72 65 6c 65 61  aller must relea
14b60 73 65 20 74 68 65 0a 2a 2a 20 6c 6f 63 6b 20 6f  se the.** lock o
14b70 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  n WAL_READ_LOCK(
14b80 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 20  pWal->readLock) 
14b90 61 6e 64 20 73 65 74 20 70 57 61 6c 2d 3e 72 65  and set pWal->re
14ba0 61 64 4c 6f 63 6b 20 74 6f 20 2d 31 2e 0a 2a 2a  adLock to -1..**
14bb0 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
14bc0 20 75 73 65 73 20 74 68 65 20 6e 42 61 63 6b 66   uses the nBackf
14bd0 69 6c 6c 20 61 6e 64 20 61 52 65 61 64 4d 61 72  ill and aReadMar
14be0 6b 5b 5d 20 66 69 65 6c 64 73 20 6f 66 20 74 68  k[] fields of th
14bf0 65 20 68 65 61 64 65 72 0a 2a 2a 20 74 6f 20 73  e header.** to s
14c00 65 6c 65 63 74 20 61 20 70 61 72 74 69 63 75 6c  elect a particul
14c10 61 72 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  ar WAL_READ_LOCK
14c20 28 29 20 74 68 61 74 20 73 74 72 69 76 65 73 20  () that strives 
14c30 74 6f 20 6c 65 74 20 74 68 65 0a 2a 2a 20 63 68  to let the.** ch
14c40 65 63 6b 70 6f 69 6e 74 20 70 72 6f 63 65 73 73  eckpoint process
14c50 20 64 6f 20 61 73 20 6d 75 63 68 20 77 6f 72 6b   do as much work
14c60 20 61 73 20 70 6f 73 73 69 62 6c 65 2e 20 20 54   as possible.  T
14c70 68 69 73 20 72 6f 75 74 69 6e 65 20 6d 69 67 68  his routine migh
14c80 74 0a 2a 2a 20 75 70 64 61 74 65 20 76 61 6c 75  t.** update valu
14c90 65 73 20 6f 66 20 74 68 65 20 61 52 65 61 64 4d  es of the aReadM
14ca0 61 72 6b 5b 5d 20 61 72 72 61 79 20 69 6e 20 74  ark[] array in t
14cb0 68 65 20 68 65 61 64 65 72 2c 20 62 75 74 20 69  he header, but i
14cc0 66 20 69 74 20 64 6f 65 73 0a 2a 2a 20 73 6f 20  f it does.** so 
14cd0 69 74 20 74 61 6b 65 73 20 63 61 72 65 20 74 6f  it takes care to
14ce0 20 68 6f 6c 64 20 61 6e 20 65 78 63 6c 75 73 69   hold an exclusi
14cf0 76 65 20 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 63  ve lock on the c
14d00 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20  orresponding.** 
14d10 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 29 20  WAL_READ_LOCK() 
14d20 77 68 69 6c 65 20 63 68 61 6e 67 69 6e 67 20 76  while changing v
14d30 61 6c 75 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  alues..*/.static
14d40 20 69 6e 74 20 77 61 6c 54 72 79 42 65 67 69 6e   int walTryBegin
14d50 52 65 61 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Read(Wal *pWal, 
14d60 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 2c 20 69  int *pChanged, i
14d70 6e 74 20 75 73 65 57 61 6c 2c 20 69 6e 74 20 63  nt useWal, int c
14d80 6e 74 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20  nt){.  volatile 
14d90 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e  WalCkptInfo *pIn
14da0 66 6f 3b 20 20 20 20 2f 2a 20 43 68 65 63 6b 70  fo;    /* Checkp
14db0 6f 69 6e 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  oint information
14dc0 20 69 6e 20 77 61 6c 2d 69 6e 64 65 78 20 2a 2f   in wal-index */
14dd0 0a 20 20 75 33 32 20 6d 78 52 65 61 64 4d 61 72  .  u32 mxReadMar
14de0 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
14df0 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 61 52     /* Largest aR
14e00 65 61 64 4d 61 72 6b 5b 5d 20 76 61 6c 75 65 20  eadMark[] value 
14e10 2a 2f 0a 20 20 69 6e 74 20 6d 78 49 3b 20 20 20  */.  int mxI;   
14e20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14e30 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66       /* Index of
14e40 20 6c 61 72 67 65 73 74 20 61 52 65 61 64 4d 61   largest aReadMa
14e50 72 6b 5b 5d 20 76 61 6c 75 65 20 2a 2f 0a 20 20  rk[] value */.  
14e60 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
14e70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14e80 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20  /* Loop counter 
14e90 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  */.  int rc = SQ
14ea0 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20  LITE_OK;        
14eb0 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
14ec0 6f 64 65 20 20 2a 2f 0a 20 20 75 33 32 20 6d 78  ode  */.  u32 mx
14ed0 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  Frame;          
14ee0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c            /* Wal
14ef0 20 66 72 61 6d 65 20 74 6f 20 6c 6f 63 6b 20 74   frame to lock t
14f00 6f 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20  o */..  assert( 
14f10 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3c 30  pWal->readLock<0
14f20 20 29 3b 20 20 20 20 20 2f 2a 20 4e 6f 74 20 63   );     /* Not c
14f30 75 72 72 65 6e 74 6c 79 20 6c 6f 63 6b 65 64 20  urrently locked 
14f40 2a 2f 0a 0a 20 20 2f 2a 20 54 61 6b 65 20 73 74  */..  /* Take st
14f50 65 70 73 20 74 6f 20 61 76 6f 69 64 20 73 70 69  eps to avoid spi
14f60 6e 6e 69 6e 67 20 66 6f 72 65 76 65 72 20 69 66  nning forever if
14f70 20 74 68 65 72 65 20 69 73 20 61 20 70 72 6f 74   there is a prot
14f80 6f 63 6f 6c 20 65 72 72 6f 72 2e 0a 20 20 2a 2a  ocol error..  **
14f90 0a 20 20 2a 2a 20 43 69 72 63 75 6d 73 74 61 6e  .  ** Circumstan
14fa0 63 65 73 20 74 68 61 74 20 63 61 75 73 65 20 61  ces that cause a
14fb0 20 52 45 54 52 59 20 73 68 6f 75 6c 64 20 6f 6e   RETRY should on
14fc0 6c 79 20 6c 61 73 74 20 66 6f 72 20 74 68 65 20  ly last for the 
14fd0 62 72 69 65 66 65 73 74 0a 20 20 2a 2a 20 69 6e  briefest.  ** in
14fe0 73 74 61 6e 63 65 73 20 6f 66 20 74 69 6d 65 2e  stances of time.
14ff0 20 20 4e 6f 20 49 2f 4f 20 6f 72 20 6f 74 68 65    No I/O or othe
15000 72 20 73 79 73 74 65 6d 20 63 61 6c 6c 73 20 61  r system calls a
15010 72 65 20 64 6f 6e 65 20 77 68 69 6c 65 20 74 68  re done while th
15020 65 0a 20 20 2a 2a 20 6c 6f 63 6b 73 20 61 72 65  e.  ** locks are
15030 20 68 65 6c 64 2c 20 73 6f 20 74 68 65 20 6c 6f   held, so the lo
15040 63 6b 73 20 73 68 6f 75 6c 64 20 6e 6f 74 20 62  cks should not b
15050 65 20 68 65 6c 64 20 66 6f 72 20 76 65 72 79 20  e held for very 
15060 6c 6f 6e 67 2e 20 42 75 74 20 0a 20 20 2a 2a 20  long. But .  ** 
15070 69 66 20 77 65 20 61 72 65 20 75 6e 6c 75 63 6b  if we are unluck
15080 79 2c 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65  y, another proce
15090 73 73 20 74 68 61 74 20 69 73 20 68 6f 6c 64 69  ss that is holdi
150a0 6e 67 20 61 20 6c 6f 63 6b 20 6d 69 67 68 74 20  ng a lock might 
150b0 67 65 74 0a 20 20 2a 2a 20 70 61 67 65 64 20 6f  get.  ** paged o
150c0 75 74 20 6f 72 20 74 61 6b 65 20 61 20 70 61 67  ut or take a pag
150d0 65 2d 66 61 75 6c 74 20 74 68 61 74 20 69 73 20  e-fault that is 
150e0 74 69 6d 65 2d 63 6f 6e 73 75 6d 69 6e 67 20 74  time-consuming t
150f0 6f 20 72 65 73 6f 6c 76 65 2c 20 0a 20 20 2a 2a  o resolve, .  **
15100 20 64 75 72 69 6e 67 20 74 68 65 20 66 65 77 20   during the few 
15110 6e 61 6e 6f 73 65 63 6f 6e 64 73 20 74 68 61 74  nanoseconds that
15120 20 69 74 20 69 73 20 68 6f 6c 64 69 6e 67 20 74   it is holding t
15130 68 65 20 6c 6f 63 6b 2e 20 20 49 6e 20 74 68 61  he lock.  In tha
15140 74 20 63 61 73 65 2c 0a 20 20 2a 2a 20 69 74 20  t case,.  ** it 
15150 6d 69 67 68 74 20 74 61 6b 65 20 6c 6f 6e 67 65  might take longe
15160 72 20 74 68 61 6e 20 6e 6f 72 6d 61 6c 20 66 6f  r than normal fo
15170 72 20 74 68 65 20 6c 6f 63 6b 20 74 6f 20 66 72  r the lock to fr
15180 65 65 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 41 66  ee..  **.  ** Af
15190 74 65 72 20 35 20 52 45 54 52 59 73 2c 20 77 65  ter 5 RETRYs, we
151a0 20 62 65 67 69 6e 20 63 61 6c 6c 69 6e 67 20 73   begin calling s
151b0 71 6c 69 74 65 33 4f 73 53 6c 65 65 70 28 29 2e  qlite3OsSleep().
151c0 20 20 54 68 65 20 66 69 72 73 74 20 66 65 77 0a    The first few.
151d0 20 20 2a 2a 20 63 61 6c 6c 73 20 74 6f 20 73 71    ** calls to sq
151e0 6c 69 74 65 33 4f 73 53 6c 65 65 70 28 29 20 68  lite3OsSleep() h
151f0 61 76 65 20 61 20 64 65 6c 61 79 20 6f 66 20 31  ave a delay of 1
15200 20 6d 69 63 72 6f 73 65 63 6f 6e 64 2e 20 20 52   microsecond.  R
15210 65 61 6c 6c 79 20 74 68 69 73 0a 20 20 2a 2a 20  eally this.  ** 
15220 69 73 20 6d 6f 72 65 20 6f 66 20 61 20 73 63 68  is more of a sch
15230 65 64 75 6c 65 72 20 79 69 65 6c 64 20 74 68 61  eduler yield tha
15240 6e 20 61 6e 20 61 63 74 75 61 6c 20 64 65 6c 61  n an actual dela
15250 79 2e 20 20 42 75 74 20 6f 6e 20 74 68 65 20 31  y.  But on the 1
15260 30 74 68 0a 20 20 2a 2a 20 61 6e 20 73 75 62 73  0th.  ** an subs
15270 65 71 75 65 6e 74 20 72 65 74 72 69 65 73 2c 20  equent retries, 
15280 74 68 65 20 64 65 6c 61 79 73 20 73 74 61 72 74  the delays start
15290 20 62 65 63 6f 6d 69 6e 67 20 6c 6f 6e 67 65 72   becoming longer
152a0 20 61 6e 64 20 6c 6f 6e 67 65 72 2c 20 0a 20 20   and longer, .  
152b0 2a 2a 20 73 6f 20 74 68 61 74 20 6f 6e 20 74 68  ** so that on th
152c0 65 20 31 30 30 74 68 20 28 61 6e 64 20 6c 61 73  e 100th (and las
152d0 74 29 20 52 45 54 52 59 20 77 65 20 64 65 6c 61  t) RETRY we dela
152e0 79 20 66 6f 72 20 33 32 33 20 6d 69 6c 6c 69 73  y for 323 millis
152f0 65 63 6f 6e 64 73 2e 0a 20 20 2a 2a 20 54 68 65  econds..  ** The
15300 20 74 6f 74 61 6c 20 64 65 6c 61 79 20 74 69 6d   total delay tim
15310 65 20 62 65 66 6f 72 65 20 67 69 76 69 6e 67 20  e before giving 
15320 75 70 20 69 73 20 6c 65 73 73 20 74 68 61 6e 20  up is less than 
15330 31 30 20 73 65 63 6f 6e 64 73 2e 0a 20 20 2a 2f  10 seconds..  */
15340 0a 20 20 69 66 28 20 63 6e 74 3e 35 20 29 7b 0a  .  if( cnt>5 ){.
15350 20 20 20 20 69 6e 74 20 6e 44 65 6c 61 79 20 3d      int nDelay =
15360 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   1;             
15370 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 75 73           /* Paus
15380 65 20 74 69 6d 65 20 69 6e 20 6d 69 63 72 6f 73  e time in micros
15390 65 63 6f 6e 64 73 20 2a 2f 0a 20 20 20 20 69 66  econds */.    if
153a0 28 20 63 6e 74 3e 31 30 30 20 29 7b 0a 20 20 20  ( cnt>100 ){.   
153b0 20 20 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57 61     VVA_ONLY( pWa
153c0 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20 31  l->lockError = 1
153d0 3b 20 29 0a 20 20 20 20 20 20 72 65 74 75 72 6e  ; ).      return
153e0 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c   SQLITE_PROTOCOL
153f0 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
15400 63 6e 74 3e 3d 31 30 20 29 20 6e 44 65 6c 61 79  cnt>=10 ) nDelay
15410 20 3d 20 28 63 6e 74 2d 39 29 2a 28 63 6e 74 2d   = (cnt-9)*(cnt-
15420 39 29 2a 33 39 3b 0a 20 20 20 20 73 71 6c 69 74  9)*39;.    sqlit
15430 65 33 4f 73 53 6c 65 65 70 28 70 57 61 6c 2d 3e  e3OsSleep(pWal->
15440 70 56 66 73 2c 20 6e 44 65 6c 61 79 29 3b 0a 20  pVfs, nDelay);. 
15450 20 7d 0a 0a 20 20 69 66 28 20 21 75 73 65 57 61   }..  if( !useWa
15460 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 77 61  l ){.    rc = wa
15470 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28 70 57  lIndexReadHdr(pW
15480 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b 0a 20  al, pChanged);. 
15490 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
154a0 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20  E_BUSY ){.      
154b0 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 6e  /* If there is n
154c0 6f 74 20 61 20 72 65 63 6f 76 65 72 79 20 72 75  ot a recovery ru
154d0 6e 6e 69 6e 67 20 69 6e 20 61 6e 6f 74 68 65 72  nning in another
154e0 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65   thread or proce
154f0 73 73 0a 20 20 20 20 20 20 2a 2a 20 74 68 65 6e  ss.      ** then
15500 20 63 6f 6e 76 65 72 74 20 42 55 53 59 20 65 72   convert BUSY er
15510 72 6f 72 73 20 74 6f 20 57 41 4c 5f 52 45 54 52  rors to WAL_RETR
15520 59 2e 20 20 49 66 20 72 65 63 6f 76 65 72 79 20  Y.  If recovery 
15530 69 73 20 6b 6e 6f 77 6e 20 74 6f 0a 20 20 20 20  is known to.    
15540 20 20 2a 2a 20 62 65 20 72 75 6e 6e 69 6e 67 2c    ** be running,
15550 20 63 6f 6e 76 65 72 74 20 42 55 53 59 20 74 6f   convert BUSY to
15560 20 42 55 53 59 5f 52 45 43 4f 56 45 52 59 2e 20   BUSY_RECOVERY. 
15570 20 54 68 65 72 65 20 69 73 20 61 20 72 61 63 65   There is a race
15580 20 68 65 72 65 0a 20 20 20 20 20 20 2a 2a 20 77   here.      ** w
15590 68 69 63 68 20 6d 69 67 68 74 20 63 61 75 73 65  hich might cause
155a0 20 57 41 4c 5f 52 45 54 52 59 20 74 6f 20 62 65   WAL_RETRY to be
155b0 20 72 65 74 75 72 6e 65 64 20 65 76 65 6e 20 69   returned even i
155c0 66 20 42 55 53 59 5f 52 45 43 4f 56 45 52 59 0a  f BUSY_RECOVERY.
155d0 20 20 20 20 20 20 2a 2a 20 77 6f 75 6c 64 20 62        ** would b
155e0 65 20 74 65 63 68 6e 69 63 61 6c 6c 79 20 63 6f  e technically co
155f0 72 72 65 63 74 2e 20 20 42 75 74 20 74 68 65 20  rrect.  But the 
15600 72 61 63 65 20 69 73 20 62 65 6e 69 67 6e 20 73  race is benign s
15610 69 6e 63 65 20 77 69 74 68 0a 20 20 20 20 20 20  ince with.      
15620 2a 2a 20 57 41 4c 5f 52 45 54 52 59 20 74 68 69  ** WAL_RETRY thi
15630 73 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20 62  s routine will b
15640 65 20 63 61 6c 6c 65 64 20 61 67 61 69 6e 20 61  e called again a
15650 6e 64 20 77 69 6c 6c 20 70 72 6f 62 61 62 6c 79  nd will probably
15660 20 62 65 0a 20 20 20 20 20 20 2a 2a 20 72 69 67   be.      ** rig
15670 68 74 20 6f 6e 20 74 68 65 20 73 65 63 6f 6e 64  ht on the second
15680 20 69 74 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20   iteration..    
15690 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 70    */.      if( p
156a0 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
156b0 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 2f  ==0 ){.        /
156c0 2a 20 54 68 69 73 20 62 72 61 6e 63 68 20 69 73  * This branch is
156d0 20 74 61 6b 65 6e 20 77 68 65 6e 20 74 68 65 20   taken when the 
156e0 78 53 68 6d 4d 61 70 28 29 20 6d 65 74 68 6f 64  xShmMap() method
156f0 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f   returns SQLITE_
15700 42 55 53 59 2e 0a 20 20 20 20 20 20 20 20 2a 2a  BUSY..        **
15710 20 57 65 20 61 73 73 75 6d 65 20 74 68 69 73 20   We assume this 
15720 69 73 20 61 20 74 72 61 6e 73 69 65 6e 74 20 63  is a transient c
15730 6f 6e 64 69 74 69 6f 6e 2c 20 73 6f 20 72 65 74  ondition, so ret
15740 75 72 6e 20 57 41 4c 5f 52 45 54 52 59 2e 20 54  urn WAL_RETRY. T
15750 68 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 78 53  he.        ** xS
15760 68 6d 4d 61 70 28 29 20 69 6d 70 6c 65 6d 65 6e  hmMap() implemen
15770 74 61 74 69 6f 6e 20 75 73 65 64 20 62 79 20 74  tation used by t
15780 68 65 20 64 65 66 61 75 6c 74 20 75 6e 69 78 20  he default unix 
15790 61 6e 64 20 77 69 6e 33 32 20 56 46 53 20 0a 20  and win32 VFS . 
157a0 20 20 20 20 20 20 20 2a 2a 20 6d 6f 64 75 6c 65         ** module
157b0 73 20 6d 61 79 20 72 65 74 75 72 6e 20 53 51 4c  s may return SQL
157c0 49 54 45 5f 42 55 53 59 20 64 75 65 20 74 6f 20  ITE_BUSY due to 
157d0 61 20 72 61 63 65 20 63 6f 6e 64 69 74 69 6f 6e  a race condition
157e0 20 69 6e 20 74 68 65 20 0a 20 20 20 20 20 20 20   in the .       
157f0 20 2a 2a 20 63 6f 64 65 20 74 68 61 74 20 64 65   ** code that de
15800 74 65 72 6d 69 6e 65 73 20 77 68 65 74 68 65 72  termines whether
15810 20 6f 72 20 6e 6f 74 20 74 68 65 20 73 68 61 72   or not the shar
15820 65 64 2d 6d 65 6d 6f 72 79 20 72 65 67 69 6f 6e  ed-memory region
15830 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 6d 75 73   .        ** mus
15840 74 20 62 65 20 7a 65 72 6f 65 64 20 62 65 66 6f  t be zeroed befo
15850 72 65 20 74 68 65 20 72 65 71 75 65 73 74 65 64  re the requested
15860 20 70 61 67 65 20 69 73 20 72 65 74 75 72 6e 65   page is returne
15870 64 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20  d..        */.  
15880 20 20 20 20 20 20 72 63 20 3d 20 57 41 4c 5f 52        rc = WAL_R
15890 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 65 6c 73  ETRY;.      }els
158a0 65 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d  e if( SQLITE_OK=
158b0 3d 28 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68  =(rc = walLockSh
158c0 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
158d0 45 43 4f 56 45 52 5f 4c 4f 43 4b 29 29 20 29 7b  ECOVER_LOCK)) ){
158e0 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f  .        walUnlo
158f0 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
15900 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 29  AL_RECOVER_LOCK)
15910 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 57  ;.        rc = W
15920 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20  AL_RETRY;.      
15930 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51  }else if( rc==SQ
15940 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
15950 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
15960 5f 42 55 53 59 5f 52 45 43 4f 56 45 52 59 3b 0a  _BUSY_RECOVERY;.
15970 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
15980 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
15990 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74  _OK ){.      ret
159a0 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20  urn rc;.    }.  
159b0 7d 0a 0a 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c  }..  pInfo = wal
159c0 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a  CkptInfo(pWal);.
159d0 20 20 69 66 28 20 21 75 73 65 57 61 6c 20 26 26    if( !useWal &&
159e0 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
159f0 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  l==pWal->hdr.mxF
15a00 72 61 6d 65 20 0a 23 69 66 64 65 66 20 53 51 4c  rame .#ifdef SQL
15a10 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e 41 50 53  ITE_ENABLE_SNAPS
15a20 48 4f 54 0a 20 20 20 26 26 20 28 70 57 61 6c 2d  HOT.   && (pWal-
15a30 3e 70 53 6e 61 70 73 68 6f 74 3d 3d 30 20 7c 7c  >pSnapshot==0 ||
15a40 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
15a50 6d 65 3d 3d 30 0a 20 20 20 20 20 7c 7c 20 30 3d  me==0.     || 0=
15a60 3d 6d 65 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68  =memcmp(&pWal->h
15a70 64 72 2c 20 70 57 61 6c 2d 3e 70 53 6e 61 70 73  dr, pWal->pSnaps
15a80 68 6f 74 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49  hot, sizeof(WalI
15a90 6e 64 65 78 48 64 72 29 29 29 0a 23 65 6e 64 69  ndexHdr))).#endi
15aa0 66 0a 20 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68  f.  ){.    /* Th
15ab0 65 20 57 41 4c 20 68 61 73 20 62 65 65 6e 20 63  e WAL has been c
15ac0 6f 6d 70 6c 65 74 65 6c 79 20 62 61 63 6b 66 69  ompletely backfi
15ad0 6c 6c 65 64 20 28 6f 72 20 69 74 20 69 73 20 65  lled (or it is e
15ae0 6d 70 74 79 29 2e 0a 20 20 20 20 2a 2a 20 61 6e  mpty)..    ** an
15af0 64 20 63 61 6e 20 62 65 20 73 61 66 65 6c 79 20  d can be safely 
15b00 69 67 6e 6f 72 65 64 2e 0a 20 20 20 20 2a 2f 0a  ignored..    */.
15b10 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b      rc = walLock
15b20 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c  Shared(pWal, WAL
15b30 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a  _READ_LOCK(0));.
15b40 20 20 20 20 77 61 6c 53 68 6d 42 61 72 72 69 65      walShmBarrie
15b50 72 28 70 57 61 6c 29 3b 0a 20 20 20 20 69 66 28  r(pWal);.    if(
15b60 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
15b70 7b 0a 20 20 20 20 20 20 69 66 28 20 6d 65 6d 63  {.      if( memc
15b80 6d 70 28 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e  mp((void *)walIn
15b90 64 65 78 48 64 72 28 70 57 61 6c 29 2c 20 26 70  dexHdr(pWal), &p
15ba0 57 61 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66  Wal->hdr, sizeof
15bb0 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 20 29  (WalIndexHdr)) )
15bc0 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49 74 20  {.        /* It 
15bd0 69 73 20 6e 6f 74 20 73 61 66 65 20 74 6f 20 61  is not safe to a
15be0 6c 6c 6f 77 20 74 68 65 20 72 65 61 64 65 72 20  llow the reader 
15bf0 74 6f 20 63 6f 6e 74 69 6e 75 65 20 68 65 72 65  to continue here
15c00 20 69 66 20 66 72 61 6d 65 73 0a 20 20 20 20 20   if frames.     
15c10 20 20 20 2a 2a 20 6d 61 79 20 68 61 76 65 20 62     ** may have b
15c20 65 65 6e 20 61 70 70 65 6e 64 65 64 20 74 6f 20  een appended to 
15c30 74 68 65 20 6c 6f 67 20 62 65 66 6f 72 65 20 52  the log before R
15c40 45 41 44 5f 4c 4f 43 4b 28 30 29 20 77 61 73 20  EAD_LOCK(0) was 
15c50 6f 62 74 61 69 6e 65 64 2e 0a 20 20 20 20 20 20  obtained..      
15c60 20 20 2a 2a 20 57 68 65 6e 20 68 6f 6c 64 69 6e    ** When holdin
15c70 67 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20  g READ_LOCK(0), 
15c80 74 68 65 20 72 65 61 64 65 72 20 69 67 6e 6f 72  the reader ignor
15c90 65 73 20 74 68 65 20 65 6e 74 69 72 65 20 6c 6f  es the entire lo
15ca0 67 20 66 69 6c 65 2c 0a 20 20 20 20 20 20 20 20  g file,.        
15cb0 2a 2a 20 77 68 69 63 68 20 69 6d 70 6c 69 65 73  ** which implies
15cc0 20 74 68 61 74 20 74 68 65 20 64 61 74 61 62 61   that the databa
15cd0 73 65 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73  se file contains
15ce0 20 61 20 74 72 75 73 74 77 6f 72 74 68 79 0a 20   a trustworthy. 
15cf0 20 20 20 20 20 20 20 2a 2a 20 73 6e 61 70 73 68         ** snapsh
15d00 6f 74 2e 20 53 69 6e 63 65 20 68 6f 6c 64 69 6e  ot. Since holdin
15d10 67 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20 70  g READ_LOCK(0) p
15d20 72 65 76 65 6e 74 73 20 61 20 63 68 65 63 6b 70  revents a checkp
15d30 6f 69 6e 74 20 66 72 6f 6d 0a 20 20 20 20 20 20  oint from.      
15d40 20 20 2a 2a 20 68 61 70 70 65 6e 69 6e 67 2c 20    ** happening, 
15d50 74 68 69 73 20 69 73 20 75 73 75 61 6c 6c 79 20  this is usually 
15d60 63 6f 72 72 65 63 74 2e 0a 20 20 20 20 20 20 20  correct..       
15d70 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 48   **.        ** H
15d80 6f 77 65 76 65 72 2c 20 69 66 20 66 72 61 6d 65  owever, if frame
15d90 73 20 68 61 76 65 20 62 65 65 6e 20 61 70 70 65  s have been appe
15da0 6e 64 65 64 20 74 6f 20 74 68 65 20 6c 6f 67 20  nded to the log 
15db0 28 6f 72 20 69 66 20 74 68 65 20 6c 6f 67 20 0a  (or if the log .
15dc0 20 20 20 20 20 20 20 20 2a 2a 20 69 73 20 77 72          ** is wr
15dd0 61 70 70 65 64 20 61 6e 64 20 77 72 69 74 74 65  apped and writte
15de0 6e 20 66 6f 72 20 74 68 61 74 20 6d 61 74 74 65  n for that matte
15df0 72 29 20 62 65 66 6f 72 65 20 74 68 65 20 52 45  r) before the RE
15e00 41 44 5f 4c 4f 43 4b 28 30 29 0a 20 20 20 20 20  AD_LOCK(0).     
15e10 20 20 20 2a 2a 20 69 73 20 6f 62 74 61 69 6e 65     ** is obtaine
15e20 64 2c 20 74 68 61 74 20 69 73 20 6e 6f 74 20 6e  d, that is not n
15e30 65 63 65 73 73 61 72 69 6c 79 20 74 72 75 65 2e  ecessarily true.
15e40 20 41 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 20   A checkpointer 
15e50 6d 61 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 68  may.        ** h
15e60 61 76 65 20 73 74 61 72 74 65 64 20 74 6f 20 62  ave started to b
15e70 61 63 6b 66 69 6c 6c 20 74 68 65 20 61 70 70 65  ackfill the appe
15e80 6e 64 65 64 20 66 72 61 6d 65 73 20 62 75 74 20  nded frames but 
15e90 63 72 61 73 68 65 64 20 62 65 66 6f 72 65 0a 20  crashed before. 
15ea0 20 20 20 20 20 20 20 2a 2a 20 69 74 20 66 69 6e         ** it fin
15eb0 69 73 68 65 64 2e 20 4c 65 61 76 69 6e 67 20 61  ished. Leaving a
15ec0 20 63 6f 72 72 75 70 74 20 69 6d 61 67 65 20 69   corrupt image i
15ed0 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  n the database f
15ee0 69 6c 65 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a  ile..        */.
15ef0 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63          walUnloc
15f00 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
15f10 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b  L_READ_LOCK(0));
15f20 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
15f30 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 20  WAL_RETRY;.     
15f40 20 7d 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 72   }.      pWal->r
15f50 65 61 64 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20  eadLock = 0;.   
15f60 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
15f70 5f 4f 4b 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  _OK;.    }else i
15f80 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55  f( rc!=SQLITE_BU
15f90 53 59 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75  SY ){.      retu
15fa0 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d  rn rc;.    }.  }
15fb0 0a 0a 20 20 2f 2a 20 49 66 20 77 65 20 67 65 74  ..  /* If we get
15fc0 20 74 68 69 73 20 66 61 72 2c 20 69 74 20 6d 65   this far, it me
15fd0 61 6e 73 20 74 68 61 74 20 74 68 65 20 72 65 61  ans that the rea
15fe0 64 65 72 20 77 69 6c 6c 20 77 61 6e 74 20 74 6f  der will want to
15ff0 20 75 73 65 0a 20 20 2a 2a 20 74 68 65 20 57 41   use.  ** the WA
16000 4c 20 74 6f 20 67 65 74 20 61 74 20 63 6f 6e 74  L to get at cont
16010 65 6e 74 20 66 72 6f 6d 20 72 65 63 65 6e 74 20  ent from recent 
16020 63 6f 6d 6d 69 74 73 2e 20 20 54 68 65 20 6a 6f  commits.  The jo
16030 62 20 6e 6f 77 20 69 73 0a 20 20 2a 2a 20 74 6f  b now is.  ** to
16040 20 73 65 6c 65 63 74 20 6f 6e 65 20 6f 66 20 74   select one of t
16050 68 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65  he aReadMark[] e
16060 6e 74 72 69 65 73 20 74 68 61 74 20 69 73 20 63  ntries that is c
16070 6c 6f 73 65 73 74 20 74 6f 0a 20 20 2a 2a 20 62  losest to.  ** b
16080 75 74 20 6e 6f 74 20 65 78 63 65 65 64 69 6e 67  ut not exceeding
16090 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
160a0 6d 65 20 61 6e 64 20 6c 6f 63 6b 20 74 68 61 74  me and lock that
160b0 20 65 6e 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 6d   entry..  */.  m
160c0 78 52 65 61 64 4d 61 72 6b 20 3d 20 30 3b 0a 20  xReadMark = 0;. 
160d0 20 6d 78 49 20 3d 20 30 3b 0a 20 20 6d 78 46 72   mxI = 0;.  mxFr
160e0 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  ame = pWal->hdr.
160f0 6d 78 46 72 61 6d 65 3b 0a 23 69 66 64 65 66 20  mxFrame;.#ifdef 
16100 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e  SQLITE_ENABLE_SN
16110 41 50 53 48 4f 54 0a 20 20 69 66 28 20 70 57 61  APSHOT.  if( pWa
16120 6c 2d 3e 70 53 6e 61 70 73 68 6f 74 20 26 26 20  l->pSnapshot && 
16130 70 57 61 6c 2d 3e 70 53 6e 61 70 73 68 6f 74 2d  pWal->pSnapshot-
16140 3e 6d 78 46 72 61 6d 65 3c 6d 78 46 72 61 6d 65  >mxFrame<mxFrame
16150 20 29 7b 0a 20 20 20 20 6d 78 46 72 61 6d 65 20   ){.    mxFrame 
16160 3d 20 70 57 61 6c 2d 3e 70 53 6e 61 70 73 68 6f  = pWal->pSnapsho
16170 74 2d 3e 6d 78 46 72 61 6d 65 3b 0a 20 20 7d 0a  t->mxFrame;.  }.
16180 23 65 6e 64 69 66 0a 20 20 66 6f 72 28 69 3d 31  #endif.  for(i=1
16190 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b  ; i<WAL_NREADER;
161a0 20 69 2b 2b 29 7b 0a 20 20 20 20 75 33 32 20 74   i++){.    u32 t
161b0 68 69 73 4d 61 72 6b 20 3d 20 70 49 6e 66 6f 2d  hisMark = pInfo-
161c0 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20  >aReadMark[i];. 
161d0 20 20 20 69 66 28 20 6d 78 52 65 61 64 4d 61 72     if( mxReadMar
161e0 6b 3c 3d 74 68 69 73 4d 61 72 6b 20 26 26 20 74  k<=thisMark && t
161f0 68 69 73 4d 61 72 6b 3c 3d 6d 78 46 72 61 6d 65  hisMark<=mxFrame
16200 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74   ){.      assert
16210 28 20 74 68 69 73 4d 61 72 6b 21 3d 52 45 41 44  ( thisMark!=READ
16220 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 20 29 3b  MARK_NOT_USED );
16230 0a 20 20 20 20 20 20 6d 78 52 65 61 64 4d 61 72  .      mxReadMar
16240 6b 20 3d 20 74 68 69 73 4d 61 72 6b 3b 0a 20 20  k = thisMark;.  
16250 20 20 20 20 6d 78 49 20 3d 20 69 3b 0a 20 20 20      mxI = i;.   
16260 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 28 70 57   }.  }.  if( (pW
16270 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57  al->readOnly & W
16280 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 29 3d 3d  AL_SHM_RDONLY)==
16290 30 0a 20 20 20 26 26 20 28 6d 78 52 65 61 64 4d  0.   && (mxReadM
162a0 61 72 6b 3c 6d 78 46 72 61 6d 65 20 7c 7c 20 6d  ark<mxFrame || m
162b0 78 49 3d 3d 30 29 0a 20 20 29 7b 0a 20 20 20 20  xI==0).  ){.    
162c0 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e  for(i=1; i<WAL_N
162d0 52 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20  READER; i++){.  
162e0 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b      rc = walLock
162f0 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
16300 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29  WAL_READ_LOCK(i)
16310 2c 20 31 29 3b 0a 20 20 20 20 20 20 69 66 28 20  , 1);.      if( 
16320 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
16330 0a 20 20 20 20 20 20 20 20 6d 78 52 65 61 64 4d  .        mxReadM
16340 61 72 6b 20 3d 20 70 49 6e 66 6f 2d 3e 61 52 65  ark = pInfo->aRe
16350 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 6d 78 46 72  adMark[i] = mxFr
16360 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 6d 78 49  ame;.        mxI
16370 20 3d 20 69 3b 0a 20 20 20 20 20 20 20 20 77 61   = i;.        wa
16380 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65  lUnlockExclusive
16390 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f  (pWal, WAL_READ_
163a0 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20  LOCK(i), 1);.   
163b0 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
163c0 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 21 3d    }else if( rc!=
163d0 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20  SQLITE_BUSY ){. 
163e0 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63         return rc
163f0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
16400 20 20 7d 0a 20 20 69 66 28 20 6d 78 49 3d 3d 30    }.  if( mxI==0
16410 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20   ){.    assert( 
16420 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc==SQLITE_BUSY 
16430 7c 7c 20 28 70 57 61 6c 2d 3e 72 65 61 64 4f 6e  || (pWal->readOn
16440 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  ly & WAL_SHM_RDO
16450 4e 4c 59 29 21 3d 30 20 29 3b 0a 20 20 20 20 72  NLY)!=0 );.    r
16460 65 74 75 72 6e 20 72 63 3d 3d 53 51 4c 49 54 45  eturn rc==SQLITE
16470 5f 42 55 53 59 20 3f 20 57 41 4c 5f 52 45 54 52  _BUSY ? WAL_RETR
16480 59 20 3a 20 53 51 4c 49 54 45 5f 52 45 41 44 4f  Y : SQLITE_READO
16490 4e 4c 59 5f 43 41 4e 54 4c 4f 43 4b 3b 0a 20 20  NLY_CANTLOCK;.  
164a0 7d 0a 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63  }..  rc = walLoc
164b0 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
164c0 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29  L_READ_LOCK(mxI)
164d0 29 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20  );.  if( rc ){. 
164e0 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d 53 51     return rc==SQ
164f0 4c 49 54 45 5f 42 55 53 59 20 3f 20 57 41 4c 5f  LITE_BUSY ? WAL_
16500 52 45 54 52 59 20 3a 20 72 63 3b 0a 20 20 7d 0a  RETRY : rc;.  }.
16510 20 20 2f 2a 20 4e 6f 77 20 74 68 61 74 20 74 68    /* Now that th
16520 65 20 72 65 61 64 2d 6c 6f 63 6b 20 68 61 73 20  e read-lock has 
16530 62 65 65 6e 20 6f 62 74 61 69 6e 65 64 2c 20 63  been obtained, c
16540 68 65 63 6b 20 74 68 61 74 20 6e 65 69 74 68 65  heck that neithe
16550 72 20 74 68 65 0a 20 20 2a 2a 20 76 61 6c 75 65  r the.  ** value
16560 20 69 6e 20 74 68 65 20 61 52 65 61 64 4d 61 72   in the aReadMar
16570 6b 5b 5d 20 61 72 72 61 79 20 6f 72 20 74 68 65  k[] array or the
16580 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
16590 20 77 61 6c 2d 69 6e 64 65 78 0a 20 20 2a 2a 20   wal-index.  ** 
165a0 68 65 61 64 65 72 20 68 61 76 65 20 63 68 61 6e  header have chan
165b0 67 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49  ged..  **.  ** I
165c0 74 20 69 73 20 6e 65 63 65 73 73 61 72 79 20 74  t is necessary t
165d0 6f 20 63 68 65 63 6b 20 74 68 61 74 20 74 68 65  o check that the
165e0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
165f0 72 20 64 69 64 20 6e 6f 74 20 63 68 61 6e 67 65  r did not change
16600 0a 20 20 2a 2a 20 62 65 74 77 65 65 6e 20 74 68  .  ** between th
16610 65 20 74 69 6d 65 20 69 74 20 77 61 73 20 72 65  e time it was re
16620 61 64 20 61 6e 64 20 77 68 65 6e 20 74 68 65 20  ad and when the 
16630 73 68 61 72 65 64 2d 6c 6f 63 6b 20 77 61 73 20  shared-lock was 
16640 6f 62 74 61 69 6e 65 64 0a 20 20 2a 2a 20 6f 6e  obtained.  ** on
16650 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d   WAL_READ_LOCK(m
16660 78 49 29 20 77 61 73 20 6f 62 74 61 69 6e 65 64  xI) was obtained
16670 20 74 6f 20 61 63 63 6f 75 6e 74 20 66 6f 72 20   to account for 
16680 74 68 65 20 70 6f 73 73 69 62 69 6c 69 74 79 0a  the possibility.
16690 20 20 2a 2a 20 74 68 61 74 20 74 68 65 20 6c 6f    ** that the lo
166a0 67 20 66 69 6c 65 20 6d 61 79 20 68 61 76 65 20  g file may have 
166b0 62 65 65 6e 20 77 72 61 70 70 65 64 20 62 79 20  been wrapped by 
166c0 61 20 77 72 69 74 65 72 2c 20 6f 72 20 74 68 61  a writer, or tha
166d0 74 20 66 72 61 6d 65 73 0a 20 20 2a 2a 20 74 68  t frames.  ** th
166e0 61 74 20 6f 63 63 75 72 20 6c 61 74 65 72 20 69  at occur later i
166f0 6e 20 74 68 65 20 6c 6f 67 20 74 68 61 6e 20 70  n the log than p
16700 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
16710 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e 0a 20   may have been. 
16720 20 2a 2a 20 63 6f 70 69 65 64 20 69 6e 74 6f 20   ** copied into 
16730 74 68 65 20 64 61 74 61 62 61 73 65 20 62 79 20  the database by 
16740 61 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 2e 20  a checkpointer. 
16750 49 66 20 65 69 74 68 65 72 20 6f 66 20 74 68 65  If either of the
16760 73 65 20 74 68 69 6e 67 73 0a 20 20 2a 2a 20 68  se things.  ** h
16770 61 70 70 65 6e 65 64 2c 20 74 68 65 6e 20 72 65  appened, then re
16780 61 64 69 6e 67 20 74 68 65 20 64 61 74 61 62 61  ading the databa
16790 73 65 20 77 69 74 68 20 74 68 65 20 63 75 72 72  se with the curr
167a0 65 6e 74 20 76 61 6c 75 65 20 6f 66 0a 20 20 2a  ent value of.  *
167b0 2a 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  * pWal->hdr.mxFr
167c0 61 6d 65 20 72 69 73 6b 73 20 72 65 61 64 69 6e  ame risks readin
167d0 67 20 61 20 63 6f 72 72 75 70 74 65 64 20 73 6e  g a corrupted sn
167e0 61 70 73 68 6f 74 2e 20 53 6f 2c 20 72 65 74 72  apshot. So, retr
167f0 79 0a 20 20 2a 2a 20 69 6e 73 74 65 61 64 2e 0a  y.  ** instead..
16800 20 20 2a 2a 0a 20 20 2a 2a 20 42 65 66 6f 72 65    **.  ** Before
16810 20 63 68 65 63 6b 69 6e 67 20 74 68 61 74 20 74   checking that t
16820 68 65 20 6c 69 76 65 20 77 61 6c 2d 69 6e 64 65  he live wal-inde
16830 78 20 68 65 61 64 65 72 20 68 61 73 20 6e 6f 74  x header has not
16840 20 63 68 61 6e 67 65 64 0a 20 20 2a 2a 20 73 69   changed.  ** si
16850 6e 63 65 20 69 74 20 77 61 73 20 72 65 61 64 2c  nce it was read,
16860 20 73 65 74 20 57 61 6c 2e 6d 69 6e 46 72 61 6d   set Wal.minFram
16870 65 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 66  e to the first f
16880 72 61 6d 65 20 69 6e 20 74 68 65 20 77 61 6c 0a  rame in the wal.
16890 20 20 2a 2a 20 66 69 6c 65 20 74 68 61 74 20 68    ** file that h
168a0 61 73 20 6e 6f 74 20 79 65 74 20 62 65 65 6e 20  as not yet been 
168b0 63 68 65 63 6b 70 6f 69 6e 74 65 64 2e 20 54 68  checkpointed. Th
168c0 69 73 20 63 6c 69 65 6e 74 20 77 69 6c 6c 20 6e  is client will n
168d0 6f 74 20 6e 65 65 64 0a 20 20 2a 2a 20 74 6f 20  ot need.  ** to 
168e0 72 65 61 64 20 61 6e 79 20 66 72 61 6d 65 73 20  read any frames 
168f0 65 61 72 6c 69 65 72 20 74 68 61 6e 20 6d 69 6e  earlier than min
16900 46 72 61 6d 65 20 66 72 6f 6d 20 74 68 65 20 77  Frame from the w
16910 61 6c 20 66 69 6c 65 20 2d 20 74 68 65 79 0a 20  al file - they. 
16920 20 2a 2a 20 63 61 6e 20 62 65 20 73 61 66 65 6c   ** can be safel
16930 79 20 72 65 61 64 20 64 69 72 65 63 74 6c 79 20  y read directly 
16940 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
16950 65 20 66 69 6c 65 2e 0a 20 20 2a 2a 0a 20 20 2a  e file..  **.  *
16960 2a 20 42 65 63 61 75 73 65 20 61 20 53 68 6d 42  * Because a ShmB
16970 61 72 72 69 65 72 28 29 20 63 61 6c 6c 20 69 73  arrier() call is
16980 20 6d 61 64 65 20 62 65 74 77 65 65 6e 20 74 61   made between ta
16990 6b 69 6e 67 20 74 68 65 20 63 6f 70 79 20 6f 66  king the copy of
169a0 20 0a 20 20 2a 2a 20 6e 42 61 63 6b 66 69 6c 6c   .  ** nBackfill
169b0 20 61 6e 64 20 63 68 65 63 6b 69 6e 67 20 74 68   and checking th
169c0 61 74 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65  at the wal-heade
169d0 72 20 69 6e 20 73 68 61 72 65 64 2d 6d 65 6d 6f  r in shared-memo
169e0 72 79 20 73 74 69 6c 6c 0a 20 20 2a 2a 20 6d 61  ry still.  ** ma
169f0 74 63 68 65 73 20 74 68 65 20 6f 6e 65 20 63 61  tches the one ca
16a00 63 68 65 64 20 69 6e 20 70 57 61 6c 2d 3e 68 64  ched in pWal->hd
16a10 72 2c 20 69 74 20 69 73 20 67 75 61 72 61 6e 74  r, it is guarant
16a20 65 65 64 20 74 68 61 74 20 74 68 65 20 0a 20 20  eed that the .  
16a30 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 20  ** checkpointer 
16a40 74 68 61 74 20 73 65 74 20 6e 42 61 63 6b 66 69  that set nBackfi
16a50 6c 6c 20 77 61 73 20 6e 6f 74 20 77 6f 72 6b 69  ll was not worki
16a60 6e 67 20 77 69 74 68 20 61 20 77 61 6c 2d 69 6e  ng with a wal-in
16a70 64 65 78 0a 20 20 2a 2a 20 68 65 61 64 65 72 20  dex.  ** header 
16a80 6e 65 77 65 72 20 74 68 61 6e 20 74 68 61 74 20  newer than that 
16a90 63 61 63 68 65 64 20 69 6e 20 70 57 61 6c 2d 3e  cached in pWal->
16aa0 68 64 72 2e 20 49 66 20 69 74 20 77 65 72 65 2c  hdr. If it were,
16ab0 20 74 68 61 74 20 63 6f 75 6c 64 0a 20 20 2a 2a   that could.  **
16ac0 20 63 61 75 73 65 20 61 20 70 72 6f 62 6c 65 6d   cause a problem
16ad0 2e 20 54 68 65 20 63 68 65 63 6b 70 6f 69 6e 74  . The checkpoint
16ae0 65 72 20 63 6f 75 6c 64 20 6f 6d 69 74 20 74 6f  er could omit to
16af0 20 63 68 65 63 6b 70 6f 69 6e 74 0a 20 20 2a 2a   checkpoint.  **
16b00 20 61 20 76 65 72 73 69 6f 6e 20 6f 66 20 70 61   a version of pa
16b10 67 65 20 58 20 74 68 61 74 20 6c 69 65 73 20 62  ge X that lies b
16b20 65 66 6f 72 65 20 70 57 61 6c 2d 3e 6d 69 6e 46  efore pWal->minF
16b30 72 61 6d 65 20 28 63 61 6c 6c 20 74 68 61 74 20  rame (call that 
16b40 76 65 72 73 69 6f 6e 0a 20 20 2a 2a 20 41 29 20  version.  ** A) 
16b50 6f 6e 20 74 68 65 20 62 61 73 69 73 20 74 68 61  on the basis tha
16b60 74 20 74 68 65 72 65 20 69 73 20 61 20 6e 65 77  t there is a new
16b70 65 72 20 76 65 72 73 69 6f 6e 20 28 76 65 72 73  er version (vers
16b80 69 6f 6e 20 42 29 20 6f 66 20 74 68 65 20 73 61  ion B) of the sa
16b90 6d 65 0a 20 20 2a 2a 20 70 61 67 65 20 6c 61 74  me.  ** page lat
16ba0 65 72 20 69 6e 20 74 68 65 20 77 61 6c 20 66 69  er in the wal fi
16bb0 6c 65 2e 20 42 75 74 20 69 66 20 76 65 72 73 69  le. But if versi
16bc0 6f 6e 20 42 20 68 61 70 70 65 6e 73 20 74 6f 20  on B happens to 
16bd0 6c 69 6b 65 20 70 61 73 74 0a 20 20 2a 2a 20 66  like past.  ** f
16be0 72 61 6d 65 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  rame pWal->hdr.m
16bf0 78 46 72 61 6d 65 20 2d 20 74 68 65 6e 20 74 68  xFrame - then th
16c00 65 20 63 6c 69 65 6e 74 20 77 6f 75 6c 64 20 69  e client would i
16c10 6e 63 6f 72 72 65 63 74 6c 79 20 61 73 73 75 6d  ncorrectly assum
16c20 65 0a 20 20 2a 2a 20 74 68 61 74 20 69 74 20 63  e.  ** that it c
16c30 61 6e 20 72 65 61 64 20 76 65 72 73 69 6f 6e 20  an read version 
16c40 41 20 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62  A from the datab
16c50 61 73 65 20 66 69 6c 65 2e 20 48 6f 77 65 76 65  ase file. Howeve
16c60 72 2c 20 73 69 6e 63 65 0a 20 20 2a 2a 20 77 65  r, since.  ** we
16c70 20 63 61 6e 20 67 75 61 72 61 6e 74 65 65 20 74   can guarantee t
16c80 68 61 74 20 74 68 65 20 63 68 65 63 6b 70 6f 69  hat the checkpoi
16c90 6e 74 65 72 20 74 68 61 74 20 73 65 74 20 6e 42  nter that set nB
16ca0 61 63 6b 66 69 6c 6c 20 63 6f 75 6c 64 20 6e 6f  ackfill could no
16cb0 74 0a 20 20 2a 2a 20 73 65 65 20 61 6e 79 20 70  t.  ** see any p
16cc0 61 67 65 73 20 70 61 73 74 20 70 57 61 6c 2d 3e  ages past pWal->
16cd0 68 64 72 2e 6d 78 46 72 61 6d 65 2c 20 74 68 69  hdr.mxFrame, thi
16ce0 73 20 70 72 6f 62 6c 65 6d 20 64 6f 65 73 20 6e  s problem does n
16cf0 6f 74 20 63 6f 6d 65 20 75 70 2e 0a 20 20 2a 2f  ot come up..  */
16d00 0a 20 20 70 57 61 6c 2d 3e 6d 69 6e 46 72 61 6d  .  pWal->minFram
16d10 65 20 3d 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b  e = pInfo->nBack
16d20 66 69 6c 6c 2b 31 3b 0a 20 20 77 61 6c 53 68 6d  fill+1;.  walShm
16d30 42 61 72 72 69 65 72 28 70 57 61 6c 29 3b 0a 20  Barrier(pWal);. 
16d40 20 69 66 28 20 70 49 6e 66 6f 2d 3e 61 52 65 61   if( pInfo->aRea
16d50 64 4d 61 72 6b 5b 6d 78 49 5d 21 3d 6d 78 52 65  dMark[mxI]!=mxRe
16d60 61 64 4d 61 72 6b 0a 20 20 20 7c 7c 20 6d 65 6d  adMark.   || mem
16d70 63 6d 70 28 28 76 6f 69 64 20 2a 29 77 61 6c 49  cmp((void *)walI
16d80 6e 64 65 78 48 64 72 28 70 57 61 6c 29 2c 20 26  ndexHdr(pWal), &
16d90 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f  pWal->hdr, sizeo
16da0 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 0a  f(WalIndexHdr)).
16db0 20 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f    ){.    walUnlo
16dc0 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
16dd0 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49  AL_READ_LOCK(mxI
16de0 29 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 57  ));.    return W
16df0 41 4c 5f 52 45 54 52 59 3b 0a 20 20 7d 65 6c 73  AL_RETRY;.  }els
16e00 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 6d  e{.    assert( m
16e10 78 52 65 61 64 4d 61 72 6b 3c 3d 70 57 61 6c 2d  xReadMark<=pWal-
16e20 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a  >hdr.mxFrame );.
16e30 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f      pWal->readLo
16e40 63 6b 20 3d 20 28 69 31 36 29 6d 78 49 3b 0a 20  ck = (i16)mxI;. 
16e50 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
16e60 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  }..#ifdef SQLITE
16e70 5f 45 4e 41 42 4c 45 5f 53 4e 41 50 53 48 4f 54  _ENABLE_SNAPSHOT
16e80 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74  ./*.** Attempt t
16e90 6f 20 72 65 64 75 63 65 20 74 68 65 20 76 61 6c  o reduce the val
16ea0 75 65 20 6f 66 20 74 68 65 20 57 61 6c 43 6b 70  ue of the WalCkp
16eb0 74 49 6e 66 6f 2e 6e 42 61 63 6b 66 69 6c 6c 41  tInfo.nBackfillA
16ec0 74 74 65 6d 70 74 65 64 20 0a 2a 2a 20 76 61 72  ttempted .** var
16ed0 69 61 62 6c 65 20 73 6f 20 74 68 61 74 20 6f 6c  iable so that ol
16ee0 64 65 72 20 73 6e 61 70 73 68 6f 74 73 20 63 61  der snapshots ca
16ef0 6e 20 62 65 20 61 63 63 65 73 73 65 64 2e 20 54  n be accessed. T
16f00 6f 20 64 6f 20 74 68 69 73 2c 20 6c 6f 6f 70 0a  o do this, loop.
16f10 2a 2a 20 74 68 72 6f 75 67 68 20 61 6c 6c 20 77  ** through all w
16f20 61 6c 20 66 72 61 6d 65 73 20 66 72 6f 6d 20 6e  al frames from n
16f30 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70 74 65  BackfillAttempte
16f40 64 20 74 6f 20 28 6e 42 61 63 6b 66 69 6c 6c 2b  d to (nBackfill+
16f50 31 29 2c 20 0a 2a 2a 20 63 6f 6d 70 61 72 69 6e  1), .** comparin
16f60 67 20 74 68 65 69 72 20 63 6f 6e 74 65 6e 74 20  g their content 
16f70 74 6f 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e  to the correspon
16f80 64 69 6e 67 20 70 61 67 65 20 77 69 74 68 20 74  ding page with t
16f90 68 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 66  he database.** f
16fa0 69 6c 65 2c 20 69 66 20 61 6e 79 2e 20 53 65 74  ile, if any. Set
16fb0 20 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d 70   nBackfillAttemp
16fc0 74 65 64 20 74 6f 20 74 68 65 20 66 72 61 6d 65  ted to the frame
16fd0 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 0a 2a   number of the.*
16fe0 2a 20 66 69 72 73 74 20 66 72 61 6d 65 20 66 6f  * first frame fo
16ff0 72 20 77 68 69 63 68 20 74 68 65 20 77 61 6c 20  r which the wal 
17000 66 69 6c 65 20 63 6f 6e 74 65 6e 74 20 6d 61 74  file content mat
17010 63 68 65 73 20 74 68 65 20 64 62 20 66 69 6c 65  ches the db file
17020 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20  ..**.** This is 
17030 6f 6e 6c 79 20 72 65 61 6c 6c 79 20 73 61 66 65  only really safe
17040 20 69 66 20 74 68 65 20 66 69 6c 65 2d 73 79 73   if the file-sys
17050 74 65 6d 20 69 73 20 73 75 63 68 20 74 68 61 74  tem is such that
17060 20 61 6e 79 20 70 61 67 65 20 0a 2a 2a 20 77 72   any page .** wr
17070 69 74 65 73 20 6d 61 64 65 20 62 79 20 65 61 72  ites made by ear
17080 6c 69 65 72 20 63 68 65 63 6b 70 6f 69 6e 74 65  lier checkpointe
17090 72 73 20 77 65 72 65 20 61 74 6f 6d 69 63 20 6f  rs were atomic o
170a0 70 65 72 61 74 69 6f 6e 73 2c 20 77 68 69 63 68  perations, which
170b0 20 0a 2a 2a 20 69 73 20 6e 6f 74 20 61 6c 77 61   .** is not alwa
170c0 79 73 20 74 72 75 65 2e 20 49 74 20 69 73 20 61  ys true. It is a
170d0 6c 73 6f 20 70 6f 73 73 69 62 6c 65 20 74 68 61  lso possible tha
170e0 74 20 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d  t nBackfillAttem
170f0 70 74 65 64 0a 2a 2a 20 6d 61 79 20 62 65 20 6c  pted.** may be l
17100 65 66 74 20 73 65 74 20 74 6f 20 61 20 76 61 6c  eft set to a val
17110 75 65 20 6c 61 72 67 65 72 20 74 68 61 6e 20 65  ue larger than e
17120 78 70 65 63 74 65 64 2c 20 69 66 20 61 20 77 61  xpected, if a wa
17130 6c 20 66 72 61 6d 65 0a 2a 2a 20 63 6f 6e 74 61  l frame.** conta
17140 69 6e 73 20 63 6f 6e 74 65 6e 74 20 74 68 61 74  ins content that
17150 20 64 75 70 6c 69 63 61 74 65 20 6f 66 20 61 6e   duplicate of an
17160 20 65 61 72 6c 69 65 72 20 76 65 72 73 69 6f 6e   earlier version
17170 20 6f 66 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20   of the same.** 
17180 70 61 67 65 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49  page..**.** SQLI
17190 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
171a0 64 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c  d if successful,
171b0 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72   or an SQLite er
171c0 72 6f 72 20 63 6f 64 65 20 69 66 20 61 6e 0a 2a  ror code if an.*
171d0 2a 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20  * error occurs. 
171e0 49 74 20 69 73 20 6e 6f 74 20 61 6e 20 65 72 72  It is not an err
171f0 6f 72 20 69 66 20 6e 42 61 63 6b 66 69 6c 6c 41  or if nBackfillA
17200 74 74 65 6d 70 74 65 64 20 63 61 6e 6e 6f 74 20  ttempted cannot 
17210 62 65 0a 2a 2a 20 64 65 63 72 65 61 73 65 64 20  be.** decreased 
17220 61 74 20 61 6c 6c 2e 0a 2a 2f 0a 69 6e 74 20 73  at all..*/.int s
17230 71 6c 69 74 65 33 57 61 6c 53 6e 61 70 73 68 6f  qlite3WalSnapsho
17240 74 52 65 63 6f 76 65 72 28 57 61 6c 20 2a 70 57  tRecover(Wal *pW
17250 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a  al){.  int rc;..
17260 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
17270 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b 0a 20  readLock>=0 );. 
17280 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63   rc = walLockExc
17290 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
172a0 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  _CKPT_LOCK, 1);.
172b0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
172c0 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 6f 6c 61 74  _OK ){.    volat
172d0 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20  ile WalCkptInfo 
172e0 2a 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74  *pInfo = walCkpt
172f0 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20 20  Info(pWal);.    
17300 69 6e 74 20 73 7a 50 61 67 65 20 3d 20 28 69 6e  int szPage = (in
17310 74 29 70 57 61 6c 2d 3e 73 7a 50 61 67 65 3b 0a  t)pWal->szPage;.
17320 20 20 20 20 69 36 34 20 73 7a 44 62 3b 20 20 20      i64 szDb;   
17330 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17340 2f 2a 20 53 69 7a 65 20 6f 66 20 64 62 20 66 69  /* Size of db fi
17350 6c 65 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a  le in bytes */..
17360 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
17370 4f 73 46 69 6c 65 53 69 7a 65 28 70 57 61 6c 2d  OsFileSize(pWal-
17380 3e 70 44 62 46 64 2c 20 26 73 7a 44 62 29 3b 0a  >pDbFd, &szDb);.
17390 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
173a0 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 76  TE_OK ){.      v
173b0 6f 69 64 20 2a 70 42 75 66 31 20 3d 20 73 71 6c  oid *pBuf1 = sql
173c0 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 7a 50 61  ite3_malloc(szPa
173d0 67 65 29 3b 0a 20 20 20 20 20 20 76 6f 69 64 20  ge);.      void 
173e0 2a 70 42 75 66 32 20 3d 20 73 71 6c 69 74 65 33  *pBuf2 = sqlite3
173f0 5f 6d 61 6c 6c 6f 63 28 73 7a 50 61 67 65 29 3b  _malloc(szPage);
17400 0a 20 20 20 20 20 20 69 66 28 20 70 42 75 66 31  .      if( pBuf1
17410 3d 3d 30 20 7c 7c 20 70 42 75 66 32 3d 3d 30 20  ==0 || pBuf2==0 
17420 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  ){.        rc = 
17430 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
17440 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
17450 20 20 20 75 33 32 20 69 20 3d 20 70 49 6e 66 6f     u32 i = pInfo
17460 2d 3e 6e 42 61 63 6b 66 69 6c 6c 41 74 74 65 6d  ->nBackfillAttem
17470 70 74 65 64 3b 0a 20 20 20 20 20 20 20 20 66 6f  pted;.        fo
17480 72 28 69 3d 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b  r(i=pInfo->nBack
17490 66 69 6c 6c 41 74 74 65 6d 70 74 65 64 3b 20 69  fillAttempted; i
174a0 3e 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c  >pInfo->nBackfil
174b0 6c 3b 20 69 2d 2d 29 7b 0a 20 20 20 20 20 20 20  l; i--){.       
174c0 20 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73     volatile ht_s
174d0 6c 6f 74 20 2a 64 75 6d 6d 79 3b 0a 20 20 20 20  lot *dummy;.    
174e0 20 20 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75        volatile u
174f0 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20  32 *aPgno;      
17500 2f 2a 20 41 72 72 61 79 20 6f 66 20 70 61 67 65  /* Array of page
17510 20 6e 75 6d 62 65 72 73 20 2a 2f 0a 20 20 20 20   numbers */.    
17520 20 20 20 20 20 20 75 33 32 20 69 5a 65 72 6f 3b        u32 iZero;
17530 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17540 2f 2a 20 46 72 61 6d 65 20 63 6f 72 72 65 73 70  /* Frame corresp
17550 6f 6e 64 69 6e 67 20 74 6f 20 61 50 67 6e 6f 5b  onding to aPgno[
17560 30 5d 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  0] */.          
17570 75 33 32 20 70 67 6e 6f 3b 20 20 20 20 20 20 20  u32 pgno;       
17580 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
17590 65 20 6e 75 6d 62 65 72 20 69 6e 20 64 62 20 66  e number in db f
175a0 69 6c 65 20 2a 2f 0a 20 20 20 20 20 20 20 20 20  ile */.         
175b0 20 69 36 34 20 69 44 62 4f 66 66 3b 20 20 20 20   i64 iDbOff;    
175c0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66             /* Of
175d0 66 73 65 74 20 6f 66 20 64 62 20 66 69 6c 65 20  fset of db file 
175e0 65 6e 74 72 79 20 2a 2f 0a 20 20 20 20 20 20 20  entry */.       
175f0 20 20 20 69 36 34 20 69 57 61 6c 4f 66 66 3b 20     i64 iWalOff; 
17600 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
17610 4f 66 66 73 65 74 20 6f 66 20 77 61 6c 20 66 69  Offset of wal fi
17620 6c 65 20 65 6e 74 72 79 20 2a 2f 0a 0a 20 20 20  le entry */..   
17630 20 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 48         rc = walH
17640 61 73 68 47 65 74 28 70 57 61 6c 2c 20 77 61 6c  ashGet(pWal, wal
17650 46 72 61 6d 65 50 61 67 65 28 69 29 2c 20 26 64  FramePage(i), &d
17660 75 6d 6d 79 2c 20 26 61 50 67 6e 6f 2c 20 26 69  ummy, &aPgno, &i
17670 5a 65 72 6f 29 3b 0a 20 20 20 20 20 20 20 20 20  Zero);.         
17680 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
17690 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  OK ) break;.    
176a0 20 20 20 20 20 20 70 67 6e 6f 20 3d 20 61 50 67        pgno = aPg
176b0 6e 6f 5b 69 2d 69 5a 65 72 6f 5d 3b 0a 20 20 20  no[i-iZero];.   
176c0 20 20 20 20 20 20 20 69 44 62 4f 66 66 20 3d 20         iDbOff = 
176d0 28 69 36 34 29 28 70 67 6e 6f 2d 31 29 20 2a 20  (i64)(pgno-1) * 
176e0 73 7a 50 61 67 65 3b 0a 0a 20 20 20 20 20 20 20  szPage;..       
176f0 20 20 20 69 66 28 20 69 44 62 4f 66 66 2b 73 7a     if( iDbOff+sz
17700 50 61 67 65 3c 3d 73 7a 44 62 20 29 7b 0a 20 20  Page<=szDb ){.  
17710 20 20 20 20 20 20 20 20 20 20 69 57 61 6c 4f 66            iWalOf
17720 66 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73  f = walFrameOffs
17730 65 74 28 69 2c 20 73 7a 50 61 67 65 29 20 2b 20  et(i, szPage) + 
17740 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a  WAL_FRAME_HDRSIZ
17750 45 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72  E;.            r
17760 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61  c = sqlite3OsRea
17770 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20  d(pWal->pWalFd, 
17780 70 42 75 66 31 2c 20 73 7a 50 61 67 65 2c 20 69  pBuf1, szPage, i
17790 57 61 6c 4f 66 66 29 3b 0a 0a 20 20 20 20 20 20  WalOff);..      
177a0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
177b0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
177c0 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71           rc = sq
177d0 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c  lite3OsRead(pWal
177e0 2d 3e 70 44 62 46 64 2c 20 70 42 75 66 32 2c 20  ->pDbFd, pBuf2, 
177f0 73 7a 50 61 67 65 2c 20 69 44 62 4f 66 66 29 3b  szPage, iDbOff);
17800 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 0a  .            }..
17810 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20              if( 
17820 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c  rc!=SQLITE_OK ||
17830 20 30 3d 3d 6d 65 6d 63 6d 70 28 70 42 75 66 31   0==memcmp(pBuf1
17840 2c 20 70 42 75 66 32 2c 20 73 7a 50 61 67 65 29  , pBuf2, szPage)
17850 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
17860 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20    break;.       
17870 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
17880 20 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 70 49   }..          pI
17890 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 41 74  nfo->nBackfillAt
178a0 74 65 6d 70 74 65 64 20 3d 20 69 2d 31 3b 0a 20  tempted = i-1;. 
178b0 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
178c0 0a 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ..      sqlite3_
178d0 66 72 65 65 28 70 42 75 66 31 29 3b 0a 20 20 20  free(pBuf1);.   
178e0 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
178f0 70 42 75 66 32 29 3b 0a 20 20 20 20 7d 0a 20 20  pBuf2);.    }.  
17900 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75    walUnlockExclu
17910 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 43  sive(pWal, WAL_C
17920 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20  KPT_LOCK, 1);.  
17930 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
17940 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  }.#endif /* SQLI
17950 54 45 5f 45 4e 41 42 4c 45 5f 53 4e 41 50 53 48  TE_ENABLE_SNAPSH
17960 4f 54 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 42 65 67  OT */../*.** Beg
17970 69 6e 20 61 20 72 65 61 64 20 74 72 61 6e 73 61  in a read transa
17980 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20 64 61 74  ction on the dat
17990 61 62 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  abase..**.** Thi
179a0 73 20 72 6f 75 74 69 6e 65 20 75 73 65 64 20 74  s routine used t
179b0 6f 20 62 65 20 63 61 6c 6c 65 64 20 73 71 6c 69  o be called sqli
179c0 74 65 33 4f 70 65 6e 53 6e 61 70 73 68 6f 74 28  te3OpenSnapshot(
179d0 29 20 61 6e 64 20 77 69 74 68 20 67 6f 6f 64 20  ) and with good 
179e0 72 65 61 73 6f 6e 3a 0a 2a 2a 20 69 74 20 74 61  reason:.** it ta
179f0 6b 65 73 20 61 20 73 6e 61 70 73 68 6f 74 20 6f  kes a snapshot o
17a00 66 20 74 68 65 20 73 74 61 74 65 20 6f 66 20 74  f the state of t
17a10 68 65 20 57 41 4c 20 61 6e 64 20 77 61 6c 2d 69  he WAL and wal-i
17a20 6e 64 65 78 20 66 6f 72 20 74 68 65 20 63 75 72  ndex for the cur
17a30 72 65 6e 74 0a 2a 2a 20 69 6e 73 74 61 6e 74 20  rent.** instant 
17a40 69 6e 20 74 69 6d 65 2e 20 20 54 68 65 20 63 75  in time.  The cu
17a50 72 72 65 6e 74 20 74 68 72 65 61 64 20 77 69 6c  rrent thread wil
17a60 6c 20 63 6f 6e 74 69 6e 75 65 20 74 6f 20 75 73  l continue to us
17a70 65 20 74 68 69 73 20 73 6e 61 70 73 68 6f 74 2e  e this snapshot.
17a80 0a 2a 2a 20 4f 74 68 65 72 20 74 68 72 65 61 64  .** Other thread
17a90 73 20 6d 69 67 68 74 20 61 70 70 65 6e 64 20 6e  s might append n
17aa0 65 77 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74 68  ew content to th
17ab0 65 20 57 41 4c 20 61 6e 64 20 77 61 6c 2d 69 6e  e WAL and wal-in
17ac0 64 65 78 20 62 75 74 0a 2a 2a 20 74 68 61 74 20  dex but.** that 
17ad0 65 78 74 72 61 20 63 6f 6e 74 65 6e 74 20 69 73  extra content is
17ae0 20 69 67 6e 6f 72 65 64 20 62 79 20 74 68 65 20   ignored by the 
17af0 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 2e 0a  current thread..
17b00 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 64 61 74  **.** If the dat
17b10 61 62 61 73 65 20 63 6f 6e 74 65 6e 74 73 20 68  abase contents h
17b20 61 76 65 20 63 68 61 6e 67 65 73 20 73 69 6e 63  ave changes sinc
17b30 65 20 74 68 65 20 70 72 65 76 69 6f 75 73 20 72  e the previous r
17b40 65 61 64 0a 2a 2a 20 74 72 61 6e 73 61 63 74 69  ead.** transacti
17b50 6f 6e 2c 20 74 68 65 6e 20 2a 70 43 68 61 6e 67  on, then *pChang
17b60 65 64 20 69 73 20 73 65 74 20 74 6f 20 31 20 62  ed is set to 1 b
17b70 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
17b80 20 20 54 68 65 0a 2a 2a 20 50 61 67 65 72 20 6c    The.** Pager l
17b90 61 79 65 72 20 77 69 6c 6c 20 75 73 65 20 74 68  ayer will use th
17ba0 69 73 20 74 6f 20 6b 6e 6f 77 20 74 68 61 74 20  is to know that 
17bb0 69 73 20 63 61 63 68 65 20 69 73 20 73 74 61 6c  is cache is stal
17bc0 65 20 61 6e 64 0a 2a 2a 20 6e 65 65 64 73 20 74  e and.** needs t
17bd0 6f 20 62 65 20 66 6c 75 73 68 65 64 2e 0a 2a 2f  o be flushed..*/
17be0 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 42  .int sqlite3WalB
17bf0 65 67 69 6e 52 65 61 64 54 72 61 6e 73 61 63 74  eginReadTransact
17c00 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69  ion(Wal *pWal, i
17c10 6e 74 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a 20  nt *pChanged){. 
17c20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
17c30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17c40 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
17c50 2a 2f 0a 20 20 69 6e 74 20 63 6e 74 20 3d 20 30  */.  int cnt = 0
17c60 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
17c70 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
17c80 66 20 54 72 79 42 65 67 69 6e 52 65 61 64 20 61  f TryBeginRead a
17c90 74 74 65 6d 70 74 73 20 2a 2f 0a 0a 23 69 66 64  ttempts */..#ifd
17ca0 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45  ef SQLITE_ENABLE
17cb0 5f 53 4e 41 50 53 48 4f 54 0a 20 20 69 6e 74 20  _SNAPSHOT.  int 
17cc0 62 43 68 61 6e 67 65 64 20 3d 20 30 3b 0a 20 20  bChanged = 0;.  
17cd0 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 70 53 6e  WalIndexHdr *pSn
17ce0 61 70 73 68 6f 74 20 3d 20 70 57 61 6c 2d 3e 70  apshot = pWal->p
17cf0 53 6e 61 70 73 68 6f 74 3b 0a 20 20 69 66 28 20  Snapshot;.  if( 
17d00 70 53 6e 61 70 73 68 6f 74 20 26 26 20 6d 65 6d  pSnapshot && mem
17d10 63 6d 70 28 70 53 6e 61 70 73 68 6f 74 2c 20 26  cmp(pSnapshot, &
17d20 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f  pWal->hdr, sizeo
17d30 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 21  f(WalIndexHdr))!
17d40 3d 30 20 29 7b 0a 20 20 20 20 62 43 68 61 6e 67  =0 ){.    bChang
17d50 65 64 20 3d 20 31 3b 0a 20 20 7d 0a 23 65 6e 64  ed = 1;.  }.#end
17d60 69 66 0a 0a 20 20 64 6f 7b 0a 20 20 20 20 72 63  if..  do{.    rc
17d70 20 3d 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65   = walTryBeginRe
17d80 61 64 28 70 57 61 6c 2c 20 70 43 68 61 6e 67 65  ad(pWal, pChange
17d90 64 2c 20 30 2c 20 2b 2b 63 6e 74 29 3b 0a 20 20  d, 0, ++cnt);.  
17da0 7d 77 68 69 6c 65 28 20 72 63 3d 3d 57 41 4c 5f  }while( rc==WAL_
17db0 52 45 54 52 59 20 29 3b 0a 20 20 74 65 73 74 63  RETRY );.  testc
17dc0 61 73 65 28 20 28 72 63 26 30 78 66 66 29 3d 3d  ase( (rc&0xff)==
17dd0 53 51 4c 49 54 45 5f 42 55 53 59 20 29 3b 0a 20  SQLITE_BUSY );. 
17de0 20 74 65 73 74 63 61 73 65 28 20 28 72 63 26 30   testcase( (rc&0
17df0 78 66 66 29 3d 3d 53 51 4c 49 54 45 5f 49 4f 45  xff)==SQLITE_IOE
17e00 52 52 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65  RR );.  testcase
17e10 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 50 52 4f  ( rc==SQLITE_PRO
17e20 54 4f 43 4f 4c 20 29 3b 0a 20 20 74 65 73 74 63  TOCOL );.  testc
17e30 61 73 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ase( rc==SQLITE_
17e40 4f 4b 20 29 3b 0a 0a 23 69 66 64 65 66 20 53 51  OK );..#ifdef SQ
17e50 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e 41 50  LITE_ENABLE_SNAP
17e60 53 48 4f 54 0a 20 20 69 66 28 20 72 63 3d 3d 53  SHOT.  if( rc==S
17e70 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
17e80 69 66 28 20 70 53 6e 61 70 73 68 6f 74 20 26 26  if( pSnapshot &&
17e90 20 6d 65 6d 63 6d 70 28 70 53 6e 61 70 73 68 6f   memcmp(pSnapsho
17ea0 74 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73  t, &pWal->hdr, s
17eb0 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64  izeof(WalIndexHd
17ec0 72 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 20 20  r))!=0 ){.      
17ed0 2f 2a 20 41 74 20 74 68 69 73 20 70 6f 69 6e 74  /* At this point
17ee0 20 74 68 65 20 63 6c 69 65 6e 74 20 68 61 73 20   the client has 
17ef0 61 20 6c 6f 63 6b 20 6f 6e 20 61 6e 20 61 52 65  a lock on an aRe
17f00 61 64 4d 61 72 6b 5b 5d 20 73 6c 6f 74 20 68 6f  adMark[] slot ho
17f10 6c 64 69 6e 67 0a 20 20 20 20 20 20 2a 2a 20 61  lding.      ** a
17f20 20 76 61 6c 75 65 20 65 71 75 61 6c 20 74 6f 20   value equal to 
17f30 6f 72 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20  or smaller than 
17f40 70 53 6e 61 70 73 68 6f 74 2d 3e 6d 78 46 72 61  pSnapshot->mxFra
17f50 6d 65 2c 20 62 75 74 20 70 57 61 6c 2d 3e 68 64  me, but pWal->hd
17f60 72 0a 20 20 20 20 20 20 2a 2a 20 69 73 20 70 6f  r.      ** is po
17f70 70 75 6c 61 74 65 64 20 77 69 74 68 20 74 68 65  pulated with the
17f80 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
17f90 72 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20  r corresponding 
17fa0 74 6f 20 74 68 65 20 68 65 61 64 0a 20 20 20 20  to the head.    
17fb0 20 20 2a 2a 20 6f 66 20 74 68 65 20 77 61 6c 20    ** of the wal 
17fc0 66 69 6c 65 2e 20 56 65 72 69 66 79 20 74 68 61  file. Verify tha
17fd0 74 20 70 53 6e 61 70 73 68 6f 74 20 69 73 20 73  t pSnapshot is s
17fe0 74 69 6c 6c 20 76 61 6c 69 64 20 62 65 66 6f 72  till valid befor
17ff0 65 0a 20 20 20 20 20 20 2a 2a 20 63 6f 6e 74 69  e.      ** conti
18000 6e 75 69 6e 67 2e 20 20 52 65 61 73 6f 6e 73 20  nuing.  Reasons 
18010 77 68 79 20 70 53 6e 61 70 73 68 6f 74 20 6d 69  why pSnapshot mi
18020 67 68 74 20 6e 6f 20 6c 6f 6e 67 65 72 20 62 65  ght no longer be
18030 20 76 61 6c 69 64 3a 0a 20 20 20 20 20 20 2a 2a   valid:.      **
18040 0a 20 20 20 20 20 20 2a 2a 20 20 20 20 28 31 29  .      **    (1)
18050 20 20 54 68 65 20 57 41 4c 20 66 69 6c 65 20 68    The WAL file h
18060 61 73 20 62 65 65 6e 20 72 65 73 65 74 20 73 69  as been reset si
18070 6e 63 65 20 74 68 65 20 73 6e 61 70 73 68 6f 74  nce the snapshot
18080 20 77 61 73 20 74 61 6b 65 6e 2e 0a 20 20 20 20   was taken..    
18090 20 20 2a 2a 20 20 20 20 20 20 20 20 20 49 6e 20    **         In 
180a0 74 68 69 73 20 63 61 73 65 2c 20 74 68 65 20 73  this case, the s
180b0 61 6c 74 20 77 69 6c 6c 20 68 61 76 65 20 63 68  alt will have ch
180c0 61 6e 67 65 64 2e 0a 20 20 20 20 20 20 2a 2a 0a  anged..      **.
180d0 20 20 20 20 20 20 2a 2a 20 20 20 20 28 32 29 20        **    (2) 
180e0 20 41 20 63 68 65 63 6b 70 6f 69 6e 74 20 61 73   A checkpoint as
180f0 20 62 65 65 6e 20 61 74 74 65 6d 70 74 65 64 20   been attempted 
18100 74 68 61 74 20 77 72 6f 74 65 20 66 72 61 6d 65  that wrote frame
18110 73 20 70 61 73 74 0a 20 20 20 20 20 20 2a 2a 20  s past.      ** 
18120 20 20 20 20 20 20 20 20 70 53 6e 61 70 73 68 6f          pSnapsho
18130 74 2d 3e 6d 78 46 72 61 6d 65 20 69 6e 74 6f 20  t->mxFrame into 
18140 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
18150 65 2e 20 20 4e 6f 74 65 20 74 68 61 74 20 74 68  e.  Note that th
18160 65 0a 20 20 20 20 20 20 2a 2a 20 20 20 20 20 20  e.      **      
18170 20 20 20 63 68 65 63 6b 70 6f 69 6e 74 20 6e 65     checkpoint ne
18180 65 64 20 6e 6f 74 20 68 61 76 65 20 63 6f 6d 70  ed not have comp
18190 6c 65 74 65 64 20 66 6f 72 20 74 68 69 73 20 74  leted for this t
181a0 6f 20 63 61 75 73 65 20 70 72 6f 62 6c 65 6d 73  o cause problems
181b0 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20  ..      */.     
181c0 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70   volatile WalCkp
181d0 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 20 3d 20 77  tInfo *pInfo = w
181e0 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29  alCkptInfo(pWal)
181f0 3b 0a 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  ;..      assert(
18200 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e   pWal->readLock>
18210 30 20 7c 7c 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  0 || pWal->hdr.m
18220 78 46 72 61 6d 65 3d 3d 30 20 29 3b 0a 20 20 20  xFrame==0 );.   
18230 20 20 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f     assert( pInfo
18240 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 70 57 61 6c  ->aReadMark[pWal
18250 2d 3e 72 65 61 64 4c 6f 63 6b 5d 3c 3d 70 53 6e  ->readLock]<=pSn
18260 61 70 73 68 6f 74 2d 3e 6d 78 46 72 61 6d 65 20  apshot->mxFrame 
18270 29 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 49 74 20  );..      /* It 
18280 69 73 20 70 6f 73 73 69 62 6c 65 20 74 68 61 74  is possible that
18290 20 74 68 65 72 65 20 69 73 20 61 20 63 68 65 63   there is a chec
182a0 6b 70 6f 69 6e 74 65 72 20 74 68 72 65 61 64 20  kpointer thread 
182b0 72 75 6e 6e 69 6e 67 20 0a 20 20 20 20 20 20 2a  running .      *
182c0 2a 20 63 6f 6e 63 75 72 72 65 6e 74 20 77 69 74  * concurrent wit
182d0 68 20 74 68 69 73 20 63 6f 64 65 2e 20 49 66 20  h this code. If 
182e0 74 68 69 73 20 69 73 20 74 68 65 20 63 61 73 65  this is the case
182f0 2c 20 69 74 20 6d 61 79 20 62 65 20 74 68 61 74  , it may be that
18300 20 74 68 65 0a 20 20 20 20 20 20 2a 2a 20 63 68   the.      ** ch
18310 65 63 6b 70 6f 69 6e 74 65 72 20 68 61 73 20 61  eckpointer has a
18320 6c 72 65 61 64 79 20 64 65 74 65 72 6d 69 6e 65  lready determine
18330 64 20 74 68 61 74 20 69 74 20 77 69 6c 6c 20 63  d that it will c
18340 68 65 63 6b 70 6f 69 6e 74 20 0a 20 20 20 20 20  heckpoint .     
18350 20 2a 2a 20 73 6e 61 70 73 68 6f 74 20 58 2c 20   ** snapshot X, 
18360 77 68 65 72 65 20 58 20 69 73 20 6c 61 74 65 72  where X is later
18370 20 69 6e 20 74 68 65 20 77 61 6c 20 66 69 6c 65   in the wal file
18380 20 74 68 61 6e 20 70 53 6e 61 70 73 68 6f 74 2c   than pSnapshot,
18390 20 62 75 74 20 0a 20 20 20 20 20 20 2a 2a 20 68   but .      ** h
183a0 61 73 20 6e 6f 74 20 79 65 74 20 73 65 74 20 74  as not yet set t
183b0 68 65 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66  he pInfo->nBackf
183c0 69 6c 6c 41 74 74 65 6d 70 74 65 64 20 76 61 72  illAttempted var
183d0 69 61 62 6c 65 20 74 6f 20 69 6e 64 69 63 61 74  iable to indicat
183e0 65 20 0a 20 20 20 20 20 20 2a 2a 20 69 74 73 20  e .      ** its 
183f0 69 6e 74 65 6e 74 2e 20 54 6f 20 61 76 6f 69 64  intent. To avoid
18400 20 74 68 65 20 72 61 63 65 20 63 6f 6e 64 69 74   the race condit
18410 69 6f 6e 20 74 68 69 73 20 6c 65 61 64 73 20 74  ion this leads t
18420 6f 2c 20 65 6e 73 75 72 65 20 74 68 61 74 0a 20  o, ensure that. 
18430 20 20 20 20 20 2a 2a 20 74 68 65 72 65 20 69 73       ** there is
18440 20 6e 6f 20 63 68 65 63 6b 70 6f 69 6e 74 65 72   no checkpointer
18450 20 70 72 6f 63 65 73 73 20 62 79 20 74 61 6b 69   process by taki
18460 6e 67 20 61 20 73 68 61 72 65 64 20 43 4b 50 54  ng a shared CKPT
18470 20 6c 6f 63 6b 20 0a 20 20 20 20 20 20 2a 2a 20   lock .      ** 
18480 62 65 66 6f 72 65 20 63 68 65 63 6b 69 6e 67 20  before checking 
18490 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
184a0 41 74 74 65 6d 70 74 65 64 2e 20 20 0a 20 20 20  Attempted.  .   
184b0 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 54     **.      ** T
184c0 4f 44 4f 3a 20 44 6f 65 73 20 74 68 65 20 61 52  ODO: Does the aR
184d0 65 61 64 4d 61 72 6b 5b 5d 20 6c 6f 63 6b 20 70  eadMark[] lock p
184e0 72 65 76 65 6e 74 20 61 20 63 68 65 63 6b 70 6f  revent a checkpo
184f0 69 6e 74 65 72 20 66 72 6f 6d 20 64 6f 69 6e 67  inter from doing
18500 0a 20 20 20 20 20 20 2a 2a 20 20 20 20 20 20 20  .      **       
18510 74 68 69 73 20 61 6c 72 65 61 64 79 3f 0a 20 20  this already?.  
18520 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 72 63 20      */.      rc 
18530 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28  = walLockShared(
18540 70 57 61 6c 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c  pWal, WAL_CKPT_L
18550 4f 43 4b 29 3b 0a 0a 20 20 20 20 20 20 69 66 28  OCK);..      if(
18560 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
18570 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65  {.        /* Che
18580 63 6b 20 74 68 61 74 20 74 68 65 20 77 61 6c 20  ck that the wal 
18590 66 69 6c 65 20 68 61 73 20 6e 6f 74 20 62 65 65  file has not bee
185a0 6e 20 77 72 61 70 70 65 64 2e 20 41 73 73 75 6d  n wrapped. Assum
185b0 69 6e 67 20 74 68 61 74 20 69 74 20 68 61 73 0a  ing that it has.
185c0 20 20 20 20 20 20 20 20 2a 2a 20 6e 6f 74 2c 20          ** not, 
185d0 61 6c 73 6f 20 63 68 65 63 6b 20 74 68 61 74 20  also check that 
185e0 6e 6f 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 20  no checkpointer 
185f0 68 61 73 20 61 74 74 65 6d 70 74 65 64 20 74 6f  has attempted to
18600 20 63 68 65 63 6b 70 6f 69 6e 74 20 61 6e 79 0a   checkpoint any.
18610 20 20 20 20 20 20 20 20 2a 2a 20 66 72 61 6d 65          ** frame
18620 73 20 62 65 79 6f 6e 64 20 70 53 6e 61 70 73 68  s beyond pSnapsh
18630 6f 74 2d 3e 6d 78 46 72 61 6d 65 2e 20 49 66 20  ot->mxFrame. If 
18640 65 69 74 68 65 72 20 6f 66 20 74 68 65 73 65 20  either of these 
18650 63 6f 6e 64 69 74 69 6f 6e 73 20 61 72 65 0a 20  conditions are. 
18660 20 20 20 20 20 20 20 2a 2a 20 74 72 75 65 2c 20         ** true, 
18670 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 42 55  return SQLITE_BU
18680 53 59 5f 53 4e 41 50 53 48 4f 54 2e 20 4f 74 68  SY_SNAPSHOT. Oth
18690 65 72 77 69 73 65 2c 20 6f 76 65 72 77 72 69 74  erwise, overwrit
186a0 65 20 70 57 61 6c 2d 3e 68 64 72 0a 20 20 20 20  e pWal->hdr.    
186b0 20 20 20 20 2a 2a 20 77 69 74 68 20 2a 70 53 6e      ** with *pSn
186c0 61 70 73 68 6f 74 20 61 6e 64 20 73 65 74 20 2a  apshot and set *
186d0 70 43 68 61 6e 67 65 64 20 61 73 20 61 70 70 72  pChanged as appr
186e0 6f 70 72 69 61 74 65 20 66 6f 72 20 6f 70 65 6e  opriate for open
186f0 69 6e 67 20 74 68 65 0a 20 20 20 20 20 20 20 20  ing the.        
18700 2a 2a 20 73 6e 61 70 73 68 6f 74 2e 20 20 2a 2f  ** snapshot.  */
18710 0a 20 20 20 20 20 20 20 20 69 66 28 20 21 6d 65  .        if( !me
18720 6d 63 6d 70 28 70 53 6e 61 70 73 68 6f 74 2d 3e  mcmp(pSnapshot->
18730 61 53 61 6c 74 2c 20 70 57 61 6c 2d 3e 68 64 72  aSalt, pWal->hdr
18740 2e 61 53 61 6c 74 2c 20 73 69 7a 65 6f 66 28 70  .aSalt, sizeof(p
18750 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 29 29  Wal->hdr.aSalt))
18760 0a 20 20 20 20 20 20 20 20 20 26 26 20 70 53 6e  .         && pSn
18770 61 70 73 68 6f 74 2d 3e 6d 78 46 72 61 6d 65 3e  apshot->mxFrame>
18780 3d 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c  =pInfo->nBackfil
18790 6c 41 74 74 65 6d 70 74 65 64 0a 20 20 20 20 20  lAttempted.     
187a0 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20     ){.          
187b0 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65  assert( pWal->re
187c0 61 64 4c 6f 63 6b 3e 30 20 29 3b 0a 20 20 20 20  adLock>0 );.    
187d0 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 70 57        memcpy(&pW
187e0 61 6c 2d 3e 68 64 72 2c 20 70 53 6e 61 70 73 68  al->hdr, pSnapsh
187f0 6f 74 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  ot, sizeof(WalIn
18800 64 65 78 48 64 72 29 29 3b 0a 20 20 20 20 20 20  dexHdr));.      
18810 20 20 20 20 2a 70 43 68 61 6e 67 65 64 20 3d 20      *pChanged = 
18820 62 43 68 61 6e 67 65 64 3b 0a 20 20 20 20 20 20  bChanged;.      
18830 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
18840 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42     rc = SQLITE_B
18850 55 53 59 5f 53 4e 41 50 53 48 4f 54 3b 0a 20 20  USY_SNAPSHOT;.  
18860 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20        }..       
18870 20 2f 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20   /* Release the 
18880 73 68 61 72 65 64 20 43 4b 50 54 20 6c 6f 63 6b  shared CKPT lock
18890 20 6f 62 74 61 69 6e 65 64 20 61 62 6f 76 65 2e   obtained above.
188a0 20 2a 2f 0a 20 20 20 20 20 20 20 20 77 61 6c 55   */.        walU
188b0 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
188c0 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 29  , WAL_CKPT_LOCK)
188d0 3b 0a 20 20 20 20 20 20 7d 0a 0a 0a 20 20 20 20  ;.      }...    
188e0 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
188f0 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 73  _OK ){.        s
18900 71 6c 69 74 65 33 57 61 6c 45 6e 64 52 65 61 64  qlite3WalEndRead
18910 54 72 61 6e 73 61 63 74 69 6f 6e 28 70 57 61 6c  Transaction(pWal
18920 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
18930 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 72 65  .  }.#endif.  re
18940 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
18950 2a 20 46 69 6e 69 73 68 20 77 69 74 68 20 61 20  * Finish with a 
18960 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
18970 2e 20 20 41 6c 6c 20 74 68 69 73 20 64 6f 65 73  .  All this does
18980 20 69 73 20 72 65 6c 65 61 73 65 20 74 68 65 0a   is release the.
18990 2a 2a 20 72 65 61 64 2d 6c 6f 63 6b 2e 0a 2a 2f  ** read-lock..*/
189a0 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c  .void sqlite3Wal
189b0 45 6e 64 52 65 61 64 54 72 61 6e 73 61 63 74 69  EndReadTransacti
189c0 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20  on(Wal *pWal){. 
189d0 20 73 71 6c 69 74 65 33 57 61 6c 45 6e 64 57 72   sqlite3WalEndWr
189e0 69 74 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 70  iteTransaction(p
189f0 57 61 6c 29 3b 0a 20 20 69 66 28 20 70 57 61 6c  Wal);.  if( pWal
18a00 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 7b  ->readLock>=0 ){
18a10 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68  .    walUnlockSh
18a20 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
18a30 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72  EAD_LOCK(pWal->r
18a40 65 61 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70  eadLock));.    p
18a50 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20  Wal->readLock = 
18a60 2d 31 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  -1;.  }.}../*.**
18a70 20 53 65 61 72 63 68 20 74 68 65 20 77 61 6c 20   Search the wal 
18a80 66 69 6c 65 20 66 6f 72 20 70 61 67 65 20 70 67  file for page pg
18a90 6e 6f 2e 20 49 66 20 66 6f 75 6e 64 2c 20 73 65  no. If found, se
18aa0 74 20 2a 70 69 52 65 61 64 20 74 6f 20 74 68 65  t *piRead to the
18ab0 20 66 72 61 6d 65 20 74 68 61 74 0a 2a 2a 20 63   frame that.** c
18ac0 6f 6e 74 61 69 6e 73 20 74 68 65 20 70 61 67 65  ontains the page
18ad0 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  . Otherwise, if 
18ae0 70 67 6e 6f 20 69 73 20 6e 6f 74 20 69 6e 20 74  pgno is not in t
18af0 68 65 20 77 61 6c 20 66 69 6c 65 2c 20 73 65 74  he wal file, set
18b00 20 2a 70 69 52 65 61 64 0a 2a 2a 20 74 6f 20 7a   *piRead.** to z
18b10 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72  ero..**.** Retur
18b20 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73  n SQLITE_OK if s
18b30 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e  uccessful, or an
18b40 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66 20 61   error code if a
18b50 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 20  n error occurs. 
18b60 49 66 20 61 6e 0a 2a 2a 20 65 72 72 6f 72 20 64  If an.** error d
18b70 6f 65 73 20 6f 63 63 75 72 2c 20 74 68 65 20 66  oes occur, the f
18b80 69 6e 61 6c 20 76 61 6c 75 65 20 6f 66 20 2a 70  inal value of *p
18b90 69 52 65 61 64 20 69 73 20 75 6e 64 65 66 69 6e  iRead is undefin
18ba0 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ed..*/.int sqlit
18bb0 65 33 57 61 6c 46 69 6e 64 46 72 61 6d 65 28 0a  e3WalFindFrame(.
18bc0 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
18bd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18be0 20 20 2f 2a 20 57 41 4c 20 68 61 6e 64 6c 65 20    /* WAL handle 
18bf0 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e 6f 2c 20  */.  Pgno pgno, 
18c00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18c10 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
18c20 20 70 61 67 65 20 6e 75 6d 62 65 72 20 74 6f 20   page number to 
18c30 72 65 61 64 20 64 61 74 61 20 66 6f 72 20 2a 2f  read data for */
18c40 0a 20 20 75 33 32 20 2a 70 69 52 65 61 64 20 20  .  u32 *piRead  
18c50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18c60 20 20 20 2f 2a 20 4f 55 54 3a 20 46 72 61 6d 65     /* OUT: Frame
18c70 20 6e 75 6d 62 65 72 20 28 6f 72 20 7a 65 72 6f   number (or zero
18c80 29 20 2a 2f 0a 29 7b 0a 20 20 75 33 32 20 69 52  ) */.){.  u32 iR
18c90 65 61 64 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ead = 0;        
18ca0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20            /* If 
18cb0 21 3d 30 2c 20 57 41 4c 20 66 72 61 6d 65 20 74  !=0, WAL frame t
18cc0 6f 20 72 65 74 75 72 6e 20 64 61 74 61 20 66 72  o return data fr
18cd0 6f 6d 20 2a 2f 0a 20 20 75 33 32 20 69 4c 61 73  om */.  u32 iLas
18ce0 74 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  t = pWal->hdr.mx
18cf0 46 72 61 6d 65 3b 20 20 2f 2a 20 4c 61 73 74 20  Frame;  /* Last 
18d00 70 61 67 65 20 69 6e 20 57 41 4c 20 66 6f 72 20  page in WAL for 
18d10 74 68 69 73 20 72 65 61 64 65 72 20 2a 2f 0a 20  this reader */. 
18d20 20 69 6e 74 20 69 48 61 73 68 3b 20 20 20 20 20   int iHash;     
18d30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18d40 20 2f 2a 20 55 73 65 64 20 74 6f 20 6c 6f 6f 70   /* Used to loop
18d50 20 74 68 72 6f 75 67 68 20 4e 20 68 61 73 68 20   through N hash 
18d60 74 61 62 6c 65 73 20 2a 2f 0a 20 20 69 6e 74 20  tables */.  int 
18d70 69 4d 69 6e 48 61 73 68 3b 0a 0a 20 20 2f 2a 20  iMinHash;..  /* 
18d80 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20  This routine is 
18d90 6f 6e 6c 79 20 62 65 20 63 61 6c 6c 65 64 20 66  only be called f
18da0 72 6f 6d 20 77 69 74 68 69 6e 20 61 20 72 65 61  rom within a rea
18db0 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 2a  d transaction. *
18dc0 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  /.  assert( pWal
18dd0 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c  ->readLock>=0 ||
18de0 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72   pWal->lockError
18df0 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65   );..  /* If the
18e00 20 22 6c 61 73 74 20 70 61 67 65 22 20 66 69 65   "last page" fie
18e10 6c 64 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ld of the wal-in
18e20 64 65 78 20 68 65 61 64 65 72 20 73 6e 61 70 73  dex header snaps
18e30 68 6f 74 20 69 73 20 30 2c 20 74 68 65 6e 0a 20  hot is 0, then. 
18e40 20 2a 2a 20 6e 6f 20 64 61 74 61 20 77 69 6c 6c   ** no data will
18e50 20 62 65 20 72 65 61 64 20 66 72 6f 6d 20 74 68   be read from th
18e60 65 20 77 61 6c 20 75 6e 64 65 72 20 61 6e 79 20  e wal under any 
18e70 63 69 72 63 75 6d 73 74 61 6e 63 65 73 2e 20 52  circumstances. R
18e80 65 74 75 72 6e 20 65 61 72 6c 79 0a 20 20 2a 2a  eturn early.  **
18e90 20 69 6e 20 74 68 69 73 20 63 61 73 65 20 61 73   in this case as
18ea0 20 61 6e 20 6f 70 74 69 6d 69 7a 61 74 69 6f 6e   an optimization
18eb0 2e 20 20 4c 69 6b 65 77 69 73 65 2c 20 69 66 20  .  Likewise, if 
18ec0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d  pWal->readLock==
18ed0 30 2c 20 0a 20 20 2a 2a 20 74 68 65 6e 20 74 68  0, .  ** then th
18ee0 65 20 57 41 4c 20 69 73 20 69 67 6e 6f 72 65 64  e WAL is ignored
18ef0 20 62 79 20 74 68 65 20 72 65 61 64 65 72 20 73   by the reader s
18f00 6f 20 72 65 74 75 72 6e 20 65 61 72 6c 79 2c 20  o return early, 
18f10 61 73 20 69 66 20 74 68 65 20 0a 20 20 2a 2a 20  as if the .  ** 
18f20 57 41 4c 20 77 65 72 65 20 65 6d 70 74 79 2e 0a  WAL were empty..
18f30 20 20 2a 2f 0a 20 20 69 66 28 20 69 4c 61 73 74    */.  if( iLast
18f40 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 72 65 61  ==0 || pWal->rea
18f50 64 4c 6f 63 6b 3d 3d 30 20 29 7b 0a 20 20 20 20  dLock==0 ){.    
18f60 2a 70 69 52 65 61 64 20 3d 20 30 3b 0a 20 20 20  *piRead = 0;.   
18f70 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
18f80 4b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 65 61  K;.  }..  /* Sea
18f90 72 63 68 20 74 68 65 20 68 61 73 68 20 74 61 62  rch the hash tab
18fa0 6c 65 20 6f 72 20 74 61 62 6c 65 73 20 66 6f 72  le or tables for
18fb0 20 61 6e 20 65 6e 74 72 79 20 6d 61 74 63 68 69   an entry matchi
18fc0 6e 67 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 20  ng page number. 
18fd0 20 2a 2a 20 70 67 6e 6f 2e 20 45 61 63 68 20 69   ** pgno. Each i
18fe0 74 65 72 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  teration of the 
18ff0 66 6f 6c 6c 6f 77 69 6e 67 20 66 6f 72 28 29 20  following for() 
19000 6c 6f 6f 70 20 73 65 61 72 63 68 65 73 20 6f 6e  loop searches on
19010 65 0a 20 20 2a 2a 20 68 61 73 68 20 74 61 62 6c  e.  ** hash tabl
19020 65 20 28 65 61 63 68 20 68 61 73 68 20 74 61 62  e (each hash tab
19030 6c 65 20 69 6e 64 65 78 65 73 20 75 70 20 74 6f  le indexes up to
19040 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45   HASHTABLE_NPAGE
19050 20 66 72 61 6d 65 73 29 2e 0a 20 20 2a 2a 0a 20   frames)..  **. 
19060 20 2a 2a 20 54 68 69 73 20 63 6f 64 65 20 6d 69   ** This code mi
19070 67 68 74 20 72 75 6e 20 63 6f 6e 63 75 72 72 65  ght run concurre
19080 6e 74 6c 79 20 74 6f 20 74 68 65 20 63 6f 64 65  ntly to the code
19090 20 69 6e 20 77 61 6c 49 6e 64 65 78 41 70 70 65   in walIndexAppe
190a0 6e 64 28 29 0a 20 20 2a 2a 20 74 68 61 74 20 61  nd().  ** that a
190b0 64 64 73 20 65 6e 74 72 69 65 73 20 74 6f 20 74  dds entries to t
190c0 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 28 61 6e  he wal-index (an
190d0 64 20 70 6f 73 73 69 62 6c 79 20 74 6f 20 74 68  d possibly to th
190e0 69 73 20 68 61 73 68 20 0a 20 20 2a 2a 20 74 61  is hash .  ** ta
190f0 62 6c 65 29 2e 20 54 68 69 73 20 6d 65 61 6e 73  ble). This means
19100 20 74 68 65 20 76 61 6c 75 65 20 6a 75 73 74 20   the value just 
19110 72 65 61 64 20 66 72 6f 6d 20 74 68 65 20 68 61  read from the ha
19120 73 68 20 0a 20 20 2a 2a 20 73 6c 6f 74 20 28 61  sh .  ** slot (a
19130 48 61 73 68 5b 69 4b 65 79 5d 29 20 6d 61 79 20  Hash[iKey]) may 
19140 68 61 76 65 20 62 65 65 6e 20 61 64 64 65 64 20  have been added 
19150 62 65 66 6f 72 65 20 6f 72 20 61 66 74 65 72 20  before or after 
19160 74 68 65 20 0a 20 20 2a 2a 20 63 75 72 72 65 6e  the .  ** curren
19170 74 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  t read transacti
19180 6f 6e 20 77 61 73 20 6f 70 65 6e 65 64 2e 20 56  on was opened. V
19190 61 6c 75 65 73 20 61 64 64 65 64 20 61 66 74 65  alues added afte
191a0 72 20 74 68 65 0a 20 20 2a 2a 20 72 65 61 64 20  r the.  ** read 
191b0 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61 73 20  transaction was 
191c0 6f 70 65 6e 65 64 20 6d 61 79 20 68 61 76 65 20  opened may have 
191d0 62 65 65 6e 20 77 72 69 74 74 65 6e 20 69 6e 63  been written inc
191e0 6f 72 72 65 63 74 6c 79 20 2d 0a 20 20 2a 2a 20  orrectly -.  ** 
191f0 69 2e 65 2e 20 74 68 65 73 65 20 73 6c 6f 74 73  i.e. these slots
19200 20 6d 61 79 20 63 6f 6e 74 61 69 6e 20 67 61 72   may contain gar
19210 62 61 67 65 20 64 61 74 61 2e 20 48 6f 77 65 76  bage data. Howev
19220 65 72 2c 20 77 65 20 61 73 73 75 6d 65 0a 20 20  er, we assume.  
19230 2a 2a 20 74 68 61 74 20 61 6e 79 20 73 6c 6f 74  ** that any slot
19240 73 20 77 72 69 74 74 65 6e 20 62 65 66 6f 72 65  s written before
19250 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 65 61   the current rea
19260 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61  d transaction wa
19270 73 0a 20 20 2a 2a 20 6f 70 65 6e 65 64 20 72 65  s.  ** opened re
19280 6d 61 69 6e 20 75 6e 6d 6f 64 69 66 69 65 64 2e  main unmodified.
19290 0a 20 20 2a 2a 0a 20 20 2a 2a 20 46 6f 72 20 74  .  **.  ** For t
192a0 68 65 20 72 65 61 73 6f 6e 73 20 61 62 6f 76 65  he reasons above
192b0 2c 20 74 68 65 20 69 66 28 2e 2e 2e 29 20 63 6f  , the if(...) co
192c0 6e 64 69 74 69 6f 6e 20 66 65 61 74 75 72 65 64  ndition featured
192d0 20 69 6e 20 74 68 65 20 69 6e 6e 65 72 0a 20 20   in the inner.  
192e0 2a 2a 20 6c 6f 6f 70 20 6f 66 20 74 68 65 20 66  ** loop of the f
192f0 6f 6c 6c 6f 77 69 6e 67 20 62 6c 6f 63 6b 20 69  ollowing block i
19300 73 20 6d 6f 72 65 20 73 74 72 69 6e 67 65 6e 74  s more stringent
19310 20 74 68 61 74 20 77 6f 75 6c 64 20 62 65 20 72   that would be r
19320 65 71 75 69 72 65 64 20 0a 20 20 2a 2a 20 69 66  equired .  ** if
19330 20 77 65 20 68 61 64 20 65 78 63 6c 75 73 69 76   we had exclusiv
19340 65 20 61 63 63 65 73 73 20 74 6f 20 74 68 65 20  e access to the 
19350 68 61 73 68 2d 74 61 62 6c 65 3a 0a 20 20 2a 2a  hash-table:.  **
19360 0a 20 20 2a 2a 20 20 20 28 61 50 67 6e 6f 5b 69  .  **   (aPgno[i
19370 46 72 61 6d 65 5d 3d 3d 70 67 6e 6f 29 3a 20 0a  Frame]==pgno): .
19380 20 20 2a 2a 20 20 20 20 20 54 68 69 73 20 63 6f    **     This co
19390 6e 64 69 74 69 6f 6e 20 66 69 6c 74 65 72 73 20  ndition filters 
193a0 6f 75 74 20 6e 6f 72 6d 61 6c 20 68 61 73 68 2d  out normal hash-
193b0 74 61 62 6c 65 20 63 6f 6c 6c 69 73 69 6f 6e 73  table collisions
193c0 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 28 69  ..  **.  **   (i
193d0 46 72 61 6d 65 3c 3d 69 4c 61 73 74 29 3a 20 0a  Frame<=iLast): .
193e0 20 20 2a 2a 20 20 20 20 20 54 68 69 73 20 63 6f    **     This co
193f0 6e 64 69 74 69 6f 6e 20 66 69 6c 74 65 72 73 20  ndition filters 
19400 6f 75 74 20 65 6e 74 72 69 65 73 20 74 68 61 74  out entries that
19410 20 77 65 72 65 20 61 64 64 65 64 20 74 6f 20 74   were added to t
19420 68 65 20 68 61 73 68 0a 20 20 2a 2a 20 20 20 20  he hash.  **    
19430 20 74 61 62 6c 65 20 61 66 74 65 72 20 74 68 65   table after the
19440 20 63 75 72 72 65 6e 74 20 72 65 61 64 2d 74 72   current read-tr
19450 61 6e 73 61 63 74 69 6f 6e 20 68 61 64 20 73 74  ansaction had st
19460 61 72 74 65 64 2e 0a 20 20 2a 2f 0a 20 20 69 4d  arted..  */.  iM
19470 69 6e 48 61 73 68 20 3d 20 77 61 6c 46 72 61 6d  inHash = walFram
19480 65 50 61 67 65 28 70 57 61 6c 2d 3e 6d 69 6e 46  ePage(pWal->minF
19490 72 61 6d 65 29 3b 0a 20 20 66 6f 72 28 69 48 61  rame);.  for(iHa
194a0 73 68 3d 77 61 6c 46 72 61 6d 65 50 61 67 65 28  sh=walFramePage(
194b0 69 4c 61 73 74 29 3b 20 69 48 61 73 68 3e 3d 69  iLast); iHash>=i
194c0 4d 69 6e 48 61 73 68 20 26 26 20 69 52 65 61 64  MinHash && iRead
194d0 3d 3d 30 3b 20 69 48 61 73 68 2d 2d 29 7b 0a 20  ==0; iHash--){. 
194e0 20 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73     volatile ht_s
194f0 6c 6f 74 20 2a 61 48 61 73 68 3b 20 20 20 20 20  lot *aHash;     
19500 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 68   /* Pointer to h
19510 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20  ash table */.   
19520 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61   volatile u32 *a
19530 50 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 2f  Pgno;          /
19540 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 61 72 72  * Pointer to arr
19550 61 79 20 6f 66 20 70 61 67 65 20 6e 75 6d 62 65  ay of page numbe
19560 72 73 20 2a 2f 0a 20 20 20 20 75 33 32 20 69 5a  rs */.    u32 iZ
19570 65 72 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20  ero;            
19580 20 20 20 20 20 20 20 20 2f 2a 20 46 72 61 6d 65          /* Frame
19590 20 6e 75 6d 62 65 72 20 63 6f 72 72 65 73 70 6f   number correspo
195a0 6e 64 69 6e 67 20 74 6f 20 61 50 67 6e 6f 5b 30  nding to aPgno[0
195b0 5d 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 4b 65  ] */.    int iKe
195c0 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y;              
195d0 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 73         /* Hash s
195e0 6c 6f 74 20 69 6e 64 65 78 20 2a 2f 0a 20 20 20  lot index */.   
195f0 20 69 6e 74 20 6e 43 6f 6c 6c 69 64 65 3b 20 20   int nCollide;  
19600 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
19610 2a 20 4e 75 6d 62 65 72 20 6f 66 20 68 61 73 68  * Number of hash
19620 20 63 6f 6c 6c 69 73 69 6f 6e 73 20 72 65 6d 61   collisions rema
19630 69 6e 69 6e 67 20 2a 2f 0a 20 20 20 20 69 6e 74  ining */.    int
19640 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
19650 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45 72             /* Er
19660 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 0a 20 20 20  ror code */..   
19670 20 72 63 20 3d 20 77 61 6c 48 61 73 68 47 65 74   rc = walHashGet
19680 28 70 57 61 6c 2c 20 69 48 61 73 68 2c 20 26 61  (pWal, iHash, &a
19690 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20 26 69  Hash, &aPgno, &i
196a0 5a 65 72 6f 29 3b 0a 20 20 20 20 69 66 28 20 72  Zero);.    if( r
196b0 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
196c0 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
196d0 0a 20 20 20 20 7d 0a 20 20 20 20 6e 43 6f 6c 6c  .    }.    nColl
196e0 69 64 65 20 3d 20 48 41 53 48 54 41 42 4c 45 5f  ide = HASHTABLE_
196f0 4e 53 4c 4f 54 3b 0a 20 20 20 20 66 6f 72 28 69  NSLOT;.    for(i
19700 4b 65 79 3d 77 61 6c 48 61 73 68 28 70 67 6e 6f  Key=walHash(pgno
19710 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20  ); aHash[iKey]; 
19720 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68  iKey=walNextHash
19730 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 75  (iKey)){.      u
19740 33 32 20 69 46 72 61 6d 65 20 3d 20 61 48 61 73  32 iFrame = aHas
19750 68 5b 69 4b 65 79 5d 20 2b 20 69 5a 65 72 6f 3b  h[iKey] + iZero;
19760 0a 20 20 20 20 20 20 69 66 28 20 69 46 72 61 6d  .      if( iFram
19770 65 3c 3d 69 4c 61 73 74 20 26 26 20 69 46 72 61  e<=iLast && iFra
19780 6d 65 3e 3d 70 57 61 6c 2d 3e 6d 69 6e 46 72 61  me>=pWal->minFra
19790 6d 65 20 26 26 20 61 50 67 6e 6f 5b 61 48 61 73  me && aPgno[aHas
197a0 68 5b 69 4b 65 79 5d 5d 3d 3d 70 67 6e 6f 20 29  h[iKey]]==pgno )
197b0 7b 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74  {.        assert
197c0 28 20 69 46 72 61 6d 65 3e 69 52 65 61 64 20 7c  ( iFrame>iRead |
197d0 7c 20 43 4f 52 52 55 50 54 5f 44 42 20 29 3b 0a  | CORRUPT_DB );.
197e0 20 20 20 20 20 20 20 20 69 52 65 61 64 20 3d 20          iRead = 
197f0 69 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 7d 0a  iFrame;.      }.
19800 20 20 20 20 20 20 69 66 28 20 28 6e 43 6f 6c 6c        if( (nColl
19810 69 64 65 2d 2d 29 3d 3d 30 20 29 7b 0a 20 20 20  ide--)==0 ){.   
19820 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
19830 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b  TE_CORRUPT_BKPT;
19840 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
19850 20 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54   }..#ifdef SQLIT
19860 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
19870 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20 49  VE_ASSERT.  /* I
19880 66 20 65 78 70 65 6e 73 69 76 65 20 61 73 73 65  f expensive asse
19890 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74 73 20  rt() statements 
198a0 61 72 65 20 61 76 61 69 6c 61 62 6c 65 2c 20 64  are available, d
198b0 6f 20 61 20 6c 69 6e 65 61 72 20 73 65 61 72 63  o a linear searc
198c0 68 0a 20 20 2a 2a 20 6f 66 20 74 68 65 20 77 61  h.  ** of the wa
198d0 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20 63 6f 6e  l-index file con
198e0 74 65 6e 74 2e 20 4d 61 6b 65 20 73 75 72 65 20  tent. Make sure 
198f0 74 68 65 20 72 65 73 75 6c 74 73 20 61 67 72 65  the results agre
19900 65 20 77 69 74 68 20 74 68 65 0a 20 20 2a 2a 20  e with the.  ** 
19910 72 65 73 75 6c 74 20 6f 62 74 61 69 6e 65 64 20  result obtained 
19920 75 73 69 6e 67 20 74 68 65 20 68 61 73 68 20 69  using the hash i
19930 6e 64 65 78 65 73 20 61 62 6f 76 65 2e 20 20 2a  ndexes above.  *
19940 2f 0a 20 20 7b 0a 20 20 20 20 75 33 32 20 69 52  /.  {.    u32 iR
19950 65 61 64 32 20 3d 20 30 3b 0a 20 20 20 20 75 33  ead2 = 0;.    u3
19960 32 20 69 54 65 73 74 3b 0a 20 20 20 20 61 73 73  2 iTest;.    ass
19970 65 72 74 28 20 70 57 61 6c 2d 3e 6d 69 6e 46 72  ert( pWal->minFr
19980 61 6d 65 3e 30 20 29 3b 0a 20 20 20 20 66 6f 72  ame>0 );.    for
19990 28 69 54 65 73 74 3d 69 4c 61 73 74 3b 20 69 54  (iTest=iLast; iT
199a0 65 73 74 3e 3d 70 57 61 6c 2d 3e 6d 69 6e 46 72  est>=pWal->minFr
199b0 61 6d 65 3b 20 69 54 65 73 74 2d 2d 29 7b 0a 20  ame; iTest--){. 
199c0 20 20 20 20 20 69 66 28 20 77 61 6c 46 72 61 6d       if( walFram
199d0 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 54 65 73  ePgno(pWal, iTes
199e0 74 29 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20 20  t)==pgno ){.    
199f0 20 20 20 20 69 52 65 61 64 32 20 3d 20 69 54 65      iRead2 = iTe
19a00 73 74 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  st;.        brea
19a10 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k;.      }.    }
19a20 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 52 65  .    assert( iRe
19a30 61 64 3d 3d 69 52 65 61 64 32 20 29 3b 0a 20 20  ad==iRead2 );.  
19a40 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2a 70 69 52  }.#endif..  *piR
19a50 65 61 64 20 3d 20 69 52 65 61 64 3b 0a 20 20 72  ead = iRead;.  r
19a60 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
19a70 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 74  .}../*.** Read t
19a80 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 66  he contents of f
19a90 72 61 6d 65 20 69 52 65 61 64 20 66 72 6f 6d 20  rame iRead from 
19aa0 74 68 65 20 77 61 6c 20 66 69 6c 65 20 69 6e 74  the wal file int
19ab0 6f 20 62 75 66 66 65 72 20 70 4f 75 74 0a 2a 2a  o buffer pOut.**
19ac0 20 28 77 68 69 63 68 20 69 73 20 6e 4f 75 74 20   (which is nOut 
19ad0 62 79 74 65 73 20 69 6e 20 73 69 7a 65 29 2e 20  bytes in size). 
19ae0 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  Return SQLITE_OK
19af0 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   if successful, 
19b00 6f 72 20 61 6e 0a 2a 2a 20 65 72 72 6f 72 20 63  or an.** error c
19b10 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a  ode otherwise..*
19b20 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c  /.int sqlite3Wal
19b30 52 65 61 64 46 72 61 6d 65 28 0a 20 20 57 61 6c  ReadFrame(.  Wal
19b40 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20   *pWal,         
19b50 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
19b60 57 41 4c 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  WAL handle */.  
19b70 75 33 32 20 69 52 65 61 64 2c 20 20 20 20 20 20  u32 iRead,      
19b80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19b90 2f 2a 20 46 72 61 6d 65 20 74 6f 20 72 65 61 64  /* Frame to read
19ba0 20 2a 2f 0a 20 20 69 6e 74 20 6e 4f 75 74 2c 20   */.  int nOut, 
19bb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19bc0 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
19bd0 20 62 75 66 66 65 72 20 70 4f 75 74 20 69 6e 20   buffer pOut in 
19be0 62 79 74 65 73 20 2a 2f 0a 20 20 75 38 20 2a 70  bytes */.  u8 *p
19bf0 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20 20  Out             
19c00 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75             /* Bu
19c10 66 66 65 72 20 74 6f 20 77 72 69 74 65 20 70 61  ffer to write pa
19c20 67 65 20 64 61 74 61 20 74 6f 20 2a 2f 0a 29 7b  ge data to */.){
19c30 0a 20 20 69 6e 74 20 73 7a 3b 0a 20 20 69 36 34  .  int sz;.  i64
19c40 20 69 4f 66 66 73 65 74 3b 0a 20 20 73 7a 20 3d   iOffset;.  sz =
19c50 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67   pWal->hdr.szPag
19c60 65 3b 0a 20 20 73 7a 20 3d 20 28 73 7a 26 30 78  e;.  sz = (sz&0x
19c70 66 65 30 30 29 20 2b 20 28 28 73 7a 26 30 78 30  fe00) + ((sz&0x0
19c80 30 30 31 29 3c 3c 31 36 29 3b 0a 20 20 74 65 73  001)<<16);.  tes
19c90 74 63 61 73 65 28 20 73 7a 3c 3d 33 32 37 36 38  tcase( sz<=32768
19ca0 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20   );.  testcase( 
19cb0 73 7a 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 69  sz>=65536 );.  i
19cc0 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61 6d  Offset = walFram
19cd0 65 4f 66 66 73 65 74 28 69 52 65 61 64 2c 20 73  eOffset(iRead, s
19ce0 7a 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48  z) + WAL_FRAME_H
19cf0 44 52 53 49 5a 45 3b 0a 20 20 2f 2a 20 74 65 73  DRSIZE;.  /* tes
19d00 74 63 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e  tcase( IS_BIG_IN
19d10 54 28 69 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f  T(iOffset) ); //
19d20 20 72 65 71 75 69 72 65 73 20 61 20 34 47 69 42   requires a 4GiB
19d30 20 57 41 4c 20 2a 2f 0a 20 20 72 65 74 75 72 6e   WAL */.  return
19d40 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70   sqlite3OsRead(p
19d50 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 70 4f 75  Wal->pWalFd, pOu
19d60 74 2c 20 28 6e 4f 75 74 3e 73 7a 20 3f 20 73 7a  t, (nOut>sz ? sz
19d70 20 3a 20 6e 4f 75 74 29 2c 20 69 4f 66 66 73 65   : nOut), iOffse
19d80 74 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65  t);.}../* .** Re
19d90 74 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f 66  turn the size of
19da0 20 74 68 65 20 64 61 74 61 62 61 73 65 20 69 6e   the database in
19db0 20 70 61 67 65 73 20 28 6f 72 20 7a 65 72 6f 2c   pages (or zero,
19dc0 20 69 66 20 75 6e 6b 6e 6f 77 6e 29 2e 0a 2a 2f   if unknown)..*/
19dd0 0a 50 67 6e 6f 20 73 71 6c 69 74 65 33 57 61 6c  .Pgno sqlite3Wal
19de0 44 62 73 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c  Dbsize(Wal *pWal
19df0 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 20 26 26  ){.  if( pWal &&
19e00 20 41 4c 57 41 59 53 28 70 57 61 6c 2d 3e 72 65   ALWAYS(pWal->re
19e10 61 64 4c 6f 63 6b 3e 3d 30 29 20 29 7b 0a 20 20  adLock>=0) ){.  
19e20 20 20 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e 68    return pWal->h
19e30 64 72 2e 6e 50 61 67 65 3b 0a 20 20 7d 0a 20 20  dr.nPage;.  }.  
19e40 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 0a 2f 2a  return 0;.}.../*
19e50 20 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69   .** This functi
19e60 6f 6e 20 73 74 61 72 74 73 20 61 20 77 72 69 74  on starts a writ
19e70 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e  e transaction on
19e80 20 74 68 65 20 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20   the WAL..**.** 
19e90 41 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  A read transacti
19ea0 6f 6e 20 6d 75 73 74 20 68 61 76 65 20 61 6c 72  on must have alr
19eb0 65 61 64 79 20 62 65 65 6e 20 73 74 61 72 74 65  eady been starte
19ec0 64 20 62 79 20 61 20 70 72 69 6f 72 20 63 61 6c  d by a prior cal
19ed0 6c 0a 2a 2a 20 74 6f 20 73 71 6c 69 74 65 33 57  l.** to sqlite3W
19ee0 61 6c 42 65 67 69 6e 52 65 61 64 54 72 61 6e 73  alBeginReadTrans
19ef0 61 63 74 69 6f 6e 28 29 2e 0a 2a 2a 0a 2a 2a 20  action()..**.** 
19f00 49 66 20 61 6e 6f 74 68 65 72 20 74 68 72 65 61  If another threa
19f10 64 20 6f 72 20 70 72 6f 63 65 73 73 20 68 61 73  d or process has
19f20 20 77 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68   written into th
19f30 65 20 64 61 74 61 62 61 73 65 20 73 69 6e 63 65  e database since
19f40 0a 2a 2a 20 74 68 65 20 72 65 61 64 20 74 72 61  .** the read tra
19f50 6e 73 61 63 74 69 6f 6e 20 77 61 73 20 73 74 61  nsaction was sta
19f60 72 74 65 64 2c 20 74 68 65 6e 20 69 74 20 69 73  rted, then it is
19f70 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20 66 6f   not possible fo
19f80 72 20 74 68 69 73 0a 2a 2a 20 74 68 72 65 61 64  r this.** thread
19f90 20 74 6f 20 77 72 69 74 65 20 61 73 20 64 6f 69   to write as doi
19fa0 6e 67 20 73 6f 20 77 6f 75 6c 64 20 63 61 75 73  ng so would caus
19fb0 65 20 61 20 66 6f 72 6b 2e 20 20 53 6f 20 74 68  e a fork.  So th
19fc0 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65  is routine.** re
19fd0 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53  turns SQLITE_BUS
19fe0 59 20 69 6e 20 74 68 61 74 20 63 61 73 65 20 61  Y in that case a
19ff0 6e 64 20 6e 6f 20 77 72 69 74 65 20 74 72 61 6e  nd no write tran
1a000 73 61 63 74 69 6f 6e 20 69 73 20 73 74 61 72 74  saction is start
1a010 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20  ed..**.** There 
1a020 63 61 6e 20 6f 6e 6c 79 20 62 65 20 61 20 73 69  can only be a si
1a030 6e 67 6c 65 20 77 72 69 74 65 72 20 61 63 74 69  ngle writer acti
1a040 76 65 20 61 74 20 61 20 74 69 6d 65 2e 0a 2a 2f  ve at a time..*/
1a050 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 42  .int sqlite3WalB
1a060 65 67 69 6e 57 72 69 74 65 54 72 61 6e 73 61 63  eginWriteTransac
1a070 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 29 7b  tion(Wal *pWal){
1a080 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 2f 2a  .  int rc;..  /*
1a090 20 43 61 6e 6e 6f 74 20 73 74 61 72 74 20 61 20   Cannot start a 
1a0a0 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f  write transactio
1a0b0 6e 20 77 69 74 68 6f 75 74 20 66 69 72 73 74 20  n without first 
1a0c0 68 6f 6c 64 69 6e 67 20 61 20 72 65 61 64 0a 20  holding a read. 
1a0d0 20 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e   ** transaction.
1a0e0 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57   */.  assert( pW
1a0f0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20  al->readLock>=0 
1a100 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  );.  assert( pWa
1a110 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20  l->writeLock==0 
1a120 26 26 20 70 57 61 6c 2d 3e 69 52 65 43 6b 73 75  && pWal->iReCksu
1a130 6d 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 70  m==0 );..  if( p
1a140 57 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 29 7b  Wal->readOnly ){
1a150 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
1a160 54 45 5f 52 45 41 44 4f 4e 4c 59 3b 0a 20 20 7d  TE_READONLY;.  }
1a170 0a 0a 20 20 2f 2a 20 4f 6e 6c 79 20 6f 6e 65 20  ..  /* Only one 
1a180 77 72 69 74 65 72 20 61 6c 6c 6f 77 65 64 20 61  writer allowed a
1a190 74 20 61 20 74 69 6d 65 2e 20 20 47 65 74 20 74  t a time.  Get t
1a1a0 68 65 20 77 72 69 74 65 20 6c 6f 63 6b 2e 20 20  he write lock.  
1a1b0 52 65 74 75 72 6e 0a 20 20 2a 2a 20 53 51 4c 49  Return.  ** SQLI
1a1c0 54 45 5f 42 55 53 59 20 69 66 20 75 6e 61 62 6c  TE_BUSY if unabl
1a1d0 65 2e 0a 20 20 2a 2f 0a 20 20 72 63 20 3d 20 77  e..  */.  rc = w
1a1e0 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  alLockExclusive(
1a1f0 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f  pWal, WAL_WRITE_
1a200 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 69 66 28 20  LOCK, 1);.  if( 
1a210 72 63 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  rc ){.    return
1a220 20 72 63 3b 0a 20 20 7d 0a 20 20 70 57 61 6c 2d   rc;.  }.  pWal-
1a230 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 31 3b 0a  >writeLock = 1;.
1a240 0a 20 20 2f 2a 20 49 66 20 61 6e 6f 74 68 65 72  .  /* If another
1a250 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 73 20   connection has 
1a260 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20 64  written to the d
1a270 61 74 61 62 61 73 65 20 66 69 6c 65 20 73 69 6e  atabase file sin
1a280 63 65 20 74 68 65 0a 20 20 2a 2a 20 74 69 6d 65  ce the.  ** time
1a290 20 74 68 65 20 72 65 61 64 20 74 72 61 6e 73 61   the read transa
1a2a0 63 74 69 6f 6e 20 6f 6e 20 74 68 69 73 20 63 6f  ction on this co
1a2b0 6e 6e 65 63 74 69 6f 6e 20 77 61 73 20 73 74 61  nnection was sta
1a2c0 72 74 65 64 2c 20 74 68 65 6e 0a 20 20 2a 2a 20  rted, then.  ** 
1a2d0 74 68 65 20 77 72 69 74 65 20 69 73 20 64 69 73  the write is dis
1a2e0 61 6c 6c 6f 77 65 64 2e 0a 20 20 2a 2f 0a 20 20  allowed..  */.  
1a2f0 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c  if( memcmp(&pWal
1a300 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20 2a 29 77  ->hdr, (void *)w
1a310 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29  alIndexHdr(pWal)
1a320 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65  , sizeof(WalInde
1a330 78 48 64 72 29 29 21 3d 30 20 29 7b 0a 20 20 20  xHdr))!=0 ){.   
1a340 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
1a350 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52  ive(pWal, WAL_WR
1a360 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20  ITE_LOCK, 1);.  
1a370 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63    pWal->writeLoc
1a380 6b 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20  k = 0;.    rc = 
1a390 53 51 4c 49 54 45 5f 42 55 53 59 5f 53 4e 41 50  SQLITE_BUSY_SNAP
1a3a0 53 48 4f 54 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  SHOT;.  }..  ret
1a3b0 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
1a3c0 20 45 6e 64 20 61 20 77 72 69 74 65 20 74 72 61   End a write tra
1a3d0 6e 73 61 63 74 69 6f 6e 2e 20 20 54 68 65 20 63  nsaction.  The c
1a3e0 6f 6d 6d 69 74 20 68 61 73 20 61 6c 72 65 61 64  ommit has alread
1a3f0 79 20 62 65 65 6e 20 64 6f 6e 65 2e 20 20 54 68  y been done.  Th
1a400 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 6d 65  is.** routine me
1a410 72 65 6c 79 20 72 65 6c 65 61 73 65 73 20 74 68  rely releases th
1a420 65 20 6c 6f 63 6b 2e 0a 2a 2f 0a 69 6e 74 20 73  e lock..*/.int s
1a430 71 6c 69 74 65 33 57 61 6c 45 6e 64 57 72 69 74  qlite3WalEndWrit
1a440 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c  eTransaction(Wal
1a450 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28 20 70   *pWal){.  if( p
1a460 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29  Wal->writeLock )
1a470 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45  {.    walUnlockE
1a480 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
1a490 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31  AL_WRITE_LOCK, 1
1a4a0 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72 69  );.    pWal->wri
1a4b0 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20  teLock = 0;.    
1a4c0 70 57 61 6c 2d 3e 69 52 65 43 6b 73 75 6d 20 3d  pWal->iReCksum =
1a4d0 20 30 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 74 72   0;.    pWal->tr
1a4e0 75 6e 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 20 3d  uncateOnCommit =
1a4f0 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   0;.  }.  return
1a500 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
1a510 2a 0a 2a 2a 20 49 66 20 61 6e 79 20 64 61 74 61  *.** If any data
1a520 20 68 61 73 20 62 65 65 6e 20 77 72 69 74 74 65   has been writte
1a530 6e 20 28 62 75 74 20 6e 6f 74 20 63 6f 6d 6d 69  n (but not commi
1a540 74 74 65 64 29 20 74 6f 20 74 68 65 20 6c 6f 67  tted) to the log
1a550 20 66 69 6c 65 2c 20 74 68 69 73 0a 2a 2a 20 66   file, this.** f
1a560 75 6e 63 74 69 6f 6e 20 6d 6f 76 65 73 20 74 68  unction moves th
1a570 65 20 77 72 69 74 65 2d 70 6f 69 6e 74 65 72 20  e write-pointer 
1a580 62 61 63 6b 20 74 6f 20 74 68 65 20 73 74 61 72  back to the star
1a590 74 20 6f 66 20 74 68 65 20 74 72 61 6e 73 61 63  t of the transac
1a5a0 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41 64 64 69  tion..**.** Addi
1a5b0 74 69 6f 6e 61 6c 6c 79 2c 20 74 68 65 20 63 61  tionally, the ca
1a5c0 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20  llback function 
1a5d0 69 73 20 69 6e 76 6f 6b 65 64 20 66 6f 72 20 65  is invoked for e
1a5e0 61 63 68 20 66 72 61 6d 65 20 77 72 69 74 74 65  ach frame writte
1a5f0 6e 0a 2a 2a 20 74 6f 20 74 68 65 20 57 41 4c 20  n.** to the WAL 
1a600 73 69 6e 63 65 20 74 68 65 20 73 74 61 72 74 20  since the start 
1a610 6f 66 20 74 68 65 20 74 72 61 6e 73 61 63 74 69  of the transacti
1a620 6f 6e 2e 20 49 66 20 74 68 65 20 63 61 6c 6c 62  on. If the callb
1a630 61 63 6b 20 72 65 74 75 72 6e 73 0a 2a 2a 20 6f  ack returns.** o
1a640 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45  ther than SQLITE
1a650 5f 4f 4b 2c 20 69 74 20 69 73 20 6e 6f 74 20 69  _OK, it is not i
1a660 6e 76 6f 6b 65 64 20 61 67 61 69 6e 20 61 6e 64  nvoked again and
1a670 20 74 68 65 20 65 72 72 6f 72 20 63 6f 64 65 20   the error code 
1a680 69 73 0a 2a 2a 20 72 65 74 75 72 6e 65 64 20 74  is.** returned t
1a690 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 0a 2a 2a  o the caller..**
1a6a0 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69  .** Otherwise, i
1a6b0 66 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 66  f the callback f
1a6c0 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20 6e 6f 74  unction does not
1a6d0 20 72 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72   return an error
1a6e0 2c 20 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69  , this.** functi
1a6f0 6f 6e 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  on returns SQLIT
1a700 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  E_OK..*/.int sql
1a710 69 74 65 33 57 61 6c 55 6e 64 6f 28 57 61 6c 20  ite3WalUndo(Wal 
1a720 2a 70 57 61 6c 2c 20 69 6e 74 20 28 2a 78 55 6e  *pWal, int (*xUn
1a730 64 6f 29 28 76 6f 69 64 20 2a 2c 20 50 67 6e 6f  do)(void *, Pgno
1a740 29 2c 20 76 6f 69 64 20 2a 70 55 6e 64 6f 43 74  ), void *pUndoCt
1a750 78 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  x){.  int rc = S
1a760 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20  QLITE_OK;.  if( 
1a770 41 4c 57 41 59 53 28 70 57 61 6c 2d 3e 77 72 69  ALWAYS(pWal->wri
1a780 74 65 4c 6f 63 6b 29 20 29 7b 0a 20 20 20 20 50  teLock) ){.    P
1a790 67 6e 6f 20 69 4d 61 78 20 3d 20 70 57 61 6c 2d  gno iMax = pWal-
1a7a0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20  >hdr.mxFrame;.  
1a7b0 20 20 50 67 6e 6f 20 69 46 72 61 6d 65 3b 0a 20    Pgno iFrame;. 
1a7c0 20 0a 20 20 20 20 2f 2a 20 52 65 73 74 6f 72 65   .    /* Restore
1a7d0 20 74 68 65 20 63 6c 69 65 6e 74 73 20 63 61 63   the clients cac
1a7e0 68 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  he of the wal-in
1a7f0 64 65 78 20 68 65 61 64 65 72 20 74 6f 20 74 68  dex header to th
1a800 65 20 73 74 61 74 65 20 69 74 0a 20 20 20 20 2a  e state it.    *
1a810 2a 20 77 61 73 20 69 6e 20 62 65 66 6f 72 65 20  * was in before 
1a820 74 68 65 20 63 6c 69 65 6e 74 20 62 65 67 61 6e  the client began
1a830 20 77 72 69 74 69 6e 67 20 74 6f 20 74 68 65 20   writing to the 
1a840 64 61 74 61 62 61 73 65 2e 20 0a 20 20 20 20 2a  database. .    *
1a850 2f 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 57  /.    memcpy(&pW
1a860 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20 2a  al->hdr, (void *
1a870 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61  )walIndexHdr(pWa
1a880 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  l), sizeof(WalIn
1a890 64 65 78 48 64 72 29 29 3b 0a 0a 20 20 20 20 66  dexHdr));..    f
1a8a0 6f 72 28 69 46 72 61 6d 65 3d 70 57 61 6c 2d 3e  or(iFrame=pWal->
1a8b0 68 64 72 2e 6d 78 46 72 61 6d 65 2b 31 3b 20 0a  hdr.mxFrame+1; .
1a8c0 20 20 20 20 20 20 20 20 41 4c 57 41 59 53 28 72          ALWAYS(r
1a8d0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29 20 26 26  c==SQLITE_OK) &&
1a8e0 20 69 46 72 61 6d 65 3c 3d 69 4d 61 78 3b 20 0a   iFrame<=iMax; .
1a8f0 20 20 20 20 20 20 20 20 69 46 72 61 6d 65 2b 2b          iFrame++
1a900 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 2f 2a  .    ){.      /*
1a910 20 54 68 69 73 20 63 61 6c 6c 20 63 61 6e 6e 6f   This call canno
1a920 74 20 66 61 69 6c 2e 20 55 6e 6c 65 73 73 20 74  t fail. Unless t
1a930 68 65 20 70 61 67 65 20 66 6f 72 20 77 68 69 63  he page for whic
1a940 68 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65  h the page numbe
1a950 72 0a 20 20 20 20 20 20 2a 2a 20 69 73 20 70 61  r.      ** is pa
1a960 73 73 65 64 20 61 73 20 74 68 65 20 73 65 63 6f  ssed as the seco
1a970 6e 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20 28  nd argument is (
1a980 61 29 20 69 6e 20 74 68 65 20 63 61 63 68 65 20  a) in the cache 
1a990 61 6e 64 20 0a 20 20 20 20 20 20 2a 2a 20 28 62  and .      ** (b
1a9a0 29 20 68 61 73 20 61 6e 20 6f 75 74 73 74 61 6e  ) has an outstan
1a9b0 64 69 6e 67 20 72 65 66 65 72 65 6e 63 65 2c 20  ding reference, 
1a9c0 74 68 65 6e 20 78 55 6e 64 6f 20 69 73 20 65 69  then xUndo is ei
1a9d0 74 68 65 72 20 61 20 6e 6f 2d 6f 70 0a 20 20 20  ther a no-op.   
1a9e0 20 20 20 2a 2a 20 28 69 66 20 28 61 29 20 69 73     ** (if (a) is
1a9f0 20 66 61 6c 73 65 29 20 6f 72 20 73 69 6d 70 6c   false) or simpl
1aa00 79 20 65 78 70 65 6c 73 20 74 68 65 20 70 61 67  y expels the pag
1aa10 65 20 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65  e from the cache
1aa20 20 28 69 66 20 28 62 29 0a 20 20 20 20 20 20 2a   (if (b).      *
1aa30 2a 20 69 73 20 66 61 6c 73 65 29 2e 0a 20 20 20  * is false)..   
1aa40 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 49     **.      ** I
1aa50 66 20 74 68 65 20 75 70 70 65 72 20 6c 61 79 65  f the upper laye
1aa60 72 20 69 73 20 64 6f 69 6e 67 20 61 20 72 6f 6c  r is doing a rol
1aa70 6c 62 61 63 6b 2c 20 69 74 20 69 73 20 67 75 61  lback, it is gua
1aa80 72 61 6e 74 65 65 64 20 74 68 61 74 20 74 68 65  ranteed that the
1aa90 72 65 0a 20 20 20 20 20 20 2a 2a 20 61 72 65 20  re.      ** are 
1aaa0 6e 6f 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 72  no outstanding r
1aab0 65 66 65 72 65 6e 63 65 73 20 74 6f 20 61 6e 79  eferences to any
1aac0 20 70 61 67 65 20 6f 74 68 65 72 20 74 68 61 6e   page other than
1aad0 20 70 61 67 65 20 31 2e 20 41 6e 64 0a 20 20 20   page 1. And.   
1aae0 20 20 20 2a 2a 20 70 61 67 65 20 31 20 69 73 20     ** page 1 is 
1aaf0 6e 65 76 65 72 20 77 72 69 74 74 65 6e 20 74 6f  never written to
1ab00 20 74 68 65 20 6c 6f 67 20 75 6e 74 69 6c 20 74   the log until t
1ab10 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69  he transaction i
1ab20 73 0a 20 20 20 20 20 20 2a 2a 20 63 6f 6d 6d 69  s.      ** commi
1ab30 74 74 65 64 2e 20 41 73 20 61 20 72 65 73 75 6c  tted. As a resul
1ab40 74 2c 20 74 68 65 20 63 61 6c 6c 20 74 6f 20 78  t, the call to x
1ab50 55 6e 64 6f 20 6d 61 79 20 6e 6f 74 20 66 61 69  Undo may not fai
1ab60 6c 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  l..      */.    
1ab70 20 20 61 73 73 65 72 74 28 20 77 61 6c 46 72 61    assert( walFra
1ab80 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 46 72  mePgno(pWal, iFr
1ab90 61 6d 65 29 21 3d 31 20 29 3b 0a 20 20 20 20 20  ame)!=1 );.     
1aba0 20 72 63 20 3d 20 78 55 6e 64 6f 28 70 55 6e 64   rc = xUndo(pUnd
1abb0 6f 43 74 78 2c 20 77 61 6c 46 72 61 6d 65 50 67  oCtx, walFramePg
1abc0 6e 6f 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29  no(pWal, iFrame)
1abd0 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
1abe0 20 69 4d 61 78 21 3d 70 57 61 6c 2d 3e 68 64 72   iMax!=pWal->hdr
1abf0 2e 6d 78 46 72 61 6d 65 20 29 20 77 61 6c 43 6c  .mxFrame ) walCl
1ac00 65 61 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b  eanupHash(pWal);
1ac10 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
1ac20 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 41 72 67 75  ;.}../* .** Argu
1ac30 6d 65 6e 74 20 61 57 61 6c 44 61 74 61 20 6d 75  ment aWalData mu
1ac40 73 74 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 61  st point to an a
1ac50 72 72 61 79 20 6f 66 20 57 41 4c 5f 53 41 56 45  rray of WAL_SAVE
1ac60 50 4f 49 4e 54 5f 4e 44 41 54 41 20 75 33 32 20  POINT_NDATA u32 
1ac70 0a 2a 2a 20 76 61 6c 75 65 73 2e 20 54 68 69 73  .** values. This
1ac80 20 66 75 6e 63 74 69 6f 6e 20 70 6f 70 75 6c 61   function popula
1ac90 74 65 73 20 74 68 65 20 61 72 72 61 79 20 77 69  tes the array wi
1aca0 74 68 20 76 61 6c 75 65 73 20 72 65 71 75 69 72  th values requir
1acb0 65 64 20 74 6f 20 0a 2a 2a 20 22 72 6f 6c 6c 62  ed to .** "rollb
1acc0 61 63 6b 22 20 74 68 65 20 77 72 69 74 65 20 70  ack" the write p
1acd0 6f 73 69 74 69 6f 6e 20 6f 66 20 74 68 65 20 57  osition of the W
1ace0 41 4c 20 68 61 6e 64 6c 65 20 62 61 63 6b 20 74  AL handle back t
1acf0 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20 0a 2a  o the current .*
1ad00 2a 20 70 6f 69 6e 74 20 69 6e 20 74 68 65 20 65  * point in the e
1ad10 76 65 6e 74 20 6f 66 20 61 20 73 61 76 65 70 6f  vent of a savepo
1ad20 69 6e 74 20 72 6f 6c 6c 62 61 63 6b 20 28 76 69  int rollback (vi
1ad30 61 20 57 61 6c 53 61 76 65 70 6f 69 6e 74 55 6e  a WalSavepointUn
1ad40 64 6f 28 29 29 2e 0a 2a 2f 0a 76 6f 69 64 20 73  do())..*/.void s
1ad50 71 6c 69 74 65 33 57 61 6c 53 61 76 65 70 6f 69  qlite3WalSavepoi
1ad60 6e 74 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33  nt(Wal *pWal, u3
1ad70 32 20 2a 61 57 61 6c 44 61 74 61 29 7b 0a 20 20  2 *aWalData){.  
1ad80 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72  assert( pWal->wr
1ad90 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 61 57 61  iteLock );.  aWa
1ada0 6c 44 61 74 61 5b 30 5d 20 3d 20 70 57 61 6c 2d  lData[0] = pWal-
1adb0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20  >hdr.mxFrame;.  
1adc0 61 57 61 6c 44 61 74 61 5b 31 5d 20 3d 20 70 57  aWalData[1] = pW
1add0 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
1ade0 73 75 6d 5b 30 5d 3b 0a 20 20 61 57 61 6c 44 61  sum[0];.  aWalDa
1adf0 74 61 5b 32 5d 20 3d 20 70 57 61 6c 2d 3e 68 64  ta[2] = pWal->hd
1ae00 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d  r.aFrameCksum[1]
1ae10 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 33 5d 20  ;.  aWalData[3] 
1ae20 3d 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 3b 0a 7d  = pWal->nCkpt;.}
1ae30 0a 0a 2f 2a 20 0a 2a 2a 20 4d 6f 76 65 20 74 68  ../* .** Move th
1ae40 65 20 77 72 69 74 65 20 70 6f 73 69 74 69 6f 6e  e write position
1ae50 20 6f 66 20 74 68 65 20 57 41 4c 20 62 61 63 6b   of the WAL back
1ae60 20 74 6f 20 74 68 65 20 70 6f 69 6e 74 20 69 64   to the point id
1ae70 65 6e 74 69 66 69 65 64 20 62 79 0a 2a 2a 20 74  entified by.** t
1ae80 68 65 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  he values in the
1ae90 20 61 57 61 6c 44 61 74 61 5b 5d 20 61 72 72 61   aWalData[] arra
1aea0 79 2e 20 61 57 61 6c 44 61 74 61 20 6d 75 73 74  y. aWalData must
1aeb0 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 61 72 72   point to an arr
1aec0 61 79 0a 2a 2a 20 6f 66 20 57 41 4c 5f 53 41 56  ay.** of WAL_SAV
1aed0 45 50 4f 49 4e 54 5f 4e 44 41 54 41 20 75 33 32  EPOINT_NDATA u32
1aee0 20 76 61 6c 75 65 73 20 74 68 61 74 20 68 61 73   values that has
1aef0 20 62 65 65 6e 20 70 72 65 76 69 6f 75 73 6c 79   been previously
1af00 20 70 6f 70 75 6c 61 74 65 64 0a 2a 2a 20 62 79   populated.** by
1af10 20 61 20 63 61 6c 6c 20 74 6f 20 57 61 6c 53 61   a call to WalSa
1af20 76 65 70 6f 69 6e 74 28 29 2e 0a 2a 2f 0a 69 6e  vepoint()..*/.in
1af30 74 20 73 71 6c 69 74 65 33 57 61 6c 53 61 76 65  t sqlite3WalSave
1af40 70 6f 69 6e 74 55 6e 64 6f 28 57 61 6c 20 2a 70  pointUndo(Wal *p
1af50 57 61 6c 2c 20 75 33 32 20 2a 61 57 61 6c 44 61  Wal, u32 *aWalDa
1af60 74 61 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  ta){.  int rc = 
1af70 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 61 73  SQLITE_OK;..  as
1af80 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74  sert( pWal->writ
1af90 65 4c 6f 63 6b 20 29 3b 0a 20 20 61 73 73 65 72  eLock );.  asser
1afa0 74 28 20 61 57 61 6c 44 61 74 61 5b 33 5d 21 3d  t( aWalData[3]!=
1afb0 70 57 61 6c 2d 3e 6e 43 6b 70 74 20 7c 7c 20 61  pWal->nCkpt || a
1afc0 57 61 6c 44 61 74 61 5b 30 5d 3c 3d 70 57 61 6c  WalData[0]<=pWal
1afd0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b  ->hdr.mxFrame );
1afe0 0a 0a 20 20 69 66 28 20 61 57 61 6c 44 61 74 61  ..  if( aWalData
1aff0 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43 6b 70 74  [3]!=pWal->nCkpt
1b000 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 69 73 20   ){.    /* This 
1b010 73 61 76 65 70 6f 69 6e 74 20 77 61 73 20 6f 70  savepoint was op
1b020 65 6e 65 64 20 69 6d 6d 65 64 69 61 74 65 6c 79  ened immediately
1b030 20 61 66 74 65 72 20 74 68 65 20 77 72 69 74 65   after the write
1b040 2d 74 72 61 6e 73 61 63 74 69 6f 6e 0a 20 20 20  -transaction.   
1b050 20 2a 2a 20 77 61 73 20 73 74 61 72 74 65 64 2e   ** was started.
1b060 20 52 69 67 68 74 20 61 66 74 65 72 20 74 68 61   Right after tha
1b070 74 2c 20 74 68 65 20 77 72 69 74 65 72 20 64 65  t, the writer de
1b080 63 69 64 65 64 20 74 6f 20 77 72 61 70 20 61 72  cided to wrap ar
1b090 6f 75 6e 64 0a 20 20 20 20 2a 2a 20 74 6f 20 74  ound.    ** to t
1b0a0 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  he start of the 
1b0b0 6c 6f 67 2e 20 55 70 64 61 74 65 20 74 68 65 20  log. Update the 
1b0c0 73 61 76 65 70 6f 69 6e 74 20 76 61 6c 75 65 73  savepoint values
1b0d0 20 74 6f 20 6d 61 74 63 68 2e 0a 20 20 20 20 2a   to match..    *
1b0e0 2f 0a 20 20 20 20 61 57 61 6c 44 61 74 61 5b 30  /.    aWalData[0
1b0f0 5d 20 3d 20 30 3b 0a 20 20 20 20 61 57 61 6c 44  ] = 0;.    aWalD
1b100 61 74 61 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e 6e  ata[3] = pWal->n
1b110 43 6b 70 74 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  Ckpt;.  }..  if(
1b120 20 61 57 61 6c 44 61 74 61 5b 30 5d 3c 70 57 61   aWalData[0]<pWa
1b130 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29  l->hdr.mxFrame )
1b140 7b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  {.    pWal->hdr.
1b150 6d 78 46 72 61 6d 65 20 3d 20 61 57 61 6c 44 61  mxFrame = aWalDa
1b160 74 61 5b 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d  ta[0];.    pWal-
1b170 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
1b180 5b 30 5d 20 3d 20 61 57 61 6c 44 61 74 61 5b 31  [0] = aWalData[1
1b190 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  ];.    pWal->hdr
1b1a0 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20  .aFrameCksum[1] 
1b1b0 3d 20 61 57 61 6c 44 61 74 61 5b 32 5d 3b 0a 20  = aWalData[2];. 
1b1c0 20 20 20 77 61 6c 43 6c 65 61 6e 75 70 48 61 73     walCleanupHas
1b1d0 68 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 0a 20 20  h(pWal);.  }..  
1b1e0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
1b1f0 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
1b200 6e 20 69 73 20 63 61 6c 6c 65 64 20 6a 75 73 74  n is called just
1b210 20 62 65 66 6f 72 65 20 77 72 69 74 69 6e 67 20   before writing 
1b220 61 20 73 65 74 20 6f 66 20 66 72 61 6d 65 73 20  a set of frames 
1b230 74 6f 20 74 68 65 20 6c 6f 67 0a 2a 2a 20 66 69  to the log.** fi
1b240 6c 65 20 28 73 65 65 20 73 71 6c 69 74 65 33 57  le (see sqlite3W
1b250 61 6c 46 72 61 6d 65 73 28 29 29 2e 20 49 74 20  alFrames()). It 
1b260 63 68 65 63 6b 73 20 74 6f 20 73 65 65 20 69 66  checks to see if
1b270 2c 20 69 6e 73 74 65 61 64 20 6f 66 20 61 70 70  , instead of app
1b280 65 6e 64 69 6e 67 0a 2a 2a 20 74 6f 20 74 68 65  ending.** to the
1b290 20 63 75 72 72 65 6e 74 20 6c 6f 67 20 66 69 6c   current log fil
1b2a0 65 2c 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c  e, it is possibl
1b2b0 65 20 74 6f 20 6f 76 65 72 77 72 69 74 65 20 74  e to overwrite t
1b2c0 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 0a  he start of the.
1b2d0 2a 2a 20 65 78 69 73 74 69 6e 67 20 6c 6f 67 20  ** existing log 
1b2e0 66 69 6c 65 20 77 69 74 68 20 74 68 65 20 6e 65  file with the ne
1b2f0 77 20 66 72 61 6d 65 73 20 28 69 2e 65 2e 20 22  w frames (i.e. "
1b300 72 65 73 65 74 22 20 74 68 65 20 6c 6f 67 29 2e  reset" the log).
1b310 20 49 66 20 73 6f 2c 0a 2a 2a 20 69 74 20 73 65   If so,.** it se
1b320 74 73 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ts pWal->hdr.mxF
1b330 72 61 6d 65 20 74 6f 20 30 2e 20 4f 74 68 65 72  rame to 0. Other
1b340 77 69 73 65 2c 20 70 57 61 6c 2d 3e 68 64 72 2e  wise, pWal->hdr.
1b350 6d 78 46 72 61 6d 65 20 69 73 20 6c 65 66 74 0a  mxFrame is left.
1b360 2a 2a 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2a  ** unchanged..**
1b370 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73  .** SQLITE_OK is
1b380 20 72 65 74 75 72 6e 65 64 20 69 66 20 6e 6f 20   returned if no 
1b390 65 72 72 6f 72 20 69 73 20 65 6e 63 6f 75 6e 74  error is encount
1b3a0 65 72 65 64 20 28 72 65 67 61 72 64 6c 65 73 73  ered (regardless
1b3b0 20 6f 66 20 77 68 65 74 68 65 72 0a 2a 2a 20 6f   of whether.** o
1b3c0 72 20 6e 6f 74 20 70 57 61 6c 2d 3e 68 64 72 2e  r not pWal->hdr.
1b3d0 6d 78 46 72 61 6d 65 20 69 73 20 6d 6f 64 69 66  mxFrame is modif
1b3e0 69 65 64 29 2e 20 41 6e 20 53 51 4c 69 74 65 20  ied). An SQLite 
1b3f0 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65  error code is re
1b400 74 75 72 6e 65 64 0a 2a 2a 20 69 66 20 61 6e 20  turned.** if an 
1b410 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f  error occurs..*/
1b420 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 52  .static int walR
1b430 65 73 74 61 72 74 4c 6f 67 28 57 61 6c 20 2a 70  estartLog(Wal *p
1b440 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  Wal){.  int rc =
1b450 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e   SQLITE_OK;.  in
1b460 74 20 63 6e 74 3b 0a 0a 20 20 69 66 28 20 70 57  t cnt;..  if( pW
1b470 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20  al->readLock==0 
1b480 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  ){.    volatile 
1b490 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e  WalCkptInfo *pIn
1b4a0 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f  fo = walCkptInfo
1b4b0 28 70 57 61 6c 29 3b 0a 20 20 20 20 61 73 73 65  (pWal);.    asse
1b4c0 72 74 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b  rt( pInfo->nBack
1b4d0 66 69 6c 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e  fill==pWal->hdr.
1b4e0 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20 20 69  mxFrame );.    i
1b4f0 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66  f( pInfo->nBackf
1b500 69 6c 6c 3e 30 20 29 7b 0a 20 20 20 20 20 20 75  ill>0 ){.      u
1b510 33 32 20 73 61 6c 74 31 3b 0a 20 20 20 20 20 20  32 salt1;.      
1b520 73 71 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65  sqlite3_randomne
1b530 73 73 28 34 2c 20 26 73 61 6c 74 31 29 3b 0a 20  ss(4, &salt1);. 
1b540 20 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63       rc = walLoc
1b550 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
1b560 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31   WAL_READ_LOCK(1
1b570 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31  ), WAL_NREADER-1
1b580 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
1b590 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
1b5a0 20 20 20 20 20 20 2f 2a 20 49 66 20 61 6c 6c 20        /* If all 
1b5b0 72 65 61 64 65 72 73 20 61 72 65 20 75 73 69 6e  readers are usin
1b5c0 67 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  g WAL_READ_LOCK(
1b5d0 30 29 20 28 69 6e 20 6f 74 68 65 72 20 77 6f 72  0) (in other wor
1b5e0 64 73 20 69 66 20 6e 6f 0a 20 20 20 20 20 20 20  ds if no.       
1b5f0 20 2a 2a 20 72 65 61 64 65 72 73 20 61 72 65 20   ** readers are 
1b600 63 75 72 72 65 6e 74 6c 79 20 75 73 69 6e 67 20  currently using 
1b610 74 68 65 20 57 41 4c 29 2c 20 74 68 65 6e 20 74  the WAL), then t
1b620 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 0a  he transactions.
1b630 20 20 20 20 20 20 20 20 2a 2a 20 66 72 61 6d 65          ** frame
1b640 73 20 77 69 6c 6c 20 6f 76 65 72 77 72 69 74 65  s will overwrite
1b650 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
1b660 65 20 65 78 69 73 74 69 6e 67 20 6c 6f 67 2e 20  e existing log. 
1b670 55 70 64 61 74 65 20 74 68 65 0a 20 20 20 20 20  Update the.     
1b680 20 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20     ** wal-index 
1b690 68 65 61 64 65 72 20 74 6f 20 72 65 66 6c 65 63  header to reflec
1b6a0 74 20 74 68 69 73 2e 0a 20 20 20 20 20 20 20 20  t this..        
1b6b0 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 49 6e  **.        ** In
1b6c0 20 74 68 65 6f 72 79 20 69 74 20 77 6f 75 6c 64   theory it would
1b6d0 20 62 65 20 4f 6b 20 74 6f 20 75 70 64 61 74 65   be Ok to update
1b6e0 20 74 68 65 20 63 61 63 68 65 20 6f 66 20 74 68   the cache of th
1b6f0 65 20 68 65 61 64 65 72 20 6f 6e 6c 79 0a 20 20  e header only.  
1b700 20 20 20 20 20 20 2a 2a 20 61 74 20 74 68 69 73        ** at this
1b710 20 70 6f 69 6e 74 2e 20 42 75 74 20 75 70 64 61   point. But upda
1b720 74 69 6e 67 20 74 68 65 20 61 63 74 75 61 6c 20  ting the actual 
1b730 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
1b740 20 69 73 20 61 6c 73 6f 0a 20 20 20 20 20 20 20   is also.       
1b750 20 2a 2a 20 73 61 66 65 20 61 6e 64 20 6d 65 61   ** safe and mea
1b760 6e 73 20 74 68 65 72 65 20 69 73 20 6e 6f 20 73  ns there is no s
1b770 70 65 63 69 61 6c 20 63 61 73 65 20 66 6f 72 20  pecial case for 
1b780 73 71 6c 69 74 65 33 57 61 6c 55 6e 64 6f 28 29  sqlite3WalUndo()
1b790 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 6f 20 68  .        ** to h
1b7a0 61 6e 64 6c 65 20 69 66 20 74 68 69 73 20 74 72  andle if this tr
1b7b0 61 6e 73 61 63 74 69 6f 6e 20 69 73 20 72 6f 6c  ansaction is rol
1b7c0 6c 65 64 20 62 61 63 6b 2e 20 20 2a 2f 0a 20 20  led back.  */.  
1b7d0 20 20 20 20 20 20 77 61 6c 52 65 73 74 61 72 74        walRestart
1b7e0 48 64 72 28 70 57 61 6c 2c 20 73 61 6c 74 31 29  Hdr(pWal, salt1)
1b7f0 3b 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c  ;.        walUnl
1b800 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
1b810 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  l, WAL_READ_LOCK
1b820 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52  (1), WAL_NREADER
1b830 2d 31 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  -1);.      }else
1b840 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
1b850 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20 20 20  BUSY ){.        
1b860 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20  return rc;.     
1b870 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 77 61 6c   }.    }.    wal
1b880 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61  UnlockShared(pWa
1b890 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  l, WAL_READ_LOCK
1b8a0 28 30 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  (0));.    pWal->
1b8b0 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31 3b 0a 20  readLock = -1;. 
1b8c0 20 20 20 63 6e 74 20 3d 20 30 3b 0a 20 20 20 20     cnt = 0;.    
1b8d0 64 6f 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 6f  do{.      int no
1b8e0 74 55 73 65 64 3b 0a 20 20 20 20 20 20 72 63 20  tUsed;.      rc 
1b8f0 3d 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61  = walTryBeginRea
1b900 64 28 70 57 61 6c 2c 20 26 6e 6f 74 55 73 65 64  d(pWal, &notUsed
1b910 2c 20 31 2c 20 2b 2b 63 6e 74 29 3b 0a 20 20 20  , 1, ++cnt);.   
1b920 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d 57 41 4c   }while( rc==WAL
1b930 5f 52 45 54 52 59 20 29 3b 0a 20 20 20 20 61 73  _RETRY );.    as
1b940 73 65 72 74 28 20 28 72 63 26 30 78 66 66 29 21  sert( (rc&0xff)!
1b950 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 3b 20  =SQLITE_BUSY ); 
1b960 2f 2a 20 42 55 53 59 20 6e 6f 74 20 70 6f 73 73  /* BUSY not poss
1b970 69 62 6c 65 20 77 68 65 6e 20 75 73 65 57 61 6c  ible when useWal
1b980 3d 3d 31 20 2a 2f 0a 20 20 20 20 74 65 73 74 63  ==1 */.    testc
1b990 61 73 65 28 20 28 72 63 26 30 78 66 66 29 3d 3d  ase( (rc&0xff)==
1b9a0 53 51 4c 49 54 45 5f 49 4f 45 52 52 20 29 3b 0a  SQLITE_IOERR );.
1b9b0 20 20 20 20 74 65 73 74 63 61 73 65 28 20 72 63      testcase( rc
1b9c0 3d 3d 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f  ==SQLITE_PROTOCO
1b9d0 4c 20 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73  L );.    testcas
1b9e0 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  e( rc==SQLITE_OK
1b9f0 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   );.  }.  return
1ba00 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e   rc;.}../*.** In
1ba10 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20  formation about 
1ba20 74 68 65 20 63 75 72 72 65 6e 74 20 73 74 61 74  the current stat
1ba30 65 20 6f 66 20 74 68 65 20 57 41 4c 20 66 69 6c  e of the WAL fil
1ba40 65 20 61 6e 64 20 77 68 65 72 65 0a 2a 2a 20 74  e and where.** t
1ba50 68 65 20 6e 65 78 74 20 66 73 79 6e 63 20 73 68  he next fsync sh
1ba60 6f 75 6c 64 20 6f 63 63 75 72 20 2d 20 70 61 73  ould occur - pas
1ba70 73 65 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33  sed from sqlite3
1ba80 57 61 6c 46 72 61 6d 65 73 28 29 20 69 6e 74 6f  WalFrames() into
1ba90 0a 2a 2a 20 77 61 6c 57 72 69 74 65 54 6f 4c 6f  .** walWriteToLo
1baa0 67 28 29 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20  g()..*/.typedef 
1bab0 73 74 72 75 63 74 20 57 61 6c 57 72 69 74 65 72  struct WalWriter
1bac0 20 7b 0a 20 20 57 61 6c 20 2a 70 57 61 6c 3b 20   {.  Wal *pWal; 
1bad0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bae0 20 20 2f 2a 20 54 68 65 20 63 6f 6d 70 6c 65 74    /* The complet
1baf0 65 20 57 41 4c 20 69 6e 66 6f 72 6d 61 74 69 6f  e WAL informatio
1bb00 6e 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66  n */.  sqlite3_f
1bb10 69 6c 65 20 2a 70 46 64 3b 20 20 20 20 20 20 20  ile *pFd;       
1bb20 20 20 20 20 2f 2a 20 54 68 65 20 57 41 4c 20 66      /* The WAL f
1bb30 69 6c 65 20 74 6f 20 77 68 69 63 68 20 77 65 20  ile to which we 
1bb40 77 72 69 74 65 20 2a 2f 0a 20 20 73 71 6c 69 74  write */.  sqlit
1bb50 65 33 5f 69 6e 74 36 34 20 69 53 79 6e 63 50 6f  e3_int64 iSyncPo
1bb60 69 6e 74 3b 20 20 20 20 2f 2a 20 46 73 79 6e 63  int;    /* Fsync
1bb70 20 61 74 20 74 68 69 73 20 6f 66 66 73 65 74 20   at this offset 
1bb80 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 46 6c 61  */.  int syncFla
1bb90 67 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  gs;             
1bba0 20 20 2f 2a 20 46 6c 61 67 73 20 66 6f 72 20 74    /* Flags for t
1bbb0 68 65 20 66 73 79 6e 63 20 2a 2f 0a 20 20 69 6e  he fsync */.  in
1bbc0 74 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20  t szPage;       
1bbd0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
1bbe0 7a 65 20 6f 66 20 6f 6e 65 20 70 61 67 65 20 2a  ze of one page *
1bbf0 2f 0a 7d 20 57 61 6c 57 72 69 74 65 72 3b 0a 0a  /.} WalWriter;..
1bc00 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 69 41 6d 74  /*.** Write iAmt
1bc10 20 62 79 74 65 73 20 6f 66 20 63 6f 6e 74 65 6e   bytes of conten
1bc20 74 20 69 6e 74 6f 20 74 68 65 20 57 41 4c 20 66  t into the WAL f
1bc30 69 6c 65 20 62 65 67 69 6e 6e 69 6e 67 20 61 74  ile beginning at
1bc40 20 69 4f 66 66 73 65 74 2e 0a 2a 2a 20 44 6f 20   iOffset..** Do 
1bc50 61 20 73 79 6e 63 20 77 68 65 6e 20 63 72 6f 73  a sync when cros
1bc60 73 69 6e 67 20 74 68 65 20 70 2d 3e 69 53 79 6e  sing the p->iSyn
1bc70 63 50 6f 69 6e 74 20 62 6f 75 6e 64 61 72 79 2e  cPoint boundary.
1bc80 0a 2a 2a 0a 2a 2a 20 49 6e 20 6f 74 68 65 72 20  .**.** In other 
1bc90 77 6f 72 64 73 2c 20 69 66 20 69 53 79 6e 63 50  words, if iSyncP
1bca0 6f 69 6e 74 20 69 73 20 69 6e 20 62 65 74 77 65  oint is in betwe
1bcb0 65 6e 20 69 4f 66 66 73 65 74 20 61 6e 64 20 69  en iOffset and i
1bcc0 4f 66 66 73 65 74 2b 69 41 6d 74 2c 0a 2a 2a 20  Offset+iAmt,.** 
1bcd0 66 69 72 73 74 20 77 72 69 74 65 20 74 68 65 20  first write the 
1bce0 70 61 72 74 20 62 65 66 6f 72 65 20 69 53 79 6e  part before iSyn
1bcf0 63 50 6f 69 6e 74 2c 20 74 68 65 6e 20 73 79 6e  cPoint, then syn
1bd00 63 2c 20 74 68 65 6e 20 77 72 69 74 65 20 74 68  c, then write th
1bd10 65 0a 2a 2a 20 72 65 73 74 2e 0a 2a 2f 0a 73 74  e.** rest..*/.st
1bd20 61 74 69 63 20 69 6e 74 20 77 61 6c 57 72 69 74  atic int walWrit
1bd30 65 54 6f 4c 6f 67 28 0a 20 20 57 61 6c 57 72 69  eToLog(.  WalWri
1bd40 74 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20  ter *p,         
1bd50 20 20 20 20 20 2f 2a 20 57 41 4c 20 74 6f 20 77       /* WAL to w
1bd60 72 69 74 65 20 74 6f 20 2a 2f 0a 20 20 76 6f 69  rite to */.  voi
1bd70 64 20 2a 70 43 6f 6e 74 65 6e 74 2c 20 20 20 20  d *pContent,    
1bd80 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65          /* Conte
1bd90 6e 74 20 74 6f 20 62 65 20 77 72 69 74 74 65 6e  nt to be written
1bda0 20 2a 2f 0a 20 20 69 6e 74 20 69 41 6d 74 2c 20   */.  int iAmt, 
1bdb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bdc0 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
1bdd0 74 65 73 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a  tes to write */.
1bde0 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
1bdf0 69 4f 66 66 73 65 74 20 20 20 20 20 20 2f 2a 20  iOffset      /* 
1be00 53 74 61 72 74 20 77 72 69 74 69 6e 67 20 61 74  Start writing at
1be10 20 74 68 69 73 20 6f 66 66 73 65 74 20 2a 2f 0a   this offset */.
1be20 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69  ){.  int rc;.  i
1be30 66 28 20 69 4f 66 66 73 65 74 3c 70 2d 3e 69 53  f( iOffset<p->iS
1be40 79 6e 63 50 6f 69 6e 74 20 26 26 20 69 4f 66 66  yncPoint && iOff
1be50 73 65 74 2b 69 41 6d 74 3e 3d 70 2d 3e 69 53 79  set+iAmt>=p->iSy
1be60 6e 63 50 6f 69 6e 74 20 29 7b 0a 20 20 20 20 69  ncPoint ){.    i
1be70 6e 74 20 69 46 69 72 73 74 41 6d 74 20 3d 20 28  nt iFirstAmt = (
1be80 69 6e 74 29 28 70 2d 3e 69 53 79 6e 63 50 6f 69  int)(p->iSyncPoi
1be90 6e 74 20 2d 20 69 4f 66 66 73 65 74 29 3b 0a 20  nt - iOffset);. 
1bea0 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
1beb0 73 57 72 69 74 65 28 70 2d 3e 70 46 64 2c 20 70  sWrite(p->pFd, p
1bec0 43 6f 6e 74 65 6e 74 2c 20 69 46 69 72 73 74 41  Content, iFirstA
1bed0 6d 74 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  mt, iOffset);.  
1bee0 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72    if( rc ) retur
1bef0 6e 20 72 63 3b 0a 20 20 20 20 69 4f 66 66 73 65  n rc;.    iOffse
1bf00 74 20 2b 3d 20 69 46 69 72 73 74 41 6d 74 3b 0a  t += iFirstAmt;.
1bf10 20 20 20 20 69 41 6d 74 20 2d 3d 20 69 46 69 72      iAmt -= iFir
1bf20 73 74 41 6d 74 3b 0a 20 20 20 20 70 43 6f 6e 74  stAmt;.    pCont
1bf30 65 6e 74 20 3d 20 28 76 6f 69 64 2a 29 28 69 46  ent = (void*)(iF
1bf40 69 72 73 74 41 6d 74 20 2b 20 28 63 68 61 72 2a  irstAmt + (char*
1bf50 29 70 43 6f 6e 74 65 6e 74 29 3b 0a 20 20 20 20  )pContent);.    
1bf60 61 73 73 65 72 74 28 20 57 41 4c 5f 53 59 4e 43  assert( WAL_SYNC
1bf70 5f 46 4c 41 47 53 28 70 2d 3e 73 79 6e 63 46 6c  _FLAGS(p->syncFl
1bf80 61 67 73 29 21 3d 30 20 29 3b 0a 20 20 20 20 72  ags)!=0 );.    r
1bf90 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e  c = sqlite3OsSyn
1bfa0 63 28 70 2d 3e 70 46 64 2c 20 57 41 4c 5f 53 59  c(p->pFd, WAL_SY
1bfb0 4e 43 5f 46 4c 41 47 53 28 70 2d 3e 73 79 6e 63  NC_FLAGS(p->sync
1bfc0 46 6c 61 67 73 29 29 3b 0a 20 20 20 20 69 66 28  Flags));.    if(
1bfd0 20 69 41 6d 74 3d 3d 30 20 7c 7c 20 72 63 20 29   iAmt==0 || rc )
1bfe0 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
1bff0 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
1c000 57 72 69 74 65 28 70 2d 3e 70 46 64 2c 20 70 43  Write(p->pFd, pC
1c010 6f 6e 74 65 6e 74 2c 20 69 41 6d 74 2c 20 69 4f  ontent, iAmt, iO
1c020 66 66 73 65 74 29 3b 0a 20 20 72 65 74 75 72 6e  ffset);.  return
1c030 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72   rc;.}../*.** Wr
1c040 69 74 65 20 6f 75 74 20 61 20 73 69 6e 67 6c 65  ite out a single
1c050 20 66 72 61 6d 65 20 6f 66 20 74 68 65 20 57 41   frame of the WA
1c060 4c 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  L.*/.static int 
1c070 77 61 6c 57 72 69 74 65 4f 6e 65 46 72 61 6d 65  walWriteOneFrame
1c080 28 0a 20 20 57 61 6c 57 72 69 74 65 72 20 2a 70  (.  WalWriter *p
1c090 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1c0a0 2f 2a 20 57 68 65 72 65 20 74 6f 20 77 72 69 74  /* Where to writ
1c0b0 65 20 74 68 65 20 66 72 61 6d 65 20 2a 2f 0a 20  e the frame */. 
1c0c0 20 50 67 48 64 72 20 2a 70 50 61 67 65 2c 20 20   PgHdr *pPage,  
1c0d0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1c0e0 54 68 65 20 70 61 67 65 20 6f 66 20 74 68 65 20  The page of the 
1c0f0 66 72 61 6d 65 20 74 6f 20 62 65 20 77 72 69 74  frame to be writ
1c100 74 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 72  ten */.  int nTr
1c110 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20 20  uncate,         
1c120 20 20 20 20 20 2f 2a 20 54 68 65 20 63 6f 6d 6d       /* The comm
1c130 69 74 20 66 6c 61 67 2e 20 20 55 73 75 61 6c 6c  it flag.  Usuall
1c140 79 20 30 2e 20 20 3e 30 20 66 6f 72 20 63 6f 6d  y 0.  >0 for com
1c150 6d 69 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  mit */.  sqlite3
1c160 5f 69 6e 74 36 34 20 69 4f 66 66 73 65 74 20 20  _int64 iOffset  
1c170 20 20 20 20 20 2f 2a 20 42 79 74 65 20 6f 66 66       /* Byte off
1c180 73 65 74 20 61 74 20 77 68 69 63 68 20 74 6f 20  set at which to 
1c190 77 72 69 74 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e  write */.){.  in
1c1a0 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
1c1b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1c1c0 20 52 65 73 75 6c 74 20 63 6f 64 65 20 66 72 6f   Result code fro
1c1d0 6d 20 73 75 62 66 75 6e 63 74 69 6f 6e 73 20 2a  m subfunctions *
1c1e0 2f 0a 20 20 76 6f 69 64 20 2a 70 44 61 74 61 3b  /.  void *pData;
1c1f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c200 20 20 20 20 2f 2a 20 44 61 74 61 20 61 63 74 75      /* Data actu
1c210 61 6c 6c 79 20 77 72 69 74 74 65 6e 20 2a 2f 0a  ally written */.
1c220 20 20 75 38 20 61 46 72 61 6d 65 5b 57 41 4c 5f    u8 aFrame[WAL_
1c230 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 5d 3b 20  FRAME_HDRSIZE]; 
1c240 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 61    /* Buffer to a
1c250 73 73 65 6d 62 6c 65 20 66 72 61 6d 65 2d 68 65  ssemble frame-he
1c260 61 64 65 72 20 69 6e 20 2a 2f 0a 23 69 66 20 64  ader in */.#if d
1c270 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 48 41  efined(SQLITE_HA
1c280 53 5f 43 4f 44 45 43 29 0a 20 20 69 66 28 20 28  S_CODEC).  if( (
1c290 70 44 61 74 61 20 3d 20 73 71 6c 69 74 65 33 50  pData = sqlite3P
1c2a0 61 67 65 72 43 6f 64 65 63 28 70 50 61 67 65 29  agerCodec(pPage)
1c2b0 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  )==0 ) return SQ
1c2c0 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b  LITE_NOMEM_BKPT;
1c2d0 0a 23 65 6c 73 65 0a 20 20 70 44 61 74 61 20 3d  .#else.  pData =
1c2e0 20 70 50 61 67 65 2d 3e 70 44 61 74 61 3b 0a 23   pPage->pData;.#
1c2f0 65 6e 64 69 66 0a 20 20 77 61 6c 45 6e 63 6f 64  endif.  walEncod
1c300 65 46 72 61 6d 65 28 70 2d 3e 70 57 61 6c 2c 20  eFrame(p->pWal, 
1c310 70 50 61 67 65 2d 3e 70 67 6e 6f 2c 20 6e 54 72  pPage->pgno, nTr
1c320 75 6e 63 61 74 65 2c 20 70 44 61 74 61 2c 20 61  uncate, pData, a
1c330 46 72 61 6d 65 29 3b 0a 20 20 72 63 20 3d 20 77  Frame);.  rc = w
1c340 61 6c 57 72 69 74 65 54 6f 4c 6f 67 28 70 2c 20  alWriteToLog(p, 
1c350 61 46 72 61 6d 65 2c 20 73 69 7a 65 6f 66 28 61  aFrame, sizeof(a
1c360 46 72 61 6d 65 29 2c 20 69 4f 66 66 73 65 74 29  Frame), iOffset)
1c370 3b 0a 20 20 69 66 28 20 72 63 20 29 20 72 65 74  ;.  if( rc ) ret
1c380 75 72 6e 20 72 63 3b 0a 20 20 2f 2a 20 57 72 69  urn rc;.  /* Wri
1c390 74 65 20 74 68 65 20 70 61 67 65 20 64 61 74 61  te the page data
1c3a0 20 2a 2f 0a 20 20 72 63 20 3d 20 77 61 6c 57 72   */.  rc = walWr
1c3b0 69 74 65 54 6f 4c 6f 67 28 70 2c 20 70 44 61 74  iteToLog(p, pDat
1c3c0 61 2c 20 70 2d 3e 73 7a 50 61 67 65 2c 20 69 4f  a, p->szPage, iO
1c3d0 66 66 73 65 74 2b 73 69 7a 65 6f 66 28 61 46 72  ffset+sizeof(aFr
1c3e0 61 6d 65 29 29 3b 0a 20 20 72 65 74 75 72 6e 20  ame));.  return 
1c3f0 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  rc;.}../*.** Thi
1c400 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
1c410 6c 6c 65 64 20 61 73 20 70 61 72 74 20 6f 66 20  lled as part of 
1c420 63 6f 6d 6d 69 74 74 69 6e 67 20 61 20 74 72 61  committing a tra
1c430 6e 73 61 63 74 69 6f 6e 20 77 69 74 68 69 6e 20  nsaction within 
1c440 77 68 69 63 68 0a 2a 2a 20 6f 6e 65 20 6f 72 20  which.** one or 
1c450 6d 6f 72 65 20 66 72 61 6d 65 73 20 68 61 76 65  more frames have
1c460 20 62 65 65 6e 20 6f 76 65 72 77 72 69 74 74 65   been overwritte
1c470 6e 2e 20 49 74 20 75 70 64 61 74 65 73 20 74 68  n. It updates th
1c480 65 20 63 68 65 63 6b 73 75 6d 73 20 66 6f 72 0a  e checksums for.
1c490 2a 2a 20 61 6c 6c 20 66 72 61 6d 65 73 20 77 72  ** all frames wr
1c4a0 69 74 74 65 6e 20 74 6f 20 74 68 65 20 77 61 6c  itten to the wal
1c4b0 20 66 69 6c 65 20 62 79 20 74 68 65 20 63 75 72   file by the cur
1c4c0 72 65 6e 74 20 74 72 61 6e 73 61 63 74 69 6f 6e  rent transaction
1c4d0 20 73 74 61 72 74 69 6e 67 0a 2a 2a 20 77 69 74   starting.** wit
1c4e0 68 20 74 68 65 20 65 61 72 6c 69 65 73 74 20 74  h the earliest t
1c4f0 6f 20 68 61 76 65 20 62 65 65 6e 20 6f 76 65 72  o have been over
1c500 77 72 69 74 74 65 6e 2e 0a 2a 2a 0a 2a 2a 20 53  written..**.** S
1c510 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
1c520 72 6e 65 64 20 69 66 20 73 75 63 63 65 73 73 66  rned if successf
1c530 75 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65  ul, or an SQLite
1c540 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65   error code othe
1c550 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rwise..*/.static
1c560 20 69 6e 74 20 77 61 6c 52 65 77 72 69 74 65 43   int walRewriteC
1c570 68 65 63 6b 73 75 6d 73 28 57 61 6c 20 2a 70 57  hecksums(Wal *pW
1c580 61 6c 2c 20 75 33 32 20 69 4c 61 73 74 29 7b 0a  al, u32 iLast){.
1c590 20 20 63 6f 6e 73 74 20 69 6e 74 20 73 7a 50 61    const int szPa
1c5a0 67 65 20 3d 20 70 57 61 6c 2d 3e 73 7a 50 61 67  ge = pWal->szPag
1c5b0 65 3b 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61  e;/* Database pa
1c5c0 67 65 20 73 69 7a 65 20 2a 2f 0a 20 20 69 6e 74  ge size */.  int
1c5d0 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
1c5e0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1c5f0 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
1c600 20 75 38 20 2a 61 42 75 66 3b 20 20 20 20 20 20   u8 *aBuf;      
1c610 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1c620 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 6c 6f   /* Buffer to lo
1c630 61 64 20 64 61 74 61 20 66 72 6f 6d 20 77 61 6c  ad data from wal
1c640 20 66 69 6c 65 20 69 6e 74 6f 20 2a 2f 0a 20 20   file into */.  
1c650 75 38 20 61 46 72 61 6d 65 5b 57 41 4c 5f 46 52  u8 aFrame[WAL_FR
1c660 41 4d 45 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20  AME_HDRSIZE];   
1c670 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 61 73 73  /* Buffer to ass
1c680 65 6d 62 6c 65 20 66 72 61 6d 65 2d 68 65 61 64  emble frame-head
1c690 65 72 73 20 69 6e 20 2a 2f 0a 20 20 75 33 32 20  ers in */.  u32 
1c6a0 69 52 65 61 64 3b 20 20 20 20 20 20 20 20 20 20  iRead;          
1c6b0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
1c6c0 65 78 74 20 66 72 61 6d 65 20 74 6f 20 72 65 61  ext frame to rea
1c6d0 64 20 66 72 6f 6d 20 77 61 6c 20 66 69 6c 65 20  d from wal file 
1c6e0 2a 2f 0a 20 20 69 36 34 20 69 43 6b 73 75 6d 4f  */.  i64 iCksumO
1c6f0 66 66 3b 0a 0a 20 20 61 42 75 66 20 3d 20 73 71  ff;..  aBuf = sq
1c700 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 7a 50  lite3_malloc(szP
1c710 61 67 65 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  age + WAL_FRAME_
1c720 48 44 52 53 49 5a 45 29 3b 0a 20 20 69 66 28 20  HDRSIZE);.  if( 
1c730 61 42 75 66 3d 3d 30 20 29 20 72 65 74 75 72 6e  aBuf==0 ) return
1c740 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 5f 42 4b   SQLITE_NOMEM_BK
1c750 50 54 3b 0a 0a 20 20 2f 2a 20 46 69 6e 64 20 74  PT;..  /* Find t
1c760 68 65 20 63 68 65 63 6b 73 75 6d 20 76 61 6c 75  he checksum valu
1c770 65 73 20 74 6f 20 75 73 65 20 61 73 20 69 6e 70  es to use as inp
1c780 75 74 20 66 6f 72 20 74 68 65 20 72 65 63 61 6c  ut for the recal
1c790 63 75 6c 61 74 69 6e 67 20 74 68 65 0a 20 20 2a  culating the.  *
1c7a0 2a 20 66 69 72 73 74 20 63 68 65 63 6b 73 75 6d  * first checksum
1c7b0 2e 20 49 66 20 74 68 65 20 66 69 72 73 74 20 66  . If the first f
1c7c0 72 61 6d 65 20 69 73 20 66 72 61 6d 65 20 31 20  rame is frame 1 
1c7d0 28 69 6d 70 6c 79 69 6e 67 20 74 68 61 74 20 74  (implying that t
1c7e0 68 65 20 63 75 72 72 65 6e 74 0a 20 20 2a 2a 20  he current.  ** 
1c7f0 74 72 61 6e 73 61 63 74 69 6f 6e 20 72 65 73 74  transaction rest
1c800 61 72 74 65 64 20 74 68 65 20 77 61 6c 20 66 69  arted the wal fi
1c810 6c 65 29 2c 20 74 68 65 73 65 20 76 61 6c 75 65  le), these value
1c820 73 20 6d 75 73 74 20 62 65 20 72 65 61 64 20 66  s must be read f
1c830 72 6f 6d 20 74 68 65 0a 20 20 2a 2a 20 77 61 6c  rom the.  ** wal
1c840 2d 66 69 6c 65 20 68 65 61 64 65 72 2e 20 4f 74  -file header. Ot
1c850 68 65 72 77 69 73 65 2c 20 72 65 61 64 20 74 68  herwise, read th
1c860 65 6d 20 66 72 6f 6d 20 74 68 65 20 66 72 61 6d  em from the fram
1c870 65 20 68 65 61 64 65 72 20 6f 66 20 74 68 65 0a  e header of the.
1c880 20 20 2a 2a 20 70 72 65 76 69 6f 75 73 20 66 72    ** previous fr
1c890 61 6d 65 2e 20 20 2a 2f 0a 20 20 61 73 73 65 72  ame.  */.  asser
1c8a0 74 28 20 70 57 61 6c 2d 3e 69 52 65 43 6b 73 75  t( pWal->iReCksu
1c8b0 6d 3e 30 20 29 3b 0a 20 20 69 66 28 20 70 57 61  m>0 );.  if( pWa
1c8c0 6c 2d 3e 69 52 65 43 6b 73 75 6d 3d 3d 31 20 29  l->iReCksum==1 )
1c8d0 7b 0a 20 20 20 20 69 43 6b 73 75 6d 4f 66 66 20  {.    iCksumOff 
1c8e0 3d 20 32 34 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  = 24;.  }else{. 
1c8f0 20 20 20 69 43 6b 73 75 6d 4f 66 66 20 3d 20 77     iCksumOff = w
1c900 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 70 57  alFrameOffset(pW
1c910 61 6c 2d 3e 69 52 65 43 6b 73 75 6d 2d 31 2c 20  al->iReCksum-1, 
1c920 73 7a 50 61 67 65 29 20 2b 20 31 36 3b 0a 20 20  szPage) + 16;.  
1c930 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  }.  rc = sqlite3
1c940 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61  OsRead(pWal->pWa
1c950 6c 46 64 2c 20 61 42 75 66 2c 20 73 69 7a 65 6f  lFd, aBuf, sizeo
1c960 66 28 75 33 32 29 2a 32 2c 20 69 43 6b 73 75 6d  f(u32)*2, iCksum
1c970 4f 66 66 29 3b 0a 20 20 70 57 61 6c 2d 3e 68 64  Off);.  pWal->hd
1c980 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d  r.aFrameCksum[0]
1c990 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62 79   = sqlite3Get4by
1c9a0 74 65 28 61 42 75 66 29 3b 0a 20 20 70 57 61 6c  te(aBuf);.  pWal
1c9b0 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
1c9c0 6d 5b 31 5d 20 3d 20 73 71 6c 69 74 65 33 47 65  m[1] = sqlite3Ge
1c9d0 74 34 62 79 74 65 28 26 61 42 75 66 5b 73 69 7a  t4byte(&aBuf[siz
1c9e0 65 6f 66 28 75 33 32 29 5d 29 3b 0a 0a 20 20 69  eof(u32)]);..  i
1c9f0 52 65 61 64 20 3d 20 70 57 61 6c 2d 3e 69 52 65  Read = pWal->iRe
1ca00 43 6b 73 75 6d 3b 0a 20 20 70 57 61 6c 2d 3e 69  Cksum;.  pWal->i
1ca10 52 65 43 6b 73 75 6d 20 3d 20 30 3b 0a 20 20 66  ReCksum = 0;.  f
1ca20 6f 72 28 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f  or(; rc==SQLITE_
1ca30 4f 4b 20 26 26 20 69 52 65 61 64 3c 3d 69 4c 61  OK && iRead<=iLa
1ca40 73 74 3b 20 69 52 65 61 64 2b 2b 29 7b 0a 20 20  st; iRead++){.  
1ca50 20 20 69 36 34 20 69 4f 66 66 20 3d 20 77 61 6c    i64 iOff = wal
1ca60 46 72 61 6d 65 4f 66 66 73 65 74 28 69 52 65 61  FrameOffset(iRea
1ca70 64 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20 20 20  d, szPage);.    
1ca80 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65  rc = sqlite3OsRe
1ca90 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  ad(pWal->pWalFd,
1caa0 20 61 42 75 66 2c 20 73 7a 50 61 67 65 2b 57 41   aBuf, szPage+WA
1cab0 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 2c  L_FRAME_HDRSIZE,
1cac0 20 69 4f 66 66 29 3b 0a 20 20 20 20 69 66 28 20   iOff);.    if( 
1cad0 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1cae0 0a 20 20 20 20 20 20 75 33 32 20 69 50 67 6e 6f  .      u32 iPgno
1caf0 2c 20 6e 44 62 53 69 7a 65 3b 0a 20 20 20 20 20  , nDbSize;.     
1cb00 20 69 50 67 6e 6f 20 3d 20 73 71 6c 69 74 65 33   iPgno = sqlite3
1cb10 47 65 74 34 62 79 74 65 28 61 42 75 66 29 3b 0a  Get4byte(aBuf);.
1cb20 20 20 20 20 20 20 6e 44 62 53 69 7a 65 20 3d 20        nDbSize = 
1cb30 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
1cb40 26 61 42 75 66 5b 34 5d 29 3b 0a 0a 20 20 20 20  &aBuf[4]);..    
1cb50 20 20 77 61 6c 45 6e 63 6f 64 65 46 72 61 6d 65    walEncodeFrame
1cb60 28 70 57 61 6c 2c 20 69 50 67 6e 6f 2c 20 6e 44  (pWal, iPgno, nD
1cb70 62 53 69 7a 65 2c 20 26 61 42 75 66 5b 57 41 4c  bSize, &aBuf[WAL
1cb80 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 5d 2c  _FRAME_HDRSIZE],
1cb90 20 61 46 72 61 6d 65 29 3b 0a 20 20 20 20 20 20   aFrame);.      
1cba0 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72  rc = sqlite3OsWr
1cbb0 69 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ite(pWal->pWalFd
1cbc0 2c 20 61 46 72 61 6d 65 2c 20 73 69 7a 65 6f 66  , aFrame, sizeof
1cbd0 28 61 46 72 61 6d 65 29 2c 20 69 4f 66 66 29 3b  (aFrame), iOff);
1cbe0 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 73 71  .    }.  }..  sq
1cbf0 6c 69 74 65 33 5f 66 72 65 65 28 61 42 75 66 29  lite3_free(aBuf)
1cc00 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
1cc10 0a 0a 2f 2a 20 0a 2a 2a 20 57 72 69 74 65 20 61  ../* .** Write a
1cc20 20 73 65 74 20 6f 66 20 66 72 61 6d 65 73 20 74   set of frames t
1cc30 6f 20 74 68 65 20 6c 6f 67 2e 20 54 68 65 20 63  o the log. The c
1cc40 61 6c 6c 65 72 20 6d 75 73 74 20 68 6f 6c 64 20  aller must hold 
1cc50 74 68 65 20 77 72 69 74 65 2d 6c 6f 63 6b 0a 2a  the write-lock.*
1cc60 2a 20 6f 6e 20 74 68 65 20 6c 6f 67 20 66 69 6c  * on the log fil
1cc70 65 20 28 6f 62 74 61 69 6e 65 64 20 75 73 69 6e  e (obtained usin
1cc80 67 20 73 71 6c 69 74 65 33 57 61 6c 42 65 67 69  g sqlite3WalBegi
1cc90 6e 57 72 69 74 65 54 72 61 6e 73 61 63 74 69 6f  nWriteTransactio
1cca0 6e 28 29 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  n())..*/.int sql
1ccb0 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28 0a 20  ite3WalFrames(. 
1ccc0 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20   Wal *pWal,     
1ccd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cce0 20 2f 2a 20 57 61 6c 20 68 61 6e 64 6c 65 20 74   /* Wal handle t
1ccf0 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20 20  o write to */.  
1cd00 69 6e 74 20 73 7a 50 61 67 65 2c 20 20 20 20 20  int szPage,     
1cd10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cd20 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  /* Database page
1cd30 2d 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20 2a  -size in bytes *
1cd40 2f 0a 20 20 50 67 48 64 72 20 2a 70 4c 69 73 74  /.  PgHdr *pList
1cd50 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1cd60 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20 64      /* List of d
1cd70 69 72 74 79 20 70 61 67 65 73 20 74 6f 20 77 72  irty pages to wr
1cd80 69 74 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 6e 54  ite */.  Pgno nT
1cd90 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20  runcate,        
1cda0 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
1cdb0 62 61 73 65 20 73 69 7a 65 20 61 66 74 65 72 20  base size after 
1cdc0 74 68 69 73 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20  this commit */. 
1cdd0 20 69 6e 74 20 69 73 43 6f 6d 6d 69 74 2c 20 20   int isCommit,  
1cde0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cdf0 20 2f 2a 20 54 72 75 65 20 69 66 20 74 68 69 73   /* True if this
1ce00 20 69 73 20 61 20 63 6f 6d 6d 69 74 20 2a 2f 0a   is a commit */.
1ce10 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67 73    int sync_flags
1ce20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ce30 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20 70 61    /* Flags to pa
1ce40 73 73 20 74 6f 20 4f 73 53 79 6e 63 28 29 20 28  ss to OsSync() (
1ce50 6f 72 20 30 29 20 2a 2f 0a 29 7b 0a 20 20 69 6e  or 0) */.){.  in
1ce60 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
1ce70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1ce80 20 55 73 65 64 20 74 6f 20 63 61 74 63 68 20 72   Used to catch r
1ce90 65 74 75 72 6e 20 63 6f 64 65 73 20 2a 2f 0a 20  eturn codes */. 
1cea0 20 75 33 32 20 69 46 72 61 6d 65 3b 20 20 20 20   u32 iFrame;    
1ceb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1cec0 20 2f 2a 20 4e 65 78 74 20 66 72 61 6d 65 20 61   /* Next frame a
1ced0 64 64 72 65 73 73 20 2a 2f 0a 20 20 50 67 48 64  ddress */.  PgHd
1cee0 72 20 2a 70 3b 20 20 20 20 20 20 20 20 20 20 20  r *p;           
1cef0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
1cf00 74 65 72 61 74 6f 72 20 74 6f 20 72 75 6e 20 74  terator to run t
1cf10 68 72 6f 75 67 68 20 70 4c 69 73 74 20 77 69 74  hrough pList wit
1cf20 68 2e 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70  h. */.  PgHdr *p
1cf30 4c 61 73 74 20 3d 20 30 3b 20 20 20 20 20 20 20  Last = 0;       
1cf40 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73 74 20          /* Last 
1cf50 66 72 61 6d 65 20 69 6e 20 6c 69 73 74 20 2a 2f  frame in list */
1cf60 0a 20 20 69 6e 74 20 6e 45 78 74 72 61 20 3d 20  .  int nExtra = 
1cf70 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
1cf80 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
1cf90 65 78 74 72 61 20 63 6f 70 69 65 73 20 6f 66 20  extra copies of 
1cfa0 6c 61 73 74 20 70 61 67 65 20 2a 2f 0a 20 20 69  last page */.  i
1cfb0 6e 74 20 73 7a 46 72 61 6d 65 3b 20 20 20 20 20  nt szFrame;     
1cfc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1cfd0 2a 20 54 68 65 20 73 69 7a 65 20 6f 66 20 61 20  * The size of a 
1cfe0 73 69 6e 67 6c 65 20 66 72 61 6d 65 20 2a 2f 0a  single frame */.
1cff0 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 20 20    i64 iOffset;  
1d000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d010 20 20 2f 2a 20 4e 65 78 74 20 62 79 74 65 20 74    /* Next byte t
1d020 6f 20 77 72 69 74 65 20 69 6e 20 57 41 4c 20 66  o write in WAL f
1d030 69 6c 65 20 2a 2f 0a 20 20 57 61 6c 57 72 69 74  ile */.  WalWrit
1d040 65 72 20 77 3b 20 20 20 20 20 20 20 20 20 20 20  er w;           
1d050 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
1d060 77 72 69 74 65 72 20 2a 2f 0a 20 20 75 33 32 20  writer */.  u32 
1d070 69 46 69 72 73 74 20 3d 20 30 3b 20 20 20 20 20  iFirst = 0;     
1d080 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
1d090 69 72 73 74 20 66 72 61 6d 65 20 74 68 61 74 20  irst frame that 
1d0a0 6d 61 79 20 62 65 20 6f 76 65 72 77 72 69 74 74  may be overwritt
1d0b0 65 6e 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65 78  en */.  WalIndex
1d0c0 48 64 72 20 2a 70 4c 69 76 65 3b 20 20 20 20 20  Hdr *pLive;     
1d0d0 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
1d0e0 65 72 20 74 6f 20 73 68 61 72 65 64 20 68 65 61  er to shared hea
1d0f0 64 65 72 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  der */..  assert
1d100 28 20 70 4c 69 73 74 20 29 3b 0a 20 20 61 73 73  ( pList );.  ass
1d110 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65  ert( pWal->write
1d120 4c 6f 63 6b 20 29 3b 0a 0a 20 20 2f 2a 20 49 66  Lock );..  /* If
1d130 20 74 68 69 73 20 66 72 61 6d 65 20 73 65 74 20   this frame set 
1d140 63 6f 6d 70 6c 65 74 65 73 20 61 20 74 72 61 6e  completes a tran
1d150 73 61 63 74 69 6f 6e 2c 20 74 68 65 6e 20 6e 54  saction, then nT
1d160 72 75 6e 63 61 74 65 3e 30 2e 20 20 49 66 0a 20  runcate>0.  If. 
1d170 20 2a 2a 20 6e 54 72 75 6e 63 61 74 65 3d 3d 30   ** nTruncate==0
1d180 20 74 68 65 6e 20 74 68 69 73 20 66 72 61 6d 65   then this frame
1d190 20 73 65 74 20 64 6f 65 73 20 6e 6f 74 20 63 6f   set does not co
1d1a0 6d 70 6c 65 74 65 20 74 68 65 20 74 72 61 6e 73  mplete the trans
1d1b0 61 63 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73  action. */.  ass
1d1c0 65 72 74 28 20 28 69 73 43 6f 6d 6d 69 74 21 3d  ert( (isCommit!=
1d1d0 30 29 3d 3d 28 6e 54 72 75 6e 63 61 74 65 21 3d  0)==(nTruncate!=
1d1e0 30 29 20 29 3b 0a 0a 23 69 66 20 64 65 66 69 6e  0) );..#if defin
1d1f0 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20  ed(SQLITE_TEST) 
1d200 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  && defined(SQLIT
1d210 45 5f 44 45 42 55 47 29 0a 20 20 7b 20 69 6e 74  E_DEBUG).  { int
1d220 20 63 6e 74 3b 20 66 6f 72 28 63 6e 74 3d 30 2c   cnt; for(cnt=0,
1d230 20 70 3d 70 4c 69 73 74 3b 20 70 3b 20 70 3d 70   p=pList; p; p=p
1d240 2d 3e 70 44 69 72 74 79 2c 20 63 6e 74 2b 2b 29  ->pDirty, cnt++)
1d250 7b 7d 0a 20 20 20 20 57 41 4c 54 52 41 43 45 28  {}.    WALTRACE(
1d260 28 22 57 41 4c 25 70 3a 20 66 72 61 6d 65 20 77  ("WAL%p: frame w
1d270 72 69 74 65 20 62 65 67 69 6e 2e 20 25 64 20 66  rite begin. %d f
1d280 72 61 6d 65 73 2e 20 6d 78 46 72 61 6d 65 3d 25  rames. mxFrame=%
1d290 64 2e 20 25 73 5c 6e 22 2c 0a 20 20 20 20 20 20  d. %s\n",.      
1d2a0 20 20 20 20 20 20 20 20 70 57 61 6c 2c 20 63 6e          pWal, cn
1d2b0 74 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  t, pWal->hdr.mxF
1d2c0 72 61 6d 65 2c 20 69 73 43 6f 6d 6d 69 74 20 3f  rame, isCommit ?
1d2d0 20 22 43 6f 6d 6d 69 74 22 20 3a 20 22 53 70 69   "Commit" : "Spi
1d2e0 6c 6c 22 29 29 3b 0a 20 20 7d 0a 23 65 6e 64 69  ll"));.  }.#endi
1d2f0 66 0a 0a 20 20 70 4c 69 76 65 20 3d 20 28 57 61  f..  pLive = (Wa
1d300 6c 49 6e 64 65 78 48 64 72 2a 29 77 61 6c 49 6e  lIndexHdr*)walIn
1d310 64 65 78 48 64 72 28 70 57 61 6c 29 3b 0a 20 20  dexHdr(pWal);.  
1d320 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c  if( memcmp(&pWal
1d330 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20 2a 29 70  ->hdr, (void *)p
1d340 4c 69 76 65 2c 20 73 69 7a 65 6f 66 28 57 61 6c  Live, sizeof(Wal
1d350 49 6e 64 65 78 48 64 72 29 29 21 3d 30 20 29 7b  IndexHdr))!=0 ){
1d360 0a 20 20 20 20 69 46 69 72 73 74 20 3d 20 70 4c  .    iFirst = pL
1d370 69 76 65 2d 3e 6d 78 46 72 61 6d 65 2b 31 3b 0a  ive->mxFrame+1;.
1d380 20 20 7d 0a 0a 20 20 2f 2a 20 53 65 65 20 69 66    }..  /* See if
1d390 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c 65 20   it is possible 
1d3a0 74 6f 20 77 72 69 74 65 20 74 68 65 73 65 20 66  to write these f
1d3b0 72 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20 73  rames into the s
1d3c0 74 61 72 74 20 6f 66 20 74 68 65 0a 20 20 2a 2a  tart of the.  **
1d3d0 20 6c 6f 67 20 66 69 6c 65 2c 20 69 6e 73 74 65   log file, inste
1d3e0 61 64 20 6f 66 20 61 70 70 65 6e 64 69 6e 67 20  ad of appending 
1d3f0 74 6f 20 69 74 20 61 74 20 70 57 61 6c 2d 3e 68  to it at pWal->h
1d400 64 72 2e 6d 78 46 72 61 6d 65 2e 0a 20 20 2a 2f  dr.mxFrame..  */
1d410 0a 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b  .  if( SQLITE_OK
1d420 21 3d 28 72 63 20 3d 20 77 61 6c 52 65 73 74 61  !=(rc = walResta
1d430 72 74 4c 6f 67 28 70 57 61 6c 29 29 20 29 7b 0a  rtLog(pWal)) ){.
1d440 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
1d450 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 69 73   }..  /* If this
1d460 20 69 73 20 74 68 65 20 66 69 72 73 74 20 66 72   is the first fr
1d470 61 6d 65 20 77 72 69 74 74 65 6e 20 69 6e 74 6f  ame written into
1d480 20 74 68 65 20 6c 6f 67 2c 20 77 72 69 74 65 20   the log, write 
1d490 74 68 65 20 57 41 4c 0a 20 20 2a 2a 20 68 65 61  the WAL.  ** hea
1d4a0 64 65 72 20 74 6f 20 74 68 65 20 73 74 61 72 74  der to the start
1d4b0 20 6f 66 20 74 68 65 20 57 41 4c 20 66 69 6c 65   of the WAL file
1d4c0 2e 20 53 65 65 20 63 6f 6d 6d 65 6e 74 73 20 61  . See comments a
1d4d0 74 20 74 68 65 20 74 6f 70 20 6f 66 0a 20 20 2a  t the top of.  *
1d4e0 2a 20 74 68 69 73 20 73 6f 75 72 63 65 20 66 69  * this source fi
1d4f0 6c 65 20 66 6f 72 20 61 20 64 65 73 63 72 69 70  le for a descrip
1d500 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41 4c 20  tion of the WAL 
1d510 68 65 61 64 65 72 20 66 6f 72 6d 61 74 2e 0a 20  header format.. 
1d520 20 2a 2f 0a 20 20 69 46 72 61 6d 65 20 3d 20 70   */.  iFrame = p
1d530 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
1d540 3b 0a 20 20 69 66 28 20 69 46 72 61 6d 65 3d 3d  ;.  if( iFrame==
1d550 30 20 29 7b 0a 20 20 20 20 75 38 20 61 57 61 6c  0 ){.    u8 aWal
1d560 48 64 72 5b 57 41 4c 5f 48 44 52 53 49 5a 45 5d  Hdr[WAL_HDRSIZE]
1d570 3b 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72  ;      /* Buffer
1d580 20 74 6f 20 61 73 73 65 6d 62 6c 65 20 77 61 6c   to assemble wal
1d590 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f 0a 20 20  -header in */.  
1d5a0 20 20 75 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b    u32 aCksum[2];
1d5b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d5c0 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66 6f 72 20  /* Checksum for 
1d5d0 77 61 6c 2d 68 65 61 64 65 72 20 2a 2f 0a 0a 20  wal-header */.. 
1d5e0 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79     sqlite3Put4by
1d5f0 74 65 28 26 61 57 61 6c 48 64 72 5b 30 5d 2c 20  te(&aWalHdr[0], 
1d600 28 57 41 4c 5f 4d 41 47 49 43 20 7c 20 53 51 4c  (WAL_MAGIC | SQL
1d610 49 54 45 5f 42 49 47 45 4e 44 49 41 4e 29 29 3b  ITE_BIGENDIAN));
1d620 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34  .    sqlite3Put4
1d630 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 34 5d  byte(&aWalHdr[4]
1d640 2c 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49 4f  , WAL_MAX_VERSIO
1d650 4e 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50  N);.    sqlite3P
1d660 75 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72  ut4byte(&aWalHdr
1d670 5b 38 5d 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20  [8], szPage);.  
1d680 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74    sqlite3Put4byt
1d690 65 28 26 61 57 61 6c 48 64 72 5b 31 32 5d 2c 20  e(&aWalHdr[12], 
1d6a0 70 57 61 6c 2d 3e 6e 43 6b 70 74 29 3b 0a 20 20  pWal->nCkpt);.  
1d6b0 20 20 69 66 28 20 70 57 61 6c 2d 3e 6e 43 6b 70    if( pWal->nCkp
1d6c0 74 3d 3d 30 20 29 20 73 71 6c 69 74 65 33 5f 72  t==0 ) sqlite3_r
1d6d0 61 6e 64 6f 6d 6e 65 73 73 28 38 2c 20 70 57 61  andomness(8, pWa
1d6e0 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 29 3b 0a 20  l->hdr.aSalt);. 
1d6f0 20 20 20 6d 65 6d 63 70 79 28 26 61 57 61 6c 48     memcpy(&aWalH
1d700 64 72 5b 31 36 5d 2c 20 70 57 61 6c 2d 3e 68 64  dr[16], pWal->hd
1d710 72 2e 61 53 61 6c 74 2c 20 38 29 3b 0a 20 20 20  r.aSalt, 8);.   
1d720 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65   walChecksumByte
1d730 73 28 31 2c 20 61 57 61 6c 48 64 72 2c 20 57 41  s(1, aWalHdr, WA
1d740 4c 5f 48 44 52 53 49 5a 45 2d 32 2a 34 2c 20 30  L_HDRSIZE-2*4, 0
1d750 2c 20 61 43 6b 73 75 6d 29 3b 0a 20 20 20 20 73  , aCksum);.    s
1d760 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
1d770 61 57 61 6c 48 64 72 5b 32 34 5d 2c 20 61 43 6b  aWalHdr[24], aCk
1d780 73 75 6d 5b 30 5d 29 3b 0a 20 20 20 20 73 71 6c  sum[0]);.    sql
1d790 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57  ite3Put4byte(&aW
1d7a0 61 6c 48 64 72 5b 32 38 5d 2c 20 61 43 6b 73 75  alHdr[28], aCksu
1d7b0 6d 5b 31 5d 29 3b 0a 20 20 20 20 0a 20 20 20 20  m[1]);.    .    
1d7c0 70 57 61 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 73  pWal->szPage = s
1d7d0 7a 50 61 67 65 3b 0a 20 20 20 20 70 57 61 6c 2d  zPage;.    pWal-
1d7e0 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d  >hdr.bigEndCksum
1d7f0 20 3d 20 53 51 4c 49 54 45 5f 42 49 47 45 4e 44   = SQLITE_BIGEND
1d800 49 41 4e 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68  IAN;.    pWal->h
1d810 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30  dr.aFrameCksum[0
1d820 5d 20 3d 20 61 43 6b 73 75 6d 5b 30 5d 3b 0a 20  ] = aCksum[0];. 
1d830 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72     pWal->hdr.aFr
1d840 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 61 43  ameCksum[1] = aC
1d850 6b 73 75 6d 5b 31 5d 3b 0a 20 20 20 20 70 57 61  ksum[1];.    pWa
1d860 6c 2d 3e 74 72 75 6e 63 61 74 65 4f 6e 43 6f 6d  l->truncateOnCom
1d870 6d 69 74 20 3d 20 31 3b 0a 0a 20 20 20 20 72 63  mit = 1;..    rc
1d880 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74   = sqlite3OsWrit
1d890 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20  e(pWal->pWalFd, 
1d8a0 61 57 61 6c 48 64 72 2c 20 73 69 7a 65 6f 66 28  aWalHdr, sizeof(
1d8b0 61 57 61 6c 48 64 72 29 2c 20 30 29 3b 0a 20 20  aWalHdr), 0);.  
1d8c0 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c    WALTRACE(("WAL
1d8d0 25 70 3a 20 77 61 6c 2d 68 65 61 64 65 72 20 77  %p: wal-header w
1d8e0 72 69 74 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c  rite %s\n", pWal
1d8f0 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20  , rc ? "failed" 
1d900 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 20 20 69 66  : "ok"));.    if
1d910 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
1d920 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
1d930 72 63 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  rc;.    }..    /
1d940 2a 20 53 79 6e 63 20 74 68 65 20 68 65 61 64 65  * Sync the heade
1d950 72 20 28 75 6e 6c 65 73 73 20 53 51 4c 49 54 45  r (unless SQLITE
1d960 5f 49 4f 43 41 50 5f 53 45 51 55 45 4e 54 49 41  _IOCAP_SEQUENTIA
1d970 4c 20 69 73 20 74 72 75 65 20 6f 72 20 75 6e 6c  L is true or unl
1d980 65 73 73 0a 20 20 20 20 2a 2a 20 61 6c 6c 20 73  ess.    ** all s
1d990 79 6e 63 69 6e 67 20 69 73 20 74 75 72 6e 65 64  yncing is turned
1d9a0 20 6f 66 66 20 62 79 20 50 52 41 47 4d 41 20 73   off by PRAGMA s
1d9b0 79 6e 63 68 72 6f 6e 6f 75 73 3d 4f 46 46 29 2e  ynchronous=OFF).
1d9c0 20 20 4f 74 68 65 72 77 69 73 65 0a 20 20 20 20    Otherwise.    
1d9d0 2a 2a 20 61 6e 20 6f 75 74 2d 6f 66 2d 6f 72 64  ** an out-of-ord
1d9e0 65 72 20 77 72 69 74 65 20 66 6f 6c 6c 6f 77 69  er write followi
1d9f0 6e 67 20 61 20 57 41 4c 20 72 65 73 74 61 72 74  ng a WAL restart
1da00 20 63 6f 75 6c 64 20 72 65 73 75 6c 74 20 69 6e   could result in
1da10 0a 20 20 20 20 2a 2a 20 64 61 74 61 62 61 73 65  .    ** database
1da20 20 63 6f 72 72 75 70 74 69 6f 6e 2e 20 20 53 65   corruption.  Se
1da30 65 20 74 68 65 20 74 69 63 6b 65 74 3a 0a 20 20  e the ticket:.  
1da40 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 20 20 20 20    **.    **     
1da50 68 74 74 70 73 3a 2f 2f 73 71 6c 69 74 65 2e 6f  https://sqlite.o
1da60 72 67 2f 73 72 63 2f 69 6e 66 6f 2f 66 66 35 62  rg/src/info/ff5b
1da70 65 37 33 64 65 65 0a 20 20 20 20 2a 2f 0a 20 20  e73dee.    */.  
1da80 20 20 69 66 28 20 70 57 61 6c 2d 3e 73 79 6e 63    if( pWal->sync
1da90 48 65 61 64 65 72 20 29 7b 0a 20 20 20 20 20 20  Header ){.      
1daa0 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79  rc = sqlite3OsSy
1dab0 6e 63 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  nc(pWal->pWalFd,
1dac0 20 43 4b 50 54 5f 53 59 4e 43 5f 46 4c 41 47 53   CKPT_SYNC_FLAGS
1dad0 28 73 79 6e 63 5f 66 6c 61 67 73 29 29 3b 0a 20  (sync_flags));. 
1dae0 20 20 20 20 20 69 66 28 20 72 63 20 29 20 72 65       if( rc ) re
1daf0 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20  turn rc;.    }. 
1db00 20 7d 0a 20 20 61 73 73 65 72 74 28 20 28 69 6e   }.  assert( (in
1db10 74 29 70 57 61 6c 2d 3e 73 7a 50 61 67 65 3d 3d  t)pWal->szPage==
1db20 73 7a 50 61 67 65 20 29 3b 0a 0a 20 20 2f 2a 20  szPage );..  /* 
1db30 53 65 74 75 70 20 69 6e 66 6f 72 6d 61 74 69 6f  Setup informatio
1db40 6e 20 6e 65 65 64 65 64 20 74 6f 20 77 72 69 74  n needed to writ
1db50 65 20 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68  e frames into th
1db60 65 20 57 41 4c 20 2a 2f 0a 20 20 77 2e 70 57 61  e WAL */.  w.pWa
1db70 6c 20 3d 20 70 57 61 6c 3b 0a 20 20 77 2e 70 46  l = pWal;.  w.pF
1db80 64 20 3d 20 70 57 61 6c 2d 3e 70 57 61 6c 46 64  d = pWal->pWalFd
1db90 3b 0a 20 20 77 2e 69 53 79 6e 63 50 6f 69 6e 74  ;.  w.iSyncPoint
1dba0 20 3d 20 30 3b 0a 20 20 77 2e 73 79 6e 63 46 6c   = 0;.  w.syncFl
1dbb0 61 67 73 20 3d 20 73 79 6e 63 5f 66 6c 61 67 73  ags = sync_flags
1dbc0 3b 0a 20 20 77 2e 73 7a 50 61 67 65 20 3d 20 73  ;.  w.szPage = s
1dbd0 7a 50 61 67 65 3b 0a 20 20 69 4f 66 66 73 65 74  zPage;.  iOffset
1dbe0 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65   = walFrameOffse
1dbf0 74 28 69 46 72 61 6d 65 2b 31 2c 20 73 7a 50 61  t(iFrame+1, szPa
1dc00 67 65 29 3b 0a 20 20 73 7a 46 72 61 6d 65 20 3d  ge);.  szFrame =
1dc10 20 73 7a 50 61 67 65 20 2b 20 57 41 4c 5f 46 52   szPage + WAL_FR
1dc20 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 0a 20 20  AME_HDRSIZE;..  
1dc30 2f 2a 20 57 72 69 74 65 20 61 6c 6c 20 66 72 61  /* Write all fra
1dc40 6d 65 73 20 69 6e 74 6f 20 74 68 65 20 6c 6f 67  mes into the log
1dc50 20 66 69 6c 65 20 65 78 61 63 74 6c 79 20 6f 6e   file exactly on
1dc60 63 65 20 2a 2f 0a 20 20 66 6f 72 28 70 3d 70 4c  ce */.  for(p=pL
1dc70 69 73 74 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69  ist; p; p=p->pDi
1dc80 72 74 79 29 7b 0a 20 20 20 20 69 6e 74 20 6e 44  rty){.    int nD
1dc90 62 53 69 7a 65 3b 20 20 20 2f 2a 20 30 20 6e 6f  bSize;   /* 0 no
1dca0 72 6d 61 6c 6c 79 2e 20 20 50 6f 73 69 74 69 76  rmally.  Positiv
1dcb0 65 20 3d 3d 20 63 6f 6d 6d 69 74 20 66 6c 61 67  e == commit flag
1dcc0 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 43 68 65 63   */..    /* Chec
1dcd0 6b 20 69 66 20 74 68 69 73 20 70 61 67 65 20 68  k if this page h
1dce0 61 73 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20  as already been 
1dcf0 77 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65  written into the
1dd00 20 77 61 6c 20 66 69 6c 65 20 62 79 0a 20 20 20   wal file by.   
1dd10 20 2a 2a 20 74 68 65 20 63 75 72 72 65 6e 74 20   ** the current 
1dd20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 49 66 20  transaction. If 
1dd30 73 6f 2c 20 6f 76 65 72 77 72 69 74 65 20 74 68  so, overwrite th
1dd40 65 20 65 78 69 73 74 69 6e 67 20 66 72 61 6d 65  e existing frame
1dd50 20 61 6e 64 0a 20 20 20 20 2a 2a 20 73 65 74 20   and.    ** set 
1dd60 57 61 6c 2e 77 72 69 74 65 4c 6f 63 6b 20 74 6f  Wal.writeLock to
1dd70 20 57 41 4c 5f 57 52 49 54 45 4c 4f 43 4b 5f 52   WAL_WRITELOCK_R
1dd80 45 43 4b 53 55 4d 20 2d 20 69 6e 64 69 63 61 74  ECKSUM - indicat
1dd90 69 6e 67 20 74 68 61 74 20 0a 20 20 20 20 2a 2a  ing that .    **
1dda0 20 63 68 65 63 6b 73 75 6d 73 20 6d 75 73 74 20   checksums must 
1ddb0 62 65 20 72 65 63 6f 6d 70 75 74 65 64 20 77 68  be recomputed wh
1ddc0 65 6e 20 74 68 65 20 74 72 61 6e 73 61 63 74 69  en the transacti
1ddd0 6f 6e 20 69 73 20 63 6f 6d 6d 69 74 74 65 64 2e  on is committed.
1dde0 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 69 46 69    */.    if( iFi
1ddf0 72 73 74 20 26 26 20 28 70 2d 3e 70 44 69 72 74  rst && (p->pDirt
1de00 79 20 7c 7c 20 69 73 43 6f 6d 6d 69 74 3d 3d 30  y || isCommit==0
1de10 29 20 29 7b 0a 20 20 20 20 20 20 75 33 32 20 69  ) ){.      u32 i
1de20 57 72 69 74 65 20 3d 20 30 3b 0a 20 20 20 20 20  Write = 0;.     
1de30 20 56 56 41 5f 4f 4e 4c 59 28 72 63 20 3d 29 20   VVA_ONLY(rc =) 
1de40 73 71 6c 69 74 65 33 57 61 6c 46 69 6e 64 46 72  sqlite3WalFindFr
1de50 61 6d 65 28 70 57 61 6c 2c 20 70 2d 3e 70 67 6e  ame(pWal, p->pgn
1de60 6f 2c 20 26 69 57 72 69 74 65 29 3b 0a 20 20 20  o, &iWrite);.   
1de70 20 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53     assert( rc==S
1de80 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 69 57 72 69  QLITE_OK || iWri
1de90 74 65 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 69  te==0 );.      i
1dea0 66 28 20 69 57 72 69 74 65 3e 3d 69 46 69 72 73  f( iWrite>=iFirs
1deb0 74 20 29 7b 0a 20 20 20 20 20 20 20 20 69 36 34  t ){.        i64
1dec0 20 69 4f 66 66 20 3d 20 77 61 6c 46 72 61 6d 65   iOff = walFrame
1ded0 4f 66 66 73 65 74 28 69 57 72 69 74 65 2c 20 73  Offset(iWrite, s
1dee0 7a 50 61 67 65 29 20 2b 20 57 41 4c 5f 46 52 41  zPage) + WAL_FRA
1def0 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20 20 20 20  ME_HDRSIZE;.    
1df00 20 20 20 20 76 6f 69 64 20 2a 70 44 61 74 61 3b      void *pData;
1df10 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 57 61  .        if( pWa
1df20 6c 2d 3e 69 52 65 43 6b 73 75 6d 3d 3d 30 20 7c  l->iReCksum==0 |
1df30 7c 20 69 57 72 69 74 65 3c 70 57 61 6c 2d 3e 69  | iWrite<pWal->i
1df40 52 65 43 6b 73 75 6d 20 29 7b 0a 20 20 20 20 20  ReCksum ){.     
1df50 20 20 20 20 20 70 57 61 6c 2d 3e 69 52 65 43 6b       pWal->iReCk
1df60 73 75 6d 20 3d 20 69 57 72 69 74 65 3b 0a 20 20  sum = iWrite;.  
1df70 20 20 20 20 20 20 7d 0a 23 69 66 20 64 65 66 69        }.#if defi
1df80 6e 65 64 28 53 51 4c 49 54 45 5f 48 41 53 5f 43  ned(SQLITE_HAS_C
1df90 4f 44 45 43 29 0a 20 20 20 20 20 20 20 20 69 66  ODEC).        if
1dfa0 28 20 28 70 44 61 74 61 20 3d 20 73 71 6c 69 74  ( (pData = sqlit
1dfb0 65 33 50 61 67 65 72 43 6f 64 65 63 28 70 29 29  e3PagerCodec(p))
1dfc0 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
1dfd0 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 23 65 6c 73 65  ITE_NOMEM;.#else
1dfe0 0a 20 20 20 20 20 20 20 20 70 44 61 74 61 20 3d  .        pData =
1dff0 20 70 2d 3e 70 44 61 74 61 3b 0a 23 65 6e 64 69   p->pData;.#endi
1e000 66 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73  f.        rc = s
1e010 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 57  qlite3OsWrite(pW
1e020 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 70 44 61 74  al->pWalFd, pDat
1e030 61 2c 20 73 7a 50 61 67 65 2c 20 69 4f 66 66 29  a, szPage, iOff)
1e040 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
1e050 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
1e060 20 20 20 20 20 20 70 2d 3e 66 6c 61 67 73 20 26        p->flags &
1e070 3d 20 7e 50 47 48 44 52 5f 57 41 4c 5f 41 50 50  = ~PGHDR_WAL_APP
1e080 45 4e 44 3b 0a 20 20 20 20 20 20 20 20 63 6f 6e  END;.        con
1e090 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 7d 0a 20  tinue;.      }. 
1e0a0 20 20 20 7d 0a 0a 20 20 20 20 69 46 72 61 6d 65     }..    iFrame
1e0b0 2b 2b 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  ++;.    assert( 
1e0c0 69 4f 66 66 73 65 74 3d 3d 77 61 6c 46 72 61 6d  iOffset==walFram
1e0d0 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2c 20  eOffset(iFrame, 
1e0e0 73 7a 50 61 67 65 29 20 29 3b 0a 20 20 20 20 6e  szPage) );.    n
1e0f0 44 62 53 69 7a 65 20 3d 20 28 69 73 43 6f 6d 6d  DbSize = (isComm
1e100 69 74 20 26 26 20 70 2d 3e 70 44 69 72 74 79 3d  it && p->pDirty=
1e110 3d 30 29 20 3f 20 6e 54 72 75 6e 63 61 74 65 20  =0) ? nTruncate 
1e120 3a 20 30 3b 0a 20 20 20 20 72 63 20 3d 20 77 61  : 0;.    rc = wa
1e130 6c 57 72 69 74 65 4f 6e 65 46 72 61 6d 65 28 26  lWriteOneFrame(&
1e140 77 2c 20 70 2c 20 6e 44 62 53 69 7a 65 2c 20 69  w, p, nDbSize, i
1e150 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 69 66 28  Offset);.    if(
1e160 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b   rc ) return rc;
1e170 0a 20 20 20 20 70 4c 61 73 74 20 3d 20 70 3b 0a  .    pLast = p;.
1e180 20 20 20 20 69 4f 66 66 73 65 74 20 2b 3d 20 73      iOffset += s
1e190 7a 46 72 61 6d 65 3b 0a 20 20 20 20 70 2d 3e 66  zFrame;.    p->f
1e1a0 6c 61 67 73 20 7c 3d 20 50 47 48 44 52 5f 57 41  lags |= PGHDR_WA
1e1b0 4c 5f 41 50 50 45 4e 44 3b 0a 20 20 7d 0a 0a 20  L_APPEND;.  }.. 
1e1c0 20 2f 2a 20 52 65 63 61 6c 63 75 6c 61 74 65 20   /* Recalculate 
1e1d0 63 68 65 63 6b 73 75 6d 73 20 77 69 74 68 69 6e  checksums within
1e1e0 20 74 68 65 20 77 61 6c 20 66 69 6c 65 20 69 66   the wal file if
1e1f0 20 72 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20   required. */.  
1e200 69 66 28 20 69 73 43 6f 6d 6d 69 74 20 26 26 20  if( isCommit && 
1e210 70 57 61 6c 2d 3e 69 52 65 43 6b 73 75 6d 20 29  pWal->iReCksum )
1e220 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 52 65  {.    rc = walRe
1e230 77 72 69 74 65 43 68 65 63 6b 73 75 6d 73 28 70  writeChecksums(p
1e240 57 61 6c 2c 20 69 46 72 61 6d 65 29 3b 0a 20 20  Wal, iFrame);.  
1e250 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72    if( rc ) retur
1e260 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  n rc;.  }..  /* 
1e270 49 66 20 74 68 69 73 20 69 73 20 74 68 65 20 65  If this is the e
1e280 6e 64 20 6f 66 20 61 20 74 72 61 6e 73 61 63 74  nd of a transact
1e290 69 6f 6e 2c 20 74 68 65 6e 20 77 65 20 6d 69 67  ion, then we mig
1e2a0 68 74 20 6e 65 65 64 20 74 6f 20 70 61 64 0a 20  ht need to pad. 
1e2b0 20 2a 2a 20 74 68 65 20 74 72 61 6e 73 61 63 74   ** the transact
1e2c0 69 6f 6e 20 61 6e 64 2f 6f 72 20 73 79 6e 63 20  ion and/or sync 
1e2d0 74 68 65 20 57 41 4c 20 66 69 6c 65 2e 0a 20 20  the WAL file..  
1e2e0 2a 2a 0a 20 20 2a 2a 20 50 61 64 64 69 6e 67 20  **.  ** Padding 
1e2f0 61 6e 64 20 73 79 6e 63 69 6e 67 20 6f 6e 6c 79  and syncing only
1e300 20 6f 63 63 75 72 20 69 66 20 74 68 69 73 20 73   occur if this s
1e310 65 74 20 6f 66 20 66 72 61 6d 65 73 20 63 6f 6d  et of frames com
1e320 70 6c 65 74 65 20 61 0a 20 20 2a 2a 20 74 72 61  plete a.  ** tra
1e330 6e 73 61 63 74 69 6f 6e 20 61 6e 64 20 69 66 20  nsaction and if 
1e340 50 52 41 47 4d 41 20 73 79 6e 63 68 72 6f 6e 6f  PRAGMA synchrono
1e350 75 73 3d 46 55 4c 4c 2e 20 20 49 66 20 73 79 6e  us=FULL.  If syn
1e360 63 68 72 6f 6e 6f 75 73 3d 3d 4e 4f 52 4d 41 4c  chronous==NORMAL
1e370 0a 20 20 2a 2a 20 6f 72 20 73 79 6e 63 68 72 6f  .  ** or synchro
1e380 6e 6f 75 73 3d 3d 4f 46 46 2c 20 74 68 65 6e 20  nous==OFF, then 
1e390 6e 6f 20 70 61 64 64 69 6e 67 20 6f 72 20 73 79  no padding or sy
1e3a0 6e 63 69 6e 67 20 61 72 65 20 6e 65 65 64 65 64  ncing are needed
1e3b0 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 49 66 20 53  ..  **.  ** If S
1e3c0 51 4c 49 54 45 5f 49 4f 43 41 50 5f 50 4f 57 45  QLITE_IOCAP_POWE
1e3d0 52 53 41 46 45 5f 4f 56 45 52 57 52 49 54 45 20  RSAFE_OVERWRITE 
1e3e0 69 73 20 64 65 66 69 6e 65 64 2c 20 74 68 65 6e  is defined, then
1e3f0 20 70 61 64 64 69 6e 67 20 69 73 20 6e 6f 74 0a   padding is not.
1e400 20 20 2a 2a 20 6e 65 65 64 65 64 20 61 6e 64 20    ** needed and 
1e410 6f 6e 6c 79 20 74 68 65 20 73 79 6e 63 20 69 73  only the sync is
1e420 20 64 6f 6e 65 2e 20 20 49 66 20 70 61 64 64 69   done.  If paddi
1e430 6e 67 20 69 73 20 6e 65 65 64 65 64 2c 20 74 68  ng is needed, th
1e440 65 6e 20 74 68 65 0a 20 20 2a 2a 20 66 69 6e 61  en the.  ** fina
1e450 6c 20 66 72 61 6d 65 20 69 73 20 72 65 70 65 61  l frame is repea
1e460 74 65 64 20 28 77 69 74 68 20 69 74 73 20 63 6f  ted (with its co
1e470 6d 6d 69 74 20 6d 61 72 6b 29 20 75 6e 74 69 6c  mmit mark) until
1e480 20 74 68 65 20 6e 65 78 74 20 73 65 63 74 6f 72   the next sector
1e490 0a 20 20 2a 2a 20 62 6f 75 6e 64 61 72 79 20 69  .  ** boundary i
1e4a0 73 20 63 72 6f 73 73 65 64 2e 20 20 4f 6e 6c 79  s crossed.  Only
1e4b0 20 74 68 65 20 70 61 72 74 20 6f 66 20 74 68 65   the part of the
1e4c0 20 57 41 4c 20 70 72 69 6f 72 20 74 6f 20 74 68   WAL prior to th
1e4d0 65 20 6c 61 73 74 0a 20 20 2a 2a 20 73 65 63 74  e last.  ** sect
1e4e0 6f 72 20 62 6f 75 6e 64 61 72 79 20 69 73 20 73  or boundary is s
1e4f0 79 6e 63 65 64 3b 20 74 68 65 20 70 61 72 74 20  ynced; the part 
1e500 6f 66 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d  of the last fram
1e510 65 20 74 68 61 74 20 65 78 74 65 6e 64 73 0a 20  e that extends. 
1e520 20 2a 2a 20 70 61 73 74 20 74 68 65 20 73 65 63   ** past the sec
1e530 74 6f 72 20 62 6f 75 6e 64 61 72 79 20 69 73 20  tor boundary is 
1e540 77 72 69 74 74 65 6e 20 61 66 74 65 72 20 74 68  written after th
1e550 65 20 73 79 6e 63 2e 0a 20 20 2a 2f 0a 20 20 69  e sync..  */.  i
1e560 66 28 20 69 73 43 6f 6d 6d 69 74 20 26 26 20 57  f( isCommit && W
1e570 41 4c 5f 53 59 4e 43 5f 46 4c 41 47 53 28 73 79  AL_SYNC_FLAGS(sy
1e580 6e 63 5f 66 6c 61 67 73 29 21 3d 30 20 29 7b 0a  nc_flags)!=0 ){.
1e590 20 20 20 20 69 6e 74 20 62 53 79 6e 63 20 3d 20      int bSync = 
1e5a0 31 3b 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d  1;.    if( pWal-
1e5b0 3e 70 61 64 54 6f 53 65 63 74 6f 72 42 6f 75 6e  >padToSectorBoun
1e5c0 64 61 72 79 20 29 7b 0a 20 20 20 20 20 20 69 6e  dary ){.      in
1e5d0 74 20 73 65 63 74 6f 72 53 69 7a 65 20 3d 20 73  t sectorSize = s
1e5e0 71 6c 69 74 65 33 53 65 63 74 6f 72 53 69 7a 65  qlite3SectorSize
1e5f0 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 29 3b 0a  (pWal->pWalFd);.
1e600 20 20 20 20 20 20 77 2e 69 53 79 6e 63 50 6f 69        w.iSyncPoi
1e610 6e 74 20 3d 20 28 28 69 4f 66 66 73 65 74 2b 73  nt = ((iOffset+s
1e620 65 63 74 6f 72 53 69 7a 65 2d 31 29 2f 73 65 63  ectorSize-1)/sec
1e630 74 6f 72 53 69 7a 65 29 2a 73 65 63 74 6f 72 53  torSize)*sectorS
1e640 69 7a 65 3b 0a 20 20 20 20 20 20 62 53 79 6e 63  ize;.      bSync
1e650 20 3d 20 28 77 2e 69 53 79 6e 63 50 6f 69 6e 74   = (w.iSyncPoint
1e660 3d 3d 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20  ==iOffset);.    
1e670 20 20 74 65 73 74 63 61 73 65 28 20 62 53 79 6e    testcase( bSyn
1e680 63 20 29 3b 0a 20 20 20 20 20 20 77 68 69 6c 65  c );.      while
1e690 28 20 69 4f 66 66 73 65 74 3c 77 2e 69 53 79 6e  ( iOffset<w.iSyn
1e6a0 63 50 6f 69 6e 74 20 29 7b 0a 20 20 20 20 20 20  cPoint ){.      
1e6b0 20 20 72 63 20 3d 20 77 61 6c 57 72 69 74 65 4f    rc = walWriteO
1e6c0 6e 65 46 72 61 6d 65 28 26 77 2c 20 70 4c 61 73  neFrame(&w, pLas
1e6d0 74 2c 20 6e 54 72 75 6e 63 61 74 65 2c 20 69 4f  t, nTruncate, iO
1e6e0 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 20 20  ffset);.        
1e6f0 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e 20  if( rc ) return 
1e700 72 63 3b 0a 20 20 20 20 20 20 20 20 69 4f 66 66  rc;.        iOff
1e710 73 65 74 20 2b 3d 20 73 7a 46 72 61 6d 65 3b 0a  set += szFrame;.
1e720 20 20 20 20 20 20 20 20 6e 45 78 74 72 61 2b 2b          nExtra++
1e730 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
1e740 20 20 20 20 69 66 28 20 62 53 79 6e 63 20 29 7b      if( bSync ){
1e750 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 72  .      assert( r
1e760 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c==SQLITE_OK );.
1e770 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
1e780 65 33 4f 73 53 79 6e 63 28 77 2e 70 46 64 2c 20  e3OsSync(w.pFd, 
1e790 57 41 4c 5f 53 59 4e 43 5f 46 4c 41 47 53 28 73  WAL_SYNC_FLAGS(s
1e7a0 79 6e 63 5f 66 6c 61 67 73 29 29 3b 0a 20 20 20  ync_flags));.   
1e7b0 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20   }.  }..  /* If 
1e7c0 74 68 69 73 20 66 72 61 6d 65 20 73 65 74 20 63  this frame set c
1e7d0 6f 6d 70 6c 65 74 65 73 20 74 68 65 20 66 69 72  ompletes the fir
1e7e0 73 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69  st transaction i
1e7f0 6e 20 74 68 65 20 57 41 4c 20 61 6e 64 0a 20 20  n the WAL and.  
1e800 2a 2a 20 69 66 20 50 52 41 47 4d 41 20 6a 6f 75  ** if PRAGMA jou
1e810 72 6e 61 6c 5f 73 69 7a 65 5f 6c 69 6d 69 74 20  rnal_size_limit 
1e820 69 73 20 73 65 74 2c 20 74 68 65 6e 20 74 72 75  is set, then tru
1e830 6e 63 61 74 65 20 74 68 65 20 57 41 4c 20 74 6f  ncate the WAL to
1e840 20 74 68 65 0a 20 20 2a 2a 20 6a 6f 75 72 6e 61   the.  ** journa
1e850 6c 20 73 69 7a 65 20 6c 69 6d 69 74 2c 20 69 66  l size limit, if
1e860 20 70 6f 73 73 69 62 6c 65 2e 0a 20 20 2a 2f 0a   possible..  */.
1e870 20 20 69 66 28 20 69 73 43 6f 6d 6d 69 74 20 26    if( isCommit &
1e880 26 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61 74 65  & pWal->truncate
1e890 4f 6e 43 6f 6d 6d 69 74 20 26 26 20 70 57 61 6c  OnCommit && pWal
1e8a0 2d 3e 6d 78 57 61 6c 53 69 7a 65 3e 3d 30 20 29  ->mxWalSize>=0 )
1e8b0 7b 0a 20 20 20 20 69 36 34 20 73 7a 20 3d 20 70  {.    i64 sz = p
1e8c0 57 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 3b 0a  Wal->mxWalSize;.
1e8d0 20 20 20 20 69 66 28 20 77 61 6c 46 72 61 6d 65      if( walFrame
1e8e0 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2b 6e 45  Offset(iFrame+nE
1e8f0 78 74 72 61 2b 31 2c 20 73 7a 50 61 67 65 29 3e  xtra+1, szPage)>
1e900 70 57 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 20  pWal->mxWalSize 
1e910 29 7b 0a 20 20 20 20 20 20 73 7a 20 3d 20 77 61  ){.      sz = wa
1e920 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46 72  lFrameOffset(iFr
1e930 61 6d 65 2b 6e 45 78 74 72 61 2b 31 2c 20 73 7a  ame+nExtra+1, sz
1e940 50 61 67 65 29 3b 0a 20 20 20 20 7d 0a 20 20 20  Page);.    }.   
1e950 20 77 61 6c 4c 69 6d 69 74 53 69 7a 65 28 70 57   walLimitSize(pW
1e960 61 6c 2c 20 73 7a 29 3b 0a 20 20 20 20 70 57 61  al, sz);.    pWa
1e970 6c 2d 3e 74 72 75 6e 63 61 74 65 4f 6e 43 6f 6d  l->truncateOnCom
1e980 6d 69 74 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20  mit = 0;.  }..  
1e990 2f 2a 20 41 70 70 65 6e 64 20 64 61 74 61 20 74  /* Append data t
1e9a0 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e  o the wal-index.
1e9b0 20 49 74 20 69 73 20 6e 6f 74 20 6e 65 63 65 73   It is not neces
1e9c0 73 61 72 79 20 74 6f 20 6c 6f 63 6b 20 74 68 65  sary to lock the
1e9d0 20 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78   .  ** wal-index
1e9e0 20 74 6f 20 64 6f 20 74 68 69 73 20 61 73 20 74   to do this as t
1e9f0 68 65 20 53 51 4c 49 54 45 5f 53 48 4d 5f 57 52  he SQLITE_SHM_WR
1ea00 49 54 45 20 6c 6f 63 6b 20 68 65 6c 64 20 6f 6e  ITE lock held on
1ea10 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 20   the wal-index. 
1ea20 20 2a 2a 20 67 75 61 72 61 6e 74 65 65 73 20 74   ** guarantees t
1ea30 68 61 74 20 74 68 65 72 65 20 61 72 65 20 6e 6f  hat there are no
1ea40 20 6f 74 68 65 72 20 77 72 69 74 65 72 73 2c 20   other writers, 
1ea50 61 6e 64 20 6e 6f 20 64 61 74 61 20 74 68 61 74  and no data that
1ea60 20 6d 61 79 0a 20 20 2a 2a 20 62 65 20 69 6e 20   may.  ** be in 
1ea70 75 73 65 20 62 79 20 65 78 69 73 74 69 6e 67 20  use by existing 
1ea80 72 65 61 64 65 72 73 20 69 73 20 62 65 69 6e 67  readers is being
1ea90 20 6f 76 65 72 77 72 69 74 74 65 6e 2e 0a 20 20   overwritten..  
1eaa0 2a 2f 0a 20 20 69 46 72 61 6d 65 20 3d 20 70 57  */.  iFrame = pW
1eab0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b  al->hdr.mxFrame;
1eac0 0a 20 20 66 6f 72 28 70 3d 70 4c 69 73 74 3b 20  .  for(p=pList; 
1ead0 70 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f  p && rc==SQLITE_
1eae0 4f 4b 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 29  OK; p=p->pDirty)
1eaf0 7b 0a 20 20 20 20 69 66 28 20 28 70 2d 3e 66 6c  {.    if( (p->fl
1eb00 61 67 73 20 26 20 50 47 48 44 52 5f 57 41 4c 5f  ags & PGHDR_WAL_
1eb10 41 50 50 45 4e 44 29 3d 3d 30 20 29 20 63 6f 6e  APPEND)==0 ) con
1eb20 74 69 6e 75 65 3b 0a 20 20 20 20 69 46 72 61 6d  tinue;.    iFram
1eb30 65 2b 2b 3b 0a 20 20 20 20 72 63 20 3d 20 77 61  e++;.    rc = wa
1eb40 6c 49 6e 64 65 78 41 70 70 65 6e 64 28 70 57 61  lIndexAppend(pWa
1eb50 6c 2c 20 69 46 72 61 6d 65 2c 20 70 2d 3e 70 67  l, iFrame, p->pg
1eb60 6e 6f 29 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65  no);.  }.  while
1eb70 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1eb80 26 26 20 6e 45 78 74 72 61 3e 30 20 29 7b 0a 20  && nExtra>0 ){. 
1eb90 20 20 20 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20     iFrame++;.   
1eba0 20 6e 45 78 74 72 61 2d 2d 3b 0a 20 20 20 20 72   nExtra--;.    r
1ebb0 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65  c = walIndexAppe
1ebc0 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c  nd(pWal, iFrame,
1ebd0 20 70 4c 61 73 74 2d 3e 70 67 6e 6f 29 3b 0a 20   pLast->pgno);. 
1ebe0 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
1ebf0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2f  LITE_OK ){.    /
1ec00 2a 20 55 70 64 61 74 65 20 74 68 65 20 70 72 69  * Update the pri
1ec10 76 61 74 65 20 63 6f 70 79 20 6f 66 20 74 68 65  vate copy of the
1ec20 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20 20 20 20   header. */.    
1ec30 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65  pWal->hdr.szPage
1ec40 20 3d 20 28 75 31 36 29 28 28 73 7a 50 61 67 65   = (u16)((szPage
1ec50 26 30 78 66 66 30 30 29 20 7c 20 28 73 7a 50 61  &0xff00) | (szPa
1ec60 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20 20 74 65  ge>>16));.    te
1ec70 73 74 63 61 73 65 28 20 73 7a 50 61 67 65 3c 3d  stcase( szPage<=
1ec80 33 32 37 36 38 20 29 3b 0a 20 20 20 20 74 65 73  32768 );.    tes
1ec90 74 63 61 73 65 28 20 73 7a 50 61 67 65 3e 3d 36  tcase( szPage>=6
1eca0 35 35 33 36 20 29 3b 0a 20 20 20 20 70 57 61 6c  5536 );.    pWal
1ecb0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20  ->hdr.mxFrame = 
1ecc0 69 46 72 61 6d 65 3b 0a 20 20 20 20 69 66 28 20  iFrame;.    if( 
1ecd0 69 73 43 6f 6d 6d 69 74 20 29 7b 0a 20 20 20 20  isCommit ){.    
1ece0 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69 43 68 61    pWal->hdr.iCha
1ecf0 6e 67 65 2b 2b 3b 0a 20 20 20 20 20 20 70 57 61  nge++;.      pWa
1ed00 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20 3d 20 6e  l->hdr.nPage = n
1ed10 54 72 75 6e 63 61 74 65 3b 0a 20 20 20 20 7d 0a  Truncate;.    }.
1ed20 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69      /* If this i
1ed30 73 20 61 20 63 6f 6d 6d 69 74 2c 20 75 70 64 61  s a commit, upda
1ed40 74 65 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  te the wal-index
1ed50 20 68 65 61 64 65 72 20 74 6f 6f 2e 20 2a 2f 0a   header too. */.
1ed60 20 20 20 20 69 66 28 20 69 73 43 6f 6d 6d 69 74      if( isCommit
1ed70 20 29 7b 0a 20 20 20 20 20 20 77 61 6c 49 6e 64   ){.      walInd
1ed80 65 78 57 72 69 74 65 48 64 72 28 70 57 61 6c 29  exWriteHdr(pWal)
1ed90 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 69 43  ;.      pWal->iC
1eda0 61 6c 6c 62 61 63 6b 20 3d 20 69 46 72 61 6d 65  allback = iFrame
1edb0 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 57  ;.    }.  }..  W
1edc0 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
1edd0 20 66 72 61 6d 65 20 77 72 69 74 65 20 25 73 5c   frame write %s\
1ede0 6e 22 2c 20 70 57 61 6c 2c 20 72 63 20 3f 20 22  n", pWal, rc ? "
1edf0 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29  failed" : "ok"))
1ee00 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
1ee10 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 72 6f  ../* .** This ro
1ee20 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65 64 20  utine is called 
1ee30 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 73 71 6c  to implement sql
1ee40 69 74 65 33 5f 77 61 6c 5f 63 68 65 63 6b 70 6f  ite3_wal_checkpo
1ee50 69 6e 74 28 29 20 61 6e 64 0a 2a 2a 20 72 65 6c  int() and.** rel
1ee60 61 74 65 64 20 69 6e 74 65 72 66 61 63 65 73 2e  ated interfaces.
1ee70 0a 2a 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20 61 20  .**.** Obtain a 
1ee80 43 48 45 43 4b 50 4f 49 4e 54 20 6c 6f 63 6b 20  CHECKPOINT lock 
1ee90 61 6e 64 20 74 68 65 6e 20 62 61 63 6b 66 69 6c  and then backfil
1eea0 6c 20 61 73 20 6d 75 63 68 20 69 6e 66 6f 72 6d  l as much inform
1eeb0 61 74 69 6f 6e 20 61 73 0a 2a 2a 20 77 65 20 63  ation as.** we c
1eec0 61 6e 20 66 72 6f 6d 20 57 41 4c 20 69 6e 74 6f  an from WAL into
1eed0 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a   the database..*
1eee0 2a 0a 2a 2a 20 49 66 20 70 61 72 61 6d 65 74 65  *.** If paramete
1eef0 72 20 78 42 75 73 79 20 69 73 20 6e 6f 74 20 4e  r xBusy is not N
1ef00 55 4c 4c 2c 20 69 74 20 69 73 20 61 20 70 6f 69  ULL, it is a poi
1ef10 6e 74 65 72 20 74 6f 20 61 20 62 75 73 79 2d 68  nter to a busy-h
1ef20 61 6e 64 6c 65 72 0a 2a 2a 20 63 61 6c 6c 62 61  andler.** callba
1ef30 63 6b 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65  ck. In this case
1ef40 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72   this function r
1ef50 75 6e 73 20 61 20 62 6c 6f 63 6b 69 6e 67 20 63  uns a blocking c
1ef60 68 65 63 6b 70 6f 69 6e 74 2e 0a 2a 2f 0a 69 6e  heckpoint..*/.in
1ef70 74 20 73 71 6c 69 74 65 33 57 61 6c 43 68 65 63  t sqlite3WalChec
1ef80 6b 70 6f 69 6e 74 28 0a 20 20 57 61 6c 20 2a 70  kpoint(.  Wal *p
1ef90 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Wal,            
1efa0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c            /* Wal
1efb0 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20   connection */. 
1efc0 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
1efd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1efe0 20 2f 2a 20 43 68 65 63 6b 20 74 68 69 73 20 68   /* Check this h
1eff0 61 6e 64 6c 65 27 73 20 69 6e 74 65 72 72 75 70  andle's interrup
1f000 74 20 66 6c 61 67 20 2a 2f 0a 20 20 69 6e 74 20  t flag */.  int 
1f010 65 4d 6f 64 65 2c 20 20 20 20 20 20 20 20 20 20  eMode,          
1f020 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
1f030 41 53 53 49 56 45 2c 20 46 55 4c 4c 2c 20 52 45  ASSIVE, FULL, RE
1f040 53 54 41 52 54 2c 20 6f 72 20 54 52 55 4e 43 41  START, or TRUNCA
1f050 54 45 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 42  TE */.  int (*xB
1f060 75 73 79 29 28 76 6f 69 64 2a 29 2c 20 20 20 20  usy)(void*),    
1f070 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74          /* Funct
1f080 69 6f 6e 20 74 6f 20 63 61 6c 6c 20 77 68 65 6e  ion to call when
1f090 20 62 75 73 79 20 2a 2f 0a 20 20 76 6f 69 64 20   busy */.  void 
1f0a0 2a 70 42 75 73 79 41 72 67 2c 20 20 20 20 20 20  *pBusyArg,      
1f0b0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
1f0c0 6e 74 65 78 74 20 61 72 67 75 6d 65 6e 74 20 66  ntext argument f
1f0d0 6f 72 20 78 42 75 73 79 48 61 6e 64 6c 65 72 20  or xBusyHandler 
1f0e0 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c  */.  int sync_fl
1f0f0 61 67 73 2c 20 20 20 20 20 20 20 20 20 20 20 20  ags,            
1f100 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f       /* Flags to
1f110 20 73 79 6e 63 20 64 62 20 66 69 6c 65 20 77 69   sync db file wi
1f120 74 68 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20 69  th (or 0) */.  i
1f130 6e 74 20 6e 42 75 66 2c 20 20 20 20 20 20 20 20  nt nBuf,        
1f140 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1f150 2a 20 53 69 7a 65 20 6f 66 20 74 65 6d 70 6f 72  * Size of tempor
1f160 61 72 79 20 62 75 66 66 65 72 20 2a 2f 0a 20 20  ary buffer */.  
1f170 75 38 20 2a 7a 42 75 66 2c 20 20 20 20 20 20 20  u8 *zBuf,       
1f180 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f190 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62 75 66  /* Temporary buf
1f1a0 66 65 72 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20  fer to use */.  
1f1b0 69 6e 74 20 2a 70 6e 4c 6f 67 2c 20 20 20 20 20  int *pnLog,     
1f1c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f1d0 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f  /* OUT: Number o
1f1e0 66 20 66 72 61 6d 65 73 20 69 6e 20 57 41 4c 20  f frames in WAL 
1f1f0 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 43 6b 70 74  */.  int *pnCkpt
1f200 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f210 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d       /* OUT: Num
1f220 62 65 72 20 6f 66 20 62 61 63 6b 66 69 6c 6c 65  ber of backfille
1f230 64 20 66 72 61 6d 65 73 20 69 6e 20 57 41 4c 20  d frames in WAL 
1f240 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  */.){.  int rc; 
1f250 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f260 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
1f270 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
1f280 69 73 43 68 61 6e 67 65 64 20 3d 20 30 3b 20 20  isChanged = 0;  
1f290 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1f2a0 72 75 65 20 69 66 20 61 20 6e 65 77 20 77 61 6c  rue if a new wal
1f2b0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73  -index header is
1f2c0 20 6c 6f 61 64 65 64 20 2a 2f 0a 20 20 69 6e 74   loaded */.  int
1f2d0 20 65 4d 6f 64 65 32 20 3d 20 65 4d 6f 64 65 3b   eMode2 = eMode;
1f2e0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1f2f0 4d 6f 64 65 20 74 6f 20 70 61 73 73 20 74 6f 20  Mode to pass to 
1f300 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 29 20  walCheckpoint() 
1f310 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 42 75 73 79  */.  int (*xBusy
1f320 32 29 28 76 6f 69 64 2a 29 20 3d 20 78 42 75 73  2)(void*) = xBus
1f330 79 3b 20 20 20 2f 2a 20 42 75 73 79 20 68 61 6e  y;   /* Busy han
1f340 64 6c 65 72 20 66 6f 72 20 65 4d 6f 64 65 32 20  dler for eMode2 
1f350 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57  */..  assert( pW
1f360 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 30 20  al->ckptLock==0 
1f370 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  );.  assert( pWa
1f380 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20  l->writeLock==0 
1f390 29 3b 0a 0a 20 20 2f 2a 20 45 56 49 44 45 4e 43  );..  /* EVIDENC
1f3a0 45 2d 4f 46 3a 20 52 2d 36 32 39 32 30 2d 34 37  E-OF: R-62920-47
1f3b0 34 35 30 20 54 68 65 20 62 75 73 79 2d 68 61 6e  450 The busy-han
1f3c0 64 6c 65 72 20 63 61 6c 6c 62 61 63 6b 20 69 73  dler callback is
1f3d0 20 6e 65 76 65 72 20 69 6e 76 6f 6b 65 64 0a 20   never invoked. 
1f3e0 20 2a 2a 20 69 6e 20 74 68 65 20 53 51 4c 49 54   ** in the SQLIT
1f3f0 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53  E_CHECKPOINT_PAS
1f400 53 49 56 45 20 6d 6f 64 65 2e 20 2a 2f 0a 20 20  SIVE mode. */.  
1f410 61 73 73 65 72 74 28 20 65 4d 6f 64 65 21 3d 53  assert( eMode!=S
1f420 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54  QLITE_CHECKPOINT
1f430 5f 50 41 53 53 49 56 45 20 7c 7c 20 78 42 75 73  _PASSIVE || xBus
1f440 79 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 70  y==0 );..  if( p
1f450 57 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 29 20  Wal->readOnly ) 
1f460 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 52 45  return SQLITE_RE
1f470 41 44 4f 4e 4c 59 3b 0a 20 20 57 41 4c 54 52 41  ADONLY;.  WALTRA
1f480 43 45 28 28 22 57 41 4c 25 70 3a 20 63 68 65 63  CE(("WAL%p: chec
1f490 6b 70 6f 69 6e 74 20 62 65 67 69 6e 73 5c 6e 22  kpoint begins\n"
1f4a0 2c 20 70 57 61 6c 29 29 3b 0a 0a 20 20 2f 2a 20  , pWal));..  /* 
1f4b0 49 4d 50 4c 45 4d 45 4e 54 41 54 49 4f 4e 2d 4f  IMPLEMENTATION-O
1f4c0 46 3a 20 52 2d 36 32 30 32 38 2d 34 37 32 31 32  F: R-62028-47212
1f4d0 20 41 6c 6c 20 63 61 6c 6c 73 20 6f 62 74 61 69   All calls obtai
1f4e0 6e 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 0a  n an exclusive .
1f4f0 20 20 2a 2a 20 22 63 68 65 63 6b 70 6f 69 6e 74    ** "checkpoint
1f500 22 20 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 64 61  " lock on the da
1f510 74 61 62 61 73 65 20 66 69 6c 65 2e 20 2a 2f 0a  tabase file. */.
1f520 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78    rc = walLockEx
1f530 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
1f540 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b  L_CKPT_LOCK, 1);
1f550 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20  .  if( rc ){.   
1f560 20 2f 2a 20 45 56 49 44 45 4e 43 45 2d 4f 46 3a   /* EVIDENCE-OF:
1f570 20 52 2d 31 30 34 32 31 2d 31 39 37 33 36 20 49   R-10421-19736 I
1f580 66 20 61 6e 79 20 6f 74 68 65 72 20 70 72 6f 63  f any other proc
1f590 65 73 73 20 69 73 20 72 75 6e 6e 69 6e 67 20 61  ess is running a
1f5a0 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69  .    ** checkpoi
1f5b0 6e 74 20 6f 70 65 72 61 74 69 6f 6e 20 61 74 20  nt operation at 
1f5c0 74 68 65 20 73 61 6d 65 20 74 69 6d 65 2c 20 74  the same time, t
1f5d0 68 65 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62  he lock cannot b
1f5e0 65 20 6f 62 74 61 69 6e 65 64 20 61 6e 64 0a 20  e obtained and. 
1f5f0 20 20 20 2a 2a 20 53 51 4c 49 54 45 5f 42 55 53     ** SQLITE_BUS
1f600 59 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 20  Y is returned.. 
1f610 20 20 20 2a 2a 20 45 56 49 44 45 4e 43 45 2d 4f     ** EVIDENCE-O
1f620 46 3a 20 52 2d 35 33 38 32 30 2d 33 33 38 39 37  F: R-53820-33897
1f630 20 45 76 65 6e 20 69 66 20 74 68 65 72 65 20 69   Even if there i
1f640 73 20 61 20 62 75 73 79 2d 68 61 6e 64 6c 65 72  s a busy-handler
1f650 20 63 6f 6e 66 69 67 75 72 65 64 2c 0a 20 20 20   configured,.   
1f660 20 2a 2a 20 69 74 20 77 69 6c 6c 20 6e 6f 74 20   ** it will not 
1f670 62 65 20 69 6e 76 6f 6b 65 64 20 69 6e 20 74 68  be invoked in th
1f680 69 73 20 63 61 73 65 2e 0a 20 20 20 20 2a 2f 0a  is case..    */.
1f690 20 20 20 20 74 65 73 74 63 61 73 65 28 20 72 63      testcase( rc
1f6a0 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 3b  ==SQLITE_BUSY );
1f6b0 0a 20 20 20 20 74 65 73 74 63 61 73 65 28 20 78  .    testcase( x
1f6c0 42 75 73 79 21 3d 30 20 29 3b 0a 20 20 20 20 72  Busy!=0 );.    r
1f6d0 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20  eturn rc;.  }.  
1f6e0 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20 3d  pWal->ckptLock =
1f6f0 20 31 3b 0a 0a 20 20 2f 2a 20 49 4d 50 4c 45 4d   1;..  /* IMPLEM
1f700 45 4e 54 41 54 49 4f 4e 2d 4f 46 3a 20 52 2d 35  ENTATION-OF: R-5
1f710 39 37 38 32 2d 33 36 38 31 38 20 54 68 65 20 53  9782-36818 The S
1f720 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54  QLITE_CHECKPOINT
1f730 5f 46 55 4c 4c 2c 20 52 45 53 54 41 52 54 20 61  _FULL, RESTART a
1f740 6e 64 0a 20 20 2a 2a 20 54 52 55 4e 43 41 54 45  nd.  ** TRUNCATE
1f750 20 6d 6f 64 65 73 20 61 6c 73 6f 20 6f 62 74 61   modes also obta
1f760 69 6e 20 74 68 65 20 65 78 63 6c 75 73 69 76 65  in the exclusive
1f770 20 22 77 72 69 74 65 72 22 20 6c 6f 63 6b 20 6f   "writer" lock o
1f780 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 0a 20  n the database. 
1f790 20 2a 2a 20 66 69 6c 65 2e 0a 20 20 2a 2a 0a 20   ** file..  **. 
1f7a0 20 2a 2a 20 45 56 49 44 45 4e 43 45 2d 4f 46 3a   ** EVIDENCE-OF:
1f7b0 20 52 2d 36 30 36 34 32 2d 30 34 30 38 32 20 49   R-60642-04082 I
1f7c0 66 20 74 68 65 20 77 72 69 74 65 72 20 6c 6f 63  f the writer loc
1f7d0 6b 20 63 61 6e 6e 6f 74 20 62 65 20 6f 62 74 61  k cannot be obta
1f7e0 69 6e 65 64 0a 20 20 2a 2a 20 69 6d 6d 65 64 69  ined.  ** immedi
1f7f0 61 74 65 6c 79 2c 20 61 6e 64 20 61 20 62 75 73  ately, and a bus
1f800 79 2d 68 61 6e 64 6c 65 72 20 69 73 20 63 6f 6e  y-handler is con
1f810 66 69 67 75 72 65 64 2c 20 69 74 20 69 73 20 69  figured, it is i
1f820 6e 76 6f 6b 65 64 20 61 6e 64 20 74 68 65 0a 20  nvoked and the. 
1f830 20 2a 2a 20 77 72 69 74 65 72 20 6c 6f 63 6b 20   ** writer lock 
1f840 72 65 74 72 69 65 64 20 75 6e 74 69 6c 20 65 69  retried until ei
1f850 74 68 65 72 20 74 68 65 20 62 75 73 79 2d 68 61  ther the busy-ha
1f860 6e 64 6c 65 72 20 72 65 74 75 72 6e 73 20 30 20  ndler returns 0 
1f870 6f 72 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 63 6b  or the.  ** lock
1f880 20 69 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79   is successfully
1f890 20 6f 62 74 61 69 6e 65 64 2e 0a 20 20 2a 2f 0a   obtained..  */.
1f8a0 20 20 69 66 28 20 65 4d 6f 64 65 21 3d 53 51 4c    if( eMode!=SQL
1f8b0 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50  ITE_CHECKPOINT_P
1f8c0 41 53 53 49 56 45 20 29 7b 0a 20 20 20 20 72 63  ASSIVE ){.    rc
1f8d0 20 3d 20 77 61 6c 42 75 73 79 4c 6f 63 6b 28 70   = walBusyLock(p
1f8e0 57 61 6c 2c 20 78 42 75 73 79 2c 20 70 42 75 73  Wal, xBusy, pBus
1f8f0 79 41 72 67 2c 20 57 41 4c 5f 57 52 49 54 45 5f  yArg, WAL_WRITE_
1f900 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 20 20 69 66  LOCK, 1);.    if
1f910 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1f920 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 77  ){.      pWal->w
1f930 72 69 74 65 4c 6f 63 6b 20 3d 20 31 3b 0a 20 20  riteLock = 1;.  
1f940 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d    }else if( rc==
1f950 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20  SQLITE_BUSY ){. 
1f960 20 20 20 20 20 65 4d 6f 64 65 32 20 3d 20 53 51       eMode2 = SQ
1f970 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f  LITE_CHECKPOINT_
1f980 50 41 53 53 49 56 45 3b 0a 20 20 20 20 20 20 78  PASSIVE;.      x
1f990 42 75 73 79 32 20 3d 20 30 3b 0a 20 20 20 20 20  Busy2 = 0;.     
1f9a0 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
1f9b0 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
1f9c0 20 52 65 61 64 20 74 68 65 20 77 61 6c 2d 69 6e   Read the wal-in
1f9d0 64 65 78 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20  dex header. */. 
1f9e0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
1f9f0 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 77  OK ){.    rc = w
1fa00 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28 70  alIndexReadHdr(p
1fa10 57 61 6c 2c 20 26 69 73 43 68 61 6e 67 65 64 29  Wal, &isChanged)
1fa20 3b 0a 20 20 20 20 69 66 28 20 69 73 43 68 61 6e  ;.    if( isChan
1fa30 67 65 64 20 26 26 20 70 57 61 6c 2d 3e 70 44 62  ged && pWal->pDb
1fa40 46 64 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 69 56  Fd->pMethods->iV
1fa50 65 72 73 69 6f 6e 3e 3d 33 20 29 7b 0a 20 20 20  ersion>=3 ){.   
1fa60 20 20 20 73 71 6c 69 74 65 33 4f 73 55 6e 66 65     sqlite3OsUnfe
1fa70 74 63 68 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  tch(pWal->pDbFd,
1fa80 20 30 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 20 20   0, 0);.    }.  
1fa90 7d 0a 0a 20 20 2f 2a 20 43 6f 70 79 20 64 61 74  }..  /* Copy dat
1faa0 61 20 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20 74  a from the log t
1fab0 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  o the database f
1fac0 69 6c 65 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63  ile. */.  if( rc
1fad0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 0a  ==SQLITE_OK ){..
1fae0 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64      if( pWal->hd
1faf0 72 2e 6d 78 46 72 61 6d 65 20 26 26 20 77 61 6c  r.mxFrame && wal
1fb00 50 61 67 65 73 69 7a 65 28 70 57 61 6c 29 21 3d  Pagesize(pWal)!=
1fb10 6e 42 75 66 20 29 7b 0a 20 20 20 20 20 20 72 63  nBuf ){.      rc
1fb20 20 3d 20 53 51 4c 49 54 45 5f 43 4f 52 52 55 50   = SQLITE_CORRUP
1fb30 54 5f 42 4b 50 54 3b 0a 20 20 20 20 7d 65 6c 73  T_BKPT;.    }els
1fb40 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61  e{.      rc = wa
1fb50 6c 43 68 65 63 6b 70 6f 69 6e 74 28 70 57 61 6c  lCheckpoint(pWal
1fb60 2c 20 64 62 2c 20 65 4d 6f 64 65 32 2c 20 78 42  , db, eMode2, xB
1fb70 75 73 79 32 2c 20 70 42 75 73 79 41 72 67 2c 20  usy2, pBusyArg, 
1fb80 73 79 6e 63 5f 66 6c 61 67 73 2c 20 7a 42 75 66  sync_flags, zBuf
1fb90 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
1fba0 20 49 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63   If no error occ
1fbb0 75 72 72 65 64 2c 20 73 65 74 20 74 68 65 20 6f  urred, set the o
1fbc0 75 74 70 75 74 20 76 61 72 69 61 62 6c 65 73 2e  utput variables.
1fbd0 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d   */.    if( rc==
1fbe0 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 72 63 3d  SQLITE_OK || rc=
1fbf0 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a  =SQLITE_BUSY ){.
1fc00 20 20 20 20 20 20 69 66 28 20 70 6e 4c 6f 67 20        if( pnLog 
1fc10 29 20 2a 70 6e 4c 6f 67 20 3d 20 28 69 6e 74 29  ) *pnLog = (int)
1fc20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
1fc30 65 3b 0a 20 20 20 20 20 20 69 66 28 20 70 6e 43  e;.      if( pnC
1fc40 6b 70 74 20 29 20 2a 70 6e 43 6b 70 74 20 3d 20  kpt ) *pnCkpt = 
1fc50 28 69 6e 74 29 28 77 61 6c 43 6b 70 74 49 6e 66  (int)(walCkptInf
1fc60 6f 28 70 57 61 6c 29 2d 3e 6e 42 61 63 6b 66 69  o(pWal)->nBackfi
1fc70 6c 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ll);.    }.  }..
1fc80 20 20 69 66 28 20 69 73 43 68 61 6e 67 65 64 20    if( isChanged 
1fc90 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 61 20 6e  ){.    /* If a n
1fca0 65 77 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  ew wal-index hea
1fcb0 64 65 72 20 77 61 73 20 6c 6f 61 64 65 64 20 62  der was loaded b
1fcc0 65 66 6f 72 65 20 74 68 65 20 63 68 65 63 6b 70  efore the checkp
1fcd0 6f 69 6e 74 20 77 61 73 20 0a 20 20 20 20 2a 2a  oint was .    **
1fce0 20 70 65 72 66 6f 72 6d 65 64 2c 20 74 68 65 6e   performed, then
1fcf0 20 74 68 65 20 70 61 67 65 72 2d 63 61 63 68 65   the pager-cache
1fd00 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
1fd10 20 70 57 61 6c 20 69 73 20 6e 6f 77 0a 20 20 20   pWal is now.   
1fd20 20 2a 2a 20 6f 75 74 20 6f 66 20 64 61 74 65 2e   ** out of date.
1fd30 20 53 6f 20 7a 65 72 6f 20 74 68 65 20 63 61 63   So zero the cac
1fd40 68 65 64 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  hed wal-index he
1fd50 61 64 65 72 20 74 6f 20 65 6e 73 75 72 65 20 74  ader to ensure t
1fd60 68 61 74 0a 20 20 20 20 2a 2a 20 6e 65 78 74 20  hat.    ** next 
1fd70 74 69 6d 65 20 74 68 65 20 70 61 67 65 72 20 6f  time the pager o
1fd80 70 65 6e 73 20 61 20 73 6e 61 70 73 68 6f 74 20  pens a snapshot 
1fd90 6f 6e 20 74 68 69 73 20 64 61 74 61 62 61 73 65  on this database
1fda0 20 69 74 20 6b 6e 6f 77 73 20 74 68 61 74 0a 20   it knows that. 
1fdb0 20 20 20 2a 2a 20 74 68 65 20 63 61 63 68 65 20     ** the cache 
1fdc0 6e 65 65 64 73 20 74 6f 20 62 65 20 72 65 73 65  needs to be rese
1fdd0 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d 65  t..    */.    me
1fde0 6d 73 65 74 28 26 70 57 61 6c 2d 3e 68 64 72 2c  mset(&pWal->hdr,
1fdf0 20 30 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e   0, sizeof(WalIn
1fe00 64 65 78 48 64 72 29 29 3b 0a 20 20 7d 0a 0a 20  dexHdr));.  }.. 
1fe10 20 2f 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20   /* Release the 
1fe20 6c 6f 63 6b 73 2e 20 2a 2f 0a 20 20 73 71 6c 69  locks. */.  sqli
1fe30 74 65 33 57 61 6c 45 6e 64 57 72 69 74 65 54 72  te3WalEndWriteTr
1fe40 61 6e 73 61 63 74 69 6f 6e 28 70 57 61 6c 29 3b  ansaction(pWal);
1fe50 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c  .  walUnlockExcl
1fe60 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
1fe70 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  CKPT_LOCK, 1);. 
1fe80 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20   pWal->ckptLock 
1fe90 3d 20 30 3b 0a 20 20 57 41 4c 54 52 41 43 45 28  = 0;.  WALTRACE(
1fea0 28 22 57 41 4c 25 70 3a 20 63 68 65 63 6b 70 6f  ("WAL%p: checkpo
1feb0 69 6e 74 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c  int %s\n", pWal,
1fec0 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a   rc ? "failed" :
1fed0 20 22 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75 72   "ok"));.  retur
1fee0 6e 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  n (rc==SQLITE_OK
1fef0 20 26 26 20 65 4d 6f 64 65 21 3d 65 4d 6f 64 65   && eMode!=eMode
1ff00 32 20 3f 20 53 51 4c 49 54 45 5f 42 55 53 59 20  2 ? SQLITE_BUSY 
1ff10 3a 20 72 63 29 3b 0a 7d 0a 0a 2f 2a 20 52 65 74  : rc);.}../* Ret
1ff20 75 72 6e 20 74 68 65 20 76 61 6c 75 65 20 74 6f  urn the value to
1ff30 20 70 61 73 73 20 74 6f 20 61 20 73 71 6c 69 74   pass to a sqlit
1ff40 65 33 5f 77 61 6c 5f 68 6f 6f 6b 20 63 61 6c 6c  e3_wal_hook call
1ff50 62 61 63 6b 2c 20 74 68 65 0a 2a 2a 20 6e 75 6d  back, the.** num
1ff60 62 65 72 20 6f 66 20 66 72 61 6d 65 73 20 69 6e  ber of frames in
1ff70 20 74 68 65 20 57 41 4c 20 61 74 20 74 68 65 20   the WAL at the 
1ff80 70 6f 69 6e 74 20 6f 66 20 74 68 65 20 6c 61 73  point of the las
1ff90 74 20 63 6f 6d 6d 69 74 20 73 69 6e 63 65 0a 2a  t commit since.*
1ffa0 2a 20 73 71 6c 69 74 65 33 57 61 6c 43 61 6c 6c  * sqlite3WalCall
1ffb0 62 61 63 6b 28 29 20 77 61 73 20 63 61 6c 6c 65  back() was calle
1ffc0 64 2e 20 20 49 66 20 6e 6f 20 63 6f 6d 6d 69 74  d.  If no commit
1ffd0 73 20 68 61 76 65 20 6f 63 63 75 72 72 65 64 20  s have occurred 
1ffe0 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 6c 61 73  since.** the las
1fff0 74 20 63 61 6c 6c 2c 20 74 68 65 6e 20 72 65 74  t call, then ret
20000 75 72 6e 20 30 2e 0a 2a 2f 0a 69 6e 74 20 73 71  urn 0..*/.int sq
20010 6c 69 74 65 33 57 61 6c 43 61 6c 6c 62 61 63 6b  lite3WalCallback
20020 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 75  (Wal *pWal){.  u
20030 33 32 20 72 65 74 20 3d 20 30 3b 0a 20 20 69 66  32 ret = 0;.  if
20040 28 20 70 57 61 6c 20 29 7b 0a 20 20 20 20 72 65  ( pWal ){.    re
20050 74 20 3d 20 70 57 61 6c 2d 3e 69 43 61 6c 6c 62  t = pWal->iCallb
20060 61 63 6b 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 69  ack;.    pWal->i
20070 43 61 6c 6c 62 61 63 6b 20 3d 20 30 3b 0a 20 20  Callback = 0;.  
20080 7d 0a 20 20 72 65 74 75 72 6e 20 28 69 6e 74 29  }.  return (int)
20090 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  ret;.}../*.** Th
200a0 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
200b0 61 6c 6c 65 64 20 74 6f 20 63 68 61 6e 67 65 20  alled to change 
200c0 74 68 65 20 57 41 4c 20 73 75 62 73 79 73 74 65  the WAL subsyste
200d0 6d 20 69 6e 74 6f 20 6f 72 20 6f 75 74 0a 2a 2a  m into or out.**
200e0 20 6f 66 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65   of locking_mode
200f0 3d 45 58 43 4c 55 53 49 56 45 2e 0a 2a 2a 0a 2a  =EXCLUSIVE..**.*
20100 2a 20 49 66 20 6f 70 20 69 73 20 7a 65 72 6f 2c  * If op is zero,
20110 20 74 68 65 6e 20 61 74 74 65 6d 70 74 20 74 6f   then attempt to
20120 20 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63   change from loc
20130 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53  king_mode=EXCLUS
20140 49 56 45 0a 2a 2a 20 69 6e 74 6f 20 6c 6f 63 6b  IVE.** into lock
20150 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 2e  ing_mode=NORMAL.
20160 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68 61    This means tha
20170 74 20 77 65 20 6d 75 73 74 20 61 63 71 75 69 72  t we must acquir
20180 65 20 61 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74  e a lock.** on t
20190 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  he pWal->readLoc
201a0 6b 20 62 79 74 65 2e 20 20 49 66 20 74 68 65 20  k byte.  If the 
201b0 57 41 4c 20 69 73 20 61 6c 72 65 61 64 79 20 69  WAL is already i
201c0 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e  n locking_mode=N
201d0 4f 52 4d 41 4c 0a 2a 2a 20 6f 72 20 69 66 20 74  ORMAL.** or if t
201e0 68 65 20 61 63 71 75 69 73 69 74 69 6f 6e 20 6f  he acquisition o
201f0 66 20 74 68 65 20 6c 6f 63 6b 20 66 61 69 6c 73  f the lock fails
20200 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20 30 2e  , then return 0.
20210 20 20 49 66 20 74 68 65 0a 2a 2a 20 74 72 61 6e    If the.** tran
20220 73 69 74 69 6f 6e 20 6f 75 74 20 6f 66 20 65 78  sition out of ex
20230 63 6c 75 73 69 76 65 2d 6d 6f 64 65 20 69 73 20  clusive-mode is 
20240 73 75 63 63 65 73 73 66 75 6c 2c 20 72 65 74 75  successful, retu
20250 72 6e 20 31 2e 20 20 54 68 69 73 0a 2a 2a 20 6f  rn 1.  This.** o
20260 70 65 72 61 74 69 6f 6e 20 6d 75 73 74 20 6f 63  peration must oc
20270 63 75 72 20 77 68 69 6c 65 20 74 68 65 20 70 61  cur while the pa
20280 67 65 72 20 69 73 20 73 74 69 6c 6c 20 68 6f 6c  ger is still hol
20290 64 69 6e 67 20 74 68 65 20 65 78 63 6c 75 73 69  ding the exclusi
202a0 76 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20 74 68  ve.** lock on th
202b0 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20  e main database 
202c0 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f  file..**.** If o
202d0 70 20 69 73 20 6f 6e 65 2c 20 74 68 65 6e 20 63  p is one, then c
202e0 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63 6b 69  hange from locki
202f0 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 69  ng_mode=NORMAL i
20300 6e 74 6f 20 0a 2a 2a 20 6c 6f 63 6b 69 6e 67 5f  nto .** locking_
20310 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2e 20  mode=EXCLUSIVE. 
20320 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68 61 74   This means that
20330 20 74 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c   the pWal->readL
20340 6f 63 6b 20 6d 75 73 74 0a 2a 2a 20 62 65 20 72  ock must.** be r
20350 65 6c 65 61 73 65 64 2e 20 20 52 65 74 75 72 6e  eleased.  Return
20360 20 31 20 69 66 20 74 68 65 20 74 72 61 6e 73 69   1 if the transi
20370 74 69 6f 6e 20 69 73 20 6d 61 64 65 20 61 6e 64  tion is made and
20380 20 30 20 69 66 20 74 68 65 0a 2a 2a 20 57 41 4c   0 if the.** WAL
20390 20 69 73 20 61 6c 72 65 61 64 79 20 69 6e 20 65   is already in e
203a0 78 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69 6e 67  xclusive-locking
203b0 20 6d 6f 64 65 20 2d 20 6d 65 61 6e 69 6e 67 20   mode - meaning 
203c0 74 68 61 74 20 74 68 69 73 0a 2a 2a 20 72 6f 75  that this.** rou
203d0 74 69 6e 65 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  tine is a no-op.
203e0 20 20 54 68 65 20 70 61 67 65 72 20 6d 75 73 74    The pager must
203f0 20 61 6c 72 65 61 64 79 20 68 6f 6c 64 20 74 68   already hold th
20400 65 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b  e exclusive lock
20410 0a 2a 2a 20 6f 6e 20 74 68 65 20 6d 61 69 6e 20  .** on the main 
20420 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 62 65  database file be
20430 66 6f 72 65 20 69 6e 76 6f 6b 69 6e 67 20 74 68  fore invoking th
20440 69 73 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 2a 2a  is operation..**
20450 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20 6e 65 67  .** If op is neg
20460 61 74 69 76 65 2c 20 74 68 65 6e 20 64 6f 20 61  ative, then do a
20470 20 64 72 79 2d 72 75 6e 20 6f 66 20 74 68 65 20   dry-run of the 
20480 6f 70 3d 3d 31 20 63 61 73 65 20 62 75 74 20 64  op==1 case but d
20490 6f 0a 2a 2a 20 6e 6f 74 20 61 63 74 75 61 6c 6c  o.** not actuall
204a0 79 20 63 68 61 6e 67 65 20 61 6e 79 74 68 69 6e  y change anythin
204b0 67 2e 20 54 68 65 20 70 61 67 65 72 20 75 73 65  g. The pager use
204c0 73 20 74 68 69 73 20 74 6f 20 73 65 65 20 69 66  s this to see if
204d0 20 69 74 0a 2a 2a 20 73 68 6f 75 6c 64 20 61 63   it.** should ac
204e0 71 75 69 72 65 20 74 68 65 20 64 61 74 61 62 61  quire the databa
204f0 73 65 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63  se exclusive loc
20500 6b 20 70 72 69 6f 72 20 74 6f 20 69 6e 76 6f 6b  k prior to invok
20510 69 6e 67 0a 2a 2a 20 74 68 65 20 6f 70 3d 3d 31  ing.** the op==1
20520 20 63 61 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71   case..*/.int sq
20530 6c 69 74 65 33 57 61 6c 45 78 63 6c 75 73 69 76  lite3WalExclusiv
20540 65 4d 6f 64 65 28 57 61 6c 20 2a 70 57 61 6c 2c  eMode(Wal *pWal,
20550 20 69 6e 74 20 6f 70 29 7b 0a 20 20 69 6e 74 20   int op){.  int 
20560 72 63 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57  rc;.  assert( pW
20570 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30  al->writeLock==0
20580 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57   );.  assert( pW
20590 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  al->exclusiveMod
205a0 65 21 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52  e!=WAL_HEAPMEMOR
205b0 59 5f 4d 4f 44 45 20 7c 7c 20 6f 70 3d 3d 2d 31  Y_MODE || op==-1
205c0 20 29 3b 0a 0a 20 20 2f 2a 20 70 57 61 6c 2d 3e   );..  /* pWal->
205d0 72 65 61 64 4c 6f 63 6b 20 69 73 20 75 73 75 61  readLock is usua
205e0 6c 6c 79 20 73 65 74 2c 20 62 75 74 20 6d 69 67  lly set, but mig
205f0 68 74 20 62 65 20 2d 31 20 69 66 20 74 68 65 72  ht be -1 if ther
20600 65 20 77 61 73 20 61 20 0a 20 20 2a 2a 20 70 72  e was a .  ** pr
20610 69 6f 72 20 65 72 72 6f 72 20 77 68 69 6c 65 20  ior error while 
20620 61 74 74 65 6d 70 74 69 6e 67 20 74 6f 20 61 63  attempting to ac
20630 71 75 69 72 65 20 61 72 65 20 72 65 61 64 2d 6c  quire are read-l
20640 6f 63 6b 2e 20 54 68 69 73 20 63 61 6e 6e 6f 74  ock. This cannot
20650 20 0a 20 20 2a 2a 20 68 61 70 70 65 6e 20 69 66   .  ** happen if
20660 20 74 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20   the connection 
20670 69 73 20 61 63 74 75 61 6c 6c 79 20 69 6e 20 65  is actually in e
20680 78 63 6c 75 73 69 76 65 20 6d 6f 64 65 20 28 61  xclusive mode (a
20690 73 20 6e 6f 20 78 53 68 6d 4c 6f 63 6b 0a 20 20  s no xShmLock.  
206a0 2a 2a 20 6c 6f 63 6b 73 20 61 72 65 20 74 61 6b  ** locks are tak
206b0 65 6e 20 69 6e 20 74 68 69 73 20 63 61 73 65 29  en in this case)
206c0 2e 20 4e 6f 72 20 73 68 6f 75 6c 64 20 74 68 65  . Nor should the
206d0 20 70 61 67 65 72 20 61 74 74 65 6d 70 74 20 74   pager attempt t
206e0 6f 0a 20 20 2a 2a 20 75 70 67 72 61 64 65 20 74  o.  ** upgrade t
206f0 6f 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f 64 65  o exclusive-mode
20700 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 75 63 68 20   following such 
20710 61 6e 20 65 72 72 6f 72 2e 0a 20 20 2a 2f 0a 20  an error..  */. 
20720 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72   assert( pWal->r
20730 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70 57  eadLock>=0 || pW
20740 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 29 3b  al->lockError );
20750 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
20760 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20  >readLock>=0 || 
20770 28 6f 70 3c 3d 30 20 26 26 20 70 57 61 6c 2d 3e  (op<=0 && pWal->
20780 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30  exclusiveMode==0
20790 29 20 29 3b 0a 0a 20 20 69 66 28 20 6f 70 3d 3d  ) );..  if( op==
207a0 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57 61  0 ){.    if( pWa
207b0 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
207c0 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e   ){.      pWal->
207d0 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20  exclusiveMode = 
207e0 30 3b 0a 20 20 20 20 20 20 69 66 28 20 77 61 6c  0;.      if( wal
207f0 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  LockShared(pWal,
20800 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70   WAL_READ_LOCK(p
20810 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 21  Wal->readLock))!
20820 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
20830 20 20 20 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c        pWal->excl
20840 75 73 69 76 65 4d 6f 64 65 20 3d 20 31 3b 0a 20  usiveMode = 1;. 
20850 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 63 20       }.      rc 
20860 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76  = pWal->exclusiv
20870 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 20 20 7d 65  eMode==0;.    }e
20880 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20 41 6c  lse{.      /* Al
20890 72 65 61 64 79 20 69 6e 20 6c 6f 63 6b 69 6e 67  ready in locking
208a0 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 2a 2f 0a  _mode=NORMAL */.
208b0 20 20 20 20 20 20 72 63 20 3d 20 30 3b 0a 20 20        rc = 0;.  
208c0 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20    }.  }else if( 
208d0 6f 70 3e 30 20 29 7b 0a 20 20 20 20 61 73 73 65  op>0 ){.    asse
208e0 72 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  rt( pWal->exclus
208f0 69 76 65 4d 6f 64 65 3d 3d 30 20 29 3b 0a 20 20  iveMode==0 );.  
20900 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
20910 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b 0a 20  readLock>=0 );. 
20920 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72     walUnlockShar
20930 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ed(pWal, WAL_REA
20940 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61  D_LOCK(pWal->rea
20950 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70 57 61  dLock));.    pWa
20960 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
20970 20 3d 20 31 3b 0a 20 20 20 20 72 63 20 3d 20 31   = 1;.    rc = 1
20980 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72  ;.  }else{.    r
20990 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  c = pWal->exclus
209a0 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 7d 0a  iveMode==0;.  }.
209b0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
209c0 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72  /* .** Return tr
209d0 75 65 20 69 66 20 74 68 65 20 61 72 67 75 6d 65  ue if the argume
209e0 6e 74 20 69 73 20 6e 6f 6e 2d 4e 55 4c 4c 20 61  nt is non-NULL a
209f0 6e 64 20 74 68 65 20 57 41 4c 20 6d 6f 64 75 6c  nd the WAL modul
20a00 65 20 69 73 20 75 73 69 6e 67 0a 2a 2a 20 68 65  e is using.** he
20a10 61 70 2d 6d 65 6d 6f 72 79 20 66 6f 72 20 74 68  ap-memory for th
20a20 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 4f 74 68  e wal-index. Oth
20a30 65 72 77 69 73 65 2c 20 69 66 20 74 68 65 20 61  erwise, if the a
20a40 72 67 75 6d 65 6e 74 20 69 73 20 4e 55 4c 4c 20  rgument is NULL 
20a50 6f 72 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6d 6f  or the.** WAL mo
20a60 64 75 6c 65 20 69 73 20 75 73 69 6e 67 20 73 68  dule is using sh
20a70 61 72 65 64 2d 6d 65 6d 6f 72 79 2c 20 72 65 74  ared-memory, ret
20a80 75 72 6e 20 66 61 6c 73 65 2e 20 0a 2a 2f 0a 69  urn false. .*/.i
20a90 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 48 65 61  nt sqlite3WalHea
20aa0 70 4d 65 6d 6f 72 79 28 57 61 6c 20 2a 70 57 61  pMemory(Wal *pWa
20ab0 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 70 57  l){.  return (pW
20ac0 61 6c 20 26 26 20 70 57 61 6c 2d 3e 65 78 63 6c  al && pWal->excl
20ad0 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48  usiveMode==WAL_H
20ae0 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29  EAPMEMORY_MODE )
20af0 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49  ;.}..#ifdef SQLI
20b00 54 45 5f 45 4e 41 42 4c 45 5f 53 4e 41 50 53 48  TE_ENABLE_SNAPSH
20b10 4f 54 0a 2f 2a 20 43 72 65 61 74 65 20 61 20 73  OT./* Create a s
20b20 6e 61 70 73 68 6f 74 20 6f 62 6a 65 63 74 2e 20  napshot object. 
20b30 20 54 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20   The content of 
20b40 61 20 73 6e 61 70 73 68 6f 74 20 69 73 20 6f 70  a snapshot is op
20b50 61 71 75 65 20 74 6f 0a 2a 2a 20 65 76 65 72 79  aque to.** every
20b60 20 6f 74 68 65 72 20 73 75 62 73 79 73 74 65 6d   other subsystem
20b70 2c 20 73 6f 20 74 68 65 20 57 41 4c 20 6d 6f 64  , so the WAL mod
20b80 75 6c 65 20 63 61 6e 20 70 75 74 20 77 68 61 74  ule can put what
20b90 65 76 65 72 20 69 74 20 6e 65 65 64 73 0a 2a 2a  ever it needs.**
20ba0 20 69 6e 20 74 68 65 20 6f 62 6a 65 63 74 2e 0a   in the object..
20bb0 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
20bc0 6c 53 6e 61 70 73 68 6f 74 47 65 74 28 57 61 6c  lSnapshotGet(Wal
20bd0 20 2a 70 57 61 6c 2c 20 73 71 6c 69 74 65 33 5f   *pWal, sqlite3_
20be0 73 6e 61 70 73 68 6f 74 20 2a 2a 70 70 53 6e 61  snapshot **ppSna
20bf0 70 73 68 6f 74 29 7b 0a 20 20 69 6e 74 20 72 63  pshot){.  int rc
20c00 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
20c10 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 70 52 65  WalIndexHdr *pRe
20c20 74 3b 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73  t;.  static cons
20c30 74 20 75 33 32 20 61 5a 65 72 6f 5b 34 5d 20 3d  t u32 aZero[4] =
20c40 20 7b 20 30 2c 20 30 2c 20 30 2c 20 30 20 7d 3b   { 0, 0, 0, 0 };
20c50 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ..  assert( pWal
20c60 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 26 26  ->readLock>=0 &&
20c70 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
20c80 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 6d 65  ==0 );..  if( me
20c90 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72 2e  mcmp(&pWal->hdr.
20ca0 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 2c 61  aFrameCksum[0],a
20cb0 5a 65 72 6f 2c 31 36 29 3d 3d 30 20 29 7b 0a 20  Zero,16)==0 ){. 
20cc0 20 20 20 2a 70 70 53 6e 61 70 73 68 6f 74 20 3d     *ppSnapshot =
20cd0 20 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   0;.    return S
20ce0 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
20cf0 0a 20 20 70 52 65 74 20 3d 20 28 57 61 6c 49 6e  .  pRet = (WalIn
20d00 64 65 78 48 64 72 2a 29 73 71 6c 69 74 65 33 5f  dexHdr*)sqlite3_
20d10 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 57 61  malloc(sizeof(Wa
20d20 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 69  lIndexHdr));.  i
20d30 66 28 20 70 52 65 74 3d 3d 30 20 29 7b 0a 20 20  f( pRet==0 ){.  
20d40 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
20d50 4d 45 4d 5f 42 4b 50 54 3b 0a 20 20 7d 65 6c 73  MEM_BKPT;.  }els
20d60 65 7b 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 52  e{.    memcpy(pR
20d70 65 74 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c 20  et, &pWal->hdr, 
20d80 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48  sizeof(WalIndexH
20d90 64 72 29 29 3b 0a 20 20 20 20 2a 70 70 53 6e 61  dr));.    *ppSna
20da0 70 73 68 6f 74 20 3d 20 28 73 71 6c 69 74 65 33  pshot = (sqlite3
20db0 5f 73 6e 61 70 73 68 6f 74 2a 29 70 52 65 74 3b  _snapshot*)pRet;
20dc0 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
20dd0 63 3b 0a 7d 0a 0a 2f 2a 20 54 72 79 20 74 6f 20  c;.}../* Try to 
20de0 6f 70 65 6e 20 6f 6e 20 70 53 6e 61 70 73 68 6f  open on pSnapsho
20df0 74 20 77 68 65 6e 20 74 68 65 20 6e 65 78 74 20  t when the next 
20e00 72 65 61 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e  read-transaction
20e10 20 73 74 61 72 74 73 0a 2a 2f 0a 76 6f 69 64 20   starts.*/.void 
20e20 73 71 6c 69 74 65 33 57 61 6c 53 6e 61 70 73 68  sqlite3WalSnapsh
20e30 6f 74 4f 70 65 6e 28 57 61 6c 20 2a 70 57 61 6c  otOpen(Wal *pWal
20e40 2c 20 73 71 6c 69 74 65 33 5f 73 6e 61 70 73 68  , sqlite3_snapsh
20e50 6f 74 20 2a 70 53 6e 61 70 73 68 6f 74 29 7b 0a  ot *pSnapshot){.
20e60 20 20 70 57 61 6c 2d 3e 70 53 6e 61 70 73 68 6f    pWal->pSnapsho
20e70 74 20 3d 20 28 57 61 6c 49 6e 64 65 78 48 64 72  t = (WalIndexHdr
20e80 2a 29 70 53 6e 61 70 73 68 6f 74 3b 0a 7d 0a 0a  *)pSnapshot;.}..
20e90 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20  /* .** Return a 
20ea0 2b 76 65 20 76 61 6c 75 65 20 69 66 20 73 6e 61  +ve value if sna
20eb0 70 73 68 6f 74 20 70 31 20 69 73 20 6e 65 77 65  pshot p1 is newe
20ec0 72 20 74 68 61 6e 20 70 32 2e 20 41 20 2d 76 65  r than p2. A -ve
20ed0 20 76 61 6c 75 65 20 69 66 0a 2a 2a 20 70 31 20   value if.** p1 
20ee0 69 73 20 6f 6c 64 65 72 20 74 68 61 6e 20 70 32  is older than p2
20ef0 20 61 6e 64 20 7a 65 72 6f 20 69 66 20 70 31 20   and zero if p1 
20f00 61 6e 64 20 70 32 20 61 72 65 20 74 68 65 20 73  and p2 are the s
20f10 61 6d 65 20 73 6e 61 70 73 68 6f 74 2e 0a 2a 2f  ame snapshot..*/
20f20 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 73 6e 61  .int sqlite3_sna
20f30 70 73 68 6f 74 5f 63 6d 70 28 73 71 6c 69 74 65  pshot_cmp(sqlite
20f40 33 5f 73 6e 61 70 73 68 6f 74 20 2a 70 31 2c 20  3_snapshot *p1, 
20f50 73 71 6c 69 74 65 33 5f 73 6e 61 70 73 68 6f 74  sqlite3_snapshot
20f60 20 2a 70 32 29 7b 0a 20 20 57 61 6c 49 6e 64 65   *p2){.  WalInde
20f70 78 48 64 72 20 2a 70 48 64 72 31 20 3d 20 28 57  xHdr *pHdr1 = (W
20f80 61 6c 49 6e 64 65 78 48 64 72 2a 29 70 31 3b 0a  alIndexHdr*)p1;.
20f90 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 70    WalIndexHdr *p
20fa0 48 64 72 32 20 3d 20 28 57 61 6c 49 6e 64 65 78  Hdr2 = (WalIndex
20fb0 48 64 72 2a 29 70 32 3b 0a 0a 20 20 2f 2a 20 61  Hdr*)p2;..  /* a
20fc0 53 61 6c 74 5b 30 5d 20 69 73 20 61 20 63 6f 70  Salt[0] is a cop
20fd0 79 20 6f 66 20 74 68 65 20 76 61 6c 75 65 20 73  y of the value s
20fe0 74 6f 72 65 64 20 69 6e 20 74 68 65 20 77 61 6c  tored in the wal
20ff0 20 66 69 6c 65 20 68 65 61 64 65 72 2e 20 49 74   file header. It
21000 0a 20 20 2a 2a 20 69 73 20 69 6e 63 72 65 6d 65  .  ** is increme
21010 6e 74 65 64 20 65 61 63 68 20 74 69 6d 65 20 74  nted each time t
21020 68 65 20 77 61 6c 20 66 69 6c 65 20 69 73 20 72  he wal file is r
21030 65 73 74 61 72 74 65 64 2e 20 20 2a 2f 0a 20 20  estarted.  */.  
21040 69 66 28 20 70 48 64 72 31 2d 3e 61 53 61 6c 74  if( pHdr1->aSalt
21050 5b 30 5d 3c 70 48 64 72 32 2d 3e 61 53 61 6c 74  [0]<pHdr2->aSalt
21060 5b 30 5d 20 29 20 72 65 74 75 72 6e 20 2d 31 3b  [0] ) return -1;
21070 0a 20 20 69 66 28 20 70 48 64 72 31 2d 3e 61 53  .  if( pHdr1->aS
21080 61 6c 74 5b 30 5d 3e 70 48 64 72 32 2d 3e 61 53  alt[0]>pHdr2->aS
21090 61 6c 74 5b 30 5d 20 29 20 72 65 74 75 72 6e 20  alt[0] ) return 
210a0 2b 31 3b 0a 20 20 69 66 28 20 70 48 64 72 31 2d  +1;.  if( pHdr1-
210b0 3e 6d 78 46 72 61 6d 65 3c 70 48 64 72 32 2d 3e  >mxFrame<pHdr2->
210c0 6d 78 46 72 61 6d 65 20 29 20 72 65 74 75 72 6e  mxFrame ) return
210d0 20 2d 31 3b 0a 20 20 69 66 28 20 70 48 64 72 31   -1;.  if( pHdr1
210e0 2d 3e 6d 78 46 72 61 6d 65 3e 70 48 64 72 32 2d  ->mxFrame>pHdr2-
210f0 3e 6d 78 46 72 61 6d 65 20 29 20 72 65 74 75 72  >mxFrame ) retur
21100 6e 20 2b 31 3b 0a 20 20 72 65 74 75 72 6e 20 30  n +1;.  return 0
21110 3b 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  ;.}.#endif /* SQ
21120 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 53 4e 41 50  LITE_ENABLE_SNAP
21130 53 48 4f 54 20 2a 2f 0a 0a 23 69 66 64 65 66 20  SHOT */..#ifdef 
21140 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 5a 49  SQLITE_ENABLE_ZI
21150 50 56 46 53 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68  PVFS./*.** If th
21160 65 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f  e argument is no
21170 74 20 4e 55 4c 4c 2c 20 69 74 20 70 6f 69 6e 74  t NULL, it point
21180 73 20 74 6f 20 61 20 57 61 6c 20 6f 62 6a 65 63  s to a Wal objec
21190 74 20 74 68 61 74 20 68 6f 6c 64 73 20 61 0a 2a  t that holds a.*
211a0 2a 20 72 65 61 64 2d 6c 6f 63 6b 2e 20 54 68 69  * read-lock. Thi
211b0 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72  s function retur
211c0 6e 73 20 74 68 65 20 64 61 74 61 62 61 73 65 20  ns the database 
211d0 70 61 67 65 2d 73 69 7a 65 20 69 66 20 69 74 20  page-size if it 
211e0 69 73 20 6b 6e 6f 77 6e 2c 0a 2a 2a 20 6f 72 20  is known,.** or 
211f0 7a 65 72 6f 20 69 66 20 69 74 20 69 73 20 6e 6f  zero if it is no
21200 74 20 28 6f 72 20 69 66 20 70 57 61 6c 20 69 73  t (or if pWal is
21210 20 4e 55 4c 4c 29 2e 0a 2a 2f 0a 69 6e 74 20 73   NULL)..*/.int s
21220 71 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73 69  qlite3WalFramesi
21230 7a 65 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20  ze(Wal *pWal){. 
21240 20 61 73 73 65 72 74 28 20 70 57 61 6c 3d 3d 30   assert( pWal==0
21250 20 7c 7c 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f   || pWal->readLo
21260 63 6b 3e 3d 30 20 29 3b 0a 20 20 72 65 74 75 72  ck>=0 );.  retur
21270 6e 20 28 70 57 61 6c 20 3f 20 70 57 61 6c 2d 3e  n (pWal ? pWal->
21280 73 7a 50 61 67 65 20 3a 20 30 29 3b 0a 7d 0a 23  szPage : 0);.}.#
21290 65 6e 64 69 66 0a 0a 2f 2a 20 52 65 74 75 72 6e  endif../* Return
212a0 20 74 68 65 20 73 71 6c 69 74 65 33 5f 66 69 6c   the sqlite3_fil
212b0 65 20 6f 62 6a 65 63 74 20 66 6f 72 20 74 68 65  e object for the
212c0 20 57 41 4c 20 66 69 6c 65 0a 2a 2f 0a 73 71 6c   WAL file.*/.sql
212d0 69 74 65 33 5f 66 69 6c 65 20 2a 73 71 6c 69 74  ite3_file *sqlit
212e0 65 33 57 61 6c 46 69 6c 65 28 57 61 6c 20 2a 70  e3WalFile(Wal *p
212f0 57 61 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 70  Wal){.  return p
21300 57 61 6c 2d 3e 70 57 61 6c 46 64 3b 0a 7d 0a 0a  Wal->pWalFd;.}..
21310 23 65 6e 64 69 66 20 2f 2a 20 23 69 66 6e 64 65  #endif /* #ifnde
21320 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 57 41  f SQLITE_OMIT_WA
21330 4c 20 2a 2f 0a                                   L */.