/ Hex Artifact Content
Login

Artifact 76e7fc6de229bea8b30bb2539110f03a494dc3a8:


0000: 2f 2a 0a 2a 2a 20 32 30 31 30 20 46 65 62 72 75  /*.** 2010 Febru
0010: 61 72 79 20 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ary 1.**.** The 
0020: 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73  author disclaims
0030: 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68   copyright to th
0040: 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20  is source code. 
0050: 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20   In place of.** 
0060: 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20  a legal notice, 
0070: 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69  here is a blessi
0080: 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79  ng:.**.**    May
0090: 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64   you do good and
00a0: 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20   not evil..**   
00b0: 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f   May you find fo
00c0: 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f  rgiveness for yo
00d0: 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69  urself and forgi
00e0: 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20  ve others..**   
00f0: 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66   May you share f
0100: 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b  reely, never tak
0110: 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f  ing more than yo
0120: 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a  u give..**.*****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 74 68  file contains th
0190: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
01a0: 20 6f 66 20 61 20 77 72 69 74 65 2d 61 68 65 61   of a write-ahea
01b0: 64 20 6c 6f 67 20 28 57 41 4c 29 20 75 73 65 64  d log (WAL) used
01c0: 20 69 6e 20 0a 2a 2a 20 22 6a 6f 75 72 6e 61 6c   in .** "journal
01d0: 5f 6d 6f 64 65 3d 57 41 4c 22 20 6d 6f 64 65 2e  _mode=WAL" mode.
01e0: 0a 2a 2a 0a 2a 2a 20 57 52 49 54 45 2d 41 48 45  .**.** WRITE-AHE
01f0: 41 44 20 4c 4f 47 20 28 57 41 4c 29 20 46 49 4c  AD LOG (WAL) FIL
0200: 45 20 46 4f 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 41  E FORMAT.**.** A
0210: 20 57 41 4c 20 66 69 6c 65 20 63 6f 6e 73 69 73   WAL file consis
0220: 74 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 66  ts of a header f
0230: 6f 6c 6c 6f 77 65 64 20 62 79 20 7a 65 72 6f 20  ollowed by zero 
0240: 6f 72 20 6d 6f 72 65 20 22 66 72 61 6d 65 73 22  or more "frames"
0250: 2e 0a 2a 2a 20 45 61 63 68 20 66 72 61 6d 65 20  ..** Each frame 
0260: 72 65 63 6f 72 64 73 20 74 68 65 20 72 65 76 69  records the revi
0270: 73 65 64 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  sed content of a
0280: 20 73 69 6e 67 6c 65 20 70 61 67 65 20 66 72 6f   single page fro
0290: 6d 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73  m the.** databas
02a0: 65 20 66 69 6c 65 2e 20 20 41 6c 6c 20 63 68 61  e file.  All cha
02b0: 6e 67 65 73 20 74 6f 20 74 68 65 20 64 61 74 61  nges to the data
02c0: 62 61 73 65 20 61 72 65 20 72 65 63 6f 72 64 65  base are recorde
02d0: 64 20 62 79 20 77 72 69 74 69 6e 67 0a 2a 2a 20  d by writing.** 
02e0: 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20  frames into the 
02f0: 57 41 4c 2e 20 20 54 72 61 6e 73 61 63 74 69 6f  WAL.  Transactio
0300: 6e 73 20 63 6f 6d 6d 69 74 20 77 68 65 6e 20 61  ns commit when a
0310: 20 66 72 61 6d 65 20 69 73 20 77 72 69 74 74 65   frame is writte
0320: 6e 20 74 68 61 74 0a 2a 2a 20 63 6f 6e 74 61 69  n that.** contai
0330: 6e 73 20 61 20 63 6f 6d 6d 69 74 20 6d 61 72 6b  ns a commit mark
0340: 65 72 2e 20 20 41 20 73 69 6e 67 6c 65 20 57 41  er.  A single WA
0350: 4c 20 63 61 6e 20 61 6e 64 20 75 73 75 61 6c 6c  L can and usuall
0360: 79 20 64 6f 65 73 20 72 65 63 6f 72 64 20 0a 2a  y does record .*
0370: 2a 20 6d 75 6c 74 69 70 6c 65 20 74 72 61 6e 73  * multiple trans
0380: 61 63 74 69 6f 6e 73 2e 20 20 50 65 72 69 6f 64  actions.  Period
0390: 69 63 61 6c 6c 79 2c 20 74 68 65 20 63 6f 6e 74  ically, the cont
03a0: 65 6e 74 20 6f 66 20 74 68 65 20 57 41 4c 20 69  ent of the WAL i
03b0: 73 0a 2a 2a 20 74 72 61 6e 73 66 65 72 72 65 64  s.** transferred
03c0: 20 62 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64   back into the d
03d0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 69 6e 20  atabase file in 
03e0: 61 6e 20 6f 70 65 72 61 74 69 6f 6e 20 63 61 6c  an operation cal
03f0: 6c 65 64 20 61 0a 2a 2a 20 22 63 68 65 63 6b 70  led a.** "checkp
0400: 6f 69 6e 74 22 2e 0a 2a 2a 0a 2a 2a 20 41 20 73  oint"..**.** A s
0410: 69 6e 67 6c 65 20 57 41 4c 20 66 69 6c 65 20 63  ingle WAL file c
0420: 61 6e 20 62 65 20 75 73 65 64 20 6d 75 6c 74 69  an be used multi
0430: 70 6c 65 20 74 69 6d 65 73 2e 20 20 49 6e 20 6f  ple times.  In o
0440: 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68 65 0a  ther words, the.
0450: 2a 2a 20 57 41 4c 20 63 61 6e 20 66 69 6c 6c 20  ** WAL can fill 
0460: 75 70 20 77 69 74 68 20 66 72 61 6d 65 73 20 61  up with frames a
0470: 6e 64 20 74 68 65 6e 20 62 65 20 63 68 65 63 6b  nd then be check
0480: 70 6f 69 6e 74 65 64 20 61 6e 64 20 74 68 65 6e  pointed and then
0490: 20 6e 65 77 0a 2a 2a 20 66 72 61 6d 65 73 20 63   new.** frames c
04a0: 61 6e 20 6f 76 65 72 77 72 69 74 65 20 74 68 65  an overwrite the
04b0: 20 6f 6c 64 20 6f 6e 65 73 2e 20 20 41 20 57 41   old ones.  A WA
04c0: 4c 20 61 6c 77 61 79 73 20 67 72 6f 77 73 20 66  L always grows f
04d0: 72 6f 6d 20 62 65 67 69 6e 6e 69 6e 67 0a 2a 2a  rom beginning.**
04e0: 20 74 6f 77 61 72 64 20 74 68 65 20 65 6e 64 2e   toward the end.
04f0: 20 20 43 68 65 63 6b 73 75 6d 73 20 61 6e 64 20    Checksums and 
0500: 63 6f 75 6e 74 65 72 73 20 61 74 74 61 63 68 65  counters attache
0510: 64 20 74 6f 20 65 61 63 68 20 66 72 61 6d 65 20  d to each frame 
0520: 61 72 65 0a 2a 2a 20 75 73 65 64 20 74 6f 20 64  are.** used to d
0530: 65 74 65 72 6d 69 6e 65 20 77 68 69 63 68 20 66  etermine which f
0540: 72 61 6d 65 73 20 77 69 74 68 69 6e 20 74 68 65  rames within the
0550: 20 57 41 4c 20 61 72 65 20 76 61 6c 69 64 20 61   WAL are valid a
0560: 6e 64 20 77 68 69 63 68 0a 2a 2a 20 61 72 65 20  nd which.** are 
0570: 6c 65 66 74 6f 76 65 72 73 20 66 72 6f 6d 20 70  leftovers from p
0580: 72 69 6f 72 20 63 68 65 63 6b 70 6f 69 6e 74 73  rior checkpoints
0590: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 57 41 4c 20  ..**.** The WAL 
05a0: 68 65 61 64 65 72 20 69 73 20 33 32 20 62 79 74  header is 32 byt
05b0: 65 73 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 63  es in size and c
05c0: 6f 6e 73 69 73 74 73 20 6f 66 20 74 68 65 20 66  onsists of the f
05d0: 6f 6c 6c 6f 77 69 6e 67 20 65 69 67 68 74 0a 2a  ollowing eight.*
05e0: 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 33 32 2d  * big-endian 32-
05f0: 62 69 74 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  bit unsigned int
0600: 65 67 65 72 20 76 61 6c 75 65 73 3a 0a 2a 2a 0a  eger values:.**.
0610: 2a 2a 20 20 20 20 20 30 3a 20 4d 61 67 69 63 20  **     0: Magic 
0620: 6e 75 6d 62 65 72 2e 20 20 30 78 33 37 37 66 30  number.  0x377f0
0630: 36 38 32 20 6f 72 20 30 78 33 37 37 66 30 36 38  682 or 0x377f068
0640: 33 0a 2a 2a 20 20 20 20 20 34 3a 20 46 69 6c 65  3.**     4: File
0650: 20 66 6f 72 6d 61 74 20 76 65 72 73 69 6f 6e 2e   format version.
0660: 20 20 43 75 72 72 65 6e 74 6c 79 20 33 30 30 37    Currently 3007
0670: 30 30 30 0a 2a 2a 20 20 20 20 20 38 3a 20 44 61  000.**     8: Da
0680: 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65  tabase page size
0690: 2e 20 20 45 78 61 6d 70 6c 65 3a 20 31 30 32 34  .  Example: 1024
06a0: 0a 2a 2a 20 20 20 20 31 32 3a 20 43 68 65 63 6b  .**    12: Check
06b0: 70 6f 69 6e 74 20 73 65 71 75 65 6e 63 65 20 6e  point sequence n
06c0: 75 6d 62 65 72 0a 2a 2a 20 20 20 20 31 36 3a 20  umber.**    16: 
06d0: 53 61 6c 74 2d 31 2c 20 72 61 6e 64 6f 6d 20 69  Salt-1, random i
06e0: 6e 74 65 67 65 72 20 69 6e 63 72 65 6d 65 6e 74  nteger increment
06f0: 65 64 20 77 69 74 68 20 65 61 63 68 20 63 68 65  ed with each che
0700: 63 6b 70 6f 69 6e 74 0a 2a 2a 20 20 20 20 32 30  ckpoint.**    20
0710: 3a 20 53 61 6c 74 2d 32 2c 20 61 20 64 69 66 66  : Salt-2, a diff
0720: 65 72 65 6e 74 20 72 61 6e 64 6f 6d 20 69 6e 74  erent random int
0730: 65 67 65 72 20 63 68 61 6e 67 69 6e 67 20 77 69  eger changing wi
0740: 74 68 20 65 61 63 68 20 63 6b 70 74 0a 2a 2a 20  th each ckpt.** 
0750: 20 20 20 32 34 3a 20 43 68 65 63 6b 73 75 6d 2d     24: Checksum-
0760: 31 20 28 66 69 72 73 74 20 70 61 72 74 20 6f 66  1 (first part of
0770: 20 63 68 65 63 6b 73 75 6d 20 66 6f 72 20 66 69   checksum for fi
0780: 72 73 74 20 32 34 20 62 79 74 65 73 20 6f 66 20  rst 24 bytes of 
0790: 68 65 61 64 65 72 29 2e 0a 2a 2a 20 20 20 20 32  header)..**    2
07a0: 38 3a 20 43 68 65 63 6b 73 75 6d 2d 32 20 28 73  8: Checksum-2 (s
07b0: 65 63 6f 6e 64 20 70 61 72 74 20 6f 66 20 63 68  econd part of ch
07c0: 65 63 6b 73 75 6d 20 66 6f 72 20 66 69 72 73 74  ecksum for first
07d0: 20 32 34 20 62 79 74 65 73 20 6f 66 20 68 65 61   24 bytes of hea
07e0: 64 65 72 29 2e 0a 2a 2a 0a 2a 2a 20 49 6d 6d 65  der)..**.** Imme
07f0: 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e  diately followin
0800: 67 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  g the wal-header
0810: 20 61 72 65 20 7a 65 72 6f 20 6f 72 20 6d 6f 72   are zero or mor
0820: 65 20 66 72 61 6d 65 73 2e 20 45 61 63 68 0a 2a  e frames. Each.*
0830: 2a 20 66 72 61 6d 65 20 63 6f 6e 73 69 73 74 73  * frame consists
0840: 20 6f 66 20 61 20 32 34 2d 62 79 74 65 20 66 72   of a 24-byte fr
0850: 61 6d 65 2d 68 65 61 64 65 72 20 66 6f 6c 6c 6f  ame-header follo
0860: 77 65 64 20 62 79 20 61 20 3c 70 61 67 65 2d 73  wed by a <page-s
0870: 69 7a 65 3e 20 62 79 74 65 73 0a 2a 2a 20 6f 66  ize> bytes.** of
0880: 20 70 61 67 65 20 64 61 74 61 2e 20 54 68 65 20   page data. The 
0890: 66 72 61 6d 65 2d 68 65 61 64 65 72 20 69 73 20  frame-header is 
08a0: 73 69 78 20 62 69 67 2d 65 6e 64 69 61 6e 20 33  six big-endian 3
08b0: 32 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20 0a  2-bit unsigned .
08c0: 2a 2a 20 69 6e 74 65 67 65 72 20 76 61 6c 75 65  ** integer value
08d0: 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  s, as follows:.*
08e0: 2a 0a 2a 2a 20 20 20 20 20 30 3a 20 50 61 67 65  *.**     0: Page
08f0: 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20 20 20 20   number..**     
0900: 34 3a 20 46 6f 72 20 63 6f 6d 6d 69 74 20 72 65  4: For commit re
0910: 63 6f 72 64 73 2c 20 74 68 65 20 73 69 7a 65 20  cords, the size 
0920: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  of the database 
0930: 69 6d 61 67 65 20 69 6e 20 70 61 67 65 73 20 0a  image in pages .
0940: 2a 2a 20 20 20 20 20 20 20 20 61 66 74 65 72 20  **        after 
0950: 74 68 65 20 63 6f 6d 6d 69 74 2e 20 46 6f 72 20  the commit. For 
0960: 61 6c 6c 20 6f 74 68 65 72 20 72 65 63 6f 72 64  all other record
0970: 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20 20  s, zero..**     
0980: 38 3a 20 53 61 6c 74 2d 31 20 28 63 6f 70 69 65  8: Salt-1 (copie
0990: 64 20 66 72 6f 6d 20 74 68 65 20 68 65 61 64 65  d from the heade
09a0: 72 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61 6c  r).**    12: Sal
09b0: 74 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f 6d  t-2 (copied from
09c0: 20 74 68 65 20 68 65 61 64 65 72 29 0a 2a 2a 20   the header).** 
09d0: 20 20 20 31 36 3a 20 43 68 65 63 6b 73 75 6d 2d     16: Checksum-
09e0: 31 2e 0a 2a 2a 20 20 20 20 32 30 3a 20 43 68 65  1..**    20: Che
09f0: 63 6b 73 75 6d 2d 32 2e 0a 2a 2a 0a 2a 2a 20 41  cksum-2..**.** A
0a00: 20 66 72 61 6d 65 20 69 73 20 63 6f 6e 73 69 64   frame is consid
0a10: 65 72 65 64 20 76 61 6c 69 64 20 69 66 20 61 6e  ered valid if an
0a20: 64 20 6f 6e 6c 79 20 69 66 20 74 68 65 20 66 6f  d only if the fo
0a30: 6c 6c 6f 77 69 6e 67 20 63 6f 6e 64 69 74 69 6f  llowing conditio
0a40: 6e 73 20 61 72 65 0a 2a 2a 20 74 72 75 65 3a 0a  ns are.** true:.
0a50: 2a 2a 0a 2a 2a 20 20 20 20 28 31 29 20 54 68 65  **.**    (1) The
0a60: 20 73 61 6c 74 2d 31 20 61 6e 64 20 73 61 6c 74   salt-1 and salt
0a70: 2d 32 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  -2 values in the
0a80: 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20 6d 61   frame-header ma
0a90: 74 63 68 0a 2a 2a 20 20 20 20 20 20 20 20 73 61  tch.**        sa
0aa0: 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  lt values in the
0ab0: 20 77 61 6c 2d 68 65 61 64 65 72 0a 2a 2a 0a 2a   wal-header.**.*
0ac0: 2a 20 20 20 20 28 32 29 20 54 68 65 20 63 68 65  *    (2) The che
0ad0: 63 6b 73 75 6d 20 76 61 6c 75 65 73 20 69 6e 20  cksum values in 
0ae0: 74 68 65 20 66 69 6e 61 6c 20 38 20 62 79 74 65  the final 8 byte
0af0: 73 20 6f 66 20 74 68 65 20 66 72 61 6d 65 2d 68  s of the frame-h
0b00: 65 61 64 65 72 0a 2a 2a 20 20 20 20 20 20 20 20  eader.**        
0b10: 65 78 61 63 74 6c 79 20 6d 61 74 63 68 20 74 68  exactly match th
0b20: 65 20 63 68 65 63 6b 73 75 6d 20 63 6f 6d 70 75  e checksum compu
0b30: 74 65 64 20 63 6f 6e 73 65 63 75 74 69 76 65 6c  ted consecutivel
0b40: 79 20 6f 6e 20 74 68 65 0a 2a 2a 20 20 20 20 20  y on the.**     
0b50: 20 20 20 57 41 4c 20 68 65 61 64 65 72 20 61 6e     WAL header an
0b60: 64 20 74 68 65 20 66 69 72 73 74 20 38 20 62 79  d the first 8 by
0b70: 74 65 73 20 61 6e 64 20 74 68 65 20 63 6f 6e 74  tes and the cont
0b80: 65 6e 74 20 6f 66 20 61 6c 6c 20 66 72 61 6d 65  ent of all frame
0b90: 73 0a 2a 2a 20 20 20 20 20 20 20 20 75 70 20 74  s.**        up t
0ba0: 6f 20 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20  o and including 
0bb0: 74 68 65 20 63 75 72 72 65 6e 74 20 66 72 61 6d  the current fram
0bc0: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65  e..**.** The che
0bd0: 63 6b 73 75 6d 20 69 73 20 63 6f 6d 70 75 74 65  cksum is compute
0be0: 64 20 75 73 69 6e 67 20 33 32 2d 62 69 74 20 62  d using 32-bit b
0bf0: 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65  ig-endian intege
0c00: 72 73 20 69 66 20 74 68 65 0a 2a 2a 20 6d 61 67  rs if the.** mag
0c10: 69 63 20 6e 75 6d 62 65 72 20 69 6e 20 74 68 65  ic number in the
0c20: 20 66 69 72 73 74 20 34 20 62 79 74 65 73 20 6f   first 4 bytes o
0c30: 66 20 74 68 65 20 57 41 4c 20 69 73 20 30 78 33  f the WAL is 0x3
0c40: 37 37 66 30 36 38 33 20 61 6e 64 20 69 74 0a 2a  77f0683 and it.*
0c50: 2a 20 69 73 20 63 6f 6d 70 75 74 65 64 20 75 73  * is computed us
0c60: 69 6e 67 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61  ing little-endia
0c70: 6e 20 69 66 20 74 68 65 20 6d 61 67 69 63 20 6e  n if the magic n
0c80: 75 6d 62 65 72 20 69 73 20 30 78 33 37 37 66 30  umber is 0x377f0
0c90: 36 38 32 2e 0a 2a 2a 20 54 68 65 20 63 68 65 63  682..** The chec
0ca0: 6b 73 75 6d 20 76 61 6c 75 65 73 20 61 72 65 20  ksum values are 
0cb0: 61 6c 77 61 79 73 20 73 74 6f 72 65 64 20 69 6e  always stored in
0cc0: 20 74 68 65 20 66 72 61 6d 65 20 68 65 61 64 65   the frame heade
0cd0: 72 20 69 6e 20 61 0a 2a 2a 20 62 69 67 2d 65 6e  r in a.** big-en
0ce0: 64 69 61 6e 20 66 6f 72 6d 61 74 20 72 65 67 61  dian format rega
0cf0: 72 64 6c 65 73 73 20 6f 66 20 77 68 69 63 68 20  rdless of which 
0d00: 62 79 74 65 20 6f 72 64 65 72 20 69 73 20 75 73  byte order is us
0d10: 65 64 20 74 6f 20 63 6f 6d 70 75 74 65 0a 2a 2a  ed to compute.**
0d20: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 2e 20 20   the checksum.  
0d30: 54 68 65 20 63 68 65 63 6b 73 75 6d 20 69 73 20  The checksum is 
0d40: 63 6f 6d 70 75 74 65 64 20 62 79 20 69 6e 74 65  computed by inte
0d50: 72 70 72 65 74 69 6e 67 20 74 68 65 20 69 6e 70  rpreting the inp
0d60: 75 74 20 61 73 0a 2a 2a 20 61 6e 20 65 76 65 6e  ut as.** an even
0d70: 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 73 69 67   number of unsig
0d80: 6e 65 64 20 33 32 2d 62 69 74 20 69 6e 74 65 67  ned 32-bit integ
0d90: 65 72 73 3a 20 78 5b 30 5d 20 74 68 72 6f 75 67  ers: x[0] throug
0da0: 68 20 78 5b 4e 5d 2e 20 20 54 68 65 0a 2a 2a 20  h x[N].  The.** 
0db0: 61 6c 67 6f 72 69 74 68 6d 20 75 73 65 64 20 66  algorithm used f
0dc0: 6f 72 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20  or the checksum 
0dd0: 69 73 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  is as follows:.*
0de0: 2a 20 0a 2a 2a 20 20 20 66 6f 72 20 69 20 66 72  * .**   for i fr
0df0: 6f 6d 20 30 20 74 6f 20 6e 2d 31 20 73 74 65 70  om 0 to n-1 step
0e00: 20 32 3a 0a 2a 2a 20 20 20 20 20 73 30 20 2b 3d   2:.**     s0 +=
0e10: 20 78 5b 69 5d 20 2b 20 73 31 3b 0a 2a 2a 20 20   x[i] + s1;.**  
0e20: 20 20 20 73 31 20 2b 3d 20 78 5b 69 2b 31 5d 20     s1 += x[i+1] 
0e30: 2b 20 73 30 3b 0a 2a 2a 20 20 20 65 6e 64 66 6f  + s0;.**   endfo
0e40: 72 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61  r.**.** Note tha
0e50: 74 20 73 30 20 61 6e 64 20 73 31 20 61 72 65 20  t s0 and s1 are 
0e60: 62 6f 74 68 20 77 65 69 67 68 74 65 64 20 63 68  both weighted ch
0e70: 65 63 6b 73 75 6d 73 20 75 73 69 6e 67 20 66 69  ecksums using fi
0e80: 62 6f 6e 61 63 63 69 20 77 65 69 67 68 74 73 0a  bonacci weights.
0e90: 2a 2a 20 69 6e 20 72 65 76 65 72 73 65 20 6f 72  ** in reverse or
0ea0: 64 65 72 20 28 74 68 65 20 6c 61 72 67 65 73 74  der (the largest
0eb0: 20 66 69 62 6f 6e 61 63 63 69 20 77 65 69 67 68   fibonacci weigh
0ec0: 74 20 6f 63 63 75 72 73 20 6f 6e 20 74 68 65 20  t occurs on the 
0ed0: 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 0a 2a 2a  first element.**
0ee0: 20 6f 66 20 74 68 65 20 73 65 71 75 65 6e 63 65   of the sequence
0ef0: 20 62 65 69 6e 67 20 73 75 6d 6d 65 64 2e 29 20   being summed.) 
0f00: 20 54 68 65 20 73 31 20 76 61 6c 75 65 20 73 70   The s1 value sp
0f10: 61 6e 73 20 61 6c 6c 20 33 32 2d 62 69 74 20 0a  ans all 32-bit .
0f20: 2a 2a 20 74 65 72 6d 73 20 6f 66 20 74 68 65 20  ** terms of the 
0f30: 73 65 71 75 65 6e 63 65 20 77 68 65 72 65 61 73  sequence whereas
0f40: 20 73 30 20 6f 6d 69 74 73 20 74 68 65 20 66 69   s0 omits the fi
0f50: 6e 61 6c 20 74 65 72 6d 2e 0a 2a 2a 0a 2a 2a 20  nal term..**.** 
0f60: 4f 6e 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c  On a checkpoint,
0f70: 20 74 68 65 20 57 41 4c 20 69 73 20 66 69 72 73   the WAL is firs
0f80: 74 20 56 46 53 2e 78 53 79 6e 63 2d 65 64 2c 20  t VFS.xSync-ed, 
0f90: 74 68 65 6e 20 76 61 6c 69 64 20 63 6f 6e 74 65  then valid conte
0fa0: 6e 74 20 6f 66 20 74 68 65 0a 2a 2a 20 57 41 4c  nt of the.** WAL
0fb0: 20 69 73 20 74 72 61 6e 73 66 65 72 72 65 64 20   is transferred 
0fc0: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
0fd0: 65 2c 20 74 68 65 6e 20 74 68 65 20 64 61 74 61  e, then the data
0fe0: 62 61 73 65 20 69 73 20 56 46 53 2e 78 53 79 6e  base is VFS.xSyn
0ff0: 63 2d 65 64 2e 0a 2a 2a 20 54 68 65 20 56 46 53  c-ed..** The VFS
1000: 2e 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e  .xSync operation
1010: 73 20 73 65 72 76 65 20 61 73 20 77 72 69 74 65  s serve as write
1020: 20 62 61 72 72 69 65 72 73 20 2d 20 61 6c 6c 20   barriers - all 
1030: 77 72 69 74 65 73 20 6c 61 75 6e 63 68 65 64 0a  writes launched.
1040: 2a 2a 20 62 65 66 6f 72 65 20 74 68 65 20 78 53  ** before the xS
1050: 79 6e 63 20 6d 75 73 74 20 63 6f 6d 70 6c 65 74  ync must complet
1060: 65 20 62 65 66 6f 72 65 20 61 6e 79 20 77 72 69  e before any wri
1070: 74 65 20 74 68 61 74 20 6c 61 75 6e 63 68 65 73  te that launches
1080: 20 61 66 74 65 72 20 74 68 65 0a 2a 2a 20 78 53   after the.** xS
1090: 79 6e 63 20 62 65 67 69 6e 73 2e 0a 2a 2a 0a 2a  ync begins..**.*
10a0: 2a 20 41 66 74 65 72 20 65 61 63 68 20 63 68 65  * After each che
10b0: 63 6b 70 6f 69 6e 74 2c 20 74 68 65 20 73 61 6c  ckpoint, the sal
10c0: 74 2d 31 20 76 61 6c 75 65 20 69 73 20 69 6e 63  t-1 value is inc
10d0: 72 65 6d 65 6e 74 65 64 20 61 6e 64 20 74 68 65  remented and the
10e0: 20 73 61 6c 74 2d 32 0a 2a 2a 20 76 61 6c 75 65   salt-2.** value
10f0: 20 69 73 20 72 61 6e 64 6f 6d 69 7a 65 64 2e 20   is randomized. 
1100: 20 54 68 69 73 20 70 72 65 76 65 6e 74 73 20 6f   This prevents o
1110: 6c 64 20 61 6e 64 20 6e 65 77 20 66 72 61 6d 65  ld and new frame
1120: 73 20 69 6e 20 74 68 65 20 57 41 4c 20 66 72 6f  s in the WAL fro
1130: 6d 0a 2a 2a 20 62 65 69 6e 67 20 63 6f 6e 73 69  m.** being consi
1140: 64 65 72 65 64 20 76 61 6c 69 64 20 61 74 20 74  dered valid at t
1150: 68 65 20 73 61 6d 65 20 74 69 6d 65 20 61 6e 64  he same time and
1160: 20 62 65 69 6e 67 20 63 68 65 63 6b 70 6f 69 6e   being checkpoin
1170: 74 69 6e 67 20 74 6f 67 65 74 68 65 72 0a 2a 2a  ting together.**
1180: 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 63 72 61   following a cra
1190: 73 68 2e 0a 2a 2a 0a 2a 2a 20 52 45 41 44 45 52  sh..**.** READER
11a0: 20 41 4c 47 4f 52 49 54 48 4d 0a 2a 2a 0a 2a 2a   ALGORITHM.**.**
11b0: 20 54 6f 20 72 65 61 64 20 61 20 70 61 67 65 20   To read a page 
11c0: 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
11d0: 65 20 28 63 61 6c 6c 20 69 74 20 70 61 67 65 20  e (call it page 
11e0: 6e 75 6d 62 65 72 20 50 29 2c 20 61 20 72 65 61  number P), a rea
11f0: 64 65 72 0a 2a 2a 20 66 69 72 73 74 20 63 68 65  der.** first che
1200: 63 6b 73 20 74 68 65 20 57 41 4c 20 74 6f 20 73  cks the WAL to s
1210: 65 65 20 69 66 20 69 74 20 63 6f 6e 74 61 69 6e  ee if it contain
1220: 73 20 70 61 67 65 20 50 2e 20 20 49 66 20 73 6f  s page P.  If so
1230: 2c 20 74 68 65 6e 20 74 68 65 0a 2a 2a 20 6c 61  , then the.** la
1240: 73 74 20 76 61 6c 69 64 20 69 6e 73 74 61 6e 63  st valid instanc
1250: 65 20 6f 66 20 70 61 67 65 20 50 20 74 68 61 74  e of page P that
1260: 20 69 73 20 61 20 66 6f 6c 6c 6f 77 65 64 20 62   is a followed b
1270: 79 20 61 20 63 6f 6d 6d 69 74 20 66 72 61 6d 65  y a commit frame
1280: 0a 2a 2a 20 6f 72 20 69 73 20 61 20 63 6f 6d 6d  .** or is a comm
1290: 69 74 20 66 72 61 6d 65 20 69 74 73 65 6c 66 20  it frame itself 
12a0: 62 65 63 6f 6d 65 73 20 74 68 65 20 76 61 6c 75  becomes the valu
12b0: 65 20 72 65 61 64 2e 20 20 49 66 20 74 68 65 20  e read.  If the 
12c0: 57 41 4c 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20  WAL.** contains 
12d0: 6e 6f 20 63 6f 70 69 65 73 20 6f 66 20 70 61 67  no copies of pag
12e0: 65 20 50 20 74 68 61 74 20 61 72 65 20 76 61 6c  e P that are val
12f0: 69 64 20 61 6e 64 20 77 68 69 63 68 20 61 72 65  id and which are
1300: 20 61 20 63 6f 6d 6d 69 74 0a 2a 2a 20 66 72 61   a commit.** fra
1310: 6d 65 20 6f 72 20 61 72 65 20 66 6f 6c 6c 6f 77  me or are follow
1320: 65 64 20 62 79 20 61 20 63 6f 6d 6d 69 74 20 66  ed by a commit f
1330: 72 61 6d 65 2c 20 74 68 65 6e 20 70 61 67 65 20  rame, then page 
1340: 50 20 69 73 20 72 65 61 64 20 66 72 6f 6d 0a 2a  P is read from.*
1350: 2a 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  * the database f
1360: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 73 74  ile..**.** To st
1370: 61 72 74 20 61 20 72 65 61 64 20 74 72 61 6e 73  art a read trans
1380: 61 63 74 69 6f 6e 2c 20 74 68 65 20 72 65 61 64  action, the read
1390: 65 72 20 72 65 63 6f 72 64 73 20 74 68 65 20 69  er records the i
13a0: 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 73 74  ndex of the last
13b0: 0a 2a 2a 20 76 61 6c 69 64 20 66 72 61 6d 65 20  .** valid frame 
13c0: 69 6e 20 74 68 65 20 57 41 4c 2e 20 20 54 68 65  in the WAL.  The
13d0: 20 72 65 61 64 65 72 20 75 73 65 73 20 74 68 69   reader uses thi
13e0: 73 20 72 65 63 6f 72 64 65 64 20 22 6d 78 46 72  s recorded "mxFr
13f0: 61 6d 65 22 20 76 61 6c 75 65 0a 2a 2a 20 66 6f  ame" value.** fo
1400: 72 20 61 6c 6c 20 73 75 62 73 65 71 75 65 6e 74  r all subsequent
1410: 20 72 65 61 64 20 6f 70 65 72 61 74 69 6f 6e 73   read operations
1420: 2e 20 20 4e 65 77 20 74 72 61 6e 73 61 63 74 69  .  New transacti
1430: 6f 6e 73 20 63 61 6e 20 62 65 20 61 70 70 65 6e  ons can be appen
1440: 64 65 64 0a 2a 2a 20 74 6f 20 74 68 65 20 57 41  ded.** to the WA
1450: 4c 2c 20 62 75 74 20 61 73 20 6c 6f 6e 67 20 61  L, but as long a
1460: 73 20 74 68 65 20 72 65 61 64 65 72 20 75 73 65  s the reader use
1470: 73 20 69 74 73 20 6f 72 69 67 69 6e 61 6c 20 6d  s its original m
1480: 78 46 72 61 6d 65 20 76 61 6c 75 65 0a 2a 2a 20  xFrame value.** 
1490: 61 6e 64 20 69 67 6e 6f 72 65 73 20 74 68 65 20  and ignores the 
14a0: 6e 65 77 6c 79 20 61 70 70 65 6e 64 65 64 20 63  newly appended c
14b0: 6f 6e 74 65 6e 74 2c 20 69 74 20 77 69 6c 6c 20  ontent, it will 
14c0: 73 65 65 20 61 20 63 6f 6e 73 69 73 74 65 6e 74  see a consistent
14d0: 20 73 6e 61 70 73 68 6f 74 0a 2a 2a 20 6f 66 20   snapshot.** of 
14e0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 72 6f  the database fro
14f0: 6d 20 61 20 73 69 6e 67 6c 65 20 70 6f 69 6e 74  m a single point
1500: 20 69 6e 20 74 69 6d 65 2e 20 20 54 68 69 73 20   in time.  This 
1510: 74 65 63 68 6e 69 71 75 65 20 61 6c 6c 6f 77 73  technique allows
1520: 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 63 6f 6e  .** multiple con
1530: 63 75 72 72 65 6e 74 20 72 65 61 64 65 72 73 20  current readers 
1540: 74 6f 20 76 69 65 77 20 64 69 66 66 65 72 65 6e  to view differen
1550: 74 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68  t versions of th
1560: 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 63 6f  e database.** co
1570: 6e 74 65 6e 74 20 73 69 6d 75 6c 74 61 6e 65 6f  ntent simultaneo
1580: 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  usly..**.** The 
1590: 72 65 61 64 65 72 20 61 6c 67 6f 72 69 74 68 6d  reader algorithm
15a0: 20 69 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73   in the previous
15b0: 20 70 61 72 61 67 72 61 70 68 73 20 77 6f 72 6b   paragraphs work
15c0: 73 20 63 6f 72 72 65 63 74 6c 79 2c 20 62 75 74  s correctly, but
15d0: 20 0a 2a 2a 20 62 65 63 61 75 73 65 20 66 72 61   .** because fra
15e0: 6d 65 73 20 66 6f 72 20 70 61 67 65 20 50 20 63  mes for page P c
15f0: 61 6e 20 61 70 70 65 61 72 20 61 6e 79 77 68 65  an appear anywhe
1600: 72 65 20 77 69 74 68 69 6e 20 74 68 65 20 57 41  re within the WA
1610: 4c 2c 20 74 68 65 0a 2a 2a 20 72 65 61 64 65 72  L, the.** reader
1620: 20 68 61 73 20 74 6f 20 73 63 61 6e 20 74 68 65   has to scan the
1630: 20 65 6e 74 69 72 65 20 57 41 4c 20 6c 6f 6f 6b   entire WAL look
1640: 69 6e 67 20 66 6f 72 20 70 61 67 65 20 50 20 66  ing for page P f
1650: 72 61 6d 65 73 2e 20 20 49 66 20 74 68 65 0a 2a  rames.  If the.*
1660: 2a 20 57 41 4c 20 69 73 20 6c 61 72 67 65 20 28  * WAL is large (
1670: 6d 75 6c 74 69 70 6c 65 20 6d 65 67 61 62 79 74  multiple megabyt
1680: 65 73 20 69 73 20 74 79 70 69 63 61 6c 29 20 74  es is typical) t
1690: 68 61 74 20 73 63 61 6e 20 63 61 6e 20 62 65 20  hat scan can be 
16a0: 73 6c 6f 77 2c 0a 2a 2a 20 61 6e 64 20 72 65 61  slow,.** and rea
16b0: 64 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 73 75  d performance su
16c0: 66 66 65 72 73 2e 20 20 54 6f 20 6f 76 65 72 63  ffers.  To overc
16d0: 6f 6d 65 20 74 68 69 73 20 70 72 6f 62 6c 65 6d  ome this problem
16e0: 2c 20 61 20 73 65 70 61 72 61 74 65 0a 2a 2a 20  , a separate.** 
16f0: 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20 63  data structure c
1700: 61 6c 6c 65 64 20 74 68 65 20 77 61 6c 2d 69 6e  alled the wal-in
1710: 64 65 78 20 69 73 20 6d 61 69 6e 74 61 69 6e 65  dex is maintaine
1720: 64 20 74 6f 20 65 78 70 65 64 69 74 65 20 74 68  d to expedite th
1730: 65 0a 2a 2a 20 73 65 61 72 63 68 20 66 6f 72 20  e.** search for 
1740: 66 72 61 6d 65 73 20 6f 66 20 61 20 70 61 72 74  frames of a part
1750: 69 63 75 6c 61 72 20 70 61 67 65 2e 0a 2a 2a 20  icular page..** 
1760: 0a 2a 2a 20 57 41 4c 2d 49 4e 44 45 58 20 46 4f  .** WAL-INDEX FO
1770: 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 43 6f 6e 63 65  RMAT.**.** Conce
1780: 70 74 75 61 6c 6c 79 2c 20 74 68 65 20 77 61 6c  ptually, the wal
1790: 2d 69 6e 64 65 78 20 69 73 20 73 68 61 72 65 64  -index is shared
17a0: 20 6d 65 6d 6f 72 79 2c 20 74 68 6f 75 67 68 20   memory, though 
17b0: 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  VFS implementati
17c0: 6f 6e 73 0a 2a 2a 20 6d 69 67 68 74 20 63 68 6f  ons.** might cho
17d0: 6f 73 65 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  ose to implement
17e0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 75   the wal-index u
17f0: 73 69 6e 67 20 61 20 6d 6d 61 70 70 65 64 20 66  sing a mmapped f
1800: 69 6c 65 2e 20 20 42 65 63 61 75 73 65 0a 2a 2a  ile.  Because.**
1810: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69   the wal-index i
1820: 73 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 2c  s shared memory,
1830: 20 53 51 4c 69 74 65 20 64 6f 65 73 20 6e 6f 74   SQLite does not
1840: 20 73 75 70 70 6f 72 74 20 6a 6f 75 72 6e 61 6c   support journal
1850: 5f 6d 6f 64 65 3d 57 41 4c 20 0a 2a 2a 20 6f 6e  _mode=WAL .** on
1860: 20 61 20 6e 65 74 77 6f 72 6b 20 66 69 6c 65 73   a network files
1870: 79 73 74 65 6d 2e 20 20 41 6c 6c 20 75 73 65 72  ystem.  All user
1880: 73 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  s of the databas
1890: 65 20 6d 75 73 74 20 62 65 20 61 62 6c 65 20 74  e must be able t
18a0: 6f 0a 2a 2a 20 73 68 61 72 65 20 6d 65 6d 6f 72  o.** share memor
18b0: 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61 6c  y..**.** The wal
18c0: 2d 69 6e 64 65 78 20 69 73 20 74 72 61 6e 73 69  -index is transi
18d0: 65 6e 74 2e 20 20 41 66 74 65 72 20 61 20 63 72  ent.  After a cr
18e0: 61 73 68 2c 20 74 68 65 20 77 61 6c 2d 69 6e 64  ash, the wal-ind
18f0: 65 78 20 63 61 6e 20 28 61 6e 64 20 73 68 6f 75  ex can (and shou
1900: 6c 64 0a 2a 2a 20 62 65 29 20 72 65 63 6f 6e 73  ld.** be) recons
1910: 74 72 75 63 74 65 64 20 66 72 6f 6d 20 74 68 65  tructed from the
1920: 20 6f 72 69 67 69 6e 61 6c 20 57 41 4c 20 66 69   original WAL fi
1930: 6c 65 2e 20 20 49 6e 20 66 61 63 74 2c 20 74 68  le.  In fact, th
1940: 65 20 56 46 53 20 69 73 20 72 65 71 75 69 72 65  e VFS is require
1950: 64 0a 2a 2a 20 74 6f 20 65 69 74 68 65 72 20 74  d.** to either t
1960: 72 75 6e 63 61 74 65 20 6f 72 20 7a 65 72 6f 20  runcate or zero 
1970: 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 74 68  the header of th
1980: 65 20 77 61 6c 2d 69 6e 64 65 78 20 77 68 65 6e  e wal-index when
1990: 20 74 68 65 20 6c 61 73 74 0a 2a 2a 20 63 6f 6e   the last.** con
19a0: 6e 65 63 74 69 6f 6e 20 74 6f 20 69 74 20 63 6c  nection to it cl
19b0: 6f 73 65 73 2e 20 20 42 65 63 61 75 73 65 20 74  oses.  Because t
19c0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
19d0: 74 72 61 6e 73 69 65 6e 74 2c 20 69 74 20 63 61  transient, it ca
19e0: 6e 0a 2a 2a 20 75 73 65 20 61 6e 20 61 72 63 68  n.** use an arch
19f0: 69 74 65 63 74 75 72 65 2d 73 70 65 63 69 66 69  itecture-specifi
1a00: 63 20 66 6f 72 6d 61 74 3b 20 69 74 20 64 6f 65  c format; it doe
1a10: 73 20 6e 6f 74 20 68 61 76 65 20 74 6f 20 62 65  s not have to be
1a20: 20 63 72 6f 73 73 2d 70 6c 61 74 66 6f 72 6d 2e   cross-platform.
1a30: 0a 2a 2a 20 48 65 6e 63 65 2c 20 75 6e 6c 69 6b  .** Hence, unlik
1a40: 65 20 74 68 65 20 64 61 74 61 62 61 73 65 20 61  e the database a
1a50: 6e 64 20 57 41 4c 20 66 69 6c 65 20 66 6f 72 6d  nd WAL file form
1a60: 61 74 73 20 77 68 69 63 68 20 73 74 6f 72 65 20  ats which store 
1a70: 61 6c 6c 20 76 61 6c 75 65 73 0a 2a 2a 20 61 73  all values.** as
1a80: 20 62 69 67 20 65 6e 64 69 61 6e 2c 20 74 68 65   big endian, the
1a90: 20 77 61 6c 2d 69 6e 64 65 78 20 63 61 6e 20 73   wal-index can s
1aa0: 74 6f 72 65 20 6d 75 6c 74 69 2d 62 79 74 65 20  tore multi-byte 
1ab0: 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 6e 61  values in the na
1ac0: 74 69 76 65 0a 2a 2a 20 62 79 74 65 20 6f 72 64  tive.** byte ord
1ad0: 65 72 20 6f 66 20 74 68 65 20 68 6f 73 74 20 63  er of the host c
1ae0: 6f 6d 70 75 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54  omputer..**.** T
1af0: 68 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74 68  he purpose of th
1b00: 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 74  e wal-index is t
1b10: 6f 20 61 6e 73 77 65 72 20 74 68 69 73 20 71 75  o answer this qu
1b20: 65 73 74 69 6f 6e 20 71 75 69 63 6b 6c 79 3a 20  estion quickly: 
1b30: 20 47 69 76 65 6e 0a 2a 2a 20 61 20 70 61 67 65   Given.** a page
1b40: 20 6e 75 6d 62 65 72 20 50 20 61 6e 64 20 61 20   number P and a 
1b50: 6d 61 78 69 6d 75 6d 20 66 72 61 6d 65 20 69 6e  maximum frame in
1b60: 64 65 78 20 4d 2c 20 72 65 74 75 72 6e 20 74 68  dex M, return th
1b70: 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 0a  e index of the .
1b80: 2a 2a 20 6c 61 73 74 20 66 72 61 6d 65 20 69 6e  ** last frame in
1b90: 20 74 68 65 20 77 61 6c 20 62 65 66 6f 72 65 20   the wal before 
1ba0: 66 72 61 6d 65 20 4d 20 66 6f 72 20 70 61 67 65  frame M for page
1bb0: 20 50 20 69 6e 20 74 68 65 20 57 41 4c 2c 20 6f   P in the WAL, o
1bc0: 72 20 72 65 74 75 72 6e 0a 2a 2a 20 4e 55 4c 4c  r return.** NULL
1bd0: 20 69 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f   if there are no
1be0: 20 66 72 61 6d 65 73 20 66 6f 72 20 70 61 67 65   frames for page
1bf0: 20 50 20 69 6e 20 74 68 65 20 57 41 4c 20 70 72   P in the WAL pr
1c00: 69 6f 72 20 74 6f 20 4d 2e 0a 2a 2a 0a 2a 2a 20  ior to M..**.** 
1c10: 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f  The wal-index co
1c20: 6e 73 69 73 74 73 20 6f 66 20 61 20 68 65 61 64  nsists of a head
1c30: 65 72 20 72 65 67 69 6f 6e 2c 20 66 6f 6c 6c 6f  er region, follo
1c40: 77 65 64 20 62 79 20 61 6e 20 6f 6e 65 20 6f 72  wed by an one or
1c50: 0a 2a 2a 20 6d 6f 72 65 20 69 6e 64 65 78 20 62  .** more index b
1c60: 6c 6f 63 6b 73 2e 20 20 0a 2a 2a 0a 2a 2a 20 54  locks.  .**.** T
1c70: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
1c80: 64 65 72 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  der contains the
1c90: 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66   total number of
1ca0: 20 66 72 61 6d 65 73 20 77 69 74 68 69 6e 20 74   frames within t
1cb0: 68 65 20 57 41 4c 0a 2a 2a 20 69 6e 20 74 68 65  he WAL.** in the
1cc0: 20 6d 78 46 72 61 6d 65 20 66 69 65 6c 64 2e 0a   mxFrame field..
1cd0: 2a 2a 0a 2a 2a 20 45 61 63 68 20 69 6e 64 65 78  **.** Each index
1ce0: 20 62 6c 6f 63 6b 20 65 78 63 65 70 74 20 66 6f   block except fo
1cf0: 72 20 74 68 65 20 66 69 72 73 74 20 63 6f 6e 74  r the first cont
1d00: 61 69 6e 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  ains information
1d10: 20 6f 6e 20 0a 2a 2a 20 48 41 53 48 54 41 42 4c   on .** HASHTABL
1d20: 45 5f 4e 50 41 47 45 20 66 72 61 6d 65 73 2e 20  E_NPAGE frames. 
1d30: 54 68 65 20 66 69 72 73 74 20 69 6e 64 65 78 20  The first index 
1d40: 62 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20 69  block contains i
1d50: 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f 6e 0a 2a 2a  nformation on.**
1d60: 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45   HASHTABLE_NPAGE
1d70: 5f 4f 4e 45 20 66 72 61 6d 65 73 2e 20 54 68 65  _ONE frames. The
1d80: 20 76 61 6c 75 65 73 20 6f 66 20 48 41 53 48 54   values of HASHT
1d90: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20 61  ABLE_NPAGE_ONE a
1da0: 6e 64 20 0a 2a 2a 20 48 41 53 48 54 41 42 4c 45  nd .** HASHTABLE
1db0: 5f 4e 50 41 47 45 20 61 72 65 20 73 65 6c 65 63  _NPAGE are selec
1dc0: 74 65 64 20 73 6f 20 74 68 61 74 20 74 6f 67 65  ted so that toge
1dd0: 74 68 65 72 20 74 68 65 20 77 61 6c 2d 69 6e 64  ther the wal-ind
1de0: 65 78 20 68 65 61 64 65 72 20 61 6e 64 0a 2a 2a  ex header and.**
1df0: 20 66 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f   first index blo
1e00: 63 6b 20 61 72 65 20 74 68 65 20 73 61 6d 65 20  ck are the same 
1e10: 73 69 7a 65 20 61 73 20 61 6c 6c 20 6f 74 68 65  size as all othe
1e20: 72 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73 20 69  r index blocks i
1e30: 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64  n the.** wal-ind
1e40: 65 78 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 69  ex..**.** Each i
1e50: 6e 64 65 78 20 62 6c 6f 63 6b 20 63 6f 6e 74 61  ndex block conta
1e60: 69 6e 73 20 74 77 6f 20 73 65 63 74 69 6f 6e 73  ins two sections
1e70: 2c 20 61 20 70 61 67 65 2d 6d 61 70 70 69 6e 67  , a page-mapping
1e80: 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74   that contains t
1e90: 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20 70  he.** database p
1ea0: 61 67 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63  age number assoc
1eb0: 69 61 74 65 64 20 77 69 74 68 20 65 61 63 68 20  iated with each 
1ec0: 77 61 6c 20 66 72 61 6d 65 2c 20 61 6e 64 20 61  wal frame, and a
1ed0: 20 68 61 73 68 2d 74 61 62 6c 65 20 0a 2a 2a 20   hash-table .** 
1ee0: 74 68 61 74 20 61 6c 6c 6f 77 73 20 72 65 61 64  that allows read
1ef0: 65 72 73 20 74 6f 20 71 75 65 72 79 20 61 6e 20  ers to query an 
1f00: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 66 6f 72 20  index block for 
1f10: 61 20 73 70 65 63 69 66 69 63 20 70 61 67 65 20  a specific page 
1f20: 6e 75 6d 62 65 72 2e 0a 2a 2a 20 54 68 65 20 70  number..** The p
1f30: 61 67 65 2d 6d 61 70 70 69 6e 67 20 69 73 20 61  age-mapping is a
1f40: 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53 48 54  n array of HASHT
1f50: 41 42 4c 45 5f 4e 50 41 47 45 20 28 6f 72 20 48  ABLE_NPAGE (or H
1f60: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
1f70: 4e 45 0a 2a 2a 20 66 6f 72 20 74 68 65 20 66 69  NE.** for the fi
1f80: 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 29  rst index block)
1f90: 20 33 32 2d 62 69 74 20 70 61 67 65 20 6e 75 6d   32-bit page num
1fa0: 62 65 72 73 2e 20 54 68 65 20 66 69 72 73 74 20  bers. The first 
1fb0: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 0a 2a 2a  entry in the .**
1fc0: 20 66 69 72 73 74 20 69 6e 64 65 78 2d 62 6c 6f   first index-blo
1fd0: 63 6b 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  ck contains the 
1fe0: 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6e 75  database page nu
1ff0: 6d 62 65 72 20 63 6f 72 72 65 73 70 6f 6e 64 69  mber correspondi
2000: 6e 67 20 74 6f 20 74 68 65 0a 2a 2a 20 66 69 72  ng to the.** fir
2010: 73 74 20 66 72 61 6d 65 20 69 6e 20 74 68 65 20  st frame in the 
2020: 57 41 4c 20 66 69 6c 65 2e 20 54 68 65 20 66 69  WAL file. The fi
2030: 72 73 74 20 65 6e 74 72 79 20 69 6e 20 74 68 65  rst entry in the
2040: 20 73 65 63 6f 6e 64 20 69 6e 64 65 78 20 62 6c   second index bl
2050: 6f 63 6b 0a 2a 2a 20 69 6e 20 74 68 65 20 57 41  ock.** in the WA
2060: 4c 20 66 69 6c 65 20 63 6f 72 72 65 73 70 6f 6e  L file correspon
2070: 64 73 20 74 6f 20 74 68 65 20 28 48 41 53 48 54  ds to the (HASHT
2080: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 31  ABLE_NPAGE_ONE+1
2090: 29 74 68 20 66 72 61 6d 65 20 69 6e 0a 2a 2a 20  )th frame in.** 
20a0: 74 68 65 20 6c 6f 67 2c 20 61 6e 64 20 73 6f 20  the log, and so 
20b0: 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c 61  on..**.** The la
20c0: 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 69  st index block i
20d0: 6e 20 61 20 77 61 6c 2d 69 6e 64 65 78 20 75 73  n a wal-index us
20e0: 75 61 6c 6c 79 20 63 6f 6e 74 61 69 6e 73 20 6c  ually contains l
20f0: 65 73 73 20 74 68 61 6e 20 74 68 65 20 66 75 6c  ess than the ful
2100: 6c 0a 2a 2a 20 63 6f 6d 70 6c 65 6d 65 6e 74 20  l.** complement 
2110: 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  of HASHTABLE_NPA
2120: 47 45 20 28 6f 72 20 48 41 53 48 54 41 42 4c 45  GE (or HASHTABLE
2130: 5f 4e 50 41 47 45 5f 4f 4e 45 29 20 70 61 67 65  _NPAGE_ONE) page
2140: 2d 6e 75 6d 62 65 72 73 2c 0a 2a 2a 20 64 65 70  -numbers,.** dep
2150: 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20 63 6f  ending on the co
2160: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 57 41  ntents of the WA
2170: 4c 20 66 69 6c 65 2e 20 54 68 69 73 20 64 6f 65  L file. This doe
2180: 73 20 6e 6f 74 20 63 68 61 6e 67 65 20 74 68 65  s not change the
2190: 0a 2a 2a 20 61 6c 6c 6f 63 61 74 65 64 20 73 69  .** allocated si
21a0: 7a 65 20 6f 66 20 74 68 65 20 70 61 67 65 2d 6d  ze of the page-m
21b0: 61 70 70 69 6e 67 20 61 72 72 61 79 20 2d 20 74  apping array - t
21c0: 68 65 20 70 61 67 65 2d 6d 61 70 70 69 6e 67 20  he page-mapping 
21d0: 61 72 72 61 79 20 6d 65 72 65 6c 79 0a 2a 2a 20  array merely.** 
21e0: 63 6f 6e 74 61 69 6e 73 20 75 6e 75 73 65 64 20  contains unused 
21f0: 65 6e 74 72 69 65 73 2e 0a 2a 2a 0a 2a 2a 20 45  entries..**.** E
2200: 76 65 6e 20 77 69 74 68 6f 75 74 20 75 73 69 6e  ven without usin
2210: 67 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  g the hash table
2220: 2c 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d 65  , the last frame
2230: 20 66 6f 72 20 70 61 67 65 20 50 0a 2a 2a 20 63   for page P.** c
2240: 61 6e 20 62 65 20 66 6f 75 6e 64 20 62 79 20 73  an be found by s
2250: 63 61 6e 6e 69 6e 67 20 74 68 65 20 70 61 67 65  canning the page
2260: 2d 6d 61 70 70 69 6e 67 20 73 65 63 74 69 6f 6e  -mapping section
2270: 73 20 6f 66 20 65 61 63 68 20 69 6e 64 65 78 20  s of each index 
2280: 62 6c 6f 63 6b 0a 2a 2a 20 73 74 61 72 74 69 6e  block.** startin
2290: 67 20 77 69 74 68 20 74 68 65 20 6c 61 73 74 20  g with the last 
22a0: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 61 6e 64 20  index block and 
22b0: 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20 74 68  moving toward th
22c0: 65 20 66 69 72 73 74 2c 20 61 6e 64 0a 2a 2a 20  e first, and.** 
22d0: 77 69 74 68 69 6e 20 65 61 63 68 20 69 6e 64 65  within each inde
22e0: 78 20 62 6c 6f 63 6b 2c 20 73 74 61 72 74 69 6e  x block, startin
22f0: 67 20 61 74 20 74 68 65 20 65 6e 64 20 61 6e 64  g at the end and
2300: 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20 74   moving toward t
2310: 68 65 0a 2a 2a 20 62 65 67 69 6e 6e 69 6e 67 2e  he.** beginning.
2320: 20 20 54 68 65 20 66 69 72 73 74 20 65 6e 74 72    The first entr
2330: 79 20 74 68 61 74 20 65 71 75 61 6c 73 20 50 20  y that equals P 
2340: 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20 74  corresponds to t
2350: 68 65 20 66 72 61 6d 65 0a 2a 2a 20 68 6f 6c 64  he frame.** hold
2360: 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74 20  ing the content 
2370: 66 6f 72 20 74 68 61 74 20 70 61 67 65 2e 0a 2a  for that page..*
2380: 2a 0a 2a 2a 20 54 68 65 20 68 61 73 68 20 74 61  *.** The hash ta
2390: 62 6c 65 20 63 6f 6e 73 69 73 74 73 20 6f 66 20  ble consists of 
23a0: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20  HASHTABLE_NSLOT 
23b0: 31 36 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20  16-bit unsigned 
23c0: 69 6e 74 65 67 65 72 73 2e 0a 2a 2a 20 48 41 53  integers..** HAS
23d0: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 3d 20 32  HTABLE_NSLOT = 2
23e0: 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  *HASHTABLE_NPAGE
23f0: 2c 20 61 6e 64 20 74 68 65 72 65 20 69 73 20 6f  , and there is o
2400: 6e 65 20 65 6e 74 72 79 20 69 6e 20 74 68 65 0a  ne entry in the.
2410: 2a 2a 20 68 61 73 68 20 74 61 62 6c 65 20 66 6f  ** hash table fo
2420: 72 20 65 61 63 68 20 70 61 67 65 20 6e 75 6d 62  r each page numb
2430: 65 72 20 69 6e 20 74 68 65 20 6d 61 70 70 69 6e  er in the mappin
2440: 67 20 73 65 63 74 69 6f 6e 2c 20 73 6f 20 74 68  g section, so th
2450: 65 20 68 61 73 68 20 0a 2a 2a 20 74 61 62 6c 65  e hash .** table
2460: 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20 74   is never more t
2470: 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2e 20 20  han half full.  
2480: 54 68 65 20 65 78 70 65 63 74 65 64 20 6e 75 6d  The expected num
2490: 62 65 72 20 6f 66 20 63 6f 6c 6c 69 73 69 6f 6e  ber of collision
24a0: 73 20 0a 2a 2a 20 70 72 69 6f 72 20 74 6f 20 66  s .** prior to f
24b0: 69 6e 64 69 6e 67 20 61 20 6d 61 74 63 68 20 69  inding a match i
24c0: 73 20 31 2e 20 20 45 61 63 68 20 65 6e 74 72 79  s 1.  Each entry
24d0: 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61 62   of the hash tab
24e0: 6c 65 20 69 73 20 61 6e 0a 2a 2a 20 31 2d 62 61  le is an.** 1-ba
24f0: 73 65 64 20 69 6e 64 65 78 20 6f 66 20 61 6e 20  sed index of an 
2500: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61 70  entry in the map
2510: 70 69 6e 67 20 73 65 63 74 69 6f 6e 20 6f 66 20  ping section of 
2520: 74 68 65 20 73 61 6d 65 0a 2a 2a 20 69 6e 64 65  the same.** inde
2530: 78 20 62 6c 6f 63 6b 2e 20 20 20 4c 65 74 20 4b  x block.   Let K
2540: 20 62 65 20 74 68 65 20 31 2d 62 61 73 65 64 20   be the 1-based 
2550: 69 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 72  index of the lar
2560: 67 65 73 74 20 65 6e 74 72 79 20 69 6e 0a 2a 2a  gest entry in.**
2570: 20 74 68 65 20 6d 61 70 70 69 6e 67 20 73 65 63   the mapping sec
2580: 74 69 6f 6e 2e 20 20 28 46 6f 72 20 69 6e 64 65  tion.  (For inde
2590: 78 20 62 6c 6f 63 6b 73 20 6f 74 68 65 72 20 74  x blocks other t
25a0: 68 61 6e 20 74 68 65 20 6c 61 73 74 2c 20 4b 20  han the last, K 
25b0: 77 69 6c 6c 0a 2a 2a 20 61 6c 77 61 79 73 20 62  will.** always b
25c0: 65 20 65 78 61 63 74 6c 79 20 48 41 53 48 54 41  e exactly HASHTA
25d0: 42 4c 45 5f 4e 50 41 47 45 20 28 34 30 39 36 29  BLE_NPAGE (4096)
25e0: 20 61 6e 64 20 66 6f 72 20 74 68 65 20 6c 61 73   and for the las
25f0: 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 0a 2a 2a  t index block.**
2600: 20 4b 20 77 69 6c 6c 20 62 65 20 28 6d 78 46 72   K will be (mxFr
2610: 61 6d 65 25 48 41 53 48 54 41 42 4c 45 5f 4e 50  ame%HASHTABLE_NP
2620: 41 47 45 29 2e 29 20 20 55 6e 75 73 65 64 20 73  AGE).)  Unused s
2630: 6c 6f 74 73 20 6f 66 20 74 68 65 20 68 61 73 68  lots of the hash
2640: 20 74 61 62 6c 65 0a 2a 2a 20 63 6f 6e 74 61 69   table.** contai
2650: 6e 20 61 20 76 61 6c 75 65 20 6f 66 20 30 2e 0a  n a value of 0..
2660: 2a 2a 0a 2a 2a 20 54 6f 20 6c 6f 6f 6b 20 66 6f  **.** To look fo
2670: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
2680: 68 61 73 68 20 74 61 62 6c 65 2c 20 66 69 72 73  hash table, firs
2690: 74 20 63 6f 6d 70 75 74 65 20 61 20 68 61 73 68  t compute a hash
26a0: 20 69 4b 65 79 20 6f 6e 0a 2a 2a 20 50 20 61 73   iKey on.** P as
26b0: 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20   follows:.**.** 
26c0: 20 20 20 20 20 69 4b 65 79 20 3d 20 28 50 20 2a       iKey = (P *
26d0: 20 33 38 33 29 20 25 20 48 41 53 48 54 41 42 4c   383) % HASHTABL
26e0: 45 5f 4e 53 4c 4f 54 0a 2a 2a 0a 2a 2a 20 54 68  E_NSLOT.**.** Th
26f0: 65 6e 20 73 74 61 72 74 20 73 63 61 6e 6e 69 6e  en start scannin
2700: 67 20 65 6e 74 72 69 65 73 20 6f 66 20 74 68 65  g entries of the
2710: 20 68 61 73 68 20 74 61 62 6c 65 2c 20 73 74 61   hash table, sta
2720: 72 74 69 6e 67 20 77 69 74 68 20 69 4b 65 79 0a  rting with iKey.
2730: 2a 2a 20 28 77 72 61 70 70 69 6e 67 20 61 72 6f  ** (wrapping aro
2740: 75 6e 64 20 74 6f 20 74 68 65 20 62 65 67 69 6e  und to the begin
2750: 6e 69 6e 67 20 77 68 65 6e 20 74 68 65 20 65 6e  ning when the en
2760: 64 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61  d of the hash ta
2770: 62 6c 65 20 69 73 0a 2a 2a 20 72 65 61 63 68 65  ble is.** reache
2780: 64 29 20 75 6e 74 69 6c 20 61 6e 20 75 6e 75 73  d) until an unus
2790: 65 64 20 68 61 73 68 20 73 6c 6f 74 20 69 73 20  ed hash slot is 
27a0: 66 6f 75 6e 64 2e 20 4c 65 74 20 74 68 65 20 66  found. Let the f
27b0: 69 72 73 74 20 75 6e 75 73 65 64 20 73 6c 6f 74  irst unused slot
27c0: 0a 2a 2a 20 62 65 20 61 74 20 69 6e 64 65 78 20  .** be at index 
27d0: 69 55 6e 75 73 65 64 2e 20 20 28 69 55 6e 75 73  iUnused.  (iUnus
27e0: 65 64 20 6d 69 67 68 74 20 62 65 20 6c 65 73 73  ed might be less
27f0: 20 74 68 61 6e 20 69 4b 65 79 20 69 66 20 74 68   than iKey if th
2800: 65 72 65 20 77 61 73 0a 2a 2a 20 77 72 61 70 2d  ere was.** wrap-
2810: 61 72 6f 75 6e 64 2e 29 20 42 65 63 61 75 73 65  around.) Because
2820: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
2830: 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20 74 68  is never more th
2840: 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2c 0a 2a 2a  an half full,.**
2850: 20 74 68 65 20 73 65 61 72 63 68 20 69 73 20 67   the search is g
2860: 75 61 72 61 6e 74 65 65 64 20 74 6f 20 65 76 65  uaranteed to eve
2870: 6e 74 75 61 6c 6c 79 20 68 69 74 20 61 6e 20 75  ntually hit an u
2880: 6e 75 73 65 64 20 65 6e 74 72 79 2e 20 20 4c 65  nused entry.  Le
2890: 74 20 0a 2a 2a 20 69 4d 61 78 20 62 65 20 74 68  t .** iMax be th
28a0: 65 20 76 61 6c 75 65 20 62 65 74 77 65 65 6e 20  e value between 
28b0: 69 4b 65 79 20 61 6e 64 20 69 55 6e 75 73 65 64  iKey and iUnused
28c0: 2c 20 63 6c 6f 73 65 73 74 20 74 6f 20 69 55 6e  , closest to iUn
28d0: 75 73 65 64 2c 0a 2a 2a 20 77 68 65 72 65 20 61  used,.** where a
28e0: 48 61 73 68 5b 69 4d 61 78 5d 3d 3d 50 2e 20 20  Hash[iMax]==P.  
28f0: 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 69  If there is no i
2900: 4d 61 78 20 65 6e 74 72 79 20 28 69 66 20 74 68  Max entry (if th
2910: 65 72 65 20 65 78 69 73 74 73 0a 2a 2a 20 6e 6f  ere exists.** no
2920: 20 68 61 73 68 20 73 6c 6f 74 20 73 75 63 68 20   hash slot such 
2930: 74 68 61 74 20 61 48 61 73 68 5b 69 5d 3d 3d 70  that aHash[i]==p
2940: 29 20 74 68 65 6e 20 70 61 67 65 20 50 20 69 73  ) then page P is
2950: 20 6e 6f 74 20 69 6e 20 74 68 65 0a 2a 2a 20 63   not in the.** c
2960: 75 72 72 65 6e 74 20 69 6e 64 65 78 20 62 6c 6f  urrent index blo
2970: 63 6b 2e 20 20 4f 74 68 65 72 77 69 73 65 20 74  ck.  Otherwise t
2980: 68 65 20 69 4d 61 78 2d 74 68 20 6d 61 70 70 69  he iMax-th mappi
2990: 6e 67 20 65 6e 74 72 79 20 6f 66 20 74 68 65 0a  ng entry of the.
29a0: 2a 2a 20 63 75 72 72 65 6e 74 20 69 6e 64 65 78  ** current index
29b0: 20 62 6c 6f 63 6b 20 63 6f 72 72 65 73 70 6f 6e   block correspon
29c0: 64 73 20 74 6f 20 74 68 65 20 6c 61 73 74 20 65  ds to the last e
29d0: 6e 74 72 79 20 74 68 61 74 20 72 65 66 65 72 65  ntry that refere
29e0: 6e 63 65 73 20 0a 2a 2a 20 70 61 67 65 20 50 2e  nces .** page P.
29f0: 0a 2a 2a 0a 2a 2a 20 41 20 68 61 73 68 20 73 65  .**.** A hash se
2a00: 61 72 63 68 20 62 65 67 69 6e 73 20 77 69 74 68  arch begins with
2a10: 20 74 68 65 20 6c 61 73 74 20 69 6e 64 65 78 20   the last index 
2a20: 62 6c 6f 63 6b 20 61 6e 64 20 6d 6f 76 65 73 20  block and moves 
2a30: 74 6f 77 61 72 64 20 74 68 65 0a 2a 2a 20 66 69  toward the.** fi
2a40: 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 2c  rst index block,
2a50: 20 6c 6f 6f 6b 69 6e 67 20 66 6f 72 20 65 6e 74   looking for ent
2a60: 72 69 65 73 20 63 6f 72 72 65 73 70 6f 6e 64 69  ries correspondi
2a70: 6e 67 20 74 6f 20 70 61 67 65 20 50 2e 20 20 4f  ng to page P.  O
2a80: 6e 0a 2a 2a 20 61 76 65 72 61 67 65 2c 20 6f 6e  n.** average, on
2a90: 6c 79 20 74 77 6f 20 6f 72 20 74 68 72 65 65 20  ly two or three 
2aa0: 73 6c 6f 74 73 20 69 6e 20 65 61 63 68 20 69 6e  slots in each in
2ab0: 64 65 78 20 62 6c 6f 63 6b 20 6e 65 65 64 20 74  dex block need t
2ac0: 6f 20 62 65 0a 2a 2a 20 65 78 61 6d 69 6e 65 64  o be.** examined
2ad0: 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 65 69 74   in order to eit
2ae0: 68 65 72 20 66 69 6e 64 20 74 68 65 20 6c 61 73  her find the las
2af0: 74 20 65 6e 74 72 79 20 66 6f 72 20 70 61 67 65  t entry for page
2b00: 20 50 2c 20 6f 72 20 74 6f 0a 2a 2a 20 65 73 74   P, or to.** est
2b10: 61 62 6c 69 73 68 20 74 68 61 74 20 6e 6f 20 73  ablish that no s
2b20: 75 63 68 20 65 6e 74 72 79 20 65 78 69 73 74 73  uch entry exists
2b30: 20 69 6e 20 74 68 65 20 62 6c 6f 63 6b 2e 20 20   in the block.  
2b40: 45 61 63 68 20 69 6e 64 65 78 20 62 6c 6f 63 6b  Each index block
2b50: 0a 2a 2a 20 68 6f 6c 64 73 20 6f 76 65 72 20 34  .** holds over 4
2b60: 30 30 30 20 65 6e 74 72 69 65 73 2e 20 20 53 6f  000 entries.  So
2b70: 20 74 77 6f 20 6f 72 20 74 68 72 65 65 20 69 6e   two or three in
2b80: 64 65 78 20 62 6c 6f 63 6b 73 20 61 72 65 20 73  dex blocks are s
2b90: 75 66 66 69 63 69 65 6e 74 0a 2a 2a 20 74 6f 20  ufficient.** to 
2ba0: 63 6f 76 65 72 20 61 20 74 79 70 69 63 61 6c 20  cover a typical 
2bb0: 31 30 20 6d 65 67 61 62 79 74 65 20 57 41 4c 20  10 megabyte WAL 
2bc0: 66 69 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20 31  file, assuming 1
2bd0: 4b 20 70 61 67 65 73 2e 20 20 38 20 6f 72 20 31  K pages.  8 or 1
2be0: 30 0a 2a 2a 20 63 6f 6d 70 61 72 69 73 6f 6e 73  0.** comparisons
2bf0: 20 28 6f 6e 20 61 76 65 72 61 67 65 29 20 73 75   (on average) su
2c00: 66 66 69 63 65 20 74 6f 20 65 69 74 68 65 72 20  ffice to either 
2c10: 6c 6f 63 61 74 65 20 61 20 66 72 61 6d 65 20 69  locate a frame i
2c20: 6e 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6f 72 20  n the.** WAL or 
2c30: 74 6f 20 65 73 74 61 62 6c 69 73 68 20 74 68 61  to establish tha
2c40: 74 20 74 68 65 20 66 72 61 6d 65 20 64 6f 65 73  t the frame does
2c50: 20 6e 6f 74 20 65 78 69 73 74 20 69 6e 20 74 68   not exist in th
2c60: 65 20 57 41 4c 2e 20 20 54 68 69 73 0a 2a 2a 20  e WAL.  This.** 
2c70: 69 73 20 6d 75 63 68 20 66 61 73 74 65 72 20 74  is much faster t
2c80: 68 61 6e 20 73 63 61 6e 6e 69 6e 67 20 74 68 65  han scanning the
2c90: 20 65 6e 74 69 72 65 20 31 30 4d 42 20 57 41 4c   entire 10MB WAL
2ca0: 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61  ..**.** Note tha
2cb0: 74 20 65 6e 74 72 69 65 73 20 61 72 65 20 61 64  t entries are ad
2cc0: 64 65 64 20 69 6e 20 6f 72 64 65 72 20 6f 66 20  ded in order of 
2cd0: 69 6e 63 72 65 61 73 69 6e 67 20 4b 2e 20 20 48  increasing K.  H
2ce0: 65 6e 63 65 2c 20 6f 6e 65 0a 2a 2a 20 72 65 61  ence, one.** rea
2cf0: 64 65 72 20 6d 69 67 68 74 20 62 65 20 75 73 69  der might be usi
2d00: 6e 67 20 73 6f 6d 65 20 76 61 6c 75 65 20 4b 30  ng some value K0
2d10: 20 61 6e 64 20 61 20 73 65 63 6f 6e 64 20 72 65   and a second re
2d20: 61 64 65 72 20 74 68 61 74 20 73 74 61 72 74 65  ader that starte
2d30: 64 0a 2a 2a 20 61 74 20 61 20 6c 61 74 65 72 20  d.** at a later 
2d40: 74 69 6d 65 20 28 61 66 74 65 72 20 61 64 64 69  time (after addi
2d50: 74 69 6f 6e 61 6c 20 74 72 61 6e 73 61 63 74 69  tional transacti
2d60: 6f 6e 73 20 77 65 72 65 20 61 64 64 65 64 20 74  ons were added t
2d70: 6f 20 74 68 65 20 57 41 4c 0a 2a 2a 20 61 6e 64  o the WAL.** and
2d80: 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   to the wal-inde
2d90: 78 29 20 6d 69 67 68 74 20 62 65 20 75 73 69 6e  x) might be usin
2da0: 67 20 61 20 64 69 66 66 65 72 65 6e 74 20 76 61  g a different va
2db0: 6c 75 65 20 4b 31 2c 20 77 68 65 72 65 20 4b 31  lue K1, where K1
2dc0: 3e 4b 30 2e 0a 2a 2a 20 42 6f 74 68 20 72 65 61  >K0..** Both rea
2dd0: 64 65 72 73 20 63 61 6e 20 75 73 65 20 74 68 65  ders can use the
2de0: 20 73 61 6d 65 20 68 61 73 68 20 74 61 62 6c 65   same hash table
2df0: 20 61 6e 64 20 6d 61 70 70 69 6e 67 20 73 65 63   and mapping sec
2e00: 74 69 6f 6e 20 74 6f 20 67 65 74 0a 2a 2a 20 74  tion to get.** t
2e10: 68 65 20 63 6f 72 72 65 63 74 20 72 65 73 75 6c  he correct resul
2e20: 74 2e 20 20 54 68 65 72 65 20 6d 61 79 20 62 65  t.  There may be
2e30: 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20   entries in the 
2e40: 68 61 73 68 20 74 61 62 6c 65 20 77 69 74 68 0a  hash table with.
2e50: 2a 2a 20 4b 3e 4b 30 20 62 75 74 20 74 6f 20 74  ** K>K0 but to t
2e60: 68 65 20 66 69 72 73 74 20 72 65 61 64 65 72 2c  he first reader,
2e70: 20 74 68 6f 73 65 20 65 6e 74 72 69 65 73 20 77   those entries w
2e80: 69 6c 6c 20 61 70 70 65 61 72 20 74 6f 20 62 65  ill appear to be
2e90: 20 75 6e 75 73 65 64 0a 2a 2a 20 73 6c 6f 74 73   unused.** slots
2ea0: 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62   in the hash tab
2eb0: 6c 65 20 61 6e 64 20 73 6f 20 74 68 65 20 66 69  le and so the fi
2ec0: 72 73 74 20 72 65 61 64 65 72 20 77 69 6c 6c 20  rst reader will 
2ed0: 67 65 74 20 61 6e 20 61 6e 73 77 65 72 20 61 73  get an answer as
2ee0: 0a 2a 2a 20 69 66 20 6e 6f 20 76 61 6c 75 65 73  .** if no values
2ef0: 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 4b 30   greater than K0
2f00: 20 68 61 64 20 65 76 65 72 20 62 65 65 6e 20 69   had ever been i
2f10: 6e 73 65 72 74 65 64 20 69 6e 74 6f 20 74 68 65  nserted into the
2f20: 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20 69   hash table.** i
2f30: 6e 20 74 68 65 20 66 69 72 73 74 20 70 6c 61 63  n the first plac
2f40: 65 20 2d 20 77 68 69 63 68 20 69 73 20 77 68 61  e - which is wha
2f50: 74 20 72 65 61 64 65 72 20 6f 6e 65 20 77 61 6e  t reader one wan
2f60: 74 73 2e 20 20 4d 65 61 6e 77 68 69 6c 65 2c 20  ts.  Meanwhile, 
2f70: 74 68 65 0a 2a 2a 20 73 65 63 6f 6e 64 20 72 65  the.** second re
2f80: 61 64 65 72 20 75 73 69 6e 67 20 4b 31 20 77 69  ader using K1 wi
2f90: 6c 6c 20 73 65 65 20 61 64 64 69 74 69 6f 6e 61  ll see additiona
2fa0: 6c 20 76 61 6c 75 65 73 20 74 68 61 74 20 77 65  l values that we
2fb0: 72 65 20 69 6e 73 65 72 74 65 64 0a 2a 2a 20 6c  re inserted.** l
2fc0: 61 74 65 72 2c 20 77 68 69 63 68 20 69 73 20 65  ater, which is e
2fd0: 78 61 63 74 6c 79 20 77 68 61 74 20 72 65 61 64  xactly what read
2fe0: 65 72 20 74 77 6f 20 77 61 6e 74 73 2e 20 20 0a  er two wants.  .
2ff0: 2a 2a 0a 2a 2a 20 57 68 65 6e 20 61 20 72 6f 6c  **.** When a rol
3000: 6c 62 61 63 6b 20 6f 63 63 75 72 73 2c 20 74 68  lback occurs, th
3010: 65 20 76 61 6c 75 65 20 6f 66 20 4b 20 69 73 20  e value of K is 
3020: 64 65 63 72 65 61 73 65 64 2e 20 48 61 73 68 20  decreased. Hash 
3030: 74 61 62 6c 65 20 65 6e 74 72 69 65 73 0a 2a 2a  table entries.**
3040: 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64   that correspond
3050: 20 74 6f 20 66 72 61 6d 65 73 20 67 72 65 61 74   to frames great
3060: 65 72 20 74 68 61 6e 20 74 68 65 20 6e 65 77 20  er than the new 
3070: 4b 20 76 61 6c 75 65 20 61 72 65 20 72 65 6d 6f  K value are remo
3080: 76 65 64 0a 2a 2a 20 66 72 6f 6d 20 74 68 65 20  ved.** from the 
3090: 68 61 73 68 20 74 61 62 6c 65 20 61 74 20 74 68  hash table at th
30a0: 69 73 20 70 6f 69 6e 74 2e 0a 2a 2f 0a 23 69 66  is point..*/.#if
30b0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
30c0: 5f 57 41 4c 0a 0a 23 69 6e 63 6c 75 64 65 20 22  _WAL..#include "
30d0: 77 61 6c 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 54 72  wal.h"../*.** Tr
30e0: 61 63 65 20 6f 75 74 70 75 74 20 6d 61 63 72 6f  ace output macro
30f0: 73 0a 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64  s.*/.#if defined
3100: 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26 26  (SQLITE_TEST) &&
3110: 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
3120: 44 45 42 55 47 29 0a 69 6e 74 20 73 71 6c 69 74  DEBUG).int sqlit
3130: 65 33 57 61 6c 54 72 61 63 65 20 3d 20 30 3b 0a  e3WalTrace = 0;.
3140: 23 20 64 65 66 69 6e 65 20 57 41 4c 54 52 41 43  # define WALTRAC
3150: 45 28 58 29 20 20 69 66 28 73 71 6c 69 74 65 33  E(X)  if(sqlite3
3160: 57 61 6c 54 72 61 63 65 29 20 73 71 6c 69 74 65  WalTrace) sqlite
3170: 33 44 65 62 75 67 50 72 69 6e 74 66 20 58 0a 23  3DebugPrintf X.#
3180: 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 57 41  else.# define WA
3190: 4c 54 52 41 43 45 28 58 29 0a 23 65 6e 64 69 66  LTRACE(X).#endif
31a0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 78 69  ../*.** The maxi
31b0: 6d 75 6d 20 28 61 6e 64 20 6f 6e 6c 79 29 20 76  mum (and only) v
31c0: 65 72 73 69 6f 6e 73 20 6f 66 20 74 68 65 20 77  ersions of the w
31d0: 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78  al and wal-index
31e0: 20 66 6f 72 6d 61 74 73 0a 2a 2a 20 74 68 61 74   formats.** that
31f0: 20 6d 61 79 20 62 65 20 69 6e 74 65 72 70 72 65   may be interpre
3200: 74 65 64 20 62 79 20 74 68 69 73 20 76 65 72 73  ted by this vers
3210: 69 6f 6e 20 6f 66 20 53 51 4c 69 74 65 2e 0a 2a  ion of SQLite..*
3220: 2a 0a 2a 2a 20 49 66 20 61 20 63 6c 69 65 6e 74  *.** If a client
3230: 20 62 65 67 69 6e 73 20 72 65 63 6f 76 65 72 69   begins recoveri
3240: 6e 67 20 61 20 57 41 4c 20 66 69 6c 65 20 61 6e  ng a WAL file an
3250: 64 20 66 69 6e 64 73 20 74 68 61 74 20 28 61 29  d finds that (a)
3260: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 0a 2a 2a   the checksum.**
3270: 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 77   values in the w
3280: 61 6c 2d 68 65 61 64 65 72 20 61 72 65 20 63 6f  al-header are co
3290: 72 72 65 63 74 20 61 6e 64 20 28 62 29 20 74 68  rrect and (b) th
32a0: 65 20 76 65 72 73 69 6f 6e 20 66 69 65 6c 64 20  e version field 
32b0: 69 73 20 6e 6f 74 0a 2a 2a 20 57 41 4c 5f 4d 41  is not.** WAL_MA
32c0: 58 5f 56 45 52 53 49 4f 4e 2c 20 72 65 63 6f 76  X_VERSION, recov
32d0: 65 72 79 20 66 61 69 6c 73 20 61 6e 64 20 53 51  ery fails and SQ
32e0: 4c 69 74 65 20 72 65 74 75 72 6e 73 20 53 51 4c  Lite returns SQL
32f0: 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2e 0a 2a 2a  ITE_CANTOPEN..**
3300: 0a 2a 2a 20 53 69 6d 69 6c 61 72 6c 79 2c 20 69  .** Similarly, i
3310: 66 20 61 20 63 6c 69 65 6e 74 20 73 75 63 63 65  f a client succe
3320: 73 73 66 75 6c 6c 79 20 72 65 61 64 73 20 61 20  ssfully reads a 
3330: 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
3340: 20 28 69 2e 65 2e 20 74 68 65 20 0a 2a 2a 20 63   (i.e. the .** c
3350: 68 65 63 6b 73 75 6d 20 74 65 73 74 20 69 73 20  hecksum test is 
3360: 73 75 63 63 65 73 73 66 75 6c 29 20 61 6e 64 20  successful) and 
3370: 66 69 6e 64 73 20 74 68 61 74 20 74 68 65 20 76  finds that the v
3380: 65 72 73 69 6f 6e 20 66 69 65 6c 64 20 69 73 20  ersion field is 
3390: 6e 6f 74 0a 2a 2a 20 57 41 4c 49 4e 44 45 58 5f  not.** WALINDEX_
33a0: 4d 41 58 5f 56 45 52 53 49 4f 4e 2c 20 74 68 65  MAX_VERSION, the
33b0: 6e 20 6e 6f 20 72 65 61 64 2d 74 72 61 6e 73 61  n no read-transa
33c0: 63 74 69 6f 6e 20 69 73 20 6f 70 65 6e 65 64 20  ction is opened 
33d0: 61 6e 64 20 53 51 4c 69 74 65 0a 2a 2a 20 72 65  and SQLite.** re
33e0: 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 43 41 4e  turns SQLITE_CAN
33f0: 54 4f 50 45 4e 2e 0a 2a 2f 0a 23 64 65 66 69 6e  TOPEN..*/.#defin
3400: 65 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49 4f  e WAL_MAX_VERSIO
3410: 4e 20 20 20 20 20 20 33 30 30 37 30 30 30 0a 23  N      3007000.#
3420: 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58 5f  define WALINDEX_
3430: 4d 41 58 5f 56 45 52 53 49 4f 4e 20 33 30 30 37  MAX_VERSION 3007
3440: 30 30 30 0a 0a 2f 2a 0a 2a 2a 20 49 6e 64 69 63  000../*.** Indic
3450: 65 73 20 6f 66 20 76 61 72 69 6f 75 73 20 6c 6f  es of various lo
3460: 63 6b 69 6e 67 20 62 79 74 65 73 2e 20 20 20 57  cking bytes.   W
3470: 41 4c 5f 4e 52 45 41 44 45 52 20 69 73 20 74 68  AL_NREADER is th
3480: 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 61  e number.** of a
3490: 76 61 69 6c 61 62 6c 65 20 72 65 61 64 65 72 20  vailable reader 
34a0: 6c 6f 63 6b 73 20 61 6e 64 20 73 68 6f 75 6c 64  locks and should
34b0: 20 62 65 20 61 74 20 6c 65 61 73 74 20 33 2e 0a   be at least 3..
34c0: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 57  */.#define WAL_W
34d0: 52 49 54 45 5f 4c 4f 43 4b 20 20 20 20 20 20 20  RITE_LOCK       
34e0: 20 20 30 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f    0.#define WAL_
34f0: 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 20 20  ALL_BUT_WRITE   
3500: 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41 4c     1.#define WAL
3510: 5f 43 4b 50 54 5f 4c 4f 43 4b 20 20 20 20 20 20  _CKPT_LOCK      
3520: 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41      1.#define WA
3530: 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20 20  L_RECOVER_LOCK  
3540: 20 20 20 20 20 32 0a 23 64 65 66 69 6e 65 20 57       2.#define W
3550: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 49 29 20  AL_READ_LOCK(I) 
3560: 20 20 20 20 20 20 28 33 2b 28 49 29 29 0a 23 64        (3+(I)).#d
3570: 65 66 69 6e 65 20 57 41 4c 5f 4e 52 45 41 44 45  efine WAL_NREADE
3580: 52 20 20 20 20 20 20 20 20 20 20 20 20 28 53 51  R            (SQ
3590: 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 2d 33  LITE_SHM_NLOCK-3
35a0: 29 0a 0a 0a 2f 2a 20 4f 62 6a 65 63 74 20 64 65  ).../* Object de
35b0: 63 6c 61 72 61 74 69 6f 6e 73 20 2a 2f 0a 74 79  clarations */.ty
35c0: 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61 6c  pedef struct Wal
35d0: 49 6e 64 65 78 48 64 72 20 57 61 6c 49 6e 64 65  IndexHdr WalInde
35e0: 78 48 64 72 3b 0a 74 79 70 65 64 65 66 20 73 74  xHdr;.typedef st
35f0: 72 75 63 74 20 57 61 6c 49 74 65 72 61 74 6f 72  ruct WalIterator
3600: 20 57 61 6c 49 74 65 72 61 74 6f 72 3b 0a 74 79   WalIterator;.ty
3610: 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61 6c  pedef struct Wal
3620: 43 6b 70 74 49 6e 66 6f 20 57 61 6c 43 6b 70 74  CkptInfo WalCkpt
3630: 49 6e 66 6f 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68  Info;.../*.** Th
3640: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65  e following obje
3650: 63 74 20 68 6f 6c 64 73 20 61 20 63 6f 70 79 20  ct holds a copy 
3660: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
3670: 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74 2e   header content.
3680: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63 74 75 61  .**.** The actua
3690: 6c 20 68 65 61 64 65 72 20 69 6e 20 74 68 65 20  l header in the 
36a0: 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69 73  wal-index consis
36b0: 74 73 20 6f 66 20 74 77 6f 20 63 6f 70 69 65 73  ts of two copies
36c0: 20 6f 66 20 74 68 69 73 0a 2a 2a 20 6f 62 6a 65   of this.** obje
36d0: 63 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73 7a  ct..**.** The sz
36e0: 50 61 67 65 20 76 61 6c 75 65 20 63 61 6e 20 62  Page value can b
36f0: 65 20 61 6e 79 20 70 6f 77 65 72 20 6f 66 20 32  e any power of 2
3700: 20 62 65 74 77 65 65 6e 20 35 31 32 20 61 6e 64   between 512 and
3710: 20 33 32 37 36 38 2c 20 69 6e 63 6c 75 73 69 76   32768, inclusiv
3720: 65 2e 0a 2a 2a 20 4f 72 20 69 74 20 63 61 6e 20  e..** Or it can 
3730: 62 65 20 31 20 74 6f 20 72 65 70 72 65 73 65 6e  be 1 to represen
3740: 74 20 61 20 36 35 35 33 36 2d 62 79 74 65 20 70  t a 65536-byte p
3750: 61 67 65 2e 20 20 54 68 65 20 6c 61 74 74 65 72  age.  The latter
3760: 20 63 61 73 65 20 77 61 73 0a 2a 2a 20 61 64 64   case was.** add
3770: 65 64 20 69 6e 20 33 2e 37 2e 31 20 77 68 65 6e  ed in 3.7.1 when
3780: 20 73 75 70 70 6f 72 74 20 66 6f 72 20 36 34 4b   support for 64K
3790: 20 70 61 67 65 73 20 77 61 73 20 61 64 64 65 64   pages was added
37a0: 2e 20 20 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61  .  .*/.struct Wa
37b0: 6c 49 6e 64 65 78 48 64 72 20 7b 0a 20 20 75 33  lIndexHdr {.  u3
37c0: 32 20 69 56 65 72 73 69 6f 6e 3b 20 20 20 20 20  2 iVersion;     
37d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
37e0: 20 57 61 6c 2d 69 6e 64 65 78 20 76 65 72 73 69   Wal-index versi
37f0: 6f 6e 20 2a 2f 0a 20 20 75 33 32 20 75 6e 75 73  on */.  u32 unus
3800: 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ed;             
3810: 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 75 73 65          /* Unuse
3820: 64 20 28 70 61 64 64 69 6e 67 29 20 66 69 65 6c  d (padding) fiel
3830: 64 20 2a 2f 0a 20 20 75 33 32 20 69 43 68 61 6e  d */.  u32 iChan
3840: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
3850: 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65         /* Counte
3860: 72 20 69 6e 63 72 65 6d 65 6e 74 65 64 20 65 61  r incremented ea
3870: 63 68 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a  ch transaction *
3880: 2f 0a 20 20 75 38 20 69 73 49 6e 69 74 3b 20 20  /.  u8 isInit;  
3890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38a0: 20 20 20 20 2f 2a 20 31 20 77 68 65 6e 20 69 6e      /* 1 when in
38b0: 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 75  itialized */.  u
38c0: 38 20 62 69 67 45 6e 64 43 6b 73 75 6d 3b 20 20  8 bigEndCksum;  
38d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
38e0: 2a 20 54 72 75 65 20 69 66 20 63 68 65 63 6b 73  * True if checks
38f0: 75 6d 73 20 69 6e 20 57 41 4c 20 61 72 65 20 62  ums in WAL are b
3900: 69 67 2d 65 6e 64 69 61 6e 20 2a 2f 0a 20 20 75  ig-endian */.  u
3910: 31 36 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20  16 szPage;      
3920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3930: 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20  * Database page 
3940: 73 69 7a 65 20 69 6e 20 62 79 74 65 73 2e 20 31  size in bytes. 1
3950: 3d 3d 36 34 4b 20 2a 2f 0a 20 20 75 33 32 20 6d  ==64K */.  u32 m
3960: 78 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20  xFrame;         
3970: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
3980: 64 65 78 20 6f 66 20 6c 61 73 74 20 76 61 6c 69  dex of last vali
3990: 64 20 66 72 61 6d 65 20 69 6e 20 74 68 65 20 57  d frame in the W
39a0: 41 4c 20 2a 2f 0a 20 20 75 33 32 20 6e 50 61 67  AL */.  u32 nPag
39b0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
39c0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
39d0: 6f 66 20 64 61 74 61 62 61 73 65 20 69 6e 20 70  of database in p
39e0: 61 67 65 73 20 2a 2f 0a 20 20 75 33 32 20 61 46  ages */.  u32 aF
39f0: 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  rameCksum[2];   
3a00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65            /* Che
3a10: 63 6b 73 75 6d 20 6f 66 20 6c 61 73 74 20 66 72  cksum of last fr
3a20: 61 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20  ame in log */.  
3a30: 75 33 32 20 61 53 61 6c 74 5b 32 5d 3b 20 20 20  u32 aSalt[2];   
3a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a50: 2f 2a 20 54 77 6f 20 73 61 6c 74 20 76 61 6c 75  /* Two salt valu
3a60: 65 73 20 63 6f 70 69 65 64 20 66 72 6f 6d 20 57  es copied from W
3a70: 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 75  AL header */.  u
3a80: 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  32 aCksum[2];   
3a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3aa0: 2a 20 43 68 65 63 6b 73 75 6d 20 6f 76 65 72 20  * Checksum over 
3ab0: 61 6c 6c 20 70 72 69 6f 72 20 66 69 65 6c 64 73  all prior fields
3ac0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20   */.};../*.** A 
3ad0: 63 6f 70 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c  copy of the foll
3ae0: 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 6f 63 63  owing object occ
3af0: 75 72 73 20 69 6e 20 74 68 65 20 77 61 6c 2d 69  urs in the wal-i
3b00: 6e 64 65 78 20 69 6d 6d 65 64 69 61 74 65 6c 79  ndex immediately
3b10: 0a 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68  .** following th
3b20: 65 20 73 65 63 6f 6e 64 20 63 6f 70 79 20 6f 66  e second copy of
3b30: 20 74 68 65 20 57 61 6c 49 6e 64 65 78 48 64 72   the WalIndexHdr
3b40: 2e 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20 73  .  This object s
3b50: 74 6f 72 65 73 0a 2a 2a 20 69 6e 66 6f 72 6d 61  tores.** informa
3b60: 74 69 6f 6e 20 75 73 65 64 20 62 79 20 63 68 65  tion used by che
3b70: 63 6b 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20 6e  ckpoint..**.** n
3b80: 42 61 63 6b 66 69 6c 6c 20 69 73 20 74 68 65 20  Backfill is the 
3b90: 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d 65 73  number of frames
3ba0: 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68 61 74   in the WAL that
3bb0: 20 68 61 76 65 20 62 65 65 6e 20 77 72 69 74 74   have been writt
3bc0: 65 6e 0a 2a 2a 20 62 61 63 6b 20 69 6e 74 6f 20  en.** back into 
3bd0: 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 28 57  the database. (W
3be0: 65 20 63 61 6c 6c 20 74 68 65 20 61 63 74 20 6f  e call the act o
3bf0: 66 20 6d 6f 76 69 6e 67 20 63 6f 6e 74 65 6e 74  f moving content
3c00: 20 66 72 6f 6d 20 57 41 4c 20 74 6f 0a 2a 2a 20   from WAL to.** 
3c10: 64 61 74 61 62 61 73 65 20 22 62 61 63 6b 66 69  database "backfi
3c20: 6c 6c 69 6e 67 22 2e 29 20 20 54 68 65 20 6e 42  lling".)  The nB
3c30: 61 63 6b 66 69 6c 6c 20 6e 75 6d 62 65 72 20 69  ackfill number i
3c40: 73 20 6e 65 76 65 72 20 67 72 65 61 74 65 72 20  s never greater 
3c50: 74 68 61 6e 0a 2a 2a 20 57 61 6c 49 6e 64 65 78  than.** WalIndex
3c60: 48 64 72 2e 6d 78 46 72 61 6d 65 2e 20 20 6e 42  Hdr.mxFrame.  nB
3c70: 61 63 6b 66 69 6c 6c 20 63 61 6e 20 6f 6e 6c 79  ackfill can only
3c80: 20 62 65 20 69 6e 63 72 65 61 73 65 64 20 62 79   be increased by
3c90: 20 74 68 72 65 61 64 73 0a 2a 2a 20 68 6f 6c 64   threads.** hold
3ca0: 69 6e 67 20 74 68 65 20 57 41 4c 5f 43 4b 50 54  ing the WAL_CKPT
3cb0: 5f 4c 4f 43 4b 20 6c 6f 63 6b 20 28 77 68 69 63  _LOCK lock (whic
3cc0: 68 20 69 6e 63 6c 75 64 65 73 20 61 20 72 65 63  h includes a rec
3cd0: 6f 76 65 72 79 20 74 68 72 65 61 64 29 2e 0a 2a  overy thread)..*
3ce0: 2a 20 48 6f 77 65 76 65 72 2c 20 61 20 57 41 4c  * However, a WAL
3cf0: 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 74 68 72 65  _WRITE_LOCK thre
3d00: 61 64 20 63 61 6e 20 6d 6f 76 65 20 74 68 65 20  ad can move the 
3d10: 76 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b 66 69  value of nBackfi
3d20: 6c 6c 20 66 72 6f 6d 0a 2a 2a 20 6d 78 46 72 61  ll from.** mxFra
3d30: 6d 65 20 62 61 63 6b 20 74 6f 20 7a 65 72 6f 20  me back to zero 
3d40: 77 68 65 6e 20 74 68 65 20 57 41 4c 20 69 73 20  when the WAL is 
3d50: 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  reset..**.** The
3d60: 72 65 20 69 73 20 6f 6e 65 20 65 6e 74 72 79 20  re is one entry 
3d70: 69 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 66  in aReadMark[] f
3d80: 6f 72 20 65 61 63 68 20 72 65 61 64 65 72 20 6c  or each reader l
3d90: 6f 63 6b 2e 20 20 49 66 20 61 20 72 65 61 64 65  ock.  If a reade
3da0: 72 0a 2a 2a 20 68 6f 6c 64 73 20 72 65 61 64 2d  r.** holds read-
3db0: 6c 6f 63 6b 20 4b 2c 20 74 68 65 6e 20 74 68 65  lock K, then the
3dc0: 20 76 61 6c 75 65 20 69 6e 20 61 52 65 61 64 4d   value in aReadM
3dd0: 61 72 6b 5b 4b 5d 20 69 73 20 6e 6f 20 67 72 65  ark[K] is no gre
3de0: 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 74 68 65  ater than.** the
3df0: 20 6d 78 46 72 61 6d 65 20 66 6f 72 20 74 68 61   mxFrame for tha
3e00: 74 20 72 65 61 64 65 72 2e 20 20 54 68 65 20 76  t reader.  The v
3e10: 61 6c 75 65 20 52 45 41 44 4d 41 52 4b 5f 4e 4f  alue READMARK_NO
3e20: 54 5f 55 53 45 44 20 28 30 78 66 66 66 66 66 66  T_USED (0xffffff
3e30: 66 66 29 0a 2a 2a 20 66 6f 72 20 61 6e 79 20 61  ff).** for any a
3e40: 52 65 61 64 4d 61 72 6b 5b 5d 20 6d 65 61 6e 73  ReadMark[] means
3e50: 20 74 68 61 74 20 65 6e 74 72 79 20 69 73 20 75   that entry is u
3e60: 6e 75 73 65 64 2e 20 20 61 52 65 61 64 4d 61 72  nused.  aReadMar
3e70: 6b 5b 30 5d 20 69 73 20 0a 2a 2a 20 61 20 73 70  k[0] is .** a sp
3e80: 65 63 69 61 6c 20 63 61 73 65 3b 20 69 74 73 20  ecial case; its 
3e90: 76 61 6c 75 65 20 69 73 20 6e 65 76 65 72 20 75  value is never u
3ea0: 73 65 64 20 61 6e 64 20 69 74 20 65 78 69 73 74  sed and it exist
3eb0: 73 20 61 73 20 61 20 70 6c 61 63 65 2d 68 6f 6c  s as a place-hol
3ec0: 64 65 72 0a 2a 2a 20 74 6f 20 61 76 6f 69 64 20  der.** to avoid 
3ed0: 68 61 76 69 6e 67 20 74 6f 20 6f 66 66 73 65 74  having to offset
3ee0: 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 69 6e 64   aReadMark[] ind
3ef0: 65 78 73 20 62 79 20 6f 6e 65 2e 20 20 52 65 61  exs by one.  Rea
3f00: 64 65 72 73 20 68 6f 6c 64 69 6e 67 0a 2a 2a 20  ders holding.** 
3f10: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29  WAL_READ_LOCK(0)
3f20: 20 61 6c 77 61 79 73 20 69 67 6e 6f 72 65 20 74   always ignore t
3f30: 68 65 20 65 6e 74 69 72 65 20 57 41 4c 20 61 6e  he entire WAL an
3f40: 64 20 72 65 61 64 20 61 6c 6c 20 63 6f 6e 74 65  d read all conte
3f50: 6e 74 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20 66  nt.** directly f
3f60: 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73 65  rom the database
3f70: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c 75  ..**.** The valu
3f80: 65 20 6f 66 20 61 52 65 61 64 4d 61 72 6b 5b 4b  e of aReadMark[K
3f90: 5d 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63 68  ] may only be ch
3fa0: 61 6e 67 65 64 20 62 79 20 61 20 74 68 72 65 61  anged by a threa
3fb0: 64 20 74 68 61 74 0a 2a 2a 20 69 73 20 68 6f 6c  d that.** is hol
3fc0: 64 69 6e 67 20 61 6e 20 65 78 63 6c 75 73 69 76  ding an exclusiv
3fd0: 65 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52 45  e lock on WAL_RE
3fe0: 41 44 5f 4c 4f 43 4b 28 4b 29 2e 20 20 54 68 75  AD_LOCK(K).  Thu
3ff0: 73 2c 20 74 68 65 20 76 61 6c 75 65 20 6f 66 0a  s, the value of.
4000: 2a 2a 20 61 52 65 61 64 4d 61 72 6b 5b 4b 5d 20  ** aReadMark[K] 
4010: 63 61 6e 6e 6f 74 20 63 68 61 6e 67 65 64 20 77  cannot changed w
4020: 68 69 6c 65 20 74 68 65 72 65 20 69 73 20 61 20  hile there is a 
4030: 72 65 61 64 65 72 20 69 73 20 75 73 69 6e 67 20  reader is using 
4040: 74 68 61 74 20 6d 61 72 6b 0a 2a 2a 20 73 69 6e  that mark.** sin
4050: 63 65 20 74 68 65 20 72 65 61 64 65 72 20 77 69  ce the reader wi
4060: 6c 6c 20 62 65 20 68 6f 6c 64 69 6e 67 20 61 20  ll be holding a 
4070: 73 68 61 72 65 64 20 6c 6f 63 6b 20 6f 6e 20 57  shared lock on W
4080: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 4b 29 2e  AL_READ_LOCK(K).
4090: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b  .**.** The check
40a0: 70 6f 69 6e 74 65 72 20 6d 61 79 20 6f 6e 6c 79  pointer may only
40b0: 20 74 72 61 6e 73 66 65 72 20 66 72 61 6d 65 73   transfer frames
40c0: 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64 61 74   from WAL to dat
40d0: 61 62 61 73 65 20 77 68 65 72 65 0a 2a 2a 20 74  abase where.** t
40e0: 68 65 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 73  he frame numbers
40f0: 20 61 72 65 20 6c 65 73 73 20 74 68 61 6e 20 6f   are less than o
4100: 72 20 65 71 75 61 6c 20 74 6f 20 65 76 65 72 79  r equal to every
4110: 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 74 68 61   aReadMark[] tha
4120: 74 20 69 73 0a 2a 2a 20 69 6e 20 75 73 65 20 28  t is.** in use (
4130: 74 68 61 74 20 69 73 2c 20 65 76 65 72 79 20 61  that is, every a
4140: 52 65 61 64 4d 61 72 6b 5b 6a 5d 20 66 6f 72 20  ReadMark[j] for 
4150: 77 68 69 63 68 20 74 68 65 72 65 20 69 73 20 61  which there is a
4160: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a   corresponding.*
4170: 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  * WAL_READ_LOCK(
4180: 6a 29 29 2e 20 20 4e 65 77 20 72 65 61 64 65 72  j)).  New reader
4190: 73 20 28 75 73 75 61 6c 6c 79 29 20 70 69 63 6b  s (usually) pick
41a0: 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d   the aReadMark[]
41b0: 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 6c 61 72   with the.** lar
41c0: 67 65 73 74 20 76 61 6c 75 65 20 61 6e 64 20 77  gest value and w
41d0: 69 6c 6c 20 69 6e 63 72 65 61 73 65 20 61 6e 20  ill increase an 
41e0: 75 6e 75 73 65 64 20 61 52 65 61 64 4d 61 72 6b  unused aReadMark
41f0: 5b 5d 20 74 6f 20 6d 78 46 72 61 6d 65 20 69 66  [] to mxFrame if
4200: 20 74 68 65 72 65 0a 2a 2a 20 69 73 20 6e 6f 74   there.** is not
4210: 20 61 6c 72 65 61 64 79 20 61 6e 20 61 52 65 61   already an aRea
4220: 64 4d 61 72 6b 5b 5d 20 65 71 75 61 6c 20 74 6f  dMark[] equal to
4230: 20 6d 78 46 72 61 6d 65 2e 20 20 54 68 65 20 65   mxFrame.  The e
4240: 78 63 65 70 74 69 6f 6e 20 74 6f 20 74 68 65 0a  xception to the.
4250: 2a 2a 20 70 72 65 76 69 6f 75 73 20 73 65 6e 74  ** previous sent
4260: 65 6e 63 65 20 69 73 20 77 68 65 6e 20 6e 42 61  ence is when nBa
4270: 63 6b 66 69 6c 6c 20 65 71 75 61 6c 73 20 6d 78  ckfill equals mx
4280: 46 72 61 6d 65 20 28 6d 65 61 6e 69 6e 67 20 74  Frame (meaning t
4290: 68 61 74 20 65 76 65 72 79 74 68 69 6e 67 0a 2a  hat everything.*
42a0: 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 68 61 73  * in the WAL has
42b0: 20 62 65 65 6e 20 62 61 63 6b 66 69 6c 6c 65 64   been backfilled
42c0: 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
42d0: 73 65 29 20 74 68 65 6e 20 6e 65 77 20 72 65 61  se) then new rea
42e0: 64 65 72 73 0a 2a 2a 20 77 69 6c 6c 20 63 68 6f  ders.** will cho
42f0: 6f 73 65 20 61 52 65 61 64 4d 61 72 6b 5b 30 5d  ose aReadMark[0]
4300: 20 77 68 69 63 68 20 68 61 73 20 76 61 6c 75 65   which has value
4310: 20 30 20 61 6e 64 20 68 65 6e 63 65 20 73 75 63   0 and hence suc
4320: 68 20 72 65 61 64 65 72 20 77 69 6c 6c 0a 2a 2a  h reader will.**
4330: 20 67 65 74 20 61 6c 6c 20 74 68 65 69 72 20 61   get all their a
4340: 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72 65 63  ll content direc
4350: 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61 74  tly from the dat
4360: 61 62 61 73 65 20 66 69 6c 65 20 61 6e 64 20 69  abase file and i
4370: 67 6e 6f 72 65 20 0a 2a 2a 20 74 68 65 20 57 41  gnore .** the WA
4380: 4c 2e 0a 2a 2a 0a 2a 2a 20 57 72 69 74 65 72 73  L..**.** Writers
4390: 20 6e 6f 72 6d 61 6c 6c 79 20 61 70 70 65 6e 64   normally append
43a0: 20 6e 65 77 20 66 72 61 6d 65 73 20 74 6f 20 74   new frames to t
43b0: 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 57 41  he end of the WA
43c0: 4c 2e 20 20 48 6f 77 65 76 65 72 2c 0a 2a 2a 20  L.  However,.** 
43d0: 69 66 20 6e 42 61 63 6b 66 69 6c 6c 20 65 71 75  if nBackfill equ
43e0: 61 6c 73 20 6d 78 46 72 61 6d 65 20 28 6d 65 61  als mxFrame (mea
43f0: 6e 69 6e 67 20 74 68 61 74 20 61 6c 6c 20 57 41  ning that all WA
4400: 4c 20 63 6f 6e 74 65 6e 74 20 68 61 73 20 62 65  L content has be
4410: 65 6e 0a 2a 2a 20 77 72 69 74 74 65 6e 20 62 61  en.** written ba
4420: 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ck into the data
4430: 62 61 73 65 29 20 61 6e 64 20 69 66 20 6e 6f 20  base) and if no 
4440: 72 65 61 64 65 72 73 20 61 72 65 20 75 73 69 6e  readers are usin
4450: 67 20 74 68 65 20 57 41 4c 0a 2a 2a 20 28 69 6e  g the WAL.** (in
4460: 20 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 69 66   other words, if
4470: 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 57 41   there are no WA
4480: 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 20 77  L_READ_LOCK(i) w
4490: 68 65 72 65 20 69 3e 30 29 20 74 68 65 6e 0a 2a  here i>0) then.*
44a0: 2a 20 74 68 65 20 77 72 69 74 65 72 20 77 69 6c  * the writer wil
44b0: 6c 20 66 69 72 73 74 20 22 72 65 73 65 74 22 20  l first "reset" 
44c0: 74 68 65 20 57 41 4c 20 62 61 63 6b 20 74 6f 20  the WAL back to 
44d0: 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 61 6e  the beginning an
44e0: 64 20 73 74 61 72 74 0a 2a 2a 20 77 72 69 74 69  d start.** writi
44f0: 6e 67 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20 62  ng new content b
4500: 65 67 69 6e 6e 69 6e 67 20 61 74 20 66 72 61 6d  eginning at fram
4510: 65 20 31 2e 0a 2a 2a 0a 2a 2a 20 57 65 20 61 73  e 1..**.** We as
4520: 73 75 6d 65 20 74 68 61 74 20 33 32 2d 62 69 74  sume that 32-bit
4530: 20 6c 6f 61 64 73 20 61 72 65 20 61 74 6f 6d 69   loads are atomi
4540: 63 20 61 6e 64 20 73 6f 20 6e 6f 20 6c 6f 63 6b  c and so no lock
4550: 73 20 61 72 65 20 6e 65 65 64 65 64 20 69 6e 0a  s are needed in.
4560: 2a 2a 20 6f 72 64 65 72 20 74 6f 20 72 65 61 64  ** order to read
4570: 20 66 72 6f 6d 20 61 6e 79 20 61 52 65 61 64 4d   from any aReadM
4580: 61 72 6b 5b 5d 20 65 6e 74 72 69 65 73 2e 0a 2a  ark[] entries..*
4590: 2f 0a 73 74 72 75 63 74 20 57 61 6c 43 6b 70 74  /.struct WalCkpt
45a0: 49 6e 66 6f 20 7b 0a 20 20 75 33 32 20 6e 42 61  Info {.  u32 nBa
45b0: 63 6b 66 69 6c 6c 3b 20 20 20 20 20 20 20 20 20  ckfill;         
45c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
45d0: 65 72 20 6f 66 20 57 41 4c 20 66 72 61 6d 65 73  er of WAL frames
45e0: 20 62 61 63 6b 66 69 6c 6c 65 64 20 69 6e 74 6f   backfilled into
45f0: 20 44 42 20 2a 2f 0a 20 20 75 33 32 20 61 52 65   DB */.  u32 aRe
4600: 61 64 4d 61 72 6b 5b 57 41 4c 5f 4e 52 45 41 44  adMark[WAL_NREAD
4610: 45 52 5d 3b 20 20 20 20 20 2f 2a 20 52 65 61 64  ER];     /* Read
4620: 65 72 20 6d 61 72 6b 73 20 2a 2f 0a 7d 3b 0a 23  er marks */.};.#
4630: 64 65 66 69 6e 65 20 52 45 41 44 4d 41 52 4b 5f  define READMARK_
4640: 4e 4f 54 5f 55 53 45 44 20 20 30 78 66 66 66 66  NOT_USED  0xffff
4650: 66 66 66 66 0a 0a 0a 2f 2a 20 41 20 62 6c 6f 63  ffff.../* A bloc
4660: 6b 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 4c 4f  k of WALINDEX_LO
4670: 43 4b 5f 52 45 53 45 52 56 45 44 20 62 79 74 65  CK_RESERVED byte
4680: 73 20 62 65 67 69 6e 6e 69 6e 67 20 61 74 0a 2a  s beginning at.*
4690: 2a 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f  * WALINDEX_LOCK_
46a0: 4f 46 46 53 45 54 20 69 73 20 72 65 73 65 72 76  OFFSET is reserv
46b0: 65 64 20 66 6f 72 20 6c 6f 63 6b 73 2e 20 53 69  ed for locks. Si
46c0: 6e 63 65 20 73 6f 6d 65 20 73 79 73 74 65 6d 73  nce some systems
46d0: 0a 2a 2a 20 6f 6e 6c 79 20 73 75 70 70 6f 72 74  .** only support
46e0: 20 6d 61 6e 64 61 74 6f 72 79 20 66 69 6c 65 2d   mandatory file-
46f0: 6c 6f 63 6b 73 2c 20 77 65 20 64 6f 20 6e 6f 74  locks, we do not
4700: 20 72 65 61 64 20 6f 72 20 77 72 69 74 65 20 64   read or write d
4710: 61 74 61 0a 2a 2a 20 66 72 6f 6d 20 74 68 65 20  ata.** from the 
4720: 72 65 67 69 6f 6e 20 6f 66 20 74 68 65 20 66 69  region of the fi
4730: 6c 65 20 6f 6e 20 77 68 69 63 68 20 6c 6f 63 6b  le on which lock
4740: 73 20 61 72 65 20 61 70 70 6c 69 65 64 2e 0a 2a  s are applied..*
4750: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44  /.#define WALIND
4760: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 20  EX_LOCK_OFFSET  
4770: 20 28 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65   (sizeof(WalInde
4780: 78 48 64 72 29 2a 32 20 2b 20 73 69 7a 65 6f 66  xHdr)*2 + sizeof
4790: 28 57 61 6c 43 6b 70 74 49 6e 66 6f 29 29 0a 23  (WalCkptInfo)).#
47a0: 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58 5f  define WALINDEX_
47b0: 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 20 31 36  LOCK_RESERVED 16
47c0: 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45  .#define WALINDE
47d0: 58 5f 48 44 52 5f 53 49 5a 45 20 20 20 20 20 20  X_HDR_SIZE      
47e0: 28 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f  (WALINDEX_LOCK_O
47f0: 46 46 53 45 54 2b 57 41 4c 49 4e 44 45 58 5f 4c  FFSET+WALINDEX_L
4800: 4f 43 4b 5f 52 45 53 45 52 56 45 44 29 0a 0a 2f  OCK_RESERVED)../
4810: 2a 20 53 69 7a 65 20 6f 66 20 68 65 61 64 65 72  * Size of header
4820: 20 62 65 66 6f 72 65 20 65 61 63 68 20 66 72 61   before each fra
4830: 6d 65 20 69 6e 20 77 61 6c 20 2a 2f 0a 23 64 65  me in wal */.#de
4840: 66 69 6e 65 20 57 41 4c 5f 46 52 41 4d 45 5f 48  fine WAL_FRAME_H
4850: 44 52 53 49 5a 45 20 32 34 0a 0a 2f 2a 20 53 69  DRSIZE 24../* Si
4860: 7a 65 20 6f 66 20 77 72 69 74 65 20 61 68 65 61  ze of write ahea
4870: 64 20 6c 6f 67 20 68 65 61 64 65 72 2c 20 69 6e  d log header, in
4880: 63 6c 75 64 69 6e 67 20 63 68 65 63 6b 73 75 6d  cluding checksum
4890: 2e 20 2a 2f 0a 2f 2a 20 23 64 65 66 69 6e 65 20  . */./* #define 
48a0: 57 41 4c 5f 48 44 52 53 49 5a 45 20 32 34 20 2a  WAL_HDRSIZE 24 *
48b0: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48 44  /.#define WAL_HD
48c0: 52 53 49 5a 45 20 33 32 0a 0a 2f 2a 20 57 41 4c  RSIZE 32../* WAL
48d0: 20 6d 61 67 69 63 20 76 61 6c 75 65 2e 20 45 69   magic value. Ei
48e0: 74 68 65 72 20 74 68 69 73 20 76 61 6c 75 65 2c  ther this value,
48f0: 20 6f 72 20 74 68 65 20 73 61 6d 65 20 76 61 6c   or the same val
4900: 75 65 20 77 69 74 68 20 74 68 65 20 6c 65 61 73  ue with the leas
4910: 74 0a 2a 2a 20 73 69 67 6e 69 66 69 63 61 6e 74  t.** significant
4920: 20 62 69 74 20 61 6c 73 6f 20 73 65 74 20 28 57   bit also set (W
4930: 41 4c 5f 4d 41 47 49 43 20 7c 20 30 78 30 30 30  AL_MAGIC | 0x000
4940: 30 30 30 30 31 29 20 69 73 20 73 74 6f 72 65 64  00001) is stored
4950: 20 69 6e 20 33 32 2d 62 69 74 0a 2a 2a 20 62 69   in 32-bit.** bi
4960: 67 2d 65 6e 64 69 61 6e 20 66 6f 72 6d 61 74 20  g-endian format 
4970: 69 6e 20 74 68 65 20 66 69 72 73 74 20 34 20 62  in the first 4 b
4980: 79 74 65 73 20 6f 66 20 61 20 57 41 4c 20 66 69  ytes of a WAL fi
4990: 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  le..**.** If the
49a0: 20 4c 53 42 20 69 73 20 73 65 74 2c 20 74 68 65   LSB is set, the
49b0: 6e 20 74 68 65 20 63 68 65 63 6b 73 75 6d 73 20  n the checksums 
49c0: 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65 20 77  for each frame w
49d0: 69 74 68 69 6e 20 74 68 65 20 57 41 4c 0a 2a 2a  ithin the WAL.**
49e0: 20 66 69 6c 65 20 61 72 65 20 63 61 6c 63 75 6c   file are calcul
49f0: 61 74 65 64 20 62 79 20 74 72 65 61 74 69 6e 67  ated by treating
4a00: 20 61 6c 6c 20 64 61 74 61 20 61 73 20 61 6e 20   all data as an 
4a10: 61 72 72 61 79 20 6f 66 20 33 32 2d 62 69 74 20  array of 32-bit 
4a20: 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 77  .** big-endian w
4a30: 6f 72 64 73 2e 20 4f 74 68 65 72 77 69 73 65 2c  ords. Otherwise,
4a40: 20 74 68 65 79 20 61 72 65 20 63 61 6c 63 75 6c   they are calcul
4a50: 61 74 65 64 20 62 79 20 69 6e 74 65 72 70 72 65  ated by interpre
4a60: 74 69 6e 67 20 0a 2a 2a 20 61 6c 6c 20 64 61 74  ting .** all dat
4a70: 61 20 61 73 20 33 32 2d 62 69 74 20 6c 69 74 74  a as 32-bit litt
4a80: 6c 65 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73 2e  le-endian words.
4a90: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f  .*/.#define WAL_
4aa0: 4d 41 47 49 43 20 30 78 33 37 37 66 30 36 38 32  MAGIC 0x377f0682
4ab0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
4ac0: 68 65 20 6f 66 66 73 65 74 20 6f 66 20 66 72 61  he offset of fra
4ad0: 6d 65 20 69 46 72 61 6d 65 20 69 6e 20 74 68 65  me iFrame in the
4ae0: 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67   write-ahead log
4af0: 20 66 69 6c 65 2c 20 0a 2a 2a 20 61 73 73 75 6d   file, .** assum
4b00: 69 6e 67 20 61 20 64 61 74 61 62 61 73 65 20 70  ing a database p
4b10: 61 67 65 20 73 69 7a 65 20 6f 66 20 73 7a 50 61  age size of szPa
4b20: 67 65 20 62 79 74 65 73 2e 20 54 68 65 20 6f 66  ge bytes. The of
4b30: 66 73 65 74 20 72 65 74 75 72 6e 65 64 0a 2a 2a  fset returned.**
4b40: 20 69 73 20 74 6f 20 74 68 65 20 73 74 61 72 74   is to the start
4b50: 20 6f 66 20 74 68 65 20 77 72 69 74 65 2d 61 68   of the write-ah
4b60: 65 61 64 20 6c 6f 67 20 66 72 61 6d 65 2d 68 65  ead log frame-he
4b70: 61 64 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  ader..*/.#define
4b80: 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28   walFrameOffset(
4b90: 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29 20  iFrame, szPage) 
4ba0: 28 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (               
4bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4bc0: 5c 0a 20 20 57 41 4c 5f 48 44 52 53 49 5a 45 20  \.  WAL_HDRSIZE 
4bd0: 2b 20 28 28 69 46 72 61 6d 65 29 2d 31 29 2a 28  + ((iFrame)-1)*(
4be0: 69 36 34 29 28 28 73 7a 50 61 67 65 29 2b 57 41  i64)((szPage)+WA
4bf0: 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 29  L_FRAME_HDRSIZE)
4c00: 20 20 20 20 20 20 20 20 20 5c 0a 29 0a 0a 2f 2a           \.)../*
4c10: 0a 2a 2a 20 41 6e 20 6f 70 65 6e 20 77 72 69 74  .** An open writ
4c20: 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65  e-ahead log file
4c30: 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64 20   is represented 
4c40: 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f  by an instance o
4c50: 66 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c 6f 77 69  f the.** followi
4c60: 6e 67 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74  ng object..*/.st
4c70: 72 75 63 74 20 57 61 6c 20 7b 0a 20 20 73 71 6c  ruct Wal {.  sql
4c80: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 3b 20  ite3_vfs *pVfs; 
4c90: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 56          /* The V
4ca0: 46 53 20 75 73 65 64 20 74 6f 20 63 72 65 61 74  FS used to creat
4cb0: 65 20 70 44 62 46 64 20 2a 2f 0a 20 20 73 71 6c  e pDbFd */.  sql
4cc0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 44 62 46 64  ite3_file *pDbFd
4cd0: 3b 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20  ;       /* File 
4ce0: 68 61 6e 64 6c 65 20 66 6f 72 20 74 68 65 20 64  handle for the d
4cf0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a  atabase file */.
4d00: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
4d10: 70 57 61 6c 46 64 3b 20 20 20 20 20 20 2f 2a 20  pWalFd;      /* 
4d20: 46 69 6c 65 20 68 61 6e 64 6c 65 20 66 6f 72 20  File handle for 
4d30: 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33  WAL file */.  u3
4d40: 32 20 69 43 61 6c 6c 62 61 63 6b 3b 20 20 20 20  2 iCallback;    
4d50: 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75           /* Valu
4d60: 65 20 74 6f 20 70 61 73 73 20 74 6f 20 6c 6f 67  e to pass to log
4d70: 20 63 61 6c 6c 62 61 63 6b 20 28 6f 72 20 30 29   callback (or 0)
4d80: 20 2a 2f 0a 20 20 69 36 34 20 6d 78 57 61 6c 53   */.  i64 mxWalS
4d90: 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ize;            
4da0: 20 2f 2a 20 54 72 75 6e 63 61 74 65 20 57 41 4c   /* Truncate WAL
4db0: 20 74 6f 20 74 68 69 73 20 73 69 7a 65 20 75 70   to this size up
4dc0: 6f 6e 20 72 65 73 65 74 20 2a 2f 0a 20 20 69 6e  on reset */.  in
4dd0: 74 20 6e 57 69 44 61 74 61 3b 20 20 20 20 20 20  t nWiData;      
4de0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
4df0: 20 6f 66 20 61 72 72 61 79 20 61 70 57 69 44 61   of array apWiDa
4e00: 74 61 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 46 69  ta */.  int szFi
4e10: 72 73 74 42 6c 6f 63 6b 3b 20 20 20 20 20 20 20  rstBlock;       
4e20: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 66 69     /* Size of fi
4e30: 72 73 74 20 62 6c 6f 63 6b 20 77 72 69 74 74 65  rst block writte
4e40: 6e 20 74 6f 20 57 41 4c 20 66 69 6c 65 20 2a 2f  n to WAL file */
4e50: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20  .  volatile u32 
4e60: 2a 2a 61 70 57 69 44 61 74 61 3b 20 20 20 2f 2a  **apWiData;   /*
4e70: 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 61 6c 2d   Pointer to wal-
4e80: 69 6e 64 65 78 20 63 6f 6e 74 65 6e 74 20 69 6e  index content in
4e90: 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 75 33 32   memory */.  u32
4ea0: 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20   szPage;        
4eb0: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
4ec0: 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f  ase page size */
4ed0: 0a 20 20 69 31 36 20 72 65 61 64 4c 6f 63 6b 3b  .  i16 readLock;
4ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4ef0: 20 57 68 69 63 68 20 72 65 61 64 20 6c 6f 63 6b   Which read lock
4f00: 20 69 73 20 62 65 69 6e 67 20 68 65 6c 64 2e 20   is being held. 
4f10: 20 2d 31 20 66 6f 72 20 6e 6f 6e 65 20 2a 2f 0a   -1 for none */.
4f20: 20 20 75 38 20 73 79 6e 63 46 6c 61 67 73 3b 20    u8 syncFlags; 
4f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4f40: 46 6c 61 67 73 20 74 6f 20 75 73 65 20 74 6f 20  Flags to use to 
4f50: 73 79 6e 63 20 68 65 61 64 65 72 20 77 72 69 74  sync header writ
4f60: 65 73 20 2a 2f 0a 20 20 75 38 20 65 78 63 6c 75  es */.  u8 exclu
4f70: 73 69 76 65 4d 6f 64 65 3b 20 20 20 20 20 20 20  siveMode;       
4f80: 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69     /* Non-zero i
4f90: 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20  f connection is 
4fa0: 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f 64  in exclusive mod
4fb0: 65 20 2a 2f 0a 20 20 75 38 20 77 72 69 74 65 4c  e */.  u8 writeL
4fc0: 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ock;            
4fd0: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 20    /* True if in 
4fe0: 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74  a write transact
4ff0: 69 6f 6e 20 2a 2f 0a 20 20 75 38 20 63 6b 70 74  ion */.  u8 ckpt
5000: 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Lock;           
5010: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 68      /* True if h
5020: 6f 6c 64 69 6e 67 20 61 20 63 68 65 63 6b 70 6f  olding a checkpo
5030: 69 6e 74 20 6c 6f 63 6b 20 2a 2f 0a 20 20 75 38  int lock */.  u8
5040: 20 72 65 61 64 4f 6e 6c 79 3b 20 20 20 20 20 20   readOnly;      
5050: 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 5f           /* WAL_
5060: 52 44 57 52 2c 20 57 41 4c 5f 52 44 4f 4e 4c 59  RDWR, WAL_RDONLY
5070: 2c 20 6f 72 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  , or WAL_SHM_RDO
5080: 4e 4c 59 20 2a 2f 0a 20 20 75 38 20 74 72 75 6e  NLY */.  u8 trun
5090: 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 3b 20 20 20  cateOnCommit;   
50a0: 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 74      /* True to t
50b0: 72 75 6e 63 61 74 65 20 57 41 4c 20 66 69 6c 65  runcate WAL file
50c0: 20 6f 6e 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20   on commit */.  
50d0: 75 38 20 73 79 6e 63 48 65 61 64 65 72 3b 20 20  u8 syncHeader;  
50e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 73             /* Fs
50f0: 79 6e 63 20 74 68 65 20 57 41 4c 20 68 65 61 64  ync the WAL head
5100: 65 72 20 69 66 20 74 72 75 65 20 2a 2f 0a 20 20  er if true */.  
5110: 75 38 20 70 61 64 54 6f 53 65 63 74 6f 72 42 6f  u8 padToSectorBo
5120: 75 6e 64 61 72 79 3b 20 20 20 20 2f 2a 20 50 61  undary;    /* Pa
5130: 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 20 6f  d transactions o
5140: 75 74 20 74 6f 20 74 68 65 20 6e 65 78 74 20 73  ut to the next s
5150: 65 63 74 6f 72 20 2a 2f 0a 20 20 57 61 6c 49 6e  ector */.  WalIn
5160: 64 65 78 48 64 72 20 68 64 72 3b 20 20 20 20 20  dexHdr hdr;     
5170: 20 20 20 20 20 20 2f 2a 20 57 61 6c 2d 69 6e 64        /* Wal-ind
5180: 65 78 20 68 65 61 64 65 72 20 66 6f 72 20 63 75  ex header for cu
5190: 72 72 65 6e 74 20 74 72 61 6e 73 61 63 74 69 6f  rrent transactio
51a0: 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  n */.  const cha
51b0: 72 20 2a 7a 57 61 6c 4e 61 6d 65 3b 20 20 20 20  r *zWalName;    
51c0: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 57 41 4c    /* Name of WAL
51d0: 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32 20 6e   file */.  u32 n
51e0: 43 6b 70 74 3b 20 20 20 20 20 20 20 20 20 20 20  Ckpt;           
51f0: 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 70 6f        /* Checkpo
5200: 69 6e 74 20 73 65 71 75 65 6e 63 65 20 63 6f 75  int sequence cou
5210: 6e 74 65 72 20 69 6e 20 74 68 65 20 77 61 6c 2d  nter in the wal-
5220: 68 65 61 64 65 72 20 2a 2f 0a 23 69 66 64 65 66  header */.#ifdef
5230: 20 53 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20   SQLITE_DEBUG.  
5240: 75 38 20 6c 6f 63 6b 45 72 72 6f 72 3b 20 20 20  u8 lockError;   
5250: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
5260: 75 65 20 69 66 20 61 20 6c 6f 63 6b 69 6e 67 20  ue if a locking 
5270: 65 72 72 6f 72 20 68 61 73 20 6f 63 63 75 72 72  error has occurr
5280: 65 64 20 2a 2f 0a 23 65 6e 64 69 66 0a 7d 3b 0a  ed */.#endif.};.
5290: 0a 2f 2a 0a 2a 2a 20 43 61 6e 64 69 64 61 74 65  ./*.** Candidate
52a0: 20 76 61 6c 75 65 73 20 66 6f 72 20 57 61 6c 2e   values for Wal.
52b0: 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 2e 0a 2a  exclusiveMode..*
52c0: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 4e 4f  /.#define WAL_NO
52d0: 52 4d 41 4c 5f 4d 4f 44 45 20 20 20 20 20 30 0a  RMAL_MODE     0.
52e0: 23 64 65 66 69 6e 65 20 57 41 4c 5f 45 58 43 4c  #define WAL_EXCL
52f0: 55 53 49 56 45 5f 4d 4f 44 45 20 20 31 20 20 20  USIVE_MODE  1   
5300: 20 20 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48    .#define WAL_H
5310: 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 32  EAPMEMORY_MODE 2
5320: 0a 0a 2f 2a 0a 2a 2a 20 50 6f 73 73 69 62 6c 65  ../*.** Possible
5330: 20 76 61 6c 75 65 73 20 66 6f 72 20 57 41 4c 2e   values for WAL.
5340: 72 65 61 64 4f 6e 6c 79 0a 2a 2f 0a 23 64 65 66  readOnly.*/.#def
5350: 69 6e 65 20 57 41 4c 5f 52 44 57 52 20 20 20 20  ine WAL_RDWR    
5360: 20 20 20 20 30 20 20 20 20 2f 2a 20 4e 6f 72 6d      0    /* Norm
5370: 61 6c 20 72 65 61 64 2f 77 72 69 74 65 20 63 6f  al read/write co
5380: 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 23 64 65 66  nnection */.#def
5390: 69 6e 65 20 57 41 4c 5f 52 44 4f 4e 4c 59 20 20  ine WAL_RDONLY  
53a0: 20 20 20 20 31 20 20 20 20 2f 2a 20 54 68 65 20      1    /* The 
53b0: 57 41 4c 20 66 69 6c 65 20 69 73 20 72 65 61 64  WAL file is read
53c0: 6f 6e 6c 79 20 2a 2f 0a 23 64 65 66 69 6e 65 20  only */.#define 
53d0: 57 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 20 20  WAL_SHM_RDONLY  
53e0: 32 20 20 20 20 2f 2a 20 54 68 65 20 53 48 4d 20  2    /* The SHM 
53f0: 66 69 6c 65 20 69 73 20 72 65 61 64 6f 6e 6c 79  file is readonly
5400: 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20   */../*.** Each 
5410: 70 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d  page of the wal-
5420: 69 6e 64 65 78 20 6d 61 70 70 69 6e 67 20 63 6f  index mapping co
5430: 6e 74 61 69 6e 73 20 61 20 68 61 73 68 2d 74 61  ntains a hash-ta
5440: 62 6c 65 20 6d 61 64 65 20 75 70 20 6f 66 0a 2a  ble made up of.*
5450: 2a 20 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41  * an array of HA
5460: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 65 6c  SHTABLE_NSLOT el
5470: 65 6d 65 6e 74 73 20 6f 66 20 74 68 65 20 66 6f  ements of the fo
5480: 6c 6c 6f 77 69 6e 67 20 74 79 70 65 2e 0a 2a 2f  llowing type..*/
5490: 0a 74 79 70 65 64 65 66 20 75 31 36 20 68 74 5f  .typedef u16 ht_
54a0: 73 6c 6f 74 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  slot;../*.** Thi
54b0: 73 20 73 74 72 75 63 74 75 72 65 20 69 73 20 75  s structure is u
54c0: 73 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  sed to implement
54d0: 20 61 6e 20 69 74 65 72 61 74 6f 72 20 74 68 61   an iterator tha
54e0: 74 20 6c 6f 6f 70 73 20 74 68 72 6f 75 67 68 0a  t loops through.
54f0: 2a 2a 20 61 6c 6c 20 66 72 61 6d 65 73 20 69 6e  ** all frames in
5500: 20 74 68 65 20 57 41 4c 20 69 6e 20 64 61 74 61   the WAL in data
5510: 62 61 73 65 20 70 61 67 65 20 6f 72 64 65 72 2e  base page order.
5520: 20 57 68 65 72 65 20 74 77 6f 20 6f 72 20 6d 6f   Where two or mo
5530: 72 65 20 66 72 61 6d 65 73 0a 2a 2a 20 63 6f 72  re frames.** cor
5540: 72 65 73 70 6f 6e 64 20 74 6f 20 74 68 65 20 73  respond to the s
5550: 61 6d 65 20 64 61 74 61 62 61 73 65 20 70 61 67  ame database pag
5560: 65 2c 20 74 68 65 20 69 74 65 72 61 74 6f 72 20  e, the iterator 
5570: 76 69 73 69 74 73 20 6f 6e 6c 79 20 74 68 65 20  visits only the 
5580: 0a 2a 2a 20 66 72 61 6d 65 20 6d 6f 73 74 20 72  .** frame most r
5590: 65 63 65 6e 74 6c 79 20 77 72 69 74 74 65 6e 20  ecently written 
55a0: 74 6f 20 74 68 65 20 57 41 4c 20 28 69 6e 20 6f  to the WAL (in o
55b0: 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68 65 20  ther words, the 
55c0: 66 72 61 6d 65 20 77 69 74 68 0a 2a 2a 20 74 68  frame with.** th
55d0: 65 20 6c 61 72 67 65 73 74 20 69 6e 64 65 78 29  e largest index)
55e0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e 74 65  ..**.** The inte
55f0: 72 6e 61 6c 73 20 6f 66 20 74 68 69 73 20 73 74  rnals of this st
5600: 72 75 63 74 75 72 65 20 61 72 65 20 6f 6e 6c 79  ructure are only
5610: 20 61 63 63 65 73 73 65 64 20 62 79 3a 0a 2a 2a   accessed by:.**
5620: 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f  .**   walIterato
5630: 72 49 6e 69 74 28 29 20 2d 20 43 72 65 61 74 65  rInit() - Create
5640: 20 61 20 6e 65 77 20 69 74 65 72 61 74 6f 72 2c   a new iterator,
5650: 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f  .**   walIterato
5660: 72 4e 65 78 74 28 29 20 2d 20 53 74 65 70 20 61  rNext() - Step a
5670: 6e 20 69 74 65 72 61 74 6f 72 2c 0a 2a 2a 20 20  n iterator,.**  
5680: 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65   walIteratorFree
5690: 28 29 20 2d 20 46 72 65 65 20 61 6e 20 69 74 65  () - Free an ite
56a0: 72 61 74 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  rator..**.** Thi
56b0: 73 20 66 75 6e 63 74 69 6f 6e 61 6c 69 74 79 20  s functionality 
56c0: 69 73 20 75 73 65 64 20 62 79 20 74 68 65 20 63  is used by the c
56d0: 68 65 63 6b 70 6f 69 6e 74 20 63 6f 64 65 20 28  heckpoint code (
56e0: 73 65 65 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e  see walCheckpoin
56f0: 74 28 29 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  t())..*/.struct 
5700: 57 61 6c 49 74 65 72 61 74 6f 72 20 7b 0a 20 20  WalIterator {.  
5710: 69 6e 74 20 69 50 72 69 6f 72 3b 20 20 20 20 20  int iPrior;     
5720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5730: 2f 2a 20 4c 61 73 74 20 72 65 73 75 6c 74 20 72  /* Last result r
5740: 65 74 75 72 6e 65 64 20 66 72 6f 6d 20 74 68 65  eturned from the
5750: 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69   iterator */.  i
5760: 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20 20  nt nSegment;    
5770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5780: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72  * Number of entr
5790: 69 65 73 20 69 6e 20 61 53 65 67 6d 65 6e 74 5b  ies in aSegment[
57a0: 5d 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 57 61  ] */.  struct Wa
57b0: 6c 53 65 67 6d 65 6e 74 20 7b 0a 20 20 20 20 69  lSegment {.    i
57c0: 6e 74 20 69 4e 65 78 74 3b 20 20 20 20 20 20 20  nt iNext;       
57d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
57e0: 4e 65 78 74 20 73 6c 6f 74 20 69 6e 20 61 49 6e  Next slot in aIn
57f0: 64 65 78 5b 5d 20 6e 6f 74 20 79 65 74 20 72 65  dex[] not yet re
5800: 74 75 72 6e 65 64 20 2a 2f 0a 20 20 20 20 68 74  turned */.    ht
5810: 5f 73 6c 6f 74 20 2a 61 49 6e 64 65 78 3b 20 20  _slot *aIndex;  
5820: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
5830: 30 2c 20 69 31 2c 20 69 32 2e 2e 2e 20 73 75 63  0, i1, i2... suc
5840: 68 20 74 68 61 74 20 61 50 67 6e 6f 5b 69 4e 5d  h that aPgno[iN]
5850: 20 61 73 63 65 6e 64 20 2a 2f 0a 20 20 20 20 75   ascend */.    u
5860: 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20  32 *aPgno;      
5870: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5880: 41 72 72 61 79 20 6f 66 20 70 61 67 65 20 6e 75  Array of page nu
5890: 6d 62 65 72 73 2e 20 2a 2f 0a 20 20 20 20 69 6e  mbers. */.    in
58a0: 74 20 6e 45 6e 74 72 79 3b 20 20 20 20 20 20 20  t nEntry;       
58b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
58c0: 72 2e 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e  r. of entries in
58d0: 20 61 50 67 6e 6f 5b 5d 20 61 6e 64 20 61 49 6e   aPgno[] and aIn
58e0: 64 65 78 5b 5d 20 2a 2f 0a 20 20 20 20 69 6e 74  dex[] */.    int
58f0: 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20   iZero;         
5900: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
5910: 61 6d 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63  ame number assoc
5920: 69 61 74 65 64 20 77 69 74 68 20 61 50 67 6e 6f  iated with aPgno
5930: 5b 30 5d 20 2a 2f 0a 20 20 7d 20 61 53 65 67 6d  [0] */.  } aSegm
5940: 65 6e 74 5b 31 5d 3b 20 20 20 20 20 20 20 20 20  ent[1];         
5950: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20           /* One 
5960: 66 6f 72 20 65 76 65 72 79 20 33 32 4b 42 20 70  for every 32KB p
5970: 61 67 65 20 69 6e 20 74 68 65 20 77 61 6c 2d 69  age in the wal-i
5980: 6e 64 65 78 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  ndex */.};../*.*
5990: 2a 20 44 65 66 69 6e 65 20 74 68 65 20 70 61 72  * Define the par
59a0: 61 6d 65 74 65 72 73 20 6f 66 20 74 68 65 20 68  ameters of the h
59b0: 61 73 68 20 74 61 62 6c 65 73 20 69 6e 20 74 68  ash tables in th
59c0: 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65  e wal-index file
59d0: 2e 20 54 68 65 72 65 0a 2a 2a 20 69 73 20 61 20  . There.** is a 
59e0: 68 61 73 68 2d 74 61 62 6c 65 20 66 6f 6c 6c 6f  hash-table follo
59f0: 77 69 6e 67 20 65 76 65 72 79 20 48 41 53 48 54  wing every HASHT
5a00: 41 42 4c 45 5f 4e 50 41 47 45 20 70 61 67 65 20  ABLE_NPAGE page 
5a10: 6e 75 6d 62 65 72 73 20 69 6e 20 74 68 65 0a 2a  numbers in the.*
5a20: 2a 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2a 0a  * wal-index..**.
5a30: 2a 2a 20 43 68 61 6e 67 69 6e 67 20 61 6e 79 20  ** Changing any 
5a40: 6f 66 20 74 68 65 73 65 20 63 6f 6e 73 74 61 6e  of these constan
5a50: 74 73 20 77 69 6c 6c 20 61 6c 74 65 72 20 74 68  ts will alter th
5a60: 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 6f 72 6d  e wal-index form
5a70: 61 74 20 61 6e 64 0a 2a 2a 20 63 72 65 61 74 65  at and.** create
5a80: 20 69 6e 63 6f 6d 70 61 74 69 62 69 6c 69 74 69   incompatibiliti
5a90: 65 73 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 48  es..*/.#define H
5aa0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 20  ASHTABLE_NPAGE  
5ab0: 20 20 20 20 34 30 39 36 20 20 20 20 20 20 20 20      4096        
5ac0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 75 73 74           /* Must
5ad0: 20 62 65 20 70 6f 77 65 72 20 6f 66 20 32 20 2a   be power of 2 *
5ae0: 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48 54 41  /.#define HASHTA
5af0: 42 4c 45 5f 48 41 53 48 5f 31 20 20 20 20 20 33  BLE_HASH_1     3
5b00: 38 33 20 20 20 20 20 20 20 20 20 20 20 20 20 20  83              
5b10: 20 20 20 20 2f 2a 20 53 68 6f 75 6c 64 20 62 65      /* Should be
5b20: 20 70 72 69 6d 65 20 2a 2f 0a 23 64 65 66 69 6e   prime */.#defin
5b30: 65 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f  e HASHTABLE_NSLO
5b40: 54 20 20 20 20 20 20 28 48 41 53 48 54 41 42 4c  T      (HASHTABL
5b50: 45 5f 4e 50 41 47 45 2a 32 29 20 20 2f 2a 20 4d  E_NPAGE*2)  /* M
5b60: 75 73 74 20 62 65 20 61 20 70 6f 77 65 72 20 6f  ust be a power o
5b70: 66 20 32 20 2a 2f 0a 0a 2f 2a 20 0a 2a 2a 20 54  f 2 */../* .** T
5b80: 68 65 20 62 6c 6f 63 6b 20 6f 66 20 70 61 67 65  he block of page
5b90: 20 6e 75 6d 62 65 72 73 20 61 73 73 6f 63 69 61   numbers associa
5ba0: 74 65 64 20 77 69 74 68 20 74 68 65 20 66 69 72  ted with the fir
5bb0: 73 74 20 68 61 73 68 2d 74 61 62 6c 65 20 69 6e  st hash-table in
5bc0: 20 61 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20   a.** wal-index 
5bd0: 69 73 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20  is smaller than 
5be0: 75 73 75 61 6c 2e 20 54 68 69 73 20 69 73 20 73  usual. This is s
5bf0: 6f 20 74 68 61 74 20 74 68 65 72 65 20 69 73 20  o that there is 
5c00: 61 20 63 6f 6d 70 6c 65 74 65 0a 2a 2a 20 68 61  a complete.** ha
5c10: 73 68 2d 74 61 62 6c 65 20 6f 6e 20 65 61 63 68  sh-table on each
5c20: 20 61 6c 69 67 6e 65 64 20 33 32 4b 42 20 70 61   aligned 32KB pa
5c30: 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ge of the wal-in
5c40: 64 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  dex..*/.#define 
5c50: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
5c60: 4f 4e 45 20 20 28 48 41 53 48 54 41 42 4c 45 5f  ONE  (HASHTABLE_
5c70: 4e 50 41 47 45 20 2d 20 28 57 41 4c 49 4e 44 45  NPAGE - (WALINDE
5c80: 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f  X_HDR_SIZE/sizeo
5c90: 66 28 75 33 32 29 29 29 0a 0a 2f 2a 20 54 68 65  f(u32)))../* The
5ca0: 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 64 69   wal-index is di
5cb0: 76 69 64 65 64 20 69 6e 74 6f 20 70 61 67 65 73  vided into pages
5cc0: 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 50 47 53   of WALINDEX_PGS
5cd0: 5a 20 62 79 74 65 73 20 65 61 63 68 2e 20 2a 2f  Z bytes each. */
5ce0: 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45  .#define WALINDE
5cf0: 58 5f 50 47 53 5a 20 20 20 28 20 20 20 20 20 20  X_PGSZ   (      
5d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5d20: 20 20 20 5c 0a 20 20 20 20 73 69 7a 65 6f 66 28     \.    sizeof(
5d30: 68 74 5f 73 6c 6f 74 29 2a 48 41 53 48 54 41 42  ht_slot)*HASHTAB
5d40: 4c 45 5f 4e 53 4c 4f 54 20 2b 20 48 41 53 48 54  LE_NSLOT + HASHT
5d50: 41 42 4c 45 5f 4e 50 41 47 45 2a 73 69 7a 65 6f  ABLE_NPAGE*sizeo
5d60: 66 28 75 33 32 29 20 5c 0a 29 0a 0a 2f 2a 0a 2a  f(u32) \.)../*.*
5d70: 2a 20 4f 62 74 61 69 6e 20 61 20 70 6f 69 6e 74  * Obtain a point
5d80: 65 72 20 74 6f 20 74 68 65 20 69 50 61 67 65 27  er to the iPage'
5d90: 74 68 20 70 61 67 65 20 6f 66 20 74 68 65 20 77  th page of the w
5da0: 61 6c 2d 69 6e 64 65 78 2e 20 54 68 65 20 77 61  al-index. The wa
5db0: 6c 2d 69 6e 64 65 78 0a 2a 2a 20 69 73 20 62 72  l-index.** is br
5dc0: 6f 6b 65 6e 20 69 6e 74 6f 20 70 61 67 65 73 20  oken into pages 
5dd0: 6f 66 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a  of WALINDEX_PGSZ
5de0: 20 62 79 74 65 73 2e 20 57 61 6c 2d 69 6e 64 65   bytes. Wal-inde
5df0: 78 20 70 61 67 65 73 20 61 72 65 0a 2a 2a 20 6e  x pages are.** n
5e00: 75 6d 62 65 72 65 64 20 66 72 6f 6d 20 7a 65 72  umbered from zer
5e10: 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 69 73  o..**.** If this
5e20: 20 63 61 6c 6c 20 69 73 20 73 75 63 63 65 73 73   call is success
5e30: 66 75 6c 2c 20 2a 70 70 50 61 67 65 20 69 73 20  ful, *ppPage is 
5e40: 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  set to point to 
5e50: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a  the wal-index.**
5e60: 20 70 61 67 65 20 61 6e 64 20 53 51 4c 49 54 45   page and SQLITE
5e70: 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 2e  _OK is returned.
5e80: 20 49 66 20 61 6e 20 65 72 72 6f 72 20 28 61 6e   If an error (an
5e90: 20 4f 4f 4d 20 6f 72 20 56 46 53 20 65 72 72 6f   OOM or VFS erro
5ea0: 72 29 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 74 68  r) occurs,.** th
5eb0: 65 6e 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  en an SQLite err
5ec0: 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  or code is retur
5ed0: 6e 65 64 20 61 6e 64 20 2a 70 70 50 61 67 65 20  ned and *ppPage 
5ee0: 69 73 20 73 65 74 20 74 6f 20 30 2e 0a 2a 2f 0a  is set to 0..*/.
5ef0: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e  static int walIn
5f00: 64 65 78 50 61 67 65 28 57 61 6c 20 2a 70 57 61  dexPage(Wal *pWa
5f10: 6c 2c 20 69 6e 74 20 69 50 61 67 65 2c 20 76 6f  l, int iPage, vo
5f20: 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 70 70 50  latile u32 **ppP
5f30: 61 67 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  age){.  int rc =
5f40: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f   SQLITE_OK;..  /
5f50: 2a 20 45 6e 6c 61 72 67 65 20 74 68 65 20 70 57  * Enlarge the pW
5f60: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 5d 20 61  al->apWiData[] a
5f70: 72 72 61 79 20 69 66 20 72 65 71 75 69 72 65 64  rray if required
5f80: 20 2a 2f 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e   */.  if( pWal->
5f90: 6e 57 69 44 61 74 61 3c 3d 69 50 61 67 65 20 29  nWiData<=iPage )
5fa0: 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20  {.    int nByte 
5fb0: 3d 20 73 69 7a 65 6f 66 28 75 33 32 2a 29 2a 28  = sizeof(u32*)*(
5fc0: 69 50 61 67 65 2b 31 29 3b 0a 20 20 20 20 76 6f  iPage+1);.    vo
5fd0: 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 61 70 4e  latile u32 **apN
5fe0: 65 77 3b 0a 20 20 20 20 61 70 4e 65 77 20 3d 20  ew;.    apNew = 
5ff0: 28 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a  (volatile u32 **
6000: 29 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63  )sqlite3_realloc
6010: 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d 3e 61  ((void *)pWal->a
6020: 70 57 69 44 61 74 61 2c 20 6e 42 79 74 65 29 3b  pWiData, nByte);
6030: 0a 20 20 20 20 69 66 28 20 21 61 70 4e 65 77 20  .    if( !apNew 
6040: 29 7b 0a 20 20 20 20 20 20 2a 70 70 50 61 67 65  ){.      *ppPage
6050: 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 65 74 75   = 0;.      retu
6060: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
6070: 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65  .    }.    memse
6080: 74 28 28 76 6f 69 64 2a 29 26 61 70 4e 65 77 5b  t((void*)&apNew[
6090: 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 5d 2c 20  pWal->nWiData], 
60a0: 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20 73 69  0,.           si
60b0: 7a 65 6f 66 28 75 33 32 2a 29 2a 28 69 50 61 67  zeof(u32*)*(iPag
60c0: 65 2b 31 2d 70 57 61 6c 2d 3e 6e 57 69 44 61 74  e+1-pWal->nWiDat
60d0: 61 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 61  a));.    pWal->a
60e0: 70 57 69 44 61 74 61 20 3d 20 61 70 4e 65 77 3b  pWiData = apNew;
60f0: 0a 20 20 20 20 70 57 61 6c 2d 3e 6e 57 69 44 61  .    pWal->nWiDa
6100: 74 61 20 3d 20 69 50 61 67 65 2b 31 3b 0a 20 20  ta = iPage+1;.  
6110: 7d 0a 0a 20 20 2f 2a 20 52 65 71 75 65 73 74 20  }..  /* Request 
6120: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65  a pointer to the
6130: 20 72 65 71 75 69 72 65 64 20 70 61 67 65 20 66   required page f
6140: 72 6f 6d 20 74 68 65 20 56 46 53 20 2a 2f 0a 20  rom the VFS */. 
6150: 20 69 66 28 20 70 57 61 6c 2d 3e 61 70 57 69 44   if( pWal->apWiD
6160: 61 74 61 5b 69 50 61 67 65 5d 3d 3d 30 20 29 7b  ata[iPage]==0 ){
6170: 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 65  .    if( pWal->e
6180: 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41  xclusiveMode==WA
6190: 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44  L_HEAPMEMORY_MOD
61a0: 45 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d  E ){.      pWal-
61b0: 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d  >apWiData[iPage]
61c0: 20 3d 20 28 75 33 32 20 76 6f 6c 61 74 69 6c 65   = (u32 volatile
61d0: 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63   *)sqlite3Malloc
61e0: 5a 65 72 6f 28 57 41 4c 49 4e 44 45 58 5f 50 47  Zero(WALINDEX_PG
61f0: 53 5a 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21  SZ);.      if( !
6200: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69  pWal->apWiData[i
6210: 50 61 67 65 5d 20 29 20 72 63 20 3d 20 53 51 4c  Page] ) rc = SQL
6220: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
6230: 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d  else{.      rc =
6240: 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4d 61 70   sqlite3OsShmMap
6250: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 50  (pWal->pDbFd, iP
6260: 61 67 65 2c 20 57 41 4c 49 4e 44 45 58 5f 50 47  age, WALINDEX_PG
6270: 53 5a 2c 20 0a 20 20 20 20 20 20 20 20 20 20 70  SZ, .          p
6280: 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 2c 20  Wal->writeLock, 
6290: 28 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a  (void volatile *
62a0: 2a 29 26 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  *)&pWal->apWiDat
62b0: 61 5b 69 50 61 67 65 5d 0a 20 20 20 20 20 20 29  a[iPage].      )
62c0: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
62d0: 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 20  SQLITE_READONLY 
62e0: 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d  ){.        pWal-
62f0: 3e 72 65 61 64 4f 6e 6c 79 20 7c 3d 20 57 41 4c  >readOnly |= WAL
6300: 5f 53 48 4d 5f 52 44 4f 4e 4c 59 3b 0a 20 20 20  _SHM_RDONLY;.   
6310: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
6320: 5f 4f 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  _OK;.      }.   
6330: 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 50 61 67   }.  }..  *ppPag
6340: 65 20 3d 20 70 57 61 6c 2d 3e 61 70 57 69 44 61  e = pWal->apWiDa
6350: 74 61 5b 69 50 61 67 65 5d 3b 0a 20 20 61 73 73  ta[iPage];.  ass
6360: 65 72 74 28 20 69 50 61 67 65 3d 3d 30 20 7c 7c  ert( iPage==0 ||
6370: 20 2a 70 70 50 61 67 65 20 7c 7c 20 72 63 21 3d   *ppPage || rc!=
6380: 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72  SQLITE_OK );.  r
6390: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
63a0: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  ** Return a poin
63b0: 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c 43 6b  ter to the WalCk
63c0: 70 74 49 6e 66 6f 20 73 74 72 75 63 74 75 72 65  ptInfo structure
63d0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
63e0: 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c  x..*/.static vol
63f0: 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66  atile WalCkptInf
6400: 6f 20 2a 77 61 6c 43 6b 70 74 49 6e 66 6f 28 57  o *walCkptInfo(W
6410: 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73  al *pWal){.  ass
6420: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
6430: 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70  ta>0 && pWal->ap
6440: 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72  WiData[0] );.  r
6450: 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20  eturn (volatile 
6460: 57 61 6c 43 6b 70 74 49 6e 66 6f 2a 29 26 28 70  WalCkptInfo*)&(p
6470: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
6480: 5b 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78  [sizeof(WalIndex
6490: 48 64 72 29 2f 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a  Hdr)/2]);.}../*.
64a0: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  ** Return a poin
64b0: 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c 49 6e  ter to the WalIn
64c0: 64 65 78 48 64 72 20 73 74 72 75 63 74 75 72 65  dexHdr structure
64d0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
64e0: 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c  x..*/.static vol
64f0: 61 74 69 6c 65 20 57 61 6c 49 6e 64 65 78 48 64  atile WalIndexHd
6500: 72 20 2a 77 61 6c 49 6e 64 65 78 48 64 72 28 57  r *walIndexHdr(W
6510: 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73  al *pWal){.  ass
6520: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
6530: 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70  ta>0 && pWal->ap
6540: 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72  WiData[0] );.  r
6550: 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20  eturn (volatile 
6560: 57 61 6c 49 6e 64 65 78 48 64 72 2a 29 70 57 61  WalIndexHdr*)pWa
6570: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 3b 0a  l->apWiData[0];.
6580: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61 72 67  }../*.** The arg
6590: 75 6d 65 6e 74 20 74 6f 20 74 68 69 73 20 6d 61  ument to this ma
65a0: 63 72 6f 20 6d 75 73 74 20 62 65 20 6f 66 20 74  cro must be of t
65b0: 79 70 65 20 75 33 32 2e 20 4f 6e 20 61 20 6c 69  ype u32. On a li
65c0: 74 74 6c 65 2d 65 6e 64 69 61 6e 0a 2a 2a 20 61  ttle-endian.** a
65d0: 72 63 68 69 74 65 63 74 75 72 65 2c 20 69 74 20  rchitecture, it 
65e0: 72 65 74 75 72 6e 73 20 74 68 65 20 75 33 32 20  returns the u32 
65f0: 76 61 6c 75 65 20 74 68 61 74 20 72 65 73 75 6c  value that resul
6600: 74 73 20 66 72 6f 6d 20 69 6e 74 65 72 70 72 65  ts from interpre
6610: 74 69 6e 67 0a 2a 2a 20 74 68 65 20 34 20 62 79  ting.** the 4 by
6620: 74 65 73 20 61 73 20 61 20 62 69 67 2d 65 6e 64  tes as a big-end
6630: 69 61 6e 20 76 61 6c 75 65 2e 20 4f 6e 20 61 20  ian value. On a 
6640: 62 69 67 2d 65 6e 64 69 61 6e 20 61 72 63 68 69  big-endian archi
6650: 74 65 63 74 75 72 65 2c 20 69 74 0a 2a 2a 20 72  tecture, it.** r
6660: 65 74 75 72 6e 73 20 74 68 65 20 76 61 6c 75 65  eturns the value
6670: 20 74 68 61 74 20 77 6f 75 6c 64 20 62 65 20 70   that would be p
6680: 72 6f 64 75 63 65 64 20 62 79 20 69 6e 74 65 70  roduced by intep
6690: 72 65 74 69 6e 67 20 74 68 65 20 34 20 62 79 74  reting the 4 byt
66a0: 65 73 0a 2a 2a 20 6f 66 20 74 68 65 20 69 6e 70  es.** of the inp
66b0: 75 74 20 76 61 6c 75 65 20 61 73 20 61 20 6c 69  ut value as a li
66c0: 74 74 6c 65 2d 65 6e 64 69 61 6e 20 69 6e 74 65  ttle-endian inte
66d0: 67 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  ger..*/.#define 
66e0: 42 59 54 45 53 57 41 50 33 32 28 78 29 20 28 20  BYTESWAP32(x) ( 
66f0: 5c 0a 20 20 20 20 28 28 28 78 29 26 30 78 30 30  \.    (((x)&0x00
6700: 30 30 30 30 46 46 29 3c 3c 32 34 29 20 2b 20 28  0000FF)<<24) + (
6710: 28 28 78 29 26 30 78 30 30 30 30 46 46 30 30 29  ((x)&0x0000FF00)
6720: 3c 3c 38 29 20 20 5c 0a 20 20 2b 20 28 28 28 78  <<8)  \.  + (((x
6730: 29 26 30 78 30 30 46 46 30 30 30 30 29 3e 3e 38  )&0x00FF0000)>>8
6740: 29 20 20 2b 20 28 28 28 78 29 26 30 78 46 46 30  )  + (((x)&0xFF0
6750: 30 30 30 30 30 29 3e 3e 32 34 29 20 5c 0a 29 0a  00000)>>24) \.).
6760: 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20  ./*.** Generate 
6770: 6f 72 20 65 78 74 65 6e 64 20 61 6e 20 38 20 62  or extend an 8 b
6780: 79 74 65 20 63 68 65 63 6b 73 75 6d 20 62 61 73  yte checksum bas
6790: 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 20 69  ed on the data i
67a0: 6e 20 0a 2a 2a 20 61 72 72 61 79 20 61 42 79 74  n .** array aByt
67b0: 65 5b 5d 20 61 6e 64 20 74 68 65 20 69 6e 69 74  e[] and the init
67c0: 69 61 6c 20 76 61 6c 75 65 73 20 6f 66 20 61 49  ial values of aI
67d0: 6e 5b 30 5d 20 61 6e 64 20 61 49 6e 5b 31 5d 20  n[0] and aIn[1] 
67e0: 28 6f 72 0a 2a 2a 20 69 6e 69 74 69 61 6c 20 76  (or.** initial v
67f0: 61 6c 75 65 73 20 6f 66 20 30 20 61 6e 64 20 30  alues of 0 and 0
6800: 20 69 66 20 61 49 6e 3d 3d 4e 55 4c 4c 29 2e 0a   if aIn==NULL)..
6810: 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b 73  **.** The checks
6820: 75 6d 20 69 73 20 77 72 69 74 74 65 6e 20 62 61  um is written ba
6830: 63 6b 20 69 6e 74 6f 20 61 4f 75 74 5b 5d 20 62  ck into aOut[] b
6840: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
6850: 0a 2a 2a 0a 2a 2a 20 6e 42 79 74 65 20 6d 75 73  .**.** nByte mus
6860: 74 20 62 65 20 61 20 70 6f 73 69 74 69 76 65 20  t be a positive 
6870: 6d 75 6c 74 69 70 6c 65 20 6f 66 20 38 2e 0a 2a  multiple of 8..*
6880: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61  /.static void wa
6890: 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28 0a  lChecksumBytes(.
68a0: 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73 75    int nativeCksu
68b0: 6d 2c 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e  m, /* True for n
68c0: 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64 65 72  ative byte-order
68d0: 2c 20 66 61 6c 73 65 20 66 6f 72 20 6e 6f 6e 2d  , false for non-
68e0: 6e 61 74 69 76 65 20 2a 2f 0a 20 20 75 38 20 2a  native */.  u8 *
68f0: 61 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  a,           /* 
6900: 43 6f 6e 74 65 6e 74 20 74 6f 20 62 65 20 63 68  Content to be ch
6910: 65 63 6b 73 75 6d 6d 65 64 20 2a 2f 0a 20 20 69  ecksummed */.  i
6920: 6e 74 20 6e 42 79 74 65 2c 20 20 20 20 20 20 20  nt nByte,       
6930: 2f 2a 20 42 79 74 65 73 20 6f 66 20 63 6f 6e 74  /* Bytes of cont
6940: 65 6e 74 20 69 6e 20 61 5b 5d 2e 20 20 4d 75 73  ent in a[].  Mus
6950: 74 20 62 65 20 61 20 6d 75 6c 74 69 70 6c 65 20  t be a multiple 
6960: 6f 66 20 38 2e 20 2a 2f 0a 20 20 63 6f 6e 73 74  of 8. */.  const
6970: 20 75 33 32 20 2a 61 49 6e 2c 20 20 2f 2a 20 49   u32 *aIn,  /* I
6980: 6e 69 74 69 61 6c 20 63 68 65 63 6b 73 75 6d 20  nitial checksum 
6990: 76 61 6c 75 65 20 69 6e 70 75 74 20 2a 2f 0a 20  value input */. 
69a0: 20 75 33 32 20 2a 61 4f 75 74 20 20 20 20 20 20   u32 *aOut      
69b0: 20 20 2f 2a 20 4f 55 54 3a 20 46 69 6e 61 6c 20    /* OUT: Final 
69c0: 63 68 65 63 6b 73 75 6d 20 76 61 6c 75 65 20 6f  checksum value o
69d0: 75 74 70 75 74 20 2a 2f 0a 29 7b 0a 20 20 75 33  utput */.){.  u3
69e0: 32 20 73 31 2c 20 73 32 3b 0a 20 20 75 33 32 20  2 s1, s2;.  u32 
69f0: 2a 61 44 61 74 61 20 3d 20 28 75 33 32 20 2a 29  *aData = (u32 *)
6a00: 61 3b 0a 20 20 75 33 32 20 2a 61 45 6e 64 20 3d  a;.  u32 *aEnd =
6a10: 20 28 75 33 32 20 2a 29 26 61 5b 6e 42 79 74 65   (u32 *)&a[nByte
6a20: 5d 3b 0a 0a 20 20 69 66 28 20 61 49 6e 20 29 7b  ];..  if( aIn ){
6a30: 0a 20 20 20 20 73 31 20 3d 20 61 49 6e 5b 30 5d  .    s1 = aIn[0]
6a40: 3b 0a 20 20 20 20 73 32 20 3d 20 61 49 6e 5b 31  ;.    s2 = aIn[1
6a50: 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  ];.  }else{.    
6a60: 73 31 20 3d 20 73 32 20 3d 20 30 3b 0a 20 20 7d  s1 = s2 = 0;.  }
6a70: 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 42 79 74  ..  assert( nByt
6a80: 65 3e 3d 38 20 29 3b 0a 20 20 61 73 73 65 72 74  e>=8 );.  assert
6a90: 28 20 28 6e 42 79 74 65 26 30 78 30 30 30 30 30  ( (nByte&0x00000
6aa0: 30 30 37 29 3d 3d 30 20 29 3b 0a 0a 20 20 69 66  007)==0 );..  if
6ab0: 28 20 6e 61 74 69 76 65 43 6b 73 75 6d 20 29 7b  ( nativeCksum ){
6ac0: 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 20  .    do {.      
6ad0: 73 31 20 2b 3d 20 2a 61 44 61 74 61 2b 2b 20 2b  s1 += *aData++ +
6ae0: 20 73 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d   s2;.      s2 +=
6af0: 20 2a 61 44 61 74 61 2b 2b 20 2b 20 73 31 3b 0a   *aData++ + s1;.
6b00: 20 20 20 20 7d 77 68 69 6c 65 28 20 61 44 61 74      }while( aDat
6b10: 61 3c 61 45 6e 64 20 29 3b 0a 20 20 7d 65 6c 73  a<aEnd );.  }els
6b20: 65 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20  e{.    do {.    
6b30: 20 20 73 31 20 2b 3d 20 42 59 54 45 53 57 41 50    s1 += BYTESWAP
6b40: 33 32 28 61 44 61 74 61 5b 30 5d 29 20 2b 20 73  32(aData[0]) + s
6b50: 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d 20 42  2;.      s2 += B
6b60: 59 54 45 53 57 41 50 33 32 28 61 44 61 74 61 5b  YTESWAP32(aData[
6b70: 31 5d 29 20 2b 20 73 31 3b 0a 20 20 20 20 20 20  1]) + s1;.      
6b80: 61 44 61 74 61 20 2b 3d 20 32 3b 0a 20 20 20 20  aData += 2;.    
6b90: 7d 77 68 69 6c 65 28 20 61 44 61 74 61 3c 61 45  }while( aData<aE
6ba0: 6e 64 20 29 3b 0a 20 20 7d 0a 0a 20 20 61 4f 75  nd );.  }..  aOu
6bb0: 74 5b 30 5d 20 3d 20 73 31 3b 0a 20 20 61 4f 75  t[0] = s1;.  aOu
6bc0: 74 5b 31 5d 20 3d 20 73 32 3b 0a 7d 0a 0a 73 74  t[1] = s2;.}..st
6bd0: 61 74 69 63 20 76 6f 69 64 20 77 61 6c 53 68 6d  atic void walShm
6be0: 42 61 72 72 69 65 72 28 57 61 6c 20 2a 70 57 61  Barrier(Wal *pWa
6bf0: 6c 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  l){.  if( pWal->
6c00: 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 21 3d 57  exclusiveMode!=W
6c10: 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f  AL_HEAPMEMORY_MO
6c20: 44 45 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  DE ){.    sqlite
6c30: 33 4f 73 53 68 6d 42 61 72 72 69 65 72 28 70 57  3OsShmBarrier(pW
6c40: 61 6c 2d 3e 70 44 62 46 64 29 3b 0a 20 20 7d 0a  al->pDbFd);.  }.
6c50: 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74  }../*.** Write t
6c60: 68 65 20 68 65 61 64 65 72 20 69 6e 66 6f 72 6d  he header inform
6c70: 61 74 69 6f 6e 20 69 6e 20 70 57 61 6c 2d 3e 68  ation in pWal->h
6c80: 64 72 20 69 6e 74 6f 20 74 68 65 20 77 61 6c 2d  dr into the wal-
6c90: 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  index..**.** The
6ca0: 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20 70 57 61   checksum on pWa
6cb0: 6c 2d 3e 68 64 72 20 69 73 20 75 70 64 61 74 65  l->hdr is update
6cc0: 64 20 62 65 66 6f 72 65 20 69 74 20 69 73 20 77  d before it is w
6cd0: 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69  ritten..*/.stati
6ce0: 63 20 76 6f 69 64 20 77 61 6c 49 6e 64 65 78 57  c void walIndexW
6cf0: 72 69 74 65 48 64 72 28 57 61 6c 20 2a 70 57 61  riteHdr(Wal *pWa
6d00: 6c 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57  l){.  volatile W
6d10: 61 6c 49 6e 64 65 78 48 64 72 20 2a 61 48 64 72  alIndexHdr *aHdr
6d20: 20 3d 20 77 61 6c 49 6e 64 65 78 48 64 72 28 70   = walIndexHdr(p
6d30: 57 61 6c 29 3b 0a 20 20 63 6f 6e 73 74 20 69 6e  Wal);.  const in
6d40: 74 20 6e 43 6b 73 75 6d 20 3d 20 6f 66 66 73 65  t nCksum = offse
6d50: 74 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 2c  tof(WalIndexHdr,
6d60: 20 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 61 73 73   aCksum);..  ass
6d70: 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65  ert( pWal->write
6d80: 4c 6f 63 6b 20 29 3b 0a 20 20 70 57 61 6c 2d 3e  Lock );.  pWal->
6d90: 68 64 72 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a  hdr.isInit = 1;.
6da0: 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56 65 72    pWal->hdr.iVer
6db0: 73 69 6f 6e 20 3d 20 57 41 4c 49 4e 44 45 58 5f  sion = WALINDEX_
6dc0: 4d 41 58 5f 56 45 52 53 49 4f 4e 3b 0a 20 20 77  MAX_VERSION;.  w
6dd0: 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
6de0: 31 2c 20 28 75 38 2a 29 26 70 57 61 6c 2d 3e 68  1, (u8*)&pWal->h
6df0: 64 72 2c 20 6e 43 6b 73 75 6d 2c 20 30 2c 20 70  dr, nCksum, 0, p
6e00: 57 61 6c 2d 3e 68 64 72 2e 61 43 6b 73 75 6d 29  Wal->hdr.aCksum)
6e10: 3b 0a 20 20 6d 65 6d 63 70 79 28 28 76 6f 69 64  ;.  memcpy((void
6e20: 20 2a 29 26 61 48 64 72 5b 31 5d 2c 20 28 76 6f   *)&aHdr[1], (vo
6e30: 69 64 20 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c  id *)&pWal->hdr,
6e40: 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
6e50: 48 64 72 29 29 3b 0a 20 20 77 61 6c 53 68 6d 42  Hdr));.  walShmB
6e60: 61 72 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20  arrier(pWal);.  
6e70: 6d 65 6d 63 70 79 28 28 76 6f 69 64 20 2a 29 26  memcpy((void *)&
6e80: 61 48 64 72 5b 30 5d 2c 20 28 76 6f 69 64 20 2a  aHdr[0], (void *
6e90: 29 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69 7a  )&pWal->hdr, siz
6ea0: 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29  eof(WalIndexHdr)
6eb0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  );.}../*.** This
6ec0: 20 66 75 6e 63 74 69 6f 6e 20 65 6e 63 6f 64 65   function encode
6ed0: 73 20 61 20 73 69 6e 67 6c 65 20 66 72 61 6d 65  s a single frame
6ee0: 20 68 65 61 64 65 72 20 61 6e 64 20 77 72 69 74   header and writ
6ef0: 65 73 20 69 74 20 74 6f 20 61 20 62 75 66 66 65  es it to a buffe
6f00: 72 0a 2a 2a 20 73 75 70 70 6c 69 65 64 20 62 79  r.** supplied by
6f10: 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 41 20 66   the caller. A f
6f20: 72 61 6d 65 2d 68 65 61 64 65 72 20 69 73 20 6d  rame-header is m
6f30: 61 64 65 20 75 70 20 6f 66 20 61 20 73 65 72 69  ade up of a seri
6f40: 65 73 20 6f 66 20 0a 2a 2a 20 34 2d 62 79 74 65  es of .** 4-byte
6f50: 20 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65   big-endian inte
6f60: 67 65 72 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73  gers, as follows
6f70: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 30 3a 20 50  :.**.**     0: P
6f80: 61 67 65 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20  age number..**  
6f90: 20 20 20 34 3a 20 46 6f 72 20 63 6f 6d 6d 69 74     4: For commit
6fa0: 20 72 65 63 6f 72 64 73 2c 20 74 68 65 20 73 69   records, the si
6fb0: 7a 65 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  ze of the databa
6fc0: 73 65 20 69 6d 61 67 65 20 69 6e 20 70 61 67 65  se image in page
6fd0: 73 20 0a 2a 2a 20 20 20 20 20 20 20 20 61 66 74  s .**        aft
6fe0: 65 72 20 74 68 65 20 63 6f 6d 6d 69 74 2e 20 46  er the commit. F
6ff0: 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20 72 65 63  or all other rec
7000: 6f 72 64 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20  ords, zero..**  
7010: 20 20 20 38 3a 20 53 61 6c 74 2d 31 20 28 63 6f     8: Salt-1 (co
7020: 70 69 65 64 20 66 72 6f 6d 20 74 68 65 20 77 61  pied from the wa
7030: 6c 2d 68 65 61 64 65 72 29 0a 2a 2a 20 20 20 20  l-header).**    
7040: 31 32 3a 20 53 61 6c 74 2d 32 20 28 63 6f 70 69  12: Salt-2 (copi
7050: 65 64 20 66 72 6f 6d 20 74 68 65 20 77 61 6c 2d  ed from the wal-
7060: 68 65 61 64 65 72 29 0a 2a 2a 20 20 20 20 31 36  header).**    16
7070: 3a 20 43 68 65 63 6b 73 75 6d 2d 31 2e 0a 2a 2a  : Checksum-1..**
7080: 20 20 20 20 32 30 3a 20 43 68 65 63 6b 73 75 6d      20: Checksum
7090: 2d 32 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  -2..*/.static vo
70a0: 69 64 20 77 61 6c 45 6e 63 6f 64 65 46 72 61 6d  id walEncodeFram
70b0: 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20  e(.  Wal *pWal, 
70c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
70d0: 20 20 20 20 20 2f 2a 20 54 68 65 20 77 72 69 74       /* The writ
70e0: 65 2d 61 68 65 61 64 20 6c 6f 67 20 2a 2f 0a 20  e-ahead log */. 
70f0: 20 75 33 32 20 69 50 61 67 65 2c 20 20 20 20 20   u32 iPage,     
7100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7110: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67   /* Database pag
7120: 65 20 6e 75 6d 62 65 72 20 66 6f 72 20 66 72 61  e number for fra
7130: 6d 65 20 2a 2f 0a 20 20 75 33 32 20 6e 54 72 75  me */.  u32 nTru
7140: 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20 20 20  ncate,          
7150: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 64          /* New d
7160: 62 20 73 69 7a 65 20 28 6f 72 20 30 20 66 6f 72  b size (or 0 for
7170: 20 6e 6f 6e 2d 63 6f 6d 6d 69 74 20 66 72 61 6d   non-commit fram
7180: 65 73 29 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61  es) */.  u8 *aDa
7190: 74 61 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ta,             
71a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
71b0: 74 65 72 20 74 6f 20 70 61 67 65 20 64 61 74 61  ter to page data
71c0: 20 2a 2f 0a 20 20 75 38 20 2a 61 46 72 61 6d 65   */.  u8 *aFrame
71d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
71e0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 57 72        /* OUT: Wr
71f0: 69 74 65 20 65 6e 63 6f 64 65 64 20 66 72 61 6d  ite encoded fram
7200: 65 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 69  e here */.){.  i
7210: 6e 74 20 6e 61 74 69 76 65 43 6b 73 75 6d 3b 20  nt nativeCksum; 
7220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7230: 2a 20 54 72 75 65 20 66 6f 72 20 6e 61 74 69 76  * True for nativ
7240: 65 20 62 79 74 65 2d 6f 72 64 65 72 20 63 68 65  e byte-order che
7250: 63 6b 73 75 6d 73 20 2a 2f 0a 20 20 75 33 32 20  cksums */.  u32 
7260: 2a 61 43 6b 73 75 6d 20 3d 20 70 57 61 6c 2d 3e  *aCksum = pWal->
7270: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 3b  hdr.aFrameCksum;
7280: 0a 20 20 61 73 73 65 72 74 28 20 57 41 4c 5f 46  .  assert( WAL_F
7290: 52 41 4d 45 5f 48 44 52 53 49 5a 45 3d 3d 32 34  RAME_HDRSIZE==24
72a0: 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74   );.  sqlite3Put
72b0: 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 30 5d  4byte(&aFrame[0]
72c0: 2c 20 69 50 61 67 65 29 3b 0a 20 20 73 71 6c 69  , iPage);.  sqli
72d0: 74 65 33 50 75 74 34 62 79 74 65 28 26 61 46 72  te3Put4byte(&aFr
72e0: 61 6d 65 5b 34 5d 2c 20 6e 54 72 75 6e 63 61 74  ame[4], nTruncat
72f0: 65 29 3b 0a 20 20 6d 65 6d 63 70 79 28 26 61 46  e);.  memcpy(&aF
7300: 72 61 6d 65 5b 38 5d 2c 20 70 57 61 6c 2d 3e 68  rame[8], pWal->h
7310: 64 72 2e 61 53 61 6c 74 2c 20 38 29 3b 0a 0a 20  dr.aSalt, 8);.. 
7320: 20 6e 61 74 69 76 65 43 6b 73 75 6d 20 3d 20 28   nativeCksum = (
7330: 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64  pWal->hdr.bigEnd
7340: 43 6b 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49  Cksum==SQLITE_BI
7350: 47 45 4e 44 49 41 4e 29 3b 0a 20 20 77 61 6c 43  GENDIAN);.  walC
7360: 68 65 63 6b 73 75 6d 42 79 74 65 73 28 6e 61 74  hecksumBytes(nat
7370: 69 76 65 43 6b 73 75 6d 2c 20 61 46 72 61 6d 65  iveCksum, aFrame
7380: 2c 20 38 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b  , 8, aCksum, aCk
7390: 73 75 6d 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b  sum);.  walCheck
73a0: 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43  sumBytes(nativeC
73b0: 6b 73 75 6d 2c 20 61 44 61 74 61 2c 20 70 57 61  ksum, aData, pWa
73c0: 6c 2d 3e 73 7a 50 61 67 65 2c 20 61 43 6b 73 75  l->szPage, aCksu
73d0: 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 73  m, aCksum);..  s
73e0: 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
73f0: 61 46 72 61 6d 65 5b 31 36 5d 2c 20 61 43 6b 73  aFrame[16], aCks
7400: 75 6d 5b 30 5d 29 3b 0a 20 20 73 71 6c 69 74 65  um[0]);.  sqlite
7410: 33 50 75 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Put4byte(&aFram
7420: 65 5b 32 30 5d 2c 20 61 43 6b 73 75 6d 5b 31 5d  e[20], aCksum[1]
7430: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63  );.}../*.** Chec
7440: 6b 20 74 6f 20 73 65 65 20 69 66 20 74 68 65 20  k to see if the 
7450: 66 72 61 6d 65 20 77 69 74 68 20 68 65 61 64 65  frame with heade
7460: 72 20 69 6e 20 61 46 72 61 6d 65 5b 5d 20 61 6e  r in aFrame[] an
7470: 64 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 69 6e 20  d content.** in 
7480: 61 44 61 74 61 5b 5d 20 69 73 20 76 61 6c 69 64  aData[] is valid
7490: 2e 20 20 49 66 20 69 74 20 69 73 20 61 20 76 61  .  If it is a va
74a0: 6c 69 64 20 66 72 61 6d 65 2c 20 66 69 6c 6c 20  lid frame, fill 
74b0: 2a 70 69 50 61 67 65 20 61 6e 64 0a 2a 2a 20 2a  *piPage and.** *
74c0: 70 6e 54 72 75 6e 63 61 74 65 20 61 6e 64 20 72  pnTruncate and r
74d0: 65 74 75 72 6e 20 74 72 75 65 2e 20 20 52 65 74  eturn true.  Ret
74e0: 75 72 6e 20 69 66 20 74 68 65 20 66 72 61 6d 65  urn if the frame
74f0: 20 69 73 20 6e 6f 74 20 76 61 6c 69 64 2e 0a 2a   is not valid..*
7500: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
7510: 44 65 63 6f 64 65 46 72 61 6d 65 28 0a 20 20 57  DecodeFrame(.  W
7520: 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20  al *pWal,       
7530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7540: 2a 20 54 68 65 20 77 72 69 74 65 2d 61 68 65 61  * The write-ahea
7550: 64 20 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 2a  d log */.  u32 *
7560: 70 69 50 61 67 65 2c 20 20 20 20 20 20 20 20 20  piPage,         
7570: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
7580: 54 3a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  T: Database page
7590: 20 6e 75 6d 62 65 72 20 66 6f 72 20 66 72 61 6d   number for fram
75a0: 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70 6e 54 72  e */.  u32 *pnTr
75b0: 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20 20  uncate,         
75c0: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e         /* OUT: N
75d0: 65 77 20 64 62 20 73 69 7a 65 20 28 6f 72 20 30  ew db size (or 0
75e0: 20 69 66 20 6e 6f 74 20 63 6f 6d 6d 69 74 29 20   if not commit) 
75f0: 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74 61 2c 20  */.  u8 *aData, 
7600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7610: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
7620: 74 6f 20 70 61 67 65 20 64 61 74 61 20 28 66 6f  to page data (fo
7630: 72 20 63 68 65 63 6b 73 75 6d 29 20 2a 2f 0a 20  r checksum) */. 
7640: 20 75 38 20 2a 61 46 72 61 6d 65 20 20 20 20 20   u8 *aFrame     
7650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7660: 20 2f 2a 20 46 72 61 6d 65 20 64 61 74 61 20 2a   /* Frame data *
7670: 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 61 74 69 76  /.){.  int nativ
7680: 65 43 6b 73 75 6d 3b 20 20 20 20 20 20 20 20 20  eCksum;         
7690: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 66         /* True f
76a0: 6f 72 20 6e 61 74 69 76 65 20 62 79 74 65 2d 6f  or native byte-o
76b0: 72 64 65 72 20 63 68 65 63 6b 73 75 6d 73 20 2a  rder checksums *
76c0: 2f 0a 20 20 75 33 32 20 2a 61 43 6b 73 75 6d 20  /.  u32 *aCksum 
76d0: 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61  = pWal->hdr.aFra
76e0: 6d 65 43 6b 73 75 6d 3b 0a 20 20 75 33 32 20 70  meCksum;.  u32 p
76f0: 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20  gno;            
7700: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
7710: 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65  ge number of the
7720: 20 66 72 61 6d 65 20 2a 2f 0a 20 20 61 73 73 65   frame */.  asse
7730: 72 74 28 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44  rt( WAL_FRAME_HD
7740: 52 53 49 5a 45 3d 3d 32 34 20 29 3b 0a 0a 20 20  RSIZE==24 );..  
7750: 2f 2a 20 41 20 66 72 61 6d 65 20 69 73 20 6f 6e  /* A frame is on
7760: 6c 79 20 76 61 6c 69 64 20 69 66 20 74 68 65 20  ly valid if the 
7770: 73 61 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74  salt values in t
7780: 68 65 20 66 72 61 6d 65 2d 68 65 61 64 65 72 0a  he frame-header.
7790: 20 20 2a 2a 20 6d 61 74 63 68 20 74 68 65 20 73    ** match the s
77a0: 61 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68  alt values in th
77b0: 65 20 77 61 6c 2d 68 65 61 64 65 72 2e 20 0a 20  e wal-header. . 
77c0: 20 2a 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70   */.  if( memcmp
77d0: 28 26 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c  (&pWal->hdr.aSal
77e0: 74 2c 20 26 61 46 72 61 6d 65 5b 38 5d 2c 20 38  t, &aFrame[8], 8
77f0: 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )!=0 ){.    retu
7800: 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  rn 0;.  }..  /* 
7810: 41 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20  A frame is only 
7820: 76 61 6c 69 64 20 69 66 20 74 68 65 20 70 61 67  valid if the pag
7830: 65 20 6e 75 6d 62 65 72 20 69 73 20 63 72 65 61  e number is crea
7840: 74 65 72 20 74 68 61 6e 20 7a 65 72 6f 2e 0a 20  ter than zero.. 
7850: 20 2a 2f 0a 20 20 70 67 6e 6f 20 3d 20 73 71 6c   */.  pgno = sql
7860: 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61 46  ite3Get4byte(&aF
7870: 72 61 6d 65 5b 30 5d 29 3b 0a 20 20 69 66 28 20  rame[0]);.  if( 
7880: 70 67 6e 6f 3d 3d 30 20 29 7b 0a 20 20 20 20 72  pgno==0 ){.    r
7890: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20  eturn 0;.  }..  
78a0: 2f 2a 20 41 20 66 72 61 6d 65 20 69 73 20 6f 6e  /* A frame is on
78b0: 6c 79 20 76 61 6c 69 64 20 69 66 20 61 20 63 68  ly valid if a ch
78c0: 65 63 6b 73 75 6d 20 6f 66 20 74 68 65 20 57 41  ecksum of the WA
78d0: 4c 20 68 65 61 64 65 72 2c 0a 20 20 2a 2a 20 61  L header,.  ** a
78e0: 6c 6c 20 70 72 69 6f 72 20 66 72 61 6d 73 2c 20  ll prior frams, 
78f0: 74 68 65 20 66 69 72 73 74 20 31 36 20 62 79 74  the first 16 byt
7900: 65 73 20 6f 66 20 74 68 69 73 20 66 72 61 6d 65  es of this frame
7910: 2d 68 65 61 64 65 72 2c 20 0a 20 20 2a 2a 20 61  -header, .  ** a
7920: 6e 64 20 74 68 65 20 66 72 61 6d 65 2d 64 61 74  nd the frame-dat
7930: 61 20 6d 61 74 63 68 65 73 20 74 68 65 20 63 68  a matches the ch
7940: 65 63 6b 73 75 6d 20 69 6e 20 74 68 65 20 6c 61  ecksum in the la
7950: 73 74 20 38 20 0a 20 20 2a 2a 20 62 79 74 65 73  st 8 .  ** bytes
7960: 20 6f 66 20 74 68 69 73 20 66 72 61 6d 65 2d 68   of this frame-h
7970: 65 61 64 65 72 2e 0a 20 20 2a 2f 0a 20 20 6e 61  eader..  */.  na
7980: 74 69 76 65 43 6b 73 75 6d 20 3d 20 28 70 57 61  tiveCksum = (pWa
7990: 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73  l->hdr.bigEndCks
79a0: 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e  um==SQLITE_BIGEN
79b0: 44 49 41 4e 29 3b 0a 20 20 77 61 6c 43 68 65 63  DIAN);.  walChec
79c0: 6b 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65  ksumBytes(native
79d0: 43 6b 73 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38  Cksum, aFrame, 8
79e0: 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d  , aCksum, aCksum
79f0: 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d  );.  walChecksum
7a00: 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75  Bytes(nativeCksu
7a10: 6d 2c 20 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e  m, aData, pWal->
7a20: 73 7a 50 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20  szPage, aCksum, 
7a30: 61 43 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20 61  aCksum);.  if( a
7a40: 43 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65  Cksum[0]!=sqlite
7a50: 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Get4byte(&aFram
7a60: 65 5b 31 36 5d 29 20 0a 20 20 20 7c 7c 20 61 43  e[16]) .   || aC
7a70: 6b 73 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33  ksum[1]!=sqlite3
7a80: 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Get4byte(&aFrame
7a90: 5b 32 30 5d 29 20 0a 20 20 29 7b 0a 20 20 20 20  [20]) .  ){.    
7aa0: 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66 61 69 6c  /* Checksum fail
7ab0: 65 64 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72  ed. */.    retur
7ac0: 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49  n 0;.  }..  /* I
7ad0: 66 20 77 65 20 72 65 61 63 68 20 74 68 69 73 20  f we reach this 
7ae0: 70 6f 69 6e 74 2c 20 74 68 65 20 66 72 61 6d 65  point, the frame
7af0: 20 69 73 20 76 61 6c 69 64 2e 20 20 52 65 74 75   is valid.  Retu
7b00: 72 6e 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62  rn the page numb
7b10: 65 72 0a 20 20 2a 2a 20 61 6e 64 20 74 68 65 20  er.  ** and the 
7b20: 6e 65 77 20 64 61 74 61 62 61 73 65 20 73 69 7a  new database siz
7b30: 65 2e 0a 20 20 2a 2f 0a 20 20 2a 70 69 50 61 67  e..  */.  *piPag
7b40: 65 20 3d 20 70 67 6e 6f 3b 0a 20 20 2a 70 6e 54  e = pgno;.  *pnT
7b50: 72 75 6e 63 61 74 65 20 3d 20 73 71 6c 69 74 65  runcate = sqlite
7b60: 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Get4byte(&aFram
7b70: 65 5b 34 5d 29 3b 0a 20 20 72 65 74 75 72 6e 20  e[4]);.  return 
7b80: 31 3b 0a 7d 0a 0a 0a 23 69 66 20 64 65 66 69 6e  1;.}...#if defin
7b90: 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20  ed(SQLITE_TEST) 
7ba0: 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  && defined(SQLIT
7bb0: 45 5f 44 45 42 55 47 29 0a 2f 2a 0a 2a 2a 20 4e  E_DEBUG)./*.** N
7bc0: 61 6d 65 73 20 6f 66 20 6c 6f 63 6b 73 2e 20 20  ames of locks.  
7bd0: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20  This routine is 
7be0: 75 73 65 64 20 74 6f 20 70 72 6f 76 69 64 65 20  used to provide 
7bf0: 64 65 62 75 67 67 69 6e 67 20 6f 75 74 70 75 74  debugging output
7c00: 20 61 6e 64 20 69 73 20 6e 6f 74 0a 2a 2a 20 61   and is not.** a
7c10: 20 70 61 72 74 20 6f 66 20 61 6e 20 6f 72 64 69   part of an ordi
7c20: 6e 61 72 79 20 62 75 69 6c 64 2e 0a 2a 2f 0a 73  nary build..*/.s
7c30: 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72  tatic const char
7c40: 20 2a 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 69 6e   *walLockName(in
7c50: 74 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66  t lockIdx){.  if
7c60: 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 57  ( lockIdx==WAL_W
7c70: 52 49 54 45 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20  RITE_LOCK ){.   
7c80: 20 72 65 74 75 72 6e 20 22 57 52 49 54 45 2d 4c   return "WRITE-L
7c90: 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66  OCK";.  }else if
7ca0: 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 43  ( lockIdx==WAL_C
7cb0: 4b 50 54 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20  KPT_LOCK ){.    
7cc0: 72 65 74 75 72 6e 20 22 43 4b 50 54 2d 4c 4f 43  return "CKPT-LOC
7cd0: 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20  K";.  }else if( 
7ce0: 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 52 45 43  lockIdx==WAL_REC
7cf0: 4f 56 45 52 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20  OVER_LOCK ){.   
7d00: 20 72 65 74 75 72 6e 20 22 52 45 43 4f 56 45 52   return "RECOVER
7d10: 2d 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 7b  -LOCK";.  }else{
7d20: 0a 20 20 20 20 73 74 61 74 69 63 20 63 68 61 72  .    static char
7d30: 20 7a 4e 61 6d 65 5b 31 35 5d 3b 0a 20 20 20 20   zName[15];.    
7d40: 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66  sqlite3_snprintf
7d50: 28 73 69 7a 65 6f 66 28 7a 4e 61 6d 65 29 2c 20  (sizeof(zName), 
7d60: 7a 4e 61 6d 65 2c 20 22 52 45 41 44 2d 4c 4f 43  zName, "READ-LOC
7d70: 4b 5b 25 64 5d 22 2c 0a 20 20 20 20 20 20 20 20  K[%d]",.        
7d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 63               loc
7d90: 6b 49 64 78 2d 57 41 4c 5f 52 45 41 44 5f 4c 4f  kIdx-WAL_READ_LO
7da0: 43 4b 28 30 29 29 3b 0a 20 20 20 20 72 65 74 75  CK(0));.    retu
7db0: 72 6e 20 7a 4e 61 6d 65 3b 0a 20 20 7d 0a 7d 0a  rn zName;.  }.}.
7dc0: 23 65 6e 64 69 66 20 2f 2a 64 65 66 69 6e 65 64  #endif /*defined
7dd0: 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 7c 7c  (SQLITE_TEST) ||
7de0: 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
7df0: 44 45 42 55 47 29 20 2a 2f 0a 20 20 20 20 0a 0a  DEBUG) */.    ..
7e00: 2f 2a 0a 2a 2a 20 53 65 74 20 6f 72 20 72 65 6c  /*.** Set or rel
7e10: 65 61 73 65 20 6c 6f 63 6b 73 20 6f 6e 20 74 68  ease locks on th
7e20: 65 20 57 41 4c 2e 20 20 4c 6f 63 6b 73 20 61 72  e WAL.  Locks ar
7e30: 65 20 65 69 74 68 65 72 20 73 68 61 72 65 64 20  e either shared 
7e40: 6f 72 20 65 78 63 6c 75 73 69 76 65 2e 0a 2a 2a  or exclusive..**
7e50: 20 41 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62   A lock cannot b
7e60: 65 20 6d 6f 76 65 64 20 64 69 72 65 63 74 6c 79  e moved directly
7e70: 20 62 65 74 77 65 65 6e 20 73 68 61 72 65 64 20   between shared 
7e80: 61 6e 64 20 65 78 63 6c 75 73 69 76 65 20 2d 20  and exclusive - 
7e90: 69 74 20 6d 75 73 74 20 67 6f 0a 2a 2a 20 74 68  it must go.** th
7ea0: 72 6f 75 67 68 20 74 68 65 20 75 6e 6c 6f 63 6b  rough the unlock
7eb0: 65 64 20 73 74 61 74 65 20 66 69 72 73 74 2e 0a  ed state first..
7ec0: 2a 2a 0a 2a 2a 20 49 6e 20 6c 6f 63 6b 69 6e 67  **.** In locking
7ed0: 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2c  _mode=EXCLUSIVE,
7ee0: 20 61 6c 6c 20 6f 66 20 74 68 65 73 65 20 72 6f   all of these ro
7ef0: 75 74 69 6e 65 73 20 62 65 63 6f 6d 65 20 6e 6f  utines become no
7f00: 2d 6f 70 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  -ops..*/.static 
7f10: 69 6e 74 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65  int walLockShare
7f20: 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  d(Wal *pWal, int
7f30: 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 6e 74   lockIdx){.  int
7f40: 20 72 63 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d   rc;.  if( pWal-
7f50: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29  >exclusiveMode )
7f60: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
7f70: 4b 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  K;.  rc = sqlite
7f80: 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d  3OsShmLock(pWal-
7f90: 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c  >pDbFd, lockIdx,
7fa0: 20 31 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20   1,.            
7fb0: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
7fc0: 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51  TE_SHM_LOCK | SQ
7fd0: 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29  LITE_SHM_SHARED)
7fe0: 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
7ff0: 41 4c 25 70 3a 20 61 63 71 75 69 72 65 20 53 48  AL%p: acquire SH
8000: 41 52 45 44 2d 25 73 20 25 73 5c 6e 22 2c 20 70  ARED-%s %s\n", p
8010: 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20 20  Wal,.           
8020: 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63   walLockName(loc
8030: 6b 49 64 78 29 2c 20 72 63 20 3f 20 22 66 61 69  kIdx), rc ? "fai
8040: 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
8050: 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d   VVA_ONLY( pWal-
8060: 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20 28 75 38  >lockError = (u8
8070: 29 28 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  )(rc!=SQLITE_OK 
8080: 26 26 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55  && rc!=SQLITE_BU
8090: 53 59 29 3b 20 29 0a 20 20 72 65 74 75 72 6e 20  SY); ).  return 
80a0: 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  rc;.}.static voi
80b0: 64 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65  d walUnlockShare
80c0: 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  d(Wal *pWal, int
80d0: 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66 28   lockIdx){.  if(
80e0: 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
80f0: 4d 6f 64 65 20 29 20 72 65 74 75 72 6e 3b 0a 20  Mode ) return;. 
8100: 20 28 76 6f 69 64 29 73 71 6c 69 74 65 33 4f 73   (void)sqlite3Os
8110: 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44  ShmLock(pWal->pD
8120: 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 31 2c  bFd, lockIdx, 1,
8130: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
8140: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
8150: 5f 53 48 4d 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51  _SHM_UNLOCK | SQ
8160: 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29  LITE_SHM_SHARED)
8170: 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
8180: 41 4c 25 70 3a 20 72 65 6c 65 61 73 65 20 53 48  AL%p: release SH
8190: 41 52 45 44 2d 25 73 5c 6e 22 2c 20 70 57 61 6c  ARED-%s\n", pWal
81a0: 2c 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f  , walLockName(lo
81b0: 63 6b 49 64 78 29 29 29 3b 0a 7d 0a 73 74 61 74  ckIdx)));.}.stat
81c0: 69 63 20 69 6e 74 20 77 61 6c 4c 6f 63 6b 45 78  ic int walLockEx
81d0: 63 6c 75 73 69 76 65 28 57 61 6c 20 2a 70 57 61  clusive(Wal *pWa
81e0: 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 2c 20  l, int lockIdx, 
81f0: 69 6e 74 20 6e 29 7b 0a 20 20 69 6e 74 20 72 63  int n){.  int rc
8200: 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78  ;.  if( pWal->ex
8210: 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65  clusiveMode ) re
8220: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
8230: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
8240: 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44  ShmLock(pWal->pD
8250: 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c  bFd, lockIdx, n,
8260: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
8270: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
8280: 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49 54  SHM_LOCK | SQLIT
8290: 45 5f 53 48 4d 5f 45 58 43 4c 55 53 49 56 45 29  E_SHM_EXCLUSIVE)
82a0: 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
82b0: 41 4c 25 70 3a 20 61 63 71 75 69 72 65 20 45 58  AL%p: acquire EX
82c0: 43 4c 55 53 49 56 45 2d 25 73 20 63 6e 74 3d 25  CLUSIVE-%s cnt=%
82d0: 64 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20  d %s\n", pWal,. 
82e0: 20 20 20 20 20 20 20 20 20 20 20 77 61 6c 4c 6f             walLo
82f0: 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c  ckName(lockIdx),
8300: 20 6e 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64   n, rc ? "failed
8310: 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 56 56  " : "ok"));.  VV
8320: 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f  A_ONLY( pWal->lo
8330: 63 6b 45 72 72 6f 72 20 3d 20 28 75 38 29 28 72  ckError = (u8)(r
8340: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c!=SQLITE_OK && 
8350: 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 29  rc!=SQLITE_BUSY)
8360: 3b 20 29 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ; ).  return rc;
8370: 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  .}.static void w
8380: 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
8390: 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  e(Wal *pWal, int
83a0: 20 6c 6f 63 6b 49 64 78 2c 20 69 6e 74 20 6e 29   lockIdx, int n)
83b0: 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78  {.  if( pWal->ex
83c0: 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65  clusiveMode ) re
83d0: 74 75 72 6e 3b 0a 20 20 28 76 6f 69 64 29 73 71  turn;.  (void)sq
83e0: 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70  lite3OsShmLock(p
83f0: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b  Wal->pDbFd, lock
8400: 49 64 78 2c 20 6e 2c 0a 20 20 20 20 20 20 20 20  Idx, n,.        
8410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8420: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f   SQLITE_SHM_UNLO
8430: 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f  CK | SQLITE_SHM_
8440: 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20 57 41  EXCLUSIVE);.  WA
8450: 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20  LTRACE(("WAL%p: 
8460: 72 65 6c 65 61 73 65 20 45 58 43 4c 55 53 49 56  release EXCLUSIV
8470: 45 2d 25 73 20 63 6e 74 3d 25 64 5c 6e 22 2c 20  E-%s cnt=%d\n", 
8480: 70 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20  pWal,.          
8490: 20 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c     walLockName(l
84a0: 6f 63 6b 49 64 78 29 2c 20 6e 29 29 3b 0a 7d 0a  ockIdx), n));.}.
84b0: 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61  ./*.** Compute a
84c0: 20 68 61 73 68 20 6f 6e 20 61 20 70 61 67 65 20   hash on a page 
84d0: 6e 75 6d 62 65 72 2e 20 20 54 68 65 20 72 65 73  number.  The res
84e0: 75 6c 74 69 6e 67 20 68 61 73 68 20 76 61 6c 75  ulting hash valu
84f0: 65 20 6d 75 73 74 20 6c 61 6e 64 0a 2a 2a 20 62  e must land.** b
8500: 65 74 77 65 65 6e 20 30 20 61 6e 64 20 28 48 41  etween 0 and (HA
8510: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29  SHTABLE_NSLOT-1)
8520: 2e 20 20 54 68 65 20 77 61 6c 48 61 73 68 4e 65  .  The walHashNe
8530: 78 74 28 29 20 66 75 6e 63 74 69 6f 6e 20 61 64  xt() function ad
8540: 76 61 6e 63 65 73 0a 2a 2a 20 74 68 65 20 68 61  vances.** the ha
8550: 73 68 20 74 6f 20 74 68 65 20 6e 65 78 74 20 76  sh to the next v
8560: 61 6c 75 65 20 69 6e 20 74 68 65 20 65 76 65 6e  alue in the even
8570: 74 20 6f 66 20 61 20 63 6f 6c 6c 69 73 69 6f 6e  t of a collision
8580: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
8590: 77 61 6c 48 61 73 68 28 75 33 32 20 69 50 61 67  walHash(u32 iPag
85a0: 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69 50  e){.  assert( iP
85b0: 61 67 65 3e 30 20 29 3b 0a 20 20 61 73 73 65 72  age>0 );.  asser
85c0: 74 28 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 53  t( (HASHTABLE_NS
85d0: 4c 4f 54 20 26 20 28 48 41 53 48 54 41 42 4c 45  LOT & (HASHTABLE
85e0: 5f 4e 53 4c 4f 54 2d 31 29 29 3d 3d 30 20 29 3b  _NSLOT-1))==0 );
85f0: 0a 20 20 72 65 74 75 72 6e 20 28 69 50 61 67 65  .  return (iPage
8600: 2a 48 41 53 48 54 41 42 4c 45 5f 48 41 53 48 5f  *HASHTABLE_HASH_
8610: 31 29 20 26 20 28 48 41 53 48 54 41 42 4c 45 5f  1) & (HASHTABLE_
8620: 4e 53 4c 4f 54 2d 31 29 3b 0a 7d 0a 73 74 61 74  NSLOT-1);.}.stat
8630: 69 63 20 69 6e 74 20 77 61 6c 4e 65 78 74 48 61  ic int walNextHa
8640: 73 68 28 69 6e 74 20 69 50 72 69 6f 72 48 61 73  sh(int iPriorHas
8650: 68 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 69 50  h){.  return (iP
8660: 72 69 6f 72 48 61 73 68 2b 31 29 26 28 48 41 53  riorHash+1)&(HAS
8670: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 3b  HTABLE_NSLOT-1);
8680: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72  .}../* .** Retur
8690: 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68  n pointers to th
86a0: 65 20 68 61 73 68 20 74 61 62 6c 65 20 61 6e 64  e hash table and
86b0: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72   page number arr
86c0: 61 79 20 73 74 6f 72 65 64 20 6f 6e 0a 2a 2a 20  ay stored on.** 
86d0: 70 61 67 65 20 69 48 61 73 68 20 6f 66 20 74 68  page iHash of th
86e0: 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 54 68 65  e wal-index. The
86f0: 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 62 72   wal-index is br
8700: 6f 6b 65 6e 20 69 6e 74 6f 20 33 32 4b 42 20 70  oken into 32KB p
8710: 61 67 65 73 0a 2a 2a 20 6e 75 6d 62 65 72 65 64  ages.** numbered
8720: 20 73 74 61 72 74 69 6e 67 20 66 72 6f 6d 20 30   starting from 0
8730: 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20 6f 75 74 70  ..**.** Set outp
8740: 75 74 20 76 61 72 69 61 62 6c 65 20 2a 70 61 48  ut variable *paH
8750: 61 73 68 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  ash to point to 
8760: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
8770: 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20 69   hash table.** i
8780: 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  n the wal-index 
8790: 66 69 6c 65 2e 20 53 65 74 20 2a 70 69 5a 65 72  file. Set *piZer
87a0: 6f 20 74 6f 20 6f 6e 65 20 6c 65 73 73 20 74 68  o to one less th
87b0: 61 6e 20 74 68 65 20 66 72 61 6d 65 20 0a 2a 2a  an the frame .**
87c0: 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 66   number of the f
87d0: 69 72 73 74 20 66 72 61 6d 65 20 69 6e 64 65 78  irst frame index
87e0: 65 64 20 62 79 20 74 68 69 73 20 68 61 73 68 20  ed by this hash 
87f0: 74 61 62 6c 65 2e 20 49 66 20 61 0a 2a 2a 20 73  table. If a.** s
8800: 6c 6f 74 20 69 6e 20 74 68 65 20 68 61 73 68 20  lot in the hash 
8810: 74 61 62 6c 65 20 69 73 20 73 65 74 20 74 6f 20  table is set to 
8820: 4e 2c 20 69 74 20 72 65 66 65 72 73 20 74 6f 20  N, it refers to 
8830: 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 0a 2a 2a  frame number .**
8840: 20 28 2a 70 69 5a 65 72 6f 2b 4e 29 20 69 6e 20   (*piZero+N) in 
8850: 74 68 65 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a 20 46  the log..**.** F
8860: 69 6e 61 6c 6c 79 2c 20 73 65 74 20 2a 70 61 50  inally, set *paP
8870: 67 6e 6f 20 73 6f 20 74 68 61 74 20 2a 70 61 50  gno so that *paP
8880: 67 6e 6f 5b 31 5d 20 69 73 20 74 68 65 20 70 61  gno[1] is the pa
8890: 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65  ge number of the
88a0: 0a 2a 2a 20 66 69 72 73 74 20 66 72 61 6d 65 20  .** first frame 
88b0: 69 6e 64 65 78 65 64 20 62 79 20 74 68 65 20 68  indexed by the h
88c0: 61 73 68 20 74 61 62 6c 65 2c 20 66 72 61 6d 65  ash table, frame
88d0: 20 28 2a 70 69 5a 65 72 6f 2b 31 29 2e 0a 2a 2f   (*piZero+1)..*/
88e0: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 48  .static int walH
88f0: 61 73 68 47 65 74 28 0a 20 20 57 61 6c 20 2a 70  ashGet(.  Wal *p
8900: 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Wal,            
8910: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c            /* WAL
8920: 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74   handle */.  int
8930: 20 69 48 61 73 68 2c 20 20 20 20 20 20 20 20 20   iHash,         
8940: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8950: 46 69 6e 64 20 74 68 65 20 69 48 61 73 68 27 74  Find the iHash't
8960: 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 76 6f 6c  h table */.  vol
8970: 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 2a  atile ht_slot **
8980: 70 61 48 61 73 68 2c 20 20 20 20 20 20 2f 2a 20  paHash,      /* 
8990: 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20  OUT: Pointer to 
89a0: 68 61 73 68 20 69 6e 64 65 78 20 2a 2f 0a 20 20  hash index */.  
89b0: 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 70  volatile u32 **p
89c0: 61 50 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20  aPgno,          
89d0: 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20  /* OUT: Pointer 
89e0: 74 6f 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61  to page number a
89f0: 72 72 61 79 20 2a 2f 0a 20 20 75 33 32 20 2a 70  rray */.  u32 *p
8a00: 69 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20 20  iZero           
8a10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
8a20: 3a 20 46 72 61 6d 65 20 61 73 73 6f 63 69 61 74  : Frame associat
8a30: 65 64 20 77 69 74 68 20 2a 70 61 50 67 6e 6f 5b  ed with *paPgno[
8a40: 30 5d 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  0] */.){.  int r
8a50: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
8a60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
8a70: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 76  turn code */.  v
8a80: 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67  olatile u32 *aPg
8a90: 6e 6f 3b 0a 0a 20 20 72 63 20 3d 20 77 61 6c 49  no;..  rc = walI
8aa0: 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20 69  ndexPage(pWal, i
8ab0: 48 61 73 68 2c 20 26 61 50 67 6e 6f 29 3b 0a 20  Hash, &aPgno);. 
8ac0: 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c   assert( rc==SQL
8ad0: 49 54 45 5f 4f 4b 20 7c 7c 20 69 48 61 73 68 3e  ITE_OK || iHash>
8ae0: 30 20 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d  0 );..  if( rc==
8af0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
8b00: 20 75 33 32 20 69 5a 65 72 6f 3b 0a 20 20 20 20   u32 iZero;.    
8b10: 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74  volatile ht_slot
8b20: 20 2a 61 48 61 73 68 3b 0a 0a 20 20 20 20 61 48   *aHash;..    aH
8b30: 61 73 68 20 3d 20 28 76 6f 6c 61 74 69 6c 65 20  ash = (volatile 
8b40: 68 74 5f 73 6c 6f 74 20 2a 29 26 61 50 67 6e 6f  ht_slot *)&aPgno
8b50: 5b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  [HASHTABLE_NPAGE
8b60: 5d 3b 0a 20 20 20 20 69 66 28 20 69 48 61 73 68  ];.    if( iHash
8b70: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 61 50 67  ==0 ){.      aPg
8b80: 6e 6f 20 3d 20 26 61 50 67 6e 6f 5b 57 41 4c 49  no = &aPgno[WALI
8b90: 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69  NDEX_HDR_SIZE/si
8ba0: 7a 65 6f 66 28 75 33 32 29 5d 3b 0a 20 20 20 20  zeof(u32)];.    
8bb0: 20 20 69 5a 65 72 6f 20 3d 20 30 3b 0a 20 20 20    iZero = 0;.   
8bc0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 5a   }else{.      iZ
8bd0: 65 72 6f 20 3d 20 48 41 53 48 54 41 42 4c 45 5f  ero = HASHTABLE_
8be0: 4e 50 41 47 45 5f 4f 4e 45 20 2b 20 28 69 48 61  NPAGE_ONE + (iHa
8bf0: 73 68 2d 31 29 2a 48 41 53 48 54 41 42 4c 45 5f  sh-1)*HASHTABLE_
8c00: 4e 50 41 47 45 3b 0a 20 20 20 20 7d 0a 20 20 0a  NPAGE;.    }.  .
8c10: 20 20 20 20 2a 70 61 50 67 6e 6f 20 3d 20 26 61      *paPgno = &a
8c20: 50 67 6e 6f 5b 2d 31 5d 3b 0a 20 20 20 20 2a 70  Pgno[-1];.    *p
8c30: 61 48 61 73 68 20 3d 20 61 48 61 73 68 3b 0a 20  aHash = aHash;. 
8c40: 20 20 20 2a 70 69 5a 65 72 6f 20 3d 20 69 5a 65     *piZero = iZe
8c50: 72 6f 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ro;.  }.  return
8c60: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65   rc;.}../*.** Re
8c70: 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20  turn the number 
8c80: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
8c90: 20 70 61 67 65 20 74 68 61 74 20 63 6f 6e 74 61   page that conta
8ca0: 69 6e 73 20 74 68 65 20 68 61 73 68 2d 74 61 62  ins the hash-tab
8cb0: 6c 65 0a 2a 2a 20 61 6e 64 20 70 61 67 65 2d 6e  le.** and page-n
8cc0: 75 6d 62 65 72 20 61 72 72 61 79 20 74 68 61 74  umber array that
8cd0: 20 63 6f 6e 74 61 69 6e 20 65 6e 74 72 69 65 73   contain entries
8ce0: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74   corresponding t
8cf0: 6f 20 57 41 4c 20 66 72 61 6d 65 0a 2a 2a 20 69  o WAL frame.** i
8d00: 46 72 61 6d 65 2e 20 54 68 65 20 77 61 6c 2d 69  Frame. The wal-i
8d10: 6e 64 65 78 20 69 73 20 62 72 6f 6b 65 6e 20 75  ndex is broken u
8d20: 70 20 69 6e 74 6f 20 33 32 4b 42 20 70 61 67 65  p into 32KB page
8d30: 73 2e 20 57 61 6c 2d 69 6e 64 65 78 20 70 61 67  s. Wal-index pag
8d40: 65 73 20 0a 2a 2a 20 61 72 65 20 6e 75 6d 62 65  es .** are numbe
8d50: 72 65 64 20 73 74 61 72 74 69 6e 67 20 66 72 6f  red starting fro
8d60: 6d 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  m 0..*/.static i
8d70: 6e 74 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28  nt walFramePage(
8d80: 75 33 32 20 69 46 72 61 6d 65 29 7b 0a 20 20 69  u32 iFrame){.  i
8d90: 6e 74 20 69 48 61 73 68 20 3d 20 28 69 46 72 61  nt iHash = (iFra
8da0: 6d 65 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  me+HASHTABLE_NPA
8db0: 47 45 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  GE-HASHTABLE_NPA
8dc0: 47 45 5f 4f 4e 45 2d 31 29 20 2f 20 48 41 53 48  GE_ONE-1) / HASH
8dd0: 54 41 42 4c 45 5f 4e 50 41 47 45 3b 0a 20 20 61  TABLE_NPAGE;.  a
8de0: 73 73 65 72 74 28 20 28 69 48 61 73 68 3d 3d 30  ssert( (iHash==0
8df0: 20 7c 7c 20 69 46 72 61 6d 65 3e 48 41 53 48 54   || iFrame>HASHT
8e00: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 0a  ABLE_NPAGE_ONE).
8e10: 20 20 20 20 20 20 20 26 26 20 28 69 48 61 73 68         && (iHash
8e20: 3e 3d 31 20 7c 7c 20 69 46 72 61 6d 65 3c 3d 48  >=1 || iFrame<=H
8e30: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
8e40: 4e 45 29 0a 20 20 20 20 20 20 20 26 26 20 28 69  NE).       && (i
8e50: 48 61 73 68 3c 3d 31 20 7c 7c 20 69 46 72 61 6d  Hash<=1 || iFram
8e60: 65 3e 28 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  e>(HASHTABLE_NPA
8e70: 47 45 5f 4f 4e 45 2b 48 41 53 48 54 41 42 4c 45  GE_ONE+HASHTABLE
8e80: 5f 4e 50 41 47 45 29 29 0a 20 20 20 20 20 20 20  _NPAGE)).       
8e90: 26 26 20 28 69 48 61 73 68 3e 3d 32 20 7c 7c 20  && (iHash>=2 || 
8ea0: 69 46 72 61 6d 65 3c 3d 48 41 53 48 54 41 42 4c  iFrame<=HASHTABL
8eb0: 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 48 41 53 48  E_NPAGE_ONE+HASH
8ec0: 54 41 42 4c 45 5f 4e 50 41 47 45 29 0a 20 20 20  TABLE_NPAGE).   
8ed0: 20 20 20 20 26 26 20 28 69 48 61 73 68 3c 3d 32      && (iHash<=2
8ee0: 20 7c 7c 20 69 46 72 61 6d 65 3e 28 48 41 53 48   || iFrame>(HASH
8ef0: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b  TABLE_NPAGE_ONE+
8f00: 32 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  2*HASHTABLE_NPAG
8f10: 45 29 29 0a 20 20 29 3b 0a 20 20 72 65 74 75 72  E)).  );.  retur
8f20: 6e 20 69 48 61 73 68 3b 0a 7d 0a 0a 2f 2a 0a 2a  n iHash;.}../*.*
8f30: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 70 61 67  * Return the pag
8f40: 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63 69 61  e number associa
8f50: 74 65 64 20 77 69 74 68 20 66 72 61 6d 65 20 69  ted with frame i
8f60: 46 72 61 6d 65 20 69 6e 20 74 68 69 73 20 57 41  Frame in this WA
8f70: 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75 33 32  L..*/.static u32
8f80: 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 57 61   walFramePgno(Wa
8f90: 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 69 46 72  l *pWal, u32 iFr
8fa0: 61 6d 65 29 7b 0a 20 20 69 6e 74 20 69 48 61 73  ame){.  int iHas
8fb0: 68 20 3d 20 77 61 6c 46 72 61 6d 65 50 61 67 65  h = walFramePage
8fc0: 28 69 46 72 61 6d 65 29 3b 0a 20 20 69 66 28 20  (iFrame);.  if( 
8fd0: 69 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20  iHash==0 ){.    
8fe0: 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e 61 70 57  return pWal->apW
8ff0: 69 44 61 74 61 5b 30 5d 5b 57 41 4c 49 4e 44 45  iData[0][WALINDE
9000: 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f  X_HDR_SIZE/sizeo
9010: 66 28 75 33 32 29 20 2b 20 69 46 72 61 6d 65 20  f(u32) + iFrame 
9020: 2d 20 31 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75  - 1];.  }.  retu
9030: 72 6e 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  rn pWal->apWiDat
9040: 61 5b 69 48 61 73 68 5d 5b 28 69 46 72 61 6d 65  a[iHash][(iFrame
9050: 2d 31 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  -1-HASHTABLE_NPA
9060: 47 45 5f 4f 4e 45 29 25 48 41 53 48 54 41 42 4c  GE_ONE)%HASHTABL
9070: 45 5f 4e 50 41 47 45 5d 3b 0a 7d 0a 0a 2f 2a 0a  E_NPAGE];.}../*.
9080: 2a 2a 20 52 65 6d 6f 76 65 20 65 6e 74 72 69 65  ** Remove entrie
9090: 73 20 66 72 6f 6d 20 74 68 65 20 68 61 73 68 20  s from the hash 
90a0: 74 61 62 6c 65 20 74 68 61 74 20 70 6f 69 6e 74  table that point
90b0: 20 74 6f 20 57 41 4c 20 73 6c 6f 74 73 20 67 72   to WAL slots gr
90c0: 65 61 74 65 72 0a 2a 2a 20 74 68 61 6e 20 70 57  eater.** than pW
90d0: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e  al->hdr.mxFrame.
90e0: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  .**.** This func
90f0: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 77  tion is called w
9100: 68 65 6e 65 76 65 72 20 70 57 61 6c 2d 3e 68 64  henever pWal->hd
9110: 72 2e 6d 78 46 72 61 6d 65 20 69 73 20 64 65 63  r.mxFrame is dec
9120: 72 65 61 73 65 64 20 64 75 65 0a 2a 2a 20 74 6f  reased due.** to
9130: 20 61 20 72 6f 6c 6c 62 61 63 6b 20 6f 72 20 73   a rollback or s
9140: 61 76 65 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20  avepoint..**.** 
9150: 41 74 20 6d 6f 73 74 20 6f 6e 6c 79 20 74 68 65  At most only the
9160: 20 68 61 73 68 20 74 61 62 6c 65 20 63 6f 6e 74   hash table cont
9170: 61 69 6e 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72  aining pWal->hdr
9180: 2e 6d 78 46 72 61 6d 65 20 6e 65 65 64 73 20 74  .mxFrame needs t
9190: 6f 20 62 65 0a 2a 2a 20 75 70 64 61 74 65 64 2e  o be.** updated.
91a0: 20 20 41 6e 79 20 6c 61 74 65 72 20 68 61 73 68    Any later hash
91b0: 20 74 61 62 6c 65 73 20 77 69 6c 6c 20 62 65 20   tables will be 
91c0: 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 63 6c  automatically cl
91d0: 65 61 72 65 64 20 77 68 65 6e 0a 2a 2a 20 70 57  eared when.** pW
91e0: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
91f0: 61 64 76 61 6e 63 65 73 20 74 6f 20 74 68 65 20  advances to the 
9200: 70 6f 69 6e 74 20 77 68 65 72 65 20 74 68 6f 73  point where thos
9210: 65 20 68 61 73 68 20 74 61 62 6c 65 73 20 61 72  e hash tables ar
9220: 65 0a 2a 2a 20 61 63 74 75 61 6c 6c 79 20 6e 65  e.** actually ne
9230: 65 64 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  eded..*/.static 
9240: 76 6f 69 64 20 77 61 6c 43 6c 65 61 6e 75 70 48  void walCleanupH
9250: 61 73 68 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ash(Wal *pWal){.
9260: 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c    volatile ht_sl
9270: 6f 74 20 2a 61 48 61 73 68 20 3d 20 30 3b 20 20  ot *aHash = 0;  
9280: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
9290: 68 61 73 68 20 74 61 62 6c 65 20 74 6f 20 63 6c  hash table to cl
92a0: 65 61 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c  ear */.  volatil
92b0: 65 20 75 33 32 20 2a 61 50 67 6e 6f 20 3d 20 30  e u32 *aPgno = 0
92c0: 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65  ;        /* Page
92d0: 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 66 6f   number array fo
92e0: 72 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a  r hash table */.
92f0: 20 20 75 33 32 20 69 5a 65 72 6f 20 3d 20 30 3b    u32 iZero = 0;
9300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9310: 20 20 2f 2a 20 66 72 61 6d 65 20 3d 3d 20 28 61    /* frame == (a
9320: 48 61 73 68 5b 78 5d 2b 69 5a 65 72 6f 29 20 2a  Hash[x]+iZero) *
9330: 2f 0a 20 20 69 6e 74 20 69 4c 69 6d 69 74 20 3d  /.  int iLimit =
9340: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
9350: 20 20 20 20 2f 2a 20 5a 65 72 6f 20 76 61 6c 75      /* Zero valu
9360: 65 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  es greater than 
9370: 74 68 69 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  this */.  int nB
9380: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
9390: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
93a0: 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20  ber of bytes to 
93b0: 7a 65 72 6f 20 69 6e 20 61 50 67 6e 6f 5b 5d 20  zero in aPgno[] 
93c0: 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20  */.  int i;     
93d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
93e0: 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
93f0: 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20  iterate through 
9400: 61 48 61 73 68 5b 5d 20 2a 2f 0a 0a 20 20 61 73  aHash[] */..  as
9410: 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74  sert( pWal->writ
9420: 65 4c 6f 63 6b 20 29 3b 0a 20 20 74 65 73 74 63  eLock );.  testc
9430: 61 73 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  ase( pWal->hdr.m
9440: 78 46 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c  xFrame==HASHTABL
9450: 45 5f 4e 50 41 47 45 5f 4f 4e 45 2d 31 20 29 3b  E_NPAGE_ONE-1 );
9460: 0a 20 20 74 65 73 74 63 61 73 65 28 20 70 57 61  .  testcase( pWa
9470: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d  l->hdr.mxFrame==
9480: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
9490: 4f 4e 45 20 29 3b 0a 20 20 74 65 73 74 63 61 73  ONE );.  testcas
94a0: 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  e( pWal->hdr.mxF
94b0: 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45 5f  rame==HASHTABLE_
94c0: 4e 50 41 47 45 5f 4f 4e 45 2b 31 20 29 3b 0a 0a  NPAGE_ONE+1 );..
94d0: 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e    if( pWal->hdr.
94e0: 6d 78 46 72 61 6d 65 3d 3d 30 20 29 20 72 65 74  mxFrame==0 ) ret
94f0: 75 72 6e 3b 0a 0a 20 20 2f 2a 20 4f 62 74 61 69  urn;..  /* Obtai
9500: 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68  n pointers to th
9510: 65 20 68 61 73 68 2d 74 61 62 6c 65 20 61 6e 64  e hash-table and
9520: 20 70 61 67 65 2d 6e 75 6d 62 65 72 20 61 72 72   page-number arr
9530: 61 79 20 63 6f 6e 74 61 69 6e 69 6e 67 20 0a 20  ay containing . 
9540: 20 2a 2a 20 74 68 65 20 65 6e 74 72 79 20 74 68   ** the entry th
9550: 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74  at corresponds t
9560: 6f 20 66 72 61 6d 65 20 70 57 61 6c 2d 3e 68 64  o frame pWal->hd
9570: 72 2e 6d 78 46 72 61 6d 65 2e 20 49 74 20 69 73  r.mxFrame. It is
9580: 20 67 75 61 72 61 6e 74 65 65 64 0a 20 20 2a 2a   guaranteed.  **
9590: 20 74 68 61 74 20 74 68 65 20 70 61 67 65 20 73   that the page s
95a0: 61 69 64 20 68 61 73 68 2d 74 61 62 6c 65 20 61  aid hash-table a
95b0: 6e 64 20 61 72 72 61 79 20 72 65 73 69 64 65 20  nd array reside 
95c0: 6f 6e 20 69 73 20 61 6c 72 65 61 64 79 20 6d 61  on is already ma
95d0: 70 70 65 64 2e 0a 20 20 2a 2f 0a 20 20 61 73 73  pped..  */.  ass
95e0: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
95f0: 74 61 3e 77 61 6c 46 72 61 6d 65 50 61 67 65 28  ta>walFramePage(
9600: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
9610: 65 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  e) );.  assert( 
9620: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 77  pWal->apWiData[w
9630: 61 6c 46 72 61 6d 65 50 61 67 65 28 70 57 61 6c  alFramePage(pWal
9640: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 29 5d 20  ->hdr.mxFrame)] 
9650: 29 3b 0a 20 20 77 61 6c 48 61 73 68 47 65 74 28  );.  walHashGet(
9660: 70 57 61 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61  pWal, walFramePa
9670: 67 65 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ge(pWal->hdr.mxF
9680: 72 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20 26  rame), &aHash, &
9690: 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a  aPgno, &iZero);.
96a0: 0a 20 20 2f 2a 20 5a 65 72 6f 20 61 6c 6c 20 68  .  /* Zero all h
96b0: 61 73 68 2d 74 61 62 6c 65 20 65 6e 74 72 69 65  ash-table entrie
96c0: 73 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  s that correspon
96d0: 64 20 74 6f 20 66 72 61 6d 65 20 6e 75 6d 62 65  d to frame numbe
96e0: 72 73 20 67 72 65 61 74 65 72 0a 20 20 2a 2a 20  rs greater.  ** 
96f0: 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  than pWal->hdr.m
9700: 78 46 72 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69  xFrame..  */.  i
9710: 4c 69 6d 69 74 20 3d 20 70 57 61 6c 2d 3e 68 64  Limit = pWal->hd
9720: 72 2e 6d 78 46 72 61 6d 65 20 2d 20 69 5a 65 72  r.mxFrame - iZer
9730: 6f 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4c 69  o;.  assert( iLi
9740: 6d 69 74 3e 30 20 29 3b 0a 20 20 66 6f 72 28 69  mit>0 );.  for(i
9750: 3d 30 3b 20 69 3c 48 41 53 48 54 41 42 4c 45 5f  =0; i<HASHTABLE_
9760: 4e 53 4c 4f 54 3b 20 69 2b 2b 29 7b 0a 20 20 20  NSLOT; i++){.   
9770: 20 69 66 28 20 61 48 61 73 68 5b 69 5d 3e 69 4c   if( aHash[i]>iL
9780: 69 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 61 48  imit ){.      aH
9790: 61 73 68 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20  ash[i] = 0;.    
97a0: 7d 0a 20 20 7d 0a 20 20 0a 20 20 2f 2a 20 5a 65  }.  }.  .  /* Ze
97b0: 72 6f 20 74 68 65 20 65 6e 74 72 69 65 73 20 69  ro the entries i
97c0: 6e 20 74 68 65 20 61 50 67 6e 6f 20 61 72 72 61  n the aPgno arra
97d0: 79 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  y that correspon
97e0: 64 20 74 6f 20 66 72 61 6d 65 73 20 77 69 74 68  d to frames with
97f0: 0a 20 20 2a 2a 20 66 72 61 6d 65 20 6e 75 6d 62  .  ** frame numb
9800: 65 72 73 20 67 72 65 61 74 65 72 20 74 68 61 6e  ers greater than
9810: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
9820: 6d 65 2e 20 0a 20 20 2a 2f 0a 20 20 6e 42 79 74  me. .  */.  nByt
9830: 65 20 3d 20 28 69 6e 74 29 28 28 63 68 61 72 20  e = (int)((char 
9840: 2a 29 61 48 61 73 68 20 2d 20 28 63 68 61 72 20  *)aHash - (char 
9850: 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d 69 74 2b  *)&aPgno[iLimit+
9860: 31 5d 29 3b 0a 20 20 6d 65 6d 73 65 74 28 28 76  1]);.  memset((v
9870: 6f 69 64 20 2a 29 26 61 50 67 6e 6f 5b 69 4c 69  oid *)&aPgno[iLi
9880: 6d 69 74 2b 31 5d 2c 20 30 2c 20 6e 42 79 74 65  mit+1], 0, nByte
9890: 29 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  );..#ifdef SQLIT
98a0: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
98b0: 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20 56  VE_ASSERT.  /* V
98c0: 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20 65  erify that the e
98d0: 76 65 72 79 20 65 6e 74 72 79 20 69 6e 20 74 68  very entry in th
98e0: 65 20 6d 61 70 70 69 6e 67 20 72 65 67 69 6f 6e  e mapping region
98f0: 20 69 73 20 73 74 69 6c 6c 20 72 65 61 63 68 61   is still reacha
9900: 62 6c 65 0a 20 20 2a 2a 20 76 69 61 20 74 68 65  ble.  ** via the
9910: 20 68 61 73 68 20 74 61 62 6c 65 20 65 76 65 6e   hash table even
9920: 20 61 66 74 65 72 20 74 68 65 20 63 6c 65 61 6e   after the clean
9930: 75 70 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69  up..  */.  if( i
9940: 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20 69 6e 74  Limit ){.    int
9950: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a   i;           /*
9960: 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f   Loop counter */
9970: 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20  .    int iKey;  
9980: 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 6b 65        /* Hash ke
9990: 79 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d 31  y */.    for(i=1
99a0: 3b 20 69 3c 3d 69 4c 69 6d 69 74 3b 20 69 2b 2b  ; i<=iLimit; i++
99b0: 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 4b 65  ){.      for(iKe
99c0: 79 3d 77 61 6c 48 61 73 68 28 61 50 67 6e 6f 5b  y=walHash(aPgno[
99d0: 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  i]); aHash[iKey]
99e0: 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
99f0: 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
9a00: 20 20 20 69 66 28 20 61 48 61 73 68 5b 69 4b 65     if( aHash[iKe
9a10: 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b 3b 0a 20  y]==i ) break;. 
9a20: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73 73       }.      ass
9a30: 65 72 74 28 20 61 48 61 73 68 5b 69 4b 65 79 5d  ert( aHash[iKey]
9a40: 3d 3d 69 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  ==i );.    }.  }
9a50: 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54  .#endif /* SQLIT
9a60: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
9a70: 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a 7d 0a 0a  VE_ASSERT */.}..
9a80: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 6e 20 65 6e  ./*.** Set an en
9a90: 74 72 79 20 69 6e 20 74 68 65 20 77 61 6c 2d 69  try in the wal-i
9aa0: 6e 64 65 78 20 74 68 61 74 20 77 69 6c 6c 20 6d  ndex that will m
9ab0: 61 70 20 64 61 74 61 62 61 73 65 20 70 61 67 65  ap database page
9ac0: 20 6e 75 6d 62 65 72 0a 2a 2a 20 70 50 61 67 65   number.** pPage
9ad0: 20 69 6e 74 6f 20 57 41 4c 20 66 72 61 6d 65 20   into WAL frame 
9ae0: 69 46 72 61 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69  iFrame..*/.stati
9af0: 63 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 41 70  c int walIndexAp
9b00: 70 65 6e 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20  pend(Wal *pWal, 
9b10: 75 33 32 20 69 46 72 61 6d 65 2c 20 75 33 32 20  u32 iFrame, u32 
9b20: 69 50 61 67 65 29 7b 0a 20 20 69 6e 74 20 72 63  iPage){.  int rc
9b30: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
9b40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
9b50: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 75 33  urn code */.  u3
9b60: 32 20 69 5a 65 72 6f 20 3d 20 30 3b 20 20 20 20  2 iZero = 0;    
9b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9b80: 20 4f 6e 65 20 6c 65 73 73 20 74 68 61 6e 20 66   One less than f
9b90: 72 61 6d 65 20 6e 75 6d 62 65 72 20 6f 66 20 61  rame number of a
9ba0: 50 67 6e 6f 5b 31 5d 20 2a 2f 0a 20 20 76 6f 6c  Pgno[1] */.  vol
9bb0: 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f  atile u32 *aPgno
9bc0: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 2f 2a 20   = 0;        /* 
9bd0: 50 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61  Page number arra
9be0: 79 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20  y */.  volatile 
9bf0: 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 20 3d  ht_slot *aHash =
9c00: 20 30 3b 20 20 20 20 2f 2a 20 48 61 73 68 20 74   0;    /* Hash t
9c10: 61 62 6c 65 20 2a 2f 0a 0a 20 20 72 63 20 3d 20  able */..  rc = 
9c20: 77 61 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c  walHashGet(pWal,
9c30: 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69 46   walFramePage(iF
9c40: 72 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20 26  rame), &aHash, &
9c50: 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a  aPgno, &iZero);.
9c60: 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20 74  .  /* Assuming t
9c70: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  he wal-index fil
9c80: 65 20 77 61 73 20 73 75 63 63 65 73 73 66 75 6c  e was successful
9c90: 6c 79 20 6d 61 70 70 65 64 2c 20 70 6f 70 75 6c  ly mapped, popul
9ca0: 61 74 65 20 74 68 65 0a 20 20 2a 2a 20 70 61 67  ate the.  ** pag
9cb0: 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 61  e number array a
9cc0: 6e 64 20 68 61 73 68 20 74 61 62 6c 65 20 65 6e  nd hash table en
9cd0: 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  try..  */.  if( 
9ce0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
9cf0: 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20  .    int iKey;  
9d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9d10: 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65     /* Hash table
9d20: 20 6b 65 79 20 2a 2f 0a 20 20 20 20 69 6e 74 20   key */.    int 
9d30: 69 64 78 3b 20 20 20 20 20 20 20 20 20 20 20 20  idx;            
9d40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
9d50: 75 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 68  ue to write to h
9d60: 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 20 2a  ash-table slot *
9d70: 2f 0a 20 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69  /.    int nColli
9d80: 64 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  de;             
9d90: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
9da0: 20 68 61 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73   hash collisions
9db0: 20 2a 2f 0a 0a 20 20 20 20 69 64 78 20 3d 20 69   */..    idx = i
9dc0: 46 72 61 6d 65 20 2d 20 69 5a 65 72 6f 3b 0a 20  Frame - iZero;. 
9dd0: 20 20 20 61 73 73 65 72 74 28 20 69 64 78 20 3c     assert( idx <
9de0: 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f  = HASHTABLE_NSLO
9df0: 54 2f 32 20 2b 20 31 20 29 3b 0a 20 20 20 20 0a  T/2 + 1 );.    .
9e00: 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69      /* If this i
9e10: 73 20 74 68 65 20 66 69 72 73 74 20 65 6e 74 72  s the first entr
9e20: 79 20 74 6f 20 62 65 20 61 64 64 65 64 20 74 6f  y to be added to
9e30: 20 74 68 69 73 20 68 61 73 68 2d 74 61 62 6c 65   this hash-table
9e40: 2c 20 7a 65 72 6f 20 74 68 65 0a 20 20 20 20 2a  , zero the.    *
9e50: 2a 20 65 6e 74 69 72 65 20 68 61 73 68 20 74 61  * entire hash ta
9e60: 62 6c 65 20 61 6e 64 20 61 50 67 6e 6f 5b 5d 20  ble and aPgno[] 
9e70: 61 72 72 61 79 20 62 65 66 6f 72 65 20 70 72 6f  array before pro
9e80: 63 65 64 69 6e 67 2e 20 0a 20 20 20 20 2a 2f 0a  ceding. .    */.
9e90: 20 20 20 20 69 66 28 20 69 64 78 3d 3d 31 20 29      if( idx==1 )
9ea0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74  {.      int nByt
9eb0: 65 20 3d 20 28 69 6e 74 29 28 28 75 38 20 2a 29  e = (int)((u8 *)
9ec0: 26 61 48 61 73 68 5b 48 41 53 48 54 41 42 4c 45  &aHash[HASHTABLE
9ed0: 5f 4e 53 4c 4f 54 5d 20 2d 20 28 75 38 20 2a 29  _NSLOT] - (u8 *)
9ee0: 26 61 50 67 6e 6f 5b 31 5d 29 3b 0a 20 20 20 20  &aPgno[1]);.    
9ef0: 20 20 6d 65 6d 73 65 74 28 28 76 6f 69 64 2a 29    memset((void*)
9f00: 26 61 50 67 6e 6f 5b 31 5d 2c 20 30 2c 20 6e 42  &aPgno[1], 0, nB
9f10: 79 74 65 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  yte);.    }..   
9f20: 20 2f 2a 20 49 66 20 74 68 65 20 65 6e 74 72 79   /* If the entry
9f30: 20 69 6e 20 61 50 67 6e 6f 5b 5d 20 69 73 20 61   in aPgno[] is a
9f40: 6c 72 65 61 64 79 20 73 65 74 2c 20 74 68 65 6e  lready set, then
9f50: 20 74 68 65 20 70 72 65 76 69 6f 75 73 20 77 72   the previous wr
9f60: 69 74 65 72 0a 20 20 20 20 2a 2a 20 6d 75 73 74  iter.    ** must
9f70: 20 68 61 76 65 20 65 78 69 74 65 64 20 75 6e 65   have exited une
9f80: 78 70 65 63 74 65 64 6c 79 20 69 6e 20 74 68 65  xpectedly in the
9f90: 20 6d 69 64 64 6c 65 20 6f 66 20 61 20 74 72 61   middle of a tra
9fa0: 6e 73 61 63 74 69 6f 6e 20 28 61 66 74 65 72 0a  nsaction (after.
9fb0: 20 20 20 20 2a 2a 20 77 72 69 74 69 6e 67 20 6f      ** writing o
9fc0: 6e 65 20 6f 72 20 6d 6f 72 65 20 64 69 72 74 79  ne or more dirty
9fd0: 20 70 61 67 65 73 20 74 6f 20 74 68 65 20 57 41   pages to the WA
9fe0: 4c 20 74 6f 20 66 72 65 65 20 75 70 20 6d 65 6d  L to free up mem
9ff0: 6f 72 79 29 2e 20 0a 20 20 20 20 2a 2a 20 52 65  ory). .    ** Re
a000: 6d 6f 76 65 20 74 68 65 20 72 65 6d 6e 61 6e 74  move the remnant
a010: 73 20 6f 66 20 74 68 61 74 20 77 72 69 74 65 72  s of that writer
a020: 73 20 75 6e 63 6f 6d 6d 69 74 74 65 64 20 74 72  s uncommitted tr
a030: 61 6e 73 61 63 74 69 6f 6e 20 66 72 6f 6d 20 0a  ansaction from .
a040: 20 20 20 20 2a 2a 20 74 68 65 20 68 61 73 68 2d      ** the hash-
a050: 74 61 62 6c 65 20 62 65 66 6f 72 65 20 77 72 69  table before wri
a060: 74 69 6e 67 20 61 6e 79 20 6e 65 77 20 65 6e 74  ting any new ent
a070: 72 69 65 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  ries..    */.   
a080: 20 69 66 28 20 61 50 67 6e 6f 5b 69 64 78 5d 20   if( aPgno[idx] 
a090: 29 7b 0a 20 20 20 20 20 20 77 61 6c 43 6c 65 61  ){.      walClea
a0a0: 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20  nupHash(pWal);. 
a0b0: 20 20 20 20 20 61 73 73 65 72 74 28 20 21 61 50       assert( !aP
a0c0: 67 6e 6f 5b 69 64 78 5d 20 29 3b 0a 20 20 20 20  gno[idx] );.    
a0d0: 7d 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20  }..    /* Write 
a0e0: 74 68 65 20 61 50 67 6e 6f 5b 5d 20 61 72 72 61  the aPgno[] arra
a0f0: 79 20 65 6e 74 72 79 20 61 6e 64 20 74 68 65 20  y entry and the 
a100: 68 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 2e  hash-table slot.
a110: 20 2a 2f 0a 20 20 20 20 6e 43 6f 6c 6c 69 64 65   */.    nCollide
a120: 20 3d 20 69 64 78 3b 0a 20 20 20 20 66 6f 72 28   = idx;.    for(
a130: 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 69 50 61  iKey=walHash(iPa
a140: 67 65 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  ge); aHash[iKey]
a150: 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
a160: 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
a170: 20 69 66 28 20 28 6e 43 6f 6c 6c 69 64 65 2d 2d   if( (nCollide--
a180: 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  )==0 ) return SQ
a190: 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50  LITE_CORRUPT_BKP
a1a0: 54 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 50 67  T;.    }.    aPg
a1b0: 6e 6f 5b 69 64 78 5d 20 3d 20 69 50 61 67 65 3b  no[idx] = iPage;
a1c0: 0a 20 20 20 20 61 48 61 73 68 5b 69 4b 65 79 5d  .    aHash[iKey]
a1d0: 20 3d 20 28 68 74 5f 73 6c 6f 74 29 69 64 78 3b   = (ht_slot)idx;
a1e0: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
a1f0: 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45  ENABLE_EXPENSIVE
a200: 5f 41 53 53 45 52 54 0a 20 20 20 20 2f 2a 20 56  _ASSERT.    /* V
a210: 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20 6e  erify that the n
a220: 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73  umber of entries
a230: 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62   in the hash tab
a240: 6c 65 20 65 78 61 63 74 6c 79 20 65 71 75 61 6c  le exactly equal
a250: 73 0a 20 20 20 20 2a 2a 20 74 68 65 20 6e 75 6d  s.    ** the num
a260: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69  ber of entries i
a270: 6e 20 74 68 65 20 6d 61 70 70 69 6e 67 20 72 65  n the mapping re
a280: 67 69 6f 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  gion..    */.   
a290: 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 20   {.      int i; 
a2a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f            /* Loo
a2b0: 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20  p counter */.   
a2c0: 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 20 3d 20     int nEntry = 
a2d0: 30 3b 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66  0;  /* Number of
a2e0: 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20   entries in the 
a2f0: 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20  hash table */.  
a300: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48      for(i=0; i<H
a310: 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 20  ASHTABLE_NSLOT; 
a320: 69 2b 2b 29 7b 20 69 66 28 20 61 48 61 73 68 5b  i++){ if( aHash[
a330: 69 5d 20 29 20 6e 45 6e 74 72 79 2b 2b 3b 20 7d  i] ) nEntry++; }
a340: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6e  .      assert( n
a350: 45 6e 74 72 79 3d 3d 69 64 78 20 29 3b 0a 20 20  Entry==idx );.  
a360: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69    }..    /* Veri
a370: 66 79 20 74 68 61 74 20 74 68 65 20 65 76 65 72  fy that the ever
a380: 79 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d  y entry in the m
a390: 61 70 70 69 6e 67 20 72 65 67 69 6f 6e 20 69 73  apping region is
a3a0: 20 72 65 61 63 68 61 62 6c 65 0a 20 20 20 20 2a   reachable.    *
a3b0: 2a 20 76 69 61 20 74 68 65 20 68 61 73 68 20 74  * via the hash t
a3c0: 61 62 6c 65 2e 20 20 54 68 69 73 20 74 75 72 6e  able.  This turn
a3d0: 73 20 6f 75 74 20 74 6f 20 62 65 20 61 20 72 65  s out to be a re
a3e0: 61 6c 6c 79 2c 20 72 65 61 6c 6c 79 20 65 78 70  ally, really exp
a3f0: 65 6e 73 69 76 65 0a 20 20 20 20 2a 2a 20 74 68  ensive.    ** th
a400: 69 6e 67 20 74 6f 20 63 68 65 63 6b 2c 20 73 6f  ing to check, so
a410: 20 6f 6e 6c 79 20 64 6f 20 74 68 69 73 20 6f 63   only do this oc
a420: 63 61 73 69 6f 6e 61 6c 6c 79 20 2d 20 6e 6f 74  casionally - not
a430: 20 6f 6e 20 65 76 65 72 79 0a 20 20 20 20 2a 2a   on every.    **
a440: 20 69 74 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20   iteration..    
a450: 2a 2f 0a 20 20 20 20 69 66 28 20 28 69 64 78 26  */.    if( (idx&
a460: 30 78 33 66 66 29 3d 3d 30 20 29 7b 0a 20 20 20  0x3ff)==0 ){.   
a470: 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20     int i;       
a480: 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e      /* Loop coun
a490: 74 65 72 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72  ter */.      for
a4a0: 28 69 3d 31 3b 20 69 3c 3d 69 64 78 3b 20 69 2b  (i=1; i<=idx; i+
a4b0: 2b 29 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 28  +){.        for(
a4c0: 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 61 50 67  iKey=walHash(aPg
a4d0: 6e 6f 5b 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b  no[i]); aHash[iK
a4e0: 65 79 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78  ey]; iKey=walNex
a4f0: 74 48 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20  tHash(iKey)){.  
a500: 20 20 20 20 20 20 20 20 69 66 28 20 61 48 61 73          if( aHas
a510: 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 20 62 72 65  h[iKey]==i ) bre
a520: 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  ak;.        }.  
a530: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 61 48        assert( aH
a540: 61 73 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 3b 0a  ash[iKey]==i );.
a550: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 23 65        }.    }.#e
a560: 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45  ndif /* SQLITE_E
a570: 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f  NABLE_EXPENSIVE_
a580: 41 53 53 45 52 54 20 2a 2f 0a 20 20 7d 0a 0a 0a  ASSERT */.  }...
a590: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
a5a0: 0a 2f 2a 0a 2a 2a 20 52 65 63 6f 76 65 72 20 74  ./*.** Recover t
a5b0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 62 79 20  he wal-index by 
a5c0: 72 65 61 64 69 6e 67 20 74 68 65 20 77 72 69 74  reading the writ
a5d0: 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65  e-ahead log file
a5e0: 2e 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  . .**.** This ro
a5f0: 75 74 69 6e 65 20 66 69 72 73 74 20 74 72 69 65  utine first trie
a600: 73 20 74 6f 20 65 73 74 61 62 6c 69 73 68 20 61  s to establish a
a610: 6e 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b  n exclusive lock
a620: 20 6f 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69   on the.** wal-i
a630: 6e 64 65 78 20 74 6f 20 70 72 65 76 65 6e 74 20  ndex to prevent 
a640: 6f 74 68 65 72 20 74 68 72 65 61 64 73 2f 70 72  other threads/pr
a650: 6f 63 65 73 73 65 73 20 66 72 6f 6d 20 64 6f 69  ocesses from doi
a660: 6e 67 20 61 6e 79 74 68 69 6e 67 0a 2a 2a 20 77  ng anything.** w
a670: 69 74 68 20 74 68 65 20 57 41 4c 20 6f 72 20 77  ith the WAL or w
a680: 61 6c 2d 69 6e 64 65 78 20 77 68 69 6c 65 20 72  al-index while r
a690: 65 63 6f 76 65 72 79 20 69 73 20 72 75 6e 6e 69  ecovery is runni
a6a0: 6e 67 2e 20 20 54 68 65 0a 2a 2a 20 57 41 4c 5f  ng.  The.** WAL_
a6b0: 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20 69 73 20  RECOVER_LOCK is 
a6c0: 61 6c 73 6f 20 68 65 6c 64 20 73 6f 20 74 68 61  also held so tha
a6d0: 74 20 6f 74 68 65 72 20 74 68 72 65 61 64 73 20  t other threads 
a6e0: 77 69 6c 6c 20 6b 6e 6f 77 0a 2a 2a 20 74 68 61  will know.** tha
a6f0: 74 20 74 68 69 73 20 74 68 72 65 61 64 20 69 73  t this thread is
a700: 20 72 75 6e 6e 69 6e 67 20 72 65 63 6f 76 65 72   running recover
a710: 79 2e 20 20 49 66 20 75 6e 61 62 6c 65 20 74 6f  y.  If unable to
a720: 20 65 73 74 61 62 6c 69 73 68 0a 2a 2a 20 74 68   establish.** th
a730: 65 20 6e 65 63 65 73 73 61 72 79 20 6c 6f 63 6b  e necessary lock
a740: 73 2c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  s, this routine 
a750: 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 42  returns SQLITE_B
a760: 55 53 59 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  USY..*/.static i
a770: 6e 74 20 77 61 6c 49 6e 64 65 78 52 65 63 6f 76  nt walIndexRecov
a780: 65 72 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20  er(Wal *pWal){. 
a790: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
a7a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a7b0: 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20   /* Return Code 
a7c0: 2a 2f 0a 20 20 69 36 34 20 6e 53 69 7a 65 3b 20  */.  i64 nSize; 
a7d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a7e0: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
a7f0: 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33  log file */.  u3
a800: 32 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 32 5d  2 aFrameCksum[2]
a810: 20 3d 20 7b 30 2c 20 30 7d 3b 0a 20 20 69 6e 74   = {0, 0};.  int
a820: 20 69 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20   iLock;         
a830: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
a840: 4c 6f 63 6b 20 6f 66 66 73 65 74 20 74 6f 20 6c  Lock offset to l
a850: 6f 63 6b 20 66 6f 72 20 63 68 65 63 6b 70 6f 69  ock for checkpoi
a860: 6e 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 6f 63  nt */.  int nLoc
a870: 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
a880: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
a890: 72 20 6f 66 20 6c 6f 63 6b 73 20 74 6f 20 68 6f  r of locks to ho
a8a0: 6c 64 20 2a 2f 0a 0a 20 20 2f 2a 20 4f 62 74 61  ld */..  /* Obta
a8b0: 69 6e 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20  in an exclusive 
a8c0: 6c 6f 63 6b 20 6f 6e 20 61 6c 6c 20 62 79 74 65  lock on all byte
a8d0: 20 69 6e 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20   in the locking 
a8e0: 72 61 6e 67 65 20 6e 6f 74 20 61 6c 72 65 61 64  range not alread
a8f0: 79 0a 20 20 2a 2a 20 6c 6f 63 6b 65 64 20 62 79  y.  ** locked by
a900: 20 74 68 65 20 63 61 6c 6c 65 72 2e 20 54 68 65   the caller. The
a910: 20 63 61 6c 6c 65 72 20 69 73 20 67 75 61 72 61   caller is guara
a920: 6e 74 65 65 64 20 74 6f 20 68 61 76 65 20 6c 6f  nteed to have lo
a930: 63 6b 65 64 20 74 68 65 0a 20 20 2a 2a 20 57 41  cked the.  ** WA
a940: 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 62 79 74  L_WRITE_LOCK byt
a950: 65 2c 20 61 6e 64 20 6d 61 79 20 68 61 76 65 20  e, and may have 
a960: 61 6c 73 6f 20 6c 6f 63 6b 65 64 20 74 68 65 20  also locked the 
a970: 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 62 79  WAL_CKPT_LOCK by
a980: 74 65 2e 0a 20 20 2a 2a 20 49 66 20 73 75 63 63  te..  ** If succ
a990: 65 73 73 66 75 6c 2c 20 74 68 65 20 73 61 6d 65  essful, the same
a9a0: 20 62 79 74 65 73 20 74 68 61 74 20 61 72 65 20   bytes that are 
a9b0: 6c 6f 63 6b 65 64 20 68 65 72 65 20 61 72 65 20  locked here are 
a9c0: 75 6e 6c 6f 63 6b 65 64 20 62 65 66 6f 72 65 0a  unlocked before.
a9d0: 20 20 2a 2a 20 74 68 69 73 20 66 75 6e 63 74 69    ** this functi
a9e0: 6f 6e 20 72 65 74 75 72 6e 73 2e 0a 20 20 2a 2f  on returns..  */
a9f0: 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
aa00: 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 31 20 7c 7c 20  >ckptLock==1 || 
aa10: 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d  pWal->ckptLock==
aa20: 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 57  0 );.  assert( W
aa30: 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45  AL_ALL_BUT_WRITE
aa40: 3d 3d 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b  ==WAL_WRITE_LOCK
aa50: 2b 31 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  +1 );.  assert( 
aa60: 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 3d 3d 57  WAL_CKPT_LOCK==W
aa70: 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45  AL_ALL_BUT_WRITE
aa80: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57   );.  assert( pW
aa90: 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
aaa0: 0a 20 20 69 4c 6f 63 6b 20 3d 20 57 41 4c 5f 41  .  iLock = WAL_A
aab0: 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 2b 20 70  LL_BUT_WRITE + p
aac0: 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3b 0a 20  Wal->ckptLock;. 
aad0: 20 6e 4c 6f 63 6b 20 3d 20 53 51 4c 49 54 45 5f   nLock = SQLITE_
aae0: 53 48 4d 5f 4e 4c 4f 43 4b 20 2d 20 69 4c 6f 63  SHM_NLOCK - iLoc
aaf0: 6b 3b 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63  k;.  rc = walLoc
ab00: 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
ab10: 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b 0a   iLock, nLock);.
ab20: 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20    if( rc ){.    
ab30: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20  return rc;.  }. 
ab40: 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
ab50: 70 3a 20 72 65 63 6f 76 65 72 79 20 62 65 67 69  p: recovery begi
ab60: 6e 2e 2e 2e 5c 6e 22 2c 20 70 57 61 6c 29 29 3b  n...\n", pWal));
ab70: 0a 0a 20 20 6d 65 6d 73 65 74 28 26 70 57 61 6c  ..  memset(&pWal
ab80: 2d 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66  ->hdr, 0, sizeof
ab90: 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a  (WalIndexHdr));.
aba0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  .  rc = sqlite3O
abb0: 73 46 69 6c 65 53 69 7a 65 28 70 57 61 6c 2d 3e  sFileSize(pWal->
abc0: 70 57 61 6c 46 64 2c 20 26 6e 53 69 7a 65 29 3b  pWalFd, &nSize);
abd0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
abe0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 67 6f 74 6f  E_OK ){.    goto
abf0: 20 72 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b   recovery_error;
ac00: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6e 53 69 7a  .  }..  if( nSiz
ac10: 65 3e 57 41 4c 5f 48 44 52 53 49 5a 45 20 29 7b  e>WAL_HDRSIZE ){
ac20: 0a 20 20 20 20 75 38 20 61 42 75 66 5b 57 41 4c  .    u8 aBuf[WAL
ac30: 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20 20 20 20  _HDRSIZE];      
ac40: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20     /* Buffer to 
ac50: 6c 6f 61 64 20 57 41 4c 20 68 65 61 64 65 72 20  load WAL header 
ac60: 69 6e 74 6f 20 2a 2f 0a 20 20 20 20 75 38 20 2a  into */.    u8 *
ac70: 61 46 72 61 6d 65 20 3d 20 30 3b 20 20 20 20 20  aFrame = 0;     
ac80: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 6c            /* Mal
ac90: 6c 6f 63 27 64 20 62 75 66 66 65 72 20 74 6f 20  loc'd buffer to 
aca0: 6c 6f 61 64 20 65 6e 74 69 72 65 20 66 72 61 6d  load entire fram
acb0: 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20 73 7a 46  e */.    int szF
acc0: 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20  rame;           
acd0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
ace0: 20 6f 66 20 62 79 74 65 73 20 69 6e 20 62 75 66   of bytes in buf
acf0: 66 65 72 20 61 46 72 61 6d 65 5b 5d 20 2a 2f 0a  fer aFrame[] */.
ad00: 20 20 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20      u8 *aData;  
ad10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad20: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
ad30: 64 61 74 61 20 70 61 72 74 20 6f 66 20 61 46 72  data part of aFr
ad40: 61 6d 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20  ame buffer */.  
ad50: 20 20 69 6e 74 20 69 46 72 61 6d 65 3b 20 20 20    int iFrame;   
ad60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad70: 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6c 61 73 74  /* Index of last
ad80: 20 66 72 61 6d 65 20 72 65 61 64 20 2a 2f 0a 20   frame read */. 
ad90: 20 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 20     i64 iOffset; 
ada0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
adb0: 20 2f 2a 20 4e 65 78 74 20 6f 66 66 73 65 74 20   /* Next offset 
adc0: 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 6c 6f 67  to read from log
add0: 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 69 6e 74   file */.    int
ade0: 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20   szPage;        
adf0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
ae00: 67 65 20 73 69 7a 65 20 61 63 63 6f 72 64 69 6e  ge size accordin
ae10: 67 20 74 6f 20 74 68 65 20 6c 6f 67 20 2a 2f 0a  g to the log */.
ae20: 20 20 20 20 75 33 32 20 6d 61 67 69 63 3b 20 20      u32 magic;  
ae30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ae40: 20 20 2f 2a 20 4d 61 67 69 63 20 76 61 6c 75 65    /* Magic value
ae50: 20 72 65 61 64 20 66 72 6f 6d 20 57 41 4c 20 68   read from WAL h
ae60: 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 75 33 32  eader */.    u32
ae70: 20 76 65 72 73 69 6f 6e 3b 20 20 20 20 20 20 20   version;       
ae80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
ae90: 67 69 63 20 76 61 6c 75 65 20 72 65 61 64 20 66  gic value read f
aea0: 72 6f 6d 20 57 41 4c 20 68 65 61 64 65 72 20 2a  rom WAL header *
aeb0: 2f 0a 20 20 20 20 69 6e 74 20 69 73 56 61 6c 69  /.    int isVali
aec0: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
aed0: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 74      /* True if t
aee0: 68 69 73 20 66 72 61 6d 65 20 69 73 20 76 61 6c  his frame is val
aef0: 69 64 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 52 65  id */..    /* Re
af00: 61 64 20 69 6e 20 74 68 65 20 57 41 4c 20 68 65  ad in the WAL he
af10: 61 64 65 72 2e 20 2a 2f 0a 20 20 20 20 72 63 20  ader. */.    rc 
af20: 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28  = sqlite3OsRead(
af30: 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 42  pWal->pWalFd, aB
af40: 75 66 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2c  uf, WAL_HDRSIZE,
af50: 20 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21   0);.    if( rc!
af60: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
af70: 20 20 20 20 67 6f 74 6f 20 72 65 63 6f 76 65 72      goto recover
af80: 79 5f 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a 0a  y_error;.    }..
af90: 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 64 61      /* If the da
afa0: 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65  tabase page size
afb0: 20 69 73 20 6e 6f 74 20 61 20 70 6f 77 65 72 20   is not a power 
afc0: 6f 66 20 74 77 6f 2c 20 6f 72 20 69 73 20 67 72  of two, or is gr
afd0: 65 61 74 65 72 20 74 68 61 6e 0a 20 20 20 20 2a  eater than.    *
afe0: 2a 20 53 51 4c 49 54 45 5f 4d 41 58 5f 50 41 47  * SQLITE_MAX_PAG
aff0: 45 5f 53 49 5a 45 2c 20 63 6f 6e 63 6c 75 64 65  E_SIZE, conclude
b000: 20 74 68 61 74 20 74 68 65 20 57 41 4c 20 66 69   that the WAL fi
b010: 6c 65 20 63 6f 6e 74 61 69 6e 73 20 6e 6f 20 76  le contains no v
b020: 61 6c 69 64 20 0a 20 20 20 20 2a 2a 20 64 61 74  alid .    ** dat
b030: 61 2e 20 53 69 6d 69 6c 61 72 6c 79 2c 20 69 66  a. Similarly, if
b040: 20 74 68 65 20 27 6d 61 67 69 63 27 20 76 61 6c   the 'magic' val
b050: 75 65 20 69 73 20 69 6e 76 61 6c 69 64 2c 20 69  ue is invalid, i
b060: 67 6e 6f 72 65 20 74 68 65 20 77 68 6f 6c 65 0a  gnore the whole.
b070: 20 20 20 20 2a 2a 20 57 41 4c 20 66 69 6c 65 2e      ** WAL file.
b080: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d 61 67 69  .    */.    magi
b090: 63 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62  c = sqlite3Get4b
b0a0: 79 74 65 28 26 61 42 75 66 5b 30 5d 29 3b 0a 20  yte(&aBuf[0]);. 
b0b0: 20 20 20 73 7a 50 61 67 65 20 3d 20 73 71 6c 69     szPage = sqli
b0c0: 74 65 33 47 65 74 34 62 79 74 65 28 26 61 42 75  te3Get4byte(&aBu
b0d0: 66 5b 38 5d 29 3b 0a 20 20 20 20 69 66 28 20 28  f[8]);.    if( (
b0e0: 6d 61 67 69 63 26 30 78 46 46 46 46 46 46 46 45  magic&0xFFFFFFFE
b0f0: 29 21 3d 57 41 4c 5f 4d 41 47 49 43 20 0a 20 20  )!=WAL_MAGIC .  
b100: 20 20 20 7c 7c 20 73 7a 50 61 67 65 26 28 73 7a     || szPage&(sz
b110: 50 61 67 65 2d 31 29 20 0a 20 20 20 20 20 7c 7c  Page-1) .     ||
b120: 20 73 7a 50 61 67 65 3e 53 51 4c 49 54 45 5f 4d   szPage>SQLITE_M
b130: 41 58 5f 50 41 47 45 5f 53 49 5a 45 20 0a 20 20  AX_PAGE_SIZE .  
b140: 20 20 20 7c 7c 20 73 7a 50 61 67 65 3c 35 31 32     || szPage<512
b150: 20 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 67   .    ){.      g
b160: 6f 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20  oto finished;.  
b170: 20 20 7d 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64    }.    pWal->hd
b180: 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 20 3d 20  r.bigEndCksum = 
b190: 28 75 38 29 28 6d 61 67 69 63 26 30 78 30 30 30  (u8)(magic&0x000
b1a0: 30 30 30 30 31 29 3b 0a 20 20 20 20 70 57 61 6c  00001);.    pWal
b1b0: 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67  ->szPage = szPag
b1c0: 65 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 6e 43 6b  e;.    pWal->nCk
b1d0: 70 74 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34  pt = sqlite3Get4
b1e0: 62 79 74 65 28 26 61 42 75 66 5b 31 32 5d 29 3b  byte(&aBuf[12]);
b1f0: 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 57 61  .    memcpy(&pWa
b200: 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 26 61  l->hdr.aSalt, &a
b210: 42 75 66 5b 31 36 5d 2c 20 38 29 3b 0a 0a 20 20  Buf[16], 8);..  
b220: 20 20 2f 2a 20 56 65 72 69 66 79 20 74 68 61 74    /* Verify that
b230: 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72 20   the WAL header 
b240: 63 68 65 63 6b 73 75 6d 20 69 73 20 63 6f 72 72  checksum is corr
b250: 65 63 74 20 2a 2f 0a 20 20 20 20 77 61 6c 43 68  ect */.    walCh
b260: 65 63 6b 73 75 6d 42 79 74 65 73 28 70 57 61 6c  ecksumBytes(pWal
b270: 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75  ->hdr.bigEndCksu
b280: 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e 44  m==SQLITE_BIGEND
b290: 49 41 4e 2c 20 0a 20 20 20 20 20 20 20 20 61 42  IAN, .        aB
b2a0: 75 66 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2d  uf, WAL_HDRSIZE-
b2b0: 32 2a 34 2c 20 30 2c 20 70 57 61 6c 2d 3e 68 64  2*4, 0, pWal->hd
b2c0: 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 0a 20 20  r.aFrameCksum.  
b2d0: 20 20 29 3b 0a 20 20 20 20 69 66 28 20 70 57 61    );.    if( pWa
b2e0: 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
b2f0: 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65 33 47 65  um[0]!=sqlite3Ge
b300: 74 34 62 79 74 65 28 26 61 42 75 66 5b 32 34 5d  t4byte(&aBuf[24]
b310: 29 0a 20 20 20 20 20 7c 7c 20 70 57 61 6c 2d 3e  ).     || pWal->
b320: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
b330: 31 5d 21 3d 73 71 6c 69 74 65 33 47 65 74 34 62  1]!=sqlite3Get4b
b340: 79 74 65 28 26 61 42 75 66 5b 32 38 5d 29 0a 20  yte(&aBuf[28]). 
b350: 20 20 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f     ){.      goto
b360: 20 66 69 6e 69 73 68 65 64 3b 0a 20 20 20 20 7d   finished;.    }
b370: 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20  ..    /* Verify 
b380: 74 68 61 74 20 74 68 65 20 76 65 72 73 69 6f 6e  that the version
b390: 20 6e 75 6d 62 65 72 20 6f 6e 20 74 68 65 20 57   number on the W
b3a0: 41 4c 20 66 6f 72 6d 61 74 20 69 73 20 6f 6e 65  AL format is one
b3b0: 20 74 68 61 74 0a 20 20 20 20 2a 2a 20 61 72 65   that.    ** are
b3c0: 20 61 62 6c 65 20 74 6f 20 75 6e 64 65 72 73 74   able to underst
b3d0: 61 6e 64 20 2a 2f 0a 20 20 20 20 76 65 72 73 69  and */.    versi
b3e0: 6f 6e 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34  on = sqlite3Get4
b3f0: 62 79 74 65 28 26 61 42 75 66 5b 34 5d 29 3b 0a  byte(&aBuf[4]);.
b400: 20 20 20 20 69 66 28 20 76 65 72 73 69 6f 6e 21      if( version!
b410: 3d 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49 4f 4e  =WAL_MAX_VERSION
b420: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
b430: 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 5f 42  QLITE_CANTOPEN_B
b440: 4b 50 54 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20  KPT;.      goto 
b450: 66 69 6e 69 73 68 65 64 3b 0a 20 20 20 20 7d 0a  finished;.    }.
b460: 0a 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f 63 20 61  .    /* Malloc a
b470: 20 62 75 66 66 65 72 20 74 6f 20 72 65 61 64 20   buffer to read 
b480: 66 72 61 6d 65 73 20 69 6e 74 6f 2e 20 2a 2f 0a  frames into. */.
b490: 20 20 20 20 73 7a 46 72 61 6d 65 20 3d 20 73 7a      szFrame = sz
b4a0: 50 61 67 65 20 2b 20 57 41 4c 5f 46 52 41 4d 45  Page + WAL_FRAME
b4b0: 5f 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 61 46  _HDRSIZE;.    aF
b4c0: 72 61 6d 65 20 3d 20 28 75 38 20 2a 29 73 71 6c  rame = (u8 *)sql
b4d0: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 7a 46 72  ite3_malloc(szFr
b4e0: 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21 61  ame);.    if( !a
b4f0: 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 20 20 72  Frame ){.      r
b500: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
b510: 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 72 65 63  ;.      goto rec
b520: 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20 20 20  overy_error;.   
b530: 20 7d 0a 20 20 20 20 61 44 61 74 61 20 3d 20 26   }.    aData = &
b540: 61 46 72 61 6d 65 5b 57 41 4c 5f 46 52 41 4d 45  aFrame[WAL_FRAME
b550: 5f 48 44 52 53 49 5a 45 5d 3b 0a 0a 20 20 20 20  _HDRSIZE];..    
b560: 2f 2a 20 52 65 61 64 20 61 6c 6c 20 66 72 61 6d  /* Read all fram
b570: 65 73 20 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20  es from the log 
b580: 66 69 6c 65 2e 20 2a 2f 0a 20 20 20 20 69 46 72  file. */.    iFr
b590: 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72  ame = 0;.    for
b5a0: 28 69 4f 66 66 73 65 74 3d 57 41 4c 5f 48 44 52  (iOffset=WAL_HDR
b5b0: 53 49 5a 45 3b 20 28 69 4f 66 66 73 65 74 2b 73  SIZE; (iOffset+s
b5c0: 7a 46 72 61 6d 65 29 3c 3d 6e 53 69 7a 65 3b 20  zFrame)<=nSize; 
b5d0: 69 4f 66 66 73 65 74 2b 3d 73 7a 46 72 61 6d 65  iOffset+=szFrame
b5e0: 29 7b 0a 20 20 20 20 20 20 75 33 32 20 70 67 6e  ){.      u32 pgn
b5f0: 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o;              
b600: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
b610: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 66 6f 72   page number for
b620: 20 66 72 61 6d 65 20 2a 2f 0a 20 20 20 20 20 20   frame */.      
b630: 75 33 32 20 6e 54 72 75 6e 63 61 74 65 3b 20 20  u32 nTruncate;  
b640: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 64              /* d
b650: 62 73 69 7a 65 20 66 69 65 6c 64 20 66 72 6f 6d  bsize field from
b660: 20 66 72 61 6d 65 20 68 65 61 64 65 72 20 2a 2f   frame header */
b670: 0a 0a 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20  ..      /* Read 
b680: 61 6e 64 20 64 65 63 6f 64 65 20 74 68 65 20 6e  and decode the n
b690: 65 78 74 20 6c 6f 67 20 66 72 61 6d 65 2e 20 2a  ext log frame. *
b6a0: 2f 0a 20 20 20 20 20 20 69 46 72 61 6d 65 2b 2b  /.      iFrame++
b6b0: 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  ;.      rc = sql
b6c0: 69 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d  ite3OsRead(pWal-
b6d0: 3e 70 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c  >pWalFd, aFrame,
b6e0: 20 73 7a 46 72 61 6d 65 2c 20 69 4f 66 66 73 65   szFrame, iOffse
b6f0: 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  t);.      if( rc
b700: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72  !=SQLITE_OK ) br
b710: 65 61 6b 3b 0a 20 20 20 20 20 20 69 73 56 61 6c  eak;.      isVal
b720: 69 64 20 3d 20 77 61 6c 44 65 63 6f 64 65 46 72  id = walDecodeFr
b730: 61 6d 65 28 70 57 61 6c 2c 20 26 70 67 6e 6f 2c  ame(pWal, &pgno,
b740: 20 26 6e 54 72 75 6e 63 61 74 65 2c 20 61 44 61   &nTruncate, aDa
b750: 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20 20  ta, aFrame);.   
b760: 20 20 20 69 66 28 20 21 69 73 56 61 6c 69 64 20     if( !isValid 
b770: 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 72  ) break;.      r
b780: 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65  c = walIndexAppe
b790: 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c  nd(pWal, iFrame,
b7a0: 20 70 67 6e 6f 29 3b 0a 20 20 20 20 20 20 69 66   pgno);.      if
b7b0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
b7c0: 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20  ) break;..      
b7d0: 2f 2a 20 49 66 20 6e 54 72 75 6e 63 61 74 65 20  /* If nTruncate 
b7e0: 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 69  is non-zero, thi
b7f0: 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 20 72 65  s is a commit re
b800: 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 20 20 69  cord. */.      i
b810: 66 28 20 6e 54 72 75 6e 63 61 74 65 20 29 7b 0a  f( nTruncate ){.
b820: 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64          pWal->hd
b830: 72 2e 6d 78 46 72 61 6d 65 20 3d 20 69 46 72 61  r.mxFrame = iFra
b840: 6d 65 3b 0a 20 20 20 20 20 20 20 20 70 57 61 6c  me;.        pWal
b850: 2d 3e 68 64 72 2e 6e 50 61 67 65 20 3d 20 6e 54  ->hdr.nPage = nT
b860: 72 75 6e 63 61 74 65 3b 0a 20 20 20 20 20 20 20  runcate;.       
b870: 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67   pWal->hdr.szPag
b880: 65 20 3d 20 28 75 31 36 29 28 28 73 7a 50 61 67  e = (u16)((szPag
b890: 65 26 30 78 66 66 30 30 29 20 7c 20 28 73 7a 50  e&0xff00) | (szP
b8a0: 61 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20 20 20  age>>16));.     
b8b0: 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50     testcase( szP
b8c0: 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20  age<=32768 );.  
b8d0: 20 20 20 20 20 20 74 65 73 74 63 61 73 65 28 20        testcase( 
b8e0: 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20 29 3b  szPage>=65536 );
b8f0: 0a 20 20 20 20 20 20 20 20 61 46 72 61 6d 65 43  .        aFrameC
b900: 6b 73 75 6d 5b 30 5d 20 3d 20 70 57 61 6c 2d 3e  ksum[0] = pWal->
b910: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
b920: 30 5d 3b 0a 20 20 20 20 20 20 20 20 61 46 72 61  0];.        aFra
b930: 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 70 57 61  meCksum[1] = pWa
b940: 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
b950: 75 6d 5b 31 5d 3b 0a 20 20 20 20 20 20 7d 0a 20  um[1];.      }. 
b960: 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65     }..    sqlite
b970: 33 5f 66 72 65 65 28 61 46 72 61 6d 65 29 3b 0a  3_free(aFrame);.
b980: 20 20 7d 0a 0a 66 69 6e 69 73 68 65 64 3a 0a 20    }..finished:. 
b990: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
b9a0: 4f 4b 20 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69  OK ){.    volati
b9b0: 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a  le WalCkptInfo *
b9c0: 70 49 6e 66 6f 3b 0a 20 20 20 20 69 6e 74 20 69  pInfo;.    int i
b9d0: 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  ;.    pWal->hdr.
b9e0: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d  aFrameCksum[0] =
b9f0: 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b   aFrameCksum[0];
ba00: 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61  .    pWal->hdr.a
ba10: 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20  FrameCksum[1] = 
ba20: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a  aFrameCksum[1];.
ba30: 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72 69 74      walIndexWrit
ba40: 65 48 64 72 28 70 57 61 6c 29 3b 0a 0a 20 20 20  eHdr(pWal);..   
ba50: 20 2f 2a 20 52 65 73 65 74 20 74 68 65 20 63 68   /* Reset the ch
ba60: 65 63 6b 70 6f 69 6e 74 2d 68 65 61 64 65 72 2e  eckpoint-header.
ba70: 20 54 68 69 73 20 69 73 20 73 61 66 65 20 62 65   This is safe be
ba80: 63 61 75 73 65 20 74 68 69 73 20 74 68 72 65 61  cause this threa
ba90: 64 20 69 73 20 0a 20 20 20 20 2a 2a 20 63 75 72  d is .    ** cur
baa0: 72 65 6e 74 6c 79 20 68 6f 6c 64 69 6e 67 20 6c  rently holding l
bab0: 6f 63 6b 73 20 74 68 61 74 20 65 78 63 6c 75 64  ocks that exclud
bac0: 65 20 61 6c 6c 20 6f 74 68 65 72 20 72 65 61 64  e all other read
bad0: 65 72 73 2c 20 77 72 69 74 65 72 73 20 61 6e 64  ers, writers and
bae0: 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69  .    ** checkpoi
baf0: 6e 74 65 72 73 2e 0a 20 20 20 20 2a 2f 0a 20 20  nters..    */.  
bb00: 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70    pInfo = walCkp
bb10: 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20  tInfo(pWal);.   
bb20: 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
bb30: 6c 20 3d 20 30 3b 0a 20 20 20 20 70 49 6e 66 6f  l = 0;.    pInfo
bb40: 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20 3d  ->aReadMark[0] =
bb50: 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b   0;.    for(i=1;
bb60: 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
bb70: 69 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61  i++) pInfo->aRea
bb80: 64 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d  dMark[i] = READM
bb90: 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20  ARK_NOT_USED;.  
bba0: 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e    if( pWal->hdr.
bbb0: 6d 78 46 72 61 6d 65 20 29 20 70 49 6e 66 6f 2d  mxFrame ) pInfo-
bbc0: 3e 61 52 65 61 64 4d 61 72 6b 5b 31 5d 20 3d 20  >aReadMark[1] = 
bbd0: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
bbe0: 65 3b 0a 0a 20 20 20 20 2f 2a 20 49 66 20 6d 6f  e;..    /* If mo
bbf0: 72 65 20 74 68 61 6e 20 6f 6e 65 20 66 72 61 6d  re than one fram
bc00: 65 20 77 61 73 20 72 65 63 6f 76 65 72 65 64 20  e was recovered 
bc10: 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20 66 69 6c  from the log fil
bc20: 65 2c 20 72 65 70 6f 72 74 20 61 6e 0a 20 20 20  e, report an.   
bc30: 20 2a 2a 20 65 76 65 6e 74 20 76 69 61 20 73 71   ** event via sq
bc40: 6c 69 74 65 33 5f 6c 6f 67 28 29 2e 20 54 68 69  lite3_log(). Thi
bc50: 73 20 69 73 20 74 6f 20 68 65 6c 70 20 77 69 74  s is to help wit
bc60: 68 20 69 64 65 6e 74 69 66 79 69 6e 67 20 70 65  h identifying pe
bc70: 72 66 6f 72 6d 61 6e 63 65 0a 20 20 20 20 2a 2a  rformance.    **
bc80: 20 70 72 6f 62 6c 65 6d 73 20 63 61 75 73 65 64   problems caused
bc90: 20 62 79 20 61 70 70 6c 69 63 61 74 69 6f 6e 73   by applications
bca0: 20 72 6f 75 74 69 6e 65 6c 79 20 73 68 75 74 74   routinely shutt
bcb0: 69 6e 67 20 64 6f 77 6e 20 77 69 74 68 6f 75 74  ing down without
bcc0: 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69  .    ** checkpoi
bcd0: 6e 74 69 6e 67 20 74 68 65 20 6c 6f 67 20 66 69  nting the log fi
bce0: 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  le..    */.    i
bcf0: 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61  f( pWal->hdr.nPa
bd00: 67 65 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  ge ){.      sqli
bd10: 74 65 33 5f 6c 6f 67 28 53 51 4c 49 54 45 5f 4e  te3_log(SQLITE_N
bd20: 4f 54 49 43 45 5f 52 45 43 4f 56 45 52 5f 57 41  OTICE_RECOVER_WA
bd30: 4c 2c 0a 20 20 20 20 20 20 20 20 20 20 22 72 65  L,.          "re
bd40: 63 6f 76 65 72 65 64 20 25 64 20 66 72 61 6d 65  covered %d frame
bd50: 73 20 66 72 6f 6d 20 57 41 4c 20 66 69 6c 65 20  s from WAL file 
bd60: 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20 20 70  %s",.          p
bd70: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
bd80: 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65  , pWal->zWalName
bd90: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a  .      );.    }.
bda0: 20 20 7d 0a 0a 72 65 63 6f 76 65 72 79 5f 65 72    }..recovery_er
bdb0: 72 6f 72 3a 0a 20 20 57 41 4c 54 52 41 43 45 28  ror:.  WALTRACE(
bdc0: 28 22 57 41 4c 25 70 3a 20 72 65 63 6f 76 65 72  ("WAL%p: recover
bdd0: 79 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  y %s\n", pWal, r
bde0: 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
bdf0: 6f 6b 22 29 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f  ok"));.  walUnlo
be00: 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
be10: 2c 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b  , iLock, nLock);
be20: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
be30: 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20  ./*.** Close an 
be40: 6f 70 65 6e 20 77 61 6c 2d 69 6e 64 65 78 2e 0a  open wal-index..
be50: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
be60: 61 6c 49 6e 64 65 78 43 6c 6f 73 65 28 57 61 6c  alIndexClose(Wal
be70: 20 2a 70 57 61 6c 2c 20 69 6e 74 20 69 73 44 65   *pWal, int isDe
be80: 6c 65 74 65 29 7b 0a 20 20 69 66 28 20 70 57 61  lete){.  if( pWa
be90: 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
bea0: 3d 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59  ==WAL_HEAPMEMORY
beb0: 5f 4d 4f 44 45 20 29 7b 0a 20 20 20 20 69 6e 74  _MODE ){.    int
bec0: 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b   i;.    for(i=0;
bed0: 20 69 3c 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61   i<pWal->nWiData
bee0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 71  ; i++){.      sq
bef0: 6c 69 74 65 33 5f 66 72 65 65 28 28 76 6f 69 64  lite3_free((void
bf00: 20 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44 61 74   *)pWal->apWiDat
bf10: 61 5b 69 5d 29 3b 0a 20 20 20 20 20 20 70 57 61  a[i]);.      pWa
bf20: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 5d 20 3d  l->apWiData[i] =
bf30: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73   0;.    }.  }els
bf40: 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  e{.    sqlite3Os
bf50: 53 68 6d 55 6e 6d 61 70 28 70 57 61 6c 2d 3e 70  ShmUnmap(pWal->p
bf60: 44 62 46 64 2c 20 69 73 44 65 6c 65 74 65 29 3b  DbFd, isDelete);
bf70: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4f  .  }.}../* .** O
bf80: 70 65 6e 20 61 20 63 6f 6e 6e 65 63 74 69 6f 6e  pen a connection
bf90: 20 74 6f 20 74 68 65 20 57 41 4c 20 66 69 6c 65   to the WAL file
bfa0: 20 7a 57 61 6c 4e 61 6d 65 2e 20 54 68 65 20 64   zWalName. The d
bfb0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 6d 75 73  atabase file mus
bfc0: 74 20 0a 2a 2a 20 61 6c 72 65 61 64 79 20 62 65  t .** already be
bfd0: 20 6f 70 65 6e 65 64 20 6f 6e 20 63 6f 6e 6e 65   opened on conne
bfe0: 63 74 69 6f 6e 20 70 44 62 46 64 2e 20 54 68 65  ction pDbFd. The
bff0: 20 62 75 66 66 65 72 20 74 68 61 74 20 7a 57 61   buffer that zWa
c000: 6c 4e 61 6d 65 20 70 6f 69 6e 74 73 0a 2a 2a 20  lName points.** 
c010: 74 6f 20 6d 75 73 74 20 72 65 6d 61 69 6e 20 76  to must remain v
c020: 61 6c 69 64 20 66 6f 72 20 74 68 65 20 6c 69 66  alid for the lif
c030: 65 74 69 6d 65 20 6f 66 20 74 68 65 20 72 65 74  etime of the ret
c040: 75 72 6e 65 64 20 57 61 6c 2a 20 68 61 6e 64 6c  urned Wal* handl
c050: 65 2e 0a 2a 2a 0a 2a 2a 20 41 20 53 48 41 52 45  e..**.** A SHARE
c060: 44 20 6c 6f 63 6b 20 73 68 6f 75 6c 64 20 62 65  D lock should be
c070: 20 68 65 6c 64 20 6f 6e 20 74 68 65 20 64 61 74   held on the dat
c080: 61 62 61 73 65 20 66 69 6c 65 20 77 68 65 6e 20  abase file when 
c090: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a  this function.**
c0a0: 20 69 73 20 63 61 6c 6c 65 64 2e 20 54 68 65 20   is called. The 
c0b0: 70 75 72 70 6f 73 65 20 6f 66 20 74 68 69 73 20  purpose of this 
c0c0: 53 48 41 52 45 44 20 6c 6f 63 6b 20 69 73 20 74  SHARED lock is t
c0d0: 6f 20 70 72 65 76 65 6e 74 20 61 6e 79 20 6f 74  o prevent any ot
c0e0: 68 65 72 0a 2a 2a 20 63 6c 69 65 6e 74 20 66 72  her.** client fr
c0f0: 6f 6d 20 75 6e 6c 69 6e 6b 69 6e 67 20 74 68 65  om unlinking the
c100: 20 57 41 4c 20 6f 72 20 77 61 6c 2d 69 6e 64 65   WAL or wal-inde
c110: 78 20 66 69 6c 65 2e 20 49 66 20 61 6e 6f 74 68  x file. If anoth
c120: 65 72 20 70 72 6f 63 65 73 73 0a 2a 2a 20 77 65  er process.** we
c130: 72 65 20 74 6f 20 64 6f 20 74 68 69 73 20 6a 75  re to do this ju
c140: 73 74 20 61 66 74 65 72 20 74 68 69 73 20 63 6c  st after this cl
c150: 69 65 6e 74 20 6f 70 65 6e 65 64 20 6f 6e 65 20  ient opened one 
c160: 6f 66 20 74 68 65 73 65 20 66 69 6c 65 73 2c 20  of these files, 
c170: 74 68 65 0a 2a 2a 20 73 79 73 74 65 6d 20 77 6f  the.** system wo
c180: 75 6c 64 20 62 65 20 62 61 64 6c 79 20 62 72 6f  uld be badly bro
c190: 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ken..**.** If th
c1a0: 65 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 73 75  e log file is su
c1b0: 63 63 65 73 73 66 75 6c 6c 79 20 6f 70 65 6e 65  ccessfully opene
c1c0: 64 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20  d, SQLITE_OK is 
c1d0: 72 65 74 75 72 6e 65 64 20 61 6e 64 20 0a 2a 2a  returned and .**
c1e0: 20 2a 70 70 57 61 6c 20 69 73 20 73 65 74 20 74   *ppWal is set t
c1f0: 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20 6e 65 77  o point to a new
c200: 20 57 41 4c 20 68 61 6e 64 6c 65 2e 20 49 66 20   WAL handle. If 
c210: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  an error occurs,
c220: 0a 2a 2a 20 61 6e 20 53 51 4c 69 74 65 20 65 72  .** an SQLite er
c230: 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75  ror code is retu
c240: 72 6e 65 64 20 61 6e 64 20 2a 70 70 57 61 6c 20  rned and *ppWal 
c250: 69 73 20 6c 65 66 74 20 75 6e 6d 6f 64 69 66 69  is left unmodifi
c260: 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ed..*/.int sqlit
c270: 65 33 57 61 6c 4f 70 65 6e 28 0a 20 20 73 71 6c  e3WalOpen(.  sql
c280: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
c290: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c2a0: 76 66 73 20 6d 6f 64 75 6c 65 20 74 6f 20 6f 70  vfs module to op
c2b0: 65 6e 20 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69  en wal and wal-i
c2c0: 6e 64 65 78 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ndex */.  sqlite
c2d0: 33 5f 66 69 6c 65 20 2a 70 44 62 46 64 2c 20 20  3_file *pDbFd,  
c2e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
c2f0: 20 6f 70 65 6e 20 64 61 74 61 62 61 73 65 20 66   open database f
c300: 69 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ile */.  const c
c310: 68 61 72 20 2a 7a 57 61 6c 4e 61 6d 65 2c 20 20  har *zWalName,  
c320: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
c330: 20 6f 66 20 74 68 65 20 57 41 4c 20 66 69 6c 65   of the WAL file
c340: 20 2a 2f 0a 20 20 69 6e 74 20 62 4e 6f 53 68 6d   */.  int bNoShm
c350: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
c360: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f        /* True to
c370: 20 72 75 6e 20 69 6e 20 68 65 61 70 2d 6d 65 6d   run in heap-mem
c380: 6f 72 79 20 6d 6f 64 65 20 2a 2f 0a 20 20 69 36  ory mode */.  i6
c390: 34 20 6d 78 57 61 6c 53 69 7a 65 2c 20 20 20 20  4 mxWalSize,    
c3a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c3b0: 20 54 72 75 6e 63 61 74 65 20 57 41 4c 20 74 6f   Truncate WAL to
c3c0: 20 74 68 69 73 20 73 69 7a 65 20 6f 6e 20 72 65   this size on re
c3d0: 73 65 74 20 2a 2f 0a 20 20 57 61 6c 20 2a 2a 70  set */.  Wal **p
c3e0: 70 57 61 6c 20 20 20 20 20 20 20 20 20 20 20 20  pWal            
c3f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
c400: 20 41 6c 6c 6f 63 61 74 65 64 20 57 61 6c 20 68   Allocated Wal h
c410: 61 6e 64 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e  andle */.){.  in
c420: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
c430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c440: 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a   Return Code */.
c450: 20 20 57 61 6c 20 2a 70 52 65 74 3b 20 20 20 20    Wal *pRet;    
c460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c470: 20 20 2f 2a 20 4f 62 6a 65 63 74 20 74 6f 20 61    /* Object to a
c480: 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65 74 75  llocate and retu
c490: 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67  rn */.  int flag
c4a0: 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s;              
c4b0: 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73          /* Flags
c4c0: 20 70 61 73 73 65 64 20 74 6f 20 4f 73 4f 70 65   passed to OsOpe
c4d0: 6e 28 29 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  n() */..  assert
c4e0: 28 20 7a 57 61 6c 4e 61 6d 65 20 26 26 20 7a 57  ( zWalName && zW
c4f0: 61 6c 4e 61 6d 65 5b 30 5d 20 29 3b 0a 20 20 61  alName[0] );.  a
c500: 73 73 65 72 74 28 20 70 44 62 46 64 20 29 3b 0a  ssert( pDbFd );.
c510: 0a 20 20 2f 2a 20 49 6e 20 74 68 65 20 61 6d 61  .  /* In the ama
c520: 6c 67 61 6d 61 74 69 6f 6e 2c 20 74 68 65 20 6f  lgamation, the o
c530: 73 5f 75 6e 69 78 2e 63 20 61 6e 64 20 6f 73 5f  s_unix.c and os_
c540: 77 69 6e 2e 63 20 73 6f 75 72 63 65 20 66 69 6c  win.c source fil
c550: 65 73 20 63 6f 6d 65 20 62 65 66 6f 72 65 0a 20  es come before. 
c560: 20 2a 2a 20 74 68 69 73 20 73 6f 75 72 63 65 20   ** this source 
c570: 66 69 6c 65 2e 20 20 56 65 72 69 66 79 20 74 68  file.  Verify th
c580: 61 74 20 74 68 65 20 23 64 65 66 69 6e 65 73 20  at the #defines 
c590: 6f 66 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 62  of the locking b
c5a0: 79 74 65 20 6f 66 66 73 65 74 73 0a 20 20 2a 2a  yte offsets.  **
c5b0: 20 69 6e 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e   in os_unix.c an
c5c0: 64 20 6f 73 5f 77 69 6e 2e 63 20 61 67 72 65 65  d os_win.c agree
c5d0: 20 77 69 74 68 20 74 68 65 20 57 41 4c 49 4e 44   with the WALIND
c5e0: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 76  EX_LOCK_OFFSET v
c5f0: 61 6c 75 65 2e 0a 20 20 2a 2f 0a 23 69 66 64 65  alue..  */.#ifde
c600: 66 20 57 49 4e 5f 53 48 4d 5f 42 41 53 45 0a 20  f WIN_SHM_BASE. 
c610: 20 61 73 73 65 72 74 28 20 57 49 4e 5f 53 48 4d   assert( WIN_SHM
c620: 5f 42 41 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f  _BASE==WALINDEX_
c630: 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23  LOCK_OFFSET );.#
c640: 65 6e 64 69 66 0a 23 69 66 64 65 66 20 55 4e 49  endif.#ifdef UNI
c650: 58 5f 53 48 4d 5f 42 41 53 45 0a 20 20 61 73 73  X_SHM_BASE.  ass
c660: 65 72 74 28 20 55 4e 49 58 5f 53 48 4d 5f 42 41  ert( UNIX_SHM_BA
c670: 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f 43  SE==WALINDEX_LOC
c680: 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65 6e 64  K_OFFSET );.#end
c690: 69 66 0a 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61  if...  /* Alloca
c6a0: 74 65 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f  te an instance o
c6b0: 66 20 73 74 72 75 63 74 20 57 61 6c 20 74 6f 20  f struct Wal to 
c6c0: 72 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 2a 70 70  return. */.  *pp
c6d0: 57 61 6c 20 3d 20 30 3b 0a 20 20 70 52 65 74 20  Wal = 0;.  pRet 
c6e0: 3d 20 28 57 61 6c 2a 29 73 71 6c 69 74 65 33 4d  = (Wal*)sqlite3M
c6f0: 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66  allocZero(sizeof
c700: 28 57 61 6c 29 20 2b 20 70 56 66 73 2d 3e 73 7a  (Wal) + pVfs->sz
c710: 4f 73 46 69 6c 65 29 3b 0a 20 20 69 66 28 20 21  OsFile);.  if( !
c720: 70 52 65 74 20 29 7b 0a 20 20 20 20 72 65 74 75  pRet ){.    retu
c730: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
c740: 0a 20 20 7d 0a 0a 20 20 70 52 65 74 2d 3e 70 56  .  }..  pRet->pV
c750: 66 73 20 3d 20 70 56 66 73 3b 0a 20 20 70 52 65  fs = pVfs;.  pRe
c760: 74 2d 3e 70 57 61 6c 46 64 20 3d 20 28 73 71 6c  t->pWalFd = (sql
c770: 69 74 65 33 5f 66 69 6c 65 20 2a 29 26 70 52 65  ite3_file *)&pRe
c780: 74 5b 31 5d 3b 0a 20 20 70 52 65 74 2d 3e 70 44  t[1];.  pRet->pD
c790: 62 46 64 20 3d 20 70 44 62 46 64 3b 0a 20 20 70  bFd = pDbFd;.  p
c7a0: 52 65 74 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20  Ret->readLock = 
c7b0: 2d 31 3b 0a 20 20 70 52 65 74 2d 3e 6d 78 57 61  -1;.  pRet->mxWa
c7c0: 6c 53 69 7a 65 20 3d 20 6d 78 57 61 6c 53 69 7a  lSize = mxWalSiz
c7d0: 65 3b 0a 20 20 70 52 65 74 2d 3e 7a 57 61 6c 4e  e;.  pRet->zWalN
c7e0: 61 6d 65 20 3d 20 7a 57 61 6c 4e 61 6d 65 3b 0a  ame = zWalName;.
c7f0: 20 20 70 52 65 74 2d 3e 73 79 6e 63 48 65 61 64    pRet->syncHead
c800: 65 72 20 3d 20 31 3b 0a 20 20 70 52 65 74 2d 3e  er = 1;.  pRet->
c810: 70 61 64 54 6f 53 65 63 74 6f 72 42 6f 75 6e 64  padToSectorBound
c820: 61 72 79 20 3d 20 31 3b 0a 20 20 70 52 65 74 2d  ary = 1;.  pRet-
c830: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d  >exclusiveMode =
c840: 20 28 62 4e 6f 53 68 6d 20 3f 20 57 41 4c 5f 48   (bNoShm ? WAL_H
c850: 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 3a 20  EAPMEMORY_MODE: 
c860: 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 29  WAL_NORMAL_MODE)
c870: 3b 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 66 69 6c  ;..  /* Open fil
c880: 65 20 68 61 6e 64 6c 65 20 6f 6e 20 74 68 65 20  e handle on the 
c890: 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20  write-ahead log 
c8a0: 66 69 6c 65 2e 20 2a 2f 0a 20 20 66 6c 61 67 73  file. */.  flags
c8b0: 20 3d 20 28 53 51 4c 49 54 45 5f 4f 50 45 4e 5f   = (SQLITE_OPEN_
c8c0: 52 45 41 44 57 52 49 54 45 7c 53 51 4c 49 54 45  READWRITE|SQLITE
c8d0: 5f 4f 50 45 4e 5f 43 52 45 41 54 45 7c 53 51 4c  _OPEN_CREATE|SQL
c8e0: 49 54 45 5f 4f 50 45 4e 5f 57 41 4c 29 3b 0a 20  ITE_OPEN_WAL);. 
c8f0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 4f   rc = sqlite3OsO
c900: 70 65 6e 28 70 56 66 73 2c 20 7a 57 61 6c 4e 61  pen(pVfs, zWalNa
c910: 6d 65 2c 20 70 52 65 74 2d 3e 70 57 61 6c 46 64  me, pRet->pWalFd
c920: 2c 20 66 6c 61 67 73 2c 20 26 66 6c 61 67 73 29  , flags, &flags)
c930: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
c940: 54 45 5f 4f 4b 20 26 26 20 66 6c 61 67 73 26 53  TE_OK && flags&S
c950: 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 4f  QLITE_OPEN_READO
c960: 4e 4c 59 20 29 7b 0a 20 20 20 20 70 52 65 74 2d  NLY ){.    pRet-
c970: 3e 72 65 61 64 4f 6e 6c 79 20 3d 20 57 41 4c 5f  >readOnly = WAL_
c980: 52 44 4f 4e 4c 59 3b 0a 20 20 7d 0a 0a 20 20 69  RDONLY;.  }..  i
c990: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
c9a0: 20 29 7b 0a 20 20 20 20 77 61 6c 49 6e 64 65 78   ){.    walIndex
c9b0: 43 6c 6f 73 65 28 70 52 65 74 2c 20 30 29 3b 0a  Close(pRet, 0);.
c9c0: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f      sqlite3OsClo
c9d0: 73 65 28 70 52 65 74 2d 3e 70 57 61 6c 46 64 29  se(pRet->pWalFd)
c9e0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
c9f0: 65 65 28 70 52 65 74 29 3b 0a 20 20 7d 65 6c 73  ee(pRet);.  }els
ca00: 65 7b 0a 20 20 20 20 69 6e 74 20 69 44 43 20 3d  e{.    int iDC =
ca10: 20 73 71 6c 69 74 65 33 4f 73 44 65 76 69 63 65   sqlite3OsDevice
ca20: 43 68 61 72 61 63 74 65 72 69 73 74 69 63 73 28  Characteristics(
ca30: 70 44 62 46 64 29 3b 0a 20 20 20 20 69 66 28 20  pDbFd);.    if( 
ca40: 69 44 43 20 26 20 53 51 4c 49 54 45 5f 49 4f 43  iDC & SQLITE_IOC
ca50: 41 50 5f 53 45 51 55 45 4e 54 49 41 4c 20 29 7b  AP_SEQUENTIAL ){
ca60: 20 70 52 65 74 2d 3e 73 79 6e 63 48 65 61 64 65   pRet->syncHeade
ca70: 72 20 3d 20 30 3b 20 7d 0a 20 20 20 20 69 66 28  r = 0; }.    if(
ca80: 20 69 44 43 20 26 20 53 51 4c 49 54 45 5f 49 4f   iDC & SQLITE_IO
ca90: 43 41 50 5f 50 4f 57 45 52 53 41 46 45 5f 4f 56  CAP_POWERSAFE_OV
caa0: 45 52 57 52 49 54 45 20 29 7b 0a 20 20 20 20 20  ERWRITE ){.     
cab0: 20 70 52 65 74 2d 3e 70 61 64 54 6f 53 65 63 74   pRet->padToSect
cac0: 6f 72 42 6f 75 6e 64 61 72 79 20 3d 20 30 3b 0a  orBoundary = 0;.
cad0: 20 20 20 20 7d 0a 20 20 20 20 2a 70 70 57 61 6c      }.    *ppWal
cae0: 20 3d 20 70 52 65 74 3b 0a 20 20 20 20 57 41 4c   = pRet;.    WAL
caf0: 54 52 41 43 45 28 28 22 57 41 4c 25 64 3a 20 6f  TRACE(("WAL%d: o
cb00: 70 65 6e 65 64 5c 6e 22 2c 20 70 52 65 74 29 29  pened\n", pRet))
cb10: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
cb20: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 61 6e  c;.}../*.** Chan
cb30: 67 65 20 74 68 65 20 73 69 7a 65 20 74 6f 20 77  ge the size to w
cb40: 68 69 63 68 20 74 68 65 20 57 41 4c 20 66 69 6c  hich the WAL fil
cb50: 65 20 69 73 20 74 72 75 63 61 74 65 64 20 6f 6e  e is trucated on
cb60: 20 65 61 63 68 20 72 65 73 65 74 2e 0a 2a 2f 0a   each reset..*/.
cb70: 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 4c  void sqlite3WalL
cb80: 69 6d 69 74 28 57 61 6c 20 2a 70 57 61 6c 2c 20  imit(Wal *pWal, 
cb90: 69 36 34 20 69 4c 69 6d 69 74 29 7b 0a 20 20 69  i64 iLimit){.  i
cba0: 66 28 20 70 57 61 6c 20 29 20 70 57 61 6c 2d 3e  f( pWal ) pWal->
cbb0: 6d 78 57 61 6c 53 69 7a 65 20 3d 20 69 4c 69 6d  mxWalSize = iLim
cbc0: 69 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e  it;.}../*.** Fin
cbd0: 64 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70  d the smallest p
cbe0: 61 67 65 20 6e 75 6d 62 65 72 20 6f 75 74 20 6f  age number out o
cbf0: 66 20 61 6c 6c 20 70 61 67 65 73 20 68 65 6c 64  f all pages held
cc00: 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68 61 74   in the WAL that
cc10: 0a 2a 2a 20 68 61 73 20 6e 6f 74 20 62 65 65 6e  .** has not been
cc20: 20 72 65 74 75 72 6e 65 64 20 62 79 20 61 6e 79   returned by any
cc30: 20 70 72 69 6f 72 20 69 6e 76 6f 63 61 74 69 6f   prior invocatio
cc40: 6e 20 6f 66 20 74 68 69 73 20 6d 65 74 68 6f 64  n of this method
cc50: 20 6f 6e 20 74 68 65 0a 2a 2a 20 73 61 6d 65 20   on the.** same 
cc60: 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65  WalIterator obje
cc70: 63 74 2e 20 20 20 57 72 69 74 65 20 69 6e 74 6f  ct.   Write into
cc80: 20 2a 70 69 46 72 61 6d 65 20 74 68 65 20 66 72   *piFrame the fr
cc90: 61 6d 65 20 69 6e 64 65 78 20 77 68 65 72 65 0a  ame index where.
cca0: 2a 2a 20 74 68 61 74 20 70 61 67 65 20 77 61 73  ** that page was
ccb0: 20 6c 61 73 74 20 77 72 69 74 74 65 6e 20 69 6e   last written in
ccc0: 74 6f 20 74 68 65 20 57 41 4c 2e 20 20 57 72 69  to the WAL.  Wri
ccd0: 74 65 20 69 6e 74 6f 20 2a 70 69 50 61 67 65 20  te into *piPage 
cce0: 74 68 65 20 70 61 67 65 0a 2a 2a 20 6e 75 6d 62  the page.** numb
ccf0: 65 72 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e  er..**.** Return
cd00: 20 30 20 6f 6e 20 73 75 63 63 65 73 73 2e 20 20   0 on success.  
cd10: 49 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20  If there are no 
cd20: 70 61 67 65 73 20 69 6e 20 74 68 65 20 57 41 4c  pages in the WAL
cd30: 20 77 69 74 68 20 61 20 70 61 67 65 0a 2a 2a 20   with a page.** 
cd40: 6e 75 6d 62 65 72 20 6c 61 72 67 65 72 20 74 68  number larger th
cd50: 61 6e 20 2a 70 69 50 61 67 65 2c 20 74 68 65 6e  an *piPage, then
cd60: 20 72 65 74 75 72 6e 20 31 2e 0a 2a 2f 0a 73 74   return 1..*/.st
cd70: 61 74 69 63 20 69 6e 74 20 77 61 6c 49 74 65 72  atic int walIter
cd80: 61 74 6f 72 4e 65 78 74 28 0a 20 20 57 61 6c 49  atorNext(.  WalI
cd90: 74 65 72 61 74 6f 72 20 2a 70 2c 20 20 20 20 20  terator *p,     
cda0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65            /* Ite
cdb0: 72 61 74 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a  rator */.  u32 *
cdc0: 70 69 50 61 67 65 2c 20 20 20 20 20 20 20 20 20  piPage,         
cdd0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
cde0: 20 54 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72   The page number
cdf0: 20 6f 66 20 74 68 65 20 6e 65 78 74 20 70 61 67   of the next pag
ce00: 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 46 72  e */.  u32 *piFr
ce10: 61 6d 65 20 20 20 20 20 20 20 20 20 20 20 20 20  ame             
ce20: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 57 61 6c       /* OUT: Wal
ce30: 20 66 72 61 6d 65 20 69 6e 64 65 78 20 6f 66 20   frame index of 
ce40: 6e 65 78 74 20 70 61 67 65 20 2a 2f 0a 29 7b 0a  next page */.){.
ce50: 20 20 75 33 32 20 69 4d 69 6e 3b 20 20 20 20 20    u32 iMin;     
ce60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ce70: 2f 2a 20 52 65 73 75 6c 74 20 70 67 6e 6f 20 6d  /* Result pgno m
ce80: 75 73 74 20 62 65 20 67 72 65 61 74 65 72 20 74  ust be greater t
ce90: 68 61 6e 20 69 4d 69 6e 20 2a 2f 0a 20 20 75 33  han iMin */.  u3
cea0: 32 20 69 52 65 74 20 3d 20 30 78 46 46 46 46 46  2 iRet = 0xFFFFF
ceb0: 46 46 46 3b 20 20 20 20 20 20 20 20 2f 2a 20 30  FFF;        /* 0
cec0: 78 66 66 66 66 66 66 66 66 20 69 73 20 6e 65 76  xffffffff is nev
ced0: 65 72 20 61 20 76 61 6c 69 64 20 70 61 67 65 20  er a valid page 
cee0: 6e 75 6d 62 65 72 20 2a 2f 0a 20 20 69 6e 74 20  number */.  int 
cef0: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
cf00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72            /* For
cf10: 20 6c 6f 6f 70 69 6e 67 20 74 68 72 6f 75 67 68   looping through
cf20: 20 73 65 67 6d 65 6e 74 73 20 2a 2f 0a 0a 20 20   segments */..  
cf30: 69 4d 69 6e 20 3d 20 70 2d 3e 69 50 72 69 6f 72  iMin = p->iPrior
cf40: 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4d 69 6e  ;.  assert( iMin
cf50: 3c 30 78 66 66 66 66 66 66 66 66 20 29 3b 0a 20  <0xffffffff );. 
cf60: 20 66 6f 72 28 69 3d 70 2d 3e 6e 53 65 67 6d 65   for(i=p->nSegme
cf70: 6e 74 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29  nt-1; i>=0; i--)
cf80: 7b 0a 20 20 20 20 73 74 72 75 63 74 20 57 61 6c  {.    struct Wal
cf90: 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 6d 65 6e  Segment *pSegmen
cfa0: 74 20 3d 20 26 70 2d 3e 61 53 65 67 6d 65 6e 74  t = &p->aSegment
cfb0: 5b 69 5d 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  [i];.    while( 
cfc0: 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 3c  pSegment->iNext<
cfd0: 70 53 65 67 6d 65 6e 74 2d 3e 6e 45 6e 74 72 79  pSegment->nEntry
cfe0: 20 29 7b 0a 20 20 20 20 20 20 75 33 32 20 69 50   ){.      u32 iP
cff0: 67 20 3d 20 70 53 65 67 6d 65 6e 74 2d 3e 61 50  g = pSegment->aP
d000: 67 6e 6f 5b 70 53 65 67 6d 65 6e 74 2d 3e 61 49  gno[pSegment->aI
d010: 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69  ndex[pSegment->i
d020: 4e 65 78 74 5d 5d 3b 0a 20 20 20 20 20 20 69 66  Next]];.      if
d030: 28 20 69 50 67 3e 69 4d 69 6e 20 29 7b 0a 20 20  ( iPg>iMin ){.  
d040: 20 20 20 20 20 20 69 66 28 20 69 50 67 3c 69 52        if( iPg<iR
d050: 65 74 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  et ){.          
d060: 69 52 65 74 20 3d 20 69 50 67 3b 0a 20 20 20 20  iRet = iPg;.    
d070: 20 20 20 20 20 20 2a 70 69 46 72 61 6d 65 20 3d        *piFrame =
d080: 20 70 53 65 67 6d 65 6e 74 2d 3e 69 5a 65 72 6f   pSegment->iZero
d090: 20 2b 20 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e   + pSegment->aIn
d0a0: 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e  dex[pSegment->iN
d0b0: 65 78 74 5d 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ext];.        }.
d0c0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
d0d0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 53 65       }.      pSe
d0e0: 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 2b 2b 3b 0a  gment->iNext++;.
d0f0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 69      }.  }..  *pi
d100: 50 61 67 65 20 3d 20 70 2d 3e 69 50 72 69 6f 72  Page = p->iPrior
d110: 20 3d 20 69 52 65 74 3b 0a 20 20 72 65 74 75 72   = iRet;.  retur
d120: 6e 20 28 69 52 65 74 3d 3d 30 78 46 46 46 46 46  n (iRet==0xFFFFF
d130: 46 46 46 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  FFF);.}../*.** T
d140: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d 65 72  his function mer
d150: 67 65 73 20 74 77 6f 20 73 6f 72 74 65 64 20 6c  ges two sorted l
d160: 69 73 74 73 20 69 6e 74 6f 20 61 20 73 69 6e 67  ists into a sing
d170: 6c 65 20 73 6f 72 74 65 64 20 6c 69 73 74 2e 0a  le sorted list..
d180: 2a 2a 0a 2a 2a 20 61 4c 65 66 74 5b 5d 20 61 6e  **.** aLeft[] an
d190: 64 20 61 52 69 67 68 74 5b 5d 20 61 72 65 20 61  d aRight[] are a
d1a0: 72 72 61 79 73 20 6f 66 20 69 6e 64 69 63 65 73  rrays of indices
d1b0: 2e 20 20 54 68 65 20 73 6f 72 74 20 6b 65 79 20  .  The sort key 
d1c0: 69 73 0a 2a 2a 20 61 43 6f 6e 74 65 6e 74 5b 61  is.** aContent[a
d1d0: 4c 65 66 74 5b 5d 5d 20 61 6e 64 20 61 43 6f 6e  Left[]] and aCon
d1e0: 74 65 6e 74 5b 61 52 69 67 68 74 5b 5d 5d 2e 20  tent[aRight[]]. 
d1f0: 20 55 70 6f 6e 20 65 6e 74 72 79 2c 20 74 68 65   Upon entry, the
d200: 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 69 73   following.** is
d210: 20 67 75 61 72 61 6e 74 65 65 64 20 66 6f 72 20   guaranteed for 
d220: 61 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a 2a 2a 20 20  all J<K:.**.**  
d230: 20 20 20 20 20 20 61 43 6f 6e 74 65 6e 74 5b 61        aContent[a
d240: 4c 65 66 74 5b 4a 5d 5d 20 3c 20 61 43 6f 6e 74  Left[J]] < aCont
d250: 65 6e 74 5b 61 4c 65 66 74 5b 4b 5d 5d 0a 2a 2a  ent[aLeft[K]].**
d260: 20 20 20 20 20 20 20 20 61 43 6f 6e 74 65 6e 74          aContent
d270: 5b 61 52 69 67 68 74 5b 4a 5d 5d 20 3c 20 61 43  [aRight[J]] < aC
d280: 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b 4b 5d  ontent[aRight[K]
d290: 5d 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ].**.** This rou
d2a0: 74 69 6e 65 20 6f 76 65 72 77 72 69 74 65 73 20  tine overwrites 
d2b0: 61 52 69 67 68 74 5b 5d 20 77 69 74 68 20 61 20  aRight[] with a 
d2c0: 6e 65 77 20 28 70 72 6f 62 61 62 6c 79 20 6c 6f  new (probably lo
d2d0: 6e 67 65 72 29 20 73 65 71 75 65 6e 63 65 0a 2a  nger) sequence.*
d2e0: 2a 20 6f 66 20 69 6e 64 69 63 65 73 20 73 75 63  * of indices suc
d2f0: 68 20 74 68 61 74 20 74 68 65 20 61 52 69 67 68  h that the aRigh
d300: 74 5b 5d 20 63 6f 6e 74 61 69 6e 73 20 65 76 65  t[] contains eve
d310: 72 79 20 69 6e 64 65 78 20 74 68 61 74 20 61 70  ry index that ap
d320: 70 65 61 72 73 20 69 6e 0a 2a 2a 20 65 69 74 68  pears in.** eith
d330: 65 72 20 61 4c 65 66 74 5b 5d 20 6f 72 20 74 68  er aLeft[] or th
d340: 65 20 6f 6c 64 20 61 52 69 67 68 74 5b 5d 20 61  e old aRight[] a
d350: 6e 64 20 73 75 63 68 20 74 68 61 74 20 74 68 65  nd such that the
d360: 20 73 65 63 6f 6e 64 20 63 6f 6e 64 69 74 69 6f   second conditio
d370: 6e 0a 2a 2a 20 61 62 6f 76 65 20 69 73 20 73 74  n.** above is st
d380: 69 6c 6c 20 6d 65 74 2e 0a 2a 2a 0a 2a 2a 20 54  ill met..**.** T
d390: 68 65 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66  he aContent[aLef
d3a0: 74 5b 58 5d 5d 20 76 61 6c 75 65 73 20 77 69 6c  t[X]] values wil
d3b0: 6c 20 62 65 20 75 6e 69 71 75 65 20 66 6f 72 20  l be unique for 
d3c0: 61 6c 6c 20 58 2e 20 20 41 6e 64 20 74 68 65 0a  all X.  And the.
d3d0: 2a 2a 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67  ** aContent[aRig
d3e0: 68 74 5b 58 5d 5d 20 76 61 6c 75 65 73 20 77 69  ht[X]] values wi
d3f0: 6c 6c 20 62 65 20 75 6e 69 71 75 65 20 74 6f 6f  ll be unique too
d400: 2e 20 20 42 75 74 20 74 68 65 72 65 20 6d 69 67  .  But there mig
d410: 68 74 20 62 65 0a 2a 2a 20 6f 6e 65 20 6f 72 20  ht be.** one or 
d420: 6d 6f 72 65 20 63 6f 6d 62 69 6e 61 74 69 6f 6e  more combination
d430: 73 20 6f 66 20 58 20 61 6e 64 20 59 20 73 75 63  s of X and Y suc
d440: 68 20 74 68 61 74 0a 2a 2a 0a 2a 2a 20 20 20 20  h that.**.**    
d450: 20 20 61 4c 65 66 74 5b 58 5d 21 3d 61 52 69 67    aLeft[X]!=aRig
d460: 68 74 5b 59 5d 20 20 26 26 20 20 61 43 6f 6e 74  ht[Y]  &&  aCont
d470: 65 6e 74 5b 61 4c 65 66 74 5b 58 5d 5d 20 3d 3d  ent[aLeft[X]] ==
d480: 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74   aContent[aRight
d490: 5b 59 5d 5d 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20  [Y]].**.** When 
d4a0: 74 68 61 74 20 68 61 70 70 65 6e 73 2c 20 6f 6d  that happens, om
d4b0: 69 74 20 74 68 65 20 61 4c 65 66 74 5b 58 5d 20  it the aLeft[X] 
d4c0: 61 6e 64 20 75 73 65 20 74 68 65 20 61 52 69 67  and use the aRig
d4d0: 68 74 5b 59 5d 20 69 6e 64 65 78 2e 0a 2a 2f 0a  ht[Y] index..*/.
d4e0: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 4d  static void walM
d4f0: 65 72 67 65 28 0a 20 20 63 6f 6e 73 74 20 75 33  erge(.  const u3
d500: 32 20 2a 61 43 6f 6e 74 65 6e 74 2c 20 20 20 20  2 *aContent,    
d510: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 73          /* Pages
d520: 20 69 6e 20 77 61 6c 20 2d 20 6b 65 79 73 20 66   in wal - keys f
d530: 6f 72 20 74 68 65 20 73 6f 72 74 20 2a 2f 0a 20  or the sort */. 
d540: 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 65 66 74 2c   ht_slot *aLeft,
d550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d560: 20 2f 2a 20 49 4e 3a 20 4c 65 66 74 20 68 61 6e   /* IN: Left han
d570: 64 20 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a  d input list */.
d580: 20 20 69 6e 74 20 6e 4c 65 66 74 2c 20 20 20 20    int nLeft,    
d590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d5a0: 20 20 2f 2a 20 49 4e 3a 20 45 6c 65 6d 65 6e 74    /* IN: Element
d5b0: 73 20 69 6e 20 61 72 72 61 79 20 2a 70 61 4c 65  s in array *paLe
d5c0: 66 74 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20  ft */.  ht_slot 
d5d0: 2a 2a 70 61 52 69 67 68 74 2c 20 20 20 20 20 20  **paRight,      
d5e0: 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55          /* IN/OU
d5f0: 54 3a 20 52 69 67 68 74 20 68 61 6e 64 20 69 6e  T: Right hand in
d600: 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e  put list */.  in
d610: 74 20 2a 70 6e 52 69 67 68 74 2c 20 20 20 20 20  t *pnRight,     
d620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d630: 20 49 4e 2f 4f 55 54 3a 20 45 6c 65 6d 65 6e 74   IN/OUT: Element
d640: 73 20 69 6e 20 2a 70 61 52 69 67 68 74 20 2a 2f  s in *paRight */
d650: 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 54 6d 70  .  ht_slot *aTmp
d660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d670: 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20     /* Temporary 
d680: 62 75 66 66 65 72 20 2a 2f 0a 29 7b 0a 20 20 69  buffer */.){.  i
d690: 6e 74 20 69 4c 65 66 74 20 3d 20 30 3b 20 20 20  nt iLeft = 0;   
d6a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
d6b0: 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20  * Current index 
d6c0: 69 6e 20 61 4c 65 66 74 20 2a 2f 0a 20 20 69 6e  in aLeft */.  in
d6d0: 74 20 69 52 69 67 68 74 20 3d 20 30 3b 20 20 20  t iRight = 0;   
d6e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d6f0: 20 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69   Current index i
d700: 6e 20 61 52 69 67 68 74 20 2a 2f 0a 20 20 69 6e  n aRight */.  in
d710: 74 20 69 4f 75 74 20 3d 20 30 3b 20 20 20 20 20  t iOut = 0;     
d720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d730: 20 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69   Current index i
d740: 6e 20 6f 75 74 70 75 74 20 62 75 66 66 65 72 20  n output buffer 
d750: 2a 2f 0a 20 20 69 6e 74 20 6e 52 69 67 68 74 20  */.  int nRight 
d760: 3d 20 2a 70 6e 52 69 67 68 74 3b 0a 20 20 68 74  = *pnRight;.  ht
d770: 5f 73 6c 6f 74 20 2a 61 52 69 67 68 74 20 3d 20  _slot *aRight = 
d780: 2a 70 61 52 69 67 68 74 3b 0a 0a 20 20 61 73 73  *paRight;..  ass
d790: 65 72 74 28 20 6e 4c 65 66 74 3e 30 20 26 26 20  ert( nLeft>0 && 
d7a0: 6e 52 69 67 68 74 3e 30 20 29 3b 0a 20 20 77 68  nRight>0 );.  wh
d7b0: 69 6c 65 28 20 69 52 69 67 68 74 3c 6e 52 69 67  ile( iRight<nRig
d7c0: 68 74 20 7c 7c 20 69 4c 65 66 74 3c 6e 4c 65 66  ht || iLeft<nLef
d7d0: 74 20 29 7b 0a 20 20 20 20 68 74 5f 73 6c 6f 74  t ){.    ht_slot
d7e0: 20 6c 6f 67 70 61 67 65 3b 0a 20 20 20 20 50 67   logpage;.    Pg
d7f0: 6e 6f 20 64 62 70 61 67 65 3b 0a 0a 20 20 20 20  no dbpage;..    
d800: 69 66 28 20 28 69 4c 65 66 74 3c 6e 4c 65 66 74  if( (iLeft<nLeft
d810: 29 20 0a 20 20 20 20 20 26 26 20 28 69 52 69 67  ) .     && (iRig
d820: 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c 20 61 43  ht>=nRight || aC
d830: 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65  ontent[aLeft[iLe
d840: 66 74 5d 5d 3c 61 43 6f 6e 74 65 6e 74 5b 61 52  ft]]<aContent[aR
d850: 69 67 68 74 5b 69 52 69 67 68 74 5d 5d 29 0a 20  ight[iRight]]). 
d860: 20 20 20 29 7b 0a 20 20 20 20 20 20 6c 6f 67 70     ){.      logp
d870: 61 67 65 20 3d 20 61 4c 65 66 74 5b 69 4c 65 66  age = aLeft[iLef
d880: 74 2b 2b 5d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  t++];.    }else{
d890: 0a 20 20 20 20 20 20 6c 6f 67 70 61 67 65 20 3d  .      logpage =
d8a0: 20 61 52 69 67 68 74 5b 69 52 69 67 68 74 2b 2b   aRight[iRight++
d8b0: 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64 62 70  ];.    }.    dbp
d8c0: 61 67 65 20 3d 20 61 43 6f 6e 74 65 6e 74 5b 6c  age = aContent[l
d8d0: 6f 67 70 61 67 65 5d 3b 0a 0a 20 20 20 20 61 54  ogpage];..    aT
d8e0: 6d 70 5b 69 4f 75 74 2b 2b 5d 20 3d 20 6c 6f 67  mp[iOut++] = log
d8f0: 70 61 67 65 3b 0a 20 20 20 20 69 66 28 20 69 4c  page;.    if( iL
d900: 65 66 74 3c 6e 4c 65 66 74 20 26 26 20 61 43 6f  eft<nLeft && aCo
d910: 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66  ntent[aLeft[iLef
d920: 74 5d 5d 3d 3d 64 62 70 61 67 65 20 29 20 69 4c  t]]==dbpage ) iL
d930: 65 66 74 2b 2b 3b 0a 0a 20 20 20 20 61 73 73 65  eft++;..    asse
d940: 72 74 28 20 69 4c 65 66 74 3e 3d 6e 4c 65 66 74  rt( iLeft>=nLeft
d950: 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65   || aContent[aLe
d960: 66 74 5b 69 4c 65 66 74 5d 5d 3e 64 62 70 61 67  ft[iLeft]]>dbpag
d970: 65 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  e );.    assert(
d980: 20 69 52 69 67 68 74 3e 3d 6e 52 69 67 68 74 20   iRight>=nRight 
d990: 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67  || aContent[aRig
d9a0: 68 74 5b 69 52 69 67 68 74 5d 5d 3e 64 62 70 61  ht[iRight]]>dbpa
d9b0: 67 65 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 61  ge );.  }..  *pa
d9c0: 52 69 67 68 74 20 3d 20 61 4c 65 66 74 3b 0a 20  Right = aLeft;. 
d9d0: 20 2a 70 6e 52 69 67 68 74 20 3d 20 69 4f 75 74   *pnRight = iOut
d9e0: 3b 0a 20 20 6d 65 6d 63 70 79 28 61 4c 65 66 74  ;.  memcpy(aLeft
d9f0: 2c 20 61 54 6d 70 2c 20 73 69 7a 65 6f 66 28 61  , aTmp, sizeof(a
da00: 54 6d 70 5b 30 5d 29 2a 69 4f 75 74 29 3b 0a 7d  Tmp[0])*iOut);.}
da10: 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74 68 65  ../*.** Sort the
da20: 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 6c 69 73   elements in lis
da30: 74 20 61 4c 69 73 74 20 75 73 69 6e 67 20 61 43  t aList using aC
da40: 6f 6e 74 65 6e 74 5b 5d 20 61 73 20 74 68 65 20  ontent[] as the 
da50: 73 6f 72 74 20 6b 65 79 2e 0a 2a 2a 20 52 65 6d  sort key..** Rem
da60: 6f 76 65 20 65 6c 65 6d 65 6e 74 73 20 77 69 74  ove elements wit
da70: 68 20 64 75 70 6c 69 63 61 74 65 20 6b 65 79 73  h duplicate keys
da80: 2c 20 70 72 65 66 65 72 72 69 6e 67 20 74 6f 20  , preferring to 
da90: 6b 65 65 70 20 74 68 65 0a 2a 2a 20 6c 61 72 67  keep the.** larg
daa0: 65 72 20 61 4c 69 73 74 5b 5d 20 76 61 6c 75 65  er aList[] value
dab0: 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 4c 69  s..**.** The aLi
dac0: 73 74 5b 5d 20 65 6e 74 72 69 65 73 20 61 72 65  st[] entries are
dad0: 20 69 6e 64 69 63 65 73 20 69 6e 74 6f 20 61 43   indices into aC
dae0: 6f 6e 74 65 6e 74 5b 5d 2e 20 20 54 68 65 20 76  ontent[].  The v
daf0: 61 6c 75 65 73 20 69 6e 0a 2a 2a 20 61 4c 69 73  alues in.** aLis
db00: 74 5b 5d 20 61 72 65 20 74 6f 20 62 65 20 73 6f  t[] are to be so
db10: 72 74 65 64 20 73 6f 20 74 68 61 74 20 66 6f 72  rted so that for
db20: 20 61 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a 2a 2a 20   all J<K:.**.** 
db30: 20 20 20 20 20 61 43 6f 6e 74 65 6e 74 5b 61 4c       aContent[aL
db40: 69 73 74 5b 4a 5d 5d 20 3c 20 61 43 6f 6e 74 65  ist[J]] < aConte
db50: 6e 74 5b 61 4c 69 73 74 5b 4b 5d 5d 0a 2a 2a 0a  nt[aList[K]].**.
db60: 2a 2a 20 46 6f 72 20 61 6e 79 20 58 20 61 6e 64  ** For any X and
db70: 20 59 20 73 75 63 68 20 74 68 61 74 0a 2a 2a 0a   Y such that.**.
db80: 2a 2a 20 20 20 20 20 20 61 43 6f 6e 74 65 6e 74  **      aContent
db90: 5b 61 4c 69 73 74 5b 58 5d 5d 20 3d 3d 20 61 43  [aList[X]] == aC
dba0: 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 59 5d 5d  ontent[aList[Y]]
dbb0: 0a 2a 2a 0a 2a 2a 20 4b 65 65 70 20 74 68 65 20  .**.** Keep the 
dbc0: 6c 61 72 67 65 72 20 6f 66 20 74 68 65 20 74 77  larger of the tw
dbd0: 6f 20 76 61 6c 75 65 73 20 61 4c 69 73 74 5b 58  o values aList[X
dbe0: 5d 20 61 6e 64 20 61 4c 69 73 74 5b 59 5d 20 61  ] and aList[Y] a
dbf0: 6e 64 20 64 69 73 63 61 72 64 0a 2a 2a 20 74 68  nd discard.** th
dc00: 65 20 73 6d 61 6c 6c 65 72 2e 0a 2a 2f 0a 73 74  e smaller..*/.st
dc10: 61 74 69 63 20 76 6f 69 64 20 77 61 6c 4d 65 72  atic void walMer
dc20: 67 65 73 6f 72 74 28 0a 20 20 63 6f 6e 73 74 20  gesort(.  const 
dc30: 75 33 32 20 2a 61 43 6f 6e 74 65 6e 74 2c 20 20  u32 *aContent,  
dc40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
dc50: 65 73 20 69 6e 20 77 61 6c 20 2a 2f 0a 20 20 68  es in wal */.  h
dc60: 74 5f 73 6c 6f 74 20 2a 61 42 75 66 66 65 72 2c  t_slot *aBuffer,
dc70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
dc80: 2a 20 42 75 66 66 65 72 20 6f 66 20 61 74 20 6c  * Buffer of at l
dc90: 65 61 73 74 20 2a 70 6e 4c 69 73 74 20 69 74 65  east *pnList ite
dca0: 6d 73 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20 68  ms to use */.  h
dcb0: 74 5f 73 6c 6f 74 20 2a 61 4c 69 73 74 2c 20 20  t_slot *aList,  
dcc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
dcd0: 2a 20 49 4e 2f 4f 55 54 3a 20 4c 69 73 74 20 74  * IN/OUT: List t
dce0: 6f 20 73 6f 72 74 20 2a 2f 0a 20 20 69 6e 74 20  o sort */.  int 
dcf0: 2a 70 6e 4c 69 73 74 20 20 20 20 20 20 20 20 20  *pnList         
dd00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
dd10: 4e 2f 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66  N/OUT: Number of
dd20: 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 4c 69   elements in aLi
dd30: 73 74 5b 5d 20 2a 2f 0a 29 7b 0a 20 20 73 74 72  st[] */.){.  str
dd40: 75 63 74 20 53 75 62 6c 69 73 74 20 7b 0a 20 20  uct Sublist {.  
dd50: 20 20 69 6e 74 20 6e 4c 69 73 74 3b 20 20 20 20    int nList;    
dd60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dd70: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65  /* Number of ele
dd80: 6d 65 6e 74 73 20 69 6e 20 61 4c 69 73 74 20 2a  ments in aList *
dd90: 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20 2a 61  /.    ht_slot *a
dda0: 4c 69 73 74 3b 20 20 20 20 20 20 20 20 20 20 20  List;           
ddb0: 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
ddc0: 6f 20 73 75 62 2d 6c 69 73 74 20 63 6f 6e 74 65  o sub-list conte
ddd0: 6e 74 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20 63 6f  nt */.  };..  co
dde0: 6e 73 74 20 69 6e 74 20 6e 4c 69 73 74 20 3d 20  nst int nList = 
ddf0: 2a 70 6e 4c 69 73 74 3b 20 20 20 20 20 20 2f 2a  *pnList;      /*
de00: 20 53 69 7a 65 20 6f 66 20 69 6e 70 75 74 20 6c   Size of input l
de10: 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4d 65  ist */.  int nMe
de20: 72 67 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20  rge = 0;        
de30: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
de40: 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69  er of elements i
de50: 6e 20 6c 69 73 74 20 61 4d 65 72 67 65 20 2a 2f  n list aMerge */
de60: 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4d 65 72  .  ht_slot *aMer
de70: 67 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  ge = 0;         
de80: 20 20 20 2f 2a 20 4c 69 73 74 20 74 6f 20 62 65     /* List to be
de90: 20 6d 65 72 67 65 64 20 2a 2f 0a 20 20 69 6e 74   merged */.  int
dea0: 20 69 4c 69 73 74 3b 20 20 20 20 20 20 20 20 20   iList;         
deb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
dec0: 49 6e 64 65 78 20 69 6e 74 6f 20 69 6e 70 75 74  Index into input
ded0: 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 69   list */.  int i
dee0: 53 75 62 20 3d 20 30 3b 20 20 20 20 20 20 20 20  Sub = 0;        
def0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
df00: 64 65 78 20 69 6e 74 6f 20 61 53 75 62 20 61 72  dex into aSub ar
df10: 72 61 79 20 2a 2f 0a 20 20 73 74 72 75 63 74 20  ray */.  struct 
df20: 53 75 62 6c 69 73 74 20 61 53 75 62 5b 31 33 5d  Sublist aSub[13]
df30: 3b 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61  ;        /* Arra
df40: 79 20 6f 66 20 73 75 62 2d 6c 69 73 74 73 20 2a  y of sub-lists *
df50: 2f 0a 0a 20 20 6d 65 6d 73 65 74 28 61 53 75 62  /..  memset(aSub
df60: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 61 53 75 62  , 0, sizeof(aSub
df70: 29 29 3b 0a 20 20 61 73 73 65 72 74 28 20 6e 4c  ));.  assert( nL
df80: 69 73 74 3c 3d 48 41 53 48 54 41 42 4c 45 5f 4e  ist<=HASHTABLE_N
df90: 50 41 47 45 20 26 26 20 6e 4c 69 73 74 3e 30 20  PAGE && nList>0 
dfa0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 48 41 53  );.  assert( HAS
dfb0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 3d 3d 28 31  HTABLE_NPAGE==(1
dfc0: 3c 3c 28 41 72 72 61 79 53 69 7a 65 28 61 53 75  <<(ArraySize(aSu
dfd0: 62 29 2d 31 29 29 20 29 3b 0a 0a 20 20 66 6f 72  b)-1)) );..  for
dfe0: 28 69 4c 69 73 74 3d 30 3b 20 69 4c 69 73 74 3c  (iList=0; iList<
dff0: 6e 4c 69 73 74 3b 20 69 4c 69 73 74 2b 2b 29 7b  nList; iList++){
e000: 0a 20 20 20 20 6e 4d 65 72 67 65 20 3d 20 31 3b  .    nMerge = 1;
e010: 0a 20 20 20 20 61 4d 65 72 67 65 20 3d 20 26 61  .    aMerge = &a
e020: 4c 69 73 74 5b 69 4c 69 73 74 5d 3b 0a 20 20 20  List[iList];.   
e030: 20 66 6f 72 28 69 53 75 62 3d 30 3b 20 69 4c 69   for(iSub=0; iLi
e040: 73 74 20 26 20 28 31 3c 3c 69 53 75 62 29 3b 20  st & (1<<iSub); 
e050: 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20 20 20 73  iSub++){.      s
e060: 74 72 75 63 74 20 53 75 62 6c 69 73 74 20 2a 70  truct Sublist *p
e070: 20 3d 20 26 61 53 75 62 5b 69 53 75 62 5d 3b 0a   = &aSub[iSub];.
e080: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d        assert( p-
e090: 3e 61 4c 69 73 74 20 26 26 20 70 2d 3e 6e 4c 69  >aList && p->nLi
e0a0: 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29 20 29 3b  st<=(1<<iSub) );
e0b0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
e0c0: 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69 73 74 5b  ->aList==&aList[
e0d0: 69 4c 69 73 74 26 7e 28 28 32 3c 3c 69 53 75 62  iList&~((2<<iSub
e0e0: 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20 20 20 77  )-1)] );.      w
e0f0: 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74 65 6e 74  alMerge(aContent
e100: 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70 2d 3e 6e  , p->aList, p->n
e110: 4c 69 73 74 2c 20 26 61 4d 65 72 67 65 2c 20 26  List, &aMerge, &
e120: 6e 4d 65 72 67 65 2c 20 61 42 75 66 66 65 72 29  nMerge, aBuffer)
e130: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 53 75 62  ;.    }.    aSub
e140: 5b 69 53 75 62 5d 2e 61 4c 69 73 74 20 3d 20 61  [iSub].aList = a
e150: 4d 65 72 67 65 3b 0a 20 20 20 20 61 53 75 62 5b  Merge;.    aSub[
e160: 69 53 75 62 5d 2e 6e 4c 69 73 74 20 3d 20 6e 4d  iSub].nList = nM
e170: 65 72 67 65 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72  erge;.  }..  for
e180: 28 69 53 75 62 2b 2b 3b 20 69 53 75 62 3c 41 72  (iSub++; iSub<Ar
e190: 72 61 79 53 69 7a 65 28 61 53 75 62 29 3b 20 69  raySize(aSub); i
e1a0: 53 75 62 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20  Sub++){.    if( 
e1b0: 6e 4c 69 73 74 20 26 20 28 31 3c 3c 69 53 75 62  nList & (1<<iSub
e1c0: 29 20 29 7b 0a 20 20 20 20 20 20 73 74 72 75 63  ) ){.      struc
e1d0: 74 20 53 75 62 6c 69 73 74 20 2a 70 20 3d 20 26  t Sublist *p = &
e1e0: 61 53 75 62 5b 69 53 75 62 5d 3b 0a 20 20 20 20  aSub[iSub];.    
e1f0: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 4c 69    assert( p->nLi
e200: 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29 20 29 3b  st<=(1<<iSub) );
e210: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
e220: 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69 73 74 5b  ->aList==&aList[
e230: 6e 4c 69 73 74 26 7e 28 28 32 3c 3c 69 53 75 62  nList&~((2<<iSub
e240: 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20 20 20 77  )-1)] );.      w
e250: 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74 65 6e 74  alMerge(aContent
e260: 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70 2d 3e 6e  , p->aList, p->n
e270: 4c 69 73 74 2c 20 26 61 4d 65 72 67 65 2c 20 26  List, &aMerge, &
e280: 6e 4d 65 72 67 65 2c 20 61 42 75 66 66 65 72 29  nMerge, aBuffer)
e290: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73  ;.    }.  }.  as
e2a0: 73 65 72 74 28 20 61 4d 65 72 67 65 3d 3d 61 4c  sert( aMerge==aL
e2b0: 69 73 74 20 29 3b 0a 20 20 2a 70 6e 4c 69 73 74  ist );.  *pnList
e2c0: 20 3d 20 6e 4d 65 72 67 65 3b 0a 0a 23 69 66 64   = nMerge;..#ifd
e2d0: 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47 0a  ef SQLITE_DEBUG.
e2e0: 20 20 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20    {.    int i;. 
e2f0: 20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 2a 70     for(i=1; i<*p
e300: 6e 4c 69 73 74 3b 20 69 2b 2b 29 7b 0a 20 20 20  nList; i++){.   
e310: 20 20 20 61 73 73 65 72 74 28 20 61 43 6f 6e 74     assert( aCont
e320: 65 6e 74 5b 61 4c 69 73 74 5b 69 5d 5d 20 3e 20  ent[aList[i]] > 
e330: 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 69  aContent[aList[i
e340: 2d 31 5d 5d 20 29 3b 0a 20 20 20 20 7d 0a 20 20  -1]] );.    }.  
e350: 7d 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 20 0a  }.#endif.}../* .
e360: 2a 2a 20 46 72 65 65 20 61 6e 20 69 74 65 72 61  ** Free an itera
e370: 74 6f 72 20 61 6c 6c 6f 63 61 74 65 64 20 62 79  tor allocated by
e380: 20 77 61 6c 49 74 65 72 61 74 6f 72 49 6e 69 74   walIteratorInit
e390: 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ()..*/.static vo
e3a0: 69 64 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72  id walIteratorFr
e3b0: 65 65 28 57 61 6c 49 74 65 72 61 74 6f 72 20 2a  ee(WalIterator *
e3c0: 70 29 7b 0a 20 20 73 71 6c 69 74 65 33 53 63 72  p){.  sqlite3Scr
e3d0: 61 74 63 68 46 72 65 65 28 70 29 3b 0a 7d 0a 0a  atchFree(p);.}..
e3e0: 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 72 75 63 74 20  /*.** Construct 
e3f0: 61 20 57 61 6c 49 6e 74 65 72 61 74 6f 72 20 6f  a WalInterator o
e400: 62 6a 65 63 74 20 74 68 61 74 20 63 61 6e 20 62  bject that can b
e410: 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f 70 20 6f  e used to loop o
e420: 76 65 72 20 61 6c 6c 20 0a 2a 2a 20 70 61 67 65  ver all .** page
e430: 73 20 69 6e 20 74 68 65 20 57 41 4c 20 69 6e 20  s in the WAL in 
e440: 61 73 63 65 6e 64 69 6e 67 20 6f 72 64 65 72 2e  ascending order.
e450: 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74   The caller must
e460: 20 68 6f 6c 64 20 74 68 65 20 63 68 65 63 6b 70   hold the checkp
e470: 6f 69 6e 74 0a 2a 2a 20 6c 6f 63 6b 2e 0a 2a 2a  oint.** lock..**
e480: 0a 2a 2a 20 4f 6e 20 73 75 63 63 65 73 73 2c 20  .** On success, 
e490: 6d 61 6b 65 20 2a 70 70 20 70 6f 69 6e 74 20 74  make *pp point t
e4a0: 6f 20 74 68 65 20 6e 65 77 6c 79 20 61 6c 6c 6f  o the newly allo
e4b0: 63 61 74 65 64 20 57 61 6c 49 6e 74 65 72 61 74  cated WalInterat
e4c0: 6f 72 20 6f 62 6a 65 63 74 0a 2a 2a 20 72 65 74  or object.** ret
e4d0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f  urn SQLITE_OK. O
e4e0: 74 68 65 72 77 69 73 65 2c 20 72 65 74 75 72 6e  therwise, return
e4f0: 20 61 6e 20 65 72 72 6f 72 20 63 6f 64 65 2e 20   an error code. 
e500: 49 66 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a  If this routine.
e510: 2a 2a 20 72 65 74 75 72 6e 73 20 61 6e 20 65 72  ** returns an er
e520: 72 6f 72 2c 20 74 68 65 20 76 61 6c 75 65 20 6f  ror, the value o
e530: 66 20 2a 70 70 20 69 73 20 75 6e 64 65 66 69 6e  f *pp is undefin
e540: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61  ed..**.** The ca
e550: 6c 6c 69 6e 67 20 72 6f 75 74 69 6e 65 20 73 68  lling routine sh
e560: 6f 75 6c 64 20 69 6e 76 6f 6b 65 20 77 61 6c 49  ould invoke walI
e570: 74 65 72 61 74 6f 72 46 72 65 65 28 29 20 74 6f  teratorFree() to
e580: 20 64 65 73 74 72 6f 79 20 74 68 65 0a 2a 2a 20   destroy the.** 
e590: 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65  WalIterator obje
e5a0: 63 74 20 77 68 65 6e 20 69 74 20 68 61 73 20 66  ct when it has f
e5b0: 69 6e 69 73 68 65 64 20 77 69 74 68 20 69 74 2e  inished with it.
e5c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
e5d0: 61 6c 49 74 65 72 61 74 6f 72 49 6e 69 74 28 57  alIteratorInit(W
e5e0: 61 6c 20 2a 70 57 61 6c 2c 20 57 61 6c 49 74 65  al *pWal, WalIte
e5f0: 72 61 74 6f 72 20 2a 2a 70 70 29 7b 0a 20 20 57  rator **pp){.  W
e600: 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 3b 20 20  alIterator *p;  
e610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e620: 2a 20 52 65 74 75 72 6e 20 76 61 6c 75 65 20 2a  * Return value *
e630: 2f 0a 20 20 69 6e 74 20 6e 53 65 67 6d 65 6e 74  /.  int nSegment
e640: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
e650: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
e660: 20 73 65 67 6d 65 6e 74 73 20 74 6f 20 6d 65 72   segments to mer
e670: 67 65 20 2a 2f 0a 20 20 75 33 32 20 69 4c 61 73  ge */.  u32 iLas
e680: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
e690: 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73 74 20          /* Last 
e6a0: 66 72 61 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a  frame in log */.
e6b0: 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20    int nByte;    
e6c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e6d0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
e6e0: 79 74 65 73 20 74 6f 20 61 6c 6c 6f 63 61 74 65  ytes to allocate
e6f0: 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 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 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f        /* Iterato
e720: 72 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20  r variable */.  
e730: 68 74 5f 73 6c 6f 74 20 2a 61 54 6d 70 3b 20 20  ht_slot *aTmp;  
e740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e750: 2f 2a 20 54 65 6d 70 20 73 70 61 63 65 20 75 73  /* Temp space us
e760: 65 64 20 62 79 20 6d 65 72 67 65 2d 73 6f 72 74  ed by merge-sort
e770: 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   */.  int rc = S
e780: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
e790: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
e7a0: 43 6f 64 65 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68  Code */..  /* Th
e7b0: 69 73 20 72 6f 75 74 69 6e 65 20 6f 6e 6c 79 20  is routine only 
e7c0: 72 75 6e 73 20 77 68 69 6c 65 20 68 6f 6c 64 69  runs while holdi
e7d0: 6e 67 20 74 68 65 20 63 68 65 63 6b 70 6f 69 6e  ng the checkpoin
e7e0: 74 20 6c 6f 63 6b 2e 20 41 6e 64 0a 20 20 2a 2a  t lock. And.  **
e7f0: 20 69 74 20 6f 6e 6c 79 20 72 75 6e 73 20 69 66   it only runs if
e800: 20 74 68 65 72 65 20 69 73 20 61 63 74 75 61 6c   there is actual
e810: 6c 79 20 63 6f 6e 74 65 6e 74 20 69 6e 20 74 68  ly content in th
e820: 65 20 6c 6f 67 20 28 6d 78 46 72 61 6d 65 3e 30  e log (mxFrame>0
e830: 29 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74  )..  */.  assert
e840: 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b  ( pWal->ckptLock
e850: 20 26 26 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78   && pWal->hdr.mx
e860: 46 72 61 6d 65 3e 30 20 29 3b 0a 20 20 69 4c 61  Frame>0 );.  iLa
e870: 73 74 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  st = pWal->hdr.m
e880: 78 46 72 61 6d 65 3b 0a 0a 20 20 2f 2a 20 41 6c  xFrame;..  /* Al
e890: 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66 6f 72  locate space for
e8a0: 20 74 68 65 20 57 61 6c 49 74 65 72 61 74 6f 72   the WalIterator
e8b0: 20 6f 62 6a 65 63 74 2e 20 2a 2f 0a 20 20 6e 53   object. */.  nS
e8c0: 65 67 6d 65 6e 74 20 3d 20 77 61 6c 46 72 61 6d  egment = walFram
e8d0: 65 50 61 67 65 28 69 4c 61 73 74 29 20 2b 20 31  ePage(iLast) + 1
e8e0: 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65  ;.  nByte = size
e8f0: 6f 66 28 57 61 6c 49 74 65 72 61 74 6f 72 29 20  of(WalIterator) 
e900: 0a 20 20 20 20 20 20 20 20 2b 20 28 6e 53 65 67  .        + (nSeg
e910: 6d 65 6e 74 2d 31 29 2a 73 69 7a 65 6f 66 28 73  ment-1)*sizeof(s
e920: 74 72 75 63 74 20 57 61 6c 53 65 67 6d 65 6e 74  truct WalSegment
e930: 29 0a 20 20 20 20 20 20 20 20 2b 20 69 4c 61 73  ).        + iLas
e940: 74 2a 73 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74  t*sizeof(ht_slot
e950: 29 3b 0a 20 20 70 20 3d 20 28 57 61 6c 49 74 65  );.  p = (WalIte
e960: 72 61 74 6f 72 20 2a 29 73 71 6c 69 74 65 33 53  rator *)sqlite3S
e970: 63 72 61 74 63 68 4d 61 6c 6c 6f 63 28 6e 42 79  cratchMalloc(nBy
e980: 74 65 29 3b 0a 20 20 69 66 28 20 21 70 20 29 7b  te);.  if( !p ){
e990: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
e9a0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
e9b0: 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 6e 42 79  memset(p, 0, nBy
e9c0: 74 65 29 3b 0a 20 20 70 2d 3e 6e 53 65 67 6d 65  te);.  p->nSegme
e9d0: 6e 74 20 3d 20 6e 53 65 67 6d 65 6e 74 3b 0a 0a  nt = nSegment;..
e9e0: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 65    /* Allocate te
e9f0: 6d 70 6f 72 61 72 79 20 73 70 61 63 65 20 75 73  mporary space us
ea00: 65 64 20 62 79 20 74 68 65 20 6d 65 72 67 65 2d  ed by the merge-
ea10: 73 6f 72 74 20 72 6f 75 74 69 6e 65 2e 20 54 68  sort routine. Th
ea20: 69 73 20 62 6c 6f 63 6b 0a 20 20 2a 2a 20 6f 66  is block.  ** of
ea30: 20 6d 65 6d 6f 72 79 20 77 69 6c 6c 20 62 65 20   memory will be 
ea40: 66 72 65 65 64 20 62 65 66 6f 72 65 20 74 68 69  freed before thi
ea50: 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72  s function retur
ea60: 6e 73 2e 0a 20 20 2a 2f 0a 20 20 61 54 6d 70 20  ns..  */.  aTmp 
ea70: 3d 20 28 68 74 5f 73 6c 6f 74 20 2a 29 73 71 6c  = (ht_slot *)sql
ea80: 69 74 65 33 53 63 72 61 74 63 68 4d 61 6c 6c 6f  ite3ScratchMallo
ea90: 63 28 0a 20 20 20 20 20 20 73 69 7a 65 6f 66 28  c(.      sizeof(
eaa0: 68 74 5f 73 6c 6f 74 29 20 2a 20 28 69 4c 61 73  ht_slot) * (iLas
eab0: 74 3e 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  t>HASHTABLE_NPAG
eac0: 45 3f 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  E?HASHTABLE_NPAG
ead0: 45 3a 69 4c 61 73 74 29 0a 20 20 29 3b 0a 20 20  E:iLast).  );.  
eae0: 69 66 28 20 21 61 54 6d 70 20 29 7b 0a 20 20 20  if( !aTmp ){.   
eaf0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
eb00: 45 4d 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69  EM;.  }..  for(i
eb10: 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  =0; rc==SQLITE_O
eb20: 4b 20 26 26 20 69 3c 6e 53 65 67 6d 65 6e 74 3b  K && i<nSegment;
eb30: 20 69 2b 2b 29 7b 0a 20 20 20 20 76 6f 6c 61 74   i++){.    volat
eb40: 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61  ile ht_slot *aHa
eb50: 73 68 3b 0a 20 20 20 20 75 33 32 20 69 5a 65 72  sh;.    u32 iZer
eb60: 6f 3b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  o;.    volatile 
eb70: 75 33 32 20 2a 61 50 67 6e 6f 3b 0a 0a 20 20 20  u32 *aPgno;..   
eb80: 20 72 63 20 3d 20 77 61 6c 48 61 73 68 47 65 74   rc = walHashGet
eb90: 28 70 57 61 6c 2c 20 69 2c 20 26 61 48 61 73 68  (pWal, i, &aHash
eba0: 2c 20 26 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f  , &aPgno, &iZero
ebb0: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  );.    if( rc==S
ebc0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
ebd0: 20 20 69 6e 74 20 6a 3b 20 20 20 20 20 20 20 20    int j;        
ebe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
ebf0: 20 43 6f 75 6e 74 65 72 20 76 61 72 69 61 62 6c   Counter variabl
ec00: 65 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e  e */.      int n
ec10: 45 6e 74 72 79 3b 20 20 20 20 20 20 20 20 20 20  Entry;          
ec20: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
ec30: 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74   of entries in t
ec40: 68 69 73 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 20  his segment */. 
ec50: 20 20 20 20 20 68 74 5f 73 6c 6f 74 20 2a 61 49       ht_slot *aI
ec60: 6e 64 65 78 3b 20 20 20 20 20 20 20 20 20 20 20  ndex;           
ec70: 20 2f 2a 20 53 6f 72 74 65 64 20 69 6e 64 65 78   /* Sorted index
ec80: 20 66 6f 72 20 74 68 69 73 20 73 65 67 6d 65 6e   for this segmen
ec90: 74 20 2a 2f 0a 0a 20 20 20 20 20 20 61 50 67 6e  t */..      aPgn
eca0: 6f 2b 2b 3b 0a 20 20 20 20 20 20 69 66 28 20 28  o++;.      if( (
ecb0: 69 2b 31 29 3d 3d 6e 53 65 67 6d 65 6e 74 20 29  i+1)==nSegment )
ecc0: 7b 0a 20 20 20 20 20 20 20 20 6e 45 6e 74 72 79  {.        nEntry
ecd0: 20 3d 20 28 69 6e 74 29 28 69 4c 61 73 74 20 2d   = (int)(iLast -
ece0: 20 69 5a 65 72 6f 29 3b 0a 20 20 20 20 20 20 7d   iZero);.      }
ecf0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 6e 45  else{.        nE
ed00: 6e 74 72 79 20 3d 20 28 69 6e 74 29 28 28 75 33  ntry = (int)((u3
ed10: 32 2a 29 61 48 61 73 68 20 2d 20 28 75 33 32 2a  2*)aHash - (u32*
ed20: 29 61 50 67 6e 6f 29 3b 0a 20 20 20 20 20 20 7d  )aPgno);.      }
ed30: 0a 20 20 20 20 20 20 61 49 6e 64 65 78 20 3d 20  .      aIndex = 
ed40: 26 28 28 68 74 5f 73 6c 6f 74 20 2a 29 26 70 2d  &((ht_slot *)&p-
ed50: 3e 61 53 65 67 6d 65 6e 74 5b 70 2d 3e 6e 53 65  >aSegment[p->nSe
ed60: 67 6d 65 6e 74 5d 29 5b 69 5a 65 72 6f 5d 3b 0a  gment])[iZero];.
ed70: 20 20 20 20 20 20 69 5a 65 72 6f 2b 2b 3b 0a 20        iZero++;. 
ed80: 20 0a 20 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b   .      for(j=0;
ed90: 20 6a 3c 6e 45 6e 74 72 79 3b 20 6a 2b 2b 29 7b   j<nEntry; j++){
eda0: 0a 20 20 20 20 20 20 20 20 61 49 6e 64 65 78 5b  .        aIndex[
edb0: 6a 5d 20 3d 20 28 68 74 5f 73 6c 6f 74 29 6a 3b  j] = (ht_slot)j;
edc0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 77  .      }.      w
edd0: 61 6c 4d 65 72 67 65 73 6f 72 74 28 28 75 33 32  alMergesort((u32
ede0: 20 2a 29 61 50 67 6e 6f 2c 20 61 54 6d 70 2c 20   *)aPgno, aTmp, 
edf0: 61 49 6e 64 65 78 2c 20 26 6e 45 6e 74 72 79 29  aIndex, &nEntry)
ee00: 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65 67 6d  ;.      p->aSegm
ee10: 65 6e 74 5b 69 5d 2e 69 5a 65 72 6f 20 3d 20 69  ent[i].iZero = i
ee20: 5a 65 72 6f 3b 0a 20 20 20 20 20 20 70 2d 3e 61  Zero;.      p->a
ee30: 53 65 67 6d 65 6e 74 5b 69 5d 2e 6e 45 6e 74 72  Segment[i].nEntr
ee40: 79 20 3d 20 6e 45 6e 74 72 79 3b 0a 20 20 20 20  y = nEntry;.    
ee50: 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d    p->aSegment[i]
ee60: 2e 61 49 6e 64 65 78 20 3d 20 61 49 6e 64 65 78  .aIndex = aIndex
ee70: 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65 67 6d  ;.      p->aSegm
ee80: 65 6e 74 5b 69 5d 2e 61 50 67 6e 6f 20 3d 20 28  ent[i].aPgno = (
ee90: 75 33 32 20 2a 29 61 50 67 6e 6f 3b 0a 20 20 20  u32 *)aPgno;.   
eea0: 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33   }.  }.  sqlite3
eeb0: 53 63 72 61 74 63 68 46 72 65 65 28 61 54 6d 70  ScratchFree(aTmp
eec0: 29 3b 0a 0a 20 20 69 66 28 20 72 63 21 3d 53 51  );..  if( rc!=SQ
eed0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 77  LITE_OK ){.    w
eee0: 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28 70  alIteratorFree(p
eef0: 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 20 3d 20 70  );.  }.  *pp = p
ef00: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
ef10: 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20  ../*.** Attempt 
ef20: 74 6f 20 6f 62 74 61 69 6e 20 74 68 65 20 65 78  to obtain the ex
ef30: 63 6c 75 73 69 76 65 20 57 41 4c 20 6c 6f 63 6b  clusive WAL lock
ef40: 20 64 65 66 69 6e 65 64 20 62 79 20 70 61 72 61   defined by para
ef50: 6d 65 74 65 72 73 20 6c 6f 63 6b 49 64 78 20 61  meters lockIdx a
ef60: 6e 64 0a 2a 2a 20 6e 2e 20 49 66 20 74 68 65 20  nd.** n. If the 
ef70: 61 74 74 65 6d 70 74 20 66 61 69 6c 73 20 61 6e  attempt fails an
ef80: 64 20 70 61 72 61 6d 65 74 65 72 20 78 42 75 73  d parameter xBus
ef90: 79 20 69 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 74  y is not NULL, t
efa0: 68 65 6e 20 69 74 20 69 73 20 61 0a 2a 2a 20 62  hen it is a.** b
efb0: 75 73 79 2d 68 61 6e 64 6c 65 72 20 66 75 6e 63  usy-handler func
efc0: 74 69 6f 6e 2e 20 49 6e 76 6f 6b 65 20 69 74 20  tion. Invoke it 
efd0: 61 6e 64 20 72 65 74 72 79 20 74 68 65 20 6c 6f  and retry the lo
efe0: 63 6b 20 75 6e 74 69 6c 20 65 69 74 68 65 72 20  ck until either 
eff0: 74 68 65 0a 2a 2a 20 6c 6f 63 6b 20 69 73 20 73  the.** lock is s
f000: 75 63 63 65 73 73 66 75 6c 6c 79 20 6f 62 74 61  uccessfully obta
f010: 69 6e 65 64 20 6f 72 20 74 68 65 20 62 75 73 79  ined or the busy
f020: 2d 68 61 6e 64 6c 65 72 20 72 65 74 75 72 6e 73  -handler returns
f030: 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e   0..*/.static in
f040: 74 20 77 61 6c 42 75 73 79 4c 6f 63 6b 28 0a 20  t walBusyLock(. 
f050: 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20   Wal *pWal,     
f060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f070: 20 2f 2a 20 57 41 4c 20 63 6f 6e 6e 65 63 74 69   /* WAL connecti
f080: 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 42  on */.  int (*xB
f090: 75 73 79 29 28 76 6f 69 64 2a 29 2c 20 20 20 20  usy)(void*),    
f0a0: 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74          /* Funct
f0b0: 69 6f 6e 20 74 6f 20 63 61 6c 6c 20 77 68 65 6e  ion to call when
f0c0: 20 62 75 73 79 20 2a 2f 0a 20 20 76 6f 69 64 20   busy */.  void 
f0d0: 2a 70 42 75 73 79 41 72 67 2c 20 20 20 20 20 20  *pBusyArg,      
f0e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
f0f0: 6e 74 65 78 74 20 61 72 67 75 6d 65 6e 74 20 66  ntext argument f
f100: 6f 72 20 78 42 75 73 79 48 61 6e 64 6c 65 72 20  or xBusyHandler 
f110: 2a 2f 0a 20 20 69 6e 74 20 6c 6f 63 6b 49 64 78  */.  int lockIdx
f120: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
f130: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f       /* Offset o
f140: 66 20 66 69 72 73 74 20 62 79 74 65 20 74 6f 20  f first byte to 
f150: 6c 6f 63 6b 20 2a 2f 0a 20 20 69 6e 74 20 6e 20  lock */.  int n 
f160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f170: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
f180: 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20  ber of bytes to 
f190: 6c 6f 63 6b 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  lock */.){.  int
f1a0: 20 72 63 3b 0a 20 20 64 6f 20 7b 0a 20 20 20 20   rc;.  do {.    
f1b0: 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
f1c0: 75 73 69 76 65 28 70 57 61 6c 2c 20 6c 6f 63 6b  usive(pWal, lock
f1d0: 49 64 78 2c 20 6e 29 3b 0a 20 20 7d 77 68 69 6c  Idx, n);.  }whil
f1e0: 65 28 20 78 42 75 73 79 20 26 26 20 72 63 3d 3d  e( xBusy && rc==
f1f0: 53 51 4c 49 54 45 5f 42 55 53 59 20 26 26 20 78  SQLITE_BUSY && x
f200: 42 75 73 79 28 70 42 75 73 79 41 72 67 29 20 29  Busy(pBusyArg) )
f210: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
f220: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 63 61 63 68  ../*.** The cach
f230: 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  e of the wal-ind
f240: 65 78 20 68 65 61 64 65 72 20 6d 75 73 74 20 62  ex header must b
f250: 65 20 76 61 6c 69 64 20 74 6f 20 63 61 6c 6c 20  e valid to call 
f260: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a  this function..*
f270: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 70 61 67  * Return the pag
f280: 65 2d 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20  e-size in bytes 
f290: 75 73 65 64 20 62 79 20 74 68 65 20 64 61 74 61  used by the data
f2a0: 62 61 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  base..*/.static 
f2b0: 69 6e 74 20 77 61 6c 50 61 67 65 73 69 7a 65 28  int walPagesize(
f2c0: 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 72 65  Wal *pWal){.  re
f2d0: 74 75 72 6e 20 28 70 57 61 6c 2d 3e 68 64 72 2e  turn (pWal->hdr.
f2e0: 73 7a 50 61 67 65 26 30 78 66 65 30 30 29 20 2b  szPage&0xfe00) +
f2f0: 20 28 28 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50   ((pWal->hdr.szP
f300: 61 67 65 26 30 78 30 30 30 31 29 3c 3c 31 36 29  age&0x0001)<<16)
f310: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20  ;.}../*.** Copy 
f320: 61 73 20 6d 75 63 68 20 63 6f 6e 74 65 6e 74 20  as much content 
f330: 61 73 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 74  as we can from t
f340: 68 65 20 57 41 4c 20 62 61 63 6b 20 69 6e 74 6f  he WAL back into
f350: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
f360: 6c 65 0a 2a 2a 20 69 6e 20 72 65 73 70 6f 6e 73  le.** in respons
f370: 65 20 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f  e to an sqlite3_
f380: 77 61 6c 5f 63 68 65 63 6b 70 6f 69 6e 74 28 29  wal_checkpoint()
f390: 20 72 65 71 75 65 73 74 20 6f 72 20 74 68 65 20   request or the 
f3a0: 65 71 75 69 76 61 6c 65 6e 74 2e 0a 2a 2a 0a 2a  equivalent..**.*
f3b0: 2a 20 54 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20  * The amount of 
f3c0: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 63 6f 70 69  information copi
f3d0: 65 73 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64  es from WAL to d
f3e0: 61 74 61 62 61 73 65 20 6d 69 67 68 74 20 62 65  atabase might be
f3f0: 20 6c 69 6d 69 74 65 64 0a 2a 2a 20 62 79 20 61   limited.** by a
f400: 63 74 69 76 65 20 72 65 61 64 65 72 73 2e 20 20  ctive readers.  
f410: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c  This routine wil
f420: 6c 20 6e 65 76 65 72 20 6f 76 65 72 77 72 69 74  l never overwrit
f430: 65 20 61 20 64 61 74 61 62 61 73 65 20 70 61 67  e a database pag
f440: 65 0a 2a 2a 20 74 68 61 74 20 61 20 63 6f 6e 63  e.** that a conc
f450: 75 72 72 65 6e 74 20 72 65 61 64 65 72 20 6d 69  urrent reader mi
f460: 67 68 74 20 62 65 20 75 73 69 6e 67 2e 0a 2a 2a  ght be using..**
f470: 0a 2a 2a 20 41 6c 6c 20 49 2f 4f 20 62 61 72 72  .** All I/O barr
f480: 69 65 72 20 6f 70 65 72 61 74 69 6f 6e 73 20 28  ier operations (
f490: 61 2e 6b 2e 61 20 66 73 79 6e 63 73 29 20 6f 63  a.k.a fsyncs) oc
f4a0: 63 75 72 20 69 6e 20 74 68 69 73 20 72 6f 75 74  cur in this rout
f4b0: 69 6e 65 20 77 68 65 6e 0a 2a 2a 20 53 51 4c 69  ine when.** SQLi
f4c0: 74 65 20 69 73 20 69 6e 20 57 41 4c 2d 6d 6f 64  te is in WAL-mod
f4d0: 65 20 69 6e 20 73 79 6e 63 68 72 6f 6e 6f 75 73  e in synchronous
f4e0: 3d 4e 4f 52 4d 41 4c 2e 20 20 54 68 61 74 20 6d  =NORMAL.  That m
f4f0: 65 61 6e 73 20 74 68 61 74 20 69 66 20 0a 2a 2a  eans that if .**
f500: 20 63 68 65 63 6b 70 6f 69 6e 74 73 20 61 72 65   checkpoints are
f510: 20 61 6c 77 61 79 73 20 72 75 6e 20 62 79 20 61   always run by a
f520: 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65   background thre
f530: 61 64 20 6f 72 20 62 61 63 6b 67 72 6f 75 6e 64  ad or background
f540: 20 0a 2a 2a 20 70 72 6f 63 65 73 73 2c 20 66 6f   .** process, fo
f550: 72 65 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73  reground threads
f560: 20 77 69 6c 6c 20 6e 65 76 65 72 20 62 6c 6f 63   will never bloc
f570: 6b 20 6f 6e 20 61 20 6c 65 6e 67 74 68 79 20 66  k on a lengthy f
f580: 73 79 6e 63 20 63 61 6c 6c 2e 0a 2a 2a 0a 2a 2a  sync call..**.**
f590: 20 46 73 79 6e 63 20 69 73 20 63 61 6c 6c 65 64   Fsync is called
f5a0: 20 6f 6e 20 74 68 65 20 57 41 4c 20 62 65 66 6f   on the WAL befo
f5b0: 72 65 20 77 72 69 74 69 6e 67 20 63 6f 6e 74 65  re writing conte
f5c0: 6e 74 20 6f 75 74 20 6f 66 20 74 68 65 20 57 41  nt out of the WA
f5d0: 4c 20 61 6e 64 0a 2a 2a 20 69 6e 74 6f 20 74 68  L and.** into th
f5e0: 65 20 64 61 74 61 62 61 73 65 2e 20 20 54 68 69  e database.  Thi
f5f0: 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20 69  s ensures that i
f600: 66 20 74 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e  f the new conten
f610: 74 20 69 73 20 70 65 72 73 69 73 74 65 6e 74 0a  t is persistent.
f620: 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 61 6e  ** in the WAL an
f630: 64 20 63 61 6e 20 62 65 20 72 65 63 6f 76 65 72  d can be recover
f640: 65 64 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 70  ed following a p
f650: 6f 77 65 72 2d 6c 6f 73 73 20 6f 72 20 68 61 72  ower-loss or har
f660: 64 20 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 46  d reset..**.** F
f670: 73 79 6e 63 20 69 73 20 61 6c 73 6f 20 63 61 6c  sync is also cal
f680: 6c 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 62  led on the datab
f690: 61 73 65 20 66 69 6c 65 20 69 66 20 28 61 6e 64  ase file if (and
f6a0: 20 6f 6e 6c 79 20 69 66 29 20 74 68 65 20 65 6e   only if) the en
f6b0: 74 69 72 65 0a 2a 2a 20 57 41 4c 20 63 6f 6e 74  tire.** WAL cont
f6c0: 65 6e 74 20 69 73 20 63 6f 70 69 65 64 20 69 6e  ent is copied in
f6d0: 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20  to the database 
f6e0: 66 69 6c 65 2e 20 20 54 68 69 73 20 73 65 63 6f  file.  This seco
f6f0: 6e 64 20 66 73 79 6e 63 20 6d 61 6b 65 73 0a 2a  nd fsync makes.*
f700: 2a 20 69 74 20 73 61 66 65 20 74 6f 20 64 65 6c  * it safe to del
f710: 65 74 65 20 74 68 65 20 57 41 4c 20 73 69 6e 63  ete the WAL sinc
f720: 65 20 74 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e  e the new conten
f730: 74 20 77 69 6c 6c 20 70 65 72 73 69 73 74 20 69  t will persist i
f740: 6e 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73  n the.** databas
f750: 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68  e file..**.** Th
f760: 69 73 20 72 6f 75 74 69 6e 65 20 75 73 65 73 20  is routine uses 
f770: 61 6e 64 20 75 70 64 61 74 65 73 20 74 68 65 20  and updates the 
f780: 6e 42 61 63 6b 66 69 6c 6c 20 66 69 65 6c 64 20  nBackfill field 
f790: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
f7a0: 20 68 65 61 64 65 72 2e 0a 2a 2a 20 54 68 69 73   header..** This
f7b0: 20 69 73 20 74 68 65 20 6f 6e 6c 79 20 72 6f 75   is the only rou
f7c0: 74 69 6e 65 20 74 68 61 20 77 69 6c 6c 20 69 6e  tine tha will in
f7d0: 63 72 65 61 73 65 20 74 68 65 20 76 61 6c 75 65  crease the value
f7e0: 20 6f 66 20 6e 42 61 63 6b 66 69 6c 6c 2e 20 20   of nBackfill.  
f7f0: 0a 2a 2a 20 28 41 20 57 41 4c 20 72 65 73 65 74  .** (A WAL reset
f800: 20 6f 72 20 72 65 63 6f 76 65 72 79 20 77 69 6c   or recovery wil
f810: 6c 20 72 65 76 65 72 74 20 6e 42 61 63 6b 66 69  l revert nBackfi
f820: 6c 6c 20 74 6f 20 7a 65 72 6f 2c 20 62 75 74 20  ll to zero, but 
f830: 6e 6f 74 20 69 6e 63 72 65 61 73 65 0a 2a 2a 20  not increase.** 
f840: 69 74 73 20 76 61 6c 75 65 2e 29 0a 2a 2a 0a 2a  its value.).**.*
f850: 2a 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73  * The caller mus
f860: 74 20 62 65 20 68 6f 6c 64 69 6e 67 20 73 75 66  t be holding suf
f870: 66 69 63 69 65 6e 74 20 6c 6f 63 6b 73 20 74 6f  ficient locks to
f880: 20 65 6e 73 75 72 65 20 74 68 61 74 20 6e 6f 20   ensure that no 
f890: 6f 74 68 65 72 0a 2a 2a 20 63 68 65 63 6b 70 6f  other.** checkpo
f8a0: 69 6e 74 20 69 73 20 72 75 6e 6e 69 6e 67 20 28  int is running (
f8b0: 69 6e 20 61 6e 79 20 6f 74 68 65 72 20 74 68 72  in any other thr
f8c0: 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 29 20  ead or process) 
f8d0: 61 74 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20 74  at the same.** t
f8e0: 69 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ime..*/.static i
f8f0: 6e 74 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74  nt walCheckpoint
f900: 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20  (.  Wal *pWal,  
f910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f920: 20 20 20 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65      /* Wal conne
f930: 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 65  ction */.  int e
f940: 4d 6f 64 65 2c 20 20 20 20 20 20 20 20 20 20 20  Mode,           
f950: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e             /* On
f960: 65 20 6f 66 20 50 41 53 53 49 56 45 2c 20 46 55  e of PASSIVE, FU
f970: 4c 4c 20 6f 72 20 52 45 53 54 41 52 54 20 2a 2f  LL or RESTART */
f980: 0a 20 20 69 6e 74 20 28 2a 78 42 75 73 79 43 61  .  int (*xBusyCa
f990: 6c 6c 29 28 76 6f 69 64 2a 29 2c 20 20 20 20 20  ll)(void*),     
f9a0: 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74     /* Function t
f9b0: 6f 20 63 61 6c 6c 20 77 68 65 6e 20 62 75 73 79  o call when busy
f9c0: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 42 75 73   */.  void *pBus
f9d0: 79 41 72 67 2c 20 20 20 20 20 20 20 20 20 20 20  yArg,           
f9e0: 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74        /* Context
f9f0: 20 61 72 67 75 6d 65 6e 74 20 66 6f 72 20 78 42   argument for xB
fa00: 75 73 79 48 61 6e 64 6c 65 72 20 2a 2f 0a 20 20  usyHandler */.  
fa10: 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20  int sync_flags, 
fa20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fa30: 2f 2a 20 46 6c 61 67 73 20 66 6f 72 20 4f 73 53  /* Flags for OsS
fa40: 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a  ync() (or 0) */.
fa50: 20 20 75 38 20 2a 7a 42 75 66 20 20 20 20 20 20    u8 *zBuf      
fa60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fa70: 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62    /* Temporary b
fa80: 75 66 66 65 72 20 74 6f 20 75 73 65 20 2a 2f 0a  uffer to use */.
fa90: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  ){.  int rc;    
faa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fab0: 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
fac0: 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50  ode */.  int szP
fad0: 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
fae0: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
faf0: 62 61 73 65 20 70 61 67 65 2d 73 69 7a 65 20 2a  base page-size *
fb00: 2f 0a 20 20 57 61 6c 49 74 65 72 61 74 6f 72 20  /.  WalIterator 
fb10: 2a 70 49 74 65 72 20 3d 20 30 3b 20 20 20 20 20  *pIter = 0;     
fb20: 20 20 20 20 2f 2a 20 57 61 6c 20 69 74 65 72 61      /* Wal itera
fb30: 74 6f 72 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20  tor context */. 
fb40: 20 75 33 32 20 69 44 62 70 61 67 65 20 3d 20 30   u32 iDbpage = 0
fb50: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
fb60: 20 2f 2a 20 4e 65 78 74 20 64 61 74 61 62 61 73   /* Next databas
fb70: 65 20 70 61 67 65 20 74 6f 20 77 72 69 74 65 20  e page to write 
fb80: 2a 2f 0a 20 20 75 33 32 20 69 46 72 61 6d 65 20  */.  u32 iFrame 
fb90: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
fba0: 20 20 20 20 20 2f 2a 20 57 61 6c 20 66 72 61 6d       /* Wal fram
fbb0: 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64 61 74  e containing dat
fbc0: 61 20 66 6f 72 20 69 44 62 70 61 67 65 20 2a 2f  a for iDbpage */
fbd0: 0a 20 20 75 33 32 20 6d 78 53 61 66 65 46 72 61  .  u32 mxSafeFra
fbe0: 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  me;             
fbf0: 20 20 20 2f 2a 20 4d 61 78 20 66 72 61 6d 65 20     /* Max frame 
fc00: 74 68 61 74 20 63 61 6e 20 62 65 20 62 61 63 6b  that can be back
fc10: 66 69 6c 6c 65 64 20 2a 2f 0a 20 20 75 33 32 20  filled */.  u32 
fc20: 6d 78 50 61 67 65 3b 20 20 20 20 20 20 20 20 20  mxPage;         
fc30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
fc40: 61 78 20 64 61 74 61 62 61 73 65 20 70 61 67 65  ax database page
fc50: 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 69   to write */.  i
fc60: 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20  nt i;           
fc70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
fc80: 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a  * Loop counter *
fc90: 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c  /.  volatile Wal
fca0: 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b  CkptInfo *pInfo;
fcb0: 20 20 20 20 2f 2a 20 54 68 65 20 63 68 65 63 6b      /* The check
fcc0: 70 6f 69 6e 74 20 73 74 61 74 75 73 20 69 6e 66  point status inf
fcd0: 6f 72 6d 61 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e  ormation */.  in
fce0: 74 20 28 2a 78 42 75 73 79 29 28 76 6f 69 64 2a  t (*xBusy)(void*
fcf0: 29 20 3d 20 30 3b 20 20 20 20 20 20 20 20 2f 2a  ) = 0;        /*
fd00: 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63 61 6c   Function to cal
fd10: 6c 20 77 68 65 6e 20 77 61 69 74 69 6e 67 20 66  l when waiting f
fd20: 6f 72 20 6c 6f 63 6b 73 20 2a 2f 0a 0a 20 20 73  or locks */..  s
fd30: 7a 50 61 67 65 20 3d 20 77 61 6c 50 61 67 65 73  zPage = walPages
fd40: 69 7a 65 28 70 57 61 6c 29 3b 0a 20 20 74 65 73  ize(pWal);.  tes
fd50: 74 63 61 73 65 28 20 73 7a 50 61 67 65 3c 3d 33  tcase( szPage<=3
fd60: 32 37 36 38 20 29 3b 0a 20 20 74 65 73 74 63 61  2768 );.  testca
fd70: 73 65 28 20 73 7a 50 61 67 65 3e 3d 36 35 35 33  se( szPage>=6553
fd80: 36 20 29 3b 0a 20 20 70 49 6e 66 6f 20 3d 20 77  6 );.  pInfo = w
fd90: 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29  alCkptInfo(pWal)
fda0: 3b 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e  ;.  if( pInfo->n
fdb0: 42 61 63 6b 66 69 6c 6c 3e 3d 70 57 61 6c 2d 3e  Backfill>=pWal->
fdc0: 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 20 72 65  hdr.mxFrame ) re
fdd0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
fde0: 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74  .  /* Allocate t
fdf0: 68 65 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20  he iterator */. 
fe00: 20 72 63 20 3d 20 77 61 6c 49 74 65 72 61 74 6f   rc = walIterato
fe10: 72 49 6e 69 74 28 70 57 61 6c 2c 20 26 70 49 74  rInit(pWal, &pIt
fe20: 65 72 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  er);.  if( rc!=S
fe30: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
fe40: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20  return rc;.  }. 
fe50: 20 61 73 73 65 72 74 28 20 70 49 74 65 72 20 29   assert( pIter )
fe60: 3b 0a 0a 20 20 69 66 28 20 65 4d 6f 64 65 21 3d  ;..  if( eMode!=
fe70: 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e  SQLITE_CHECKPOIN
fe80: 54 5f 50 41 53 53 49 56 45 20 29 20 78 42 75 73  T_PASSIVE ) xBus
fe90: 79 20 3d 20 78 42 75 73 79 43 61 6c 6c 3b 0a 0a  y = xBusyCall;..
fea0: 20 20 2f 2a 20 43 6f 6d 70 75 74 65 20 69 6e 20    /* Compute in 
feb0: 6d 78 53 61 66 65 46 72 61 6d 65 20 74 68 65 20  mxSafeFrame the 
fec0: 69 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 73  index of the las
fed0: 74 20 66 72 61 6d 65 20 6f 66 20 74 68 65 20 57  t frame of the W
fee0: 41 4c 20 74 68 61 74 20 69 73 0a 20 20 2a 2a 20  AL that is.  ** 
fef0: 73 61 66 65 20 74 6f 20 77 72 69 74 65 20 69 6e  safe to write in
ff00: 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 2e  to the database.
ff10: 20 20 46 72 61 6d 65 73 20 62 65 79 6f 6e 64 20    Frames beyond 
ff20: 6d 78 53 61 66 65 46 72 61 6d 65 20 6d 69 67 68  mxSafeFrame migh
ff30: 74 0a 20 20 2a 2a 20 6f 76 65 72 77 72 69 74 65  t.  ** overwrite
ff40: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 73 20   database pages 
ff50: 74 68 61 74 20 61 72 65 20 69 6e 20 75 73 65 20  that are in use 
ff60: 62 79 20 61 63 74 69 76 65 20 72 65 61 64 65 72  by active reader
ff70: 73 20 61 6e 64 20 74 68 75 73 0a 20 20 2a 2a 20  s and thus.  ** 
ff80: 63 61 6e 6e 6f 74 20 62 65 20 62 61 63 6b 66 69  cannot be backfi
ff90: 6c 6c 65 64 20 66 72 6f 6d 20 74 68 65 20 57 41  lled from the WA
ffa0: 4c 2e 0a 20 20 2a 2f 0a 20 20 6d 78 53 61 66 65  L..  */.  mxSafe
ffb0: 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64  Frame = pWal->hd
ffc0: 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 6d 78 50  r.mxFrame;.  mxP
ffd0: 61 67 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  age = pWal->hdr.
ffe0: 6e 50 61 67 65 3b 0a 20 20 66 6f 72 28 69 3d 31  nPage;.  for(i=1
fff0: 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b  ; i<WAL_NREADER;
10000 20 69 2b 2b 29 7b 0a 20 20 20 20 75 33 32 20 79   i++){.    u32 y
10010 20 3d 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d   = pInfo->aReadM
10020 61 72 6b 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20  ark[i];.    if( 
10030 6d 78 53 61 66 65 46 72 61 6d 65 3e 79 20 29 7b  mxSafeFrame>y ){
10040 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 79  .      assert( y
10050 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  <=pWal->hdr.mxFr
10060 61 6d 65 20 29 3b 0a 20 20 20 20 20 20 72 63 20  ame );.      rc 
10070 3d 20 77 61 6c 42 75 73 79 4c 6f 63 6b 28 70 57  = walBusyLock(pW
10080 61 6c 2c 20 78 42 75 73 79 2c 20 70 42 75 73 79  al, xBusy, pBusy
10090 41 72 67 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Arg, WAL_READ_LO
100a0 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20 20 20  CK(i), 1);.     
100b0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
100c0 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49  OK ){.        pI
100d0 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69  nfo->aReadMark[i
100e0 5d 20 3d 20 28 69 3d 3d 31 20 3f 20 6d 78 53 61  ] = (i==1 ? mxSa
100f0 66 65 46 72 61 6d 65 20 3a 20 52 45 41 44 4d 41  feFrame : READMA
10100 52 4b 5f 4e 4f 54 5f 55 53 45 44 29 3b 0a 20 20  RK_NOT_USED);.  
10110 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45        walUnlockE
10120 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
10130 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c  AL_READ_LOCK(i),
10140 20 31 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65   1);.      }else
10150 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
10160 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20 20 20  BUSY ){.        
10170 6d 78 53 61 66 65 46 72 61 6d 65 20 3d 20 79 3b  mxSafeFrame = y;
10180 0a 20 20 20 20 20 20 20 20 78 42 75 73 79 20 3d  .        xBusy =
10190 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b   0;.      }else{
101a0 0a 20 20 20 20 20 20 20 20 67 6f 74 6f 20 77 61  .        goto wa
101b0 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74 3b  lcheckpoint_out;
101c0 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
101d0 20 7d 0a 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d   }..  if( pInfo-
101e0 3e 6e 42 61 63 6b 66 69 6c 6c 3c 6d 78 53 61 66  >nBackfill<mxSaf
101f0 65 46 72 61 6d 65 0a 20 20 20 26 26 20 28 72 63  eFrame.   && (rc
10200 20 3d 20 77 61 6c 42 75 73 79 4c 6f 63 6b 28 70   = walBusyLock(p
10210 57 61 6c 2c 20 78 42 75 73 79 2c 20 70 42 75 73  Wal, xBusy, pBus
10220 79 41 72 67 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  yArg, WAL_READ_L
10230 4f 43 4b 28 30 29 2c 20 31 29 29 3d 3d 53 51 4c  OCK(0), 1))==SQL
10240 49 54 45 5f 4f 4b 0a 20 20 29 7b 0a 20 20 20 20  ITE_OK.  ){.    
10250 69 36 34 20 6e 53 69 7a 65 3b 20 20 20 20 20 20  i64 nSize;      
10260 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
10270 20 43 75 72 72 65 6e 74 20 73 69 7a 65 20 6f 66   Current size of
10280 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 2a   database file *
10290 2f 0a 20 20 20 20 75 33 32 20 6e 42 61 63 6b 66  /.    u32 nBackf
102a0 69 6c 6c 20 3d 20 70 49 6e 66 6f 2d 3e 6e 42 61  ill = pInfo->nBa
102b0 63 6b 66 69 6c 6c 3b 0a 0a 20 20 20 20 2f 2a 20  ckfill;..    /* 
102c0 53 79 6e 63 20 74 68 65 20 57 41 4c 20 74 6f 20  Sync the WAL to 
102d0 64 69 73 6b 20 2a 2f 0a 20 20 20 20 69 66 28 20  disk */.    if( 
102e0 73 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a 20 20  sync_flags ){.  
102f0 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
10300 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57 61  OsSync(pWal->pWa
10310 6c 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73 29  lFd, sync_flags)
10320 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
10330 49 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  If the database 
10340 6d 61 79 20 67 72 6f 77 20 61 73 20 61 20 72 65  may grow as a re
10350 73 75 6c 74 20 6f 66 20 74 68 69 73 20 63 68 65  sult of this che
10360 63 6b 70 6f 69 6e 74 2c 20 68 69 6e 74 0a 20 20  ckpoint, hint.  
10370 20 20 2a 2a 20 61 62 6f 75 74 20 74 68 65 20 65    ** about the e
10380 76 65 6e 74 75 61 6c 20 73 69 7a 65 20 6f 66 20  ventual size of 
10390 74 68 65 20 64 62 20 66 69 6c 65 20 74 6f 20 74  the db file to t
103a0 68 65 20 56 46 53 20 6c 61 79 65 72 2e 0a 20 20  he VFS layer..  
103b0 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d    */.    if( rc=
103c0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
103d0 20 20 20 20 69 36 34 20 6e 52 65 71 20 3d 20 28      i64 nReq = (
103e0 28 69 36 34 29 6d 78 50 61 67 65 20 2a 20 73 7a  (i64)mxPage * sz
103f0 50 61 67 65 29 3b 0a 20 20 20 20 20 20 72 63 20  Page);.      rc 
10400 3d 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53  = sqlite3OsFileS
10410 69 7a 65 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  ize(pWal->pDbFd,
10420 20 26 6e 53 69 7a 65 29 3b 0a 20 20 20 20 20 20   &nSize);.      
10430 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
10440 4b 20 26 26 20 6e 53 69 7a 65 3c 6e 52 65 71 20  K && nSize<nReq 
10450 29 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  ){.        sqlit
10460 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 48  e3OsFileControlH
10470 69 6e 74 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  int(pWal->pDbFd,
10480 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 53 49   SQLITE_FCNTL_SI
10490 5a 45 5f 48 49 4e 54 2c 20 26 6e 52 65 71 29 3b  ZE_HINT, &nReq);
104a0 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
104b0 0a 20 20 20 20 2f 2a 20 49 74 65 72 61 74 65 20  .    /* Iterate 
104c0 74 68 72 6f 75 67 68 20 74 68 65 20 63 6f 6e 74  through the cont
104d0 65 6e 74 73 20 6f 66 20 74 68 65 20 57 41 4c 2c  ents of the WAL,
104e0 20 63 6f 70 79 69 6e 67 20 64 61 74 61 20 74 6f   copying data to
104f0 20 74 68 65 20 64 62 20 66 69 6c 65 2e 20 2a 2f   the db file. */
10500 0a 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d  .    while( rc==
10510 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 30 3d 3d  SQLITE_OK && 0==
10520 77 61 6c 49 74 65 72 61 74 6f 72 4e 65 78 74 28  walIteratorNext(
10530 70 49 74 65 72 2c 20 26 69 44 62 70 61 67 65 2c  pIter, &iDbpage,
10540 20 26 69 46 72 61 6d 65 29 20 29 7b 0a 20 20 20   &iFrame) ){.   
10550 20 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 0a     i64 iOffset;.
10560 20 20 20 20 20 20 61 73 73 65 72 74 28 20 77 61        assert( wa
10570 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c  lFramePgno(pWal,
10580 20 69 46 72 61 6d 65 29 3d 3d 69 44 62 70 61 67   iFrame)==iDbpag
10590 65 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 69  e );.      if( i
105a0 46 72 61 6d 65 3c 3d 6e 42 61 63 6b 66 69 6c 6c  Frame<=nBackfill
105b0 20 7c 7c 20 69 46 72 61 6d 65 3e 6d 78 53 61 66   || iFrame>mxSaf
105c0 65 46 72 61 6d 65 20 7c 7c 20 69 44 62 70 61 67  eFrame || iDbpag
105d0 65 3e 6d 78 50 61 67 65 20 29 20 63 6f 6e 74 69  e>mxPage ) conti
105e0 6e 75 65 3b 0a 20 20 20 20 20 20 69 4f 66 66 73  nue;.      iOffs
105f0 65 74 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66  et = walFrameOff
10600 73 65 74 28 69 46 72 61 6d 65 2c 20 73 7a 50 61  set(iFrame, szPa
10610 67 65 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  ge) + WAL_FRAME_
10620 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 20 20 2f  HDRSIZE;.      /
10630 2a 20 74 65 73 74 63 61 73 65 28 20 49 53 5f 42  * testcase( IS_B
10640 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20  IG_INT(iOffset) 
10650 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73 20 61  ); // requires a
10660 20 34 47 69 42 20 57 41 4c 20 66 69 6c 65 20 2a   4GiB WAL file *
10670 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  /.      rc = sql
10680 69 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d  ite3OsRead(pWal-
10690 3e 70 57 61 6c 46 64 2c 20 7a 42 75 66 2c 20 73  >pWalFd, zBuf, s
106a0 7a 50 61 67 65 2c 20 69 4f 66 66 73 65 74 29 3b  zPage, iOffset);
106b0 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
106c0 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
106d0 3b 0a 20 20 20 20 20 20 69 4f 66 66 73 65 74 20  ;.      iOffset 
106e0 3d 20 28 69 44 62 70 61 67 65 2d 31 29 2a 28 69  = (iDbpage-1)*(i
106f0 36 34 29 73 7a 50 61 67 65 3b 0a 20 20 20 20 20  64)szPage;.     
10700 20 74 65 73 74 63 61 73 65 28 20 49 53 5f 42 49   testcase( IS_BI
10710 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20 29  G_INT(iOffset) )
10720 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  ;.      rc = sql
10730 69 74 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c  ite3OsWrite(pWal
10740 2d 3e 70 44 62 46 64 2c 20 7a 42 75 66 2c 20 73  ->pDbFd, zBuf, s
10750 7a 50 61 67 65 2c 20 69 4f 66 66 73 65 74 29 3b  zPage, iOffset);
10760 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
10770 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
10780 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
10790 49 66 20 77 6f 72 6b 20 77 61 73 20 61 63 74 75  If work was actu
107a0 61 6c 6c 79 20 61 63 63 6f 6d 70 6c 69 73 68 65  ally accomplishe
107b0 64 2e 2e 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20  d... */.    if( 
107c0 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
107d0 0a 20 20 20 20 20 20 69 66 28 20 6d 78 53 61 66  .      if( mxSaf
107e0 65 46 72 61 6d 65 3d 3d 77 61 6c 49 6e 64 65 78  eFrame==walIndex
107f0 48 64 72 28 70 57 61 6c 29 2d 3e 6d 78 46 72 61  Hdr(pWal)->mxFra
10800 6d 65 20 29 7b 0a 20 20 20 20 20 20 20 20 69 36  me ){.        i6
10810 34 20 73 7a 44 62 20 3d 20 70 57 61 6c 2d 3e 68  4 szDb = pWal->h
10820 64 72 2e 6e 50 61 67 65 2a 28 69 36 34 29 73 7a  dr.nPage*(i64)sz
10830 50 61 67 65 3b 0a 20 20 20 20 20 20 20 20 74 65  Page;.        te
10840 73 74 63 61 73 65 28 20 49 53 5f 42 49 47 5f 49  stcase( IS_BIG_I
10850 4e 54 28 73 7a 44 62 29 20 29 3b 0a 20 20 20 20  NT(szDb) );.    
10860 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
10870 4f 73 54 72 75 6e 63 61 74 65 28 70 57 61 6c 2d  OsTruncate(pWal-
10880 3e 70 44 62 46 64 2c 20 73 7a 44 62 29 3b 0a 20  >pDbFd, szDb);. 
10890 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
108a0 51 4c 49 54 45 5f 4f 4b 20 26 26 20 73 79 6e 63  QLITE_OK && sync
108b0 5f 66 6c 61 67 73 20 29 7b 0a 20 20 20 20 20 20  _flags ){.      
108c0 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
108d0 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 44 62  OsSync(pWal->pDb
108e0 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73 29 3b  Fd, sync_flags);
108f0 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
10900 20 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d   }.      if( rc=
10910 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
10920 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61        pInfo->nBa
10930 63 6b 66 69 6c 6c 20 3d 20 6d 78 53 61 66 65 46  ckfill = mxSafeF
10940 72 61 6d 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20  rame;.      }.  
10950 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 52 65 6c 65    }..    /* Rele
10960 61 73 65 20 74 68 65 20 72 65 61 64 65 72 20 6c  ase the reader l
10970 6f 63 6b 20 68 65 6c 64 20 77 68 69 6c 65 20 62  ock held while b
10980 61 63 6b 66 69 6c 6c 69 6e 67 20 2a 2f 0a 20 20  ackfilling */.  
10990 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75    walUnlockExclu
109a0 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52  sive(pWal, WAL_R
109b0 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 31 29 3b  EAD_LOCK(0), 1);
109c0 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
109d0 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20  SQLITE_BUSY ){. 
109e0 20 20 20 2f 2a 20 52 65 73 65 74 20 74 68 65 20     /* Reset the 
109f0 72 65 74 75 72 6e 20 63 6f 64 65 20 73 6f 20 61  return code so a
10a00 73 20 6e 6f 74 20 74 6f 20 72 65 70 6f 72 74 20  s not to report 
10a10 61 20 63 68 65 63 6b 70 6f 69 6e 74 20 66 61 69  a checkpoint fai
10a20 6c 75 72 65 0a 20 20 20 20 2a 2a 20 6a 75 73 74  lure.    ** just
10a30 20 62 65 63 61 75 73 65 20 74 68 65 72 65 20 61   because there a
10a40 72 65 20 61 63 74 69 76 65 20 72 65 61 64 65 72  re active reader
10a50 73 2e 20 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20  s.  */.    rc = 
10a60 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a  SQLITE_OK;.  }..
10a70 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20    /* If this is 
10a80 61 6e 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 50  an SQLITE_CHECKP
10a90 4f 49 4e 54 5f 52 45 53 54 41 52 54 20 6f 70 65  OINT_RESTART ope
10aa0 72 61 74 69 6f 6e 2c 20 61 6e 64 20 74 68 65 20  ration, and the 
10ab0 65 6e 74 69 72 65 20 77 61 6c 0a 20 20 2a 2a 20  entire wal.  ** 
10ac0 66 69 6c 65 20 68 61 73 20 62 65 65 6e 20 63 6f  file has been co
10ad0 70 69 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61  pied into the da
10ae0 74 61 62 61 73 65 20 66 69 6c 65 2c 20 74 68 65  tabase file, the
10af0 6e 20 62 6c 6f 63 6b 20 75 6e 74 69 6c 20 61 6c  n block until al
10b00 6c 0a 20 20 2a 2a 20 72 65 61 64 65 72 73 20 68  l.  ** readers h
10b10 61 76 65 20 66 69 6e 69 73 68 65 64 20 75 73 69  ave finished usi
10b20 6e 67 20 74 68 65 20 77 61 6c 20 66 69 6c 65 2e  ng the wal file.
10b30 20 54 68 69 73 20 65 6e 73 75 72 65 73 20 74 68   This ensures th
10b40 61 74 20 74 68 65 20 6e 65 78 74 0a 20 20 2a 2a  at the next.  **
10b50 20 70 72 6f 63 65 73 73 20 74 6f 20 77 72 69 74   process to writ
10b60 65 20 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  e to the databas
10b70 65 20 72 65 73 74 61 72 74 73 20 74 68 65 20 77  e restarts the w
10b80 61 6c 20 66 69 6c 65 2e 0a 20 20 2a 2f 0a 20 20  al file..  */.  
10b90 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
10ba0 4b 20 26 26 20 65 4d 6f 64 65 21 3d 53 51 4c 49  K && eMode!=SQLI
10bb0 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41  TE_CHECKPOINT_PA
10bc0 53 53 49 56 45 20 29 7b 0a 20 20 20 20 61 73 73  SSIVE ){.    ass
10bd0 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65  ert( pWal->write
10be0 4c 6f 63 6b 20 29 3b 0a 20 20 20 20 69 66 28 20  Lock );.    if( 
10bf0 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
10c00 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  <pWal->hdr.mxFra
10c10 6d 65 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  me ){.      rc =
10c20 20 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a 20 20   SQLITE_BUSY;.  
10c30 20 20 7d 65 6c 73 65 20 69 66 28 20 65 4d 6f 64    }else if( eMod
10c40 65 3d 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b 50  e==SQLITE_CHECKP
10c50 4f 49 4e 54 5f 52 45 53 54 41 52 54 20 29 7b 0a  OINT_RESTART ){.
10c60 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6d 78        assert( mx
10c70 53 61 66 65 46 72 61 6d 65 3d 3d 70 57 61 6c 2d  SafeFrame==pWal-
10c80 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a  >hdr.mxFrame );.
10c90 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 42 75        rc = walBu
10ca0 73 79 4c 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75  syLock(pWal, xBu
10cb0 73 79 2c 20 70 42 75 73 79 41 72 67 2c 20 57 41  sy, pBusyArg, WA
10cc0 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20  L_READ_LOCK(1), 
10cd0 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a  WAL_NREADER-1);.
10ce0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
10cf0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
10d00 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c     walUnlockExcl
10d10 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
10d20 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41  READ_LOCK(1), WA
10d30 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20 20  L_NREADER-1);.  
10d40 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
10d50 0a 20 77 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f  . walcheckpoint_
10d60 6f 75 74 3a 0a 20 20 77 61 6c 49 74 65 72 61 74  out:.  walIterat
10d70 6f 72 46 72 65 65 28 70 49 74 65 72 29 3b 0a 20  orFree(pIter);. 
10d80 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
10d90 2a 0a 2a 2a 20 49 66 20 74 68 65 20 57 41 4c 20  *.** If the WAL 
10da0 66 69 6c 65 20 69 73 20 63 75 72 72 65 6e 74 6c  file is currentl
10db0 79 20 6c 61 72 67 65 72 20 74 68 61 6e 20 6e 4d  y larger than nM
10dc0 61 78 20 62 79 74 65 73 20 69 6e 20 73 69 7a 65  ax bytes in size
10dd0 2c 20 74 72 75 6e 63 61 74 65 0a 2a 2a 20 69 74  , truncate.** it
10de0 20 74 6f 20 65 78 61 63 74 6c 79 20 6e 4d 61 78   to exactly nMax
10df0 20 62 79 74 65 73 2e 20 49 66 20 61 6e 20 65 72   bytes. If an er
10e00 72 6f 72 20 6f 63 63 75 72 73 20 77 68 69 6c 65  ror occurs while
10e10 20 64 6f 69 6e 67 20 73 6f 2c 20 69 67 6e 6f 72   doing so, ignor
10e20 65 20 69 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  e it..*/.static 
10e30 76 6f 69 64 20 77 61 6c 4c 69 6d 69 74 53 69 7a  void walLimitSiz
10e40 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 36 34  e(Wal *pWal, i64
10e50 20 6e 4d 61 78 29 7b 0a 20 20 69 36 34 20 73 7a   nMax){.  i64 sz
10e60 3b 0a 20 20 69 6e 74 20 72 78 3b 0a 20 20 73 71  ;.  int rx;.  sq
10e70 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67 6e  lite3BeginBenign
10e80 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 72 78 20 3d  Malloc();.  rx =
10e90 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69   sqlite3OsFileSi
10ea0 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  ze(pWal->pWalFd,
10eb0 20 26 73 7a 29 3b 0a 20 20 69 66 28 20 72 78 3d   &sz);.  if( rx=
10ec0 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 28 73  =SQLITE_OK && (s
10ed0 7a 20 3e 20 6e 4d 61 78 20 29 20 29 7b 0a 20 20  z > nMax ) ){.  
10ee0 20 20 72 78 20 3d 20 73 71 6c 69 74 65 33 4f 73    rx = sqlite3Os
10ef0 54 72 75 6e 63 61 74 65 28 70 57 61 6c 2d 3e 70  Truncate(pWal->p
10f00 57 61 6c 46 64 2c 20 6e 4d 61 78 29 3b 0a 20 20  WalFd, nMax);.  
10f10 7d 0a 20 20 73 71 6c 69 74 65 33 45 6e 64 42 65  }.  sqlite3EndBe
10f20 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20  nignMalloc();.  
10f30 69 66 28 20 72 78 20 29 7b 0a 20 20 20 20 73 71  if( rx ){.    sq
10f40 6c 69 74 65 33 5f 6c 6f 67 28 72 78 2c 20 22 63  lite3_log(rx, "c
10f50 61 6e 6e 6f 74 20 6c 69 6d 69 74 20 57 41 4c 20  annot limit WAL 
10f60 73 69 7a 65 3a 20 25 73 22 2c 20 70 57 61 6c 2d  size: %s", pWal-
10f70 3e 7a 57 61 6c 4e 61 6d 65 29 3b 0a 20 20 7d 0a  >zWalName);.  }.
10f80 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61  }../*.** Close a
10f90 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 61   connection to a
10fa0 20 6c 6f 67 20 66 69 6c 65 2e 0a 2a 2f 0a 69 6e   log file..*/.in
10fb0 74 20 73 71 6c 69 74 65 33 57 61 6c 43 6c 6f 73  t sqlite3WalClos
10fc0 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20  e(.  Wal *pWal, 
10fd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10fe0 20 20 20 20 20 2f 2a 20 57 61 6c 20 74 6f 20 63       /* Wal to c
10ff0 6c 6f 73 65 20 2a 2f 0a 20 20 69 6e 74 20 73 79  lose */.  int sy
11000 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20 20  nc_flags,       
11010 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61            /* Fla
11020 67 73 20 74 6f 20 70 61 73 73 20 74 6f 20 4f 73  gs to pass to Os
11030 53 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f  Sync() (or 0) */
11040 0a 20 20 69 6e 74 20 6e 42 75 66 2c 0a 20 20 75  .  int nBuf,.  u
11050 38 20 2a 7a 42 75 66 20 20 20 20 20 20 20 20 20  8 *zBuf         
11060 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
11070 2a 20 42 75 66 66 65 72 20 6f 66 20 61 74 20 6c  * Buffer of at l
11080 65 61 73 74 20 6e 42 75 66 20 62 79 74 65 73 20  east nBuf bytes 
11090 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  */.){.  int rc =
110a0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66   SQLITE_OK;.  if
110b0 28 20 70 57 61 6c 20 29 7b 0a 20 20 20 20 69 6e  ( pWal ){.    in
110c0 74 20 69 73 44 65 6c 65 74 65 20 3d 20 30 3b 20  t isDelete = 0; 
110d0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
110e0 72 75 65 20 74 6f 20 75 6e 6c 69 6e 6b 20 77 61  rue to unlink wa
110f0 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20  l and wal-index 
11100 66 69 6c 65 73 20 2a 2f 0a 0a 20 20 20 20 2f 2a  files */..    /*
11110 20 49 66 20 61 6e 20 45 58 43 4c 55 53 49 56 45   If an EXCLUSIVE
11120 20 6c 6f 63 6b 20 63 61 6e 20 62 65 20 6f 62 74   lock can be obt
11130 61 69 6e 65 64 20 6f 6e 20 74 68 65 20 64 61 74  ained on the dat
11140 61 62 61 73 65 20 66 69 6c 65 20 28 75 73 69 6e  abase file (usin
11150 67 20 74 68 65 0a 20 20 20 20 2a 2a 20 6f 72 64  g the.    ** ord
11160 69 6e 61 72 79 2c 20 72 6f 6c 6c 62 61 63 6b 2d  inary, rollback-
11170 6d 6f 64 65 20 6c 6f 63 6b 69 6e 67 20 6d 65 74  mode locking met
11180 68 6f 64 73 2c 20 74 68 69 73 20 67 75 61 72 61  hods, this guara
11190 6e 74 65 65 73 20 74 68 61 74 20 74 68 65 0a 20  ntees that the. 
111a0 20 20 20 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e     ** connection
111b0 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
111c0 20 74 68 69 73 20 6c 6f 67 20 66 69 6c 65 20 69   this log file i
111d0 73 20 74 68 65 20 6f 6e 6c 79 20 63 6f 6e 6e 65  s the only conne
111e0 63 74 69 6f 6e 20 74 6f 0a 20 20 20 20 2a 2a 20  ction to.    ** 
111f0 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 49 6e  the database. In
11200 20 74 68 69 73 20 63 61 73 65 20 63 68 65 63 6b   this case check
11210 70 6f 69 6e 74 20 74 68 65 20 64 61 74 61 62 61  point the databa
11220 73 65 20 61 6e 64 20 75 6e 6c 69 6e 6b 20 62 6f  se and unlink bo
11230 74 68 0a 20 20 20 20 2a 2a 20 74 68 65 20 77 61  th.    ** the wa
11240 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20  l and wal-index 
11250 66 69 6c 65 73 2e 0a 20 20 20 20 2a 2a 0a 20 20  files..    **.  
11260 20 20 2a 2a 20 54 68 65 20 45 58 43 4c 55 53 49    ** The EXCLUSI
11270 56 45 20 6c 6f 63 6b 20 69 73 20 6e 6f 74 20 72  VE lock is not r
11280 65 6c 65 61 73 65 64 20 62 65 66 6f 72 65 20 72  eleased before r
11290 65 74 75 72 6e 69 6e 67 2e 0a 20 20 20 20 2a 2f  eturning..    */
112a0 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
112b0 33 4f 73 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44  3OsLock(pWal->pD
112c0 62 46 64 2c 20 53 51 4c 49 54 45 5f 4c 4f 43 4b  bFd, SQLITE_LOCK
112d0 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20 20  _EXCLUSIVE);.   
112e0 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
112f0 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  OK ){.      if( 
11300 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
11310 6f 64 65 3d 3d 57 41 4c 5f 4e 4f 52 4d 41 4c 5f  ode==WAL_NORMAL_
11320 4d 4f 44 45 20 29 7b 0a 20 20 20 20 20 20 20 20  MODE ){.        
11330 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
11340 6f 64 65 20 3d 20 57 41 4c 5f 45 58 43 4c 55 53  ode = WAL_EXCLUS
11350 49 56 45 5f 4d 4f 44 45 3b 0a 20 20 20 20 20 20  IVE_MODE;.      
11360 7d 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  }.      rc = sql
11370 69 74 65 33 57 61 6c 43 68 65 63 6b 70 6f 69 6e  ite3WalCheckpoin
11380 74 28 0a 20 20 20 20 20 20 20 20 20 20 70 57 61  t(.          pWa
11390 6c 2c 20 53 51 4c 49 54 45 5f 43 48 45 43 4b 50  l, SQLITE_CHECKP
113a0 4f 49 4e 54 5f 50 41 53 53 49 56 45 2c 20 30 2c  OINT_PASSIVE, 0,
113b0 20 30 2c 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20   0, sync_flags, 
113c0 6e 42 75 66 2c 20 7a 42 75 66 2c 20 30 2c 20 30  nBuf, zBuf, 0, 0
113d0 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20  .      );.      
113e0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
113f0 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74  K ){.        int
11400 20 62 50 65 72 73 69 73 74 20 3d 20 2d 31 3b 0a   bPersist = -1;.
11410 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f          sqlite3O
11420 73 46 69 6c 65 43 6f 6e 74 72 6f 6c 48 69 6e 74  sFileControlHint
11430 28 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 57  (.            pW
11440 61 6c 2d 3e 70 44 62 46 64 2c 20 53 51 4c 49 54  al->pDbFd, SQLIT
11450 45 5f 46 43 4e 54 4c 5f 50 45 52 53 49 53 54 5f  E_FCNTL_PERSIST_
11460 57 41 4c 2c 20 26 62 50 65 72 73 69 73 74 0a 20  WAL, &bPersist. 
11470 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20         );.      
11480 20 20 69 66 28 20 62 50 65 72 73 69 73 74 21 3d    if( bPersist!=
11490 31 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 2f  1 ){.          /
114a0 2a 20 54 72 79 20 74 6f 20 64 65 6c 65 74 65 20  * Try to delete 
114b0 74 68 65 20 57 41 4c 20 66 69 6c 65 20 69 66 20  the WAL file if 
114c0 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 63  the checkpoint c
114d0 6f 6d 70 6c 65 74 65 64 20 61 6e 64 0a 20 20 20  ompleted and.   
114e0 20 20 20 20 20 20 20 2a 2a 20 66 73 79 6e 65 64         ** fsyned
114f0 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29   (rc==SQLITE_OK)
11500 20 61 6e 64 20 69 66 20 77 65 20 61 72 65 20 6e   and if we are n
11510 6f 74 20 69 6e 20 70 65 72 73 69 73 74 65 6e 74  ot in persistent
11520 2d 77 61 6c 0a 20 20 20 20 20 20 20 20 20 20 2a  -wal.          *
11530 2a 20 6d 6f 64 65 20 28 21 62 50 65 72 73 69 73  * mode (!bPersis
11540 74 29 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20  t) */.          
11550 69 73 44 65 6c 65 74 65 20 3d 20 31 3b 0a 20 20  isDelete = 1;.  
11560 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
11570 70 57 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 3e  pWal->mxWalSize>
11580 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
11590 2f 2a 20 54 72 79 20 74 6f 20 74 72 75 6e 63 61  /* Try to trunca
115a0 74 65 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20  te the WAL file 
115b0 74 6f 20 7a 65 72 6f 20 62 79 74 65 73 20 69 66  to zero bytes if
115c0 20 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 0a   the checkpoint.
115d0 20 20 20 20 20 20 20 20 20 20 2a 2a 20 63 6f 6d            ** com
115e0 70 6c 65 74 65 64 20 61 6e 64 20 66 73 79 6e 63  pleted and fsync
115f0 65 64 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  ed (rc==SQLITE_O
11600 4b 29 20 61 6e 64 20 77 65 20 61 72 65 20 69 6e  K) and we are in
11610 20 70 65 72 73 69 73 74 65 6e 74 0a 20 20 20 20   persistent.    
11620 20 20 20 20 20 20 2a 2a 20 57 41 4c 20 6d 6f 64        ** WAL mod
11630 65 20 28 62 50 65 72 73 69 73 74 29 20 61 6e 64  e (bPersist) and
11640 20 69 66 20 74 68 65 20 50 52 41 47 4d 41 20 6a   if the PRAGMA j
11650 6f 75 72 6e 61 6c 5f 73 69 7a 65 5f 6c 69 6d 69  ournal_size_limi
11660 74 20 69 73 20 61 0a 20 20 20 20 20 20 20 20 20  t is a.         
11670 20 2a 2a 20 6e 6f 6e 2d 6e 65 67 61 74 69 76 65   ** non-negative
11680 20 76 61 6c 75 65 20 28 70 57 61 6c 2d 3e 6d 78   value (pWal->mx
11690 57 61 6c 53 69 7a 65 3e 3d 30 29 2e 20 20 4e 6f  WalSize>=0).  No
116a0 74 65 20 74 68 61 74 20 77 65 20 74 72 75 6e 63  te that we trunc
116b0 61 74 65 0a 20 20 20 20 20 20 20 20 20 20 2a 2a  ate.          **
116c0 20 74 6f 20 7a 65 72 6f 20 62 79 74 65 73 20 61   to zero bytes a
116d0 73 20 74 72 75 6e 63 61 74 69 6e 67 20 74 6f 20  s truncating to 
116e0 74 68 65 20 6a 6f 75 72 6e 61 6c 5f 73 69 7a 65  the journal_size
116f0 5f 6c 69 6d 69 74 20 6d 69 67 68 74 0a 20 20 20  _limit might.   
11700 20 20 20 20 20 20 20 2a 2a 20 6c 65 61 76 65 20         ** leave 
11710 61 20 63 6f 72 72 75 70 74 20 57 41 4c 20 66 69  a corrupt WAL fi
11720 6c 65 20 6f 6e 20 64 69 73 6b 2e 20 2a 2f 0a 20  le on disk. */. 
11730 20 20 20 20 20 20 20 20 20 77 61 6c 4c 69 6d 69           walLimi
11740 74 53 69 7a 65 28 70 57 61 6c 2c 20 30 29 3b 0a  tSize(pWal, 0);.
11750 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
11760 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 77 61 6c  }.    }..    wal
11770 49 6e 64 65 78 43 6c 6f 73 65 28 70 57 61 6c 2c  IndexClose(pWal,
11780 20 69 73 44 65 6c 65 74 65 29 3b 0a 20 20 20 20   isDelete);.    
11790 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 28 70  sqlite3OsClose(p
117a0 57 61 6c 2d 3e 70 57 61 6c 46 64 29 3b 0a 20 20  Wal->pWalFd);.  
117b0 20 20 69 66 28 20 69 73 44 65 6c 65 74 65 20 29    if( isDelete )
117c0 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 42  {.      sqlite3B
117d0 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63  eginBenignMalloc
117e0 28 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  ();.      sqlite
117f0 33 4f 73 44 65 6c 65 74 65 28 70 57 61 6c 2d 3e  3OsDelete(pWal->
11800 70 56 66 73 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c  pVfs, pWal->zWal
11810 4e 61 6d 65 2c 20 30 29 3b 0a 20 20 20 20 20 20  Name, 0);.      
11820 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e  sqlite3EndBenign
11830 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 20 20 7d 0a  Malloc();.    }.
11840 20 20 20 20 57 41 4c 54 52 41 43 45 28 28 22 57      WALTRACE(("W
11850 41 4c 25 70 3a 20 63 6c 6f 73 65 64 5c 6e 22 2c  AL%p: closed\n",
11860 20 70 57 61 6c 29 29 3b 0a 20 20 20 20 73 71 6c   pWal));.    sql
11870 69 74 65 33 5f 66 72 65 65 28 28 76 6f 69 64 20  ite3_free((void 
11880 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61  *)pWal->apWiData
11890 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
118a0 72 65 65 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20  ree(pWal);.  }. 
118b0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
118c0 2a 0a 2a 2a 20 54 72 79 20 74 6f 20 72 65 61 64  *.** Try to read
118d0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
118e0 65 61 64 65 72 2e 20 20 52 65 74 75 72 6e 20 30  eader.  Return 0
118f0 20 6f 6e 20 73 75 63 63 65 73 73 20 61 6e 64 20   on success and 
11900 31 20 69 66 0a 2a 2a 20 74 68 65 72 65 20 69 73  1 if.** there is
11910 20 61 20 70 72 6f 62 6c 65 6d 2e 0a 2a 2a 0a 2a   a problem..**.*
11920 2a 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  * The wal-index 
11930 69 73 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d  is in shared mem
11940 6f 72 79 2e 20 20 41 6e 6f 74 68 65 72 20 74 68  ory.  Another th
11950 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 20  read or process 
11960 6d 69 67 68 74 0a 2a 2a 20 62 65 20 77 72 69 74  might.** be writ
11970 69 6e 67 20 74 68 65 20 68 65 61 64 65 72 20 61  ing the header a
11980 74 20 74 68 65 20 73 61 6d 65 20 74 69 6d 65 20  t the same time 
11990 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 20 69  this procedure i
119a0 73 20 74 72 79 69 6e 67 20 74 6f 0a 2a 2a 20 72  s trying to.** r
119b0 65 61 64 20 69 74 2c 20 77 68 69 63 68 20 6d 69  ead it, which mi
119c0 67 68 74 20 72 65 73 75 6c 74 20 69 6e 20 69 6e  ght result in in
119d0 63 6f 6e 73 69 73 74 65 6e 63 79 2e 20 20 41 20  consistency.  A 
119e0 64 69 72 74 79 20 72 65 61 64 20 69 73 20 64 65  dirty read is de
119f0 74 65 63 74 65 64 0a 2a 2a 20 62 79 20 76 65 72  tected.** by ver
11a00 69 66 79 69 6e 67 20 74 68 61 74 20 62 6f 74 68  ifying that both
11a10 20 63 6f 70 69 65 73 20 6f 66 20 74 68 65 20 68   copies of the h
11a20 65 61 64 65 72 20 61 72 65 20 74 68 65 20 73 61  eader are the sa
11a30 6d 65 20 61 6e 64 20 61 6c 73 6f 20 62 79 0a 2a  me and also by.*
11a40 2a 20 61 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20  * a checksum on 
11a50 74 68 65 20 68 65 61 64 65 72 2e 0a 2a 2a 0a 2a  the header..**.*
11a60 2a 20 49 66 20 61 6e 64 20 6f 6e 6c 79 20 69 66  * If and only if
11a70 20 74 68 65 20 72 65 61 64 20 69 73 20 63 6f 6e   the read is con
11a80 73 69 73 74 65 6e 74 20 61 6e 64 20 74 68 65 20  sistent and the 
11a90 68 65 61 64 65 72 20 69 73 20 64 69 66 66 65 72  header is differ
11aa0 65 6e 74 20 66 72 6f 6d 0a 2a 2a 20 70 57 61 6c  ent from.** pWal
11ab0 2d 3e 68 64 72 2c 20 74 68 65 6e 20 70 57 61 6c  ->hdr, then pWal
11ac0 2d 3e 68 64 72 20 69 73 20 75 70 64 61 74 65 64  ->hdr is updated
11ad0 20 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e 74 20   to the content 
11ae0 6f 66 20 74 68 65 20 6e 65 77 20 68 65 61 64 65  of the new heade
11af0 72 0a 2a 2a 20 61 6e 64 20 2a 70 43 68 61 6e 67  r.** and *pChang
11b00 65 64 20 69 73 20 73 65 74 20 74 6f 20 31 2e 0a  ed is set to 1..
11b10 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 63 68 65  **.** If the che
11b20 63 6b 73 75 6d 20 63 61 6e 6e 6f 74 20 62 65 20  cksum cannot be 
11b30 76 65 72 69 66 69 65 64 20 72 65 74 75 72 6e 20  verified return 
11b40 6e 6f 6e 2d 7a 65 72 6f 2e 20 49 66 20 74 68 65  non-zero. If the
11b50 20 68 65 61 64 65 72 0a 2a 2a 20 69 73 20 72 65   header.** is re
11b60 61 64 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20  ad successfully 
11b70 61 6e 64 20 74 68 65 20 63 68 65 63 6b 73 75 6d  and the checksum
11b80 20 76 65 72 69 66 69 65 64 2c 20 72 65 74 75 72   verified, retur
11b90 6e 20 7a 65 72 6f 2e 0a 2a 2f 0a 73 74 61 74 69  n zero..*/.stati
11ba0 63 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 54 72  c int walIndexTr
11bb0 79 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 2c 20  yHdr(Wal *pWal, 
11bc0 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a  int *pChanged){.
11bd0 20 20 75 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b    u32 aCksum[2];
11be0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11bf0 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 6f 6e    /* Checksum on
11c00 20 74 68 65 20 68 65 61 64 65 72 20 63 6f 6e 74   the header cont
11c10 65 6e 74 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65  ent */.  WalInde
11c20 78 48 64 72 20 68 31 2c 20 68 32 3b 20 20 20 20  xHdr h1, h2;    
11c30 20 20 20 20 20 20 20 20 20 2f 2a 20 54 77 6f 20           /* Two 
11c40 63 6f 70 69 65 73 20 6f 66 20 74 68 65 20 68 65  copies of the he
11c50 61 64 65 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a  ader content */.
11c60 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20 76 6f    WalIndexHdr vo
11c70 6c 61 74 69 6c 65 20 2a 61 48 64 72 3b 20 20 20  latile *aHdr;   
11c80 20 20 2f 2a 20 48 65 61 64 65 72 20 69 6e 20 73    /* Header in s
11c90 68 61 72 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a  hared memory */.
11ca0 0a 20 20 2f 2a 20 54 68 65 20 66 69 72 73 74 20  .  /* The first 
11cb0 70 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d  page of the wal-
11cc0 69 6e 64 65 78 20 6d 75 73 74 20 62 65 20 6d 61  index must be ma
11cd0 70 70 65 64 20 61 74 20 74 68 69 73 20 70 6f 69  pped at this poi
11ce0 6e 74 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  nt. */.  assert(
11cf0 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30   pWal->nWiData>0
11d00 20 26 26 20 70 57 61 6c 2d 3e 61 70 57 69 44 61   && pWal->apWiDa
11d10 74 61 5b 30 5d 20 29 3b 0a 0a 20 20 2f 2a 20 52  ta[0] );..  /* R
11d20 65 61 64 20 74 68 65 20 68 65 61 64 65 72 2e 20  ead the header. 
11d30 54 68 69 73 20 6d 69 67 68 74 20 68 61 70 70 65  This might happe
11d40 6e 20 63 6f 6e 63 75 72 72 65 6e 74 6c 79 20 77  n concurrently w
11d50 69 74 68 20 61 20 77 72 69 74 65 20 74 6f 20 74  ith a write to t
11d60 68 65 0a 20 20 2a 2a 20 73 61 6d 65 20 61 72 65  he.  ** same are
11d70 61 20 6f 66 20 73 68 61 72 65 64 20 6d 65 6d 6f  a of shared memo
11d80 72 79 20 6f 6e 20 61 20 64 69 66 66 65 72 65 6e  ry on a differen
11d90 74 20 43 50 55 20 69 6e 20 61 20 53 4d 50 2c 0a  t CPU in a SMP,.
11da0 20 20 2a 2a 20 6d 65 61 6e 69 6e 67 20 69 74 20    ** meaning it 
11db0 69 73 20 70 6f 73 73 69 62 6c 65 20 74 68 61 74  is possible that
11dc0 20 61 6e 20 69 6e 63 6f 6e 73 69 73 74 65 6e 74   an inconsistent
11dd0 20 73 6e 61 70 73 68 6f 74 20 69 73 20 72 65 61   snapshot is rea
11de0 64 0a 20 20 2a 2a 20 66 72 6f 6d 20 74 68 65 20  d.  ** from the 
11df0 66 69 6c 65 2e 20 49 66 20 74 68 69 73 20 68 61  file. If this ha
11e00 70 70 65 6e 73 2c 20 72 65 74 75 72 6e 20 6e 6f  ppens, return no
11e10 6e 2d 7a 65 72 6f 2e 0a 20 20 2a 2a 0a 20 20 2a  n-zero..  **.  *
11e20 2a 20 54 68 65 72 65 20 61 72 65 20 74 77 6f 20  * There are two 
11e30 63 6f 70 69 65 73 20 6f 66 20 74 68 65 20 68 65  copies of the he
11e40 61 64 65 72 20 61 74 20 74 68 65 20 62 65 67 69  ader at the begi
11e50 6e 6e 69 6e 67 20 6f 66 20 74 68 65 20 77 61 6c  nning of the wal
11e60 2d 69 6e 64 65 78 2e 0a 20 20 2a 2a 20 57 68 65  -index..  ** Whe
11e70 6e 20 72 65 61 64 69 6e 67 2c 20 72 65 61 64 20  n reading, read 
11e80 5b 30 5d 20 66 69 72 73 74 20 74 68 65 6e 20 5b  [0] first then [
11e90 31 5d 2e 20 20 57 72 69 74 65 73 20 61 72 65 20  1].  Writes are 
11ea0 69 6e 20 74 68 65 20 72 65 76 65 72 73 65 20 6f  in the reverse o
11eb0 72 64 65 72 2e 0a 20 20 2a 2a 20 4d 65 6d 6f 72  rder..  ** Memor
11ec0 79 20 62 61 72 72 69 65 72 73 20 61 72 65 20 75  y barriers are u
11ed0 73 65 64 20 74 6f 20 70 72 65 76 65 6e 74 20 74  sed to prevent t
11ee0 68 65 20 63 6f 6d 70 69 6c 65 72 20 6f 72 20 74  he compiler or t
11ef0 68 65 20 68 61 72 64 77 61 72 65 20 66 72 6f 6d  he hardware from
11f00 0a 20 20 2a 2a 20 72 65 6f 72 64 65 72 69 6e 67  .  ** reordering
11f10 20 74 68 65 20 72 65 61 64 73 20 61 6e 64 20 77   the reads and w
11f20 72 69 74 65 73 2e 0a 20 20 2a 2f 0a 20 20 61 48  rites..  */.  aH
11f30 64 72 20 3d 20 77 61 6c 49 6e 64 65 78 48 64 72  dr = walIndexHdr
11f40 28 70 57 61 6c 29 3b 0a 20 20 6d 65 6d 63 70 79  (pWal);.  memcpy
11f50 28 26 68 31 2c 20 28 76 6f 69 64 20 2a 29 26 61  (&h1, (void *)&a
11f60 48 64 72 5b 30 5d 2c 20 73 69 7a 65 6f 66 28 68  Hdr[0], sizeof(h
11f70 31 29 29 3b 0a 20 20 77 61 6c 53 68 6d 42 61 72  1));.  walShmBar
11f80 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20 6d 65  rier(pWal);.  me
11f90 6d 63 70 79 28 26 68 32 2c 20 28 76 6f 69 64 20  mcpy(&h2, (void 
11fa0 2a 29 26 61 48 64 72 5b 31 5d 2c 20 73 69 7a 65  *)&aHdr[1], size
11fb0 6f 66 28 68 32 29 29 3b 0a 0a 20 20 69 66 28 20  of(h2));..  if( 
11fc0 6d 65 6d 63 6d 70 28 26 68 31 2c 20 26 68 32 2c  memcmp(&h1, &h2,
11fd0 20 73 69 7a 65 6f 66 28 68 31 29 29 21 3d 30 20   sizeof(h1))!=0 
11fe0 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b  ){.    return 1;
11ff0 20 20 20 2f 2a 20 44 69 72 74 79 20 72 65 61 64     /* Dirty read
12000 20 2a 2f 0a 20 20 7d 20 20 0a 20 20 69 66 28 20   */.  }  .  if( 
12010 68 31 2e 69 73 49 6e 69 74 3d 3d 30 20 29 7b 0a  h1.isInit==0 ){.
12020 20 20 20 20 72 65 74 75 72 6e 20 31 3b 20 20 20      return 1;   
12030 2f 2a 20 4d 61 6c 66 6f 72 6d 65 64 20 68 65 61  /* Malformed hea
12040 64 65 72 20 2d 20 70 72 6f 62 61 62 6c 79 20 61  der - probably a
12050 6c 6c 20 7a 65 72 6f 73 20 2a 2f 0a 20 20 7d 0a  ll zeros */.  }.
12060 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74    walChecksumByt
12070 65 73 28 31 2c 20 28 75 38 2a 29 26 68 31 2c 20  es(1, (u8*)&h1, 
12080 73 69 7a 65 6f 66 28 68 31 29 2d 73 69 7a 65 6f  sizeof(h1)-sizeo
12090 66 28 68 31 2e 61 43 6b 73 75 6d 29 2c 20 30 2c  f(h1.aCksum), 0,
120a0 20 61 43 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20   aCksum);.  if( 
120b0 61 43 6b 73 75 6d 5b 30 5d 21 3d 68 31 2e 61 43  aCksum[0]!=h1.aC
120c0 6b 73 75 6d 5b 30 5d 20 7c 7c 20 61 43 6b 73 75  ksum[0] || aCksu
120d0 6d 5b 31 5d 21 3d 68 31 2e 61 43 6b 73 75 6d 5b  m[1]!=h1.aCksum[
120e0 31 5d 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  1] ){.    return
120f0 20 31 3b 20 20 20 2f 2a 20 43 68 65 63 6b 73 75   1;   /* Checksu
12100 6d 20 64 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68  m does not match
12110 20 2a 2f 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6d   */.  }..  if( m
12120 65 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72  emcmp(&pWal->hdr
12130 2c 20 26 68 31 2c 20 73 69 7a 65 6f 66 28 57 61  , &h1, sizeof(Wa
12140 6c 49 6e 64 65 78 48 64 72 29 29 20 29 7b 0a 20  lIndexHdr)) ){. 
12150 20 20 20 2a 70 43 68 61 6e 67 65 64 20 3d 20 31     *pChanged = 1
12160 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 57  ;.    memcpy(&pW
12170 61 6c 2d 3e 68 64 72 2c 20 26 68 31 2c 20 73 69  al->hdr, &h1, si
12180 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
12190 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a  ));.    pWal->sz
121a0 50 61 67 65 20 3d 20 28 70 57 61 6c 2d 3e 68 64  Page = (pWal->hd
121b0 72 2e 73 7a 50 61 67 65 26 30 78 66 65 30 30 29  r.szPage&0xfe00)
121c0 20 2b 20 28 28 70 57 61 6c 2d 3e 68 64 72 2e 73   + ((pWal->hdr.s
121d0 7a 50 61 67 65 26 30 78 30 30 30 31 29 3c 3c 31  zPage&0x0001)<<1
121e0 36 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73 65  6);.    testcase
121f0 28 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 3c 3d  ( pWal->szPage<=
12200 33 32 37 36 38 20 29 3b 0a 20 20 20 20 74 65 73  32768 );.    tes
12210 74 63 61 73 65 28 20 70 57 61 6c 2d 3e 73 7a 50  tcase( pWal->szP
12220 61 67 65 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20  age>=65536 );.  
12230 7d 0a 0a 20 20 2f 2a 20 54 68 65 20 68 65 61 64  }..  /* The head
12240 65 72 20 77 61 73 20 73 75 63 63 65 73 73 66 75  er was successfu
12250 6c 6c 79 20 72 65 61 64 2e 20 52 65 74 75 72 6e  lly read. Return
12260 20 7a 65 72 6f 2e 20 2a 2f 0a 20 20 72 65 74 75   zero. */.  retu
12270 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  rn 0;.}../*.** R
12280 65 61 64 20 74 68 65 20 77 61 6c 2d 69 6e 64 65  ead the wal-inde
12290 78 20 68 65 61 64 65 72 20 66 72 6f 6d 20 74 68  x header from th
122a0 65 20 77 61 6c 2d 69 6e 64 65 78 20 61 6e 64 20  e wal-index and 
122b0 69 6e 74 6f 20 70 57 61 6c 2d 3e 68 64 72 2e 0a  into pWal->hdr..
122c0 2a 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 68 65  ** If the wal-he
122d0 61 64 65 72 20 61 70 70 65 61 72 73 20 74 6f 20  ader appears to 
122e0 62 65 20 63 6f 72 72 75 70 74 2c 20 74 72 79 20  be corrupt, try 
122f0 74 6f 20 72 65 63 6f 6e 73 74 72 75 63 74 20 74  to reconstruct t
12300 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20  he.** wal-index 
12310 66 72 6f 6d 20 74 68 65 20 57 41 4c 20 62 65 66  from the WAL bef
12320 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a  ore returning..*
12330 2a 0a 2a 2a 20 53 65 74 20 2a 70 43 68 61 6e 67  *.** Set *pChang
12340 65 64 20 74 6f 20 31 20 69 66 20 74 68 65 20 77  ed to 1 if the w
12350 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
12360 76 61 6c 75 65 20 69 6e 20 70 57 61 6c 2d 3e 68  value in pWal->h
12370 64 72 20 69 73 0a 2a 2a 20 63 68 61 6e 67 65 64  dr is.** changed
12380 20 62 79 20 74 68 69 73 20 6f 70 65 72 74 69 6f   by this opertio
12390 6e 2e 20 20 49 66 20 70 57 61 6c 2d 3e 68 64 72  n.  If pWal->hdr
123a0 20 69 73 20 75 6e 63 68 61 6e 67 65 64 2c 20 73   is unchanged, s
123b0 65 74 20 2a 70 43 68 61 6e 67 65 64 0a 2a 2a 20  et *pChanged.** 
123c0 74 6f 20 30 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  to 0..**.** If t
123d0 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
123e0 64 65 72 20 69 73 20 73 75 63 63 65 73 73 66 75  der is successfu
123f0 6c 6c 79 20 72 65 61 64 2c 20 72 65 74 75 72 6e  lly read, return
12400 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 0a 2a 2a 20   SQLITE_OK. .** 
12410 4f 74 68 65 72 77 69 73 65 20 61 6e 20 53 51 4c  Otherwise an SQL
12420 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a  ite error code..
12430 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  */.static int wa
12440 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28 57 61  lIndexReadHdr(Wa
12450 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43  l *pWal, int *pC
12460 68 61 6e 67 65 64 29 7b 0a 20 20 69 6e 74 20 72  hanged){.  int r
12470 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
12480 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
12490 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69  turn code */.  i
124a0 6e 74 20 62 61 64 48 64 72 3b 20 20 20 20 20 20  nt badHdr;      
124b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
124c0 2a 20 54 72 75 65 20 69 66 20 61 20 68 65 61 64  * True if a head
124d0 65 72 20 72 65 61 64 20 66 61 69 6c 65 64 20 2a  er read failed *
124e0 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32  /.  volatile u32
124f0 20 2a 70 61 67 65 30 3b 20 20 20 20 20 20 20 20   *page0;        
12500 20 20 20 20 2f 2a 20 43 68 75 6e 6b 20 6f 66 20      /* Chunk of 
12510 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 74 61 69  wal-index contai
12520 6e 69 6e 67 20 68 65 61 64 65 72 20 2a 2f 0a 0a  ning header */..
12530 20 20 2f 2a 20 45 6e 73 75 72 65 20 74 68 61 74    /* Ensure that
12540 20 70 61 67 65 20 30 20 6f 66 20 74 68 65 20 77   page 0 of the w
12550 61 6c 2d 69 6e 64 65 78 20 28 74 68 65 20 70 61  al-index (the pa
12560 67 65 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73  ge that contains
12570 20 74 68 65 20 0a 20 20 2a 2a 20 77 61 6c 2d 69   the .  ** wal-i
12580 6e 64 65 78 20 68 65 61 64 65 72 29 20 69 73 20  ndex header) is 
12590 6d 61 70 70 65 64 2e 20 52 65 74 75 72 6e 20 65  mapped. Return e
125a0 61 72 6c 79 20 69 66 20 61 6e 20 65 72 72 6f 72  arly if an error
125b0 20 6f 63 63 75 72 73 20 68 65 72 65 2e 0a 20 20   occurs here..  
125c0 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 43 68  */.  assert( pCh
125d0 61 6e 67 65 64 20 29 3b 0a 20 20 72 63 20 3d 20  anged );.  rc = 
125e0 77 61 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61  walIndexPage(pWa
125f0 6c 2c 20 30 2c 20 26 70 61 67 65 30 29 3b 0a 20  l, 0, &page0);. 
12600 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
12610 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  OK ){.    return
12620 20 72 63 3b 0a 20 20 7d 3b 0a 20 20 61 73 73 65   rc;.  };.  asse
12630 72 74 28 20 70 61 67 65 30 20 7c 7c 20 70 57 61  rt( page0 || pWa
12640 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20  l->writeLock==0 
12650 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20  );..  /* If the 
12660 66 69 72 73 74 20 70 61 67 65 20 6f 66 20 74 68  first page of th
12670 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 61 73 20  e wal-index has 
12680 62 65 65 6e 20 6d 61 70 70 65 64 2c 20 74 72 79  been mapped, try
12690 20 74 6f 20 72 65 61 64 20 74 68 65 0a 20 20 2a   to read the.  *
126a0 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  * wal-index head
126b0 65 72 20 69 6d 6d 65 64 69 61 74 65 6c 79 2c 20  er immediately, 
126c0 77 69 74 68 6f 75 74 20 68 6f 6c 64 69 6e 67 20  without holding 
126d0 61 6e 79 20 6c 6f 63 6b 2e 20 54 68 69 73 20 75  any lock. This u
126e0 73 75 61 6c 6c 79 0a 20 20 2a 2a 20 77 6f 72 6b  sually.  ** work
126f0 73 2c 20 62 75 74 20 6d 61 79 20 66 61 69 6c 20  s, but may fail 
12700 69 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  if the wal-index
12710 20 68 65 61 64 65 72 20 69 73 20 63 6f 72 72 75   header is corru
12720 70 74 20 6f 72 20 63 75 72 72 65 6e 74 6c 79 20  pt or currently 
12730 0a 20 20 2a 2a 20 62 65 69 6e 67 20 6d 6f 64 69  .  ** being modi
12740 66 69 65 64 20 62 79 20 61 6e 6f 74 68 65 72 20  fied by another 
12750 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73  thread or proces
12760 73 2e 0a 20 20 2a 2f 0a 20 20 62 61 64 48 64 72  s..  */.  badHdr
12770 20 3d 20 28 70 61 67 65 30 20 3f 20 77 61 6c 49   = (page0 ? walI
12780 6e 64 65 78 54 72 79 48 64 72 28 70 57 61 6c 2c  ndexTryHdr(pWal,
12790 20 70 43 68 61 6e 67 65 64 29 20 3a 20 31 29 3b   pChanged) : 1);
127a0 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69  ..  /* If the fi
127b0 72 73 74 20 61 74 74 65 6d 70 74 20 66 61 69 6c  rst attempt fail
127c0 65 64 2c 20 69 74 20 6d 69 67 68 74 20 68 61 76  ed, it might hav
127d0 65 20 62 65 65 6e 20 64 75 65 20 74 6f 20 61 20  e been due to a 
127e0 72 61 63 65 0a 20 20 2a 2a 20 77 69 74 68 20 61  race.  ** with a
127f0 20 77 72 69 74 65 72 2e 20 20 53 6f 20 67 65 74   writer.  So get
12800 20 61 20 57 52 49 54 45 20 6c 6f 63 6b 20 61 6e   a WRITE lock an
12810 64 20 74 72 79 20 61 67 61 69 6e 2e 0a 20 20 2a  d try again..  *
12820 2f 0a 20 20 61 73 73 65 72 74 28 20 62 61 64 48  /.  assert( badH
12830 64 72 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 77  dr==0 || pWal->w
12840 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20  riteLock==0 );. 
12850 20 69 66 28 20 62 61 64 48 64 72 20 29 7b 0a 20   if( badHdr ){. 
12860 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 72 65 61     if( pWal->rea
12870 64 4f 6e 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f  dOnly & WAL_SHM_
12880 52 44 4f 4e 4c 59 20 29 7b 0a 20 20 20 20 20 20  RDONLY ){.      
12890 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28  if( SQLITE_OK==(
128a0 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72  rc = walLockShar
128b0 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49  ed(pWal, WAL_WRI
128c0 54 45 5f 4c 4f 43 4b 29 29 20 29 7b 0a 20 20 20  TE_LOCK)) ){.   
128d0 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68       walUnlockSh
128e0 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 57  ared(pWal, WAL_W
128f0 52 49 54 45 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20  RITE_LOCK);.    
12900 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
12910 52 45 41 44 4f 4e 4c 59 5f 52 45 43 4f 56 45 52  READONLY_RECOVER
12920 59 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  Y;.      }.    }
12930 65 6c 73 65 20 69 66 28 20 53 51 4c 49 54 45 5f  else if( SQLITE_
12940 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c 4c 6f 63  OK==(rc = walLoc
12950 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
12960 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c   WAL_WRITE_LOCK,
12970 20 31 29 29 20 29 7b 0a 20 20 20 20 20 20 70 57   1)) ){.      pW
12980 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20  al->writeLock = 
12990 31 3b 0a 20 20 20 20 20 20 69 66 28 20 53 51 4c  1;.      if( SQL
129a0 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61  ITE_OK==(rc = wa
129b0 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c  lIndexPage(pWal,
129c0 20 30 2c 20 26 70 61 67 65 30 29 29 20 29 7b 0a   0, &page0)) ){.
129d0 20 20 20 20 20 20 20 20 62 61 64 48 64 72 20 3d          badHdr =
129e0 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28   walIndexTryHdr(
129f0 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b  pWal, pChanged);
12a00 0a 20 20 20 20 20 20 20 20 69 66 28 20 62 61 64  .        if( bad
12a10 48 64 72 20 29 7b 0a 20 20 20 20 20 20 20 20 20  Hdr ){.         
12a20 20 2f 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 69   /* If the wal-i
12a30 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20 73  ndex header is s
12a40 74 69 6c 6c 20 6d 61 6c 66 6f 72 6d 65 64 20 65  till malformed e
12a50 76 65 6e 20 77 68 69 6c 65 20 68 6f 6c 64 69 6e  ven while holdin
12a60 67 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 61  g.          ** a
12a70 20 57 52 49 54 45 20 6c 6f 63 6b 2c 20 69 74 20   WRITE lock, it 
12a80 63 61 6e 20 6f 6e 6c 79 20 6d 65 61 6e 20 74 68  can only mean th
12a90 61 74 20 74 68 65 20 68 65 61 64 65 72 20 69 73  at the header is
12aa0 20 63 6f 72 72 75 70 74 65 64 20 61 6e 64 0a 20   corrupted and. 
12ab0 20 20 20 20 20 20 20 20 20 2a 2a 20 6e 65 65 64           ** need
12ac0 73 20 74 6f 20 62 65 20 72 65 63 6f 6e 73 74 72  s to be reconstr
12ad0 75 63 74 65 64 2e 20 20 53 6f 20 72 75 6e 20 72  ucted.  So run r
12ae0 65 63 6f 76 65 72 79 20 74 6f 20 64 6f 20 65 78  ecovery to do ex
12af0 61 63 74 6c 79 20 74 68 61 74 2e 0a 20 20 20 20  actly that..    
12b00 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20        */.       
12b10 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78     rc = walIndex
12b20 52 65 63 6f 76 65 72 28 70 57 61 6c 29 3b 0a 20  Recover(pWal);. 
12b30 20 20 20 20 20 20 20 20 20 2a 70 43 68 61 6e 67           *pChang
12b40 65 64 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  ed = 1;.        
12b50 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
12b60 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
12b70 3d 20 30 3b 0a 20 20 20 20 20 20 77 61 6c 55 6e  = 0;.      walUn
12b80 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  lockExclusive(pW
12b90 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f  al, WAL_WRITE_LO
12ba0 43 4b 2c 20 31 29 3b 0a 20 20 20 20 7d 0a 20 20  CK, 1);.    }.  
12bb0 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 68  }..  /* If the h
12bc0 65 61 64 65 72 20 69 73 20 72 65 61 64 20 73 75  eader is read su
12bd0 63 63 65 73 73 66 75 6c 6c 79 2c 20 63 68 65 63  ccessfully, chec
12be0 6b 20 74 68 65 20 76 65 72 73 69 6f 6e 20 6e 75  k the version nu
12bf0 6d 62 65 72 20 74 6f 20 6d 61 6b 65 0a 20 20 2a  mber to make.  *
12c00 2a 20 73 75 72 65 20 74 68 65 20 77 61 6c 2d 69  * sure the wal-i
12c10 6e 64 65 78 20 77 61 73 20 6e 6f 74 20 63 6f 6e  ndex was not con
12c20 73 74 72 75 63 74 65 64 20 77 69 74 68 20 73 6f  structed with so
12c30 6d 65 20 66 75 74 75 72 65 20 66 6f 72 6d 61 74  me future format
12c40 20 74 68 61 74 0a 20 20 2a 2a 20 74 68 69 73 20   that.  ** this 
12c50 76 65 72 73 69 6f 6e 20 6f 66 20 53 51 4c 69 74  version of SQLit
12c60 65 20 63 61 6e 6e 6f 74 20 75 6e 64 65 72 73 74  e cannot underst
12c70 61 6e 64 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  and..  */.  if( 
12c80 62 61 64 48 64 72 3d 3d 30 20 26 26 20 70 57 61  badHdr==0 && pWa
12c90 6c 2d 3e 68 64 72 2e 69 56 65 72 73 69 6f 6e 21  l->hdr.iVersion!
12ca0 3d 57 41 4c 49 4e 44 45 58 5f 4d 41 58 5f 56 45  =WALINDEX_MAX_VE
12cb0 52 53 49 4f 4e 20 29 7b 0a 20 20 20 20 72 63 20  RSION ){.    rc 
12cc0 3d 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45  = SQLITE_CANTOPE
12cd0 4e 5f 42 4b 50 54 3b 0a 20 20 7d 0a 0a 20 20 72  N_BKPT;.  }..  r
12ce0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
12cf0 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 76  ** This is the v
12d00 61 6c 75 65 20 74 68 61 74 20 77 61 6c 54 72 79  alue that walTry
12d10 42 65 67 69 6e 52 65 61 64 20 72 65 74 75 72 6e  BeginRead return
12d20 73 20 77 68 65 6e 20 69 74 20 6e 65 65 64 73 20  s when it needs 
12d30 74 6f 0a 2a 2a 20 62 65 20 72 65 74 72 69 65 64  to.** be retried
12d40 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c  ..*/.#define WAL
12d50 5f 52 45 54 52 59 20 20 28 2d 31 29 0a 0a 2f 2a  _RETRY  (-1)../*
12d60 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f 20 73  .** Attempt to s
12d70 74 61 72 74 20 61 20 72 65 61 64 20 74 72 61 6e  tart a read tran
12d80 73 61 63 74 69 6f 6e 2e 20 20 54 68 69 73 20 6d  saction.  This m
12d90 69 67 68 74 20 66 61 69 6c 20 64 75 65 20 74 6f  ight fail due to
12da0 20 61 20 72 61 63 65 20 6f 72 0a 2a 2a 20 6f 74   a race or.** ot
12db0 68 65 72 20 74 72 61 6e 73 69 65 6e 74 20 63 6f  her transient co
12dc0 6e 64 69 74 69 6f 6e 2e 20 20 57 68 65 6e 20 74  ndition.  When t
12dd0 68 61 74 20 68 61 70 70 65 6e 73 2c 20 69 74 20  hat happens, it 
12de0 72 65 74 75 72 6e 73 20 57 41 4c 5f 52 45 54 52  returns WAL_RETR
12df0 59 20 74 6f 0a 2a 2a 20 69 6e 64 69 63 61 74 65  Y to.** indicate
12e00 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 20 74   to the caller t
12e10 68 61 74 20 69 74 20 69 73 20 73 61 66 65 20 74  hat it is safe t
12e20 6f 20 72 65 74 72 79 20 69 6d 6d 65 64 69 61 74  o retry immediat
12e30 65 6c 79 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75  ely..**.** On su
12e40 63 63 65 73 73 20 72 65 74 75 72 6e 20 53 51 4c  ccess return SQL
12e50 49 54 45 5f 4f 4b 2e 20 20 4f 6e 20 61 20 70 65  ITE_OK.  On a pe
12e60 72 6d 61 6e 65 6e 74 20 66 61 69 6c 75 72 65 20  rmanent failure 
12e70 28 73 75 63 68 20 61 6e 0a 2a 2a 20 49 2f 4f 20  (such an.** I/O 
12e80 65 72 72 6f 72 20 6f 72 20 61 6e 20 53 51 4c 49  error or an SQLI
12e90 54 45 5f 42 55 53 59 20 62 65 63 61 75 73 65 20  TE_BUSY because 
12ea0 61 6e 6f 74 68 65 72 20 70 72 6f 63 65 73 73 20  another process 
12eb0 69 73 20 72 75 6e 6e 69 6e 67 0a 2a 2a 20 72 65  is running.** re
12ec0 63 6f 76 65 72 79 29 20 72 65 74 75 72 6e 20 61  covery) return a
12ed0 20 70 6f 73 69 74 69 76 65 20 65 72 72 6f 72 20   positive error 
12ee0 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  code..**.** The 
12ef0 75 73 65 57 61 6c 20 70 61 72 61 6d 65 74 65 72  useWal parameter
12f00 20 69 73 20 74 72 75 65 20 74 6f 20 66 6f 72 63   is true to forc
12f10 65 20 74 68 65 20 75 73 65 20 6f 66 20 74 68 65  e the use of the
12f20 20 57 41 4c 20 61 6e 64 20 64 69 73 61 62 6c 65   WAL and disable
12f30 0a 2a 2a 20 74 68 65 20 63 61 73 65 20 77 68 65  .** the case whe
12f40 72 65 20 74 68 65 20 57 41 4c 20 69 73 20 62 79  re the WAL is by
12f50 70 61 73 73 65 64 20 62 65 63 61 75 73 65 20 69  passed because i
12f60 74 20 68 61 73 20 62 65 65 6e 20 63 6f 6d 70 6c  t has been compl
12f70 65 74 65 6c 79 0a 2a 2a 20 63 68 65 63 6b 70 6f  etely.** checkpo
12f80 69 6e 74 65 64 2e 20 20 49 66 20 75 73 65 57 61  inted.  If useWa
12f90 6c 3d 3d 30 20 74 68 65 6e 20 74 68 69 73 20 72  l==0 then this r
12fa0 6f 75 74 69 6e 65 20 63 61 6c 6c 73 20 77 61 6c  outine calls wal
12fb0 49 6e 64 65 78 52 65 61 64 48 64 72 28 29 20 0a  IndexReadHdr() .
12fc0 2a 2a 20 74 6f 20 6d 61 6b 65 20 61 20 63 6f 70  ** to make a cop
12fd0 79 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  y of the wal-ind
12fe0 65 78 20 68 65 61 64 65 72 20 69 6e 74 6f 20 70  ex header into p
12ff0 57 61 6c 2d 3e 68 64 72 2e 20 20 49 66 20 74 68  Wal->hdr.  If th
13000 65 20 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20  e .** wal-index 
13010 68 65 61 64 65 72 20 68 61 73 20 63 68 61 6e 67  header has chang
13020 65 64 2c 20 2a 70 43 68 61 6e 67 65 64 20 69 73  ed, *pChanged is
13030 20 73 65 74 20 74 6f 20 31 20 28 61 73 20 61 6e   set to 1 (as an
13040 20 69 6e 64 69 63 61 74 69 6f 6e 20 0a 2a 2a 20   indication .** 
13050 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 20 74 68  to the caller th
13060 61 74 20 74 68 65 20 6c 6f 63 61 6c 20 70 61 67  at the local pag
13070 65 74 20 63 61 63 68 65 20 69 73 20 6f 62 73 6f  et cache is obso
13080 6c 65 74 65 20 61 6e 64 20 6e 65 65 64 73 20 74  lete and needs t
13090 6f 20 62 65 20 0a 2a 2a 20 66 6c 75 73 68 65 64  o be .** flushed
130a0 2e 29 20 20 57 68 65 6e 20 75 73 65 57 61 6c 3d  .)  When useWal=
130b0 3d 31 2c 20 74 68 65 20 77 61 6c 2d 69 6e 64 65  =1, the wal-inde
130c0 78 20 68 65 61 64 65 72 20 69 73 20 61 73 73 75  x header is assu
130d0 6d 65 64 20 74 6f 20 61 6c 72 65 61 64 79 0a 2a  med to already.*
130e0 2a 20 62 65 20 6c 6f 61 64 65 64 20 61 6e 64 20  * be loaded and 
130f0 74 68 65 20 70 43 68 61 6e 67 65 64 20 70 61 72  the pChanged par
13100 61 6d 65 74 65 72 20 69 73 20 75 6e 75 73 65 64  ameter is unused
13110 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c  ..**.** The call
13120 65 72 20 6d 75 73 74 20 73 65 74 20 74 68 65 20  er must set the 
13130 63 6e 74 20 70 61 72 61 6d 65 74 65 72 20 74 6f  cnt parameter to
13140 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 70   the number of p
13150 72 69 6f 72 20 63 61 6c 6c 73 20 74 6f 0a 2a 2a  rior calls to.**
13160 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 64 75   this routine du
13170 72 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74  ring the current
13180 20 72 65 61 64 20 61 74 74 65 6d 70 74 20 74 68   read attempt th
13190 61 74 20 72 65 74 75 72 6e 65 64 20 57 41 4c 5f  at returned WAL_
131a0 52 45 54 52 59 2e 0a 2a 2a 20 54 68 69 73 20 72  RETRY..** This r
131b0 6f 75 74 69 6e 65 20 77 69 6c 6c 20 73 74 61 72  outine will star
131c0 74 20 74 61 6b 69 6e 67 20 6d 6f 72 65 20 61 67  t taking more ag
131d0 67 72 65 73 73 69 76 65 20 6d 65 61 73 75 72 65  gressive measure
131e0 73 20 74 6f 20 63 6c 65 61 72 20 74 68 65 0a 2a  s to clear the.*
131f0 2a 20 72 61 63 65 20 63 6f 6e 64 69 74 69 6f 6e  * race condition
13200 73 20 61 66 74 65 72 20 6d 75 6c 74 69 70 6c 65  s after multiple
13210 20 57 41 4c 5f 52 45 54 52 59 20 72 65 74 75 72   WAL_RETRY retur
13220 6e 73 2c 20 61 6e 64 20 61 66 74 65 72 20 61 6e  ns, and after an
13230 20 65 78 63 65 73 73 69 76 65 0a 2a 2a 20 6e 75   excessive.** nu
13240 6d 62 65 72 20 6f 66 20 65 72 72 6f 72 73 20 77  mber of errors w
13250 69 6c 6c 20 75 6c 74 69 6d 61 74 65 6c 79 20 72  ill ultimately r
13260 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 50 52 4f  eturn SQLITE_PRO
13270 54 4f 43 4f 4c 2e 20 20 54 68 65 0a 2a 2a 20 53  TOCOL.  The.** S
13280 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 20 72  QLITE_PROTOCOL r
13290 65 74 75 72 6e 20 69 6e 64 69 63 61 74 65 73 20  eturn indicates 
132a0 74 68 61 74 20 73 6f 6d 65 20 6f 74 68 65 72 20  that some other 
132b0 70 72 6f 63 65 73 73 20 68 61 73 20 67 6f 6e 65  process has gone
132c0 20 72 6f 67 75 65 0a 2a 2a 20 61 6e 64 20 69 73   rogue.** and is
132d0 20 6e 6f 74 20 68 6f 6e 6f 72 69 6e 67 20 74 68   not honoring th
132e0 65 20 6c 6f 63 6b 69 6e 67 20 70 72 6f 74 6f 63  e locking protoc
132f0 6f 6c 2e 20 20 54 68 65 72 65 20 69 73 20 61 20  ol.  There is a 
13300 76 61 6e 69 73 68 69 6e 67 6c 79 20 73 6d 61 6c  vanishingly smal
13310 6c 0a 2a 2a 20 63 68 61 6e 63 65 20 74 68 61 74  l.** chance that
13320 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c   SQLITE_PROTOCOL
13330 20 63 6f 75 6c 64 20 62 65 20 72 65 74 75 72 6e   could be return
13340 65 64 20 62 65 63 61 75 73 65 20 6f 66 20 61 20  ed because of a 
13350 72 75 6e 20 6f 66 20 72 65 61 6c 6c 79 0a 2a 2a  run of really.**
13360 20 62 61 64 20 6c 75 63 6b 20 77 68 65 6e 20 74   bad luck when t
13370 68 65 72 65 20 69 73 20 6c 6f 74 73 20 6f 66 20  here is lots of 
13380 63 6f 6e 74 65 6e 74 69 6f 6e 20 66 6f 72 20 74  contention for t
13390 68 65 20 77 61 6c 2d 69 6e 64 65 78 2c 20 62 75  he wal-index, bu
133a0 74 20 74 68 61 74 0a 2a 2a 20 70 6f 73 73 69 62  t that.** possib
133b0 69 6c 69 74 79 20 69 73 20 73 6f 20 73 6d 61 6c  ility is so smal
133c0 6c 20 74 68 61 74 20 69 74 20 63 61 6e 20 62 65  l that it can be
133d0 20 73 61 66 65 6c 79 20 6e 65 67 6c 65 63 74 65   safely neglecte
133e0 64 2c 20 77 65 20 62 65 6c 69 65 76 65 2e 0a 2a  d, we believe..*
133f0 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63 65 73 73 2c  *.** On success,
13400 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 6f 62   this routine ob
13410 74 61 69 6e 73 20 61 20 72 65 61 64 20 6c 6f 63  tains a read loc
13420 6b 20 6f 6e 20 0a 2a 2a 20 57 41 4c 5f 52 45 41  k on .** WAL_REA
13430 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61  D_LOCK(pWal->rea
13440 64 4c 6f 63 6b 29 2e 20 20 54 68 65 20 70 57 61  dLock).  The pWa
13450 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69 6e 74 65  l->readLock inte
13460 67 65 72 20 69 73 0a 2a 2a 20 69 6e 20 74 68 65  ger is.** in the
13470 20 72 61 6e 67 65 20 30 20 3c 3d 20 70 57 61 6c   range 0 <= pWal
13480 2d 3e 72 65 61 64 4c 6f 63 6b 20 3c 20 57 41 4c  ->readLock < WAL
13490 5f 4e 52 45 41 44 45 52 2e 20 20 49 66 20 70 57  _NREADER.  If pW
134a0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 28 2d  al->readLock==(-
134b0 31 29 0a 2a 2a 20 74 68 61 74 20 6d 65 61 6e 73  1).** that means
134c0 20 74 68 65 20 57 61 6c 20 64 6f 65 73 20 6e 6f   the Wal does no
134d0 74 20 68 6f 6c 64 20 61 6e 79 20 72 65 61 64 20  t hold any read 
134e0 6c 6f 63 6b 2e 20 20 54 68 65 20 72 65 61 64 65  lock.  The reade
134f0 72 20 6d 75 73 74 20 6e 6f 74 0a 2a 2a 20 61 63  r must not.** ac
13500 63 65 73 73 20 61 6e 79 20 64 61 74 61 62 61 73  cess any databas
13510 65 20 70 61 67 65 20 74 68 61 74 20 69 73 20 6d  e page that is m
13520 6f 64 69 66 69 65 64 20 62 79 20 61 20 57 41 4c  odified by a WAL
13530 20 66 72 61 6d 65 20 75 70 20 74 6f 20 61 6e 64   frame up to and
13540 0a 2a 2a 20 69 6e 63 6c 75 64 69 6e 67 20 66 72  .** including fr
13550 61 6d 65 20 6e 75 6d 62 65 72 20 61 52 65 61 64  ame number aRead
13560 4d 61 72 6b 5b 70 57 61 6c 2d 3e 72 65 61 64 4c  Mark[pWal->readL
13570 6f 63 6b 5d 2e 20 20 54 68 65 20 72 65 61 64 65  ock].  The reade
13580 72 20 77 69 6c 6c 0a 2a 2a 20 75 73 65 20 57 41  r will.** use WA
13590 4c 20 66 72 61 6d 65 73 20 75 70 20 74 6f 20 61  L frames up to a
135a0 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20 70 57 61  nd including pWa
135b0 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69  l->hdr.mxFrame i
135c0 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  f pWal->readLock
135d0 3e 30 0a 2a 2a 20 4f 72 20 69 66 20 70 57 61 6c  >0.** Or if pWal
135e0 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 2c 20 74  ->readLock==0, t
135f0 68 65 6e 20 74 68 65 20 72 65 61 64 65 72 20 77  hen the reader w
13600 69 6c 6c 20 69 67 6e 6f 72 65 20 74 68 65 20 57  ill ignore the W
13610 41 4c 0a 2a 2a 20 63 6f 6d 70 6c 65 74 65 6c 79  AL.** completely
13620 20 61 6e 64 20 67 65 74 20 61 6c 6c 20 63 6f 6e   and get all con
13630 74 65 6e 74 20 64 69 72 65 63 74 6c 79 20 66 72  tent directly fr
13640 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73 65 20  om the database 
13650 66 69 6c 65 2e 0a 2a 2a 20 49 66 20 74 68 65 20  file..** If the 
13660 75 73 65 57 61 6c 20 70 61 72 61 6d 65 74 65 72  useWal parameter
13670 20 69 73 20 31 20 74 68 65 6e 20 74 68 65 20 57   is 1 then the W
13680 41 4c 20 77 69 6c 6c 20 6e 65 76 65 72 20 62 65  AL will never be
13690 20 69 67 6e 6f 72 65 64 20 61 6e 64 0a 2a 2a 20   ignored and.** 
136a0 74 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c  this routine wil
136b0 6c 20 61 6c 77 61 79 73 20 73 65 74 20 70 57 61  l always set pWa
136c0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 30 20 6f 6e  l->readLock>0 on
136d0 20 73 75 63 63 65 73 73 2e 0a 2a 2a 20 57 68 65   success..** Whe
136e0 6e 20 74 68 65 20 72 65 61 64 20 74 72 61 6e 73  n the read trans
136f0 61 63 74 69 6f 6e 20 69 73 20 63 6f 6d 70 6c 65  action is comple
13700 74 65 64 2c 20 74 68 65 20 63 61 6c 6c 65 72 20  ted, the caller 
13710 6d 75 73 74 20 72 65 6c 65 61 73 65 20 74 68 65  must release the
13720 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f  .** lock on WAL_
13730 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e  READ_LOCK(pWal->
13740 72 65 61 64 4c 6f 63 6b 29 20 61 6e 64 20 73 65  readLock) and se
13750 74 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  t pWal->readLock
13760 20 74 6f 20 2d 31 2e 0a 2a 2a 0a 2a 2a 20 54 68   to -1..**.** Th
13770 69 73 20 72 6f 75 74 69 6e 65 20 75 73 65 73 20  is routine uses 
13780 74 68 65 20 6e 42 61 63 6b 66 69 6c 6c 20 61 6e  the nBackfill an
13790 64 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 66 69  d aReadMark[] fi
137a0 65 6c 64 73 20 6f 66 20 74 68 65 20 68 65 61 64  elds of the head
137b0 65 72 0a 2a 2a 20 74 6f 20 73 65 6c 65 63 74 20  er.** to select 
137c0 61 20 70 61 72 74 69 63 75 6c 61 72 20 57 41 4c  a particular WAL
137d0 5f 52 45 41 44 5f 4c 4f 43 4b 28 29 20 74 68 61  _READ_LOCK() tha
137e0 74 20 73 74 72 69 76 65 73 20 74 6f 20 6c 65 74  t strives to let
137f0 20 74 68 65 0a 2a 2a 20 63 68 65 63 6b 70 6f 69   the.** checkpoi
13800 6e 74 20 70 72 6f 63 65 73 73 20 64 6f 20 61 73  nt process do as
13810 20 6d 75 63 68 20 77 6f 72 6b 20 61 73 20 70 6f   much work as po
13820 73 73 69 62 6c 65 2e 20 20 54 68 69 73 20 72 6f  ssible.  This ro
13830 75 74 69 6e 65 20 6d 69 67 68 74 0a 2a 2a 20 75  utine might.** u
13840 70 64 61 74 65 20 76 61 6c 75 65 73 20 6f 66 20  pdate values of 
13850 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20  the aReadMark[] 
13860 61 72 72 61 79 20 69 6e 20 74 68 65 20 68 65 61  array in the hea
13870 64 65 72 2c 20 62 75 74 20 69 66 20 69 74 20 64  der, but if it d
13880 6f 65 73 0a 2a 2a 20 73 6f 20 69 74 20 74 61 6b  oes.** so it tak
13890 65 73 20 63 61 72 65 20 74 6f 20 68 6f 6c 64 20  es care to hold 
138a0 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63  an exclusive loc
138b0 6b 20 6f 6e 20 74 68 65 20 63 6f 72 72 65 73 70  k on the corresp
138c0 6f 6e 64 69 6e 67 0a 2a 2a 20 57 41 4c 5f 52 45  onding.** WAL_RE
138d0 41 44 5f 4c 4f 43 4b 28 29 20 77 68 69 6c 65 20  AD_LOCK() while 
138e0 63 68 61 6e 67 69 6e 67 20 76 61 6c 75 65 73 2e  changing values.
138f0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
13900 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64 28 57  alTryBeginRead(W
13910 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70  al *pWal, int *p
13920 43 68 61 6e 67 65 64 2c 20 69 6e 74 20 75 73 65  Changed, int use
13930 57 61 6c 2c 20 69 6e 74 20 63 6e 74 29 7b 0a 20  Wal, int cnt){. 
13940 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70   volatile WalCkp
13950 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b 20 20 20  tInfo *pInfo;   
13960 20 2f 2a 20 43 68 65 63 6b 70 6f 69 6e 74 20 69   /* Checkpoint i
13970 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e 20 77 61  nformation in wa
13980 6c 2d 69 6e 64 65 78 20 2a 2f 0a 20 20 75 33 32  l-index */.  u32
13990 20 6d 78 52 65 61 64 4d 61 72 6b 3b 20 20 20 20   mxReadMark;    
139a0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
139b0 4c 61 72 67 65 73 74 20 61 52 65 61 64 4d 61 72  Largest aReadMar
139c0 6b 5b 5d 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69  k[] value */.  i
139d0 6e 74 20 6d 78 49 3b 20 20 20 20 20 20 20 20 20  nt mxI;         
139e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
139f0 2a 20 49 6e 64 65 78 20 6f 66 20 6c 61 72 67 65  * Index of large
13a00 73 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 76  st aReadMark[] v
13a10 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b  alue */.  int i;
13a20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13a30 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f            /* Loo
13a40 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 69  p counter */.  i
13a50 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
13a60 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  K;             /
13a70 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 20 2a  * Return code  *
13a80 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  /..  assert( pWa
13a90 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3c 30 20 29 3b  l->readLock<0 );
13aa0 20 20 20 20 20 2f 2a 20 4e 6f 74 20 63 75 72 72       /* Not curr
13ab0 65 6e 74 6c 79 20 6c 6f 63 6b 65 64 20 2a 2f 0a  ently locked */.
13ac0 0a 20 20 2f 2a 20 54 61 6b 65 20 73 74 65 70 73  .  /* Take steps
13ad0 20 74 6f 20 61 76 6f 69 64 20 73 70 69 6e 6e 69   to avoid spinni
13ae0 6e 67 20 66 6f 72 65 76 65 72 20 69 66 20 74 68  ng forever if th
13af0 65 72 65 20 69 73 20 61 20 70 72 6f 74 6f 63 6f  ere is a protoco
13b00 6c 20 65 72 72 6f 72 2e 0a 20 20 2a 2a 0a 20 20  l error..  **.  
13b10 2a 2a 20 43 69 72 63 75 6d 73 74 61 6e 63 65 73  ** Circumstances
13b20 20 74 68 61 74 20 63 61 75 73 65 20 61 20 52 45   that cause a RE
13b30 54 52 59 20 73 68 6f 75 6c 64 20 6f 6e 6c 79 20  TRY should only 
13b40 6c 61 73 74 20 66 6f 72 20 74 68 65 20 62 72 69  last for the bri
13b50 65 66 65 73 74 0a 20 20 2a 2a 20 69 6e 73 74 61  efest.  ** insta
13b60 6e 63 65 73 20 6f 66 20 74 69 6d 65 2e 20 20 4e  nces of time.  N
13b70 6f 20 49 2f 4f 20 6f 72 20 6f 74 68 65 72 20 73  o I/O or other s
13b80 79 73 74 65 6d 20 63 61 6c 6c 73 20 61 72 65 20  ystem calls are 
13b90 64 6f 6e 65 20 77 68 69 6c 65 20 74 68 65 0a 20  done while the. 
13ba0 20 2a 2a 20 6c 6f 63 6b 73 20 61 72 65 20 68 65   ** locks are he
13bb0 6c 64 2c 20 73 6f 20 74 68 65 20 6c 6f 63 6b 73  ld, so the locks
13bc0 20 73 68 6f 75 6c 64 20 6e 6f 74 20 62 65 20 68   should not be h
13bd0 65 6c 64 20 66 6f 72 20 76 65 72 79 20 6c 6f 6e  eld for very lon
13be0 67 2e 20 42 75 74 20 0a 20 20 2a 2a 20 69 66 20  g. But .  ** if 
13bf0 77 65 20 61 72 65 20 75 6e 6c 75 63 6b 79 2c 20  we are unlucky, 
13c00 61 6e 6f 74 68 65 72 20 70 72 6f 63 65 73 73 20  another process 
13c10 74 68 61 74 20 69 73 20 68 6f 6c 64 69 6e 67 20  that is holding 
13c20 61 20 6c 6f 63 6b 20 6d 69 67 68 74 20 67 65 74  a lock might get
13c30 0a 20 20 2a 2a 20 70 61 67 65 64 20 6f 75 74 20  .  ** paged out 
13c40 6f 72 20 74 61 6b 65 20 61 20 70 61 67 65 2d 66  or take a page-f
13c50 61 75 6c 74 20 74 68 61 74 20 69 73 20 74 69 6d  ault that is tim
13c60 65 2d 63 6f 6e 73 75 6d 69 6e 67 20 74 6f 20 72  e-consuming to r
13c70 65 73 6f 6c 76 65 2c 20 0a 20 20 2a 2a 20 64 75  esolve, .  ** du
13c80 72 69 6e 67 20 74 68 65 20 66 65 77 20 6e 61 6e  ring the few nan
13c90 6f 73 65 63 6f 6e 64 73 20 74 68 61 74 20 69 74  oseconds that it
13ca0 20 69 73 20 68 6f 6c 64 69 6e 67 20 74 68 65 20   is holding the 
13cb0 6c 6f 63 6b 2e 20 20 49 6e 20 74 68 61 74 20 63  lock.  In that c
13cc0 61 73 65 2c 0a 20 20 2a 2a 20 69 74 20 6d 69 67  ase,.  ** it mig
13cd0 68 74 20 74 61 6b 65 20 6c 6f 6e 67 65 72 20 74  ht take longer t
13ce0 68 61 6e 20 6e 6f 72 6d 61 6c 20 66 6f 72 20 74  han normal for t
13cf0 68 65 20 6c 6f 63 6b 20 74 6f 20 66 72 65 65 2e  he lock to free.
13d00 0a 20 20 2a 2a 0a 20 20 2a 2a 20 41 66 74 65 72  .  **.  ** After
13d10 20 35 20 52 45 54 52 59 73 2c 20 77 65 20 62 65   5 RETRYs, we be
13d20 67 69 6e 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69  gin calling sqli
13d30 74 65 33 4f 73 53 6c 65 65 70 28 29 2e 20 20 54  te3OsSleep().  T
13d40 68 65 20 66 69 72 73 74 20 66 65 77 0a 20 20 2a  he first few.  *
13d50 2a 20 63 61 6c 6c 73 20 74 6f 20 73 71 6c 69 74  * calls to sqlit
13d60 65 33 4f 73 53 6c 65 65 70 28 29 20 68 61 76 65  e3OsSleep() have
13d70 20 61 20 64 65 6c 61 79 20 6f 66 20 31 20 6d 69   a delay of 1 mi
13d80 63 72 6f 73 65 63 6f 6e 64 2e 20 20 52 65 61 6c  crosecond.  Real
13d90 6c 79 20 74 68 69 73 0a 20 20 2a 2a 20 69 73 20  ly this.  ** is 
13da0 6d 6f 72 65 20 6f 66 20 61 20 73 63 68 65 64 75  more of a schedu
13db0 6c 65 72 20 79 69 65 6c 64 20 74 68 61 6e 20 61  ler yield than a
13dc0 6e 20 61 63 74 75 61 6c 20 64 65 6c 61 79 2e 20  n actual delay. 
13dd0 20 42 75 74 20 6f 6e 20 74 68 65 20 31 30 74 68   But on the 10th
13de0 0a 20 20 2a 2a 20 61 6e 20 73 75 62 73 65 71 75  .  ** an subsequ
13df0 65 6e 74 20 72 65 74 72 69 65 73 2c 20 74 68 65  ent retries, the
13e00 20 64 65 6c 61 79 73 20 73 74 61 72 74 20 62 65   delays start be
13e10 63 6f 6d 69 6e 67 20 6c 6f 6e 67 65 72 20 61 6e  coming longer an
13e20 64 20 6c 6f 6e 67 65 72 2c 20 0a 20 20 2a 2a 20  d longer, .  ** 
13e30 73 6f 20 74 68 61 74 20 6f 6e 20 74 68 65 20 31  so that on the 1
13e40 30 30 74 68 20 28 61 6e 64 20 6c 61 73 74 29 20  00th (and last) 
13e50 52 45 54 52 59 20 77 65 20 64 65 6c 61 79 20 66  RETRY we delay f
13e60 6f 72 20 32 31 20 6d 69 6c 6c 69 73 65 63 6f 6e  or 21 millisecon
13e70 64 73 2e 0a 20 20 2a 2a 20 54 68 65 20 74 6f 74  ds..  ** The tot
13e80 61 6c 20 64 65 6c 61 79 20 74 69 6d 65 20 62 65  al delay time be
13e90 66 6f 72 65 20 67 69 76 69 6e 67 20 75 70 20 69  fore giving up i
13ea0 73 20 6c 65 73 73 20 74 68 61 6e 20 31 20 73 65  s less than 1 se
13eb0 63 6f 6e 64 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  cond..  */.  if(
13ec0 20 63 6e 74 3e 35 20 29 7b 0a 20 20 20 20 69 6e   cnt>5 ){.    in
13ed0 74 20 6e 44 65 6c 61 79 20 3d 20 31 3b 20 20 20  t nDelay = 1;   
13ee0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13ef0 20 20 20 2f 2a 20 50 61 75 73 65 20 74 69 6d 65     /* Pause time
13f00 20 69 6e 20 6d 69 63 72 6f 73 65 63 6f 6e 64 73   in microseconds
13f10 20 2a 2f 0a 20 20 20 20 69 66 28 20 63 6e 74 3e   */.    if( cnt>
13f20 31 30 30 20 29 7b 0a 20 20 20 20 20 20 56 56 41  100 ){.      VVA
13f30 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f 63  _ONLY( pWal->loc
13f40 6b 45 72 72 6f 72 20 3d 20 31 3b 20 29 0a 20 20  kError = 1; ).  
13f50 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
13f60 45 5f 50 52 4f 54 4f 43 4f 4c 3b 0a 20 20 20 20  E_PROTOCOL;.    
13f70 7d 0a 20 20 20 20 69 66 28 20 63 6e 74 3e 3d 31  }.    if( cnt>=1
13f80 30 20 29 20 6e 44 65 6c 61 79 20 3d 20 28 63 6e  0 ) nDelay = (cn
13f90 74 2d 39 29 2a 32 33 38 3b 20 20 2f 2a 20 4d 61  t-9)*238;  /* Ma
13fa0 78 20 64 65 6c 61 79 20 32 31 6d 73 2e 20 54 6f  x delay 21ms. To
13fb0 74 61 6c 20 64 65 6c 61 79 20 39 39 36 6d 73 20  tal delay 996ms 
13fc0 2a 2f 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  */.    sqlite3Os
13fd0 53 6c 65 65 70 28 70 57 61 6c 2d 3e 70 56 66 73  Sleep(pWal->pVfs
13fe0 2c 20 6e 44 65 6c 61 79 29 3b 0a 20 20 7d 0a 0a  , nDelay);.  }..
13ff0 20 20 69 66 28 20 21 75 73 65 57 61 6c 20 29 7b    if( !useWal ){
14000 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64  .    rc = walInd
14010 65 78 52 65 61 64 48 64 72 28 70 57 61 6c 2c 20  exReadHdr(pWal, 
14020 70 43 68 61 6e 67 65 64 29 3b 0a 20 20 20 20 69  pChanged);.    i
14030 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  f( rc==SQLITE_BU
14040 53 59 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 49  SY ){.      /* I
14050 66 20 74 68 65 72 65 20 69 73 20 6e 6f 74 20 61  f there is not a
14060 20 72 65 63 6f 76 65 72 79 20 72 75 6e 6e 69 6e   recovery runnin
14070 67 20 69 6e 20 61 6e 6f 74 68 65 72 20 74 68 72  g in another thr
14080 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 0a 20  ead or process. 
14090 20 20 20 20 20 2a 2a 20 74 68 65 6e 20 63 6f 6e       ** then con
140a0 76 65 72 74 20 42 55 53 59 20 65 72 72 6f 72 73  vert BUSY errors
140b0 20 74 6f 20 57 41 4c 5f 52 45 54 52 59 2e 20 20   to WAL_RETRY.  
140c0 49 66 20 72 65 63 6f 76 65 72 79 20 69 73 20 6b  If recovery is k
140d0 6e 6f 77 6e 20 74 6f 0a 20 20 20 20 20 20 2a 2a  nown to.      **
140e0 20 62 65 20 72 75 6e 6e 69 6e 67 2c 20 63 6f 6e   be running, con
140f0 76 65 72 74 20 42 55 53 59 20 74 6f 20 42 55 53  vert BUSY to BUS
14100 59 5f 52 45 43 4f 56 45 52 59 2e 20 20 54 68 65  Y_RECOVERY.  The
14110 72 65 20 69 73 20 61 20 72 61 63 65 20 68 65 72  re is a race her
14120 65 0a 20 20 20 20 20 20 2a 2a 20 77 68 69 63 68  e.      ** which
14130 20 6d 69 67 68 74 20 63 61 75 73 65 20 57 41 4c   might cause WAL
14140 5f 52 45 54 52 59 20 74 6f 20 62 65 20 72 65 74  _RETRY to be ret
14150 75 72 6e 65 64 20 65 76 65 6e 20 69 66 20 42 55  urned even if BU
14160 53 59 5f 52 45 43 4f 56 45 52 59 0a 20 20 20 20  SY_RECOVERY.    
14170 20 20 2a 2a 20 77 6f 75 6c 64 20 62 65 20 74 65    ** would be te
14180 63 68 6e 69 63 61 6c 6c 79 20 63 6f 72 72 65 63  chnically correc
14190 74 2e 20 20 42 75 74 20 74 68 65 20 72 61 63 65  t.  But the race
141a0 20 69 73 20 62 65 6e 69 67 6e 20 73 69 6e 63 65   is benign since
141b0 20 77 69 74 68 0a 20 20 20 20 20 20 2a 2a 20 57   with.      ** W
141c0 41 4c 5f 52 45 54 52 59 20 74 68 69 73 20 72 6f  AL_RETRY this ro
141d0 75 74 69 6e 65 20 77 69 6c 6c 20 62 65 20 63 61  utine will be ca
141e0 6c 6c 65 64 20 61 67 61 69 6e 20 61 6e 64 20 77  lled again and w
141f0 69 6c 6c 20 70 72 6f 62 61 62 6c 79 20 62 65 0a  ill probably be.
14200 20 20 20 20 20 20 2a 2a 20 72 69 67 68 74 20 6f        ** right o
14210 6e 20 74 68 65 20 73 65 63 6f 6e 64 20 69 74 65  n the second ite
14220 72 61 74 69 6f 6e 2e 0a 20 20 20 20 20 20 2a 2f  ration..      */
14230 0a 20 20 20 20 20 20 69 66 28 20 70 57 61 6c 2d  .      if( pWal-
14240 3e 61 70 57 69 44 61 74 61 5b 30 5d 3d 3d 30 20  >apWiData[0]==0 
14250 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 54 68  ){.        /* Th
14260 69 73 20 62 72 61 6e 63 68 20 69 73 20 74 61 6b  is branch is tak
14270 65 6e 20 77 68 65 6e 20 74 68 65 20 78 53 68 6d  en when the xShm
14280 4d 61 70 28 29 20 6d 65 74 68 6f 64 20 72 65 74  Map() method ret
14290 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53 59  urns SQLITE_BUSY
142a0 2e 0a 20 20 20 20 20 20 20 20 2a 2a 20 57 65 20  ..        ** We 
142b0 61 73 73 75 6d 65 20 74 68 69 73 20 69 73 20 61  assume this is a
142c0 20 74 72 61 6e 73 69 65 6e 74 20 63 6f 6e 64 69   transient condi
142d0 74 69 6f 6e 2c 20 73 6f 20 72 65 74 75 72 6e 20  tion, so return 
142e0 57 41 4c 5f 52 45 54 52 59 2e 20 54 68 65 0a 20  WAL_RETRY. The. 
142f0 20 20 20 20 20 20 20 2a 2a 20 78 53 68 6d 4d 61         ** xShmMa
14300 70 28 29 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  p() implementati
14310 6f 6e 20 75 73 65 64 20 62 79 20 74 68 65 20 64  on used by the d
14320 65 66 61 75 6c 74 20 75 6e 69 78 20 61 6e 64 20  efault unix and 
14330 77 69 6e 33 32 20 56 46 53 20 0a 20 20 20 20 20  win32 VFS .     
14340 20 20 20 2a 2a 20 6d 6f 64 75 6c 65 73 20 6d 61     ** modules ma
14350 79 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  y return SQLITE_
14360 42 55 53 59 20 64 75 65 20 74 6f 20 61 20 72 61  BUSY due to a ra
14370 63 65 20 63 6f 6e 64 69 74 69 6f 6e 20 69 6e 20  ce condition in 
14380 74 68 65 20 0a 20 20 20 20 20 20 20 20 2a 2a 20  the .        ** 
14390 63 6f 64 65 20 74 68 61 74 20 64 65 74 65 72 6d  code that determ
143a0 69 6e 65 73 20 77 68 65 74 68 65 72 20 6f 72 20  ines whether or 
143b0 6e 6f 74 20 74 68 65 20 73 68 61 72 65 64 2d 6d  not the shared-m
143c0 65 6d 6f 72 79 20 72 65 67 69 6f 6e 20 0a 20 20  emory region .  
143d0 20 20 20 20 20 20 2a 2a 20 6d 75 73 74 20 62 65        ** must be
143e0 20 7a 65 72 6f 65 64 20 62 65 66 6f 72 65 20 74   zeroed before t
143f0 68 65 20 72 65 71 75 65 73 74 65 64 20 70 61 67  he requested pag
14400 65 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 20  e is returned.. 
14410 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20         */.      
14420 20 20 72 63 20 3d 20 57 41 4c 5f 52 45 54 52 59    rc = WAL_RETRY
14430 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  ;.      }else if
14440 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63  ( SQLITE_OK==(rc
14450 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64   = walLockShared
14460 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 43 4f 56  (pWal, WAL_RECOV
14470 45 52 5f 4c 4f 43 4b 29 29 20 29 7b 0a 20 20 20  ER_LOCK)) ){.   
14480 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68       walUnlockSh
14490 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
144a0 45 43 4f 56 45 52 5f 4c 4f 43 4b 29 3b 0a 20 20  ECOVER_LOCK);.  
144b0 20 20 20 20 20 20 72 63 20 3d 20 57 41 4c 5f 52        rc = WAL_R
144c0 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 65 6c 73  ETRY;.      }els
144d0 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45  e if( rc==SQLITE
144e0 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20 20  _BUSY ){.       
144f0 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55 53   rc = SQLITE_BUS
14500 59 5f 52 45 43 4f 56 45 52 59 3b 0a 20 20 20 20  Y_RECOVERY;.    
14510 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
14520 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
14530 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
14540 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  rc;.    }.  }.. 
14550 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74   pInfo = walCkpt
14560 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 69 66  Info(pWal);.  if
14570 28 20 21 75 73 65 57 61 6c 20 26 26 20 70 49 6e  ( !useWal && pIn
14580 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70  fo->nBackfill==p
14590 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
145a0 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 57   ){.    /* The W
145b0 41 4c 20 68 61 73 20 62 65 65 6e 20 63 6f 6d 70  AL has been comp
145c0 6c 65 74 65 6c 79 20 62 61 63 6b 66 69 6c 6c 65  letely backfille
145d0 64 20 28 6f 72 20 69 74 20 69 73 20 65 6d 70 74  d (or it is empt
145e0 79 29 2e 0a 20 20 20 20 2a 2a 20 61 6e 64 20 63  y)..    ** and c
145f0 61 6e 20 62 65 20 73 61 66 65 6c 79 20 69 67 6e  an be safely ign
14600 6f 72 65 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  ored..    */.   
14610 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61   rc = walLockSha
14620 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
14630 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20  AD_LOCK(0));.   
14640 20 77 61 6c 53 68 6d 42 61 72 72 69 65 72 28 70   walShmBarrier(p
14650 57 61 6c 29 3b 0a 20 20 20 20 69 66 28 20 72 63  Wal);.    if( rc
14660 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
14670 20 20 20 20 20 69 66 28 20 6d 65 6d 63 6d 70 28       if( memcmp(
14680 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78  (void *)walIndex
14690 48 64 72 28 70 57 61 6c 29 2c 20 26 70 57 61 6c  Hdr(pWal), &pWal
146a0 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61  ->hdr, sizeof(Wa
146b0 6c 49 6e 64 65 78 48 64 72 29 29 20 29 7b 0a 20  lIndexHdr)) ){. 
146c0 20 20 20 20 20 20 20 2f 2a 20 49 74 20 69 73 20         /* It is 
146d0 6e 6f 74 20 73 61 66 65 20 74 6f 20 61 6c 6c 6f  not safe to allo
146e0 77 20 74 68 65 20 72 65 61 64 65 72 20 74 6f 20  w the reader to 
146f0 63 6f 6e 74 69 6e 75 65 20 68 65 72 65 20 69 66  continue here if
14700 20 66 72 61 6d 65 73 0a 20 20 20 20 20 20 20 20   frames.        
14710 2a 2a 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e  ** may have been
14720 20 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65   appended to the
14730 20 6c 6f 67 20 62 65 66 6f 72 65 20 52 45 41 44   log before READ
14740 5f 4c 4f 43 4b 28 30 29 20 77 61 73 20 6f 62 74  _LOCK(0) was obt
14750 61 69 6e 65 64 2e 0a 20 20 20 20 20 20 20 20 2a  ained..        *
14760 2a 20 57 68 65 6e 20 68 6f 6c 64 69 6e 67 20 52  * When holding R
14770 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 74 68 65  EAD_LOCK(0), the
14780 20 72 65 61 64 65 72 20 69 67 6e 6f 72 65 73 20   reader ignores 
14790 74 68 65 20 65 6e 74 69 72 65 20 6c 6f 67 20 66  the entire log f
147a0 69 6c 65 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20  ile,.        ** 
147b0 77 68 69 63 68 20 69 6d 70 6c 69 65 73 20 74 68  which implies th
147c0 61 74 20 74 68 65 20 64 61 74 61 62 61 73 65 20  at the database 
147d0 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 61 20  file contains a 
147e0 74 72 75 73 74 77 6f 72 74 68 79 0a 20 20 20 20  trustworthy.    
147f0 20 20 20 20 2a 2a 20 73 6e 61 70 73 68 6f 54 2e      ** snapshoT.
14800 20 53 69 6e 63 65 20 68 6f 6c 64 69 6e 67 20 52   Since holding R
14810 45 41 44 5f 4c 4f 43 4b 28 30 29 20 70 72 65 76  EAD_LOCK(0) prev
14820 65 6e 74 73 20 61 20 63 68 65 63 6b 70 6f 69 6e  ents a checkpoin
14830 74 20 66 72 6f 6d 0a 20 20 20 20 20 20 20 20 2a  t from.        *
14840 2a 20 68 61 70 70 65 6e 69 6e 67 2c 20 74 68 69  * happening, thi
14850 73 20 69 73 20 75 73 75 61 6c 6c 79 20 63 6f 72  s is usually cor
14860 72 65 63 74 2e 0a 20 20 20 20 20 20 20 20 2a 2a  rect..        **
14870 0a 20 20 20 20 20 20 20 20 2a 2a 20 48 6f 77 65  .        ** Howe
14880 76 65 72 2c 20 69 66 20 66 72 61 6d 65 73 20 68  ver, if frames h
14890 61 76 65 20 62 65 65 6e 20 61 70 70 65 6e 64 65  ave been appende
148a0 64 20 74 6f 20 74 68 65 20 6c 6f 67 20 28 6f 72  d to the log (or
148b0 20 69 66 20 74 68 65 20 6c 6f 67 20 0a 20 20 20   if the log .   
148c0 20 20 20 20 20 2a 2a 20 69 73 20 77 72 61 70 70       ** is wrapp
148d0 65 64 20 61 6e 64 20 77 72 69 74 74 65 6e 20 66  ed and written f
148e0 6f 72 20 74 68 61 74 20 6d 61 74 74 65 72 29 20  or that matter) 
148f0 62 65 66 6f 72 65 20 74 68 65 20 52 45 41 44 5f  before the READ_
14900 4c 4f 43 4b 28 30 29 0a 20 20 20 20 20 20 20 20  LOCK(0).        
14910 2a 2a 20 69 73 20 6f 62 74 61 69 6e 65 64 2c 20  ** is obtained, 
14920 74 68 61 74 20 69 73 20 6e 6f 74 20 6e 65 63 65  that is not nece
14930 73 73 61 72 69 6c 79 20 74 72 75 65 2e 20 41 20  ssarily true. A 
14940 63 68 65 63 6b 70 6f 69 6e 74 65 72 20 6d 61 79  checkpointer may
14950 0a 20 20 20 20 20 20 20 20 2a 2a 20 68 61 76 65  .        ** have
14960 20 73 74 61 72 74 65 64 20 74 6f 20 62 61 63 6b   started to back
14970 66 69 6c 6c 20 74 68 65 20 61 70 70 65 6e 64 65  fill the appende
14980 64 20 66 72 61 6d 65 73 20 62 75 74 20 63 72 61  d frames but cra
14990 73 68 65 64 20 62 65 66 6f 72 65 0a 20 20 20 20  shed before.    
149a0 20 20 20 20 2a 2a 20 69 74 20 66 69 6e 69 73 68      ** it finish
149b0 65 64 2e 20 4c 65 61 76 69 6e 67 20 61 20 63 6f  ed. Leaving a co
149c0 72 72 75 70 74 20 69 6d 61 67 65 20 69 6e 20 74  rrupt image in t
149d0 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
149e0 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20  ..        */.   
149f0 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68       walUnlockSh
14a00 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
14a10 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20  EAD_LOCK(0));.  
14a20 20 20 20 20 20 20 72 65 74 75 72 6e 20 57 41 4c        return WAL
14a30 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 0a  _RETRY;.      }.
14a40 20 20 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64        pWal->read
14a50 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20  Lock = 0;.      
14a60 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
14a70 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  ;.    }else if( 
14a80 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc!=SQLITE_BUSY 
14a90 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
14aa0 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  rc;.    }.  }.. 
14ab0 20 2f 2a 20 49 66 20 77 65 20 67 65 74 20 74 68   /* If we get th
14ac0 69 73 20 66 61 72 2c 20 69 74 20 6d 65 61 6e 73  is far, it means
14ad0 20 74 68 61 74 20 74 68 65 20 72 65 61 64 65 72   that the reader
14ae0 20 77 69 6c 6c 20 77 61 6e 74 20 74 6f 20 75 73   will want to us
14af0 65 0a 20 20 2a 2a 20 74 68 65 20 57 41 4c 20 74  e.  ** the WAL t
14b00 6f 20 67 65 74 20 61 74 20 63 6f 6e 74 65 6e 74  o get at content
14b10 20 66 72 6f 6d 20 72 65 63 65 6e 74 20 63 6f 6d   from recent com
14b20 6d 69 74 73 2e 20 20 54 68 65 20 6a 6f 62 20 6e  mits.  The job n
14b30 6f 77 20 69 73 0a 20 20 2a 2a 20 74 6f 20 73 65  ow is.  ** to se
14b40 6c 65 63 74 20 6f 6e 65 20 6f 66 20 74 68 65 20  lect one of the 
14b50 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e 74 72  aReadMark[] entr
14b60 69 65 73 20 74 68 61 74 20 69 73 20 63 6c 6f 73  ies that is clos
14b70 65 73 74 20 74 6f 0a 20 20 2a 2a 20 62 75 74 20  est to.  ** but 
14b80 6e 6f 74 20 65 78 63 65 65 64 69 6e 67 20 70 57  not exceeding pW
14b90 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
14ba0 61 6e 64 20 6c 6f 63 6b 20 74 68 61 74 20 65 6e  and lock that en
14bb0 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 6d 78 52 65  try..  */.  mxRe
14bc0 61 64 4d 61 72 6b 20 3d 20 30 3b 0a 20 20 6d 78  adMark = 0;.  mx
14bd0 49 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 31  I = 0;.  for(i=1
14be0 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b  ; i<WAL_NREADER;
14bf0 20 69 2b 2b 29 7b 0a 20 20 20 20 75 33 32 20 74   i++){.    u32 t
14c00 68 69 73 4d 61 72 6b 20 3d 20 70 49 6e 66 6f 2d  hisMark = pInfo-
14c10 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20  >aReadMark[i];. 
14c20 20 20 20 69 66 28 20 6d 78 52 65 61 64 4d 61 72     if( mxReadMar
14c30 6b 3c 3d 74 68 69 73 4d 61 72 6b 20 26 26 20 74  k<=thisMark && t
14c40 68 69 73 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e 68  hisMark<=pWal->h
14c50 64 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20  dr.mxFrame ){.  
14c60 20 20 20 20 61 73 73 65 72 74 28 20 74 68 69 73      assert( this
14c70 4d 61 72 6b 21 3d 52 45 41 44 4d 41 52 4b 5f 4e  Mark!=READMARK_N
14c80 4f 54 5f 55 53 45 44 20 29 3b 0a 20 20 20 20 20  OT_USED );.     
14c90 20 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20 74 68   mxReadMark = th
14ca0 69 73 4d 61 72 6b 3b 0a 20 20 20 20 20 20 6d 78  isMark;.      mx
14cb0 49 20 3d 20 69 3b 0a 20 20 20 20 7d 0a 20 20 7d  I = i;.    }.  }
14cc0 0a 20 20 2f 2a 20 54 68 65 72 65 20 77 61 73 20  .  /* There was 
14cd0 6f 6e 63 65 20 61 6e 20 22 69 66 22 20 68 65 72  once an "if" her
14ce0 65 2e 20 54 68 65 20 65 78 74 72 61 20 22 7b 22  e. The extra "{"
14cf0 20 69 73 20 74 6f 20 70 72 65 73 65 72 76 65 20   is to preserve 
14d00 69 6e 64 65 6e 74 61 74 69 6f 6e 2e 20 2a 2f 0a  indentation. */.
14d10 20 20 7b 0a 20 20 20 20 69 66 28 20 28 70 57 61    {.    if( (pWa
14d20 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57 41  l->readOnly & WA
14d30 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 29 3d 3d 30  L_SHM_RDONLY)==0
14d40 0a 20 20 20 20 20 26 26 20 28 6d 78 52 65 61 64  .     && (mxRead
14d50 4d 61 72 6b 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d  Mark<pWal->hdr.m
14d60 78 46 72 61 6d 65 20 7c 7c 20 6d 78 49 3d 3d 30  xFrame || mxI==0
14d70 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 66  ).    ){.      f
14d80 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52  or(i=1; i<WAL_NR
14d90 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20  EADER; i++){.   
14da0 20 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63       rc = walLoc
14db0 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
14dc0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69   WAL_READ_LOCK(i
14dd0 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20 69  ), 1);.        i
14de0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
14df0 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 78   ){.          mx
14e00 52 65 61 64 4d 61 72 6b 20 3d 20 70 49 6e 66 6f  ReadMark = pInfo
14e10 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d  ->aReadMark[i] =
14e20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
14e30 6d 65 3b 0a 20 20 20 20 20 20 20 20 20 20 6d 78  me;.          mx
14e40 49 20 3d 20 69 3b 0a 20 20 20 20 20 20 20 20 20  I = i;.         
14e50 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
14e60 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  ive(pWal, WAL_RE
14e70 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a  AD_LOCK(i), 1);.
14e80 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
14e90 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69  .        }else i
14ea0 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55  f( rc!=SQLITE_BU
14eb0 53 59 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  SY ){.          
14ec0 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20  return rc;.     
14ed0 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
14ee0 20 7d 0a 20 20 20 20 69 66 28 20 6d 78 49 3d 3d   }.    if( mxI==
14ef0 30 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72  0 ){.      asser
14f00 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  t( rc==SQLITE_BU
14f10 53 59 20 7c 7c 20 28 70 57 61 6c 2d 3e 72 65 61  SY || (pWal->rea
14f20 64 4f 6e 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f  dOnly & WAL_SHM_
14f30 52 44 4f 4e 4c 59 29 21 3d 30 20 29 3b 0a 20 20  RDONLY)!=0 );.  
14f40 20 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d 53      return rc==S
14f50 51 4c 49 54 45 5f 42 55 53 59 20 3f 20 57 41 4c  QLITE_BUSY ? WAL
14f60 5f 52 45 54 52 59 20 3a 20 53 51 4c 49 54 45 5f  _RETRY : SQLITE_
14f70 52 45 41 44 4f 4e 4c 59 5f 43 41 4e 54 4c 4f 43  READONLY_CANTLOC
14f80 4b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 63  K;.    }..    rc
14f90 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64   = walLockShared
14fa0 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f  (pWal, WAL_READ_
14fb0 4c 4f 43 4b 28 6d 78 49 29 29 3b 0a 20 20 20 20  LOCK(mxI));.    
14fc0 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 20 20  if( rc ){.      
14fd0 72 65 74 75 72 6e 20 72 63 3d 3d 53 51 4c 49 54  return rc==SQLIT
14fe0 45 5f 42 55 53 59 20 3f 20 57 41 4c 5f 52 45 54  E_BUSY ? WAL_RET
14ff0 52 59 20 3a 20 72 63 3b 0a 20 20 20 20 7d 0a 20  RY : rc;.    }. 
15000 20 20 20 2f 2a 20 4e 6f 77 20 74 68 61 74 20 74     /* Now that t
15010 68 65 20 72 65 61 64 2d 6c 6f 63 6b 20 68 61 73  he read-lock has
15020 20 62 65 65 6e 20 6f 62 74 61 69 6e 65 64 2c 20   been obtained, 
15030 63 68 65 63 6b 20 74 68 61 74 20 6e 65 69 74 68  check that neith
15040 65 72 20 74 68 65 0a 20 20 20 20 2a 2a 20 76 61  er the.    ** va
15050 6c 75 65 20 69 6e 20 74 68 65 20 61 52 65 61 64  lue in the aRead
15060 4d 61 72 6b 5b 5d 20 61 72 72 61 79 20 6f 72 20  Mark[] array or 
15070 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
15080 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 20 20  the wal-index.  
15090 20 20 2a 2a 20 68 65 61 64 65 72 20 68 61 76 65    ** header have
150a0 20 63 68 61 6e 67 65 64 2e 0a 20 20 20 20 2a 2a   changed..    **
150b0 0a 20 20 20 20 2a 2a 20 49 74 20 69 73 20 6e 65  .    ** It is ne
150c0 63 65 73 73 61 72 79 20 74 6f 20 63 68 65 63 6b  cessary to check
150d0 20 74 68 61 74 20 74 68 65 20 77 61 6c 2d 69 6e   that the wal-in
150e0 64 65 78 20 68 65 61 64 65 72 20 64 69 64 20 6e  dex header did n
150f0 6f 74 20 63 68 61 6e 67 65 0a 20 20 20 20 2a 2a  ot change.    **
15100 20 62 65 74 77 65 65 6e 20 74 68 65 20 74 69 6d   between the tim
15110 65 20 69 74 20 77 61 73 20 72 65 61 64 20 61 6e  e it was read an
15120 64 20 77 68 65 6e 20 74 68 65 20 73 68 61 72 65  d when the share
15130 64 2d 6c 6f 63 6b 20 77 61 73 20 6f 62 74 61 69  d-lock was obtai
15140 6e 65 64 0a 20 20 20 20 2a 2a 20 6f 6e 20 57 41  ned.    ** on WA
15150 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29  L_READ_LOCK(mxI)
15160 20 77 61 73 20 6f 62 74 61 69 6e 65 64 20 74 6f   was obtained to
15170 20 61 63 63 6f 75 6e 74 20 66 6f 72 20 74 68 65   account for the
15180 20 70 6f 73 73 69 62 69 6c 69 74 79 0a 20 20 20   possibility.   
15190 20 2a 2a 20 74 68 61 74 20 74 68 65 20 6c 6f 67   ** that the log
151a0 20 66 69 6c 65 20 6d 61 79 20 68 61 76 65 20 62   file may have b
151b0 65 65 6e 20 77 72 61 70 70 65 64 20 62 79 20 61  een wrapped by a
151c0 20 77 72 69 74 65 72 2c 20 6f 72 20 74 68 61 74   writer, or that
151d0 20 66 72 61 6d 65 73 0a 20 20 20 20 2a 2a 20 74   frames.    ** t
151e0 68 61 74 20 6f 63 63 75 72 20 6c 61 74 65 72 20  hat occur later 
151f0 69 6e 20 74 68 65 20 6c 6f 67 20 74 68 61 6e 20  in the log than 
15200 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
15210 65 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e 0a  e may have been.
15220 20 20 20 20 2a 2a 20 63 6f 70 69 65 64 20 69 6e      ** copied in
15230 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20  to the database 
15240 62 79 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 65  by a checkpointe
15250 72 2e 20 49 66 20 65 69 74 68 65 72 20 6f 66 20  r. If either of 
15260 74 68 65 73 65 20 74 68 69 6e 67 73 0a 20 20 20  these things.   
15270 20 2a 2a 20 68 61 70 70 65 6e 65 64 2c 20 74 68   ** happened, th
15280 65 6e 20 72 65 61 64 69 6e 67 20 74 68 65 20 64  en reading the d
15290 61 74 61 62 61 73 65 20 77 69 74 68 20 74 68 65  atabase with the
152a0 20 63 75 72 72 65 6e 74 20 76 61 6c 75 65 20 6f   current value o
152b0 66 0a 20 20 20 20 2a 2a 20 70 57 61 6c 2d 3e 68  f.    ** pWal->h
152c0 64 72 2e 6d 78 46 72 61 6d 65 20 72 69 73 6b 73  dr.mxFrame risks
152d0 20 72 65 61 64 69 6e 67 20 61 20 63 6f 72 72 75   reading a corru
152e0 70 74 65 64 20 73 6e 61 70 73 68 6f 74 2e 20 53  pted snapshot. S
152f0 6f 2c 20 72 65 74 72 79 0a 20 20 20 20 2a 2a 20  o, retry.    ** 
15300 69 6e 73 74 65 61 64 2e 0a 20 20 20 20 2a 2a 0a  instead..    **.
15310 20 20 20 20 2a 2a 20 54 68 69 73 20 64 6f 65 73      ** This does
15320 20 6e 6f 74 20 67 75 61 72 61 6e 74 65 65 20 74   not guarantee t
15330 68 61 74 20 74 68 65 20 63 6f 70 79 20 6f 66 20  hat the copy of 
15340 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
15350 61 64 65 72 20 69 73 20 75 70 20 74 6f 0a 20 20  ader is up to.  
15360 20 20 2a 2a 20 64 61 74 65 20 62 65 66 6f 72 65    ** date before
15370 20 70 72 6f 63 65 65 64 69 6e 67 2e 20 54 68 61   proceeding. Tha
15380 74 20 77 6f 75 6c 64 20 6e 6f 74 20 62 65 20 70  t would not be p
15390 6f 73 73 69 62 6c 65 20 77 69 74 68 6f 75 74 20  ossible without 
153a0 73 6f 6d 65 68 6f 77 0a 20 20 20 20 2a 2a 20 62  somehow.    ** b
153b0 6c 6f 63 6b 69 6e 67 20 77 72 69 74 65 72 73 2e  locking writers.
153c0 20 49 74 20 6f 6e 6c 79 20 67 75 61 72 61 6e 74   It only guarant
153d0 65 65 73 20 74 68 61 74 20 61 20 64 61 6e 67 65  ees that a dange
153e0 72 6f 75 73 20 63 68 65 63 6b 70 6f 69 6e 74 20  rous checkpoint 
153f0 6f 72 20 0a 20 20 20 20 2a 2a 20 6c 6f 67 2d 77  or .    ** log-w
15400 72 61 70 20 28 65 69 74 68 65 72 20 6f 66 20 77  rap (either of w
15410 68 69 63 68 20 77 6f 75 6c 64 20 72 65 71 75 69  hich would requi
15420 72 65 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20  re an exclusive 
15430 6c 6f 63 6b 20 6f 6e 0a 20 20 20 20 2a 2a 20 57  lock on.    ** W
15440 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49  AL_READ_LOCK(mxI
15450 29 29 20 68 61 73 20 6e 6f 74 20 6f 63 63 75 72  )) has not occur
15460 72 65 64 20 73 69 6e 63 65 20 74 68 65 20 73 6e  red since the sn
15470 61 70 73 68 6f 74 20 77 61 73 20 76 61 6c 69 64  apshot was valid
15480 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 77 61 6c  ..    */.    wal
15490 53 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c 29  ShmBarrier(pWal)
154a0 3b 0a 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d  ;.    if( pInfo-
154b0 3e 61 52 65 61 64 4d 61 72 6b 5b 6d 78 49 5d 21  >aReadMark[mxI]!
154c0 3d 6d 78 52 65 61 64 4d 61 72 6b 0a 20 20 20 20  =mxReadMark.    
154d0 20 7c 7c 20 6d 65 6d 63 6d 70 28 28 76 6f 69 64   || memcmp((void
154e0 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70   *)walIndexHdr(p
154f0 57 61 6c 29 2c 20 26 70 57 61 6c 2d 3e 68 64 72  Wal), &pWal->hdr
15500 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65  , sizeof(WalInde
15510 78 48 64 72 29 29 0a 20 20 20 20 29 7b 0a 20 20  xHdr)).    ){.  
15520 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61      walUnlockSha
15530 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
15540 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b 0a 20  AD_LOCK(mxI));. 
15550 20 20 20 20 20 72 65 74 75 72 6e 20 57 41 4c 5f       return WAL_
15560 52 45 54 52 59 3b 0a 20 20 20 20 7d 65 6c 73 65  RETRY;.    }else
15570 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  {.      assert( 
15580 6d 78 52 65 61 64 4d 61 72 6b 3c 3d 70 57 61 6c  mxReadMark<=pWal
15590 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b  ->hdr.mxFrame );
155a0 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 72 65 61  .      pWal->rea
155b0 64 4c 6f 63 6b 20 3d 20 28 69 31 36 29 6d 78 49  dLock = (i16)mxI
155c0 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65  ;.    }.  }.  re
155d0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
155e0 2a 20 42 65 67 69 6e 20 61 20 72 65 61 64 20 74  * Begin a read t
155f0 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68  ransaction on th
15600 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2a 0a 2a  e database..**.*
15610 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 75  * This routine u
15620 73 65 64 20 74 6f 20 62 65 20 63 61 6c 6c 65 64  sed to be called
15630 20 73 71 6c 69 74 65 33 4f 70 65 6e 53 6e 61 70   sqlite3OpenSnap
15640 73 68 6f 74 28 29 20 61 6e 64 20 77 69 74 68 20  shot() and with 
15650 67 6f 6f 64 20 72 65 61 73 6f 6e 3a 0a 2a 2a 20  good reason:.** 
15660 69 74 20 74 61 6b 65 73 20 61 20 73 6e 61 70 73  it takes a snaps
15670 68 6f 74 20 6f 66 20 74 68 65 20 73 74 61 74 65  hot of the state
15680 20 6f 66 20 74 68 65 20 57 41 4c 20 61 6e 64 20   of the WAL and 
15690 77 61 6c 2d 69 6e 64 65 78 20 66 6f 72 20 74 68  wal-index for th
156a0 65 20 63 75 72 72 65 6e 74 0a 2a 2a 20 69 6e 73  e current.** ins
156b0 74 61 6e 74 20 69 6e 20 74 69 6d 65 2e 20 20 54  tant in time.  T
156c0 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61  he current threa
156d0 64 20 77 69 6c 6c 20 63 6f 6e 74 69 6e 75 65 20  d will continue 
156e0 74 6f 20 75 73 65 20 74 68 69 73 20 73 6e 61 70  to use this snap
156f0 73 68 6f 74 2e 0a 2a 2a 20 4f 74 68 65 72 20 74  shot..** Other t
15700 68 72 65 61 64 73 20 6d 69 67 68 74 20 61 70 70  hreads might app
15710 65 6e 64 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20  end new content 
15720 74 6f 20 74 68 65 20 57 41 4c 20 61 6e 64 20 77  to the WAL and w
15730 61 6c 2d 69 6e 64 65 78 20 62 75 74 0a 2a 2a 20  al-index but.** 
15740 74 68 61 74 20 65 78 74 72 61 20 63 6f 6e 74 65  that extra conte
15750 6e 74 20 69 73 20 69 67 6e 6f 72 65 64 20 62 79  nt is ignored by
15760 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68 72   the current thr
15770 65 61 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ead..**.** If th
15780 65 20 64 61 74 61 62 61 73 65 20 63 6f 6e 74 65  e database conte
15790 6e 74 73 20 68 61 76 65 20 63 68 61 6e 67 65 73  nts have changes
157a0 20 73 69 6e 63 65 20 74 68 65 20 70 72 65 76 69   since the previ
157b0 6f 75 73 20 72 65 61 64 0a 2a 2a 20 74 72 61 6e  ous read.** tran
157c0 73 61 63 74 69 6f 6e 2c 20 74 68 65 6e 20 2a 70  saction, then *p
157d0 43 68 61 6e 67 65 64 20 69 73 20 73 65 74 20 74  Changed is set t
157e0 6f 20 31 20 62 65 66 6f 72 65 20 72 65 74 75 72  o 1 before retur
157f0 6e 69 6e 67 2e 20 20 54 68 65 0a 2a 2a 20 50 61  ning.  The.** Pa
15800 67 65 72 20 6c 61 79 65 72 20 77 69 6c 6c 20 75  ger layer will u
15810 73 65 20 74 68 69 73 20 74 6f 20 6b 6e 6f 77 20  se this to know 
15820 74 68 61 74 20 69 73 20 63 61 63 68 65 20 69 73  that is cache is
15830 20 73 74 61 6c 65 20 61 6e 64 0a 2a 2a 20 6e 65   stale and.** ne
15840 65 64 73 20 74 6f 20 62 65 20 66 6c 75 73 68 65  eds to be flushe
15850 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  d..*/.int sqlite
15860 33 57 61 6c 42 65 67 69 6e 52 65 61 64 54 72 61  3WalBeginReadTra
15870 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57  nsaction(Wal *pW
15880 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e 67 65  al, int *pChange
15890 64 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  d){.  int rc;   
158a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
158b0 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
158c0 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 63 6e  code */.  int cn
158d0 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  t = 0;          
158e0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
158f0 62 65 72 20 6f 66 20 54 72 79 42 65 67 69 6e 52  ber of TryBeginR
15900 65 61 64 20 61 74 74 65 6d 70 74 73 20 2a 2f 0a  ead attempts */.
15910 0a 20 20 64 6f 7b 0a 20 20 20 20 72 63 20 3d 20  .  do{.    rc = 
15920 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64 28  walTryBeginRead(
15930 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 2c 20  pWal, pChanged, 
15940 30 2c 20 2b 2b 63 6e 74 29 3b 0a 20 20 7d 77 68  0, ++cnt);.  }wh
15950 69 6c 65 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54  ile( rc==WAL_RET
15960 52 59 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65  RY );.  testcase
15970 28 20 28 72 63 26 30 78 66 66 29 3d 3d 53 51 4c  ( (rc&0xff)==SQL
15980 49 54 45 5f 42 55 53 59 20 29 3b 0a 20 20 74 65  ITE_BUSY );.  te
15990 73 74 63 61 73 65 28 20 28 72 63 26 30 78 66 66  stcase( (rc&0xff
159a0 29 3d 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 20  )==SQLITE_IOERR 
159b0 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 72  );.  testcase( r
159c0 63 3d 3d 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43  c==SQLITE_PROTOC
159d0 4f 4c 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65  OL );.  testcase
159e0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
159f0 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
15a00 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 69 73 68 20  }../*.** Finish 
15a10 77 69 74 68 20 61 20 72 65 61 64 20 74 72 61 6e  with a read tran
15a20 73 61 63 74 69 6f 6e 2e 20 20 41 6c 6c 20 74 68  saction.  All th
15a30 69 73 20 64 6f 65 73 20 69 73 20 72 65 6c 65 61  is does is relea
15a40 73 65 20 74 68 65 0a 2a 2a 20 72 65 61 64 2d 6c  se the.** read-l
15a50 6f 63 6b 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  ock..*/.void sql
15a60 69 74 65 33 57 61 6c 45 6e 64 52 65 61 64 54 72  ite3WalEndReadTr
15a70 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70  ansaction(Wal *p
15a80 57 61 6c 29 7b 0a 20 20 73 71 6c 69 74 65 33 57  Wal){.  sqlite3W
15a90 61 6c 45 6e 64 57 72 69 74 65 54 72 61 6e 73 61  alEndWriteTransa
15aa0 63 74 69 6f 6e 28 70 57 61 6c 29 3b 0a 20 20 69  ction(pWal);.  i
15ab0 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  f( pWal->readLoc
15ac0 6b 3e 3d 30 20 29 7b 0a 20 20 20 20 77 61 6c 55  k>=0 ){.    walU
15ad0 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
15ae0 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
15af0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29  pWal->readLock))
15b00 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64  ;.    pWal->read
15b10 4c 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20 7d 0a 7d  Lock = -1;.  }.}
15b20 0a 0a 2f 2a 0a 2a 2a 20 53 65 61 72 63 68 20 74  ../*.** Search t
15b30 68 65 20 77 61 6c 20 66 69 6c 65 20 66 6f 72 20  he wal file for 
15b40 70 61 67 65 20 70 67 6e 6f 2e 20 49 66 20 66 6f  page pgno. If fo
15b50 75 6e 64 2c 20 73 65 74 20 2a 70 69 52 65 61 64  und, set *piRead
15b60 20 74 6f 20 74 68 65 20 66 72 61 6d 65 20 74 68   to the frame th
15b70 61 74 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 74  at.** contains t
15b80 68 65 20 70 61 67 65 2e 20 4f 74 68 65 72 77 69  he page. Otherwi
15b90 73 65 2c 20 69 66 20 70 67 6e 6f 20 69 73 20 6e  se, if pgno is n
15ba0 6f 74 20 69 6e 20 74 68 65 20 77 61 6c 20 66 69  ot in the wal fi
15bb0 6c 65 2c 20 73 65 74 20 2a 70 69 52 65 61 64 0a  le, set *piRead.
15bc0 2a 2a 20 74 6f 20 7a 65 72 6f 2e 0a 2a 2a 0a 2a  ** to zero..**.*
15bd0 2a 20 52 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  * Return SQLITE_
15be0 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c  OK if successful
15bf0 2c 20 6f 72 20 61 6e 20 65 72 72 6f 72 20 63 6f  , or an error co
15c00 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f  de if an error o
15c10 63 63 75 72 73 2e 20 49 66 20 61 6e 0a 2a 2a 20  ccurs. If an.** 
15c20 65 72 72 6f 72 20 64 6f 65 73 20 6f 63 63 75 72  error does occur
15c30 2c 20 74 68 65 20 66 69 6e 61 6c 20 76 61 6c 75  , the final valu
15c40 65 20 6f 66 20 2a 70 69 52 65 61 64 20 69 73 20  e of *piRead is 
15c50 75 6e 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e  undefined..*/.in
15c60 74 20 73 71 6c 69 74 65 33 57 61 6c 46 69 6e 64  t sqlite3WalFind
15c70 46 72 61 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57  Frame(.  Wal *pW
15c80 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
15c90 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20           /* WAL 
15ca0 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 50 67 6e 6f  handle */.  Pgno
15cb0 20 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20   pgno,          
15cc0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
15cd0 61 74 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d  atabase page num
15ce0 62 65 72 20 74 6f 20 72 65 61 64 20 64 61 74 61  ber to read data
15cf0 20 66 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a 70   for */.  u32 *p
15d00 69 52 65 61 64 20 20 20 20 20 20 20 20 20 20 20  iRead           
15d10 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
15d20 3a 20 46 72 61 6d 65 20 6e 75 6d 62 65 72 20 28  : Frame number (
15d30 6f 72 20 7a 65 72 6f 29 20 2a 2f 0a 29 7b 0a 20  or zero) */.){. 
15d40 20 75 33 32 20 69 52 65 61 64 20 3d 20 30 3b 20   u32 iRead = 0; 
15d50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15d60 20 2f 2a 20 49 66 20 21 3d 30 2c 20 57 41 4c 20   /* If !=0, WAL 
15d70 66 72 61 6d 65 20 74 6f 20 72 65 74 75 72 6e 20  frame to return 
15d80 64 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 75  data from */.  u
15d90 33 32 20 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d  32 iLast = pWal-
15da0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 20 20 2f  >hdr.mxFrame;  /
15db0 2a 20 4c 61 73 74 20 70 61 67 65 20 69 6e 20 57  * Last page in W
15dc0 41 4c 20 66 6f 72 20 74 68 69 73 20 72 65 61 64  AL for this read
15dd0 65 72 20 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73  er */.  int iHas
15de0 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  h;              
15df0 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20          /* Used 
15e00 74 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20  to loop through 
15e10 4e 20 68 61 73 68 20 74 61 62 6c 65 73 20 2a 2f  N hash tables */
15e20 0a 0a 20 20 2f 2a 20 54 68 69 73 20 72 6f 75 74  ..  /* This rout
15e30 69 6e 65 20 69 73 20 6f 6e 6c 79 20 62 65 20 63  ine is only be c
15e40 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74 68 69  alled from withi
15e50 6e 20 61 20 72 65 61 64 20 74 72 61 6e 73 61 63  n a read transac
15e60 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72  tion. */.  asser
15e70 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  t( pWal->readLoc
15e80 6b 3e 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f  k>=0 || pWal->lo
15e90 63 6b 45 72 72 6f 72 20 29 3b 0a 0a 20 20 2f 2a  ckError );..  /*
15ea0 20 49 66 20 74 68 65 20 22 6c 61 73 74 20 70 61   If the "last pa
15eb0 67 65 22 20 66 69 65 6c 64 20 6f 66 20 74 68 65  ge" field of the
15ec0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
15ed0 72 20 73 6e 61 70 73 68 6f 74 20 69 73 20 30 2c  r snapshot is 0,
15ee0 20 74 68 65 6e 0a 20 20 2a 2a 20 6e 6f 20 64 61   then.  ** no da
15ef0 74 61 20 77 69 6c 6c 20 62 65 20 72 65 61 64 20  ta will be read 
15f00 66 72 6f 6d 20 74 68 65 20 77 61 6c 20 75 6e 64  from the wal und
15f10 65 72 20 61 6e 79 20 63 69 72 63 75 6d 73 74 61  er any circumsta
15f20 6e 63 65 73 2e 20 52 65 74 75 72 6e 20 65 61 72  nces. Return ear
15f30 6c 79 0a 20 20 2a 2a 20 69 6e 20 74 68 69 73 20  ly.  ** in this 
15f40 63 61 73 65 20 61 73 20 61 6e 20 6f 70 74 69 6d  case as an optim
15f50 69 7a 61 74 69 6f 6e 2e 20 20 4c 69 6b 65 77 69  ization.  Likewi
15f60 73 65 2c 20 69 66 20 70 57 61 6c 2d 3e 72 65 61  se, if pWal->rea
15f70 64 4c 6f 63 6b 3d 3d 30 2c 20 0a 20 20 2a 2a 20  dLock==0, .  ** 
15f80 74 68 65 6e 20 74 68 65 20 57 41 4c 20 69 73 20  then the WAL is 
15f90 69 67 6e 6f 72 65 64 20 62 79 20 74 68 65 20 72  ignored by the r
15fa0 65 61 64 65 72 20 73 6f 20 72 65 74 75 72 6e 20  eader so return 
15fb0 65 61 72 6c 79 2c 20 61 73 20 69 66 20 74 68 65  early, as if the
15fc0 20 0a 20 20 2a 2a 20 57 41 4c 20 77 65 72 65 20   .  ** WAL were 
15fd0 65 6d 70 74 79 2e 0a 20 20 2a 2f 0a 20 20 69 66  empty..  */.  if
15fe0 28 20 69 4c 61 73 74 3d 3d 30 20 7c 7c 20 70 57  ( iLast==0 || pW
15ff0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20  al->readLock==0 
16000 29 7b 0a 20 20 20 20 2a 70 69 52 65 61 64 20 3d  ){.    *piRead =
16010 20 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   0;.    return S
16020 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20  QLITE_OK;.  }.. 
16030 20 2f 2a 20 53 65 61 72 63 68 20 74 68 65 20 68   /* Search the h
16040 61 73 68 20 74 61 62 6c 65 20 6f 72 20 74 61 62  ash table or tab
16050 6c 65 73 20 66 6f 72 20 61 6e 20 65 6e 74 72 79  les for an entry
16060 20 6d 61 74 63 68 69 6e 67 20 70 61 67 65 20 6e   matching page n
16070 75 6d 62 65 72 0a 20 20 2a 2a 20 70 67 6e 6f 2e  umber.  ** pgno.
16080 20 45 61 63 68 20 69 74 65 72 61 74 69 6f 6e 20   Each iteration 
16090 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
160a0 20 66 6f 72 28 29 20 6c 6f 6f 70 20 73 65 61 72   for() loop sear
160b0 63 68 65 73 20 6f 6e 65 0a 20 20 2a 2a 20 68 61  ches one.  ** ha
160c0 73 68 20 74 61 62 6c 65 20 28 65 61 63 68 20 68  sh table (each h
160d0 61 73 68 20 74 61 62 6c 65 20 69 6e 64 65 78 65  ash table indexe
160e0 73 20 75 70 20 74 6f 20 48 41 53 48 54 41 42 4c  s up to HASHTABL
160f0 45 5f 4e 50 41 47 45 20 66 72 61 6d 65 73 29 2e  E_NPAGE frames).
16100 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 69 73 20  .  **.  ** This 
16110 63 6f 64 65 20 6d 69 67 68 74 20 72 75 6e 20 63  code might run c
16120 6f 6e 63 75 72 72 65 6e 74 6c 79 20 74 6f 20 74  oncurrently to t
16130 68 65 20 63 6f 64 65 20 69 6e 20 77 61 6c 49 6e  he code in walIn
16140 64 65 78 41 70 70 65 6e 64 28 29 0a 20 20 2a 2a  dexAppend().  **
16150 20 74 68 61 74 20 61 64 64 73 20 65 6e 74 72 69   that adds entri
16160 65 73 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e  es to the wal-in
16170 64 65 78 20 28 61 6e 64 20 70 6f 73 73 69 62 6c  dex (and possibl
16180 79 20 74 6f 20 74 68 69 73 20 68 61 73 68 20 0a  y to this hash .
16190 20 20 2a 2a 20 74 61 62 6c 65 29 2e 20 54 68 69    ** table). Thi
161a0 73 20 6d 65 61 6e 73 20 74 68 65 20 76 61 6c 75  s means the valu
161b0 65 20 6a 75 73 74 20 72 65 61 64 20 66 72 6f 6d  e just read from
161c0 20 74 68 65 20 68 61 73 68 20 0a 20 20 2a 2a 20   the hash .  ** 
161d0 73 6c 6f 74 20 28 61 48 61 73 68 5b 69 4b 65 79  slot (aHash[iKey
161e0 5d 29 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e  ]) may have been
161f0 20 61 64 64 65 64 20 62 65 66 6f 72 65 20 6f 72   added before or
16200 20 61 66 74 65 72 20 74 68 65 20 0a 20 20 2a 2a   after the .  **
16210 20 63 75 72 72 65 6e 74 20 72 65 61 64 20 74 72   current read tr
16220 61 6e 73 61 63 74 69 6f 6e 20 77 61 73 20 6f 70  ansaction was op
16230 65 6e 65 64 2e 20 56 61 6c 75 65 73 20 61 64 64  ened. Values add
16240 65 64 20 61 66 74 65 72 20 74 68 65 0a 20 20 2a  ed after the.  *
16250 2a 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  * read transacti
16260 6f 6e 20 77 61 73 20 6f 70 65 6e 65 64 20 6d 61  on was opened ma
16270 79 20 68 61 76 65 20 62 65 65 6e 20 77 72 69 74  y have been writ
16280 74 65 6e 20 69 6e 63 6f 72 72 65 63 74 6c 79 20  ten incorrectly 
16290 2d 0a 20 20 2a 2a 20 69 2e 65 2e 20 74 68 65 73  -.  ** i.e. thes
162a0 65 20 73 6c 6f 74 73 20 6d 61 79 20 63 6f 6e 74  e slots may cont
162b0 61 69 6e 20 67 61 72 62 61 67 65 20 64 61 74 61  ain garbage data
162c0 2e 20 48 6f 77 65 76 65 72 2c 20 77 65 20 61 73  . However, we as
162d0 73 75 6d 65 0a 20 20 2a 2a 20 74 68 61 74 20 61  sume.  ** that a
162e0 6e 79 20 73 6c 6f 74 73 20 77 72 69 74 74 65 6e  ny slots written
162f0 20 62 65 66 6f 72 65 20 74 68 65 20 63 75 72 72   before the curr
16300 65 6e 74 20 72 65 61 64 20 74 72 61 6e 73 61 63  ent read transac
16310 74 69 6f 6e 20 77 61 73 0a 20 20 2a 2a 20 6f 70  tion was.  ** op
16320 65 6e 65 64 20 72 65 6d 61 69 6e 20 75 6e 6d 6f  ened remain unmo
16330 64 69 66 69 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a  dified..  **.  *
16340 2a 20 46 6f 72 20 74 68 65 20 72 65 61 73 6f 6e  * For the reason
16350 73 20 61 62 6f 76 65 2c 20 74 68 65 20 69 66 28  s above, the if(
16360 2e 2e 2e 29 20 63 6f 6e 64 69 74 69 6f 6e 20 66  ...) condition f
16370 65 61 74 75 72 65 64 20 69 6e 20 74 68 65 20 69  eatured in the i
16380 6e 6e 65 72 0a 20 20 2a 2a 20 6c 6f 6f 70 20 6f  nner.  ** loop o
16390 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
163a0 62 6c 6f 63 6b 20 69 73 20 6d 6f 72 65 20 73 74  block is more st
163b0 72 69 6e 67 65 6e 74 20 74 68 61 74 20 77 6f 75  ringent that wou
163c0 6c 64 20 62 65 20 72 65 71 75 69 72 65 64 20 0a  ld be required .
163d0 20 20 2a 2a 20 69 66 20 77 65 20 68 61 64 20 65    ** if we had e
163e0 78 63 6c 75 73 69 76 65 20 61 63 63 65 73 73 20  xclusive access 
163f0 74 6f 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c  to the hash-tabl
16400 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 28  e:.  **.  **   (
16410 61 50 67 6e 6f 5b 69 46 72 61 6d 65 5d 3d 3d 70  aPgno[iFrame]==p
16420 67 6e 6f 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20  gno): .  **     
16430 54 68 69 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66  This condition f
16440 69 6c 74 65 72 73 20 6f 75 74 20 6e 6f 72 6d 61  ilters out norma
16450 6c 20 68 61 73 68 2d 74 61 62 6c 65 20 63 6f 6c  l hash-table col
16460 6c 69 73 69 6f 6e 73 2e 0a 20 20 2a 2a 0a 20 20  lisions..  **.  
16470 2a 2a 20 20 20 28 69 46 72 61 6d 65 3c 3d 69 4c  **   (iFrame<=iL
16480 61 73 74 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20  ast): .  **     
16490 54 68 69 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66  This condition f
164a0 69 6c 74 65 72 73 20 6f 75 74 20 65 6e 74 72 69  ilters out entri
164b0 65 73 20 74 68 61 74 20 77 65 72 65 20 61 64 64  es that were add
164c0 65 64 20 74 6f 20 74 68 65 20 68 61 73 68 0a 20  ed to the hash. 
164d0 20 2a 2a 20 20 20 20 20 74 61 62 6c 65 20 61 66   **     table af
164e0 74 65 72 20 74 68 65 20 63 75 72 72 65 6e 74 20  ter the current 
164f0 72 65 61 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e  read-transaction
16500 20 68 61 64 20 73 74 61 72 74 65 64 2e 0a 20 20   had started..  
16510 2a 2f 0a 20 20 66 6f 72 28 69 48 61 73 68 3d 77  */.  for(iHash=w
16520 61 6c 46 72 61 6d 65 50 61 67 65 28 69 4c 61 73  alFramePage(iLas
16530 74 29 3b 20 69 48 61 73 68 3e 3d 30 20 26 26 20  t); iHash>=0 && 
16540 69 52 65 61 64 3d 3d 30 3b 20 69 48 61 73 68 2d  iRead==0; iHash-
16550 2d 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65  -){.    volatile
16560 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b   ht_slot *aHash;
16570 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
16580 20 74 6f 20 68 61 73 68 20 74 61 62 6c 65 20 2a   to hash table *
16590 2f 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75  /.    volatile u
165a0 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20  32 *aPgno;      
165b0 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
165c0 6f 20 61 72 72 61 79 20 6f 66 20 70 61 67 65 20  o array of page 
165d0 6e 75 6d 62 65 72 73 20 2a 2f 0a 20 20 20 20 75  numbers */.    u
165e0 33 32 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20  32 iZero;       
165f0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
16600 46 72 61 6d 65 20 6e 75 6d 62 65 72 20 63 6f 72  Frame number cor
16610 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 61 50  responding to aP
16620 67 6e 6f 5b 30 5d 20 2a 2f 0a 20 20 20 20 69 6e  gno[0] */.    in
16630 74 20 69 4b 65 79 3b 20 20 20 20 20 20 20 20 20  t iKey;         
16640 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48              /* H
16650 61 73 68 20 73 6c 6f 74 20 69 6e 64 65 78 20 2a  ash slot index *
16660 2f 0a 20 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69  /.    int nColli
16670 64 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  de;             
16680 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
16690 20 68 61 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73   hash collisions
166a0 20 72 65 6d 61 69 6e 69 6e 67 20 2a 2f 0a 20 20   remaining */.  
166b0 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
166c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
166d0 2f 2a 20 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f  /* Error code */
166e0 0a 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 48 61  ..    rc = walHa
166f0 73 68 47 65 74 28 70 57 61 6c 2c 20 69 48 61 73  shGet(pWal, iHas
16700 68 2c 20 26 61 48 61 73 68 2c 20 26 61 50 67 6e  h, &aHash, &aPgn
16710 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20  o, &iZero);.    
16720 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
16730 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  K ){.      retur
16740 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20  n rc;.    }.    
16750 6e 43 6f 6c 6c 69 64 65 20 3d 20 48 41 53 48 54  nCollide = HASHT
16760 41 42 4c 45 5f 4e 53 4c 4f 54 3b 0a 20 20 20 20  ABLE_NSLOT;.    
16770 66 6f 72 28 69 4b 65 79 3d 77 61 6c 48 61 73 68  for(iKey=walHash
16780 28 70 67 6e 6f 29 3b 20 61 48 61 73 68 5b 69 4b  (pgno); aHash[iK
16790 65 79 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78  ey]; iKey=walNex
167a0 74 48 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20  tHash(iKey)){.  
167b0 20 20 20 20 75 33 32 20 69 46 72 61 6d 65 20 3d      u32 iFrame =
167c0 20 61 48 61 73 68 5b 69 4b 65 79 5d 20 2b 20 69   aHash[iKey] + i
167d0 5a 65 72 6f 3b 0a 20 20 20 20 20 20 69 66 28 20  Zero;.      if( 
167e0 69 46 72 61 6d 65 3c 3d 69 4c 61 73 74 20 26 26  iFrame<=iLast &&
167f0 20 61 50 67 6e 6f 5b 61 48 61 73 68 5b 69 4b 65   aPgno[aHash[iKe
16800 79 5d 5d 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20  y]]==pgno ){.   
16810 20 20 20 20 20 2f 2a 20 61 73 73 65 72 74 28 20       /* assert( 
16820 69 46 72 61 6d 65 3e 69 52 65 61 64 20 29 3b 20  iFrame>iRead ); 
16830 2d 2d 20 6e 6f 74 20 74 72 75 65 20 69 66 20 74  -- not true if t
16840 68 65 72 65 20 69 73 20 63 6f 72 72 75 70 74 69  here is corrupti
16850 6f 6e 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 52  on */.        iR
16860 65 61 64 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20  ead = iFrame;.  
16870 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
16880 28 6e 43 6f 6c 6c 69 64 65 2d 2d 29 3d 3d 30 20  (nCollide--)==0 
16890 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
168a0 6e 20 53 51 4c 49 54 45 5f 43 4f 52 52 55 50 54  n SQLITE_CORRUPT
168b0 5f 42 4b 50 54 3b 0a 20 20 20 20 20 20 7d 0a 20  _BKPT;.      }. 
168c0 20 20 20 7d 0a 20 20 7d 0a 0a 23 69 66 64 65 66     }.  }..#ifdef
168d0 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45   SQLITE_ENABLE_E
168e0 58 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54 0a  XPENSIVE_ASSERT.
168f0 20 20 2f 2a 20 49 66 20 65 78 70 65 6e 73 69 76    /* If expensiv
16900 65 20 61 73 73 65 72 74 28 29 20 73 74 61 74 65  e assert() state
16910 6d 65 6e 74 73 20 61 72 65 20 61 76 61 69 6c 61  ments are availa
16920 62 6c 65 2c 20 64 6f 20 61 20 6c 69 6e 65 61 72  ble, do a linear
16930 20 73 65 61 72 63 68 0a 20 20 2a 2a 20 6f 66 20   search.  ** of 
16940 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69  the wal-index fi
16950 6c 65 20 63 6f 6e 74 65 6e 74 2e 20 4d 61 6b 65  le content. Make
16960 20 73 75 72 65 20 74 68 65 20 72 65 73 75 6c 74   sure the result
16970 73 20 61 67 72 65 65 20 77 69 74 68 20 74 68 65  s agree with the
16980 0a 20 20 2a 2a 20 72 65 73 75 6c 74 20 6f 62 74  .  ** result obt
16990 61 69 6e 65 64 20 75 73 69 6e 67 20 74 68 65 20  ained using the 
169a0 68 61 73 68 20 69 6e 64 65 78 65 73 20 61 62 6f  hash indexes abo
169b0 76 65 2e 20 20 2a 2f 0a 20 20 7b 0a 20 20 20 20  ve.  */.  {.    
169c0 75 33 32 20 69 52 65 61 64 32 20 3d 20 30 3b 0a  u32 iRead2 = 0;.
169d0 20 20 20 20 75 33 32 20 69 54 65 73 74 3b 0a 20      u32 iTest;. 
169e0 20 20 20 66 6f 72 28 69 54 65 73 74 3d 69 4c 61     for(iTest=iLa
169f0 73 74 3b 20 69 54 65 73 74 3e 30 3b 20 69 54 65  st; iTest>0; iTe
16a00 73 74 2d 2d 29 7b 0a 20 20 20 20 20 20 69 66 28  st--){.      if(
16a10 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57   walFramePgno(pW
16a20 61 6c 2c 20 69 54 65 73 74 29 3d 3d 70 67 6e 6f  al, iTest)==pgno
16a30 20 29 7b 0a 20 20 20 20 20 20 20 20 69 52 65 61   ){.        iRea
16a40 64 32 20 3d 20 69 54 65 73 74 3b 0a 20 20 20 20  d2 = iTest;.    
16a50 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
16a60 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 73   }.    }.    ass
16a70 65 72 74 28 20 69 52 65 61 64 3d 3d 69 52 65 61  ert( iRead==iRea
16a80 64 32 20 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66  d2 );.  }.#endif
16a90 0a 0a 20 20 2a 70 69 52 65 61 64 20 3d 20 69 52  ..  *piRead = iR
16aa0 65 61 64 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  ead;.  return SQ
16ab0 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
16ac0 2a 20 52 65 61 64 20 74 68 65 20 63 6f 6e 74 65  * Read the conte
16ad0 6e 74 73 20 6f 66 20 66 72 61 6d 65 20 69 52 65  nts of frame iRe
16ae0 61 64 20 66 72 6f 6d 20 74 68 65 20 77 61 6c 20  ad from the wal 
16af0 66 69 6c 65 20 69 6e 74 6f 20 62 75 66 66 65 72  file into buffer
16b00 20 70 4f 75 74 0a 2a 2a 20 28 77 68 69 63 68 20   pOut.** (which 
16b10 69 73 20 6e 4f 75 74 20 62 79 74 65 73 20 69 6e  is nOut bytes in
16b20 20 73 69 7a 65 29 2e 20 52 65 74 75 72 6e 20 53   size). Return S
16b30 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63  QLITE_OK if succ
16b40 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 0a 2a 2a  essful, or an.**
16b50 20 65 72 72 6f 72 20 63 6f 64 65 20 6f 74 68 65   error code othe
16b60 72 77 69 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71  rwise..*/.int sq
16b70 6c 69 74 65 33 57 61 6c 52 65 61 64 46 72 61 6d  lite3WalReadFram
16b80 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20  e(.  Wal *pWal, 
16b90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16ba0 20 20 20 20 20 2f 2a 20 57 41 4c 20 68 61 6e 64       /* WAL hand
16bb0 6c 65 20 2a 2f 0a 20 20 75 33 32 20 69 52 65 61  le */.  u32 iRea
16bc0 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d,              
16bd0 20 20 20 20 20 20 20 20 2f 2a 20 46 72 61 6d 65          /* Frame
16be0 20 74 6f 20 72 65 61 64 20 2a 2f 0a 20 20 69 6e   to read */.  in
16bf0 74 20 6e 4f 75 74 2c 20 20 20 20 20 20 20 20 20  t nOut,         
16c00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
16c10 20 53 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20   Size of buffer 
16c20 70 4f 75 74 20 69 6e 20 62 79 74 65 73 20 2a 2f  pOut in bytes */
16c30 0a 20 20 75 38 20 2a 70 4f 75 74 20 20 20 20 20  .  u8 *pOut     
16c40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16c50 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20     /* Buffer to 
16c60 77 72 69 74 65 20 70 61 67 65 20 64 61 74 61 20  write page data 
16c70 74 6f 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 73  to */.){.  int s
16c80 7a 3b 0a 20 20 69 36 34 20 69 4f 66 66 73 65 74  z;.  i64 iOffset
16c90 3b 0a 20 20 73 7a 20 3d 20 70 57 61 6c 2d 3e 68  ;.  sz = pWal->h
16ca0 64 72 2e 73 7a 50 61 67 65 3b 0a 20 20 73 7a 20  dr.szPage;.  sz 
16cb0 3d 20 28 73 7a 26 30 78 66 65 30 30 29 20 2b 20  = (sz&0xfe00) + 
16cc0 28 28 73 7a 26 30 78 30 30 30 31 29 3c 3c 31 36  ((sz&0x0001)<<16
16cd0 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 73  );.  testcase( s
16ce0 7a 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20 74 65  z<=32768 );.  te
16cf0 73 74 63 61 73 65 28 20 73 7a 3e 3d 36 35 35 33  stcase( sz>=6553
16d00 36 20 29 3b 0a 20 20 69 4f 66 66 73 65 74 20 3d  6 );.  iOffset =
16d10 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28   walFrameOffset(
16d20 69 52 65 61 64 2c 20 73 7a 29 20 2b 20 57 41 4c  iRead, sz) + WAL
16d30 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a  _FRAME_HDRSIZE;.
16d40 20 20 2f 2a 20 74 65 73 74 63 61 73 65 28 20 49    /* testcase( I
16d50 53 5f 42 49 47 5f 49 4e 54 28 69 4f 66 66 73 65  S_BIG_INT(iOffse
16d60 74 29 20 29 3b 20 2f 2f 20 72 65 71 75 69 72 65  t) ); // require
16d70 73 20 61 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a  s a 4GiB WAL */.
16d80 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
16d90 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61  OsRead(pWal->pWa
16da0 6c 46 64 2c 20 70 4f 75 74 2c 20 28 6e 4f 75 74  lFd, pOut, (nOut
16db0 3e 73 7a 20 3f 20 73 7a 20 3a 20 6e 4f 75 74 29  >sz ? sz : nOut)
16dc0 2c 20 69 4f 66 66 73 65 74 29 3b 0a 7d 0a 0a 2f  , iOffset);.}../
16dd0 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  * .** Return the
16de0 20 73 69 7a 65 20 6f 66 20 74 68 65 20 64 61 74   size of the dat
16df0 61 62 61 73 65 20 69 6e 20 70 61 67 65 73 20 28  abase in pages (
16e00 6f 72 20 7a 65 72 6f 2c 20 69 66 20 75 6e 6b 6e  or zero, if unkn
16e10 6f 77 6e 29 2e 0a 2a 2f 0a 50 67 6e 6f 20 73 71  own)..*/.Pgno sq
16e20 6c 69 74 65 33 57 61 6c 44 62 73 69 7a 65 28 57  lite3WalDbsize(W
16e30 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28  al *pWal){.  if(
16e40 20 70 57 61 6c 20 26 26 20 41 4c 57 41 59 53 28   pWal && ALWAYS(
16e50 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
16e60 30 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  0) ){.    return
16e70 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65   pWal->hdr.nPage
16e80 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30  ;.  }.  return 0
16e90 3b 0a 7d 0a 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69  ;.}.../* .** Thi
16ea0 73 20 66 75 6e 63 74 69 6f 6e 20 73 74 61 72 74  s function start
16eb0 73 20 61 20 77 72 69 74 65 20 74 72 61 6e 73 61  s a write transa
16ec0 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20 57 41 4c  ction on the WAL
16ed0 2e 0a 2a 2a 0a 2a 2a 20 41 20 72 65 61 64 20 74  ..**.** A read t
16ee0 72 61 6e 73 61 63 74 69 6f 6e 20 6d 75 73 74 20  ransaction must 
16ef0 68 61 76 65 20 61 6c 72 65 61 64 79 20 62 65 65  have already bee
16f00 6e 20 73 74 61 72 74 65 64 20 62 79 20 61 20 70  n started by a p
16f10 72 69 6f 72 20 63 61 6c 6c 0a 2a 2a 20 74 6f 20  rior call.** to 
16f20 73 71 6c 69 74 65 33 57 61 6c 42 65 67 69 6e 52  sqlite3WalBeginR
16f30 65 61 64 54 72 61 6e 73 61 63 74 69 6f 6e 28 29  eadTransaction()
16f40 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 6f 74 68  ..**.** If anoth
16f50 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f  er thread or pro
16f60 63 65 73 73 20 68 61 73 20 77 72 69 74 74 65 6e  cess has written
16f70 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
16f80 73 65 20 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20  se since.** the 
16f90 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
16fa0 20 77 61 73 20 73 74 61 72 74 65 64 2c 20 74 68   was started, th
16fb0 65 6e 20 69 74 20 69 73 20 6e 6f 74 20 70 6f 73  en it is not pos
16fc0 73 69 62 6c 65 20 66 6f 72 20 74 68 69 73 0a 2a  sible for this.*
16fd0 2a 20 74 68 72 65 61 64 20 74 6f 20 77 72 69 74  * thread to writ
16fe0 65 20 61 73 20 64 6f 69 6e 67 20 73 6f 20 77 6f  e as doing so wo
16ff0 75 6c 64 20 63 61 75 73 65 20 61 20 66 6f 72 6b  uld cause a fork
17000 2e 20 20 53 6f 20 74 68 69 73 20 72 6f 75 74 69  .  So this routi
17010 6e 65 0a 2a 2a 20 72 65 74 75 72 6e 73 20 53 51  ne.** returns SQ
17020 4c 49 54 45 5f 42 55 53 59 20 69 6e 20 74 68 61  LITE_BUSY in tha
17030 74 20 63 61 73 65 20 61 6e 64 20 6e 6f 20 77 72  t case and no wr
17040 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ite transaction 
17050 69 73 20 73 74 61 72 74 65 64 2e 0a 2a 2a 0a 2a  is started..**.*
17060 2a 20 54 68 65 72 65 20 63 61 6e 20 6f 6e 6c 79  * There can only
17070 20 62 65 20 61 20 73 69 6e 67 6c 65 20 77 72 69   be a single wri
17080 74 65 72 20 61 63 74 69 76 65 20 61 74 20 61 20  ter active at a 
17090 74 69 6d 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  time..*/.int sql
170a0 69 74 65 33 57 61 6c 42 65 67 69 6e 57 72 69 74  ite3WalBeginWrit
170b0 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c  eTransaction(Wal
170c0 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72   *pWal){.  int r
170d0 63 3b 0a 0a 20 20 2f 2a 20 43 61 6e 6e 6f 74 20  c;..  /* Cannot 
170e0 73 74 61 72 74 20 61 20 77 72 69 74 65 20 74 72  start a write tr
170f0 61 6e 73 61 63 74 69 6f 6e 20 77 69 74 68 6f 75  ansaction withou
17100 74 20 66 69 72 73 74 20 68 6f 6c 64 69 6e 67 20  t first holding 
17110 61 20 72 65 61 64 0a 20 20 2a 2a 20 74 72 61 6e  a read.  ** tran
17120 73 61 63 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73  saction. */.  as
17130 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64  sert( pWal->read
17140 4c 6f 63 6b 3e 3d 30 20 29 3b 0a 0a 20 20 69 66  Lock>=0 );..  if
17150 28 20 70 57 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79  ( pWal->readOnly
17160 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
17170 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 3b 0a  QLITE_READONLY;.
17180 20 20 7d 0a 0a 20 20 2f 2a 20 4f 6e 6c 79 20 6f    }..  /* Only o
17190 6e 65 20 77 72 69 74 65 72 20 61 6c 6c 6f 77 65  ne writer allowe
171a0 64 20 61 74 20 61 20 74 69 6d 65 2e 20 20 47 65  d at a time.  Ge
171b0 74 20 74 68 65 20 77 72 69 74 65 20 6c 6f 63 6b  t the write lock
171c0 2e 20 20 52 65 74 75 72 6e 0a 20 20 2a 2a 20 53  .  Return.  ** S
171d0 51 4c 49 54 45 5f 42 55 53 59 20 69 66 20 75 6e  QLITE_BUSY if un
171e0 61 62 6c 65 2e 0a 20 20 2a 2f 0a 20 20 72 63 20  able..  */.  rc 
171f0 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69  = walLockExclusi
17200 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49  ve(pWal, WAL_WRI
17210 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 69  TE_LOCK, 1);.  i
17220 66 28 20 72 63 20 29 7b 0a 20 20 20 20 72 65 74  f( rc ){.    ret
17230 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70 57  urn rc;.  }.  pW
17240 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20  al->writeLock = 
17250 31 3b 0a 0a 20 20 2f 2a 20 49 66 20 61 6e 6f 74  1;..  /* If anot
17260 68 65 72 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68  her connection h
17270 61 73 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68  as written to th
17280 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  e database file 
17290 73 69 6e 63 65 20 74 68 65 0a 20 20 2a 2a 20 74  since the.  ** t
172a0 69 6d 65 20 74 68 65 20 72 65 61 64 20 74 72 61  ime the read tra
172b0 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68 69 73  nsaction on this
172c0 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 77 61 73 20   connection was 
172d0 73 74 61 72 74 65 64 2c 20 74 68 65 6e 0a 20 20  started, then.  
172e0 2a 2a 20 74 68 65 20 77 72 69 74 65 20 69 73 20  ** the write is 
172f0 64 69 73 61 6c 6c 6f 77 65 64 2e 0a 20 20 2a 2f  disallowed..  */
17300 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 70  .  if( memcmp(&p
17310 57 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20  Wal->hdr, (void 
17320 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57  *)walIndexHdr(pW
17330 61 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49  al), sizeof(WalI
17340 6e 64 65 78 48 64 72 29 29 21 3d 30 20 29 7b 0a  ndexHdr))!=0 ){.
17350 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63      walUnlockExc
17360 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
17370 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b  _WRITE_LOCK, 1);
17380 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65  .    pWal->write
17390 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 72 63  Lock = 0;.    rc
173a0 20 3d 20 53 51 4c 49 54 45 5f 42 55 53 59 5f 53   = SQLITE_BUSY_S
173b0 4e 41 50 53 48 4f 54 3b 0a 20 20 7d 0a 0a 20 20  NAPSHOT;.  }..  
173c0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
173d0 0a 2a 2a 20 45 6e 64 20 61 20 77 72 69 74 65 20  .** End a write 
173e0 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 20 54 68  transaction.  Th
173f0 65 20 63 6f 6d 6d 69 74 20 68 61 73 20 61 6c 72  e commit has alr
17400 65 61 64 79 20 62 65 65 6e 20 64 6f 6e 65 2e 20  eady been done. 
17410 20 54 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65   This.** routine
17420 20 6d 65 72 65 6c 79 20 72 65 6c 65 61 73 65 73   merely releases
17430 20 74 68 65 20 6c 6f 63 6b 2e 0a 2a 2f 0a 69 6e   the lock..*/.in
17440 74 20 73 71 6c 69 74 65 33 57 61 6c 45 6e 64 57  t sqlite3WalEndW
17450 72 69 74 65 54 72 61 6e 73 61 63 74 69 6f 6e 28  riteTransaction(
17460 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66  Wal *pWal){.  if
17470 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
17480 6b 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f  k ){.    walUnlo
17490 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
174a0 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b  , WAL_WRITE_LOCK
174b0 2c 20 31 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  , 1);.    pWal->
174c0 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20  writeLock = 0;. 
174d0 20 20 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61 74     pWal->truncat
174e0 65 4f 6e 43 6f 6d 6d 69 74 20 3d 20 30 3b 0a 20  eOnCommit = 0;. 
174f0 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
17500 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
17510 49 66 20 61 6e 79 20 64 61 74 61 20 68 61 73 20  If any data has 
17520 62 65 65 6e 20 77 72 69 74 74 65 6e 20 28 62 75  been written (bu
17530 74 20 6e 6f 74 20 63 6f 6d 6d 69 74 74 65 64 29  t not committed)
17540 20 74 6f 20 74 68 65 20 6c 6f 67 20 66 69 6c 65   to the log file
17550 2c 20 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69  , this.** functi
17560 6f 6e 20 6d 6f 76 65 73 20 74 68 65 20 77 72 69  on moves the wri
17570 74 65 2d 70 6f 69 6e 74 65 72 20 62 61 63 6b 20  te-pointer back 
17580 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  to the start of 
17590 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e  the transaction.
175a0 0a 2a 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61  .**.** Additiona
175b0 6c 6c 79 2c 20 74 68 65 20 63 61 6c 6c 62 61 63  lly, the callbac
175c0 6b 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 69 6e  k function is in
175d0 76 6f 6b 65 64 20 66 6f 72 20 65 61 63 68 20 66  voked for each f
175e0 72 61 6d 65 20 77 72 69 74 74 65 6e 0a 2a 2a 20  rame written.** 
175f0 74 6f 20 74 68 65 20 57 41 4c 20 73 69 6e 63 65  to the WAL since
17600 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
17610 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 49  e transaction. I
17620 66 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 72  f the callback r
17630 65 74 75 72 6e 73 0a 2a 2a 20 6f 74 68 65 72 20  eturns.** other 
17640 74 68 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 2c 20  than SQLITE_OK, 
17650 69 74 20 69 73 20 6e 6f 74 20 69 6e 76 6f 6b 65  it is not invoke
17660 64 20 61 67 61 69 6e 20 61 6e 64 20 74 68 65 20  d again and the 
17670 65 72 72 6f 72 20 63 6f 64 65 20 69 73 0a 2a 2a  error code is.**
17680 20 72 65 74 75 72 6e 65 64 20 74 6f 20 74 68 65   returned to the
17690 20 63 61 6c 6c 65 72 2e 0a 2a 2a 0a 2a 2a 20 4f   caller..**.** O
176a0 74 68 65 72 77 69 73 65 2c 20 69 66 20 74 68 65  therwise, if the
176b0 20 63 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69   callback functi
176c0 6f 6e 20 64 6f 65 73 20 6e 6f 74 20 72 65 74 75  on does not retu
176d0 72 6e 20 61 6e 20 65 72 72 6f 72 2c 20 74 68 69  rn an error, thi
176e0 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 72 65  s.** function re
176f0 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b 2e  turns SQLITE_OK.
17700 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
17710 61 6c 55 6e 64 6f 28 57 61 6c 20 2a 70 57 61 6c  alUndo(Wal *pWal
17720 2c 20 69 6e 74 20 28 2a 78 55 6e 64 6f 29 28 76  , int (*xUndo)(v
17730 6f 69 64 20 2a 2c 20 50 67 6e 6f 29 2c 20 76 6f  oid *, Pgno), vo
17740 69 64 20 2a 70 55 6e 64 6f 43 74 78 29 7b 0a 20  id *pUndoCtx){. 
17750 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
17760 5f 4f 4b 3b 0a 20 20 69 66 28 20 41 4c 57 41 59  _OK;.  if( ALWAY
17770 53 28 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  S(pWal->writeLoc
17780 6b 29 20 29 7b 0a 20 20 20 20 50 67 6e 6f 20 69  k) ){.    Pgno i
17790 4d 61 78 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  Max = pWal->hdr.
177a0 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 50 67 6e  mxFrame;.    Pgn
177b0 6f 20 69 46 72 61 6d 65 3b 0a 20 20 0a 20 20 20  o iFrame;.  .   
177c0 20 2f 2a 20 52 65 73 74 6f 72 65 20 74 68 65 20   /* Restore the 
177d0 63 6c 69 65 6e 74 73 20 63 61 63 68 65 20 6f 66  clients cache of
177e0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
177f0 65 61 64 65 72 20 74 6f 20 74 68 65 20 73 74 61  eader to the sta
17800 74 65 20 69 74 0a 20 20 20 20 2a 2a 20 77 61 73  te it.    ** was
17810 20 69 6e 20 62 65 66 6f 72 65 20 74 68 65 20 63   in before the c
17820 6c 69 65 6e 74 20 62 65 67 61 6e 20 77 72 69 74  lient began writ
17830 69 6e 67 20 74 6f 20 74 68 65 20 64 61 74 61 62  ing to the datab
17840 61 73 65 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20  ase. .    */.   
17850 20 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68   memcpy(&pWal->h
17860 64 72 2c 20 28 76 6f 69 64 20 2a 29 77 61 6c 49  dr, (void *)walI
17870 6e 64 65 78 48 64 72 28 70 57 61 6c 29 2c 20 73  ndexHdr(pWal), s
17880 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64  izeof(WalIndexHd
17890 72 29 29 3b 0a 0a 20 20 20 20 66 6f 72 28 69 46  r));..    for(iF
178a0 72 61 6d 65 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d  rame=pWal->hdr.m
178b0 78 46 72 61 6d 65 2b 31 3b 20 0a 20 20 20 20 20  xFrame+1; .     
178c0 20 20 20 41 4c 57 41 59 53 28 72 63 3d 3d 53 51     ALWAYS(rc==SQ
178d0 4c 49 54 45 5f 4f 4b 29 20 26 26 20 69 46 72 61  LITE_OK) && iFra
178e0 6d 65 3c 3d 69 4d 61 78 3b 20 0a 20 20 20 20 20  me<=iMax; .     
178f0 20 20 20 69 46 72 61 6d 65 2b 2b 0a 20 20 20 20     iFrame++.    
17900 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73  ){.      /* This
17910 20 63 61 6c 6c 20 63 61 6e 6e 6f 74 20 66 61 69   call cannot fai
17920 6c 2e 20 55 6e 6c 65 73 73 20 74 68 65 20 70 61  l. Unless the pa
17930 67 65 20 66 6f 72 20 77 68 69 63 68 20 74 68 65  ge for which the
17940 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 20 20 20   page number.   
17950 20 20 20 2a 2a 20 69 73 20 70 61 73 73 65 64 20     ** is passed 
17960 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72  as the second ar
17970 67 75 6d 65 6e 74 20 69 73 20 28 61 29 20 69 6e  gument is (a) in
17980 20 74 68 65 20 63 61 63 68 65 20 61 6e 64 20 0a   the cache and .
17990 20 20 20 20 20 20 2a 2a 20 28 62 29 20 68 61 73        ** (b) has
179a0 20 61 6e 20 6f 75 74 73 74 61 6e 64 69 6e 67 20   an outstanding 
179b0 72 65 66 65 72 65 6e 63 65 2c 20 74 68 65 6e 20  reference, then 
179c0 78 55 6e 64 6f 20 69 73 20 65 69 74 68 65 72 20  xUndo is either 
179d0 61 20 6e 6f 2d 6f 70 0a 20 20 20 20 20 20 2a 2a  a no-op.      **
179e0 20 28 69 66 20 28 61 29 20 69 73 20 66 61 6c 73   (if (a) is fals
179f0 65 29 20 6f 72 20 73 69 6d 70 6c 79 20 65 78 70  e) or simply exp
17a00 65 6c 73 20 74 68 65 20 70 61 67 65 20 66 72 6f  els the page fro
17a10 6d 20 74 68 65 20 63 61 63 68 65 20 28 69 66 20  m the cache (if 
17a20 28 62 29 0a 20 20 20 20 20 20 2a 2a 20 69 73 20  (b).      ** is 
17a30 66 61 6c 73 65 29 2e 0a 20 20 20 20 20 20 2a 2a  false)..      **
17a40 0a 20 20 20 20 20 20 2a 2a 20 49 66 20 74 68 65  .      ** If the
17a50 20 75 70 70 65 72 20 6c 61 79 65 72 20 69 73 20   upper layer is 
17a60 64 6f 69 6e 67 20 61 20 72 6f 6c 6c 62 61 63 6b  doing a rollback
17a70 2c 20 69 74 20 69 73 20 67 75 61 72 61 6e 74 65  , it is guarante
17a80 65 64 20 74 68 61 74 20 74 68 65 72 65 0a 20 20  ed that there.  
17a90 20 20 20 20 2a 2a 20 61 72 65 20 6e 6f 20 6f 75      ** are no ou
17aa0 74 73 74 61 6e 64 69 6e 67 20 72 65 66 65 72 65  tstanding refere
17ab0 6e 63 65 73 20 74 6f 20 61 6e 79 20 70 61 67 65  nces to any page
17ac0 20 6f 74 68 65 72 20 74 68 61 6e 20 70 61 67 65   other than page
17ad0 20 31 2e 20 41 6e 64 0a 20 20 20 20 20 20 2a 2a   1. And.      **
17ae0 20 70 61 67 65 20 31 20 69 73 20 6e 65 76 65 72   page 1 is never
17af0 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20   written to the 
17b00 6c 6f 67 20 75 6e 74 69 6c 20 74 68 65 20 74 72  log until the tr
17b10 61 6e 73 61 63 74 69 6f 6e 20 69 73 0a 20 20 20  ansaction is.   
17b20 20 20 20 2a 2a 20 63 6f 6d 6d 69 74 74 65 64 2e     ** committed.
17b30 20 41 73 20 61 20 72 65 73 75 6c 74 2c 20 74 68   As a result, th
17b40 65 20 63 61 6c 6c 20 74 6f 20 78 55 6e 64 6f 20  e call to xUndo 
17b50 6d 61 79 20 6e 6f 74 20 66 61 69 6c 2e 0a 20 20  may not fail..  
17b60 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 61 73 73      */.      ass
17b70 65 72 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e  ert( walFramePgn
17b80 6f 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 21  o(pWal, iFrame)!
17b90 3d 31 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  =1 );.      rc =
17ba0 20 78 55 6e 64 6f 28 70 55 6e 64 6f 43 74 78 2c   xUndo(pUndoCtx,
17bb0 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57   walFramePgno(pW
17bc0 61 6c 2c 20 69 46 72 61 6d 65 29 29 3b 0a 20 20  al, iFrame));.  
17bd0 20 20 7d 0a 20 20 20 20 69 66 28 20 69 4d 61 78    }.    if( iMax
17be0 21 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  !=pWal->hdr.mxFr
17bf0 61 6d 65 20 29 20 77 61 6c 43 6c 65 61 6e 75 70  ame ) walCleanup
17c00 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 7d 0a  Hash(pWal);.  }.
17c10 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
17c20 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74  LITE_OK );.  ret
17c30 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  urn rc;.}../* .*
17c40 2a 20 41 72 67 75 6d 65 6e 74 20 61 57 61 6c 44  * Argument aWalD
17c50 61 74 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74  ata must point t
17c60 6f 20 61 6e 20 61 72 72 61 79 20 6f 66 20 57 41  o an array of WA
17c70 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54  L_SAVEPOINT_NDAT
17c80 41 20 75 33 32 20 0a 2a 2a 20 76 61 6c 75 65 73  A u32 .** values
17c90 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
17ca0 70 6f 70 75 6c 61 74 65 73 20 74 68 65 20 61 72  populates the ar
17cb0 72 61 79 20 77 69 74 68 20 76 61 6c 75 65 73 20  ray with values 
17cc0 72 65 71 75 69 72 65 64 20 74 6f 20 0a 2a 2a 20  required to .** 
17cd0 22 72 6f 6c 6c 62 61 63 6b 22 20 74 68 65 20 77  "rollback" the w
17ce0 72 69 74 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66  rite position of
17cf0 20 74 68 65 20 57 41 4c 20 68 61 6e 64 6c 65 20   the WAL handle 
17d00 62 61 63 6b 20 74 6f 20 74 68 65 20 63 75 72 72  back to the curr
17d10 65 6e 74 20 0a 2a 2a 20 70 6f 69 6e 74 20 69 6e  ent .** point in
17d20 20 74 68 65 20 65 76 65 6e 74 20 6f 66 20 61 20   the event of a 
17d30 73 61 76 65 70 6f 69 6e 74 20 72 6f 6c 6c 62 61  savepoint rollba
17d40 63 6b 20 28 76 69 61 20 57 61 6c 53 61 76 65 70  ck (via WalSavep
17d50 6f 69 6e 74 55 6e 64 6f 28 29 29 2e 0a 2a 2f 0a  ointUndo())..*/.
17d60 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 53  void sqlite3WalS
17d70 61 76 65 70 6f 69 6e 74 28 57 61 6c 20 2a 70 57  avepoint(Wal *pW
17d80 61 6c 2c 20 75 33 32 20 2a 61 57 61 6c 44 61 74  al, u32 *aWalDat
17d90 61 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57  a){.  assert( pW
17da0 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
17db0 0a 20 20 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d  .  aWalData[0] =
17dc0 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
17dd0 6d 65 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 31  me;.  aWalData[1
17de0 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46  ] = pWal->hdr.aF
17df0 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20  rameCksum[0];.  
17e00 61 57 61 6c 44 61 74 61 5b 32 5d 20 3d 20 70 57  aWalData[2] = pW
17e10 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
17e20 73 75 6d 5b 31 5d 3b 0a 20 20 61 57 61 6c 44 61  sum[1];.  aWalDa
17e30 74 61 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e 6e 43  ta[3] = pWal->nC
17e40 6b 70 74 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4d  kpt;.}../* .** M
17e50 6f 76 65 20 74 68 65 20 77 72 69 74 65 20 70 6f  ove the write po
17e60 73 69 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41  sition of the WA
17e70 4c 20 62 61 63 6b 20 74 6f 20 74 68 65 20 70 6f  L back to the po
17e80 69 6e 74 20 69 64 65 6e 74 69 66 69 65 64 20 62  int identified b
17e90 79 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 73 20  y.** the values 
17ea0 69 6e 20 74 68 65 20 61 57 61 6c 44 61 74 61 5b  in the aWalData[
17eb0 5d 20 61 72 72 61 79 2e 20 61 57 61 6c 44 61 74  ] array. aWalDat
17ec0 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f 20  a must point to 
17ed0 61 6e 20 61 72 72 61 79 0a 2a 2a 20 6f 66 20 57  an array.** of W
17ee0 41 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41  AL_SAVEPOINT_NDA
17ef0 54 41 20 75 33 32 20 76 61 6c 75 65 73 20 74 68  TA u32 values th
17f00 61 74 20 68 61 73 20 62 65 65 6e 20 70 72 65 76  at has been prev
17f10 69 6f 75 73 6c 79 20 70 6f 70 75 6c 61 74 65 64  iously populated
17f20 0a 2a 2a 20 62 79 20 61 20 63 61 6c 6c 20 74 6f  .** by a call to
17f30 20 57 61 6c 53 61 76 65 70 6f 69 6e 74 28 29 2e   WalSavepoint().
17f40 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
17f50 61 6c 53 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28  alSavepointUndo(
17f60 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a  Wal *pWal, u32 *
17f70 61 57 61 6c 44 61 74 61 29 7b 0a 20 20 69 6e 74  aWalData){.  int
17f80 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
17f90 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ..  assert( pWal
17fa0 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20  ->writeLock );. 
17fb0 20 61 73 73 65 72 74 28 20 61 57 61 6c 44 61 74   assert( aWalDat
17fc0 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43 6b 70  a[3]!=pWal->nCkp
17fd0 74 20 7c 7c 20 61 57 61 6c 44 61 74 61 5b 30 5d  t || aWalData[0]
17fe0 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  <=pWal->hdr.mxFr
17ff0 61 6d 65 20 29 3b 0a 0a 20 20 69 66 28 20 61 57  ame );..  if( aW
18000 61 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d  alData[3]!=pWal-
18010 3e 6e 43 6b 70 74 20 29 7b 0a 20 20 20 20 2f 2a  >nCkpt ){.    /*
18020 20 54 68 69 73 20 73 61 76 65 70 6f 69 6e 74 20   This savepoint 
18030 77 61 73 20 6f 70 65 6e 65 64 20 69 6d 6d 65 64  was opened immed
18040 69 61 74 65 6c 79 20 61 66 74 65 72 20 74 68 65  iately after the
18050 20 77 72 69 74 65 2d 74 72 61 6e 73 61 63 74 69   write-transacti
18060 6f 6e 0a 20 20 20 20 2a 2a 20 77 61 73 20 73 74  on.    ** was st
18070 61 72 74 65 64 2e 20 52 69 67 68 74 20 61 66 74  arted. Right aft
18080 65 72 20 74 68 61 74 2c 20 74 68 65 20 77 72 69  er that, the wri
18090 74 65 72 20 64 65 63 69 64 65 64 20 74 6f 20 77  ter decided to w
180a0 72 61 70 20 61 72 6f 75 6e 64 0a 20 20 20 20 2a  rap around.    *
180b0 2a 20 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f  * to the start o
180c0 66 20 74 68 65 20 6c 6f 67 2e 20 55 70 64 61 74  f the log. Updat
180d0 65 20 74 68 65 20 73 61 76 65 70 6f 69 6e 74 20  e the savepoint 
180e0 76 61 6c 75 65 73 20 74 6f 20 6d 61 74 63 68 2e  values to match.
180f0 0a 20 20 20 20 2a 2f 0a 20 20 20 20 61 57 61 6c  .    */.    aWal
18100 44 61 74 61 5b 30 5d 20 3d 20 30 3b 0a 20 20 20  Data[0] = 0;.   
18110 20 61 57 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70   aWalData[3] = p
18120 57 61 6c 2d 3e 6e 43 6b 70 74 3b 0a 20 20 7d 0a  Wal->nCkpt;.  }.
18130 0a 20 20 69 66 28 20 61 57 61 6c 44 61 74 61 5b  .  if( aWalData[
18140 30 5d 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  0]<pWal->hdr.mxF
18150 72 61 6d 65 20 29 7b 0a 20 20 20 20 70 57 61 6c  rame ){.    pWal
18160 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20  ->hdr.mxFrame = 
18170 61 57 61 6c 44 61 74 61 5b 30 5d 3b 0a 20 20 20  aWalData[0];.   
18180 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
18190 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 57 61 6c  eCksum[0] = aWal
181a0 44 61 74 61 5b 31 5d 3b 0a 20 20 20 20 70 57 61  Data[1];.    pWa
181b0 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
181c0 75 6d 5b 31 5d 20 3d 20 61 57 61 6c 44 61 74 61  um[1] = aWalData
181d0 5b 32 5d 3b 0a 20 20 20 20 77 61 6c 43 6c 65 61  [2];.    walClea
181e0 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20  nupHash(pWal);. 
181f0 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
18200 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  .}.../*.** This 
18210 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
18220 65 64 20 6a 75 73 74 20 62 65 66 6f 72 65 20 77  ed just before w
18230 72 69 74 69 6e 67 20 61 20 73 65 74 20 6f 66 20  riting a set of 
18240 66 72 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f  frames to the lo
18250 67 0a 2a 2a 20 66 69 6c 65 20 28 73 65 65 20 73  g.** file (see s
18260 71 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28  qlite3WalFrames(
18270 29 29 2e 20 49 74 20 63 68 65 63 6b 73 20 74 6f  )). It checks to
18280 20 73 65 65 20 69 66 2c 20 69 6e 73 74 65 61 64   see if, instead
18290 20 6f 66 20 61 70 70 65 6e 64 69 6e 67 0a 2a 2a   of appending.**
182a0 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20   to the current 
182b0 6c 6f 67 20 66 69 6c 65 2c 20 69 74 20 69 73 20  log file, it is 
182c0 70 6f 73 73 69 62 6c 65 20 74 6f 20 6f 76 65 72  possible to over
182d0 77 72 69 74 65 20 74 68 65 20 73 74 61 72 74 20  write the start 
182e0 6f 66 20 74 68 65 0a 2a 2a 20 65 78 69 73 74 69  of the.** existi
182f0 6e 67 20 6c 6f 67 20 66 69 6c 65 20 77 69 74 68  ng log file with
18300 20 74 68 65 20 6e 65 77 20 66 72 61 6d 65 73 20   the new frames 
18310 28 69 2e 65 2e 20 22 72 65 73 65 74 22 20 74 68  (i.e. "reset" th
18320 65 20 6c 6f 67 29 2e 20 49 66 20 73 6f 2c 0a 2a  e log). If so,.*
18330 2a 20 69 74 20 73 65 74 73 20 70 57 61 6c 2d 3e  * it sets pWal->
18340 68 64 72 2e 6d 78 46 72 61 6d 65 20 74 6f 20 30  hdr.mxFrame to 0
18350 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 70 57 61  . Otherwise, pWa
18360 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69  l->hdr.mxFrame i
18370 73 20 6c 65 66 74 0a 2a 2a 20 75 6e 63 68 61 6e  s left.** unchan
18380 67 65 64 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54  ged..**.** SQLIT
18390 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
183a0 20 69 66 20 6e 6f 20 65 72 72 6f 72 20 69 73 20   if no error is 
183b0 65 6e 63 6f 75 6e 74 65 72 65 64 20 28 72 65 67  encountered (reg
183c0 61 72 64 6c 65 73 73 20 6f 66 20 77 68 65 74 68  ardless of wheth
183d0 65 72 0a 2a 2a 20 6f 72 20 6e 6f 74 20 70 57 61  er.** or not pWa
183e0 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69  l->hdr.mxFrame i
183f0 73 20 6d 6f 64 69 66 69 65 64 29 2e 20 41 6e 20  s modified). An 
18400 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
18410 65 20 69 73 20 72 65 74 75 72 6e 65 64 0a 2a 2a  e is returned.**
18420 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   if an error occ
18430 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  urs..*/.static i
18440 6e 74 20 77 61 6c 52 65 73 74 61 72 74 4c 6f 67  nt walRestartLog
18450 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69  (Wal *pWal){.  i
18460 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
18470 4b 3b 0a 20 20 69 6e 74 20 63 6e 74 3b 0a 0a 20  K;.  int cnt;.. 
18480 20 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c   if( pWal->readL
18490 6f 63 6b 3d 3d 30 20 29 7b 0a 20 20 20 20 76 6f  ock==0 ){.    vo
184a0 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e  latile WalCkptIn
184b0 66 6f 20 2a 70 49 6e 66 6f 20 3d 20 77 61 6c 43  fo *pInfo = walC
184c0 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20  kptInfo(pWal);. 
184d0 20 20 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f     assert( pInfo
184e0 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70 57 61  ->nBackfill==pWa
184f0 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29  l->hdr.mxFrame )
18500 3b 0a 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d  ;.    if( pInfo-
18510 3e 6e 42 61 63 6b 66 69 6c 6c 3e 30 20 29 7b 0a  >nBackfill>0 ){.
18520 20 20 20 20 20 20 75 33 32 20 73 61 6c 74 31 3b        u32 salt1;
18530 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72  .      sqlite3_r
18540 61 6e 64 6f 6d 6e 65 73 73 28 34 2c 20 26 73 61  andomness(4, &sa
18550 6c 74 31 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  lt1);.      rc =
18560 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76   walLockExclusiv
18570 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
18580 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52  _LOCK(1), WAL_NR
18590 45 41 44 45 52 2d 31 29 3b 0a 20 20 20 20 20 20  EADER-1);.      
185a0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
185b0 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20  K ){.        /* 
185c0 49 66 20 61 6c 6c 20 72 65 61 64 65 72 73 20 61  If all readers a
185d0 72 65 20 75 73 69 6e 67 20 57 41 4c 5f 52 45 41  re using WAL_REA
185e0 44 5f 4c 4f 43 4b 28 30 29 20 28 69 6e 20 6f 74  D_LOCK(0) (in ot
185f0 68 65 72 20 77 6f 72 64 73 20 69 66 20 6e 6f 0a  her words if no.
18600 20 20 20 20 20 20 20 20 2a 2a 20 72 65 61 64 65          ** reade
18610 72 73 20 61 72 65 20 63 75 72 72 65 6e 74 6c 79  rs are currently
18620 20 75 73 69 6e 67 20 74 68 65 20 57 41 4c 29 2c   using the WAL),
18630 20 74 68 65 6e 20 74 68 65 20 74 72 61 6e 73 61   then the transa
18640 63 74 69 6f 6e 73 0a 20 20 20 20 20 20 20 20 2a  ctions.        *
18650 2a 20 66 72 61 6d 65 73 20 77 69 6c 6c 20 6f 76  * frames will ov
18660 65 72 77 72 69 74 65 20 74 68 65 20 73 74 61 72  erwrite the star
18670 74 20 6f 66 20 74 68 65 20 65 78 69 73 74 69 6e  t of the existin
18680 67 20 6c 6f 67 2e 20 55 70 64 61 74 65 20 74 68  g log. Update th
18690 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 77 61 6c  e.        ** wal
186a0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f  -index header to
186b0 20 72 65 66 6c 65 63 74 20 74 68 69 73 2e 0a 20   reflect this.. 
186c0 20 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20         **.      
186d0 20 20 2a 2a 20 49 6e 20 74 68 65 6f 72 79 20 69    ** In theory i
186e0 74 20 77 6f 75 6c 64 20 62 65 20 4f 6b 20 74 6f  t would be Ok to
186f0 20 75 70 64 61 74 65 20 74 68 65 20 63 61 63 68   update the cach
18700 65 20 6f 66 20 74 68 65 20 68 65 61 64 65 72 20  e of the header 
18710 6f 6e 6c 79 0a 20 20 20 20 20 20 20 20 2a 2a 20  only.        ** 
18720 61 74 20 74 68 69 73 20 70 6f 69 6e 74 2e 20 42  at this point. B
18730 75 74 20 75 70 64 61 74 69 6e 67 20 74 68 65 20  ut updating the 
18740 61 63 74 75 61 6c 20 77 61 6c 2d 69 6e 64 65 78  actual wal-index
18750 20 68 65 61 64 65 72 20 69 73 20 61 6c 73 6f 0a   header is also.
18760 20 20 20 20 20 20 20 20 2a 2a 20 73 61 66 65 20          ** safe 
18770 61 6e 64 20 6d 65 61 6e 73 20 74 68 65 72 65 20  and means there 
18780 69 73 20 6e 6f 20 73 70 65 63 69 61 6c 20 63 61  is no special ca
18790 73 65 20 66 6f 72 20 73 71 6c 69 74 65 33 57 61  se for sqlite3Wa
187a0 6c 55 6e 64 6f 28 29 0a 20 20 20 20 20 20 20 20  lUndo().        
187b0 2a 2a 20 74 6f 20 68 61 6e 64 6c 65 20 69 66 20  ** to handle if 
187c0 74 68 69 73 20 74 72 61 6e 73 61 63 74 69 6f 6e  this transaction
187d0 20 69 73 20 72 6f 6c 6c 65 64 20 62 61 63 6b 2e   is rolled back.
187e0 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  .        */.    
187f0 20 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20      int i;      
18800 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
18810 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f   Loop counter */
18820 0a 20 20 20 20 20 20 20 20 75 33 32 20 2a 61 53  .        u32 *aS
18830 61 6c 74 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  alt = pWal->hdr.
18840 61 53 61 6c 74 3b 20 20 20 20 20 20 20 2f 2a 20  aSalt;       /* 
18850 42 69 67 2d 65 6e 64 69 61 6e 20 73 61 6c 74 20  Big-endian salt 
18860 76 61 6c 75 65 73 20 2a 2f 0a 0a 20 20 20 20 20  values */..     
18870 20 20 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 2b 2b     pWal->nCkpt++
18880 3b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e  ;.        pWal->
18890 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20 30 3b  hdr.mxFrame = 0;
188a0 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
188b0 50 75 74 34 62 79 74 65 28 28 75 38 2a 29 26 61  Put4byte((u8*)&a
188c0 53 61 6c 74 5b 30 5d 2c 20 31 20 2b 20 73 71 6c  Salt[0], 1 + sql
188d0 69 74 65 33 47 65 74 34 62 79 74 65 28 28 75 38  ite3Get4byte((u8
188e0 2a 29 26 61 53 61 6c 74 5b 30 5d 29 29 3b 0a 20  *)&aSalt[0]));. 
188f0 20 20 20 20 20 20 20 61 53 61 6c 74 5b 31 5d 20         aSalt[1] 
18900 3d 20 73 61 6c 74 31 3b 0a 20 20 20 20 20 20 20  = salt1;.       
18910 20 77 61 6c 49 6e 64 65 78 57 72 69 74 65 48 64   walIndexWriteHd
18920 72 28 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 20  r(pWal);.       
18930 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
18940 6c 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 70  l = 0;.        p
18950 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b  Info->aReadMark[
18960 31 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  1] = 0;.        
18970 66 6f 72 28 69 3d 32 3b 20 69 3c 57 41 4c 5f 4e  for(i=2; i<WAL_N
18980 52 45 41 44 45 52 3b 20 69 2b 2b 29 20 70 49 6e  READER; i++) pIn
18990 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d  fo->aReadMark[i]
189a0 20 3d 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f   = READMARK_NOT_
189b0 55 53 45 44 3b 0a 20 20 20 20 20 20 20 20 61 73  USED;.        as
189c0 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e 61 52 65  sert( pInfo->aRe
189d0 61 64 4d 61 72 6b 5b 30 5d 3d 3d 30 20 29 3b 0a  adMark[0]==0 );.
189e0 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63          walUnloc
189f0 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
18a00 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31   WAL_READ_LOCK(1
18a10 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31  ), WAL_NREADER-1
18a20 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69  );.      }else i
18a30 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55  f( rc!=SQLITE_BU
18a40 53 59 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65  SY ){.        re
18a50 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d  turn rc;.      }
18a60 0a 20 20 20 20 7d 0a 20 20 20 20 77 61 6c 55 6e  .    }.    walUn
18a70 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  lockShared(pWal,
18a80 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
18a90 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 72 65  ));.    pWal->re
18aa0 61 64 4c 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20 20  adLock = -1;.   
18ab0 20 63 6e 74 20 3d 20 30 3b 0a 20 20 20 20 64 6f   cnt = 0;.    do
18ac0 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 6f 74 55  {.      int notU
18ad0 73 65 64 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  sed;.      rc = 
18ae0 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64 28  walTryBeginRead(
18af0 70 57 61 6c 2c 20 26 6e 6f 74 55 73 65 64 2c 20  pWal, &notUsed, 
18b00 31 2c 20 2b 2b 63 6e 74 29 3b 0a 20 20 20 20 7d  1, ++cnt);.    }
18b10 77 68 69 6c 65 28 20 72 63 3d 3d 57 41 4c 5f 52  while( rc==WAL_R
18b20 45 54 52 59 20 29 3b 0a 20 20 20 20 61 73 73 65  ETRY );.    asse
18b30 72 74 28 20 28 72 63 26 30 78 66 66 29 21 3d 53  rt( (rc&0xff)!=S
18b40 51 4c 49 54 45 5f 42 55 53 59 20 29 3b 20 2f 2a  QLITE_BUSY ); /*
18b50 20 42 55 53 59 20 6e 6f 74 20 70 6f 73 73 69 62   BUSY not possib
18b60 6c 65 20 77 68 65 6e 20 75 73 65 57 61 6c 3d 3d  le when useWal==
18b70 31 20 2a 2f 0a 20 20 20 20 74 65 73 74 63 61 73  1 */.    testcas
18b80 65 28 20 28 72 63 26 30 78 66 66 29 3d 3d 53 51  e( (rc&0xff)==SQ
18b90 4c 49 54 45 5f 49 4f 45 52 52 20 29 3b 0a 20 20  LITE_IOERR );.  
18ba0 20 20 74 65 73 74 63 61 73 65 28 20 72 63 3d 3d    testcase( rc==
18bb0 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 20  SQLITE_PROTOCOL 
18bc0 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73 65 28  );.    testcase(
18bd0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
18be0 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
18bf0 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 66 6f  c;.}../*.** Info
18c00 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 74 68  rmation about th
18c10 65 20 63 75 72 72 65 6e 74 20 73 74 61 74 65 20  e current state 
18c20 6f 66 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20  of the WAL file 
18c30 61 6e 64 20 77 68 65 72 65 0a 2a 2a 20 74 68 65  and where.** the
18c40 20 6e 65 78 74 20 66 73 79 6e 63 20 73 68 6f 75   next fsync shou
18c50 6c 64 20 6f 63 63 75 72 20 2d 20 70 61 73 73 65  ld occur - passe
18c60 64 20 66 72 6f 6d 20 73 71 6c 69 74 65 33 57 61  d from sqlite3Wa
18c70 6c 46 72 61 6d 65 73 28 29 20 69 6e 74 6f 0a 2a  lFrames() into.*
18c80 2a 20 77 61 6c 57 72 69 74 65 54 6f 4c 6f 67 28  * walWriteToLog(
18c90 29 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74  )..*/.typedef st
18ca0 72 75 63 74 20 57 61 6c 57 72 69 74 65 72 20 7b  ruct WalWriter {
18cb0 0a 20 20 57 61 6c 20 2a 70 57 61 6c 3b 20 20 20  .  Wal *pWal;   
18cc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18cd0 2f 2a 20 54 68 65 20 63 6f 6d 70 6c 65 74 65 20  /* The complete 
18ce0 57 41 4c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  WAL information 
18cf0 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  */.  sqlite3_fil
18d00 65 20 2a 70 46 64 3b 20 20 20 20 20 20 20 20 20  e *pFd;         
18d10 20 20 2f 2a 20 54 68 65 20 57 41 4c 20 66 69 6c    /* The WAL fil
18d20 65 20 74 6f 20 77 68 69 63 68 20 77 65 20 77 72  e to which we wr
18d30 69 74 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ite */.  sqlite3
18d40 5f 69 6e 74 36 34 20 69 53 79 6e 63 50 6f 69 6e  _int64 iSyncPoin
18d50 74 3b 20 20 20 20 2f 2a 20 46 73 79 6e 63 20 61  t;    /* Fsync a
18d60 74 20 74 68 69 73 20 6f 66 66 73 65 74 20 2a 2f  t this offset */
18d70 0a 20 20 69 6e 74 20 73 79 6e 63 46 6c 61 67 73  .  int syncFlags
18d80 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
18d90 2f 2a 20 46 6c 61 67 73 20 66 6f 72 20 74 68 65  /* Flags for the
18da0 20 66 73 79 6e 63 20 2a 2f 0a 20 20 69 6e 74 20   fsync */.  int 
18db0 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20  szPage;         
18dc0 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
18dd0 20 6f 66 20 6f 6e 65 20 70 61 67 65 20 2a 2f 0a   of one page */.
18de0 7d 20 57 61 6c 57 72 69 74 65 72 3b 0a 0a 2f 2a  } WalWriter;../*
18df0 0a 2a 2a 20 57 72 69 74 65 20 69 41 6d 74 20 62  .** Write iAmt b
18e00 79 74 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74 20  ytes of content 
18e10 69 6e 74 6f 20 74 68 65 20 57 41 4c 20 66 69 6c  into the WAL fil
18e20 65 20 62 65 67 69 6e 6e 69 6e 67 20 61 74 20 69  e beginning at i
18e30 4f 66 66 73 65 74 2e 0a 2a 2a 20 44 6f 20 61 20  Offset..** Do a 
18e40 73 79 6e 63 20 77 68 65 6e 20 63 72 6f 73 73 69  sync when crossi
18e50 6e 67 20 74 68 65 20 70 2d 3e 69 53 79 6e 63 50  ng the p->iSyncP
18e60 6f 69 6e 74 20 62 6f 75 6e 64 61 72 79 2e 0a 2a  oint boundary..*
18e70 2a 0a 2a 2a 20 49 6e 20 6f 74 68 65 72 20 77 6f  *.** In other wo
18e80 72 64 73 2c 20 69 66 20 69 53 79 6e 63 50 6f 69  rds, if iSyncPoi
18e90 6e 74 20 69 73 20 69 6e 20 62 65 74 77 65 65 6e  nt is in between
18ea0 20 69 4f 66 66 73 65 74 20 61 6e 64 20 69 4f 66   iOffset and iOf
18eb0 66 73 65 74 2b 69 41 6d 74 2c 0a 2a 2a 20 66 69  fset+iAmt,.** fi
18ec0 72 73 74 20 77 72 69 74 65 20 74 68 65 20 70 61  rst write the pa
18ed0 72 74 20 62 65 66 6f 72 65 20 69 53 79 6e 63 50  rt before iSyncP
18ee0 6f 69 6e 74 2c 20 74 68 65 6e 20 73 79 6e 63 2c  oint, then sync,
18ef0 20 74 68 65 6e 20 77 72 69 74 65 20 74 68 65 0a   then write the.
18f00 2a 2a 20 72 65 73 74 2e 0a 2a 2f 0a 73 74 61 74  ** rest..*/.stat
18f10 69 63 20 69 6e 74 20 77 61 6c 57 72 69 74 65 54  ic int walWriteT
18f20 6f 4c 6f 67 28 0a 20 20 57 61 6c 57 72 69 74 65  oLog(.  WalWrite
18f30 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20  r *p,           
18f40 20 20 20 2f 2a 20 57 41 4c 20 74 6f 20 77 72 69     /* WAL to wri
18f50 74 65 20 74 6f 20 2a 2f 0a 20 20 76 6f 69 64 20  te to */.  void 
18f60 2a 70 43 6f 6e 74 65 6e 74 2c 20 20 20 20 20 20  *pContent,      
18f70 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 6e 74        /* Content
18f80 20 74 6f 20 62 65 20 77 72 69 74 74 65 6e 20 2a   to be written *
18f90 2f 0a 20 20 69 6e 74 20 69 41 6d 74 2c 20 20 20  /.  int iAmt,   
18fa0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
18fb0 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
18fc0 73 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20  s to write */.  
18fd0 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f  sqlite3_int64 iO
18fe0 66 66 73 65 74 20 20 20 20 20 20 2f 2a 20 53 74  ffset      /* St
18ff0 61 72 74 20 77 72 69 74 69 6e 67 20 61 74 20 74  art writing at t
19000 68 69 73 20 6f 66 66 73 65 74 20 2a 2f 0a 29 7b  his offset */.){
19010 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28  .  int rc;.  if(
19020 20 69 4f 66 66 73 65 74 3c 70 2d 3e 69 53 79 6e   iOffset<p->iSyn
19030 63 50 6f 69 6e 74 20 26 26 20 69 4f 66 66 73 65  cPoint && iOffse
19040 74 2b 69 41 6d 74 3e 3d 70 2d 3e 69 53 79 6e 63  t+iAmt>=p->iSync
19050 50 6f 69 6e 74 20 29 7b 0a 20 20 20 20 69 6e 74  Point ){.    int
19060 20 69 46 69 72 73 74 41 6d 74 20 3d 20 28 69 6e   iFirstAmt = (in
19070 74 29 28 70 2d 3e 69 53 79 6e 63 50 6f 69 6e 74  t)(p->iSyncPoint
19080 20 2d 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20   - iOffset);.   
19090 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57   rc = sqlite3OsW
190a0 72 69 74 65 28 70 2d 3e 70 46 64 2c 20 70 43 6f  rite(p->pFd, pCo
190b0 6e 74 65 6e 74 2c 20 69 46 69 72 73 74 41 6d 74  ntent, iFirstAmt
190c0 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20  , iOffset);.    
190d0 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e 20  if( rc ) return 
190e0 72 63 3b 0a 20 20 20 20 69 4f 66 66 73 65 74 20  rc;.    iOffset 
190f0 2b 3d 20 69 46 69 72 73 74 41 6d 74 3b 0a 20 20  += iFirstAmt;.  
19100 20 20 69 41 6d 74 20 2d 3d 20 69 46 69 72 73 74    iAmt -= iFirst
19110 41 6d 74 3b 0a 20 20 20 20 70 43 6f 6e 74 65 6e  Amt;.    pConten
19120 74 20 3d 20 28 76 6f 69 64 2a 29 28 69 46 69 72  t = (void*)(iFir
19130 73 74 41 6d 74 20 2b 20 28 63 68 61 72 2a 29 70  stAmt + (char*)p
19140 43 6f 6e 74 65 6e 74 29 3b 0a 20 20 20 20 61 73  Content);.    as
19150 73 65 72 74 28 20 70 2d 3e 73 79 6e 63 46 6c 61  sert( p->syncFla
19160 67 73 20 26 20 28 53 51 4c 49 54 45 5f 53 59 4e  gs & (SQLITE_SYN
19170 43 5f 4e 4f 52 4d 41 4c 7c 53 51 4c 49 54 45 5f  C_NORMAL|SQLITE_
19180 53 59 4e 43 5f 46 55 4c 4c 29 20 29 3b 0a 20 20  SYNC_FULL) );.  
19190 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
191a0 53 79 6e 63 28 70 2d 3e 70 46 64 2c 20 70 2d 3e  Sync(p->pFd, p->
191b0 73 79 6e 63 46 6c 61 67 73 20 26 20 53 51 4c 49  syncFlags & SQLI
191c0 54 45 5f 53 59 4e 43 5f 4d 41 53 4b 29 3b 0a 20  TE_SYNC_MASK);. 
191d0 20 20 20 69 66 28 20 69 41 6d 74 3d 3d 30 20 7c     if( iAmt==0 |
191e0 7c 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63  | rc ) return rc
191f0 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c  ;.  }.  rc = sql
19200 69 74 65 33 4f 73 57 72 69 74 65 28 70 2d 3e 70  ite3OsWrite(p->p
19210 46 64 2c 20 70 43 6f 6e 74 65 6e 74 2c 20 69 41  Fd, pContent, iA
19220 6d 74 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  mt, iOffset);.  
19230 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
19240 0a 2a 2a 20 57 72 69 74 65 20 6f 75 74 20 61 20  .** Write out a 
19250 73 69 6e 67 6c 65 20 66 72 61 6d 65 20 6f 66 20  single frame of 
19260 74 68 65 20 57 41 4c 0a 2a 2f 0a 73 74 61 74 69  the WAL.*/.stati
19270 63 20 69 6e 74 20 77 61 6c 57 72 69 74 65 4f 6e  c int walWriteOn
19280 65 46 72 61 6d 65 28 0a 20 20 57 61 6c 57 72 69  eFrame(.  WalWri
19290 74 65 72 20 2a 70 2c 20 20 20 20 20 20 20 20 20  ter *p,         
192a0 20 20 20 20 20 20 2f 2a 20 57 68 65 72 65 20 74        /* Where t
192b0 6f 20 77 72 69 74 65 20 74 68 65 20 66 72 61 6d  o write the fram
192c0 65 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 50  e */.  PgHdr *pP
192d0 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  age,            
192e0 20 20 20 2f 2a 20 54 68 65 20 70 61 67 65 20 6f     /* The page o
192f0 66 20 74 68 65 20 66 72 61 6d 65 20 74 6f 20 62  f the frame to b
19300 65 20 77 72 69 74 74 65 6e 20 2a 2f 0a 20 20 69  e written */.  i
19310 6e 74 20 6e 54 72 75 6e 63 61 74 65 2c 20 20 20  nt nTruncate,   
19320 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
19330 65 20 63 6f 6d 6d 69 74 20 66 6c 61 67 2e 20 20  e commit flag.  
19340 55 73 75 61 6c 6c 79 20 30 2e 20 20 3e 30 20 66  Usually 0.  >0 f
19350 6f 72 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20 73  or commit */.  s
19360 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66  qlite3_int64 iOf
19370 66 73 65 74 20 20 20 20 20 20 20 2f 2a 20 42 79  fset       /* By
19380 74 65 20 6f 66 66 73 65 74 20 61 74 20 77 68 69  te offset at whi
19390 63 68 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 29  ch to write */.)
193a0 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  {.  int rc;     
193b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
193c0 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 63 6f      /* Result co
193d0 64 65 20 66 72 6f 6d 20 73 75 62 66 75 6e 63 74  de from subfunct
193e0 69 6f 6e 73 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  ions */.  void *
193f0 70 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20  pData;          
19400 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
19410 61 20 61 63 74 75 61 6c 6c 79 20 77 72 69 74 74  a actually writt
19420 65 6e 20 2a 2f 0a 20 20 75 38 20 61 46 72 61 6d  en */.  u8 aFram
19430 65 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  e[WAL_FRAME_HDRS
19440 49 5a 45 5d 3b 20 20 20 2f 2a 20 42 75 66 66 65  IZE];   /* Buffe
19450 72 20 74 6f 20 61 73 73 65 6d 62 6c 65 20 66 72  r to assemble fr
19460 61 6d 65 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f  ame-header in */
19470 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c  .#if defined(SQL
19480 49 54 45 5f 48 41 53 5f 43 4f 44 45 43 29 0a 20  ITE_HAS_CODEC). 
19490 20 69 66 28 20 28 70 44 61 74 61 20 3d 20 73 71   if( (pData = sq
194a0 6c 69 74 65 33 50 61 67 65 72 43 6f 64 65 63 28  lite3PagerCodec(
194b0 70 50 61 67 65 29 29 3d 3d 30 20 29 20 72 65 74  pPage))==0 ) ret
194c0 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
194d0 3b 0a 23 65 6c 73 65 0a 20 20 70 44 61 74 61 20  ;.#else.  pData 
194e0 3d 20 70 50 61 67 65 2d 3e 70 44 61 74 61 3b 0a  = pPage->pData;.
194f0 23 65 6e 64 69 66 0a 20 20 77 61 6c 45 6e 63 6f  #endif.  walEnco
19500 64 65 46 72 61 6d 65 28 70 2d 3e 70 57 61 6c 2c  deFrame(p->pWal,
19510 20 70 50 61 67 65 2d 3e 70 67 6e 6f 2c 20 6e 54   pPage->pgno, nT
19520 72 75 6e 63 61 74 65 2c 20 70 44 61 74 61 2c 20  runcate, pData, 
19530 61 46 72 61 6d 65 29 3b 0a 20 20 72 63 20 3d 20  aFrame);.  rc = 
19540 77 61 6c 57 72 69 74 65 54 6f 4c 6f 67 28 70 2c  walWriteToLog(p,
19550 20 61 46 72 61 6d 65 2c 20 73 69 7a 65 6f 66 28   aFrame, sizeof(
19560 61 46 72 61 6d 65 29 2c 20 69 4f 66 66 73 65 74  aFrame), iOffset
19570 29 3b 0a 20 20 69 66 28 20 72 63 20 29 20 72 65  );.  if( rc ) re
19580 74 75 72 6e 20 72 63 3b 0a 20 20 2f 2a 20 57 72  turn rc;.  /* Wr
19590 69 74 65 20 74 68 65 20 70 61 67 65 20 64 61 74  ite the page dat
195a0 61 20 2a 2f 0a 20 20 72 63 20 3d 20 77 61 6c 57  a */.  rc = walW
195b0 72 69 74 65 54 6f 4c 6f 67 28 70 2c 20 70 44 61  riteToLog(p, pDa
195c0 74 61 2c 20 70 2d 3e 73 7a 50 61 67 65 2c 20 69  ta, p->szPage, i
195d0 4f 66 66 73 65 74 2b 73 69 7a 65 6f 66 28 61 46  Offset+sizeof(aF
195e0 72 61 6d 65 29 29 3b 0a 20 20 72 65 74 75 72 6e  rame));.  return
195f0 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 57   rc;.}../* .** W
19600 72 69 74 65 20 61 20 73 65 74 20 6f 66 20 66 72  rite a set of fr
19610 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67 2e  ames to the log.
19620 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74   The caller must
19630 20 68 6f 6c 64 20 74 68 65 20 77 72 69 74 65 2d   hold the write-
19640 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20 6c  lock.** on the l
19650 6f 67 20 66 69 6c 65 20 28 6f 62 74 61 69 6e 65  og file (obtaine
19660 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 57  d using sqlite3W
19670 61 6c 42 65 67 69 6e 57 72 69 74 65 54 72 61 6e  alBeginWriteTran
19680 73 61 63 74 69 6f 6e 28 29 29 2e 0a 2a 2f 0a 69  saction())..*/.i
19690 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 46 72 61  nt sqlite3WalFra
196a0 6d 65 73 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c  mes(.  Wal *pWal
196b0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
196c0 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 68 61         /* Wal ha
196d0 6e 64 6c 65 20 74 6f 20 77 72 69 74 65 20 74 6f  ndle to write to
196e0 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65   */.  int szPage
196f0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
19700 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
19710 65 20 70 61 67 65 2d 73 69 7a 65 20 69 6e 20 62  e page-size in b
19720 79 74 65 73 20 2a 2f 0a 20 20 50 67 48 64 72 20  ytes */.  PgHdr 
19730 2a 70 4c 69 73 74 2c 20 20 20 20 20 20 20 20 20  *pList,         
19740 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73            /* Lis
19750 74 20 6f 66 20 64 69 72 74 79 20 70 61 67 65 73  t of dirty pages
19760 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 50   to write */.  P
19770 67 6e 6f 20 6e 54 72 75 6e 63 61 74 65 2c 20 20  gno nTruncate,  
19780 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
19790 2a 20 44 61 74 61 62 61 73 65 20 73 69 7a 65 20  * Database size 
197a0 61 66 74 65 72 20 74 68 69 73 20 63 6f 6d 6d 69  after this commi
197b0 74 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43 6f 6d  t */.  int isCom
197c0 6d 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  mit,            
197d0 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
197e0 66 20 74 68 69 73 20 69 73 20 61 20 63 6f 6d 6d  f this is a comm
197f0 69 74 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63  it */.  int sync
19800 5f 66 6c 61 67 73 20 20 20 20 20 20 20 20 20 20  _flags          
19810 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73          /* Flags
19820 20 74 6f 20 70 61 73 73 20 74 6f 20 4f 73 53 79   to pass to OsSy
19830 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 29  nc() (or 0) */.)
19840 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  {.  int rc;     
19850 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19860 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 63      /* Used to c
19870 61 74 63 68 20 72 65 74 75 72 6e 20 63 6f 64 65  atch return code
19880 73 20 2a 2f 0a 20 20 75 33 32 20 69 46 72 61 6d  s */.  u32 iFram
19890 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
198a0 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 66         /* Next f
198b0 72 61 6d 65 20 61 64 64 72 65 73 73 20 2a 2f 0a  rame address */.
198c0 20 20 50 67 48 64 72 20 2a 70 3b 20 20 20 20 20    PgHdr *p;     
198d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
198e0 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f    /* Iterator to
198f0 20 72 75 6e 20 74 68 72 6f 75 67 68 20 70 4c 69   run through pLi
19900 73 74 20 77 69 74 68 2e 20 2a 2f 0a 20 20 50 67  st with. */.  Pg
19910 48 64 72 20 2a 70 4c 61 73 74 20 3d 20 30 3b 20  Hdr *pLast = 0; 
19920 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
19930 20 4c 61 73 74 20 66 72 61 6d 65 20 69 6e 20 6c   Last frame in l
19940 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 45 78  ist */.  int nEx
19950 74 72 61 20 3d 20 30 3b 20 20 20 20 20 20 20 20  tra = 0;        
19960 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
19970 65 72 20 6f 66 20 65 78 74 72 61 20 63 6f 70 69  er of extra copi
19980 65 73 20 6f 66 20 6c 61 73 74 20 70 61 67 65 20  es of last page 
19990 2a 2f 0a 20 20 69 6e 74 20 73 7a 46 72 61 6d 65  */.  int szFrame
199a0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
199b0 20 20 20 20 20 2f 2a 20 54 68 65 20 73 69 7a 65       /* The size
199c0 20 6f 66 20 61 20 73 69 6e 67 6c 65 20 66 72 61   of a single fra
199d0 6d 65 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66  me */.  i64 iOff
199e0 73 65 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  set;            
199f0 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
19a00 62 79 74 65 20 74 6f 20 77 72 69 74 65 20 69 6e  byte to write in
19a10 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 57   WAL file */.  W
19a20 61 6c 57 72 69 74 65 72 20 77 3b 20 20 20 20 20  alWriter w;     
19a30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
19a40 2a 20 54 68 65 20 77 72 69 74 65 72 20 2a 2f 0a  * The writer */.
19a50 0a 20 20 61 73 73 65 72 74 28 20 70 4c 69 73 74  .  assert( pList
19a60 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57   );.  assert( pW
19a70 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
19a80 0a 0a 20 20 2f 2a 20 49 66 20 74 68 69 73 20 66  ..  /* If this f
19a90 72 61 6d 65 20 73 65 74 20 63 6f 6d 70 6c 65 74  rame set complet
19aa0 65 73 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e  es a transaction
19ab0 2c 20 74 68 65 6e 20 6e 54 72 75 6e 63 61 74 65  , then nTruncate
19ac0 3e 30 2e 20 20 49 66 0a 20 20 2a 2a 20 6e 54 72  >0.  If.  ** nTr
19ad0 75 6e 63 61 74 65 3d 3d 30 20 74 68 65 6e 20 74  uncate==0 then t
19ae0 68 69 73 20 66 72 61 6d 65 20 73 65 74 20 64 6f  his frame set do
19af0 65 73 20 6e 6f 74 20 63 6f 6d 70 6c 65 74 65 20  es not complete 
19b00 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e  the transaction.
19b10 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 28 69   */.  assert( (i
19b20 73 43 6f 6d 6d 69 74 21 3d 30 29 3d 3d 28 6e 54  sCommit!=0)==(nT
19b30 72 75 6e 63 61 74 65 21 3d 30 29 20 29 3b 0a 0a  runcate!=0) );..
19b40 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49  #if defined(SQLI
19b50 54 45 5f 54 45 53 54 29 20 26 26 20 64 65 66 69  TE_TEST) && defi
19b60 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42 55 47  ned(SQLITE_DEBUG
19b70 29 0a 20 20 7b 20 69 6e 74 20 63 6e 74 3b 20 66  ).  { int cnt; f
19b80 6f 72 28 63 6e 74 3d 30 2c 20 70 3d 70 4c 69 73  or(cnt=0, p=pLis
19b90 74 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74  t; p; p=p->pDirt
19ba0 79 2c 20 63 6e 74 2b 2b 29 7b 7d 0a 20 20 20 20  y, cnt++){}.    
19bb0 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70  WALTRACE(("WAL%p
19bc0 3a 20 66 72 61 6d 65 20 77 72 69 74 65 20 62 65  : frame write be
19bd0 67 69 6e 2e 20 25 64 20 66 72 61 6d 65 73 2e 20  gin. %d frames. 
19be0 6d 78 46 72 61 6d 65 3d 25 64 2e 20 25 73 5c 6e  mxFrame=%d. %s\n
19bf0 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ",.             
19c00 20 70 57 61 6c 2c 20 63 6e 74 2c 20 70 57 61 6c   pWal, cnt, pWal
19c10 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2c 20 69  ->hdr.mxFrame, i
19c20 73 43 6f 6d 6d 69 74 20 3f 20 22 43 6f 6d 6d 69  sCommit ? "Commi
19c30 74 22 20 3a 20 22 53 70 69 6c 6c 22 29 29 3b 0a  t" : "Spill"));.
19c40 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2f 2a    }.#endif..  /*
19c50 20 53 65 65 20 69 66 20 69 74 20 69 73 20 70 6f   See if it is po
19c60 73 73 69 62 6c 65 20 74 6f 20 77 72 69 74 65 20  ssible to write 
19c70 74 68 65 73 65 20 66 72 61 6d 65 73 20 69 6e 74  these frames int
19c80 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74  o the start of t
19c90 68 65 0a 20 20 2a 2a 20 6c 6f 67 20 66 69 6c 65  he.  ** log file
19ca0 2c 20 69 6e 73 74 65 61 64 20 6f 66 20 61 70 70  , instead of app
19cb0 65 6e 64 69 6e 67 20 74 6f 20 69 74 20 61 74 20  ending to it at 
19cc0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
19cd0 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 53 51  e..  */.  if( SQ
19ce0 4c 49 54 45 5f 4f 4b 21 3d 28 72 63 20 3d 20 77  LITE_OK!=(rc = w
19cf0 61 6c 52 65 73 74 61 72 74 4c 6f 67 28 70 57 61  alRestartLog(pWa
19d00 6c 29 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72  l)) ){.    retur
19d10 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  n rc;.  }..  /* 
19d20 49 66 20 74 68 69 73 20 69 73 20 74 68 65 20 66  If this is the f
19d30 69 72 73 74 20 66 72 61 6d 65 20 77 72 69 74 74  irst frame writt
19d40 65 6e 20 69 6e 74 6f 20 74 68 65 20 6c 6f 67 2c  en into the log,
19d50 20 77 72 69 74 65 20 74 68 65 20 57 41 4c 0a 20   write the WAL. 
19d60 20 2a 2a 20 68 65 61 64 65 72 20 74 6f 20 74 68   ** header to th
19d70 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 57  e start of the W
19d80 41 4c 20 66 69 6c 65 2e 20 53 65 65 20 63 6f 6d  AL file. See com
19d90 6d 65 6e 74 73 20 61 74 20 74 68 65 20 74 6f 70  ments at the top
19da0 20 6f 66 0a 20 20 2a 2a 20 74 68 69 73 20 73 6f   of.  ** this so
19db0 75 72 63 65 20 66 69 6c 65 20 66 6f 72 20 61 20  urce file for a 
19dc0 64 65 73 63 72 69 70 74 69 6f 6e 20 6f 66 20 74  description of t
19dd0 68 65 20 57 41 4c 20 68 65 61 64 65 72 20 66 6f  he WAL header fo
19de0 72 6d 61 74 2e 0a 20 20 2a 2f 0a 20 20 69 46 72  rmat..  */.  iFr
19df0 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  ame = pWal->hdr.
19e00 6d 78 46 72 61 6d 65 3b 0a 20 20 69 66 28 20 69  mxFrame;.  if( i
19e10 46 72 61 6d 65 3d 3d 30 20 29 7b 0a 20 20 20 20  Frame==0 ){.    
19e20 75 38 20 61 57 61 6c 48 64 72 5b 57 41 4c 5f 48  u8 aWalHdr[WAL_H
19e30 44 52 53 49 5a 45 5d 3b 20 20 20 20 20 20 2f 2a  DRSIZE];      /*
19e40 20 42 75 66 66 65 72 20 74 6f 20 61 73 73 65 6d   Buffer to assem
19e50 62 6c 65 20 77 61 6c 2d 68 65 61 64 65 72 20 69  ble wal-header i
19e60 6e 20 2a 2f 0a 20 20 20 20 75 33 32 20 61 43 6b  n */.    u32 aCk
19e70 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20  sum[2];         
19e80 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 73         /* Checks
19e90 75 6d 20 66 6f 72 20 77 61 6c 2d 68 65 61 64 65  um for wal-heade
19ea0 72 20 2a 2f 0a 0a 20 20 20 20 73 71 6c 69 74 65  r */..    sqlite
19eb0 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c 48  3Put4byte(&aWalH
19ec0 64 72 5b 30 5d 2c 20 28 57 41 4c 5f 4d 41 47 49  dr[0], (WAL_MAGI
19ed0 43 20 7c 20 53 51 4c 49 54 45 5f 42 49 47 45 4e  C | SQLITE_BIGEN
19ee0 44 49 41 4e 29 29 3b 0a 20 20 20 20 73 71 6c 69  DIAN));.    sqli
19ef0 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61  te3Put4byte(&aWa
19f00 6c 48 64 72 5b 34 5d 2c 20 57 41 4c 5f 4d 41 58  lHdr[4], WAL_MAX
19f10 5f 56 45 52 53 49 4f 4e 29 3b 0a 20 20 20 20 73  _VERSION);.    s
19f20 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
19f30 61 57 61 6c 48 64 72 5b 38 5d 2c 20 73 7a 50 61  aWalHdr[8], szPa
19f40 67 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ge);.    sqlite3
19f50 50 75 74 34 62 79 74 65 28 26 61 57 61 6c 48 64  Put4byte(&aWalHd
19f60 72 5b 31 32 5d 2c 20 70 57 61 6c 2d 3e 6e 43 6b  r[12], pWal->nCk
19f70 70 74 29 3b 0a 20 20 20 20 69 66 28 20 70 57 61  pt);.    if( pWa
19f80 6c 2d 3e 6e 43 6b 70 74 3d 3d 30 20 29 20 73 71  l->nCkpt==0 ) sq
19f90 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73  lite3_randomness
19fa0 28 38 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53  (8, pWal->hdr.aS
19fb0 61 6c 74 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79  alt);.    memcpy
19fc0 28 26 61 57 61 6c 48 64 72 5b 31 36 5d 2c 20 70  (&aWalHdr[16], p
19fd0 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20  Wal->hdr.aSalt, 
19fe0 38 29 3b 0a 20 20 20 20 77 61 6c 43 68 65 63 6b  8);.    walCheck
19ff0 73 75 6d 42 79 74 65 73 28 31 2c 20 61 57 61 6c  sumBytes(1, aWal
1a000 48 64 72 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45  Hdr, WAL_HDRSIZE
1a010 2d 32 2a 34 2c 20 30 2c 20 61 43 6b 73 75 6d 29  -2*4, 0, aCksum)
1a020 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74  ;.    sqlite3Put
1a030 34 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32  4byte(&aWalHdr[2
1a040 34 5d 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b 0a  4], aCksum[0]);.
1a050 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62      sqlite3Put4b
1a060 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32 38 5d  yte(&aWalHdr[28]
1a070 2c 20 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 20 20  , aCksum[1]);.  
1a080 20 20 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50    .    pWal->szP
1a090 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20  age = szPage;.  
1a0a0 20 20 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45    pWal->hdr.bigE
1a0b0 6e 64 43 6b 73 75 6d 20 3d 20 53 51 4c 49 54 45  ndCksum = SQLITE
1a0c0 5f 42 49 47 45 4e 44 49 41 4e 3b 0a 20 20 20 20  _BIGENDIAN;.    
1a0d0 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
1a0e0 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 43 6b 73 75  Cksum[0] = aCksu
1a0f0 6d 5b 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  m[0];.    pWal->
1a100 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
1a110 31 5d 20 3d 20 61 43 6b 73 75 6d 5b 31 5d 3b 0a  1] = aCksum[1];.
1a120 20 20 20 20 70 57 61 6c 2d 3e 74 72 75 6e 63 61      pWal->trunca
1a130 74 65 4f 6e 43 6f 6d 6d 69 74 20 3d 20 31 3b 0a  teOnCommit = 1;.
1a140 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
1a150 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70  3OsWrite(pWal->p
1a160 57 61 6c 46 64 2c 20 61 57 61 6c 48 64 72 2c 20  WalFd, aWalHdr, 
1a170 73 69 7a 65 6f 66 28 61 57 61 6c 48 64 72 29 2c  sizeof(aWalHdr),
1a180 20 30 29 3b 0a 20 20 20 20 57 41 4c 54 52 41 43   0);.    WALTRAC
1a190 45 28 28 22 57 41 4c 25 70 3a 20 77 61 6c 2d 68  E(("WAL%p: wal-h
1a1a0 65 61 64 65 72 20 77 72 69 74 65 20 25 73 5c 6e  eader write %s\n
1a1b0 22 2c 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66  ", pWal, rc ? "f
1a1c0 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b  ailed" : "ok"));
1a1d0 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
1a1e0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
1a1f0 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
1a200 0a 0a 20 20 20 20 2f 2a 20 53 79 6e 63 20 74 68  ..    /* Sync th
1a210 65 20 68 65 61 64 65 72 20 28 75 6e 6c 65 73 73  e header (unless
1a220 20 53 51 4c 49 54 45 5f 49 4f 43 41 50 5f 53 45   SQLITE_IOCAP_SE
1a230 51 55 45 4e 54 49 41 4c 20 69 73 20 74 72 75 65  QUENTIAL is true
1a240 20 6f 72 20 75 6e 6c 65 73 73 0a 20 20 20 20 2a   or unless.    *
1a250 2a 20 61 6c 6c 20 73 79 6e 63 69 6e 67 20 69 73  * all syncing is
1a260 20 74 75 72 6e 65 64 20 6f 66 66 20 62 79 20 50   turned off by P
1a270 52 41 47 4d 41 20 73 79 6e 63 68 72 6f 6e 6f 75  RAGMA synchronou
1a280 73 3d 4f 46 46 29 2e 20 20 4f 74 68 65 72 77 69  s=OFF).  Otherwi
1a290 73 65 0a 20 20 20 20 2a 2a 20 61 6e 20 6f 75 74  se.    ** an out
1a2a0 2d 6f 66 2d 6f 72 64 65 72 20 77 72 69 74 65 20  -of-order write 
1a2b0 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 57 41 4c 20  following a WAL 
1a2c0 72 65 73 74 61 72 74 20 63 6f 75 6c 64 20 72 65  restart could re
1a2d0 73 75 6c 74 20 69 6e 0a 20 20 20 20 2a 2a 20 64  sult in.    ** d
1a2e0 61 74 61 62 61 73 65 20 63 6f 72 72 75 70 74 69  atabase corrupti
1a2f0 6f 6e 2e 20 20 53 65 65 20 74 68 65 20 74 69 63  on.  See the tic
1a300 6b 65 74 3a 0a 20 20 20 20 2a 2a 0a 20 20 20 20  ket:.    **.    
1a310 2a 2a 20 20 20 20 20 68 74 74 70 3a 2f 2f 6c 6f  **     http://lo
1a320 63 61 6c 68 6f 73 74 3a 35 39 31 2f 73 71 6c 69  calhost:591/sqli
1a330 74 65 2f 69 6e 66 6f 2f 66 66 35 62 65 37 33 64  te/info/ff5be73d
1a340 65 65 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66  ee.    */.    if
1a350 28 20 70 57 61 6c 2d 3e 73 79 6e 63 48 65 61 64  ( pWal->syncHead
1a360 65 72 20 26 26 20 73 79 6e 63 5f 66 6c 61 67 73  er && sync_flags
1a370 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73   ){.      rc = s
1a380 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 70 57 61  qlite3OsSync(pWa
1a390 6c 2d 3e 70 57 61 6c 46 64 2c 20 73 79 6e 63 5f  l->pWalFd, sync_
1a3a0 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 53  flags & SQLITE_S
1a3b0 59 4e 43 5f 4d 41 53 4b 29 3b 0a 20 20 20 20 20  YNC_MASK);.     
1a3c0 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e   if( rc ) return
1a3d0 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20   rc;.    }.  }. 
1a3e0 20 61 73 73 65 72 74 28 20 28 69 6e 74 29 70 57   assert( (int)pW
1a3f0 61 6c 2d 3e 73 7a 50 61 67 65 3d 3d 73 7a 50 61  al->szPage==szPa
1a400 67 65 20 29 3b 0a 0a 20 20 2f 2a 20 53 65 74 75  ge );..  /* Setu
1a410 70 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6e 65  p information ne
1a420 65 64 65 64 20 74 6f 20 77 72 69 74 65 20 66 72  eded to write fr
1a430 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20 57 41  ames into the WA
1a440 4c 20 2a 2f 0a 20 20 77 2e 70 57 61 6c 20 3d 20  L */.  w.pWal = 
1a450 70 57 61 6c 3b 0a 20 20 77 2e 70 46 64 20 3d 20  pWal;.  w.pFd = 
1a460 70 57 61 6c 2d 3e 70 57 61 6c 46 64 3b 0a 20 20  pWal->pWalFd;.  
1a470 77 2e 69 53 79 6e 63 50 6f 69 6e 74 20 3d 20 30  w.iSyncPoint = 0
1a480 3b 0a 20 20 77 2e 73 79 6e 63 46 6c 61 67 73 20  ;.  w.syncFlags 
1a490 3d 20 73 79 6e 63 5f 66 6c 61 67 73 3b 0a 20 20  = sync_flags;.  
1a4a0 77 2e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67  w.szPage = szPag
1a4b0 65 3b 0a 20 20 69 4f 66 66 73 65 74 20 3d 20 77  e;.  iOffset = w
1a4c0 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46  alFrameOffset(iF
1a4d0 72 61 6d 65 2b 31 2c 20 73 7a 50 61 67 65 29 3b  rame+1, szPage);
1a4e0 0a 20 20 73 7a 46 72 61 6d 65 20 3d 20 73 7a 50  .  szFrame = szP
1a4f0 61 67 65 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  age + WAL_FRAME_
1a500 48 44 52 53 49 5a 45 3b 0a 0a 20 20 2f 2a 20 57  HDRSIZE;..  /* W
1a510 72 69 74 65 20 61 6c 6c 20 66 72 61 6d 65 73 20  rite all frames 
1a520 69 6e 74 6f 20 74 68 65 20 6c 6f 67 20 66 69 6c  into the log fil
1a530 65 20 65 78 61 63 74 6c 79 20 6f 6e 63 65 20 2a  e exactly once *
1a540 2f 0a 20 20 66 6f 72 28 70 3d 70 4c 69 73 74 3b  /.  for(p=pList;
1a550 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 29   p; p=p->pDirty)
1a560 7b 0a 20 20 20 20 69 6e 74 20 6e 44 62 53 69 7a  {.    int nDbSiz
1a570 65 3b 20 20 20 2f 2a 20 30 20 6e 6f 72 6d 61 6c  e;   /* 0 normal
1a580 6c 79 2e 20 20 50 6f 73 69 74 69 76 65 20 3d 3d  ly.  Positive ==
1a590 20 63 6f 6d 6d 69 74 20 66 6c 61 67 20 2a 2f 0a   commit flag */.
1a5a0 20 20 20 20 69 46 72 61 6d 65 2b 2b 3b 0a 20 20      iFrame++;.  
1a5b0 20 20 61 73 73 65 72 74 28 20 69 4f 66 66 73 65    assert( iOffse
1a5c0 74 3d 3d 77 61 6c 46 72 61 6d 65 4f 66 66 73 65  t==walFrameOffse
1a5d0 74 28 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65  t(iFrame, szPage
1a5e0 29 20 29 3b 0a 20 20 20 20 6e 44 62 53 69 7a 65  ) );.    nDbSize
1a5f0 20 3d 20 28 69 73 43 6f 6d 6d 69 74 20 26 26 20   = (isCommit && 
1a600 70 2d 3e 70 44 69 72 74 79 3d 3d 30 29 20 3f 20  p->pDirty==0) ? 
1a610 6e 54 72 75 6e 63 61 74 65 20 3a 20 30 3b 0a 20  nTruncate : 0;. 
1a620 20 20 20 72 63 20 3d 20 77 61 6c 57 72 69 74 65     rc = walWrite
1a630 4f 6e 65 46 72 61 6d 65 28 26 77 2c 20 70 2c 20  OneFrame(&w, p, 
1a640 6e 44 62 53 69 7a 65 2c 20 69 4f 66 66 73 65 74  nDbSize, iOffset
1a650 29 3b 0a 20 20 20 20 69 66 28 20 72 63 20 29 20  );.    if( rc ) 
1a660 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 70  return rc;.    p
1a670 4c 61 73 74 20 3d 20 70 3b 0a 20 20 20 20 69 4f  Last = p;.    iO
1a680 66 66 73 65 74 20 2b 3d 20 73 7a 46 72 61 6d 65  ffset += szFrame
1a690 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74  ;.  }..  /* If t
1a6a0 68 69 73 20 69 73 20 74 68 65 20 65 6e 64 20 6f  his is the end o
1a6b0 66 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c  f a transaction,
1a6c0 20 74 68 65 6e 20 77 65 20 6d 69 67 68 74 20 6e   then we might n
1a6d0 65 65 64 20 74 6f 20 70 61 64 0a 20 20 2a 2a 20  eed to pad.  ** 
1a6e0 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  the transaction 
1a6f0 61 6e 64 2f 6f 72 20 73 79 6e 63 20 74 68 65 20  and/or sync the 
1a700 57 41 4c 20 66 69 6c 65 2e 0a 20 20 2a 2a 0a 20  WAL file..  **. 
1a710 20 2a 2a 20 50 61 64 64 69 6e 67 20 61 6e 64 20   ** Padding and 
1a720 73 79 6e 63 69 6e 67 20 6f 6e 6c 79 20 6f 63 63  syncing only occ
1a730 75 72 20 69 66 20 74 68 69 73 20 73 65 74 20 6f  ur if this set o
1a740 66 20 66 72 61 6d 65 73 20 63 6f 6d 70 6c 65 74  f frames complet
1a750 65 20 61 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63  e a.  ** transac
1a760 74 69 6f 6e 20 61 6e 64 20 69 66 20 50 52 41 47  tion and if PRAG
1a770 4d 41 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 46  MA synchronous=F
1a780 55 4c 4c 2e 20 20 49 66 20 73 79 6e 63 68 72 6f  ULL.  If synchro
1a790 6e 6f 75 73 3d 3d 4e 4f 52 4d 41 4c 0a 20 20 2a  nous==NORMAL.  *
1a7a0 2a 20 6f 72 20 73 79 6e 63 68 6f 6e 6f 75 73 3d  * or synchonous=
1a7b0 3d 4f 46 46 2c 20 74 68 65 6e 20 6e 6f 20 70 61  =OFF, then no pa
1a7c0 64 64 69 6e 67 20 6f 72 20 73 79 6e 63 69 6e 67  dding or syncing
1a7d0 20 61 72 65 20 6e 65 65 64 65 64 2e 0a 20 20 2a   are needed..  *
1a7e0 2a 0a 20 20 2a 2a 20 49 66 20 53 51 4c 49 54 45  *.  ** If SQLITE
1a7f0 5f 49 4f 43 41 50 5f 50 4f 57 45 52 53 41 46 45  _IOCAP_POWERSAFE
1a800 5f 4f 56 45 52 57 52 49 54 45 20 69 73 20 64 65  _OVERWRITE is de
1a810 66 69 6e 65 64 2c 20 74 68 65 6e 20 70 61 64 64  fined, then padd
1a820 69 6e 67 20 69 73 20 6e 6f 74 0a 20 20 2a 2a 20  ing is not.  ** 
1a830 6e 65 65 64 65 64 20 61 6e 64 20 6f 6e 6c 79 20  needed and only 
1a840 74 68 65 20 73 79 6e 63 20 69 73 20 64 6f 6e 65  the sync is done
1a850 2e 20 20 49 66 20 70 61 64 64 69 6e 67 20 69 73  .  If padding is
1a860 20 6e 65 65 64 65 64 2c 20 74 68 65 6e 20 74 68   needed, then th
1a870 65 0a 20 20 2a 2a 20 66 69 6e 61 6c 20 66 72 61  e.  ** final fra
1a880 6d 65 20 69 73 20 72 65 70 65 61 74 65 64 20 28  me is repeated (
1a890 77 69 74 68 20 69 74 73 20 63 6f 6d 6d 69 74 20  with its commit 
1a8a0 6d 61 72 6b 29 20 75 6e 74 69 6c 20 74 68 65 20  mark) until the 
1a8b0 6e 65 78 74 20 73 65 63 74 6f 72 0a 20 20 2a 2a  next sector.  **
1a8c0 20 62 6f 75 6e 64 61 72 79 20 69 73 20 63 72 6f   boundary is cro
1a8d0 73 73 65 64 2e 20 20 4f 6e 6c 79 20 74 68 65 20  ssed.  Only the 
1a8e0 70 61 72 74 20 6f 66 20 74 68 65 20 57 41 4c 20  part of the WAL 
1a8f0 70 72 69 6f 72 20 74 6f 20 74 68 65 20 6c 61 73  prior to the las
1a900 74 0a 20 20 2a 2a 20 73 65 63 74 6f 72 20 62 6f  t.  ** sector bo
1a910 75 6e 64 61 72 79 20 69 73 20 73 79 6e 63 65 64  undary is synced
1a920 3b 20 74 68 65 20 70 61 72 74 20 6f 66 20 74 68  ; the part of th
1a930 65 20 6c 61 73 74 20 66 72 61 6d 65 20 74 68 61  e last frame tha
1a940 74 20 65 78 74 65 6e 64 73 0a 20 20 2a 2a 20 70  t extends.  ** p
1a950 61 73 74 20 74 68 65 20 73 65 63 74 6f 72 20 62  ast the sector b
1a960 6f 75 6e 64 61 72 79 20 69 73 20 77 72 69 74 74  oundary is writt
1a970 65 6e 20 61 66 74 65 72 20 74 68 65 20 73 79 6e  en after the syn
1a980 63 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69 73  c..  */.  if( is
1a990 43 6f 6d 6d 69 74 20 26 26 20 28 73 79 6e 63 5f  Commit && (sync_
1a9a0 66 6c 61 67 73 20 26 20 57 41 4c 5f 53 59 4e 43  flags & WAL_SYNC
1a9b0 5f 54 52 41 4e 53 41 43 54 49 4f 4e 53 29 21 3d  _TRANSACTIONS)!=
1a9c0 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57 61  0 ){.    if( pWa
1a9d0 6c 2d 3e 70 61 64 54 6f 53 65 63 74 6f 72 42 6f  l->padToSectorBo
1a9e0 75 6e 64 61 72 79 20 29 7b 0a 20 20 20 20 20 20  undary ){.      
1a9f0 69 6e 74 20 73 65 63 74 6f 72 53 69 7a 65 20 3d  int sectorSize =
1aa00 20 73 71 6c 69 74 65 33 53 65 63 74 6f 72 53 69   sqlite3SectorSi
1aa10 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 29  ze(pWal->pWalFd)
1aa20 3b 0a 20 20 20 20 20 20 77 2e 69 53 79 6e 63 50  ;.      w.iSyncP
1aa30 6f 69 6e 74 20 3d 20 28 28 69 4f 66 66 73 65 74  oint = ((iOffset
1aa40 2b 73 65 63 74 6f 72 53 69 7a 65 2d 31 29 2f 73  +sectorSize-1)/s
1aa50 65 63 74 6f 72 53 69 7a 65 29 2a 73 65 63 74 6f  ectorSize)*secto
1aa60 72 53 69 7a 65 3b 0a 20 20 20 20 20 20 77 68 69  rSize;.      whi
1aa70 6c 65 28 20 69 4f 66 66 73 65 74 3c 77 2e 69 53  le( iOffset<w.iS
1aa80 79 6e 63 50 6f 69 6e 74 20 29 7b 0a 20 20 20 20  yncPoint ){.    
1aa90 20 20 20 20 72 63 20 3d 20 77 61 6c 57 72 69 74      rc = walWrit
1aaa0 65 4f 6e 65 46 72 61 6d 65 28 26 77 2c 20 70 4c  eOneFrame(&w, pL
1aab0 61 73 74 2c 20 6e 54 72 75 6e 63 61 74 65 2c 20  ast, nTruncate, 
1aac0 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20  iOffset);.      
1aad0 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72    if( rc ) retur
1aae0 6e 20 72 63 3b 0a 20 20 20 20 20 20 20 20 69 4f  n rc;.        iO
1aaf0 66 66 73 65 74 20 2b 3d 20 73 7a 46 72 61 6d 65  ffset += szFrame
1ab00 3b 0a 20 20 20 20 20 20 20 20 6e 45 78 74 72 61  ;.        nExtra
1ab10 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ++;.      }.    
1ab20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20  }else{.      rc 
1ab30 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28  = sqlite3OsSync(
1ab40 77 2e 70 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67  w.pFd, sync_flag
1ab50 73 20 26 20 53 51 4c 49 54 45 5f 53 59 4e 43 5f  s & SQLITE_SYNC_
1ab60 4d 41 53 4b 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  MASK);.    }.  }
1ab70 0a 0a 20 20 2f 2a 20 49 66 20 74 68 69 73 20 66  ..  /* If this f
1ab80 72 61 6d 65 20 73 65 74 20 63 6f 6d 70 6c 65 74  rame set complet
1ab90 65 73 20 74 68 65 20 66 69 72 73 74 20 74 72 61  es the first tra
1aba0 6e 73 61 63 74 69 6f 6e 20 69 6e 20 74 68 65 20  nsaction in the 
1abb0 57 41 4c 20 61 6e 64 0a 20 20 2a 2a 20 69 66 20  WAL and.  ** if 
1abc0 50 52 41 47 4d 41 20 6a 6f 75 72 6e 61 6c 5f 73  PRAGMA journal_s
1abd0 69 7a 65 5f 6c 69 6d 69 74 20 69 73 20 73 65 74  ize_limit is set
1abe0 2c 20 74 68 65 6e 20 74 72 75 6e 63 61 74 65 20  , then truncate 
1abf0 74 68 65 20 57 41 4c 20 74 6f 20 74 68 65 0a 20  the WAL to the. 
1ac00 20 2a 2a 20 6a 6f 75 72 6e 61 6c 20 73 69 7a 65   ** journal size
1ac10 20 6c 69 6d 69 74 2c 20 69 66 20 70 6f 73 73 69   limit, if possi
1ac20 62 6c 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  ble..  */.  if( 
1ac30 69 73 43 6f 6d 6d 69 74 20 26 26 20 70 57 61 6c  isCommit && pWal
1ac40 2d 3e 74 72 75 6e 63 61 74 65 4f 6e 43 6f 6d 6d  ->truncateOnComm
1ac50 69 74 20 26 26 20 70 57 61 6c 2d 3e 6d 78 57 61  it && pWal->mxWa
1ac60 6c 53 69 7a 65 3e 3d 30 20 29 7b 0a 20 20 20 20  lSize>=0 ){.    
1ac70 69 36 34 20 73 7a 20 3d 20 70 57 61 6c 2d 3e 6d  i64 sz = pWal->m
1ac80 78 57 61 6c 53 69 7a 65 3b 0a 20 20 20 20 69 66  xWalSize;.    if
1ac90 28 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74  ( walFrameOffset
1aca0 28 69 46 72 61 6d 65 2b 6e 45 78 74 72 61 2b 31  (iFrame+nExtra+1
1acb0 2c 20 73 7a 50 61 67 65 29 3e 70 57 61 6c 2d 3e  , szPage)>pWal->
1acc0 6d 78 57 61 6c 53 69 7a 65 20 29 7b 0a 20 20 20  mxWalSize ){.   
1acd0 20 20 20 73 7a 20 3d 20 77 61 6c 46 72 61 6d 65     sz = walFrame
1ace0 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2b 6e 45  Offset(iFrame+nE
1acf0 78 74 72 61 2b 31 2c 20 73 7a 50 61 67 65 29 3b  xtra+1, szPage);
1ad00 0a 20 20 20 20 7d 0a 20 20 20 20 77 61 6c 4c 69  .    }.    walLi
1ad10 6d 69 74 53 69 7a 65 28 70 57 61 6c 2c 20 73 7a  mitSize(pWal, sz
1ad20 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 74 72 75  );.    pWal->tru
1ad30 6e 63 61 74 65 4f 6e 43 6f 6d 6d 69 74 20 3d 20  ncateOnCommit = 
1ad40 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 70 70  0;.  }..  /* App
1ad50 65 6e 64 20 64 61 74 61 20 74 6f 20 74 68 65 20  end data to the 
1ad60 77 61 6c 2d 69 6e 64 65 78 2e 20 49 74 20 69 73  wal-index. It is
1ad70 20 6e 6f 74 20 6e 65 63 65 73 73 61 72 79 20 74   not necessary t
1ad80 6f 20 6c 6f 63 6b 20 74 68 65 20 0a 20 20 2a 2a  o lock the .  **
1ad90 20 77 61 6c 2d 69 6e 64 65 78 20 74 6f 20 64 6f   wal-index to do
1ada0 20 74 68 69 73 20 61 73 20 74 68 65 20 53 51 4c   this as the SQL
1adb0 49 54 45 5f 53 48 4d 5f 57 52 49 54 45 20 6c 6f  ITE_SHM_WRITE lo
1adc0 63 6b 20 68 65 6c 64 20 6f 6e 20 74 68 65 20 77  ck held on the w
1add0 61 6c 2d 69 6e 64 65 78 0a 20 20 2a 2a 20 67 75  al-index.  ** gu
1ade0 61 72 61 6e 74 65 65 73 20 74 68 61 74 20 74 68  arantees that th
1adf0 65 72 65 20 61 72 65 20 6e 6f 20 6f 74 68 65 72  ere are no other
1ae00 20 77 72 69 74 65 72 73 2c 20 61 6e 64 20 6e 6f   writers, and no
1ae10 20 64 61 74 61 20 74 68 61 74 20 6d 61 79 0a 20   data that may. 
1ae20 20 2a 2a 20 62 65 20 69 6e 20 75 73 65 20 62 79   ** be in use by
1ae30 20 65 78 69 73 74 69 6e 67 20 72 65 61 64 65 72   existing reader
1ae40 73 20 69 73 20 62 65 69 6e 67 20 6f 76 65 72 77  s is being overw
1ae50 72 69 74 74 65 6e 2e 0a 20 20 2a 2f 0a 20 20 69  ritten..  */.  i
1ae60 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64  Frame = pWal->hd
1ae70 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 66 6f 72  r.mxFrame;.  for
1ae80 28 70 3d 70 4c 69 73 74 3b 20 70 20 26 26 20 72  (p=pList; p && r
1ae90 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 70 3d  c==SQLITE_OK; p=
1aea0 70 2d 3e 70 44 69 72 74 79 29 7b 0a 20 20 20 20  p->pDirty){.    
1aeb0 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 72 63  iFrame++;.    rc
1aec0 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e   = walIndexAppen
1aed0 64 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c 20  d(pWal, iFrame, 
1aee0 70 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 20 20  p->pgno);.  }.  
1aef0 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54  while( rc==SQLIT
1af00 45 5f 4f 4b 20 26 26 20 6e 45 78 74 72 61 3e 30  E_OK && nExtra>0
1af10 20 29 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b 2b   ){.    iFrame++
1af20 3b 0a 20 20 20 20 6e 45 78 74 72 61 2d 2d 3b 0a  ;.    nExtra--;.
1af30 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65      rc = walInde
1af40 78 41 70 70 65 6e 64 28 70 57 61 6c 2c 20 69 46  xAppend(pWal, iF
1af50 72 61 6d 65 2c 20 70 4c 61 73 74 2d 3e 70 67 6e  rame, pLast->pgn
1af60 6f 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72  o);.  }..  if( r
1af70 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
1af80 20 20 20 20 2f 2a 20 55 70 64 61 74 65 20 74 68      /* Update th
1af90 65 20 70 72 69 76 61 74 65 20 63 6f 70 79 20 6f  e private copy o
1afa0 66 20 74 68 65 20 68 65 61 64 65 72 2e 20 2a 2f  f the header. */
1afb0 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 73  .    pWal->hdr.s
1afc0 7a 50 61 67 65 20 3d 20 28 75 31 36 29 28 28 73  zPage = (u16)((s
1afd0 7a 50 61 67 65 26 30 78 66 66 30 30 29 20 7c 20  zPage&0xff00) | 
1afe0 28 73 7a 50 61 67 65 3e 3e 31 36 29 29 3b 0a 20  (szPage>>16));. 
1aff0 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50     testcase( szP
1b000 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20  age<=32768 );.  
1b010 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50 61    testcase( szPa
1b020 67 65 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 20  ge>=65536 );.   
1b030 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
1b040 6d 65 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20  me = iFrame;.   
1b050 20 69 66 28 20 69 73 43 6f 6d 6d 69 74 20 29 7b   if( isCommit ){
1b060 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  .      pWal->hdr
1b070 2e 69 43 68 61 6e 67 65 2b 2b 3b 0a 20 20 20 20  .iChange++;.    
1b080 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67    pWal->hdr.nPag
1b090 65 20 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a 20  e = nTruncate;. 
1b0a0 20 20 20 7d 0a 20 20 20 20 2f 2a 20 49 66 20 74     }.    /* If t
1b0b0 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 2c  his is a commit,
1b0c0 20 75 70 64 61 74 65 20 74 68 65 20 77 61 6c 2d   update the wal-
1b0d0 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f 6f  index header too
1b0e0 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 69 73 43  . */.    if( isC
1b0f0 6f 6d 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 77  ommit ){.      w
1b100 61 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72 28  alIndexWriteHdr(
1b110 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 70 57 61  pWal);.      pWa
1b120 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20 69  l->iCallback = i
1b130 46 72 61 6d 65 3b 0a 20 20 20 20 7d 0a 20 20 7d  Frame;.    }.  }
1b140 0a 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ..  WALTRACE(("W
1b150 41 4c 25 70 3a 20 66 72 61 6d 65 20 77 72 69 74  AL%p: frame writ
1b160 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  e %s\n", pWal, r
1b170 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
1b180 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75 72 6e 20  ok"));.  return 
1b190 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68  rc;.}../* .** Th
1b1a0 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61  is routine is ca
1b1b0 6c 6c 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e  lled to implemen
1b1c0 74 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68  t sqlite3_wal_ch
1b1d0 65 63 6b 70 6f 69 6e 74 28 29 20 61 6e 64 0a 2a  eckpoint() and.*
1b1e0 2a 20 72 65 6c 61 74 65 64 20 69 6e 74 65 72 66  * related interf
1b1f0 61 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74 61  aces..**.** Obta
1b200 69 6e 20 61 20 43 48 45 43 4b 50 4f 49 4e 54 20  in a CHECKPOINT 
1b210 6c 6f 63 6b 20 61 6e 64 20 74 68 65 6e 20 62 61  lock and then ba
1b220 63 6b 66 69 6c 6c 20 61 73 20 6d 75 63 68 20 69  ckfill as much i
1b230 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 73 0a 2a 2a  nformation as.**
1b240 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 57 41 4c   we can from WAL
1b250 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
1b260 73 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70 61 72  se..**.** If par
1b270 61 6d 65 74 65 72 20 78 42 75 73 79 20 69 73 20  ameter xBusy is 
1b280 6e 6f 74 20 4e 55 4c 4c 2c 20 69 74 20 69 73 20  not NULL, it is 
1b290 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 62  a pointer to a b
1b2a0 75 73 79 2d 68 61 6e 64 6c 65 72 0a 2a 2a 20 63  usy-handler.** c
1b2b0 61 6c 6c 62 61 63 6b 2e 20 49 6e 20 74 68 69 73  allback. In this
1b2c0 20 63 61 73 65 20 74 68 69 73 20 66 75 6e 63 74   case this funct
1b2d0 69 6f 6e 20 72 75 6e 73 20 61 20 62 6c 6f 63 6b  ion runs a block
1b2e0 69 6e 67 20 63 68 65 63 6b 70 6f 69 6e 74 2e 0a  ing checkpoint..
1b2f0 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
1b300 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a 20 20 57  lCheckpoint(.  W
1b310 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20  al *pWal,       
1b320 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b330 2a 20 57 61 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e  * Wal connection
1b340 20 2a 2f 0a 20 20 69 6e 74 20 65 4d 6f 64 65 2c   */.  int eMode,
1b350 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b360 20 20 20 20 20 20 2f 2a 20 50 41 53 53 49 56 45        /* PASSIVE
1b370 2c 20 46 55 4c 4c 20 6f 72 20 52 45 53 54 41 52  , FULL or RESTAR
1b380 54 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 42 75  T */.  int (*xBu
1b390 73 79 29 28 76 6f 69 64 2a 29 2c 20 20 20 20 20  sy)(void*),     
1b3a0 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69         /* Functi
1b3b0 6f 6e 20 74 6f 20 63 61 6c 6c 20 77 68 65 6e 20  on to call when 
1b3c0 62 75 73 79 20 2a 2f 0a 20 20 76 6f 69 64 20 2a  busy */.  void *
1b3d0 70 42 75 73 79 41 72 67 2c 20 20 20 20 20 20 20  pBusyArg,       
1b3e0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e            /* Con
1b3f0 74 65 78 74 20 61 72 67 75 6d 65 6e 74 20 66 6f  text argument fo
1b400 72 20 78 42 75 73 79 48 61 6e 64 6c 65 72 20 2a  r xBusyHandler *
1b410 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61  /.  int sync_fla
1b420 67 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  gs,             
1b430 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20      /* Flags to 
1b440 73 79 6e 63 20 64 62 20 66 69 6c 65 20 77 69 74  sync db file wit
1b450 68 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20 69 6e  h (or 0) */.  in
1b460 74 20 6e 42 75 66 2c 20 20 20 20 20 20 20 20 20  t nBuf,         
1b470 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1b480 20 53 69 7a 65 20 6f 66 20 74 65 6d 70 6f 72 61   Size of tempora
1b490 72 79 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 75  ry buffer */.  u
1b4a0 38 20 2a 7a 42 75 66 2c 20 20 20 20 20 20 20 20  8 *zBuf,        
1b4b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b4c0 2a 20 54 65 6d 70 6f 72 61 72 79 20 62 75 66 66  * Temporary buff
1b4d0 65 72 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20 69  er to use */.  i
1b4e0 6e 74 20 2a 70 6e 4c 6f 67 2c 20 20 20 20 20 20  nt *pnLog,      
1b4f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1b500 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66  * OUT: Number of
1b510 20 66 72 61 6d 65 73 20 69 6e 20 57 41 4c 20 2a   frames in WAL *
1b520 2f 0a 20 20 69 6e 74 20 2a 70 6e 43 6b 70 74 20  /.  int *pnCkpt 
1b530 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b540 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62      /* OUT: Numb
1b550 65 72 20 6f 66 20 62 61 63 6b 66 69 6c 6c 65 64  er of backfilled
1b560 20 66 72 61 6d 65 73 20 69 6e 20 57 41 4c 20 2a   frames in WAL *
1b570 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20  /.){.  int rc;  
1b580 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1b590 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
1b5a0 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69   code */.  int i
1b5b0 73 43 68 61 6e 67 65 64 20 3d 20 30 3b 20 20 20  sChanged = 0;   
1b5c0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
1b5d0 75 65 20 69 66 20 61 20 6e 65 77 20 77 61 6c 2d  ue if a new wal-
1b5e0 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20  index header is 
1b5f0 6c 6f 61 64 65 64 20 2a 2f 0a 20 20 69 6e 74 20  loaded */.  int 
1b600 65 4d 6f 64 65 32 20 3d 20 65 4d 6f 64 65 3b 20  eMode2 = eMode; 
1b610 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
1b620 6f 64 65 20 74 6f 20 70 61 73 73 20 74 6f 20 77  ode to pass to w
1b630 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 29 20 2a  alCheckpoint() *
1b640 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  /..  assert( pWa
1b650 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 30 20 29  l->ckptLock==0 )
1b660 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ;.  assert( pWal
1b670 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29  ->writeLock==0 )
1b680 3b 0a 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 72  ;..  if( pWal->r
1b690 65 61 64 4f 6e 6c 79 20 29 20 72 65 74 75 72 6e  eadOnly ) return
1b6a0 20 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59   SQLITE_READONLY
1b6b0 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
1b6c0 41 4c 25 70 3a 20 63 68 65 63 6b 70 6f 69 6e 74  AL%p: checkpoint
1b6d0 20 62 65 67 69 6e 73 5c 6e 22 2c 20 70 57 61 6c   begins\n", pWal
1b6e0 29 29 3b 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f  ));.  rc = walLo
1b6f0 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
1b700 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c  , WAL_CKPT_LOCK,
1b710 20 31 29 3b 0a 20 20 69 66 28 20 72 63 20 29 7b   1);.  if( rc ){
1b720 0a 20 20 20 20 2f 2a 20 55 73 75 61 6c 6c 79 20  .    /* Usually 
1b730 74 68 69 73 20 69 73 20 53 51 4c 49 54 45 5f 42  this is SQLITE_B
1b740 55 53 59 20 6d 65 61 6e 69 6e 67 20 74 68 61 74  USY meaning that
1b750 20 61 6e 6f 74 68 65 72 20 74 68 72 65 61 64 20   another thread 
1b760 6f 72 20 70 72 6f 63 65 73 73 0a 20 20 20 20 2a  or process.    *
1b770 2a 20 69 73 20 61 6c 72 65 61 64 79 20 72 75 6e  * is already run
1b780 6e 69 6e 67 20 61 20 63 68 65 63 6b 70 6f 69 6e  ning a checkpoin
1b790 74 2c 20 6f 72 20 6d 61 79 62 65 20 61 20 72 65  t, or maybe a re
1b7a0 63 6f 76 65 72 79 2e 20 20 42 75 74 20 69 74 20  covery.  But it 
1b7b0 6d 69 67 68 74 0a 20 20 20 20 2a 2a 20 61 6c 73  might.    ** als
1b7c0 6f 20 62 65 20 53 51 4c 49 54 45 5f 49 4f 45 52  o be SQLITE_IOER
1b7d0 52 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e  R. */.    return
1b7e0 20 72 63 3b 0a 20 20 7d 0a 20 20 70 57 61 6c 2d   rc;.  }.  pWal-
1b7f0 3e 63 6b 70 74 4c 6f 63 6b 20 3d 20 31 3b 0a 0a  >ckptLock = 1;..
1b800 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20    /* If this is 
1b810 61 20 62 6c 6f 63 6b 69 6e 67 2d 63 68 65 63 6b  a blocking-check
1b820 70 6f 69 6e 74 2c 20 74 68 65 6e 20 6f 62 74 61  point, then obta
1b830 69 6e 20 74 68 65 20 77 72 69 74 65 2d 6c 6f 63  in the write-loc
1b840 6b 20 61 73 20 77 65 6c 6c 0a 20 20 2a 2a 20 74  k as well.  ** t
1b850 6f 20 70 72 65 76 65 6e 74 20 61 6e 79 20 77 72  o prevent any wr
1b860 69 74 65 72 73 20 66 72 6f 6d 20 72 75 6e 6e 69  iters from runni
1b870 6e 67 20 77 68 69 6c 65 20 74 68 65 20 63 68 65  ng while the che
1b880 63 6b 70 6f 69 6e 74 20 69 73 20 75 6e 64 65 72  ckpoint is under
1b890 77 61 79 2e 0a 20 20 2a 2a 20 54 68 69 73 20 68  way..  ** This h
1b8a0 61 73 20 74 6f 20 62 65 20 64 6f 6e 65 20 62 65  as to be done be
1b8b0 66 6f 72 65 20 74 68 65 20 63 61 6c 6c 20 74 6f  fore the call to
1b8c0 20 77 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72   walIndexReadHdr
1b8d0 28 29 20 62 65 6c 6f 77 2e 0a 20 20 2a 2a 0a 20  () below..  **. 
1b8e0 20 2a 2a 20 49 66 20 74 68 65 20 77 72 69 74 65   ** If the write
1b8f0 72 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62 65  r lock cannot be
1b900 20 6f 62 74 61 69 6e 65 64 2c 20 74 68 65 6e 20   obtained, then 
1b910 61 20 70 61 73 73 69 76 65 20 63 68 65 63 6b 70  a passive checkp
1b920 6f 69 6e 74 20 69 73 0a 20 20 2a 2a 20 72 75 6e  oint is.  ** run
1b930 20 69 6e 73 74 65 61 64 2e 20 53 69 6e 63 65 20   instead. Since 
1b940 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 65 72  the checkpointer
1b950 20 69 73 20 6e 6f 74 20 68 6f 6c 64 69 6e 67 20   is not holding 
1b960 74 68 65 20 77 72 69 74 65 72 20 6c 6f 63 6b 2c  the writer lock,
1b970 0a 20 20 2a 2a 20 74 68 65 72 65 20 69 73 20 6e  .  ** there is n
1b980 6f 20 70 6f 69 6e 74 20 69 6e 20 62 6c 6f 63 6b  o point in block
1b990 69 6e 67 20 77 61 69 74 69 6e 67 20 66 6f 72 20  ing waiting for 
1b9a0 61 6e 79 20 72 65 61 64 65 72 73 2e 20 41 73 73  any readers. Ass
1b9b0 75 6d 69 6e 67 20 6e 6f 20 0a 20 20 2a 2a 20 6f  uming no .  ** o
1b9c0 74 68 65 72 20 65 72 72 6f 72 20 6f 63 63 75 72  ther error occur
1b9d0 73 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  s, this function
1b9e0 20 77 69 6c 6c 20 72 65 74 75 72 6e 20 53 51 4c   will return SQL
1b9f0 49 54 45 5f 42 55 53 59 20 74 6f 20 74 68 65 20  ITE_BUSY to the 
1ba00 63 61 6c 6c 65 72 2e 0a 20 20 2a 2f 0a 20 20 69  caller..  */.  i
1ba10 66 28 20 65 4d 6f 64 65 21 3d 53 51 4c 49 54 45  f( eMode!=SQLITE
1ba20 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53  _CHECKPOINT_PASS
1ba30 49 56 45 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  IVE ){.    rc = 
1ba40 77 61 6c 42 75 73 79 4c 6f 63 6b 28 70 57 61 6c  walBusyLock(pWal
1ba50 2c 20 78 42 75 73 79 2c 20 70 42 75 73 79 41 72  , xBusy, pBusyAr
1ba60 67 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43  g, WAL_WRITE_LOC
1ba70 4b 2c 20 31 29 3b 0a 20 20 20 20 69 66 28 20 72  K, 1);.    if( r
1ba80 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
1ba90 20 20 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74        pWal->writ
1baa0 65 4c 6f 63 6b 20 3d 20 31 3b 0a 20 20 20 20 7d  eLock = 1;.    }
1bab0 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c  else if( rc==SQL
1bac0 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20  ITE_BUSY ){.    
1bad0 20 20 65 4d 6f 64 65 32 20 3d 20 53 51 4c 49 54    eMode2 = SQLIT
1bae0 45 5f 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53  E_CHECKPOINT_PAS
1baf0 53 49 56 45 3b 0a 20 20 20 20 20 20 72 63 20 3d  SIVE;.      rc =
1bb00 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20   SQLITE_OK;.    
1bb10 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 61 64  }.  }..  /* Read
1bb20 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
1bb30 65 61 64 65 72 2e 20 2a 2f 0a 20 20 69 66 28 20  eader. */.  if( 
1bb40 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1bb50 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64  .    rc = walInd
1bb60 65 78 52 65 61 64 48 64 72 28 70 57 61 6c 2c 20  exReadHdr(pWal, 
1bb70 26 69 73 43 68 61 6e 67 65 64 29 3b 0a 20 20 20  &isChanged);.   
1bb80 20 69 66 28 20 69 73 43 68 61 6e 67 65 64 20 26   if( isChanged &
1bb90 26 20 70 57 61 6c 2d 3e 70 44 62 46 64 2d 3e 70  & pWal->pDbFd->p
1bba0 4d 65 74 68 6f 64 73 2d 3e 69 56 65 72 73 69 6f  Methods->iVersio
1bbb0 6e 3e 3d 33 20 29 7b 0a 20 20 20 20 20 20 73 71  n>=3 ){.      sq
1bbc0 6c 69 74 65 33 4f 73 55 6e 66 65 74 63 68 28 70  lite3OsUnfetch(p
1bbd0 57 61 6c 2d 3e 70 44 62 46 64 2c 20 30 2c 20 30  Wal->pDbFd, 0, 0
1bbe0 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
1bbf0 2f 2a 20 43 6f 70 79 20 64 61 74 61 20 66 72 6f  /* Copy data fro
1bc00 6d 20 74 68 65 20 6c 6f 67 20 74 6f 20 74 68 65  m the log to the
1bc10 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 20   database file. 
1bc20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
1bc30 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 66  ITE_OK ){.    if
1bc40 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  ( pWal->hdr.mxFr
1bc50 61 6d 65 20 26 26 20 77 61 6c 50 61 67 65 73 69  ame && walPagesi
1bc60 7a 65 28 70 57 61 6c 29 21 3d 6e 42 75 66 20 29  ze(pWal)!=nBuf )
1bc70 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
1bc80 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54  ITE_CORRUPT_BKPT
1bc90 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
1bca0 20 20 20 72 63 20 3d 20 77 61 6c 43 68 65 63 6b     rc = walCheck
1bcb0 70 6f 69 6e 74 28 70 57 61 6c 2c 20 65 4d 6f 64  point(pWal, eMod
1bcc0 65 32 2c 20 78 42 75 73 79 2c 20 70 42 75 73 79  e2, xBusy, pBusy
1bcd0 41 72 67 2c 20 73 79 6e 63 5f 66 6c 61 67 73 2c  Arg, sync_flags,
1bce0 20 7a 42 75 66 29 3b 0a 20 20 20 20 7d 0a 0a 20   zBuf);.    }.. 
1bcf0 20 20 20 2f 2a 20 49 66 20 6e 6f 20 65 72 72 6f     /* If no erro
1bd00 72 20 6f 63 63 75 72 72 65 64 2c 20 73 65 74 20  r occurred, set 
1bd10 74 68 65 20 6f 75 74 70 75 74 20 76 61 72 69 61  the output varia
1bd20 62 6c 65 73 2e 20 2a 2f 0a 20 20 20 20 69 66 28  bles. */.    if(
1bd30 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc==SQLITE_OK |
1bd40 7c 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  | rc==SQLITE_BUS
1bd50 59 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  Y ){.      if( p
1bd60 6e 4c 6f 67 20 29 20 2a 70 6e 4c 6f 67 20 3d 20  nLog ) *pnLog = 
1bd70 28 69 6e 74 29 70 57 61 6c 2d 3e 68 64 72 2e 6d  (int)pWal->hdr.m
1bd80 78 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 69 66  xFrame;.      if
1bd90 28 20 70 6e 43 6b 70 74 20 29 20 2a 70 6e 43 6b  ( pnCkpt ) *pnCk
1bda0 70 74 20 3d 20 28 69 6e 74 29 28 77 61 6c 43 6b  pt = (int)(walCk
1bdb0 70 74 49 6e 66 6f 28 70 57 61 6c 29 2d 3e 6e 42  ptInfo(pWal)->nB
1bdc0 61 63 6b 66 69 6c 6c 29 3b 0a 20 20 20 20 7d 0a  ackfill);.    }.
1bdd0 20 20 7d 0a 0a 20 20 69 66 28 20 69 73 43 68 61    }..  if( isCha
1bde0 6e 67 65 64 20 29 7b 0a 20 20 20 20 2f 2a 20 49  nged ){.    /* I
1bdf0 66 20 61 20 6e 65 77 20 77 61 6c 2d 69 6e 64 65  f a new wal-inde
1be00 78 20 68 65 61 64 65 72 20 77 61 73 20 6c 6f 61  x header was loa
1be10 64 65 64 20 62 65 66 6f 72 65 20 74 68 65 20 63  ded before the c
1be20 68 65 63 6b 70 6f 69 6e 74 20 77 61 73 20 0a 20  heckpoint was . 
1be30 20 20 20 2a 2a 20 70 65 72 66 6f 72 6d 65 64 2c     ** performed,
1be40 20 74 68 65 6e 20 74 68 65 20 70 61 67 65 72 2d   then the pager-
1be50 63 61 63 68 65 20 61 73 73 6f 63 69 61 74 65 64  cache associated
1be60 20 77 69 74 68 20 70 57 61 6c 20 69 73 20 6e 6f   with pWal is no
1be70 77 0a 20 20 20 20 2a 2a 20 6f 75 74 20 6f 66 20  w.    ** out of 
1be80 64 61 74 65 2e 20 53 6f 20 7a 65 72 6f 20 74 68  date. So zero th
1be90 65 20 63 61 63 68 65 64 20 77 61 6c 2d 69 6e 64  e cached wal-ind
1bea0 65 78 20 68 65 61 64 65 72 20 74 6f 20 65 6e 73  ex header to ens
1beb0 75 72 65 20 74 68 61 74 0a 20 20 20 20 2a 2a 20  ure that.    ** 
1bec0 6e 65 78 74 20 74 69 6d 65 20 74 68 65 20 70 61  next time the pa
1bed0 67 65 72 20 6f 70 65 6e 73 20 61 20 73 6e 61 70  ger opens a snap
1bee0 73 68 6f 74 20 6f 6e 20 74 68 69 73 20 64 61 74  shot on this dat
1bef0 61 62 61 73 65 20 69 74 20 6b 6e 6f 77 73 20 74  abase it knows t
1bf00 68 61 74 0a 20 20 20 20 2a 2a 20 74 68 65 20 63  hat.    ** the c
1bf10 61 63 68 65 20 6e 65 65 64 73 20 74 6f 20 62 65  ache needs to be
1bf20 20 72 65 73 65 74 2e 0a 20 20 20 20 2a 2f 0a 20   reset..    */. 
1bf30 20 20 20 6d 65 6d 73 65 74 28 26 70 57 61 6c 2d     memset(&pWal-
1bf40 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  >hdr, 0, sizeof(
1bf50 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 20  WalIndexHdr));. 
1bf60 20 7d 0a 0a 20 20 2f 2a 20 52 65 6c 65 61 73 65   }..  /* Release
1bf70 20 74 68 65 20 6c 6f 63 6b 73 2e 20 2a 2f 0a 20   the locks. */. 
1bf80 20 73 71 6c 69 74 65 33 57 61 6c 45 6e 64 57 72   sqlite3WalEndWr
1bf90 69 74 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 70  iteTransaction(p
1bfa0 57 61 6c 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f 63  Wal);.  walUnloc
1bfb0 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
1bfc0 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20   WAL_CKPT_LOCK, 
1bfd0 31 29 3b 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74  1);.  pWal->ckpt
1bfe0 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 57 41 4c 54  Lock = 0;.  WALT
1bff0 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63 68  RACE(("WAL%p: ch
1c000 65 63 6b 70 6f 69 6e 74 20 25 73 5c 6e 22 2c 20  eckpoint %s\n", 
1c010 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c  pWal, rc ? "fail
1c020 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20  ed" : "ok"));.  
1c030 72 65 74 75 72 6e 20 28 72 63 3d 3d 53 51 4c 49  return (rc==SQLI
1c040 54 45 5f 4f 4b 20 26 26 20 65 4d 6f 64 65 21 3d  TE_OK && eMode!=
1c050 65 4d 6f 64 65 32 20 3f 20 53 51 4c 49 54 45 5f  eMode2 ? SQLITE_
1c060 42 55 53 59 20 3a 20 72 63 29 3b 0a 7d 0a 0a 2f  BUSY : rc);.}../
1c070 2a 20 52 65 74 75 72 6e 20 74 68 65 20 76 61 6c  * Return the val
1c080 75 65 20 74 6f 20 70 61 73 73 20 74 6f 20 61 20  ue to pass to a 
1c090 73 71 6c 69 74 65 33 5f 77 61 6c 5f 68 6f 6f 6b  sqlite3_wal_hook
1c0a0 20 63 61 6c 6c 62 61 63 6b 2c 20 74 68 65 0a 2a   callback, the.*
1c0b0 2a 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d  * number of fram
1c0c0 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20 61 74  es in the WAL at
1c0d0 20 74 68 65 20 70 6f 69 6e 74 20 6f 66 20 74 68   the point of th
1c0e0 65 20 6c 61 73 74 20 63 6f 6d 6d 69 74 20 73 69  e last commit si
1c0f0 6e 63 65 0a 2a 2a 20 73 71 6c 69 74 65 33 57 61  nce.** sqlite3Wa
1c100 6c 43 61 6c 6c 62 61 63 6b 28 29 20 77 61 73 20  lCallback() was 
1c110 63 61 6c 6c 65 64 2e 20 20 49 66 20 6e 6f 20 63  called.  If no c
1c120 6f 6d 6d 69 74 73 20 68 61 76 65 20 6f 63 63 75  ommits have occu
1c130 72 72 65 64 20 73 69 6e 63 65 0a 2a 2a 20 74 68  rred since.** th
1c140 65 20 6c 61 73 74 20 63 61 6c 6c 2c 20 74 68 65  e last call, the
1c150 6e 20 72 65 74 75 72 6e 20 30 2e 0a 2a 2f 0a 69  n return 0..*/.i
1c160 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 43 61 6c  nt sqlite3WalCal
1c170 6c 62 61 63 6b 28 57 61 6c 20 2a 70 57 61 6c 29  lback(Wal *pWal)
1c180 7b 0a 20 20 75 33 32 20 72 65 74 20 3d 20 30 3b  {.  u32 ret = 0;
1c190 0a 20 20 69 66 28 20 70 57 61 6c 20 29 7b 0a 20  .  if( pWal ){. 
1c1a0 20 20 20 72 65 74 20 3d 20 70 57 61 6c 2d 3e 69     ret = pWal->i
1c1b0 43 61 6c 6c 62 61 63 6b 3b 0a 20 20 20 20 70 57  Callback;.    pW
1c1c0 61 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20  al->iCallback = 
1c1d0 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  0;.  }.  return 
1c1e0 28 69 6e 74 29 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a  (int)ret;.}../*.
1c1f0 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
1c200 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 63 68   is called to ch
1c210 61 6e 67 65 20 74 68 65 20 57 41 4c 20 73 75 62  ange the WAL sub
1c220 73 79 73 74 65 6d 20 69 6e 74 6f 20 6f 72 20 6f  system into or o
1c230 75 74 0a 2a 2a 20 6f 66 20 6c 6f 63 6b 69 6e 67  ut.** of locking
1c240 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2e  _mode=EXCLUSIVE.
1c250 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20  .**.** If op is 
1c260 7a 65 72 6f 2c 20 74 68 65 6e 20 61 74 74 65 6d  zero, then attem
1c270 70 74 20 74 6f 20 63 68 61 6e 67 65 20 66 72 6f  pt to change fro
1c280 6d 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45  m locking_mode=E
1c290 58 43 4c 55 53 49 56 45 0a 2a 2a 20 69 6e 74 6f  XCLUSIVE.** into
1c2a0 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f   locking_mode=NO
1c2b0 52 4d 41 4c 2e 20 20 54 68 69 73 20 6d 65 61 6e  RMAL.  This mean
1c2c0 73 20 74 68 61 74 20 77 65 20 6d 75 73 74 20 61  s that we must a
1c2d0 63 71 75 69 72 65 20 61 20 6c 6f 63 6b 0a 2a 2a  cquire a lock.**
1c2e0 20 6f 6e 20 74 68 65 20 70 57 61 6c 2d 3e 72 65   on the pWal->re
1c2f0 61 64 4c 6f 63 6b 20 62 79 74 65 2e 20 20 49 66  adLock byte.  If
1c300 20 74 68 65 20 57 41 4c 20 69 73 20 61 6c 72 65   the WAL is alre
1c310 61 64 79 20 69 6e 20 6c 6f 63 6b 69 6e 67 5f 6d  ady in locking_m
1c320 6f 64 65 3d 4e 4f 52 4d 41 4c 0a 2a 2a 20 6f 72  ode=NORMAL.** or
1c330 20 69 66 20 74 68 65 20 61 63 71 75 69 73 69 74   if the acquisit
1c340 69 6f 6e 20 6f 66 20 74 68 65 20 6c 6f 63 6b 20  ion of the lock 
1c350 66 61 69 6c 73 2c 20 74 68 65 6e 20 72 65 74 75  fails, then retu
1c360 72 6e 20 30 2e 20 20 49 66 20 74 68 65 0a 2a 2a  rn 0.  If the.**
1c370 20 74 72 61 6e 73 69 74 69 6f 6e 20 6f 75 74 20   transition out 
1c380 6f 66 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f 64  of exclusive-mod
1c390 65 20 69 73 20 73 75 63 63 65 73 73 66 75 6c 2c  e is successful,
1c3a0 20 72 65 74 75 72 6e 20 31 2e 20 20 54 68 69 73   return 1.  This
1c3b0 0a 2a 2a 20 6f 70 65 72 61 74 69 6f 6e 20 6d 75  .** operation mu
1c3c0 73 74 20 6f 63 63 75 72 20 77 68 69 6c 65 20 74  st occur while t
1c3d0 68 65 20 70 61 67 65 72 20 69 73 20 73 74 69 6c  he pager is stil
1c3e0 6c 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 65 78  l holding the ex
1c3f0 63 6c 75 73 69 76 65 0a 2a 2a 20 6c 6f 63 6b 20  clusive.** lock 
1c400 6f 6e 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61  on the main data
1c410 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a  base file..**.**
1c420 20 49 66 20 6f 70 20 69 73 20 6f 6e 65 2c 20 74   If op is one, t
1c430 68 65 6e 20 63 68 61 6e 67 65 20 66 72 6f 6d 20  hen change from 
1c440 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52  locking_mode=NOR
1c450 4d 41 4c 20 69 6e 74 6f 20 0a 2a 2a 20 6c 6f 63  MAL into .** loc
1c460 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53  king_mode=EXCLUS
1c470 49 56 45 2e 20 20 54 68 69 73 20 6d 65 61 6e 73  IVE.  This means
1c480 20 74 68 61 74 20 74 68 65 20 70 57 61 6c 2d 3e   that the pWal->
1c490 72 65 61 64 4c 6f 63 6b 20 6d 75 73 74 0a 2a 2a  readLock must.**
1c4a0 20 62 65 20 72 65 6c 65 61 73 65 64 2e 20 20 52   be released.  R
1c4b0 65 74 75 72 6e 20 31 20 69 66 20 74 68 65 20 74  eturn 1 if the t
1c4c0 72 61 6e 73 69 74 69 6f 6e 20 69 73 20 6d 61 64  ransition is mad
1c4d0 65 20 61 6e 64 20 30 20 69 66 20 74 68 65 0a 2a  e and 0 if the.*
1c4e0 2a 20 57 41 4c 20 69 73 20 61 6c 72 65 61 64 79  * WAL is already
1c4f0 20 69 6e 20 65 78 63 6c 75 73 69 76 65 2d 6c 6f   in exclusive-lo
1c500 63 6b 69 6e 67 20 6d 6f 64 65 20 2d 20 6d 65 61  cking mode - mea
1c510 6e 69 6e 67 20 74 68 61 74 20 74 68 69 73 0a 2a  ning that this.*
1c520 2a 20 72 6f 75 74 69 6e 65 20 69 73 20 61 20 6e  * routine is a n
1c530 6f 2d 6f 70 2e 20 20 54 68 65 20 70 61 67 65 72  o-op.  The pager
1c540 20 6d 75 73 74 20 61 6c 72 65 61 64 79 20 68 6f   must already ho
1c550 6c 64 20 74 68 65 20 65 78 63 6c 75 73 69 76 65  ld the exclusive
1c560 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20   lock.** on the 
1c570 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 66 69  main database fi
1c580 6c 65 20 62 65 66 6f 72 65 20 69 6e 76 6f 6b 69  le before invoki
1c590 6e 67 20 74 68 69 73 20 6f 70 65 72 61 74 69 6f  ng this operatio
1c5a0 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20 69  n..**.** If op i
1c5b0 73 20 6e 65 67 61 74 69 76 65 2c 20 74 68 65 6e  s negative, then
1c5c0 20 64 6f 20 61 20 64 72 79 2d 72 75 6e 20 6f 66   do a dry-run of
1c5d0 20 74 68 65 20 6f 70 3d 3d 31 20 63 61 73 65 20   the op==1 case 
1c5e0 62 75 74 20 64 6f 0a 2a 2a 20 6e 6f 74 20 61 63  but do.** not ac
1c5f0 74 75 61 6c 6c 79 20 63 68 61 6e 67 65 20 61 6e  tually change an
1c600 79 74 68 69 6e 67 2e 20 54 68 65 20 70 61 67 65  ything. The page
1c610 72 20 75 73 65 73 20 74 68 69 73 20 74 6f 20 73  r uses this to s
1c620 65 65 20 69 66 20 69 74 0a 2a 2a 20 73 68 6f 75  ee if it.** shou
1c630 6c 64 20 61 63 71 75 69 72 65 20 74 68 65 20 64  ld acquire the d
1c640 61 74 61 62 61 73 65 20 65 78 63 6c 75 73 69 76  atabase exclusiv
1c650 65 20 6c 6f 63 6b 20 70 72 69 6f 72 20 74 6f 20  e lock prior to 
1c660 69 6e 76 6f 6b 69 6e 67 0a 2a 2a 20 74 68 65 20  invoking.** the 
1c670 6f 70 3d 3d 31 20 63 61 73 65 2e 0a 2a 2f 0a 69  op==1 case..*/.i
1c680 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 45 78 63  nt sqlite3WalExc
1c690 6c 75 73 69 76 65 4d 6f 64 65 28 57 61 6c 20 2a  lusiveMode(Wal *
1c6a0 70 57 61 6c 2c 20 69 6e 74 20 6f 70 29 7b 0a 20  pWal, int op){. 
1c6b0 20 69 6e 74 20 72 63 3b 0a 20 20 61 73 73 65 72   int rc;.  asser
1c6c0 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  t( pWal->writeLo
1c6d0 63 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72  ck==0 );.  asser
1c6e0 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69  t( pWal->exclusi
1c6f0 76 65 4d 6f 64 65 21 3d 57 41 4c 5f 48 45 41 50  veMode!=WAL_HEAP
1c700 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 7c 7c 20 6f  MEMORY_MODE || o
1c710 70 3d 3d 2d 31 20 29 3b 0a 0a 20 20 2f 2a 20 70  p==-1 );..  /* p
1c720 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69 73  Wal->readLock is
1c730 20 75 73 75 61 6c 6c 79 20 73 65 74 2c 20 62 75   usually set, bu
1c740 74 20 6d 69 67 68 74 20 62 65 20 2d 31 20 69 66  t might be -1 if
1c750 20 74 68 65 72 65 20 77 61 73 20 61 20 0a 20 20   there was a .  
1c760 2a 2a 20 70 72 69 6f 72 20 65 72 72 6f 72 20 77  ** prior error w
1c770 68 69 6c 65 20 61 74 74 65 6d 70 74 69 6e 67 20  hile attempting 
1c780 74 6f 20 61 63 71 75 69 72 65 20 61 72 65 20 72  to acquire are r
1c790 65 61 64 2d 6c 6f 63 6b 2e 20 54 68 69 73 20 63  ead-lock. This c
1c7a0 61 6e 6e 6f 74 20 0a 20 20 2a 2a 20 68 61 70 70  annot .  ** happ
1c7b0 65 6e 20 69 66 20 74 68 65 20 63 6f 6e 6e 65 63  en if the connec
1c7c0 74 69 6f 6e 20 69 73 20 61 63 74 75 61 6c 6c 79  tion is actually
1c7d0 20 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f   in exclusive mo
1c7e0 64 65 20 28 61 73 20 6e 6f 20 78 53 68 6d 4c 6f  de (as no xShmLo
1c7f0 63 6b 0a 20 20 2a 2a 20 6c 6f 63 6b 73 20 61 72  ck.  ** locks ar
1c800 65 20 74 61 6b 65 6e 20 69 6e 20 74 68 69 73 20  e taken in this 
1c810 63 61 73 65 29 2e 20 4e 6f 72 20 73 68 6f 75 6c  case). Nor shoul
1c820 64 20 74 68 65 20 70 61 67 65 72 20 61 74 74 65  d the pager atte
1c830 6d 70 74 20 74 6f 0a 20 20 2a 2a 20 75 70 67 72  mpt to.  ** upgr
1c840 61 64 65 20 74 6f 20 65 78 63 6c 75 73 69 76 65  ade to exclusive
1c850 2d 6d 6f 64 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  -mode following 
1c860 73 75 63 68 20 61 6e 20 65 72 72 6f 72 2e 0a 20  such an error.. 
1c870 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57   */.  assert( pW
1c880 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20  al->readLock>=0 
1c890 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72  || pWal->lockErr
1c8a0 6f 72 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  or );.  assert( 
1c8b0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
1c8c0 30 20 7c 7c 20 28 6f 70 3c 3d 30 20 26 26 20 70  0 || (op<=0 && p
1c8d0 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
1c8e0 64 65 3d 3d 30 29 20 29 3b 0a 0a 20 20 69 66 28  de==0) );..  if(
1c8f0 20 6f 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66   op==0 ){.    if
1c900 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76  ( pWal->exclusiv
1c910 65 4d 6f 64 65 20 29 7b 0a 20 20 20 20 20 20 70  eMode ){.      p
1c920 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
1c930 64 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66  de = 0;.      if
1c940 28 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28  ( walLockShared(
1c950 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  pWal, WAL_READ_L
1c960 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  OCK(pWal->readLo
1c970 63 6b 29 29 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ck))!=SQLITE_OK 
1c980 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d  ){.        pWal-
1c990 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d  >exclusiveMode =
1c9a0 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   1;.      }.    
1c9b0 20 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63    rc = pWal->exc
1c9c0 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20  lusiveMode==0;. 
1c9d0 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
1c9e0 2f 2a 20 41 6c 72 65 61 64 79 20 69 6e 20 6c 6f  /* Already in lo
1c9f0 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41  cking_mode=NORMA
1ca00 4c 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20  L */.      rc = 
1ca10 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65  0;.    }.  }else
1ca20 20 69 66 28 20 6f 70 3e 30 20 29 7b 0a 20 20 20   if( op>0 ){.   
1ca30 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 65   assert( pWal->e
1ca40 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 20  xclusiveMode==0 
1ca50 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
1ca60 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30  Wal->readLock>=0
1ca70 20 29 3b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63   );.    walUnloc
1ca80 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
1ca90 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c  L_READ_LOCK(pWal
1caa0 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 3b 0a 20 20  ->readLock));.  
1cab0 20 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76    pWal->exclusiv
1cac0 65 4d 6f 64 65 20 3d 20 31 3b 0a 20 20 20 20 72  eMode = 1;.    r
1cad0 63 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a  c = 1;.  }else{.
1cae0 20 20 20 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65      rc = pWal->e
1caf0 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 3b  xclusiveMode==0;
1cb00 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
1cb10 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75  ;.}../* .** Retu
1cb20 72 6e 20 74 72 75 65 20 69 66 20 74 68 65 20 61  rn true if the a
1cb30 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f 6e 2d 4e  rgument is non-N
1cb40 55 4c 4c 20 61 6e 64 20 74 68 65 20 57 41 4c 20  ULL and the WAL 
1cb50 6d 6f 64 75 6c 65 20 69 73 20 75 73 69 6e 67 0a  module is using.
1cb60 2a 2a 20 68 65 61 70 2d 6d 65 6d 6f 72 79 20 66  ** heap-memory f
1cb70 6f 72 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  or the wal-index
1cb80 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69 66 20  . Otherwise, if 
1cb90 74 68 65 20 61 72 67 75 6d 65 6e 74 20 69 73 20  the argument is 
1cba0 4e 55 4c 4c 20 6f 72 20 74 68 65 0a 2a 2a 20 57  NULL or the.** W
1cbb0 41 4c 20 6d 6f 64 75 6c 65 20 69 73 20 75 73 69  AL module is usi
1cbc0 6e 67 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79  ng shared-memory
1cbd0 2c 20 72 65 74 75 72 6e 20 66 61 6c 73 65 2e 20  , return false. 
1cbe0 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
1cbf0 61 6c 48 65 61 70 4d 65 6d 6f 72 79 28 57 61 6c  alHeapMemory(Wal
1cc00 20 2a 70 57 61 6c 29 7b 0a 20 20 72 65 74 75 72   *pWal){.  retur
1cc10 6e 20 28 70 57 61 6c 20 26 26 20 70 57 61 6c 2d  n (pWal && pWal-
1cc20 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d  >exclusiveMode==
1cc30 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d  WAL_HEAPMEMORY_M
1cc40 4f 44 45 20 29 3b 0a 7d 0a 0a 23 69 66 64 65 66  ODE );.}..#ifdef
1cc50 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 5a   SQLITE_ENABLE_Z
1cc60 49 50 56 46 53 0a 2f 2a 0a 2a 2a 20 49 66 20 74  IPVFS./*.** If t
1cc70 68 65 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e  he argument is n
1cc80 6f 74 20 4e 55 4c 4c 2c 20 69 74 20 70 6f 69 6e  ot NULL, it poin
1cc90 74 73 20 74 6f 20 61 20 57 61 6c 20 6f 62 6a 65  ts to a Wal obje
1cca0 63 74 20 74 68 61 74 20 68 6f 6c 64 73 20 61 0a  ct that holds a.
1ccb0 2a 2a 20 72 65 61 64 2d 6c 6f 63 6b 2e 20 54 68  ** read-lock. Th
1ccc0 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75  is function retu
1ccd0 72 6e 73 20 74 68 65 20 64 61 74 61 62 61 73 65  rns the database
1cce0 20 70 61 67 65 2d 73 69 7a 65 20 69 66 20 69 74   page-size if it
1ccf0 20 69 73 20 6b 6e 6f 77 6e 2c 0a 2a 2a 20 6f 72   is known,.** or
1cd00 20 7a 65 72 6f 20 69 66 20 69 74 20 69 73 20 6e   zero if it is n
1cd10 6f 74 20 28 6f 72 20 69 66 20 70 57 61 6c 20 69  ot (or if pWal i
1cd20 73 20 4e 55 4c 4c 29 2e 0a 2a 2f 0a 69 6e 74 20  s NULL)..*/.int 
1cd30 73 71 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73  sqlite3WalFrames
1cd40 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ize(Wal *pWal){.
1cd50 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 3d 3d    assert( pWal==
1cd60 30 20 7c 7c 20 70 57 61 6c 2d 3e 72 65 61 64 4c  0 || pWal->readL
1cd70 6f 63 6b 3e 3d 30 20 29 3b 0a 20 20 72 65 74 75  ock>=0 );.  retu
1cd80 72 6e 20 28 70 57 61 6c 20 3f 20 70 57 61 6c 2d  rn (pWal ? pWal-
1cd90 3e 73 7a 50 61 67 65 20 3a 20 30 29 3b 0a 7d 0a  >szPage : 0);.}.
1cda0 23 65 6e 64 69 66 0a 0a 23 65 6e 64 69 66 20 2f  #endif..#endif /
1cdb0 2a 20 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45  * #ifndef SQLITE
1cdc0 5f 4f 4d 49 54 5f 57 41 4c 20 2a 2f 0a           _OMIT_WAL */.