/ Hex Artifact Content
Login

Artifact 847692349eb6e1fb8543dbc97e69ddbfa4cc7ea7:


0000: 2f 2a 0a 2a 2a 20 32 30 31 30 20 46 65 62 72 75  /*.** 2010 Febru
0010: 61 72 79 20 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ary 1.**.** The 
0020: 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73  author disclaims
0030: 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68   copyright to th
0040: 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20  is source code. 
0050: 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20   In place of.** 
0060: 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20  a legal notice, 
0070: 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69  here is a blessi
0080: 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79  ng:.**.**    May
0090: 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64   you do good and
00a0: 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20   not evil..**   
00b0: 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f   May you find fo
00c0: 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f  rgiveness for yo
00d0: 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69  urself and forgi
00e0: 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20  ve others..**   
00f0: 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66   May you share f
0100: 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b  reely, never tak
0110: 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f  ing more than yo
0120: 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a  u give..**.*****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 74 68  file contains th
0190: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
01a0: 20 6f 66 20 61 20 77 72 69 74 65 2d 61 68 65 61   of a write-ahea
01b0: 64 20 6c 6f 67 20 28 57 41 4c 29 20 75 73 65 64  d log (WAL) used
01c0: 20 69 6e 20 0a 2a 2a 20 22 6a 6f 75 72 6e 61 6c   in .** "journal
01d0: 5f 6d 6f 64 65 3d 57 41 4c 22 20 6d 6f 64 65 2e  _mode=WAL" mode.
01e0: 0a 2a 2a 0a 2a 2a 20 57 52 49 54 45 2d 41 48 45  .**.** WRITE-AHE
01f0: 41 44 20 4c 4f 47 20 28 57 41 4c 29 20 46 49 4c  AD LOG (WAL) FIL
0200: 45 20 46 4f 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 41  E FORMAT.**.** A
0210: 20 57 41 4c 20 66 69 6c 65 20 63 6f 6e 73 69 73   WAL file consis
0220: 74 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 66  ts of a header f
0230: 6f 6c 6c 6f 77 65 64 20 62 79 20 7a 65 72 6f 20  ollowed by zero 
0240: 6f 72 20 6d 6f 72 65 20 22 66 72 61 6d 65 73 22  or more "frames"
0250: 2e 0a 2a 2a 20 45 61 63 68 20 66 72 61 6d 65 20  ..** Each frame 
0260: 72 65 63 6f 72 64 73 20 74 68 65 20 72 65 76 69  records the revi
0270: 73 65 64 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  sed content of a
0280: 20 73 69 6e 67 6c 65 20 70 61 67 65 20 66 72 6f   single page fro
0290: 6d 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73  m the.** databas
02a0: 65 20 66 69 6c 65 2e 20 20 41 6c 6c 20 63 68 61  e file.  All cha
02b0: 6e 67 65 73 20 74 6f 20 74 68 65 20 64 61 74 61  nges to the data
02c0: 62 61 73 65 20 61 72 65 20 72 65 63 6f 72 64 65  base are recorde
02d0: 64 20 62 79 20 77 72 69 74 69 6e 67 0a 2a 2a 20  d by writing.** 
02e0: 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20  frames into the 
02f0: 57 41 4c 2e 20 20 54 72 61 6e 73 61 63 74 69 6f  WAL.  Transactio
0300: 6e 73 20 63 6f 6d 6d 69 74 20 77 68 65 6e 20 61  ns commit when a
0310: 20 66 72 61 6d 65 20 69 73 20 77 72 69 74 74 65   frame is writte
0320: 6e 20 74 68 61 74 0a 2a 2a 20 63 6f 6e 74 61 69  n that.** contai
0330: 6e 73 20 61 20 63 6f 6d 6d 69 74 20 6d 61 72 6b  ns a commit mark
0340: 65 72 2e 20 20 41 20 73 69 6e 67 6c 65 20 57 41  er.  A single WA
0350: 4c 20 63 61 6e 20 61 6e 64 20 75 73 75 61 6c 6c  L can and usuall
0360: 79 20 64 6f 65 73 20 72 65 63 6f 72 64 20 0a 2a  y does record .*
0370: 2a 20 6d 75 6c 74 69 70 6c 65 20 74 72 61 6e 73  * multiple trans
0380: 61 63 74 69 6f 6e 73 2e 20 20 50 65 72 69 6f 64  actions.  Period
0390: 69 63 61 6c 6c 79 2c 20 74 68 65 20 63 6f 6e 74  ically, the cont
03a0: 65 6e 74 20 6f 66 20 74 68 65 20 57 41 4c 20 69  ent of the WAL i
03b0: 73 0a 2a 2a 20 74 72 61 6e 73 66 65 72 72 65 64  s.** transferred
03c0: 20 62 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64   back into the d
03d0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 69 6e 20  atabase file in 
03e0: 61 6e 20 6f 70 65 72 61 74 69 6f 6e 20 63 61 6c  an operation cal
03f0: 6c 65 64 20 61 0a 2a 2a 20 22 63 68 65 63 6b 70  led a.** "checkp
0400: 6f 69 6e 74 22 2e 0a 2a 2a 0a 2a 2a 20 41 20 73  oint"..**.** A s
0410: 69 6e 67 6c 65 20 57 41 4c 20 66 69 6c 65 20 63  ingle WAL file c
0420: 61 6e 20 62 65 20 75 73 65 64 20 6d 75 6c 74 69  an be used multi
0430: 70 6c 65 20 74 69 6d 65 73 2e 20 20 49 6e 20 6f  ple times.  In o
0440: 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68 65 0a  ther words, the.
0450: 2a 2a 20 57 41 4c 20 63 61 6e 20 66 69 6c 6c 20  ** WAL can fill 
0460: 75 70 20 77 69 74 68 20 66 72 61 6d 65 73 20 61  up with frames a
0470: 6e 64 20 74 68 65 6e 20 62 65 20 63 68 65 63 6b  nd then be check
0480: 70 6f 69 6e 74 65 64 20 61 6e 64 20 74 68 65 6e  pointed and then
0490: 20 6e 65 77 0a 2a 2a 20 66 72 61 6d 65 73 20 63   new.** frames c
04a0: 61 6e 20 6f 76 65 72 77 72 69 74 65 20 74 68 65  an overwrite the
04b0: 20 6f 6c 64 20 6f 6e 65 73 2e 20 20 41 20 57 41   old ones.  A WA
04c0: 4c 20 61 6c 77 61 79 73 20 67 72 6f 77 73 20 66  L always grows f
04d0: 72 6f 6d 20 62 65 67 69 6e 6e 69 6e 67 0a 2a 2a  rom beginning.**
04e0: 20 74 6f 77 61 72 64 20 74 68 65 20 65 6e 64 2e   toward the end.
04f0: 20 20 43 68 65 63 6b 73 75 6d 73 20 61 6e 64 20    Checksums and 
0500: 63 6f 75 6e 74 65 72 73 20 61 74 74 61 63 68 65  counters attache
0510: 64 20 74 6f 20 65 61 63 68 20 66 72 61 6d 65 20  d to each frame 
0520: 61 72 65 0a 2a 2a 20 75 73 65 64 20 74 6f 20 64  are.** used to d
0530: 65 74 65 72 6d 69 6e 65 20 77 68 69 63 68 20 66  etermine which f
0540: 72 61 6d 65 73 20 77 69 74 68 69 6e 20 74 68 65  rames within the
0550: 20 57 41 4c 20 61 72 65 20 76 61 6c 69 64 20 61   WAL are valid a
0560: 6e 64 20 77 68 69 63 68 0a 2a 2a 20 61 72 65 20  nd which.** are 
0570: 6c 65 66 74 6f 76 65 72 73 20 66 72 6f 6d 20 70  leftovers from p
0580: 72 69 6f 72 20 63 68 65 63 6b 70 6f 69 6e 74 73  rior checkpoints
0590: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 57 41 4c 20  ..**.** The WAL 
05a0: 68 65 61 64 65 72 20 69 73 20 33 32 20 62 79 74  header is 32 byt
05b0: 65 73 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 63  es in size and c
05c0: 6f 6e 73 69 73 74 73 20 6f 66 20 74 68 65 20 66  onsists of the f
05d0: 6f 6c 6c 6f 77 69 6e 67 20 65 69 67 68 74 0a 2a  ollowing eight.*
05e0: 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 33 32 2d  * big-endian 32-
05f0: 62 69 74 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  bit unsigned int
0600: 65 67 65 72 20 76 61 6c 75 65 73 3a 0a 2a 2a 0a  eger values:.**.
0610: 2a 2a 20 20 20 20 20 30 3a 20 4d 61 67 69 63 20  **     0: Magic 
0620: 6e 75 6d 62 65 72 2e 20 20 30 78 33 37 37 66 30  number.  0x377f0
0630: 36 38 32 20 6f 72 20 30 78 33 37 37 66 30 36 38  682 or 0x377f068
0640: 33 0a 2a 2a 20 20 20 20 20 34 3a 20 46 69 6c 65  3.**     4: File
0650: 20 66 6f 72 6d 61 74 20 76 65 72 73 69 6f 6e 2e   format version.
0660: 20 20 43 75 72 72 65 6e 74 6c 79 20 33 30 30 37    Currently 3007
0670: 30 30 30 0a 2a 2a 20 20 20 20 20 38 3a 20 44 61  000.**     8: Da
0680: 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65  tabase page size
0690: 2e 20 20 45 78 61 6d 70 6c 65 3a 20 31 30 32 34  .  Example: 1024
06a0: 0a 2a 2a 20 20 20 20 31 32 3a 20 43 68 65 63 6b  .**    12: Check
06b0: 70 6f 69 6e 74 20 73 65 71 75 65 6e 63 65 20 6e  point sequence n
06c0: 75 6d 62 65 72 0a 2a 2a 20 20 20 20 31 36 3a 20  umber.**    16: 
06d0: 53 61 6c 74 2d 31 2c 20 72 61 6e 64 6f 6d 20 69  Salt-1, random i
06e0: 6e 74 65 67 65 72 20 69 6e 63 72 65 6d 65 6e 74  nteger increment
06f0: 65 64 20 77 69 74 68 20 65 61 63 68 20 63 68 65  ed with each che
0700: 63 6b 70 6f 69 6e 74 0a 2a 2a 20 20 20 20 32 30  ckpoint.**    20
0710: 3a 20 53 61 6c 74 2d 32 2c 20 61 20 64 69 66 66  : Salt-2, a diff
0720: 65 72 65 6e 74 20 72 61 6e 64 6f 6d 20 69 6e 74  erent random int
0730: 65 67 65 72 20 63 68 61 6e 67 69 6e 67 20 77 69  eger changing wi
0740: 74 68 20 65 61 63 68 20 63 6b 70 74 0a 2a 2a 20  th each ckpt.** 
0750: 20 20 20 32 34 3a 20 43 68 65 63 6b 73 75 6d 2d     24: Checksum-
0760: 31 20 28 66 69 72 73 74 20 70 61 72 74 20 6f 66  1 (first part of
0770: 20 63 68 65 63 6b 73 75 6d 20 66 6f 72 20 66 69   checksum for fi
0780: 72 73 74 20 32 34 20 62 79 74 65 73 20 6f 66 20  rst 24 bytes of 
0790: 68 65 61 64 65 72 29 2e 0a 2a 2a 20 20 20 20 32  header)..**    2
07a0: 38 3a 20 43 68 65 63 6b 73 75 6d 2d 32 20 28 73  8: Checksum-2 (s
07b0: 65 63 6f 6e 64 20 70 61 72 74 20 6f 66 20 63 68  econd part of ch
07c0: 65 63 6b 73 75 6d 20 66 6f 72 20 66 69 72 73 74  ecksum for first
07d0: 20 32 34 20 62 79 74 65 73 20 6f 66 20 68 65 61   24 bytes of hea
07e0: 64 65 72 29 2e 0a 2a 2a 0a 2a 2a 20 49 6d 6d 65  der)..**.** Imme
07f0: 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e  diately followin
0800: 67 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  g the wal-header
0810: 20 61 72 65 20 7a 65 72 6f 20 6f 72 20 6d 6f 72   are zero or mor
0820: 65 20 66 72 61 6d 65 73 2e 20 45 61 63 68 0a 2a  e frames. Each.*
0830: 2a 20 66 72 61 6d 65 20 63 6f 6e 73 69 73 74 73  * frame consists
0840: 20 6f 66 20 61 20 32 34 2d 62 79 74 65 20 66 72   of a 24-byte fr
0850: 61 6d 65 2d 68 65 61 64 65 72 20 66 6f 6c 6c 6f  ame-header follo
0860: 77 65 64 20 62 79 20 61 20 3c 70 61 67 65 2d 73  wed by a <page-s
0870: 69 7a 65 3e 20 62 79 74 65 73 0a 2a 2a 20 6f 66  ize> bytes.** of
0880: 20 70 61 67 65 20 64 61 74 61 2e 20 54 68 65 20   page data. The 
0890: 66 72 61 6d 65 2d 68 65 61 64 65 72 20 69 73 20  frame-header is 
08a0: 73 69 78 20 62 69 67 2d 65 6e 64 69 61 6e 20 33  six big-endian 3
08b0: 32 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20 0a  2-bit unsigned .
08c0: 2a 2a 20 69 6e 74 65 67 65 72 20 76 61 6c 75 65  ** integer value
08d0: 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  s, as follows:.*
08e0: 2a 0a 2a 2a 20 20 20 20 20 30 3a 20 50 61 67 65  *.**     0: Page
08f0: 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20 20 20 20   number..**     
0900: 34 3a 20 46 6f 72 20 63 6f 6d 6d 69 74 20 72 65  4: For commit re
0910: 63 6f 72 64 73 2c 20 74 68 65 20 73 69 7a 65 20  cords, the size 
0920: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  of the database 
0930: 69 6d 61 67 65 20 69 6e 20 70 61 67 65 73 20 0a  image in pages .
0940: 2a 2a 20 20 20 20 20 20 20 20 61 66 74 65 72 20  **        after 
0950: 74 68 65 20 63 6f 6d 6d 69 74 2e 20 46 6f 72 20  the commit. For 
0960: 61 6c 6c 20 6f 74 68 65 72 20 72 65 63 6f 72 64  all other record
0970: 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20 20  s, zero..**     
0980: 38 3a 20 53 61 6c 74 2d 31 20 28 63 6f 70 69 65  8: Salt-1 (copie
0990: 64 20 66 72 6f 6d 20 74 68 65 20 68 65 61 64 65  d from the heade
09a0: 72 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61 6c  r).**    12: Sal
09b0: 74 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f 6d  t-2 (copied from
09c0: 20 74 68 65 20 68 65 61 64 65 72 29 0a 2a 2a 20   the header).** 
09d0: 20 20 20 31 36 3a 20 43 68 65 63 6b 73 75 6d 2d     16: Checksum-
09e0: 31 2e 0a 2a 2a 20 20 20 20 32 30 3a 20 43 68 65  1..**    20: Che
09f0: 63 6b 73 75 6d 2d 32 2e 0a 2a 2a 0a 2a 2a 20 41  cksum-2..**.** A
0a00: 20 66 72 61 6d 65 20 69 73 20 63 6f 6e 73 69 64   frame is consid
0a10: 65 72 65 64 20 76 61 6c 69 64 20 69 66 20 61 6e  ered valid if an
0a20: 64 20 6f 6e 6c 79 20 69 66 20 74 68 65 20 66 6f  d only if the fo
0a30: 6c 6c 6f 77 69 6e 67 20 63 6f 6e 64 69 74 69 6f  llowing conditio
0a40: 6e 73 20 61 72 65 0a 2a 2a 20 74 72 75 65 3a 0a  ns are.** true:.
0a50: 2a 2a 0a 2a 2a 20 20 20 20 28 31 29 20 54 68 65  **.**    (1) The
0a60: 20 73 61 6c 74 2d 31 20 61 6e 64 20 73 61 6c 74   salt-1 and salt
0a70: 2d 32 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  -2 values in the
0a80: 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20 6d 61   frame-header ma
0a90: 74 63 68 0a 2a 2a 20 20 20 20 20 20 20 20 73 61  tch.**        sa
0aa0: 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  lt values in the
0ab0: 20 77 61 6c 2d 68 65 61 64 65 72 0a 2a 2a 0a 2a   wal-header.**.*
0ac0: 2a 20 20 20 20 28 32 29 20 54 68 65 20 63 68 65  *    (2) The che
0ad0: 63 6b 73 75 6d 20 76 61 6c 75 65 73 20 69 6e 20  cksum values in 
0ae0: 74 68 65 20 66 69 6e 61 6c 20 38 20 62 79 74 65  the final 8 byte
0af0: 73 20 6f 66 20 74 68 65 20 66 72 61 6d 65 2d 68  s of the frame-h
0b00: 65 61 64 65 72 0a 2a 2a 20 20 20 20 20 20 20 20  eader.**        
0b10: 65 78 61 63 74 6c 79 20 6d 61 74 63 68 20 74 68  exactly match th
0b20: 65 20 63 68 65 63 6b 73 75 6d 20 63 6f 6d 70 75  e checksum compu
0b30: 74 65 64 20 63 6f 6e 73 65 63 75 74 69 76 65 6c  ted consecutivel
0b40: 79 20 6f 6e 20 74 68 65 0a 2a 2a 20 20 20 20 20  y on the.**     
0b50: 20 20 20 57 41 4c 20 68 65 61 64 65 72 20 61 6e     WAL header an
0b60: 64 20 74 68 65 20 66 69 72 73 74 20 38 20 62 79  d the first 8 by
0b70: 74 65 73 20 61 6e 64 20 74 68 65 20 63 6f 6e 74  tes and the cont
0b80: 65 6e 74 20 6f 66 20 61 6c 6c 20 66 72 61 6d 65  ent of all frame
0b90: 73 0a 2a 2a 20 20 20 20 20 20 20 20 75 70 20 74  s.**        up t
0ba0: 6f 20 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20  o and including 
0bb0: 74 68 65 20 63 75 72 72 65 6e 74 20 66 72 61 6d  the current fram
0bc0: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65  e..**.** The che
0bd0: 63 6b 73 75 6d 20 69 73 20 63 6f 6d 70 75 74 65  cksum is compute
0be0: 64 20 75 73 69 6e 67 20 33 32 2d 62 69 74 20 62  d using 32-bit b
0bf0: 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65  ig-endian intege
0c00: 72 73 20 69 66 20 74 68 65 0a 2a 2a 20 6d 61 67  rs if the.** mag
0c10: 69 63 20 6e 75 6d 62 65 72 20 69 6e 20 74 68 65  ic number in the
0c20: 20 66 69 72 73 74 20 34 20 62 79 74 65 73 20 6f   first 4 bytes o
0c30: 66 20 74 68 65 20 57 41 4c 20 69 73 20 30 78 33  f the WAL is 0x3
0c40: 37 37 66 30 36 38 33 20 61 6e 64 20 69 74 0a 2a  77f0683 and it.*
0c50: 2a 20 69 73 20 63 6f 6d 70 75 74 65 64 20 75 73  * is computed us
0c60: 69 6e 67 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61  ing little-endia
0c70: 6e 20 69 66 20 74 68 65 20 6d 61 67 69 63 20 6e  n if the magic n
0c80: 75 6d 62 65 72 20 69 73 20 30 78 33 37 37 66 30  umber is 0x377f0
0c90: 36 38 32 2e 0a 2a 2a 20 54 68 65 20 63 68 65 63  682..** The chec
0ca0: 6b 73 75 6d 20 76 61 6c 75 65 73 20 61 72 65 20  ksum values are 
0cb0: 61 6c 77 61 79 73 20 73 74 6f 72 65 64 20 69 6e  always stored in
0cc0: 20 74 68 65 20 66 72 61 6d 65 20 68 65 61 64 65   the frame heade
0cd0: 72 20 69 6e 20 61 0a 2a 2a 20 62 69 67 2d 65 6e  r in a.** big-en
0ce0: 64 69 61 6e 20 66 6f 72 6d 61 74 20 72 65 67 61  dian format rega
0cf0: 72 64 6c 65 73 73 20 6f 66 20 77 68 69 63 68 20  rdless of which 
0d00: 62 79 74 65 20 6f 72 64 65 72 20 69 73 20 75 73  byte order is us
0d10: 65 64 20 74 6f 20 63 6f 6d 70 75 74 65 0a 2a 2a  ed to compute.**
0d20: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 2e 20 20   the checksum.  
0d30: 54 68 65 20 63 68 65 63 6b 73 75 6d 20 69 73 20  The checksum is 
0d40: 63 6f 6d 70 75 74 65 64 20 62 79 20 69 6e 74 65  computed by inte
0d50: 72 70 72 65 74 69 6e 67 20 74 68 65 20 69 6e 70  rpreting the inp
0d60: 75 74 20 61 73 0a 2a 2a 20 61 6e 20 65 76 65 6e  ut as.** an even
0d70: 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 73 69 67   number of unsig
0d80: 6e 65 64 20 33 32 2d 62 69 74 20 69 6e 74 65 67  ned 32-bit integ
0d90: 65 72 73 3a 20 78 5b 30 5d 20 74 68 72 6f 75 67  ers: x[0] throug
0da0: 68 20 78 5b 4e 5d 2e 20 20 54 68 65 0a 2a 2a 20  h x[N].  The.** 
0db0: 61 6c 67 6f 72 69 74 68 6d 20 75 73 65 64 20 66  algorithm used f
0dc0: 6f 72 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20  or the checksum 
0dd0: 69 73 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  is as follows:.*
0de0: 2a 20 0a 2a 2a 20 20 20 66 6f 72 20 69 20 66 72  * .**   for i fr
0df0: 6f 6d 20 30 20 74 6f 20 6e 2d 31 20 73 74 65 70  om 0 to n-1 step
0e00: 20 32 3a 0a 2a 2a 20 20 20 20 20 73 30 20 2b 3d   2:.**     s0 +=
0e10: 20 78 5b 69 5d 20 2b 20 73 31 3b 0a 2a 2a 20 20   x[i] + s1;.**  
0e20: 20 20 20 73 31 20 2b 3d 20 78 5b 69 2b 31 5d 20     s1 += x[i+1] 
0e30: 2b 20 73 30 3b 0a 2a 2a 20 20 20 65 6e 64 66 6f  + s0;.**   endfo
0e40: 72 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61  r.**.** Note tha
0e50: 74 20 73 30 20 61 6e 64 20 73 31 20 61 72 65 20  t s0 and s1 are 
0e60: 62 6f 74 68 20 77 65 69 67 68 74 65 64 20 63 68  both weighted ch
0e70: 65 63 6b 73 75 6d 73 20 75 73 69 6e 67 20 66 69  ecksums using fi
0e80: 62 6f 6e 61 63 63 69 20 77 65 69 67 68 74 73 0a  bonacci weights.
0e90: 2a 2a 20 69 6e 20 72 65 76 65 72 73 65 20 6f 72  ** in reverse or
0ea0: 64 65 72 20 28 74 68 65 20 6c 61 72 67 65 73 74  der (the largest
0eb0: 20 66 69 62 6f 6e 61 63 63 69 20 77 65 69 67 68   fibonacci weigh
0ec0: 74 20 6f 63 63 75 72 73 20 6f 6e 20 74 68 65 20  t occurs on the 
0ed0: 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 0a 2a 2a  first element.**
0ee0: 20 6f 66 20 74 68 65 20 73 65 71 75 65 6e 63 65   of the sequence
0ef0: 20 62 65 69 6e 67 20 73 75 6d 6d 65 64 2e 29 20   being summed.) 
0f00: 20 54 68 65 20 73 31 20 76 61 6c 75 65 20 73 70   The s1 value sp
0f10: 61 6e 73 20 61 6c 6c 20 33 32 2d 62 69 74 20 0a  ans all 32-bit .
0f20: 2a 2a 20 74 65 72 6d 73 20 6f 66 20 74 68 65 20  ** terms of the 
0f30: 73 65 71 75 65 6e 63 65 20 77 68 65 72 65 61 73  sequence whereas
0f40: 20 73 30 20 6f 6d 69 74 73 20 74 68 65 20 66 69   s0 omits the fi
0f50: 6e 61 6c 20 74 65 72 6d 2e 0a 2a 2a 0a 2a 2a 20  nal term..**.** 
0f60: 4f 6e 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c  On a checkpoint,
0f70: 20 74 68 65 20 57 41 4c 20 69 73 20 66 69 72 73   the WAL is firs
0f80: 74 20 56 46 53 2e 78 53 79 6e 63 2d 65 64 2c 20  t VFS.xSync-ed, 
0f90: 74 68 65 6e 20 76 61 6c 69 64 20 63 6f 6e 74 65  then valid conte
0fa0: 6e 74 20 6f 66 20 74 68 65 0a 2a 2a 20 57 41 4c  nt of the.** WAL
0fb0: 20 69 73 20 74 72 61 6e 73 66 65 72 72 65 64 20   is transferred 
0fc0: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
0fd0: 65 2c 20 74 68 65 6e 20 74 68 65 20 64 61 74 61  e, then the data
0fe0: 62 61 73 65 20 69 73 20 56 46 53 2e 78 53 79 6e  base is VFS.xSyn
0ff0: 63 2d 65 64 2e 0a 2a 2a 20 54 68 65 20 56 46 53  c-ed..** The VFS
1000: 2e 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e  .xSync operation
1010: 73 20 73 65 72 76 65 20 61 73 20 77 72 69 74 65  s serve as write
1020: 20 62 61 72 72 69 65 72 73 20 2d 20 61 6c 6c 20   barriers - all 
1030: 77 72 69 74 65 73 20 6c 61 75 6e 63 68 65 64 0a  writes launched.
1040: 2a 2a 20 62 65 66 6f 72 65 20 74 68 65 20 78 53  ** before the xS
1050: 79 6e 63 20 6d 75 73 74 20 63 6f 6d 70 6c 65 74  ync must complet
1060: 65 20 62 65 66 6f 72 65 20 61 6e 79 20 77 72 69  e before any wri
1070: 74 65 20 74 68 61 74 20 6c 61 75 6e 63 68 65 73  te that launches
1080: 20 61 66 74 65 72 20 74 68 65 0a 2a 2a 20 78 53   after the.** xS
1090: 79 6e 63 20 62 65 67 69 6e 73 2e 0a 2a 2a 0a 2a  ync begins..**.*
10a0: 2a 20 41 66 74 65 72 20 65 61 63 68 20 63 68 65  * After each che
10b0: 63 6b 70 6f 69 6e 74 2c 20 74 68 65 20 73 61 6c  ckpoint, the sal
10c0: 74 2d 31 20 76 61 6c 75 65 20 69 73 20 69 6e 63  t-1 value is inc
10d0: 72 65 6d 65 6e 74 65 64 20 61 6e 64 20 74 68 65  remented and the
10e0: 20 73 61 6c 74 2d 32 0a 2a 2a 20 76 61 6c 75 65   salt-2.** value
10f0: 20 69 73 20 72 61 6e 64 6f 6d 69 7a 65 64 2e 20   is randomized. 
1100: 20 54 68 69 73 20 70 72 65 76 65 6e 74 73 20 6f   This prevents o
1110: 6c 64 20 61 6e 64 20 6e 65 77 20 66 72 61 6d 65  ld and new frame
1120: 73 20 69 6e 20 74 68 65 20 57 41 4c 20 66 72 6f  s in the WAL fro
1130: 6d 0a 2a 2a 20 62 65 69 6e 67 20 63 6f 6e 73 69  m.** being consi
1140: 64 65 72 65 64 20 76 61 6c 69 64 20 61 74 20 74  dered valid at t
1150: 68 65 20 73 61 6d 65 20 74 69 6d 65 20 61 6e 64  he same time and
1160: 20 62 65 69 6e 67 20 63 68 65 63 6b 70 6f 69 6e   being checkpoin
1170: 74 69 6e 67 20 74 6f 67 65 74 68 65 72 0a 2a 2a  ting together.**
1180: 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 63 72 61   following a cra
1190: 73 68 2e 0a 2a 2a 0a 2a 2a 20 52 45 41 44 45 52  sh..**.** READER
11a0: 20 41 4c 47 4f 52 49 54 48 4d 0a 2a 2a 0a 2a 2a   ALGORITHM.**.**
11b0: 20 54 6f 20 72 65 61 64 20 61 20 70 61 67 65 20   To read a page 
11c0: 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
11d0: 65 20 28 63 61 6c 6c 20 69 74 20 70 61 67 65 20  e (call it page 
11e0: 6e 75 6d 62 65 72 20 50 29 2c 20 61 20 72 65 61  number P), a rea
11f0: 64 65 72 0a 2a 2a 20 66 69 72 73 74 20 63 68 65  der.** first che
1200: 63 6b 73 20 74 68 65 20 57 41 4c 20 74 6f 20 73  cks the WAL to s
1210: 65 65 20 69 66 20 69 74 20 63 6f 6e 74 61 69 6e  ee if it contain
1220: 73 20 70 61 67 65 20 50 2e 20 20 49 66 20 73 6f  s page P.  If so
1230: 2c 20 74 68 65 6e 20 74 68 65 0a 2a 2a 20 6c 61  , then the.** la
1240: 73 74 20 76 61 6c 69 64 20 69 6e 73 74 61 6e 63  st valid instanc
1250: 65 20 6f 66 20 70 61 67 65 20 50 20 74 68 61 74  e of page P that
1260: 20 69 73 20 61 20 66 6f 6c 6c 6f 77 65 64 20 62   is a followed b
1270: 79 20 61 20 63 6f 6d 6d 69 74 20 66 72 61 6d 65  y a commit frame
1280: 0a 2a 2a 20 6f 72 20 69 73 20 61 20 63 6f 6d 6d  .** or is a comm
1290: 69 74 20 66 72 61 6d 65 20 69 74 73 65 6c 66 20  it frame itself 
12a0: 62 65 63 6f 6d 65 73 20 74 68 65 20 76 61 6c 75  becomes the valu
12b0: 65 20 72 65 61 64 2e 20 20 49 66 20 74 68 65 20  e read.  If the 
12c0: 57 41 4c 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20  WAL.** contains 
12d0: 6e 6f 20 63 6f 70 69 65 73 20 6f 66 20 70 61 67  no copies of pag
12e0: 65 20 50 20 74 68 61 74 20 61 72 65 20 76 61 6c  e P that are val
12f0: 69 64 20 61 6e 64 20 77 68 69 63 68 20 61 72 65  id and which are
1300: 20 61 20 63 6f 6d 6d 69 74 0a 2a 2a 20 66 72 61   a commit.** fra
1310: 6d 65 20 6f 72 20 61 72 65 20 66 6f 6c 6c 6f 77  me or are follow
1320: 65 64 20 62 79 20 61 20 63 6f 6d 6d 69 74 20 66  ed by a commit f
1330: 72 61 6d 65 2c 20 74 68 65 6e 20 70 61 67 65 20  rame, then page 
1340: 50 20 69 73 20 72 65 61 64 20 66 72 6f 6d 0a 2a  P is read from.*
1350: 2a 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  * the database f
1360: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 73 74  ile..**.** To st
1370: 61 72 74 20 61 20 72 65 61 64 20 74 72 61 6e 73  art a read trans
1380: 61 63 74 69 6f 6e 2c 20 74 68 65 20 72 65 61 64  action, the read
1390: 65 72 20 72 65 63 6f 72 64 73 20 74 68 65 20 69  er records the i
13a0: 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 73 74  ndex of the last
13b0: 0a 2a 2a 20 76 61 6c 69 64 20 66 72 61 6d 65 20  .** valid frame 
13c0: 69 6e 20 74 68 65 20 57 41 4c 2e 20 20 54 68 65  in the WAL.  The
13d0: 20 72 65 61 64 65 72 20 75 73 65 73 20 74 68 69   reader uses thi
13e0: 73 20 72 65 63 6f 72 64 65 64 20 22 6d 78 46 72  s recorded "mxFr
13f0: 61 6d 65 22 20 76 61 6c 75 65 0a 2a 2a 20 66 6f  ame" value.** fo
1400: 72 20 61 6c 6c 20 73 75 62 73 65 71 75 65 6e 74  r all subsequent
1410: 20 72 65 61 64 20 6f 70 65 72 61 74 69 6f 6e 73   read operations
1420: 2e 20 20 4e 65 77 20 74 72 61 6e 73 61 63 74 69  .  New transacti
1430: 6f 6e 73 20 63 61 6e 20 62 65 20 61 70 70 65 6e  ons can be appen
1440: 64 65 64 0a 2a 2a 20 74 6f 20 74 68 65 20 57 41  ded.** to the WA
1450: 4c 2c 20 62 75 74 20 61 73 20 6c 6f 6e 67 20 61  L, but as long a
1460: 73 20 74 68 65 20 72 65 61 64 65 72 20 75 73 65  s the reader use
1470: 73 20 69 74 73 20 6f 72 69 67 69 6e 61 6c 20 6d  s its original m
1480: 78 46 72 61 6d 65 20 76 61 6c 75 65 0a 2a 2a 20  xFrame value.** 
1490: 61 6e 64 20 69 67 6e 6f 72 65 73 20 74 68 65 20  and ignores the 
14a0: 6e 65 77 6c 79 20 61 70 70 65 6e 64 65 64 20 63  newly appended c
14b0: 6f 6e 74 65 6e 74 2c 20 69 74 20 77 69 6c 6c 20  ontent, it will 
14c0: 73 65 65 20 61 20 63 6f 6e 73 69 73 74 65 6e 74  see a consistent
14d0: 20 73 6e 61 70 73 68 6f 74 0a 2a 2a 20 6f 66 20   snapshot.** of 
14e0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 72 6f  the database fro
14f0: 6d 20 61 20 73 69 6e 67 6c 65 20 70 6f 69 6e 74  m a single point
1500: 20 69 6e 20 74 69 6d 65 2e 20 20 54 68 69 73 20   in time.  This 
1510: 74 65 63 68 6e 69 71 75 65 20 61 6c 6c 6f 77 73  technique allows
1520: 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 63 6f 6e  .** multiple con
1530: 63 75 72 72 65 6e 74 20 72 65 61 64 65 72 73 20  current readers 
1540: 74 6f 20 76 69 65 77 20 64 69 66 66 65 72 65 6e  to view differen
1550: 74 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68  t versions of th
1560: 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 63 6f  e database.** co
1570: 6e 74 65 6e 74 20 73 69 6d 75 6c 74 61 6e 65 6f  ntent simultaneo
1580: 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  usly..**.** The 
1590: 72 65 61 64 65 72 20 61 6c 67 6f 72 69 74 68 6d  reader algorithm
15a0: 20 69 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73   in the previous
15b0: 20 70 61 72 61 67 72 61 70 68 73 20 77 6f 72 6b   paragraphs work
15c0: 73 20 63 6f 72 72 65 63 74 6c 79 2c 20 62 75 74  s correctly, but
15d0: 20 0a 2a 2a 20 62 65 63 61 75 73 65 20 66 72 61   .** because fra
15e0: 6d 65 73 20 66 6f 72 20 70 61 67 65 20 50 20 63  mes for page P c
15f0: 61 6e 20 61 70 70 65 61 72 20 61 6e 79 77 68 65  an appear anywhe
1600: 72 65 20 77 69 74 68 69 6e 20 74 68 65 20 57 41  re within the WA
1610: 4c 2c 20 74 68 65 0a 2a 2a 20 72 65 61 64 65 72  L, the.** reader
1620: 20 68 61 73 20 74 6f 20 73 63 61 6e 20 74 68 65   has to scan the
1630: 20 65 6e 74 69 72 65 20 57 41 4c 20 6c 6f 6f 6b   entire WAL look
1640: 69 6e 67 20 66 6f 72 20 70 61 67 65 20 50 20 66  ing for page P f
1650: 72 61 6d 65 73 2e 20 20 49 66 20 74 68 65 0a 2a  rames.  If the.*
1660: 2a 20 57 41 4c 20 69 73 20 6c 61 72 67 65 20 28  * WAL is large (
1670: 6d 75 6c 74 69 70 6c 65 20 6d 65 67 61 62 79 74  multiple megabyt
1680: 65 73 20 69 73 20 74 79 70 69 63 61 6c 29 20 74  es is typical) t
1690: 68 61 74 20 73 63 61 6e 20 63 61 6e 20 62 65 20  hat scan can be 
16a0: 73 6c 6f 77 2c 0a 2a 2a 20 61 6e 64 20 72 65 61  slow,.** and rea
16b0: 64 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 73 75  d performance su
16c0: 66 66 65 72 73 2e 20 20 54 6f 20 6f 76 65 72 63  ffers.  To overc
16d0: 6f 6d 65 20 74 68 69 73 20 70 72 6f 62 6c 65 6d  ome this problem
16e0: 2c 20 61 20 73 65 70 61 72 61 74 65 0a 2a 2a 20  , a separate.** 
16f0: 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20 63  data structure c
1700: 61 6c 6c 65 64 20 74 68 65 20 77 61 6c 2d 69 6e  alled the wal-in
1710: 64 65 78 20 69 73 20 6d 61 69 6e 74 61 69 6e 65  dex is maintaine
1720: 64 20 74 6f 20 65 78 70 65 64 69 74 65 20 74 68  d to expedite th
1730: 65 0a 2a 2a 20 73 65 61 72 63 68 20 66 6f 72 20  e.** search for 
1740: 66 72 61 6d 65 73 20 6f 66 20 61 20 70 61 72 74  frames of a part
1750: 69 63 75 6c 61 72 20 70 61 67 65 2e 0a 2a 2a 20  icular page..** 
1760: 0a 2a 2a 20 57 41 4c 2d 49 4e 44 45 58 20 46 4f  .** WAL-INDEX FO
1770: 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 43 6f 6e 63 65  RMAT.**.** Conce
1780: 70 74 75 61 6c 6c 79 2c 20 74 68 65 20 77 61 6c  ptually, the wal
1790: 2d 69 6e 64 65 78 20 69 73 20 73 68 61 72 65 64  -index is shared
17a0: 20 6d 65 6d 6f 72 79 2c 20 74 68 6f 75 67 68 20   memory, though 
17b0: 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  VFS implementati
17c0: 6f 6e 73 0a 2a 2a 20 6d 69 67 68 74 20 63 68 6f  ons.** might cho
17d0: 6f 73 65 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  ose to implement
17e0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 75   the wal-index u
17f0: 73 69 6e 67 20 61 20 6d 6d 61 70 70 65 64 20 66  sing a mmapped f
1800: 69 6c 65 2e 20 20 42 65 63 61 75 73 65 0a 2a 2a  ile.  Because.**
1810: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69   the wal-index i
1820: 73 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 2c  s shared memory,
1830: 20 53 51 4c 69 74 65 20 64 6f 65 73 20 6e 6f 74   SQLite does not
1840: 20 73 75 70 70 6f 72 74 20 6a 6f 75 72 6e 61 6c   support journal
1850: 5f 6d 6f 64 65 3d 57 41 4c 20 0a 2a 2a 20 6f 6e  _mode=WAL .** on
1860: 20 61 20 6e 65 74 77 6f 72 6b 20 66 69 6c 65 73   a network files
1870: 79 73 74 65 6d 2e 20 20 41 6c 6c 20 75 73 65 72  ystem.  All user
1880: 73 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  s of the databas
1890: 65 20 6d 75 73 74 20 62 65 20 61 62 6c 65 20 74  e must be able t
18a0: 6f 0a 2a 2a 20 73 68 61 72 65 20 6d 65 6d 6f 72  o.** share memor
18b0: 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61 6c  y..**.** The wal
18c0: 2d 69 6e 64 65 78 20 69 73 20 74 72 61 6e 73 69  -index is transi
18d0: 65 6e 74 2e 20 20 41 66 74 65 72 20 61 20 63 72  ent.  After a cr
18e0: 61 73 68 2c 20 74 68 65 20 77 61 6c 2d 69 6e 64  ash, the wal-ind
18f0: 65 78 20 63 61 6e 20 28 61 6e 64 20 73 68 6f 75  ex can (and shou
1900: 6c 64 0a 2a 2a 20 62 65 29 20 72 65 63 6f 6e 73  ld.** be) recons
1910: 74 72 75 63 74 65 64 20 66 72 6f 6d 20 74 68 65  tructed from the
1920: 20 6f 72 69 67 69 6e 61 6c 20 57 41 4c 20 66 69   original WAL fi
1930: 6c 65 2e 20 20 49 6e 20 66 61 63 74 2c 20 74 68  le.  In fact, th
1940: 65 20 56 46 53 20 69 73 20 72 65 71 75 69 72 65  e VFS is require
1950: 64 0a 2a 2a 20 74 6f 20 65 69 74 68 65 72 20 74  d.** to either t
1960: 72 75 6e 63 61 74 65 20 6f 72 20 7a 65 72 6f 20  runcate or zero 
1970: 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 74 68  the header of th
1980: 65 20 77 61 6c 2d 69 6e 64 65 78 20 77 68 65 6e  e wal-index when
1990: 20 74 68 65 20 6c 61 73 74 0a 2a 2a 20 63 6f 6e   the last.** con
19a0: 6e 65 63 74 69 6f 6e 20 74 6f 20 69 74 20 63 6c  nection to it cl
19b0: 6f 73 65 73 2e 20 20 42 65 63 61 75 73 65 20 74  oses.  Because t
19c0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
19d0: 74 72 61 6e 73 69 65 6e 74 2c 20 69 74 20 63 61  transient, it ca
19e0: 6e 0a 2a 2a 20 75 73 65 20 61 6e 20 61 72 63 68  n.** use an arch
19f0: 69 74 65 63 74 75 72 65 2d 73 70 65 63 69 66 69  itecture-specifi
1a00: 63 20 66 6f 72 6d 61 74 3b 20 69 74 20 64 6f 65  c format; it doe
1a10: 73 20 6e 6f 74 20 68 61 76 65 20 74 6f 20 62 65  s not have to be
1a20: 20 63 72 6f 73 73 2d 70 6c 61 74 66 6f 72 6d 2e   cross-platform.
1a30: 0a 2a 2a 20 48 65 6e 63 65 2c 20 75 6e 6c 69 6b  .** Hence, unlik
1a40: 65 20 74 68 65 20 64 61 74 61 62 61 73 65 20 61  e the database a
1a50: 6e 64 20 57 41 4c 20 66 69 6c 65 20 66 6f 72 6d  nd WAL file form
1a60: 61 74 73 20 77 68 69 63 68 20 73 74 6f 72 65 20  ats which store 
1a70: 61 6c 6c 20 76 61 6c 75 65 73 0a 2a 2a 20 61 73  all values.** as
1a80: 20 62 69 67 20 65 6e 64 69 61 6e 2c 20 74 68 65   big endian, the
1a90: 20 77 61 6c 2d 69 6e 64 65 78 20 63 61 6e 20 73   wal-index can s
1aa0: 74 6f 72 65 20 6d 75 6c 74 69 2d 62 79 74 65 20  tore multi-byte 
1ab0: 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 6e 61  values in the na
1ac0: 74 69 76 65 0a 2a 2a 20 62 79 74 65 20 6f 72 64  tive.** byte ord
1ad0: 65 72 20 6f 66 20 74 68 65 20 68 6f 73 74 20 63  er of the host c
1ae0: 6f 6d 70 75 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54  omputer..**.** T
1af0: 68 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74 68  he purpose of th
1b00: 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 74  e wal-index is t
1b10: 6f 20 61 6e 73 77 65 72 20 74 68 69 73 20 71 75  o answer this qu
1b20: 65 73 74 69 6f 6e 20 71 75 69 63 6b 6c 79 3a 20  estion quickly: 
1b30: 20 47 69 76 65 6e 0a 2a 2a 20 61 20 70 61 67 65   Given.** a page
1b40: 20 6e 75 6d 62 65 72 20 50 20 61 6e 64 20 61 20   number P and a 
1b50: 6d 61 78 69 6d 75 6d 20 66 72 61 6d 65 20 69 6e  maximum frame in
1b60: 64 65 78 20 4d 2c 20 72 65 74 75 72 6e 20 74 68  dex M, return th
1b70: 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 0a  e index of the .
1b80: 2a 2a 20 6c 61 73 74 20 66 72 61 6d 65 20 69 6e  ** last frame in
1b90: 20 74 68 65 20 77 61 6c 20 62 65 66 6f 72 65 20   the wal before 
1ba0: 66 72 61 6d 65 20 4d 20 66 6f 72 20 70 61 67 65  frame M for page
1bb0: 20 50 20 69 6e 20 74 68 65 20 57 41 4c 2c 20 6f   P in the WAL, o
1bc0: 72 20 72 65 74 75 72 6e 0a 2a 2a 20 4e 55 4c 4c  r return.** NULL
1bd0: 20 69 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f   if there are no
1be0: 20 66 72 61 6d 65 73 20 66 6f 72 20 70 61 67 65   frames for page
1bf0: 20 50 20 69 6e 20 74 68 65 20 57 41 4c 20 70 72   P in the WAL pr
1c00: 69 6f 72 20 74 6f 20 4d 2e 0a 2a 2a 0a 2a 2a 20  ior to M..**.** 
1c10: 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f  The wal-index co
1c20: 6e 73 69 73 74 73 20 6f 66 20 61 20 68 65 61 64  nsists of a head
1c30: 65 72 20 72 65 67 69 6f 6e 2c 20 66 6f 6c 6c 6f  er region, follo
1c40: 77 65 64 20 62 79 20 61 6e 20 6f 6e 65 20 6f 72  wed by an one or
1c50: 0a 2a 2a 20 6d 6f 72 65 20 69 6e 64 65 78 20 62  .** more index b
1c60: 6c 6f 63 6b 73 2e 20 20 0a 2a 2a 0a 2a 2a 20 54  locks.  .**.** T
1c70: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
1c80: 64 65 72 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  der contains the
1c90: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
1ca0: 20 66 72 61 6d 65 73 20 77 69 74 68 69 6e 20 74   frames within t
1cb0: 68 65 20 57 41 4c 0a 2a 2a 20 69 6e 20 74 68 65  he WAL.** in the
1cc0: 20 6d 78 46 72 61 6d 65 20 66 69 65 6c 64 2e 0a   mxFrame field..
1cd0: 2a 2a 0a 2a 2a 20 45 61 63 68 20 69 6e 64 65 78  **.** Each index
1ce0: 20 62 6c 6f 63 6b 20 65 78 63 65 70 74 20 66 6f   block except fo
1cf0: 72 20 74 68 65 20 66 69 72 73 74 20 63 6f 6e 74  r the first cont
1d00: 61 69 6e 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  ains information
1d10: 20 6f 6e 20 0a 2a 2a 20 48 41 53 48 54 41 42 4c   on .** HASHTABL
1d20: 45 5f 4e 50 41 47 45 20 66 72 61 6d 65 73 2e 20  E_NPAGE frames. 
1d30: 54 68 65 20 66 69 72 73 74 20 69 6e 64 65 78 20  The first index 
1d40: 62 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20 69  block contains i
1d50: 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f 6e 0a 2a 2a  nformation on.**
1d60: 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45   HASHTABLE_NPAGE
1d70: 5f 4f 4e 45 20 66 72 61 6d 65 73 2e 20 54 68 65  _ONE frames. The
1d80: 20 76 61 6c 75 65 73 20 6f 66 20 48 41 53 48 54   values of HASHT
1d90: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20 61  ABLE_NPAGE_ONE a
1da0: 6e 64 20 0a 2a 2a 20 48 41 53 48 54 41 42 4c 45  nd .** HASHTABLE
1db0: 5f 4e 50 41 47 45 20 61 72 65 20 73 65 6c 65 63  _NPAGE are selec
1dc0: 74 65 64 20 73 6f 20 74 68 61 74 20 74 6f 67 65  ted so that toge
1dd0: 74 68 65 72 20 74 68 65 20 77 61 6c 2d 69 6e 64  ther the wal-ind
1de0: 65 78 20 68 65 61 64 65 72 20 61 6e 64 0a 2a 2a  ex header and.**
1df0: 20 66 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f   first index blo
1e00: 63 6b 20 61 72 65 20 74 68 65 20 73 61 6d 65 20  ck are the same 
1e10: 73 69 7a 65 20 61 73 20 61 6c 6c 20 6f 74 68 65  size as all othe
1e20: 72 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73 20 69  r index blocks i
1e30: 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64  n the.** wal-ind
1e40: 65 78 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 69  ex..**.** Each i
1e50: 6e 64 65 78 20 62 6c 6f 63 6b 20 63 6f 6e 74 61  ndex block conta
1e60: 69 6e 73 20 74 77 6f 20 73 65 63 74 69 6f 6e 73  ins two sections
1e70: 2c 20 61 20 70 61 67 65 2d 6d 61 70 70 69 6e 67  , a page-mapping
1e80: 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74   that contains t
1e90: 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20 70  he.** database p
1ea0: 61 67 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63  age number assoc
1eb0: 69 61 74 65 64 20 77 69 74 68 20 65 61 63 68 20  iated with each 
1ec0: 77 61 6c 20 66 72 61 6d 65 2c 20 61 6e 64 20 61  wal frame, and a
1ed0: 20 68 61 73 68 2d 74 61 62 6c 65 20 0a 2a 2a 20   hash-table .** 
1ee0: 74 68 61 74 20 61 6c 6c 6f 77 73 20 72 65 61 64  that allows read
1ef0: 65 72 73 20 74 6f 20 71 75 65 72 79 20 61 6e 20  ers to query an 
1f00: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 66 6f 72 20  index block for 
1f10: 61 20 73 70 65 63 69 66 69 63 20 70 61 67 65 20  a specific page 
1f20: 6e 75 6d 62 65 72 2e 0a 2a 2a 20 54 68 65 20 70  number..** The p
1f30: 61 67 65 2d 6d 61 70 70 69 6e 67 20 69 73 20 61  age-mapping is a
1f40: 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53 48 54  n array of HASHT
1f50: 41 42 4c 45 5f 4e 50 41 47 45 20 28 6f 72 20 48  ABLE_NPAGE (or H
1f60: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
1f70: 4e 45 0a 2a 2a 20 66 6f 72 20 74 68 65 20 66 69  NE.** for the fi
1f80: 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 29  rst index block)
1f90: 20 33 32 2d 62 69 74 20 70 61 67 65 20 6e 75 6d   32-bit page num
1fa0: 62 65 72 73 2e 20 54 68 65 20 66 69 72 73 74 20  bers. The first 
1fb0: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 0a 2a 2a  entry in the .**
1fc0: 20 66 69 72 73 74 20 69 6e 64 65 78 2d 62 6c 6f   first index-blo
1fd0: 63 6b 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  ck contains the 
1fe0: 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6e 75  database page nu
1ff0: 6d 62 65 72 20 63 6f 72 72 65 73 70 6f 6e 64 69  mber correspondi
2000: 6e 67 20 74 6f 20 74 68 65 0a 2a 2a 20 66 69 72  ng to the.** fir
2010: 73 74 20 66 72 61 6d 65 20 69 6e 20 74 68 65 20  st frame in the 
2020: 57 41 4c 20 66 69 6c 65 2e 20 54 68 65 20 66 69  WAL file. The fi
2030: 72 73 74 20 65 6e 74 72 79 20 69 6e 20 74 68 65  rst entry in the
2040: 20 73 65 63 6f 6e 64 20 69 6e 64 65 78 20 62 6c   second index bl
2050: 6f 63 6b 0a 2a 2a 20 69 6e 20 74 68 65 20 57 41  ock.** in the WA
2060: 4c 20 66 69 6c 65 20 63 6f 72 72 65 73 70 6f 6e  L file correspon
2070: 64 73 20 74 6f 20 74 68 65 20 28 48 41 53 48 54  ds to the (HASHT
2080: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 31  ABLE_NPAGE_ONE+1
2090: 29 74 68 20 66 72 61 6d 65 20 69 6e 0a 2a 2a 20  )th frame in.** 
20a0: 74 68 65 20 6c 6f 67 2c 20 61 6e 64 20 73 6f 20  the log, and so 
20b0: 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c 61  on..**.** The la
20c0: 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 69  st index block i
20d0: 6e 20 61 20 77 61 6c 2d 69 6e 64 65 78 20 75 73  n a wal-index us
20e0: 75 61 6c 6c 79 20 63 6f 6e 74 61 69 6e 73 20 6c  ually contains l
20f0: 65 73 73 20 74 68 61 6e 20 74 68 65 20 66 75 6c  ess than the ful
2100: 6c 0a 2a 2a 20 63 6f 6d 70 6c 65 6d 65 6e 74 20  l.** complement 
2110: 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  of HASHTABLE_NPA
2120: 47 45 20 28 6f 72 20 48 41 53 48 54 41 42 4c 45  GE (or HASHTABLE
2130: 5f 4e 50 41 47 45 5f 4f 4e 45 29 20 70 61 67 65  _NPAGE_ONE) page
2140: 2d 6e 75 6d 62 65 72 73 2c 0a 2a 2a 20 64 65 70  -numbers,.** dep
2150: 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20 63 6f  ending on the co
2160: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 57 41  ntents of the WA
2170: 4c 20 66 69 6c 65 2e 20 54 68 69 73 20 64 6f 65  L file. This doe
2180: 73 20 6e 6f 74 20 63 68 61 6e 67 65 20 74 68 65  s not change the
2190: 0a 2a 2a 20 61 6c 6c 6f 63 61 74 65 64 20 73 69  .** allocated si
21a0: 7a 65 20 6f 66 20 74 68 65 20 70 61 67 65 2d 6d  ze of the page-m
21b0: 61 70 70 69 6e 67 20 61 72 72 61 79 20 2d 20 74  apping array - t
21c0: 68 65 20 70 61 67 65 2d 6d 61 70 70 69 6e 67 20  he page-mapping 
21d0: 61 72 72 61 79 20 6d 65 72 65 6c 79 0a 2a 2a 20  array merely.** 
21e0: 63 6f 6e 74 61 69 6e 73 20 75 6e 75 73 65 64 20  contains unused 
21f0: 65 6e 74 72 69 65 73 2e 0a 2a 2a 0a 2a 2a 20 45  entries..**.** E
2200: 76 65 6e 20 77 69 74 68 6f 75 74 20 75 73 69 6e  ven without usin
2210: 67 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  g the hash table
2220: 2c 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d 65  , the last frame
2230: 20 66 6f 72 20 70 61 67 65 20 50 0a 2a 2a 20 63   for page P.** c
2240: 61 6e 20 62 65 20 66 6f 75 6e 64 20 62 79 20 73  an be found by s
2250: 63 61 6e 6e 69 6e 67 20 74 68 65 20 70 61 67 65  canning the page
2260: 2d 6d 61 70 70 69 6e 67 20 73 65 63 74 69 6f 6e  -mapping section
2270: 73 20 6f 66 20 65 61 63 68 20 69 6e 64 65 78 20  s of each index 
2280: 62 6c 6f 63 6b 0a 2a 2a 20 73 74 61 72 74 69 6e  block.** startin
2290: 67 20 77 69 74 68 20 74 68 65 20 6c 61 73 74 20  g with the last 
22a0: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 61 6e 64 20  index block and 
22b0: 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20 74 68  moving toward th
22c0: 65 20 66 69 72 73 74 2c 20 61 6e 64 0a 2a 2a 20  e first, and.** 
22d0: 77 69 74 68 69 6e 20 65 61 63 68 20 69 6e 64 65  within each inde
22e0: 78 20 62 6c 6f 63 6b 2c 20 73 74 61 72 74 69 6e  x block, startin
22f0: 67 20 61 74 20 74 68 65 20 65 6e 64 20 61 6e 64  g at the end and
2300: 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20 74   moving toward t
2310: 68 65 0a 2a 2a 20 62 65 67 69 6e 6e 69 6e 67 2e  he.** beginning.
2320: 20 20 54 68 65 20 66 69 72 73 74 20 65 6e 74 72    The first entr
2330: 79 20 74 68 61 74 20 65 71 75 61 6c 73 20 50 20  y that equals P 
2340: 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20 74  corresponds to t
2350: 68 65 20 66 72 61 6d 65 0a 2a 2a 20 68 6f 6c 64  he frame.** hold
2360: 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74 20  ing the content 
2370: 66 6f 72 20 74 68 61 74 20 70 61 67 65 2e 0a 2a  for that page..*
2380: 2a 0a 2a 2a 20 54 68 65 20 68 61 73 68 20 74 61  *.** The hash ta
2390: 62 6c 65 20 63 6f 6e 73 69 73 74 73 20 6f 66 20  ble consists of 
23a0: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20  HASHTABLE_NSLOT 
23b0: 31 36 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20  16-bit unsigned 
23c0: 69 6e 74 65 67 65 72 73 2e 0a 2a 2a 20 48 41 53  integers..** HAS
23d0: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 3d 20 32  HTABLE_NSLOT = 2
23e0: 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  *HASHTABLE_NPAGE
23f0: 2c 20 61 6e 64 20 74 68 65 72 65 20 69 73 20 6f  , and there is o
2400: 6e 65 20 65 6e 74 72 79 20 69 6e 20 74 68 65 0a  ne entry in the.
2410: 2a 2a 20 68 61 73 68 20 74 61 62 6c 65 20 66 6f  ** hash table fo
2420: 72 20 65 61 63 68 20 70 61 67 65 20 6e 75 6d 62  r each page numb
2430: 65 72 20 69 6e 20 74 68 65 20 6d 61 70 70 69 6e  er in the mappin
2440: 67 20 73 65 63 74 69 6f 6e 2c 20 73 6f 20 74 68  g section, so th
2450: 65 20 68 61 73 68 20 0a 2a 2a 20 74 61 62 6c 65  e hash .** table
2460: 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20 74   is never more t
2470: 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2e 20 20  han half full.  
2480: 54 68 65 20 65 78 70 65 63 74 65 64 20 6e 75 6d  The expected num
2490: 62 65 72 20 6f 66 20 63 6f 6c 6c 69 73 69 6f 6e  ber of collision
24a0: 73 20 0a 2a 2a 20 70 72 69 6f 72 20 74 6f 20 66  s .** prior to f
24b0: 69 6e 64 69 6e 67 20 61 20 6d 61 74 63 68 20 69  inding a match i
24c0: 73 20 31 2e 20 20 45 61 63 68 20 65 6e 74 72 79  s 1.  Each entry
24d0: 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61 62   of the hash tab
24e0: 6c 65 20 69 73 20 61 6e 0a 2a 2a 20 31 2d 62 61  le is an.** 1-ba
24f0: 73 65 64 20 69 6e 64 65 78 20 6f 66 20 61 6e 20  sed index of an 
2500: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61 70  entry in the map
2510: 70 69 6e 67 20 73 65 63 74 69 6f 6e 20 6f 66 20  ping section of 
2520: 74 68 65 20 73 61 6d 65 0a 2a 2a 20 69 6e 64 65  the same.** inde
2530: 78 20 62 6c 6f 63 6b 2e 20 20 20 4c 65 74 20 4b  x block.   Let K
2540: 20 62 65 20 74 68 65 20 31 2d 62 61 73 65 64 20   be the 1-based 
2550: 69 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 72  index of the lar
2560: 67 65 73 74 20 65 6e 74 72 79 20 69 6e 0a 2a 2a  gest entry in.**
2570: 20 74 68 65 20 6d 61 70 70 69 6e 67 20 73 65 63   the mapping sec
2580: 74 69 6f 6e 2e 20 20 28 46 6f 72 20 69 6e 64 65  tion.  (For inde
2590: 78 20 62 6c 6f 63 6b 73 20 6f 74 68 65 72 20 74  x blocks other t
25a0: 68 61 6e 20 74 68 65 20 6c 61 73 74 2c 20 4b 20  han the last, K 
25b0: 77 69 6c 6c 0a 2a 2a 20 61 6c 77 61 79 73 20 62  will.** always b
25c0: 65 20 65 78 61 63 74 6c 79 20 48 41 53 48 54 41  e exactly HASHTA
25d0: 42 4c 45 5f 4e 50 41 47 45 20 28 34 30 39 36 29  BLE_NPAGE (4096)
25e0: 20 61 6e 64 20 66 6f 72 20 74 68 65 20 6c 61 73   and for the las
25f0: 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 0a 2a 2a  t index block.**
2600: 20 4b 20 77 69 6c 6c 20 62 65 20 28 6d 78 46 72   K will be (mxFr
2610: 61 6d 65 25 48 41 53 48 54 41 42 4c 45 5f 4e 50  ame%HASHTABLE_NP
2620: 41 47 45 29 2e 29 20 20 55 6e 75 73 65 64 20 73  AGE).)  Unused s
2630: 6c 6f 74 73 20 6f 66 20 74 68 65 20 68 61 73 68  lots of the hash
2640: 20 74 61 62 6c 65 0a 2a 2a 20 63 6f 6e 74 61 69   table.** contai
2650: 6e 20 61 20 76 61 6c 75 65 20 6f 66 20 30 2e 0a  n a value of 0..
2660: 2a 2a 0a 2a 2a 20 54 6f 20 6c 6f 6f 6b 20 66 6f  **.** To look fo
2670: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
2680: 68 61 73 68 20 74 61 62 6c 65 2c 20 66 69 72 73  hash table, firs
2690: 74 20 63 6f 6d 70 75 74 65 20 61 20 68 61 73 68  t compute a hash
26a0: 20 69 4b 65 79 20 6f 6e 0a 2a 2a 20 50 20 61 73   iKey on.** P as
26b0: 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20   follows:.**.** 
26c0: 20 20 20 20 20 69 4b 65 79 20 3d 20 28 50 20 2a       iKey = (P *
26d0: 20 33 38 33 29 20 25 20 48 41 53 48 54 41 42 4c   383) % HASHTABL
26e0: 45 5f 4e 53 4c 4f 54 0a 2a 2a 0a 2a 2a 20 54 68  E_NSLOT.**.** Th
26f0: 65 6e 20 73 74 61 72 74 20 73 63 61 6e 6e 69 6e  en start scannin
2700: 67 20 65 6e 74 72 69 65 73 20 6f 66 20 74 68 65  g entries of the
2710: 20 68 61 73 68 20 74 61 62 6c 65 2c 20 73 74 61   hash table, sta
2720: 72 74 69 6e 67 20 77 69 74 68 20 69 4b 65 79 0a  rting with iKey.
2730: 2a 2a 20 28 77 72 61 70 70 69 6e 67 20 61 72 6f  ** (wrapping aro
2740: 75 6e 64 20 74 6f 20 74 68 65 20 62 65 67 69 6e  und to the begin
2750: 6e 69 6e 67 20 77 68 65 6e 20 74 68 65 20 65 6e  ning when the en
2760: 64 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61  d of the hash ta
2770: 62 6c 65 20 69 73 0a 2a 2a 20 72 65 61 63 68 65  ble is.** reache
2780: 64 29 20 75 6e 74 69 6c 20 61 6e 20 75 6e 75 73  d) until an unus
2790: 65 64 20 68 61 73 68 20 73 6c 6f 74 20 69 73 20  ed hash slot is 
27a0: 66 6f 75 6e 64 2e 20 4c 65 74 20 74 68 65 20 66  found. Let the f
27b0: 69 72 73 74 20 75 6e 75 73 65 64 20 73 6c 6f 74  irst unused slot
27c0: 0a 2a 2a 20 62 65 20 61 74 20 69 6e 64 65 78 20  .** be at index 
27d0: 69 55 6e 75 73 65 64 2e 20 20 28 69 55 6e 75 73  iUnused.  (iUnus
27e0: 65 64 20 6d 69 67 68 74 20 62 65 20 6c 65 73 73  ed might be less
27f0: 20 74 68 61 6e 20 69 4b 65 79 20 69 66 20 74 68   than iKey if th
2800: 65 72 65 20 77 61 73 0a 2a 2a 20 77 72 61 70 2d  ere was.** wrap-
2810: 61 72 6f 75 6e 64 2e 29 20 42 65 63 61 75 73 65  around.) Because
2820: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
2830: 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20 74 68  is never more th
2840: 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2c 0a 2a 2a  an half full,.**
2850: 20 74 68 65 20 73 65 61 72 63 68 20 69 73 20 67   the search is g
2860: 75 61 72 61 6e 74 65 65 64 20 74 6f 20 65 76 65  uaranteed to eve
2870: 6e 74 75 61 6c 6c 79 20 68 69 74 20 61 6e 20 75  ntually hit an u
2880: 6e 75 73 65 64 20 65 6e 74 72 79 2e 20 20 4c 65  nused entry.  Le
2890: 74 20 0a 2a 2a 20 69 4d 61 78 20 62 65 20 74 68  t .** iMax be th
28a0: 65 20 76 61 6c 75 65 20 62 65 74 77 65 65 6e 20  e value between 
28b0: 69 4b 65 79 20 61 6e 64 20 69 55 6e 75 73 65 64  iKey and iUnused
28c0: 2c 20 63 6c 6f 73 65 73 74 20 74 6f 20 69 55 6e  , closest to iUn
28d0: 75 73 65 64 2c 0a 2a 2a 20 77 68 65 72 65 20 61  used,.** where a
28e0: 48 61 73 68 5b 69 4d 61 78 5d 3d 3d 50 2e 20 20  Hash[iMax]==P.  
28f0: 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 69  If there is no i
2900: 4d 61 78 20 65 6e 74 72 79 20 28 69 66 20 74 68  Max entry (if th
2910: 65 72 65 20 65 78 69 73 74 73 0a 2a 2a 20 6e 6f  ere exists.** no
2920: 20 68 61 73 68 20 73 6c 6f 74 20 73 75 63 68 20   hash slot such 
2930: 74 68 61 74 20 61 48 61 73 68 5b 69 5d 3d 3d 70  that aHash[i]==p
2940: 29 20 74 68 65 6e 20 70 61 67 65 20 50 20 69 73  ) then page P is
2950: 20 6e 6f 74 20 69 6e 20 74 68 65 0a 2a 2a 20 63   not in the.** c
2960: 75 72 72 65 6e 74 20 69 6e 64 65 78 20 62 6c 6f  urrent index blo
2970: 63 6b 2e 20 20 4f 74 68 65 72 77 69 73 65 20 74  ck.  Otherwise t
2980: 68 65 20 69 4d 61 78 2d 74 68 20 6d 61 70 70 69  he iMax-th mappi
2990: 6e 67 20 65 6e 74 72 79 20 6f 66 20 74 68 65 0a  ng entry of the.
29a0: 2a 2a 20 63 75 72 72 65 6e 74 20 69 6e 64 65 78  ** current index
29b0: 20 62 6c 6f 63 6b 20 63 6f 72 72 65 73 70 6f 6e   block correspon
29c0: 64 73 20 74 6f 20 74 68 65 20 6c 61 73 74 20 65  ds to the last e
29d0: 6e 74 72 79 20 74 68 61 74 20 72 65 66 65 72 65  ntry that refere
29e0: 6e 63 65 73 20 0a 2a 2a 20 70 61 67 65 20 50 2e  nces .** page P.
29f0: 0a 2a 2a 0a 2a 2a 20 41 20 68 61 73 68 20 73 65  .**.** A hash se
2a00: 61 72 63 68 20 62 65 67 69 6e 73 20 77 69 74 68  arch begins with
2a10: 20 74 68 65 20 6c 61 73 74 20 69 6e 64 65 78 20   the last index 
2a20: 62 6c 6f 63 6b 20 61 6e 64 20 6d 6f 76 65 73 20  block and moves 
2a30: 74 6f 77 61 72 64 20 74 68 65 0a 2a 2a 20 66 69  toward the.** fi
2a40: 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 2c  rst index block,
2a50: 20 6c 6f 6f 6b 69 6e 67 20 66 6f 72 20 65 6e 74   looking for ent
2a60: 72 69 65 73 20 63 6f 72 72 65 73 70 6f 6e 64 69  ries correspondi
2a70: 6e 67 20 74 6f 20 70 61 67 65 20 50 2e 20 20 4f  ng to page P.  O
2a80: 6e 0a 2a 2a 20 61 76 65 72 61 67 65 2c 20 6f 6e  n.** average, on
2a90: 6c 79 20 74 77 6f 20 6f 72 20 74 68 72 65 65 20  ly two or three 
2aa0: 73 6c 6f 74 73 20 69 6e 20 65 61 63 68 20 69 6e  slots in each in
2ab0: 64 65 78 20 62 6c 6f 63 6b 20 6e 65 65 64 20 74  dex block need t
2ac0: 6f 20 62 65 0a 2a 2a 20 65 78 61 6d 69 6e 65 64  o be.** examined
2ad0: 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 65 69 74   in order to eit
2ae0: 68 65 72 20 66 69 6e 64 20 74 68 65 20 6c 61 73  her find the las
2af0: 74 20 65 6e 74 72 79 20 66 6f 72 20 70 61 67 65  t entry for page
2b00: 20 50 2c 20 6f 72 20 74 6f 0a 2a 2a 20 65 73 74   P, or to.** est
2b10: 61 62 6c 69 73 68 20 74 68 61 74 20 6e 6f 20 73  ablish that no s
2b20: 75 63 68 20 65 6e 74 72 79 20 65 78 69 73 74 73  uch entry exists
2b30: 20 69 6e 20 74 68 65 20 62 6c 6f 63 6b 2e 20 20   in the block.  
2b40: 45 61 63 68 20 69 6e 64 65 78 20 62 6c 6f 63 6b  Each index block
2b50: 0a 2a 2a 20 68 6f 6c 64 73 20 6f 76 65 72 20 34  .** holds over 4
2b60: 30 30 30 20 65 6e 74 72 69 65 73 2e 20 20 53 6f  000 entries.  So
2b70: 20 74 77 6f 20 6f 72 20 74 68 72 65 65 20 69 6e   two or three in
2b80: 64 65 78 20 62 6c 6f 63 6b 73 20 61 72 65 20 73  dex blocks are s
2b90: 75 66 66 69 63 69 65 6e 74 0a 2a 2a 20 74 6f 20  ufficient.** to 
2ba0: 63 6f 76 65 72 20 61 20 74 79 70 69 63 61 6c 20  cover a typical 
2bb0: 31 30 20 6d 65 67 61 62 79 74 65 20 57 41 4c 20  10 megabyte WAL 
2bc0: 66 69 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20 31  file, assuming 1
2bd0: 4b 20 70 61 67 65 73 2e 20 20 38 20 6f 72 20 31  K pages.  8 or 1
2be0: 30 0a 2a 2a 20 63 6f 6d 70 61 72 69 73 6f 6e 73  0.** comparisons
2bf0: 20 28 6f 6e 20 61 76 65 72 61 67 65 29 20 73 75   (on average) su
2c00: 66 66 69 63 65 20 74 6f 20 65 69 74 68 65 72 20  ffice to either 
2c10: 6c 6f 63 61 74 65 20 61 20 66 72 61 6d 65 20 69  locate a frame i
2c20: 6e 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6f 72 20  n the.** WAL or 
2c30: 74 6f 20 65 73 74 61 62 6c 69 73 68 20 74 68 61  to establish tha
2c40: 74 20 74 68 65 20 66 72 61 6d 65 20 64 6f 65 73  t the frame does
2c50: 20 6e 6f 74 20 65 78 69 73 74 20 69 6e 20 74 68   not exist in th
2c60: 65 20 57 41 4c 2e 20 20 54 68 69 73 0a 2a 2a 20  e WAL.  This.** 
2c70: 69 73 20 6d 75 63 68 20 66 61 73 74 65 72 20 74  is much faster t
2c80: 68 61 6e 20 73 63 61 6e 6e 69 6e 67 20 74 68 65  han scanning the
2c90: 20 65 6e 74 69 72 65 20 31 30 4d 42 20 57 41 4c   entire 10MB WAL
2ca0: 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61  ..**.** Note tha
2cb0: 74 20 65 6e 74 72 69 65 73 20 61 72 65 20 61 64  t entries are ad
2cc0: 64 65 64 20 69 6e 20 6f 72 64 65 72 20 6f 66 20  ded in order of 
2cd0: 69 6e 63 72 65 61 73 69 6e 67 20 4b 2e 20 20 48  increasing K.  H
2ce0: 65 6e 63 65 2c 20 6f 6e 65 0a 2a 2a 20 72 65 61  ence, one.** rea
2cf0: 64 65 72 20 6d 69 67 68 74 20 62 65 20 75 73 69  der might be usi
2d00: 6e 67 20 73 6f 6d 65 20 76 61 6c 75 65 20 4b 30  ng some value K0
2d10: 20 61 6e 64 20 61 20 73 65 63 6f 6e 64 20 72 65   and a second re
2d20: 61 64 65 72 20 74 68 61 74 20 73 74 61 72 74 65  ader that starte
2d30: 64 0a 2a 2a 20 61 74 20 61 20 6c 61 74 65 72 20  d.** at a later 
2d40: 74 69 6d 65 20 28 61 66 74 65 72 20 61 64 64 69  time (after addi
2d50: 74 69 6f 6e 61 6c 20 74 72 61 6e 73 61 63 74 69  tional transacti
2d60: 6f 6e 73 20 77 65 72 65 20 61 64 64 65 64 20 74  ons were added t
2d70: 6f 20 74 68 65 20 57 41 4c 0a 2a 2a 20 61 6e 64  o the WAL.** and
2d80: 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   to the wal-inde
2d90: 78 29 20 6d 69 67 68 74 20 62 65 20 75 73 69 6e  x) might be usin
2da0: 67 20 61 20 64 69 66 66 65 72 65 6e 74 20 76 61  g a different va
2db0: 6c 75 65 20 4b 31 2c 20 77 68 65 72 65 20 4b 31  lue K1, where K1
2dc0: 3e 4b 30 2e 0a 2a 2a 20 42 6f 74 68 20 72 65 61  >K0..** Both rea
2dd0: 64 65 72 73 20 63 61 6e 20 75 73 65 20 74 68 65  ders can use the
2de0: 20 73 61 6d 65 20 68 61 73 68 20 74 61 62 6c 65   same hash table
2df0: 20 61 6e 64 20 6d 61 70 70 69 6e 67 20 73 65 63   and mapping sec
2e00: 74 69 6f 6e 20 74 6f 20 67 65 74 0a 2a 2a 20 74  tion to get.** t
2e10: 68 65 20 63 6f 72 72 65 63 74 20 72 65 73 75 6c  he correct resul
2e20: 74 2e 20 20 54 68 65 72 65 20 6d 61 79 20 62 65  t.  There may be
2e30: 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20   entries in the 
2e40: 68 61 73 68 20 74 61 62 6c 65 20 77 69 74 68 0a  hash table with.
2e50: 2a 2a 20 4b 3e 4b 30 20 62 75 74 20 74 6f 20 74  ** K>K0 but to t
2e60: 68 65 20 66 69 72 73 74 20 72 65 61 64 65 72 2c  he first reader,
2e70: 20 74 68 6f 73 65 20 65 6e 74 72 69 65 73 20 77   those entries w
2e80: 69 6c 6c 20 61 70 70 65 61 72 20 74 6f 20 62 65  ill appear to be
2e90: 20 75 6e 75 73 65 64 0a 2a 2a 20 73 6c 6f 74 73   unused.** slots
2ea0: 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62   in the hash tab
2eb0: 6c 65 20 61 6e 64 20 73 6f 20 74 68 65 20 66 69  le and so the fi
2ec0: 72 73 74 20 72 65 61 64 65 72 20 77 69 6c 6c 20  rst reader will 
2ed0: 67 65 74 20 61 6e 20 61 6e 73 77 65 72 20 61 73  get an answer as
2ee0: 0a 2a 2a 20 69 66 20 6e 6f 20 76 61 6c 75 65 73  .** if no values
2ef0: 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 4b 30   greater than K0
2f00: 20 68 61 64 20 65 76 65 72 20 62 65 65 6e 20 69   had ever been i
2f10: 6e 73 65 72 74 65 64 20 69 6e 74 6f 20 74 68 65  nserted into the
2f20: 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20 69   hash table.** i
2f30: 6e 20 74 68 65 20 66 69 72 73 74 20 70 6c 61 63  n the first plac
2f40: 65 20 2d 20 77 68 69 63 68 20 69 73 20 77 68 61  e - which is wha
2f50: 74 20 72 65 61 64 65 72 20 6f 6e 65 20 77 61 6e  t reader one wan
2f60: 74 73 2e 20 20 4d 65 61 6e 77 68 69 6c 65 2c 20  ts.  Meanwhile, 
2f70: 74 68 65 0a 2a 2a 20 73 65 63 6f 6e 64 20 72 65  the.** second re
2f80: 61 64 65 72 20 75 73 69 6e 67 20 4b 31 20 77 69  ader using K1 wi
2f90: 6c 6c 20 73 65 65 20 61 64 64 69 74 69 6f 6e 61  ll see additiona
2fa0: 6c 20 76 61 6c 75 65 73 20 74 68 61 74 20 77 65  l values that we
2fb0: 72 65 20 69 6e 73 65 72 74 65 64 0a 2a 2a 20 6c  re inserted.** l
2fc0: 61 74 65 72 2c 20 77 68 69 63 68 20 69 73 20 65  ater, which is e
2fd0: 78 61 63 74 6c 79 20 77 68 61 74 20 72 65 61 64  xactly what read
2fe0: 65 72 20 74 77 6f 20 77 61 6e 74 73 2e 20 20 0a  er two wants.  .
2ff0: 2a 2a 0a 2a 2a 20 57 68 65 6e 20 61 20 72 6f 6c  **.** When a rol
3000: 6c 62 61 63 6b 20 6f 63 63 75 72 73 2c 20 74 68  lback occurs, th
3010: 65 20 76 61 6c 75 65 20 6f 66 20 4b 20 69 73 20  e value of K is 
3020: 64 65 63 72 65 61 73 65 64 2e 20 48 61 73 68 20  decreased. Hash 
3030: 74 61 62 6c 65 20 65 6e 74 72 69 65 73 0a 2a 2a  table entries.**
3040: 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64   that correspond
3050: 20 74 6f 20 66 72 61 6d 65 73 20 67 72 65 61 74   to frames great
3060: 65 72 20 74 68 61 6e 20 74 68 65 20 6e 65 77 20  er than the new 
3070: 4b 20 76 61 6c 75 65 20 61 72 65 20 72 65 6d 6f  K value are remo
3080: 76 65 64 0a 2a 2a 20 66 72 6f 6d 20 74 68 65 20  ved.** from the 
3090: 68 61 73 68 20 74 61 62 6c 65 20 61 74 20 74 68  hash table at th
30a0: 69 73 20 70 6f 69 6e 74 2e 0a 2a 2f 0a 23 69 66  is point..*/.#if
30b0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
30c0: 5f 57 41 4c 0a 0a 23 69 6e 63 6c 75 64 65 20 22  _WAL..#include "
30d0: 77 61 6c 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 54 72  wal.h"../*.** Tr
30e0: 61 63 65 20 6f 75 74 70 75 74 20 6d 61 63 72 6f  ace output macro
30f0: 73 0a 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64  s.*/.#if defined
3100: 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26 26  (SQLITE_TEST) &&
3110: 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
3120: 44 45 42 55 47 29 0a 69 6e 74 20 73 71 6c 69 74  DEBUG).int sqlit
3130: 65 33 57 61 6c 54 72 61 63 65 20 3d 20 30 3b 0a  e3WalTrace = 0;.
3140: 23 20 64 65 66 69 6e 65 20 57 41 4c 54 52 41 43  # define WALTRAC
3150: 45 28 58 29 20 20 69 66 28 73 71 6c 69 74 65 33  E(X)  if(sqlite3
3160: 57 61 6c 54 72 61 63 65 29 20 73 71 6c 69 74 65  WalTrace) sqlite
3170: 33 44 65 62 75 67 50 72 69 6e 74 66 20 58 0a 23  3DebugPrintf X.#
3180: 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 57 41  else.# define WA
3190: 4c 54 52 41 43 45 28 58 29 0a 23 65 6e 64 69 66  LTRACE(X).#endif
31a0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 78 69  ../*.** The maxi
31b0: 6d 75 6d 20 28 61 6e 64 20 6f 6e 6c 79 29 20 76  mum (and only) v
31c0: 65 72 73 69 6f 6e 73 20 6f 66 20 74 68 65 20 77  ersions of the w
31d0: 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78  al and wal-index
31e0: 20 66 6f 72 6d 61 74 73 0a 2a 2a 20 74 68 61 74   formats.** that
31f0: 20 6d 61 79 20 62 65 20 69 6e 74 65 72 70 72 65   may be interpre
3200: 74 65 64 20 62 79 20 74 68 69 73 20 76 65 72 73  ted by this vers
3210: 69 6f 6e 20 6f 66 20 53 51 4c 69 74 65 2e 0a 2a  ion of SQLite..*
3220: 2a 0a 2a 2a 20 49 66 20 61 20 63 6c 69 65 6e 74  *.** If a client
3230: 20 62 65 67 69 6e 73 20 72 65 63 6f 76 65 72 69   begins recoveri
3240: 6e 67 20 61 20 57 41 4c 20 66 69 6c 65 20 61 6e  ng a WAL file an
3250: 64 20 66 69 6e 64 73 20 74 68 61 74 20 28 61 29  d finds that (a)
3260: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 0a 2a 2a   the checksum.**
3270: 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 77   values in the w
3280: 61 6c 2d 68 65 61 64 65 72 20 61 72 65 20 63 6f  al-header are co
3290: 72 72 65 63 74 20 61 6e 64 20 28 62 29 20 74 68  rrect and (b) th
32a0: 65 20 76 65 72 73 69 6f 6e 20 66 69 65 6c 64 20  e version field 
32b0: 69 73 20 6e 6f 74 0a 2a 2a 20 57 41 4c 5f 4d 41  is not.** WAL_MA
32c0: 58 5f 56 45 52 53 49 4f 4e 2c 20 72 65 63 6f 76  X_VERSION, recov
32d0: 65 72 79 20 66 61 69 6c 73 20 61 6e 64 20 53 51  ery fails and SQ
32e0: 4c 69 74 65 20 72 65 74 75 72 6e 73 20 53 51 4c  Lite returns SQL
32f0: 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2e 0a 2a 2a  ITE_CANTOPEN..**
3300: 0a 2a 2a 20 53 69 6d 69 6c 61 72 6c 79 2c 20 69  .** Similarly, i
3310: 66 20 61 20 63 6c 69 65 6e 74 20 73 75 63 63 65  f a client succe
3320: 73 73 66 75 6c 6c 79 20 72 65 61 64 73 20 61 20  ssfully reads a 
3330: 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
3340: 20 28 69 2e 65 2e 20 74 68 65 20 0a 2a 2a 20 63   (i.e. the .** c
3350: 68 65 63 6b 73 75 6d 20 74 65 73 74 20 69 73 20  hecksum test is 
3360: 73 75 63 63 65 73 73 66 75 6c 29 20 61 6e 64 20  successful) and 
3370: 66 69 6e 64 73 20 74 68 61 74 20 74 68 65 20 76  finds that the v
3380: 65 72 73 69 6f 6e 20 66 69 65 6c 64 20 69 73 20  ersion field is 
3390: 6e 6f 74 0a 2a 2a 20 57 41 4c 49 4e 44 45 58 5f  not.** WALINDEX_
33a0: 4d 41 58 5f 56 45 52 53 49 4f 4e 2c 20 74 68 65  MAX_VERSION, the
33b0: 6e 20 6e 6f 20 72 65 61 64 2d 74 72 61 6e 73 61  n no read-transa
33c0: 63 74 69 6f 6e 20 69 73 20 6f 70 65 6e 65 64 20  ction is opened 
33d0: 61 6e 64 20 53 51 4c 69 74 65 0a 2a 2a 20 72 65  and SQLite.** re
33e0: 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 43 41 4e  turns SQLITE_CAN
33f0: 54 4f 50 45 4e 2e 0a 2a 2f 0a 23 64 65 66 69 6e  TOPEN..*/.#defin
3400: 65 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49 4f  e WAL_MAX_VERSIO
3410: 4e 20 20 20 20 20 20 33 30 30 37 30 30 30 0a 23  N      3007000.#
3420: 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58 5f  define WALINDEX_
3430: 4d 41 58 5f 56 45 52 53 49 4f 4e 20 33 30 30 37  MAX_VERSION 3007
3440: 30 30 30 0a 0a 2f 2a 0a 2a 2a 20 49 6e 64 69 63  000../*.** Indic
3450: 65 73 20 6f 66 20 76 61 72 69 6f 75 73 20 6c 6f  es of various lo
3460: 63 6b 69 6e 67 20 62 79 74 65 73 2e 20 20 20 57  cking bytes.   W
3470: 41 4c 5f 4e 52 45 41 44 45 52 20 69 73 20 74 68  AL_NREADER is th
3480: 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 61  e number.** of a
3490: 76 61 69 6c 61 62 6c 65 20 72 65 61 64 65 72 20  vailable reader 
34a0: 6c 6f 63 6b 73 20 61 6e 64 20 73 68 6f 75 6c 64  locks and should
34b0: 20 62 65 20 61 74 20 6c 65 61 73 74 20 33 2e 0a   be at least 3..
34c0: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 57  */.#define WAL_W
34d0: 52 49 54 45 5f 4c 4f 43 4b 20 20 20 20 20 20 20  RITE_LOCK       
34e0: 20 20 30 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f    0.#define WAL_
34f0: 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 20 20  ALL_BUT_WRITE   
3500: 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41 4c     1.#define WAL
3510: 5f 43 4b 50 54 5f 4c 4f 43 4b 20 20 20 20 20 20  _CKPT_LOCK      
3520: 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41      1.#define WA
3530: 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20 20  L_RECOVER_LOCK  
3540: 20 20 20 20 20 32 0a 23 64 65 66 69 6e 65 20 57       2.#define W
3550: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 49 29 20  AL_READ_LOCK(I) 
3560: 20 20 20 20 20 20 28 33 2b 28 49 29 29 0a 23 64        (3+(I)).#d
3570: 65 66 69 6e 65 20 57 41 4c 5f 4e 52 45 41 44 45  efine WAL_NREADE
3580: 52 20 20 20 20 20 20 20 20 20 20 20 20 28 53 51  R            (SQ
3590: 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 2d 33  LITE_SHM_NLOCK-3
35a0: 29 0a 0a 0a 2f 2a 20 4f 62 6a 65 63 74 20 64 65  ).../* Object de
35b0: 63 6c 61 72 61 74 69 6f 6e 73 20 2a 2f 0a 74 79  clarations */.ty
35c0: 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61 6c  pedef struct Wal
35d0: 49 6e 64 65 78 48 64 72 20 57 61 6c 49 6e 64 65  IndexHdr WalInde
35e0: 78 48 64 72 3b 0a 74 79 70 65 64 65 66 20 73 74  xHdr;.typedef st
35f0: 72 75 63 74 20 57 61 6c 49 74 65 72 61 74 6f 72  ruct WalIterator
3600: 20 57 61 6c 49 74 65 72 61 74 6f 72 3b 0a 74 79   WalIterator;.ty
3610: 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61 6c  pedef struct Wal
3620: 43 6b 70 74 49 6e 66 6f 20 57 61 6c 43 6b 70 74  CkptInfo WalCkpt
3630: 49 6e 66 6f 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68  Info;.../*.** Th
3640: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65  e following obje
3650: 63 74 20 68 6f 6c 64 73 20 61 20 63 6f 70 79 20  ct holds a copy 
3660: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
3670: 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74 2e   header content.
3680: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63 74 75 61  .**.** The actua
3690: 6c 20 68 65 61 64 65 72 20 69 6e 20 74 68 65 20  l header in the 
36a0: 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69 73  wal-index consis
36b0: 74 73 20 6f 66 20 74 77 6f 20 63 6f 70 69 65 73  ts of two copies
36c0: 20 6f 66 20 74 68 69 73 0a 2a 2a 20 6f 62 6a 65   of this.** obje
36d0: 63 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 7a  ct..**.** The sz
36e0: 50 61 67 65 20 76 61 6c 75 65 20 63 61 6e 20 62  Page value can b
36f0: 65 20 61 6e 79 20 70 6f 77 65 72 20 6f 66 20 32  e any power of 2
3700: 20 62 65 74 77 65 65 6e 20 35 31 32 20 61 6e 64   between 512 and
3710: 20 33 32 37 36 38 2c 20 69 6e 63 6c 75 73 69 76   32768, inclusiv
3720: 65 2e 0a 2a 2a 20 4f 72 20 69 74 20 63 61 6e 20  e..** Or it can 
3730: 62 65 20 31 20 74 6f 20 72 65 70 72 65 73 65 6e  be 1 to represen
3740: 74 20 61 20 36 35 35 33 36 2d 62 79 74 65 20 70  t a 65536-byte p
3750: 61 67 65 2e 20 20 54 68 65 20 6c 61 74 74 65 72  age.  The latter
3760: 20 63 61 73 65 20 77 61 73 0a 2a 2a 20 61 64 64   case was.** add
3770: 65 64 20 69 6e 20 33 2e 37 2e 31 20 77 68 65 6e  ed in 3.7.1 when
3780: 20 73 75 70 70 6f 72 74 20 66 6f 72 20 36 34 4b   support for 64K
3790: 20 70 61 67 65 73 20 77 61 73 20 61 64 64 65 64   pages was added
37a0: 2e 20 20 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61  .  .*/.struct Wa
37b0: 6c 49 6e 64 65 78 48 64 72 20 7b 0a 20 20 75 33  lIndexHdr {.  u3
37c0: 32 20 69 56 65 72 73 69 6f 6e 3b 20 20 20 20 20  2 iVersion;     
37d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
37e0: 20 57 61 6c 2d 69 6e 64 65 78 20 76 65 72 73 69   Wal-index versi
37f0: 6f 6e 20 2a 2f 0a 20 20 75 33 32 20 75 6e 75 73  on */.  u32 unus
3800: 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ed;             
3810: 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 75 73 65          /* Unuse
3820: 64 20 28 70 61 64 64 69 6e 67 29 20 66 69 65 6c  d (padding) fiel
3830: 64 20 2a 2f 0a 20 20 75 33 32 20 69 43 68 61 6e  d */.  u32 iChan
3840: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
3850: 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65         /* Counte
3860: 72 20 69 6e 63 72 65 6d 65 6e 74 65 64 20 65 61  r incremented ea
3870: 63 68 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a  ch transaction *
3880: 2f 0a 20 20 75 38 20 69 73 49 6e 69 74 3b 20 20  /.  u8 isInit;  
3890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38a0: 20 20 20 20 2f 2a 20 31 20 77 68 65 6e 20 69 6e      /* 1 when in
38b0: 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 75  itialized */.  u
38c0: 38 20 62 69 67 45 6e 64 43 6b 73 75 6d 3b 20 20  8 bigEndCksum;  
38d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
38e0: 2a 20 54 72 75 65 20 69 66 20 63 68 65 63 6b 73  * True if checks
38f0: 75 6d 73 20 69 6e 20 57 41 4c 20 61 72 65 20 62  ums in WAL are b
3900: 69 67 2d 65 6e 64 69 61 6e 20 2a 2f 0a 20 20 75  ig-endian */.  u
3910: 31 36 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20  16 szPage;      
3920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3930: 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20  * Database page 
3940: 73 69 7a 65 20 69 6e 20 62 79 74 65 73 2e 20 31  size in bytes. 1
3950: 3d 3d 36 34 4b 20 2a 2f 0a 20 20 75 33 32 20 6d  ==64K */.  u32 m
3960: 78 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20  xFrame;         
3970: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
3980: 64 65 78 20 6f 66 20 6c 61 73 74 20 76 61 6c 69  dex of last vali
3990: 64 20 66 72 61 6d 65 20 69 6e 20 74 68 65 20 57  d frame in the W
39a0: 41 4c 20 2a 2f 0a 20 20 75 33 32 20 6e 50 61 67  AL */.  u32 nPag
39b0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
39c0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
39d0: 6f 66 20 64 61 74 61 62 61 73 65 20 69 6e 20 70  of database in p
39e0: 61 67 65 73 20 2a 2f 0a 20 20 75 33 32 20 61 46  ages */.  u32 aF
39f0: 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  rameCksum[2];   
3a00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65            /* Che
3a10: 63 6b 73 75 6d 20 6f 66 20 6c 61 73 74 20 66 72  cksum of last fr
3a20: 61 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20  ame in log */.  
3a30: 75 33 32 20 61 53 61 6c 74 5b 32 5d 3b 20 20 20  u32 aSalt[2];   
3a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a50: 2f 2a 20 54 77 6f 20 73 61 6c 74 20 76 61 6c 75  /* Two salt valu
3a60: 65 73 20 63 6f 70 69 65 64 20 66 72 6f 6d 20 57  es copied from W
3a70: 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 75  AL header */.  u
3a80: 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  32 aCksum[2];   
3a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3aa0: 2a 20 43 68 65 63 6b 73 75 6d 20 6f 76 65 72 20  * Checksum over 
3ab0: 61 6c 6c 20 70 72 69 6f 72 20 66 69 65 6c 64 73  all prior fields
3ac0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20   */.};../*.** A 
3ad0: 63 6f 70 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c  copy of the foll
3ae0: 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 6f 63 63  owing object occ
3af0: 75 72 73 20 69 6e 20 74 68 65 20 77 61 6c 2d 69  urs in the wal-i
3b00: 6e 64 65 78 20 69 6d 6d 65 64 69 61 74 65 6c 79  ndex immediately
3b10: 0a 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68  .** following th
3b20: 65 20 73 65 63 6f 6e 64 20 63 6f 70 79 20 6f 66  e second copy of
3b30: 20 74 68 65 20 57 61 6c 49 6e 64 65 78 48 64 72   the WalIndexHdr
3b40: 2e 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20 73  .  This object s
3b50: 74 6f 72 65 73 0a 2a 2a 20 69 6e 66 6f 72 6d 61  tores.** informa
3b60: 74 69 6f 6e 20 75 73 65 64 20 62 79 20 63 68 65  tion used by che
3b70: 63 6b 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20 6e  ckpoint..**.** n
3b80: 42 61 63 6b 66 69 6c 6c 20 69 73 20 74 68 65 20  Backfill is the 
3b90: 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d 65 73  number of frames
3ba0: 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68 61 74   in the WAL that
3bb0: 20 68 61 76 65 20 62 65 65 6e 20 77 72 69 74 74   have been writt
3bc0: 65 6e 0a 2a 2a 20 62 61 63 6b 20 69 6e 74 6f 20  en.** back into 
3bd0: 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 28 57  the database. (W
3be0: 65 20 63 61 6c 6c 20 74 68 65 20 61 63 74 20 6f  e call the act o
3bf0: 66 20 6d 6f 76 69 6e 67 20 63 6f 6e 74 65 6e 74  f moving content
3c00: 20 66 72 6f 6d 20 57 41 4c 20 74 6f 0a 2a 2a 20   from WAL to.** 
3c10: 64 61 74 61 62 61 73 65 20 22 62 61 63 6b 66 69  database "backfi
3c20: 6c 6c 69 6e 67 22 2e 29 20 20 54 68 65 20 6e 42  lling".)  The nB
3c30: 61 63 6b 66 69 6c 6c 20 6e 75 6d 62 65 72 20 69  ackfill number i
3c40: 73 20 6e 65 76 65 72 20 67 72 65 61 74 65 72 20  s never greater 
3c50: 74 68 61 6e 0a 2a 2a 20 57 61 6c 49 6e 64 65 78  than.** WalIndex
3c60: 48 64 72 2e 6d 78 46 72 61 6d 65 2e 20 20 6e 42  Hdr.mxFrame.  nB
3c70: 61 63 6b 66 69 6c 6c 20 63 61 6e 20 6f 6e 6c 79  ackfill can only
3c80: 20 62 65 20 69 6e 63 72 65 61 73 65 64 20 62 79   be increased by
3c90: 20 74 68 72 65 61 64 73 0a 2a 2a 20 68 6f 6c 64   threads.** hold
3ca0: 69 6e 67 20 74 68 65 20 57 41 4c 5f 43 4b 50 54  ing the WAL_CKPT
3cb0: 5f 4c 4f 43 4b 20 6c 6f 63 6b 20 28 77 68 69 63  _LOCK lock (whic
3cc0: 68 20 69 6e 63 6c 75 64 65 73 20 61 20 72 65 63  h includes a rec
3cd0: 6f 76 65 72 79 20 74 68 72 65 61 64 29 2e 0a 2a  overy thread)..*
3ce0: 2a 20 48 6f 77 65 76 65 72 2c 20 61 20 57 41 4c  * However, a WAL
3cf0: 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 74 68 72 65  _WRITE_LOCK thre
3d00: 61 64 20 63 61 6e 20 6d 6f 76 65 20 74 68 65 20  ad can move the 
3d10: 76 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b 66 69  value of nBackfi
3d20: 6c 6c 20 66 72 6f 6d 0a 2a 2a 20 6d 78 46 72 61  ll from.** mxFra
3d30: 6d 65 20 62 61 63 6b 20 74 6f 20 7a 65 72 6f 20  me back to zero 
3d40: 77 68 65 6e 20 74 68 65 20 57 41 4c 20 69 73 20  when the WAL is 
3d50: 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  reset..**.** The
3d60: 72 65 20 69 73 20 6f 6e 65 20 65 6e 74 72 79 20  re is one entry 
3d70: 69 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 66  in aReadMark[] f
3d80: 6f 72 20 65 61 63 68 20 72 65 61 64 65 72 20 6c  or each reader l
3d90: 6f 63 6b 2e 20 20 49 66 20 61 20 72 65 61 64 65  ock.  If a reade
3da0: 72 0a 2a 2a 20 68 6f 6c 64 73 20 72 65 61 64 2d  r.** holds read-
3db0: 6c 6f 63 6b 20 4b 2c 20 74 68 65 6e 20 74 68 65  lock K, then the
3dc0: 20 76 61 6c 75 65 20 69 6e 20 61 52 65 61 64 4d   value in aReadM
3dd0: 61 72 6b 5b 4b 5d 20 69 73 20 6e 6f 20 67 72 65  ark[K] is no gre
3de0: 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 74 68 65  ater than.** the
3df0: 20 6d 78 46 72 61 6d 65 20 66 6f 72 20 74 68 61   mxFrame for tha
3e00: 74 20 72 65 61 64 65 72 2e 20 20 54 68 65 20 76  t reader.  The v
3e10: 61 6c 75 65 20 52 45 41 44 4d 41 52 4b 5f 4e 4f  alue READMARK_NO
3e20: 54 5f 55 53 45 44 20 28 30 78 66 66 66 66 66 66  T_USED (0xffffff
3e30: 66 66 29 0a 2a 2a 20 66 6f 72 20 61 6e 79 20 61  ff).** for any a
3e40: 52 65 61 64 4d 61 72 6b 5b 5d 20 6d 65 61 6e 73  ReadMark[] means
3e50: 20 74 68 61 74 20 65 6e 74 72 79 20 69 73 20 75   that entry is u
3e60: 6e 75 73 65 64 2e 20 20 61 52 65 61 64 4d 61 72  nused.  aReadMar
3e70: 6b 5b 30 5d 20 69 73 20 0a 2a 2a 20 61 20 73 70  k[0] is .** a sp
3e80: 65 63 69 61 6c 20 63 61 73 65 3b 20 69 74 73 20  ecial case; its 
3e90: 76 61 6c 75 65 20 69 73 20 6e 65 76 65 72 20 75  value is never u
3ea0: 73 65 64 20 61 6e 64 20 69 74 20 65 78 69 73 74  sed and it exist
3eb0: 73 20 61 73 20 61 20 70 6c 61 63 65 2d 68 6f 6c  s as a place-hol
3ec0: 64 65 72 0a 2a 2a 20 74 6f 20 61 76 6f 69 64 20  der.** to avoid 
3ed0: 68 61 76 69 6e 67 20 74 6f 20 6f 66 66 73 65 74  having to offset
3ee0: 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 69 6e 64   aReadMark[] ind
3ef0: 65 78 73 20 62 79 20 6f 6e 65 2e 20 20 52 65 61  exs by one.  Rea
3f00: 64 65 72 73 20 68 6f 6c 64 69 6e 67 0a 2a 2a 20  ders holding.** 
3f10: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29  WAL_READ_LOCK(0)
3f20: 20 61 6c 77 61 79 73 20 69 67 6e 6f 72 65 20 74   always ignore t
3f30: 68 65 20 65 6e 74 69 72 65 20 57 41 4c 20 61 6e  he entire WAL an
3f40: 64 20 72 65 61 64 20 61 6c 6c 20 63 6f 6e 74 65  d read all conte
3f50: 6e 74 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20 66  nt.** directly f
3f60: 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73 65  rom the database
3f70: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c 75  ..**.** The valu
3f80: 65 20 6f 66 20 61 52 65 61 64 4d 61 72 6b 5b 4b  e of aReadMark[K
3f90: 5d 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63 68  ] may only be ch
3fa0: 61 6e 67 65 64 20 62 79 20 61 20 74 68 72 65 61  anged by a threa
3fb0: 64 20 74 68 61 74 0a 2a 2a 20 69 73 20 68 6f 6c  d that.** is hol
3fc0: 64 69 6e 67 20 61 6e 20 65 78 63 6c 75 73 69 76  ding an exclusiv
3fd0: 65 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52 45  e lock on WAL_RE
3fe0: 41 44 5f 4c 4f 43 4b 28 4b 29 2e 20 20 54 68 75  AD_LOCK(K).  Thu
3ff0: 73 2c 20 74 68 65 20 76 61 6c 75 65 20 6f 66 0a  s, the value of.
4000: 2a 2a 20 61 52 65 61 64 4d 61 72 6b 5b 4b 5d 20  ** aReadMark[K] 
4010: 63 61 6e 6e 6f 74 20 63 68 61 6e 67 65 64 20 77  cannot changed w
4020: 68 69 6c 65 20 74 68 65 72 65 20 69 73 20 61 20  hile there is a 
4030: 72 65 61 64 65 72 20 69 73 20 75 73 69 6e 67 20  reader is using 
4040: 74 68 61 74 20 6d 61 72 6b 0a 2a 2a 20 73 69 6e  that mark.** sin
4050: 63 65 20 74 68 65 20 72 65 61 64 65 72 20 77 69  ce the reader wi
4060: 6c 6c 20 62 65 20 68 6f 6c 64 69 6e 67 20 61 20  ll be holding a 
4070: 73 68 61 72 65 64 20 6c 6f 63 6b 20 6f 6e 20 57  shared lock on W
4080: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 4b 29 2e  AL_READ_LOCK(K).
4090: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b  .**.** The check
40a0: 70 6f 69 6e 74 65 72 20 6d 61 79 20 6f 6e 6c 79  pointer may only
40b0: 20 74 72 61 6e 73 66 65 72 20 66 72 61 6d 65 73   transfer frames
40c0: 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64 61 74   from WAL to dat
40d0: 61 62 61 73 65 20 77 68 65 72 65 0a 2a 2a 20 74  abase where.** t
40e0: 68 65 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 73  he frame numbers
40f0: 20 61 72 65 20 6c 65 73 73 20 74 68 61 6e 20 6f   are less than o
4100: 72 20 65 71 75 61 6c 20 74 6f 20 65 76 65 72 79  r equal to every
4110: 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 74 68 61   aReadMark[] tha
4120: 74 20 69 73 0a 2a 2a 20 69 6e 20 75 73 65 20 28  t is.** in use (
4130: 74 68 61 74 20 69 73 2c 20 65 76 65 72 79 20 61  that is, every a
4140: 52 65 61 64 4d 61 72 6b 5b 6a 5d 20 66 6f 72 20  ReadMark[j] for 
4150: 77 68 69 63 68 20 74 68 65 72 65 20 69 73 20 61  which there is a
4160: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a   corresponding.*
4170: 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  * WAL_READ_LOCK(
4180: 6a 29 29 2e 20 20 4e 65 77 20 72 65 61 64 65 72  j)).  New reader
4190: 73 20 28 75 73 75 61 6c 6c 79 29 20 70 69 63 6b  s (usually) pick
41a0: 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d   the aReadMark[]
41b0: 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 6c 61 72   with the.** lar
41c0: 67 65 73 74 20 76 61 6c 75 65 20 61 6e 64 20 77  gest value and w
41d0: 69 6c 6c 20 69 6e 63 72 65 61 73 65 20 61 6e 20  ill increase an 
41e0: 75 6e 75 73 65 64 20 61 52 65 61 64 4d 61 72 6b  unused aReadMark
41f0: 5b 5d 20 74 6f 20 6d 78 46 72 61 6d 65 20 69 66  [] to mxFrame if
4200: 20 74 68 65 72 65 0a 2a 2a 20 69 73 20 6e 6f 74   there.** is not
4210: 20 61 6c 72 65 61 64 79 20 61 6e 20 61 52 65 61   already an aRea
4220: 64 4d 61 72 6b 5b 5d 20 65 71 75 61 6c 20 74 6f  dMark[] equal to
4230: 20 6d 78 46 72 61 6d 65 2e 20 20 54 68 65 20 65   mxFrame.  The e
4240: 78 63 65 70 74 69 6f 6e 20 74 6f 20 74 68 65 0a  xception to the.
4250: 2a 2a 20 70 72 65 76 69 6f 75 73 20 73 65 6e 74  ** previous sent
4260: 65 6e 63 65 20 69 73 20 77 68 65 6e 20 6e 42 61  ence is when nBa
4270: 63 6b 66 69 6c 6c 20 65 71 75 61 6c 73 20 6d 78  ckfill equals mx
4280: 46 72 61 6d 65 20 28 6d 65 61 6e 69 6e 67 20 74  Frame (meaning t
4290: 68 61 74 20 65 76 65 72 79 74 68 69 6e 67 0a 2a  hat everything.*
42a0: 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 68 61 73  * in the WAL has
42b0: 20 62 65 65 6e 20 62 61 63 6b 66 69 6c 6c 65 64   been backfilled
42c0: 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
42d0: 73 65 29 20 74 68 65 6e 20 6e 65 77 20 72 65 61  se) then new rea
42e0: 64 65 72 73 0a 2a 2a 20 77 69 6c 6c 20 63 68 6f  ders.** will cho
42f0: 6f 73 65 20 61 52 65 61 64 4d 61 72 6b 5b 30 5d  ose aReadMark[0]
4300: 20 77 68 69 63 68 20 68 61 73 20 76 61 6c 75 65   which has value
4310: 20 30 20 61 6e 64 20 68 65 6e 63 65 20 73 75 63   0 and hence suc
4320: 68 20 72 65 61 64 65 72 20 77 69 6c 6c 0a 2a 2a  h reader will.**
4330: 20 67 65 74 20 61 6c 6c 20 74 68 65 69 72 20 61   get all their a
4340: 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72 65 63  ll content direc
4350: 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61 74  tly from the dat
4360: 61 62 61 73 65 20 66 69 6c 65 20 61 6e 64 20 69  abase file and i
4370: 67 6e 6f 72 65 20 0a 2a 2a 20 74 68 65 20 57 41  gnore .** the WA
4380: 4c 2e 0a 2a 2a 0a 2a 2a 20 57 72 69 74 65 72 73  L..**.** Writers
4390: 20 6e 6f 72 6d 61 6c 6c 79 20 61 70 70 65 6e 64   normally append
43a0: 20 6e 65 77 20 66 72 61 6d 65 73 20 74 6f 20 74   new frames to t
43b0: 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 57 41  he end of the WA
43c0: 4c 2e 20 20 48 6f 77 65 76 65 72 2c 0a 2a 2a 20  L.  However,.** 
43d0: 69 66 20 6e 42 61 63 6b 66 69 6c 6c 20 65 71 75  if nBackfill equ
43e0: 61 6c 73 20 6d 78 46 72 61 6d 65 20 28 6d 65 61  als mxFrame (mea
43f0: 6e 69 6e 67 20 74 68 61 74 20 61 6c 6c 20 57 41  ning that all WA
4400: 4c 20 63 6f 6e 74 65 6e 74 20 68 61 73 20 62 65  L content has be
4410: 65 6e 0a 2a 2a 20 77 72 69 74 74 65 6e 20 62 61  en.** written ba
4420: 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ck into the data
4430: 62 61 73 65 29 20 61 6e 64 20 69 66 20 6e 6f 20  base) and if no 
4440: 72 65 61 64 65 72 73 20 61 72 65 20 75 73 69 6e  readers are usin
4450: 67 20 74 68 65 20 57 41 4c 0a 2a 2a 20 28 69 6e  g the WAL.** (in
4460: 20 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 69 66   other words, if
4470: 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 57 41   there are no WA
4480: 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 20 77  L_READ_LOCK(i) w
4490: 68 65 72 65 20 69 3e 30 29 20 74 68 65 6e 0a 2a  here i>0) then.*
44a0: 2a 20 74 68 65 20 77 72 69 74 65 72 20 77 69 6c  * the writer wil
44b0: 6c 20 66 69 72 73 74 20 22 72 65 73 65 74 22 20  l first "reset" 
44c0: 74 68 65 20 57 41 4c 20 62 61 63 6b 20 74 6f 20  the WAL back to 
44d0: 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 61 6e  the beginning an
44e0: 64 20 73 74 61 72 74 0a 2a 2a 20 77 72 69 74 69  d start.** writi
44f0: 6e 67 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20 62  ng new content b
4500: 65 67 69 6e 6e 69 6e 67 20 61 74 20 66 72 61 6d  eginning at fram
4510: 65 20 31 2e 0a 2a 2a 0a 2a 2a 20 57 65 20 61 73  e 1..**.** We as
4520: 73 75 6d 65 20 74 68 61 74 20 33 32 2d 62 69 74  sume that 32-bit
4530: 20 6c 6f 61 64 73 20 61 72 65 20 61 74 6f 6d 69   loads are atomi
4540: 63 20 61 6e 64 20 73 6f 20 6e 6f 20 6c 6f 63 6b  c and so no lock
4550: 73 20 61 72 65 20 6e 65 65 64 65 64 20 69 6e 0a  s are needed in.
4560: 2a 2a 20 6f 72 64 65 72 20 74 6f 20 72 65 61 64  ** order to read
4570: 20 66 72 6f 6d 20 61 6e 79 20 61 52 65 61 64 4d   from any aReadM
4580: 61 72 6b 5b 5d 20 65 6e 74 72 69 65 73 2e 0a 2a  ark[] entries..*
4590: 2f 0a 73 74 72 75 63 74 20 57 61 6c 43 6b 70 74  /.struct WalCkpt
45a0: 49 6e 66 6f 20 7b 0a 20 20 75 33 32 20 6e 42 61  Info {.  u32 nBa
45b0: 63 6b 66 69 6c 6c 3b 20 20 20 20 20 20 20 20 20  ckfill;         
45c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
45d0: 65 72 20 6f 66 20 57 41 4c 20 66 72 61 6d 65 73  er of WAL frames
45e0: 20 62 61 63 6b 66 69 6c 6c 65 64 20 69 6e 74 6f   backfilled into
45f0: 20 44 42 20 2a 2f 0a 20 20 75 33 32 20 61 52 65   DB */.  u32 aRe
4600: 61 64 4d 61 72 6b 5b 57 41 4c 5f 4e 52 45 41 44  adMark[WAL_NREAD
4610: 45 52 5d 3b 20 20 20 20 20 2f 2a 20 52 65 61 64  ER];     /* Read
4620: 65 72 20 6d 61 72 6b 73 20 2a 2f 0a 7d 3b 0a 23  er marks */.};.#
4630: 64 65 66 69 6e 65 20 52 45 41 44 4d 41 52 4b 5f  define READMARK_
4640: 4e 4f 54 5f 55 53 45 44 20 20 30 78 66 66 66 66  NOT_USED  0xffff
4650: 66 66 66 66 0a 0a 0a 2f 2a 20 41 20 62 6c 6f 63  ffff.../* A bloc
4660: 6b 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 4c 4f  k of WALINDEX_LO
4670: 43 4b 5f 52 45 53 45 52 56 45 44 20 62 79 74 65  CK_RESERVED byte
4680: 73 20 62 65 67 69 6e 6e 69 6e 67 20 61 74 0a 2a  s beginning at.*
4690: 2a 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f  * WALINDEX_LOCK_
46a0: 4f 46 46 53 45 54 20 69 73 20 72 65 73 65 72 76  OFFSET is reserv
46b0: 65 64 20 66 6f 72 20 6c 6f 63 6b 73 2e 20 53 69  ed for locks. Si
46c0: 6e 63 65 20 73 6f 6d 65 20 73 79 73 74 65 6d 73  nce some systems
46d0: 0a 2a 2a 20 6f 6e 6c 79 20 73 75 70 70 6f 72 74  .** only support
46e0: 20 6d 61 6e 64 61 74 6f 72 79 20 66 69 6c 65 2d   mandatory file-
46f0: 6c 6f 63 6b 73 2c 20 77 65 20 64 6f 20 6e 6f 74  locks, we do not
4700: 20 72 65 61 64 20 6f 72 20 77 72 69 74 65 20 64   read or write d
4710: 61 74 61 0a 2a 2a 20 66 72 6f 6d 20 74 68 65 20  ata.** from the 
4720: 72 65 67 69 6f 6e 20 6f 66 20 74 68 65 20 66 69  region of the fi
4730: 6c 65 20 6f 6e 20 77 68 69 63 68 20 6c 6f 63 6b  le on which lock
4740: 73 20 61 72 65 20 61 70 70 6c 69 65 64 2e 0a 2a  s are applied..*
4750: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44  /.#define WALIND
4760: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 20  EX_LOCK_OFFSET  
4770: 20 28 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65   (sizeof(WalInde
4780: 78 48 64 72 29 2a 32 20 2b 20 73 69 7a 65 6f 66  xHdr)*2 + sizeof
4790: 28 57 61 6c 43 6b 70 74 49 6e 66 6f 29 29 0a 23  (WalCkptInfo)).#
47a0: 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58 5f  define WALINDEX_
47b0: 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 20 31 36  LOCK_RESERVED 16
47c0: 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45  .#define WALINDE
47d0: 58 5f 48 44 52 5f 53 49 5a 45 20 20 20 20 20 20  X_HDR_SIZE      
47e0: 28 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f  (WALINDEX_LOCK_O
47f0: 46 46 53 45 54 2b 57 41 4c 49 4e 44 45 58 5f 4c  FFSET+WALINDEX_L
4800: 4f 43 4b 5f 52 45 53 45 52 56 45 44 29 0a 0a 2f  OCK_RESERVED)../
4810: 2a 20 53 69 7a 65 20 6f 66 20 68 65 61 64 65 72  * Size of header
4820: 20 62 65 66 6f 72 65 20 65 61 63 68 20 66 72 61   before each fra
4830: 6d 65 20 69 6e 20 77 61 6c 20 2a 2f 0a 23 64 65  me in wal */.#de
4840: 66 69 6e 65 20 57 41 4c 5f 46 52 41 4d 45 5f 48  fine WAL_FRAME_H
4850: 44 52 53 49 5a 45 20 32 34 0a 0a 2f 2a 20 53 69  DRSIZE 24../* Si
4860: 7a 65 20 6f 66 20 77 72 69 74 65 20 61 68 65 61  ze of write ahea
4870: 64 20 6c 6f 67 20 68 65 61 64 65 72 2c 20 69 6e  d log header, in
4880: 63 6c 75 64 69 6e 67 20 63 68 65 63 6b 73 75 6d  cluding checksum
4890: 2e 20 2a 2f 0a 2f 2a 20 23 64 65 66 69 6e 65 20  . */./* #define 
48a0: 57 41 4c 5f 48 44 52 53 49 5a 45 20 32 34 20 2a  WAL_HDRSIZE 24 *
48b0: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48 44  /.#define WAL_HD
48c0: 52 53 49 5a 45 20 33 32 0a 0a 2f 2a 20 57 41 4c  RSIZE 32../* WAL
48d0: 20 6d 61 67 69 63 20 76 61 6c 75 65 2e 20 45 69   magic value. Ei
48e0: 74 68 65 72 20 74 68 69 73 20 76 61 6c 75 65 2c  ther this value,
48f0: 20 6f 72 20 74 68 65 20 73 61 6d 65 20 76 61 6c   or the same val
4900: 75 65 20 77 69 74 68 20 74 68 65 20 6c 65 61 73  ue with the leas
4910: 74 0a 2a 2a 20 73 69 67 6e 69 66 69 63 61 6e 74  t.** significant
4920: 20 62 69 74 20 61 6c 73 6f 20 73 65 74 20 28 57   bit also set (W
4930: 41 4c 5f 4d 41 47 49 43 20 7c 20 30 78 30 30 30  AL_MAGIC | 0x000
4940: 30 30 30 30 31 29 20 69 73 20 73 74 6f 72 65 64  00001) is stored
4950: 20 69 6e 20 33 32 2d 62 69 74 0a 2a 2a 20 62 69   in 32-bit.** bi
4960: 67 2d 65 6e 64 69 61 6e 20 66 6f 72 6d 61 74 20  g-endian format 
4970: 69 6e 20 74 68 65 20 66 69 72 73 74 20 34 20 62  in the first 4 b
4980: 79 74 65 73 20 6f 66 20 61 20 57 41 4c 20 66 69  ytes of a WAL fi
4990: 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  le..**.** If the
49a0: 20 4c 53 42 20 69 73 20 73 65 74 2c 20 74 68 65   LSB is set, the
49b0: 6e 20 74 68 65 20 63 68 65 63 6b 73 75 6d 73 20  n the checksums 
49c0: 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65 20 77  for each frame w
49d0: 69 74 68 69 6e 20 74 68 65 20 57 41 4c 0a 2a 2a  ithin the WAL.**
49e0: 20 66 69 6c 65 20 61 72 65 20 63 61 6c 63 75 6c   file are calcul
49f0: 61 74 65 64 20 62 79 20 74 72 65 61 74 69 6e 67  ated by treating
4a00: 20 61 6c 6c 20 64 61 74 61 20 61 73 20 61 6e 20   all data as an 
4a10: 61 72 72 61 79 20 6f 66 20 33 32 2d 62 69 74 20  array of 32-bit 
4a20: 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 77  .** big-endian w
4a30: 6f 72 64 73 2e 20 4f 74 68 65 72 77 69 73 65 2c  ords. Otherwise,
4a40: 20 74 68 65 79 20 61 72 65 20 63 61 6c 63 75 6c   they are calcul
4a50: 61 74 65 64 20 62 79 20 69 6e 74 65 72 70 72 65  ated by interpre
4a60: 74 69 6e 67 20 0a 2a 2a 20 61 6c 6c 20 64 61 74  ting .** all dat
4a70: 61 20 61 73 20 33 32 2d 62 69 74 20 6c 69 74 74  a as 32-bit litt
4a80: 6c 65 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73 2e  le-endian words.
4a90: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f  .*/.#define WAL_
4aa0: 4d 41 47 49 43 20 30 78 33 37 37 66 30 36 38 32  MAGIC 0x377f0682
4ab0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
4ac0: 68 65 20 6f 66 66 73 65 74 20 6f 66 20 66 72 61  he offset of fra
4ad0: 6d 65 20 69 46 72 61 6d 65 20 69 6e 20 74 68 65  me iFrame in the
4ae0: 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67   write-ahead log
4af0: 20 66 69 6c 65 2c 20 0a 2a 2a 20 61 73 73 75 6d   file, .** assum
4b00: 69 6e 67 20 61 20 64 61 74 61 62 61 73 65 20 70  ing a database p
4b10: 61 67 65 20 73 69 7a 65 20 6f 66 20 73 7a 50 61  age size of szPa
4b20: 67 65 20 62 79 74 65 73 2e 20 54 68 65 20 6f 66  ge bytes. The of
4b30: 66 73 65 74 20 72 65 74 75 72 6e 65 64 0a 2a 2a  fset returned.**
4b40: 20 69 73 20 74 6f 20 74 68 65 20 73 74 61 72 74   is to the start
4b50: 20 6f 66 20 74 68 65 20 77 72 69 74 65 2d 61 68   of the write-ah
4b60: 65 61 64 20 6c 6f 67 20 66 72 61 6d 65 2d 68 65  ead log frame-he
4b70: 61 64 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  ader..*/.#define
4b80: 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28   walFrameOffset(
4b90: 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29 20  iFrame, szPage) 
4ba0: 28 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (               
4bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4bc0: 5c 0a 20 20 57 41 4c 5f 48 44 52 53 49 5a 45 20  \.  WAL_HDRSIZE 
4bd0: 2b 20 28 28 69 46 72 61 6d 65 29 2d 31 29 2a 28  + ((iFrame)-1)*(
4be0: 69 36 34 29 28 28 73 7a 50 61 67 65 29 2b 57 41  i64)((szPage)+WA
4bf0: 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 29  L_FRAME_HDRSIZE)
4c00: 20 20 20 20 20 20 20 20 20 5c 0a 29 0a 0a 2f 2a           \.)../*
4c10: 0a 2a 2a 20 41 6e 20 6f 70 65 6e 20 77 72 69 74  .** An open writ
4c20: 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65  e-ahead log file
4c30: 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64 20   is represented 
4c40: 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f  by an instance o
4c50: 66 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c 6f 77 69  f the.** followi
4c60: 6e 67 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  ng object..*/.st
4c70: 72 75 63 74 20 57 61 6c 20 7b 0a 20 20 73 71 6c  ruct Wal {.  sql
4c80: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 3b 20  ite3_vfs *pVfs; 
4c90: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 56          /* The V
4ca0: 46 53 20 75 73 65 64 20 74 6f 20 63 72 65 61 74  FS used to creat
4cb0: 65 20 70 44 62 46 64 20 2a 2f 0a 20 20 73 71 6c  e pDbFd */.  sql
4cc0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 44 62 46 64  ite3_file *pDbFd
4cd0: 3b 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20  ;       /* File 
4ce0: 68 61 6e 64 6c 65 20 66 6f 72 20 74 68 65 20 64  handle for the d
4cf0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a  atabase file */.
4d00: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
4d10: 70 57 61 6c 46 64 3b 20 20 20 20 20 20 2f 2a 20  pWalFd;      /* 
4d20: 46 69 6c 65 20 68 61 6e 64 6c 65 20 66 6f 72 20  File handle for 
4d30: 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33  WAL file */.  u3
4d40: 32 20 69 43 61 6c 6c 62 61 63 6b 3b 20 20 20 20  2 iCallback;    
4d50: 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75           /* Valu
4d60: 65 20 74 6f 20 70 61 73 73 20 74 6f 20 6c 6f 67  e to pass to log
4d70: 20 63 61 6c 6c 62 61 63 6b 20 28 6f 72 20 30 29   callback (or 0)
4d80: 20 2a 2f 0a 20 20 69 36 34 20 6d 78 57 61 6c 53   */.  i64 mxWalS
4d90: 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ize;            
4da0: 20 2f 2a 20 54 72 75 6e 63 61 74 65 20 57 41 4c   /* Truncate WAL
4db0: 20 74 6f 20 74 68 69 73 20 73 69 7a 65 20 75 70   to this size up
4dc0: 6f 6e 20 72 65 73 65 74 20 2a 2f 0a 20 20 69 6e  on reset */.  in
4dd0: 74 20 6e 57 69 44 61 74 61 3b 20 20 20 20 20 20  t nWiData;      
4de0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
4df0: 20 6f 66 20 61 72 72 61 79 20 61 70 57 69 44 61   of array apWiDa
4e00: 74 61 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 46 69  ta */.  int szFi
4e10: 72 73 74 42 6c 6f 63 6b 3b 20 20 20 20 20 20 20  rstBlock;       
4e20: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 66 69     /* Size of fi
4e30: 72 73 74 20 62 6c 6f 63 6b 20 77 72 69 74 74 65  rst block writte
4e40: 6e 20 74 6f 20 57 41 4c 20 66 69 6c 65 20 2a 2f  n to WAL file */
4e50: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20  .  volatile u32 
4e60: 2a 2a 61 70 57 69 44 61 74 61 3b 20 20 20 2f 2a  **apWiData;   /*
4e70: 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 61 6c 2d   Pointer to wal-
4e80: 69 6e 64 65 78 20 63 6f 6e 74 65 6e 74 20 69 6e  index content in
4e90: 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 75 33 32   memory */.  u32
4ea0: 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20   szPage;        
4eb0: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
4ec0: 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f  ase page size */
4ed0: 0a 20 20 69 31 36 20 72 65 61 64 4c 6f 63 6b 3b  .  i16 readLock;
4ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4ef0: 20 57 68 69 63 68 20 72 65 61 64 20 6c 6f 63 6b   Which read lock
4f00: 20 69 73 20 62 65 69 6e 67 20 68 65 6c 64 2e 20   is being held. 
4f10: 20 2d 31 20 66 6f 72 20 6e 6f 6e 65 20 2a 2f 0a   -1 for none */.
4f20: 20 20 75 38 20 73 79 6e 63 46 6c 61 67 73 3b 20    u8 syncFlags; 
4f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4f40: 46 6c 61 67 73 20 74 6f 20 75 73 65 20 74 6f 20  Flags to use to 
4f50: 73 79 6e 63 20 68 65 61 64 65 72 20 77 72 69 74  sync header writ
4f60: 65 73 20 2a 2f 0a 20 20 75 38 20 65 78 63 6c 75  es */.  u8 exclu
4f70: 73 69 76 65 4d 6f 64 65 3b 20 20 20 20 20 20 20  siveMode;       
4f80: 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69     /* Non-zero i
4f90: 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20  f connection is 
4fa0: 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f 64  in exclusive mod
4fb0: 65 20 2a 2f 0a 20 20 75 38 20 77 72 69 74 65 4c  e */.  u8 writeL
4fc0: 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ock;            
4fd0: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 20    /* True if in 
4fe0: 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74  a write transact
4ff0: 69 6f 6e 20 2a 2f 0a 20 20 75 38 20 63 6b 70 74  ion */.  u8 ckpt
5000: 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Lock;           
5010: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 68      /* True if h
5020: 6f 6c 64 69 6e 67 20 61 20 63 68 65 63 6b 70 6f  olding a checkpo
5030: 69 6e 74 20 6c 6f 63 6b 20 2a 2f 0a 20 20 75 38  int lock */.  u8
5040: 20 72 65 61 64 4f 6e 6c 79 3b 20 20 20 20 20 20   readOnly;      
5050: 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 5f           /* WAL_
5060: 52 44 57 52 2c 20 57 41 4c 5f 52 44 4f 4e 4c 59  RDWR, WAL_RDONLY
5070: 2c 20 6f 72 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  , or WAL_SHM_RDO
5080: 4e 4c 59 20 2a 2f 0a 20 20 75 38 20 74 72 75 6e  NLY */.  u8 trun
5090: 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 3b 20 20 20  cateOnCommit;   
50a0: 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 74      /* True to t
50b0: 72 75 6e 63 61 74 65 20 57 41 4c 20 66 69 6c 65  runcate WAL file
50c0: 20 6f 6e 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20   on commit */.  
50d0: 75 38 20 73 79 6e 63 48 65 61 64 65 72 3b 20 20  u8 syncHeader;  
50e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 73             /* Fs
50f0: 79 6e 63 20 74 68 65 20 57 41 4c 20 68 65 61 64  ync the WAL head
5100: 65 72 20 69 66 20 74 72 75 65 20 2a 2f 0a 20 20  er if true */.  
5110: 75 38 20 70 61 64 54 6f 53 65 63 74 6f 72 42 6f  u8 padToSectorBo
5120: 75 6e 64 61 72 79 3b 20 20 20 20 2f 2a 20 50 61  undary;    /* Pa
5130: 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 20 6f  d transactions o
5140: 75 74 20 74 6f 20 74 68 65 20 6e 65 78 74 20 73  ut to the next s
5150: 65 63 74 6f 72 20 2a 2f 0a 20 20 57 61 6c 49 6e  ector */.  WalIn
5160: 64 65 78 48 64 72 20 68 64 72 3b 20 20 20 20 20  dexHdr hdr;     
5170: 20 20 20 20 20 20 2f 2a 20 57 61 6c 2d 69 6e 64        /* Wal-ind
5180: 65 78 20 68 65 61 64 65 72 20 66 6f 72 20 63 75  ex header for cu
5190: 72 72 65 6e 74 20 74 72 61 6e 73 61 63 74 69 6f  rrent transactio
51a0: 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  n */.  const cha
51b0: 72 20 2a 7a 57 61 6c 4e 61 6d 65 3b 20 20 20 20  r *zWalName;    
51c0: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 57 41 4c    /* Name of WAL
51d0: 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32 20 6e   file */.  u32 n
51e0: 43 6b 70 74 3b 20 20 20 20 20 20 20 20 20 20 20  Ckpt;           
51f0: 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 70 6f        /* Checkpo
5200: 69 6e 74 20 73 65 71 75 65 6e 63 65 20 63 6f 75  int sequence cou
5210: 6e 74 65 72 20 69 6e 20 74 68 65 20 77 61 6c 2d  nter in the wal-
5220: 68 65 61 64 65 72 20 2a 2f 0a 23 69 66 64 65 66  header */.#ifdef
5230: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20   SQLITE_DEBUG.  
5240: 75 38 20 6c 6f 63 6b 45 72 72 6f 72 3b 20 20 20  u8 lockError;   
5250: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
5260: 75 65 20 69 66 20 61 20 6c 6f 63 6b 69 6e 67 20  ue if a locking 
5270: 65 72 72 6f 72 20 68 61 73 20 6f 63 63 75 72 72  error has occurr
5280: 65 64 20 2a 2f 0a 23 65 6e 64 69 66 0a 7d 3b 0a  ed */.#endif.};.
5290: 0a 2f 2a 0a 2a 2a 20 43 61 6e 64 69 64 61 74 65  ./*.** Candidate
52a0: 20 76 61 6c 75 65 73 20 66 6f 72 20 57 61 6c 2e   values for Wal.
52b0: 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 2e 0a 2a  exclusiveMode..*
52c0: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 4e 4f  /.#define WAL_NO
52d0: 52 4d 41 4c 5f 4d 4f 44 45 20 20 20 20 20 30 0a  RMAL_MODE     0.
52e0: 23 64 65 66 69 6e 65 20 57 41 4c 5f 45 58 43 4c  #define WAL_EXCL
52f0: 55 53 49 56 45 5f 4d 4f 44 45 20 20 31 20 20 20  USIVE_MODE  1   
5300: 20 20 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48    .#define WAL_H
5310: 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 32  EAPMEMORY_MODE 2
5320: 0a 0a 2f 2a 0a 2a 2a 20 50 6f 73 73 69 62 6c 65  ../*.** Possible
5330: 20 76 61 6c 75 65 73 20 66 6f 72 20 57 41 4c 2e   values for WAL.
5340: 72 65 61 64 4f 6e 6c 79 0a 2a 2f 0a 23 64 65 66  readOnly.*/.#def
5350: 69 6e 65 20 57 41 4c 5f 52 44 57 52 20 20 20 20  ine WAL_RDWR    
5360: 20 20 20 20 30 20 20 20 20 2f 2a 20 4e 6f 72 6d      0    /* Norm
5370: 61 6c 20 72 65 61 64 2f 77 72 69 74 65 20 63 6f  al read/write co
5380: 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 23 64 65 66  nnection */.#def
5390: 69 6e 65 20 57 41 4c 5f 52 44 4f 4e 4c 59 20 20  ine WAL_RDONLY  
53a0: 20 20 20 20 31 20 20 20 20 2f 2a 20 54 68 65 20      1    /* The 
53b0: 57 41 4c 20 66 69 6c 65 20 69 73 20 72 65 61 64  WAL file is read
53c0: 6f 6e 6c 79 20 2a 2f 0a 23 64 65 66 69 6e 65 20  only */.#define 
53d0: 57 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 20 20  WAL_SHM_RDONLY  
53e0: 32 20 20 20 20 2f 2a 20 54 68 65 20 53 48 4d 20  2    /* The SHM 
53f0: 66 69 6c 65 20 69 73 20 72 65 61 64 6f 6e 6c 79  file is readonly
5400: 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20   */../*.** Each 
5410: 70 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d  page of the wal-
5420: 69 6e 64 65 78 20 6d 61 70 70 69 6e 67 20 63 6f  index mapping co
5430: 6e 74 61 69 6e 73 20 61 20 68 61 73 68 2d 74 61  ntains a hash-ta
5440: 62 6c 65 20 6d 61 64 65 20 75 70 20 6f 66 0a 2a  ble made up of.*
5450: 2a 20 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41  * an array of HA
5460: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 65 6c  SHTABLE_NSLOT el
5470: 65 6d 65 6e 74 73 20 6f 66 20 74 68 65 20 66 6f  ements of the fo
5480: 6c 6c 6f 77 69 6e 67 20 74 79 70 65 2e 0a 2a 2f  llowing type..*/
5490: 0a 74 79 70 65 64 65 66 20 75 31 36 20 68 74 5f  .typedef u16 ht_
54a0: 73 6c 6f 74 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  slot;../*.** Thi
54b0: 73 20 73 74 72 75 63 74 75 72 65 20 69 73 20 75  s structure is u
54c0: 73 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  sed to implement
54d0: 20 61 6e 20 69 74 65 72 61 74 6f 72 20 74 68 61   an iterator tha
54e0: 74 20 6c 6f 6f 70 73 20 74 68 72 6f 75 67 68 0a  t loops through.
54f0: 2a 2a 20 61 6c 6c 20 66 72 61 6d 65 73 20 69 6e  ** all frames in
5500: 20 74 68 65 20 57 41 4c 20 69 6e 20 64 61 74 61   the WAL in data
5510: 62 61 73 65 20 70 61 67 65 20 6f 72 64 65 72 2e  base page order.
5520: 20 57 68 65 72 65 20 74 77 6f 20 6f 72 20 6d 6f   Where two or mo
5530: 72 65 20 66 72 61 6d 65 73 0a 2a 2a 20 63 6f 72  re frames.** cor
5540: 72 65 73 70 6f 6e 64 20 74 6f 20 74 68 65 20 73  respond to the s
5550: 61 6d 65 20 64 61 74 61 62 61 73 65 20 70 61 67  ame database pag
5560: 65 2c 20 74 68 65 20 69 74 65 72 61 74 6f 72 20  e, the iterator 
5570: 76 69 73 69 74 73 20 6f 6e 6c 79 20 74 68 65 20  visits only the 
5580: 0a 2a 2a 20 66 72 61 6d 65 20 6d 6f 73 74 20 72  .** frame most r
5590: 65 63 65 6e 74 6c 79 20 77 72 69 74 74 65 6e 20  ecently written 
55a0: 74 6f 20 74 68 65 20 57 41 4c 20 28 69 6e 20 6f  to the WAL (in o
55b0: 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68 65 20  ther words, the 
55c0: 66 72 61 6d 65 20 77 69 74 68 0a 2a 2a 20 74 68  frame with.** th
55d0: 65 20 6c 61 72 67 65 73 74 20 69 6e 64 65 78 29  e largest index)
55e0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e 74 65  ..**.** The inte
55f0: 72 6e 61 6c 73 20 6f 66 20 74 68 69 73 20 73 74  rnals of this st
5600: 72 75 63 74 75 72 65 20 61 72 65 20 6f 6e 6c 79  ructure are only
5610: 20 61 63 63 65 73 73 65 64 20 62 79 3a 0a 2a 2a   accessed by:.**
5620: 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f  .**   walIterato
5630: 72 49 6e 69 74 28 29 20 2d 20 43 72 65 61 74 65  rInit() - Create
5640: 20 61 20 6e 65 77 20 69 74 65 72 61 74 6f 72 2c   a new iterator,
5650: 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f  .**   walIterato
5660: 72 4e 65 78 74 28 29 20 2d 20 53 74 65 70 20 61  rNext() - Step a
5670: 6e 20 69 74 65 72 61 74 6f 72 2c 0a 2a 2a 20 20  n iterator,.**  
5680: 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65   walIteratorFree
5690: 28 29 20 2d 20 46 72 65 65 20 61 6e 20 69 74 65  () - Free an ite
56a0: 72 61 74 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  rator..**.** Thi
56b0: 73 20 66 75 6e 63 74 69 6f 6e 61 6c 69 74 79 20  s functionality 
56c0: 69 73 20 75 73 65 64 20 62 79 20 74 68 65 20 63  is used by the c
56d0: 68 65 63 6b 70 6f 69 6e 74 20 63 6f 64 65 20 28  heckpoint code (
56e0: 73 65 65 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e  see walCheckpoin
56f0: 74 28 29 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  t())..*/.struct 
5700: 57 61 6c 49 74 65 72 61 74 6f 72 20 7b 0a 20 20  WalIterator {.  
5710: 69 6e 74 20 69 50 72 69 6f 72 3b 20 20 20 20 20  int iPrior;     
5720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5730: 2f 2a 20 4c 61 73 74 20 72 65 73 75 6c 74 20 72  /* Last result r
5740: 65 74 75 72 6e 65 64 20 66 72 6f 6d 20 74 68 65  eturned from the
5750: 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69   iterator */.  i
5760: 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20 20  nt nSegment;    
5770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5780: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72  * Number of entr
5790: 69 65 73 20 69 6e 20 61 53 65 67 6d 65 6e 74 5b  ies in aSegment[
57a0: 5d 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 57 61  ] */.  struct Wa
57b0: 6c 53 65 67 6d 65 6e 74 20 7b 0a 20 20 20 20 69  lSegment {.    i
57c0: 6e 74 20 69 4e 65 78 74 3b 20 20 20 20 20 20 20  nt iNext;       
57d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
57e0: 4e 65 78 74 20 73 6c 6f 74 20 69 6e 20 61 49 6e  Next slot in aIn
57f0: 64 65 78 5b 5d 20 6e 6f 74 20 79 65 74 20 72 65  dex[] not yet re
5800: 74 75 72 6e 65 64 20 2a 2f 0a 20 20 20 20 68 74  turned */.    ht
5810: 5f 73 6c 6f 74 20 2a 61 49 6e 64 65 78 3b 20 20  _slot *aIndex;  
5820: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
5830: 30 2c 20 69 31 2c 20 69 32 2e 2e 2e 20 73 75 63  0, i1, i2... suc
5840: 68 20 74 68 61 74 20 61 50 67 6e 6f 5b 69 4e 5d  h that aPgno[iN]
5850: 20 61 73 63 65 6e 64 20 2a 2f 0a 20 20 20 20 75   ascend */.    u
5860: 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20  32 *aPgno;      
5870: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5880: 41 72 72 61 79 20 6f 66 20 70 61 67 65 20 6e 75  Array of page nu
5890: 6d 62 65 72 73 2e 20 2a 2f 0a 20 20 20 20 69 6e  mbers. */.    in
58a0: 74 20 6e 45 6e 74 72 79 3b 20 20 20 20 20 20 20  t nEntry;       
58b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
58c0: 72 2e 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e  r. of entries in
58d0: 20 61 50 67 6e 6f 5b 5d 20 61 6e 64 20 61 49 6e   aPgno[] and aIn
58e0: 64 65 78 5b 5d 20 2a 2f 0a 20 20 20 20 69 6e 74  dex[] */.    int
58f0: 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20   iZero;         
5900: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
5910: 61 6d 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63  ame number assoc
5920: 69 61 74 65 64 20 77 69 74 68 20 61 50 67 6e 6f  iated with aPgno
5930: 5b 30 5d 20 2a 2f 0a 20 20 7d 20 61 53 65 67 6d  [0] */.  } aSegm
5940: 65 6e 74 5b 31 5d 3b 20 20 20 20 20 20 20 20 20  ent[1];         
5950: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20           /* One 
5960: 66 6f 72 20 65 76 65 72 79 20 33 32 4b 42 20 70  for every 32KB p
5970: 61 67 65 20 69 6e 20 74 68 65 20 77 61 6c 2d 69  age in the wal-i
5980: 6e 64 65 78 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  ndex */.};../*.*
5990: 2a 20 44 65 66 69 6e 65 20 74 68 65 20 70 61 72  * Define the par
59a0: 61 6d 65 74 65 72 73 20 6f 66 20 74 68 65 20 68  ameters of the h
59b0: 61 73 68 20 74 61 62 6c 65 73 20 69 6e 20 74 68  ash tables in th
59c0: 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65  e wal-index file
59d0: 2e 20 54 68 65 72 65 0a 2a 2a 20 69 73 20 61 20  . There.** is a 
59e0: 68 61 73 68 2d 74 61 62 6c 65 20 66 6f 6c 6c 6f  hash-table follo
59f0: 77 69 6e 67 20 65 76 65 72 79 20 48 41 53 48 54  wing every HASHT
5a00: 41 42 4c 45 5f 4e 50 41 47 45 20 70 61 67 65 20  ABLE_NPAGE page 
5a10: 6e 75 6d 62 65 72 73 20 69 6e 20 74 68 65 0a 2a  numbers in the.*
5a20: 2a 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2a 0a  * wal-index..**.
5a30: 2a 2a 20 43 68 61 6e 67 69 6e 67 20 61 6e 79 20  ** Changing any 
5a40: 6f 66 20 74 68 65 73 65 20 63 6f 6e 73 74 61 6e  of these constan
5a50: 74 73 20 77 69 6c 6c 20 61 6c 74 65 72 20 74 68  ts will alter th
5a60: 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 6f 72 6d  e wal-index form
5a70: 61 74 20 61 6e 64 0a 2a 2a 20 63 72 65 61 74 65  at and.** create
5a80: 20 69 6e 63 6f 6d 70 61 74 69 62 69 6c 69 74 69   incompatibiliti
5a90: 65 73 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 48  es..*/.#define H
5aa0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 20  ASHTABLE_NPAGE  
5ab0: 20 20 20 20 34 30 39 36 20 20 20 20 20 20 20 20      4096        
5ac0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 73 74           /* Must
5ad0: 20 62 65 20 70 6f 77 65 72 20 6f 66 20 32 20 2a   be power of 2 *
5ae0: 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48 54 41  /.#define HASHTA
5af0: 42 4c 45 5f 48 41 53 48 5f 31 20 20 20 20 20 33  BLE_HASH_1     3
5b00: 38 33 20 20 20 20 20 20 20 20 20 20 20 20 20 20  83              
5b10: 20 20 20 20 2f 2a 20 53 68 6f 75 6c 64 20 62 65      /* Should be
5b20: 20 70 72 69 6d 65 20 2a 2f 0a 23 64 65 66 69 6e   prime */.#defin
5b30: 65 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f  e HASHTABLE_NSLO
5b40: 54 20 20 20 20 20 20 28 48 41 53 48 54 41 42 4c  T      (HASHTABL
5b50: 45 5f 4e 50 41 47 45 2a 32 29 20 20 2f 2a 20 4d  E_NPAGE*2)  /* M
5b60: 75 73 74 20 62 65 20 61 20 70 6f 77 65 72 20 6f  ust be a power o
5b70: 66 20 32 20 2a 2f 0a 0a 2f 2a 20 0a 2a 2a 20 54  f 2 */../* .** T
5b80: 68 65 20 62 6c 6f 63 6b 20 6f 66 20 70 61 67 65  he block of page
5b90: 20 6e 75 6d 62 65 72 73 20 61 73 73 6f 63 69 61   numbers associa
5ba0: 74 65 64 20 77 69 74 68 20 74 68 65 20 66 69 72  ted with the fir
5bb0: 73 74 20 68 61 73 68 2d 74 61 62 6c 65 20 69 6e  st hash-table in
5bc0: 20 61 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20   a.** wal-index 
5bd0: 69 73 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20  is smaller than 
5be0: 75 73 75 61 6c 2e 20 54 68 69 73 20 69 73 20 73  usual. This is s
5bf0: 6f 20 74 68 61 74 20 74 68 65 72 65 20 69 73 20  o that there is 
5c00: 61 20 63 6f 6d 70 6c 65 74 65 0a 2a 2a 20 68 61  a complete.** ha
5c10: 73 68 2d 74 61 62 6c 65 20 6f 6e 20 65 61 63 68  sh-table on each
5c20: 20 61 6c 69 67 6e 65 64 20 33 32 4b 42 20 70 61   aligned 32KB pa
5c30: 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ge of the wal-in
5c40: 64 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  dex..*/.#define 
5c50: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
5c60: 4f 4e 45 20 20 28 48 41 53 48 54 41 42 4c 45 5f  ONE  (HASHTABLE_
5c70: 4e 50 41 47 45 20 2d 20 28 57 41 4c 49 4e 44 45  NPAGE - (WALINDE
5c80: 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f  X_HDR_SIZE/sizeo
5c90: 66 28 75 33 32 29 29 29 0a 0a 2f 2a 20 54 68 65  f(u32)))../* The
5ca0: 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 64 69   wal-index is di
5cb0: 76 69 64 65 64 20 69 6e 74 6f 20 70 61 67 65 73  vided into pages
5cc0: 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 50 47 53   of WALINDEX_PGS
5cd0: 5a 20 62 79 74 65 73 20 65 61 63 68 2e 20 2a 2f  Z bytes each. */
5ce0: 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45  .#define WALINDE
5cf0: 58 5f 50 47 53 5a 20 20 20 28 20 20 20 20 20 20  X_PGSZ   (      
5d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5d20: 20 20 20 5c 0a 20 20 20 20 73 69 7a 65 6f 66 28     \.    sizeof(
5d30: 68 74 5f 73 6c 6f 74 29 2a 48 41 53 48 54 41 42  ht_slot)*HASHTAB
5d40: 4c 45 5f 4e 53 4c 4f 54 20 2b 20 48 41 53 48 54  LE_NSLOT + HASHT
5d50: 41 42 4c 45 5f 4e 50 41 47 45 2a 73 69 7a 65 6f  ABLE_NPAGE*sizeo
5d60: 66 28 75 33 32 29 20 5c 0a 29 0a 0a 2f 2a 0a 2a  f(u32) \.)../*.*
5d70: 2a 20 4f 62 74 61 69 6e 20 61 20 70 6f 69 6e 74  * Obtain a point
5d80: 65 72 20 74 6f 20 74 68 65 20 69 50 61 67 65 27  er to the iPage'
5d90: 74 68 20 70 61 67 65 20 6f 66 20 74 68 65 20 77  th page of the w
5da0: 61 6c 2d 69 6e 64 65 78 2e 20 54 68 65 20 77 61  al-index. The wa
5db0: 6c 2d 69 6e 64 65 78 0a 2a 2a 20 69 73 20 62 72  l-index.** is br
5dc0: 6f 6b 65 6e 20 69 6e 74 6f 20 70 61 67 65 73 20  oken into pages 
5dd0: 6f 66 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a  of WALINDEX_PGSZ
5de0: 20 62 79 74 65 73 2e 20 57 61 6c 2d 69 6e 64 65   bytes. Wal-inde
5df0: 78 20 70 61 67 65 73 20 61 72 65 0a 2a 2a 20 6e  x pages are.** n
5e00: 75 6d 62 65 72 65 64 20 66 72 6f 6d 20 7a 65 72  umbered from zer
5e10: 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 69 73  o..**.** If this
5e20: 20 63 61 6c 6c 20 69 73 20 73 75 63 63 65 73 73   call is success
5e30: 66 75 6c 2c 20 2a 70 70 50 61 67 65 20 69 73 20  ful, *ppPage is 
5e40: 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  set to point to 
5e50: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a  the wal-index.**
5e60: 20 70 61 67 65 20 61 6e 64 20 53 51 4c 49 54 45   page and SQLITE
5e70: 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 2e  _OK is returned.
5e80: 20 49 66 20 61 6e 20 65 72 72 6f 72 20 28 61 6e   If an error (an
5e90: 20 4f 4f 4d 20 6f 72 20 56 46 53 20 65 72 72 6f   OOM or VFS erro
5ea0: 72 29 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 74 68  r) occurs,.** th
5eb0: 65 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  en an SQLite err
5ec0: 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  or code is retur
5ed0: 6e 65 64 20 61 6e 64 20 2a 70 70 50 61 67 65 20  ned and *ppPage 
5ee0: 69 73 20 73 65 74 20 74 6f 20 30 2e 0a 2a 2f 0a  is set to 0..*/.
5ef0: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e  static int walIn
5f00: 64 65 78 50 61 67 65 28 57 61 6c 20 2a 70 57 61  dexPage(Wal *pWa
5f10: 6c 2c 20 69 6e 74 20 69 50 61 67 65 2c 20 76 6f  l, int iPage, vo
5f20: 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 70 70 50  latile u32 **ppP
5f30: 61 67 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  age){.  int rc =
5f40: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f   SQLITE_OK;..  /
5f50: 2a 20 45 6e 6c 61 72 67 65 20 74 68 65 20 70 57  * Enlarge the pW
5f60: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 5d 20 61  al->apWiData[] a
5f70: 72 72 61 79 20 69 66 20 72 65 71 75 69 72 65 64  rray if required
5f80: 20 2a 2f 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e   */.  if( pWal->
5f90: 6e 57 69 44 61 74 61 3c 3d 69 50 61 67 65 20 29  nWiData<=iPage )
5fa0: 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20  {.    int nByte 
5fb0: 3d 20 73 69 7a 65 6f 66 28 75 33 32 2a 29 2a 28  = sizeof(u32*)*(
5fc0: 69 50 61 67 65 2b 31 29 3b 0a 20 20 20 20 76 6f  iPage+1);.    vo
5fd0: 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 61 70 4e  latile u32 **apN
5fe0: 65 77 3b 0a 20 20 20 20 61 70 4e 65 77 20 3d 20  ew;.    apNew = 
5ff0: 28 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a  (volatile u32 **
6000: 29 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63  )sqlite3_realloc
6010: 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d 3e 61  ((void *)pWal->a
6020: 70 57 69 44 61 74 61 2c 20 6e 42 79 74 65 29 3b  pWiData, nByte);
6030: 0a 20 20 20 20 69 66 28 20 21 61 70 4e 65 77 20  .    if( !apNew 
6040: 29 7b 0a 20 20 20 20 20 20 2a 70 70 50 61 67 65  ){.      *ppPage
6050: 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 65 74 75   = 0;.      retu
6060: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
6070: 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65  .    }.    memse
6080: 74 28 28 76 6f 69 64 2a 29 26 61 70 4e 65 77 5b  t((void*)&apNew[
6090: 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 5d 2c 20  pWal->nWiData], 
60a0: 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20 73 69  0,.           si
60b0: 7a 65 6f 66 28 75 33 32 2a 29 2a 28 69 50 61 67  zeof(u32*)*(iPag
60c0: 65 2b 31 2d 70 57 61 6c 2d 3e 6e 57 69 44 61 74  e+1-pWal->nWiDat
60d0: 61 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 61  a));.    pWal->a
60e0: 70 57 69 44 61 74 61 20 3d 20 61 70 4e 65 77 3b  pWiData = apNew;
60f0: 0a 20 20 20 20 70 57 61 6c 2d 3e 6e 57 69 44 61  .    pWal->nWiDa
6100: 74 61 20 3d 20 69 50 61 67 65 2b 31 3b 0a 20 20  ta = iPage+1;.  
6110: 7d 0a 0a 20 20 2f 2a 20 52 65 71 75 65 73 74 20  }..  /* Request 
6120: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65  a pointer to the
6130: 20 72 65 71 75 69 72 65 64 20 70 61 67 65 20 66   required page f
6140: 72 6f 6d 20 74 68 65 20 56 46 53 20 2a 2f 0a 20  rom the VFS */. 
6150: 20 69 66 28 20 70 57 61 6c 2d 3e 61 70 57 69 44   if( pWal->apWiD
6160: 61 74 61 5b 69 50 61 67 65 5d 3d 3d 30 20 29 7b  ata[iPage]==0 ){
6170: 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 65  .    if( pWal->e
6180: 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41  xclusiveMode==WA
6190: 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44  L_HEAPMEMORY_MOD
61a0: 45 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d  E ){.      pWal-
61b0: 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d  >apWiData[iPage]
61c0: 20 3d 20 28 75 33 32 20 76 6f 6c 61 74 69 6c 65   = (u32 volatile
61d0: 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   *)sqlite3Malloc
61e0: 5a 65 72 6f 28 57 41 4c 49 4e 44 45 58 5f 50 47  Zero(WALINDEX_PG
61f0: 53 5a 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21  SZ);.      if( !
6200: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69  pWal->apWiData[i
6210: 50 61 67 65 5d 20 29 20 72 63 20 3d 20 53 51 4c  Page] ) rc = SQL
6220: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
6230: 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d  else{.      rc =
6240: 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4d 61 70   sqlite3OsShmMap
6250: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 50  (pWal->pDbFd, iP
6260: 61 67 65 2c 20 57 41 4c 49 4e 44 45 58 5f 50 47  age, WALINDEX_PG
6270: 53 5a 2c 20 0a 20 20 20 20 20 20 20 20 20 20 70  SZ, .          p
6280: 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 2c 20  Wal->writeLock, 
6290: 28 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a  (void volatile *
62a0: 2a 29 26 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  *)&pWal->apWiDat
62b0: 61 5b 69 50 61 67 65 5d 0a 20 20 20 20 20 20 29  a[iPage].      )
62c0: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
62d0: 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 20  SQLITE_READONLY 
62e0: 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d  ){.        pWal-
62f0: 3e 72 65 61 64 4f 6e 6c 79 20 7c 3d 20 57 41 4c  >readOnly |= WAL
6300: 5f 53 48 4d 5f 52 44 4f 4e 4c 59 3b 0a 20 20 20  _SHM_RDONLY;.   
6310: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
6320: 5f 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  _OK;.      }.   
6330: 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 50 61 67   }.  }..  *ppPag
6340: 65 20 3d 20 70 57 61 6c 2d 3e 61 70 57 69 44 61  e = pWal->apWiDa
6350: 74 61 5b 69 50 61 67 65 5d 3b 0a 20 20 61 73 73  ta[iPage];.  ass
6360: 65 72 74 28 20 69 50 61 67 65 3d 3d 30 20 7c 7c  ert( iPage==0 ||
6370: 20 2a 70 70 50 61 67 65 20 7c 7c 20 72 63 21 3d   *ppPage || rc!=
6380: 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72  SQLITE_OK );.  r
6390: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
63a0: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  ** Return a poin
63b0: 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c 43 6b  ter to the WalCk
63c0: 70 74 49 6e 66 6f 20 73 74 72 75 63 74 75 72 65  ptInfo structure
63d0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
63e0: 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c  x..*/.static vol
63f0: 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66  atile WalCkptInf
6400: 6f 20 2a 77 61 6c 43 6b 70 74 49 6e 66 6f 28 57  o *walCkptInfo(W
6410: 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73  al *pWal){.  ass
6420: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
6430: 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70  ta>0 && pWal->ap
6440: 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72  WiData[0] );.  r
6450: 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20  eturn (volatile 
6460: 57 61 6c 43 6b 70 74 49 6e 66 6f 2a 29 26 28 70  WalCkptInfo*)&(p
6470: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
6480: 5b 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78  [sizeof(WalIndex
6490: 48 64 72 29 2f 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a  Hdr)/2]);.}../*.
64a0: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  ** Return a poin
64b0: 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c 49 6e  ter to the WalIn
64c0: 64 65 78 48 64 72 20 73 74 72 75 63 74 75 72 65  dexHdr structure
64d0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
64e0: 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c  x..*/.static vol
64f0: 61 74 69 6c 65 20 57 61 6c 49 6e 64 65 78 48 64  atile WalIndexHd
6500: 72 20 2a 77 61 6c 49 6e 64 65 78 48 64 72 28 57  r *walIndexHdr(W
6510: 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73  al *pWal){.  ass
6520: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
6530: 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70  ta>0 && pWal->ap
6540: 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72  WiData[0] );.  r
6550: 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20  eturn (volatile 
6560: 57 61 6c 49 6e 64 65 78 48 64 72 2a 29 70 57 61  WalIndexHdr*)pWa
6570: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 3b 0a  l->apWiData[0];.
6580: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61 72 67  }../*.** The arg
6590: 75 6d 65 6e 74 20 74 6f 20 74 68 69 73 20 6d 61  ument to this ma
65a0: 63 72 6f 20 6d 75 73 74 20 62 65 20 6f 66 20 74  cro must be of t
65b0: 79 70 65 20 75 33 32 2e 20 4f 6e 20 61 20 6c 69  ype u32. On a li
65c0: 74 74 6c 65 2d 65 6e 64 69 61 6e 0a 2a 2a 20 61  ttle-endian.** a
65d0: 72 63 68 69 74 65 63 74 75 72 65 2c 20 69 74 20  rchitecture, it 
65e0: 72 65 74 75 72 6e 73 20 74 68 65 20 75 33 32 20  returns the u32 
65f0: 76 61 6c 75 65 20 74 68 61 74 20 72 65 73 75 6c  value that resul
6600: 74 73 20 66 72 6f 6d 20 69 6e 74 65 72 70 72 65  ts from interpre
6610: 74 69 6e 67 0a 2a 2a 20 74 68 65 20 34 20 62 79  ting.** the 4 by
6620: 74 65 73 20 61 73 20 61 20 62 69 67 2d 65 6e 64  tes as a big-end
6630: 69 61 6e 20 76 61 6c 75 65 2e 20 4f 6e 20 61 20  ian value. On a 
6640: 62 69 67 2d 65 6e 64 69 61 6e 20 61 72 63 68 69  big-endian archi
6650: 74 65 63 74 75 72 65 2c 20 69 74 0a 2a 2a 20 72  tecture, it.** r
6660: 65 74 75 72 6e 73 20 74 68 65 20 76 61 6c 75 65  eturns the value
6670: 20 74 68 61 74 20 77 6f 75 6c 64 20 62 65 20 70   that would be p
6680: 72 6f 64 75 63 65 64 20 62 79 20 69 6e 74 65 72  roduced by inter
6690: 70 72 65 74 69 6e 67 20 74 68 65 20 34 20 62 79  preting the 4 by
66a0: 74 65 73 0a 2a 2a 20 6f 66 20 74 68 65 20 69 6e  tes.** of the in
66b0: 70 75 74 20 76 61 6c 75 65 20 61 73 20 61 20 6c  put value as a l
66c0: 69 74 74 6c 65 2d 65 6e 64 69 61 6e 20 69 6e 74  ittle-endian int
66d0: 65 67 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  eger..*/.#define
66e0: 20 42 59 54 45 53 57 41 50 33 32 28 78 29 20 28   BYTESWAP32(x) (
66f0: 20 5c 0a 20 20 20 20 28 28 28 78 29 26 30 78 30   \.    (((x)&0x0
6700: 30 30 30 30 30 46 46 29 3c 3c 32 34 29 20 2b 20  00000FF)<<24) + 
6710: 28 28 28 78 29 26 30 78 30 30 30 30 46 46 30 30  (((x)&0x0000FF00
6720: 29 3c 3c 38 29 20 20 5c 0a 20 20 2b 20 28 28 28  )<<8)  \.  + (((
6730: 78 29 26 30 78 30 30 46 46 30 30 30 30 29 3e 3e  x)&0x00FF0000)>>
6740: 38 29 20 20 2b 20 28 28 28 78 29 26 30 78 46 46  8)  + (((x)&0xFF
6750: 30 30 30 30 30 30 29 3e 3e 32 34 29 20 5c 0a 29  000000)>>24) \.)
6760: 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65  ../*.** Generate
6770: 20 6f 72 20 65 78 74 65 6e 64 20 61 6e 20 38 20   or extend an 8 
6780: 62 79 74 65 20 63 68 65 63 6b 73 75 6d 20 62 61  byte checksum ba
6790: 73 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 20  sed on the data 
67a0: 69 6e 20 0a 2a 2a 20 61 72 72 61 79 20 61 42 79  in .** array aBy
67b0: 74 65 5b 5d 20 61 6e 64 20 74 68 65 20 69 6e 69  te[] and the ini
67c0: 74 69 61 6c 20 76 61 6c 75 65 73 20 6f 66 20 61  tial values of a
67d0: 49 6e 5b 30 5d 20 61 6e 64 20 61 49 6e 5b 31 5d  In[0] and aIn[1]
67e0: 20 28 6f 72 0a 2a 2a 20 69 6e 69 74 69 61 6c 20   (or.** initial 
67f0: 76 61 6c 75 65 73 20 6f 66 20 30 20 61 6e 64 20  values of 0 and 
6800: 30 20 69 66 20 61 49 6e 3d 3d 4e 55 4c 4c 29 2e  0 if aIn==NULL).
6810: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b  .**.** The check
6820: 73 75 6d 20 69 73 20 77 72 69 74 74 65 6e 20 62  sum is written b
6830: 61 63 6b 20 69 6e 74 6f 20 61 4f 75 74 5b 5d 20  ack into aOut[] 
6840: 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  before returning
6850: 2e 0a 2a 2a 0a 2a 2a 20 6e 42 79 74 65 20 6d 75  ..**.** nByte mu
6860: 73 74 20 62 65 20 61 20 70 6f 73 69 74 69 76 65  st be a positive
6870: 20 6d 75 6c 74 69 70 6c 65 20 6f 66 20 38 2e 0a   multiple of 8..
6880: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
6890: 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
68a0: 0a 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73  .  int nativeCks
68b0: 75 6d 2c 20 2f 2a 20 54 72 75 65 20 66 6f 72 20  um, /* True for 
68c0: 6e 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64 65  native byte-orde
68d0: 72 2c 20 66 61 6c 73 65 20 66 6f 72 20 6e 6f 6e  r, false for non
68e0: 2d 6e 61 74 69 76 65 20 2a 2f 0a 20 20 75 38 20  -native */.  u8 
68f0: 2a 61 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  *a,           /*
6900: 20 43 6f 6e 74 65 6e 74 20 74 6f 20 62 65 20 63   Content to be c
6910: 68 65 63 6b 73 75 6d 6d 65 64 20 2a 2f 0a 20 20  hecksummed */.  
6920: 69 6e 74 20 6e 42 79 74 65 2c 20 20 20 20 20 20  int nByte,      
6930: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 63 6f 6e   /* Bytes of con
6940: 74 65 6e 74 20 69 6e 20 61 5b 5d 2e 20 20 4d 75  tent in a[].  Mu
6950: 73 74 20 62 65 20 61 20 6d 75 6c 74 69 70 6c 65  st be a multiple
6960: 20 6f 66 20 38 2e 20 2a 2f 0a 20 20 63 6f 6e 73   of 8. */.  cons
6970: 74 20 75 33 32 20 2a 61 49 6e 2c 20 20 2f 2a 20  t u32 *aIn,  /* 
6980: 49 6e 69 74 69 61 6c 20 63 68 65 63 6b 73 75 6d  Initial checksum
6990: 20 76 61 6c 75 65 20 69 6e 70 75 74 20 2a 2f 0a   value input */.
69a0: 20 20 75 33 32 20 2a 61 4f 75 74 20 20 20 20 20    u32 *aOut     
69b0: 20 20 20 2f 2a 20 4f 55 54 3a 20 46 69 6e 61 6c     /* OUT: Final
69c0: 20 63 68 65 63 6b 73 75 6d 20 76 61 6c 75 65 20   checksum value 
69d0: 6f 75 74 70 75 74 20 2a 2f 0a 29 7b 0a 20 20 75  output */.){.  u
69e0: 33 32 20 73 31 2c 20 73 32 3b 0a 20 20 75 33 32  32 s1, s2;.  u32
69f0: 20 2a 61 44 61 74 61 20 3d 20 28 75 33 32 20 2a   *aData = (u32 *
6a00: 29 61 3b 0a 20 20 75 33 32 20 2a 61 45 6e 64 20  )a;.  u32 *aEnd 
6a10: 3d 20 28 75 33 32 20 2a 29 26 61 5b 6e 42 79 74  = (u32 *)&a[nByt
6a20: 65 5d 3b 0a 0a 20 20 69 66 28 20 61 49 6e 20 29  e];..  if( aIn )
6a30: 7b 0a 20 20 20 20 73 31 20 3d 20 61 49 6e 5b 30  {.    s1 = aIn[0
6a40: 5d 3b 0a 20 20 20 20 73 32 20 3d 20 61 49 6e 5b  ];.    s2 = aIn[
6a50: 31 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  1];.  }else{.   
6a60: 20 73 31 20 3d 20 73 32 20 3d 20 30 3b 0a 20 20   s1 = s2 = 0;.  
6a70: 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 42 79  }..  assert( nBy
6a80: 74 65 3e 3d 38 20 29 3b 0a 20 20 61 73 73 65 72  te>=8 );.  asser
6a90: 74 28 20 28 6e 42 79 74 65 26 30 78 30 30 30 30  t( (nByte&0x0000
6aa0: 30 30 30 37 29 3d 3d 30 20 29 3b 0a 0a 20 20 69  0007)==0 );..  i
6ab0: 66 28 20 6e 61 74 69 76 65 43 6b 73 75 6d 20 29  f( nativeCksum )
6ac0: 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 20  {.    do {.     
6ad0: 20 73 31 20 2b 3d 20 2a 61 44 61 74 61 2b 2b 20   s1 += *aData++ 
6ae0: 2b 20 73 32 3b 0a 20 20 20 20 20 20 73 32 20 2b  + s2;.      s2 +
6af0: 3d 20 2a 61 44 61 74 61 2b 2b 20 2b 20 73 31 3b  = *aData++ + s1;
6b00: 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 61 44 61  .    }while( aDa
6b10: 74 61 3c 61 45 6e 64 20 29 3b 0a 20 20 7d 65 6c  ta<aEnd );.  }el
6b20: 73 65 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20  se{.    do {.   
6b30: 20 20 20 73 31 20 2b 3d 20 42 59 54 45 53 57 41     s1 += BYTESWA
6b40: 50 33 32 28 61 44 61 74 61 5b 30 5d 29 20 2b 20  P32(aData[0]) + 
6b50: 73 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d 20  s2;.      s2 += 
6b60: 42 59 54 45 53 57 41 50 33 32 28 61 44 61 74 61  BYTESWAP32(aData
6b70: 5b 31 5d 29 20 2b 20 73 31 3b 0a 20 20 20 20 20  [1]) + s1;.     
6b80: 20 61 44 61 74 61 20 2b 3d 20 32 3b 0a 20 20 20   aData += 2;.   
6b90: 20 7d 77 68 69 6c 65 28 20 61 44 61 74 61 3c 61   }while( aData<a
6ba0: 45 6e 64 20 29 3b 0a 20 20 7d 0a 0a 20 20 61 4f  End );.  }..  aO
6bb0: 75 74 5b 30 5d 20 3d 20 73 31 3b 0a 20 20 61 4f  ut[0] = s1;.  aO
6bc0: 75 74 5b 31 5d 20 3d 20 73 32 3b 0a 7d 0a 0a 73  ut[1] = s2;.}..s
6bd0: 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 53 68  tatic void walSh
6be0: 6d 42 61 72 72 69 65 72 28 57 61 6c 20 2a 70 57  mBarrier(Wal *pW
6bf0: 61 6c 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d  al){.  if( pWal-
6c00: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 21 3d  >exclusiveMode!=
6c10: 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d  WAL_HEAPMEMORY_M
6c20: 4f 44 45 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  ODE ){.    sqlit
6c30: 65 33 4f 73 53 68 6d 42 61 72 72 69 65 72 28 70  e3OsShmBarrier(p
6c40: 57 61 6c 2d 3e 70 44 62 46 64 29 3b 0a 20 20 7d  Wal->pDbFd);.  }
6c50: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20  .}../*.** Write 
6c60: 74 68 65 20 68 65 61 64 65 72 20 69 6e 66 6f 72  the header infor
6c70: 6d 61 74 69 6f 6e 20 69 6e 20 70 57 61 6c 2d 3e  mation in pWal->
6c80: 68 64 72 20 69 6e 74 6f 20 74 68 65 20 77 61 6c  hdr into the wal
6c90: 2d 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 54 68  -index..**.** Th
6ca0: 65 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20 70 57  e checksum on pW
6cb0: 61 6c 2d 3e 68 64 72 20 69 73 20 75 70 64 61 74  al->hdr is updat
6cc0: 65 64 20 62 65 66 6f 72 65 20 69 74 20 69 73 20  ed before it is 
6cd0: 77 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 61 74  written..*/.stat
6ce0: 69 63 20 76 6f 69 64 20 77 61 6c 49 6e 64 65 78  ic void walIndex
6cf0: 57 72 69 74 65 48 64 72 28 57 61 6c 20 2a 70 57  WriteHdr(Wal *pW
6d00: 61 6c 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20  al){.  volatile 
6d10: 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 61 48 64  WalIndexHdr *aHd
6d20: 72 20 3d 20 77 61 6c 49 6e 64 65 78 48 64 72 28  r = walIndexHdr(
6d30: 70 57 61 6c 29 3b 0a 20 20 63 6f 6e 73 74 20 69  pWal);.  const i
6d40: 6e 74 20 6e 43 6b 73 75 6d 20 3d 20 6f 66 66 73  nt nCksum = offs
6d50: 65 74 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  etof(WalIndexHdr
6d60: 2c 20 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 61 73  , aCksum);..  as
6d70: 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74  sert( pWal->writ
6d80: 65 4c 6f 63 6b 20 29 3b 0a 20 20 70 57 61 6c 2d  eLock );.  pWal-
6d90: 3e 68 64 72 2e 69 73 49 6e 69 74 20 3d 20 31 3b  >hdr.isInit = 1;
6da0: 0a 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56 65  .  pWal->hdr.iVe
6db0: 72 73 69 6f 6e 20 3d 20 57 41 4c 49 4e 44 45 58  rsion = WALINDEX
6dc0: 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 3b 0a 20 20  _MAX_VERSION;.  
6dd0: 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73  walChecksumBytes
6de0: 28 31 2c 20 28 75 38 2a 29 26 70 57 61 6c 2d 3e  (1, (u8*)&pWal->
6df0: 68 64 72 2c 20 6e 43 6b 73 75 6d 2c 20 30 2c 20  hdr, nCksum, 0, 
6e00: 70 57 61 6c 2d 3e 68 64 72 2e 61 43 6b 73 75 6d  pWal->hdr.aCksum
6e10: 29 3b 0a 20 20 6d 65 6d 63 70 79 28 28 76 6f 69  );.  memcpy((voi
6e20: 64 20 2a 29 26 61 48 64 72 5b 31 5d 2c 20 28 76  d *)&aHdr[1], (v
6e30: 6f 69 64 20 2a 29 26 70 57 61 6c 2d 3e 68 64 72  oid *)&pWal->hdr
6e40: 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65  , sizeof(WalInde
6e50: 78 48 64 72 29 29 3b 0a 20 20 77 61 6c 53 68 6d  xHdr));.  walShm
6e60: 42 61 72 72 69 65 72 28 70 57 61 6c 29 3b 0a 20  Barrier(pWal);. 
6e70: 20 6d 65 6d 63 70 79 28 28 76 6f 69 64 20 2a 29   memcpy((void *)
6e80: 26 61 48 64 72 5b 30 5d 2c 20 28 76 6f 69 64 20  &aHdr[0], (void 
6e90: 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69  *)&pWal->hdr, si
6ea0: 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
6eb0: 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  ));.}../*.** Thi
6ec0: 73 20 66 75 6e 63 74 69 6f 6e 20 65 6e 63 6f 64  s function encod
6ed0: 65 73 20 61 20 73 69 6e 67 6c 65 20 66 72 61 6d  es a single fram
6ee0: 65 20 68 65 61 64 65 72 20 61 6e 64 20 77 72 69  e header and wri
6ef0: 74 65 73 20 69 74 20 74 6f 20 61 20 62 75 66 66  tes it to a buff
6f00: 65 72 0a 2a 2a 20 73 75 70 70 6c 69 65 64 20 62  er.** supplied b
6f10: 79 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 41 20  y the caller. A 
6f20: 66 72 61 6d 65 2d 68 65 61 64 65 72 20 69 73 20  frame-header is 
6f30: 6d 61 64 65 20 75 70 20 6f 66 20 61 20 73 65 72  made up of a ser
6f40: 69 65 73 20 6f 66 20 0a 2a 2a 20 34 2d 62 79 74  ies of .** 4-byt
6f50: 65 20 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74  e big-endian int
6f60: 65 67 65 72 73 2c 20 61 73 20 66 6f 6c 6c 6f 77  egers, as follow
6f70: 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 30 3a 20  s:.**.**     0: 
6f80: 50 61 67 65 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20  Page number..** 
6f90: 20 20 20 20 34 3a 20 46 6f 72 20 63 6f 6d 6d 69      4: For commi
6fa0: 74 20 72 65 63 6f 72 64 73 2c 20 74 68 65 20 73  t records, the s
6fb0: 69 7a 65 20 6f 66 20 74 68 65 20 64 61 74 61 62  ize of the datab
6fc0: 61 73 65 20 69 6d 61 67 65 20 69 6e 20 70 61 67  ase image in pag
6fd0: 65 73 20 0a 2a 2a 20 20 20 20 20 20 20 20 61 66  es .**        af
6fe0: 74 65 72 20 74 68 65 20 63 6f 6d 6d 69 74 2e 20  ter the commit. 
6ff0: 46 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 72 65  For all other re
7000: 63 6f 72 64 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20  cords, zero..** 
7010: 20 20 20 20 38 3a 20 53 61 6c 74 2d 31 20 28 63      8: Salt-1 (c
7020: 6f 70 69 65 64 20 66 72 6f 6d 20 74 68 65 20 77  opied from the w
7030: 61 6c 2d 68 65 61 64 65 72 29 0a 2a 2a 20 20 20  al-header).**   
7040: 20 31 32 3a 20 53 61 6c 74 2d 32 20 28 63 6f 70   12: Salt-2 (cop
7050: 69 65 64 20 66 72 6f 6d 20 74 68 65 20 77 61 6c  ied from the wal
7060: 2d 68 65 61 64 65 72 29 0a 2a 2a 20 20 20 20 31  -header).**    1
7070: 36 3a 20 43 68 65 63 6b 73 75 6d 2d 31 2e 0a 2a  6: Checksum-1..*
7080: 2a 20 20 20 20 32 30 3a 20 43 68 65 63 6b 73 75  *    20: Checksu
7090: 6d 2d 32 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  m-2..*/.static v
70a0: 6f 69 64 20 77 61 6c 45 6e 63 6f 64 65 46 72 61  oid walEncodeFra
70b0: 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c  me(.  Wal *pWal,
70c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
70d0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 77 72 69        /* The wri
70e0: 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 2a 2f 0a  te-ahead log */.
70f0: 20 20 75 33 32 20 69 50 61 67 65 2c 20 20 20 20    u32 iPage,    
7100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7110: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61    /* Database pa
7120: 67 65 20 6e 75 6d 62 65 72 20 66 6f 72 20 66 72  ge number for fr
7130: 61 6d 65 20 2a 2f 0a 20 20 75 33 32 20 6e 54 72  ame */.  u32 nTr
7140: 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20 20  uncate,         
7150: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20           /* New 
7160: 64 62 20 73 69 7a 65 20 28 6f 72 20 30 20 66 6f  db size (or 0 fo
7170: 72 20 6e 6f 6e 2d 63 6f 6d 6d 69 74 20 66 72 61  r non-commit fra
7180: 6d 65 73 29 20 2a 2f 0a 20 20 75 38 20 2a 61 44  mes) */.  u8 *aD
7190: 61 74 61 2c 20 20 20 20 20 20 20 20 20 20 20 20  ata,            
71a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
71b0: 6e 74 65 72 20 74 6f 20 70 61 67 65 20 64 61 74  nter to page dat
71c0: 61 20 2a 2f 0a 20 20 75 38 20 2a 61 46 72 61 6d  a */.  u8 *aFram
71d0: 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e               
71e0: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 57         /* OUT: W
71f0: 72 69 74 65 20 65 6e 63 6f 64 65 64 20 66 72 61  rite encoded fra
7200: 6d 65 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20  me here */.){.  
7210: 69 6e 74 20 6e 61 74 69 76 65 43 6b 73 75 6d 3b  int nativeCksum;
7220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7230: 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e 61 74 69  /* True for nati
7240: 76 65 20 62 79 74 65 2d 6f 72 64 65 72 20 63 68  ve byte-order ch
7250: 65 63 6b 73 75 6d 73 20 2a 2f 0a 20 20 75 33 32  ecksums */.  u32
7260: 20 2a 61 43 6b 73 75 6d 20 3d 20 70 57 61 6c 2d   *aCksum = pWal-
7270: 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
7280: 3b 0a 20 20 61 73 73 65 72 74 28 20 57 41 4c 5f  ;.  assert( WAL_
7290: 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3d 3d 32  FRAME_HDRSIZE==2
72a0: 34 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 50 75  4 );.  sqlite3Pu
72b0: 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 30  t4byte(&aFrame[0
72c0: 5d 2c 20 69 50 61 67 65 29 3b 0a 20 20 73 71 6c  ], iPage);.  sql
72d0: 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 46  ite3Put4byte(&aF
72e0: 72 61 6d 65 5b 34 5d 2c 20 6e 54 72 75 6e 63 61  rame[4], nTrunca
72f0: 74 65 29 3b 0a 20 20 6d 65 6d 63 70 79 28 26 61  te);.  memcpy(&a
7300: 46 72 61 6d 65 5b 38 5d 2c 20 70 57 61 6c 2d 3e  Frame[8], pWal->
7310: 68 64 72 2e 61 53 61 6c 74 2c 20 38 29 3b 0a 0a  hdr.aSalt, 8);..
7320: 20 20 6e 61 74 69 76 65 43 6b 73 75 6d 20 3d 20    nativeCksum = 
7330: 28 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e  (pWal->hdr.bigEn
7340: 64 43 6b 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42  dCksum==SQLITE_B
7350: 49 47 45 4e 44 49 41 4e 29 3b 0a 20 20 77 61 6c  IGENDIAN);.  wal
7360: 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28 6e 61  ChecksumBytes(na
7370: 74 69 76 65 43 6b 73 75 6d 2c 20 61 46 72 61 6d  tiveCksum, aFram
7380: 65 2c 20 38 2c 20 61 43 6b 73 75 6d 2c 20 61 43  e, 8, aCksum, aC
7390: 6b 73 75 6d 29 3b 0a 20 20 77 61 6c 43 68 65 63  ksum);.  walChec
73a0: 6b 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65  ksumBytes(native
73b0: 43 6b 73 75 6d 2c 20 61 44 61 74 61 2c 20 70 57  Cksum, aData, pW
73c0: 61 6c 2d 3e 73 7a 50 61 67 65 2c 20 61 43 6b 73  al->szPage, aCks
73d0: 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a 0a 20 20  um, aCksum);..  
73e0: 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28  sqlite3Put4byte(
73f0: 26 61 46 72 61 6d 65 5b 31 36 5d 2c 20 61 43 6b  &aFrame[16], aCk
7400: 73 75 6d 5b 30 5d 29 3b 0a 20 20 73 71 6c 69 74  sum[0]);.  sqlit
7410: 65 33 50 75 74 34 62 79 74 65 28 26 61 46 72 61  e3Put4byte(&aFra
7420: 6d 65 5b 32 30 5d 2c 20 61 43 6b 73 75 6d 5b 31  me[20], aCksum[1
7430: 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65  ]);.}../*.** Che
7440: 63 6b 20 74 6f 20 73 65 65 20 69 66 20 74 68 65  ck to see if the
7450: 20 66 72 61 6d 65 20 77 69 74 68 20 68 65 61 64   frame with head
7460: 65 72 20 69 6e 20 61 46 72 61 6d 65 5b 5d 20 61  er in aFrame[] a
7470: 6e 64 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 69 6e  nd content.** in
7480: 20 61 44 61 74 61 5b 5d 20 69 73 20 76 61 6c 69   aData[] is vali
7490: 64 2e 20 20 49 66 20 69 74 20 69 73 20 61 20 76  d.  If it is a v
74a0: 61 6c 69 64 20 66 72 61 6d 65 2c 20 66 69 6c 6c  alid frame, fill
74b0: 20 2a 70 69 50 61 67 65 20 61 6e 64 0a 2a 2a 20   *piPage and.** 
74c0: 2a 70 6e 54 72 75 6e 63 61 74 65 20 61 6e 64 20  *pnTruncate and 
74d0: 72 65 74 75 72 6e 20 74 72 75 65 2e 20 20 52 65  return true.  Re
74e0: 74 75 72 6e 20 69 66 20 74 68 65 20 66 72 61 6d  turn if the fram
74f0: 65 20 69 73 20 6e 6f 74 20 76 61 6c 69 64 2e 0a  e is not valid..
7500: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  */.static int wa
7510: 6c 44 65 63 6f 64 65 46 72 61 6d 65 28 0a 20 20  lDecodeFrame(.  
7520: 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20  Wal *pWal,      
7530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7540: 2f 2a 20 54 68 65 20 77 72 69 74 65 2d 61 68 65  /* The write-ahe
7550: 61 64 20 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20  ad log */.  u32 
7560: 2a 70 69 50 61 67 65 2c 20 20 20 20 20 20 20 20  *piPage,        
7570: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
7580: 55 54 3a 20 44 61 74 61 62 61 73 65 20 70 61 67  UT: Database pag
7590: 65 20 6e 75 6d 62 65 72 20 66 6f 72 20 66 72 61  e number for fra
75a0: 6d 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70 6e 54  me */.  u32 *pnT
75b0: 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20  runcate,        
75c0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
75d0: 4e 65 77 20 64 62 20 73 69 7a 65 20 28 6f 72 20  New db size (or 
75e0: 30 20 69 66 20 6e 6f 74 20 63 6f 6d 6d 69 74 29  0 if not commit)
75f0: 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74 61 2c   */.  u8 *aData,
7600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7610: 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
7620: 20 74 6f 20 70 61 67 65 20 64 61 74 61 20 28 66   to page data (f
7630: 6f 72 20 63 68 65 63 6b 73 75 6d 29 20 2a 2f 0a  or checksum) */.
7640: 20 20 75 38 20 2a 61 46 72 61 6d 65 20 20 20 20    u8 *aFrame    
7650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7660: 20 20 2f 2a 20 46 72 61 6d 65 20 64 61 74 61 20    /* Frame data 
7670: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 61 74 69  */.){.  int nati
7680: 76 65 43 6b 73 75 6d 3b 20 20 20 20 20 20 20 20  veCksum;        
7690: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
76a0: 66 6f 72 20 6e 61 74 69 76 65 20 62 79 74 65 2d  for native byte-
76b0: 6f 72 64 65 72 20 63 68 65 63 6b 73 75 6d 73 20  order checksums 
76c0: 2a 2f 0a 20 20 75 33 32 20 2a 61 43 6b 73 75 6d  */.  u32 *aCksum
76d0: 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72   = pWal->hdr.aFr
76e0: 61 6d 65 43 6b 73 75 6d 3b 0a 20 20 75 33 32 20  ameCksum;.  u32 
76f0: 70 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20  pgno;           
7700: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
7710: 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68  age number of th
7720: 65 20 66 72 61 6d 65 20 2a 2f 0a 20 20 61 73 73  e frame */.  ass
7730: 65 72 74 28 20 57 41 4c 5f 46 52 41 4d 45 5f 48  ert( WAL_FRAME_H
7740: 44 52 53 49 5a 45 3d 3d 32 34 20 29 3b 0a 0a 20  DRSIZE==24 );.. 
7750: 20 2f 2a 20 41 20 66 72 61 6d 65 20 69 73 20 6f   /* A frame is o
7760: 6e 6c 79 20 76 61 6c 69 64 20 69 66 20 74 68 65  nly valid if the
7770: 20 73 61 6c 74 20 76 61 6c 75 65 73 20 69 6e 20   salt values in 
7780: 74 68 65 20 66 72 61 6d 65 2d 68 65 61 64 65 72  the frame-header
7790: 0a 20 20 2a 2a 20 6d 61 74 63 68 20 74 68 65 20  .  ** match the 
77a0: 73 61 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74  salt values in t
77b0: 68 65 20 77 61 6c 2d 68 65 61 64 65 72 2e 20 0a  he wal-header. .
77c0: 20 20 2a 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d    */.  if( memcm
77d0: 70 28 26 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61  p(&pWal->hdr.aSa
77e0: 6c 74 2c 20 26 61 46 72 61 6d 65 5b 38 5d 2c 20  lt, &aFrame[8], 
77f0: 38 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  8)!=0 ){.    ret
7800: 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  urn 0;.  }..  /*
7810: 20 41 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79   A frame is only
7820: 20 76 61 6c 69 64 20 69 66 20 74 68 65 20 70 61   valid if the pa
7830: 67 65 20 6e 75 6d 62 65 72 20 69 73 20 63 72 65  ge number is cre
7840: 61 74 65 72 20 74 68 61 6e 20 7a 65 72 6f 2e 0a  ater than zero..
7850: 20 20 2a 2f 0a 20 20 70 67 6e 6f 20 3d 20 73 71    */.  pgno = sq
7860: 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61  lite3Get4byte(&a
7870: 46 72 61 6d 65 5b 30 5d 29 3b 0a 20 20 69 66 28  Frame[0]);.  if(
7880: 20 70 67 6e 6f 3d 3d 30 20 29 7b 0a 20 20 20 20   pgno==0 ){.    
7890: 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20  return 0;.  }.. 
78a0: 20 2f 2a 20 41 20 66 72 61 6d 65 20 69 73 20 6f   /* A frame is o
78b0: 6e 6c 79 20 76 61 6c 69 64 20 69 66 20 61 20 63  nly valid if a c
78c0: 68 65 63 6b 73 75 6d 20 6f 66 20 74 68 65 20 57  hecksum of the W
78d0: 41 4c 20 68 65 61 64 65 72 2c 0a 20 20 2a 2a 20  AL header,.  ** 
78e0: 61 6c 6c 20 70 72 69 6f 72 20 66 72 61 6d 73 2c  all prior frams,
78f0: 20 74 68 65 20 66 69 72 73 74 20 31 36 20 62 79   the first 16 by
7900: 74 65 73 20 6f 66 20 74 68 69 73 20 66 72 61 6d  tes of this fram
7910: 65 2d 68 65 61 64 65 72 2c 20 0a 20 20 2a 2a 20  e-header, .  ** 
7920: 61 6e 64 20 74 68 65 20 66 72 61 6d 65 2d 64 61  and the frame-da
7930: 74 61 20 6d 61 74 63 68 65 73 20 74 68 65 20 63  ta matches the c
7940: 68 65 63 6b 73 75 6d 20 69 6e 20 74 68 65 20 6c  hecksum in the l
7950: 61 73 74 20 38 20 0a 20 20 2a 2a 20 62 79 74 65  ast 8 .  ** byte
7960: 73 20 6f 66 20 74 68 69 73 20 66 72 61 6d 65 2d  s of this frame-
7970: 68 65 61 64 65 72 2e 0a 20 20 2a 2f 0a 20 20 6e  header..  */.  n
7980: 61 74 69 76 65 43 6b 73 75 6d 20 3d 20 28 70 57  ativeCksum = (pW
7990: 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b  al->hdr.bigEndCk
79a0: 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45  sum==SQLITE_BIGE
79b0: 4e 44 49 41 4e 29 3b 0a 20 20 77 61 6c 43 68 65  NDIAN);.  walChe
79c0: 63 6b 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76  cksumBytes(nativ
79d0: 65 43 6b 73 75 6d 2c 20 61 46 72 61 6d 65 2c 20  eCksum, aFrame, 
79e0: 38 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75  8, aCksum, aCksu
79f0: 6d 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75  m);.  walChecksu
7a00: 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73  mBytes(nativeCks
7a10: 75 6d 2c 20 61 44 61 74 61 2c 20 70 57 61 6c 2d  um, aData, pWal-
7a20: 3e 73 7a 50 61 67 65 2c 20 61 43 6b 73 75 6d 2c  >szPage, aCksum,
7a30: 20 61 43 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20   aCksum);.  if( 
7a40: 61 43 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74  aCksum[0]!=sqlit
7a50: 65 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61  e3Get4byte(&aFra
7a60: 6d 65 5b 31 36 5d 29 20 0a 20 20 20 7c 7c 20 61  me[16]) .   || a
7a70: 43 6b 73 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65  Cksum[1]!=sqlite
7a80: 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Get4byte(&aFram
7a90: 65 5b 32 30 5d 29 20 0a 20 20 29 7b 0a 20 20 20  e[20]) .  ){.   
7aa0: 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66 61 69   /* Checksum fai
7ab0: 6c 65 64 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75  led. */.    retu
7ac0: 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  rn 0;.  }..  /* 
7ad0: 49 66 20 77 65 20 72 65 61 63 68 20 74 68 69 73  If we reach this
7ae0: 20 70 6f 69 6e 74 2c 20 74 68 65 20 66 72 61 6d   point, the fram
7af0: 65 20 69 73 20 76 61 6c 69 64 2e 20 20 52 65 74  e is valid.  Ret
7b00: 75 72 6e 20 74 68 65 20 70 61 67 65 20 6e 75 6d  urn the page num
7b10: 62 65 72 0a 20 20 2a 2a 20 61 6e 64 20 74 68 65  ber.  ** and the
7b20: 20 6e 65 77 20 64 61 74 61 62 61 73 65 20 73 69   new database si
7b30: 7a 65 2e 0a 20 20 2a 2f 0a 20 20 2a 70 69 50 61  ze..  */.  *piPa
7b40: 67 65 20 3d 20 70 67 6e 6f 3b 0a 20 20 2a 70 6e  ge = pgno;.  *pn
7b50: 54 72 75 6e 63 61 74 65 20 3d 20 73 71 6c 69 74  Truncate = sqlit
7b60: 65 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61  e3Get4byte(&aFra
7b70: 6d 65 5b 34 5d 29 3b 0a 20 20 72 65 74 75 72 6e  me[4]);.  return
7b80: 20 31 3b 0a 7d 0a 0a 0a 23 69 66 20 64 65 66 69   1;.}...#if defi
7b90: 6e 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29  ned(SQLITE_TEST)
7ba0: 20 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49   && defined(SQLI
7bb0: 54 45 5f 44 45 42 55 47 29 0a 2f 2a 0a 2a 2a 20  TE_DEBUG)./*.** 
7bc0: 4e 61 6d 65 73 20 6f 66 20 6c 6f 63 6b 73 2e 20  Names of locks. 
7bd0: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73   This routine is
7be0: 20 75 73 65 64 20 74 6f 20 70 72 6f 76 69 64 65   used to provide
7bf0: 20 64 65 62 75 67 67 69 6e 67 20 6f 75 74 70 75   debugging outpu
7c00: 74 20 61 6e 64 20 69 73 20 6e 6f 74 0a 2a 2a 20  t and is not.** 
7c10: 61 20 70 61 72 74 20 6f 66 20 61 6e 20 6f 72 64  a part of an ord
7c20: 69 6e 61 72 79 20 62 75 69 6c 64 2e 0a 2a 2f 0a  inary build..*/.
7c30: 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61  static const cha
7c40: 72 20 2a 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 69  r *walLockName(i
7c50: 6e 74 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69  nt lockIdx){.  i
7c60: 66 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f  f( lockIdx==WAL_
7c70: 57 52 49 54 45 5f 4c 4f 43 4b 20 29 7b 0a 20 20  WRITE_LOCK ){.  
7c80: 20 20 72 65 74 75 72 6e 20 22 57 52 49 54 45 2d    return "WRITE-
7c90: 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69  LOCK";.  }else i
7ca0: 66 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f  f( lockIdx==WAL_
7cb0: 43 4b 50 54 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20  CKPT_LOCK ){.   
7cc0: 20 72 65 74 75 72 6e 20 22 43 4b 50 54 2d 4c 4f   return "CKPT-LO
7cd0: 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  CK";.  }else if(
7ce0: 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 52 45   lockIdx==WAL_RE
7cf0: 43 4f 56 45 52 5f 4c 4f 43 4b 20 29 7b 0a 20 20  COVER_LOCK ){.  
7d00: 20 20 72 65 74 75 72 6e 20 22 52 45 43 4f 56 45    return "RECOVE
7d10: 52 2d 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65  R-LOCK";.  }else
7d20: 7b 0a 20 20 20 20 73 74 61 74 69 63 20 63 68 61  {.    static cha
7d30: 72 20 7a 4e 61 6d 65 5b 31 35 5d 3b 0a 20 20 20  r zName[15];.   
7d40: 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74   sqlite3_snprint
7d50: 66 28 73 69 7a 65 6f 66 28 7a 4e 61 6d 65 29 2c  f(sizeof(zName),
7d60: 20 7a 4e 61 6d 65 2c 20 22 52 45 41 44 2d 4c 4f   zName, "READ-LO
7d70: 43 4b 5b 25 64 5d 22 2c 0a 20 20 20 20 20 20 20  CK[%d]",.       
7d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f                lo
7d90: 63 6b 49 64 78 2d 57 41 4c 5f 52 45 41 44 5f 4c  ckIdx-WAL_READ_L
7da0: 4f 43 4b 28 30 29 29 3b 0a 20 20 20 20 72 65 74  OCK(0));.    ret
7db0: 75 72 6e 20 7a 4e 61 6d 65 3b 0a 20 20 7d 0a 7d  urn zName;.  }.}
7dc0: 0a 23 65 6e 64 69 66 20 2f 2a 64 65 66 69 6e 65  .#endif /*define
7dd0: 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 7c  d(SQLITE_TEST) |
7de0: 7c 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  | defined(SQLITE
7df0: 5f 44 45 42 55 47 29 20 2a 2f 0a 20 20 20 20 0a  _DEBUG) */.    .
7e00: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 6f 72 20 72 65  ./*.** Set or re
7e10: 6c 65 61 73 65 20 6c 6f 63 6b 73 20 6f 6e 20 74  lease locks on t
7e20: 68 65 20 57 41 4c 2e 20 20 4c 6f 63 6b 73 20 61  he WAL.  Locks a
7e30: 72 65 20 65 69 74 68 65 72 20 73 68 61 72 65 64  re either shared
7e40: 20 6f 72 20 65 78 63 6c 75 73 69 76 65 2e 0a 2a   or exclusive..*
7e50: 2a 20 41 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20  * A lock cannot 
7e60: 62 65 20 6d 6f 76 65 64 20 64 69 72 65 63 74 6c  be moved directl
7e70: 79 20 62 65 74 77 65 65 6e 20 73 68 61 72 65 64  y between shared
7e80: 20 61 6e 64 20 65 78 63 6c 75 73 69 76 65 20 2d   and exclusive -
7e90: 20 69 74 20 6d 75 73 74 20 67 6f 0a 2a 2a 20 74   it must go.** t
7ea0: 68 72 6f 75 67 68 20 74 68 65 20 75 6e 6c 6f 63  hrough the unloc
7eb0: 6b 65 64 20 73 74 61 74 65 20 66 69 72 73 74 2e  ked state first.
7ec0: 0a 2a 2a 0a 2a 2a 20 49 6e 20 6c 6f 63 6b 69 6e  .**.** In lockin
7ed0: 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45  g_mode=EXCLUSIVE
7ee0: 2c 20 61 6c 6c 20 6f 66 20 74 68 65 73 65 20 72  , all of these r
7ef0: 6f 75 74 69 6e 65 73 20 62 65 63 6f 6d 65 20 6e  outines become n
7f00: 6f 2d 6f 70 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  o-ops..*/.static
7f10: 20 69 6e 74 20 77 61 6c 4c 6f 63 6b 53 68 61 72   int walLockShar
7f20: 65 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e  ed(Wal *pWal, in
7f30: 74 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 6e  t lockIdx){.  in
7f40: 74 20 72 63 3b 0a 20 20 69 66 28 20 70 57 61 6c  t rc;.  if( pWal
7f50: 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20  ->exclusiveMode 
7f60: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
7f70: 4f 4b 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  OK;.  rc = sqlit
7f80: 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c  e3OsShmLock(pWal
7f90: 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78  ->pDbFd, lockIdx
7fa0: 2c 20 31 2c 0a 20 20 20 20 20 20 20 20 20 20 20  , 1,.           
7fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
7fc0: 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53  ITE_SHM_LOCK | S
7fd0: 51 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44  QLITE_SHM_SHARED
7fe0: 29 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  );.  WALTRACE(("
7ff0: 57 41 4c 25 70 3a 20 61 63 71 75 69 72 65 20 53  WAL%p: acquire S
8000: 48 41 52 45 44 2d 25 73 20 25 73 5c 6e 22 2c 20  HARED-%s %s\n", 
8010: 70 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20  pWal,.          
8020: 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f    walLockName(lo
8030: 63 6b 49 64 78 29 2c 20 72 63 20 3f 20 22 66 61  ckIdx), rc ? "fa
8040: 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a  iled" : "ok"));.
8050: 20 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57 61 6c    VVA_ONLY( pWal
8060: 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20 28 75  ->lockError = (u
8070: 38 29 28 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  8)(rc!=SQLITE_OK
8080: 20 26 26 20 72 63 21 3d 53 51 4c 49 54 45 5f 42   && rc!=SQLITE_B
8090: 55 53 59 29 3b 20 29 0a 20 20 72 65 74 75 72 6e  USY); ).  return
80a0: 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f   rc;.}.static vo
80b0: 69 64 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72  id walUnlockShar
80c0: 65 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e  ed(Wal *pWal, in
80d0: 74 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66  t lockIdx){.  if
80e0: 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76  ( pWal->exclusiv
80f0: 65 4d 6f 64 65 20 29 20 72 65 74 75 72 6e 3b 0a  eMode ) return;.
8100: 20 20 28 76 6f 69 64 29 73 71 6c 69 74 65 33 4f    (void)sqlite3O
8110: 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70  sShmLock(pWal->p
8120: 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 31  DbFd, lockIdx, 1
8130: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
8140: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54             SQLIT
8150: 45 5f 53 48 4d 5f 55 4e 4c 4f 43 4b 20 7c 20 53  E_SHM_UNLOCK | S
8160: 51 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44  QLITE_SHM_SHARED
8170: 29 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  );.  WALTRACE(("
8180: 57 41 4c 25 70 3a 20 72 65 6c 65 61 73 65 20 53  WAL%p: release S
8190: 48 41 52 45 44 2d 25 73 5c 6e 22 2c 20 70 57 61  HARED-%s\n", pWa
81a0: 6c 2c 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c  l, walLockName(l
81b0: 6f 63 6b 49 64 78 29 29 29 3b 0a 7d 0a 73 74 61  ockIdx)));.}.sta
81c0: 74 69 63 20 69 6e 74 20 77 61 6c 4c 6f 63 6b 45  tic int walLockE
81d0: 78 63 6c 75 73 69 76 65 28 57 61 6c 20 2a 70 57  xclusive(Wal *pW
81e0: 61 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 2c  al, int lockIdx,
81f0: 20 69 6e 74 20 6e 29 7b 0a 20 20 69 6e 74 20 72   int n){.  int r
8200: 63 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65  c;.  if( pWal->e
8210: 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72  xclusiveMode ) r
8220: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
8230: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  .  rc = sqlite3O
8240: 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70  sShmLock(pWal->p
8250: 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e  DbFd, lockIdx, n
8260: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
8270: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
8280: 5f 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49  _SHM_LOCK | SQLI
8290: 54 45 5f 53 48 4d 5f 45 58 43 4c 55 53 49 56 45  TE_SHM_EXCLUSIVE
82a0: 29 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  );.  WALTRACE(("
82b0: 57 41 4c 25 70 3a 20 61 63 71 75 69 72 65 20 45  WAL%p: acquire E
82c0: 58 43 4c 55 53 49 56 45 2d 25 73 20 63 6e 74 3d  XCLUSIVE-%s cnt=
82d0: 25 64 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 0a  %d %s\n", pWal,.
82e0: 20 20 20 20 20 20 20 20 20 20 20 20 77 61 6c 4c              walL
82f0: 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29  ockName(lockIdx)
8300: 2c 20 6e 2c 20 72 63 20 3f 20 22 66 61 69 6c 65  , n, rc ? "faile
8310: 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 56  d" : "ok"));.  V
8320: 56 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c  VA_ONLY( pWal->l
8330: 6f 63 6b 45 72 72 6f 72 20 3d 20 28 75 38 29 28  ockError = (u8)(
8340: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc!=SQLITE_OK &&
8350: 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc!=SQLITE_BUSY
8360: 29 3b 20 29 0a 20 20 72 65 74 75 72 6e 20 72 63  ); ).  return rc
8370: 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20  ;.}.static void 
8380: 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69  walUnlockExclusi
8390: 76 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e  ve(Wal *pWal, in
83a0: 74 20 6c 6f 63 6b 49 64 78 2c 20 69 6e 74 20 6e  t lockIdx, int n
83b0: 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65  ){.  if( pWal->e
83c0: 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72  xclusiveMode ) r
83d0: 65 74 75 72 6e 3b 0a 20 20 28 76 6f 69 64 29 73  eturn;.  (void)s
83e0: 71 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28  qlite3OsShmLock(
83f0: 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63  pWal->pDbFd, loc
8400: 6b 49 64 78 2c 20 6e 2c 0a 20 20 20 20 20 20 20  kIdx, n,.       
8410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8420: 20 20 53 51 4c 49 54 45 5f 53 48 4d 5f 55 4e 4c    SQLITE_SHM_UNL
8430: 4f 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d  OCK | SQLITE_SHM
8440: 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20 57  _EXCLUSIVE);.  W
8450: 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
8460: 20 72 65 6c 65 61 73 65 20 45 58 43 4c 55 53 49   release EXCLUSI
8470: 56 45 2d 25 73 20 63 6e 74 3d 25 64 5c 6e 22 2c  VE-%s cnt=%d\n",
8480: 20 70 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20   pWal,.         
8490: 20 20 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28      walLockName(
84a0: 6c 6f 63 6b 49 64 78 29 2c 20 6e 29 29 3b 0a 7d  lockIdx), n));.}
84b0: 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20  ../*.** Compute 
84c0: 61 20 68 61 73 68 20 6f 6e 20 61 20 70 61 67 65  a hash on a page
84d0: 20 6e 75 6d 62 65 72 2e 20 20 54 68 65 20 72 65   number.  The re
84e0: 73 75 6c 74 69 6e 67 20 68 61 73 68 20 76 61 6c  sulting hash val
84f0: 75 65 20 6d 75 73 74 20 6c 61 6e 64 0a 2a 2a 20  ue must land.** 
8500: 62 65 74 77 65 65 6e 20 30 20 61 6e 64 20 28 48  between 0 and (H
8510: 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31  ASHTABLE_NSLOT-1
8520: 29 2e 20 20 54 68 65 20 77 61 6c 48 61 73 68 4e  ).  The walHashN
8530: 65 78 74 28 29 20 66 75 6e 63 74 69 6f 6e 20 61  ext() function a
8540: 64 76 61 6e 63 65 73 0a 2a 2a 20 74 68 65 20 68  dvances.** the h
8550: 61 73 68 20 74 6f 20 74 68 65 20 6e 65 78 74 20  ash to the next 
8560: 76 61 6c 75 65 20 69 6e 20 74 68 65 20 65 76 65  value in the eve
8570: 6e 74 20 6f 66 20 61 20 63 6f 6c 6c 69 73 69 6f  nt of a collisio
8580: 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  n..*/.static int
8590: 20 77 61 6c 48 61 73 68 28 75 33 32 20 69 50 61   walHash(u32 iPa
85a0: 67 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69  ge){.  assert( i
85b0: 50 61 67 65 3e 30 20 29 3b 0a 20 20 61 73 73 65  Page>0 );.  asse
85c0: 72 74 28 20 28 48 41 53 48 54 41 42 4c 45 5f 4e  rt( (HASHTABLE_N
85d0: 53 4c 4f 54 20 26 20 28 48 41 53 48 54 41 42 4c  SLOT & (HASHTABL
85e0: 45 5f 4e 53 4c 4f 54 2d 31 29 29 3d 3d 30 20 29  E_NSLOT-1))==0 )
85f0: 3b 0a 20 20 72 65 74 75 72 6e 20 28 69 50 61 67  ;.  return (iPag
8600: 65 2a 48 41 53 48 54 41 42 4c 45 5f 48 41 53 48  e*HASHTABLE_HASH
8610: 5f 31 29 20 26 20 28 48 41 53 48 54 41 42 4c 45  _1) & (HASHTABLE
8620: 5f 4e 53 4c 4f 54 2d 31 29 3b 0a 7d 0a 73 74 61  _NSLOT-1);.}.sta
8630: 74 69 63 20 69 6e 74 20 77 61 6c 4e 65 78 74 48  tic int walNextH
8640: 61 73 68 28 69 6e 74 20 69 50 72 69 6f 72 48 61  ash(int iPriorHa
8650: 73 68 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 69  sh){.  return (i
8660: 50 72 69 6f 72 48 61 73 68 2b 31 29 26 28 48 41  PriorHash+1)&(HA
8670: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29  SHTABLE_NSLOT-1)
8680: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75  ;.}../* .** Retu
8690: 72 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 74  rn pointers to t
86a0: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 61 6e  he hash table an
86b0: 64 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72  d page number ar
86c0: 72 61 79 20 73 74 6f 72 65 64 20 6f 6e 0a 2a 2a  ray stored on.**
86d0: 20 70 61 67 65 20 69 48 61 73 68 20 6f 66 20 74   page iHash of t
86e0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 54 68  he wal-index. Th
86f0: 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 62  e wal-index is b
8700: 72 6f 6b 65 6e 20 69 6e 74 6f 20 33 32 4b 42 20  roken into 32KB 
8710: 70 61 67 65 73 0a 2a 2a 20 6e 75 6d 62 65 72 65  pages.** numbere
8720: 64 20 73 74 61 72 74 69 6e 67 20 66 72 6f 6d 20  d starting from 
8730: 30 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20 6f 75 74  0..**.** Set out
8740: 70 75 74 20 76 61 72 69 61 62 6c 65 20 2a 70 61  put variable *pa
8750: 48 61 73 68 20 74 6f 20 70 6f 69 6e 74 20 74 6f  Hash to point to
8760: 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
8770: 65 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20  e hash table.** 
8780: 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  in the wal-index
8790: 20 66 69 6c 65 2e 20 53 65 74 20 2a 70 69 5a 65   file. Set *piZe
87a0: 72 6f 20 74 6f 20 6f 6e 65 20 6c 65 73 73 20 74  ro to one less t
87b0: 68 61 6e 20 74 68 65 20 66 72 61 6d 65 20 0a 2a  han the frame .*
87c0: 2a 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20  * number of the 
87d0: 66 69 72 73 74 20 66 72 61 6d 65 20 69 6e 64 65  first frame inde
87e0: 78 65 64 20 62 79 20 74 68 69 73 20 68 61 73 68  xed by this hash
87f0: 20 74 61 62 6c 65 2e 20 49 66 20 61 0a 2a 2a 20   table. If a.** 
8800: 73 6c 6f 74 20 69 6e 20 74 68 65 20 68 61 73 68  slot in the hash
8810: 20 74 61 62 6c 65 20 69 73 20 73 65 74 20 74 6f   table is set to
8820: 20 4e 2c 20 69 74 20 72 65 66 65 72 73 20 74 6f   N, it refers to
8830: 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 0a 2a   frame number .*
8840: 2a 20 28 2a 70 69 5a 65 72 6f 2b 4e 29 20 69 6e  * (*piZero+N) in
8850: 20 74 68 65 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a 20   the log..**.** 
8860: 46 69 6e 61 6c 6c 79 2c 20 73 65 74 20 2a 70 61  Finally, set *pa
8870: 50 67 6e 6f 20 73 6f 20 74 68 61 74 20 2a 70 61  Pgno so that *pa
8880: 50 67 6e 6f 5b 31 5d 20 69 73 20 74 68 65 20 70  Pgno[1] is the p
8890: 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68  age number of th
88a0: 65 0a 2a 2a 20 66 69 72 73 74 20 66 72 61 6d 65  e.** first frame
88b0: 20 69 6e 64 65 78 65 64 20 62 79 20 74 68 65 20   indexed by the 
88c0: 68 61 73 68 20 74 61 62 6c 65 2c 20 66 72 61 6d  hash table, fram
88d0: 65 20 28 2a 70 69 5a 65 72 6f 2b 31 29 2e 0a 2a  e (*piZero+1)..*
88e0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
88f0: 48 61 73 68 47 65 74 28 0a 20 20 57 61 6c 20 2a  HashGet(.  Wal *
8900: 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  pWal,           
8910: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41             /* WA
8920: 4c 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e  L handle */.  in
8930: 74 20 69 48 61 73 68 2c 20 20 20 20 20 20 20 20  t iHash,        
8940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8950: 20 46 69 6e 64 20 74 68 65 20 69 48 61 73 68 27   Find the iHash'
8960: 74 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 76 6f  th table */.  vo
8970: 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a  latile ht_slot *
8980: 2a 70 61 48 61 73 68 2c 20 20 20 20 20 20 2f 2a  *paHash,      /*
8990: 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f   OUT: Pointer to
89a0: 20 68 61 73 68 20 69 6e 64 65 78 20 2a 2f 0a 20   hash index */. 
89b0: 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a   volatile u32 **
89c0: 70 61 50 67 6e 6f 2c 20 20 20 20 20 20 20 20 20  paPgno,         
89d0: 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72   /* OUT: Pointer
89e0: 20 74 6f 20 70 61 67 65 20 6e 75 6d 62 65 72 20   to page number 
89f0: 61 72 72 61 79 20 2a 2f 0a 20 20 75 33 32 20 2a  array */.  u32 *
8a00: 70 69 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20  piZero          
8a10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
8a20: 54 3a 20 46 72 61 6d 65 20 61 73 73 6f 63 69 61  T: Frame associa
8a30: 74 65 64 20 77 69 74 68 20 2a 70 61 50 67 6e 6f  ted with *paPgno
8a40: 5b 30 5d 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  [0] */.){.  int 
8a50: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
8a60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
8a70: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
8a80: 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50  volatile u32 *aP
8a90: 67 6e 6f 3b 0a 0a 20 20 72 63 20 3d 20 77 61 6c  gno;..  rc = wal
8aa0: 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20  IndexPage(pWal, 
8ab0: 69 48 61 73 68 2c 20 26 61 50 67 6e 6f 29 3b 0a  iHash, &aPgno);.
8ac0: 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
8ad0: 4c 49 54 45 5f 4f 4b 20 7c 7c 20 69 48 61 73 68  LITE_OK || iHash
8ae0: 3e 30 20 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d  >0 );..  if( rc=
8af0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
8b00: 20 20 75 33 32 20 69 5a 65 72 6f 3b 0a 20 20 20    u32 iZero;.   
8b10: 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f   volatile ht_slo
8b20: 74 20 2a 61 48 61 73 68 3b 0a 0a 20 20 20 20 61  t *aHash;..    a
8b30: 48 61 73 68 20 3d 20 28 76 6f 6c 61 74 69 6c 65  Hash = (volatile
8b40: 20 68 74 5f 73 6c 6f 74 20 2a 29 26 61 50 67 6e   ht_slot *)&aPgn
8b50: 6f 5b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  o[HASHTABLE_NPAG
8b60: 45 5d 3b 0a 20 20 20 20 69 66 28 20 69 48 61 73  E];.    if( iHas
8b70: 68 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 61 50  h==0 ){.      aP
8b80: 67 6e 6f 20 3d 20 26 61 50 67 6e 6f 5b 57 41 4c  gno = &aPgno[WAL
8b90: 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73  INDEX_HDR_SIZE/s
8ba0: 69 7a 65 6f 66 28 75 33 32 29 5d 3b 0a 20 20 20  izeof(u32)];.   
8bb0: 20 20 20 69 5a 65 72 6f 20 3d 20 30 3b 0a 20 20     iZero = 0;.  
8bc0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69    }else{.      i
8bd0: 5a 65 72 6f 20 3d 20 48 41 53 48 54 41 42 4c 45  Zero = HASHTABLE
8be0: 5f 4e 50 41 47 45 5f 4f 4e 45 20 2b 20 28 69 48  _NPAGE_ONE + (iH
8bf0: 61 73 68 2d 31 29 2a 48 41 53 48 54 41 42 4c 45  ash-1)*HASHTABLE
8c00: 5f 4e 50 41 47 45 3b 0a 20 20 20 20 7d 0a 20 20  _NPAGE;.    }.  
8c10: 0a 20 20 20 20 2a 70 61 50 67 6e 6f 20 3d 20 26  .    *paPgno = &
8c20: 61 50 67 6e 6f 5b 2d 31 5d 3b 0a 20 20 20 20 2a  aPgno[-1];.    *
8c30: 70 61 48 61 73 68 20 3d 20 61 48 61 73 68 3b 0a  paHash = aHash;.
8c40: 20 20 20 20 2a 70 69 5a 65 72 6f 20 3d 20 69 5a      *piZero = iZ
8c50: 65 72 6f 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ero;.  }.  retur
8c60: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  n rc;.}../*.** R
8c70: 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72  eturn the number
8c80: 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
8c90: 78 20 70 61 67 65 20 74 68 61 74 20 63 6f 6e 74  x page that cont
8ca0: 61 69 6e 73 20 74 68 65 20 68 61 73 68 2d 74 61  ains the hash-ta
8cb0: 62 6c 65 0a 2a 2a 20 61 6e 64 20 70 61 67 65 2d  ble.** and page-
8cc0: 6e 75 6d 62 65 72 20 61 72 72 61 79 20 74 68 61  number array tha
8cd0: 74 20 63 6f 6e 74 61 69 6e 20 65 6e 74 72 69 65  t contain entrie
8ce0: 73 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20  s corresponding 
8cf0: 74 6f 20 57 41 4c 20 66 72 61 6d 65 0a 2a 2a 20  to WAL frame.** 
8d00: 69 46 72 61 6d 65 2e 20 54 68 65 20 77 61 6c 2d  iFrame. The wal-
8d10: 69 6e 64 65 78 20 69 73 20 62 72 6f 6b 65 6e 20  index is broken 
8d20: 75 70 20 69 6e 74 6f 20 33 32 4b 42 20 70 61 67  up into 32KB pag
8d30: 65 73 2e 20 57 61 6c 2d 69 6e 64 65 78 20 70 61  es. Wal-index pa
8d40: 67 65 73 20 0a 2a 2a 20 61 72 65 20 6e 75 6d 62  ges .** are numb
8d50: 65 72 65 64 20 73 74 61 72 74 69 6e 67 20 66 72  ered starting fr
8d60: 6f 6d 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  om 0..*/.static 
8d70: 69 6e 74 20 77 61 6c 46 72 61 6d 65 50 61 67 65  int walFramePage
8d80: 28 75 33 32 20 69 46 72 61 6d 65 29 7b 0a 20 20  (u32 iFrame){.  
8d90: 69 6e 74 20 69 48 61 73 68 20 3d 20 28 69 46 72  int iHash = (iFr
8da0: 61 6d 65 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50  ame+HASHTABLE_NP
8db0: 41 47 45 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50  AGE-HASHTABLE_NP
8dc0: 41 47 45 5f 4f 4e 45 2d 31 29 20 2f 20 48 41 53  AGE_ONE-1) / HAS
8dd0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 3b 0a 20 20  HTABLE_NPAGE;.  
8de0: 61 73 73 65 72 74 28 20 28 69 48 61 73 68 3d 3d  assert( (iHash==
8df0: 30 20 7c 7c 20 69 46 72 61 6d 65 3e 48 41 53 48  0 || iFrame>HASH
8e00: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29  TABLE_NPAGE_ONE)
8e10: 0a 20 20 20 20 20 20 20 26 26 20 28 69 48 61 73  .       && (iHas
8e20: 68 3e 3d 31 20 7c 7c 20 69 46 72 61 6d 65 3c 3d  h>=1 || iFrame<=
8e30: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
8e40: 4f 4e 45 29 0a 20 20 20 20 20 20 20 26 26 20 28  ONE).       && (
8e50: 69 48 61 73 68 3c 3d 31 20 7c 7c 20 69 46 72 61  iHash<=1 || iFra
8e60: 6d 65 3e 28 48 41 53 48 54 41 42 4c 45 5f 4e 50  me>(HASHTABLE_NP
8e70: 41 47 45 5f 4f 4e 45 2b 48 41 53 48 54 41 42 4c  AGE_ONE+HASHTABL
8e80: 45 5f 4e 50 41 47 45 29 29 0a 20 20 20 20 20 20  E_NPAGE)).      
8e90: 20 26 26 20 28 69 48 61 73 68 3e 3d 32 20 7c 7c   && (iHash>=2 ||
8ea0: 20 69 46 72 61 6d 65 3c 3d 48 41 53 48 54 41 42   iFrame<=HASHTAB
8eb0: 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 48 41 53  LE_NPAGE_ONE+HAS
8ec0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 29 0a 20 20  HTABLE_NPAGE).  
8ed0: 20 20 20 20 20 26 26 20 28 69 48 61 73 68 3c 3d       && (iHash<=
8ee0: 32 20 7c 7c 20 69 46 72 61 6d 65 3e 28 48 41 53  2 || iFrame>(HAS
8ef0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45  HTABLE_NPAGE_ONE
8f00: 2b 32 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  +2*HASHTABLE_NPA
8f10: 47 45 29 29 0a 20 20 29 3b 0a 20 20 72 65 74 75  GE)).  );.  retu
8f20: 72 6e 20 69 48 61 73 68 3b 0a 7d 0a 0a 2f 2a 0a  rn iHash;.}../*.
8f30: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 70 61  ** Return the pa
8f40: 67 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63 69  ge number associ
8f50: 61 74 65 64 20 77 69 74 68 20 66 72 61 6d 65 20  ated with frame 
8f60: 69 46 72 61 6d 65 20 69 6e 20 74 68 69 73 20 57  iFrame in this W
8f70: 41 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75 33  AL..*/.static u3
8f80: 32 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 57  2 walFramePgno(W
8f90: 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 69 46  al *pWal, u32 iF
8fa0: 72 61 6d 65 29 7b 0a 20 20 69 6e 74 20 69 48 61  rame){.  int iHa
8fb0: 73 68 20 3d 20 77 61 6c 46 72 61 6d 65 50 61 67  sh = walFramePag
8fc0: 65 28 69 46 72 61 6d 65 29 3b 0a 20 20 69 66 28  e(iFrame);.  if(
8fd0: 20 69 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20   iHash==0 ){.   
8fe0: 20 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e 61 70   return pWal->ap
8ff0: 57 69 44 61 74 61 5b 30 5d 5b 57 41 4c 49 4e 44  WiData[0][WALIND
9000: 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65  EX_HDR_SIZE/size
9010: 6f 66 28 75 33 32 29 20 2b 20 69 46 72 61 6d 65  of(u32) + iFrame
9020: 20 2d 20 31 5d 3b 0a 20 20 7d 0a 20 20 72 65 74   - 1];.  }.  ret
9030: 75 72 6e 20 70 57 61 6c 2d 3e 61 70 57 69 44 61  urn pWal->apWiDa
9040: 74 61 5b 69 48 61 73 68 5d 5b 28 69 46 72 61 6d  ta[iHash][(iFram
9050: 65 2d 31 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50  e-1-HASHTABLE_NP
9060: 41 47 45 5f 4f 4e 45 29 25 48 41 53 48 54 41 42  AGE_ONE)%HASHTAB
9070: 4c 45 5f 4e 50 41 47 45 5d 3b 0a 7d 0a 0a 2f 2a  LE_NPAGE];.}../*
9080: 0a 2a 2a 20 52 65 6d 6f 76 65 20 65 6e 74 72 69  .** Remove entri
9090: 65 73 20 66 72 6f 6d 20 74 68 65 20 68 61 73 68  es from the hash
90a0: 20 74 61 62 6c 65 20 74 68 61 74 20 70 6f 69 6e   table that poin
90b0: 74 20 74 6f 20 57 41 4c 20 73 6c 6f 74 73 20 67  t to WAL slots g
90c0: 72 65 61 74 65 72 0a 2a 2a 20 74 68 61 6e 20 70  reater.** than p
90d0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
90e0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ..**.** This fun
90f0: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
9100: 77 68 65 6e 65 76 65 72 20 70 57 61 6c 2d 3e 68  whenever pWal->h
9110: 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20 64 65  dr.mxFrame is de
9120: 63 72 65 61 73 65 64 20 64 75 65 0a 2a 2a 20 74  creased due.** t
9130: 6f 20 61 20 72 6f 6c 6c 62 61 63 6b 20 6f 72 20  o a rollback or 
9140: 73 61 76 65 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a  savepoint..**.**
9150: 20 41 74 20 6d 6f 73 74 20 6f 6e 6c 79 20 74 68   At most only th
9160: 65 20 68 61 73 68 20 74 61 62 6c 65 20 63 6f 6e  e hash table con
9170: 74 61 69 6e 69 6e 67 20 70 57 61 6c 2d 3e 68 64  taining pWal->hd
9180: 72 2e 6d 78 46 72 61 6d 65 20 6e 65 65 64 73 20  r.mxFrame needs 
9190: 74 6f 20 62 65 0a 2a 2a 20 75 70 64 61 74 65 64  to be.** updated
91a0: 2e 20 20 41 6e 79 20 6c 61 74 65 72 20 68 61 73  .  Any later has
91b0: 68 20 74 61 62 6c 65 73 20 77 69 6c 6c 20 62 65  h tables will be
91c0: 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 63   automatically c
91d0: 6c 65 61 72 65 64 20 77 68 65 6e 0a 2a 2a 20 70  leared when.** p
91e0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
91f0: 20 61 64 76 61 6e 63 65 73 20 74 6f 20 74 68 65   advances to the
9200: 20 70 6f 69 6e 74 20 77 68 65 72 65 20 74 68 6f   point where tho
9210: 73 65 20 68 61 73 68 20 74 61 62 6c 65 73 20 61  se hash tables a
9220: 72 65 0a 2a 2a 20 61 63 74 75 61 6c 6c 79 20 6e  re.** actually n
9230: 65 65 64 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  eeded..*/.static
9240: 20 76 6f 69 64 20 77 61 6c 43 6c 65 61 6e 75 70   void walCleanup
9250: 48 61 73 68 28 57 61 6c 20 2a 70 57 61 6c 29 7b  Hash(Wal *pWal){
9260: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73  .  volatile ht_s
9270: 6c 6f 74 20 2a 61 48 61 73 68 20 3d 20 30 3b 20  lot *aHash = 0; 
9280: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
9290: 20 68 61 73 68 20 74 61 62 6c 65 20 74 6f 20 63   hash table to c
92a0: 6c 65 61 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  lear */.  volati
92b0: 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 20 3d 20  le u32 *aPgno = 
92c0: 30 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67  0;        /* Pag
92d0: 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 66  e number array f
92e0: 6f 72 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f  or hash table */
92f0: 0a 20 20 75 33 32 20 69 5a 65 72 6f 20 3d 20 30  .  u32 iZero = 0
9300: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
9310: 20 20 20 2f 2a 20 66 72 61 6d 65 20 3d 3d 20 28     /* frame == (
9320: 61 48 61 73 68 5b 78 5d 2b 69 5a 65 72 6f 29 20  aHash[x]+iZero) 
9330: 2a 2f 0a 20 20 69 6e 74 20 69 4c 69 6d 69 74 20  */.  int iLimit 
9340: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
9350: 20 20 20 20 20 2f 2a 20 5a 65 72 6f 20 76 61 6c       /* Zero val
9360: 75 65 73 20 67 72 65 61 74 65 72 20 74 68 61 6e  ues greater than
9370: 20 74 68 69 73 20 2a 2f 0a 20 20 69 6e 74 20 6e   this */.  int n
9380: 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20  Byte;           
9390: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
93a0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f  mber of bytes to
93b0: 20 7a 65 72 6f 20 69 6e 20 61 50 67 6e 6f 5b 5d   zero in aPgno[]
93c0: 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20   */.  int i;    
93d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
93e0: 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f        /* Used to
93f0: 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68   iterate through
9400: 20 61 48 61 73 68 5b 5d 20 2a 2f 0a 0a 20 20 61   aHash[] */..  a
9410: 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69  ssert( pWal->wri
9420: 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 74 65 73 74  teLock );.  test
9430: 63 61 73 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e  case( pWal->hdr.
9440: 6d 78 46 72 61 6d 65 3d 3d 48 41 53 48 54 41 42  mxFrame==HASHTAB
9450: 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2d 31 20 29  LE_NPAGE_ONE-1 )
9460: 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 70 57  ;.  testcase( pW
9470: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d  al->hdr.mxFrame=
9480: 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  =HASHTABLE_NPAGE
9490: 5f 4f 4e 45 20 29 3b 0a 20 20 74 65 73 74 63 61  _ONE );.  testca
94a0: 73 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  se( pWal->hdr.mx
94b0: 46 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45  Frame==HASHTABLE
94c0: 5f 4e 50 41 47 45 5f 4f 4e 45 2b 31 20 29 3b 0a  _NPAGE_ONE+1 );.
94d0: 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72  .  if( pWal->hdr
94e0: 2e 6d 78 46 72 61 6d 65 3d 3d 30 20 29 20 72 65  .mxFrame==0 ) re
94f0: 74 75 72 6e 3b 0a 0a 20 20 2f 2a 20 4f 62 74 61  turn;..  /* Obta
9500: 69 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 74  in pointers to t
9510: 68 65 20 68 61 73 68 2d 74 61 62 6c 65 20 61 6e  he hash-table an
9520: 64 20 70 61 67 65 2d 6e 75 6d 62 65 72 20 61 72  d page-number ar
9530: 72 61 79 20 63 6f 6e 74 61 69 6e 69 6e 67 20 0a  ray containing .
9540: 20 20 2a 2a 20 74 68 65 20 65 6e 74 72 79 20 74    ** the entry t
9550: 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 73 20  hat corresponds 
9560: 74 6f 20 66 72 61 6d 65 20 70 57 61 6c 2d 3e 68  to frame pWal->h
9570: 64 72 2e 6d 78 46 72 61 6d 65 2e 20 49 74 20 69  dr.mxFrame. It i
9580: 73 20 67 75 61 72 61 6e 74 65 65 64 0a 20 20 2a  s guaranteed.  *
9590: 2a 20 74 68 61 74 20 74 68 65 20 70 61 67 65 20  * that the page 
95a0: 73 61 69 64 20 68 61 73 68 2d 74 61 62 6c 65 20  said hash-table 
95b0: 61 6e 64 20 61 72 72 61 79 20 72 65 73 69 64 65  and array reside
95c0: 20 6f 6e 20 69 73 20 61 6c 72 65 61 64 79 20 6d   on is already m
95d0: 61 70 70 65 64 2e 0a 20 20 2a 2f 0a 20 20 61 73  apped..  */.  as
95e0: 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44  sert( pWal->nWiD
95f0: 61 74 61 3e 77 61 6c 46 72 61 6d 65 50 61 67 65  ata>walFramePage
9600: 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  (pWal->hdr.mxFra
9610: 6d 65 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28  me) );.  assert(
9620: 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
9630: 77 61 6c 46 72 61 6d 65 50 61 67 65 28 70 57 61  walFramePage(pWa
9640: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 29 5d  l->hdr.mxFrame)]
9650: 20 29 3b 0a 20 20 77 61 6c 48 61 73 68 47 65 74   );.  walHashGet
9660: 28 70 57 61 6c 2c 20 77 61 6c 46 72 61 6d 65 50  (pWal, walFrameP
9670: 61 67 65 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  age(pWal->hdr.mx
9680: 46 72 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20  Frame), &aHash, 
9690: 26 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b  &aPgno, &iZero);
96a0: 0a 0a 20 20 2f 2a 20 5a 65 72 6f 20 61 6c 6c 20  ..  /* Zero all 
96b0: 68 61 73 68 2d 74 61 62 6c 65 20 65 6e 74 72 69  hash-table entri
96c0: 65 73 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f  es that correspo
96d0: 6e 64 20 74 6f 20 66 72 61 6d 65 20 6e 75 6d 62  nd to frame numb
96e0: 65 72 73 20 67 72 65 61 74 65 72 0a 20 20 2a 2a  ers greater.  **
96f0: 20 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e   than pWal->hdr.
9700: 6d 78 46 72 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20  mxFrame..  */.  
9710: 69 4c 69 6d 69 74 20 3d 20 70 57 61 6c 2d 3e 68  iLimit = pWal->h
9720: 64 72 2e 6d 78 46 72 61 6d 65 20 2d 20 69 5a 65  dr.mxFrame - iZe
9730: 72 6f 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4c  ro;.  assert( iL
9740: 69 6d 69 74 3e 30 20 29 3b 0a 20 20 66 6f 72 28  imit>0 );.  for(
9750: 69 3d 30 3b 20 69 3c 48 41 53 48 54 41 42 4c 45  i=0; i<HASHTABLE
9760: 5f 4e 53 4c 4f 54 3b 20 69 2b 2b 29 7b 0a 20 20  _NSLOT; i++){.  
9770: 20 20 69 66 28 20 61 48 61 73 68 5b 69 5d 3e 69    if( aHash[i]>i
9780: 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 61  Limit ){.      a
9790: 48 61 73 68 5b 69 5d 20 3d 20 30 3b 0a 20 20 20  Hash[i] = 0;.   
97a0: 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 2f 2a 20 5a   }.  }.  .  /* Z
97b0: 65 72 6f 20 74 68 65 20 65 6e 74 72 69 65 73 20  ero the entries 
97c0: 69 6e 20 74 68 65 20 61 50 67 6e 6f 20 61 72 72  in the aPgno arr
97d0: 61 79 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f  ay that correspo
97e0: 6e 64 20 74 6f 20 66 72 61 6d 65 73 20 77 69 74  nd to frames wit
97f0: 68 0a 20 20 2a 2a 20 66 72 61 6d 65 20 6e 75 6d  h.  ** frame num
9800: 62 65 72 73 20 67 72 65 61 74 65 72 20 74 68 61  bers greater tha
9810: 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  n pWal->hdr.mxFr
9820: 61 6d 65 2e 20 0a 20 20 2a 2f 0a 20 20 6e 42 79  ame. .  */.  nBy
9830: 74 65 20 3d 20 28 69 6e 74 29 28 28 63 68 61 72  te = (int)((char
9840: 20 2a 29 61 48 61 73 68 20 2d 20 28 63 68 61 72   *)aHash - (char
9850: 20 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d 69 74   *)&aPgno[iLimit
9860: 2b 31 5d 29 3b 0a 20 20 6d 65 6d 73 65 74 28 28  +1]);.  memset((
9870: 76 6f 69 64 20 2a 29 26 61 50 67 6e 6f 5b 69 4c  void *)&aPgno[iL
9880: 69 6d 69 74 2b 31 5d 2c 20 30 2c 20 6e 42 79 74  imit+1], 0, nByt
9890: 65 29 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49  e);..#ifdef SQLI
98a0: 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53  TE_ENABLE_EXPENS
98b0: 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20  IVE_ASSERT.  /* 
98c0: 56 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20  Verify that the 
98d0: 65 76 65 72 79 20 65 6e 74 72 79 20 69 6e 20 74  every entry in t
98e0: 68 65 20 6d 61 70 70 69 6e 67 20 72 65 67 69 6f  he mapping regio
98f0: 6e 20 69 73 20 73 74 69 6c 6c 20 72 65 61 63 68  n is still reach
9900: 61 62 6c 65 0a 20 20 2a 2a 20 76 69 61 20 74 68  able.  ** via th
9910: 65 20 68 61 73 68 20 74 61 62 6c 65 20 65 76 65  e hash table eve
9920: 6e 20 61 66 74 65 72 20 74 68 65 20 63 6c 65 61  n after the clea
9930: 6e 75 70 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  nup..  */.  if( 
9940: 69 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20 69 6e  iLimit ){.    in
9950: 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 2f  t i;           /
9960: 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a  * Loop counter *
9970: 2f 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20  /.    int iKey; 
9980: 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 6b         /* Hash k
9990: 65 79 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d  ey */.    for(i=
99a0: 31 3b 20 69 3c 3d 69 4c 69 6d 69 74 3b 20 69 2b  1; i<=iLimit; i+
99b0: 2b 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 4b  +){.      for(iK
99c0: 65 79 3d 77 61 6c 48 61 73 68 28 61 50 67 6e 6f  ey=walHash(aPgno
99d0: 5b 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b 65 79  [i]); aHash[iKey
99e0: 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48  ]; iKey=walNextH
99f0: 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20  ash(iKey)){.    
9a00: 20 20 20 20 69 66 28 20 61 48 61 73 68 5b 69 4b      if( aHash[iK
9a10: 65 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b 3b 0a  ey]==i ) break;.
9a20: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73        }.      as
9a30: 73 65 72 74 28 20 61 48 61 73 68 5b 69 4b 65 79  sert( aHash[iKey
9a40: 5d 3d 3d 69 20 29 3b 0a 20 20 20 20 7d 0a 20 20  ]==i );.    }.  
9a50: 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  }.#endif /* SQLI
9a60: 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53  TE_ENABLE_EXPENS
9a70: 49 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a 7d 0a  IVE_ASSERT */.}.
9a80: 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 6e 20 65  ../*.** Set an e
9a90: 6e 74 72 79 20 69 6e 20 74 68 65 20 77 61 6c 2d  ntry in the wal-
9aa0: 69 6e 64 65 78 20 74 68 61 74 20 77 69 6c 6c 20  index that will 
9ab0: 6d 61 70 20 64 61 74 61 62 61 73 65 20 70 61 67  map database pag
9ac0: 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 70 50 61 67  e number.** pPag
9ad0: 65 20 69 6e 74 6f 20 57 41 4c 20 66 72 61 6d 65  e into WAL frame
9ae0: 20 69 46 72 61 6d 65 2e 0a 2a 2f 0a 73 74 61 74   iFrame..*/.stat
9af0: 69 63 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 41  ic int walIndexA
9b00: 70 70 65 6e 64 28 57 61 6c 20 2a 70 57 61 6c 2c  ppend(Wal *pWal,
9b10: 20 75 33 32 20 69 46 72 61 6d 65 2c 20 75 33 32   u32 iFrame, u32
9b20: 20 69 50 61 67 65 29 7b 0a 20 20 69 6e 74 20 72   iPage){.  int r
9b30: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
9b40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
9b50: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 75  turn code */.  u
9b60: 33 32 20 69 5a 65 72 6f 20 3d 20 30 3b 20 20 20  32 iZero = 0;   
9b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9b80: 2a 20 4f 6e 65 20 6c 65 73 73 20 74 68 61 6e 20  * One less than 
9b90: 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 6f 66 20  frame number of 
9ba0: 61 50 67 6e 6f 5b 31 5d 20 2a 2f 0a 20 20 76 6f  aPgno[1] */.  vo
9bb0: 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e  latile u32 *aPgn
9bc0: 6f 20 3d 20 30 3b 20 20 20 20 20 20 20 20 2f 2a  o = 0;        /*
9bd0: 20 50 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72   Page number arr
9be0: 61 79 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65  ay */.  volatile
9bf0: 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 20   ht_slot *aHash 
9c00: 3d 20 30 3b 20 20 20 20 2f 2a 20 48 61 73 68 20  = 0;    /* Hash 
9c10: 74 61 62 6c 65 20 2a 2f 0a 0a 20 20 72 63 20 3d  table */..  rc =
9c20: 20 77 61 6c 48 61 73 68 47 65 74 28 70 57 61 6c   walHashGet(pWal
9c30: 2c 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69  , walFramePage(i
9c40: 46 72 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20  Frame), &aHash, 
9c50: 26 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b  &aPgno, &iZero);
9c60: 0a 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20  ..  /* Assuming 
9c70: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69  the wal-index fi
9c80: 6c 65 20 77 61 73 20 73 75 63 63 65 73 73 66 75  le was successfu
9c90: 6c 6c 79 20 6d 61 70 70 65 64 2c 20 70 6f 70 75  lly mapped, popu
9ca0: 6c 61 74 65 20 74 68 65 0a 20 20 2a 2a 20 70 61  late the.  ** pa
9cb0: 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20  ge number array 
9cc0: 61 6e 64 20 68 61 73 68 20 74 61 62 6c 65 20 65  and hash table e
9cd0: 6e 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  ntry..  */.  if(
9ce0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
9cf0: 7b 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20  {.    int iKey; 
9d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9d10: 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c      /* Hash tabl
9d20: 65 20 6b 65 79 20 2a 2f 0a 20 20 20 20 69 6e 74  e key */.    int
9d30: 20 69 64 78 3b 20 20 20 20 20 20 20 20 20 20 20   idx;           
9d40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61             /* Va
9d50: 6c 75 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20  lue to write to 
9d60: 68 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 20  hash-table slot 
9d70: 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 43 6f 6c 6c  */.    int nColl
9d80: 69 64 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ide;            
9d90: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
9da0: 66 20 68 61 73 68 20 63 6f 6c 6c 69 73 69 6f 6e  f hash collision
9db0: 73 20 2a 2f 0a 0a 20 20 20 20 69 64 78 20 3d 20  s */..    idx = 
9dc0: 69 46 72 61 6d 65 20 2d 20 69 5a 65 72 6f 3b 0a  iFrame - iZero;.
9dd0: 20 20 20 20 61 73 73 65 72 74 28 20 69 64 78 20      assert( idx 
9de0: 3c 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c  <= HASHTABLE_NSL
9df0: 4f 54 2f 32 20 2b 20 31 20 29 3b 0a 20 20 20 20  OT/2 + 1 );.    
9e00: 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20  .    /* If this 
9e10: 69 73 20 74 68 65 20 66 69 72 73 74 20 65 6e 74  is the first ent
9e20: 72 79 20 74 6f 20 62 65 20 61 64 64 65 64 20 74  ry to be added t
9e30: 6f 20 74 68 69 73 20 68 61 73 68 2d 74 61 62 6c  o this hash-tabl
9e40: 65 2c 20 7a 65 72 6f 20 74 68 65 0a 20 20 20 20  e, zero the.    
9e50: 2a 2a 20 65 6e 74 69 72 65 20 68 61 73 68 20 74  ** entire hash t
9e60: 61 62 6c 65 20 61 6e 64 20 61 50 67 6e 6f 5b 5d  able and aPgno[]
9e70: 20 61 72 72 61 79 20 62 65 66 6f 72 65 20 70 72   array before pr
9e80: 6f 63 65 65 64 69 6e 67 2e 20 0a 20 20 20 20 2a  oceeding. .    *
9e90: 2f 0a 20 20 20 20 69 66 28 20 69 64 78 3d 3d 31  /.    if( idx==1
9ea0: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 42   ){.      int nB
9eb0: 79 74 65 20 3d 20 28 69 6e 74 29 28 28 75 38 20  yte = (int)((u8 
9ec0: 2a 29 26 61 48 61 73 68 5b 48 41 53 48 54 41 42  *)&aHash[HASHTAB
9ed0: 4c 45 5f 4e 53 4c 4f 54 5d 20 2d 20 28 75 38 20  LE_NSLOT] - (u8 
9ee0: 2a 29 26 61 50 67 6e 6f 5b 31 5d 29 3b 0a 20 20  *)&aPgno[1]);.  
9ef0: 20 20 20 20 6d 65 6d 73 65 74 28 28 76 6f 69 64      memset((void
9f00: 2a 29 26 61 50 67 6e 6f 5b 31 5d 2c 20 30 2c 20  *)&aPgno[1], 0, 
9f10: 6e 42 79 74 65 29 3b 0a 20 20 20 20 7d 0a 0a 20  nByte);.    }.. 
9f20: 20 20 20 2f 2a 20 49 66 20 74 68 65 20 65 6e 74     /* If the ent
9f30: 72 79 20 69 6e 20 61 50 67 6e 6f 5b 5d 20 69 73  ry in aPgno[] is
9f40: 20 61 6c 72 65 61 64 79 20 73 65 74 2c 20 74 68   already set, th
9f50: 65 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73 20  en the previous 
9f60: 77 72 69 74 65 72 0a 20 20 20 20 2a 2a 20 6d 75  writer.    ** mu
9f70: 73 74 20 68 61 76 65 20 65 78 69 74 65 64 20 75  st have exited u
9f80: 6e 65 78 70 65 63 74 65 64 6c 79 20 69 6e 20 74  nexpectedly in t
9f90: 68 65 20 6d 69 64 64 6c 65 20 6f 66 20 61 20 74  he middle of a t
9fa0: 72 61 6e 73 61 63 74 69 6f 6e 20 28 61 66 74 65  ransaction (afte
9fb0: 72 0a 20 20 20 20 2a 2a 20 77 72 69 74 69 6e 67  r.    ** writing
9fc0: 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 64 69 72   one or more dir
9fd0: 74 79 20 70 61 67 65 73 20 74 6f 20 74 68 65 20  ty pages to the 
9fe0: 57 41 4c 20 74 6f 20 66 72 65 65 20 75 70 20 6d  WAL to free up m
9ff0: 65 6d 6f 72 79 29 2e 20 0a 20 20 20 20 2a 2a 20  emory). .    ** 
a000: 52 65 6d 6f 76 65 20 74 68 65 20 72 65 6d 6e 61  Remove the remna
a010: 6e 74 73 20 6f 66 20 74 68 61 74 20 77 72 69 74  nts of that writ
a020: 65 72 73 20 75 6e 63 6f 6d 6d 69 74 74 65 64 20  ers uncommitted 
a030: 74 72 61 6e 73 61 63 74 69 6f 6e 20 66 72 6f 6d  transaction from
a040: 20 0a 20 20 20 20 2a 2a 20 74 68 65 20 68 61 73   .    ** the has
a050: 68 2d 74 61 62 6c 65 20 62 65 66 6f 72 65 20 77  h-table before w
a060: 72 69 74 69 6e 67 20 61 6e 79 20 6e 65 77 20 65  riting any new e
a070: 6e 74 72 69 65 73 2e 0a 20 20 20 20 2a 2f 0a 20  ntries..    */. 
a080: 20 20 20 69 66 28 20 61 50 67 6e 6f 5b 69 64 78     if( aPgno[idx
a090: 5d 20 29 7b 0a 20 20 20 20 20 20 77 61 6c 43 6c  ] ){.      walCl
a0a0: 65 61 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b  eanupHash(pWal);
a0b0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 21  .      assert( !
a0c0: 61 50 67 6e 6f 5b 69 64 78 5d 20 29 3b 0a 20 20  aPgno[idx] );.  
a0d0: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74    }..    /* Writ
a0e0: 65 20 74 68 65 20 61 50 67 6e 6f 5b 5d 20 61 72  e the aPgno[] ar
a0f0: 72 61 79 20 65 6e 74 72 79 20 61 6e 64 20 74 68  ray entry and th
a100: 65 20 68 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f  e hash-table slo
a110: 74 2e 20 2a 2f 0a 20 20 20 20 6e 43 6f 6c 6c 69  t. */.    nColli
a120: 64 65 20 3d 20 69 64 78 3b 0a 20 20 20 20 66 6f  de = idx;.    fo
a130: 72 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 69  r(iKey=walHash(i
a140: 50 61 67 65 29 3b 20 61 48 61 73 68 5b 69 4b 65  Page); aHash[iKe
a150: 79 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74  y]; iKey=walNext
a160: 48 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20  Hash(iKey)){.   
a170: 20 20 20 69 66 28 20 28 6e 43 6f 6c 6c 69 64 65     if( (nCollide
a180: 2d 2d 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  --)==0 ) return 
a190: 53 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 42  SQLITE_CORRUPT_B
a1a0: 4b 50 54 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  KPT;.    }.    a
a1b0: 50 67 6e 6f 5b 69 64 78 5d 20 3d 20 69 50 61 67  Pgno[idx] = iPag
a1c0: 65 3b 0a 20 20 20 20 61 48 61 73 68 5b 69 4b 65  e;.    aHash[iKe
a1d0: 79 5d 20 3d 20 28 68 74 5f 73 6c 6f 74 29 69 64  y] = (ht_slot)id
a1e0: 78 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  x;..#ifdef SQLIT
a1f0: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
a200: 56 45 5f 41 53 53 45 52 54 0a 20 20 20 20 2f 2a  VE_ASSERT.    /*
a210: 20 56 65 72 69 66 79 20 74 68 61 74 20 74 68 65   Verify that the
a220: 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69   number of entri
a230: 65 73 20 69 6e 20 74 68 65 20 68 61 73 68 20 74  es in the hash t
a240: 61 62 6c 65 20 65 78 61 63 74 6c 79 20 65 71 75  able exactly equ
a250: 61 6c 73 0a 20 20 20 20 2a 2a 20 74 68 65 20 6e  als.    ** the n
a260: 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73  umber of entries
a270: 20 69 6e 20 74 68 65 20 6d 61 70 70 69 6e 67 20   in the mapping 
a280: 72 65 67 69 6f 6e 2e 0a 20 20 20 20 2a 2f 0a 20  region..    */. 
a290: 20 20 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 69     {.      int i
a2a0: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c  ;           /* L
a2b0: 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20  oop counter */. 
a2c0: 20 20 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 20       int nEntry 
a2d0: 3d 20 30 3b 20 20 2f 2a 20 4e 75 6d 62 65 72 20  = 0;  /* Number 
a2e0: 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68  of entries in th
a2f0: 65 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a  e hash table */.
a300: 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69        for(i=0; i
a310: 3c 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54  <HASHTABLE_NSLOT
a320: 3b 20 69 2b 2b 29 7b 20 69 66 28 20 61 48 61 73  ; i++){ if( aHas
a330: 68 5b 69 5d 20 29 20 6e 45 6e 74 72 79 2b 2b 3b  h[i] ) nEntry++;
a340: 20 7d 0a 20 20 20 20 20 20 61 73 73 65 72 74 28   }.      assert(
a350: 20 6e 45 6e 74 72 79 3d 3d 69 64 78 20 29 3b 0a   nEntry==idx );.
a360: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 56 65      }..    /* Ve
a370: 72 69 66 79 20 74 68 61 74 20 74 68 65 20 65 76  rify that the ev
a380: 65 72 79 20 65 6e 74 72 79 20 69 6e 20 74 68 65  ery entry in the
a390: 20 6d 61 70 70 69 6e 67 20 72 65 67 69 6f 6e 20   mapping region 
a3a0: 69 73 20 72 65 61 63 68 61 62 6c 65 0a 20 20 20  is reachable.   
a3b0: 20 2a 2a 20 76 69 61 20 74 68 65 20 68 61 73 68   ** via the hash
a3c0: 20 74 61 62 6c 65 2e 20 20 54 68 69 73 20 74 75   table.  This tu
a3d0: 72 6e 73 20 6f 75 74 20 74 6f 20 62 65 20 61 20  rns out to be a 
a3e0: 72 65 61 6c 6c 79 2c 20 72 65 61 6c 6c 79 20 65  really, really e
a3f0: 78 70 65 6e 73 69 76 65 0a 20 20 20 20 2a 2a 20  xpensive.    ** 
a400: 74 68 69 6e 67 20 74 6f 20 63 68 65 63 6b 2c 20  thing to check, 
a410: 73 6f 20 6f 6e 6c 79 20 64 6f 20 74 68 69 73 20  so only do this 
a420: 6f 63 63 61 73 69 6f 6e 61 6c 6c 79 20 2d 20 6e  occasionally - n
a430: 6f 74 20 6f 6e 20 65 76 65 72 79 0a 20 20 20 20  ot on every.    
a440: 2a 2a 20 69 74 65 72 61 74 69 6f 6e 2e 0a 20 20  ** iteration..  
a450: 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 28 69 64    */.    if( (id
a460: 78 26 30 78 33 66 66 29 3d 3d 30 20 29 7b 0a 20  x&0x3ff)==0 ){. 
a470: 20 20 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20       int i;     
a480: 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f        /* Loop co
a490: 75 6e 74 65 72 20 2a 2f 0a 20 20 20 20 20 20 66  unter */.      f
a4a0: 6f 72 28 69 3d 31 3b 20 69 3c 3d 69 64 78 3b 20  or(i=1; i<=idx; 
a4b0: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 66 6f  i++){.        fo
a4c0: 72 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 61  r(iKey=walHash(a
a4d0: 50 67 6e 6f 5b 69 5d 29 3b 20 61 48 61 73 68 5b  Pgno[i]); aHash[
a4e0: 69 4b 65 79 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e  iKey]; iKey=walN
a4f0: 65 78 74 48 61 73 68 28 69 4b 65 79 29 29 7b 0a  extHash(iKey)){.
a500: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 61 48            if( aH
a510: 61 73 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 20 62  ash[iKey]==i ) b
a520: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a  reak;.        }.
a530: 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
a540: 61 48 61 73 68 5b 69 4b 65 79 5d 3d 3d 69 20 29  aHash[iKey]==i )
a550: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
a560: 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45  #endif /* SQLITE
a570: 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56  _ENABLE_EXPENSIV
a580: 45 5f 41 53 53 45 52 54 20 2a 2f 0a 20 20 7d 0a  E_ASSERT */.  }.
a590: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
a5a0: 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 63 6f 76 65 72  .../*.** Recover
a5b0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 62   the wal-index b
a5c0: 79 20 72 65 61 64 69 6e 67 20 74 68 65 20 77 72  y reading the wr
a5d0: 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69  ite-ahead log fi
a5e0: 6c 65 2e 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  le. .**.** This 
a5f0: 72 6f 75 74 69 6e 65 20 66 69 72 73 74 20 74 72  routine first tr
a600: 69 65 73 20 74 6f 20 65 73 74 61 62 6c 69 73 68  ies to establish
a610: 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c 6f   an exclusive lo
a620: 63 6b 20 6f 6e 20 74 68 65 0a 2a 2a 20 77 61 6c  ck on the.** wal
a630: 2d 69 6e 64 65 78 20 74 6f 20 70 72 65 76 65 6e  -index to preven
a640: 74 20 6f 74 68 65 72 20 74 68 72 65 61 64 73 2f  t other threads/
a650: 70 72 6f 63 65 73 73 65 73 20 66 72 6f 6d 20 64  processes from d
a660: 6f 69 6e 67 20 61 6e 79 74 68 69 6e 67 0a 2a 2a  oing anything.**
a670: 20 77 69 74 68 20 74 68 65 20 57 41 4c 20 6f 72   with the WAL or
a680: 20 77 61 6c 2d 69 6e 64 65 78 20 77 68 69 6c 65   wal-index while
a690: 20 72 65 63 6f 76 65 72 79 20 69 73 20 72 75 6e   recovery is run
a6a0: 6e 69 6e 67 2e 20 20 54 68 65 0a 2a 2a 20 57 41  ning.  The.** WA
a6b0: 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20 69  L_RECOVER_LOCK i
a6c0: 73 20 61 6c 73 6f 20 68 65 6c 64 20 73 6f 20 74  s also held so t
a6d0: 68 61 74 20 6f 74 68 65 72 20 74 68 72 65 61 64  hat other thread
a6e0: 73 20 77 69 6c 6c 20 6b 6e 6f 77 0a 2a 2a 20 74  s will know.** t
a6f0: 68 61 74 20 74 68 69 73 20 74 68 72 65 61 64 20  hat this thread 
a700: 69 73 20 72 75 6e 6e 69 6e 67 20 72 65 63 6f 76  is running recov
a710: 65 72 79 2e 20 20 49 66 20 75 6e 61 62 6c 65 20  ery.  If unable 
a720: 74 6f 20 65 73 74 61 62 6c 69 73 68 0a 2a 2a 20  to establish.** 
a730: 74 68 65 20 6e 65 63 65 73 73 61 72 79 20 6c 6f  the necessary lo
a740: 63 6b 73 2c 20 74 68 69 73 20 72 6f 75 74 69 6e  cks, this routin
a750: 65 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45  e returns SQLITE
a760: 5f 42 55 53 59 2e 0a 2a 2f 0a 73 74 61 74 69 63  _BUSY..*/.static
a770: 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 52 65 63   int walIndexRec
a780: 6f 76 65 72 28 57 61 6c 20 2a 70 57 61 6c 29 7b  over(Wal *pWal){
a790: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
a7a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a7b0: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64     /* Return Cod
a7c0: 65 20 2a 2f 0a 20 20 69 36 34 20 6e 53 69 7a 65  e */.  i64 nSize
a7d0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
a7e0: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
a7f0: 66 20 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a 20 20  f log file */.  
a800: 75 33 32 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b  u32 aFrameCksum[
a810: 32 5d 20 3d 20 7b 30 2c 20 30 7d 3b 0a 20 20 69  2] = {0, 0};.  i
a820: 6e 74 20 69 4c 6f 63 6b 3b 20 20 20 20 20 20 20  nt iLock;       
a830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
a840: 2a 20 4c 6f 63 6b 20 6f 66 66 73 65 74 20 74 6f  * Lock offset to
a850: 20 6c 6f 63 6b 20 66 6f 72 20 63 68 65 63 6b 70   lock for checkp
a860: 6f 69 6e 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c  oint */.  int nL
a870: 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ock;            
a880: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
a890: 62 65 72 20 6f 66 20 6c 6f 63 6b 73 20 74 6f 20  ber of locks to 
a8a0: 68 6f 6c 64 20 2a 2f 0a 0a 20 20 2f 2a 20 4f 62  hold */..  /* Ob
a8b0: 74 61 69 6e 20 61 6e 20 65 78 63 6c 75 73 69 76  tain an exclusiv
a8c0: 65 20 6c 6f 63 6b 20 6f 6e 20 61 6c 6c 20 62 79  e lock on all by
a8d0: 74 65 20 69 6e 20 74 68 65 20 6c 6f 63 6b 69 6e  te in the lockin
a8e0: 67 20 72 61 6e 67 65 20 6e 6f 74 20 61 6c 72 65  g range not alre
a8f0: 61 64 79 0a 20 20 2a 2a 20 6c 6f 63 6b 65 64 20  ady.  ** locked 
a900: 62 79 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 54  by the caller. T
a910: 68 65 20 63 61 6c 6c 65 72 20 69 73 20 67 75 61  he caller is gua
a920: 72 61 6e 74 65 65 64 20 74 6f 20 68 61 76 65 20  ranteed to have 
a930: 6c 6f 63 6b 65 64 20 74 68 65 0a 20 20 2a 2a 20  locked the.  ** 
a940: 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 62  WAL_WRITE_LOCK b
a950: 79 74 65 2c 20 61 6e 64 20 6d 61 79 20 68 61 76  yte, and may hav
a960: 65 20 61 6c 73 6f 20 6c 6f 63 6b 65 64 20 74 68  e also locked th
a970: 65 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20  e WAL_CKPT_LOCK 
a980: 62 79 74 65 2e 0a 20 20 2a 2a 20 49 66 20 73 75  byte..  ** If su
a990: 63 63 65 73 73 66 75 6c 2c 20 74 68 65 20 73 61  ccessful, the sa
a9a0: 6d 65 20 62 79 74 65 73 20 74 68 61 74 20 61 72  me bytes that ar
a9b0: 65 20 6c 6f 63 6b 65 64 20 68 65 72 65 20 61 72  e locked here ar
a9c0: 65 20 75 6e 6c 6f 63 6b 65 64 20 62 65 66 6f 72  e unlocked befor
a9d0: 65 0a 20 20 2a 2a 20 74 68 69 73 20 66 75 6e 63  e.  ** this func
a9e0: 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e 0a 20 20  tion returns..  
a9f0: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  */.  assert( pWa
aa00: 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 31 20 7c  l->ckptLock==1 |
aa10: 7c 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b  | pWal->ckptLock
aa20: 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
aa30: 20 57 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49   WAL_ALL_BUT_WRI
aa40: 54 45 3d 3d 57 41 4c 5f 57 52 49 54 45 5f 4c 4f  TE==WAL_WRITE_LO
aa50: 43 4b 2b 31 20 29 3b 0a 20 20 61 73 73 65 72 74  CK+1 );.  assert
aa60: 28 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 3d  ( WAL_CKPT_LOCK=
aa70: 3d 57 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49  =WAL_ALL_BUT_WRI
aa80: 54 45 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  TE );.  assert( 
aa90: 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
aaa0: 29 3b 0a 20 20 69 4c 6f 63 6b 20 3d 20 57 41 4c  );.  iLock = WAL
aab0: 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 2b  _ALL_BUT_WRITE +
aac0: 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3b   pWal->ckptLock;
aad0: 0a 20 20 6e 4c 6f 63 6b 20 3d 20 53 51 4c 49 54  .  nLock = SQLIT
aae0: 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 20 2d 20 69 4c  E_SHM_NLOCK - iL
aaf0: 6f 63 6b 3b 0a 20 20 72 63 20 3d 20 77 61 6c 4c  ock;.  rc = walL
ab00: 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
ab10: 6c 2c 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29  l, iLock, nLock)
ab20: 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20  ;.  if( rc ){.  
ab30: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d    return rc;.  }
ab40: 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41  .  WALTRACE(("WA
ab50: 4c 25 70 3a 20 72 65 63 6f 76 65 72 79 20 62 65  L%p: recovery be
ab60: 67 69 6e 2e 2e 2e 5c 6e 22 2c 20 70 57 61 6c 29  gin...\n", pWal)
ab70: 29 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 70 57  );..  memset(&pW
ab80: 61 6c 2d 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65  al->hdr, 0, size
ab90: 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
aba0: 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  ;..  rc = sqlite
abb0: 33 4f 73 46 69 6c 65 53 69 7a 65 28 70 57 61 6c  3OsFileSize(pWal
abc0: 2d 3e 70 57 61 6c 46 64 2c 20 26 6e 53 69 7a 65  ->pWalFd, &nSize
abd0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
abe0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 67 6f  ITE_OK ){.    go
abf0: 74 6f 20 72 65 63 6f 76 65 72 79 5f 65 72 72 6f  to recovery_erro
ac00: 72 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6e 53  r;.  }..  if( nS
ac10: 69 7a 65 3e 57 41 4c 5f 48 44 52 53 49 5a 45 20  ize>WAL_HDRSIZE 
ac20: 29 7b 0a 20 20 20 20 75 38 20 61 42 75 66 5b 57  ){.    u8 aBuf[W
ac30: 41 4c 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20 20  AL_HDRSIZE];    
ac40: 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74       /* Buffer t
ac50: 6f 20 6c 6f 61 64 20 57 41 4c 20 68 65 61 64 65  o load WAL heade
ac60: 72 20 69 6e 74 6f 20 2a 2f 0a 20 20 20 20 75 38  r into */.    u8
ac70: 20 2a 61 46 72 61 6d 65 20 3d 20 30 3b 20 20 20   *aFrame = 0;   
ac80: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
ac90: 61 6c 6c 6f 63 27 64 20 62 75 66 66 65 72 20 74  alloc'd buffer t
aca0: 6f 20 6c 6f 61 64 20 65 6e 74 69 72 65 20 66 72  o load entire fr
acb0: 61 6d 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20 73  ame */.    int s
acc0: 7a 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20  zFrame;         
acd0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
ace0: 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20 62  er of bytes in b
acf0: 75 66 66 65 72 20 61 46 72 61 6d 65 5b 5d 20 2a  uffer aFrame[] *
ad00: 2f 0a 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b  /.    u8 *aData;
ad10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad20: 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
ad30: 6f 20 64 61 74 61 20 70 61 72 74 20 6f 66 20 61  o data part of a
ad40: 46 72 61 6d 65 20 62 75 66 66 65 72 20 2a 2f 0a  Frame buffer */.
ad50: 20 20 20 20 69 6e 74 20 69 46 72 61 6d 65 3b 20      int iFrame; 
ad60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad70: 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6c 61    /* Index of la
ad80: 73 74 20 66 72 61 6d 65 20 72 65 61 64 20 2a 2f  st frame read */
ad90: 0a 20 20 20 20 69 36 34 20 69 4f 66 66 73 65 74  .    i64 iOffset
ada0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
adb0: 20 20 20 2f 2a 20 4e 65 78 74 20 6f 66 66 73 65     /* Next offse
adc0: 74 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 6c  t to read from l
add0: 6f 67 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 69  og file */.    i
ade0: 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20  nt szPage;      
adf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
ae00: 50 61 67 65 20 73 69 7a 65 20 61 63 63 6f 72 64  Page size accord
ae10: 69 6e 67 20 74 6f 20 74 68 65 20 6c 6f 67 20 2a  ing to the log *
ae20: 2f 0a 20 20 20 20 75 33 32 20 6d 61 67 69 63 3b  /.    u32 magic;
ae30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ae40: 20 20 20 20 2f 2a 20 4d 61 67 69 63 20 76 61 6c      /* Magic val
ae50: 75 65 20 72 65 61 64 20 66 72 6f 6d 20 57 41 4c  ue read from WAL
ae60: 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 75   header */.    u
ae70: 33 32 20 76 65 72 73 69 6f 6e 3b 20 20 20 20 20  32 version;     
ae80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
ae90: 4d 61 67 69 63 20 76 61 6c 75 65 20 72 65 61 64  Magic value read
aea0: 20 66 72 6f 6d 20 57 41 4c 20 68 65 61 64 65 72   from WAL header
aeb0: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 73 56 61   */.    int isVa
aec0: 6c 69 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  lid;            
aed0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
aee0: 20 74 68 69 73 20 66 72 61 6d 65 20 69 73 20 76   this frame is v
aef0: 61 6c 69 64 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20  alid */..    /* 
af00: 52 65 61 64 20 69 6e 20 74 68 65 20 57 41 4c 20  Read in the WAL 
af10: 68 65 61 64 65 72 2e 20 2a 2f 0a 20 20 20 20 72  header. */.    r
af20: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61  c = sqlite3OsRea
af30: 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20  d(pWal->pWalFd, 
af40: 61 42 75 66 2c 20 57 41 4c 5f 48 44 52 53 49 5a  aBuf, WAL_HDRSIZ
af50: 45 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 72  E, 0);.    if( r
af60: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
af70: 20 20 20 20 20 20 67 6f 74 6f 20 72 65 63 6f 76        goto recov
af80: 65 72 79 5f 65 72 72 6f 72 3b 0a 20 20 20 20 7d  ery_error;.    }
af90: 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20  ..    /* If the 
afa0: 64 61 74 61 62 61 73 65 20 70 61 67 65 20 73 69  database page si
afb0: 7a 65 20 69 73 20 6e 6f 74 20 61 20 70 6f 77 65  ze is not a powe
afc0: 72 20 6f 66 20 74 77 6f 2c 20 6f 72 20 69 73 20  r of two, or is 
afd0: 67 72 65 61 74 65 72 20 74 68 61 6e 0a 20 20 20  greater than.   
afe0: 20 2a 2a 20 53 51 4c 49 54 45 5f 4d 41 58 5f 50   ** SQLITE_MAX_P
aff0: 41 47 45 5f 53 49 5a 45 2c 20 63 6f 6e 63 6c 75  AGE_SIZE, conclu
b000: 64 65 20 74 68 61 74 20 74 68 65 20 57 41 4c 20  de that the WAL 
b010: 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 6e 6f  file contains no
b020: 20 76 61 6c 69 64 20 0a 20 20 20 20 2a 2a 20 64   valid .    ** d
b030: 61 74 61 2e 20 53 69 6d 69 6c 61 72 6c 79 2c 20  ata. Similarly, 
b040: 69 66 20 74 68 65 20 27 6d 61 67 69 63 27 20 76  if the 'magic' v
b050: 61 6c 75 65 20 69 73 20 69 6e 76 61 6c 69 64 2c  alue is invalid,
b060: 20 69 67 6e 6f 72 65 20 74 68 65 20 77 68 6f 6c   ignore the whol
b070: 65 0a 20 20 20 20 2a 2a 20 57 41 4c 20 66 69 6c  e.    ** WAL fil
b080: 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d 61  e..    */.    ma
b090: 67 69 63 20 3d 20 73 71 6c 69 74 65 33 47 65 74  gic = sqlite3Get
b0a0: 34 62 79 74 65 28 26 61 42 75 66 5b 30 5d 29 3b  4byte(&aBuf[0]);
b0b0: 0a 20 20 20 20 73 7a 50 61 67 65 20 3d 20 73 71  .    szPage = sq
b0c0: 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61  lite3Get4byte(&a
b0d0: 42 75 66 5b 38 5d 29 3b 0a 20 20 20 20 69 66 28  Buf[8]);.    if(
b0e0: 20 28 6d 61 67 69 63 26 30 78 46 46 46 46 46 46   (magic&0xFFFFFF
b0f0: 46 45 29 21 3d 57 41 4c 5f 4d 41 47 49 43 20 0a  FE)!=WAL_MAGIC .
b100: 20 20 20 20 20 7c 7c 20 73 7a 50 61 67 65 26 28       || szPage&(
b110: 73 7a 50 61 67 65 2d 31 29 20 0a 20 20 20 20 20  szPage-1) .     
b120: 7c 7c 20 73 7a 50 61 67 65 3e 53 51 4c 49 54 45  || szPage>SQLITE
b130: 5f 4d 41 58 5f 50 41 47 45 5f 53 49 5a 45 20 0a  _MAX_PAGE_SIZE .
b140: 20 20 20 20 20 7c 7c 20 73 7a 50 61 67 65 3c 35       || szPage<5
b150: 31 32 20 0a 20 20 20 20 29 7b 0a 20 20 20 20 20  12 .    ){.     
b160: 20 67 6f 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a   goto finished;.
b170: 20 20 20 20 7d 0a 20 20 20 20 70 57 61 6c 2d 3e      }.    pWal->
b180: 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 20  hdr.bigEndCksum 
b190: 3d 20 28 75 38 29 28 6d 61 67 69 63 26 30 78 30  = (u8)(magic&0x0
b1a0: 30 30 30 30 30 30 31 29 3b 0a 20 20 20 20 70 57  0000001);.    pW
b1b0: 61 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50  al->szPage = szP
b1c0: 61 67 65 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 6e  age;.    pWal->n
b1d0: 43 6b 70 74 20 3d 20 73 71 6c 69 74 65 33 47 65  Ckpt = sqlite3Ge
b1e0: 74 34 62 79 74 65 28 26 61 42 75 66 5b 31 32 5d  t4byte(&aBuf[12]
b1f0: 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70  );.    memcpy(&p
b200: 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20  Wal->hdr.aSalt, 
b210: 26 61 42 75 66 5b 31 36 5d 2c 20 38 29 3b 0a 0a  &aBuf[16], 8);..
b220: 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20 74 68      /* Verify th
b230: 61 74 20 74 68 65 20 57 41 4c 20 68 65 61 64 65  at the WAL heade
b240: 72 20 63 68 65 63 6b 73 75 6d 20 69 73 20 63 6f  r checksum is co
b250: 72 72 65 63 74 20 2a 2f 0a 20 20 20 20 77 61 6c  rrect */.    wal
b260: 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28 70 57  ChecksumBytes(pW
b270: 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b  al->hdr.bigEndCk
b280: 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45  sum==SQLITE_BIGE
b290: 4e 44 49 41 4e 2c 20 0a 20 20 20 20 20 20 20 20  NDIAN, .        
b2a0: 61 42 75 66 2c 20 57 41 4c 5f 48 44 52 53 49 5a  aBuf, WAL_HDRSIZ
b2b0: 45 2d 32 2a 34 2c 20 30 2c 20 70 57 61 6c 2d 3e  E-2*4, 0, pWal->
b2c0: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 0a  hdr.aFrameCksum.
b2d0: 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28 20 70      );.    if( p
b2e0: 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
b2f0: 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65 33  ksum[0]!=sqlite3
b300: 47 65 74 34 62 79 74 65 28 26 61 42 75 66 5b 32  Get4byte(&aBuf[2
b310: 34 5d 29 0a 20 20 20 20 20 7c 7c 20 70 57 61 6c  4]).     || pWal
b320: 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
b330: 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33 47 65 74  m[1]!=sqlite3Get
b340: 34 62 79 74 65 28 26 61 42 75 66 5b 32 38 5d 29  4byte(&aBuf[28])
b350: 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 67 6f  .    ){.      go
b360: 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20 20  to finished;.   
b370: 20 7d 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69 66   }..    /* Verif
b380: 79 20 74 68 61 74 20 74 68 65 20 76 65 72 73 69  y that the versi
b390: 6f 6e 20 6e 75 6d 62 65 72 20 6f 6e 20 74 68 65  on number on the
b3a0: 20 57 41 4c 20 66 6f 72 6d 61 74 20 69 73 20 6f   WAL format is o
b3b0: 6e 65 20 74 68 61 74 0a 20 20 20 20 2a 2a 20 61  ne that.    ** a
b3c0: 72 65 20 61 62 6c 65 20 74 6f 20 75 6e 64 65 72  re able to under
b3d0: 73 74 61 6e 64 20 2a 2f 0a 20 20 20 20 76 65 72  stand */.    ver
b3e0: 73 69 6f 6e 20 3d 20 73 71 6c 69 74 65 33 47 65  sion = sqlite3Ge
b3f0: 74 34 62 79 74 65 28 26 61 42 75 66 5b 34 5d 29  t4byte(&aBuf[4])
b400: 3b 0a 20 20 20 20 69 66 28 20 76 65 72 73 69 6f  ;.    if( versio
b410: 6e 21 3d 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49  n!=WAL_MAX_VERSI
b420: 4f 4e 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  ON ){.      rc =
b430: 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e   SQLITE_CANTOPEN
b440: 5f 42 4b 50 54 3b 0a 20 20 20 20 20 20 67 6f 74  _BKPT;.      got
b450: 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20 20 20  o finished;.    
b460: 7d 0a 0a 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f 63  }..    /* Malloc
b470: 20 61 20 62 75 66 66 65 72 20 74 6f 20 72 65 61   a buffer to rea
b480: 64 20 66 72 61 6d 65 73 20 69 6e 74 6f 2e 20 2a  d frames into. *
b490: 2f 0a 20 20 20 20 73 7a 46 72 61 6d 65 20 3d 20  /.    szFrame = 
b4a0: 73 7a 50 61 67 65 20 2b 20 57 41 4c 5f 46 52 41  szPage + WAL_FRA
b4b0: 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20 20 20 20  ME_HDRSIZE;.    
b4c0: 61 46 72 61 6d 65 20 3d 20 28 75 38 20 2a 29 73  aFrame = (u8 *)s
b4d0: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 7a  qlite3_malloc(sz
b4e0: 46 72 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20  Frame);.    if( 
b4f0: 21 61 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 20  !aFrame ){.     
b500: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
b510: 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 72  EM;.      goto r
b520: 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20  ecovery_error;. 
b530: 20 20 20 7d 0a 20 20 20 20 61 44 61 74 61 20 3d     }.    aData =
b540: 20 26 61 46 72 61 6d 65 5b 57 41 4c 5f 46 52 41   &aFrame[WAL_FRA
b550: 4d 45 5f 48 44 52 53 49 5a 45 5d 3b 0a 0a 20 20  ME_HDRSIZE];..  
b560: 20 20 2f 2a 20 52 65 61 64 20 61 6c 6c 20 66 72    /* Read all fr
b570: 61 6d 65 73 20 66 72 6f 6d 20 74 68 65 20 6c 6f  ames from the lo
b580: 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 20 20 69  g file. */.    i
b590: 46 72 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20 66  Frame = 0;.    f
b5a0: 6f 72 28 69 4f 66 66 73 65 74 3d 57 41 4c 5f 48  or(iOffset=WAL_H
b5b0: 44 52 53 49 5a 45 3b 20 28 69 4f 66 66 73 65 74  DRSIZE; (iOffset
b5c0: 2b 73 7a 46 72 61 6d 65 29 3c 3d 6e 53 69 7a 65  +szFrame)<=nSize
b5d0: 3b 20 69 4f 66 66 73 65 74 2b 3d 73 7a 46 72 61  ; iOffset+=szFra
b5e0: 6d 65 29 7b 0a 20 20 20 20 20 20 75 33 32 20 70  me){.      u32 p
b5f0: 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20  gno;            
b600: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
b610: 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 66  se page number f
b620: 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20 20 20 20  or frame */.    
b630: 20 20 75 33 32 20 6e 54 72 75 6e 63 61 74 65 3b    u32 nTruncate;
b640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
b650: 20 64 62 73 69 7a 65 20 66 69 65 6c 64 20 66 72   dbsize field fr
b660: 6f 6d 20 66 72 61 6d 65 20 68 65 61 64 65 72 20  om frame header 
b670: 2a 2f 0a 0a 20 20 20 20 20 20 2f 2a 20 52 65 61  */..      /* Rea
b680: 64 20 61 6e 64 20 64 65 63 6f 64 65 20 74 68 65  d and decode the
b690: 20 6e 65 78 74 20 6c 6f 67 20 66 72 61 6d 65 2e   next log frame.
b6a0: 20 2a 2f 0a 20 20 20 20 20 20 69 46 72 61 6d 65   */.      iFrame
b6b0: 2b 2b 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  ++;.      rc = s
b6c0: 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57 61  qlite3OsRead(pWa
b6d0: 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 46 72 61 6d  l->pWalFd, aFram
b6e0: 65 2c 20 73 7a 46 72 61 6d 65 2c 20 69 4f 66 66  e, szFrame, iOff
b6f0: 73 65 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20  set);.      if( 
b700: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
b710: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 69 73 56  break;.      isV
b720: 61 6c 69 64 20 3d 20 77 61 6c 44 65 63 6f 64 65  alid = walDecode
b730: 46 72 61 6d 65 28 70 57 61 6c 2c 20 26 70 67 6e  Frame(pWal, &pgn
b740: 6f 2c 20 26 6e 54 72 75 6e 63 61 74 65 2c 20 61  o, &nTruncate, a
b750: 44 61 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a 20  Data, aFrame);. 
b760: 20 20 20 20 20 69 66 28 20 21 69 73 56 61 6c 69       if( !isVali
b770: 64 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  d ) break;.     
b780: 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70   rc = walIndexAp
b790: 70 65 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d  pend(pWal, iFram
b7a0: 65 2c 20 70 67 6e 6f 29 3b 0a 20 20 20 20 20 20  e, pgno);.      
b7b0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
b7c0: 4b 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20  K ) break;..    
b7d0: 20 20 2f 2a 20 49 66 20 6e 54 72 75 6e 63 61 74    /* If nTruncat
b7e0: 65 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74  e is non-zero, t
b7f0: 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 20  his is a commit 
b800: 72 65 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 20  record. */.     
b810: 20 69 66 28 20 6e 54 72 75 6e 63 61 74 65 20 29   if( nTruncate )
b820: 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e  {.        pWal->
b830: 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20 69 46  hdr.mxFrame = iF
b840: 72 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 70 57  rame;.        pW
b850: 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20 3d 20  al->hdr.nPage = 
b860: 6e 54 72 75 6e 63 61 74 65 3b 0a 20 20 20 20 20  nTruncate;.     
b870: 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50     pWal->hdr.szP
b880: 61 67 65 20 3d 20 28 75 31 36 29 28 28 73 7a 50  age = (u16)((szP
b890: 61 67 65 26 30 78 66 66 30 30 29 20 7c 20 28 73  age&0xff00) | (s
b8a0: 7a 50 61 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20  zPage>>16));.   
b8b0: 20 20 20 20 20 74 65 73 74 63 61 73 65 28 20 73       testcase( s
b8c0: 7a 50 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a  zPage<=32768 );.
b8d0: 20 20 20 20 20 20 20 20 74 65 73 74 63 61 73 65          testcase
b8e0: 28 20 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20  ( szPage>=65536 
b8f0: 29 3b 0a 20 20 20 20 20 20 20 20 61 46 72 61 6d  );.        aFram
b900: 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 70 57 61 6c  eCksum[0] = pWal
b910: 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
b920: 6d 5b 30 5d 3b 0a 20 20 20 20 20 20 20 20 61 46  m[0];.        aF
b930: 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 70  rameCksum[1] = p
b940: 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
b950: 6b 73 75 6d 5b 31 5d 3b 0a 20 20 20 20 20 20 7d  ksum[1];.      }
b960: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69  .    }..    sqli
b970: 74 65 33 5f 66 72 65 65 28 61 46 72 61 6d 65 29  te3_free(aFrame)
b980: 3b 0a 20 20 7d 0a 0a 66 69 6e 69 73 68 65 64 3a  ;.  }..finished:
b990: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
b9a0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 6f 6c 61  E_OK ){.    vola
b9b0: 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f  tile WalCkptInfo
b9c0: 20 2a 70 49 6e 66 6f 3b 0a 20 20 20 20 69 6e 74   *pInfo;.    int
b9d0: 20 69 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64   i;.    pWal->hd
b9e0: 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d  r.aFrameCksum[0]
b9f0: 20 3d 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30   = aFrameCksum[0
ba00: 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  ];.    pWal->hdr
ba10: 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20  .aFrameCksum[1] 
ba20: 3d 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d  = aFrameCksum[1]
ba30: 3b 0a 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72  ;.    walIndexWr
ba40: 69 74 65 48 64 72 28 70 57 61 6c 29 3b 0a 0a 20  iteHdr(pWal);.. 
ba50: 20 20 20 2f 2a 20 52 65 73 65 74 20 74 68 65 20     /* Reset the 
ba60: 63 68 65 63 6b 70 6f 69 6e 74 2d 68 65 61 64 65  checkpoint-heade
ba70: 72 2e 20 54 68 69 73 20 69 73 20 73 61 66 65 20  r. This is safe 
ba80: 62 65 63 61 75 73 65 20 74 68 69 73 20 74 68 72  because this thr
ba90: 65 61 64 20 69 73 20 0a 20 20 20 20 2a 2a 20 63  ead is .    ** c
baa0: 75 72 72 65 6e 74 6c 79 20 68 6f 6c 64 69 6e 67  urrently holding
bab0: 20 6c 6f 63 6b 73 20 74 68 61 74 20 65 78 63 6c   locks that excl
bac0: 75 64 65 20 61 6c 6c 20 6f 74 68 65 72 20 72 65  ude all other re
bad0: 61 64 65 72 73 2c 20 77 72 69 74 65 72 73 20 61  aders, writers a
bae0: 6e 64 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70  nd.    ** checkp
baf0: 6f 69 6e 74 65 72 73 2e 0a 20 20 20 20 2a 2f 0a  ointers..    */.
bb00: 20 20 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43      pInfo = walC
bb10: 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20  kptInfo(pWal);. 
bb20: 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66     pInfo->nBackf
bb30: 69 6c 6c 20 3d 20 30 3b 0a 20 20 20 20 70 49 6e  ill = 0;.    pIn
bb40: 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d  fo->aReadMark[0]
bb50: 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d   = 0;.    for(i=
bb60: 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52  1; i<WAL_NREADER
bb70: 3b 20 69 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52  ; i++) pInfo->aR
bb80: 65 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41  eadMark[i] = REA
bb90: 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a  DMARK_NOT_USED;.
bba0: 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64      if( pWal->hd
bbb0: 72 2e 6d 78 46 72 61 6d 65 20 29 20 70 49 6e 66  r.mxFrame ) pInf
bbc0: 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 31 5d 20  o->aReadMark[1] 
bbd0: 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  = pWal->hdr.mxFr
bbe0: 61 6d 65 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20  ame;..    /* If 
bbf0: 6d 6f 72 65 20 74 68 61 6e 20 6f 6e 65 20 66 72  more than one fr
bc00: 61 6d 65 20 77 61 73 20 72 65 63 6f 76 65 72 65  ame was recovere
bc10: 64 20 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20 66  d from the log f
bc20: 69 6c 65 2c 20 72 65 70 6f 72 74 20 61 6e 0a 20  ile, report an. 
bc30: 20 20 20 2a 2a 20 65 76 65 6e 74 20 76 69 61 20     ** event via 
bc40: 73 71 6c 69 74 65 33 5f 6c 6f 67 28 29 2e 20 54  sqlite3_log(). T
bc50: 68 69 73 20 69 73 20 74 6f 20 68 65 6c 70 20 77  his is to help w
bc60: 69 74 68 20 69 64 65 6e 74 69 66 79 69 6e 67 20  ith identifying 
bc70: 70 65 72 66 6f 72 6d 61 6e 63 65 0a 20 20 20 20  performance.    
bc80: 2a 2a 20 70 72 6f 62 6c 65 6d 73 20 63 61 75 73  ** problems caus
bc90: 65 64 20 62 79 20 61 70 70 6c 69 63 61 74 69 6f  ed by applicatio
bca0: 6e 73 20 72 6f 75 74 69 6e 65 6c 79 20 73 68 75  ns routinely shu
bcb0: 74 74 69 6e 67 20 64 6f 77 6e 20 77 69 74 68 6f  tting down witho
bcc0: 75 74 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70  ut.    ** checkp
bcd0: 6f 69 6e 74 69 6e 67 20 74 68 65 20 6c 6f 67 20  ointing the log 
bce0: 66 69 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  file..    */.   
bcf0: 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6e   if( pWal->hdr.n
bd00: 50 61 67 65 20 29 7b 0a 20 20 20 20 20 20 73 71  Page ){.      sq
bd10: 6c 69 74 65 33 5f 6c 6f 67 28 53 51 4c 49 54 45  lite3_log(SQLITE
bd20: 5f 4e 4f 54 49 43 45 5f 52 45 43 4f 56 45 52 5f  _NOTICE_RECOVER_
bd30: 57 41 4c 2c 0a 20 20 20 20 20 20 20 20 20 20 22  WAL,.          "
bd40: 72 65 63 6f 76 65 72 65 64 20 25 64 20 66 72 61  recovered %d fra
bd50: 6d 65 73 20 66 72 6f 6d 20 57 41 4c 20 66 69 6c  mes from WAL fil
bd60: 65 20 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20  e %s",.         
bd70: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
bd80: 6d 65 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61  me, pWal->zWalNa
bd90: 6d 65 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20  me.      );.    
bda0: 7d 0a 20 20 7d 0a 0a 72 65 63 6f 76 65 72 79 5f  }.  }..recovery_
bdb0: 65 72 72 6f 72 3a 0a 20 20 57 41 4c 54 52 41 43  error:.  WALTRAC
bdc0: 45 28 28 22 57 41 4c 25 70 3a 20 72 65 63 6f 76  E(("WAL%p: recov
bdd0: 65 72 79 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c  ery %s\n", pWal,
bde0: 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a   rc ? "failed" :
bdf0: 20 22 6f 6b 22 29 29 3b 0a 20 20 77 61 6c 55 6e   "ok"));.  walUn
be00: 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  lockExclusive(pW
be10: 61 6c 2c 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b  al, iLock, nLock
be20: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
be30: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61  }../*.** Close a
be40: 6e 20 6f 70 65 6e 20 77 61 6c 2d 69 6e 64 65 78  n open wal-index
be50: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
be60: 20 77 61 6c 49 6e 64 65 78 43 6c 6f 73 65 28 57   walIndexClose(W
be70: 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 69 73  al *pWal, int is
be80: 44 65 6c 65 74 65 29 7b 0a 20 20 69 66 28 20 70  Delete){.  if( p
be90: 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
bea0: 64 65 3d 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f  de==WAL_HEAPMEMO
beb0: 52 59 5f 4d 4f 44 45 20 29 7b 0a 20 20 20 20 69  RY_MODE ){.    i
bec0: 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d  nt i;.    for(i=
bed0: 30 3b 20 69 3c 70 57 61 6c 2d 3e 6e 57 69 44 61  0; i<pWal->nWiDa
bee0: 74 61 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ta; i++){.      
bef0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 28 76 6f  sqlite3_free((vo
bf00: 69 64 20 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44  id *)pWal->apWiD
bf10: 61 74 61 5b 69 5d 29 3b 0a 20 20 20 20 20 20 70  ata[i]);.      p
bf20: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 5d  Wal->apWiData[i]
bf30: 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 65   = 0;.    }.  }e
bf40: 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  lse{.    sqlite3
bf50: 4f 73 53 68 6d 55 6e 6d 61 70 28 70 57 61 6c 2d  OsShmUnmap(pWal-
bf60: 3e 70 44 62 46 64 2c 20 69 73 44 65 6c 65 74 65  >pDbFd, isDelete
bf70: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  );.  }.}../* .**
bf80: 20 4f 70 65 6e 20 61 20 63 6f 6e 6e 65 63 74 69   Open a connecti
bf90: 6f 6e 20 74 6f 20 74 68 65 20 57 41 4c 20 66 69  on to the WAL fi
bfa0: 6c 65 20 7a 57 61 6c 4e 61 6d 65 2e 20 54 68 65  le zWalName. The
bfb0: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 6d   database file m
bfc0: 75 73 74 20 0a 2a 2a 20 61 6c 72 65 61 64 79 20  ust .** already 
bfd0: 62 65 20 6f 70 65 6e 65 64 20 6f 6e 20 63 6f 6e  be opened on con
bfe0: 6e 65 63 74 69 6f 6e 20 70 44 62 46 64 2e 20 54  nection pDbFd. T
bff0: 68 65 20 62 75 66 66 65 72 20 74 68 61 74 20 7a  he buffer that z
c000: 57 61 6c 4e 61 6d 65 20 70 6f 69 6e 74 73 0a 2a  WalName points.*
c010: 2a 20 74 6f 20 6d 75 73 74 20 72 65 6d 61 69 6e  * to must remain
c020: 20 76 61 6c 69 64 20 66 6f 72 20 74 68 65 20 6c   valid for the l
c030: 69 66 65 74 69 6d 65 20 6f 66 20 74 68 65 20 72  ifetime of the r
c040: 65 74 75 72 6e 65 64 20 57 61 6c 2a 20 68 61 6e  eturned Wal* han
c050: 64 6c 65 2e 0a 2a 2a 0a 2a 2a 20 41 20 53 48 41  dle..**.** A SHA
c060: 52 45 44 20 6c 6f 63 6b 20 73 68 6f 75 6c 64 20  RED lock should 
c070: 62 65 20 68 65 6c 64 20 6f 6e 20 74 68 65 20 64  be held on the d
c080: 61 74 61 62 61 73 65 20 66 69 6c 65 20 77 68 65  atabase file whe
c090: 6e 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a  n this function.
c0a0: 2a 2a 20 69 73 20 63 61 6c 6c 65 64 2e 20 54 68  ** is called. Th
c0b0: 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74 68 69  e purpose of thi
c0c0: 73 20 53 48 41 52 45 44 20 6c 6f 63 6b 20 69 73  s SHARED lock is
c0d0: 20 74 6f 20 70 72 65 76 65 6e 74 20 61 6e 79 20   to prevent any 
c0e0: 6f 74 68 65 72 0a 2a 2a 20 63 6c 69 65 6e 74 20  other.** client 
c0f0: 66 72 6f 6d 20 75 6e 6c 69 6e 6b 69 6e 67 20 74  from unlinking t
c100: 68 65 20 57 41 4c 20 6f 72 20 77 61 6c 2d 69 6e  he WAL or wal-in
c110: 64 65 78 20 66 69 6c 65 2e 20 49 66 20 61 6e 6f  dex file. If ano
c120: 74 68 65 72 20 70 72 6f 63 65 73 73 0a 2a 2a 20  ther process.** 
c130: 77 65 72 65 20 74 6f 20 64 6f 20 74 68 69 73 20  were to do this 
c140: 6a 75 73 74 20 61 66 74 65 72 20 74 68 69 73 20  just after this 
c150: 63 6c 69 65 6e 74 20 6f 70 65 6e 65 64 20 6f 6e  client opened on
c160: 65 20 6f 66 20 74 68 65 73 65 20 66 69 6c 65 73  e of these files
c170: 2c 20 74 68 65 0a 2a 2a 20 73 79 73 74 65 6d 20  , the.** system 
c180: 77 6f 75 6c 64 20 62 65 20 62 61 64 6c 79 20 62  would be badly b
c190: 72 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  roken..**.** If 
c1a0: 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 69 73 20  the log file is 
c1b0: 73 75 63 63 65 73 73 66 75 6c 6c 79 20 6f 70 65  successfully ope
c1c0: 6e 65 64 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69  ned, SQLITE_OK i
c1d0: 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 0a  s returned and .
c1e0: 2a 2a 20 2a 70 70 57 61 6c 20 69 73 20 73 65 74  ** *ppWal is set
c1f0: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20 6e   to point to a n
c200: 65 77 20 57 41 4c 20 68 61 6e 64 6c 65 2e 20 49  ew WAL handle. I
c210: 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72  f an error occur
c220: 73 2c 0a 2a 2a 20 61 6e 20 53 51 4c 69 74 65 20  s,.** an SQLite 
c230: 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65  error code is re
c240: 74 75 72 6e 65 64 20 61 6e 64 20 2a 70 70 57 61  turned and *ppWa
c250: 6c 20 69 73 20 6c 65 66 74 20 75 6e 6d 6f 64 69  l is left unmodi
c260: 66 69 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  fied..*/.int sql
c270: 69 74 65 33 57 61 6c 4f 70 65 6e 28 0a 20 20 73  ite3WalOpen(.  s
c280: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
c290: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
c2a0: 2a 20 76 66 73 20 6d 6f 64 75 6c 65 20 74 6f 20  * vfs module to 
c2b0: 6f 70 65 6e 20 77 61 6c 20 61 6e 64 20 77 61 6c  open wal and wal
c2c0: 2d 69 6e 64 65 78 20 2a 2f 0a 20 20 73 71 6c 69  -index */.  sqli
c2d0: 74 65 33 5f 66 69 6c 65 20 2a 70 44 62 46 64 2c  te3_file *pDbFd,
c2e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
c2f0: 68 65 20 6f 70 65 6e 20 64 61 74 61 62 61 73 65  he open database
c300: 20 66 69 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74   file */.  const
c310: 20 63 68 61 72 20 2a 7a 57 61 6c 4e 61 6d 65 2c   char *zWalName,
c320: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61             /* Na
c330: 6d 65 20 6f 66 20 74 68 65 20 57 41 4c 20 66 69  me of the WAL fi
c340: 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 62 4e 6f 53  le */.  int bNoS
c350: 68 6d 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  hm,             
c360: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
c370: 74 6f 20 72 75 6e 20 69 6e 20 68 65 61 70 2d 6d  to run in heap-m
c380: 65 6d 6f 72 79 20 6d 6f 64 65 20 2a 2f 0a 20 20  emory mode */.  
c390: 69 36 34 20 6d 78 57 61 6c 53 69 7a 65 2c 20 20  i64 mxWalSize,  
c3a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c3b0: 2f 2a 20 54 72 75 6e 63 61 74 65 20 57 41 4c 20  /* Truncate WAL 
c3c0: 74 6f 20 74 68 69 73 20 73 69 7a 65 20 6f 6e 20  to this size on 
c3d0: 72 65 73 65 74 20 2a 2f 0a 20 20 57 61 6c 20 2a  reset */.  Wal *
c3e0: 2a 70 70 57 61 6c 20 20 20 20 20 20 20 20 20 20  *ppWal          
c3f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
c400: 54 3a 20 41 6c 6c 6f 63 61 74 65 64 20 57 61 6c  T: Allocated Wal
c410: 20 68 61 6e 64 6c 65 20 2a 2f 0a 29 7b 0a 20 20   handle */.){.  
c420: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
c430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c440: 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a  /* Return Code *
c450: 2f 0a 20 20 57 61 6c 20 2a 70 52 65 74 3b 20 20  /.  Wal *pRet;  
c460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c470: 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 74 6f      /* Object to
c480: 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65   allocate and re
c490: 74 75 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 66 6c  turn */.  int fl
c4a0: 61 67 73 3b 20 20 20 20 20 20 20 20 20 20 20 20  ags;            
c4b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61            /* Fla
c4c0: 67 73 20 70 61 73 73 65 64 20 74 6f 20 4f 73 4f  gs passed to OsO
c4d0: 70 65 6e 28 29 20 2a 2f 0a 0a 20 20 61 73 73 65  pen() */..  asse
c4e0: 72 74 28 20 7a 57 61 6c 4e 61 6d 65 20 26 26 20  rt( zWalName && 
c4f0: 7a 57 61 6c 4e 61 6d 65 5b 30 5d 20 29 3b 0a 20  zWalName[0] );. 
c500: 20 61 73 73 65 72 74 28 20 70 44 62 46 64 20 29   assert( pDbFd )
c510: 3b 0a 0a 20 20 2f 2a 20 49 6e 20 74 68 65 20 61  ;..  /* In the a
c520: 6d 61 6c 67 61 6d 61 74 69 6f 6e 2c 20 74 68 65  malgamation, the
c530: 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e 64 20 6f   os_unix.c and o
c540: 73 5f 77 69 6e 2e 63 20 73 6f 75 72 63 65 20 66  s_win.c source f
c550: 69 6c 65 73 20 63 6f 6d 65 20 62 65 66 6f 72 65  iles come before
c560: 0a 20 20 2a 2a 20 74 68 69 73 20 73 6f 75 72 63  .  ** this sourc
c570: 65 20 66 69 6c 65 2e 20 20 56 65 72 69 66 79 20  e file.  Verify 
c580: 74 68 61 74 20 74 68 65 20 23 64 65 66 69 6e 65  that the #define
c590: 73 20 6f 66 20 74 68 65 20 6c 6f 63 6b 69 6e 67  s of the locking
c5a0: 20 62 79 74 65 20 6f 66 66 73 65 74 73 0a 20 20   byte offsets.  
c5b0: 2a 2a 20 69 6e 20 6f 73 5f 75 6e 69 78 2e 63 20  ** in os_unix.c 
c5c0: 61 6e 64 20 6f 73 5f 77 69 6e 2e 63 20 61 67 72  and os_win.c agr
c5d0: 65 65 20 77 69 74 68 20 74 68 65 20 57 41 4c 49  ee with the WALI
c5e0: 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54  NDEX_LOCK_OFFSET
c5f0: 20 76 61 6c 75 65 2e 0a 20 20 2a 2f 0a 23 69 66   value..  */.#if
c600: 64 65 66 20 57 49 4e 5f 53 48 4d 5f 42 41 53 45  def WIN_SHM_BASE
c610: 0a 20 20 61 73 73 65 72 74 28 20 57 49 4e 5f 53  .  assert( WIN_S
c620: 48 4d 5f 42 41 53 45 3d 3d 57 41 4c 49 4e 44 45  HM_BASE==WALINDE
c630: 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b  X_LOCK_OFFSET );
c640: 0a 23 65 6e 64 69 66 0a 23 69 66 64 65 66 20 55  .#endif.#ifdef U
c650: 4e 49 58 5f 53 48 4d 5f 42 41 53 45 0a 20 20 61  NIX_SHM_BASE.  a
c660: 73 73 65 72 74 28 20 55 4e 49 58 5f 53 48 4d 5f  ssert( UNIX_SHM_
c670: 42 41 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c  BASE==WALINDEX_L
c680: 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65  OCK_OFFSET );.#e
c690: 6e 64 69 66 0a 0a 0a 20 20 2f 2a 20 41 6c 6c 6f  ndif...  /* Allo
c6a0: 63 61 74 65 20 61 6e 20 69 6e 73 74 61 6e 63 65  cate an instance
c6b0: 20 6f 66 20 73 74 72 75 63 74 20 57 61 6c 20 74   of struct Wal t
c6c0: 6f 20 72 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 2a  o return. */.  *
c6d0: 70 70 57 61 6c 20 3d 20 30 3b 0a 20 20 70 52 65  ppWal = 0;.  pRe
c6e0: 74 20 3d 20 28 57 61 6c 2a 29 73 71 6c 69 74 65  t = (Wal*)sqlite
c6f0: 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65  3MallocZero(size
c700: 6f 66 28 57 61 6c 29 20 2b 20 70 56 66 73 2d 3e  of(Wal) + pVfs->
c710: 73 7a 4f 73 46 69 6c 65 29 3b 0a 20 20 69 66 28  szOsFile);.  if(
c720: 20 21 70 52 65 74 20 29 7b 0a 20 20 20 20 72 65   !pRet ){.    re
c730: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
c740: 4d 3b 0a 20 20 7d 0a 0a 20 20 70 52 65 74 2d 3e  M;.  }..  pRet->
c750: 70 56 66 73 20 3d 20 70 56 66 73 3b 0a 20 20 70  pVfs = pVfs;.  p
c760: 52 65 74 2d 3e 70 57 61 6c 46 64 20 3d 20 28 73  Ret->pWalFd = (s
c770: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 29 26 70  qlite3_file *)&p
c780: 52 65 74 5b 31 5d 3b 0a 20 20 70 52 65 74 2d 3e  Ret[1];.  pRet->
c790: 70 44 62 46 64 20 3d 20 70 44 62 46 64 3b 0a 20  pDbFd = pDbFd;. 
c7a0: 20 70 52 65 74 2d 3e 72 65 61 64 4c 6f 63 6b 20   pRet->readLock 
c7b0: 3d 20 2d 31 3b 0a 20 20 70 52 65 74 2d 3e 6d 78  = -1;.  pRet->mx
c7c0: 57 61 6c 53 69 7a 65 20 3d 20 6d 78 57 61 6c 53  WalSize = mxWalS
c7d0: 69 7a 65 3b 0a 20 20 70 52 65 74 2d 3e 7a 57 61  ize;.  pRet->zWa
c7e0: 6c 4e 61 6d 65 20 3d 20 7a 57 61 6c 4e 61 6d 65  lName = zWalName
c7f0: 3b 0a 20 20 70 52 65 74 2d 3e 73 79 6e 63 48 65  ;.  pRet->syncHe
c800: 61 64 65 72 20 3d 20 31 3b 0a 20 20 70 52 65 74  ader = 1;.  pRet
c810: 2d 3e 70 61 64 54 6f 53 65 63 74 6f 72 42 6f 75  ->padToSectorBou
c820: 6e 64 61 72 79 20 3d 20 31 3b 0a 20 20 70 52 65  ndary = 1;.  pRe
c830: 74 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  t->exclusiveMode
c840: 20 3d 20 28 62 4e 6f 53 68 6d 20 3f 20 57 41 4c   = (bNoShm ? WAL
c850: 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45  _HEAPMEMORY_MODE
c860: 3a 20 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44  : WAL_NORMAL_MOD
c870: 45 29 3b 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 66  E);..  /* Open f
c880: 69 6c 65 20 68 61 6e 64 6c 65 20 6f 6e 20 74 68  ile handle on th
c890: 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f  e write-ahead lo
c8a0: 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 66 6c 61  g file. */.  fla
c8b0: 67 73 20 3d 20 28 53 51 4c 49 54 45 5f 4f 50 45  gs = (SQLITE_OPE
c8c0: 4e 5f 52 45 41 44 57 52 49 54 45 7c 53 51 4c 49  N_READWRITE|SQLI
c8d0: 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54 45 7c 53  TE_OPEN_CREATE|S
c8e0: 51 4c 49 54 45 5f 4f 50 45 4e 5f 57 41 4c 29 3b  QLITE_OPEN_WAL);
c8f0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  .  rc = sqlite3O
c900: 73 4f 70 65 6e 28 70 56 66 73 2c 20 7a 57 61 6c  sOpen(pVfs, zWal
c910: 4e 61 6d 65 2c 20 70 52 65 74 2d 3e 70 57 61 6c  Name, pRet->pWal
c920: 46 64 2c 20 66 6c 61 67 73 2c 20 26 66 6c 61 67  Fd, flags, &flag
c930: 73 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  s);.  if( rc==SQ
c940: 4c 49 54 45 5f 4f 4b 20 26 26 20 66 6c 61 67 73  LITE_OK && flags
c950: 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41  &SQLITE_OPEN_REA
c960: 44 4f 4e 4c 59 20 29 7b 0a 20 20 20 20 70 52 65  DONLY ){.    pRe
c970: 74 2d 3e 72 65 61 64 4f 6e 6c 79 20 3d 20 57 41  t->readOnly = WA
c980: 4c 5f 52 44 4f 4e 4c 59 3b 0a 20 20 7d 0a 0a 20  L_RDONLY;.  }.. 
c990: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
c9a0: 4f 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49 6e 64  OK ){.    walInd
c9b0: 65 78 43 6c 6f 73 65 28 70 52 65 74 2c 20 30 29  exClose(pRet, 0)
c9c0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43  ;.    sqlite3OsC
c9d0: 6c 6f 73 65 28 70 52 65 74 2d 3e 70 57 61 6c 46  lose(pRet->pWalF
c9e0: 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  d);.    sqlite3_
c9f0: 66 72 65 65 28 70 52 65 74 29 3b 0a 20 20 7d 65  free(pRet);.  }e
ca00: 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 69 44 43  lse{.    int iDC
ca10: 20 3d 20 73 71 6c 69 74 65 33 4f 73 44 65 76 69   = sqlite3OsDevi
ca20: 63 65 43 68 61 72 61 63 74 65 72 69 73 74 69 63  ceCharacteristic
ca30: 73 28 70 44 62 46 64 29 3b 0a 20 20 20 20 69 66  s(pDbFd);.    if
ca40: 28 20 69 44 43 20 26 20 53 51 4c 49 54 45 5f 49  ( iDC & SQLITE_I
ca50: 4f 43 41 50 5f 53 45 51 55 45 4e 54 49 41 4c 20  OCAP_SEQUENTIAL 
ca60: 29 7b 20 70 52 65 74 2d 3e 73 79 6e 63 48 65 61  ){ pRet->syncHea
ca70: 64 65 72 20 3d 20 30 3b 20 7d 0a 20 20 20 20 69  der = 0; }.    i
ca80: 66 28 20 69 44 43 20 26 20 53 51 4c 49 54 45 5f  f( iDC & SQLITE_
ca90: 49 4f 43 41 50 5f 50 4f 57 45 52 53 41 46 45 5f  IOCAP_POWERSAFE_
caa0: 4f 56 45 52 57 52 49 54 45 20 29 7b 0a 20 20 20  OVERWRITE ){.   
cab0: 20 20 20 70 52 65 74 2d 3e 70 61 64 54 6f 53 65     pRet->padToSe
cac0: 63 74 6f 72 42 6f 75 6e 64 61 72 79 20 3d 20 30  ctorBoundary = 0
cad0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 70 57  ;.    }.    *ppW
cae0: 61 6c 20 3d 20 70 52 65 74 3b 0a 20 20 20 20 57  al = pRet;.    W
caf0: 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 64 3a  ALTRACE(("WAL%d:
cb00: 20 6f 70 65 6e 65 64 5c 6e 22 2c 20 70 52 65 74   opened\n", pRet
cb10: 29 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ));.  }.  return
cb20: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68   rc;.}../*.** Ch
cb30: 61 6e 67 65 20 74 68 65 20 73 69 7a 65 20 74 6f  ange the size to
cb40: 20 77 68 69 63 68 20 74 68 65 20 57 41 4c 20 66   which the WAL f
cb50: 69 6c 65 20 69 73 20 74 72 75 63 61 74 65 64 20  ile is trucated 
cb60: 6f 6e 20 65 61 63 68 20 72 65 73 65 74 2e 0a 2a  on each reset..*
cb70: 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61  /.void sqlite3Wa
cb80: 6c 4c 69 6d 69 74 28 57 61 6c 20 2a 70 57 61 6c  lLimit(Wal *pWal
cb90: 2c 20 69 36 34 20 69 4c 69 6d 69 74 29 7b 0a 20  , i64 iLimit){. 
cba0: 20 69 66 28 20 70 57 61 6c 20 29 20 70 57 61 6c   if( pWal ) pWal
cbb0: 2d 3e 6d 78 57 61 6c 53 69 7a 65 20 3d 20 69 4c  ->mxWalSize = iL
cbc0: 69 6d 69 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46  imit;.}../*.** F
cbd0: 69 6e 64 20 74 68 65 20 73 6d 61 6c 6c 65 73 74  ind the smallest
cbe0: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 75 74   page number out
cbf0: 20 6f 66 20 61 6c 6c 20 70 61 67 65 73 20 68 65   of all pages he
cc00: 6c 64 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68  ld in the WAL th
cc10: 61 74 0a 2a 2a 20 68 61 73 20 6e 6f 74 20 62 65  at.** has not be
cc20: 65 6e 20 72 65 74 75 72 6e 65 64 20 62 79 20 61  en returned by a
cc30: 6e 79 20 70 72 69 6f 72 20 69 6e 76 6f 63 61 74  ny prior invocat
cc40: 69 6f 6e 20 6f 66 20 74 68 69 73 20 6d 65 74 68  ion of this meth
cc50: 6f 64 20 6f 6e 20 74 68 65 0a 2a 2a 20 73 61 6d  od on the.** sam
cc60: 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62  e WalIterator ob
cc70: 6a 65 63 74 2e 20 20 20 57 72 69 74 65 20 69 6e  ject.   Write in
cc80: 74 6f 20 2a 70 69 46 72 61 6d 65 20 74 68 65 20  to *piFrame the 
cc90: 66 72 61 6d 65 20 69 6e 64 65 78 20 77 68 65 72  frame index wher
cca0: 65 0a 2a 2a 20 74 68 61 74 20 70 61 67 65 20 77  e.** that page w
ccb0: 61 73 20 6c 61 73 74 20 77 72 69 74 74 65 6e 20  as last written 
ccc0: 69 6e 74 6f 20 74 68 65 20 57 41 4c 2e 20 20 57  into the WAL.  W
ccd0: 72 69 74 65 20 69 6e 74 6f 20 2a 70 69 50 61 67  rite into *piPag
cce0: 65 20 74 68 65 20 70 61 67 65 0a 2a 2a 20 6e 75  e the page.** nu
ccf0: 6d 62 65 72 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75  mber..**.** Retu
cd00: 72 6e 20 30 20 6f 6e 20 73 75 63 63 65 73 73 2e  rn 0 on success.
cd10: 20 20 49 66 20 74 68 65 72 65 20 61 72 65 20 6e    If there are n
cd20: 6f 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 57  o pages in the W
cd30: 41 4c 20 77 69 74 68 20 61 20 70 61 67 65 0a 2a  AL with a page.*
cd40: 2a 20 6e 75 6d 62 65 72 20 6c 61 72 67 65 72 20  * number larger 
cd50: 74 68 61 6e 20 2a 70 69 50 61 67 65 2c 20 74 68  than *piPage, th
cd60: 65 6e 20 72 65 74 75 72 6e 20 31 2e 0a 2a 2f 0a  en return 1..*/.
cd70: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 74  static int walIt
cd80: 65 72 61 74 6f 72 4e 65 78 74 28 0a 20 20 57 61  eratorNext(.  Wa
cd90: 6c 49 74 65 72 61 74 6f 72 20 2a 70 2c 20 20 20  lIterator *p,   
cda0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
cdb0: 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 75 33 32  terator */.  u32
cdc0: 20 2a 70 69 50 61 67 65 2c 20 20 20 20 20 20 20   *piPage,       
cdd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
cde0: 54 3a 20 54 68 65 20 70 61 67 65 20 6e 75 6d 62  T: The page numb
cdf0: 65 72 20 6f 66 20 74 68 65 20 6e 65 78 74 20 70  er of the next p
ce00: 61 67 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69  age */.  u32 *pi
ce10: 46 72 61 6d 65 20 20 20 20 20 20 20 20 20 20 20  Frame           
ce20: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 57         /* OUT: W
ce30: 61 6c 20 66 72 61 6d 65 20 69 6e 64 65 78 20 6f  al frame index o
ce40: 66 20 6e 65 78 74 20 70 61 67 65 20 2a 2f 0a 29  f next page */.)
ce50: 7b 0a 20 20 75 33 32 20 69 4d 69 6e 3b 20 20 20  {.  u32 iMin;   
ce60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ce70: 20 20 2f 2a 20 52 65 73 75 6c 74 20 70 67 6e 6f    /* Result pgno
ce80: 20 6d 75 73 74 20 62 65 20 67 72 65 61 74 65 72   must be greater
ce90: 20 74 68 61 6e 20 69 4d 69 6e 20 2a 2f 0a 20 20   than iMin */.  
cea0: 75 33 32 20 69 52 65 74 20 3d 20 30 78 46 46 46  u32 iRet = 0xFFF
ceb0: 46 46 46 46 46 3b 20 20 20 20 20 20 20 20 2f 2a  FFFFF;        /*
cec0: 20 30 78 66 66 66 66 66 66 66 66 20 69 73 20 6e   0xffffffff is n
ced0: 65 76 65 72 20 61 20 76 61 6c 69 64 20 70 61 67  ever a valid pag
cee0: 65 20 6e 75 6d 62 65 72 20 2a 2f 0a 20 20 69 6e  e number */.  in
cef0: 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20  t i;            
cf00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
cf10: 6f 72 20 6c 6f 6f 70 69 6e 67 20 74 68 72 6f 75  or looping throu
cf20: 67 68 20 73 65 67 6d 65 6e 74 73 20 2a 2f 0a 0a  gh segments */..
cf30: 20 20 69 4d 69 6e 20 3d 20 70 2d 3e 69 50 72 69    iMin = p->iPri
cf40: 6f 72 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4d  or;.  assert( iM
cf50: 69 6e 3c 30 78 66 66 66 66 66 66 66 66 20 29 3b  in<0xffffffff );
cf60: 0a 20 20 66 6f 72 28 69 3d 70 2d 3e 6e 53 65 67  .  for(i=p->nSeg
cf70: 6d 65 6e 74 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d  ment-1; i>=0; i-
cf80: 2d 29 7b 0a 20 20 20 20 73 74 72 75 63 74 20 57  -){.    struct W
cf90: 61 6c 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 6d  alSegment *pSegm
cfa0: 65 6e 74 20 3d 20 26 70 2d 3e 61 53 65 67 6d 65  ent = &p->aSegme
cfb0: 6e 74 5b 69 5d 3b 0a 20 20 20 20 77 68 69 6c 65  nt[i];.    while
cfc0: 28 20 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78  ( pSegment->iNex
cfd0: 74 3c 70 53 65 67 6d 65 6e 74 2d 3e 6e 45 6e 74  t<pSegment->nEnt
cfe0: 72 79 20 29 7b 0a 20 20 20 20 20 20 75 33 32 20  ry ){.      u32 
cff0: 69 50 67 20 3d 20 70 53 65 67 6d 65 6e 74 2d 3e  iPg = pSegment->
d000: 61 50 67 6e 6f 5b 70 53 65 67 6d 65 6e 74 2d 3e  aPgno[pSegment->
d010: 61 49 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d  aIndex[pSegment-
d020: 3e 69 4e 65 78 74 5d 5d 3b 0a 20 20 20 20 20 20  >iNext]];.      
d030: 69 66 28 20 69 50 67 3e 69 4d 69 6e 20 29 7b 0a  if( iPg>iMin ){.
d040: 20 20 20 20 20 20 20 20 69 66 28 20 69 50 67 3c          if( iPg<
d050: 69 52 65 74 20 29 7b 0a 20 20 20 20 20 20 20 20  iRet ){.        
d060: 20 20 69 52 65 74 20 3d 20 69 50 67 3b 0a 20 20    iRet = iPg;.  
d070: 20 20 20 20 20 20 20 20 2a 70 69 46 72 61 6d 65          *piFrame
d080: 20 3d 20 70 53 65 67 6d 65 6e 74 2d 3e 69 5a 65   = pSegment->iZe
d090: 72 6f 20 2b 20 70 53 65 67 6d 65 6e 74 2d 3e 61  ro + pSegment->a
d0a0: 49 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d 3e  Index[pSegment->
d0b0: 69 4e 65 78 74 5d 3b 0a 20 20 20 20 20 20 20 20  iNext];.        
d0c0: 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  }.        break;
d0d0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70  .      }.      p
d0e0: 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 2b 2b  Segment->iNext++
d0f0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a  ;.    }.  }..  *
d100: 70 69 50 61 67 65 20 3d 20 70 2d 3e 69 50 72 69  piPage = p->iPri
d110: 6f 72 20 3d 20 69 52 65 74 3b 0a 20 20 72 65 74  or = iRet;.  ret
d120: 75 72 6e 20 28 69 52 65 74 3d 3d 30 78 46 46 46  urn (iRet==0xFFF
d130: 46 46 46 46 46 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  FFFFF);.}../*.**
d140: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d   This function m
d150: 65 72 67 65 73 20 74 77 6f 20 73 6f 72 74 65 64  erges two sorted
d160: 20 6c 69 73 74 73 20 69 6e 74 6f 20 61 20 73 69   lists into a si
d170: 6e 67 6c 65 20 73 6f 72 74 65 64 20 6c 69 73 74  ngle sorted list
d180: 2e 0a 2a 2a 0a 2a 2a 20 61 4c 65 66 74 5b 5d 20  ..**.** aLeft[] 
d190: 61 6e 64 20 61 52 69 67 68 74 5b 5d 20 61 72 65  and aRight[] are
d1a0: 20 61 72 72 61 79 73 20 6f 66 20 69 6e 64 69 63   arrays of indic
d1b0: 65 73 2e 20 20 54 68 65 20 73 6f 72 74 20 6b 65  es.  The sort ke
d1c0: 79 20 69 73 0a 2a 2a 20 61 43 6f 6e 74 65 6e 74  y is.** aContent
d1d0: 5b 61 4c 65 66 74 5b 5d 5d 20 61 6e 64 20 61 43  [aLeft[]] and aC
d1e0: 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b 5d 5d  ontent[aRight[]]
d1f0: 2e 20 20 55 70 6f 6e 20 65 6e 74 72 79 2c 20 74  .  Upon entry, t
d200: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20  he following.** 
d210: 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 66 6f  is guaranteed fo
d220: 72 20 61 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a 2a 2a  r all J<K:.**.**
d230: 20 20 20 20 20 20 20 20 61 43 6f 6e 74 65 6e 74          aContent
d240: 5b 61 4c 65 66 74 5b 4a 5d 5d 20 3c 20 61 43 6f  [aLeft[J]] < aCo
d250: 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 4b 5d 5d 0a  ntent[aLeft[K]].
d260: 2a 2a 20 20 20 20 20 20 20 20 61 43 6f 6e 74 65  **        aConte
d270: 6e 74 5b 61 52 69 67 68 74 5b 4a 5d 5d 20 3c 20  nt[aRight[J]] < 
d280: 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b  aContent[aRight[
d290: 4b 5d 5d 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72  K]].**.** This r
d2a0: 6f 75 74 69 6e 65 20 6f 76 65 72 77 72 69 74 65  outine overwrite
d2b0: 73 20 61 52 69 67 68 74 5b 5d 20 77 69 74 68 20  s aRight[] with 
d2c0: 61 20 6e 65 77 20 28 70 72 6f 62 61 62 6c 79 20  a new (probably 
d2d0: 6c 6f 6e 67 65 72 29 20 73 65 71 75 65 6e 63 65  longer) sequence
d2e0: 0a 2a 2a 20 6f 66 20 69 6e 64 69 63 65 73 20 73  .** of indices s
d2f0: 75 63 68 20 74 68 61 74 20 74 68 65 20 61 52 69  uch that the aRi
d300: 67 68 74 5b 5d 20 63 6f 6e 74 61 69 6e 73 20 65  ght[] contains e
d310: 76 65 72 79 20 69 6e 64 65 78 20 74 68 61 74 20  very index that 
d320: 61 70 70 65 61 72 73 20 69 6e 0a 2a 2a 20 65 69  appears in.** ei
d330: 74 68 65 72 20 61 4c 65 66 74 5b 5d 20 6f 72 20  ther aLeft[] or 
d340: 74 68 65 20 6f 6c 64 20 61 52 69 67 68 74 5b 5d  the old aRight[]
d350: 20 61 6e 64 20 73 75 63 68 20 74 68 61 74 20 74   and such that t
d360: 68 65 20 73 65 63 6f 6e 64 20 63 6f 6e 64 69 74  he second condit
d370: 69 6f 6e 0a 2a 2a 20 61 62 6f 76 65 20 69 73 20  ion.** above is 
d380: 73 74 69 6c 6c 20 6d 65 74 2e 0a 2a 2a 0a 2a 2a  still met..**.**
d390: 20 54 68 65 20 61 43 6f 6e 74 65 6e 74 5b 61 4c   The aContent[aL
d3a0: 65 66 74 5b 58 5d 5d 20 76 61 6c 75 65 73 20 77  eft[X]] values w
d3b0: 69 6c 6c 20 62 65 20 75 6e 69 71 75 65 20 66 6f  ill be unique fo
d3c0: 72 20 61 6c 6c 20 58 2e 20 20 41 6e 64 20 74 68  r all X.  And th
d3d0: 65 0a 2a 2a 20 61 43 6f 6e 74 65 6e 74 5b 61 52  e.** aContent[aR
d3e0: 69 67 68 74 5b 58 5d 5d 20 76 61 6c 75 65 73 20  ight[X]] values 
d3f0: 77 69 6c 6c 20 62 65 20 75 6e 69 71 75 65 20 74  will be unique t
d400: 6f 6f 2e 20 20 42 75 74 20 74 68 65 72 65 20 6d  oo.  But there m
d410: 69 67 68 74 20 62 65 0a 2a 2a 20 6f 6e 65 20 6f  ight be.** one o
d420: 72 20 6d 6f 72 65 20 63 6f 6d 62 69 6e 61 74 69  r more combinati
d430: 6f 6e 73 20 6f 66 20 58 20 61 6e 64 20 59 20 73  ons of X and Y s
d440: 75 63 68 20 74 68 61 74 0a 2a 2a 0a 2a 2a 20 20  uch that.**.**  
d450: 20 20 20 20 61 4c 65 66 74 5b 58 5d 21 3d 61 52      aLeft[X]!=aR
d460: 69 67 68 74 5b 59 5d 20 20 26 26 20 20 61 43 6f  ight[Y]  &&  aCo
d470: 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 58 5d 5d 20  ntent[aLeft[X]] 
d480: 3d 3d 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67  == aContent[aRig
d490: 68 74 5b 59 5d 5d 0a 2a 2a 0a 2a 2a 20 57 68 65  ht[Y]].**.** Whe
d4a0: 6e 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c 20  n that happens, 
d4b0: 6f 6d 69 74 20 74 68 65 20 61 4c 65 66 74 5b 58  omit the aLeft[X
d4c0: 5d 20 61 6e 64 20 75 73 65 20 74 68 65 20 61 52  ] and use the aR
d4d0: 69 67 68 74 5b 59 5d 20 69 6e 64 65 78 2e 0a 2a  ight[Y] index..*
d4e0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61  /.static void wa
d4f0: 6c 4d 65 72 67 65 28 0a 20 20 63 6f 6e 73 74 20  lMerge(.  const 
d500: 75 33 32 20 2a 61 43 6f 6e 74 65 6e 74 2c 20 20  u32 *aContent,  
d510: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
d520: 65 73 20 69 6e 20 77 61 6c 20 2d 20 6b 65 79 73  es in wal - keys
d530: 20 66 6f 72 20 74 68 65 20 73 6f 72 74 20 2a 2f   for the sort */
d540: 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 65 66  .  ht_slot *aLef
d550: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
d560: 20 20 20 2f 2a 20 49 4e 3a 20 4c 65 66 74 20 68     /* IN: Left h
d570: 61 6e 64 20 69 6e 70 75 74 20 6c 69 73 74 20 2a  and input list *
d580: 2f 0a 20 20 69 6e 74 20 6e 4c 65 66 74 2c 20 20  /.  int nLeft,  
d590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d5a0: 20 20 20 20 2f 2a 20 49 4e 3a 20 45 6c 65 6d 65      /* IN: Eleme
d5b0: 6e 74 73 20 69 6e 20 61 72 72 61 79 20 2a 70 61  nts in array *pa
d5c0: 4c 65 66 74 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f  Left */.  ht_slo
d5d0: 74 20 2a 2a 70 61 52 69 67 68 74 2c 20 20 20 20  t **paRight,    
d5e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f            /* IN/
d5f0: 4f 55 54 3a 20 52 69 67 68 74 20 68 61 6e 64 20  OUT: Right hand 
d600: 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20  input list */.  
d610: 69 6e 74 20 2a 70 6e 52 69 67 68 74 2c 20 20 20  int *pnRight,   
d620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d630: 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45 6c 65 6d 65  /* IN/OUT: Eleme
d640: 6e 74 73 20 69 6e 20 2a 70 61 52 69 67 68 74 20  nts in *paRight 
d650: 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 54  */.  ht_slot *aT
d660: 6d 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20  mp              
d670: 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72       /* Temporar
d680: 79 20 62 75 66 66 65 72 20 2a 2f 0a 29 7b 0a 20  y buffer */.){. 
d690: 20 69 6e 74 20 69 4c 65 66 74 20 3d 20 30 3b 20   int iLeft = 0; 
d6a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d6b0: 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65   /* Current inde
d6c0: 78 20 69 6e 20 61 4c 65 66 74 20 2a 2f 0a 20 20  x in aLeft */.  
d6d0: 69 6e 74 20 69 52 69 67 68 74 20 3d 20 30 3b 20  int iRight = 0; 
d6e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d6f0: 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65 78  /* Current index
d700: 20 69 6e 20 61 52 69 67 68 74 20 2a 2f 0a 20 20   in aRight */.  
d710: 69 6e 74 20 69 4f 75 74 20 3d 20 30 3b 20 20 20  int iOut = 0;   
d720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d730: 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65 78  /* Current index
d740: 20 69 6e 20 6f 75 74 70 75 74 20 62 75 66 66 65   in output buffe
d750: 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 69 67 68  r */.  int nRigh
d760: 74 20 3d 20 2a 70 6e 52 69 67 68 74 3b 0a 20 20  t = *pnRight;.  
d770: 68 74 5f 73 6c 6f 74 20 2a 61 52 69 67 68 74 20  ht_slot *aRight 
d780: 3d 20 2a 70 61 52 69 67 68 74 3b 0a 0a 20 20 61  = *paRight;..  a
d790: 73 73 65 72 74 28 20 6e 4c 65 66 74 3e 30 20 26  ssert( nLeft>0 &
d7a0: 26 20 6e 52 69 67 68 74 3e 30 20 29 3b 0a 20 20  & nRight>0 );.  
d7b0: 77 68 69 6c 65 28 20 69 52 69 67 68 74 3c 6e 52  while( iRight<nR
d7c0: 69 67 68 74 20 7c 7c 20 69 4c 65 66 74 3c 6e 4c  ight || iLeft<nL
d7d0: 65 66 74 20 29 7b 0a 20 20 20 20 68 74 5f 73 6c  eft ){.    ht_sl
d7e0: 6f 74 20 6c 6f 67 70 61 67 65 3b 0a 20 20 20 20  ot logpage;.    
d7f0: 50 67 6e 6f 20 64 62 70 61 67 65 3b 0a 0a 20 20  Pgno dbpage;..  
d800: 20 20 69 66 28 20 28 69 4c 65 66 74 3c 6e 4c 65    if( (iLeft<nLe
d810: 66 74 29 20 0a 20 20 20 20 20 26 26 20 28 69 52  ft) .     && (iR
d820: 69 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c 20  ight>=nRight || 
d830: 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69  aContent[aLeft[i
d840: 4c 65 66 74 5d 5d 3c 61 43 6f 6e 74 65 6e 74 5b  Left]]<aContent[
d850: 61 52 69 67 68 74 5b 69 52 69 67 68 74 5d 5d 29  aRight[iRight]])
d860: 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 6c 6f  .    ){.      lo
d870: 67 70 61 67 65 20 3d 20 61 4c 65 66 74 5b 69 4c  gpage = aLeft[iL
d880: 65 66 74 2b 2b 5d 3b 0a 20 20 20 20 7d 65 6c 73  eft++];.    }els
d890: 65 7b 0a 20 20 20 20 20 20 6c 6f 67 70 61 67 65  e{.      logpage
d8a0: 20 3d 20 61 52 69 67 68 74 5b 69 52 69 67 68 74   = aRight[iRight
d8b0: 2b 2b 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64  ++];.    }.    d
d8c0: 62 70 61 67 65 20 3d 20 61 43 6f 6e 74 65 6e 74  bpage = aContent
d8d0: 5b 6c 6f 67 70 61 67 65 5d 3b 0a 0a 20 20 20 20  [logpage];..    
d8e0: 61 54 6d 70 5b 69 4f 75 74 2b 2b 5d 20 3d 20 6c  aTmp[iOut++] = l
d8f0: 6f 67 70 61 67 65 3b 0a 20 20 20 20 69 66 28 20  ogpage;.    if( 
d900: 69 4c 65 66 74 3c 6e 4c 65 66 74 20 26 26 20 61  iLeft<nLeft && a
d910: 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69 4c  Content[aLeft[iL
d920: 65 66 74 5d 5d 3d 3d 64 62 70 61 67 65 20 29 20  eft]]==dbpage ) 
d930: 69 4c 65 66 74 2b 2b 3b 0a 0a 20 20 20 20 61 73  iLeft++;..    as
d940: 73 65 72 74 28 20 69 4c 65 66 74 3e 3d 6e 4c 65  sert( iLeft>=nLe
d950: 66 74 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61  ft || aContent[a
d960: 4c 65 66 74 5b 69 4c 65 66 74 5d 5d 3e 64 62 70  Left[iLeft]]>dbp
d970: 61 67 65 20 29 3b 0a 20 20 20 20 61 73 73 65 72  age );.    asser
d980: 74 28 20 69 52 69 67 68 74 3e 3d 6e 52 69 67 68  t( iRight>=nRigh
d990: 74 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61 52  t || aContent[aR
d9a0: 69 67 68 74 5b 69 52 69 67 68 74 5d 5d 3e 64 62  ight[iRight]]>db
d9b0: 70 61 67 65 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a  page );.  }..  *
d9c0: 70 61 52 69 67 68 74 20 3d 20 61 4c 65 66 74 3b  paRight = aLeft;
d9d0: 0a 20 20 2a 70 6e 52 69 67 68 74 20 3d 20 69 4f  .  *pnRight = iO
d9e0: 75 74 3b 0a 20 20 6d 65 6d 63 70 79 28 61 4c 65  ut;.  memcpy(aLe
d9f0: 66 74 2c 20 61 54 6d 70 2c 20 73 69 7a 65 6f 66  ft, aTmp, sizeof
da00: 28 61 54 6d 70 5b 30 5d 29 2a 69 4f 75 74 29 3b  (aTmp[0])*iOut);
da10: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74  .}../*.** Sort t
da20: 68 65 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 6c  he elements in l
da30: 69 73 74 20 61 4c 69 73 74 20 75 73 69 6e 67 20  ist aList using 
da40: 61 43 6f 6e 74 65 6e 74 5b 5d 20 61 73 20 74 68  aContent[] as th
da50: 65 20 73 6f 72 74 20 6b 65 79 2e 0a 2a 2a 20 52  e sort key..** R
da60: 65 6d 6f 76 65 20 65 6c 65 6d 65 6e 74 73 20 77  emove elements w
da70: 69 74 68 20 64 75 70 6c 69 63 61 74 65 20 6b 65  ith duplicate ke
da80: 79 73 2c 20 70 72 65 66 65 72 72 69 6e 67 20 74  ys, preferring t
da90: 6f 20 6b 65 65 70 20 74 68 65 0a 2a 2a 20 6c 61  o keep the.** la
daa0: 72 67 65 72 20 61 4c 69 73 74 5b 5d 20 76 61 6c  rger aList[] val
dab0: 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61  ues..**.** The a
dac0: 4c 69 73 74 5b 5d 20 65 6e 74 72 69 65 73 20 61  List[] entries a
dad0: 72 65 20 69 6e 64 69 63 65 73 20 69 6e 74 6f 20  re indices into 
dae0: 61 43 6f 6e 74 65 6e 74 5b 5d 2e 20 20 54 68 65  aContent[].  The
daf0: 20 76 61 6c 75 65 73 20 69 6e 0a 2a 2a 20 61 4c   values in.** aL
db00: 69 73 74 5b 5d 20 61 72 65 20 74 6f 20 62 65 20  ist[] are to be 
db10: 73 6f 72 74 65 64 20 73 6f 20 74 68 61 74 20 66  sorted so that f
db20: 6f 72 20 61 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a 2a  or all J<K:.**.*
db30: 2a 20 20 20 20 20 20 61 43 6f 6e 74 65 6e 74 5b  *      aContent[
db40: 61 4c 69 73 74 5b 4a 5d 5d 20 3c 20 61 43 6f 6e  aList[J]] < aCon
db50: 74 65 6e 74 5b 61 4c 69 73 74 5b 4b 5d 5d 0a 2a  tent[aList[K]].*
db60: 2a 0a 2a 2a 20 46 6f 72 20 61 6e 79 20 58 20 61  *.** For any X a
db70: 6e 64 20 59 20 73 75 63 68 20 74 68 61 74 0a 2a  nd Y such that.*
db80: 2a 0a 2a 2a 20 20 20 20 20 20 61 43 6f 6e 74 65  *.**      aConte
db90: 6e 74 5b 61 4c 69 73 74 5b 58 5d 5d 20 3d 3d 20  nt[aList[X]] == 
dba0: 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 59  aContent[aList[Y
dbb0: 5d 5d 0a 2a 2a 0a 2a 2a 20 4b 65 65 70 20 74 68  ]].**.** Keep th
dbc0: 65 20 6c 61 72 67 65 72 20 6f 66 20 74 68 65 20  e larger of the 
dbd0: 74 77 6f 20 76 61 6c 75 65 73 20 61 4c 69 73 74  two values aList
dbe0: 5b 58 5d 20 61 6e 64 20 61 4c 69 73 74 5b 59 5d  [X] and aList[Y]
dbf0: 20 61 6e 64 20 64 69 73 63 61 72 64 0a 2a 2a 20   and discard.** 
dc00: 74 68 65 20 73 6d 61 6c 6c 65 72 2e 0a 2a 2f 0a  the smaller..*/.
dc10: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 4d  static void walM
dc20: 65 72 67 65 73 6f 72 74 28 0a 20 20 63 6f 6e 73  ergesort(.  cons
dc30: 74 20 75 33 32 20 2a 61 43 6f 6e 74 65 6e 74 2c  t u32 *aContent,
dc40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
dc50: 61 67 65 73 20 69 6e 20 77 61 6c 20 2a 2f 0a 20  ages in wal */. 
dc60: 20 68 74 5f 73 6c 6f 74 20 2a 61 42 75 66 66 65   ht_slot *aBuffe
dc70: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r,              
dc80: 20 2f 2a 20 42 75 66 66 65 72 20 6f 66 20 61 74   /* Buffer of at
dc90: 20 6c 65 61 73 74 20 2a 70 6e 4c 69 73 74 20 69   least *pnList i
dca0: 74 65 6d 73 20 74 6f 20 75 73 65 20 2a 2f 0a 20  tems to use */. 
dcb0: 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 69 73 74 2c   ht_slot *aList,
dcc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dcd0: 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4c 69 73 74   /* IN/OUT: List
dce0: 20 74 6f 20 73 6f 72 74 20 2a 2f 0a 20 20 69 6e   to sort */.  in
dcf0: 74 20 2a 70 6e 4c 69 73 74 20 20 20 20 20 20 20  t *pnList       
dd00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
dd10: 20 49 4e 2f 4f 55 54 3a 20 4e 75 6d 62 65 72 20   IN/OUT: Number 
dd20: 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61  of elements in a
dd30: 4c 69 73 74 5b 5d 20 2a 2f 0a 29 7b 0a 20 20 73  List[] */.){.  s
dd40: 74 72 75 63 74 20 53 75 62 6c 69 73 74 20 7b 0a  truct Sublist {.
dd50: 20 20 20 20 69 6e 74 20 6e 4c 69 73 74 3b 20 20      int nList;  
dd60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dd70: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65    /* Number of e
dd80: 6c 65 6d 65 6e 74 73 20 69 6e 20 61 4c 69 73 74  lements in aList
dd90: 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20   */.    ht_slot 
dda0: 2a 61 4c 69 73 74 3b 20 20 20 20 20 20 20 20 20  *aList;         
ddb0: 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
ddc0: 20 74 6f 20 73 75 62 2d 6c 69 73 74 20 63 6f 6e   to sub-list con
ddd0: 74 65 6e 74 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20  tent */.  };..  
dde0: 63 6f 6e 73 74 20 69 6e 74 20 6e 4c 69 73 74 20  const int nList 
ddf0: 3d 20 2a 70 6e 4c 69 73 74 3b 20 20 20 20 20 20  = *pnList;      
de00: 2f 2a 20 53 69 7a 65 20 6f 66 20 69 6e 70 75 74  /* Size of input
de10: 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e   list */.  int n
de20: 4d 65 72 67 65 20 3d 20 30 3b 20 20 20 20 20 20  Merge = 0;      
de30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
de40: 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73  mber of elements
de50: 20 69 6e 20 6c 69 73 74 20 61 4d 65 72 67 65 20   in list aMerge 
de60: 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4d  */.  ht_slot *aM
de70: 65 72 67 65 20 3d 20 30 3b 20 20 20 20 20 20 20  erge = 0;       
de80: 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 74 6f 20       /* List to 
de90: 62 65 20 6d 65 72 67 65 64 20 2a 2f 0a 20 20 69  be merged */.  i
dea0: 6e 74 20 69 4c 69 73 74 3b 20 20 20 20 20 20 20  nt iList;       
deb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
dec0: 2a 20 49 6e 64 65 78 20 69 6e 74 6f 20 69 6e 70  * Index into inp
ded0: 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74  ut list */.  int
dee0: 20 69 53 75 62 20 3d 20 30 3b 20 20 20 20 20 20   iSub = 0;      
def0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
df00: 49 6e 64 65 78 20 69 6e 74 6f 20 61 53 75 62 20  Index into aSub 
df10: 61 72 72 61 79 20 2a 2f 0a 20 20 73 74 72 75 63  array */.  struc
df20: 74 20 53 75 62 6c 69 73 74 20 61 53 75 62 5b 31  t Sublist aSub[1
df30: 33 5d 3b 20 20 20 20 20 20 20 20 2f 2a 20 41 72  3];        /* Ar
df40: 72 61 79 20 6f 66 20 73 75 62 2d 6c 69 73 74 73  ray of sub-lists
df50: 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65 74 28 61 53   */..  memset(aS
df60: 75 62 2c 20 30 2c 20 73 69 7a 65 6f 66 28 61 53  ub, 0, sizeof(aS
df70: 75 62 29 29 3b 0a 20 20 61 73 73 65 72 74 28 20  ub));.  assert( 
df80: 6e 4c 69 73 74 3c 3d 48 41 53 48 54 41 42 4c 45  nList<=HASHTABLE
df90: 5f 4e 50 41 47 45 20 26 26 20 6e 4c 69 73 74 3e  _NPAGE && nList>
dfa0: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 48  0 );.  assert( H
dfb0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3d 3d  ASHTABLE_NPAGE==
dfc0: 28 31 3c 3c 28 41 72 72 61 79 53 69 7a 65 28 61  (1<<(ArraySize(a
dfd0: 53 75 62 29 2d 31 29 29 20 29 3b 0a 0a 20 20 66  Sub)-1)) );..  f
dfe0: 6f 72 28 69 4c 69 73 74 3d 30 3b 20 69 4c 69 73  or(iList=0; iLis
dff0: 74 3c 6e 4c 69 73 74 3b 20 69 4c 69 73 74 2b 2b  t<nList; iList++
e000: 29 7b 0a 20 20 20 20 6e 4d 65 72 67 65 20 3d 20  ){.    nMerge = 
e010: 31 3b 0a 20 20 20 20 61 4d 65 72 67 65 20 3d 20  1;.    aMerge = 
e020: 26 61 4c 69 73 74 5b 69 4c 69 73 74 5d 3b 0a 20  &aList[iList];. 
e030: 20 20 20 66 6f 72 28 69 53 75 62 3d 30 3b 20 69     for(iSub=0; i
e040: 4c 69 73 74 20 26 20 28 31 3c 3c 69 53 75 62 29  List & (1<<iSub)
e050: 3b 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20 20  ; iSub++){.     
e060: 20 73 74 72 75 63 74 20 53 75 62 6c 69 73 74 20   struct Sublist 
e070: 2a 70 20 3d 20 26 61 53 75 62 5b 69 53 75 62 5d  *p = &aSub[iSub]
e080: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
e090: 70 2d 3e 61 4c 69 73 74 20 26 26 20 70 2d 3e 6e  p->aList && p->n
e0a0: 4c 69 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29 20  List<=(1<<iSub) 
e0b0: 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
e0c0: 20 70 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69 73   p->aList==&aLis
e0d0: 74 5b 69 4c 69 73 74 26 7e 28 28 32 3c 3c 69 53  t[iList&~((2<<iS
e0e0: 75 62 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20 20  ub)-1)] );.     
e0f0: 20 77 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74 65   walMerge(aConte
e100: 6e 74 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70 2d  nt, p->aList, p-
e110: 3e 6e 4c 69 73 74 2c 20 26 61 4d 65 72 67 65 2c  >nList, &aMerge,
e120: 20 26 6e 4d 65 72 67 65 2c 20 61 42 75 66 66 65   &nMerge, aBuffe
e130: 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 53  r);.    }.    aS
e140: 75 62 5b 69 53 75 62 5d 2e 61 4c 69 73 74 20 3d  ub[iSub].aList =
e150: 20 61 4d 65 72 67 65 3b 0a 20 20 20 20 61 53 75   aMerge;.    aSu
e160: 62 5b 69 53 75 62 5d 2e 6e 4c 69 73 74 20 3d 20  b[iSub].nList = 
e170: 6e 4d 65 72 67 65 3b 0a 20 20 7d 0a 0a 20 20 66  nMerge;.  }..  f
e180: 6f 72 28 69 53 75 62 2b 2b 3b 20 69 53 75 62 3c  or(iSub++; iSub<
e190: 41 72 72 61 79 53 69 7a 65 28 61 53 75 62 29 3b  ArraySize(aSub);
e1a0: 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20 69 66   iSub++){.    if
e1b0: 28 20 6e 4c 69 73 74 20 26 20 28 31 3c 3c 69 53  ( nList & (1<<iS
e1c0: 75 62 29 20 29 7b 0a 20 20 20 20 20 20 73 74 72  ub) ){.      str
e1d0: 75 63 74 20 53 75 62 6c 69 73 74 20 2a 70 20 3d  uct Sublist *p =
e1e0: 20 26 61 53 75 62 5b 69 53 75 62 5d 3b 0a 20 20   &aSub[iSub];.  
e1f0: 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e      assert( p->n
e200: 4c 69 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29 20  List<=(1<<iSub) 
e210: 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  );.      assert(
e220: 20 70 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69 73   p->aList==&aLis
e230: 74 5b 6e 4c 69 73 74 26 7e 28 28 32 3c 3c 69 53  t[nList&~((2<<iS
e240: 75 62 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20 20  ub)-1)] );.     
e250: 20 77 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74 65   walMerge(aConte
e260: 6e 74 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70 2d  nt, p->aList, p-
e270: 3e 6e 4c 69 73 74 2c 20 26 61 4d 65 72 67 65 2c  >nList, &aMerge,
e280: 20 26 6e 4d 65 72 67 65 2c 20 61 42 75 66 66 65   &nMerge, aBuffe
e290: 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  r);.    }.  }.  
e2a0: 61 73 73 65 72 74 28 20 61 4d 65 72 67 65 3d 3d  assert( aMerge==
e2b0: 61 4c 69 73 74 20 29 3b 0a 20 20 2a 70 6e 4c 69  aList );.  *pnLi
e2c0: 73 74 20 3d 20 6e 4d 65 72 67 65 3b 0a 0a 23 69  st = nMerge;..#i
e2d0: 66 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55  fdef SQLITE_DEBU
e2e0: 47 0a 20 20 7b 0a 20 20 20 20 69 6e 74 20 69 3b  G.  {.    int i;
e2f0: 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c  .    for(i=1; i<
e300: 2a 70 6e 4c 69 73 74 3b 20 69 2b 2b 29 7b 0a 20  *pnList; i++){. 
e310: 20 20 20 20 20 61 73 73 65 72 74 28 20 61 43 6f       assert( aCo
e320: 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 69 5d 5d 20  ntent[aList[i]] 
e330: 3e 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74  > aContent[aList
e340: 5b 69 2d 31 5d 5d 20 29 3b 0a 20 20 20 20 7d 0a  [i-1]] );.    }.
e350: 20 20 7d 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a    }.#endif.}../*
e360: 20 0a 2a 2a 20 46 72 65 65 20 61 6e 20 69 74 65   .** Free an ite
e370: 72 61 74 6f 72 20 61 6c 6c 6f 63 61 74 65 64 20  rator allocated 
e380: 62 79 20 77 61 6c 49 74 65 72 61 74 6f 72 49 6e  by walIteratorIn
e390: 69 74 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  it()..*/.static 
e3a0: 76 6f 69 64 20 77 61 6c 49 74 65 72 61 74 6f 72  void walIterator
e3b0: 46 72 65 65 28 57 61 6c 49 74 65 72 61 74 6f 72  Free(WalIterator
e3c0: 20 2a 70 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f   *p){.  sqlite3_
e3d0: 66 72 65 65 28 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  free(p);.}../*.*
e3e0: 2a 20 43 6f 6e 73 74 72 75 63 74 20 61 20 57 61  * Construct a Wa
e3f0: 6c 49 6e 74 65 72 61 74 6f 72 20 6f 62 6a 65 63  lInterator objec
e400: 74 20 74 68 61 74 20 63 61 6e 20 62 65 20 75 73  t that can be us
e410: 65 64 20 74 6f 20 6c 6f 6f 70 20 6f 76 65 72 20  ed to loop over 
e420: 61 6c 6c 20 0a 2a 2a 20 70 61 67 65 73 20 69 6e  all .** pages in
e430: 20 74 68 65 20 57 41 4c 20 69 6e 20 61 73 63 65   the WAL in asce
e440: 6e 64 69 6e 67 20 6f 72 64 65 72 2e 20 54 68 65  nding order. The
e450: 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 68 6f 6c   caller must hol
e460: 64 20 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74  d the checkpoint
e470: 0a 2a 2a 20 6c 6f 63 6b 2e 0a 2a 2a 0a 2a 2a 20  .** lock..**.** 
e480: 4f 6e 20 73 75 63 63 65 73 73 2c 20 6d 61 6b 65  On success, make
e490: 20 2a 70 70 20 70 6f 69 6e 74 20 74 6f 20 74 68   *pp point to th
e4a0: 65 20 6e 65 77 6c 79 20 61 6c 6c 6f 63 61 74 65  e newly allocate
e4b0: 64 20 57 61 6c 49 6e 74 65 72 61 74 6f 72 20 6f  d WalInterator o
e4c0: 62 6a 65 63 74 0a 2a 2a 20 72 65 74 75 72 6e 20  bject.** return 
e4d0: 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f 74 68 65 72  SQLITE_OK. Other
e4e0: 77 69 73 65 2c 20 72 65 74 75 72 6e 20 61 6e 20  wise, return an 
e4f0: 65 72 72 6f 72 20 63 6f 64 65 2e 20 49 66 20 74  error code. If t
e500: 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72  his routine.** r
e510: 65 74 75 72 6e 73 20 61 6e 20 65 72 72 6f 72 2c  eturns an error,
e520: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 2a 70   the value of *p
e530: 70 20 69 73 20 75 6e 64 65 66 69 6e 65 64 2e 0a  p is undefined..
e540: 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 69 6e  **.** The callin
e550: 67 20 72 6f 75 74 69 6e 65 20 73 68 6f 75 6c 64  g routine should
e560: 20 69 6e 76 6f 6b 65 20 77 61 6c 49 74 65 72 61   invoke walItera
e570: 74 6f 72 46 72 65 65 28 29 20 74 6f 20 64 65 73  torFree() to des
e580: 74 72 6f 79 20 74 68 65 0a 2a 2a 20 57 61 6c 49  troy the.** WalI
e590: 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 20 77  terator object w
e5a0: 68 65 6e 20 69 74 20 68 61 73 20 66 69 6e 69 73  hen it has finis
e5b0: 68 65 64 20 77 69 74 68 20 69 74 2e 0a 2a 2f 0a  hed with it..*/.
e5c0: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 74  static int walIt
e5d0: 65 72 61 74 6f 72 49 6e 69 74 28 57 61 6c 20 2a  eratorInit(Wal *
e5e0: 70 57 61 6c 2c 20 57 61 6c 49 74 65 72 61 74 6f  pWal, WalIterato
e5f0: 72 20 2a 2a 70 70 29 7b 0a 20 20 57 61 6c 49 74  r **pp){.  WalIt
e600: 65 72 61 74 6f 72 20 2a 70 3b 20 20 20 20 20 20  erator *p;      
e610: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
e620: 74 75 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 20 20  turn value */.  
e630: 69 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20  int nSegment;   
e640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e650: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 65 67  /* Number of seg
e660: 6d 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20 2a  ments to merge *
e670: 2f 0a 20 20 75 33 32 20 69 4c 61 73 74 3b 20 20  /.  u32 iLast;  
e680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e690: 20 20 20 20 2f 2a 20 4c 61 73 74 20 66 72 61 6d      /* Last fram
e6a0: 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20 69 6e  e in log */.  in
e6b0: 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20  t nByte;        
e6c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
e6d0: 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   Number of bytes
e6e0: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a   to allocate */.
e6f0: 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
e700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e710: 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 76 61    /* Iterator va
e720: 72 69 61 62 6c 65 20 2a 2f 0a 20 20 68 74 5f 73  riable */.  ht_s
e730: 6c 6f 74 20 2a 61 54 6d 70 3b 20 20 20 20 20 20  lot *aTmp;      
e740: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
e750: 65 6d 70 20 73 70 61 63 65 20 75 73 65 64 20 62  emp space used b
e760: 79 20 6d 65 72 67 65 2d 73 6f 72 74 20 2a 2f 0a  y merge-sort */.
e770: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
e780: 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  E_OK;           
e790: 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65    /* Return Code
e7a0: 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 69 73 20 72   */..  /* This r
e7b0: 6f 75 74 69 6e 65 20 6f 6e 6c 79 20 72 75 6e 73  outine only runs
e7c0: 20 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67 20 74   while holding t
e7d0: 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 6c 6f  he checkpoint lo
e7e0: 63 6b 2e 20 41 6e 64 0a 20 20 2a 2a 20 69 74 20  ck. And.  ** it 
e7f0: 6f 6e 6c 79 20 72 75 6e 73 20 69 66 20 74 68 65  only runs if the
e800: 72 65 20 69 73 20 61 63 74 75 61 6c 6c 79 20 63  re is actually c
e810: 6f 6e 74 65 6e 74 20 69 6e 20 74 68 65 20 6c 6f  ontent in the lo
e820: 67 20 28 6d 78 46 72 61 6d 65 3e 30 29 2e 0a 20  g (mxFrame>0).. 
e830: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57   */.  assert( pW
e840: 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20 26 26 20  al->ckptLock && 
e850: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
e860: 65 3e 30 20 29 3b 0a 20 20 69 4c 61 73 74 20 3d  e>0 );.  iLast =
e870: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
e880: 6d 65 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61  me;..  /* Alloca
e890: 74 65 20 73 70 61 63 65 20 66 6f 72 20 74 68 65  te space for the
e8a0: 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a   WalIterator obj
e8b0: 65 63 74 2e 20 2a 2f 0a 20 20 6e 53 65 67 6d 65  ect. */.  nSegme
e8c0: 6e 74 20 3d 20 77 61 6c 46 72 61 6d 65 50 61 67  nt = walFramePag
e8d0: 65 28 69 4c 61 73 74 29 20 2b 20 31 3b 0a 20 20  e(iLast) + 1;.  
e8e0: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 57  nByte = sizeof(W
e8f0: 61 6c 49 74 65 72 61 74 6f 72 29 20 0a 20 20 20  alIterator) .   
e900: 20 20 20 20 20 2b 20 28 6e 53 65 67 6d 65 6e 74       + (nSegment
e910: 2d 31 29 2a 73 69 7a 65 6f 66 28 73 74 72 75 63  -1)*sizeof(struc
e920: 74 20 57 61 6c 53 65 67 6d 65 6e 74 29 0a 20 20  t WalSegment).  
e930: 20 20 20 20 20 20 2b 20 69 4c 61 73 74 2a 73 69        + iLast*si
e940: 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 3b 0a 20  zeof(ht_slot);. 
e950: 20 70 20 3d 20 28 57 61 6c 49 74 65 72 61 74 6f   p = (WalIterato
e960: 72 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  r *)sqlite3_mall
e970: 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28  oc(nByte);.  if(
e980: 20 21 70 20 29 7b 0a 20 20 20 20 72 65 74 75 72   !p ){.    retur
e990: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
e9a0: 20 20 7d 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20    }.  memset(p, 
e9b0: 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 70 2d 3e  0, nByte);.  p->
e9c0: 6e 53 65 67 6d 65 6e 74 20 3d 20 6e 53 65 67 6d  nSegment = nSegm
e9d0: 65 6e 74 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63  ent;..  /* Alloc
e9e0: 61 74 65 20 74 65 6d 70 6f 72 61 72 79 20 73 70  ate temporary sp
e9f0: 61 63 65 20 75 73 65 64 20 62 79 20 74 68 65 20  ace used by the 
ea00: 6d 65 72 67 65 2d 73 6f 72 74 20 72 6f 75 74 69  merge-sort routi
ea10: 6e 65 2e 20 54 68 69 73 20 62 6c 6f 63 6b 0a 20  ne. This block. 
ea20: 20 2a 2a 20 6f 66 20 6d 65 6d 6f 72 79 20 77 69   ** of memory wi
ea30: 6c 6c 20 62 65 20 66 72 65 65 64 20 62 65 66 6f  ll be freed befo
ea40: 72 65 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  re this function
ea50: 20 72 65 74 75 72 6e 73 2e 0a 20 20 2a 2f 0a 20   returns..  */. 
ea60: 20 61 54 6d 70 20 3d 20 28 68 74 5f 73 6c 6f 74   aTmp = (ht_slot
ea70: 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   *)sqlite3_mallo
ea80: 63 28 0a 20 20 20 20 20 20 73 69 7a 65 6f 66 28  c(.      sizeof(
ea90: 68 74 5f 73 6c 6f 74 29 20 2a 20 28 69 4c 61 73  ht_slot) * (iLas
eaa0: 74 3e 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  t>HASHTABLE_NPAG
eab0: 45 3f 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  E?HASHTABLE_NPAG
eac0: 45 3a 69 4c 61 73 74 29 0a 20 20 29 3b 0a 20 20  E:iLast).  );.  
ead0: 69 66 28 20 21 61 54 6d 70 20 29 7b 0a 20 20 20  if( !aTmp ){.   
eae0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
eaf0: 45 4d 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69  EM;.  }..  for(i
eb00: 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  =0; rc==SQLITE_O
eb10: 4b 20 26 26 20 69 3c 6e 53 65 67 6d 65 6e 74 3b  K && i<nSegment;
eb20: 20 69 2b 2b 29 7b 0a 20 20 20 20 76 6f 6c 61 74   i++){.    volat
eb30: 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61  ile ht_slot *aHa
eb40: 73 68 3b 0a 20 20 20 20 75 33 32 20 69 5a 65 72  sh;.    u32 iZer
eb50: 6f 3b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  o;.    volatile 
eb60: 75 33 32 20 2a 61 50 67 6e 6f 3b 0a 0a 20 20 20  u32 *aPgno;..   
eb70: 20 72 63 20 3d 20 77 61 6c 48 61 73 68 47 65 74   rc = walHashGet
eb80: 28 70 57 61 6c 2c 20 69 2c 20 26 61 48 61 73 68  (pWal, i, &aHash
eb90: 2c 20 26 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f  , &aPgno, &iZero
eba0: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  );.    if( rc==S
ebb0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
ebc0: 20 20 69 6e 74 20 6a 3b 20 20 20 20 20 20 20 20    int j;        
ebd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
ebe0: 20 43 6f 75 6e 74 65 72 20 76 61 72 69 61 62 6c   Counter variabl
ebf0: 65 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e  e */.      int n
ec00: 45 6e 74 72 79 3b 20 20 20 20 20 20 20 20 20 20  Entry;          
ec10: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
ec20: 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74   of entries in t
ec30: 68 69 73 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 20  his segment */. 
ec40: 20 20 20 20 20 68 74 5f 73 6c 6f 74 20 2a 61 49       ht_slot *aI
ec50: 6e 64 65 78 3b 20 20 20 20 20 20 20 20 20 20 20  ndex;           
ec60: 20 2f 2a 20 53 6f 72 74 65 64 20 69 6e 64 65 78   /* Sorted index
ec70: 20 66 6f 72 20 74 68 69 73 20 73 65 67 6d 65 6e   for this segmen
ec80: 74 20 2a 2f 0a 0a 20 20 20 20 20 20 61 50 67 6e  t */..      aPgn
ec90: 6f 2b 2b 3b 0a 20 20 20 20 20 20 69 66 28 20 28  o++;.      if( (
eca0: 69 2b 31 29 3d 3d 6e 53 65 67 6d 65 6e 74 20 29  i+1)==nSegment )
ecb0: 7b 0a 20 20 20 20 20 20 20 20 6e 45 6e 74 72 79  {.        nEntry
ecc0: 20 3d 20 28 69 6e 74 29 28 69 4c 61 73 74 20 2d   = (int)(iLast -
ecd0: 20 69 5a 65 72 6f 29 3b 0a 20 20 20 20 20 20 7d   iZero);.      }
ece0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 6e 45  else{.        nE
ecf0: 6e 74 72 79 20 3d 20 28 69 6e 74 29 28 28 75 33  ntry = (int)((u3
ed00: 32 2a 29 61 48 61 73 68 20 2d 20 28 75 33 32 2a  2*)aHash - (u32*
ed10: 29 61 50 67 6e 6f 29 3b 0a 20 20 20 20 20 20 7d  )aPgno);.      }
ed20: 0a 20 20 20 20 20 20 61 49 6e 64 65 78 20 3d 20  .      aIndex = 
ed30: 26 28 28 68 74 5f 73 6c 6f 74 20 2a 29 26 70 2d  &((ht_slot *)&p-
ed40: 3e 61 53 65 67 6d 65 6e 74 5b 70 2d 3e 6e 53 65  >aSegment[p->nSe
ed50: 67 6d 65 6e 74 5d 29 5b 69 5a 65 72 6f 5d 3b 0a  gment])[iZero];.
ed60: 20 20 20 20 20 20 69 5a 65 72 6f 2b 2b 3b 0a 20        iZero++;. 
ed70: 20 0a 20 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b   .      for(j=0;
ed80: 20 6a 3c 6e 45 6e 74 72 79 3b 20 6a 2b 2b 29 7b   j<nEntry; j++){
ed90: 0a 20 20 20 20 20 20 20 20 61 49 6e 64 65 78 5b  .        aIndex[
eda0: 6a 5d 20 3d 20 28 68 74 5f 73 6c 6f 74 29 6a 3b  j] = (ht_slot)j;
edb0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 77  .      }.      w
edc0: 61 6c 4d 65 72 67 65 73 6f 72 74 28 28 75 33 32  alMergesort((u32
edd0: 20 2a 29 61 50 67 6e 6f 2c 20 61 54 6d 70 2c 20   *)aPgno, aTmp, 
ede0: 61 49 6e 64 65 78 2c 20 26 6e 45 6e 74 72 79 29  aIndex, &nEntry)
edf0: 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65 67 6d  ;.      p->aSegm
ee00: 65 6e 74 5b 69 5d 2e 69 5a 65 72 6f 20 3d 20 69  ent[i].iZero = i
ee10: 5a 65 72 6f 3b 0a 20 20 20 20 20 20 70 2d 3e 61  Zero;.      p->a
ee20: 53 65 67 6d 65 6e 74 5b 69 5d 2e 6e 45 6e 74 72  Segment[i].nEntr
ee30: 79 20 3d 20 6e 45 6e 74 72 79 3b 0a 20 20 20 20  y = nEntry;.    
ee40: 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d    p->aSegment[i]
ee50: 2e 61 49 6e 64 65 78 20 3d 20 61 49 6e 64 65 78  .aIndex = aIndex
ee60: 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65 67 6d  ;.      p->aSegm
ee70: 65 6e 74 5b 69 5d 2e 61 50 67 6e 6f 20 3d 20 28  ent[i].aPgno = (
ee80: 75 33 32 20 2a 29 61 50 67 6e 6f 3b 0a 20 20 20  u32 *)aPgno;.   
ee90: 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33   }.  }.  sqlite3
eea0: 5f 66 72 65 65 28 61 54 6d 70 29 3b 0a 0a 20 20  _free(aTmp);..  
eeb0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
eec0: 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49 74 65 72  K ){.    walIter
eed0: 61 74 6f 72 46 72 65 65 28 70 29 3b 0a 20 20 7d  atorFree(p);.  }
eee0: 0a 20 20 2a 70 70 20 3d 20 70 3b 0a 20 20 72 65  .  *pp = p;.  re
eef0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
ef00: 2a 20 41 74 74 65 6d 70 74 20 74 6f 20 6f 62 74  * Attempt to obt
ef10: 61 69 6e 20 74 68 65 20 65 78 63 6c 75 73 69 76  ain the exclusiv
ef20: 65 20 57 41 4c 20 6c 6f 63 6b 20 64 65 66 69 6e  e WAL lock defin
ef30: 65 64 20 62 79 20 70 61 72 61 6d 65 74 65 72 73  ed by parameters
ef40: 20 6c 6f 63 6b 49 64 78 20 61 6e 64 0a 2a 2a 20   lockIdx and.** 
ef50: 6e 2e 20 49 66 20 74 68 65 20 61 74 74 65 6d 70  n. If the attemp
ef60: 74 20 66 61 69 6c 73 20 61 6e 64 20 70 61 72 61  t fails and para
ef70: 6d 65 74 65 72 20 78 42 75 73 79 20 69 73 20 6e  meter xBusy is n
ef80: 6f 74 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 69 74  ot NULL, then it
ef90: 20 69 73 20 61 0a 2a 2a 20 62 75 73 79 2d 68 61   is a.** busy-ha
efa0: 6e 64 6c 65 72 20 66 75 6e 63 74 69 6f 6e 2e 20  ndler function. 
efb0: 49 6e 76 6f 6b 65 20 69 74 20 61 6e 64 20 72 65  Invoke it and re
efc0: 74 72 79 20 74 68 65 20 6c 6f 63 6b 20 75 6e 74  try the lock unt
efd0: 69 6c 20 65 69 74 68 65 72 20 74 68 65 0a 2a 2a  il either the.**
efe0: 20 6c 6f 63 6b 20 69 73 20 73 75 63 63 65 73 73   lock is success
eff0: 66 75 6c 6c 79 20 6f 62 74 61 69 6e 65 64 20 6f  fully obtained o
f000: 72 20 74 68 65 20 62 75 73 79 2d 68 61 6e 64 6c  r the busy-handl
f010: 65 72 20 72 65 74 75 72 6e 73 20 30 2e 0a 2a 2f  er returns 0..*/
f020: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 42  .static int walB
f030: 75 73 79 4c 6f 63 6b 28 0a 20 20 57 61 6c 20 2a  usyLock(.  Wal *
f040: 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  pWal,           
f050: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41             /* WA
f060: 4c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a  L connection */.
f070: 20 20 69 6e 74 20 28 2a 78 42 75 73 79 29 28 76    int (*xBusy)(v
f080: 6f 69 64 2a 29 2c 20 20 20 20 20 20 20 20 20 20  oid*),          
f090: 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f    /* Function to
f0a0: 20 63 61 6c 6c 20 77 68 65 6e 20 62 75 73 79 20   call when busy 
f0b0: 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 42 75 73 79  */.  void *pBusy
f0c0: 41 72 67 2c 20 20 20 20 20 20 20 20 20 20 20 20  Arg,            
f0d0: 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20       /* Context 
f0e0: 61 72 67 75 6d 65 6e 74 20 66 6f 72 20 78 42 75  argument for xBu
f0f0: 73 79 48 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69  syHandler */.  i
f100: 6e 74 20 6c 6f 63 6b 49 64 78 2c 20 20 20 20 20  nt lockIdx,     
f110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
f120: 2a 20 4f 66 66 73 65 74 20 6f 66 20 66 69 72 73  * Offset of firs
f130: 74 20 62 79 74 65 20 74 6f 20 6c 6f 63 6b 20 2a  t byte to lock *
f140: 2f 0a 20 20 69 6e 74 20 6e 20 20 20 20 20 20 20  /.  int n       
f150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f160: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
f170: 20 62 79 74 65 73 20 74 6f 20 6c 6f 63 6b 20 2a   bytes to lock *
f180: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  /.){.  int rc;. 
f190: 20 64 6f 20 7b 0a 20 20 20 20 72 63 20 3d 20 77   do {.    rc = w
f1a0: 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  alLockExclusive(
f1b0: 70 57 61 6c 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e  pWal, lockIdx, n
f1c0: 29 3b 0a 20 20 7d 77 68 69 6c 65 28 20 78 42 75  );.  }while( xBu
f1d0: 73 79 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45  sy && rc==SQLITE
f1e0: 5f 42 55 53 59 20 26 26 20 78 42 75 73 79 28 70  _BUSY && xBusy(p
f1f0: 42 75 73 79 41 72 67 29 20 29 3b 0a 20 20 72 65  BusyArg) );.  re
f200: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
f210: 2a 20 54 68 65 20 63 61 63 68 65 20 6f 66 20 74  * The cache of t
f220: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
f230: 64 65 72 20 6d 75 73 74 20 62 65 20 76 61 6c 69  der must be vali
f240: 64 20 74 6f 20 63 61 6c 6c 20 74 68 69 73 20 66  d to call this f
f250: 75 6e 63 74 69 6f 6e 2e 0a 2a 2a 20 52 65 74 75  unction..** Retu
f260: 72 6e 20 74 68 65 20 70 61 67 65 2d 73 69 7a 65  rn the page-size
f270: 20 69 6e 20 62 79 74 65 73 20 75 73 65 64 20 62   in bytes used b
f280: 79 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a  y the database..
f290: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  */.static int wa
f2a0: 6c 50 61 67 65 73 69 7a 65 28 57 61 6c 20 2a 70  lPagesize(Wal *p
f2b0: 57 61 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 28  Wal){.  return (
f2c0: 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65  pWal->hdr.szPage
f2d0: 26 30 78 66 65 30 30 29 20 2b 20 28 28 70 57 61  &0xfe00) + ((pWa
f2e0: 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26 30 78  l->hdr.szPage&0x
f2f0: 30 30 30 31 29 3c 3c 31 36 29 3b 0a 7d 0a 0a 2f  0001)<<16);.}../
f300: 2a 0a 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69  *.** The followi
f310: 6e 67 20 69 73 20 67 75 61 72 61 6e 74 65 65 64  ng is guaranteed
f320: 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   when this funct
f330: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 3a 0a 2a  ion is called:.*
f340: 2a 0a 2a 2a 20 20 20 61 29 20 74 68 65 20 57 52  *.**   a) the WR
f350: 49 54 45 52 20 6c 6f 63 6b 20 69 73 20 68 65 6c  ITER lock is hel
f360: 64 2c 0a 2a 2a 20 20 20 62 29 20 74 68 65 20 65  d,.**   b) the e
f370: 6e 74 69 72 65 20 6c 6f 67 20 66 69 6c 65 20 68  ntire log file h
f380: 61 73 20 62 65 65 6e 20 63 68 65 63 6b 70 6f 69  as been checkpoi
f390: 6e 74 65 64 2c 20 61 6e 64 0a 2a 2a 20 20 20 63  nted, and.**   c
f3a0: 29 20 61 6e 79 20 65 78 69 73 74 69 6e 67 20 72  ) any existing r
f3b0: 65 61 64 65 72 73 20 61 72 65 20 72 65 61 64 69  eaders are readi
f3c0: 6e 67 20 65 78 63 6c 75 73 69 76 65 6c 79 20 66  ng exclusively f
f3d0: 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73 65  rom the database
f3e0: 0a 2a 2a 20 20 20 20 20 20 66 69 6c 65 20 2d 20  .**      file - 
f3f0: 74 68 65 72 65 20 61 72 65 20 6e 6f 20 72 65 61  there are no rea
f400: 64 65 72 73 20 74 68 61 74 20 6d 61 79 20 61 74  ders that may at
f410: 74 65 6d 70 74 20 74 6f 20 72 65 61 64 20 61 20  tempt to read a 
f420: 66 72 61 6d 65 20 66 72 6f 6d 0a 2a 2a 20 20 20  frame from.**   
f430: 20 20 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e     the log file.
f440: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  .**.** This func
f450: 74 69 6f 6e 20 75 70 64 61 74 65 73 20 74 68 65  tion updates the
f460: 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20 73   shared-memory s
f470: 74 72 75 63 74 75 72 65 73 20 73 6f 20 74 68 61  tructures so tha
f480: 74 20 74 68 65 20 6e 65 78 74 0a 2a 2a 20 63 6c  t the next.** cl
f490: 69 65 6e 74 20 74 6f 20 77 72 69 74 65 20 74 6f  ient to write to
f4a0: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 28 77   the database (w
f4b0: 68 69 63 68 20 6d 61 79 20 62 65 20 74 68 69 73  hich may be this
f4c0: 20 6f 6e 65 29 20 64 6f 65 73 20 73 6f 20 62 79   one) does so by
f4d0: 0a 2a 2a 20 77 72 69 74 69 6e 67 20 66 72 61 6d  .** writing fram
f4e0: 65 73 20 69 6e 74 6f 20 74 68 65 20 73 74 61 72  es into the star
f4f0: 74 20 6f 66 20 74 68 65 20 6c 6f 67 20 66 69 6c  t of the log fil
f500: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c  e..**.** The val
f510: 75 65 20 6f 66 20 70 61 72 61 6d 65 74 65 72 20  ue of parameter 
f520: 73 61 6c 74 31 20 69 73 20 75 73 65 64 20 61 73  salt1 is used as
f530: 20 74 68 65 20 61 53 61 6c 74 5b 31 5d 20 76 61   the aSalt[1] va
f540: 6c 75 65 20 69 6e 20 74 68 65 20 0a 2a 2a 20 6e  lue in the .** n
f550: 65 77 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  ew wal-index hea
f560: 64 65 72 2e 20 49 74 20 73 68 6f 75 6c 64 20 62  der. It should b
f570: 65 20 70 61 73 73 65 64 20 61 20 70 73 65 75 64  e passed a pseud
f580: 6f 2d 72 61 6e 64 6f 6d 20 76 61 6c 75 65 20 28  o-random value (
f590: 69 2e 65 2e 20 0a 2a 2a 20 6f 6e 65 20 6f 62 74  i.e. .** one obt
f5a0: 61 69 6e 65 64 20 66 72 6f 6d 20 73 71 6c 69 74  ained from sqlit
f5b0: 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 29 29  e3_randomness())
f5c0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
f5d0: 20 77 61 6c 52 65 73 74 61 72 74 48 64 72 28 57   walRestartHdr(W
f5e0: 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 73 61  al *pWal, u32 sa
f5f0: 6c 74 31 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65  lt1){.  volatile
f600: 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49   WalCkptInfo *pI
f610: 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66  nfo = walCkptInf
f620: 6f 28 70 57 61 6c 29 3b 0a 20 20 69 6e 74 20 69  o(pWal);.  int i
f630: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
f640: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f             /* Lo
f650: 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20  op counter */.  
f660: 75 33 32 20 2a 61 53 61 6c 74 20 3d 20 70 57 61  u32 *aSalt = pWa
f670: 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 3b 20 20 20  l->hdr.aSalt;   
f680: 2f 2a 20 42 69 67 2d 65 6e 64 69 61 6e 20 73 61  /* Big-endian sa
f690: 6c 74 20 76 61 6c 75 65 73 20 2a 2f 0a 20 20 70  lt values */.  p
f6a0: 57 61 6c 2d 3e 6e 43 6b 70 74 2b 2b 3b 0a 20 20  Wal->nCkpt++;.  
f6b0: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
f6c0: 65 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33  e = 0;.  sqlite3
f6d0: 50 75 74 34 62 79 74 65 28 28 75 38 2a 29 26 61  Put4byte((u8*)&a
f6e0: 53 61 6c 74 5b 30 5d 2c 20 31 20 2b 20 73 71 6c  Salt[0], 1 + sql
f6f0: 69 74 65 33 47 65 74 34 62 79 74 65 28 28 75 38  ite3Get4byte((u8
f700: 2a 29 26 61 53 61 6c 74 5b 30 5d 29 29 3b 0a 20  *)&aSalt[0]));. 
f710: 20 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68   memcpy(&pWal->h
f720: 64 72 2e 61 53 61 6c 74 5b 31 5d 2c 20 26 73 61  dr.aSalt[1], &sa
f730: 6c 74 31 2c 20 34 29 3b 0a 20 20 77 61 6c 49 6e  lt1, 4);.  walIn
f740: 64 65 78 57 72 69 74 65 48 64 72 28 70 57 61 6c  dexWriteHdr(pWal
f750: 29 3b 0a 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63  );.  pInfo->nBac
f760: 6b 66 69 6c 6c 20 3d 20 30 3b 0a 20 20 70 49 6e  kfill = 0;.  pIn
f770: 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 31 5d  fo->aReadMark[1]
f780: 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 32 3b   = 0;.  for(i=2;
f790: 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
f7a0: 69 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61  i++) pInfo->aRea
f7b0: 64 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d  dMark[i] = READM
f7c0: 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20  ARK_NOT_USED;.  
f7d0: 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e 61  assert( pInfo->a
f7e0: 52 65 61 64 4d 61 72 6b 5b 30 5d 3d 3d 30 20 29  ReadMark[0]==0 )
f7f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20  ;.}../*.** Copy 
f800: 61 73 20 6d 75 63 68 20 63 6f 6e 74 65 6e 74 20  as much content 
f810: 61 73 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 74  as we can from t
f820: 68 65 20 57 41 4c 20 62 61 63 6b 20 69 6e 74 6f  he WAL back into
f830: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
f840: 6c 65 0a 2a 2a 20 69 6e 20 72 65 73 70 6f 6e 73  le.** in respons
f850: 65 20 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f  e to an sqlite3_
f860: 77 61 6c 5f 63 68 65 63 6b 70 6f 69 6e 74 28 29  wal_checkpoint()
f870: 20 72 65 71 75 65 73 74 20 6f 72 20 74 68 65 20   request or the 
f880: 65 71 75 69 76 61 6c 65 6e 74 2e 0a 2a 2a 0a 2a  equivalent..**.*
f890: 2a 20 54 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20  * The amount of 
f8a0: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 63 6f 70 69  information copi
f8b0: 65 73 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64  es from WAL to d
f8c0: 61 74 61 62 61 73 65 20 6d 69 67 68 74 20 62 65  atabase might be
f8d0: 20 6c 69 6d 69 74 65 64 0a 2a 2a 20 62 79 20 61   limited.** by a
f8e0: 63 74 69 76 65 20 72 65 61 64 65 72 73 2e 20 20  ctive readers.  
f8f0: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c  This routine wil
f900: 6c 20 6e 65 76 65 72 20 6f 76 65 72 77 72 69 74  l never overwrit
f910: 65 20 61 20 64 61 74 61 62 61 73 65 20 70 61 67  e a database pag
f920: 65 0a 2a 2a 20 74 68 61 74 20 61 20 63 6f 6e 63  e.** that a conc
f930: 75 72 72 65 6e 74 20 72 65 61 64 65 72 20 6d 69  urrent reader mi
f940: 67 68 74 20 62 65 20 75 73 69 6e 67 2e 0a 2a 2a  ght be using..**
f950: 0a 2a 2a 20 41 6c 6c 20 49 2f 4f 20 62 61 72 72  .** All I/O barr
f960: 69 65 72 20 6f 70 65 72 61 74 69 6f 6e 73 20 28  ier operations (
f970: 61 2e 6b 2e 61 20 66 73 79 6e 63 73 29 20 6f 63  a.k.a fsyncs) oc
f980: 63 75 72 20 69 6e 20 74 68 69 73 20 72 6f 75 74  cur in this rout
f990: 69 6e 65 20 77 68 65 6e 0a 2a 2a 20 53 51 4c 69  ine when.** SQLi
f9a0: 74 65 20 69 73 20 69 6e 20 57 41 4c 2d 6d 6f 64  te is in WAL-mod
f9b0: 65 20 69 6e 20 73 79 6e 63 68 72 6f 6e 6f 75 73  e in synchronous
f9c0: 3d 4e 4f 52 4d 41 4c 2e 20 20 54 68 61 74 20 6d  =NORMAL.  That m
f9d0: 65 61 6e 73 20 74 68 61 74 20 69 66 20 0a 2a 2a  eans that if .**
f9e0: 20 63 68 65 63 6b 70 6f 69 6e 74 73 20 61 72 65   checkpoints are
f9f0: 20 61 6c 77 61 79 73 20 72 75 6e 20 62 79 20 61   always run by a
fa00: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
fa10: 61 64 20 6f 72 20 62 61 63 6b 67 72 6f 75 6e 64  ad or background
fa20: 20 0a 2a 2a 20 70 72 6f 63 65 73 73 2c 20 66 6f   .** process, fo
fa30: 72 65 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73  reground threads
fa40: 20 77 69 6c 6c 20 6e 65 76 65 72 20 62 6c 6f 63   will never bloc
fa50: 6b 20 6f 6e 20 61 20 6c 65 6e 67 74 68 79 20 66  k on a lengthy f
fa60: 73 79 6e 63 20 63 61 6c 6c 2e 0a 2a 2a 0a 2a 2a  sync call..**.**
fa70: 20 46 73 79 6e 63 20 69 73 20 63 61 6c 6c 65 64   Fsync is called
fa80: 20 6f 6e 20 74 68 65 20 57 41 4c 20 62 65 66 6f   on the WAL befo
fa90: 72 65 20 77 72 69 74 69 6e 67 20 63 6f 6e 74 65  re writing conte
faa0: 6e 74 20 6f 75 74 20 6f 66 20 74 68 65 20 57 41  nt out of the WA
fab0: 4c 20 61 6e 64 0a 2a 2a 20 69 6e 74 6f 20 74 68  L and.** into th
fac0: 65 20 64 61 74 61 62 61 73 65 2e 20 20 54 68 69  e database.  Thi
fad0: 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20 69  s ensures that i
fae0: 66 20 74 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e  f the new conten
faf0: 74 20 69 73 20 70 65 72 73 69 73 74 65 6e 74 0a  t is persistent.
fb00: 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 61 6e  ** in the WAL an
fb10: 64 20 63 61 6e 20 62 65 20 72 65 63 6f 76 65 72  d can be recover
fb20: 65 64 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 70  ed following a p
fb30: 6f 77 65 72 2d 6c 6f 73 73 20 6f 72 20 68 61 72  ower-loss or har
fb40: 64 20 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 46  d reset..**.** F
fb50: 73 79 6e 63 20 69 73 20 61 6c 73 6f 20 63 61 6c  sync is also cal
fb60: 6c 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 62  led on the datab
fb70: 61 73 65 20 66 69 6c 65 20 69 66 20 28 61 6e 64  ase file if (and
fb80: 20 6f 6e 6c 79 20 69 66 29 20 74 68 65 20 65 6e   only if) the en
fb90: 74 69 72 65 0a 2a 2a 20 57 41 4c 20 63 6f 6e 74  tire.** WAL cont
fba0: 65 6e 74 20 69 73 20 63 6f 70 69 65 64 20 69 6e  ent is copied in
fbb0: 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20  to the database 
fbc0: 66 69 6c 65 2e 20 20 54 68 69 73 20 73 65 63 6f  file.  This seco
fbd0: 6e 64 20 66 73 79 6e 63 20 6d 61 6b 65 73 0a 2a  nd fsync makes.*
fbe0: 2a 20 69 74 20 73 61 66 65 20 74 6f 20 64 65 6c  * it safe to del
fbf0: 65 74 65 20 74 68 65 20 57 41 4c 20 73 69 6e 63  ete the WAL sinc
fc00: 65 20 74 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e  e the new conten
fc10: 74 20 77 69 6c 6c 20 70 65 72 73 69 73 74 20 69  t will persist i
fc20: 6e 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73  n the.** databas
fc30: 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68  e file..**.** Th
fc40: 69 73 20 72 6f 75 74 69 6e 65 20 75 73 65 73 20  is routine uses 
fc50: 61 6e 64 20 75 70 64 61 74 65 73 20 74 68 65 20  and updates the 
fc60: 6e 42 61 63 6b 66 69 6c 6c 20 66 69 65 6c 64 20  nBackfill field 
fc70: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
fc80: 20 68 65 61 64 65 72 2e 0a 2a 2a 20 54 68 69 73   header..** This
fc90: 20 69 73 20 74 68 65 20 6f 6e 6c 79 20 72 6f 75   is the only rou
fca0: 74 69 6e 65 20 74 68 61 74 20 77 69 6c 6c 20 69  tine that will i
fcb0: 6e 63 72 65 61 73 65 20 74 68 65 20 76 61 6c 75  ncrease the valu
fcc0: 65 20 6f 66 20 6e 42 61 63 6b 66 69 6c 6c 2e 20  e of nBackfill. 
fcd0: 20 0a 2a 2a 20 28 41 20 57 41 4c 20 72 65 73 65   .** (A WAL rese
fce0: 74 20 6f 72 20 72 65 63 6f 76 65 72 79 20 77 69  t or recovery wi
fcf0: 6c 6c 20 72 65 76 65 72 74 20 6e 42 61 63 6b 66  ll revert nBackf
fd00: 69 6c 6c 20 74 6f 20 7a 65 72 6f 2c 20 62 75 74  ill to zero, but
fd10: 20 6e 6f 74 20 69 6e 63 72 65 61 73 65 0a 2a 2a   not increase.**
fd20: 20 69 74 73 20 76 61 6c 75 65 2e 29 0a 2a 2a 0a   its value.).**.
fd30: 2a 2a 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75  ** The caller mu
fd40: 73 74 20 62 65 20 68 6f 6c 64 69 6e 67 20 73 75  st be holding su
fd50: 66 66 69 63 69 65 6e 74 20 6c 6f 63 6b 73 20 74  fficient locks t
fd60: 6f 20 65 6e 73 75 72 65 20 74 68 61 74 20 6e 6f  o ensure that no
fd70: 20 6f 74 68 65 72 0a 2a 2a 20 63 68 65 63 6b 70   other.** checkp
fd80: 6f 69 6e 74 20 69 73 20 72 75 6e 6e 69 6e 67 20  oint is running 
fd90: 28 69 6e 20 61 6e 79 20 6f 74 68 65 72 20 74 68  (in any other th
fda0: 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 29  read or process)
fdb0: 20 61 74 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20   at the same.** 
fdc0: 74 69 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  time..*/.static 
fdd0: 69 6e 74 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e  int walCheckpoin
fde0: 74 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20  t(.  Wal *pWal, 
fdf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fe00: 20 20 20 20 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e       /* Wal conn
fe10: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20  ection */.  int 
fe20: 65 4d 6f 64 65 2c 20 20 20 20 20 20 20 20 20 20  eMode,          
fe30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
fe40: 6e 65 20 6f 66 20 50 41 53 53 49 56 45 2c 20 46  ne of PASSIVE, F
fe50: 55 4c 4c 20 6f 72 20 52 45 53 54 41 52 54 20 2a  ULL or RESTART *
fe60: 2f 0a 20 20 69 6e 74 20 28 2a 78 42 75 73 79 29  /.  int (*xBusy)
fe70: 28 76 6f 69 64 2a 29 2c 20 20 20 20 20 20 20 20  (void*),        
fe80: 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20      /* Function 
fe90: 74 6f 20 63 61 6c 6c 20 77 68 65 6e 20 62 75 73  to call when bus
fea0: 79 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 42 75  y */.  void *pBu
feb0: 73 79 41 72 67 2c 20 20 20 20 20 20 20 20 20 20  syArg,          
fec0: 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78         /* Contex
fed0: 74 20 61 72 67 75 6d 65 6e 74 20 66 6f 72 20 78  t argument for x
fee0: 42 75 73 79 48 61 6e 64 6c 65 72 20 2a 2f 0a 20  BusyHandler */. 
fef0: 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67 73 2c   int sync_flags,
ff00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ff10: 20 2f 2a 20 46 6c 61 67 73 20 66 6f 72 20 4f 73   /* Flags for Os
ff20: 53 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f  Sync() (or 0) */
ff30: 0a 20 20 75 38 20 2a 7a 42 75 66 20 20 20 20 20  .  u8 *zBuf     
ff40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ff50: 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20     /* Temporary 
ff60: 62 75 66 66 65 72 20 74 6f 20 75 73 65 20 2a 2f  buffer to use */
ff70: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  .){.  int rc;   
ff80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ff90: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
ffa0: 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  code */.  int sz
ffb0: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  Page;           
ffc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
ffd0: 61 62 61 73 65 20 70 61 67 65 2d 73 69 7a 65 20  abase page-size 
ffe0: 2a 2f 0a 20 20 57 61 6c 49 74 65 72 61 74 6f 72  */.  WalIterator
fff0: 20 2a 70 49 74 65 72 20 3d 20 30 3b 20 20 20 20   *pIter = 0;    
10000 20 20 20 20 20 2f 2a 20 57 61 6c 20 69 74 65 72       /* Wal iter
10010 61 74 6f 72 20 63 6f 6e 74 65 78 74 20 2a 2f 0a  ator context */.
10020 20 20 75 33 32 20 69 44 62 70 61 67 65 20 3d 20    u32 iDbpage = 
10030 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
10040 20 20 2f 2a 20 4e 65 78 74 20 64 61 74 61 62 61    /* Next databa
10050 73 65 20 70 61 67 65 20 74 6f 20 77 72 69 74 65  se page to write
10060 20 2a 2f 0a 20 20 75 33 32 20 69 46 72 61 6d 65   */.  u32 iFrame
10070 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
10080 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 66 72 61        /* Wal fra
10090 6d 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64 61  me containing da
100a0 74 61 20 66 6f 72 20 69 44 62 70 61 67 65 20 2a  ta for iDbpage *
100b0 2f 0a 20 20 75 33 32 20 6d 78 53 61 66 65 46 72  /.  u32 mxSafeFr
100c0 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ame;            
100d0 20 20 20 20 2f 2a 20 4d 61 78 20 66 72 61 6d 65      /* Max frame
100e0 20 74 68 61 74 20 63 61 6e 20 62 65 20 62 61 63   that can be bac
100f0 6b 66 69 6c 6c 65 64 20 2a 2f 0a 20 20 75 33 32  kfilled */.  u32
10100 20 6d 78 50 61 67 65 3b 20 20 20 20 20 20 20 20   mxPage;        
10110 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
10120 4d 61 78 20 64 61 74 61 62 61 73 65 20 70 61 67  Max database pag
10130 65 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20  e to write */.  
10140 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
10150 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10160 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20  /* Loop counter 
10170 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57 61  */.  volatile Wa
10180 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f  lCkptInfo *pInfo
10190 3b 20 20 20 20 2f 2a 20 54 68 65 20 63 68 65 63  ;    /* The chec
101a0 6b 70 6f 69 6e 74 20 73 74 61 74 75 73 20 69 6e  kpoint status in
101b0 66 6f 72 6d 61 74 69 6f 6e 20 2a 2f 0a 0a 20 20  formation */..  
101c0 73 7a 50 61 67 65 20 3d 20 77 61 6c 50 61 67 65  szPage = walPage
101d0 73 69 7a 65 28 70 57 61 6c 29 3b 0a 20 20 74 65  size(pWal);.  te
101e0 73 74 63 61 73 65 28 20 73 7a 50 61 67 65 3c 3d  stcase( szPage<=
101f0 33 32 37 36 38 20 29 3b 0a 20 20 74 65 73 74 63  32768 );.  testc
10200 61 73 65 28 20 73 7a 50 61 67 65 3e 3d 36 35 35  ase( szPage>=655
10210 33 36 20 29 3b 0a 20 20 70 49 6e 66 6f 20 3d 20  36 );.  pInfo = 
10220 77 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c  walCkptInfo(pWal
10230 29 3b 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e  );.  if( pInfo->
10240 6e 42 61 63 6b 66 69 6c 6c 3e 3d 70 57 61 6c 2d  nBackfill>=pWal-
10250 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 20 72  >hdr.mxFrame ) r
10260 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
10270 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20  ..  /* Allocate 
10280 74 68 65 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a  the iterator */.
10290 20 20 72 63 20 3d 20 77 61 6c 49 74 65 72 61 74    rc = walIterat
102a0 6f 72 49 6e 69 74 28 70 57 61 6c 2c 20 26 70 49  orInit(pWal, &pI
102b0 74 65 72 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  ter);.  if( rc!=
102c0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
102d0 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
102e0 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72 20    assert( pIter 
102f0 29 3b 0a 0a 20 20 2f 2a 20 45 56 49 44 45 4e 43  );..  /* EVIDENC
10300 45 2d 4f 46 3a 20 52 2d 36 32 39 32 30 2d 34 37  E-OF: R-62920-47
10310 34 35 30 20 54 68 65 20 62 75 73 79 2d 68 61 6e  450 The busy-han
10320 64 6c 65 72 20 63 61 6c 6c 62 61 63 6b 20 69 73  dler callback is
10330 20 6e 65 76 65 72 20 69 6e 76 6f 6b 65 64 0a 20   never invoked. 
10340 20 2a 2a 20 69 6e 20 74 68 65 20 53 51 4c 49 54   ** in the SQLIT
10350 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53  E_CHECKPOINT_PAS
10360 53 49 56 45 20 6d 6f 64 65 2e 20 2a 2f 0a 20 20  SIVE mode. */.  
10370 61 73 73 65 72 74 28 20 65 4d 6f 64 65 21 3d 53  assert( eMode!=S
10380 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54  QLITE_CHECKPOINT
10390 5f 50 41 53 53 49 56 45 20 7c 7c 20 78 42 75 73  _PASSIVE || xBus
103a0 79 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 43 6f  y==0 );..  /* Co
103b0 6d 70 75 74 65 20 69 6e 20 6d 78 53 61 66 65 46  mpute in mxSafeF
103c0 72 61 6d 65 20 74 68 65 20 69 6e 64 65 78 20 6f  rame the index o
103d0 66 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d 65  f the last frame
103e0 20 6f 66 20 74 68 65 20 57 41 4c 20 74 68 61 74   of the WAL that
103f0 20 69 73 0a 20 20 2a 2a 20 73 61 66 65 20 74 6f   is.  ** safe to
10400 20 77 72 69 74 65 20 69 6e 74 6f 20 74 68 65 20   write into the 
10410 64 61 74 61 62 61 73 65 2e 20 20 46 72 61 6d 65  database.  Frame
10420 73 20 62 65 79 6f 6e 64 20 6d 78 53 61 66 65 46  s beyond mxSafeF
10430 72 61 6d 65 20 6d 69 67 68 74 0a 20 20 2a 2a 20  rame might.  ** 
10440 6f 76 65 72 77 72 69 74 65 20 64 61 74 61 62 61  overwrite databa
10450 73 65 20 70 61 67 65 73 20 74 68 61 74 20 61 72  se pages that ar
10460 65 20 69 6e 20 75 73 65 20 62 79 20 61 63 74 69  e in use by acti
10470 76 65 20 72 65 61 64 65 72 73 20 61 6e 64 20 74  ve readers and t
10480 68 75 73 0a 20 20 2a 2a 20 63 61 6e 6e 6f 74 20  hus.  ** cannot 
10490 62 65 20 62 61 63 6b 66 69 6c 6c 65 64 20 66 72  be backfilled fr
104a0 6f 6d 20 74 68 65 20 57 41 4c 2e 0a 20 20 2a 2f  om the WAL..  */
104b0 0a 20 20 6d 78 53 61 66 65 46 72 61 6d 65 20 3d  .  mxSafeFrame =
104c0 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
104d0 6d 65 3b 0a 20 20 6d 78 50 61 67 65 20 3d 20 70  me;.  mxPage = p
104e0 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 3b 0a  Wal->hdr.nPage;.
104f0 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c    for(i=1; i<WAL
10500 5f 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a  _NREADER; i++){.
10510 20 20 20 20 75 33 32 20 79 20 3d 20 70 49 6e 66      u32 y = pInf
10520 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b  o->aReadMark[i];
10530 0a 20 20 20 20 69 66 28 20 6d 78 53 61 66 65 46  .    if( mxSafeF
10540 72 61 6d 65 3e 79 20 29 7b 0a 20 20 20 20 20 20  rame>y ){.      
10550 61 73 73 65 72 74 28 20 79 3c 3d 70 57 61 6c 2d  assert( y<=pWal-
10560 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a  >hdr.mxFrame );.
10570 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 42 75        rc = walBu
10580 73 79 4c 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75  syLock(pWal, xBu
10590 73 79 2c 20 70 42 75 73 79 41 72 67 2c 20 57 41  sy, pBusyArg, WA
105a0 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20  L_READ_LOCK(i), 
105b0 31 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  1);.      if( rc
105c0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
105d0 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 61 52         pInfo->aR
105e0 65 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 28 69 3d  eadMark[i] = (i=
105f0 3d 31 20 3f 20 6d 78 53 61 66 65 46 72 61 6d 65  =1 ? mxSafeFrame
10600 20 3a 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f   : READMARK_NOT_
10610 55 53 45 44 29 3b 0a 20 20 20 20 20 20 20 20 77  USED);.        w
10620 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
10630 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
10640 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20  _LOCK(i), 1);.  
10650 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63      }else if( rc
10660 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b  ==SQLITE_BUSY ){
10670 0a 20 20 20 20 20 20 20 20 6d 78 53 61 66 65 46  .        mxSafeF
10680 72 61 6d 65 20 3d 20 79 3b 0a 20 20 20 20 20 20  rame = y;.      
10690 20 20 78 42 75 73 79 20 3d 20 30 3b 0a 20 20 20    xBusy = 0;.   
106a0 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
106b0 20 20 67 6f 74 6f 20 77 61 6c 63 68 65 63 6b 70    goto walcheckp
106c0 6f 69 6e 74 5f 6f 75 74 3b 0a 20 20 20 20 20 20  oint_out;.      
106d0 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  }.    }.  }..  i
106e0 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66  f( pInfo->nBackf
106f0 69 6c 6c 3c 6d 78 53 61 66 65 46 72 61 6d 65 0a  ill<mxSafeFrame.
10700 20 20 20 26 26 20 28 72 63 20 3d 20 77 61 6c 42     && (rc = walB
10710 75 73 79 4c 6f 63 6b 28 70 57 61 6c 2c 20 78 42  usyLock(pWal, xB
10720 75 73 79 2c 20 70 42 75 73 79 41 72 67 2c 20 57  usy, pBusyArg, W
10730 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c  AL_READ_LOCK(0),
10740 20 31 29 29 3d 3d 53 51 4c 49 54 45 5f 4f 4b 0a   1))==SQLITE_OK.
10750 20 20 29 7b 0a 20 20 20 20 69 36 34 20 6e 53 69    ){.    i64 nSi
10760 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ze;             
10770 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
10780 74 20 73 69 7a 65 20 6f 66 20 64 61 74 61 62 61  t size of databa
10790 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 75  se file */.    u
107a0 33 32 20 6e 42 61 63 6b 66 69 6c 6c 20 3d 20 70  32 nBackfill = p
107b0 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3b  Info->nBackfill;
107c0 0a 0a 20 20 20 20 2f 2a 20 53 79 6e 63 20 74 68  ..    /* Sync th
107d0 65 20 57 41 4c 20 74 6f 20 64 69 73 6b 20 2a 2f  e WAL to disk */
107e0 0a 20 20 20 20 69 66 28 20 73 79 6e 63 5f 66 6c  .    if( sync_fl
107f0 61 67 73 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ags ){.      rc 
10800 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28  = sqlite3OsSync(
10810 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 73 79  pWal->pWalFd, sy
10820 6e 63 5f 66 6c 61 67 73 29 3b 0a 20 20 20 20 7d  nc_flags);.    }
10830 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20  ..    /* If the 
10840 64 61 74 61 62 61 73 65 20 6d 61 79 20 67 72 6f  database may gro
10850 77 20 61 73 20 61 20 72 65 73 75 6c 74 20 6f 66  w as a result of
10860 20 74 68 69 73 20 63 68 65 63 6b 70 6f 69 6e 74   this checkpoint
10870 2c 20 68 69 6e 74 0a 20 20 20 20 2a 2a 20 61 62  , hint.    ** ab
10880 6f 75 74 20 74 68 65 20 65 76 65 6e 74 75 61 6c  out the eventual
10890 20 73 69 7a 65 20 6f 66 20 74 68 65 20 64 62 20   size of the db 
108a0 66 69 6c 65 20 74 6f 20 74 68 65 20 56 46 53 20  file to the VFS 
108b0 6c 61 79 65 72 2e 0a 20 20 20 20 2a 2f 0a 20 20  layer..    */.  
108c0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
108d0 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 36 34  _OK ){.      i64
108e0 20 6e 52 65 71 20 3d 20 28 28 69 36 34 29 6d 78   nReq = ((i64)mx
108f0 50 61 67 65 20 2a 20 73 7a 50 61 67 65 29 3b 0a  Page * szPage);.
10900 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
10910 65 33 4f 73 46 69 6c 65 53 69 7a 65 28 70 57 61  e3OsFileSize(pWa
10920 6c 2d 3e 70 44 62 46 64 2c 20 26 6e 53 69 7a 65  l->pDbFd, &nSize
10930 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
10940 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 6e 53  =SQLITE_OK && nS
10950 69 7a 65 3c 6e 52 65 71 20 29 7b 0a 20 20 20 20  ize<nReq ){.    
10960 20 20 20 20 73 71 6c 69 74 65 33 4f 73 46 69 6c      sqlite3OsFil
10970 65 43 6f 6e 74 72 6f 6c 48 69 6e 74 28 70 57 61  eControlHint(pWa
10980 6c 2d 3e 70 44 62 46 64 2c 20 53 51 4c 49 54 45  l->pDbFd, SQLITE
10990 5f 46 43 4e 54 4c 5f 53 49 5a 45 5f 48 49 4e 54  _FCNTL_SIZE_HINT
109a0 2c 20 26 6e 52 65 71 29 3b 0a 20 20 20 20 20 20  , &nReq);.      
109b0 7d 0a 20 20 20 20 7d 0a 0a 0a 20 20 20 20 2f 2a  }.    }...    /*
109c0 20 49 74 65 72 61 74 65 20 74 68 72 6f 75 67 68   Iterate through
109d0 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
109e0 20 74 68 65 20 57 41 4c 2c 20 63 6f 70 79 69 6e   the WAL, copyin
109f0 67 20 64 61 74 61 20 74 6f 20 74 68 65 20 64 62  g data to the db
10a00 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 20 20 77 68   file. */.    wh
10a10 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ile( rc==SQLITE_
10a20 4f 4b 20 26 26 20 30 3d 3d 77 61 6c 49 74 65 72  OK && 0==walIter
10a30 61 74 6f 72 4e 65 78 74 28 70 49 74 65 72 2c 20  atorNext(pIter, 
10a40 26 69 44 62 70 61 67 65 2c 20 26 69 46 72 61 6d  &iDbpage, &iFram
10a50 65 29 20 29 7b 0a 20 20 20 20 20 20 69 36 34 20  e) ){.      i64 
10a60 69 4f 66 66 73 65 74 3b 0a 20 20 20 20 20 20 61  iOffset;.      a
10a70 73 73 65 72 74 28 20 77 61 6c 46 72 61 6d 65 50  ssert( walFrameP
10a80 67 6e 6f 28 70 57 61 6c 2c 20 69 46 72 61 6d 65  gno(pWal, iFrame
10a90 29 3d 3d 69 44 62 70 61 67 65 20 29 3b 0a 20 20  )==iDbpage );.  
10aa0 20 20 20 20 69 66 28 20 69 46 72 61 6d 65 3c 3d      if( iFrame<=
10ab0 6e 42 61 63 6b 66 69 6c 6c 20 7c 7c 20 69 46 72  nBackfill || iFr
10ac0 61 6d 65 3e 6d 78 53 61 66 65 46 72 61 6d 65 20  ame>mxSafeFrame 
10ad0 7c 7c 20 69 44 62 70 61 67 65 3e 6d 78 50 61 67  || iDbpage>mxPag
10ae0 65 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20  e ) continue;.  
10af0 20 20 20 20 69 4f 66 66 73 65 74 20 3d 20 77 61      iOffset = wa
10b00 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46 72  lFrameOffset(iFr
10b10 61 6d 65 2c 20 73 7a 50 61 67 65 29 20 2b 20 57  ame, szPage) + W
10b20 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
10b30 3b 0a 20 20 20 20 20 20 2f 2a 20 74 65 73 74 63  ;.      /* testc
10b40 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28  ase( IS_BIG_INT(
10b50 69 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f 20 72  iOffset) ); // r
10b60 65 71 75 69 72 65 73 20 61 20 34 47 69 42 20 57  equires a 4GiB W
10b70 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 20  AL file */.     
10b80 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52   rc = sqlite3OsR
10b90 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ead(pWal->pWalFd
10ba0 2c 20 7a 42 75 66 2c 20 73 7a 50 61 67 65 2c 20  , zBuf, szPage, 
10bb0 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20  iOffset);.      
10bc0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
10bd0 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  K ) break;.     
10be0 20 69 4f 66 66 73 65 74 20 3d 20 28 69 44 62 70   iOffset = (iDbp
10bf0 61 67 65 2d 31 29 2a 28 69 36 34 29 73 7a 50 61  age-1)*(i64)szPa
10c00 67 65 3b 0a 20 20 20 20 20 20 74 65 73 74 63 61  ge;.      testca
10c10 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28 69  se( IS_BIG_INT(i
10c20 4f 66 66 73 65 74 29 20 29 3b 0a 20 20 20 20 20  Offset) );.     
10c30 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57   rc = sqlite3OsW
10c40 72 69 74 65 28 70 57 61 6c 2d 3e 70 44 62 46 64  rite(pWal->pDbFd
10c50 2c 20 7a 42 75 66 2c 20 73 7a 50 61 67 65 2c 20  , zBuf, szPage, 
10c60 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20  iOffset);.      
10c70 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
10c80 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d  K ) break;.    }
10c90 0a 0a 20 20 20 20 2f 2a 20 49 66 20 77 6f 72 6b  ..    /* If work
10ca0 20 77 61 73 20 61 63 74 75 61 6c 6c 79 20 61 63   was actually ac
10cb0 63 6f 6d 70 6c 69 73 68 65 64 2e 2e 2e 20 2a 2f  complished... */
10cc0 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
10cd0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
10ce0 69 66 28 20 6d 78 53 61 66 65 46 72 61 6d 65 3d  if( mxSafeFrame=
10cf0 3d 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61  =walIndexHdr(pWa
10d00 6c 29 2d 3e 6d 78 46 72 61 6d 65 20 29 7b 0a 20  l)->mxFrame ){. 
10d10 20 20 20 20 20 20 20 69 36 34 20 73 7a 44 62 20         i64 szDb 
10d20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67  = pWal->hdr.nPag
10d30 65 2a 28 69 36 34 29 73 7a 50 61 67 65 3b 0a 20  e*(i64)szPage;. 
10d40 20 20 20 20 20 20 20 74 65 73 74 63 61 73 65 28         testcase(
10d50 20 49 53 5f 42 49 47 5f 49 4e 54 28 73 7a 44 62   IS_BIG_INT(szDb
10d60 29 20 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20  ) );.        rc 
10d70 3d 20 73 71 6c 69 74 65 33 4f 73 54 72 75 6e 63  = sqlite3OsTrunc
10d80 61 74 65 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  ate(pWal->pDbFd,
10d90 20 73 7a 44 62 29 3b 0a 20 20 20 20 20 20 20 20   szDb);.        
10da0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
10db0 4b 20 26 26 20 73 79 6e 63 5f 66 6c 61 67 73 20  K && sync_flags 
10dc0 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20  ){.          rc 
10dd0 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28  = sqlite3OsSync(
10de0 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 73 79 6e  pWal->pDbFd, syn
10df0 63 5f 66 6c 61 67 73 29 3b 0a 20 20 20 20 20 20  c_flags);.      
10e00 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
10e10 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
10e20 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 70  _OK ){.        p
10e30 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 20  Info->nBackfill 
10e40 3d 20 6d 78 53 61 66 65 46 72 61 6d 65 3b 0a 20  = mxSafeFrame;. 
10e50 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
10e60 20 20 2f 2a 20 52 65 6c 65 61 73 65 20 74 68 65    /* Release the
10e70 20 72 65 61 64 65 72 20 6c 6f 63 6b 20 68 65 6c   reader lock hel
10e80 64 20 77 68 69 6c 65 20 62 61 63 6b 66 69 6c 6c  d while backfill
10e90 69 6e 67 20 2a 2f 0a 20 20 20 20 77 61 6c 55 6e  ing */.    walUn
10ea0 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  lockExclusive(pW
10eb0 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  al, WAL_READ_LOC
10ec0 4b 28 30 29 2c 20 31 29 3b 0a 20 20 7d 0a 0a 20  K(0), 1);.  }.. 
10ed0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
10ee0 42 55 53 59 20 29 7b 0a 20 20 20 20 2f 2a 20 52  BUSY ){.    /* R
10ef0 65 73 65 74 20 74 68 65 20 72 65 74 75 72 6e 20  eset the return 
10f00 63 6f 64 65 20 73 6f 20 61 73 20 6e 6f 74 20 74  code so as not t
10f10 6f 20 72 65 70 6f 72 74 20 61 20 63 68 65 63 6b  o report a check
10f20 70 6f 69 6e 74 20 66 61 69 6c 75 72 65 0a 20 20  point failure.  
10f30 20 20 2a 2a 20 6a 75 73 74 20 62 65 63 61 75 73    ** just becaus
10f40 65 20 74 68 65 72 65 20 61 72 65 20 61 63 74 69  e there are acti
10f50 76 65 20 72 65 61 64 65 72 73 2e 20 20 2a 2f 0a  ve readers.  */.
10f60 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
10f70 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66  OK;.  }..  /* If
10f80 20 74 68 69 73 20 69 73 20 61 6e 20 53 51 4c 49   this is an SQLI
10f90 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 52 45  TE_CHECKPOINT_RE
10fa0 53 54 41 52 54 20 6f 72 20 54 52 55 4e 43 41 54  START or TRUNCAT
10fb0 45 20 6f 70 65 72 61 74 69 6f 6e 2c 20 61 6e 64  E operation, and
10fc0 20 74 68 65 0a 20 20 2a 2a 20 65 6e 74 69 72 65   the.  ** entire
10fd0 20 77 61 6c 20 66 69 6c 65 20 68 61 73 20 62 65   wal file has be
10fe0 65 6e 20 63 6f 70 69 65 64 20 69 6e 74 6f 20 74  en copied into t
10ff0 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
11000 2c 20 74 68 65 6e 20 62 6c 6f 63 6b 20 0a 20 20  , then block .  
11010 2a 2a 20 75 6e 74 69 6c 20 61 6c 6c 20 72 65 61  ** until all rea
11020 64 65 72 73 20 68 61 76 65 20 66 69 6e 69 73 68  ders have finish
11030 65 64 20 75 73 69 6e 67 20 74 68 65 20 77 61 6c  ed using the wal
11040 20 66 69 6c 65 2e 20 54 68 69 73 20 65 6e 73 75   file. This ensu
11050 72 65 73 20 74 68 61 74 20 0a 20 20 2a 2a 20 74  res that .  ** t
11060 68 65 20 6e 65 78 74 20 70 72 6f 63 65 73 73 20  he next process 
11070 74 6f 20 77 72 69 74 65 20 74 6f 20 74 68 65 20  to write to the 
11080 64 61 74 61 62 61 73 65 20 72 65 73 74 61 72 74  database restart
11090 73 20 74 68 65 20 77 61 6c 20 66 69 6c 65 2e 0a  s the wal file..
110a0 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53    */.  if( rc==S
110b0 51 4c 49 54 45 5f 4f 4b 20 26 26 20 65 4d 6f 64  QLITE_OK && eMod
110c0 65 21 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b 50  e!=SQLITE_CHECKP
110d0 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 29 7b 0a  OINT_PASSIVE ){.
110e0 20 20 20 20 61 73 73 65 72 74 28 20 70 57 61 6c      assert( pWal
110f0 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20  ->writeLock );. 
11100 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 42     if( pInfo->nB
11110 61 63 6b 66 69 6c 6c 3c 70 57 61 6c 2d 3e 68 64  ackfill<pWal->hd
11120 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20  r.mxFrame ){.   
11130 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42     rc = SQLITE_B
11140 55 53 59 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  USY;.    }else i
11150 66 28 20 65 4d 6f 64 65 3e 3d 53 51 4c 49 54 45  f( eMode>=SQLITE
11160 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 52 45 53 54  _CHECKPOINT_REST
11170 41 52 54 20 29 7b 0a 20 20 20 20 20 20 75 33 32  ART ){.      u32
11180 20 73 61 6c 74 31 3b 0a 20 20 20 20 20 20 73 71   salt1;.      sq
11190 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73  lite3_randomness
111a0 28 34 2c 20 26 73 61 6c 74 31 29 3b 0a 20 20 20  (4, &salt1);.   
111b0 20 20 20 61 73 73 65 72 74 28 20 6d 78 53 61 66     assert( mxSaf
111c0 65 46 72 61 6d 65 3d 3d 70 57 61 6c 2d 3e 68 64  eFrame==pWal->hd
111d0 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20  r.mxFrame );.   
111e0 20 20 20 72 63 20 3d 20 77 61 6c 42 75 73 79 4c     rc = walBusyL
111f0 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73 79 2c  ock(pWal, xBusy,
11200 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c 5f 52   pBusyArg, WAL_R
11210 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c  EAD_LOCK(1), WAL
11220 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20  _NREADER-1);.   
11230 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
11240 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
11250 69 66 28 20 65 4d 6f 64 65 3d 3d 53 51 4c 49 54  if( eMode==SQLIT
11260 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 54 52 55  E_CHECKPOINT_TRU
11270 4e 43 41 54 45 20 29 7b 0a 20 20 20 20 20 20 20  NCATE ){.       
11280 20 20 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54 41     /* IMPLEMENTA
11290 54 49 4f 4e 2d 4f 46 3a 20 52 2d 34 34 36 39 39  TION-OF: R-44699
112a0 2d 35 37 31 34 30 20 54 68 69 73 20 6d 6f 64 65  -57140 This mode
112b0 20 77 6f 72 6b 73 20 74 68 65 20 73 61 6d 65 20   works the same 
112c0 77 61 79 20 61 73 0a 20 20 20 20 20 20 20 20 20  way as.         
112d0 20 2a 2a 20 53 51 4c 49 54 45 5f 43 48 45 43 4b   ** SQLITE_CHECK
112e0 50 4f 49 4e 54 5f 52 45 53 54 41 52 54 20 77 69  POINT_RESTART wi
112f0 74 68 20 74 68 65 20 61 64 64 69 74 69 6f 6e 20  th the addition 
11300 74 68 61 74 20 69 74 20 61 6c 73 6f 0a 20 20 20  that it also.   
11310 20 20 20 20 20 20 20 2a 2a 20 74 72 75 6e 63 61         ** trunca
11320 74 65 73 20 74 68 65 20 6c 6f 67 20 66 69 6c 65  tes the log file
11330 20 74 6f 20 7a 65 72 6f 20 62 79 74 65 73 20 6a   to zero bytes j
11340 75 73 74 20 70 72 69 6f 72 20 74 6f 20 61 0a 20  ust prior to a. 
11350 20 20 20 20 20 20 20 20 20 2a 2a 20 73 75 63 63           ** succ
11360 65 73 73 66 75 6c 20 72 65 74 75 72 6e 2e 0a 20  essful return.. 
11370 20 20 20 20 20 20 20 20 20 2a 2a 0a 20 20 20 20           **.    
11380 20 20 20 20 20 20 2a 2a 20 49 6e 20 74 68 65 6f        ** In theo
11390 72 79 2c 20 69 74 20 6d 69 67 68 74 20 62 65 20  ry, it might be 
113a0 73 61 66 65 20 74 6f 20 64 6f 20 74 68 69 73 20  safe to do this 
113b0 77 69 74 68 6f 75 74 20 75 70 64 61 74 69 6e 67  without updating
113c0 20 74 68 65 0a 20 20 20 20 20 20 20 20 20 20 2a   the.          *
113d0 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  * wal-index head
113e0 65 72 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d  er in shared mem
113f0 6f 72 79 2c 20 61 73 20 61 6c 6c 20 73 75 62 73  ory, as all subs
11400 65 71 75 65 6e 74 20 72 65 61 64 65 72 20 6f 72  equent reader or
11410 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 77 72  .          ** wr
11420 69 74 65 72 20 63 6c 69 65 6e 74 73 20 73 68 6f  iter clients sho
11430 75 6c 64 20 73 65 65 20 74 68 61 74 20 74 68 65  uld see that the
11440 20 65 6e 74 69 72 65 20 6c 6f 67 20 66 69 6c 65   entire log file
11450 20 68 61 73 20 62 65 65 6e 0a 20 20 20 20 20 20   has been.      
11460 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69 6e      ** checkpoin
11470 74 65 64 20 61 6e 64 20 62 65 68 61 76 65 20 61  ted and behave a
11480 63 63 6f 72 64 69 6e 67 6c 79 2e 20 54 68 69 73  ccordingly. This
11490 20 73 65 65 6d 73 20 75 6e 73 61 66 65 20 74 68   seems unsafe th
114a0 6f 75 67 68 2c 0a 20 20 20 20 20 20 20 20 20 20  ough,.          
114b0 2a 2a 20 61 73 20 69 74 20 77 6f 75 6c 64 20 6c  ** as it would l
114c0 65 61 76 65 20 74 68 65 20 73 79 73 74 65 6d 20  eave the system 
114d0 69 6e 20 61 20 73 74 61 74 65 20 77 68 65 72 65  in a state where
114e0 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
114f0 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 74 68  .          ** th
11500 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
11510 65 72 20 64 6f 20 6e 6f 74 20 6d 61 74 63 68 20  er do not match 
11520 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
11530 74 68 65 20 0a 20 20 20 20 20 20 20 20 20 20 2a  the .          *
11540 2a 20 66 69 6c 65 2d 73 79 73 74 65 6d 2e 20 54  * file-system. T
11550 6f 20 61 76 6f 69 64 20 74 68 69 73 2c 20 75 70  o avoid this, up
11560 64 61 74 65 20 74 68 65 20 77 61 6c 2d 69 6e 64  date the wal-ind
11570 65 78 20 68 65 61 64 65 72 20 74 6f 0a 20 20 20  ex header to.   
11580 20 20 20 20 20 20 20 2a 2a 20 69 6e 64 69 63 61         ** indica
11590 74 65 20 74 68 61 74 20 74 68 65 20 6c 6f 67 20  te that the log 
115a0 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 7a 65  file contains ze
115b0 72 6f 20 76 61 6c 69 64 20 66 72 61 6d 65 73 2e  ro valid frames.
115c0 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 77    */.          w
115d0 61 6c 52 65 73 74 61 72 74 48 64 72 28 70 57 61  alRestartHdr(pWa
115e0 6c 2c 20 73 61 6c 74 31 29 3b 0a 20 20 20 20 20  l, salt1);.     
115f0 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
11600 33 4f 73 54 72 75 6e 63 61 74 65 28 70 57 61 6c  3OsTruncate(pWal
11610 2d 3e 70 57 61 6c 46 64 2c 20 30 29 3b 0a 20 20  ->pWalFd, 0);.  
11620 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
11630 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69  walUnlockExclusi
11640 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ve(pWal, WAL_REA
11650 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e  D_LOCK(1), WAL_N
11660 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20 20 20  READER-1);.     
11670 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 77   }.    }.  }.. w
11680 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74  alcheckpoint_out
11690 3a 0a 20 20 77 61 6c 49 74 65 72 61 74 6f 72 46  :.  walIteratorF
116a0 72 65 65 28 70 49 74 65 72 29 3b 0a 20 20 72 65  ree(pIter);.  re
116b0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
116c0 2a 20 49 66 20 74 68 65 20 57 41 4c 20 66 69 6c  * If the WAL fil
116d0 65 20 69 73 20 63 75 72 72 65 6e 74 6c 79 20 6c  e is currently l
116e0 61 72 67 65 72 20 74 68 61 6e 20 6e 4d 61 78 20  arger than nMax 
116f0 62 79 74 65 73 20 69 6e 20 73 69 7a 65 2c 20 74  bytes in size, t
11700 72 75 6e 63 61 74 65 0a 2a 2a 20 69 74 20 74 6f  runcate.** it to
11710 20 65 78 61 63 74 6c 79 20 6e 4d 61 78 20 62 79   exactly nMax by
11720 74 65 73 2e 20 49 66 20 61 6e 20 65 72 72 6f 72  tes. If an error
11730 20 6f 63 63 75 72 73 20 77 68 69 6c 65 20 64 6f   occurs while do
11740 69 6e 67 20 73 6f 2c 20 69 67 6e 6f 72 65 20 69  ing so, ignore i
11750 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t..*/.static voi
11760 64 20 77 61 6c 4c 69 6d 69 74 53 69 7a 65 28 57  d walLimitSize(W
11770 61 6c 20 2a 70 57 61 6c 2c 20 69 36 34 20 6e 4d  al *pWal, i64 nM
11780 61 78 29 7b 0a 20 20 69 36 34 20 73 7a 3b 0a 20  ax){.  i64 sz;. 
11790 20 69 6e 74 20 72 78 3b 0a 20 20 73 71 6c 69 74   int rx;.  sqlit
117a0 65 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c  e3BeginBenignMal
117b0 6c 6f 63 28 29 3b 0a 20 20 72 78 20 3d 20 73 71  loc();.  rx = sq
117c0 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a 65 28  lite3OsFileSize(
117d0 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 26 73  pWal->pWalFd, &s
117e0 7a 29 3b 0a 20 20 69 66 28 20 72 78 3d 3d 53 51  z);.  if( rx==SQ
117f0 4c 49 54 45 5f 4f 4b 20 26 26 20 28 73 7a 20 3e  LITE_OK && (sz >
11800 20 6e 4d 61 78 20 29 20 29 7b 0a 20 20 20 20 72   nMax ) ){.    r
11810 78 20 3d 20 73 71 6c 69 74 65 33 4f 73 54 72 75  x = sqlite3OsTru
11820 6e 63 61 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c  ncate(pWal->pWal
11830 46 64 2c 20 6e 4d 61 78 29 3b 0a 20 20 7d 0a 20  Fd, nMax);.  }. 
11840 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67   sqlite3EndBenig
11850 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 69 66 28  nMalloc();.  if(
11860 20 72 78 20 29 7b 0a 20 20 20 20 73 71 6c 69 74   rx ){.    sqlit
11870 65 33 5f 6c 6f 67 28 72 78 2c 20 22 63 61 6e 6e  e3_log(rx, "cann
11880 6f 74 20 6c 69 6d 69 74 20 57 41 4c 20 73 69 7a  ot limit WAL siz
11890 65 3a 20 25 73 22 2c 20 70 57 61 6c 2d 3e 7a 57  e: %s", pWal->zW
118a0 61 6c 4e 61 6d 65 29 3b 0a 20 20 7d 0a 7d 0a 0a  alName);.  }.}..
118b0 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 63 6f  /*.** Close a co
118c0 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 61 20 6c 6f  nnection to a lo
118d0 67 20 66 69 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 73  g file..*/.int s
118e0 71 6c 69 74 65 33 57 61 6c 43 6c 6f 73 65 28 0a  qlite3WalClose(.
118f0 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
11900 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11910 20 20 2f 2a 20 57 61 6c 20 74 6f 20 63 6c 6f 73    /* Wal to clos
11920 65 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f  e */.  int sync_
11930 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20 20 20  flags,          
11940 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20         /* Flags 
11950 74 6f 20 70 61 73 73 20 74 6f 20 4f 73 53 79 6e  to pass to OsSyn
11960 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20  c() (or 0) */.  
11970 69 6e 74 20 6e 42 75 66 2c 0a 20 20 75 38 20 2a  int nBuf,.  u8 *
11980 7a 42 75 66 20 20 20 20 20 20 20 20 20 20 20 20  zBuf            
11990 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
119a0 75 66 66 65 72 20 6f 66 20 61 74 20 6c 65 61 73  uffer of at leas
119b0 74 20 6e 42 75 66 20 62 79 74 65 73 20 2a 2f 0a  t nBuf bytes */.
119c0 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
119d0 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70  LITE_OK;.  if( p
119e0 57 61 6c 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  Wal ){.    int i
119f0 73 44 65 6c 65 74 65 20 3d 20 30 3b 20 20 20 20  sDelete = 0;    
11a00 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
11a10 20 74 6f 20 75 6e 6c 69 6e 6b 20 77 61 6c 20 61   to unlink wal a
11a20 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  nd wal-index fil
11a30 65 73 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 49 66  es */..    /* If
11a40 20 61 6e 20 45 58 43 4c 55 53 49 56 45 20 6c 6f   an EXCLUSIVE lo
11a50 63 6b 20 63 61 6e 20 62 65 20 6f 62 74 61 69 6e  ck can be obtain
11a60 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 62 61  ed on the databa
11a70 73 65 20 66 69 6c 65 20 28 75 73 69 6e 67 20 74  se file (using t
11a80 68 65 0a 20 20 20 20 2a 2a 20 6f 72 64 69 6e 61  he.    ** ordina
11a90 72 79 2c 20 72 6f 6c 6c 62 61 63 6b 2d 6d 6f 64  ry, rollback-mod
11aa0 65 20 6c 6f 63 6b 69 6e 67 20 6d 65 74 68 6f 64  e locking method
11ab0 73 2c 20 74 68 69 73 20 67 75 61 72 61 6e 74 65  s, this guarante
11ac0 65 73 20 74 68 61 74 20 74 68 65 0a 20 20 20 20  es that the.    
11ad0 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 61 73  ** connection as
11ae0 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68  sociated with th
11af0 69 73 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 74  is log file is t
11b00 68 65 20 6f 6e 6c 79 20 63 6f 6e 6e 65 63 74 69  he only connecti
11b10 6f 6e 20 74 6f 0a 20 20 20 20 2a 2a 20 74 68 65  on to.    ** the
11b20 20 64 61 74 61 62 61 73 65 2e 20 49 6e 20 74 68   database. In th
11b30 69 73 20 63 61 73 65 20 63 68 65 63 6b 70 6f 69  is case checkpoi
11b40 6e 74 20 74 68 65 20 64 61 74 61 62 61 73 65 20  nt the database 
11b50 61 6e 64 20 75 6e 6c 69 6e 6b 20 62 6f 74 68 0a  and unlink both.
11b60 20 20 20 20 2a 2a 20 74 68 65 20 77 61 6c 20 61      ** the wal a
11b70 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  nd wal-index fil
11b80 65 73 2e 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a  es..    **.    *
11b90 2a 20 54 68 65 20 45 58 43 4c 55 53 49 56 45 20  * The EXCLUSIVE 
11ba0 6c 6f 63 6b 20 69 73 20 6e 6f 74 20 72 65 6c 65  lock is not rele
11bb0 61 73 65 64 20 62 65 66 6f 72 65 20 72 65 74 75  ased before retu
11bc0 72 6e 69 6e 67 2e 0a 20 20 20 20 2a 2f 0a 20 20  rning..    */.  
11bd0 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
11be0 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64  Lock(pWal->pDbFd
11bf0 2c 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 5f 45 58  , SQLITE_LOCK_EX
11c00 43 4c 55 53 49 56 45 29 3b 0a 20 20 20 20 69 66  CLUSIVE);.    if
11c10 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
11c20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 57 61  ){.      if( pWa
11c30 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
11c40 3d 3d 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44  ==WAL_NORMAL_MOD
11c50 45 20 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61  E ){.        pWa
11c60 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
11c70 20 3d 20 57 41 4c 5f 45 58 43 4c 55 53 49 56 45   = WAL_EXCLUSIVE
11c80 5f 4d 4f 44 45 3b 0a 20 20 20 20 20 20 7d 0a 20  _MODE;.      }. 
11c90 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
11ca0 33 57 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a  3WalCheckpoint(.
11cb0 20 20 20 20 20 20 20 20 20 20 70 57 61 6c 2c 20            pWal, 
11cc0 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e  SQLITE_CHECKPOIN
11cd0 54 5f 50 41 53 53 49 56 45 2c 20 30 2c 20 30 2c  T_PASSIVE, 0, 0,
11ce0 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20 6e 42 75   sync_flags, nBu
11cf0 66 2c 20 7a 42 75 66 2c 20 30 2c 20 30 0a 20 20  f, zBuf, 0, 0.  
11d00 20 20 20 20 29 3b 0a 20 20 20 20 20 20 69 66 28      );.      if(
11d10 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
11d20 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 62 50  {.        int bP
11d30 65 72 73 69 73 74 20 3d 20 2d 31 3b 0a 20 20 20  ersist = -1;.   
11d40 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73 46 69       sqlite3OsFi
11d50 6c 65 43 6f 6e 74 72 6f 6c 48 69 6e 74 28 0a 20  leControlHint(. 
11d60 20 20 20 20 20 20 20 20 20 20 20 70 57 61 6c 2d             pWal-
11d70 3e 70 44 62 46 64 2c 20 53 51 4c 49 54 45 5f 46  >pDbFd, SQLITE_F
11d80 43 4e 54 4c 5f 50 45 52 53 49 53 54 5f 57 41 4c  CNTL_PERSIST_WAL
11d90 2c 20 26 62 50 65 72 73 69 73 74 0a 20 20 20 20  , &bPersist.    
11da0 20 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 69      );.        i
11db0 66 28 20 62 50 65 72 73 69 73 74 21 3d 31 20 29  f( bPersist!=1 )
11dc0 7b 0a 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54  {.          /* T
11dd0 72 79 20 74 6f 20 64 65 6c 65 74 65 20 74 68 65  ry to delete the
11de0 20 57 41 4c 20 66 69 6c 65 20 69 66 20 74 68 65   WAL file if the
11df0 20 63 68 65 63 6b 70 6f 69 6e 74 20 63 6f 6d 70   checkpoint comp
11e00 6c 65 74 65 64 20 61 6e 64 0a 20 20 20 20 20 20  leted and.      
11e10 20 20 20 20 2a 2a 20 66 73 79 6e 65 64 20 28 72      ** fsyned (r
11e20 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29 20 61 6e  c==SQLITE_OK) an
11e30 64 20 69 66 20 77 65 20 61 72 65 20 6e 6f 74 20  d if we are not 
11e40 69 6e 20 70 65 72 73 69 73 74 65 6e 74 2d 77 61  in persistent-wa
11e50 6c 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 6d  l.          ** m
11e60 6f 64 65 20 28 21 62 50 65 72 73 69 73 74 29 20  ode (!bPersist) 
11e70 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 69 73 44  */.          isD
11e80 65 6c 65 74 65 20 3d 20 31 3b 0a 20 20 20 20 20  elete = 1;.     
11e90 20 20 20 7d 65 6c 73 65 20 69 66 28 20 70 57 61     }else if( pWa
11ea0 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 3e 3d 30 20  l->mxWalSize>=0 
11eb0 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ){.          /* 
11ec0 54 72 79 20 74 6f 20 74 72 75 6e 63 61 74 65 20  Try to truncate 
11ed0 74 68 65 20 57 41 4c 20 66 69 6c 65 20 74 6f 20  the WAL file to 
11ee0 7a 65 72 6f 20 62 79 74 65 73 20 69 66 20 74 68  zero bytes if th
11ef0 65 20 63 68 65 63 6b 70 6f 69 6e 74 0a 20 20 20  e checkpoint.   
11f00 20 20 20 20 20 20 20 2a 2a 20 63 6f 6d 70 6c 65         ** comple
11f10 74 65 64 20 61 6e 64 20 66 73 79 6e 63 65 64 20  ted and fsynced 
11f20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29 20  (rc==SQLITE_OK) 
11f30 61 6e 64 20 77 65 20 61 72 65 20 69 6e 20 70 65  and we are in pe
11f40 72 73 69 73 74 65 6e 74 0a 20 20 20 20 20 20 20  rsistent.       
11f50 20 20 20 2a 2a 20 57 41 4c 20 6d 6f 64 65 20 28     ** WAL mode (
11f60 62 50 65 72 73 69 73 74 29 20 61 6e 64 20 69 66  bPersist) and if
11f70 20 74 68 65 20 50 52 41 47 4d 41 20 6a 6f 75 72   the PRAGMA jour
11f80 6e 61 6c 5f 73 69 7a 65 5f 6c 69 6d 69 74 20 69  nal_size_limit i
11f90 73 20 61 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  s a.          **
11fa0 20 6e 6f 6e 2d 6e 65 67 61 74 69 76 65 20 76 61   non-negative va
11fb0 6c 75 65 20 28 70 57 61 6c 2d 3e 6d 78 57 61 6c  lue (pWal->mxWal
11fc0 53 69 7a 65 3e 3d 30 29 2e 20 20 4e 6f 74 65 20  Size>=0).  Note 
11fd0 74 68 61 74 20 77 65 20 74 72 75 6e 63 61 74 65  that we truncate
11fe0 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 74 6f  .          ** to
11ff0 20 7a 65 72 6f 20 62 79 74 65 73 20 61 73 20 74   zero bytes as t
12000 72 75 6e 63 61 74 69 6e 67 20 74 6f 20 74 68 65  runcating to the
12010 20 6a 6f 75 72 6e 61 6c 5f 73 69 7a 65 5f 6c 69   journal_size_li
12020 6d 69 74 20 6d 69 67 68 74 0a 20 20 20 20 20 20  mit might.      
12030 20 20 20 20 2a 2a 20 6c 65 61 76 65 20 61 20 63      ** leave a c
12040 6f 72 72 75 70 74 20 57 41 4c 20 66 69 6c 65 20  orrupt WAL file 
12050 6f 6e 20 64 69 73 6b 2e 20 2a 2f 0a 20 20 20 20  on disk. */.    
12060 20 20 20 20 20 20 77 61 6c 4c 69 6d 69 74 53 69        walLimitSi
12070 7a 65 28 70 57 61 6c 2c 20 30 29 3b 0a 20 20 20  ze(pWal, 0);.   
12080 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
12090 20 20 20 7d 0a 0a 20 20 20 20 77 61 6c 49 6e 64     }..    walInd
120a0 65 78 43 6c 6f 73 65 28 70 57 61 6c 2c 20 69 73  exClose(pWal, is
120b0 44 65 6c 65 74 65 29 3b 0a 20 20 20 20 73 71 6c  Delete);.    sql
120c0 69 74 65 33 4f 73 43 6c 6f 73 65 28 70 57 61 6c  ite3OsClose(pWal
120d0 2d 3e 70 57 61 6c 46 64 29 3b 0a 20 20 20 20 69  ->pWalFd);.    i
120e0 66 28 20 69 73 44 65 6c 65 74 65 20 29 7b 0a 20  f( isDelete ){. 
120f0 20 20 20 20 20 73 71 6c 69 74 65 33 42 65 67 69       sqlite3Begi
12100 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  nBenignMalloc();
12110 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73  .      sqlite3Os
12120 44 65 6c 65 74 65 28 70 57 61 6c 2d 3e 70 56 66  Delete(pWal->pVf
12130 73 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d  s, pWal->zWalNam
12140 65 2c 20 30 29 3b 0a 20 20 20 20 20 20 73 71 6c  e, 0);.      sql
12150 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c  ite3EndBenignMal
12160 6c 6f 63 28 29 3b 0a 20 20 20 20 7d 0a 20 20 20  loc();.    }.   
12170 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
12180 70 3a 20 63 6c 6f 73 65 64 5c 6e 22 2c 20 70 57  p: closed\n", pW
12190 61 6c 29 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  al));.    sqlite
121a0 33 5f 66 72 65 65 28 28 76 6f 69 64 20 2a 29 70  3_free((void *)p
121b0 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 29 3b 0a  Wal->apWiData);.
121c0 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
121d0 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20 20 72 65  (pWal);.  }.  re
121e0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
121f0 2a 20 54 72 79 20 74 6f 20 72 65 61 64 20 74 68  * Try to read th
12200 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
12210 65 72 2e 20 20 52 65 74 75 72 6e 20 30 20 6f 6e  er.  Return 0 on
12220 20 73 75 63 63 65 73 73 20 61 6e 64 20 31 20 69   success and 1 i
12230 66 0a 2a 2a 20 74 68 65 72 65 20 69 73 20 61 20  f.** there is a 
12240 70 72 6f 62 6c 65 6d 2e 0a 2a 2a 0a 2a 2a 20 54  problem..**.** T
12250 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
12260 69 6e 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79  in shared memory
12270 2e 20 20 41 6e 6f 74 68 65 72 20 74 68 72 65 61  .  Another threa
12280 64 20 6f 72 20 70 72 6f 63 65 73 73 20 6d 69 67  d or process mig
12290 68 74 0a 2a 2a 20 62 65 20 77 72 69 74 69 6e 67  ht.** be writing
122a0 20 74 68 65 20 68 65 61 64 65 72 20 61 74 20 74   the header at t
122b0 68 65 20 73 61 6d 65 20 74 69 6d 65 20 74 68 69  he same time thi
122c0 73 20 70 72 6f 63 65 64 75 72 65 20 69 73 20 74  s procedure is t
122d0 72 79 69 6e 67 20 74 6f 0a 2a 2a 20 72 65 61 64  rying to.** read
122e0 20 69 74 2c 20 77 68 69 63 68 20 6d 69 67 68 74   it, which might
122f0 20 72 65 73 75 6c 74 20 69 6e 20 69 6e 63 6f 6e   result in incon
12300 73 69 73 74 65 6e 63 79 2e 20 20 41 20 64 69 72  sistency.  A dir
12310 74 79 20 72 65 61 64 20 69 73 20 64 65 74 65 63  ty read is detec
12320 74 65 64 0a 2a 2a 20 62 79 20 76 65 72 69 66 79  ted.** by verify
12330 69 6e 67 20 74 68 61 74 20 62 6f 74 68 20 63 6f  ing that both co
12340 70 69 65 73 20 6f 66 20 74 68 65 20 68 65 61 64  pies of the head
12350 65 72 20 61 72 65 20 74 68 65 20 73 61 6d 65 20  er are the same 
12360 61 6e 64 20 61 6c 73 6f 20 62 79 0a 2a 2a 20 61  and also by.** a
12370 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20 74 68 65   checksum on the
12380 20 68 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 49   header..**.** I
12390 66 20 61 6e 64 20 6f 6e 6c 79 20 69 66 20 74 68  f and only if th
123a0 65 20 72 65 61 64 20 69 73 20 63 6f 6e 73 69 73  e read is consis
123b0 74 65 6e 74 20 61 6e 64 20 74 68 65 20 68 65 61  tent and the hea
123c0 64 65 72 20 69 73 20 64 69 66 66 65 72 65 6e 74  der is different
123d0 20 66 72 6f 6d 0a 2a 2a 20 70 57 61 6c 2d 3e 68   from.** pWal->h
123e0 64 72 2c 20 74 68 65 6e 20 70 57 61 6c 2d 3e 68  dr, then pWal->h
123f0 64 72 20 69 73 20 75 70 64 61 74 65 64 20 74 6f  dr is updated to
12400 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20   the content of 
12410 74 68 65 20 6e 65 77 20 68 65 61 64 65 72 0a 2a  the new header.*
12420 2a 20 61 6e 64 20 2a 70 43 68 61 6e 67 65 64 20  * and *pChanged 
12430 69 73 20 73 65 74 20 74 6f 20 31 2e 0a 2a 2a 0a  is set to 1..**.
12440 2a 2a 20 49 66 20 74 68 65 20 63 68 65 63 6b 73  ** If the checks
12450 75 6d 20 63 61 6e 6e 6f 74 20 62 65 20 76 65 72  um cannot be ver
12460 69 66 69 65 64 20 72 65 74 75 72 6e 20 6e 6f 6e  ified return non
12470 2d 7a 65 72 6f 2e 20 49 66 20 74 68 65 20 68 65  -zero. If the he
12480 61 64 65 72 0a 2a 2a 20 69 73 20 72 65 61 64 20  ader.** is read 
12490 73 75 63 63 65 73 73 66 75 6c 6c 79 20 61 6e 64  successfully and
124a0 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 76 65   the checksum ve
124b0 72 69 66 69 65 64 2c 20 72 65 74 75 72 6e 20 7a  rified, return z
124c0 65 72 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ero..*/.static i
124d0 6e 74 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64  nt walIndexTryHd
124e0 72 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  r(Wal *pWal, int
124f0 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a 20 20 75   *pChanged){.  u
12500 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  32 aCksum[2];   
12510 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
12520 2a 20 43 68 65 63 6b 73 75 6d 20 6f 6e 20 74 68  * Checksum on th
12530 65 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74  e header content
12540 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65 78 48 64   */.  WalIndexHd
12550 72 20 68 31 2c 20 68 32 3b 20 20 20 20 20 20 20  r h1, h2;       
12560 20 20 20 20 20 20 2f 2a 20 54 77 6f 20 63 6f 70        /* Two cop
12570 69 65 73 20 6f 66 20 74 68 65 20 68 65 61 64 65  ies of the heade
12580 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 57  r content */.  W
12590 61 6c 49 6e 64 65 78 48 64 72 20 76 6f 6c 61 74  alIndexHdr volat
125a0 69 6c 65 20 2a 61 48 64 72 3b 20 20 20 20 20 2f  ile *aHdr;     /
125b0 2a 20 48 65 61 64 65 72 20 69 6e 20 73 68 61 72  * Header in shar
125c0 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a 0a 20 20  ed memory */..  
125d0 2f 2a 20 54 68 65 20 66 69 72 73 74 20 70 61 67  /* The first pag
125e0 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  e of the wal-ind
125f0 65 78 20 6d 75 73 74 20 62 65 20 6d 61 70 70 65  ex must be mappe
12600 64 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74 2e  d at this point.
12610 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57   */.  assert( pW
12620 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20 26 26  al->nWiData>0 &&
12630 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
12640 30 5d 20 29 3b 0a 0a 20 20 2f 2a 20 52 65 61 64  0] );..  /* Read
12650 20 74 68 65 20 68 65 61 64 65 72 2e 20 54 68 69   the header. Thi
12660 73 20 6d 69 67 68 74 20 68 61 70 70 65 6e 20 63  s might happen c
12670 6f 6e 63 75 72 72 65 6e 74 6c 79 20 77 69 74 68  oncurrently with
12680 20 61 20 77 72 69 74 65 20 74 6f 20 74 68 65 0a   a write to the.
12690 20 20 2a 2a 20 73 61 6d 65 20 61 72 65 61 20 6f    ** same area o
126a0 66 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 20  f shared memory 
126b0 6f 6e 20 61 20 64 69 66 66 65 72 65 6e 74 20 43  on a different C
126c0 50 55 20 69 6e 20 61 20 53 4d 50 2c 0a 20 20 2a  PU in a SMP,.  *
126d0 2a 20 6d 65 61 6e 69 6e 67 20 69 74 20 69 73 20  * meaning it is 
126e0 70 6f 73 73 69 62 6c 65 20 74 68 61 74 20 61 6e  possible that an
126f0 20 69 6e 63 6f 6e 73 69 73 74 65 6e 74 20 73 6e   inconsistent sn
12700 61 70 73 68 6f 74 20 69 73 20 72 65 61 64 0a 20  apshot is read. 
12710 20 2a 2a 20 66 72 6f 6d 20 74 68 65 20 66 69 6c   ** from the fil
12720 65 2e 20 49 66 20 74 68 69 73 20 68 61 70 70 65  e. If this happe
12730 6e 73 2c 20 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a  ns, return non-z
12740 65 72 6f 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54  ero..  **.  ** T
12750 68 65 72 65 20 61 72 65 20 74 77 6f 20 63 6f 70  here are two cop
12760 69 65 73 20 6f 66 20 74 68 65 20 68 65 61 64 65  ies of the heade
12770 72 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e 69  r at the beginni
12780 6e 67 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ng of the wal-in
12790 64 65 78 2e 0a 20 20 2a 2a 20 57 68 65 6e 20 72  dex..  ** When r
127a0 65 61 64 69 6e 67 2c 20 72 65 61 64 20 5b 30 5d  eading, read [0]
127b0 20 66 69 72 73 74 20 74 68 65 6e 20 5b 31 5d 2e   first then [1].
127c0 20 20 57 72 69 74 65 73 20 61 72 65 20 69 6e 20    Writes are in 
127d0 74 68 65 20 72 65 76 65 72 73 65 20 6f 72 64 65  the reverse orde
127e0 72 2e 0a 20 20 2a 2a 20 4d 65 6d 6f 72 79 20 62  r..  ** Memory b
127f0 61 72 72 69 65 72 73 20 61 72 65 20 75 73 65 64  arriers are used
12800 20 74 6f 20 70 72 65 76 65 6e 74 20 74 68 65 20   to prevent the 
12810 63 6f 6d 70 69 6c 65 72 20 6f 72 20 74 68 65 20  compiler or the 
12820 68 61 72 64 77 61 72 65 20 66 72 6f 6d 0a 20 20  hardware from.  
12830 2a 2a 20 72 65 6f 72 64 65 72 69 6e 67 20 74 68  ** reordering th
12840 65 20 72 65 61 64 73 20 61 6e 64 20 77 72 69 74  e reads and writ
12850 65 73 2e 0a 20 20 2a 2f 0a 20 20 61 48 64 72 20  es..  */.  aHdr 
12860 3d 20 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57  = walIndexHdr(pW
12870 61 6c 29 3b 0a 20 20 6d 65 6d 63 70 79 28 26 68  al);.  memcpy(&h
12880 31 2c 20 28 76 6f 69 64 20 2a 29 26 61 48 64 72  1, (void *)&aHdr
12890 5b 30 5d 2c 20 73 69 7a 65 6f 66 28 68 31 29 29  [0], sizeof(h1))
128a0 3b 0a 20 20 77 61 6c 53 68 6d 42 61 72 72 69 65  ;.  walShmBarrie
128b0 72 28 70 57 61 6c 29 3b 0a 20 20 6d 65 6d 63 70  r(pWal);.  memcp
128c0 79 28 26 68 32 2c 20 28 76 6f 69 64 20 2a 29 26  y(&h2, (void *)&
128d0 61 48 64 72 5b 31 5d 2c 20 73 69 7a 65 6f 66 28  aHdr[1], sizeof(
128e0 68 32 29 29 3b 0a 0a 20 20 69 66 28 20 6d 65 6d  h2));..  if( mem
128f0 63 6d 70 28 26 68 31 2c 20 26 68 32 2c 20 73 69  cmp(&h1, &h2, si
12900 7a 65 6f 66 28 68 31 29 29 21 3d 30 20 29 7b 0a  zeof(h1))!=0 ){.
12910 20 20 20 20 72 65 74 75 72 6e 20 31 3b 20 20 20      return 1;   
12920 2f 2a 20 44 69 72 74 79 20 72 65 61 64 20 2a 2f  /* Dirty read */
12930 0a 20 20 7d 20 20 0a 20 20 69 66 28 20 68 31 2e  .  }  .  if( h1.
12940 69 73 49 6e 69 74 3d 3d 30 20 29 7b 0a 20 20 20  isInit==0 ){.   
12950 20 72 65 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20   return 1;   /* 
12960 4d 61 6c 66 6f 72 6d 65 64 20 68 65 61 64 65 72  Malformed header
12970 20 2d 20 70 72 6f 62 61 62 6c 79 20 61 6c 6c 20   - probably all 
12980 7a 65 72 6f 73 20 2a 2f 0a 20 20 7d 0a 20 20 77  zeros */.  }.  w
12990 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
129a0 31 2c 20 28 75 38 2a 29 26 68 31 2c 20 73 69 7a  1, (u8*)&h1, siz
129b0 65 6f 66 28 68 31 29 2d 73 69 7a 65 6f 66 28 68  eof(h1)-sizeof(h
129c0 31 2e 61 43 6b 73 75 6d 29 2c 20 30 2c 20 61 43  1.aCksum), 0, aC
129d0 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20 61 43 6b  ksum);.  if( aCk
129e0 73 75 6d 5b 30 5d 21 3d 68 31 2e 61 43 6b 73 75  sum[0]!=h1.aCksu
129f0 6d 5b 30 5d 20 7c 7c 20 61 43 6b 73 75 6d 5b 31  m[0] || aCksum[1
12a00 5d 21 3d 68 31 2e 61 43 6b 73 75 6d 5b 31 5d 20  ]!=h1.aCksum[1] 
12a10 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b  ){.    return 1;
12a20 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 64     /* Checksum d
12a30 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68 20 2a 2f  oes not match */
12a40 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6d 65 6d 63  .  }..  if( memc
12a50 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 26  mp(&pWal->hdr, &
12a60 68 31 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  h1, sizeof(WalIn
12a70 64 65 78 48 64 72 29 29 20 29 7b 0a 20 20 20 20  dexHdr)) ){.    
12a80 2a 70 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20  *pChanged = 1;. 
12a90 20 20 20 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d     memcpy(&pWal-
12aa0 3e 68 64 72 2c 20 26 68 31 2c 20 73 69 7a 65 6f  >hdr, &h1, sizeo
12ab0 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b  f(WalIndexHdr));
12ac0 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50 61 67  .    pWal->szPag
12ad0 65 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72 2e 73  e = (pWal->hdr.s
12ae0 7a 50 61 67 65 26 30 78 66 65 30 30 29 20 2b 20  zPage&0xfe00) + 
12af0 28 28 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61  ((pWal->hdr.szPa
12b00 67 65 26 30 78 30 30 30 31 29 3c 3c 31 36 29 3b  ge&0x0001)<<16);
12b10 0a 20 20 20 20 74 65 73 74 63 61 73 65 28 20 70  .    testcase( p
12b20 57 61 6c 2d 3e 73 7a 50 61 67 65 3c 3d 33 32 37  Wal->szPage<=327
12b30 36 38 20 29 3b 0a 20 20 20 20 74 65 73 74 63 61  68 );.    testca
12b40 73 65 28 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65  se( pWal->szPage
12b50 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 7d 0a 0a  >=65536 );.  }..
12b60 20 20 2f 2a 20 54 68 65 20 68 65 61 64 65 72 20    /* The header 
12b70 77 61 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79  was successfully
12b80 20 72 65 61 64 2e 20 52 65 74 75 72 6e 20 7a 65   read. Return ze
12b90 72 6f 2e 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20  ro. */.  return 
12ba0 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64  0;.}../*.** Read
12bb0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
12bc0 65 61 64 65 72 20 66 72 6f 6d 20 74 68 65 20 77  eader from the w
12bd0 61 6c 2d 69 6e 64 65 78 20 61 6e 64 20 69 6e 74  al-index and int
12be0 6f 20 70 57 61 6c 2d 3e 68 64 72 2e 0a 2a 2a 20  o pWal->hdr..** 
12bf0 49 66 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65  If the wal-heade
12c00 72 20 61 70 70 65 61 72 73 20 74 6f 20 62 65 20  r appears to be 
12c10 63 6f 72 72 75 70 74 2c 20 74 72 79 20 74 6f 20  corrupt, try to 
12c20 72 65 63 6f 6e 73 74 72 75 63 74 20 74 68 65 0a  reconstruct the.
12c30 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 66 72 6f  ** wal-index fro
12c40 6d 20 74 68 65 20 57 41 4c 20 62 65 66 6f 72 65  m the WAL before
12c50 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2a 0a 2a   returning..**.*
12c60 2a 20 53 65 74 20 2a 70 43 68 61 6e 67 65 64 20  * Set *pChanged 
12c70 74 6f 20 31 20 69 66 20 74 68 65 20 77 61 6c 2d  to 1 if the wal-
12c80 69 6e 64 65 78 20 68 65 61 64 65 72 20 76 61 6c  index header val
12c90 75 65 20 69 6e 20 70 57 61 6c 2d 3e 68 64 72 20  ue in pWal->hdr 
12ca0 69 73 0a 2a 2a 20 63 68 61 6e 67 65 64 20 62 79  is.** changed by
12cb0 20 74 68 69 73 20 6f 70 65 72 61 74 69 6f 6e 2e   this operation.
12cc0 20 20 49 66 20 70 57 61 6c 2d 3e 68 64 72 20 69    If pWal->hdr i
12cd0 73 20 75 6e 63 68 61 6e 67 65 64 2c 20 73 65 74  s unchanged, set
12ce0 20 2a 70 43 68 61 6e 67 65 64 0a 2a 2a 20 74 6f   *pChanged.** to
12cf0 20 30 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65   0..**.** If the
12d00 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
12d10 72 20 69 73 20 73 75 63 63 65 73 73 66 75 6c 6c  r is successfull
12d20 79 20 72 65 61 64 2c 20 72 65 74 75 72 6e 20 53  y read, return S
12d30 51 4c 49 54 45 5f 4f 4b 2e 20 0a 2a 2a 20 4f 74  QLITE_OK. .** Ot
12d40 68 65 72 77 69 73 65 20 61 6e 20 53 51 4c 69 74  herwise an SQLit
12d50 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f  e error code..*/
12d60 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49  .static int walI
12d70 6e 64 65 78 52 65 61 64 48 64 72 28 57 61 6c 20  ndexReadHdr(Wal 
12d80 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61  *pWal, int *pCha
12d90 6e 67 65 64 29 7b 0a 20 20 69 6e 74 20 72 63 3b  nged){.  int rc;
12da0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12db0 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
12dc0 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74  rn code */.  int
12dd0 20 62 61 64 48 64 72 3b 20 20 20 20 20 20 20 20   badHdr;        
12de0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12df0 54 72 75 65 20 69 66 20 61 20 68 65 61 64 65 72  True if a header
12e00 20 72 65 61 64 20 66 61 69 6c 65 64 20 2a 2f 0a   read failed */.
12e10 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a    volatile u32 *
12e20 70 61 67 65 30 3b 20 20 20 20 20 20 20 20 20 20  page0;          
12e30 20 20 2f 2a 20 43 68 75 6e 6b 20 6f 66 20 77 61    /* Chunk of wa
12e40 6c 2d 69 6e 64 65 78 20 63 6f 6e 74 61 69 6e 69  l-index containi
12e50 6e 67 20 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20  ng header */..  
12e60 2f 2a 20 45 6e 73 75 72 65 20 74 68 61 74 20 70  /* Ensure that p
12e70 61 67 65 20 30 20 6f 66 20 74 68 65 20 77 61 6c  age 0 of the wal
12e80 2d 69 6e 64 65 78 20 28 74 68 65 20 70 61 67 65  -index (the page
12e90 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74   that contains t
12ea0 68 65 20 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64  he .  ** wal-ind
12eb0 65 78 20 68 65 61 64 65 72 29 20 69 73 20 6d 61  ex header) is ma
12ec0 70 70 65 64 2e 20 52 65 74 75 72 6e 20 65 61 72  pped. Return ear
12ed0 6c 79 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f  ly if an error o
12ee0 63 63 75 72 73 20 68 65 72 65 2e 0a 20 20 2a 2f  ccurs here..  */
12ef0 0a 20 20 61 73 73 65 72 74 28 20 70 43 68 61 6e  .  assert( pChan
12f00 67 65 64 20 29 3b 0a 20 20 72 63 20 3d 20 77 61  ged );.  rc = wa
12f10 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c  lIndexPage(pWal,
12f20 20 30 2c 20 26 70 61 67 65 30 29 3b 0a 20 20 69   0, &page0);.  i
12f30 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
12f40 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72   ){.    return r
12f50 63 3b 0a 20 20 7d 3b 0a 20 20 61 73 73 65 72 74  c;.  };.  assert
12f60 28 20 70 61 67 65 30 20 7c 7c 20 70 57 61 6c 2d  ( page0 || pWal-
12f70 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b  >writeLock==0 );
12f80 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69  ..  /* If the fi
12f90 72 73 74 20 70 61 67 65 20 6f 66 20 74 68 65 20  rst page of the 
12fa0 77 61 6c 2d 69 6e 64 65 78 20 68 61 73 20 62 65  wal-index has be
12fb0 65 6e 20 6d 61 70 70 65 64 2c 20 74 72 79 20 74  en mapped, try t
12fc0 6f 20 72 65 61 64 20 74 68 65 0a 20 20 2a 2a 20  o read the.  ** 
12fd0 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
12fe0 20 69 6d 6d 65 64 69 61 74 65 6c 79 2c 20 77 69   immediately, wi
12ff0 74 68 6f 75 74 20 68 6f 6c 64 69 6e 67 20 61 6e  thout holding an
13000 79 20 6c 6f 63 6b 2e 20 54 68 69 73 20 75 73 75  y lock. This usu
13010 61 6c 6c 79 0a 20 20 2a 2a 20 77 6f 72 6b 73 2c  ally.  ** works,
13020 20 62 75 74 20 6d 61 79 20 66 61 69 6c 20 69 66   but may fail if
13030 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
13040 65 61 64 65 72 20 69 73 20 63 6f 72 72 75 70 74  eader is corrupt
13050 20 6f 72 20 63 75 72 72 65 6e 74 6c 79 20 0a 20   or currently . 
13060 20 2a 2a 20 62 65 69 6e 67 20 6d 6f 64 69 66 69   ** being modifi
13070 65 64 20 62 79 20 61 6e 6f 74 68 65 72 20 74 68  ed by another th
13080 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 2e  read or process.
13090 0a 20 20 2a 2f 0a 20 20 62 61 64 48 64 72 20 3d  .  */.  badHdr =
130a0 20 28 70 61 67 65 30 20 3f 20 77 61 6c 49 6e 64   (page0 ? walInd
130b0 65 78 54 72 79 48 64 72 28 70 57 61 6c 2c 20 70  exTryHdr(pWal, p
130c0 43 68 61 6e 67 65 64 29 20 3a 20 31 29 3b 0a 0a  Changed) : 1);..
130d0 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72 73    /* If the firs
130e0 74 20 61 74 74 65 6d 70 74 20 66 61 69 6c 65 64  t attempt failed
130f0 2c 20 69 74 20 6d 69 67 68 74 20 68 61 76 65 20  , it might have 
13100 62 65 65 6e 20 64 75 65 20 74 6f 20 61 20 72 61  been due to a ra
13110 63 65 0a 20 20 2a 2a 20 77 69 74 68 20 61 20 77  ce.  ** with a w
13120 72 69 74 65 72 2e 20 20 53 6f 20 67 65 74 20 61  riter.  So get a
13130 20 57 52 49 54 45 20 6c 6f 63 6b 20 61 6e 64 20   WRITE lock and 
13140 74 72 79 20 61 67 61 69 6e 2e 0a 20 20 2a 2f 0a  try again..  */.
13150 20 20 61 73 73 65 72 74 28 20 62 61 64 48 64 72    assert( badHdr
13160 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 77 72 69  ==0 || pWal->wri
13170 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 69  teLock==0 );.  i
13180 66 28 20 62 61 64 48 64 72 20 29 7b 0a 20 20 20  f( badHdr ){.   
13190 20 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4f   if( pWal->readO
131a0 6e 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52 44  nly & WAL_SHM_RD
131b0 4f 4e 4c 59 20 29 7b 0a 20 20 20 20 20 20 69 66  ONLY ){.      if
131c0 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63  ( SQLITE_OK==(rc
131d0 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64   = walLockShared
131e0 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45  (pWal, WAL_WRITE
131f0 5f 4c 4f 43 4b 29 29 20 29 7b 0a 20 20 20 20 20  _LOCK)) ){.     
13200 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72     walUnlockShar
13210 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49  ed(pWal, WAL_WRI
13220 54 45 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 20 20  TE_LOCK);.      
13230 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 52 45    rc = SQLITE_RE
13240 41 44 4f 4e 4c 59 5f 52 45 43 4f 56 45 52 59 3b  ADONLY_RECOVERY;
13250 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c  .      }.    }el
13260 73 65 20 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b  se if( SQLITE_OK
13270 3d 3d 28 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45  ==(rc = walLockE
13280 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
13290 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31  AL_WRITE_LOCK, 1
132a0 29 29 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c  )) ){.      pWal
132b0 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 31 3b  ->writeLock = 1;
132c0 0a 20 20 20 20 20 20 69 66 28 20 53 51 4c 49 54  .      if( SQLIT
132d0 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c 49  E_OK==(rc = walI
132e0 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20 30  ndexPage(pWal, 0
132f0 2c 20 26 70 61 67 65 30 29 29 20 29 7b 0a 20 20  , &page0)) ){.  
13300 20 20 20 20 20 20 62 61 64 48 64 72 20 3d 20 77        badHdr = w
13310 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28 70 57  alIndexTryHdr(pW
13320 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b 0a 20  al, pChanged);. 
13330 20 20 20 20 20 20 20 69 66 28 20 62 61 64 48 64         if( badHd
13340 72 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2f  r ){.          /
13350 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  * If the wal-ind
13360 65 78 20 68 65 61 64 65 72 20 69 73 20 73 74 69  ex header is sti
13370 6c 6c 20 6d 61 6c 66 6f 72 6d 65 64 20 65 76 65  ll malformed eve
13380 6e 20 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67 0a  n while holding.
13390 20 20 20 20 20 20 20 20 20 20 2a 2a 20 61 20 57            ** a W
133a0 52 49 54 45 20 6c 6f 63 6b 2c 20 69 74 20 63 61  RITE lock, it ca
133b0 6e 20 6f 6e 6c 79 20 6d 65 61 6e 20 74 68 61 74  n only mean that
133c0 20 74 68 65 20 68 65 61 64 65 72 20 69 73 20 63   the header is c
133d0 6f 72 72 75 70 74 65 64 20 61 6e 64 0a 20 20 20  orrupted and.   
133e0 20 20 20 20 20 20 20 2a 2a 20 6e 65 65 64 73 20         ** needs 
133f0 74 6f 20 62 65 20 72 65 63 6f 6e 73 74 72 75 63  to be reconstruc
13400 74 65 64 2e 20 20 53 6f 20 72 75 6e 20 72 65 63  ted.  So run rec
13410 6f 76 65 72 79 20 74 6f 20 64 6f 20 65 78 61 63  overy to do exac
13420 74 6c 79 20 74 68 61 74 2e 0a 20 20 20 20 20 20  tly that..      
13430 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 20      */.         
13440 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52 65   rc = walIndexRe
13450 63 6f 76 65 72 28 70 57 61 6c 29 3b 0a 20 20 20  cover(pWal);.   
13460 20 20 20 20 20 20 20 2a 70 43 68 61 6e 67 65 64         *pChanged
13470 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a   = 1;.        }.
13480 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 57        }.      pW
13490 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20  al->writeLock = 
134a0 30 3b 0a 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f  0;.      walUnlo
134b0 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
134c0 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b  , WAL_WRITE_LOCK
134d0 2c 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  , 1);.    }.  }.
134e0 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 68 65 61  .  /* If the hea
134f0 64 65 72 20 69 73 20 72 65 61 64 20 73 75 63 63  der is read succ
13500 65 73 73 66 75 6c 6c 79 2c 20 63 68 65 63 6b 20  essfully, check 
13510 74 68 65 20 76 65 72 73 69 6f 6e 20 6e 75 6d 62  the version numb
13520 65 72 20 74 6f 20 6d 61 6b 65 0a 20 20 2a 2a 20  er to make.  ** 
13530 73 75 72 65 20 74 68 65 20 77 61 6c 2d 69 6e 64  sure the wal-ind
13540 65 78 20 77 61 73 20 6e 6f 74 20 63 6f 6e 73 74  ex was not const
13550 72 75 63 74 65 64 20 77 69 74 68 20 73 6f 6d 65  ructed with some
13560 20 66 75 74 75 72 65 20 66 6f 72 6d 61 74 20 74   future format t
13570 68 61 74 0a 20 20 2a 2a 20 74 68 69 73 20 76 65  hat.  ** this ve
13580 72 73 69 6f 6e 20 6f 66 20 53 51 4c 69 74 65 20  rsion of SQLite 
13590 63 61 6e 6e 6f 74 20 75 6e 64 65 72 73 74 61 6e  cannot understan
135a0 64 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 62 61  d..  */.  if( ba
135b0 64 48 64 72 3d 3d 30 20 26 26 20 70 57 61 6c 2d  dHdr==0 && pWal-
135c0 3e 68 64 72 2e 69 56 65 72 73 69 6f 6e 21 3d 57  >hdr.iVersion!=W
135d0 41 4c 49 4e 44 45 58 5f 4d 41 58 5f 56 45 52 53  ALINDEX_MAX_VERS
135e0 49 4f 4e 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  ION ){.    rc = 
135f0 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 5f  SQLITE_CANTOPEN_
13600 42 4b 50 54 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  BKPT;.  }..  ret
13610 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
13620 20 54 68 69 73 20 69 73 20 74 68 65 20 76 61 6c   This is the val
13630 75 65 20 74 68 61 74 20 77 61 6c 54 72 79 42 65  ue that walTryBe
13640 67 69 6e 52 65 61 64 20 72 65 74 75 72 6e 73 20  ginRead returns 
13650 77 68 65 6e 20 69 74 20 6e 65 65 64 73 20 74 6f  when it needs to
13660 0a 2a 2a 20 62 65 20 72 65 74 72 69 65 64 2e 0a  .** be retried..
13670 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 52  */.#define WAL_R
13680 45 54 52 59 20 20 28 2d 31 29 0a 0a 2f 2a 0a 2a  ETRY  (-1)../*.*
13690 2a 20 41 74 74 65 6d 70 74 20 74 6f 20 73 74 61  * Attempt to sta
136a0 72 74 20 61 20 72 65 61 64 20 74 72 61 6e 73 61  rt a read transa
136b0 63 74 69 6f 6e 2e 20 20 54 68 69 73 20 6d 69 67  ction.  This mig
136c0 68 74 20 66 61 69 6c 20 64 75 65 20 74 6f 20 61  ht fail due to a
136d0 20 72 61 63 65 20 6f 72 0a 2a 2a 20 6f 74 68 65   race or.** othe
136e0 72 20 74 72 61 6e 73 69 65 6e 74 20 63 6f 6e 64  r transient cond
136f0 69 74 69 6f 6e 2e 20 20 57 68 65 6e 20 74 68 61  ition.  When tha
13700 74 20 68 61 70 70 65 6e 73 2c 20 69 74 20 72 65  t happens, it re
13710 74 75 72 6e 73 20 57 41 4c 5f 52 45 54 52 59 20  turns WAL_RETRY 
13720 74 6f 0a 2a 2a 20 69 6e 64 69 63 61 74 65 20 74  to.** indicate t
13730 6f 20 74 68 65 20 63 61 6c 6c 65 72 20 74 68 61  o the caller tha
13740 74 20 69 74 20 69 73 20 73 61 66 65 20 74 6f 20  t it is safe to 
13750 72 65 74 72 79 20 69 6d 6d 65 64 69 61 74 65 6c  retry immediatel
13760 79 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63  y..**.** On succ
13770 65 73 73 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ess return SQLIT
13780 45 5f 4f 4b 2e 20 20 4f 6e 20 61 20 70 65 72 6d  E_OK.  On a perm
13790 61 6e 65 6e 74 20 66 61 69 6c 75 72 65 20 28 73  anent failure (s
137a0 75 63 68 20 61 6e 0a 2a 2a 20 49 2f 4f 20 65 72  uch an.** I/O er
137b0 72 6f 72 20 6f 72 20 61 6e 20 53 51 4c 49 54 45  ror or an SQLITE
137c0 5f 42 55 53 59 20 62 65 63 61 75 73 65 20 61 6e  _BUSY because an
137d0 6f 74 68 65 72 20 70 72 6f 63 65 73 73 20 69 73  other process is
137e0 20 72 75 6e 6e 69 6e 67 0a 2a 2a 20 72 65 63 6f   running.** reco
137f0 76 65 72 79 29 20 72 65 74 75 72 6e 20 61 20 70  very) return a p
13800 6f 73 69 74 69 76 65 20 65 72 72 6f 72 20 63 6f  ositive error co
13810 64 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 75 73  de..**.** The us
13820 65 57 61 6c 20 70 61 72 61 6d 65 74 65 72 20 69  eWal parameter i
13830 73 20 74 72 75 65 20 74 6f 20 66 6f 72 63 65 20  s true to force 
13840 74 68 65 20 75 73 65 20 6f 66 20 74 68 65 20 57  the use of the W
13850 41 4c 20 61 6e 64 20 64 69 73 61 62 6c 65 0a 2a  AL and disable.*
13860 2a 20 74 68 65 20 63 61 73 65 20 77 68 65 72 65  * the case where
13870 20 74 68 65 20 57 41 4c 20 69 73 20 62 79 70 61   the WAL is bypa
13880 73 73 65 64 20 62 65 63 61 75 73 65 20 69 74 20  ssed because it 
13890 68 61 73 20 62 65 65 6e 20 63 6f 6d 70 6c 65 74  has been complet
138a0 65 6c 79 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e  ely.** checkpoin
138b0 74 65 64 2e 20 20 49 66 20 75 73 65 57 61 6c 3d  ted.  If useWal=
138c0 3d 30 20 74 68 65 6e 20 74 68 69 73 20 72 6f 75  =0 then this rou
138d0 74 69 6e 65 20 63 61 6c 6c 73 20 77 61 6c 49 6e  tine calls walIn
138e0 64 65 78 52 65 61 64 48 64 72 28 29 20 0a 2a 2a  dexReadHdr() .**
138f0 20 74 6f 20 6d 61 6b 65 20 61 20 63 6f 70 79 20   to make a copy 
13900 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
13910 20 68 65 61 64 65 72 20 69 6e 74 6f 20 70 57 61   header into pWa
13920 6c 2d 3e 68 64 72 2e 20 20 49 66 20 74 68 65 20  l->hdr.  If the 
13930 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  .** wal-index he
13940 61 64 65 72 20 68 61 73 20 63 68 61 6e 67 65 64  ader has changed
13950 2c 20 2a 70 43 68 61 6e 67 65 64 20 69 73 20 73  , *pChanged is s
13960 65 74 20 74 6f 20 31 20 28 61 73 20 61 6e 20 69  et to 1 (as an i
13970 6e 64 69 63 61 74 69 6f 6e 20 0a 2a 2a 20 74 6f  ndication .** to
13980 20 74 68 65 20 63 61 6c 6c 65 72 20 74 68 61 74   the caller that
13990 20 74 68 65 20 6c 6f 63 61 6c 20 70 61 67 65 74   the local paget
139a0 20 63 61 63 68 65 20 69 73 20 6f 62 73 6f 6c 65   cache is obsole
139b0 74 65 20 61 6e 64 20 6e 65 65 64 73 20 74 6f 20  te and needs to 
139c0 62 65 20 0a 2a 2a 20 66 6c 75 73 68 65 64 2e 29  be .** flushed.)
139d0 20 20 57 68 65 6e 20 75 73 65 57 61 6c 3d 3d 31    When useWal==1
139e0 2c 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  , the wal-index 
139f0 68 65 61 64 65 72 20 69 73 20 61 73 73 75 6d 65  header is assume
13a00 64 20 74 6f 20 61 6c 72 65 61 64 79 0a 2a 2a 20  d to already.** 
13a10 62 65 20 6c 6f 61 64 65 64 20 61 6e 64 20 74 68  be loaded and th
13a20 65 20 70 43 68 61 6e 67 65 64 20 70 61 72 61 6d  e pChanged param
13a30 65 74 65 72 20 69 73 20 75 6e 75 73 65 64 2e 0a  eter is unused..
13a40 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 65 72  **.** The caller
13a50 20 6d 75 73 74 20 73 65 74 20 74 68 65 20 63 6e   must set the cn
13a60 74 20 70 61 72 61 6d 65 74 65 72 20 74 6f 20 74  t parameter to t
13a70 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70 72 69  he number of pri
13a80 6f 72 20 63 61 6c 6c 73 20 74 6f 0a 2a 2a 20 74  or calls to.** t
13a90 68 69 73 20 72 6f 75 74 69 6e 65 20 64 75 72 69  his routine duri
13aa0 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74 20 72  ng the current r
13ab0 65 61 64 20 61 74 74 65 6d 70 74 20 74 68 61 74  ead attempt that
13ac0 20 72 65 74 75 72 6e 65 64 20 57 41 4c 5f 52 45   returned WAL_RE
13ad0 54 52 59 2e 0a 2a 2a 20 54 68 69 73 20 72 6f 75  TRY..** This rou
13ae0 74 69 6e 65 20 77 69 6c 6c 20 73 74 61 72 74 20  tine will start 
13af0 74 61 6b 69 6e 67 20 6d 6f 72 65 20 61 67 67 72  taking more aggr
13b00 65 73 73 69 76 65 20 6d 65 61 73 75 72 65 73 20  essive measures 
13b10 74 6f 20 63 6c 65 61 72 20 74 68 65 0a 2a 2a 20  to clear the.** 
13b20 72 61 63 65 20 63 6f 6e 64 69 74 69 6f 6e 73 20  race conditions 
13b30 61 66 74 65 72 20 6d 75 6c 74 69 70 6c 65 20 57  after multiple W
13b40 41 4c 5f 52 45 54 52 59 20 72 65 74 75 72 6e 73  AL_RETRY returns
13b50 2c 20 61 6e 64 20 61 66 74 65 72 20 61 6e 20 65  , and after an e
13b60 78 63 65 73 73 69 76 65 0a 2a 2a 20 6e 75 6d 62  xcessive.** numb
13b70 65 72 20 6f 66 20 65 72 72 6f 72 73 20 77 69 6c  er of errors wil
13b80 6c 20 75 6c 74 69 6d 61 74 65 6c 79 20 72 65 74  l ultimately ret
13b90 75 72 6e 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f  urn SQLITE_PROTO
13ba0 43 4f 4c 2e 20 20 54 68 65 0a 2a 2a 20 53 51 4c  COL.  The.** SQL
13bb0 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 20 72 65 74  ITE_PROTOCOL ret
13bc0 75 72 6e 20 69 6e 64 69 63 61 74 65 73 20 74 68  urn indicates th
13bd0 61 74 20 73 6f 6d 65 20 6f 74 68 65 72 20 70 72  at some other pr
13be0 6f 63 65 73 73 20 68 61 73 20 67 6f 6e 65 20 72  ocess has gone r
13bf0 6f 67 75 65 0a 2a 2a 20 61 6e 64 20 69 73 20 6e  ogue.** and is n
13c00 6f 74 20 68 6f 6e 6f 72 69 6e 67 20 74 68 65 20  ot honoring the 
13c10 6c 6f 63 6b 69 6e 67 20 70 72 6f 74 6f 63 6f 6c  locking protocol
13c20 2e 20 20 54 68 65 72 65 20 69 73 20 61 20 76 61  .  There is a va
13c30 6e 69 73 68 69 6e 67 6c 79 20 73 6d 61 6c 6c 0a  nishingly small.
13c40 2a 2a 20 63 68 61 6e 63 65 20 74 68 61 74 20 53  ** chance that S
13c50 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 20 63  QLITE_PROTOCOL c
13c60 6f 75 6c 64 20 62 65 20 72 65 74 75 72 6e 65 64  ould be returned
13c70 20 62 65 63 61 75 73 65 20 6f 66 20 61 20 72 75   because of a ru
13c80 6e 20 6f 66 20 72 65 61 6c 6c 79 0a 2a 2a 20 62  n of really.** b
13c90 61 64 20 6c 75 63 6b 20 77 68 65 6e 20 74 68 65  ad luck when the
13ca0 72 65 20 69 73 20 6c 6f 74 73 20 6f 66 20 63 6f  re is lots of co
13cb0 6e 74 65 6e 74 69 6f 6e 20 66 6f 72 20 74 68 65  ntention for the
13cc0 20 77 61 6c 2d 69 6e 64 65 78 2c 20 62 75 74 20   wal-index, but 
13cd0 74 68 61 74 0a 2a 2a 20 70 6f 73 73 69 62 69 6c  that.** possibil
13ce0 69 74 79 20 69 73 20 73 6f 20 73 6d 61 6c 6c 20  ity is so small 
13cf0 74 68 61 74 20 69 74 20 63 61 6e 20 62 65 20 73  that it can be s
13d00 61 66 65 6c 79 20 6e 65 67 6c 65 63 74 65 64 2c  afely neglected,
13d10 20 77 65 20 62 65 6c 69 65 76 65 2e 0a 2a 2a 0a   we believe..**.
13d20 2a 2a 20 4f 6e 20 73 75 63 63 65 73 73 2c 20 74  ** On success, t
13d30 68 69 73 20 72 6f 75 74 69 6e 65 20 6f 62 74 61  his routine obta
13d40 69 6e 73 20 61 20 72 65 61 64 20 6c 6f 63 6b 20  ins a read lock 
13d50 6f 6e 20 0a 2a 2a 20 57 41 4c 5f 52 45 41 44 5f  on .** WAL_READ_
13d60 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c  LOCK(pWal->readL
13d70 6f 63 6b 29 2e 20 20 54 68 65 20 70 57 61 6c 2d  ock).  The pWal-
13d80 3e 72 65 61 64 4c 6f 63 6b 20 69 6e 74 65 67 65  >readLock intege
13d90 72 20 69 73 0a 2a 2a 20 69 6e 20 74 68 65 20 72  r is.** in the r
13da0 61 6e 67 65 20 30 20 3c 3d 20 70 57 61 6c 2d 3e  ange 0 <= pWal->
13db0 72 65 61 64 4c 6f 63 6b 20 3c 20 57 41 4c 5f 4e  readLock < WAL_N
13dc0 52 45 41 44 45 52 2e 20 20 49 66 20 70 57 61 6c  READER.  If pWal
13dd0 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 28 2d 31 29  ->readLock==(-1)
13de0 0a 2a 2a 20 74 68 61 74 20 6d 65 61 6e 73 20 74  .** that means t
13df0 68 65 20 57 61 6c 20 64 6f 65 73 20 6e 6f 74 20  he Wal does not 
13e00 68 6f 6c 64 20 61 6e 79 20 72 65 61 64 20 6c 6f  hold any read lo
13e10 63 6b 2e 20 20 54 68 65 20 72 65 61 64 65 72 20  ck.  The reader 
13e20 6d 75 73 74 20 6e 6f 74 0a 2a 2a 20 61 63 63 65  must not.** acce
13e30 73 73 20 61 6e 79 20 64 61 74 61 62 61 73 65 20  ss any database 
13e40 70 61 67 65 20 74 68 61 74 20 69 73 20 6d 6f 64  page that is mod
13e50 69 66 69 65 64 20 62 79 20 61 20 57 41 4c 20 66  ified by a WAL f
13e60 72 61 6d 65 20 75 70 20 74 6f 20 61 6e 64 0a 2a  rame up to and.*
13e70 2a 20 69 6e 63 6c 75 64 69 6e 67 20 66 72 61 6d  * including fram
13e80 65 20 6e 75 6d 62 65 72 20 61 52 65 61 64 4d 61  e number aReadMa
13e90 72 6b 5b 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  rk[pWal->readLoc
13ea0 6b 5d 2e 20 20 54 68 65 20 72 65 61 64 65 72 20  k].  The reader 
13eb0 77 69 6c 6c 0a 2a 2a 20 75 73 65 20 57 41 4c 20  will.** use WAL 
13ec0 66 72 61 6d 65 73 20 75 70 20 74 6f 20 61 6e 64  frames up to and
13ed0 20 69 6e 63 6c 75 64 69 6e 67 20 70 57 61 6c 2d   including pWal-
13ee0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 66 20  >hdr.mxFrame if 
13ef0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 30  pWal->readLock>0
13f00 0a 2a 2a 20 4f 72 20 69 66 20 70 57 61 6c 2d 3e  .** Or if pWal->
13f10 72 65 61 64 4c 6f 63 6b 3d 3d 30 2c 20 74 68 65  readLock==0, the
13f20 6e 20 74 68 65 20 72 65 61 64 65 72 20 77 69 6c  n the reader wil
13f30 6c 20 69 67 6e 6f 72 65 20 74 68 65 20 57 41 4c  l ignore the WAL
13f40 0a 2a 2a 20 63 6f 6d 70 6c 65 74 65 6c 79 20 61  .** completely a
13f50 6e 64 20 67 65 74 20 61 6c 6c 20 63 6f 6e 74 65  nd get all conte
13f60 6e 74 20 64 69 72 65 63 74 6c 79 20 66 72 6f 6d  nt directly from
13f70 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
13f80 6c 65 2e 0a 2a 2a 20 49 66 20 74 68 65 20 75 73  le..** If the us
13f90 65 57 61 6c 20 70 61 72 61 6d 65 74 65 72 20 69  eWal parameter i
13fa0 73 20 31 20 74 68 65 6e 20 74 68 65 20 57 41 4c  s 1 then the WAL
13fb0 20 77 69 6c 6c 20 6e 65 76 65 72 20 62 65 20 69   will never be i
13fc0 67 6e 6f 72 65 64 20 61 6e 64 0a 2a 2a 20 74 68  gnored and.** th
13fd0 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20  is routine will 
13fe0 61 6c 77 61 79 73 20 73 65 74 20 70 57 61 6c 2d  always set pWal-
13ff0 3e 72 65 61 64 4c 6f 63 6b 3e 30 20 6f 6e 20 73  >readLock>0 on s
14000 75 63 63 65 73 73 2e 0a 2a 2a 20 57 68 65 6e 20  uccess..** When 
14010 74 68 65 20 72 65 61 64 20 74 72 61 6e 73 61 63  the read transac
14020 74 69 6f 6e 20 69 73 20 63 6f 6d 70 6c 65 74 65  tion is complete
14030 64 2c 20 74 68 65 20 63 61 6c 6c 65 72 20 6d 75  d, the caller mu
14040 73 74 20 72 65 6c 65 61 73 65 20 74 68 65 0a 2a  st release the.*
14050 2a 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52 45  * lock on WAL_RE
14060 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65  AD_LOCK(pWal->re
14070 61 64 4c 6f 63 6b 29 20 61 6e 64 20 73 65 74 20  adLock) and set 
14080 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 74  pWal->readLock t
14090 6f 20 2d 31 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  o -1..**.** This
140a0 20 72 6f 75 74 69 6e 65 20 75 73 65 73 20 74 68   routine uses th
140b0 65 20 6e 42 61 63 6b 66 69 6c 6c 20 61 6e 64 20  e nBackfill and 
140c0 61 52 65 61 64 4d 61 72 6b 5b 5d 20 66 69 65 6c  aReadMark[] fiel
140d0 64 73 20 6f 66 20 74 68 65 20 68 65 61 64 65 72  ds of the header
140e0 0a 2a 2a 20 74 6f 20 73 65 6c 65 63 74 20 61 20  .** to select a 
140f0 70 61 72 74 69 63 75 6c 61 72 20 57 41 4c 5f 52  particular WAL_R
14100 45 41 44 5f 4c 4f 43 4b 28 29 20 74 68 61 74 20  EAD_LOCK() that 
14110 73 74 72 69 76 65 73 20 74 6f 20 6c 65 74 20 74  strives to let t
14120 68 65 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74  he.** checkpoint
14130 20 70 72 6f 63 65 73 73 20 64 6f 20 61 73 20 6d   process do as m
14140 75 63 68 20 77 6f 72 6b 20 61 73 20 70 6f 73 73  uch work as poss
14150 69 62 6c 65 2e 20 20 54 68 69 73 20 72 6f 75 74  ible.  This rout
14160 69 6e 65 20 6d 69 67 68 74 0a 2a 2a 20 75 70 64  ine might.** upd
14170 61 74 65 20 76 61 6c 75 65 73 20 6f 66 20 74 68  ate values of th
14180 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 61 72  e aReadMark[] ar
14190 72 61 79 20 69 6e 20 74 68 65 20 68 65 61 64 65  ray in the heade
141a0 72 2c 20 62 75 74 20 69 66 20 69 74 20 64 6f 65  r, but if it doe
141b0 73 0a 2a 2a 20 73 6f 20 69 74 20 74 61 6b 65 73  s.** so it takes
141c0 20 63 61 72 65 20 74 6f 20 68 6f 6c 64 20 61 6e   care to hold an
141d0 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20   exclusive lock 
141e0 6f 6e 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e  on the correspon
141f0 64 69 6e 67 0a 2a 2a 20 57 41 4c 5f 52 45 41 44  ding.** WAL_READ
14200 5f 4c 4f 43 4b 28 29 20 77 68 69 6c 65 20 63 68  _LOCK() while ch
14210 61 6e 67 69 6e 67 20 76 61 6c 75 65 73 2e 0a 2a  anging values..*
14220 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
14230 54 72 79 42 65 67 69 6e 52 65 61 64 28 57 61 6c  TryBeginRead(Wal
14240 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68   *pWal, int *pCh
14250 61 6e 67 65 64 2c 20 69 6e 74 20 75 73 65 57 61  anged, int useWa
14260 6c 2c 20 69 6e 74 20 63 6e 74 29 7b 0a 20 20 76  l, int cnt){.  v
14270 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49  olatile WalCkptI
14280 6e 66 6f 20 2a 70 49 6e 66 6f 3b 20 20 20 20 2f  nfo *pInfo;    /
14290 2a 20 43 68 65 63 6b 70 6f 69 6e 74 20 69 6e 66  * Checkpoint inf
142a0 6f 72 6d 61 74 69 6f 6e 20 69 6e 20 77 61 6c 2d  ormation in wal-
142b0 69 6e 64 65 78 20 2a 2f 0a 20 20 75 33 32 20 6d  index */.  u32 m
142c0 78 52 65 61 64 4d 61 72 6b 3b 20 20 20 20 20 20  xReadMark;      
142d0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
142e0 72 67 65 73 74 20 61 52 65 61 64 4d 61 72 6b 5b  rgest aReadMark[
142f0 5d 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74  ] value */.  int
14300 20 6d 78 49 3b 20 20 20 20 20 20 20 20 20 20 20   mxI;           
14310 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
14320 49 6e 64 65 78 20 6f 66 20 6c 61 72 67 65 73 74  Index of largest
14330 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 76 61 6c   aReadMark[] val
14340 75 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20  ue */.  int i;  
14350 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14360 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20          /* Loop 
14370 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 69 6e 74  counter */.  int
14380 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
14390 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
143a0 52 65 74 75 72 6e 20 63 6f 64 65 20 20 2a 2f 0a  Return code  */.
143b0 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
143c0 3e 72 65 61 64 4c 6f 63 6b 3c 30 20 29 3b 20 20  >readLock<0 );  
143d0 20 20 20 2f 2a 20 4e 6f 74 20 63 75 72 72 65 6e     /* Not curren
143e0 74 6c 79 20 6c 6f 63 6b 65 64 20 2a 2f 0a 0a 20  tly locked */.. 
143f0 20 2f 2a 20 54 61 6b 65 20 73 74 65 70 73 20 74   /* Take steps t
14400 6f 20 61 76 6f 69 64 20 73 70 69 6e 6e 69 6e 67  o avoid spinning
14410 20 66 6f 72 65 76 65 72 20 69 66 20 74 68 65 72   forever if ther
14420 65 20 69 73 20 61 20 70 72 6f 74 6f 63 6f 6c 20  e is a protocol 
14430 65 72 72 6f 72 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  error..  **.  **
14440 20 43 69 72 63 75 6d 73 74 61 6e 63 65 73 20 74   Circumstances t
14450 68 61 74 20 63 61 75 73 65 20 61 20 52 45 54 52  hat cause a RETR
14460 59 20 73 68 6f 75 6c 64 20 6f 6e 6c 79 20 6c 61  Y should only la
14470 73 74 20 66 6f 72 20 74 68 65 20 62 72 69 65 66  st for the brief
14480 65 73 74 0a 20 20 2a 2a 20 69 6e 73 74 61 6e 63  est.  ** instanc
14490 65 73 20 6f 66 20 74 69 6d 65 2e 20 20 4e 6f 20  es of time.  No 
144a0 49 2f 4f 20 6f 72 20 6f 74 68 65 72 20 73 79 73  I/O or other sys
144b0 74 65 6d 20 63 61 6c 6c 73 20 61 72 65 20 64 6f  tem calls are do
144c0 6e 65 20 77 68 69 6c 65 20 74 68 65 0a 20 20 2a  ne while the.  *
144d0 2a 20 6c 6f 63 6b 73 20 61 72 65 20 68 65 6c 64  * locks are held
144e0 2c 20 73 6f 20 74 68 65 20 6c 6f 63 6b 73 20 73  , so the locks s
144f0 68 6f 75 6c 64 20 6e 6f 74 20 62 65 20 68 65 6c  hould not be hel
14500 64 20 66 6f 72 20 76 65 72 79 20 6c 6f 6e 67 2e  d for very long.
14510 20 42 75 74 20 0a 20 20 2a 2a 20 69 66 20 77 65   But .  ** if we
14520 20 61 72 65 20 75 6e 6c 75 63 6b 79 2c 20 61 6e   are unlucky, an
14530 6f 74 68 65 72 20 70 72 6f 63 65 73 73 20 74 68  other process th
14540 61 74 20 69 73 20 68 6f 6c 64 69 6e 67 20 61 20  at is holding a 
14550 6c 6f 63 6b 20 6d 69 67 68 74 20 67 65 74 0a 20  lock might get. 
14560 20 2a 2a 20 70 61 67 65 64 20 6f 75 74 20 6f 72   ** paged out or
14570 20 74 61 6b 65 20 61 20 70 61 67 65 2d 66 61 75   take a page-fau
14580 6c 74 20 74 68 61 74 20 69 73 20 74 69 6d 65 2d  lt that is time-
14590 63 6f 6e 73 75 6d 69 6e 67 20 74 6f 20 72 65 73  consuming to res
145a0 6f 6c 76 65 2c 20 0a 20 20 2a 2a 20 64 75 72 69  olve, .  ** duri
145b0 6e 67 20 74 68 65 20 66 65 77 20 6e 61 6e 6f 73  ng the few nanos
145c0 65 63 6f 6e 64 73 20 74 68 61 74 20 69 74 20 69  econds that it i
145d0 73 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 6c 6f  s holding the lo
145e0 63 6b 2e 20 20 49 6e 20 74 68 61 74 20 63 61 73  ck.  In that cas
145f0 65 2c 0a 20 20 2a 2a 20 69 74 20 6d 69 67 68 74  e,.  ** it might
14600 20 74 61 6b 65 20 6c 6f 6e 67 65 72 20 74 68 61   take longer tha
14610 6e 20 6e 6f 72 6d 61 6c 20 66 6f 72 20 74 68 65  n normal for the
14620 20 6c 6f 63 6b 20 74 6f 20 66 72 65 65 2e 0a 20   lock to free.. 
14630 20 2a 2a 0a 20 20 2a 2a 20 41 66 74 65 72 20 35   **.  ** After 5
14640 20 52 45 54 52 59 73 2c 20 77 65 20 62 65 67 69   RETRYs, we begi
14650 6e 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65  n calling sqlite
14660 33 4f 73 53 6c 65 65 70 28 29 2e 20 20 54 68 65  3OsSleep().  The
14670 20 66 69 72 73 74 20 66 65 77 0a 20 20 2a 2a 20   first few.  ** 
14680 63 61 6c 6c 73 20 74 6f 20 73 71 6c 69 74 65 33  calls to sqlite3
14690 4f 73 53 6c 65 65 70 28 29 20 68 61 76 65 20 61  OsSleep() have a
146a0 20 64 65 6c 61 79 20 6f 66 20 31 20 6d 69 63 72   delay of 1 micr
146b0 6f 73 65 63 6f 6e 64 2e 20 20 52 65 61 6c 6c 79  osecond.  Really
146c0 20 74 68 69 73 0a 20 20 2a 2a 20 69 73 20 6d 6f   this.  ** is mo
146d0 72 65 20 6f 66 20 61 20 73 63 68 65 64 75 6c 65  re of a schedule
146e0 72 20 79 69 65 6c 64 20 74 68 61 6e 20 61 6e 20  r yield than an 
146f0 61 63 74 75 61 6c 20 64 65 6c 61 79 2e 20 20 42  actual delay.  B
14700 75 74 20 6f 6e 20 74 68 65 20 31 30 74 68 0a 20  ut on the 10th. 
14710 20 2a 2a 20 61 6e 20 73 75 62 73 65 71 75 65 6e   ** an subsequen
14720 74 20 72 65 74 72 69 65 73 2c 20 74 68 65 20 64  t retries, the d
14730 65 6c 61 79 73 20 73 74 61 72 74 20 62 65 63 6f  elays start beco
14740 6d 69 6e 67 20 6c 6f 6e 67 65 72 20 61 6e 64 20  ming longer and 
14750 6c 6f 6e 67 65 72 2c 20 0a 20 20 2a 2a 20 73 6f  longer, .  ** so
14760 20 74 68 61 74 20 6f 6e 20 74 68 65 20 31 30 30   that on the 100
14770 74 68 20 28 61 6e 64 20 6c 61 73 74 29 20 52 45  th (and last) RE
14780 54 52 59 20 77 65 20 64 65 6c 61 79 20 66 6f 72  TRY we delay for
14790 20 33 32 33 20 6d 69 6c 6c 69 73 65 63 6f 6e 64   323 millisecond
147a0 73 2e 0a 20 20 2a 2a 20 54 68 65 20 74 6f 74 61  s..  ** The tota
147b0 6c 20 64 65 6c 61 79 20 74 69 6d 65 20 62 65 66  l delay time bef
147c0 6f 72 65 20 67 69 76 69 6e 67 20 75 70 20 69 73  ore giving up is
147d0 20 6c 65 73 73 20 74 68 61 6e 20 31 30 20 73 65   less than 10 se
147e0 63 6f 6e 64 73 2e 0a 20 20 2a 2f 0a 20 20 69 66  conds..  */.  if
147f0 28 20 63 6e 74 3e 35 20 29 7b 0a 20 20 20 20 69  ( cnt>5 ){.    i
14800 6e 74 20 6e 44 65 6c 61 79 20 3d 20 31 3b 20 20  nt nDelay = 1;  
14810 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14820 20 20 20 20 2f 2a 20 50 61 75 73 65 20 74 69 6d      /* Pause tim
14830 65 20 69 6e 20 6d 69 63 72 6f 73 65 63 6f 6e 64  e in microsecond
14840 73 20 2a 2f 0a 20 20 20 20 69 66 28 20 63 6e 74  s */.    if( cnt
14850 3e 31 30 30 20 29 7b 0a 20 20 20 20 20 20 56 56  >100 ){.      VV
14860 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f  A_ONLY( pWal->lo
14870 63 6b 45 72 72 6f 72 20 3d 20 31 3b 20 29 0a 20  ckError = 1; ). 
14880 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
14890 54 45 5f 50 52 4f 54 4f 43 4f 4c 3b 0a 20 20 20  TE_PROTOCOL;.   
148a0 20 7d 0a 20 20 20 20 69 66 28 20 63 6e 74 3e 3d   }.    if( cnt>=
148b0 31 30 20 29 20 6e 44 65 6c 61 79 20 3d 20 28 63  10 ) nDelay = (c
148c0 6e 74 2d 39 29 2a 28 63 6e 74 2d 39 29 2a 33 39  nt-9)*(cnt-9)*39
148d0 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53  ;.    sqlite3OsS
148e0 6c 65 65 70 28 70 57 61 6c 2d 3e 70 56 66 73 2c  leep(pWal->pVfs,
148f0 20 6e 44 65 6c 61 79 29 3b 0a 20 20 7d 0a 0a 20   nDelay);.  }.. 
14900 20 69 66 28 20 21 75 73 65 57 61 6c 20 29 7b 0a   if( !useWal ){.
14910 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65      rc = walInde
14920 78 52 65 61 64 48 64 72 28 70 57 61 6c 2c 20 70  xReadHdr(pWal, p
14930 43 68 61 6e 67 65 64 29 3b 0a 20 20 20 20 69 66  Changed);.    if
14940 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc==SQLITE_BUS
14950 59 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 49 66  Y ){.      /* If
14960 20 74 68 65 72 65 20 69 73 20 6e 6f 74 20 61 20   there is not a 
14970 72 65 63 6f 76 65 72 79 20 72 75 6e 6e 69 6e 67  recovery running
14980 20 69 6e 20 61 6e 6f 74 68 65 72 20 74 68 72 65   in another thre
14990 61 64 20 6f 72 20 70 72 6f 63 65 73 73 0a 20 20  ad or process.  
149a0 20 20 20 20 2a 2a 20 74 68 65 6e 20 63 6f 6e 76      ** then conv
149b0 65 72 74 20 42 55 53 59 20 65 72 72 6f 72 73 20  ert BUSY errors 
149c0 74 6f 20 57 41 4c 5f 52 45 54 52 59 2e 20 20 49  to WAL_RETRY.  I
149d0 66 20 72 65 63 6f 76 65 72 79 20 69 73 20 6b 6e  f recovery is kn
149e0 6f 77 6e 20 74 6f 0a 20 20 20 20 20 20 2a 2a 20  own to.      ** 
149f0 62 65 20 72 75 6e 6e 69 6e 67 2c 20 63 6f 6e 76  be running, conv
14a00 65 72 74 20 42 55 53 59 20 74 6f 20 42 55 53 59  ert BUSY to BUSY
14a10 5f 52 45 43 4f 56 45 52 59 2e 20 20 54 68 65 72  _RECOVERY.  Ther
14a20 65 20 69 73 20 61 20 72 61 63 65 20 68 65 72 65  e is a race here
14a30 0a 20 20 20 20 20 20 2a 2a 20 77 68 69 63 68 20  .      ** which 
14a40 6d 69 67 68 74 20 63 61 75 73 65 20 57 41 4c 5f  might cause WAL_
14a50 52 45 54 52 59 20 74 6f 20 62 65 20 72 65 74 75  RETRY to be retu
14a60 72 6e 65 64 20 65 76 65 6e 20 69 66 20 42 55 53  rned even if BUS
14a70 59 5f 52 45 43 4f 56 45 52 59 0a 20 20 20 20 20  Y_RECOVERY.     
14a80 20 2a 2a 20 77 6f 75 6c 64 20 62 65 20 74 65 63   ** would be tec
14a90 68 6e 69 63 61 6c 6c 79 20 63 6f 72 72 65 63 74  hnically correct
14aa0 2e 20 20 42 75 74 20 74 68 65 20 72 61 63 65 20  .  But the race 
14ab0 69 73 20 62 65 6e 69 67 6e 20 73 69 6e 63 65 20  is benign since 
14ac0 77 69 74 68 0a 20 20 20 20 20 20 2a 2a 20 57 41  with.      ** WA
14ad0 4c 5f 52 45 54 52 59 20 74 68 69 73 20 72 6f 75  L_RETRY this rou
14ae0 74 69 6e 65 20 77 69 6c 6c 20 62 65 20 63 61 6c  tine will be cal
14af0 6c 65 64 20 61 67 61 69 6e 20 61 6e 64 20 77 69  led again and wi
14b00 6c 6c 20 70 72 6f 62 61 62 6c 79 20 62 65 0a 20  ll probably be. 
14b10 20 20 20 20 20 2a 2a 20 72 69 67 68 74 20 6f 6e       ** right on
14b20 20 74 68 65 20 73 65 63 6f 6e 64 20 69 74 65 72   the second iter
14b30 61 74 69 6f 6e 2e 0a 20 20 20 20 20 20 2a 2f 0a  ation..      */.
14b40 20 20 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e        if( pWal->
14b50 61 70 57 69 44 61 74 61 5b 30 5d 3d 3d 30 20 29  apWiData[0]==0 )
14b60 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 54 68 69  {.        /* Thi
14b70 73 20 62 72 61 6e 63 68 20 69 73 20 74 61 6b 65  s branch is take
14b80 6e 20 77 68 65 6e 20 74 68 65 20 78 53 68 6d 4d  n when the xShmM
14b90 61 70 28 29 20 6d 65 74 68 6f 64 20 72 65 74 75  ap() method retu
14ba0 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53 59 2e  rns SQLITE_BUSY.
14bb0 0a 20 20 20 20 20 20 20 20 2a 2a 20 57 65 20 61  .        ** We a
14bc0 73 73 75 6d 65 20 74 68 69 73 20 69 73 20 61 20  ssume this is a 
14bd0 74 72 61 6e 73 69 65 6e 74 20 63 6f 6e 64 69 74  transient condit
14be0 69 6f 6e 2c 20 73 6f 20 72 65 74 75 72 6e 20 57  ion, so return W
14bf0 41 4c 5f 52 45 54 52 59 2e 20 54 68 65 0a 20 20  AL_RETRY. The.  
14c00 20 20 20 20 20 20 2a 2a 20 78 53 68 6d 4d 61 70        ** xShmMap
14c10 28 29 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  () implementatio
14c20 6e 20 75 73 65 64 20 62 79 20 74 68 65 20 64 65  n used by the de
14c30 66 61 75 6c 74 20 75 6e 69 78 20 61 6e 64 20 77  fault unix and w
14c40 69 6e 33 32 20 56 46 53 20 0a 20 20 20 20 20 20  in32 VFS .      
14c50 20 20 2a 2a 20 6d 6f 64 75 6c 65 73 20 6d 61 79    ** modules may
14c60 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 42   return SQLITE_B
14c70 55 53 59 20 64 75 65 20 74 6f 20 61 20 72 61 63  USY due to a rac
14c80 65 20 63 6f 6e 64 69 74 69 6f 6e 20 69 6e 20 74  e condition in t
14c90 68 65 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 63  he .        ** c
14ca0 6f 64 65 20 74 68 61 74 20 64 65 74 65 72 6d 69  ode that determi
14cb0 6e 65 73 20 77 68 65 74 68 65 72 20 6f 72 20 6e  nes whether or n
14cc0 6f 74 20 74 68 65 20 73 68 61 72 65 64 2d 6d 65  ot the shared-me
14cd0 6d 6f 72 79 20 72 65 67 69 6f 6e 20 0a 20 20 20  mory region .   
14ce0 20 20 20 20 20 2a 2a 20 6d 75 73 74 20 62 65 20       ** must be 
14cf0 7a 65 72 6f 65 64 20 62 65 66 6f 72 65 20 74 68  zeroed before th
14d00 65 20 72 65 71 75 65 73 74 65 64 20 70 61 67 65  e requested page
14d10 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 20 20   is returned..  
14d20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20        */.       
14d30 20 72 63 20 3d 20 57 41 4c 5f 52 45 54 52 59 3b   rc = WAL_RETRY;
14d40 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
14d50 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20   SQLITE_OK==(rc 
14d60 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28  = walLockShared(
14d70 70 57 61 6c 2c 20 57 41 4c 5f 52 45 43 4f 56 45  pWal, WAL_RECOVE
14d80 52 5f 4c 4f 43 4b 29 29 20 29 7b 0a 20 20 20 20  R_LOCK)) ){.    
14d90 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61      walUnlockSha
14da0 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
14db0 43 4f 56 45 52 5f 4c 4f 43 4b 29 3b 0a 20 20 20  COVER_LOCK);.   
14dc0 20 20 20 20 20 72 63 20 3d 20 57 41 4c 5f 52 45       rc = WAL_RE
14dd0 54 52 59 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  TRY;.      }else
14de0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
14df0 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20 20 20  BUSY ){.        
14e00 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55 53 59  rc = SQLITE_BUSY
14e10 5f 52 45 43 4f 56 45 52 59 3b 0a 20 20 20 20 20  _RECOVERY;.     
14e20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28   }.    }.    if(
14e30 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
14e40 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72  {.      return r
14e50 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  c;.    }.  }..  
14e60 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49  pInfo = walCkptI
14e70 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 69 66 28  nfo(pWal);.  if(
14e80 20 21 75 73 65 57 61 6c 20 26 26 20 70 49 6e 66   !useWal && pInf
14e90 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70 57  o->nBackfill==pW
14ea0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
14eb0 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 57 41  ){.    /* The WA
14ec0 4c 20 68 61 73 20 62 65 65 6e 20 63 6f 6d 70 6c  L has been compl
14ed0 65 74 65 6c 79 20 62 61 63 6b 66 69 6c 6c 65 64  etely backfilled
14ee0 20 28 6f 72 20 69 74 20 69 73 20 65 6d 70 74 79   (or it is empty
14ef0 29 2e 0a 20 20 20 20 2a 2a 20 61 6e 64 20 63 61  )..    ** and ca
14f00 6e 20 62 65 20 73 61 66 65 6c 79 20 69 67 6e 6f  n be safely igno
14f10 72 65 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  red..    */.    
14f20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72  rc = walLockShar
14f30 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ed(pWal, WAL_REA
14f40 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20 20  D_LOCK(0));.    
14f50 77 61 6c 53 68 6d 42 61 72 72 69 65 72 28 70 57  walShmBarrier(pW
14f60 61 6c 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  al);.    if( rc=
14f70 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
14f80 20 20 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 28      if( memcmp((
14f90 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48  void *)walIndexH
14fa0 64 72 28 70 57 61 6c 29 2c 20 26 70 57 61 6c 2d  dr(pWal), &pWal-
14fb0 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c  >hdr, sizeof(Wal
14fc0 49 6e 64 65 78 48 64 72 29 29 20 29 7b 0a 20 20  IndexHdr)) ){.  
14fd0 20 20 20 20 20 20 2f 2a 20 49 74 20 69 73 20 6e        /* It is n
14fe0 6f 74 20 73 61 66 65 20 74 6f 20 61 6c 6c 6f 77  ot safe to allow
14ff0 20 74 68 65 20 72 65 61 64 65 72 20 74 6f 20 63   the reader to c
15000 6f 6e 74 69 6e 75 65 20 68 65 72 65 20 69 66 20  ontinue here if 
15010 66 72 61 6d 65 73 0a 20 20 20 20 20 20 20 20 2a  frames.        *
15020 2a 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20  * may have been 
15030 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20  appended to the 
15040 6c 6f 67 20 62 65 66 6f 72 65 20 52 45 41 44 5f  log before READ_
15050 4c 4f 43 4b 28 30 29 20 77 61 73 20 6f 62 74 61  LOCK(0) was obta
15060 69 6e 65 64 2e 0a 20 20 20 20 20 20 20 20 2a 2a  ined..        **
15070 20 57 68 65 6e 20 68 6f 6c 64 69 6e 67 20 52 45   When holding RE
15080 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 74 68 65 20  AD_LOCK(0), the 
15090 72 65 61 64 65 72 20 69 67 6e 6f 72 65 73 20 74  reader ignores t
150a0 68 65 20 65 6e 74 69 72 65 20 6c 6f 67 20 66 69  he entire log fi
150b0 6c 65 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20 77  le,.        ** w
150c0 68 69 63 68 20 69 6d 70 6c 69 65 73 20 74 68 61  hich implies tha
150d0 74 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  t the database f
150e0 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 61 20 74  ile contains a t
150f0 72 75 73 74 77 6f 72 74 68 79 0a 20 20 20 20 20  rustworthy.     
15100 20 20 20 2a 2a 20 73 6e 61 70 73 68 6f 74 2e 20     ** snapshot. 
15110 53 69 6e 63 65 20 68 6f 6c 64 69 6e 67 20 52 45  Since holding RE
15120 41 44 5f 4c 4f 43 4b 28 30 29 20 70 72 65 76 65  AD_LOCK(0) preve
15130 6e 74 73 20 61 20 63 68 65 63 6b 70 6f 69 6e 74  nts a checkpoint
15140 20 66 72 6f 6d 0a 20 20 20 20 20 20 20 20 2a 2a   from.        **
15150 20 68 61 70 70 65 6e 69 6e 67 2c 20 74 68 69 73   happening, this
15160 20 69 73 20 75 73 75 61 6c 6c 79 20 63 6f 72 72   is usually corr
15170 65 63 74 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a  ect..        **.
15180 20 20 20 20 20 20 20 20 2a 2a 20 48 6f 77 65 76          ** Howev
15190 65 72 2c 20 69 66 20 66 72 61 6d 65 73 20 68 61  er, if frames ha
151a0 76 65 20 62 65 65 6e 20 61 70 70 65 6e 64 65 64  ve been appended
151b0 20 74 6f 20 74 68 65 20 6c 6f 67 20 28 6f 72 20   to the log (or 
151c0 69 66 20 74 68 65 20 6c 6f 67 20 0a 20 20 20 20  if the log .    
151d0 20 20 20 20 2a 2a 20 69 73 20 77 72 61 70 70 65      ** is wrappe
151e0 64 20 61 6e 64 20 77 72 69 74 74 65 6e 20 66 6f  d and written fo
151f0 72 20 74 68 61 74 20 6d 61 74 74 65 72 29 20 62  r that matter) b
15200 65 66 6f 72 65 20 74 68 65 20 52 45 41 44 5f 4c  efore the READ_L
15210 4f 43 4b 28 30 29 0a 20 20 20 20 20 20 20 20 2a  OCK(0).        *
15220 2a 20 69 73 20 6f 62 74 61 69 6e 65 64 2c 20 74  * is obtained, t
15230 68 61 74 20 69 73 20 6e 6f 74 20 6e 65 63 65 73  hat is not neces
15240 73 61 72 69 6c 79 20 74 72 75 65 2e 20 41 20 63  sarily true. A c
15250 68 65 63 6b 70 6f 69 6e 74 65 72 20 6d 61 79 0a  heckpointer may.
15260 20 20 20 20 20 20 20 20 2a 2a 20 68 61 76 65 20          ** have 
15270 73 74 61 72 74 65 64 20 74 6f 20 62 61 63 6b 66  started to backf
15280 69 6c 6c 20 74 68 65 20 61 70 70 65 6e 64 65 64  ill the appended
15290 20 66 72 61 6d 65 73 20 62 75 74 20 63 72 61 73   frames but cras
152a0 68 65 64 20 62 65 66 6f 72 65 0a 20 20 20 20 20  hed before.     
152b0 20 20 20 2a 2a 20 69 74 20 66 69 6e 69 73 68 65     ** it finishe
152c0 64 2e 20 4c 65 61 76 69 6e 67 20 61 20 63 6f 72  d. Leaving a cor
152d0 72 75 70 74 20 69 6d 61 67 65 20 69 6e 20 74 68  rupt image in th
152e0 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e  e database file.
152f0 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  .        */.    
15300 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61      walUnlockSha
15310 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
15320 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20  AD_LOCK(0));.   
15330 20 20 20 20 20 72 65 74 75 72 6e 20 57 41 4c 5f       return WAL_
15340 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 0a 20  RETRY;.      }. 
15350 20 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c       pWal->readL
15360 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 72  ock = 0;.      r
15370 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
15380 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72  .    }else if( r
15390 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29  c!=SQLITE_BUSY )
153a0 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72  {.      return r
153b0 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  c;.    }.  }..  
153c0 2f 2a 20 49 66 20 77 65 20 67 65 74 20 74 68 69  /* If we get thi
153d0 73 20 66 61 72 2c 20 69 74 20 6d 65 61 6e 73 20  s far, it means 
153e0 74 68 61 74 20 74 68 65 20 72 65 61 64 65 72 20  that the reader 
153f0 77 69 6c 6c 20 77 61 6e 74 20 74 6f 20 75 73 65  will want to use
15400 0a 20 20 2a 2a 20 74 68 65 20 57 41 4c 20 74 6f  .  ** the WAL to
15410 20 67 65 74 20 61 74 20 63 6f 6e 74 65 6e 74 20   get at content 
15420 66 72 6f 6d 20 72 65 63 65 6e 74 20 63 6f 6d 6d  from recent comm
15430 69 74 73 2e 20 20 54 68 65 20 6a 6f 62 20 6e 6f  its.  The job no
15440 77 20 69 73 0a 20 20 2a 2a 20 74 6f 20 73 65 6c  w is.  ** to sel
15450 65 63 74 20 6f 6e 65 20 6f 66 20 74 68 65 20 61  ect one of the a
15460 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e 74 72 69  ReadMark[] entri
15470 65 73 20 74 68 61 74 20 69 73 20 63 6c 6f 73 65  es that is close
15480 73 74 20 74 6f 0a 20 20 2a 2a 20 62 75 74 20 6e  st to.  ** but n
15490 6f 74 20 65 78 63 65 65 64 69 6e 67 20 70 57 61  ot exceeding pWa
154a0 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 61  l->hdr.mxFrame a
154b0 6e 64 20 6c 6f 63 6b 20 74 68 61 74 20 65 6e 74  nd lock that ent
154c0 72 79 2e 0a 20 20 2a 2f 0a 20 20 6d 78 52 65 61  ry..  */.  mxRea
154d0 64 4d 61 72 6b 20 3d 20 30 3b 0a 20 20 6d 78 49  dMark = 0;.  mxI
154e0 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 31 3b   = 0;.  for(i=1;
154f0 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
15500 69 2b 2b 29 7b 0a 20 20 20 20 75 33 32 20 74 68  i++){.    u32 th
15510 69 73 4d 61 72 6b 20 3d 20 70 49 6e 66 6f 2d 3e  isMark = pInfo->
15520 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20 20  aReadMark[i];.  
15530 20 20 69 66 28 20 6d 78 52 65 61 64 4d 61 72 6b    if( mxReadMark
15540 3c 3d 74 68 69 73 4d 61 72 6b 20 26 26 20 74 68  <=thisMark && th
15550 69 73 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e 68 64  isMark<=pWal->hd
15560 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20  r.mxFrame ){.   
15570 20 20 20 61 73 73 65 72 74 28 20 74 68 69 73 4d     assert( thisM
15580 61 72 6b 21 3d 52 45 41 44 4d 41 52 4b 5f 4e 4f  ark!=READMARK_NO
15590 54 5f 55 53 45 44 20 29 3b 0a 20 20 20 20 20 20  T_USED );.      
155a0 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20 74 68 69  mxReadMark = thi
155b0 73 4d 61 72 6b 3b 0a 20 20 20 20 20 20 6d 78 49  sMark;.      mxI
155c0 20 3d 20 69 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   = i;.    }.  }.
155d0 20 20 2f 2a 20 54 68 65 72 65 20 77 61 73 20 6f    /* There was o
155e0 6e 63 65 20 61 6e 20 22 69 66 22 20 68 65 72 65  nce an "if" here
155f0 2e 20 54 68 65 20 65 78 74 72 61 20 22 7b 22 20  . The extra "{" 
15600 69 73 20 74 6f 20 70 72 65 73 65 72 76 65 20 69  is to preserve i
15610 6e 64 65 6e 74 61 74 69 6f 6e 2e 20 2a 2f 0a 20  ndentation. */. 
15620 20 7b 0a 20 20 20 20 69 66 28 20 28 70 57 61 6c   {.    if( (pWal
15630 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57 41 4c  ->readOnly & WAL
15640 5f 53 48 4d 5f 52 44 4f 4e 4c 59 29 3d 3d 30 0a  _SHM_RDONLY)==0.
15650 20 20 20 20 20 26 26 20 28 6d 78 52 65 61 64 4d       && (mxReadM
15660 61 72 6b 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  ark<pWal->hdr.mx
15670 46 72 61 6d 65 20 7c 7c 20 6d 78 49 3d 3d 30 29  Frame || mxI==0)
15680 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 66 6f  .    ){.      fo
15690 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52 45  r(i=1; i<WAL_NRE
156a0 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  ADER; i++){.    
156b0 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b      rc = walLock
156c0 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
156d0 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29  WAL_READ_LOCK(i)
156e0 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20 69 66  , 1);.        if
156f0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
15700 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 78 52  ){.          mxR
15710 65 61 64 4d 61 72 6b 20 3d 20 70 49 6e 66 6f 2d  eadMark = pInfo-
15720 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d 20  >aReadMark[i] = 
15730 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
15740 65 3b 0a 20 20 20 20 20 20 20 20 20 20 6d 78 49  e;.          mxI
15750 20 3d 20 69 3b 0a 20 20 20 20 20 20 20 20 20 20   = i;.          
15760 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69  walUnlockExclusi
15770 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ve(pWal, WAL_REA
15780 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20  D_LOCK(i), 1);. 
15790 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a           break;.
157a0 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66          }else if
157b0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc!=SQLITE_BUS
157c0 59 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72  Y ){.          r
157d0 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20  eturn rc;.      
157e0 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
157f0 7d 0a 20 20 20 20 69 66 28 20 6d 78 49 3d 3d 30  }.    if( mxI==0
15800 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74   ){.      assert
15810 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc==SQLITE_BUS
15820 59 20 7c 7c 20 28 70 57 61 6c 2d 3e 72 65 61 64  Y || (pWal->read
15830 4f 6e 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52  Only & WAL_SHM_R
15840 44 4f 4e 4c 59 29 21 3d 30 20 29 3b 0a 20 20 20  DONLY)!=0 );.   
15850 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d 53 51     return rc==SQ
15860 4c 49 54 45 5f 42 55 53 59 20 3f 20 57 41 4c 5f  LITE_BUSY ? WAL_
15870 52 45 54 52 59 20 3a 20 53 51 4c 49 54 45 5f 52  RETRY : SQLITE_R
15880 45 41 44 4f 4e 4c 59 5f 43 41 4e 54 4c 4f 43 4b  EADONLY_CANTLOCK
15890 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 63 20  ;.    }..    rc 
158a0 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28  = walLockShared(
158b0 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  pWal, WAL_READ_L
158c0 4f 43 4b 28 6d 78 49 29 29 3b 0a 20 20 20 20 69  OCK(mxI));.    i
158d0 66 28 20 72 63 20 29 7b 0a 20 20 20 20 20 20 72  f( rc ){.      r
158e0 65 74 75 72 6e 20 72 63 3d 3d 53 51 4c 49 54 45  eturn rc==SQLITE
158f0 5f 42 55 53 59 20 3f 20 57 41 4c 5f 52 45 54 52  _BUSY ? WAL_RETR
15900 59 20 3a 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20  Y : rc;.    }.  
15910 20 20 2f 2a 20 4e 6f 77 20 74 68 61 74 20 74 68    /* Now that th
15920 65 20 72 65 61 64 2d 6c 6f 63 6b 20 68 61 73 20  e read-lock has 
15930 62 65 65 6e 20 6f 62 74 61 69 6e 65 64 2c 20 63  been obtained, c
15940 68 65 63 6b 20 74 68 61 74 20 6e 65 69 74 68 65  heck that neithe
15950 72 20 74 68 65 0a 20 20 20 20 2a 2a 20 76 61 6c  r the.    ** val
15960 75 65 20 69 6e 20 74 68 65 20 61 52 65 61 64 4d  ue in the aReadM
15970 61 72 6b 5b 5d 20 61 72 72 61 79 20 6f 72 20 74  ark[] array or t
15980 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
15990 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 20 20 20  he wal-index.   
159a0 20 2a 2a 20 68 65 61 64 65 72 20 68 61 76 65 20   ** header have 
159b0 63 68 61 6e 67 65 64 2e 0a 20 20 20 20 2a 2a 0a  changed..    **.
159c0 20 20 20 20 2a 2a 20 49 74 20 69 73 20 6e 65 63      ** It is nec
159d0 65 73 73 61 72 79 20 74 6f 20 63 68 65 63 6b 20  essary to check 
159e0 74 68 61 74 20 74 68 65 20 77 61 6c 2d 69 6e 64  that the wal-ind
159f0 65 78 20 68 65 61 64 65 72 20 64 69 64 20 6e 6f  ex header did no
15a00 74 20 63 68 61 6e 67 65 0a 20 20 20 20 2a 2a 20  t change.    ** 
15a10 62 65 74 77 65 65 6e 20 74 68 65 20 74 69 6d 65  between the time
15a20 20 69 74 20 77 61 73 20 72 65 61 64 20 61 6e 64   it was read and
15a30 20 77 68 65 6e 20 74 68 65 20 73 68 61 72 65 64   when the shared
15a40 2d 6c 6f 63 6b 20 77 61 73 20 6f 62 74 61 69 6e  -lock was obtain
15a50 65 64 0a 20 20 20 20 2a 2a 20 6f 6e 20 57 41 4c  ed.    ** on WAL
15a60 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 20  _READ_LOCK(mxI) 
15a70 77 61 73 20 6f 62 74 61 69 6e 65 64 20 74 6f 20  was obtained to 
15a80 61 63 63 6f 75 6e 74 20 66 6f 72 20 74 68 65 20  account for the 
15a90 70 6f 73 73 69 62 69 6c 69 74 79 0a 20 20 20 20  possibility.    
15aa0 2a 2a 20 74 68 61 74 20 74 68 65 20 6c 6f 67 20  ** that the log 
15ab0 66 69 6c 65 20 6d 61 79 20 68 61 76 65 20 62 65  file may have be
15ac0 65 6e 20 77 72 61 70 70 65 64 20 62 79 20 61 20  en wrapped by a 
15ad0 77 72 69 74 65 72 2c 20 6f 72 20 74 68 61 74 20  writer, or that 
15ae0 66 72 61 6d 65 73 0a 20 20 20 20 2a 2a 20 74 68  frames.    ** th
15af0 61 74 20 6f 63 63 75 72 20 6c 61 74 65 72 20 69  at occur later i
15b00 6e 20 74 68 65 20 6c 6f 67 20 74 68 61 6e 20 70  n the log than p
15b10 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
15b20 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e 0a 20   may have been. 
15b30 20 20 20 2a 2a 20 63 6f 70 69 65 64 20 69 6e 74     ** copied int
15b40 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20 62  o the database b
15b50 79 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 65 72  y a checkpointer
15b60 2e 20 49 66 20 65 69 74 68 65 72 20 6f 66 20 74  . If either of t
15b70 68 65 73 65 20 74 68 69 6e 67 73 0a 20 20 20 20  hese things.    
15b80 2a 2a 20 68 61 70 70 65 6e 65 64 2c 20 74 68 65  ** happened, the
15b90 6e 20 72 65 61 64 69 6e 67 20 74 68 65 20 64 61  n reading the da
15ba0 74 61 62 61 73 65 20 77 69 74 68 20 74 68 65 20  tabase with the 
15bb0 63 75 72 72 65 6e 74 20 76 61 6c 75 65 20 6f 66  current value of
15bc0 0a 20 20 20 20 2a 2a 20 70 57 61 6c 2d 3e 68 64  .    ** pWal->hd
15bd0 72 2e 6d 78 46 72 61 6d 65 20 72 69 73 6b 73 20  r.mxFrame risks 
15be0 72 65 61 64 69 6e 67 20 61 20 63 6f 72 72 75 70  reading a corrup
15bf0 74 65 64 20 73 6e 61 70 73 68 6f 74 2e 20 53 6f  ted snapshot. So
15c00 2c 20 72 65 74 72 79 0a 20 20 20 20 2a 2a 20 69  , retry.    ** i
15c10 6e 73 74 65 61 64 2e 0a 20 20 20 20 2a 2a 0a 20  nstead..    **. 
15c20 20 20 20 2a 2a 20 54 68 69 73 20 64 6f 65 73 20     ** This does 
15c30 6e 6f 74 20 67 75 61 72 61 6e 74 65 65 20 74 68  not guarantee th
15c40 61 74 20 74 68 65 20 63 6f 70 79 20 6f 66 20 74  at the copy of t
15c50 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
15c60 64 65 72 20 69 73 20 75 70 20 74 6f 0a 20 20 20  der is up to.   
15c70 20 2a 2a 20 64 61 74 65 20 62 65 66 6f 72 65 20   ** date before 
15c80 70 72 6f 63 65 65 64 69 6e 67 2e 20 54 68 61 74  proceeding. That
15c90 20 77 6f 75 6c 64 20 6e 6f 74 20 62 65 20 70 6f   would not be po
15ca0 73 73 69 62 6c 65 20 77 69 74 68 6f 75 74 20 73  ssible without s
15cb0 6f 6d 65 68 6f 77 0a 20 20 20 20 2a 2a 20 62 6c  omehow.    ** bl
15cc0 6f 63 6b 69 6e 67 20 77 72 69 74 65 72 73 2e 20  ocking writers. 
15cd0 49 74 20 6f 6e 6c 79 20 67 75 61 72 61 6e 74 65  It only guarante
15ce0 65 73 20 74 68 61 74 20 61 20 64 61 6e 67 65 72  es that a danger
15cf0 6f 75 73 20 63 68 65 63 6b 70 6f 69 6e 74 20 6f  ous checkpoint o
15d00 72 20 0a 20 20 20 20 2a 2a 20 6c 6f 67 2d 77 72  r .    ** log-wr
15d10 61 70 20 28 65 69 74 68 65 72 20 6f 66 20 77 68  ap (either of wh
15d20 69 63 68 20 77 6f 75 6c 64 20 72 65 71 75 69 72  ich would requir
15d30 65 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c  e an exclusive l
15d40 6f 63 6b 20 6f 6e 0a 20 20 20 20 2a 2a 20 57 41  ock on.    ** WA
15d50 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29  L_READ_LOCK(mxI)
15d60 29 20 68 61 73 20 6e 6f 74 20 6f 63 63 75 72 72  ) has not occurr
15d70 65 64 20 73 69 6e 63 65 20 74 68 65 20 73 6e 61  ed since the sna
15d80 70 73 68 6f 74 20 77 61 73 20 76 61 6c 69 64 2e  pshot was valid.
15d90 0a 20 20 20 20 2a 2f 0a 20 20 20 20 77 61 6c 53  .    */.    walS
15da0 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c 29 3b  hmBarrier(pWal);
15db0 0a 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e  .    if( pInfo->
15dc0 61 52 65 61 64 4d 61 72 6b 5b 6d 78 49 5d 21 3d  aReadMark[mxI]!=
15dd0 6d 78 52 65 61 64 4d 61 72 6b 0a 20 20 20 20 20  mxReadMark.     
15de0 7c 7c 20 6d 65 6d 63 6d 70 28 28 76 6f 69 64 20  || memcmp((void 
15df0 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57  *)walIndexHdr(pW
15e00 61 6c 29 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c  al), &pWal->hdr,
15e10 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
15e20 48 64 72 29 29 0a 20 20 20 20 29 7b 0a 20 20 20  Hdr)).    ){.   
15e30 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72     walUnlockShar
15e40 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ed(pWal, WAL_REA
15e50 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b 0a 20 20  D_LOCK(mxI));.  
15e60 20 20 20 20 72 65 74 75 72 6e 20 57 41 4c 5f 52      return WAL_R
15e70 45 54 52 59 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  ETRY;.    }else{
15e80 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6d  .      assert( m
15e90 78 52 65 61 64 4d 61 72 6b 3c 3d 70 57 61 6c 2d  xReadMark<=pWal-
15ea0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a  >hdr.mxFrame );.
15eb0 20 20 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64        pWal->read
15ec0 4c 6f 63 6b 20 3d 20 28 69 31 36 29 6d 78 49 3b  Lock = (i16)mxI;
15ed0 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
15ee0 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
15ef0 20 42 65 67 69 6e 20 61 20 72 65 61 64 20 74 72   Begin a read tr
15f00 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68 65  ansaction on the
15f10 20 64 61 74 61 62 61 73 65 2e 0a 2a 2a 0a 2a 2a   database..**.**
15f20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 75 73   This routine us
15f30 65 64 20 74 6f 20 62 65 20 63 61 6c 6c 65 64 20  ed to be called 
15f40 73 71 6c 69 74 65 33 4f 70 65 6e 53 6e 61 70 73  sqlite3OpenSnaps
15f50 68 6f 74 28 29 20 61 6e 64 20 77 69 74 68 20 67  hot() and with g
15f60 6f 6f 64 20 72 65 61 73 6f 6e 3a 0a 2a 2a 20 69  ood reason:.** i
15f70 74 20 74 61 6b 65 73 20 61 20 73 6e 61 70 73 68  t takes a snapsh
15f80 6f 74 20 6f 66 20 74 68 65 20 73 74 61 74 65 20  ot of the state 
15f90 6f 66 20 74 68 65 20 57 41 4c 20 61 6e 64 20 77  of the WAL and w
15fa0 61 6c 2d 69 6e 64 65 78 20 66 6f 72 20 74 68 65  al-index for the
15fb0 20 63 75 72 72 65 6e 74 0a 2a 2a 20 69 6e 73 74   current.** inst
15fc0 61 6e 74 20 69 6e 20 74 69 6d 65 2e 20 20 54 68  ant in time.  Th
15fd0 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64  e current thread
15fe0 20 77 69 6c 6c 20 63 6f 6e 74 69 6e 75 65 20 74   will continue t
15ff0 6f 20 75 73 65 20 74 68 69 73 20 73 6e 61 70 73  o use this snaps
16000 68 6f 74 2e 0a 2a 2a 20 4f 74 68 65 72 20 74 68  hot..** Other th
16010 72 65 61 64 73 20 6d 69 67 68 74 20 61 70 70 65  reads might appe
16020 6e 64 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20 74  nd new content t
16030 6f 20 74 68 65 20 57 41 4c 20 61 6e 64 20 77 61  o the WAL and wa
16040 6c 2d 69 6e 64 65 78 20 62 75 74 0a 2a 2a 20 74  l-index but.** t
16050 68 61 74 20 65 78 74 72 61 20 63 6f 6e 74 65 6e  hat extra conten
16060 74 20 69 73 20 69 67 6e 6f 72 65 64 20 62 79 20  t is ignored by 
16070 74 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65  the current thre
16080 61 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  ad..**.** If the
16090 20 64 61 74 61 62 61 73 65 20 63 6f 6e 74 65 6e   database conten
160a0 74 73 20 68 61 76 65 20 63 68 61 6e 67 65 73 20  ts have changes 
160b0 73 69 6e 63 65 20 74 68 65 20 70 72 65 76 69 6f  since the previo
160c0 75 73 20 72 65 61 64 0a 2a 2a 20 74 72 61 6e 73  us read.** trans
160d0 61 63 74 69 6f 6e 2c 20 74 68 65 6e 20 2a 70 43  action, then *pC
160e0 68 61 6e 67 65 64 20 69 73 20 73 65 74 20 74 6f  hanged is set to
160f0 20 31 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e   1 before return
16100 69 6e 67 2e 20 20 54 68 65 0a 2a 2a 20 50 61 67  ing.  The.** Pag
16110 65 72 20 6c 61 79 65 72 20 77 69 6c 6c 20 75 73  er layer will us
16120 65 20 74 68 69 73 20 74 6f 20 6b 6e 6f 77 20 74  e this to know t
16130 68 61 74 20 69 73 20 63 61 63 68 65 20 69 73 20  hat is cache is 
16140 73 74 61 6c 65 20 61 6e 64 0a 2a 2a 20 6e 65 65  stale and.** nee
16150 64 73 20 74 6f 20 62 65 20 66 6c 75 73 68 65 64  ds to be flushed
16160 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
16170 57 61 6c 42 65 67 69 6e 52 65 61 64 54 72 61 6e  WalBeginReadTran
16180 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61  saction(Wal *pWa
16190 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e 67 65 64  l, int *pChanged
161a0 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  ){.  int rc;    
161b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
161c0 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
161d0 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 63 6e 74  ode */.  int cnt
161e0 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
161f0 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
16200 65 72 20 6f 66 20 54 72 79 42 65 67 69 6e 52 65  er of TryBeginRe
16210 61 64 20 61 74 74 65 6d 70 74 73 20 2a 2f 0a 0a  ad attempts */..
16220 20 20 64 6f 7b 0a 20 20 20 20 72 63 20 3d 20 77    do{.    rc = w
16230 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64 28 70  alTryBeginRead(p
16240 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 2c 20 30  Wal, pChanged, 0
16250 2c 20 2b 2b 63 6e 74 29 3b 0a 20 20 7d 77 68 69  , ++cnt);.  }whi
16260 6c 65 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54 52  le( rc==WAL_RETR
16270 59 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28  Y );.  testcase(
16280 20 28 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49   (rc&0xff)==SQLI
16290 54 45 5f 42 55 53 59 20 29 3b 0a 20 20 74 65 73  TE_BUSY );.  tes
162a0 74 63 61 73 65 28 20 28 72 63 26 30 78 66 66 29  tcase( (rc&0xff)
162b0 3d 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 20 29  ==SQLITE_IOERR )
162c0 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 72 63  ;.  testcase( rc
162d0 3d 3d 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f  ==SQLITE_PROTOCO
162e0 4c 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28  L );.  testcase(
162f0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
16300 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
16310 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 69 73 68 20 77  ../*.** Finish w
16320 69 74 68 20 61 20 72 65 61 64 20 74 72 61 6e 73  ith a read trans
16330 61 63 74 69 6f 6e 2e 20 20 41 6c 6c 20 74 68 69  action.  All thi
16340 73 20 64 6f 65 73 20 69 73 20 72 65 6c 65 61 73  s does is releas
16350 65 20 74 68 65 0a 2a 2a 20 72 65 61 64 2d 6c 6f  e the.** read-lo
16360 63 6b 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  ck..*/.void sqli
16370 74 65 33 57 61 6c 45 6e 64 52 65 61 64 54 72 61  te3WalEndReadTra
16380 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57  nsaction(Wal *pW
16390 61 6c 29 7b 0a 20 20 73 71 6c 69 74 65 33 57 61  al){.  sqlite3Wa
163a0 6c 45 6e 64 57 72 69 74 65 54 72 61 6e 73 61 63  lEndWriteTransac
163b0 74 69 6f 6e 28 70 57 61 6c 29 3b 0a 20 20 69 66  tion(pWal);.  if
163c0 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  ( pWal->readLock
163d0 3e 3d 30 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e  >=0 ){.    walUn
163e0 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  lockShared(pWal,
163f0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70   WAL_READ_LOCK(p
16400 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 3b  Wal->readLock));
16410 0a 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c  .    pWal->readL
16420 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20 7d 0a 7d 0a  ock = -1;.  }.}.
16430 0a 2f 2a 0a 2a 2a 20 53 65 61 72 63 68 20 74 68  ./*.** Search th
16440 65 20 77 61 6c 20 66 69 6c 65 20 66 6f 72 20 70  e wal file for p
16450 61 67 65 20 70 67 6e 6f 2e 20 49 66 20 66 6f 75  age pgno. If fou
16460 6e 64 2c 20 73 65 74 20 2a 70 69 52 65 61 64 20  nd, set *piRead 
16470 74 6f 20 74 68 65 20 66 72 61 6d 65 20 74 68 61  to the frame tha
16480 74 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 74 68  t.** contains th
16490 65 20 70 61 67 65 2e 20 4f 74 68 65 72 77 69 73  e page. Otherwis
164a0 65 2c 20 69 66 20 70 67 6e 6f 20 69 73 20 6e 6f  e, if pgno is no
164b0 74 20 69 6e 20 74 68 65 20 77 61 6c 20 66 69 6c  t in the wal fil
164c0 65 2c 20 73 65 74 20 2a 70 69 52 65 61 64 0a 2a  e, set *piRead.*
164d0 2a 20 74 6f 20 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a  * to zero..**.**
164e0 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   Return SQLITE_O
164f0 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c  K if successful,
16500 20 6f 72 20 61 6e 20 65 72 72 6f 72 20 63 6f 64   or an error cod
16510 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63  e if an error oc
16520 63 75 72 73 2e 20 49 66 20 61 6e 0a 2a 2a 20 65  curs. If an.** e
16530 72 72 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c  rror does occur,
16540 20 74 68 65 20 66 69 6e 61 6c 20 76 61 6c 75 65   the final value
16550 20 6f 66 20 2a 70 69 52 65 61 64 20 69 73 20 75   of *piRead is u
16560 6e 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74  ndefined..*/.int
16570 20 73 71 6c 69 74 65 33 57 61 6c 46 69 6e 64 46   sqlite3WalFindF
16580 72 61 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57 61  rame(.  Wal *pWa
16590 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
165a0 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 68          /* WAL h
165b0 61 6e 64 6c 65 20 2a 2f 0a 20 20 50 67 6e 6f 20  andle */.  Pgno 
165c0 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20  pgno,           
165d0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
165e0 74 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62  tabase page numb
165f0 65 72 20 74 6f 20 72 65 61 64 20 64 61 74 61 20  er to read data 
16600 66 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69  for */.  u32 *pi
16610 52 65 61 64 20 20 20 20 20 20 20 20 20 20 20 20  Read            
16620 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
16630 20 46 72 61 6d 65 20 6e 75 6d 62 65 72 20 28 6f   Frame number (o
16640 72 20 7a 65 72 6f 29 20 2a 2f 0a 29 7b 0a 20 20  r zero) */.){.  
16650 75 33 32 20 69 52 65 61 64 20 3d 20 30 3b 20 20  u32 iRead = 0;  
16660 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16670 2f 2a 20 49 66 20 21 3d 30 2c 20 57 41 4c 20 66  /* If !=0, WAL f
16680 72 61 6d 65 20 74 6f 20 72 65 74 75 72 6e 20 64  rame to return d
16690 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 75 33  ata from */.  u3
166a0 32 20 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d 3e  2 iLast = pWal->
166b0 68 64 72 2e 6d 78 46 72 61 6d 65 3b 20 20 2f 2a  hdr.mxFrame;  /*
166c0 20 4c 61 73 74 20 70 61 67 65 20 69 6e 20 57 41   Last page in WA
166d0 4c 20 66 6f 72 20 74 68 69 73 20 72 65 61 64 65  L for this reade
166e0 72 20 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73 68  r */.  int iHash
166f0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
16700 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
16710 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20 4e  o loop through N
16720 20 68 61 73 68 20 74 61 62 6c 65 73 20 2a 2f 0a   hash tables */.
16730 0a 20 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69  .  /* This routi
16740 6e 65 20 69 73 20 6f 6e 6c 79 20 62 65 20 63 61  ne is only be ca
16750 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e  lled from within
16760 20 61 20 72 65 61 64 20 74 72 61 6e 73 61 63 74   a read transact
16770 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74  ion. */.  assert
16780 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  ( pWal->readLock
16790 3e 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63  >=0 || pWal->loc
167a0 6b 45 72 72 6f 72 20 29 3b 0a 0a 20 20 2f 2a 20  kError );..  /* 
167b0 49 66 20 74 68 65 20 22 6c 61 73 74 20 70 61 67  If the "last pag
167c0 65 22 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20  e" field of the 
167d0 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
167e0 20 73 6e 61 70 73 68 6f 74 20 69 73 20 30 2c 20   snapshot is 0, 
167f0 74 68 65 6e 0a 20 20 2a 2a 20 6e 6f 20 64 61 74  then.  ** no dat
16800 61 20 77 69 6c 6c 20 62 65 20 72 65 61 64 20 66  a will be read f
16810 72 6f 6d 20 74 68 65 20 77 61 6c 20 75 6e 64 65  rom the wal unde
16820 72 20 61 6e 79 20 63 69 72 63 75 6d 73 74 61 6e  r any circumstan
16830 63 65 73 2e 20 52 65 74 75 72 6e 20 65 61 72 6c  ces. Return earl
16840 79 0a 20 20 2a 2a 20 69 6e 20 74 68 69 73 20 63  y.  ** in this c
16850 61 73 65 20 61 73 20 61 6e 20 6f 70 74 69 6d 69  ase as an optimi
16860 7a 61 74 69 6f 6e 2e 20 20 4c 69 6b 65 77 69 73  zation.  Likewis
16870 65 2c 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64  e, if pWal->read
16880 4c 6f 63 6b 3d 3d 30 2c 20 0a 20 20 2a 2a 20 74  Lock==0, .  ** t
16890 68 65 6e 20 74 68 65 20 57 41 4c 20 69 73 20 69  hen the WAL is i
168a0 67 6e 6f 72 65 64 20 62 79 20 74 68 65 20 72 65  gnored by the re
168b0 61 64 65 72 20 73 6f 20 72 65 74 75 72 6e 20 65  ader so return e
168c0 61 72 6c 79 2c 20 61 73 20 69 66 20 74 68 65 20  arly, as if the 
168d0 0a 20 20 2a 2a 20 57 41 4c 20 77 65 72 65 20 65  .  ** WAL were e
168e0 6d 70 74 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  mpty..  */.  if(
168f0 20 69 4c 61 73 74 3d 3d 30 20 7c 7c 20 70 57 61   iLast==0 || pWa
16900 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20 29  l->readLock==0 )
16910 7b 0a 20 20 20 20 2a 70 69 52 65 61 64 20 3d 20  {.    *piRead = 
16920 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  0;.    return SQ
16930 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20  LITE_OK;.  }..  
16940 2f 2a 20 53 65 61 72 63 68 20 74 68 65 20 68 61  /* Search the ha
16950 73 68 20 74 61 62 6c 65 20 6f 72 20 74 61 62 6c  sh table or tabl
16960 65 73 20 66 6f 72 20 61 6e 20 65 6e 74 72 79 20  es for an entry 
16970 6d 61 74 63 68 69 6e 67 20 70 61 67 65 20 6e 75  matching page nu
16980 6d 62 65 72 0a 20 20 2a 2a 20 70 67 6e 6f 2e 20  mber.  ** pgno. 
16990 45 61 63 68 20 69 74 65 72 61 74 69 6f 6e 20 6f  Each iteration o
169a0 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
169b0 66 6f 72 28 29 20 6c 6f 6f 70 20 73 65 61 72 63  for() loop searc
169c0 68 65 73 20 6f 6e 65 0a 20 20 2a 2a 20 68 61 73  hes one.  ** has
169d0 68 20 74 61 62 6c 65 20 28 65 61 63 68 20 68 61  h table (each ha
169e0 73 68 20 74 61 62 6c 65 20 69 6e 64 65 78 65 73  sh table indexes
169f0 20 75 70 20 74 6f 20 48 41 53 48 54 41 42 4c 45   up to HASHTABLE
16a00 5f 4e 50 41 47 45 20 66 72 61 6d 65 73 29 2e 0a  _NPAGE frames)..
16a10 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 69 73 20 63    **.  ** This c
16a20 6f 64 65 20 6d 69 67 68 74 20 72 75 6e 20 63 6f  ode might run co
16a30 6e 63 75 72 72 65 6e 74 6c 79 20 74 6f 20 74 68  ncurrently to th
16a40 65 20 63 6f 64 65 20 69 6e 20 77 61 6c 49 6e 64  e code in walInd
16a50 65 78 41 70 70 65 6e 64 28 29 0a 20 20 2a 2a 20  exAppend().  ** 
16a60 74 68 61 74 20 61 64 64 73 20 65 6e 74 72 69 65  that adds entrie
16a70 73 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64  s to the wal-ind
16a80 65 78 20 28 61 6e 64 20 70 6f 73 73 69 62 6c 79  ex (and possibly
16a90 20 74 6f 20 74 68 69 73 20 68 61 73 68 20 0a 20   to this hash . 
16aa0 20 2a 2a 20 74 61 62 6c 65 29 2e 20 54 68 69 73   ** table). This
16ab0 20 6d 65 61 6e 73 20 74 68 65 20 76 61 6c 75 65   means the value
16ac0 20 6a 75 73 74 20 72 65 61 64 20 66 72 6f 6d 20   just read from 
16ad0 74 68 65 20 68 61 73 68 20 0a 20 20 2a 2a 20 73  the hash .  ** s
16ae0 6c 6f 74 20 28 61 48 61 73 68 5b 69 4b 65 79 5d  lot (aHash[iKey]
16af0 29 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20  ) may have been 
16b00 61 64 64 65 64 20 62 65 66 6f 72 65 20 6f 72 20  added before or 
16b10 61 66 74 65 72 20 74 68 65 20 0a 20 20 2a 2a 20  after the .  ** 
16b20 63 75 72 72 65 6e 74 20 72 65 61 64 20 74 72 61  current read tra
16b30 6e 73 61 63 74 69 6f 6e 20 77 61 73 20 6f 70 65  nsaction was ope
16b40 6e 65 64 2e 20 56 61 6c 75 65 73 20 61 64 64 65  ned. Values adde
16b50 64 20 61 66 74 65 72 20 74 68 65 0a 20 20 2a 2a  d after the.  **
16b60 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
16b70 6e 20 77 61 73 20 6f 70 65 6e 65 64 20 6d 61 79  n was opened may
16b80 20 68 61 76 65 20 62 65 65 6e 20 77 72 69 74 74   have been writt
16b90 65 6e 20 69 6e 63 6f 72 72 65 63 74 6c 79 20 2d  en incorrectly -
16ba0 0a 20 20 2a 2a 20 69 2e 65 2e 20 74 68 65 73 65  .  ** i.e. these
16bb0 20 73 6c 6f 74 73 20 6d 61 79 20 63 6f 6e 74 61   slots may conta
16bc0 69 6e 20 67 61 72 62 61 67 65 20 64 61 74 61 2e  in garbage data.
16bd0 20 48 6f 77 65 76 65 72 2c 20 77 65 20 61 73 73   However, we ass
16be0 75 6d 65 0a 20 20 2a 2a 20 74 68 61 74 20 61 6e  ume.  ** that an
16bf0 79 20 73 6c 6f 74 73 20 77 72 69 74 74 65 6e 20  y slots written 
16c00 62 65 66 6f 72 65 20 74 68 65 20 63 75 72 72 65  before the curre
16c10 6e 74 20 72 65 61 64 20 74 72 61 6e 73 61 63 74  nt read transact
16c20 69 6f 6e 20 77 61 73 0a 20 20 2a 2a 20 6f 70 65  ion was.  ** ope
16c30 6e 65 64 20 72 65 6d 61 69 6e 20 75 6e 6d 6f 64  ned remain unmod
16c40 69 66 69 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  ified..  **.  **
16c50 20 46 6f 72 20 74 68 65 20 72 65 61 73 6f 6e 73   For the reasons
16c60 20 61 62 6f 76 65 2c 20 74 68 65 20 69 66 28 2e   above, the if(.
16c70 2e 2e 29 20 63 6f 6e 64 69 74 69 6f 6e 20 66 65  ..) condition fe
16c80 61 74 75 72 65 64 20 69 6e 20 74 68 65 20 69 6e  atured in the in
16c90 6e 65 72 0a 20 20 2a 2a 20 6c 6f 6f 70 20 6f 66  ner.  ** loop of
16ca0 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62   the following b
16cb0 6c 6f 63 6b 20 69 73 20 6d 6f 72 65 20 73 74 72  lock is more str
16cc0 69 6e 67 65 6e 74 20 74 68 61 74 20 77 6f 75 6c  ingent that woul
16cd0 64 20 62 65 20 72 65 71 75 69 72 65 64 20 0a 20  d be required . 
16ce0 20 2a 2a 20 69 66 20 77 65 20 68 61 64 20 65 78   ** if we had ex
16cf0 63 6c 75 73 69 76 65 20 61 63 63 65 73 73 20 74  clusive access t
16d00 6f 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65  o the hash-table
16d10 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 28 61  :.  **.  **   (a
16d20 50 67 6e 6f 5b 69 46 72 61 6d 65 5d 3d 3d 70 67  Pgno[iFrame]==pg
16d30 6e 6f 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54  no): .  **     T
16d40 68 69 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69  his condition fi
16d50 6c 74 65 72 73 20 6f 75 74 20 6e 6f 72 6d 61 6c  lters out normal
16d60 20 68 61 73 68 2d 74 61 62 6c 65 20 63 6f 6c 6c   hash-table coll
16d70 69 73 69 6f 6e 73 2e 0a 20 20 2a 2a 0a 20 20 2a  isions..  **.  *
16d80 2a 20 20 20 28 69 46 72 61 6d 65 3c 3d 69 4c 61  *   (iFrame<=iLa
16d90 73 74 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54  st): .  **     T
16da0 68 69 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69  his condition fi
16db0 6c 74 65 72 73 20 6f 75 74 20 65 6e 74 72 69 65  lters out entrie
16dc0 73 20 74 68 61 74 20 77 65 72 65 20 61 64 64 65  s that were adde
16dd0 64 20 74 6f 20 74 68 65 20 68 61 73 68 0a 20 20  d to the hash.  
16de0 2a 2a 20 20 20 20 20 74 61 62 6c 65 20 61 66 74  **     table aft
16df0 65 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 72  er the current r
16e00 65 61 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead-transaction 
16e10 68 61 64 20 73 74 61 72 74 65 64 2e 0a 20 20 2a  had started..  *
16e20 2f 0a 20 20 66 6f 72 28 69 48 61 73 68 3d 77 61  /.  for(iHash=wa
16e30 6c 46 72 61 6d 65 50 61 67 65 28 69 4c 61 73 74  lFramePage(iLast
16e40 29 3b 20 69 48 61 73 68 3e 3d 30 20 26 26 20 69  ); iHash>=0 && i
16e50 52 65 61 64 3d 3d 30 3b 20 69 48 61 73 68 2d 2d  Read==0; iHash--
16e60 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  ){.    volatile 
16e70 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b 20  ht_slot *aHash; 
16e80 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
16e90 74 6f 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f  to hash table */
16ea0 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33  .    volatile u3
16eb0 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20 20  2 *aPgno;       
16ec0 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
16ed0 20 61 72 72 61 79 20 6f 66 20 70 61 67 65 20 6e   array of page n
16ee0 75 6d 62 65 72 73 20 2a 2f 0a 20 20 20 20 75 33  umbers */.    u3
16ef0 32 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20  2 iZero;        
16f00 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
16f10 72 61 6d 65 20 6e 75 6d 62 65 72 20 63 6f 72 72  rame number corr
16f20 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 61 50 67  esponding to aPg
16f30 6e 6f 5b 30 5d 20 2a 2f 0a 20 20 20 20 69 6e 74  no[0] */.    int
16f40 20 69 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20   iKey;          
16f50 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61             /* Ha
16f60 73 68 20 73 6c 6f 74 20 69 6e 64 65 78 20 2a 2f  sh slot index */
16f70 0a 20 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69 64  .    int nCollid
16f80 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
16f90 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
16fa0 68 61 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73 20  hash collisions 
16fb0 72 65 6d 61 69 6e 69 6e 67 20 2a 2f 0a 20 20 20  remaining */.   
16fc0 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
16fd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
16fe0 2a 20 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a  * Error code */.
16ff0 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 48 61 73  .    rc = walHas
17000 68 47 65 74 28 70 57 61 6c 2c 20 69 48 61 73 68  hGet(pWal, iHash
17010 2c 20 26 61 48 61 73 68 2c 20 26 61 50 67 6e 6f  , &aHash, &aPgno
17020 2c 20 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20 69  , &iZero);.    i
17030 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
17040 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
17050 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e   rc;.    }.    n
17060 43 6f 6c 6c 69 64 65 20 3d 20 48 41 53 48 54 41  Collide = HASHTA
17070 42 4c 45 5f 4e 53 4c 4f 54 3b 0a 20 20 20 20 66  BLE_NSLOT;.    f
17080 6f 72 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28  or(iKey=walHash(
17090 70 67 6e 6f 29 3b 20 61 48 61 73 68 5b 69 4b 65  pgno); aHash[iKe
170a0 79 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74  y]; iKey=walNext
170b0 48 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20  Hash(iKey)){.   
170c0 20 20 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20     u32 iFrame = 
170d0 61 48 61 73 68 5b 69 4b 65 79 5d 20 2b 20 69 5a  aHash[iKey] + iZ
170e0 65 72 6f 3b 0a 20 20 20 20 20 20 69 66 28 20 69  ero;.      if( i
170f0 46 72 61 6d 65 3c 3d 69 4c 61 73 74 20 26 26 20  Frame<=iLast && 
17100 61 50 67 6e 6f 5b 61 48 61 73 68 5b 69 4b 65 79  aPgno[aHash[iKey
17110 5d 5d 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20 20  ]]==pgno ){.    
17120 20 20 20 20 2f 2a 20 61 73 73 65 72 74 28 20 69      /* assert( i
17130 46 72 61 6d 65 3e 69 52 65 61 64 20 29 3b 20 2d  Frame>iRead ); -
17140 2d 20 6e 6f 74 20 74 72 75 65 20 69 66 20 74 68  - not true if th
17150 65 72 65 20 69 73 20 63 6f 72 72 75 70 74 69 6f  ere is corruptio
17160 6e 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 52 65  n */.        iRe
17170 61 64 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20  ad = iFrame;.   
17180 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 28     }.      if( (
17190 6e 43 6f 6c 6c 69 64 65 2d 2d 29 3d 3d 30 20 29  nCollide--)==0 )
171a0 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  {.        return
171b0 20 53 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f   SQLITE_CORRUPT_
171c0 42 4b 50 54 3b 0a 20 20 20 20 20 20 7d 0a 20 20  BKPT;.      }.  
171d0 20 20 7d 0a 20 20 7d 0a 0a 23 69 66 64 65 66 20    }.  }..#ifdef 
171e0 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58  SQLITE_ENABLE_EX
171f0 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54 0a 20  PENSIVE_ASSERT. 
17200 20 2f 2a 20 49 66 20 65 78 70 65 6e 73 69 76 65   /* If expensive
17210 20 61 73 73 65 72 74 28 29 20 73 74 61 74 65 6d   assert() statem
17220 65 6e 74 73 20 61 72 65 20 61 76 61 69 6c 61 62  ents are availab
17230 6c 65 2c 20 64 6f 20 61 20 6c 69 6e 65 61 72 20  le, do a linear 
17240 73 65 61 72 63 68 0a 20 20 2a 2a 20 6f 66 20 74  search.  ** of t
17250 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  he wal-index fil
17260 65 20 63 6f 6e 74 65 6e 74 2e 20 4d 61 6b 65 20  e content. Make 
17270 73 75 72 65 20 74 68 65 20 72 65 73 75 6c 74 73  sure the results
17280 20 61 67 72 65 65 20 77 69 74 68 20 74 68 65 0a   agree with the.
17290 20 20 2a 2a 20 72 65 73 75 6c 74 20 6f 62 74 61    ** result obta
172a0 69 6e 65 64 20 75 73 69 6e 67 20 74 68 65 20 68  ined using the h
172b0 61 73 68 20 69 6e 64 65 78 65 73 20 61 62 6f 76  ash indexes abov
172c0 65 2e 20 20 2a 2f 0a 20 20 7b 0a 20 20 20 20 75  e.  */.  {.    u
172d0 33 32 20 69 52 65 61 64 32 20 3d 20 30 3b 0a 20  32 iRead2 = 0;. 
172e0 20 20 20 75 33 32 20 69 54 65 73 74 3b 0a 20 20     u32 iTest;.  
172f0 20 20 66 6f 72 28 69 54 65 73 74 3d 69 4c 61 73    for(iTest=iLas
17300 74 3b 20 69 54 65 73 74 3e 30 3b 20 69 54 65 73  t; iTest>0; iTes
17310 74 2d 2d 29 7b 0a 20 20 20 20 20 20 69 66 28 20  t--){.      if( 
17320 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61  walFramePgno(pWa
17330 6c 2c 20 69 54 65 73 74 29 3d 3d 70 67 6e 6f 20  l, iTest)==pgno 
17340 29 7b 0a 20 20 20 20 20 20 20 20 69 52 65 61 64  ){.        iRead
17350 32 20 3d 20 69 54 65 73 74 3b 0a 20 20 20 20 20  2 = iTest;.     
17360 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
17370 7d 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65  }.    }.    asse
17380 72 74 28 20 69 52 65 61 64 3d 3d 69 52 65 61 64  rt( iRead==iRead
17390 32 20 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a  2 );.  }.#endif.
173a0 0a 20 20 2a 70 69 52 65 61 64 20 3d 20 69 52 65  .  *piRead = iRe
173b0 61 64 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  ad;.  return SQL
173c0 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
173d0 20 52 65 61 64 20 74 68 65 20 63 6f 6e 74 65 6e   Read the conten
173e0 74 73 20 6f 66 20 66 72 61 6d 65 20 69 52 65 61  ts of frame iRea
173f0 64 20 66 72 6f 6d 20 74 68 65 20 77 61 6c 20 66  d from the wal f
17400 69 6c 65 20 69 6e 74 6f 20 62 75 66 66 65 72 20  ile into buffer 
17410 70 4f 75 74 0a 2a 2a 20 28 77 68 69 63 68 20 69  pOut.** (which i
17420 73 20 6e 4f 75 74 20 62 79 74 65 73 20 69 6e 20  s nOut bytes in 
17430 73 69 7a 65 29 2e 20 52 65 74 75 72 6e 20 53 51  size). Return SQ
17440 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65  LITE_OK if succe
17450 73 73 66 75 6c 2c 20 6f 72 20 61 6e 0a 2a 2a 20  ssful, or an.** 
17460 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72  error code other
17470 77 69 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  wise..*/.int sql
17480 69 74 65 33 57 61 6c 52 65 61 64 46 72 61 6d 65  ite3WalReadFrame
17490 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20  (.  Wal *pWal,  
174a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
174b0 20 20 20 20 2f 2a 20 57 41 4c 20 68 61 6e 64 6c      /* WAL handl
174c0 65 20 2a 2f 0a 20 20 75 33 32 20 69 52 65 61 64  e */.  u32 iRead
174d0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
174e0 20 20 20 20 20 20 20 2f 2a 20 46 72 61 6d 65 20         /* Frame 
174f0 74 6f 20 72 65 61 64 20 2a 2f 0a 20 20 69 6e 74  to read */.  int
17500 20 6e 4f 75 74 2c 20 20 20 20 20 20 20 20 20 20   nOut,          
17510 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
17520 53 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20 70  Size of buffer p
17530 4f 75 74 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  Out in bytes */.
17540 20 20 75 38 20 2a 70 4f 75 74 20 20 20 20 20 20    u8 *pOut      
17550 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17560 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 77    /* Buffer to w
17570 72 69 74 65 20 70 61 67 65 20 64 61 74 61 20 74  rite page data t
17580 6f 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 73 7a  o */.){.  int sz
17590 3b 0a 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b  ;.  i64 iOffset;
175a0 0a 20 20 73 7a 20 3d 20 70 57 61 6c 2d 3e 68 64  .  sz = pWal->hd
175b0 72 2e 73 7a 50 61 67 65 3b 0a 20 20 73 7a 20 3d  r.szPage;.  sz =
175c0 20 28 73 7a 26 30 78 66 65 30 30 29 20 2b 20 28   (sz&0xfe00) + (
175d0 28 73 7a 26 30 78 30 30 30 31 29 3c 3c 31 36 29  (sz&0x0001)<<16)
175e0 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 73 7a  ;.  testcase( sz
175f0 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20 74 65 73  <=32768 );.  tes
17600 74 63 61 73 65 28 20 73 7a 3e 3d 36 35 35 33 36  tcase( sz>=65536
17610 20 29 3b 0a 20 20 69 4f 66 66 73 65 74 20 3d 20   );.  iOffset = 
17620 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69  walFrameOffset(i
17630 52 65 61 64 2c 20 73 7a 29 20 2b 20 57 41 4c 5f  Read, sz) + WAL_
17640 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20  FRAME_HDRSIZE;. 
17650 20 2f 2a 20 74 65 73 74 63 61 73 65 28 20 49 53   /* testcase( IS
17660 5f 42 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74  _BIG_INT(iOffset
17670 29 20 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73  ) ); // requires
17680 20 61 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20   a 4GiB WAL */. 
17690 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f   return sqlite3O
176a0 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c  sRead(pWal->pWal
176b0 46 64 2c 20 70 4f 75 74 2c 20 28 6e 4f 75 74 3e  Fd, pOut, (nOut>
176c0 73 7a 20 3f 20 73 7a 20 3a 20 6e 4f 75 74 29 2c  sz ? sz : nOut),
176d0 20 69 4f 66 66 73 65 74 29 3b 0a 7d 0a 0a 2f 2a   iOffset);.}../*
176e0 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20   .** Return the 
176f0 73 69 7a 65 20 6f 66 20 74 68 65 20 64 61 74 61  size of the data
17700 62 61 73 65 20 69 6e 20 70 61 67 65 73 20 28 6f  base in pages (o
17710 72 20 7a 65 72 6f 2c 20 69 66 20 75 6e 6b 6e 6f  r zero, if unkno
17720 77 6e 29 2e 0a 2a 2f 0a 50 67 6e 6f 20 73 71 6c  wn)..*/.Pgno sql
17730 69 74 65 33 57 61 6c 44 62 73 69 7a 65 28 57 61  ite3WalDbsize(Wa
17740 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28 20  l *pWal){.  if( 
17750 70 57 61 6c 20 26 26 20 41 4c 57 41 59 53 28 70  pWal && ALWAYS(p
17760 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30  Wal->readLock>=0
17770 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
17780 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 3b  pWal->hdr.nPage;
17790 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b  .  }.  return 0;
177a0 0a 7d 0a 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73  .}.../* .** This
177b0 20 66 75 6e 63 74 69 6f 6e 20 73 74 61 72 74 73   function starts
177c0 20 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63   a write transac
177d0 74 69 6f 6e 20 6f 6e 20 74 68 65 20 57 41 4c 2e  tion on the WAL.
177e0 0a 2a 2a 0a 2a 2a 20 41 20 72 65 61 64 20 74 72  .**.** A read tr
177f0 61 6e 73 61 63 74 69 6f 6e 20 6d 75 73 74 20 68  ansaction must h
17800 61 76 65 20 61 6c 72 65 61 64 79 20 62 65 65 6e  ave already been
17810 20 73 74 61 72 74 65 64 20 62 79 20 61 20 70 72   started by a pr
17820 69 6f 72 20 63 61 6c 6c 0a 2a 2a 20 74 6f 20 73  ior call.** to s
17830 71 6c 69 74 65 33 57 61 6c 42 65 67 69 6e 52 65  qlite3WalBeginRe
17840 61 64 54 72 61 6e 73 61 63 74 69 6f 6e 28 29 2e  adTransaction().
17850 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 6f 74 68 65  .**.** If anothe
17860 72 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63  r thread or proc
17870 65 73 73 20 68 61 73 20 77 72 69 74 74 65 6e 20  ess has written 
17880 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
17890 65 20 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 72  e since.** the r
178a0 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
178b0 77 61 73 20 73 74 61 72 74 65 64 2c 20 74 68 65  was started, the
178c0 6e 20 69 74 20 69 73 20 6e 6f 74 20 70 6f 73 73  n it is not poss
178d0 69 62 6c 65 20 66 6f 72 20 74 68 69 73 0a 2a 2a  ible for this.**
178e0 20 74 68 72 65 61 64 20 74 6f 20 77 72 69 74 65   thread to write
178f0 20 61 73 20 64 6f 69 6e 67 20 73 6f 20 77 6f 75   as doing so wou
17900 6c 64 20 63 61 75 73 65 20 61 20 66 6f 72 6b 2e  ld cause a fork.
17910 20 20 53 6f 20 74 68 69 73 20 72 6f 75 74 69 6e    So this routin
17920 65 0a 2a 2a 20 72 65 74 75 72 6e 73 20 53 51 4c  e.** returns SQL
17930 49 54 45 5f 42 55 53 59 20 69 6e 20 74 68 61 74  ITE_BUSY in that
17940 20 63 61 73 65 20 61 6e 64 20 6e 6f 20 77 72 69   case and no wri
17950 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69  te transaction i
17960 73 20 73 74 61 72 74 65 64 2e 0a 2a 2a 0a 2a 2a  s started..**.**
17970 20 54 68 65 72 65 20 63 61 6e 20 6f 6e 6c 79 20   There can only 
17980 62 65 20 61 20 73 69 6e 67 6c 65 20 77 72 69 74  be a single writ
17990 65 72 20 61 63 74 69 76 65 20 61 74 20 61 20 74  er active at a t
179a0 69 6d 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ime..*/.int sqli
179b0 74 65 33 57 61 6c 42 65 67 69 6e 57 72 69 74 65  te3WalBeginWrite
179c0 54 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20  Transaction(Wal 
179d0 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63  *pWal){.  int rc
179e0 3b 0a 0a 20 20 2f 2a 20 43 61 6e 6e 6f 74 20 73  ;..  /* Cannot s
179f0 74 61 72 74 20 61 20 77 72 69 74 65 20 74 72 61  tart a write tra
17a00 6e 73 61 63 74 69 6f 6e 20 77 69 74 68 6f 75 74  nsaction without
17a10 20 66 69 72 73 74 20 68 6f 6c 64 69 6e 67 20 61   first holding a
17a20 20 72 65 61 64 0a 20 20 2a 2a 20 74 72 61 6e 73   read.  ** trans
17a30 61 63 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73  action. */.  ass
17a40 65 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c  ert( pWal->readL
17a50 6f 63 6b 3e 3d 30 20 29 3b 0a 0a 20 20 69 66 28  ock>=0 );..  if(
17a60 20 70 57 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20   pWal->readOnly 
17a70 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
17a80 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 3b 0a 20  LITE_READONLY;. 
17a90 20 7d 0a 0a 20 20 2f 2a 20 4f 6e 6c 79 20 6f 6e   }..  /* Only on
17aa0 65 20 77 72 69 74 65 72 20 61 6c 6c 6f 77 65 64  e writer allowed
17ab0 20 61 74 20 61 20 74 69 6d 65 2e 20 20 47 65 74   at a time.  Get
17ac0 20 74 68 65 20 77 72 69 74 65 20 6c 6f 63 6b 2e   the write lock.
17ad0 20 20 52 65 74 75 72 6e 0a 20 20 2a 2a 20 53 51    Return.  ** SQ
17ae0 4c 49 54 45 5f 42 55 53 59 20 69 66 20 75 6e 61  LITE_BUSY if una
17af0 62 6c 65 2e 0a 20 20 2a 2f 0a 20 20 72 63 20 3d  ble..  */.  rc =
17b00 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76   walLockExclusiv
17b10 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54  e(pWal, WAL_WRIT
17b20 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 69 66  E_LOCK, 1);.  if
17b30 28 20 72 63 20 29 7b 0a 20 20 20 20 72 65 74 75  ( rc ){.    retu
17b40 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70 57 61  rn rc;.  }.  pWa
17b50 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 31  l->writeLock = 1
17b60 3b 0a 0a 20 20 2f 2a 20 49 66 20 61 6e 6f 74 68  ;..  /* If anoth
17b70 65 72 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68 61  er connection ha
17b80 73 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65  s written to the
17b90 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 73   database file s
17ba0 69 6e 63 65 20 74 68 65 0a 20 20 2a 2a 20 74 69  ince the.  ** ti
17bb0 6d 65 20 74 68 65 20 72 65 61 64 20 74 72 61 6e  me the read tran
17bc0 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68 69 73 20  saction on this 
17bd0 63 6f 6e 6e 65 63 74 69 6f 6e 20 77 61 73 20 73  connection was s
17be0 74 61 72 74 65 64 2c 20 74 68 65 6e 0a 20 20 2a  tarted, then.  *
17bf0 2a 20 74 68 65 20 77 72 69 74 65 20 69 73 20 64  * the write is d
17c00 69 73 61 6c 6c 6f 77 65 64 2e 0a 20 20 2a 2f 0a  isallowed..  */.
17c10 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57    if( memcmp(&pW
17c20 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20 2a  al->hdr, (void *
17c30 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61  )walIndexHdr(pWa
17c40 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  l), sizeof(WalIn
17c50 64 65 78 48 64 72 29 29 21 3d 30 20 29 7b 0a 20  dexHdr))!=0 ){. 
17c60 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c     walUnlockExcl
17c70 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
17c80 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  WRITE_LOCK, 1);.
17c90 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c      pWal->writeL
17ca0 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 72 63 20  ock = 0;.    rc 
17cb0 3d 20 53 51 4c 49 54 45 5f 42 55 53 59 5f 53 4e  = SQLITE_BUSY_SN
17cc0 41 50 53 48 4f 54 3b 0a 20 20 7d 0a 0a 20 20 72  APSHOT;.  }..  r
17cd0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
17ce0 2a 2a 20 45 6e 64 20 61 20 77 72 69 74 65 20 74  ** End a write t
17cf0 72 61 6e 73 61 63 74 69 6f 6e 2e 20 20 54 68 65  ransaction.  The
17d00 20 63 6f 6d 6d 69 74 20 68 61 73 20 61 6c 72 65   commit has alre
17d10 61 64 79 20 62 65 65 6e 20 64 6f 6e 65 2e 20 20  ady been done.  
17d20 54 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 20  This.** routine 
17d30 6d 65 72 65 6c 79 20 72 65 6c 65 61 73 65 73 20  merely releases 
17d40 74 68 65 20 6c 6f 63 6b 2e 0a 2a 2f 0a 69 6e 74  the lock..*/.int
17d50 20 73 71 6c 69 74 65 33 57 61 6c 45 6e 64 57 72   sqlite3WalEndWr
17d60 69 74 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 57  iteTransaction(W
17d70 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28  al *pWal){.  if(
17d80 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
17d90 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63   ){.    walUnloc
17da0 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
17db0 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c   WAL_WRITE_LOCK,
17dc0 20 31 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77   1);.    pWal->w
17dd0 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20  riteLock = 0;.  
17de0 20 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61 74 65    pWal->truncate
17df0 4f 6e 43 6f 6d 6d 69 74 20 3d 20 30 3b 0a 20 20  OnCommit = 0;.  
17e00 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  }.  return SQLIT
17e10 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  E_OK;.}../*.** I
17e20 66 20 61 6e 79 20 64 61 74 61 20 68 61 73 20 62  f any data has b
17e30 65 65 6e 20 77 72 69 74 74 65 6e 20 28 62 75 74  een written (but
17e40 20 6e 6f 74 20 63 6f 6d 6d 69 74 74 65 64 29 20   not committed) 
17e50 74 6f 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2c  to the log file,
17e60 20 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f   this.** functio
17e70 6e 20 6d 6f 76 65 73 20 74 68 65 20 77 72 69 74  n moves the writ
17e80 65 2d 70 6f 69 6e 74 65 72 20 62 61 63 6b 20 74  e-pointer back t
17e90 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74  o the start of t
17ea0 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a  he transaction..
17eb0 2a 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c  **.** Additional
17ec0 6c 79 2c 20 74 68 65 20 63 61 6c 6c 62 61 63 6b  ly, the callback
17ed0 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 69 6e 76   function is inv
17ee0 6f 6b 65 64 20 66 6f 72 20 65 61 63 68 20 66 72  oked for each fr
17ef0 61 6d 65 20 77 72 69 74 74 65 6e 0a 2a 2a 20 74  ame written.** t
17f00 6f 20 74 68 65 20 57 41 4c 20 73 69 6e 63 65 20  o the WAL since 
17f10 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
17f20 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 49 66   transaction. If
17f30 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 72 65   the callback re
17f40 74 75 72 6e 73 0a 2a 2a 20 6f 74 68 65 72 20 74  turns.** other t
17f50 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 69  han SQLITE_OK, i
17f60 74 20 69 73 20 6e 6f 74 20 69 6e 76 6f 6b 65 64  t is not invoked
17f70 20 61 67 61 69 6e 20 61 6e 64 20 74 68 65 20 65   again and the e
17f80 72 72 6f 72 20 63 6f 64 65 20 69 73 0a 2a 2a 20  rror code is.** 
17f90 72 65 74 75 72 6e 65 64 20 74 6f 20 74 68 65 20  returned to the 
17fa0 63 61 6c 6c 65 72 2e 0a 2a 2a 0a 2a 2a 20 4f 74  caller..**.** Ot
17fb0 68 65 72 77 69 73 65 2c 20 69 66 20 74 68 65 20  herwise, if the 
17fc0 63 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f  callback functio
17fd0 6e 20 64 6f 65 73 20 6e 6f 74 20 72 65 74 75 72  n does not retur
17fe0 6e 20 61 6e 20 65 72 72 6f 72 2c 20 74 68 69 73  n an error, this
17ff0 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 72 65 74  .** function ret
18000 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a  urns SQLITE_OK..
18010 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
18020 6c 55 6e 64 6f 28 57 61 6c 20 2a 70 57 61 6c 2c  lUndo(Wal *pWal,
18030 20 69 6e 74 20 28 2a 78 55 6e 64 6f 29 28 76 6f   int (*xUndo)(vo
18040 69 64 20 2a 2c 20 50 67 6e 6f 29 2c 20 76 6f 69  id *, Pgno), voi
18050 64 20 2a 70 55 6e 64 6f 43 74 78 29 7b 0a 20 20  d *pUndoCtx){.  
18060 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
18070 4f 4b 3b 0a 20 20 69 66 28 20 41 4c 57 41 59 53  OK;.  if( ALWAYS
18080 28 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b  (pWal->writeLock
18090 29 20 29 7b 0a 20 20 20 20 50 67 6e 6f 20 69 4d  ) ){.    Pgno iM
180a0 61 78 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  ax = pWal->hdr.m
180b0 78 46 72 61 6d 65 3b 0a 20 20 20 20 50 67 6e 6f  xFrame;.    Pgno
180c0 20 69 46 72 61 6d 65 3b 0a 20 20 0a 20 20 20 20   iFrame;.  .    
180d0 2f 2a 20 52 65 73 74 6f 72 65 20 74 68 65 20 63  /* Restore the c
180e0 6c 69 65 6e 74 73 20 63 61 63 68 65 20 6f 66 20  lients cache of 
180f0 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
18100 61 64 65 72 20 74 6f 20 74 68 65 20 73 74 61 74  ader to the stat
18110 65 20 69 74 0a 20 20 20 20 2a 2a 20 77 61 73 20  e it.    ** was 
18120 69 6e 20 62 65 66 6f 72 65 20 74 68 65 20 63 6c  in before the cl
18130 69 65 6e 74 20 62 65 67 61 6e 20 77 72 69 74 69  ient began writi
18140 6e 67 20 74 6f 20 74 68 65 20 64 61 74 61 62 61  ng to the databa
18150 73 65 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20 20  se. .    */.    
18160 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64  memcpy(&pWal->hd
18170 72 2c 20 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e  r, (void *)walIn
18180 64 65 78 48 64 72 28 70 57 61 6c 29 2c 20 73 69  dexHdr(pWal), si
18190 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
181a0 29 29 3b 0a 0a 20 20 20 20 66 6f 72 28 69 46 72  ));..    for(iFr
181b0 61 6d 65 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  ame=pWal->hdr.mx
181c0 46 72 61 6d 65 2b 31 3b 20 0a 20 20 20 20 20 20  Frame+1; .      
181d0 20 20 41 4c 57 41 59 53 28 72 63 3d 3d 53 51 4c    ALWAYS(rc==SQL
181e0 49 54 45 5f 4f 4b 29 20 26 26 20 69 46 72 61 6d  ITE_OK) && iFram
181f0 65 3c 3d 69 4d 61 78 3b 20 0a 20 20 20 20 20 20  e<=iMax; .      
18200 20 20 69 46 72 61 6d 65 2b 2b 0a 20 20 20 20 29    iFrame++.    )
18210 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20  {.      /* This 
18220 63 61 6c 6c 20 63 61 6e 6e 6f 74 20 66 61 69 6c  call cannot fail
18230 2e 20 55 6e 6c 65 73 73 20 74 68 65 20 70 61 67  . Unless the pag
18240 65 20 66 6f 72 20 77 68 69 63 68 20 74 68 65 20  e for which the 
18250 70 61 67 65 20 6e 75 6d 62 65 72 0a 20 20 20 20  page number.    
18260 20 20 2a 2a 20 69 73 20 70 61 73 73 65 64 20 61    ** is passed a
18270 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67  s the second arg
18280 75 6d 65 6e 74 20 69 73 20 28 61 29 20 69 6e 20  ument is (a) in 
18290 74 68 65 20 63 61 63 68 65 20 61 6e 64 20 0a 20  the cache and . 
182a0 20 20 20 20 20 2a 2a 20 28 62 29 20 68 61 73 20       ** (b) has 
182b0 61 6e 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 72  an outstanding r
182c0 65 66 65 72 65 6e 63 65 2c 20 74 68 65 6e 20 78  eference, then x
182d0 55 6e 64 6f 20 69 73 20 65 69 74 68 65 72 20 61  Undo is either a
182e0 20 6e 6f 2d 6f 70 0a 20 20 20 20 20 20 2a 2a 20   no-op.      ** 
182f0 28 69 66 20 28 61 29 20 69 73 20 66 61 6c 73 65  (if (a) is false
18300 29 20 6f 72 20 73 69 6d 70 6c 79 20 65 78 70 65  ) or simply expe
18310 6c 73 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d  ls the page from
18320 20 74 68 65 20 63 61 63 68 65 20 28 69 66 20 28   the cache (if (
18330 62 29 0a 20 20 20 20 20 20 2a 2a 20 69 73 20 66  b).      ** is f
18340 61 6c 73 65 29 2e 0a 20 20 20 20 20 20 2a 2a 0a  alse)..      **.
18350 20 20 20 20 20 20 2a 2a 20 49 66 20 74 68 65 20        ** If the 
18360 75 70 70 65 72 20 6c 61 79 65 72 20 69 73 20 64  upper layer is d
18370 6f 69 6e 67 20 61 20 72 6f 6c 6c 62 61 63 6b 2c  oing a rollback,
18380 20 69 74 20 69 73 20 67 75 61 72 61 6e 74 65 65   it is guarantee
18390 64 20 74 68 61 74 20 74 68 65 72 65 0a 20 20 20  d that there.   
183a0 20 20 20 2a 2a 20 61 72 65 20 6e 6f 20 6f 75 74     ** are no out
183b0 73 74 61 6e 64 69 6e 67 20 72 65 66 65 72 65 6e  standing referen
183c0 63 65 73 20 74 6f 20 61 6e 79 20 70 61 67 65 20  ces to any page 
183d0 6f 74 68 65 72 20 74 68 61 6e 20 70 61 67 65 20  other than page 
183e0 31 2e 20 41 6e 64 0a 20 20 20 20 20 20 2a 2a 20  1. And.      ** 
183f0 70 61 67 65 20 31 20 69 73 20 6e 65 76 65 72 20  page 1 is never 
18400 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20 6c  written to the l
18410 6f 67 20 75 6e 74 69 6c 20 74 68 65 20 74 72 61  og until the tra
18420 6e 73 61 63 74 69 6f 6e 20 69 73 0a 20 20 20 20  nsaction is.    
18430 20 20 2a 2a 20 63 6f 6d 6d 69 74 74 65 64 2e 20    ** committed. 
18440 41 73 20 61 20 72 65 73 75 6c 74 2c 20 74 68 65  As a result, the
18450 20 63 61 6c 6c 20 74 6f 20 78 55 6e 64 6f 20 6d   call to xUndo m
18460 61 79 20 6e 6f 74 20 66 61 69 6c 2e 0a 20 20 20  ay not fail..   
18470 20 20 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65     */.      asse
18480 72 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f  rt( walFramePgno
18490 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 21 3d  (pWal, iFrame)!=
184a0 31 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  1 );.      rc = 
184b0 78 55 6e 64 6f 28 70 55 6e 64 6f 43 74 78 2c 20  xUndo(pUndoCtx, 
184c0 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61  walFramePgno(pWa
184d0 6c 2c 20 69 46 72 61 6d 65 29 29 3b 0a 20 20 20  l, iFrame));.   
184e0 20 7d 0a 20 20 20 20 69 66 28 20 69 4d 61 78 21   }.    if( iMax!
184f0 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  =pWal->hdr.mxFra
18500 6d 65 20 29 20 77 61 6c 43 6c 65 61 6e 75 70 48  me ) walCleanupH
18510 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20  ash(pWal);.  }. 
18520 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
18530 2a 20 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 61  * .** Argument a
18540 57 61 6c 44 61 74 61 20 6d 75 73 74 20 70 6f 69  WalData must poi
18550 6e 74 20 74 6f 20 61 6e 20 61 72 72 61 79 20 6f  nt to an array o
18560 66 20 57 41 4c 5f 53 41 56 45 50 4f 49 4e 54 5f  f WAL_SAVEPOINT_
18570 4e 44 41 54 41 20 75 33 32 20 0a 2a 2a 20 76 61  NDATA u32 .** va
18580 6c 75 65 73 2e 20 54 68 69 73 20 66 75 6e 63 74  lues. This funct
18590 69 6f 6e 20 70 6f 70 75 6c 61 74 65 73 20 74 68  ion populates th
185a0 65 20 61 72 72 61 79 20 77 69 74 68 20 76 61 6c  e array with val
185b0 75 65 73 20 72 65 71 75 69 72 65 64 20 74 6f 20  ues required to 
185c0 0a 2a 2a 20 22 72 6f 6c 6c 62 61 63 6b 22 20 74  .** "rollback" t
185d0 68 65 20 77 72 69 74 65 20 70 6f 73 69 74 69 6f  he write positio
185e0 6e 20 6f 66 20 74 68 65 20 57 41 4c 20 68 61 6e  n of the WAL han
185f0 64 6c 65 20 62 61 63 6b 20 74 6f 20 74 68 65 20  dle back to the 
18600 63 75 72 72 65 6e 74 20 0a 2a 2a 20 70 6f 69 6e  current .** poin
18610 74 20 69 6e 20 74 68 65 20 65 76 65 6e 74 20 6f  t in the event o
18620 66 20 61 20 73 61 76 65 70 6f 69 6e 74 20 72 6f  f a savepoint ro
18630 6c 6c 62 61 63 6b 20 28 76 69 61 20 57 61 6c 53  llback (via WalS
18640 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28 29 29 2e  avepointUndo()).
18650 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33  .*/.void sqlite3
18660 57 61 6c 53 61 76 65 70 6f 69 6e 74 28 57 61 6c  WalSavepoint(Wal
18670 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a 61 57 61   *pWal, u32 *aWa
18680 6c 44 61 74 61 29 7b 0a 20 20 61 73 73 65 72 74  lData){.  assert
18690 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
186a0 6b 20 29 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b  k );.  aWalData[
186b0 30 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  0] = pWal->hdr.m
186c0 78 46 72 61 6d 65 3b 0a 20 20 61 57 61 6c 44 61  xFrame;.  aWalDa
186d0 74 61 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64  ta[1] = pWal->hd
186e0 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d  r.aFrameCksum[0]
186f0 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 32 5d 20  ;.  aWalData[2] 
18700 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61  = pWal->hdr.aFra
18710 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 61 57  meCksum[1];.  aW
18720 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70 57 61 6c  alData[3] = pWal
18730 2d 3e 6e 43 6b 70 74 3b 0a 7d 0a 0a 2f 2a 20 0a  ->nCkpt;.}../* .
18740 2a 2a 20 4d 6f 76 65 20 74 68 65 20 77 72 69 74  ** Move the writ
18750 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66 20 74 68  e position of th
18760 65 20 57 41 4c 20 62 61 63 6b 20 74 6f 20 74 68  e WAL back to th
18770 65 20 70 6f 69 6e 74 20 69 64 65 6e 74 69 66 69  e point identifi
18780 65 64 20 62 79 0a 2a 2a 20 74 68 65 20 76 61 6c  ed by.** the val
18790 75 65 73 20 69 6e 20 74 68 65 20 61 57 61 6c 44  ues in the aWalD
187a0 61 74 61 5b 5d 20 61 72 72 61 79 2e 20 61 57 61  ata[] array. aWa
187b0 6c 44 61 74 61 20 6d 75 73 74 20 70 6f 69 6e 74  lData must point
187c0 20 74 6f 20 61 6e 20 61 72 72 61 79 0a 2a 2a 20   to an array.** 
187d0 6f 66 20 57 41 4c 5f 53 41 56 45 50 4f 49 4e 54  of WAL_SAVEPOINT
187e0 5f 4e 44 41 54 41 20 75 33 32 20 76 61 6c 75 65  _NDATA u32 value
187f0 73 20 74 68 61 74 20 68 61 73 20 62 65 65 6e 20  s that has been 
18800 70 72 65 76 69 6f 75 73 6c 79 20 70 6f 70 75 6c  previously popul
18810 61 74 65 64 0a 2a 2a 20 62 79 20 61 20 63 61 6c  ated.** by a cal
18820 6c 20 74 6f 20 57 61 6c 53 61 76 65 70 6f 69 6e  l to WalSavepoin
18830 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  t()..*/.int sqli
18840 74 65 33 57 61 6c 53 61 76 65 70 6f 69 6e 74 55  te3WalSavepointU
18850 6e 64 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75  ndo(Wal *pWal, u
18860 33 32 20 2a 61 57 61 6c 44 61 74 61 29 7b 0a 20  32 *aWalData){. 
18870 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
18880 5f 4f 4b 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  _OK;..  assert( 
18890 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
188a0 29 3b 0a 20 20 61 73 73 65 72 74 28 20 61 57 61  );.  assert( aWa
188b0 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e  lData[3]!=pWal->
188c0 6e 43 6b 70 74 20 7c 7c 20 61 57 61 6c 44 61 74  nCkpt || aWalDat
188d0 61 5b 30 5d 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e  a[0]<=pWal->hdr.
188e0 6d 78 46 72 61 6d 65 20 29 3b 0a 0a 20 20 69 66  mxFrame );..  if
188f0 28 20 61 57 61 6c 44 61 74 61 5b 33 5d 21 3d 70  ( aWalData[3]!=p
18900 57 61 6c 2d 3e 6e 43 6b 70 74 20 29 7b 0a 20 20  Wal->nCkpt ){.  
18910 20 20 2f 2a 20 54 68 69 73 20 73 61 76 65 70 6f    /* This savepo
18920 69 6e 74 20 77 61 73 20 6f 70 65 6e 65 64 20 69  int was opened i
18930 6d 6d 65 64 69 61 74 65 6c 79 20 61 66 74 65 72  mmediately after
18940 20 74 68 65 20 77 72 69 74 65 2d 74 72 61 6e 73   the write-trans
18950 61 63 74 69 6f 6e 0a 20 20 20 20 2a 2a 20 77 61  action.    ** wa
18960 73 20 73 74 61 72 74 65 64 2e 20 52 69 67 68 74  s started. Right
18970 20 61 66 74 65 72 20 74 68 61 74 2c 20 74 68 65   after that, the
18980 20 77 72 69 74 65 72 20 64 65 63 69 64 65 64 20   writer decided 
18990 74 6f 20 77 72 61 70 20 61 72 6f 75 6e 64 0a 20  to wrap around. 
189a0 20 20 20 2a 2a 20 74 6f 20 74 68 65 20 73 74 61     ** to the sta
189b0 72 74 20 6f 66 20 74 68 65 20 6c 6f 67 2e 20 55  rt of the log. U
189c0 70 64 61 74 65 20 74 68 65 20 73 61 76 65 70 6f  pdate the savepo
189d0 69 6e 74 20 76 61 6c 75 65 73 20 74 6f 20 6d 61  int values to ma
189e0 74 63 68 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  tch..    */.    
189f0 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d 20 30 3b  aWalData[0] = 0;
18a00 0a 20 20 20 20 61 57 61 6c 44 61 74 61 5b 33 5d  .    aWalData[3]
18a10 20 3d 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 3b 0a   = pWal->nCkpt;.
18a20 20 20 7d 0a 0a 20 20 69 66 28 20 61 57 61 6c 44    }..  if( aWalD
18a30 61 74 61 5b 30 5d 3c 70 57 61 6c 2d 3e 68 64 72  ata[0]<pWal->hdr
18a40 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20  .mxFrame ){.    
18a50 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
18a60 65 20 3d 20 61 57 61 6c 44 61 74 61 5b 30 5d 3b  e = aWalData[0];
18a70 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61  .    pWal->hdr.a
18a80 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d 20  FrameCksum[0] = 
18a90 61 57 61 6c 44 61 74 61 5b 31 5d 3b 0a 20 20 20  aWalData[1];.   
18aa0 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
18ab0 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 61 57 61 6c  eCksum[1] = aWal
18ac0 44 61 74 61 5b 32 5d 3b 0a 20 20 20 20 77 61 6c  Data[2];.    wal
18ad0 43 6c 65 61 6e 75 70 48 61 73 68 28 70 57 61 6c  CleanupHash(pWal
18ae0 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
18af0 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
18b00 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
18b10 61 6c 6c 65 64 20 6a 75 73 74 20 62 65 66 6f 72  alled just befor
18b20 65 20 77 72 69 74 69 6e 67 20 61 20 73 65 74 20  e writing a set 
18b30 6f 66 20 66 72 61 6d 65 73 20 74 6f 20 74 68 65  of frames to the
18b40 20 6c 6f 67 0a 2a 2a 20 66 69 6c 65 20 28 73 65   log.** file (se
18b50 65 20 73 71 6c 69 74 65 33 57 61 6c 46 72 61 6d  e sqlite3WalFram
18b60 65 73 28 29 29 2e 20 49 74 20 63 68 65 63 6b 73  es()). It checks
18b70 20 74 6f 20 73 65 65 20 69 66 2c 20 69 6e 73 74   to see if, inst
18b80 65 61 64 20 6f 66 20 61 70 70 65 6e 64 69 6e 67  ead of appending
18b90 0a 2a 2a 20 74 6f 20 74 68 65 20 63 75 72 72 65  .** to the curre
18ba0 6e 74 20 6c 6f 67 20 66 69 6c 65 2c 20 69 74 20  nt log file, it 
18bb0 69 73 20 70 6f 73 73 69 62 6c 65 20 74 6f 20 6f  is possible to o
18bc0 76 65 72 77 72 69 74 65 20 74 68 65 20 73 74 61  verwrite the sta
18bd0 72 74 20 6f 66 20 74 68 65 0a 2a 2a 20 65 78 69  rt of the.** exi
18be0 73 74 69 6e 67 20 6c 6f 67 20 66 69 6c 65 20 77  sting log file w
18bf0 69 74 68 20 74 68 65 20 6e 65 77 20 66 72 61 6d  ith the new fram
18c00 65 73 20 28 69 2e 65 2e 20 22 72 65 73 65 74 22  es (i.e. "reset"
18c10 20 74 68 65 20 6c 6f 67 29 2e 20 49 66 20 73 6f   the log). If so
18c20 2c 0a 2a 2a 20 69 74 20 73 65 74 73 20 70 57 61  ,.** it sets pWa
18c30 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 74  l->hdr.mxFrame t
18c40 6f 20 30 2e 20 4f 74 68 65 72 77 69 73 65 2c 20  o 0. Otherwise, 
18c50 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
18c60 65 20 69 73 20 6c 65 66 74 0a 2a 2a 20 75 6e 63  e is left.** unc
18c70 68 61 6e 67 65 64 2e 0a 2a 2a 0a 2a 2a 20 53 51  hanged..**.** SQ
18c80 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72  LITE_OK is retur
18c90 6e 65 64 20 69 66 20 6e 6f 20 65 72 72 6f 72 20  ned if no error 
18ca0 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 20 28  is encountered (
18cb0 72 65 67 61 72 64 6c 65 73 73 20 6f 66 20 77 68  regardless of wh
18cc0 65 74 68 65 72 0a 2a 2a 20 6f 72 20 6e 6f 74 20  ether.** or not 
18cd0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
18ce0 65 20 69 73 20 6d 6f 64 69 66 69 65 64 29 2e 20  e is modified). 
18cf0 41 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  An SQLite error 
18d00 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65 64  code is returned
18d10 0a 2a 2a 20 69 66 20 61 6e 20 65 72 72 6f 72 20  .** if an error 
18d20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69  occurs..*/.stati
18d30 63 20 69 6e 74 20 77 61 6c 52 65 73 74 61 72 74  c int walRestart
18d40 4c 6f 67 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  Log(Wal *pWal){.
18d50 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
18d60 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 63 6e 74 3b  E_OK;.  int cnt;
18d70 0a 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 72 65  ..  if( pWal->re
18d80 61 64 4c 6f 63 6b 3d 3d 30 20 29 7b 0a 20 20 20  adLock==0 ){.   
18d90 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70   volatile WalCkp
18da0 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 20 3d 20 77  tInfo *pInfo = w
18db0 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29  alCkptInfo(pWal)
18dc0 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 49  ;.    assert( pI
18dd0 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d  nfo->nBackfill==
18de0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
18df0 65 20 29 3b 0a 20 20 20 20 69 66 28 20 70 49 6e  e );.    if( pIn
18e00 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3e 30 20  fo->nBackfill>0 
18e10 29 7b 0a 20 20 20 20 20 20 75 33 32 20 73 61 6c  ){.      u32 sal
18e20 74 31 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  t1;.      sqlite
18e30 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 34 2c 20  3_randomness(4, 
18e40 26 73 61 6c 74 31 29 3b 0a 20 20 20 20 20 20 72  &salt1);.      r
18e50 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75  c = walLockExclu
18e60 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52  sive(pWal, WAL_R
18e70 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c  EAD_LOCK(1), WAL
18e80 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20  _NREADER-1);.   
18e90 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
18ea0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
18eb0 2f 2a 20 49 66 20 61 6c 6c 20 72 65 61 64 65 72  /* If all reader
18ec0 73 20 61 72 65 20 75 73 69 6e 67 20 57 41 4c 5f  s are using WAL_
18ed0 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20 28 69 6e  READ_LOCK(0) (in
18ee0 20 6f 74 68 65 72 20 77 6f 72 64 73 20 69 66 20   other words if 
18ef0 6e 6f 0a 20 20 20 20 20 20 20 20 2a 2a 20 72 65  no.        ** re
18f00 61 64 65 72 73 20 61 72 65 20 63 75 72 72 65 6e  aders are curren
18f10 74 6c 79 20 75 73 69 6e 67 20 74 68 65 20 57 41  tly using the WA
18f20 4c 29 2c 20 74 68 65 6e 20 74 68 65 20 74 72 61  L), then the tra
18f30 6e 73 61 63 74 69 6f 6e 73 0a 20 20 20 20 20 20  nsactions.      
18f40 20 20 2a 2a 20 66 72 61 6d 65 73 20 77 69 6c 6c    ** frames will
18f50 20 6f 76 65 72 77 72 69 74 65 20 74 68 65 20 73   overwrite the s
18f60 74 61 72 74 20 6f 66 20 74 68 65 20 65 78 69 73  tart of the exis
18f70 74 69 6e 67 20 6c 6f 67 2e 20 55 70 64 61 74 65  ting log. Update
18f80 20 74 68 65 0a 20 20 20 20 20 20 20 20 2a 2a 20   the.        ** 
18f90 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
18fa0 20 74 6f 20 72 65 66 6c 65 63 74 20 74 68 69 73   to reflect this
18fb0 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20 20  ..        **.   
18fc0 20 20 20 20 20 2a 2a 20 49 6e 20 74 68 65 6f 72       ** In theor
18fd0 79 20 69 74 20 77 6f 75 6c 64 20 62 65 20 4f 6b  y it would be Ok
18fe0 20 74 6f 20 75 70 64 61 74 65 20 74 68 65 20 63   to update the c
18ff0 61 63 68 65 20 6f 66 20 74 68 65 20 68 65 61 64  ache of the head
19000 65 72 20 6f 6e 6c 79 0a 20 20 20 20 20 20 20 20  er only.        
19010 2a 2a 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74  ** at this point
19020 2e 20 42 75 74 20 75 70 64 61 74 69 6e 67 20 74  . But updating t
19030 68 65 20 61 63 74 75 61 6c 20 77 61 6c 2d 69 6e  he actual wal-in
19040 64 65 78 20 68 65 61 64 65 72 20 69 73 20 61 6c  dex header is al
19050 73 6f 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 61  so.        ** sa
19060 66 65 20 61 6e 64 20 6d 65 61 6e 73 20 74 68 65  fe and means the
19070 72 65 20 69 73 20 6e 6f 20 73 70 65 63 69 61 6c  re is no special
19080 20 63 61 73 65 20 66 6f 72 20 73 71 6c 69 74 65   case for sqlite
19090 33 57 61 6c 55 6e 64 6f 28 29 0a 20 20 20 20 20  3WalUndo().     
190a0 20 20 20 2a 2a 20 74 6f 20 68 61 6e 64 6c 65 20     ** to handle 
190b0 69 66 20 74 68 69 73 20 74 72 61 6e 73 61 63 74  if this transact
190c0 69 6f 6e 20 69 73 20 72 6f 6c 6c 65 64 20 62 61  ion is rolled ba
190d0 63 6b 2e 20 20 2a 2f 0a 20 20 20 20 20 20 20 20  ck.  */.        
190e0 77 61 6c 52 65 73 74 61 72 74 48 64 72 28 70 57  walRestartHdr(pW
190f0 61 6c 2c 20 73 61 6c 74 31 29 3b 0a 20 20 20 20  al, salt1);.    
19100 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63      walUnlockExc
19110 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
19120 5f 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57  _READ_LOCK(1), W
19130 41 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20  AL_NREADER-1);. 
19140 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72       }else if( r
19150 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29  c!=SQLITE_BUSY )
19160 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  {.        return
19170 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20   rc;.      }.   
19180 20 7d 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b   }.    walUnlock
19190 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c  Shared(pWal, WAL
191a0 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a  _READ_LOCK(0));.
191b0 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f      pWal->readLo
191c0 63 6b 20 3d 20 2d 31 3b 0a 20 20 20 20 63 6e 74  ck = -1;.    cnt
191d0 20 3d 20 30 3b 0a 20 20 20 20 64 6f 7b 0a 20 20   = 0;.    do{.  
191e0 20 20 20 20 69 6e 74 20 6e 6f 74 55 73 65 64 3b      int notUsed;
191f0 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 54  .      rc = walT
19200 72 79 42 65 67 69 6e 52 65 61 64 28 70 57 61 6c  ryBeginRead(pWal
19210 2c 20 26 6e 6f 74 55 73 65 64 2c 20 31 2c 20 2b  , &notUsed, 1, +
19220 2b 63 6e 74 29 3b 0a 20 20 20 20 7d 77 68 69 6c  +cnt);.    }whil
19230 65 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54 52 59  e( rc==WAL_RETRY
19240 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
19250 28 72 63 26 30 78 66 66 29 21 3d 53 51 4c 49 54  (rc&0xff)!=SQLIT
19260 45 5f 42 55 53 59 20 29 3b 20 2f 2a 20 42 55 53  E_BUSY ); /* BUS
19270 59 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20 77  Y not possible w
19280 68 65 6e 20 75 73 65 57 61 6c 3d 3d 31 20 2a 2f  hen useWal==1 */
19290 0a 20 20 20 20 74 65 73 74 63 61 73 65 28 20 28  .    testcase( (
192a0 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49 54 45  rc&0xff)==SQLITE
192b0 5f 49 4f 45 52 52 20 29 3b 0a 20 20 20 20 74 65  _IOERR );.    te
192c0 73 74 63 61 73 65 28 20 72 63 3d 3d 53 51 4c 49  stcase( rc==SQLI
192d0 54 45 5f 50 52 4f 54 4f 43 4f 4c 20 29 3b 0a 20  TE_PROTOCOL );. 
192e0 20 20 20 74 65 73 74 63 61 73 65 28 20 72 63 3d     testcase( rc=
192f0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20  =SQLITE_OK );.  
19300 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
19310 0a 0a 2f 2a 0a 2a 2a 20 49 6e 66 6f 72 6d 61 74  ../*.** Informat
19320 69 6f 6e 20 61 62 6f 75 74 20 74 68 65 20 63 75  ion about the cu
19330 72 72 65 6e 74 20 73 74 61 74 65 20 6f 66 20 74  rrent state of t
19340 68 65 20 57 41 4c 20 66 69 6c 65 20 61 6e 64 20  he WAL file and 
19350 77 68 65 72 65 0a 2a 2a 20 74 68 65 20 6e 65 78  where.** the nex
19360 74 20 66 73 79 6e 63 20 73 68 6f 75 6c 64 20 6f  t fsync should o
19370 63 63 75 72 20 2d 20 70 61 73 73 65 64 20 66 72  ccur - passed fr
19380 6f 6d 20 73 71 6c 69 74 65 33 57 61 6c 46 72 61  om sqlite3WalFra
19390 6d 65 73 28 29 20 69 6e 74 6f 0a 2a 2a 20 77 61  mes() into.** wa
193a0 6c 57 72 69 74 65 54 6f 4c 6f 67 28 29 2e 0a 2a  lWriteToLog()..*
193b0 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
193c0 20 57 61 6c 57 72 69 74 65 72 20 7b 0a 20 20 57   WalWriter {.  W
193d0 61 6c 20 2a 70 57 61 6c 3b 20 20 20 20 20 20 20  al *pWal;       
193e0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
193f0 68 65 20 63 6f 6d 70 6c 65 74 65 20 57 41 4c 20  he complete WAL 
19400 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 2a 2f 0a 20  information */. 
19410 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
19420 46 64 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a  Fd;           /*
19430 20 54 68 65 20 57 41 4c 20 66 69 6c 65 20 74 6f   The WAL file to
19440 20 77 68 69 63 68 20 77 65 20 77 72 69 74 65 20   which we write 
19450 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  */.  sqlite3_int
19460 36 34 20 69 53 79 6e 63 50 6f 69 6e 74 3b 20 20  64 iSyncPoint;  
19470 20 20 2f 2a 20 46 73 79 6e 63 20 61 74 20 74 68    /* Fsync at th
19480 69 73 20 6f 66 66 73 65 74 20 2a 2f 0a 20 20 69  is offset */.  i
19490 6e 74 20 73 79 6e 63 46 6c 61 67 73 3b 20 20 20  nt syncFlags;   
194a0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
194b0 6c 61 67 73 20 66 6f 72 20 74 68 65 20 66 73 79  lags for the fsy
194c0 6e 63 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61  nc */.  int szPa
194d0 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
194e0 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
194f0 6f 6e 65 20 70 61 67 65 20 2a 2f 0a 7d 20 57 61  one page */.} Wa
19500 6c 57 72 69 74 65 72 3b 0a 0a 2f 2a 0a 2a 2a 20  lWriter;../*.** 
19510 57 72 69 74 65 20 69 41 6d 74 20 62 79 74 65 73  Write iAmt bytes
19520 20 6f 66 20 63 6f 6e 74 65 6e 74 20 69 6e 74 6f   of content into
19530 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20 62 65   the WAL file be
19540 67 69 6e 6e 69 6e 67 20 61 74 20 69 4f 66 66 73  ginning at iOffs
19550 65 74 2e 0a 2a 2a 20 44 6f 20 61 20 73 79 6e 63  et..** Do a sync
19560 20 77 68 65 6e 20 63 72 6f 73 73 69 6e 67 20 74   when crossing t
19570 68 65 20 70 2d 3e 69 53 79 6e 63 50 6f 69 6e 74  he p->iSyncPoint
19580 20 62 6f 75 6e 64 61 72 79 2e 0a 2a 2a 0a 2a 2a   boundary..**.**
19590 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c   In other words,
195a0 20 69 66 20 69 53 79 6e 63 50 6f 69 6e 74 20 69   if iSyncPoint i
195b0 73 20 69 6e 20 62 65 74 77 65 65 6e 20 69 4f 66  s in between iOf
195c0 66 73 65 74 20 61 6e 64 20 69 4f 66 66 73 65 74  fset and iOffset
195d0 2b 69 41 6d 74 2c 0a 2a 2a 20 66 69 72 73 74 20  +iAmt,.** first 
195e0 77 72 69 74 65 20 74 68 65 20 70 61 72 74 20 62  write the part b
195f0 65 66 6f 72 65 20 69 53 79 6e 63 50 6f 69 6e 74  efore iSyncPoint
19600 2c 20 74 68 65 6e 20 73 79 6e 63 2c 20 74 68 65  , then sync, the
19610 6e 20 77 72 69 74 65 20 74 68 65 0a 2a 2a 20 72  n write the.** r
19620 65 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  est..*/.static i
19630 6e 74 20 77 61 6c 57 72 69 74 65 54 6f 4c 6f 67  nt walWriteToLog
19640 28 0a 20 20 57 61 6c 57 72 69 74 65 72 20 2a 70  (.  WalWriter *p
19650 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
19660 2a 20 57 41 4c 20 74 6f 20 77 72 69 74 65 20 74  * WAL to write t
19670 6f 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 43 6f  o */.  void *pCo
19680 6e 74 65 6e 74 2c 20 20 20 20 20 20 20 20 20 20  ntent,          
19690 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 74 6f 20    /* Content to 
196a0 62 65 20 77 72 69 74 74 65 6e 20 2a 2f 0a 20 20  be written */.  
196b0 69 6e 74 20 69 41 6d 74 2c 20 20 20 20 20 20 20  int iAmt,       
196c0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
196d0 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f  mber of bytes to
196e0 20 77 72 69 74 65 20 2a 2f 0a 20 20 73 71 6c 69   write */.  sqli
196f0 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 66 73 65  te3_int64 iOffse
19700 74 20 20 20 20 20 20 2f 2a 20 53 74 61 72 74 20  t      /* Start 
19710 77 72 69 74 69 6e 67 20 61 74 20 74 68 69 73 20  writing at this 
19720 6f 66 66 73 65 74 20 2a 2f 0a 29 7b 0a 20 20 69  offset */.){.  i
19730 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 69 4f 66  nt rc;.  if( iOf
19740 66 73 65 74 3c 70 2d 3e 69 53 79 6e 63 50 6f 69  fset<p->iSyncPoi
19750 6e 74 20 26 26 20 69 4f 66 66 73 65 74 2b 69 41  nt && iOffset+iA
19760 6d 74 3e 3d 70 2d 3e 69 53 79 6e 63 50 6f 69 6e  mt>=p->iSyncPoin
19770 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 46 69  t ){.    int iFi
19780 72 73 74 41 6d 74 20 3d 20 28 69 6e 74 29 28 70  rstAmt = (int)(p
19790 2d 3e 69 53 79 6e 63 50 6f 69 6e 74 20 2d 20 69  ->iSyncPoint - i
197a0 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 72 63 20  Offset);.    rc 
197b0 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65  = sqlite3OsWrite
197c0 28 70 2d 3e 70 46 64 2c 20 70 43 6f 6e 74 65 6e  (p->pFd, pConten
197d0 74 2c 20 69 46 69 72 73 74 41 6d 74 2c 20 69 4f  t, iFirstAmt, iO
197e0 66 66 73 65 74 29 3b 0a 20 20 20 20 69 66 28 20  ffset);.    if( 
197f0 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a  rc ) return rc;.
19800 20 20 20 20 69 4f 66 66 73 65 74 20 2b 3d 20 69      iOffset += i
19810 46 69 72 73 74 41 6d 74 3b 0a 20 20 20 20 69 41  FirstAmt;.    iA
19820 6d 74 20 2d 3d 20 69 46 69 72 73 74 41 6d 74 3b  mt -= iFirstAmt;
19830 0a 20 20 20 20 70 43 6f 6e 74 65 6e 74 20 3d 20  .    pContent = 
19840 28 76 6f 69 64 2a 29 28 69 46 69 72 73 74 41 6d  (void*)(iFirstAm
19850 74 20 2b 20 28 63 68 61 72 2a 29 70 43 6f 6e 74  t + (char*)pCont
19860 65 6e 74 29 3b 0a 20 20 20 20 61 73 73 65 72 74  ent);.    assert
19870 28 20 70 2d 3e 73 79 6e 63 46 6c 61 67 73 20 26  ( p->syncFlags &
19880 20 28 53 51 4c 49 54 45 5f 53 59 4e 43 5f 4e 4f   (SQLITE_SYNC_NO
19890 52 4d 41 4c 7c 53 51 4c 49 54 45 5f 53 59 4e 43  RMAL|SQLITE_SYNC
198a0 5f 46 55 4c 4c 29 20 29 3b 0a 20 20 20 20 72 63  _FULL) );.    rc
198b0 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63   = sqlite3OsSync
198c0 28 70 2d 3e 70 46 64 2c 20 70 2d 3e 73 79 6e 63  (p->pFd, p->sync
198d0 46 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53  Flags & SQLITE_S
198e0 59 4e 43 5f 4d 41 53 4b 29 3b 0a 20 20 20 20 69  YNC_MASK);.    i
198f0 66 28 20 69 41 6d 74 3d 3d 30 20 7c 7c 20 72 63  f( iAmt==0 || rc
19900 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20   ) return rc;.  
19910 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  }.  rc = sqlite3
19920 4f 73 57 72 69 74 65 28 70 2d 3e 70 46 64 2c 20  OsWrite(p->pFd, 
19930 70 43 6f 6e 74 65 6e 74 2c 20 69 41 6d 74 2c 20  pContent, iAmt, 
19940 69 4f 66 66 73 65 74 29 3b 0a 20 20 72 65 74 75  iOffset);.  retu
19950 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
19960 57 72 69 74 65 20 6f 75 74 20 61 20 73 69 6e 67  Write out a sing
19970 6c 65 20 66 72 61 6d 65 20 6f 66 20 74 68 65 20  le frame of the 
19980 57 41 4c 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  WAL.*/.static in
19990 74 20 77 61 6c 57 72 69 74 65 4f 6e 65 46 72 61  t walWriteOneFra
199a0 6d 65 28 0a 20 20 57 61 6c 57 72 69 74 65 72 20  me(.  WalWriter 
199b0 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  *p,             
199c0 20 20 2f 2a 20 57 68 65 72 65 20 74 6f 20 77 72    /* Where to wr
199d0 69 74 65 20 74 68 65 20 66 72 61 6d 65 20 2a 2f  ite the frame */
199e0 0a 20 20 50 67 48 64 72 20 2a 70 50 61 67 65 2c  .  PgHdr *pPage,
199f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
19a00 2a 20 54 68 65 20 70 61 67 65 20 6f 66 20 74 68  * The page of th
19a10 65 20 66 72 61 6d 65 20 74 6f 20 62 65 20 77 72  e frame to be wr
19a20 69 74 74 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 6e  itten */.  int n
19a30 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20  Truncate,       
19a40 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 63 6f         /* The co
19a50 6d 6d 69 74 20 66 6c 61 67 2e 20 20 55 73 75 61  mmit flag.  Usua
19a60 6c 6c 79 20 30 2e 20 20 3e 30 20 66 6f 72 20 63  lly 0.  >0 for c
19a70 6f 6d 6d 69 74 20 2a 2f 0a 20 20 73 71 6c 69 74  ommit */.  sqlit
19a80 65 33 5f 69 6e 74 36 34 20 69 4f 66 66 73 65 74  e3_int64 iOffset
19a90 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 20 6f         /* Byte o
19aa0 66 66 73 65 74 20 61 74 20 77 68 69 63 68 20 74  ffset at which t
19ab0 6f 20 77 72 69 74 65 20 2a 2f 0a 29 7b 0a 20 20  o write */.){.  
19ac0 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
19ad0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19ae0 2f 2a 20 52 65 73 75 6c 74 20 63 6f 64 65 20 66  /* Result code f
19af0 72 6f 6d 20 73 75 62 66 75 6e 63 74 69 6f 6e 73  rom subfunctions
19b00 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 44 61 74   */.  void *pDat
19b10 61 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  a;              
19b20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 20 61 63        /* Data ac
19b30 74 75 61 6c 6c 79 20 77 72 69 74 74 65 6e 20 2a  tually written *
19b40 2f 0a 20 20 75 38 20 61 46 72 61 6d 65 5b 57 41  /.  u8 aFrame[WA
19b50 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 5d  L_FRAME_HDRSIZE]
19b60 3b 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f  ;   /* Buffer to
19b70 20 61 73 73 65 6d 62 6c 65 20 66 72 61 6d 65 2d   assemble frame-
19b80 68 65 61 64 65 72 20 69 6e 20 2a 2f 0a 23 69 66  header in */.#if
19b90 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
19ba0 48 41 53 5f 43 4f 44 45 43 29 0a 20 20 69 66 28  HAS_CODEC).  if(
19bb0 20 28 70 44 61 74 61 20 3d 20 73 71 6c 69 74 65   (pData = sqlite
19bc0 33 50 61 67 65 72 43 6f 64 65 63 28 70 50 61 67  3PagerCodec(pPag
19bd0 65 29 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  e))==0 ) return 
19be0 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 23 65  SQLITE_NOMEM;.#e
19bf0 6c 73 65 0a 20 20 70 44 61 74 61 20 3d 20 70 50  lse.  pData = pP
19c00 61 67 65 2d 3e 70 44 61 74 61 3b 0a 23 65 6e 64  age->pData;.#end
19c10 69 66 0a 20 20 77 61 6c 45 6e 63 6f 64 65 46 72  if.  walEncodeFr
19c20 61 6d 65 28 70 2d 3e 70 57 61 6c 2c 20 70 50 61  ame(p->pWal, pPa
19c30 67 65 2d 3e 70 67 6e 6f 2c 20 6e 54 72 75 6e 63  ge->pgno, nTrunc
19c40 61 74 65 2c 20 70 44 61 74 61 2c 20 61 46 72 61  ate, pData, aFra
19c50 6d 65 29 3b 0a 20 20 72 63 20 3d 20 77 61 6c 57  me);.  rc = walW
19c60 72 69 74 65 54 6f 4c 6f 67 28 70 2c 20 61 46 72  riteToLog(p, aFr
19c70 61 6d 65 2c 20 73 69 7a 65 6f 66 28 61 46 72 61  ame, sizeof(aFra
19c80 6d 65 29 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20  me), iOffset);. 
19c90 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e   if( rc ) return
19ca0 20 72 63 3b 0a 20 20 2f 2a 20 57 72 69 74 65 20   rc;.  /* Write 
19cb0 74 68 65 20 70 61 67 65 20 64 61 74 61 20 2a 2f  the page data */
19cc0 0a 20 20 72 63 20 3d 20 77 61 6c 57 72 69 74 65  .  rc = walWrite
19cd0 54 6f 4c 6f 67 28 70 2c 20 70 44 61 74 61 2c 20  ToLog(p, pData, 
19ce0 70 2d 3e 73 7a 50 61 67 65 2c 20 69 4f 66 66 73  p->szPage, iOffs
19cf0 65 74 2b 73 69 7a 65 6f 66 28 61 46 72 61 6d 65  et+sizeof(aFrame
19d00 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ));.  return rc;
19d10 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 57 72 69 74 65  .}../* .** Write
19d20 20 61 20 73 65 74 20 6f 66 20 66 72 61 6d 65 73   a set of frames
19d30 20 74 6f 20 74 68 65 20 6c 6f 67 2e 20 54 68 65   to the log. The
19d40 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 68 6f 6c   caller must hol
19d50 64 20 74 68 65 20 77 72 69 74 65 2d 6c 6f 63 6b  d the write-lock
19d60 0a 2a 2a 20 6f 6e 20 74 68 65 20 6c 6f 67 20 66  .** on the log f
19d70 69 6c 65 20 28 6f 62 74 61 69 6e 65 64 20 75 73  ile (obtained us
19d80 69 6e 67 20 73 71 6c 69 74 65 33 57 61 6c 42 65  ing sqlite3WalBe
19d90 67 69 6e 57 72 69 74 65 54 72 61 6e 73 61 63 74  ginWriteTransact
19da0 69 6f 6e 28 29 29 2e 0a 2a 2f 0a 69 6e 74 20 73  ion())..*/.int s
19db0 71 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28  qlite3WalFrames(
19dc0 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20  .  Wal *pWal,   
19dd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19de0 20 20 20 2f 2a 20 57 61 6c 20 68 61 6e 64 6c 65     /* Wal handle
19df0 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a   to write to */.
19e00 20 20 69 6e 74 20 73 7a 50 61 67 65 2c 20 20 20    int szPage,   
19e10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19e20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61    /* Database pa
19e30 67 65 2d 73 69 7a 65 20 69 6e 20 62 79 74 65 73  ge-size in bytes
19e40 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 4c 69   */.  PgHdr *pLi
19e50 73 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  st,             
19e60 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66        /* List of
19e70 20 64 69 72 74 79 20 70 61 67 65 73 20 74 6f 20   dirty pages to 
19e80 77 72 69 74 65 20 2a 2f 0a 20 20 50 67 6e 6f 20  write */.  Pgno 
19e90 6e 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20  nTruncate,      
19ea0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
19eb0 74 61 62 61 73 65 20 73 69 7a 65 20 61 66 74 65  tabase size afte
19ec0 72 20 74 68 69 73 20 63 6f 6d 6d 69 74 20 2a 2f  r this commit */
19ed0 0a 20 20 69 6e 74 20 69 73 43 6f 6d 6d 69 74 2c  .  int isCommit,
19ee0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19ef0 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 74 68     /* True if th
19f00 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 20 2a  is is a commit *
19f10 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61  /.  int sync_fla
19f20 67 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20  gs              
19f30 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20      /* Flags to 
19f40 70 61 73 73 20 74 6f 20 4f 73 53 79 6e 63 28 29  pass to OsSync()
19f50 20 28 6f 72 20 30 29 20 2a 2f 0a 29 7b 0a 20 20   (or 0) */.){.  
19f60 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
19f70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19f80 2f 2a 20 55 73 65 64 20 74 6f 20 63 61 74 63 68  /* Used to catch
19f90 20 72 65 74 75 72 6e 20 63 6f 64 65 73 20 2a 2f   return codes */
19fa0 0a 20 20 75 33 32 20 69 46 72 61 6d 65 3b 20 20  .  u32 iFrame;  
19fb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19fc0 20 20 20 2f 2a 20 4e 65 78 74 20 66 72 61 6d 65     /* Next frame
19fd0 20 61 64 64 72 65 73 73 20 2a 2f 0a 20 20 50 67   address */.  Pg
19fe0 48 64 72 20 2a 70 3b 20 20 20 20 20 20 20 20 20  Hdr *p;         
19ff0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1a000 20 49 74 65 72 61 74 6f 72 20 74 6f 20 72 75 6e   Iterator to run
1a010 20 74 68 72 6f 75 67 68 20 70 4c 69 73 74 20 77   through pList w
1a020 69 74 68 2e 20 2a 2f 0a 20 20 50 67 48 64 72 20  ith. */.  PgHdr 
1a030 2a 70 4c 61 73 74 20 3d 20 30 3b 20 20 20 20 20  *pLast = 0;     
1a040 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73            /* Las
1a050 74 20 66 72 61 6d 65 20 69 6e 20 6c 69 73 74 20  t frame in list 
1a060 2a 2f 0a 20 20 69 6e 74 20 6e 45 78 74 72 61 20  */.  int nExtra 
1a070 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
1a080 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
1a090 66 20 65 78 74 72 61 20 63 6f 70 69 65 73 20 6f  f extra copies o
1a0a0 66 20 6c 61 73 74 20 70 61 67 65 20 2a 2f 0a 20  f last page */. 
1a0b0 20 69 6e 74 20 73 7a 46 72 61 6d 65 3b 20 20 20   int szFrame;   
1a0c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a0d0 20 2f 2a 20 54 68 65 20 73 69 7a 65 20 6f 66 20   /* The size of 
1a0e0 61 20 73 69 6e 67 6c 65 20 66 72 61 6d 65 20 2a  a single frame *
1a0f0 2f 0a 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b  /.  i64 iOffset;
1a100 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a110 20 20 20 20 2f 2a 20 4e 65 78 74 20 62 79 74 65      /* Next byte
1a120 20 74 6f 20 77 72 69 74 65 20 69 6e 20 57 41 4c   to write in WAL
1a130 20 66 69 6c 65 20 2a 2f 0a 20 20 57 61 6c 57 72   file */.  WalWr
1a140 69 74 65 72 20 77 3b 20 20 20 20 20 20 20 20 20  iter w;         
1a150 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
1a160 65 20 77 72 69 74 65 72 20 2a 2f 0a 0a 20 20 61  e writer */..  a
1a170 73 73 65 72 74 28 20 70 4c 69 73 74 20 29 3b 0a  ssert( pList );.
1a180 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
1a190 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 0a 20 20  writeLock );..  
1a1a0 2f 2a 20 49 66 20 74 68 69 73 20 66 72 61 6d 65  /* If this frame
1a1b0 20 73 65 74 20 63 6f 6d 70 6c 65 74 65 73 20 61   set completes a
1a1c0 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20 74 68   transaction, th
1a1d0 65 6e 20 6e 54 72 75 6e 63 61 74 65 3e 30 2e 20  en nTruncate>0. 
1a1e0 20 49 66 0a 20 20 2a 2a 20 6e 54 72 75 6e 63 61   If.  ** nTrunca
1a1f0 74 65 3d 3d 30 20 74 68 65 6e 20 74 68 69 73 20  te==0 then this 
1a200 66 72 61 6d 65 20 73 65 74 20 64 6f 65 73 20 6e  frame set does n
1a210 6f 74 20 63 6f 6d 70 6c 65 74 65 20 74 68 65 20  ot complete the 
1a220 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 2a 2f 0a  transaction. */.
1a230 20 20 61 73 73 65 72 74 28 20 28 69 73 43 6f 6d    assert( (isCom
1a240 6d 69 74 21 3d 30 29 3d 3d 28 6e 54 72 75 6e 63  mit!=0)==(nTrunc
1a250 61 74 65 21 3d 30 29 20 29 3b 0a 0a 23 69 66 20  ate!=0) );..#if 
1a260 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54  defined(SQLITE_T
1a270 45 53 54 29 20 26 26 20 64 65 66 69 6e 65 64 28  EST) && defined(
1a280 53 51 4c 49 54 45 5f 44 45 42 55 47 29 0a 20 20  SQLITE_DEBUG).  
1a290 7b 20 69 6e 74 20 63 6e 74 3b 20 66 6f 72 28 63  { int cnt; for(c
1a2a0 6e 74 3d 30 2c 20 70 3d 70 4c 69 73 74 3b 20 70  nt=0, p=pList; p
1a2b0 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 2c 20 63  ; p=p->pDirty, c
1a2c0 6e 74 2b 2b 29 7b 7d 0a 20 20 20 20 57 41 4c 54  nt++){}.    WALT
1a2d0 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 66 72  RACE(("WAL%p: fr
1a2e0 61 6d 65 20 77 72 69 74 65 20 62 65 67 69 6e 2e  ame write begin.
1a2f0 20 25 64 20 66 72 61 6d 65 73 2e 20 6d 78 46 72   %d frames. mxFr
1a300 61 6d 65 3d 25 64 2e 20 25 73 5c 6e 22 2c 0a 20  ame=%d. %s\n",. 
1a310 20 20 20 20 20 20 20 20 20 20 20 20 20 70 57 61               pWa
1a320 6c 2c 20 63 6e 74 2c 20 70 57 61 6c 2d 3e 68 64  l, cnt, pWal->hd
1a330 72 2e 6d 78 46 72 61 6d 65 2c 20 69 73 43 6f 6d  r.mxFrame, isCom
1a340 6d 69 74 20 3f 20 22 43 6f 6d 6d 69 74 22 20 3a  mit ? "Commit" :
1a350 20 22 53 70 69 6c 6c 22 29 29 3b 0a 20 20 7d 0a   "Spill"));.  }.
1a360 23 65 6e 64 69 66 0a 0a 20 20 2f 2a 20 53 65 65  #endif..  /* See
1a370 20 69 66 20 69 74 20 69 73 20 70 6f 73 73 69 62   if it is possib
1a380 6c 65 20 74 6f 20 77 72 69 74 65 20 74 68 65 73  le to write thes
1a390 65 20 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68  e frames into th
1a3a0 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 0a 20  e start of the. 
1a3b0 20 2a 2a 20 6c 6f 67 20 66 69 6c 65 2c 20 69 6e   ** log file, in
1a3c0 73 74 65 61 64 20 6f 66 20 61 70 70 65 6e 64 69  stead of appendi
1a3d0 6e 67 20 74 6f 20 69 74 20 61 74 20 70 57 61 6c  ng to it at pWal
1a3e0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a 20  ->hdr.mxFrame.. 
1a3f0 20 2a 2f 0a 20 20 69 66 28 20 53 51 4c 49 54 45   */.  if( SQLITE
1a400 5f 4f 4b 21 3d 28 72 63 20 3d 20 77 61 6c 52 65  _OK!=(rc = walRe
1a410 73 74 61 72 74 4c 6f 67 28 70 57 61 6c 29 29 20  startLog(pWal)) 
1a420 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  ){.    return rc
1a430 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74  ;.  }..  /* If t
1a440 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74  his is the first
1a450 20 66 72 61 6d 65 20 77 72 69 74 74 65 6e 20 69   frame written i
1a460 6e 74 6f 20 74 68 65 20 6c 6f 67 2c 20 77 72 69  nto the log, wri
1a470 74 65 20 74 68 65 20 57 41 4c 0a 20 20 2a 2a 20  te the WAL.  ** 
1a480 68 65 61 64 65 72 20 74 6f 20 74 68 65 20 73 74  header to the st
1a490 61 72 74 20 6f 66 20 74 68 65 20 57 41 4c 20 66  art of the WAL f
1a4a0 69 6c 65 2e 20 53 65 65 20 63 6f 6d 6d 65 6e 74  ile. See comment
1a4b0 73 20 61 74 20 74 68 65 20 74 6f 70 20 6f 66 0a  s at the top of.
1a4c0 20 20 2a 2a 20 74 68 69 73 20 73 6f 75 72 63 65    ** this source
1a4d0 20 66 69 6c 65 20 66 6f 72 20 61 20 64 65 73 63   file for a desc
1a4e0 72 69 70 74 69 6f 6e 20 6f 66 20 74 68 65 20 57  ription of the W
1a4f0 41 4c 20 68 65 61 64 65 72 20 66 6f 72 6d 61 74  AL header format
1a500 2e 0a 20 20 2a 2f 0a 20 20 69 46 72 61 6d 65 20  ..  */.  iFrame 
1a510 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  = pWal->hdr.mxFr
1a520 61 6d 65 3b 0a 20 20 69 66 28 20 69 46 72 61 6d  ame;.  if( iFram
1a530 65 3d 3d 30 20 29 7b 0a 20 20 20 20 75 38 20 61  e==0 ){.    u8 a
1a540 57 61 6c 48 64 72 5b 57 41 4c 5f 48 44 52 53 49  WalHdr[WAL_HDRSI
1a550 5a 45 5d 3b 20 20 20 20 20 20 2f 2a 20 42 75 66  ZE];      /* Buf
1a560 66 65 72 20 74 6f 20 61 73 73 65 6d 62 6c 65 20  fer to assemble 
1a570 77 61 6c 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f  wal-header in */
1a580 0a 20 20 20 20 75 33 32 20 61 43 6b 73 75 6d 5b  .    u32 aCksum[
1a590 32 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  2];             
1a5a0 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66     /* Checksum f
1a5b0 6f 72 20 77 61 6c 2d 68 65 61 64 65 72 20 2a 2f  or wal-header */
1a5c0 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74  ..    sqlite3Put
1a5d0 34 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 30  4byte(&aWalHdr[0
1a5e0 5d 2c 20 28 57 41 4c 5f 4d 41 47 49 43 20 7c 20  ], (WAL_MAGIC | 
1a5f0 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e  SQLITE_BIGENDIAN
1a600 29 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50  ));.    sqlite3P
1a610 75 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72  ut4byte(&aWalHdr
1a620 5b 34 5d 2c 20 57 41 4c 5f 4d 41 58 5f 56 45 52  [4], WAL_MAX_VER
1a630 53 49 4f 4e 29 3b 0a 20 20 20 20 73 71 6c 69 74  SION);.    sqlit
1a640 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c  e3Put4byte(&aWal
1a650 48 64 72 5b 38 5d 2c 20 73 7a 50 61 67 65 29 3b  Hdr[8], szPage);
1a660 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34  .    sqlite3Put4
1a670 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 31 32  byte(&aWalHdr[12
1a680 5d 2c 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 29 3b  ], pWal->nCkpt);
1a690 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 6e  .    if( pWal->n
1a6a0 43 6b 70 74 3d 3d 30 20 29 20 73 71 6c 69 74 65  Ckpt==0 ) sqlite
1a6b0 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 38 2c 20  3_randomness(8, 
1a6c0 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 29  pWal->hdr.aSalt)
1a6d0 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 61 57  ;.    memcpy(&aW
1a6e0 61 6c 48 64 72 5b 31 36 5d 2c 20 70 57 61 6c 2d  alHdr[16], pWal-
1a6f0 3e 68 64 72 2e 61 53 61 6c 74 2c 20 38 29 3b 0a  >hdr.aSalt, 8);.
1a700 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42      walChecksumB
1a710 79 74 65 73 28 31 2c 20 61 57 61 6c 48 64 72 2c  ytes(1, aWalHdr,
1a720 20 57 41 4c 5f 48 44 52 53 49 5a 45 2d 32 2a 34   WAL_HDRSIZE-2*4
1a730 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b 0a 20 20  , 0, aCksum);.  
1a740 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74    sqlite3Put4byt
1a750 65 28 26 61 57 61 6c 48 64 72 5b 32 34 5d 2c 20  e(&aWalHdr[24], 
1a760 61 43 6b 73 75 6d 5b 30 5d 29 3b 0a 20 20 20 20  aCksum[0]);.    
1a770 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28  sqlite3Put4byte(
1a780 26 61 57 61 6c 48 64 72 5b 32 38 5d 2c 20 61 43  &aWalHdr[28], aC
1a790 6b 73 75 6d 5b 31 5d 29 3b 0a 20 20 20 20 0a 20  ksum[1]);.    . 
1a7a0 20 20 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 20     pWal->szPage 
1a7b0 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 70 57  = szPage;.    pW
1a7c0 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b  al->hdr.bigEndCk
1a7d0 73 75 6d 20 3d 20 53 51 4c 49 54 45 5f 42 49 47  sum = SQLITE_BIG
1a7e0 45 4e 44 49 41 4e 3b 0a 20 20 20 20 70 57 61 6c  ENDIAN;.    pWal
1a7f0 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
1a800 6d 5b 30 5d 20 3d 20 61 43 6b 73 75 6d 5b 30 5d  m[0] = aCksum[0]
1a810 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  ;.    pWal->hdr.
1a820 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d  aFrameCksum[1] =
1a830 20 61 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 20 20   aCksum[1];.    
1a840 70 57 61 6c 2d 3e 74 72 75 6e 63 61 74 65 4f 6e  pWal->truncateOn
1a850 43 6f 6d 6d 69 74 20 3d 20 31 3b 0a 0a 20 20 20  Commit = 1;..   
1a860 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57   rc = sqlite3OsW
1a870 72 69 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46  rite(pWal->pWalF
1a880 64 2c 20 61 57 61 6c 48 64 72 2c 20 73 69 7a 65  d, aWalHdr, size
1a890 6f 66 28 61 57 61 6c 48 64 72 29 2c 20 30 29 3b  of(aWalHdr), 0);
1a8a0 0a 20 20 20 20 57 41 4c 54 52 41 43 45 28 28 22  .    WALTRACE(("
1a8b0 57 41 4c 25 70 3a 20 77 61 6c 2d 68 65 61 64 65  WAL%p: wal-heade
1a8c0 72 20 77 72 69 74 65 20 25 73 5c 6e 22 2c 20 70  r write %s\n", p
1a8d0 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c 65  Wal, rc ? "faile
1a8e0 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 20  d" : "ok"));.   
1a8f0 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
1a900 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75  OK ){.      retu
1a910 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 0a 20 20  rn rc;.    }..  
1a920 20 20 2f 2a 20 53 79 6e 63 20 74 68 65 20 68 65    /* Sync the he
1a930 61 64 65 72 20 28 75 6e 6c 65 73 73 20 53 51 4c  ader (unless SQL
1a940 49 54 45 5f 49 4f 43 41 50 5f 53 45 51 55 45 4e  ITE_IOCAP_SEQUEN
1a950 54 49 41 4c 20 69 73 20 74 72 75 65 20 6f 72 20  TIAL is true or 
1a960 75 6e 6c 65 73 73 0a 20 20 20 20 2a 2a 20 61 6c  unless.    ** al
1a970 6c 20 73 79 6e 63 69 6e 67 20 69 73 20 74 75 72  l syncing is tur
1a980 6e 65 64 20 6f 66 66 20 62 79 20 50 52 41 47 4d  ned off by PRAGM
1a990 41 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 4f 46  A synchronous=OF
1a9a0 46 29 2e 20 20 4f 74 68 65 72 77 69 73 65 0a 20  F).  Otherwise. 
1a9b0 20 20 20 2a 2a 20 61 6e 20 6f 75 74 2d 6f 66 2d     ** an out-of-
1a9c0 6f 72 64 65 72 20 77 72 69 74 65 20 66 6f 6c 6c  order write foll
1a9d0 6f 77 69 6e 67 20 61 20 57 41 4c 20 72 65 73 74  owing a WAL rest
1a9e0 61 72 74 20 63 6f 75 6c 64 20 72 65 73 75 6c 74  art could result
1a9f0 20 69 6e 0a 20 20 20 20 2a 2a 20 64 61 74 61 62   in.    ** datab
1aa00 61 73 65 20 63 6f 72 72 75 70 74 69 6f 6e 2e 20  ase corruption. 
1aa10 20 53 65 65 20 74 68 65 20 74 69 63 6b 65 74 3a   See the ticket:
1aa20 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 20  .    **.    **  
1aa30 20 20 20 68 74 74 70 3a 2f 2f 6c 6f 63 61 6c 68     http://localh
1aa40 6f 73 74 3a 35 39 31 2f 73 71 6c 69 74 65 2f 69  ost:591/sqlite/i
1aa50 6e 66 6f 2f 66 66 35 62 65 37 33 64 65 65 0a 20  nfo/ff5be73dee. 
1aa60 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 57     */.    if( pW
1aa70 61 6c 2d 3e 73 79 6e 63 48 65 61 64 65 72 20 26  al->syncHeader &
1aa80 26 20 73 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a  & sync_flags ){.
1aa90 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
1aaa0 65 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70  e3OsSync(pWal->p
1aab0 57 61 6c 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67  WalFd, sync_flag
1aac0 73 20 26 20 53 51 4c 49 54 45 5f 53 59 4e 43 5f  s & SQLITE_SYNC_
1aad0 4d 41 53 4b 29 3b 0a 20 20 20 20 20 20 69 66 28  MASK);.      if(
1aae0 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63 3b   rc ) return rc;
1aaf0 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73  .    }.  }.  ass
1ab00 65 72 74 28 20 28 69 6e 74 29 70 57 61 6c 2d 3e  ert( (int)pWal->
1ab10 73 7a 50 61 67 65 3d 3d 73 7a 50 61 67 65 20 29  szPage==szPage )
1ab20 3b 0a 0a 20 20 2f 2a 20 53 65 74 75 70 20 69 6e  ;..  /* Setup in
1ab30 66 6f 72 6d 61 74 69 6f 6e 20 6e 65 65 64 65 64  formation needed
1ab40 20 74 6f 20 77 72 69 74 65 20 66 72 61 6d 65 73   to write frames
1ab50 20 69 6e 74 6f 20 74 68 65 20 57 41 4c 20 2a 2f   into the WAL */
1ab60 0a 20 20 77 2e 70 57 61 6c 20 3d 20 70 57 61 6c  .  w.pWal = pWal
1ab70 3b 0a 20 20 77 2e 70 46 64 20 3d 20 70 57 61 6c  ;.  w.pFd = pWal
1ab80 2d 3e 70 57 61 6c 46 64 3b 0a 20 20 77 2e 69 53  ->pWalFd;.  w.iS
1ab90 79 6e 63 50 6f 69 6e 74 20 3d 20 30 3b 0a 20 20  yncPoint = 0;.  
1aba0 77 2e 73 79 6e 63 46 6c 61 67 73 20 3d 20 73 79  w.syncFlags = sy
1abb0 6e 63 5f 66 6c 61 67 73 3b 0a 20 20 77 2e 73 7a  nc_flags;.  w.sz
1abc0 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20  Page = szPage;. 
1abd0 20 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72   iOffset = walFr
1abe0 61 6d 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65  ameOffset(iFrame
1abf0 2b 31 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20 73  +1, szPage);.  s
1ac00 7a 46 72 61 6d 65 20 3d 20 73 7a 50 61 67 65 20  zFrame = szPage 
1ac10 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  + WAL_FRAME_HDRS
1ac20 49 5a 45 3b 0a 0a 20 20 2f 2a 20 57 72 69 74 65  IZE;..  /* Write
1ac30 20 61 6c 6c 20 66 72 61 6d 65 73 20 69 6e 74 6f   all frames into
1ac40 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 65 78   the log file ex
1ac50 61 63 74 6c 79 20 6f 6e 63 65 20 2a 2f 0a 20 20  actly once */.  
1ac60 66 6f 72 28 70 3d 70 4c 69 73 74 3b 20 70 3b 20  for(p=pList; p; 
1ac70 70 3d 70 2d 3e 70 44 69 72 74 79 29 7b 0a 20 20  p=p->pDirty){.  
1ac80 20 20 69 6e 74 20 6e 44 62 53 69 7a 65 3b 20 20    int nDbSize;  
1ac90 20 2f 2a 20 30 20 6e 6f 72 6d 61 6c 6c 79 2e 20   /* 0 normally. 
1aca0 20 50 6f 73 69 74 69 76 65 20 3d 3d 20 63 6f 6d   Positive == com
1acb0 6d 69 74 20 66 6c 61 67 20 2a 2f 0a 20 20 20 20  mit flag */.    
1acc0 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 61 73  iFrame++;.    as
1acd0 73 65 72 74 28 20 69 4f 66 66 73 65 74 3d 3d 77  sert( iOffset==w
1ace0 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46  alFrameOffset(iF
1acf0 72 61 6d 65 2c 20 73 7a 50 61 67 65 29 20 29 3b  rame, szPage) );
1ad00 0a 20 20 20 20 6e 44 62 53 69 7a 65 20 3d 20 28  .    nDbSize = (
1ad10 69 73 43 6f 6d 6d 69 74 20 26 26 20 70 2d 3e 70  isCommit && p->p
1ad20 44 69 72 74 79 3d 3d 30 29 20 3f 20 6e 54 72 75  Dirty==0) ? nTru
1ad30 6e 63 61 74 65 20 3a 20 30 3b 0a 20 20 20 20 72  ncate : 0;.    r
1ad40 63 20 3d 20 77 61 6c 57 72 69 74 65 4f 6e 65 46  c = walWriteOneF
1ad50 72 61 6d 65 28 26 77 2c 20 70 2c 20 6e 44 62 53  rame(&w, p, nDbS
1ad60 69 7a 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20  ize, iOffset);. 
1ad70 20 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75     if( rc ) retu
1ad80 72 6e 20 72 63 3b 0a 20 20 20 20 70 4c 61 73 74  rn rc;.    pLast
1ad90 20 3d 20 70 3b 0a 20 20 20 20 69 4f 66 66 73 65   = p;.    iOffse
1ada0 74 20 2b 3d 20 73 7a 46 72 61 6d 65 3b 0a 20 20  t += szFrame;.  
1adb0 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 69 73 20  }..  /* If this 
1adc0 69 73 20 74 68 65 20 65 6e 64 20 6f 66 20 61 20  is the end of a 
1add0 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20 74 68 65  transaction, the
1ade0 6e 20 77 65 20 6d 69 67 68 74 20 6e 65 65 64 20  n we might need 
1adf0 74 6f 20 70 61 64 0a 20 20 2a 2a 20 74 68 65 20  to pad.  ** the 
1ae00 74 72 61 6e 73 61 63 74 69 6f 6e 20 61 6e 64 2f  transaction and/
1ae10 6f 72 20 73 79 6e 63 20 74 68 65 20 57 41 4c 20  or sync the WAL 
1ae20 66 69 6c 65 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20  file..  **.  ** 
1ae30 50 61 64 64 69 6e 67 20 61 6e 64 20 73 79 6e 63  Padding and sync
1ae40 69 6e 67 20 6f 6e 6c 79 20 6f 63 63 75 72 20 69  ing only occur i
1ae50 66 20 74 68 69 73 20 73 65 74 20 6f 66 20 66 72  f this set of fr
1ae60 61 6d 65 73 20 63 6f 6d 70 6c 65 74 65 20 61 0a  ames complete a.
1ae70 20 20 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e    ** transaction
1ae80 20 61 6e 64 20 69 66 20 50 52 41 47 4d 41 20 73   and if PRAGMA s
1ae90 79 6e 63 68 72 6f 6e 6f 75 73 3d 46 55 4c 4c 2e  ynchronous=FULL.
1aea0 20 20 49 66 20 73 79 6e 63 68 72 6f 6e 6f 75 73    If synchronous
1aeb0 3d 3d 4e 4f 52 4d 41 4c 0a 20 20 2a 2a 20 6f 72  ==NORMAL.  ** or
1aec0 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 3d 4f 46   synchronous==OF
1aed0 46 2c 20 74 68 65 6e 20 6e 6f 20 70 61 64 64 69  F, then no paddi
1aee0 6e 67 20 6f 72 20 73 79 6e 63 69 6e 67 20 61 72  ng or syncing ar
1aef0 65 20 6e 65 65 64 65 64 2e 0a 20 20 2a 2a 0a 20  e needed..  **. 
1af00 20 2a 2a 20 49 66 20 53 51 4c 49 54 45 5f 49 4f   ** If SQLITE_IO
1af10 43 41 50 5f 50 4f 57 45 52 53 41 46 45 5f 4f 56  CAP_POWERSAFE_OV
1af20 45 52 57 52 49 54 45 20 69 73 20 64 65 66 69 6e  ERWRITE is defin
1af30 65 64 2c 20 74 68 65 6e 20 70 61 64 64 69 6e 67  ed, then padding
1af40 20 69 73 20 6e 6f 74 0a 20 20 2a 2a 20 6e 65 65   is not.  ** nee
1af50 64 65 64 20 61 6e 64 20 6f 6e 6c 79 20 74 68 65  ded and only the
1af60 20 73 79 6e 63 20 69 73 20 64 6f 6e 65 2e 20 20   sync is done.  
1af70 49 66 20 70 61 64 64 69 6e 67 20 69 73 20 6e 65  If padding is ne
1af80 65 64 65 64 2c 20 74 68 65 6e 20 74 68 65 0a 20  eded, then the. 
1af90 20 2a 2a 20 66 69 6e 61 6c 20 66 72 61 6d 65 20   ** final frame 
1afa0 69 73 20 72 65 70 65 61 74 65 64 20 28 77 69 74  is repeated (wit
1afb0 68 20 69 74 73 20 63 6f 6d 6d 69 74 20 6d 61 72  h its commit mar
1afc0 6b 29 20 75 6e 74 69 6c 20 74 68 65 20 6e 65 78  k) until the nex
1afd0 74 20 73 65 63 74 6f 72 0a 20 20 2a 2a 20 62 6f  t sector.  ** bo
1afe0 75 6e 64 61 72 79 20 69 73 20 63 72 6f 73 73 65  undary is crosse
1aff0 64 2e 20 20 4f 6e 6c 79 20 74 68 65 20 70 61 72  d.  Only the par
1b000 74 20 6f 66 20 74 68 65 20 57 41 4c 20 70 72 69  t of the WAL pri
1b010 6f 72 20 74 6f 20 74 68 65 20 6c 61 73 74 0a 20  or to the last. 
1b020 20 2a 2a 20 73 65 63 74 6f 72 20 62 6f 75 6e 64   ** sector bound
1b030 61 72 79 20 69 73 20 73 79 6e 63 65 64 3b 20 74  ary is synced; t
1b040 68 65 20 70 61 72 74 20 6f 66 20 74 68 65 20 6c  he part of the l
1b050 61 73 74 20 66 72 61 6d 65 20 74 68 61 74 20 65  ast frame that e
1b060 78 74 65 6e 64 73 0a 20 20 2a 2a 20 70 61 73 74  xtends.  ** past
1b070 20 74 68 65 20 73 65 63 74 6f 72 20 62 6f 75 6e   the sector boun
1b080 64 61 72 79 20 69 73 20 77 72 69 74 74 65 6e 20  dary is written 
1b090 61 66 74 65 72 20 74 68 65 20 73 79 6e 63 2e 0a  after the sync..
1b0a0 20 20 2a 2f 0a 20 20 69 66 28 20 69 73 43 6f 6d    */.  if( isCom
1b0b0 6d 69 74 20 26 26 20 28 73 79 6e 63 5f 66 6c 61  mit && (sync_fla
1b0c0 67 73 20 26 20 57 41 4c 5f 53 59 4e 43 5f 54 52  gs & WAL_SYNC_TR
1b0d0 41 4e 53 41 43 54 49 4f 4e 53 29 21 3d 30 20 29  ANSACTIONS)!=0 )
1b0e0 7b 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e  {.    if( pWal->
1b0f0 70 61 64 54 6f 53 65 63 74 6f 72 42 6f 75 6e 64  padToSectorBound
1b100 61 72 79 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  ary ){.      int
1b110 20 73 65 63 74 6f 72 53 69 7a 65 20 3d 20 73 71   sectorSize = sq
1b120 6c 69 74 65 33 53 65 63 74 6f 72 53 69 7a 65 28  lite3SectorSize(
1b130 70 57 61 6c 2d 3e 70 57 61 6c 46 64 29 3b 0a 20  pWal->pWalFd);. 
1b140 20 20 20 20 20 77 2e 69 53 79 6e 63 50 6f 69 6e       w.iSyncPoin
1b150 74 20 3d 20 28 28 69 4f 66 66 73 65 74 2b 73 65  t = ((iOffset+se
1b160 63 74 6f 72 53 69 7a 65 2d 31 29 2f 73 65 63 74  ctorSize-1)/sect
1b170 6f 72 53 69 7a 65 29 2a 73 65 63 74 6f 72 53 69  orSize)*sectorSi
1b180 7a 65 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28  ze;.      while(
1b190 20 69 4f 66 66 73 65 74 3c 77 2e 69 53 79 6e 63   iOffset<w.iSync
1b1a0 50 6f 69 6e 74 20 29 7b 0a 20 20 20 20 20 20 20  Point ){.       
1b1b0 20 72 63 20 3d 20 77 61 6c 57 72 69 74 65 4f 6e   rc = walWriteOn
1b1c0 65 46 72 61 6d 65 28 26 77 2c 20 70 4c 61 73 74  eFrame(&w, pLast
1b1d0 2c 20 6e 54 72 75 6e 63 61 74 65 2c 20 69 4f 66  , nTruncate, iOf
1b1e0 66 73 65 74 29 3b 0a 20 20 20 20 20 20 20 20 69  fset);.        i
1b1f0 66 28 20 72 63 20 29 20 72 65 74 75 72 6e 20 72  f( rc ) return r
1b200 63 3b 0a 20 20 20 20 20 20 20 20 69 4f 66 66 73  c;.        iOffs
1b210 65 74 20 2b 3d 20 73 7a 46 72 61 6d 65 3b 0a 20  et += szFrame;. 
1b220 20 20 20 20 20 20 20 6e 45 78 74 72 61 2b 2b 3b         nExtra++;
1b230 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c  .      }.    }el
1b240 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  se{.      rc = s
1b250 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 77 2e 70  qlite3OsSync(w.p
1b260 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73 20 26  Fd, sync_flags &
1b270 20 53 51 4c 49 54 45 5f 53 59 4e 43 5f 4d 41 53   SQLITE_SYNC_MAS
1b280 4b 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  K);.    }.  }.. 
1b290 20 2f 2a 20 49 66 20 74 68 69 73 20 66 72 61 6d   /* If this fram
1b2a0 65 20 73 65 74 20 63 6f 6d 70 6c 65 74 65 73 20  e set completes 
1b2b0 74 68 65 20 66 69 72 73 74 20 74 72 61 6e 73 61  the first transa
1b2c0 63 74 69 6f 6e 20 69 6e 20 74 68 65 20 57 41 4c  ction in the WAL
1b2d0 20 61 6e 64 0a 20 20 2a 2a 20 69 66 20 50 52 41   and.  ** if PRA
1b2e0 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 73 69 7a 65  GMA journal_size
1b2f0 5f 6c 69 6d 69 74 20 69 73 20 73 65 74 2c 20 74  _limit is set, t
1b300 68 65 6e 20 74 72 75 6e 63 61 74 65 20 74 68 65  hen truncate the
1b310 20 57 41 4c 20 74 6f 20 74 68 65 0a 20 20 2a 2a   WAL to the.  **
1b320 20 6a 6f 75 72 6e 61 6c 20 73 69 7a 65 20 6c 69   journal size li
1b330 6d 69 74 2c 20 69 66 20 70 6f 73 73 69 62 6c 65  mit, if possible
1b340 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69 73 43  ..  */.  if( isC
1b350 6f 6d 6d 69 74 20 26 26 20 70 57 61 6c 2d 3e 74  ommit && pWal->t
1b360 72 75 6e 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 20  runcateOnCommit 
1b370 26 26 20 70 57 61 6c 2d 3e 6d 78 57 61 6c 53 69  && pWal->mxWalSi
1b380 7a 65 3e 3d 30 20 29 7b 0a 20 20 20 20 69 36 34  ze>=0 ){.    i64
1b390 20 73 7a 20 3d 20 70 57 61 6c 2d 3e 6d 78 57 61   sz = pWal->mxWa
1b3a0 6c 53 69 7a 65 3b 0a 20 20 20 20 69 66 28 20 77  lSize;.    if( w
1b3b0 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46  alFrameOffset(iF
1b3c0 72 61 6d 65 2b 6e 45 78 74 72 61 2b 31 2c 20 73  rame+nExtra+1, s
1b3d0 7a 50 61 67 65 29 3e 70 57 61 6c 2d 3e 6d 78 57  zPage)>pWal->mxW
1b3e0 61 6c 53 69 7a 65 20 29 7b 0a 20 20 20 20 20 20  alSize ){.      
1b3f0 73 7a 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66  sz = walFrameOff
1b400 73 65 74 28 69 46 72 61 6d 65 2b 6e 45 78 74 72  set(iFrame+nExtr
1b410 61 2b 31 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20  a+1, szPage);.  
1b420 20 20 7d 0a 20 20 20 20 77 61 6c 4c 69 6d 69 74    }.    walLimit
1b430 53 69 7a 65 28 70 57 61 6c 2c 20 73 7a 29 3b 0a  Size(pWal, sz);.
1b440 20 20 20 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61      pWal->trunca
1b450 74 65 4f 6e 43 6f 6d 6d 69 74 20 3d 20 30 3b 0a  teOnCommit = 0;.
1b460 20 20 7d 0a 0a 20 20 2f 2a 20 41 70 70 65 6e 64    }..  /* Append
1b470 20 64 61 74 61 20 74 6f 20 74 68 65 20 77 61 6c   data to the wal
1b480 2d 69 6e 64 65 78 2e 20 49 74 20 69 73 20 6e 6f  -index. It is no
1b490 74 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20 6c  t necessary to l
1b4a0 6f 63 6b 20 74 68 65 20 0a 20 20 2a 2a 20 77 61  ock the .  ** wa
1b4b0 6c 2d 69 6e 64 65 78 20 74 6f 20 64 6f 20 74 68  l-index to do th
1b4c0 69 73 20 61 73 20 74 68 65 20 53 51 4c 49 54 45  is as the SQLITE
1b4d0 5f 53 48 4d 5f 57 52 49 54 45 20 6c 6f 63 6b 20  _SHM_WRITE lock 
1b4e0 68 65 6c 64 20 6f 6e 20 74 68 65 20 77 61 6c 2d  held on the wal-
1b4f0 69 6e 64 65 78 0a 20 20 2a 2a 20 67 75 61 72 61  index.  ** guara
1b500 6e 74 65 65 73 20 74 68 61 74 20 74 68 65 72 65  ntees that there
1b510 20 61 72 65 20 6e 6f 20 6f 74 68 65 72 20 77 72   are no other wr
1b520 69 74 65 72 73 2c 20 61 6e 64 20 6e 6f 20 64 61  iters, and no da
1b530 74 61 20 74 68 61 74 20 6d 61 79 0a 20 20 2a 2a  ta that may.  **
1b540 20 62 65 20 69 6e 20 75 73 65 20 62 79 20 65 78   be in use by ex
1b550 69 73 74 69 6e 67 20 72 65 61 64 65 72 73 20 69  isting readers i
1b560 73 20 62 65 69 6e 67 20 6f 76 65 72 77 72 69 74  s being overwrit
1b570 74 65 6e 2e 0a 20 20 2a 2f 0a 20 20 69 46 72 61  ten..  */.  iFra
1b580 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  me = pWal->hdr.m
1b590 78 46 72 61 6d 65 3b 0a 20 20 66 6f 72 28 70 3d  xFrame;.  for(p=
1b5a0 70 4c 69 73 74 3b 20 70 20 26 26 20 72 63 3d 3d  pList; p && rc==
1b5b0 53 51 4c 49 54 45 5f 4f 4b 3b 20 70 3d 70 2d 3e  SQLITE_OK; p=p->
1b5c0 70 44 69 72 74 79 29 7b 0a 20 20 20 20 69 46 72  pDirty){.    iFr
1b5d0 61 6d 65 2b 2b 3b 0a 20 20 20 20 72 63 20 3d 20  ame++;.    rc = 
1b5e0 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64 28 70  walIndexAppend(p
1b5f0 57 61 6c 2c 20 69 46 72 61 6d 65 2c 20 70 2d 3e  Wal, iFrame, p->
1b600 70 67 6e 6f 29 3b 0a 20 20 7d 0a 20 20 77 68 69  pgno);.  }.  whi
1b610 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  le( rc==SQLITE_O
1b620 4b 20 26 26 20 6e 45 78 74 72 61 3e 30 20 29 7b  K && nExtra>0 ){
1b630 0a 20 20 20 20 69 46 72 61 6d 65 2b 2b 3b 0a 20  .    iFrame++;. 
1b640 20 20 20 6e 45 78 74 72 61 2d 2d 3b 0a 20 20 20     nExtra--;.   
1b650 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70   rc = walIndexAp
1b660 70 65 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d  pend(pWal, iFram
1b670 65 2c 20 70 4c 61 73 74 2d 3e 70 67 6e 6f 29 3b  e, pLast->pgno);
1b680 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
1b690 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
1b6a0 20 2f 2a 20 55 70 64 61 74 65 20 74 68 65 20 70   /* Update the p
1b6b0 72 69 76 61 74 65 20 63 6f 70 79 20 6f 66 20 74  rivate copy of t
1b6c0 68 65 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20 20  he header. */.  
1b6d0 20 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61    pWal->hdr.szPa
1b6e0 67 65 20 3d 20 28 75 31 36 29 28 28 73 7a 50 61  ge = (u16)((szPa
1b6f0 67 65 26 30 78 66 66 30 30 29 20 7c 20 28 73 7a  ge&0xff00) | (sz
1b700 50 61 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20 20  Page>>16));.    
1b710 74 65 73 74 63 61 73 65 28 20 73 7a 50 61 67 65  testcase( szPage
1b720 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20 20 20 74  <=32768 );.    t
1b730 65 73 74 63 61 73 65 28 20 73 7a 50 61 67 65 3e  estcase( szPage>
1b740 3d 36 35 35 33 36 20 29 3b 0a 20 20 20 20 70 57  =65536 );.    pW
1b750 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
1b760 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20 20 69 66  = iFrame;.    if
1b770 28 20 69 73 43 6f 6d 6d 69 74 20 29 7b 0a 20 20  ( isCommit ){.  
1b780 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69 43      pWal->hdr.iC
1b790 68 61 6e 67 65 2b 2b 3b 0a 20 20 20 20 20 20 70  hange++;.      p
1b7a0 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20 3d  Wal->hdr.nPage =
1b7b0 20 6e 54 72 75 6e 63 61 74 65 3b 0a 20 20 20 20   nTruncate;.    
1b7c0 7d 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73  }.    /* If this
1b7d0 20 69 73 20 61 20 63 6f 6d 6d 69 74 2c 20 75 70   is a commit, up
1b7e0 64 61 74 65 20 74 68 65 20 77 61 6c 2d 69 6e 64  date the wal-ind
1b7f0 65 78 20 68 65 61 64 65 72 20 74 6f 6f 2e 20 2a  ex header too. *
1b800 2f 0a 20 20 20 20 69 66 28 20 69 73 43 6f 6d 6d  /.    if( isComm
1b810 69 74 20 29 7b 0a 20 20 20 20 20 20 77 61 6c 49  it ){.      walI
1b820 6e 64 65 78 57 72 69 74 65 48 64 72 28 70 57 61  ndexWriteHdr(pWa
1b830 6c 29 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e  l);.      pWal->
1b840 69 43 61 6c 6c 62 61 63 6b 20 3d 20 69 46 72 61  iCallback = iFra
1b850 6d 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  me;.    }.  }.. 
1b860 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
1b870 70 3a 20 66 72 61 6d 65 20 77 72 69 74 65 20 25  p: frame write %
1b880 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72 63 20 3f  s\n", pWal, rc ?
1b890 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22   "failed" : "ok"
1b8a0 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ));.  return rc;
1b8b0 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20  .}../* .** This 
1b8c0 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65  routine is calle
1b8d0 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 73  d to implement s
1b8e0 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68 65 63 6b  qlite3_wal_check
1b8f0 70 6f 69 6e 74 28 29 20 61 6e 64 0a 2a 2a 20 72  point() and.** r
1b900 65 6c 61 74 65 64 20 69 6e 74 65 72 66 61 63 65  elated interface
1b910 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20  s..**.** Obtain 
1b920 61 20 43 48 45 43 4b 50 4f 49 4e 54 20 6c 6f 63  a CHECKPOINT loc
1b930 6b 20 61 6e 64 20 74 68 65 6e 20 62 61 63 6b 66  k and then backf
1b940 69 6c 6c 20 61 73 20 6d 75 63 68 20 69 6e 66 6f  ill as much info
1b950 72 6d 61 74 69 6f 6e 20 61 73 0a 2a 2a 20 77 65  rmation as.** we
1b960 20 63 61 6e 20 66 72 6f 6d 20 57 41 4c 20 69 6e   can from WAL in
1b970 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 2e  to the database.
1b980 0a 2a 2a 0a 2a 2a 20 49 66 20 70 61 72 61 6d 65  .**.** If parame
1b990 74 65 72 20 78 42 75 73 79 20 69 73 20 6e 6f 74  ter xBusy is not
1b9a0 20 4e 55 4c 4c 2c 20 69 74 20 69 73 20 61 20 70   NULL, it is a p
1b9b0 6f 69 6e 74 65 72 20 74 6f 20 61 20 62 75 73 79  ointer to a busy
1b9c0 2d 68 61 6e 64 6c 65 72 0a 2a 2a 20 63 61 6c 6c  -handler.** call
1b9d0 62 61 63 6b 2e 20 49 6e 20 74 68 69 73 20 63 61  back. In this ca
1b9e0 73 65 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  se this function
1b9f0 20 72 75 6e 73 20 61 20 62 6c 6f 63 6b 69 6e 67   runs a blocking
1ba00 20 63 68 65 63 6b 70 6f 69 6e 74 2e 0a 2a 2f 0a   checkpoint..*/.
1ba10 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 43 68  int sqlite3WalCh
1ba20 65 63 6b 70 6f 69 6e 74 28 0a 20 20 57 61 6c 20  eckpoint(.  Wal 
1ba30 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20  *pWal,          
1ba40 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
1ba50 61 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f  al connection */
1ba60 0a 20 20 69 6e 74 20 65 4d 6f 64 65 2c 20 20 20  .  int eMode,   
1ba70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1ba80 20 20 20 2f 2a 20 50 41 53 53 49 56 45 2c 20 46     /* PASSIVE, F
1ba90 55 4c 4c 2c 20 52 45 53 54 41 52 54 2c 20 6f 72  ULL, RESTART, or
1baa0 20 54 52 55 4e 43 41 54 45 20 2a 2f 0a 20 20 69   TRUNCATE */.  i
1bab0 6e 74 20 28 2a 78 42 75 73 79 29 28 76 6f 69 64  nt (*xBusy)(void
1bac0 2a 29 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  *),            /
1bad0 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63 61  * Function to ca
1bae0 6c 6c 20 77 68 65 6e 20 62 75 73 79 20 2a 2f 0a  ll when busy */.
1baf0 20 20 76 6f 69 64 20 2a 70 42 75 73 79 41 72 67    void *pBusyArg
1bb00 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
1bb10 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 61 72 67    /* Context arg
1bb20 75 6d 65 6e 74 20 66 6f 72 20 78 42 75 73 79 48  ument for xBusyH
1bb30 61 6e 64 6c 65 72 20 2a 2f 0a 20 20 69 6e 74 20  andler */.  int 
1bb40 73 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20 20  sync_flags,     
1bb50 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
1bb60 6c 61 67 73 20 74 6f 20 73 79 6e 63 20 64 62 20  lags to sync db 
1bb70 66 69 6c 65 20 77 69 74 68 20 28 6f 72 20 30 29  file with (or 0)
1bb80 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20   */.  int nBuf, 
1bb90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bba0 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
1bbb0 20 74 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65   temporary buffe
1bbc0 72 20 2a 2f 0a 20 20 75 38 20 2a 7a 42 75 66 2c  r */.  u8 *zBuf,
1bbd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1bbe0 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72         /* Tempor
1bbf0 61 72 79 20 62 75 66 66 65 72 20 74 6f 20 75 73  ary buffer to us
1bc00 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4c 6f  e */.  int *pnLo
1bc10 67 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  g,              
1bc20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e         /* OUT: N
1bc30 75 6d 62 65 72 20 6f 66 20 66 72 61 6d 65 73 20  umber of frames 
1bc40 69 6e 20 57 41 4c 20 2a 2f 0a 20 20 69 6e 74 20  in WAL */.  int 
1bc50 2a 70 6e 43 6b 70 74 20 20 20 20 20 20 20 20 20  *pnCkpt         
1bc60 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
1bc70 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66 20 62 61  UT: Number of ba
1bc80 63 6b 66 69 6c 6c 65 64 20 66 72 61 6d 65 73 20  ckfilled frames 
1bc90 69 6e 20 57 41 4c 20 2a 2f 0a 29 7b 0a 20 20 69  in WAL */.){.  i
1bca0 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
1bcb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1bcc0 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
1bcd0 0a 20 20 69 6e 74 20 69 73 43 68 61 6e 67 65 64  .  int isChanged
1bce0 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
1bcf0 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61 20     /* True if a 
1bd00 6e 65 77 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  new wal-index he
1bd10 61 64 65 72 20 69 73 20 6c 6f 61 64 65 64 20 2a  ader is loaded *
1bd20 2f 0a 20 20 69 6e 74 20 65 4d 6f 64 65 32 20 3d  /.  int eMode2 =
1bd30 20 65 4d 6f 64 65 3b 20 20 20 20 20 20 20 20 20   eMode;         
1bd40 20 20 20 20 2f 2a 20 4d 6f 64 65 20 74 6f 20 70      /* Mode to p
1bd50 61 73 73 20 74 6f 20 77 61 6c 43 68 65 63 6b 70  ass to walCheckp
1bd60 6f 69 6e 74 28 29 20 2a 2f 0a 20 20 69 6e 74 20  oint() */.  int 
1bd70 28 2a 78 42 75 73 79 32 29 28 76 6f 69 64 2a 29  (*xBusy2)(void*)
1bd80 20 3d 20 78 42 75 73 79 3b 20 20 20 2f 2a 20 42   = xBusy;   /* B
1bd90 75 73 79 20 68 61 6e 64 6c 65 72 20 66 6f 72 20  usy handler for 
1bda0 65 4d 6f 64 65 32 20 2a 2f 0a 0a 20 20 61 73 73  eMode2 */..  ass
1bdb0 65 72 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c  ert( pWal->ckptL
1bdc0 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65  ock==0 );.  asse
1bdd0 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c  rt( pWal->writeL
1bde0 6f 63 6b 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20  ock==0 );..  /* 
1bdf0 45 56 49 44 45 4e 43 45 2d 4f 46 3a 20 52 2d 36  EVIDENCE-OF: R-6
1be00 32 39 32 30 2d 34 37 34 35 30 20 54 68 65 20 62  2920-47450 The b
1be10 75 73 79 2d 68 61 6e 64 6c 65 72 20 63 61 6c 6c  usy-handler call
1be20 62 61 63 6b 20 69 73 20 6e 65 76 65 72 20 69 6e  back is never in
1be30 76 6f 6b 65 64 0a 20 20 2a 2a 20 69 6e 20 74 68  voked.  ** in th
1be40 65 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f  e SQLITE_CHECKPO
1be50 49 4e 54 5f 50 41 53 53 49 56 45 20 6d 6f 64 65  INT_PASSIVE mode
1be60 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 65  . */.  assert( e
1be70 4d 6f 64 65 21 3d 53 51 4c 49 54 45 5f 43 48 45  Mode!=SQLITE_CHE
1be80 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 20  CKPOINT_PASSIVE 
1be90 7c 7c 20 78 42 75 73 79 3d 3d 30 20 29 3b 0a 0a  || xBusy==0 );..
1bea0 20 20 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64    if( pWal->read
1beb0 4f 6e 6c 79 20 29 20 72 65 74 75 72 6e 20 53 51  Only ) return SQ
1bec0 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 3b 0a 20  LITE_READONLY;. 
1bed0 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
1bee0 70 3a 20 63 68 65 63 6b 70 6f 69 6e 74 20 62 65  p: checkpoint be
1bef0 67 69 6e 73 5c 6e 22 2c 20 70 57 61 6c 29 29 3b  gins\n", pWal));
1bf00 0a 0a 20 20 2f 2a 20 49 4d 50 4c 45 4d 45 4e 54  ..  /* IMPLEMENT
1bf10 41 54 49 4f 4e 2d 4f 46 3a 20 52 2d 36 32 30 32  ATION-OF: R-6202
1bf20 38 2d 34 37 32 31 32 20 41 6c 6c 20 63 61 6c 6c  8-47212 All call
1bf30 73 20 6f 62 74 61 69 6e 20 61 6e 20 65 78 63 6c  s obtain an excl
1bf40 75 73 69 76 65 20 0a 20 20 2a 2a 20 22 63 68 65  usive .  ** "che
1bf50 63 6b 70 6f 69 6e 74 22 20 6c 6f 63 6b 20 6f 6e  ckpoint" lock on
1bf60 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
1bf70 6c 65 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 77 61  le. */.  rc = wa
1bf80 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  lLockExclusive(p
1bf90 57 61 6c 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f  Wal, WAL_CKPT_LO
1bfa0 43 4b 2c 20 31 29 3b 0a 20 20 69 66 28 20 72 63  CK, 1);.  if( rc
1bfb0 20 29 7b 0a 20 20 20 20 2f 2a 20 45 56 49 44 45   ){.    /* EVIDE
1bfc0 4e 43 45 2d 4f 46 3a 20 52 2d 31 30 34 32 31 2d  NCE-OF: R-10421-
1bfd0 31 39 37 33 36 20 49 66 20 61 6e 79 20 6f 74 68  19736 If any oth
1bfe0 65 72 20 70 72 6f 63 65 73 73 20 69 73 20 72 75  er process is ru
1bff0 6e 6e 69 6e 67 20 61 0a 20 20 20 20 2a 2a 20 63  nning a.    ** c
1c000 68 65 63 6b 70 6f 69 6e 74 20 6f 70 65 72 61 74  heckpoint operat
1c010 69 6f 6e 20 61 74 20 74 68 65 20 73 61 6d 65 20  ion at the same 
1c020 74 69 6d 65 2c 20 74 68 65 20 6c 6f 63 6b 20 63  time, the lock c
1c030 61 6e 6e 6f 74 20 62 65 20 6f 62 74 61 69 6e 65  annot be obtaine
1c040 64 20 61 6e 64 0a 20 20 20 20 2a 2a 20 53 51 4c  d and.    ** SQL
1c050 49 54 45 5f 42 55 53 59 20 69 73 20 72 65 74 75  ITE_BUSY is retu
1c060 72 6e 65 64 2e 0a 20 20 20 20 2a 2a 20 45 56 49  rned..    ** EVI
1c070 44 45 4e 43 45 2d 4f 46 3a 20 52 2d 35 33 38 32  DENCE-OF: R-5382
1c080 30 2d 33 33 38 39 37 20 45 76 65 6e 20 69 66 20  0-33897 Even if 
1c090 74 68 65 72 65 20 69 73 20 61 20 62 75 73 79 2d  there is a busy-
1c0a0 68 61 6e 64 6c 65 72 20 63 6f 6e 66 69 67 75 72  handler configur
1c0b0 65 64 2c 0a 20 20 20 20 2a 2a 20 69 74 20 77 69  ed,.    ** it wi
1c0c0 6c 6c 20 6e 6f 74 20 62 65 20 69 6e 76 6f 6b 65  ll not be invoke
1c0d0 64 20 69 6e 20 74 68 69 73 20 63 61 73 65 2e 0a  d in this case..
1c0e0 20 20 20 20 2a 2f 0a 20 20 20 20 74 65 73 74 63      */.    testc
1c0f0 61 73 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ase( rc==SQLITE_
1c100 42 55 53 59 20 29 3b 0a 20 20 20 20 74 65 73 74  BUSY );.    test
1c110 63 61 73 65 28 20 78 42 75 73 79 21 3d 30 20 29  case( xBusy!=0 )
1c120 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  ;.    return rc;
1c130 0a 20 20 7d 0a 20 20 70 57 61 6c 2d 3e 63 6b 70  .  }.  pWal->ckp
1c140 74 4c 6f 63 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a  tLock = 1;..  /*
1c150 20 49 4d 50 4c 45 4d 45 4e 54 41 54 49 4f 4e 2d   IMPLEMENTATION-
1c160 4f 46 3a 20 52 2d 35 39 37 38 32 2d 33 36 38 31  OF: R-59782-3681
1c170 38 20 54 68 65 20 53 51 4c 49 54 45 5f 43 48 45  8 The SQLITE_CHE
1c180 43 4b 50 4f 49 4e 54 5f 46 55 4c 4c 2c 20 52 45  CKPOINT_FULL, RE
1c190 53 54 41 52 54 20 61 6e 64 0a 20 20 2a 2a 20 54  START and.  ** T
1c1a0 52 55 4e 43 41 54 45 20 6d 6f 64 65 73 20 61 6c  RUNCATE modes al
1c1b0 73 6f 20 6f 62 74 61 69 6e 20 74 68 65 20 65 78  so obtain the ex
1c1c0 63 6c 75 73 69 76 65 20 22 77 72 69 74 65 72 22  clusive "writer"
1c1d0 20 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 64 61 74   lock on the dat
1c1e0 61 62 61 73 65 0a 20 20 2a 2a 20 66 69 6c 65 2e  abase.  ** file.
1c1f0 0a 20 20 2a 2a 0a 20 20 2a 2a 20 45 56 49 44 45  .  **.  ** EVIDE
1c200 4e 43 45 2d 4f 46 3a 20 52 2d 36 30 36 34 32 2d  NCE-OF: R-60642-
1c210 30 34 30 38 32 20 49 66 20 74 68 65 20 77 72 69  04082 If the wri
1c220 74 65 72 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20  ter lock cannot 
1c230 62 65 20 6f 62 74 61 69 6e 65 64 0a 20 20 2a 2a  be obtained.  **
1c240 20 69 6d 6d 65 64 69 61 74 65 6c 79 2c 20 61 6e   immediately, an
1c250 64 20 61 20 62 75 73 79 2d 68 61 6e 64 6c 65 72  d a busy-handler
1c260 20 69 73 20 63 6f 6e 66 69 67 75 72 65 64 2c 20   is configured, 
1c270 69 74 20 69 73 20 69 6e 76 6f 6b 65 64 20 61 6e  it is invoked an
1c280 64 20 74 68 65 0a 20 20 2a 2a 20 77 72 69 74 65  d the.  ** write
1c290 72 20 6c 6f 63 6b 20 72 65 74 72 69 65 64 20 75  r lock retried u
1c2a0 6e 74 69 6c 20 65 69 74 68 65 72 20 74 68 65 20  ntil either the 
1c2b0 62 75 73 79 2d 68 61 6e 64 6c 65 72 20 72 65 74  busy-handler ret
1c2c0 75 72 6e 73 20 30 20 6f 72 20 74 68 65 0a 20 20  urns 0 or the.  
1c2d0 2a 2a 20 6c 6f 63 6b 20 69 73 20 73 75 63 63 65  ** lock is succe
1c2e0 73 73 66 75 6c 6c 79 20 6f 62 74 61 69 6e 65 64  ssfully obtained
1c2f0 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 65 4d 6f  ..  */.  if( eMo
1c300 64 65 21 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b  de!=SQLITE_CHECK
1c310 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 29 7b  POINT_PASSIVE ){
1c320 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 42 75 73  .    rc = walBus
1c330 79 4c 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73  yLock(pWal, xBus
1c340 79 2c 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c  y, pBusyArg, WAL
1c350 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b  _WRITE_LOCK, 1);
1c360 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
1c370 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
1c380 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
1c390 3d 20 31 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  = 1;.    }else i
1c3a0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  f( rc==SQLITE_BU
1c3b0 53 59 20 29 7b 0a 20 20 20 20 20 20 65 4d 6f 64  SY ){.      eMod
1c3c0 65 32 20 3d 20 53 51 4c 49 54 45 5f 43 48 45 43  e2 = SQLITE_CHEC
1c3d0 4b 50 4f 49 4e 54 5f 50 41 53 53 49 56 45 3b 0a  KPOINT_PASSIVE;.
1c3e0 20 20 20 20 20 20 78 42 75 73 79 32 20 3d 20 30        xBusy2 = 0
1c3f0 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  ;.      rc = SQL
1c400 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20  ITE_OK;.    }.  
1c410 7d 0a 0a 20 20 2f 2a 20 52 65 61 64 20 74 68 65  }..  /* Read the
1c420 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
1c430 72 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  r. */.  if( rc==
1c440 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
1c450 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52 65   rc = walIndexRe
1c460 61 64 48 64 72 28 70 57 61 6c 2c 20 26 69 73 43  adHdr(pWal, &isC
1c470 68 61 6e 67 65 64 29 3b 0a 20 20 20 20 69 66 28  hanged);.    if(
1c480 20 69 73 43 68 61 6e 67 65 64 20 26 26 20 70 57   isChanged && pW
1c490 61 6c 2d 3e 70 44 62 46 64 2d 3e 70 4d 65 74 68  al->pDbFd->pMeth
1c4a0 6f 64 73 2d 3e 69 56 65 72 73 69 6f 6e 3e 3d 33  ods->iVersion>=3
1c4b0 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ){.      sqlite
1c4c0 33 4f 73 55 6e 66 65 74 63 68 28 70 57 61 6c 2d  3OsUnfetch(pWal-
1c4d0 3e 70 44 62 46 64 2c 20 30 2c 20 30 29 3b 0a 20  >pDbFd, 0, 0);. 
1c4e0 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43     }.  }..  /* C
1c4f0 6f 70 79 20 64 61 74 61 20 66 72 6f 6d 20 74 68  opy data from th
1c500 65 20 6c 6f 67 20 74 6f 20 74 68 65 20 64 61 74  e log to the dat
1c510 61 62 61 73 65 20 66 69 6c 65 2e 20 2a 2f 0a 20  abase file. */. 
1c520 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
1c530 4f 4b 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57  OK ){.    if( pW
1c540 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
1c550 26 26 20 77 61 6c 50 61 67 65 73 69 7a 65 28 70  && walPagesize(p
1c560 57 61 6c 29 21 3d 6e 42 75 66 20 29 7b 0a 20 20  Wal)!=nBuf ){.  
1c570 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
1c580 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20  CORRUPT_BKPT;.  
1c590 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72    }else{.      r
1c5a0 63 20 3d 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e  c = walCheckpoin
1c5b0 74 28 70 57 61 6c 2c 20 65 4d 6f 64 65 32 2c 20  t(pWal, eMode2, 
1c5c0 78 42 75 73 79 32 2c 20 70 42 75 73 79 41 72 67  xBusy2, pBusyArg
1c5d0 2c 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20 7a 42  , sync_flags, zB
1c5e0 75 66 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  uf);.    }..    
1c5f0 2f 2a 20 49 66 20 6e 6f 20 65 72 72 6f 72 20 6f  /* If no error o
1c600 63 63 75 72 72 65 64 2c 20 73 65 74 20 74 68 65  ccurred, set the
1c610 20 6f 75 74 70 75 74 20 76 61 72 69 61 62 6c 65   output variable
1c620 73 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63  s. */.    if( rc
1c630 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 72  ==SQLITE_OK || r
1c640 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29  c==SQLITE_BUSY )
1c650 7b 0a 20 20 20 20 20 20 69 66 28 20 70 6e 4c 6f  {.      if( pnLo
1c660 67 20 29 20 2a 70 6e 4c 6f 67 20 3d 20 28 69 6e  g ) *pnLog = (in
1c670 74 29 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  t)pWal->hdr.mxFr
1c680 61 6d 65 3b 0a 20 20 20 20 20 20 69 66 28 20 70  ame;.      if( p
1c690 6e 43 6b 70 74 20 29 20 2a 70 6e 43 6b 70 74 20  nCkpt ) *pnCkpt 
1c6a0 3d 20 28 69 6e 74 29 28 77 61 6c 43 6b 70 74 49  = (int)(walCkptI
1c6b0 6e 66 6f 28 70 57 61 6c 29 2d 3e 6e 42 61 63 6b  nfo(pWal)->nBack
1c6c0 66 69 6c 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  fill);.    }.  }
1c6d0 0a 0a 20 20 69 66 28 20 69 73 43 68 61 6e 67 65  ..  if( isChange
1c6e0 64 20 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 61  d ){.    /* If a
1c6f0 20 6e 65 77 20 77 61 6c 2d 69 6e 64 65 78 20 68   new wal-index h
1c700 65 61 64 65 72 20 77 61 73 20 6c 6f 61 64 65 64  eader was loaded
1c710 20 62 65 66 6f 72 65 20 74 68 65 20 63 68 65 63   before the chec
1c720 6b 70 6f 69 6e 74 20 77 61 73 20 0a 20 20 20 20  kpoint was .    
1c730 2a 2a 20 70 65 72 66 6f 72 6d 65 64 2c 20 74 68  ** performed, th
1c740 65 6e 20 74 68 65 20 70 61 67 65 72 2d 63 61 63  en the pager-cac
1c750 68 65 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  he associated wi
1c760 74 68 20 70 57 61 6c 20 69 73 20 6e 6f 77 0a 20  th pWal is now. 
1c770 20 20 20 2a 2a 20 6f 75 74 20 6f 66 20 64 61 74     ** out of dat
1c780 65 2e 20 53 6f 20 7a 65 72 6f 20 74 68 65 20 63  e. So zero the c
1c790 61 63 68 65 64 20 77 61 6c 2d 69 6e 64 65 78 20  ached wal-index 
1c7a0 68 65 61 64 65 72 20 74 6f 20 65 6e 73 75 72 65  header to ensure
1c7b0 20 74 68 61 74 0a 20 20 20 20 2a 2a 20 6e 65 78   that.    ** nex
1c7c0 74 20 74 69 6d 65 20 74 68 65 20 70 61 67 65 72  t time the pager
1c7d0 20 6f 70 65 6e 73 20 61 20 73 6e 61 70 73 68 6f   opens a snapsho
1c7e0 74 20 6f 6e 20 74 68 69 73 20 64 61 74 61 62 61  t on this databa
1c7f0 73 65 20 69 74 20 6b 6e 6f 77 73 20 74 68 61 74  se it knows that
1c800 0a 20 20 20 20 2a 2a 20 74 68 65 20 63 61 63 68  .    ** the cach
1c810 65 20 6e 65 65 64 73 20 74 6f 20 62 65 20 72 65  e needs to be re
1c820 73 65 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  set..    */.    
1c830 6d 65 6d 73 65 74 28 26 70 57 61 6c 2d 3e 68 64  memset(&pWal->hd
1c840 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 57 61 6c  r, 0, sizeof(Wal
1c850 49 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 7d 0a  IndexHdr));.  }.
1c860 0a 20 20 2f 2a 20 52 65 6c 65 61 73 65 20 74 68  .  /* Release th
1c870 65 20 6c 6f 63 6b 73 2e 20 2a 2f 0a 20 20 73 71  e locks. */.  sq
1c880 6c 69 74 65 33 57 61 6c 45 6e 64 57 72 69 74 65  lite3WalEndWrite
1c890 54 72 61 6e 73 61 63 74 69 6f 6e 28 70 57 61 6c  Transaction(pWal
1c8a0 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78  );.  walUnlockEx
1c8b0 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
1c8c0 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b  L_CKPT_LOCK, 1);
1c8d0 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63  .  pWal->ckptLoc
1c8e0 6b 20 3d 20 30 3b 0a 20 20 57 41 4c 54 52 41 43  k = 0;.  WALTRAC
1c8f0 45 28 28 22 57 41 4c 25 70 3a 20 63 68 65 63 6b  E(("WAL%p: check
1c900 70 6f 69 6e 74 20 25 73 5c 6e 22 2c 20 70 57 61  point %s\n", pWa
1c910 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22  l, rc ? "failed"
1c920 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 72 65 74   : "ok"));.  ret
1c930 75 72 6e 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f  urn (rc==SQLITE_
1c940 4f 4b 20 26 26 20 65 4d 6f 64 65 21 3d 65 4d 6f  OK && eMode!=eMo
1c950 64 65 32 20 3f 20 53 51 4c 49 54 45 5f 42 55 53  de2 ? SQLITE_BUS
1c960 59 20 3a 20 72 63 29 3b 0a 7d 0a 0a 2f 2a 20 52  Y : rc);.}../* R
1c970 65 74 75 72 6e 20 74 68 65 20 76 61 6c 75 65 20  eturn the value 
1c980 74 6f 20 70 61 73 73 20 74 6f 20 61 20 73 71 6c  to pass to a sql
1c990 69 74 65 33 5f 77 61 6c 5f 68 6f 6f 6b 20 63 61  ite3_wal_hook ca
1c9a0 6c 6c 62 61 63 6b 2c 20 74 68 65 0a 2a 2a 20 6e  llback, the.** n
1c9b0 75 6d 62 65 72 20 6f 66 20 66 72 61 6d 65 73 20  umber of frames 
1c9c0 69 6e 20 74 68 65 20 57 41 4c 20 61 74 20 74 68  in the WAL at th
1c9d0 65 20 70 6f 69 6e 74 20 6f 66 20 74 68 65 20 6c  e point of the l
1c9e0 61 73 74 20 63 6f 6d 6d 69 74 20 73 69 6e 63 65  ast commit since
1c9f0 0a 2a 2a 20 73 71 6c 69 74 65 33 57 61 6c 43 61  .** sqlite3WalCa
1ca00 6c 6c 62 61 63 6b 28 29 20 77 61 73 20 63 61 6c  llback() was cal
1ca10 6c 65 64 2e 20 20 49 66 20 6e 6f 20 63 6f 6d 6d  led.  If no comm
1ca20 69 74 73 20 68 61 76 65 20 6f 63 63 75 72 72 65  its have occurre
1ca30 64 20 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 6c  d since.** the l
1ca40 61 73 74 20 63 61 6c 6c 2c 20 74 68 65 6e 20 72  ast call, then r
1ca50 65 74 75 72 6e 20 30 2e 0a 2a 2f 0a 69 6e 74 20  eturn 0..*/.int 
1ca60 73 71 6c 69 74 65 33 57 61 6c 43 61 6c 6c 62 61  sqlite3WalCallba
1ca70 63 6b 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20  ck(Wal *pWal){. 
1ca80 20 75 33 32 20 72 65 74 20 3d 20 30 3b 0a 20 20   u32 ret = 0;.  
1ca90 69 66 28 20 70 57 61 6c 20 29 7b 0a 20 20 20 20  if( pWal ){.    
1caa0 72 65 74 20 3d 20 70 57 61 6c 2d 3e 69 43 61 6c  ret = pWal->iCal
1cab0 6c 62 61 63 6b 3b 0a 20 20 20 20 70 57 61 6c 2d  lback;.    pWal-
1cac0 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20 30 3b 0a  >iCallback = 0;.
1cad0 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 28 69 6e    }.  return (in
1cae0 74 29 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  t)ret;.}../*.** 
1caf0 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
1cb00 20 63 61 6c 6c 65 64 20 74 6f 20 63 68 61 6e 67   called to chang
1cb10 65 20 74 68 65 20 57 41 4c 20 73 75 62 73 79 73  e the WAL subsys
1cb20 74 65 6d 20 69 6e 74 6f 20 6f 72 20 6f 75 74 0a  tem into or out.
1cb30 2a 2a 20 6f 66 20 6c 6f 63 6b 69 6e 67 5f 6d 6f  ** of locking_mo
1cb40 64 65 3d 45 58 43 4c 55 53 49 56 45 2e 0a 2a 2a  de=EXCLUSIVE..**
1cb50 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20 7a 65 72  .** If op is zer
1cb60 6f 2c 20 74 68 65 6e 20 61 74 74 65 6d 70 74 20  o, then attempt 
1cb70 74 6f 20 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c  to change from l
1cb80 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c  ocking_mode=EXCL
1cb90 55 53 49 56 45 0a 2a 2a 20 69 6e 74 6f 20 6c 6f  USIVE.** into lo
1cba0 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41  cking_mode=NORMA
1cbb0 4c 2e 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74  L.  This means t
1cbc0 68 61 74 20 77 65 20 6d 75 73 74 20 61 63 71 75  hat we must acqu
1cbd0 69 72 65 20 61 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e  ire a lock.** on
1cbe0 20 74 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c   the pWal->readL
1cbf0 6f 63 6b 20 62 79 74 65 2e 20 20 49 66 20 74 68  ock byte.  If th
1cc00 65 20 57 41 4c 20 69 73 20 61 6c 72 65 61 64 79  e WAL is already
1cc10 20 69 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65   in locking_mode
1cc20 3d 4e 4f 52 4d 41 4c 0a 2a 2a 20 6f 72 20 69 66  =NORMAL.** or if
1cc30 20 74 68 65 20 61 63 71 75 69 73 69 74 69 6f 6e   the acquisition
1cc40 20 6f 66 20 74 68 65 20 6c 6f 63 6b 20 66 61 69   of the lock fai
1cc50 6c 73 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20  ls, then return 
1cc60 30 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 74 72  0.  If the.** tr
1cc70 61 6e 73 69 74 69 6f 6e 20 6f 75 74 20 6f 66 20  ansition out of 
1cc80 65 78 63 6c 75 73 69 76 65 2d 6d 6f 64 65 20 69  exclusive-mode i
1cc90 73 20 73 75 63 63 65 73 73 66 75 6c 2c 20 72 65  s successful, re
1cca0 74 75 72 6e 20 31 2e 20 20 54 68 69 73 0a 2a 2a  turn 1.  This.**
1ccb0 20 6f 70 65 72 61 74 69 6f 6e 20 6d 75 73 74 20   operation must 
1ccc0 6f 63 63 75 72 20 77 68 69 6c 65 20 74 68 65 20  occur while the 
1ccd0 70 61 67 65 72 20 69 73 20 73 74 69 6c 6c 20 68  pager is still h
1cce0 6f 6c 64 69 6e 67 20 74 68 65 20 65 78 63 6c 75  olding the exclu
1ccf0 73 69 76 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20  sive.** lock on 
1cd00 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73  the main databas
1cd10 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66  e file..**.** If
1cd20 20 6f 70 20 69 73 20 6f 6e 65 2c 20 74 68 65 6e   op is one, then
1cd30 20 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63   change from loc
1cd40 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c  king_mode=NORMAL
1cd50 20 69 6e 74 6f 20 0a 2a 2a 20 6c 6f 63 6b 69 6e   into .** lockin
1cd60 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45  g_mode=EXCLUSIVE
1cd70 2e 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68  .  This means th
1cd80 61 74 20 74 68 65 20 70 57 61 6c 2d 3e 72 65 61  at the pWal->rea
1cd90 64 4c 6f 63 6b 20 6d 75 73 74 0a 2a 2a 20 62 65  dLock must.** be
1cda0 20 72 65 6c 65 61 73 65 64 2e 20 20 52 65 74 75   released.  Retu
1cdb0 72 6e 20 31 20 69 66 20 74 68 65 20 74 72 61 6e  rn 1 if the tran
1cdc0 73 69 74 69 6f 6e 20 69 73 20 6d 61 64 65 20 61  sition is made a
1cdd0 6e 64 20 30 20 69 66 20 74 68 65 0a 2a 2a 20 57  nd 0 if the.** W
1cde0 41 4c 20 69 73 20 61 6c 72 65 61 64 79 20 69 6e  AL is already in
1cdf0 20 65 78 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69   exclusive-locki
1ce00 6e 67 20 6d 6f 64 65 20 2d 20 6d 65 61 6e 69 6e  ng mode - meanin
1ce10 67 20 74 68 61 74 20 74 68 69 73 0a 2a 2a 20 72  g that this.** r
1ce20 6f 75 74 69 6e 65 20 69 73 20 61 20 6e 6f 2d 6f  outine is a no-o
1ce30 70 2e 20 20 54 68 65 20 70 61 67 65 72 20 6d 75  p.  The pager mu
1ce40 73 74 20 61 6c 72 65 61 64 79 20 68 6f 6c 64 20  st already hold 
1ce50 74 68 65 20 65 78 63 6c 75 73 69 76 65 20 6c 6f  the exclusive lo
1ce60 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20 6d 61 69  ck.** on the mai
1ce70 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  n database file 
1ce80 62 65 66 6f 72 65 20 69 6e 76 6f 6b 69 6e 67 20  before invoking 
1ce90 74 68 69 73 20 6f 70 65 72 61 74 69 6f 6e 2e 0a  this operation..
1cea0 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20 6e  **.** If op is n
1ceb0 65 67 61 74 69 76 65 2c 20 74 68 65 6e 20 64 6f  egative, then do
1cec0 20 61 20 64 72 79 2d 72 75 6e 20 6f 66 20 74 68   a dry-run of th
1ced0 65 20 6f 70 3d 3d 31 20 63 61 73 65 20 62 75 74  e op==1 case but
1cee0 20 64 6f 0a 2a 2a 20 6e 6f 74 20 61 63 74 75 61   do.** not actua
1cef0 6c 6c 79 20 63 68 61 6e 67 65 20 61 6e 79 74 68  lly change anyth
1cf00 69 6e 67 2e 20 54 68 65 20 70 61 67 65 72 20 75  ing. The pager u
1cf10 73 65 73 20 74 68 69 73 20 74 6f 20 73 65 65 20  ses this to see 
1cf20 69 66 20 69 74 0a 2a 2a 20 73 68 6f 75 6c 64 20  if it.** should 
1cf30 61 63 71 75 69 72 65 20 74 68 65 20 64 61 74 61  acquire the data
1cf40 62 61 73 65 20 65 78 63 6c 75 73 69 76 65 20 6c  base exclusive l
1cf50 6f 63 6b 20 70 72 69 6f 72 20 74 6f 20 69 6e 76  ock prior to inv
1cf60 6f 6b 69 6e 67 0a 2a 2a 20 74 68 65 20 6f 70 3d  oking.** the op=
1cf70 3d 31 20 63 61 73 65 2e 0a 2a 2f 0a 69 6e 74 20  =1 case..*/.int 
1cf80 73 71 6c 69 74 65 33 57 61 6c 45 78 63 6c 75 73  sqlite3WalExclus
1cf90 69 76 65 4d 6f 64 65 28 57 61 6c 20 2a 70 57 61  iveMode(Wal *pWa
1cfa0 6c 2c 20 69 6e 74 20 6f 70 29 7b 0a 20 20 69 6e  l, int op){.  in
1cfb0 74 20 72 63 3b 0a 20 20 61 73 73 65 72 74 28 20  t rc;.  assert( 
1cfc0 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d  pWal->writeLock=
1cfd0 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
1cfe0 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
1cff0 6f 64 65 21 3d 57 41 4c 5f 48 45 41 50 4d 45 4d  ode!=WAL_HEAPMEM
1d000 4f 52 59 5f 4d 4f 44 45 20 7c 7c 20 6f 70 3d 3d  ORY_MODE || op==
1d010 2d 31 20 29 3b 0a 0a 20 20 2f 2a 20 70 57 61 6c  -1 );..  /* pWal
1d020 2d 3e 72 65 61 64 4c 6f 63 6b 20 69 73 20 75 73  ->readLock is us
1d030 75 61 6c 6c 79 20 73 65 74 2c 20 62 75 74 20 6d  ually set, but m
1d040 69 67 68 74 20 62 65 20 2d 31 20 69 66 20 74 68  ight be -1 if th
1d050 65 72 65 20 77 61 73 20 61 20 0a 20 20 2a 2a 20  ere was a .  ** 
1d060 70 72 69 6f 72 20 65 72 72 6f 72 20 77 68 69 6c  prior error whil
1d070 65 20 61 74 74 65 6d 70 74 69 6e 67 20 74 6f 20  e attempting to 
1d080 61 63 71 75 69 72 65 20 61 72 65 20 72 65 61 64  acquire are read
1d090 2d 6c 6f 63 6b 2e 20 54 68 69 73 20 63 61 6e 6e  -lock. This cann
1d0a0 6f 74 20 0a 20 20 2a 2a 20 68 61 70 70 65 6e 20  ot .  ** happen 
1d0b0 69 66 20 74 68 65 20 63 6f 6e 6e 65 63 74 69 6f  if the connectio
1d0c0 6e 20 69 73 20 61 63 74 75 61 6c 6c 79 20 69 6e  n is actually in
1d0d0 20 65 78 63 6c 75 73 69 76 65 20 6d 6f 64 65 20   exclusive mode 
1d0e0 28 61 73 20 6e 6f 20 78 53 68 6d 4c 6f 63 6b 0a  (as no xShmLock.
1d0f0 20 20 2a 2a 20 6c 6f 63 6b 73 20 61 72 65 20 74    ** locks are t
1d100 61 6b 65 6e 20 69 6e 20 74 68 69 73 20 63 61 73  aken in this cas
1d110 65 29 2e 20 4e 6f 72 20 73 68 6f 75 6c 64 20 74  e). Nor should t
1d120 68 65 20 70 61 67 65 72 20 61 74 74 65 6d 70 74  he pager attempt
1d130 20 74 6f 0a 20 20 2a 2a 20 75 70 67 72 61 64 65   to.  ** upgrade
1d140 20 74 6f 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f   to exclusive-mo
1d150 64 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 75 63  de following suc
1d160 68 20 61 6e 20 65 72 72 6f 72 2e 0a 20 20 2a 2f  h an error..  */
1d170 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
1d180 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20  >readLock>=0 || 
1d190 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20  pWal->lockError 
1d1a0 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  );.  assert( pWa
1d1b0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c  l->readLock>=0 |
1d1c0 7c 20 28 6f 70 3c 3d 30 20 26 26 20 70 57 61 6c  | (op<=0 && pWal
1d1d0 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d  ->exclusiveMode=
1d1e0 3d 30 29 20 29 3b 0a 0a 20 20 69 66 28 20 6f 70  =0) );..  if( op
1d1f0 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70  ==0 ){.    if( p
1d200 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
1d210 64 65 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c  de ){.      pWal
1d220 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20  ->exclusiveMode 
1d230 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20 77  = 0;.      if( w
1d240 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61  alLockShared(pWa
1d250 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  l, WAL_READ_LOCK
1d260 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29  (pWal->readLock)
1d270 29 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  )!=SQLITE_OK ){.
1d280 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 65 78          pWal->ex
1d290 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 31 3b  clusiveMode = 1;
1d2a0 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72  .      }.      r
1d2b0 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  c = pWal->exclus
1d2c0 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 20 20  iveMode==0;.    
1d2d0 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20  }else{.      /* 
1d2e0 41 6c 72 65 61 64 79 20 69 6e 20 6c 6f 63 6b 69  Already in locki
1d2f0 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 2a  ng_mode=NORMAL *
1d300 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 30 3b 0a  /.      rc = 0;.
1d310 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66      }.  }else if
1d320 28 20 6f 70 3e 30 20 29 7b 0a 20 20 20 20 61 73  ( op>0 ){.    as
1d330 73 65 72 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c  sert( pWal->excl
1d340 75 73 69 76 65 4d 6f 64 65 3d 3d 30 20 29 3b 0a  usiveMode==0 );.
1d350 20 20 20 20 61 73 73 65 72 74 28 20 70 57 61 6c      assert( pWal
1d360 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b  ->readLock>=0 );
1d370 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68  .    walUnlockSh
1d380 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
1d390 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72  EAD_LOCK(pWal->r
1d3a0 65 61 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70  eadLock));.    p
1d3b0 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
1d3c0 64 65 20 3d 20 31 3b 0a 20 20 20 20 72 63 20 3d  de = 1;.    rc =
1d3d0 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20   1;.  }else{.   
1d3e0 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c   rc = pWal->excl
1d3f0 75 73 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20  usiveMode==0;.  
1d400 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
1d410 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20  ../* .** Return 
1d420 74 72 75 65 20 69 66 20 74 68 65 20 61 72 67 75  true if the argu
1d430 6d 65 6e 74 20 69 73 20 6e 6f 6e 2d 4e 55 4c 4c  ment is non-NULL
1d440 20 61 6e 64 20 74 68 65 20 57 41 4c 20 6d 6f 64   and the WAL mod
1d450 75 6c 65 20 69 73 20 75 73 69 6e 67 0a 2a 2a 20  ule is using.** 
1d460 68 65 61 70 2d 6d 65 6d 6f 72 79 20 66 6f 72 20  heap-memory for 
1d470 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 4f  the wal-index. O
1d480 74 68 65 72 77 69 73 65 2c 20 69 66 20 74 68 65  therwise, if the
1d490 20 61 72 67 75 6d 65 6e 74 20 69 73 20 4e 55 4c   argument is NUL
1d4a0 4c 20 6f 72 20 74 68 65 0a 2a 2a 20 57 41 4c 20  L or the.** WAL 
1d4b0 6d 6f 64 75 6c 65 20 69 73 20 75 73 69 6e 67 20  module is using 
1d4c0 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 2c 20 72  shared-memory, r
1d4d0 65 74 75 72 6e 20 66 61 6c 73 65 2e 20 0a 2a 2f  eturn false. .*/
1d4e0 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 48  .int sqlite3WalH
1d4f0 65 61 70 4d 65 6d 6f 72 79 28 57 61 6c 20 2a 70  eapMemory(Wal *p
1d500 57 61 6c 29 7b 0a 20 20 72 65 74 75 72 6e 20 28  Wal){.  return (
1d510 70 57 61 6c 20 26 26 20 70 57 61 6c 2d 3e 65 78  pWal && pWal->ex
1d520 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c  clusiveMode==WAL
1d530 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45  _HEAPMEMORY_MODE
1d540 20 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51   );.}..#ifdef SQ
1d550 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 5a 49 50 56  LITE_ENABLE_ZIPV
1d560 46 53 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68 65 20  FS./*.** If the 
1d570 61 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f 74 20  argument is not 
1d580 4e 55 4c 4c 2c 20 69 74 20 70 6f 69 6e 74 73 20  NULL, it points 
1d590 74 6f 20 61 20 57 61 6c 20 6f 62 6a 65 63 74 20  to a Wal object 
1d5a0 74 68 61 74 20 68 6f 6c 64 73 20 61 0a 2a 2a 20  that holds a.** 
1d5b0 72 65 61 64 2d 6c 6f 63 6b 2e 20 54 68 69 73 20  read-lock. This 
1d5c0 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
1d5d0 20 74 68 65 20 64 61 74 61 62 61 73 65 20 70 61   the database pa
1d5e0 67 65 2d 73 69 7a 65 20 69 66 20 69 74 20 69 73  ge-size if it is
1d5f0 20 6b 6e 6f 77 6e 2c 0a 2a 2a 20 6f 72 20 7a 65   known,.** or ze
1d600 72 6f 20 69 66 20 69 74 20 69 73 20 6e 6f 74 20  ro if it is not 
1d610 28 6f 72 20 69 66 20 70 57 61 6c 20 69 73 20 4e  (or if pWal is N
1d620 55 4c 4c 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ULL)..*/.int sql
1d630 69 74 65 33 57 61 6c 46 72 61 6d 65 73 69 7a 65  ite3WalFramesize
1d640 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61  (Wal *pWal){.  a
1d650 73 73 65 72 74 28 20 70 57 61 6c 3d 3d 30 20 7c  ssert( pWal==0 |
1d660 7c 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  | pWal->readLock
1d670 3e 3d 30 20 29 3b 0a 20 20 72 65 74 75 72 6e 20  >=0 );.  return 
1d680 28 70 57 61 6c 20 3f 20 70 57 61 6c 2d 3e 73 7a  (pWal ? pWal->sz
1d690 50 61 67 65 20 3a 20 30 29 3b 0a 7d 0a 23 65 6e  Page : 0);.}.#en
1d6a0 64 69 66 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 23  dif..#endif /* #
1d6b0 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d  ifndef SQLITE_OM
1d6c0 49 54 5f 57 41 4c 20 2a 2f 0a                    IT_WAL */.