/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact 40e6d0acde18a0d4796310db4d6382a12340388c:


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 2c 20 72 65 74 75 72   number P, retur
1b50: 6e 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74  n the index of t
1b60: 68 65 20 6c 61 73 74 20 66 72 61 6d 65 20 66 6f  he last frame fo
1b70: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
1b80: 57 41 4c 2c 0a 2a 2a 20 6f 72 20 72 65 74 75 72  WAL,.** or retur
1b90: 6e 20 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20  n NULL if there 
1ba0: 61 72 65 20 6e 6f 20 66 72 61 6d 65 73 20 66 6f  are no frames fo
1bb0: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
1bc0: 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77  WAL..**.** The w
1bd0: 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69 73 74  al-index consist
1be0: 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 72 65  s of a header re
1bf0: 67 69 6f 6e 2c 20 66 6f 6c 6c 6f 77 65 64 20 62  gion, followed b
1c00: 79 20 61 6e 20 6f 6e 65 20 6f 72 0a 2a 2a 20 6d  y an one or.** m
1c10: 6f 72 65 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73  ore index blocks
1c20: 2e 20 20 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61  .  .**.** The wa
1c30: 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 63  l-index header c
1c40: 6f 6e 74 61 69 6e 73 20 74 68 65 20 74 6f 74 61  ontains the tota
1c50: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d  l number of fram
1c60: 65 73 20 77 69 74 68 69 6e 20 74 68 65 20 57 41  es within the WA
1c70: 4c 0a 2a 2a 20 69 6e 20 74 68 65 20 74 68 65 20  L.** in the the 
1c80: 6d 78 46 72 61 6d 65 20 66 69 65 6c 64 2e 20 20  mxFrame field.  
1c90: 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 69 6e 64 65  .**.** Each inde
1ca0: 78 20 62 6c 6f 63 6b 20 65 78 63 65 70 74 20 66  x block except f
1cb0: 6f 72 20 74 68 65 20 66 69 72 73 74 20 63 6f 6e  or the first con
1cc0: 74 61 69 6e 73 20 69 6e 66 6f 72 6d 61 74 69 6f  tains informatio
1cd0: 6e 20 6f 6e 20 0a 2a 2a 20 48 41 53 48 54 41 42  n on .** HASHTAB
1ce0: 4c 45 5f 4e 50 41 47 45 20 66 72 61 6d 65 73 2e  LE_NPAGE frames.
1cf0: 20 54 68 65 20 66 69 72 73 74 20 69 6e 64 65 78   The first index
1d00: 20 62 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20   block contains 
1d10: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f 6e 0a 2a  information on.*
1d20: 2a 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  * HASHTABLE_NPAG
1d30: 45 5f 4f 4e 45 20 66 72 61 6d 65 73 2e 20 54 68  E_ONE frames. Th
1d40: 65 20 76 61 6c 75 65 73 20 6f 66 20 48 41 53 48  e values of HASH
1d50: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20  TABLE_NPAGE_ONE 
1d60: 61 6e 64 20 0a 2a 2a 20 48 41 53 48 54 41 42 4c  and .** HASHTABL
1d70: 45 5f 4e 50 41 47 45 20 61 72 65 20 73 65 6c 65  E_NPAGE are sele
1d80: 63 74 65 64 20 73 6f 20 74 68 61 74 20 74 6f 67  cted so that tog
1d90: 65 74 68 65 72 20 74 68 65 20 77 61 6c 2d 69 6e  ether the wal-in
1da0: 64 65 78 20 68 65 61 64 65 72 20 61 6e 64 0a 2a  dex header and.*
1db0: 2a 20 66 69 72 73 74 20 69 6e 64 65 78 20 62 6c  * first index bl
1dc0: 6f 63 6b 20 61 72 65 20 74 68 65 20 73 61 6d 65  ock are the same
1dd0: 20 73 69 7a 65 20 61 73 20 61 6c 6c 20 6f 74 68   size as all oth
1de0: 65 72 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73 20  er index blocks 
1df0: 69 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e  in the.** wal-in
1e00: 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20  dex..**.** Each 
1e10: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 63 6f 6e 74  index block cont
1e20: 61 69 6e 73 20 74 77 6f 20 73 65 63 74 69 6f 6e  ains two section
1e30: 73 2c 20 61 20 70 61 67 65 2d 6d 61 70 70 69 6e  s, a page-mappin
1e40: 67 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  g that contains 
1e50: 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20  the.** database 
1e60: 70 61 67 65 20 6e 75 6d 62 65 72 20 61 73 73 6f  page number asso
1e70: 63 69 61 74 65 64 20 77 69 74 68 20 65 61 63 68  ciated with each
1e80: 20 77 61 6c 20 66 72 61 6d 65 2c 20 61 6e 64 20   wal frame, and 
1e90: 61 20 68 61 73 68 2d 74 61 62 6c 65 20 0a 2a 2a  a hash-table .**
1ea0: 20 74 68 61 74 20 61 6c 6c 6f 77 73 20 72 65 61   that allows rea
1eb0: 64 65 72 73 20 74 6f 20 71 75 65 72 79 20 61 6e  ders to query an
1ec0: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 66 6f 72   index block for
1ed0: 20 61 20 73 70 65 63 69 66 69 63 20 70 61 67 65   a specific page
1ee0: 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 54 68 65 20   number..** The 
1ef0: 70 61 67 65 2d 6d 61 70 70 69 6e 67 20 69 73 20  page-mapping is 
1f00: 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53 48  an array of HASH
1f10: 54 41 42 4c 45 5f 4e 50 41 47 45 20 28 6f 72 20  TABLE_NPAGE (or 
1f20: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
1f30: 4f 4e 45 0a 2a 2a 20 66 6f 72 20 74 68 65 20 66  ONE.** for the f
1f40: 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b  irst index block
1f50: 29 20 33 32 2d 62 69 74 20 70 61 67 65 20 6e 75  ) 32-bit page nu
1f60: 6d 62 65 72 73 2e 20 54 68 65 20 66 69 72 73 74  mbers. The first
1f70: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 0a 2a   entry in the .*
1f80: 2a 20 66 69 72 73 74 20 69 6e 64 65 78 2d 62 6c  * first index-bl
1f90: 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  ock contains the
1fa0: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6e   database page n
1fb0: 75 6d 62 65 72 20 63 6f 72 72 65 73 70 6f 6e 64  umber correspond
1fc0: 69 6e 67 20 74 6f 20 74 68 65 0a 2a 2a 20 66 69  ing to the.** fi
1fd0: 72 73 74 20 66 72 61 6d 65 20 69 6e 20 74 68 65  rst frame in the
1fe0: 20 57 41 4c 20 66 69 6c 65 2e 20 54 68 65 20 66   WAL file. The f
1ff0: 69 72 73 74 20 65 6e 74 72 79 20 69 6e 20 74 68  irst entry in th
2000: 65 20 73 65 63 6f 6e 64 20 69 6e 64 65 78 20 62  e second index b
2010: 6c 6f 63 6b 0a 2a 2a 20 69 6e 20 74 68 65 20 57  lock.** in the W
2020: 41 4c 20 66 69 6c 65 20 63 6f 72 72 65 73 70 6f  AL file correspo
2030: 6e 64 73 20 74 6f 20 74 68 65 20 28 48 41 53 48  nds to the (HASH
2040: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b  TABLE_NPAGE_ONE+
2050: 31 29 74 68 20 66 72 61 6d 65 20 69 6e 0a 2a 2a  1)th frame in.**
2060: 20 74 68 65 20 6c 6f 67 2c 20 61 6e 64 20 73 6f   the log, and so
2070: 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c   on..**.** The l
2080: 61 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20  ast index block 
2090: 69 6e 20 61 20 77 61 6c 2d 69 6e 64 65 78 20 75  in a wal-index u
20a0: 73 75 61 6c 6c 79 20 63 6f 6e 74 61 69 6e 73 20  sually contains 
20b0: 6c 65 73 73 20 74 68 61 6e 20 74 68 65 20 66 75  less than the fu
20c0: 6c 6c 0a 2a 2a 20 63 6f 6d 70 6c 65 6d 65 6e 74  ll.** complement
20d0: 20 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e 50   of HASHTABLE_NP
20e0: 41 47 45 20 28 6f 72 20 48 41 53 48 54 41 42 4c  AGE (or HASHTABL
20f0: 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 20 70 61 67  E_NPAGE_ONE) pag
2100: 65 2d 6e 75 6d 62 65 72 73 2c 0a 2a 2a 20 64 65  e-numbers,.** de
2110: 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20 63  pending on the c
2120: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 57  ontents of the W
2130: 41 4c 20 66 69 6c 65 2e 20 54 68 69 73 20 64 6f  AL file. This do
2140: 65 73 20 6e 6f 74 20 63 68 61 6e 67 65 20 74 68  es not change th
2150: 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74 65 64 20 73  e.** allocated s
2160: 69 7a 65 20 6f 66 20 74 68 65 20 70 61 67 65 2d  ize of the page-
2170: 6d 61 70 70 69 6e 67 20 61 72 72 61 79 20 2d 20  mapping array - 
2180: 74 68 65 20 70 61 67 65 2d 6d 61 70 70 69 6e 67  the page-mapping
2190: 20 61 72 72 61 79 20 6d 65 72 65 6c 79 0a 2a 2a   array merely.**
21a0: 20 63 6f 6e 74 61 69 6e 73 20 75 6e 75 73 65 64   contains unused
21b0: 20 65 6e 74 72 69 65 73 2e 0a 2a 2a 0a 2a 2a 20   entries..**.** 
21c0: 45 76 65 6e 20 77 69 74 68 6f 75 74 20 75 73 69  Even without usi
21d0: 6e 67 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ng the hash tabl
21e0: 65 2c 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d  e, the last fram
21f0: 65 20 66 6f 72 20 70 61 67 65 20 50 0a 2a 2a 20  e for page P.** 
2200: 63 61 6e 20 62 65 20 66 6f 75 6e 64 20 62 79 20  can be found by 
2210: 73 63 61 6e 6e 69 6e 67 20 74 68 65 20 70 61 67  scanning the pag
2220: 65 2d 6d 61 70 70 69 6e 67 20 73 65 63 74 69 6f  e-mapping sectio
2230: 6e 73 20 6f 66 20 65 61 63 68 20 69 6e 64 65 78  ns of each index
2240: 20 62 6c 6f 63 6b 0a 2a 2a 20 73 74 61 72 74 69   block.** starti
2250: 6e 67 20 77 69 74 68 20 74 68 65 20 6c 61 73 74  ng with the last
2260: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 61 6e 64   index block and
2270: 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20 74   moving toward t
2280: 68 65 20 66 69 72 73 74 2c 20 61 6e 64 0a 2a 2a  he first, and.**
2290: 20 77 69 74 68 69 6e 20 65 61 63 68 20 69 6e 64   within each ind
22a0: 65 78 20 62 6c 6f 63 6b 2c 20 73 74 61 72 74 69  ex block, starti
22b0: 6e 67 20 61 74 20 74 68 65 20 65 6e 64 20 61 6e  ng at the end an
22c0: 64 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20  d moving toward 
22d0: 74 68 65 0a 2a 2a 20 62 65 67 69 6e 6e 69 6e 67  the.** beginning
22e0: 2e 20 20 54 68 65 20 66 69 72 73 74 20 65 6e 74  .  The first ent
22f0: 72 79 20 74 68 61 74 20 65 71 75 61 6c 73 20 50  ry that equals P
2300: 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20   corresponds to 
2310: 74 68 65 20 66 72 61 6d 65 0a 2a 2a 20 68 6f 6c  the frame.** hol
2320: 64 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74  ding the content
2330: 20 66 6f 72 20 74 68 61 74 20 70 61 67 65 2e 0a   for that page..
2340: 2a 2a 0a 2a 2a 20 54 68 65 20 68 61 73 68 20 74  **.** The hash t
2350: 61 62 6c 65 20 63 6f 6e 73 69 73 74 73 20 6f 66  able consists of
2360: 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54   HASHTABLE_NSLOT
2370: 20 31 36 2d 62 69 74 20 75 6e 73 69 67 6e 65 64   16-bit unsigned
2380: 20 69 6e 74 65 67 65 72 73 2e 0a 2a 2a 20 48 41   integers..** HA
2390: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 3d 20  SHTABLE_NSLOT = 
23a0: 32 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  2*HASHTABLE_NPAG
23b0: 45 2c 20 61 6e 64 20 74 68 65 72 65 20 69 73 20  E, and there is 
23c0: 6f 6e 65 20 65 6e 74 72 79 20 69 6e 20 74 68 65  one entry in the
23d0: 0a 2a 2a 20 68 61 73 68 20 74 61 62 6c 65 20 66  .** hash table f
23e0: 6f 72 20 65 61 63 68 20 70 61 67 65 20 6e 75 6d  or each page num
23f0: 62 65 72 20 69 6e 20 74 68 65 20 6d 61 70 70 69  ber in the mappi
2400: 6e 67 20 73 65 63 74 69 6f 6e 2c 20 73 6f 20 74  ng section, so t
2410: 68 65 20 68 61 73 68 20 0a 2a 2a 20 74 61 62 6c  he hash .** tabl
2420: 65 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20  e is never more 
2430: 74 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2e 20  than half full. 
2440: 20 54 68 65 20 65 78 70 65 63 74 65 64 20 6e 75   The expected nu
2450: 6d 62 65 72 20 6f 66 20 63 6f 6c 6c 69 73 69 6f  mber of collisio
2460: 6e 73 20 0a 2a 2a 20 70 72 69 6f 72 20 74 6f 20  ns .** prior to 
2470: 66 69 6e 64 69 6e 67 20 61 20 6d 61 74 63 68 20  finding a match 
2480: 69 73 20 31 2e 20 20 45 61 63 68 20 65 6e 74 72  is 1.  Each entr
2490: 79 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61  y of the hash ta
24a0: 62 6c 65 20 69 73 20 61 6e 0a 2a 2a 20 31 2d 62  ble is an.** 1-b
24b0: 61 73 65 64 20 69 6e 64 65 78 20 6f 66 20 61 6e  ased index of an
24c0: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61   entry in the ma
24d0: 70 70 69 6e 67 20 73 65 63 74 69 6f 6e 20 6f 66  pping section of
24e0: 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20 69 6e 64   the same.** ind
24f0: 65 78 20 62 6c 6f 63 6b 2e 20 20 20 4c 65 74 20  ex block.   Let 
2500: 4b 20 62 65 20 74 68 65 20 31 2d 62 61 73 65 64  K be the 1-based
2510: 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61   index of the la
2520: 72 67 65 73 74 20 65 6e 74 72 79 20 69 6e 0a 2a  rgest entry in.*
2530: 2a 20 74 68 65 20 6d 61 70 70 69 6e 67 20 73 65  * the mapping se
2540: 63 74 69 6f 6e 2e 20 20 28 46 6f 72 20 69 6e 64  ction.  (For ind
2550: 65 78 20 62 6c 6f 63 6b 73 20 6f 74 68 65 72 20  ex blocks other 
2560: 74 68 61 6e 20 74 68 65 20 6c 61 73 74 2c 20 4b  than the last, K
2570: 20 77 69 6c 6c 0a 2a 2a 20 61 6c 77 61 79 73 20   will.** always 
2580: 62 65 20 65 78 61 63 74 6c 79 20 48 41 53 48 54  be exactly HASHT
2590: 41 42 4c 45 5f 4e 50 41 47 45 20 28 34 30 39 36  ABLE_NPAGE (4096
25a0: 29 20 61 6e 64 20 66 6f 72 20 74 68 65 20 6c 61  ) and for the la
25b0: 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 0a 2a  st index block.*
25c0: 2a 20 4b 20 77 69 6c 6c 20 62 65 20 28 6d 78 46  * K will be (mxF
25d0: 72 61 6d 65 25 48 41 53 48 54 41 42 4c 45 5f 4e  rame%HASHTABLE_N
25e0: 50 41 47 45 29 2e 29 20 20 55 6e 75 73 65 64 20  PAGE).)  Unused 
25f0: 73 6c 6f 74 73 20 6f 66 20 74 68 65 20 68 61 73  slots of the has
2600: 68 20 74 61 62 6c 65 0a 2a 2a 20 63 6f 6e 74 61  h table.** conta
2610: 69 6e 20 61 20 76 61 6c 75 65 20 6f 66 20 30 2e  in a value of 0.
2620: 0a 2a 2a 0a 2a 2a 20 54 6f 20 6c 6f 6f 6b 20 66  .**.** To look f
2630: 6f 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65  or page P in the
2640: 20 68 61 73 68 20 74 61 62 6c 65 2c 20 66 69 72   hash table, fir
2650: 73 74 20 63 6f 6d 70 75 74 65 20 61 20 68 61 73  st compute a has
2660: 68 20 69 4b 65 79 20 6f 6e 0a 2a 2a 20 50 20 61  h iKey on.** P a
2670: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a  s follows:.**.**
2680: 20 20 20 20 20 20 69 4b 65 79 20 3d 20 28 50 20        iKey = (P 
2690: 2a 20 33 38 33 29 20 25 20 48 41 53 48 54 41 42  * 383) % HASHTAB
26a0: 4c 45 5f 4e 53 4c 4f 54 0a 2a 2a 0a 2a 2a 20 54  LE_NSLOT.**.** T
26b0: 68 65 6e 20 73 74 61 72 74 20 73 63 61 6e 6e 69  hen start scanni
26c0: 6e 67 20 65 6e 74 72 69 65 73 20 6f 66 20 74 68  ng entries of th
26d0: 65 20 68 61 73 68 20 74 61 62 6c 65 2c 20 73 74  e hash table, st
26e0: 61 72 74 69 6e 67 20 77 69 74 68 20 69 4b 65 79  arting with iKey
26f0: 0a 2a 2a 20 28 77 72 61 70 70 69 6e 67 20 61 72  .** (wrapping ar
2700: 6f 75 6e 64 20 74 6f 20 74 68 65 20 62 65 67 69  ound to the begi
2710: 6e 6e 69 6e 67 20 77 68 65 6e 20 74 68 65 20 65  nning when the e
2720: 6e 64 20 6f 66 20 74 68 65 20 68 61 73 68 20 74  nd of the hash t
2730: 61 62 6c 65 20 69 73 0a 2a 2a 20 72 65 61 63 68  able is.** reach
2740: 65 64 29 20 75 6e 74 69 6c 20 61 6e 20 75 6e 75  ed) until an unu
2750: 73 65 64 20 68 61 73 68 20 73 6c 6f 74 20 69 73  sed hash slot is
2760: 20 66 6f 75 6e 64 2e 20 4c 65 74 20 74 68 65 20   found. Let the 
2770: 66 69 72 73 74 20 75 6e 75 73 65 64 20 73 6c 6f  first unused slo
2780: 74 0a 2a 2a 20 62 65 20 61 74 20 69 6e 64 65 78  t.** be at index
2790: 20 69 55 6e 75 73 65 64 2e 20 20 28 69 55 6e 75   iUnused.  (iUnu
27a0: 73 65 64 20 6d 69 67 68 74 20 62 65 20 6c 65 73  sed might be les
27b0: 73 20 74 68 61 6e 20 69 4b 65 79 20 69 66 20 74  s than iKey if t
27c0: 68 65 72 65 20 77 61 73 0a 2a 2a 20 77 72 61 70  here was.** wrap
27d0: 2d 61 72 6f 75 6e 64 2e 29 20 42 65 63 61 75 73  -around.) Becaus
27e0: 65 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  e the hash table
27f0: 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20 74   is never more t
2800: 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2c 0a 2a  han half full,.*
2810: 2a 20 74 68 65 20 73 65 61 72 63 68 20 69 73 20  * the search is 
2820: 67 75 61 72 61 6e 74 65 65 64 20 74 6f 20 65 76  guaranteed to ev
2830: 65 6e 74 75 61 6c 6c 79 20 68 69 74 20 61 6e 20  entually hit an 
2840: 75 6e 75 73 65 64 20 65 6e 74 72 79 2e 20 20 4c  unused entry.  L
2850: 65 74 20 0a 2a 2a 20 69 4d 61 78 20 62 65 20 74  et .** iMax be t
2860: 68 65 20 76 61 6c 75 65 20 62 65 74 77 65 65 6e  he value between
2870: 20 69 4b 65 79 20 61 6e 64 20 69 55 6e 75 73 65   iKey and iUnuse
2880: 64 2c 20 63 6c 6f 73 65 73 74 20 74 6f 20 69 55  d, closest to iU
2890: 6e 75 73 65 64 2c 0a 2a 2a 20 77 68 65 72 65 20  nused,.** where 
28a0: 61 48 61 73 68 5b 69 4d 61 78 5d 3d 3d 50 2e 20  aHash[iMax]==P. 
28b0: 20 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20   If there is no 
28c0: 69 4d 61 78 20 65 6e 74 72 79 20 28 69 66 20 74  iMax entry (if t
28d0: 68 65 72 65 20 65 78 69 73 74 73 0a 2a 2a 20 6e  here exists.** n
28e0: 6f 20 68 61 73 68 20 73 6c 6f 74 20 73 75 63 68  o hash slot such
28f0: 20 74 68 61 74 20 61 48 61 73 68 5b 69 5d 3d 3d   that aHash[i]==
2900: 70 29 20 74 68 65 6e 20 70 61 67 65 20 50 20 69  p) then page P i
2910: 73 20 6e 6f 74 20 69 6e 20 74 68 65 0a 2a 2a 20  s not in the.** 
2920: 63 75 72 72 65 6e 74 20 69 6e 64 65 78 20 62 6c  current index bl
2930: 6f 63 6b 2e 20 20 4f 74 68 65 72 77 69 73 65 20  ock.  Otherwise 
2940: 74 68 65 20 69 4d 61 78 2d 74 68 20 6d 61 70 70  the iMax-th mapp
2950: 69 6e 67 20 65 6e 74 72 79 20 6f 66 20 74 68 65  ing entry of the
2960: 0a 2a 2a 20 63 75 72 72 65 6e 74 20 69 6e 64 65  .** current inde
2970: 78 20 62 6c 6f 63 6b 20 63 6f 72 72 65 73 70 6f  x block correspo
2980: 6e 64 73 20 74 6f 20 74 68 65 20 6c 61 73 74 20  nds to the last 
2990: 65 6e 74 72 79 20 74 68 61 74 20 72 65 66 65 72  entry that refer
29a0: 65 6e 63 65 73 20 0a 2a 2a 20 70 61 67 65 20 50  ences .** page P
29b0: 2e 0a 2a 2a 0a 2a 2a 20 41 20 68 61 73 68 20 73  ..**.** A hash s
29c0: 65 61 72 63 68 20 62 65 67 69 6e 73 20 77 69 74  earch begins wit
29d0: 68 20 74 68 65 20 6c 61 73 74 20 69 6e 64 65 78  h the last index
29e0: 20 62 6c 6f 63 6b 20 61 6e 64 20 6d 6f 76 65 73   block and moves
29f0: 20 74 6f 77 61 72 64 20 74 68 65 0a 2a 2a 20 66   toward the.** f
2a00: 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b  irst index block
2a10: 2c 20 6c 6f 6f 6b 69 6e 67 20 66 6f 72 20 65 6e  , looking for en
2a20: 74 72 69 65 73 20 63 6f 72 72 65 73 70 6f 6e 64  tries correspond
2a30: 69 6e 67 20 74 6f 20 70 61 67 65 20 50 2e 20 20  ing to page P.  
2a40: 4f 6e 0a 2a 2a 20 61 76 65 72 61 67 65 2c 20 6f  On.** average, o
2a50: 6e 6c 79 20 74 77 6f 20 6f 72 20 74 68 72 65 65  nly two or three
2a60: 20 73 6c 6f 74 73 20 69 6e 20 65 61 63 68 20 69   slots in each i
2a70: 6e 64 65 78 20 62 6c 6f 63 6b 20 6e 65 65 64 20  ndex block need 
2a80: 74 6f 20 62 65 0a 2a 2a 20 65 78 61 6d 69 6e 65  to be.** examine
2a90: 64 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 65 69  d in order to ei
2aa0: 74 68 65 72 20 66 69 6e 64 20 74 68 65 20 6c 61  ther find the la
2ab0: 73 74 20 65 6e 74 72 79 20 66 6f 72 20 70 61 67  st entry for pag
2ac0: 65 20 50 2c 20 6f 72 20 74 6f 0a 2a 2a 20 65 73  e P, or to.** es
2ad0: 74 61 62 6c 69 73 68 20 74 68 61 74 20 6e 6f 20  tablish that no 
2ae0: 73 75 63 68 20 65 6e 74 72 79 20 65 78 69 73 74  such entry exist
2af0: 73 20 69 6e 20 74 68 65 20 62 6c 6f 63 6b 2e 20  s in the block. 
2b00: 20 45 61 63 68 20 69 6e 64 65 78 20 62 6c 6f 63   Each index bloc
2b10: 6b 0a 2a 2a 20 68 6f 6c 64 73 20 6f 76 65 72 20  k.** holds over 
2b20: 34 30 30 30 20 65 6e 74 72 69 65 73 2e 20 20 53  4000 entries.  S
2b30: 6f 20 74 77 6f 20 6f 72 20 74 68 72 65 65 20 69  o two or three i
2b40: 6e 64 65 78 20 62 6c 6f 63 6b 73 20 61 72 65 20  ndex blocks are 
2b50: 73 75 66 66 69 63 69 65 6e 74 0a 2a 2a 20 74 6f  sufficient.** to
2b60: 20 63 6f 76 65 72 20 61 20 74 79 70 69 63 61 6c   cover a typical
2b70: 20 31 30 20 6d 65 67 61 62 79 74 65 20 57 41 4c   10 megabyte WAL
2b80: 20 66 69 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20   file, assuming 
2b90: 31 4b 20 70 61 67 65 73 2e 20 20 38 20 6f 72 20  1K pages.  8 or 
2ba0: 31 30 0a 2a 2a 20 63 6f 6d 70 61 72 69 73 6f 6e  10.** comparison
2bb0: 73 20 28 6f 6e 20 61 76 65 72 61 67 65 29 20 73  s (on average) s
2bc0: 75 66 66 69 63 65 20 74 6f 20 65 69 74 68 65 72  uffice to either
2bd0: 20 6c 6f 63 61 74 65 20 61 20 66 72 61 6d 65 20   locate a frame 
2be0: 69 6e 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6f 72  in the.** WAL or
2bf0: 20 74 6f 20 65 73 74 61 62 6c 69 73 68 20 74 68   to establish th
2c00: 61 74 20 74 68 65 20 66 72 61 6d 65 20 64 6f 65  at the frame doe
2c10: 73 20 6e 6f 74 20 65 78 69 73 74 20 69 6e 20 74  s not exist in t
2c20: 68 65 20 57 41 4c 2e 20 20 54 68 69 73 0a 2a 2a  he WAL.  This.**
2c30: 20 69 73 20 6d 75 63 68 20 66 61 73 74 65 72 20   is much faster 
2c40: 74 68 61 6e 20 73 63 61 6e 6e 69 6e 67 20 74 68  than scanning th
2c50: 65 20 65 6e 74 69 72 65 20 31 30 4d 42 20 57 41  e entire 10MB WA
2c60: 4c 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68  L..**.** Note th
2c70: 61 74 20 65 6e 74 72 69 65 73 20 61 72 65 20 61  at entries are a
2c80: 64 64 65 64 20 69 6e 20 6f 72 64 65 72 20 6f 66  dded in order of
2c90: 20 69 6e 63 72 65 61 73 69 6e 67 20 4b 2e 20 20   increasing K.  
2ca0: 48 65 6e 63 65 2c 20 6f 6e 65 0a 2a 2a 20 72 65  Hence, one.** re
2cb0: 61 64 65 72 20 6d 69 67 68 74 20 62 65 20 75 73  ader might be us
2cc0: 69 6e 67 20 73 6f 6d 65 20 76 61 6c 75 65 20 4b  ing some value K
2cd0: 30 20 61 6e 64 20 61 20 73 65 63 6f 6e 64 20 72  0 and a second r
2ce0: 65 61 64 65 72 20 74 68 61 74 20 73 74 61 72 74  eader that start
2cf0: 65 64 0a 2a 2a 20 61 74 20 61 20 6c 61 74 65 72  ed.** at a later
2d00: 20 74 69 6d 65 20 28 61 66 74 65 72 20 61 64 64   time (after add
2d10: 69 74 69 6f 6e 61 6c 20 74 72 61 6e 73 61 63 74  itional transact
2d20: 69 6f 6e 73 20 77 65 72 65 20 61 64 64 65 64 20  ions were added 
2d30: 74 6f 20 74 68 65 20 57 41 4c 0a 2a 2a 20 61 6e  to the WAL.** an
2d40: 64 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64  d to the wal-ind
2d50: 65 78 29 20 6d 69 67 68 74 20 62 65 20 75 73 69  ex) might be usi
2d60: 6e 67 20 61 20 64 69 66 66 65 72 65 6e 74 20 76  ng a different v
2d70: 61 6c 75 65 20 4b 31 2c 20 77 68 65 72 65 20 4b  alue K1, where K
2d80: 31 3e 4b 30 2e 0a 2a 2a 20 42 6f 74 68 20 72 65  1>K0..** Both re
2d90: 61 64 65 72 73 20 63 61 6e 20 75 73 65 20 74 68  aders can use th
2da0: 65 20 73 61 6d 65 20 68 61 73 68 20 74 61 62 6c  e same hash tabl
2db0: 65 20 61 6e 64 20 6d 61 70 70 69 6e 67 20 73 65  e and mapping se
2dc0: 63 74 69 6f 6e 20 74 6f 20 67 65 74 0a 2a 2a 20  ction to get.** 
2dd0: 74 68 65 20 63 6f 72 72 65 63 74 20 72 65 73 75  the correct resu
2de0: 6c 74 2e 20 20 54 68 65 72 65 20 6d 61 79 20 62  lt.  There may b
2df0: 65 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65  e entries in the
2e00: 20 68 61 73 68 20 74 61 62 6c 65 20 77 69 74 68   hash table with
2e10: 0a 2a 2a 20 4b 3e 4b 30 20 62 75 74 20 74 6f 20  .** K>K0 but to 
2e20: 74 68 65 20 66 69 72 73 74 20 72 65 61 64 65 72  the first reader
2e30: 2c 20 74 68 6f 73 65 20 65 6e 74 72 69 65 73 20  , those entries 
2e40: 77 69 6c 6c 20 61 70 70 65 61 72 20 74 6f 20 62  will appear to b
2e50: 65 20 75 6e 75 73 65 64 0a 2a 2a 20 73 6c 6f 74  e unused.** slot
2e60: 73 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61  s in the hash ta
2e70: 62 6c 65 20 61 6e 64 20 73 6f 20 74 68 65 20 66  ble and so the f
2e80: 69 72 73 74 20 72 65 61 64 65 72 20 77 69 6c 6c  irst reader will
2e90: 20 67 65 74 20 61 6e 20 61 6e 73 77 65 72 20 61   get an answer a
2ea0: 73 0a 2a 2a 20 69 66 20 6e 6f 20 76 61 6c 75 65  s.** if no value
2eb0: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 4b  s greater than K
2ec0: 30 20 68 61 64 20 65 76 65 72 20 62 65 65 6e 20  0 had ever been 
2ed0: 69 6e 73 65 72 74 65 64 20 69 6e 74 6f 20 74 68  inserted into th
2ee0: 65 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20  e hash table.** 
2ef0: 69 6e 20 74 68 65 20 66 69 72 73 74 20 70 6c 61  in the first pla
2f00: 63 65 20 2d 20 77 68 69 63 68 20 69 73 20 77 68  ce - which is wh
2f10: 61 74 20 72 65 61 64 65 72 20 6f 6e 65 20 77 61  at reader one wa
2f20: 6e 74 73 2e 20 20 4d 65 61 6e 77 68 69 6c 65 2c  nts.  Meanwhile,
2f30: 20 74 68 65 0a 2a 2a 20 73 65 63 6f 6e 64 20 72   the.** second r
2f40: 65 61 64 65 72 20 75 73 69 6e 67 20 4b 31 20 77  eader using K1 w
2f50: 69 6c 6c 20 73 65 65 20 61 64 64 69 74 69 6f 6e  ill see addition
2f60: 61 6c 20 76 61 6c 75 65 73 20 74 68 61 74 20 77  al values that w
2f70: 65 72 65 20 69 6e 73 65 72 74 65 64 0a 2a 2a 20  ere inserted.** 
2f80: 6c 61 74 65 72 2c 20 77 68 69 63 68 20 69 73 20  later, which is 
2f90: 65 78 61 63 74 6c 79 20 77 68 61 74 20 72 65 61  exactly what rea
2fa0: 64 65 72 20 74 77 6f 20 77 61 6e 74 73 2e 20 20  der two wants.  
2fb0: 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 61 20 72 6f  .**.** When a ro
2fc0: 6c 6c 62 61 63 6b 20 6f 63 63 75 72 73 2c 20 74  llback occurs, t
2fd0: 68 65 20 76 61 6c 75 65 20 6f 66 20 4b 20 69 73  he value of K is
2fe0: 20 64 65 63 72 65 61 73 65 64 2e 20 48 61 73 68   decreased. Hash
2ff0: 20 74 61 62 6c 65 20 65 6e 74 72 69 65 73 0a 2a   table entries.*
3000: 2a 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  * that correspon
3010: 64 20 74 6f 20 66 72 61 6d 65 73 20 67 72 65 61  d to frames grea
3020: 74 65 72 20 74 68 61 6e 20 74 68 65 20 6e 65 77  ter than the new
3030: 20 4b 20 76 61 6c 75 65 20 61 72 65 20 72 65 6d   K value are rem
3040: 6f 76 65 64 0a 2a 2a 20 66 72 6f 6d 20 74 68 65  oved.** from the
3050: 20 68 61 73 68 20 74 61 62 6c 65 20 61 74 20 74   hash table at t
3060: 68 69 73 20 70 6f 69 6e 74 2e 0a 2a 2f 0a 23 69  his point..*/.#i
3070: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
3080: 54 5f 57 41 4c 0a 0a 23 69 6e 63 6c 75 64 65 20  T_WAL..#include 
3090: 22 77 61 6c 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 54  "wal.h"../*.** T
30a0: 72 61 63 65 20 6f 75 74 70 75 74 20 6d 61 63 72  race output macr
30b0: 6f 73 0a 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65  os.*/.#if define
30c0: 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26  d(SQLITE_TEST) &
30d0: 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  & defined(SQLITE
30e0: 5f 44 45 42 55 47 29 0a 69 6e 74 20 73 71 6c 69  _DEBUG).int sqli
30f0: 74 65 33 57 61 6c 54 72 61 63 65 20 3d 20 30 3b  te3WalTrace = 0;
3100: 0a 23 20 64 65 66 69 6e 65 20 57 41 4c 54 52 41  .# define WALTRA
3110: 43 45 28 58 29 20 20 69 66 28 73 71 6c 69 74 65  CE(X)  if(sqlite
3120: 33 57 61 6c 54 72 61 63 65 29 20 73 71 6c 69 74  3WalTrace) sqlit
3130: 65 33 44 65 62 75 67 50 72 69 6e 74 66 20 58 0a  e3DebugPrintf X.
3140: 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 57  #else.# define W
3150: 41 4c 54 52 41 43 45 28 58 29 0a 23 65 6e 64 69  ALTRACE(X).#endi
3160: 66 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 78  f../*.** The max
3170: 69 6d 75 6d 20 28 61 6e 64 20 6f 6e 6c 79 29 20  imum (and only) 
3180: 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68 65 20  versions of the 
3190: 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65  wal and wal-inde
31a0: 78 20 66 6f 72 6d 61 74 73 0a 2a 2a 20 74 68 61  x formats.** tha
31b0: 74 20 6d 61 79 20 62 65 20 69 6e 74 65 72 70 72  t may be interpr
31c0: 65 74 65 64 20 62 79 20 74 68 69 73 20 76 65 72  eted by this ver
31d0: 73 69 6f 6e 20 6f 66 20 53 51 4c 69 74 65 2e 0a  sion of SQLite..
31e0: 2a 2a 0a 2a 2a 20 49 66 20 61 20 63 6c 69 65 6e  **.** If a clien
31f0: 74 20 62 65 67 69 6e 73 20 72 65 63 6f 76 65 72  t begins recover
3200: 69 6e 67 20 61 20 57 41 4c 20 66 69 6c 65 20 61  ing a WAL file a
3210: 6e 64 20 66 69 6e 64 73 20 74 68 61 74 20 28 61  nd finds that (a
3220: 29 20 74 68 65 20 63 68 65 63 6b 73 75 6d 0a 2a  ) the checksum.*
3230: 2a 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20  * values in the 
3240: 77 61 6c 2d 68 65 61 64 65 72 20 61 72 65 20 63  wal-header are c
3250: 6f 72 72 65 63 74 20 61 6e 64 20 28 62 29 20 74  orrect and (b) t
3260: 68 65 20 76 65 72 73 69 6f 6e 20 66 69 65 6c 64  he version field
3270: 20 69 73 20 6e 6f 74 0a 2a 2a 20 57 41 4c 5f 4d   is not.** WAL_M
3280: 41 58 5f 56 45 52 53 49 4f 4e 2c 20 72 65 63 6f  AX_VERSION, reco
3290: 76 65 72 79 20 66 61 69 6c 73 20 61 6e 64 20 53  very fails and S
32a0: 51 4c 69 74 65 20 72 65 74 75 72 6e 73 20 53 51  QLite returns SQ
32b0: 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2e 0a 2a  LITE_CANTOPEN..*
32c0: 2a 0a 2a 2a 20 53 69 6d 69 6c 61 72 6c 79 2c 20  *.** Similarly, 
32d0: 69 66 20 61 20 63 6c 69 65 6e 74 20 73 75 63 63  if a client succ
32e0: 65 73 73 66 75 6c 6c 79 20 72 65 61 64 73 20 61  essfully reads a
32f0: 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
3300: 72 20 28 69 2e 65 2e 20 74 68 65 20 0a 2a 2a 20  r (i.e. the .** 
3310: 63 68 65 63 6b 73 75 6d 20 74 65 73 74 20 69 73  checksum test is
3320: 20 73 75 63 63 65 73 73 66 75 6c 29 20 61 6e 64   successful) and
3330: 20 66 69 6e 64 73 20 74 68 61 74 20 74 68 65 20   finds that the 
3340: 76 65 72 73 69 6f 6e 20 66 69 65 6c 64 20 69 73  version field is
3350: 20 6e 6f 74 0a 2a 2a 20 57 41 4c 49 4e 44 45 58   not.** WALINDEX
3360: 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 2c 20 74 68  _MAX_VERSION, th
3370: 65 6e 20 6e 6f 20 72 65 61 64 2d 74 72 61 6e 73  en no read-trans
3380: 61 63 74 69 6f 6e 20 69 73 20 6f 70 65 6e 65 64  action is opened
3390: 20 61 6e 64 20 53 51 4c 69 74 65 0a 2a 2a 20 72   and SQLite.** r
33a0: 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 43 41  eturns SQLITE_CA
33b0: 4e 54 4f 50 45 4e 2e 0a 2a 2f 0a 23 64 65 66 69  NTOPEN..*/.#defi
33c0: 6e 65 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49  ne WAL_MAX_VERSI
33d0: 4f 4e 20 20 20 20 20 20 33 30 30 37 30 30 30 0a  ON      3007000.
33e0: 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58  #define WALINDEX
33f0: 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 20 33 30 30  _MAX_VERSION 300
3400: 37 30 30 30 0a 0a 2f 2a 0a 2a 2a 20 49 6e 64 69  7000../*.** Indi
3410: 63 65 73 20 6f 66 20 76 61 72 69 6f 75 73 20 6c  ces of various l
3420: 6f 63 6b 69 6e 67 20 62 79 74 65 73 2e 20 20 20  ocking bytes.   
3430: 57 41 4c 5f 4e 52 45 41 44 45 52 20 69 73 20 74  WAL_NREADER is t
3440: 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20  he number.** of 
3450: 61 76 61 69 6c 61 62 6c 65 20 72 65 61 64 65 72  available reader
3460: 20 6c 6f 63 6b 73 20 61 6e 64 20 73 68 6f 75 6c   locks and shoul
3470: 64 20 62 65 20 61 74 20 6c 65 61 73 74 20 33 2e  d be at least 3.
3480: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f  .*/.#define WAL_
3490: 57 52 49 54 45 5f 4c 4f 43 4b 20 20 20 20 20 20  WRITE_LOCK      
34a0: 20 20 20 30 0a 23 64 65 66 69 6e 65 20 57 41 4c     0.#define WAL
34b0: 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 20  _ALL_BUT_WRITE  
34c0: 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41      1.#define WA
34d0: 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 20 20 20 20  L_CKPT_LOCK     
34e0: 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57       1.#define W
34f0: 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20  AL_RECOVER_LOCK 
3500: 20 20 20 20 20 20 32 0a 23 64 65 66 69 6e 65 20        2.#define 
3510: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 49 29  WAL_READ_LOCK(I)
3520: 20 20 20 20 20 20 20 28 33 2b 28 49 29 29 0a 23         (3+(I)).#
3530: 64 65 66 69 6e 65 20 57 41 4c 5f 4e 52 45 41 44  define WAL_NREAD
3540: 45 52 20 20 20 20 20 20 20 20 20 20 20 20 28 53  ER            (S
3550: 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 2d  QLITE_SHM_NLOCK-
3560: 33 29 0a 0a 0a 2f 2a 20 4f 62 6a 65 63 74 20 64  3).../* Object d
3570: 65 63 6c 61 72 61 74 69 6f 6e 73 20 2a 2f 0a 74  eclarations */.t
3580: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61  ypedef struct Wa
3590: 6c 49 6e 64 65 78 48 64 72 20 57 61 6c 49 6e 64  lIndexHdr WalInd
35a0: 65 78 48 64 72 3b 0a 74 79 70 65 64 65 66 20 73  exHdr;.typedef s
35b0: 74 72 75 63 74 20 57 61 6c 49 74 65 72 61 74 6f  truct WalIterato
35c0: 72 20 57 61 6c 49 74 65 72 61 74 6f 72 3b 0a 74  r WalIterator;.t
35d0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61  ypedef struct Wa
35e0: 6c 43 6b 70 74 49 6e 66 6f 20 57 61 6c 43 6b 70  lCkptInfo WalCkp
35f0: 74 49 6e 66 6f 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54  tInfo;.../*.** T
3600: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a  he following obj
3610: 65 63 74 20 68 6f 6c 64 73 20 61 20 63 6f 70 79  ect holds a copy
3620: 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
3630: 78 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74  x header content
3640: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63 74 75  ..**.** The actu
3650: 61 6c 20 68 65 61 64 65 72 20 69 6e 20 74 68 65  al header in the
3660: 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69   wal-index consi
3670: 73 74 73 20 6f 66 20 74 77 6f 20 63 6f 70 69 65  sts of two copie
3680: 73 20 6f 66 20 74 68 69 73 0a 2a 2a 20 6f 62 6a  s of this.** obj
3690: 65 63 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57  ect..*/.struct W
36a0: 61 6c 49 6e 64 65 78 48 64 72 20 7b 0a 20 20 75  alIndexHdr {.  u
36b0: 33 32 20 69 56 65 72 73 69 6f 6e 3b 20 20 20 20  32 iVersion;    
36c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
36d0: 2a 20 57 61 6c 2d 69 6e 64 65 78 20 76 65 72 73  * Wal-index vers
36e0: 69 6f 6e 20 2a 2f 0a 20 20 75 33 32 20 75 6e 75  ion */.  u32 unu
36f0: 73 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  sed;            
3700: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 75 73           /* Unus
3710: 65 64 20 28 70 61 64 64 69 6e 67 29 20 66 69 65  ed (padding) fie
3720: 6c 64 20 2a 2f 0a 20 20 75 33 32 20 69 43 68 61  ld */.  u32 iCha
3730: 6e 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  nge;            
3740: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74          /* Count
3750: 65 72 20 69 6e 63 72 65 6d 65 6e 74 65 64 20 65  er incremented e
3760: 61 63 68 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ach transaction 
3770: 2a 2f 0a 20 20 75 38 20 69 73 49 6e 69 74 3b 20  */.  u8 isInit; 
3780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3790: 20 20 20 20 20 2f 2a 20 31 20 77 68 65 6e 20 69       /* 1 when i
37a0: 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20  nitialized */.  
37b0: 75 38 20 62 69 67 45 6e 64 43 6b 73 75 6d 3b 20  u8 bigEndCksum; 
37c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
37d0: 2f 2a 20 54 72 75 65 20 69 66 20 63 68 65 63 6b  /* True if check
37e0: 73 75 6d 73 20 69 6e 20 57 41 4c 20 61 72 65 20  sums in WAL are 
37f0: 62 69 67 2d 65 6e 64 69 61 6e 20 2a 2f 0a 20 20  big-endian */.  
3800: 75 31 36 20 73 7a 50 61 67 65 3b 20 20 20 20 20  u16 szPage;     
3810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3820: 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  /* Database page
3830: 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20 2a   size in bytes *
3840: 2f 0a 20 20 75 33 32 20 6d 78 46 72 61 6d 65 3b  /.  u32 mxFrame;
3850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3860: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20      /* Index of 
3870: 6c 61 73 74 20 76 61 6c 69 64 20 66 72 61 6d 65  last valid frame
3880: 20 69 6e 20 74 68 65 20 57 41 4c 20 2a 2f 0a 20   in the WAL */. 
3890: 20 75 33 32 20 6e 50 61 67 65 3b 20 20 20 20 20   u32 nPage;     
38a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38b0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 64 61 74 61   /* Size of data
38c0: 62 61 73 65 20 69 6e 20 70 61 67 65 73 20 2a 2f  base in pages */
38d0: 0a 20 20 75 33 32 20 61 46 72 61 6d 65 43 6b 73  .  u32 aFrameCks
38e0: 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  um[2];          
38f0: 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 6f     /* Checksum o
3900: 66 20 6c 61 73 74 20 66 72 61 6d 65 20 69 6e 20  f last frame in 
3910: 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 61 53 61  log */.  u32 aSa
3920: 6c 74 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  lt[2];          
3930: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 77 6f 20           /* Two 
3940: 73 61 6c 74 20 76 61 6c 75 65 73 20 63 6f 70 69  salt values copi
3950: 65 64 20 66 72 6f 6d 20 57 41 4c 20 68 65 61 64  ed from WAL head
3960: 65 72 20 2a 2f 0a 20 20 75 33 32 20 61 43 6b 73  er */.  u32 aCks
3970: 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  um[2];          
3980: 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b          /* Check
3990: 73 75 6d 20 6f 76 65 72 20 61 6c 6c 20 70 72 69  sum over all pri
39a0: 6f 72 20 66 69 65 6c 64 73 20 2a 2f 0a 7d 3b 0a  or fields */.};.
39b0: 0a 2f 2a 0a 2a 2a 20 41 20 63 6f 70 79 20 6f 66  ./*.** A copy of
39c0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f   the following o
39d0: 62 6a 65 63 74 20 6f 63 63 75 72 73 20 69 6e 20  bject occurs in 
39e0: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 6d  the wal-index im
39f0: 6d 65 64 69 61 74 65 6c 79 0a 2a 2a 20 66 6f 6c  mediately.** fol
3a00: 6c 6f 77 69 6e 67 20 74 68 65 20 73 65 63 6f 6e  lowing the secon
3a10: 64 20 63 6f 70 79 20 6f 66 20 74 68 65 20 57 61  d copy of the Wa
3a20: 6c 49 6e 64 65 78 48 64 72 2e 20 20 54 68 69 73  lIndexHdr.  This
3a30: 20 6f 62 6a 65 63 74 20 73 74 6f 72 65 73 0a 2a   object stores.*
3a40: 2a 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73  * information us
3a50: 65 64 20 62 79 20 63 68 65 63 6b 70 6f 69 6e 74  ed by checkpoint
3a60: 2e 0a 2a 2a 0a 2a 2a 20 6e 42 61 63 6b 66 69 6c  ..**.** nBackfil
3a70: 6c 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  l is the number 
3a80: 6f 66 20 66 72 61 6d 65 73 20 69 6e 20 74 68 65  of frames in the
3a90: 20 57 41 4c 20 74 68 61 74 20 68 61 76 65 20 62   WAL that have b
3aa0: 65 65 6e 20 77 72 69 74 74 65 6e 0a 2a 2a 20 62  een written.** b
3ab0: 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74  ack into the dat
3ac0: 61 62 61 73 65 2e 20 28 57 65 20 63 61 6c 6c 20  abase. (We call 
3ad0: 74 68 65 20 61 63 74 20 6f 66 20 6d 6f 76 69 6e  the act of movin
3ae0: 67 20 63 6f 6e 74 65 6e 74 20 66 72 6f 6d 20 57  g content from W
3af0: 41 4c 20 74 6f 0a 2a 2a 20 64 61 74 61 62 61 73  AL to.** databas
3b00: 65 20 22 62 61 63 6b 66 69 6c 6c 69 6e 67 22 2e  e "backfilling".
3b10: 29 20 20 54 68 65 20 6e 42 61 63 6b 66 69 6c 6c  )  The nBackfill
3b20: 20 6e 75 6d 62 65 72 20 69 73 20 6e 65 76 65 72   number is never
3b30: 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a   greater than.**
3b40: 20 57 61 6c 49 6e 64 65 78 48 64 72 2e 6d 78 46   WalIndexHdr.mxF
3b50: 72 61 6d 65 2e 20 20 6e 42 61 63 6b 66 69 6c 6c  rame.  nBackfill
3b60: 20 63 61 6e 20 6f 6e 6c 79 20 62 65 20 69 6e 63   can only be inc
3b70: 72 65 61 73 65 64 20 62 79 20 74 68 72 65 61 64  reased by thread
3b80: 73 0a 2a 2a 20 68 6f 6c 64 69 6e 67 20 74 68 65  s.** holding the
3b90: 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 6c   WAL_CKPT_LOCK l
3ba0: 6f 63 6b 20 28 77 68 69 63 68 20 69 6e 63 6c 75  ock (which inclu
3bb0: 64 65 73 20 61 20 72 65 63 6f 76 65 72 79 20 74  des a recovery t
3bc0: 68 72 65 61 64 29 2e 0a 2a 2a 20 48 6f 77 65 76  hread)..** Howev
3bd0: 65 72 2c 20 61 20 57 41 4c 5f 57 52 49 54 45 5f  er, a WAL_WRITE_
3be0: 4c 4f 43 4b 20 74 68 72 65 61 64 20 63 61 6e 20  LOCK thread can 
3bf0: 6d 6f 76 65 20 74 68 65 20 76 61 6c 75 65 20 6f  move the value o
3c00: 66 20 6e 42 61 63 6b 66 69 6c 6c 20 66 72 6f 6d  f nBackfill from
3c10: 0a 2a 2a 20 6d 78 46 72 61 6d 65 20 62 61 63 6b  .** mxFrame back
3c20: 20 74 6f 20 7a 65 72 6f 20 77 68 65 6e 20 74 68   to zero when th
3c30: 65 20 57 41 4c 20 69 73 20 72 65 73 65 74 2e 0a  e WAL is reset..
3c40: 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 69 73 20 6f  **.** There is o
3c50: 6e 65 20 65 6e 74 72 79 20 69 6e 20 61 52 65 61  ne entry in aRea
3c60: 64 4d 61 72 6b 5b 5d 20 66 6f 72 20 65 61 63 68  dMark[] for each
3c70: 20 72 65 61 64 65 72 20 6c 6f 63 6b 2e 20 20 49   reader lock.  I
3c80: 66 20 61 20 72 65 61 64 65 72 0a 2a 2a 20 68 6f  f a reader.** ho
3c90: 6c 64 73 20 72 65 61 64 2d 6c 6f 63 6b 20 4b 2c  lds read-lock K,
3ca0: 20 74 68 65 6e 20 74 68 65 20 76 61 6c 75 65 20   then the value 
3cb0: 69 6e 20 61 52 65 61 64 4d 61 72 6b 5b 4b 5d 20  in aReadMark[K] 
3cc0: 69 73 20 6e 6f 20 67 72 65 61 74 65 72 20 74 68  is no greater th
3cd0: 61 6e 0a 2a 2a 20 74 68 65 20 6d 78 46 72 61 6d  an.** the mxFram
3ce0: 65 20 66 6f 72 20 74 68 61 74 20 72 65 61 64 65  e for that reade
3cf0: 72 2e 20 20 54 68 65 20 76 61 6c 75 65 20 52 45  r.  The value RE
3d00: 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 20  ADMARK_NOT_USED 
3d10: 28 30 78 66 66 66 66 66 66 66 66 29 0a 2a 2a 20  (0xffffffff).** 
3d20: 66 6f 72 20 61 6e 79 20 61 52 65 61 64 4d 61 72  for any aReadMar
3d30: 6b 5b 5d 20 6d 65 61 6e 73 20 74 68 61 74 20 65  k[] means that e
3d40: 6e 74 72 79 20 69 73 20 75 6e 75 73 65 64 2e 20  ntry is unused. 
3d50: 20 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20 69 73   aReadMark[0] is
3d60: 20 0a 2a 2a 20 61 20 73 70 65 63 69 61 6c 20 63   .** a special c
3d70: 61 73 65 3b 20 69 74 73 20 76 61 6c 75 65 20 69  ase; its value i
3d80: 73 20 6e 65 76 65 72 20 75 73 65 64 20 61 6e 64  s never used and
3d90: 20 69 74 20 65 78 69 73 74 73 20 61 73 20 61 20   it exists as a 
3da0: 70 6c 61 63 65 2d 68 6f 6c 64 65 72 0a 2a 2a 20  place-holder.** 
3db0: 74 6f 20 61 76 6f 69 64 20 68 61 76 69 6e 67 20  to avoid having 
3dc0: 74 6f 20 6f 66 66 73 65 74 20 61 52 65 61 64 4d  to offset aReadM
3dd0: 61 72 6b 5b 5d 20 69 6e 64 65 78 73 20 62 79 20  ark[] indexs by 
3de0: 6f 6e 65 2e 20 20 52 65 61 64 65 72 73 20 68 6f  one.  Readers ho
3df0: 6c 64 69 6e 67 0a 2a 2a 20 57 41 4c 5f 52 45 41  lding.** WAL_REA
3e00: 44 5f 4c 4f 43 4b 28 30 29 20 61 6c 77 61 79 73  D_LOCK(0) always
3e10: 20 69 67 6e 6f 72 65 20 74 68 65 20 65 6e 74 69   ignore the enti
3e20: 72 65 20 57 41 4c 20 61 6e 64 20 72 65 61 64 20  re WAL and read 
3e30: 61 6c 6c 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 64  all content.** d
3e40: 69 72 65 63 74 6c 79 20 66 72 6f 6d 20 74 68 65  irectly from the
3e50: 20 64 61 74 61 62 61 73 65 2e 0a 2a 2a 0a 2a 2a   database..**.**
3e60: 20 54 68 65 20 76 61 6c 75 65 20 6f 66 20 61 52   The value of aR
3e70: 65 61 64 4d 61 72 6b 5b 4b 5d 20 6d 61 79 20 6f  eadMark[K] may o
3e80: 6e 6c 79 20 62 65 20 63 68 61 6e 67 65 64 20 62  nly be changed b
3e90: 79 20 61 20 74 68 72 65 61 64 20 74 68 61 74 0a  y a thread that.
3ea0: 2a 2a 20 69 73 20 68 6f 6c 64 69 6e 67 20 61 6e  ** is holding an
3eb0: 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20   exclusive lock 
3ec0: 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  on WAL_READ_LOCK
3ed0: 28 4b 29 2e 20 20 54 68 75 73 2c 20 74 68 65 20  (K).  Thus, the 
3ee0: 76 61 6c 75 65 20 6f 66 0a 2a 2a 20 61 52 65 61  value of.** aRea
3ef0: 64 4d 61 72 6b 5b 4b 5d 20 63 61 6e 6e 6f 74 20  dMark[K] cannot 
3f00: 63 68 61 6e 67 65 64 20 77 68 69 6c 65 20 74 68  changed while th
3f10: 65 72 65 20 69 73 20 61 20 72 65 61 64 65 72 20  ere is a reader 
3f20: 69 73 20 75 73 69 6e 67 20 74 68 61 74 20 6d 61  is using that ma
3f30: 72 6b 0a 2a 2a 20 73 69 6e 63 65 20 74 68 65 20  rk.** since the 
3f40: 72 65 61 64 65 72 20 77 69 6c 6c 20 62 65 20 68  reader will be h
3f50: 6f 6c 64 69 6e 67 20 61 20 73 68 61 72 65 64 20  olding a shared 
3f60: 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52 45 41 44  lock on WAL_READ
3f70: 5f 4c 4f 43 4b 28 4b 29 2e 0a 2a 2a 0a 2a 2a 20  _LOCK(K)..**.** 
3f80: 54 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 65 72  The checkpointer
3f90: 20 6d 61 79 20 6f 6e 6c 79 20 74 72 61 6e 73 66   may only transf
3fa0: 65 72 20 66 72 61 6d 65 73 20 66 72 6f 6d 20 57  er frames from W
3fb0: 41 4c 20 74 6f 20 64 61 74 61 62 61 73 65 20 77  AL to database w
3fc0: 68 65 72 65 0a 2a 2a 20 74 68 65 20 66 72 61 6d  here.** the fram
3fd0: 65 20 6e 75 6d 62 65 72 73 20 61 72 65 20 6c 65  e numbers are le
3fe0: 73 73 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c  ss than or equal
3ff0: 20 74 6f 20 65 76 65 72 79 20 61 52 65 61 64 4d   to every aReadM
4000: 61 72 6b 5b 5d 20 74 68 61 74 20 69 73 0a 2a 2a  ark[] that is.**
4010: 20 69 6e 20 75 73 65 20 28 74 68 61 74 20 69 73   in use (that is
4020: 2c 20 65 76 65 72 79 20 61 52 65 61 64 4d 61 72  , every aReadMar
4030: 6b 5b 6a 5d 20 66 6f 72 20 77 68 69 63 68 20 74  k[j] for which t
4040: 68 65 72 65 20 69 73 20 61 20 63 6f 72 72 65 73  here is a corres
4050: 70 6f 6e 64 69 6e 67 0a 2a 2a 20 57 41 4c 5f 52  ponding.** WAL_R
4060: 45 41 44 5f 4c 4f 43 4b 28 6a 29 29 2e 20 20 4e  EAD_LOCK(j)).  N
4070: 65 77 20 72 65 61 64 65 72 73 20 28 75 73 75 61  ew readers (usua
4080: 6c 6c 79 29 20 70 69 63 6b 20 74 68 65 20 61 52  lly) pick the aR
4090: 65 61 64 4d 61 72 6b 5b 5d 20 77 69 74 68 20 74  eadMark[] with t
40a0: 68 65 0a 2a 2a 20 6c 61 72 67 65 73 74 20 76 61  he.** largest va
40b0: 6c 75 65 20 61 6e 64 20 77 69 6c 6c 20 69 6e 63  lue and will inc
40c0: 72 65 61 73 65 20 61 6e 20 75 6e 75 73 65 64 20  rease an unused 
40d0: 61 52 65 61 64 4d 61 72 6b 5b 5d 20 74 6f 20 6d  aReadMark[] to m
40e0: 78 46 72 61 6d 65 20 69 66 20 74 68 65 72 65 0a  xFrame if there.
40f0: 2a 2a 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  ** is not alread
4100: 79 20 61 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d  y an aReadMark[]
4110: 20 65 71 75 61 6c 20 74 6f 20 6d 78 46 72 61 6d   equal to mxFram
4120: 65 2e 20 20 54 68 65 20 65 78 63 65 70 74 69 6f  e.  The exceptio
4130: 6e 20 74 6f 20 74 68 65 0a 2a 2a 20 70 72 65 76  n to the.** prev
4140: 69 6f 75 73 20 73 65 6e 74 65 6e 63 65 20 69 73  ious sentence is
4150: 20 77 68 65 6e 20 6e 42 61 63 6b 66 69 6c 6c 20   when nBackfill 
4160: 65 71 75 61 6c 73 20 6d 78 46 72 61 6d 65 20 28  equals mxFrame (
4170: 6d 65 61 6e 69 6e 67 20 74 68 61 74 20 65 76 65  meaning that eve
4180: 72 79 74 68 69 6e 67 0a 2a 2a 20 69 6e 20 74 68  rything.** in th
4190: 65 20 57 41 4c 20 68 61 73 20 62 65 65 6e 20 62  e WAL has been b
41a0: 61 63 6b 66 69 6c 6c 65 64 20 69 6e 74 6f 20 74  ackfilled into t
41b0: 68 65 20 64 61 74 61 62 61 73 65 29 20 74 68 65  he database) the
41c0: 6e 20 6e 65 77 20 72 65 61 64 65 72 73 0a 2a 2a  n new readers.**
41d0: 20 77 69 6c 6c 20 63 68 6f 6f 73 65 20 61 52 65   will choose aRe
41e0: 61 64 4d 61 72 6b 5b 30 5d 20 77 68 69 63 68 20  adMark[0] which 
41f0: 68 61 73 20 76 61 6c 75 65 20 30 20 61 6e 64 20  has value 0 and 
4200: 68 65 6e 63 65 20 73 75 63 68 20 72 65 61 64 65  hence such reade
4210: 72 20 77 69 6c 6c 0a 2a 2a 20 67 65 74 20 61 6c  r will.** get al
4220: 6c 20 74 68 65 69 72 20 61 6c 6c 20 63 6f 6e 74  l their all cont
4230: 65 6e 74 20 64 69 72 65 63 74 6c 79 20 66 72 6f  ent directly fro
4240: 6d 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  m the database f
4250: 69 6c 65 20 61 6e 64 20 69 67 6e 6f 72 65 20 0a  ile and ignore .
4260: 2a 2a 20 74 68 65 20 57 41 4c 2e 0a 2a 2a 0a 2a  ** the WAL..**.*
4270: 2a 20 57 72 69 74 65 72 73 20 6e 6f 72 6d 61 6c  * Writers normal
4280: 6c 79 20 61 70 70 65 6e 64 20 6e 65 77 20 66 72  ly append new fr
4290: 61 6d 65 73 20 74 6f 20 74 68 65 20 65 6e 64 20  ames to the end 
42a0: 6f 66 20 74 68 65 20 57 41 4c 2e 20 20 48 6f 77  of the WAL.  How
42b0: 65 76 65 72 2c 0a 2a 2a 20 69 66 20 6e 42 61 63  ever,.** if nBac
42c0: 6b 66 69 6c 6c 20 65 71 75 61 6c 73 20 6d 78 46  kfill equals mxF
42d0: 72 61 6d 65 20 28 6d 65 61 6e 69 6e 67 20 74 68  rame (meaning th
42e0: 61 74 20 61 6c 6c 20 57 41 4c 20 63 6f 6e 74 65  at all WAL conte
42f0: 6e 74 20 68 61 73 20 62 65 65 6e 0a 2a 2a 20 77  nt has been.** w
4300: 72 69 74 74 65 6e 20 62 61 63 6b 20 69 6e 74 6f  ritten back into
4310: 20 74 68 65 20 64 61 74 61 62 61 73 65 29 20 61   the database) a
4320: 6e 64 20 69 66 20 6e 6f 20 72 65 61 64 65 72 73  nd if no readers
4330: 20 61 72 65 20 75 73 69 6e 67 20 74 68 65 20 57   are using the W
4340: 41 4c 0a 2a 2a 20 28 69 6e 20 6f 74 68 65 72 20  AL.** (in other 
4350: 77 6f 72 64 73 2c 20 69 66 20 74 68 65 72 65 20  words, if there 
4360: 61 72 65 20 6e 6f 20 57 41 4c 5f 52 45 41 44 5f  are no WAL_READ_
4370: 4c 4f 43 4b 28 69 29 20 77 68 65 72 65 20 69 3e  LOCK(i) where i>
4380: 30 29 20 74 68 65 6e 0a 2a 2a 20 74 68 65 20 77  0) then.** the w
4390: 72 69 74 65 72 20 77 69 6c 6c 20 66 69 72 73 74  riter will first
43a0: 20 22 72 65 73 65 74 22 20 74 68 65 20 57 41 4c   "reset" the WAL
43b0: 20 62 61 63 6b 20 74 6f 20 74 68 65 20 62 65 67   back to the beg
43c0: 69 6e 6e 69 6e 67 20 61 6e 64 20 73 74 61 72 74  inning and start
43d0: 0a 2a 2a 20 77 72 69 74 69 6e 67 20 6e 65 77 20  .** writing new 
43e0: 63 6f 6e 74 65 6e 74 20 62 65 67 69 6e 6e 69 6e  content beginnin
43f0: 67 20 61 74 20 66 72 61 6d 65 20 31 2e 0a 2a 2a  g at frame 1..**
4400: 0a 2a 2a 20 57 65 20 61 73 73 75 6d 65 20 74 68  .** We assume th
4410: 61 74 20 33 32 2d 62 69 74 20 6c 6f 61 64 73 20  at 32-bit loads 
4420: 61 72 65 20 61 74 6f 6d 69 63 20 61 6e 64 20 73  are atomic and s
4430: 6f 20 6e 6f 20 6c 6f 63 6b 73 20 61 72 65 20 6e  o no locks are n
4440: 65 65 64 65 64 20 69 6e 0a 2a 2a 20 6f 72 64 65  eeded in.** orde
4450: 72 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 61  r to read from a
4460: 6e 79 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65  ny aReadMark[] e
4470: 6e 74 72 69 65 73 2e 0a 2a 2f 0a 73 74 72 75 63  ntries..*/.struc
4480: 74 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 7b 0a  t WalCkptInfo {.
4490: 20 20 75 33 32 20 6e 42 61 63 6b 66 69 6c 6c 3b    u32 nBackfill;
44a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
44b0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 57    /* Number of W
44c0: 41 4c 20 66 72 61 6d 65 73 20 62 61 63 6b 66 69  AL frames backfi
44d0: 6c 6c 65 64 20 69 6e 74 6f 20 44 42 20 2a 2f 0a  lled into DB */.
44e0: 20 20 75 33 32 20 61 52 65 61 64 4d 61 72 6b 5b    u32 aReadMark[
44f0: 57 41 4c 5f 4e 52 45 41 44 45 52 5d 3b 20 20 20  WAL_NREADER];   
4500: 20 20 2f 2a 20 52 65 61 64 65 72 20 6d 61 72 6b    /* Reader mark
4510: 73 20 2a 2f 0a 7d 3b 0a 23 64 65 66 69 6e 65 20  s */.};.#define 
4520: 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45  READMARK_NOT_USE
4530: 44 20 20 30 78 66 66 66 66 66 66 66 66 0a 0a 0a  D  0xffffffff...
4540: 2f 2a 20 41 20 62 6c 6f 63 6b 20 6f 66 20 57 41  /* A block of WA
4550: 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 52 45 53 45  LINDEX_LOCK_RESE
4560: 52 56 45 44 20 62 79 74 65 73 20 62 65 67 69 6e  RVED bytes begin
4570: 6e 69 6e 67 20 61 74 0a 2a 2a 20 57 41 4c 49 4e  ning at.** WALIN
4580: 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20  DEX_LOCK_OFFSET 
4590: 69 73 20 72 65 73 65 72 76 65 64 20 66 6f 72 20  is reserved for 
45a0: 6c 6f 63 6b 73 2e 20 53 69 6e 63 65 20 73 6f 6d  locks. Since som
45b0: 65 20 73 79 73 74 65 6d 73 0a 2a 2a 20 6f 6e 6c  e systems.** onl
45c0: 79 20 73 75 70 70 6f 72 74 20 6d 61 6e 64 61 74  y support mandat
45d0: 6f 72 79 20 66 69 6c 65 2d 6c 6f 63 6b 73 2c 20  ory file-locks, 
45e0: 77 65 20 64 6f 20 6e 6f 74 20 72 65 61 64 20 6f  we do not read o
45f0: 72 20 77 72 69 74 65 20 64 61 74 61 0a 2a 2a 20  r write data.** 
4600: 66 72 6f 6d 20 74 68 65 20 72 65 67 69 6f 6e 20  from the region 
4610: 6f 66 20 74 68 65 20 66 69 6c 65 20 6f 6e 20 77  of the file on w
4620: 68 69 63 68 20 6c 6f 63 6b 73 20 61 72 65 20 61  hich locks are a
4630: 70 70 6c 69 65 64 2e 0a 2a 2f 0a 23 64 65 66 69  pplied..*/.#defi
4640: 6e 65 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b  ne WALINDEX_LOCK
4650: 5f 4f 46 46 53 45 54 20 20 20 28 73 69 7a 65 6f  _OFFSET   (sizeo
4660: 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 2a 32  f(WalIndexHdr)*2
4670: 20 2b 20 73 69 7a 65 6f 66 28 57 61 6c 43 6b 70   + sizeof(WalCkp
4680: 74 49 6e 66 6f 29 29 0a 23 64 65 66 69 6e 65 20  tInfo)).#define 
4690: 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 52 45  WALINDEX_LOCK_RE
46a0: 53 45 52 56 45 44 20 31 36 0a 23 64 65 66 69 6e  SERVED 16.#defin
46b0: 65 20 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53  e WALINDEX_HDR_S
46c0: 49 5a 45 20 20 20 20 20 20 28 57 41 4c 49 4e 44  IZE      (WALIND
46d0: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 2b 57  EX_LOCK_OFFSET+W
46e0: 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 52 45 53  ALINDEX_LOCK_RES
46f0: 45 52 56 45 44 29 0a 0a 2f 2a 20 53 69 7a 65 20  ERVED)../* Size 
4700: 6f 66 20 68 65 61 64 65 72 20 62 65 66 6f 72 65  of header before
4710: 20 65 61 63 68 20 66 72 61 6d 65 20 69 6e 20 77   each frame in w
4720: 61 6c 20 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41  al */.#define WA
4730: 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 20  L_FRAME_HDRSIZE 
4740: 32 34 0a 0a 2f 2a 20 53 69 7a 65 20 6f 66 20 77  24../* Size of w
4750: 72 69 74 65 20 61 68 65 61 64 20 6c 6f 67 20 68  rite ahead log h
4760: 65 61 64 65 72 2c 20 69 6e 63 6c 75 64 69 6e 67  eader, including
4770: 20 63 68 65 63 6b 73 75 6d 2e 20 2a 2f 0a 2f 2a   checksum. */./*
4780: 20 23 64 65 66 69 6e 65 20 57 41 4c 5f 48 44 52   #define WAL_HDR
4790: 53 49 5a 45 20 32 34 20 2a 2f 0a 23 64 65 66 69  SIZE 24 */.#defi
47a0: 6e 65 20 57 41 4c 5f 48 44 52 53 49 5a 45 20 33  ne WAL_HDRSIZE 3
47b0: 32 0a 0a 2f 2a 20 57 41 4c 20 6d 61 67 69 63 20  2../* WAL magic 
47c0: 76 61 6c 75 65 2e 20 45 69 74 68 65 72 20 74 68  value. Either th
47d0: 69 73 20 76 61 6c 75 65 2c 20 6f 72 20 74 68 65  is value, or the
47e0: 20 73 61 6d 65 20 76 61 6c 75 65 20 77 69 74 68   same value with
47f0: 20 74 68 65 20 6c 65 61 73 74 0a 2a 2a 20 73 69   the least.** si
4800: 67 6e 69 66 69 63 61 6e 74 20 62 69 74 20 61 6c  gnificant bit al
4810: 73 6f 20 73 65 74 20 28 57 41 4c 5f 4d 41 47 49  so set (WAL_MAGI
4820: 43 20 7c 20 30 78 30 30 30 30 30 30 30 31 29 20  C | 0x00000001) 
4830: 69 73 20 73 74 6f 72 65 64 20 69 6e 20 33 32 2d  is stored in 32-
4840: 62 69 74 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61  bit.** big-endia
4850: 6e 20 66 6f 72 6d 61 74 20 69 6e 20 74 68 65 20  n format in the 
4860: 66 69 72 73 74 20 34 20 62 79 74 65 73 20 6f 66  first 4 bytes of
4870: 20 61 20 57 41 4c 20 66 69 6c 65 2e 0a 2a 2a 0a   a WAL file..**.
4880: 2a 2a 20 49 66 20 74 68 65 20 4c 53 42 20 69 73  ** If the LSB is
4890: 20 73 65 74 2c 20 74 68 65 6e 20 74 68 65 20 63   set, then the c
48a0: 68 65 63 6b 73 75 6d 73 20 66 6f 72 20 65 61 63  hecksums for eac
48b0: 68 20 66 72 61 6d 65 20 77 69 74 68 69 6e 20 74  h frame within t
48c0: 68 65 20 57 41 4c 0a 2a 2a 20 66 69 6c 65 20 61  he WAL.** file a
48d0: 72 65 20 63 61 6c 63 75 6c 61 74 65 64 20 62 79  re calculated by
48e0: 20 74 72 65 61 74 69 6e 67 20 61 6c 6c 20 64 61   treating all da
48f0: 74 61 20 61 73 20 61 6e 20 61 72 72 61 79 20 6f  ta as an array o
4900: 66 20 33 32 2d 62 69 74 20 0a 2a 2a 20 62 69 67  f 32-bit .** big
4910: 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73 2e 20 4f  -endian words. O
4920: 74 68 65 72 77 69 73 65 2c 20 74 68 65 79 20 61  therwise, they a
4930: 72 65 20 63 61 6c 63 75 6c 61 74 65 64 20 62 79  re calculated by
4940: 20 69 6e 74 65 72 70 72 65 74 69 6e 67 20 0a 2a   interpreting .*
4950: 2a 20 61 6c 6c 20 64 61 74 61 20 61 73 20 33 32  * all data as 32
4960: 2d 62 69 74 20 6c 69 74 74 6c 65 2d 65 6e 64 69  -bit little-endi
4970: 61 6e 20 77 6f 72 64 73 2e 0a 2a 2f 0a 23 64 65  an words..*/.#de
4980: 66 69 6e 65 20 57 41 4c 5f 4d 41 47 49 43 20 30  fine WAL_MAGIC 0
4990: 78 33 37 37 66 30 36 38 32 0a 0a 2f 2a 0a 2a 2a  x377f0682../*.**
49a0: 20 52 65 74 75 72 6e 20 74 68 65 20 6f 66 66 73   Return the offs
49b0: 65 74 20 6f 66 20 66 72 61 6d 65 20 69 46 72 61  et of frame iFra
49c0: 6d 65 20 69 6e 20 74 68 65 20 77 72 69 74 65 2d  me in the write-
49d0: 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65 2c 20  ahead log file, 
49e0: 0a 2a 2a 20 61 73 73 75 6d 69 6e 67 20 61 20 64  .** assuming a d
49f0: 61 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a  atabase page siz
4a00: 65 20 6f 66 20 73 7a 50 61 67 65 20 62 79 74 65  e of szPage byte
4a10: 73 2e 20 54 68 65 20 6f 66 66 73 65 74 20 72 65  s. The offset re
4a20: 74 75 72 6e 65 64 0a 2a 2a 20 69 73 20 74 6f 20  turned.** is to 
4a30: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
4a40: 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67   write-ahead log
4a50: 20 66 72 61 6d 65 2d 68 65 61 64 65 72 2e 0a 2a   frame-header..*
4a60: 2f 0a 23 64 65 66 69 6e 65 20 77 61 6c 46 72 61  /.#define walFra
4a70: 6d 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2c  meOffset(iFrame,
4a80: 20 73 7a 50 61 67 65 29 20 28 20 20 20 20 20 20   szPage) (      
4a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4aa0: 20 20 20 20 20 20 20 20 20 5c 0a 20 20 57 41 4c           \.  WAL
4ab0: 5f 48 44 52 53 49 5a 45 20 2b 20 28 28 69 46 72  _HDRSIZE + ((iFr
4ac0: 61 6d 65 29 2d 31 29 2a 28 28 73 7a 50 61 67 65  ame)-1)*((szPage
4ad0: 29 2b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  )+WAL_FRAME_HDRS
4ae0: 49 5a 45 29 20 20 20 20 20 20 20 20 5c 0a 29 0a  IZE)        \.).
4af0: 0a 2f 2a 0a 2a 2a 20 41 6e 20 6f 70 65 6e 20 77  ./*.** An open w
4b00: 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66  rite-ahead log f
4b10: 69 6c 65 20 69 73 20 72 65 70 72 65 73 65 6e 74  ile is represent
4b20: 65 64 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63  ed by an instanc
4b30: 65 20 6f 66 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c  e of the.** foll
4b40: 6f 77 69 6e 67 20 6f 62 6a 65 63 74 2e 0a 2a 2f  owing object..*/
4b50: 0a 73 74 72 75 63 74 20 57 61 6c 20 7b 0a 20 20  .struct Wal {.  
4b60: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
4b70: 73 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68  s;         /* Th
4b80: 65 20 56 46 53 20 75 73 65 64 20 74 6f 20 63 72  e VFS used to cr
4b90: 65 61 74 65 20 70 44 62 46 64 20 2a 2f 0a 20 20  eate pDbFd */.  
4ba0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 44  sqlite3_file *pD
4bb0: 62 46 64 3b 20 20 20 20 20 20 20 2f 2a 20 46 69  bFd;       /* Fi
4bc0: 6c 65 20 68 61 6e 64 6c 65 20 66 6f 72 20 74 68  le handle for th
4bd0: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  e database file 
4be0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  */.  sqlite3_fil
4bf0: 65 20 2a 70 57 61 6c 46 64 3b 20 20 20 20 20 20  e *pWalFd;      
4c00: 2f 2a 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 66  /* File handle f
4c10: 6f 72 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20  or WAL file */. 
4c20: 20 75 33 32 20 69 43 61 6c 6c 62 61 63 6b 3b 20   u32 iCallback; 
4c30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56              /* V
4c40: 61 6c 75 65 20 74 6f 20 70 61 73 73 20 74 6f 20  alue to pass to 
4c50: 6c 6f 67 20 63 61 6c 6c 62 61 63 6b 20 28 6f 72  log callback (or
4c60: 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 57 69   0) */.  int nWi
4c70: 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
4c80: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61      /* Size of a
4c90: 72 72 61 79 20 61 70 57 69 44 61 74 61 20 2a 2f  rray apWiData */
4ca0: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20  .  volatile u32 
4cb0: 2a 2a 61 70 57 69 44 61 74 61 3b 20 20 20 2f 2a  **apWiData;   /*
4cc0: 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 61 6c 2d   Pointer to wal-
4cd0: 69 6e 64 65 78 20 63 6f 6e 74 65 6e 74 20 69 6e  index content in
4ce0: 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 75 31 36   memory */.  u16
4cf0: 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20   szPage;        
4d00: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
4d10: 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f  ase page size */
4d20: 0a 20 20 69 31 36 20 72 65 61 64 4c 6f 63 6b 3b  .  i16 readLock;
4d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4d40: 20 57 68 69 63 68 20 72 65 61 64 20 6c 6f 63 6b   Which read lock
4d50: 20 69 73 20 62 65 69 6e 67 20 68 65 6c 64 2e 20   is being held. 
4d60: 20 2d 31 20 66 6f 72 20 6e 6f 6e 65 20 2a 2f 0a   -1 for none */.
4d70: 20 20 75 38 20 65 78 63 6c 75 73 69 76 65 4d 6f    u8 exclusiveMo
4d80: 64 65 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20  de;          /* 
4d90: 4e 6f 6e 2d 7a 65 72 6f 20 69 66 20 63 6f 6e 6e  Non-zero if conn
4da0: 65 63 74 69 6f 6e 20 69 73 20 69 6e 20 65 78 63  ection is in exc
4db0: 6c 75 73 69 76 65 20 6d 6f 64 65 20 2a 2f 0a 20  lusive mode */. 
4dc0: 20 75 38 20 69 73 57 49 6e 64 65 78 4f 70 65 6e   u8 isWIndexOpen
4dd0: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54  ;           /* T
4de0: 72 75 65 20 69 66 20 53 68 6d 4f 70 65 6e 28 29  rue if ShmOpen()
4df0: 20 63 61 6c 6c 65 64 20 6f 6e 20 70 44 62 46 64   called on pDbFd
4e00: 20 2a 2f 0a 20 20 75 38 20 77 72 69 74 65 4c 6f   */.  u8 writeLo
4e10: 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ck;             
4e20: 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 20 61   /* True if in a
4e30: 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69   write transacti
4e40: 6f 6e 20 2a 2f 0a 20 20 75 38 20 63 6b 70 74 4c  on */.  u8 ckptL
4e50: 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ock;            
4e60: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 68 6f     /* True if ho
4e70: 6c 64 69 6e 67 20 61 20 63 68 65 63 6b 70 6f 69  lding a checkpoi
4e80: 6e 74 20 6c 6f 63 6b 20 2a 2f 0a 20 20 57 61 6c  nt lock */.  Wal
4e90: 49 6e 64 65 78 48 64 72 20 68 64 72 3b 20 20 20  IndexHdr hdr;   
4ea0: 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 2d 69          /* Wal-i
4eb0: 6e 64 65 78 20 68 65 61 64 65 72 20 66 6f 72 20  ndex header for 
4ec0: 63 75 72 72 65 6e 74 20 74 72 61 6e 73 61 63 74  current transact
4ed0: 69 6f 6e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a  ion */.  char *z
4ee0: 57 61 6c 4e 61 6d 65 3b 20 20 20 20 20 20 20 20  WalName;        
4ef0: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 57      /* Name of W
4f00: 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32  AL file */.  u32
4f10: 20 6e 43 6b 70 74 3b 20 20 20 20 20 20 20 20 20   nCkpt;         
4f20: 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b          /* Check
4f30: 70 6f 69 6e 74 20 73 65 71 75 65 6e 63 65 20 63  point sequence c
4f40: 6f 75 6e 74 65 72 20 69 6e 20 74 68 65 20 77 61  ounter in the wa
4f50: 6c 2d 68 65 61 64 65 72 20 2a 2f 0a 23 69 66 64  l-header */.#ifd
4f60: 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47 0a  ef SQLITE_DEBUG.
4f70: 20 20 75 38 20 6c 6f 63 6b 45 72 72 6f 72 3b 20    u8 lockError; 
4f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4f90: 54 72 75 65 20 69 66 20 61 20 6c 6f 63 6b 69 6e  True if a lockin
4fa0: 67 20 65 72 72 6f 72 20 68 61 73 20 6f 63 63 75  g error has occu
4fb0: 72 72 65 64 20 2a 2f 0a 23 65 6e 64 69 66 0a 7d  rred */.#endif.}
4fc0: 3b 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 70 61  ;../*.** Each pa
4fd0: 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ge of the wal-in
4fe0: 64 65 78 20 6d 61 70 70 69 6e 67 20 63 6f 6e 74  dex mapping cont
4ff0: 61 69 6e 73 20 61 20 68 61 73 68 2d 74 61 62 6c  ains a hash-tabl
5000: 65 20 6d 61 64 65 20 75 70 20 6f 66 0a 2a 2a 20  e made up of.** 
5010: 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53 48  an array of HASH
5020: 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 65 6c 65 6d  TABLE_NSLOT elem
5030: 65 6e 74 73 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ents of the foll
5040: 6f 77 69 6e 67 20 74 79 70 65 2e 0a 2a 2f 0a 74  owing type..*/.t
5050: 79 70 65 64 65 66 20 75 31 36 20 68 74 5f 73 6c  ypedef u16 ht_sl
5060: 6f 74 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ot;../*.** This 
5070: 73 74 72 75 63 74 75 72 65 20 69 73 20 75 73 65  structure is use
5080: 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 61  d to implement a
5090: 6e 20 69 74 65 72 61 74 6f 72 20 74 68 61 74 20  n iterator that 
50a0: 6c 6f 6f 70 73 20 74 68 72 6f 75 67 68 0a 2a 2a  loops through.**
50b0: 20 61 6c 6c 20 66 72 61 6d 65 73 20 69 6e 20 74   all frames in t
50c0: 68 65 20 57 41 4c 20 69 6e 20 64 61 74 61 62 61  he WAL in databa
50d0: 73 65 20 70 61 67 65 20 6f 72 64 65 72 2e 20 57  se page order. W
50e0: 68 65 72 65 20 74 77 6f 20 6f 72 20 6d 6f 72 65  here two or more
50f0: 20 66 72 61 6d 65 73 0a 2a 2a 20 63 6f 72 72 65   frames.** corre
5100: 73 70 6f 6e 64 20 74 6f 20 74 68 65 20 73 61 6d  spond to the sam
5110: 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65 2c  e database page,
5120: 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 76 69   the iterator vi
5130: 73 69 74 73 20 6f 6e 6c 79 20 74 68 65 20 0a 2a  sits only the .*
5140: 2a 20 66 72 61 6d 65 20 6d 6f 73 74 20 72 65 63  * frame most rec
5150: 65 6e 74 6c 79 20 77 72 69 74 74 65 6e 20 74 6f  ently written to
5160: 20 74 68 65 20 57 41 4c 20 28 69 6e 20 6f 74 68   the WAL (in oth
5170: 65 72 20 77 6f 72 64 73 2c 20 74 68 65 20 66 72  er words, the fr
5180: 61 6d 65 20 77 69 74 68 0a 2a 2a 20 74 68 65 20  ame with.** the 
5190: 6c 61 72 67 65 73 74 20 69 6e 64 65 78 29 2e 0a  largest index)..
51a0: 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e 74 65 72 6e  **.** The intern
51b0: 61 6c 73 20 6f 66 20 74 68 69 73 20 73 74 72 75  als of this stru
51c0: 63 74 75 72 65 20 61 72 65 20 6f 6e 6c 79 20 61  cture are only a
51d0: 63 63 65 73 73 65 64 20 62 79 3a 0a 2a 2a 0a 2a  ccessed by:.**.*
51e0: 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f 72 49  *   walIteratorI
51f0: 6e 69 74 28 29 20 2d 20 43 72 65 61 74 65 20 61  nit() - Create a
5200: 20 6e 65 77 20 69 74 65 72 61 74 6f 72 2c 0a 2a   new iterator,.*
5210: 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f 72 4e  *   walIteratorN
5220: 65 78 74 28 29 20 2d 20 53 74 65 70 20 61 6e 20  ext() - Step an 
5230: 69 74 65 72 61 74 6f 72 2c 0a 2a 2a 20 20 20 77  iterator,.**   w
5240: 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28 29  alIteratorFree()
5250: 20 2d 20 46 72 65 65 20 61 6e 20 69 74 65 72 61   - Free an itera
5260: 74 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  tor..**.** This 
5270: 66 75 6e 63 74 69 6f 6e 61 6c 69 74 79 20 69 73  functionality is
5280: 20 75 73 65 64 20 62 79 20 74 68 65 20 63 68 65   used by the che
5290: 63 6b 70 6f 69 6e 74 20 63 6f 64 65 20 28 73 65  ckpoint code (se
52a0: 65 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28  e walCheckpoint(
52b0: 29 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61  ))..*/.struct Wa
52c0: 6c 49 74 65 72 61 74 6f 72 20 7b 0a 20 20 69 6e  lIterator {.  in
52d0: 74 20 69 50 72 69 6f 72 3b 20 20 20 20 20 20 20  t iPrior;       
52e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
52f0: 20 4c 61 73 74 20 72 65 73 75 6c 74 20 72 65 74   Last result ret
5300: 75 72 6e 65 64 20 66 72 6f 6d 20 74 68 65 20 69  urned from the i
5310: 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74  terator */.  int
5320: 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20 20 20 20   nSegment;      
5330: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5340: 53 69 7a 65 20 6f 66 20 74 68 65 20 61 53 65 67  Size of the aSeg
5350: 6d 65 6e 74 5b 5d 20 61 72 72 61 79 20 2a 2f 0a  ment[] array */.
5360: 20 20 73 74 72 75 63 74 20 57 61 6c 53 65 67 6d    struct WalSegm
5370: 65 6e 74 20 7b 0a 20 20 20 20 69 6e 74 20 69 4e  ent {.    int iN
5380: 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ext;            
5390: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
53a0: 73 6c 6f 74 20 69 6e 20 61 49 6e 64 65 78 5b 5d  slot in aIndex[]
53b0: 20 6e 6f 74 20 79 65 74 20 72 65 74 75 72 6e 65   not yet returne
53c0: 64 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74  d */.    ht_slot
53d0: 20 2a 61 49 6e 64 65 78 3b 20 20 20 20 20 20 20   *aIndex;       
53e0: 20 20 20 20 20 20 20 2f 2a 20 69 30 2c 20 69 31         /* i0, i1
53f0: 2c 20 69 32 2e 2e 2e 20 73 75 63 68 20 74 68 61  , i2... such tha
5400: 74 20 61 50 67 6e 6f 5b 69 4e 5d 20 61 73 63 65  t aPgno[iN] asce
5410: 6e 64 20 2a 2f 0a 20 20 20 20 75 33 32 20 2a 61  nd */.    u32 *a
5420: 50 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20  Pgno;           
5430: 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79          /* Array
5440: 20 6f 66 20 70 61 67 65 20 6e 75 6d 62 65 72 73   of page numbers
5450: 2e 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 45 6e  . */.    int nEn
5460: 74 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  try;            
5470: 20 20 20 20 20 20 20 2f 2a 20 4d 61 78 20 73 69         /* Max si
5480: 7a 65 20 6f 66 20 61 50 67 6e 6f 5b 5d 20 61 6e  ze of aPgno[] an
5490: 64 20 61 49 6e 64 65 78 5b 5d 20 61 72 72 61 79  d aIndex[] array
54a0: 73 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 5a 65  s */.    int iZe
54b0: 72 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ro;             
54c0: 20 20 20 20 20 20 20 2f 2a 20 46 72 61 6d 65 20         /* Frame 
54d0: 6e 75 6d 62 65 72 20 61 73 73 6f 63 69 61 74 65  number associate
54e0: 64 20 77 69 74 68 20 61 50 67 6e 6f 5b 30 5d 20  d with aPgno[0] 
54f0: 2a 2f 0a 20 20 7d 20 61 53 65 67 6d 65 6e 74 5b  */.  } aSegment[
5500: 31 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  1];             
5510: 20 20 20 20 20 2f 2a 20 4f 6e 65 20 66 6f 72 20       /* One for 
5520: 65 76 65 72 79 20 33 32 4b 42 20 70 61 67 65 20  every 32KB page 
5530: 69 6e 20 74 68 65 20 57 41 4c 20 2a 2f 0a 7d 3b  in the WAL */.};
5540: 0a 0a 2f 2a 0a 2a 2a 20 44 65 66 69 6e 65 20 74  ../*.** Define t
5550: 68 65 20 70 61 72 61 6d 65 74 65 72 73 20 6f 66  he parameters of
5560: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 73   the hash tables
5570: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
5580: 78 20 66 69 6c 65 2e 20 54 68 65 72 65 0a 2a 2a  x file. There.**
5590: 20 69 73 20 61 20 68 61 73 68 2d 74 61 62 6c 65   is a hash-table
55a0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 65 76 65 72 79   following every
55b0: 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45   HASHTABLE_NPAGE
55c0: 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20 69 6e   page numbers in
55d0: 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65   the.** wal-inde
55e0: 78 2e 0a 2a 2a 0a 2a 2a 20 43 68 61 6e 67 69 6e  x..**.** Changin
55f0: 67 20 61 6e 79 20 6f 66 20 74 68 65 73 65 20 63  g any of these c
5600: 6f 6e 73 74 61 6e 74 73 20 77 69 6c 6c 20 61 6c  onstants will al
5610: 74 65 72 20 74 68 65 20 77 61 6c 2d 69 6e 64 65  ter the wal-inde
5620: 78 20 66 6f 72 6d 61 74 20 61 6e 64 0a 2a 2a 20  x format and.** 
5630: 63 72 65 61 74 65 20 69 6e 63 6f 6d 70 61 74 69  create incompati
5640: 62 69 6c 69 74 69 65 73 2e 0a 2a 2f 0a 23 64 65  bilities..*/.#de
5650: 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f 4e  fine HASHTABLE_N
5660: 50 41 47 45 20 20 20 20 20 20 34 30 39 36 20 20  PAGE      4096  
5670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5680: 2a 20 4d 75 73 74 20 62 65 20 70 6f 77 65 72 20  * Must be power 
5690: 6f 66 20 32 20 2a 2f 0a 23 64 65 66 69 6e 65 20  of 2 */.#define 
56a0: 48 41 53 48 54 41 42 4c 45 5f 48 41 53 48 5f 31  HASHTABLE_HASH_1
56b0: 20 20 20 20 20 33 38 33 20 20 20 20 20 20 20 20       383        
56c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 68 6f            /* Sho
56d0: 75 6c 64 20 62 65 20 70 72 69 6d 65 20 2a 2f 0a  uld be prime */.
56e0: 23 64 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c  #define HASHTABL
56f0: 45 5f 4e 53 4c 4f 54 20 20 20 20 20 20 28 48 41  E_NSLOT      (HA
5700: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 2a 32 29  SHTABLE_NPAGE*2)
5710: 20 20 2f 2a 20 4d 75 73 74 20 62 65 20 61 20 70    /* Must be a p
5720: 6f 77 65 72 20 6f 66 20 32 20 2a 2f 0a 0a 2f 2a  ower of 2 */../*
5730: 20 0a 2a 2a 20 54 68 65 20 62 6c 6f 63 6b 20 6f   .** The block o
5740: 66 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20 61  f page numbers a
5750: 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74  ssociated with t
5760: 68 65 20 66 69 72 73 74 20 68 61 73 68 2d 74 61  he first hash-ta
5770: 62 6c 65 20 69 6e 20 61 0a 2a 2a 20 77 61 6c 2d  ble in a.** wal-
5780: 69 6e 64 65 78 20 69 73 20 73 6d 61 6c 6c 65 72  index is smaller
5790: 20 74 68 61 6e 20 75 73 75 61 6c 2e 20 54 68 69   than usual. Thi
57a0: 73 20 69 73 20 73 6f 20 74 68 61 74 20 74 68 65  s is so that the
57b0: 72 65 20 69 73 20 61 20 63 6f 6d 70 6c 65 74 65  re is a complete
57c0: 0a 2a 2a 20 68 61 73 68 2d 74 61 62 6c 65 20 6f  .** hash-table o
57d0: 6e 20 65 61 63 68 20 61 6c 69 67 6e 65 64 20 33  n each aligned 3
57e0: 32 4b 42 20 70 61 67 65 20 6f 66 20 74 68 65 20  2KB page of the 
57f0: 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 23 64  wal-index..*/.#d
5800: 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f  efine HASHTABLE_
5810: 4e 50 41 47 45 5f 4f 4e 45 20 20 28 48 41 53 48  NPAGE_ONE  (HASH
5820: 54 41 42 4c 45 5f 4e 50 41 47 45 20 2d 20 28 57  TABLE_NPAGE - (W
5830: 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45  ALINDEX_HDR_SIZE
5840: 2f 73 69 7a 65 6f 66 28 75 33 32 29 29 29 0a 0a  /sizeof(u32)))..
5850: 2f 2a 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78  /* The wal-index
5860: 20 69 73 20 64 69 76 69 64 65 64 20 69 6e 74 6f   is divided into
5870: 20 70 61 67 65 73 20 6f 66 20 57 41 4c 49 4e 44   pages of WALIND
5880: 45 58 5f 50 47 53 5a 20 62 79 74 65 73 20 65 61  EX_PGSZ bytes ea
5890: 63 68 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20 57  ch. */.#define W
58a0: 41 4c 49 4e 44 45 58 5f 50 47 53 5a 20 20 20 28  ALINDEX_PGSZ   (
58b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58d0: 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20 73           \.    s
58e0: 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 2a 48  izeof(ht_slot)*H
58f0: 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 2b  ASHTABLE_NSLOT +
5900: 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45   HASHTABLE_NPAGE
5910: 2a 73 69 7a 65 6f 66 28 75 33 32 29 20 5c 0a 29  *sizeof(u32) \.)
5920: 0a 0a 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20 61  ../*.** Obtain a
5930: 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20   pointer to the 
5940: 69 50 61 67 65 27 74 68 20 70 61 67 65 20 6f 66  iPage'th page of
5950: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20   the wal-index. 
5960: 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a  The wal-index.**
5970: 20 69 73 20 62 72 6f 6b 65 6e 20 69 6e 74 6f 20   is broken into 
5980: 70 61 67 65 73 20 6f 66 20 57 41 4c 49 4e 44 45  pages of WALINDE
5990: 58 5f 50 47 53 5a 20 62 79 74 65 73 2e 20 57 61  X_PGSZ bytes. Wa
59a0: 6c 2d 69 6e 64 65 78 20 70 61 67 65 73 20 61 72  l-index pages ar
59b0: 65 0a 2a 2a 20 6e 75 6d 62 65 72 65 64 20 66 72  e.** numbered fr
59c0: 6f 6d 20 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20 49  om zero..**.** I
59d0: 66 20 74 68 69 73 20 63 61 6c 6c 20 69 73 20 73  f this call is s
59e0: 75 63 63 65 73 73 66 75 6c 2c 20 2a 70 70 50 61  uccessful, *ppPa
59f0: 67 65 20 69 73 20 73 65 74 20 74 6f 20 70 6f 69  ge is set to poi
5a00: 6e 74 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e  nt to the wal-in
5a10: 64 65 78 0a 2a 2a 20 70 61 67 65 20 61 6e 64 20  dex.** page and 
5a20: 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
5a30: 75 72 6e 65 64 2e 20 49 66 20 61 6e 20 65 72 72  urned. If an err
5a40: 6f 72 20 28 61 6e 20 4f 4f 4d 20 6f 72 20 56 46  or (an OOM or VF
5a50: 53 20 65 72 72 6f 72 29 20 6f 63 63 75 72 73 2c  S error) occurs,
5a60: 0a 2a 2a 20 74 68 65 6e 20 61 6e 20 53 51 4c 69  .** then an SQLi
5a70: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73  te error code is
5a80: 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 2a 70   returned and *p
5a90: 70 50 61 67 65 20 69 73 20 73 65 74 20 74 6f 20  pPage is set to 
5aa0: 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  0..*/.static int
5ab0: 20 77 61 6c 49 6e 64 65 78 50 61 67 65 28 57 61   walIndexPage(Wa
5ac0: 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 69 50 61  l *pWal, int iPa
5ad0: 67 65 2c 20 76 6f 6c 61 74 69 6c 65 20 75 33 32  ge, volatile u32
5ae0: 20 2a 2a 70 70 50 61 67 65 29 7b 0a 20 20 69 6e   **ppPage){.  in
5af0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
5b00: 3b 0a 0a 20 20 2f 2a 20 45 6e 6c 61 72 67 65 20  ;..  /* Enlarge 
5b10: 74 68 65 20 70 57 61 6c 2d 3e 61 70 57 69 44 61  the pWal->apWiDa
5b20: 74 61 5b 5d 20 61 72 72 61 79 20 69 66 20 72 65  ta[] array if re
5b30: 71 75 69 72 65 64 20 2a 2f 0a 20 20 69 66 28 20  quired */.  if( 
5b40: 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3c 3d 69  pWal->nWiData<=i
5b50: 50 61 67 65 20 29 7b 0a 20 20 20 20 69 6e 74 20  Page ){.    int 
5b60: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 75  nByte = sizeof(u
5b70: 33 32 20 2a 29 2a 28 69 50 61 67 65 2b 31 29 3b  32 *)*(iPage+1);
5b80: 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33  .    volatile u3
5b90: 32 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 20 20 61  2 **apNew;.    a
5ba0: 70 4e 65 77 20 3d 20 28 76 6f 6c 61 74 69 6c 65  pNew = (volatile
5bb0: 20 75 33 32 20 2a 2a 29 73 71 6c 69 74 65 33 5f   u32 **)sqlite3_
5bc0: 72 65 61 6c 6c 6f 63 28 70 57 61 6c 2d 3e 61 70  realloc(pWal->ap
5bd0: 57 69 44 61 74 61 2c 20 6e 42 79 74 65 29 3b 0a  WiData, nByte);.
5be0: 20 20 20 20 69 66 28 20 21 61 70 4e 65 77 20 29      if( !apNew )
5bf0: 7b 0a 20 20 20 20 20 20 2a 70 70 50 61 67 65 20  {.      *ppPage 
5c00: 3d 20 30 3b 0a 20 20 20 20 20 20 72 65 74 75 72  = 0;.      retur
5c10: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
5c20: 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74      }.    memset
5c30: 28 26 61 70 4e 65 77 5b 70 57 61 6c 2d 3e 6e 57  (&apNew[pWal->nW
5c40: 69 44 61 74 61 5d 2c 20 30 2c 20 73 69 7a 65 6f  iData], 0, sizeo
5c50: 66 28 75 33 32 20 2a 29 2a 28 69 50 61 67 65 2b  f(u32 *)*(iPage+
5c60: 31 2d 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 29  1-pWal->nWiData)
5c70: 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 61 70 57  );.    pWal->apW
5c80: 69 44 61 74 61 20 3d 20 61 70 4e 65 77 3b 0a 20  iData = apNew;. 
5c90: 20 20 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61     pWal->nWiData
5ca0: 20 3d 20 69 50 61 67 65 2b 31 3b 0a 20 20 7d 0a   = iPage+1;.  }.
5cb0: 0a 20 20 2f 2a 20 52 65 71 75 65 73 74 20 61 20  .  /* Request a 
5cc0: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 72  pointer to the r
5cd0: 65 71 75 69 72 65 64 20 70 61 67 65 20 66 72 6f  equired page fro
5ce0: 6d 20 74 68 65 20 56 46 53 20 2a 2f 0a 20 20 69  m the VFS */.  i
5cf0: 66 28 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  f( pWal->apWiDat
5d00: 61 5b 69 50 61 67 65 5d 3d 3d 30 20 29 7b 0a 20  a[iPage]==0 ){. 
5d10: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
5d20: 73 53 68 6d 4d 61 70 28 70 57 61 6c 2d 3e 70 44  sShmMap(pWal->pD
5d30: 62 46 64 2c 20 69 50 61 67 65 2c 20 57 41 4c 49  bFd, iPage, WALI
5d40: 4e 44 45 58 5f 50 47 53 5a 2c 20 0a 20 20 20 20  NDEX_PGSZ, .    
5d50: 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c      pWal->writeL
5d60: 6f 63 6b 2c 20 28 76 6f 69 64 20 76 6f 6c 61 74  ock, (void volat
5d70: 69 6c 65 20 2a 2a 29 26 70 57 61 6c 2d 3e 61 70  ile **)&pWal->ap
5d80: 57 69 44 61 74 61 5b 69 50 61 67 65 5d 0a 20 20  WiData[iPage].  
5d90: 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 70 50    );.  }..  *ppP
5da0: 61 67 65 20 3d 20 70 57 61 6c 2d 3e 61 70 57 69  age = pWal->apWi
5db0: 44 61 74 61 5b 69 50 61 67 65 5d 3b 0a 20 20 61  Data[iPage];.  a
5dc0: 73 73 65 72 74 28 20 69 50 61 67 65 3d 3d 30 20  ssert( iPage==0 
5dd0: 7c 7c 20 2a 70 70 50 61 67 65 20 7c 7c 20 72 63  || *ppPage || rc
5de0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20  !=SQLITE_OK );. 
5df0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
5e00: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f  *.** Return a po
5e10: 69 6e 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c  inter to the Wal
5e20: 43 6b 70 74 49 6e 66 6f 20 73 74 72 75 63 74 75  CkptInfo structu
5e30: 72 65 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e  re in the wal-in
5e40: 64 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  dex..*/.static v
5e50: 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49  olatile WalCkptI
5e60: 6e 66 6f 20 2a 77 61 6c 43 6b 70 74 49 6e 66 6f  nfo *walCkptInfo
5e70: 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61  (Wal *pWal){.  a
5e80: 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69  ssert( pWal->nWi
5e90: 44 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e  Data>0 && pWal->
5ea0: 61 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20  apWiData[0] );. 
5eb0: 20 72 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c   return (volatil
5ec0: 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 2a 29 26  e WalCkptInfo*)&
5ed0: 28 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b  (pWal->apWiData[
5ee0: 30 5d 5b 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64  0][sizeof(WalInd
5ef0: 65 78 48 64 72 29 2f 32 5d 29 3b 0a 7d 0a 0a 2f  exHdr)/2]);.}../
5f00: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f  *.** Return a po
5f10: 69 6e 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c  inter to the Wal
5f20: 49 6e 64 65 78 48 64 72 20 73 74 72 75 63 74 75  IndexHdr structu
5f30: 72 65 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e  re in the wal-in
5f40: 64 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  dex..*/.static v
5f50: 6f 6c 61 74 69 6c 65 20 57 61 6c 49 6e 64 65 78  olatile WalIndex
5f60: 48 64 72 20 2a 77 61 6c 49 6e 64 65 78 48 64 72  Hdr *walIndexHdr
5f70: 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61  (Wal *pWal){.  a
5f80: 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69  ssert( pWal->nWi
5f90: 44 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e  Data>0 && pWal->
5fa0: 61 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20  apWiData[0] );. 
5fb0: 20 72 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c   return (volatil
5fc0: 65 20 57 61 6c 49 6e 64 65 78 48 64 72 2a 29 70  e WalIndexHdr*)p
5fd0: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
5fe0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61  ;.}../*.** The a
5ff0: 72 67 75 6d 65 6e 74 20 74 6f 20 74 68 69 73 20  rgument to this 
6000: 6d 61 63 72 6f 20 6d 75 73 74 20 62 65 20 6f 66  macro must be of
6010: 20 74 79 70 65 20 75 33 32 2e 20 4f 6e 20 61 20   type u32. On a 
6020: 6c 69 74 74 6c 65 2d 65 6e 64 69 61 6e 0a 2a 2a  little-endian.**
6030: 20 61 72 63 68 69 74 65 63 74 75 72 65 2c 20 69   architecture, i
6040: 74 20 72 65 74 75 72 6e 73 20 74 68 65 20 75 33  t returns the u3
6050: 32 20 76 61 6c 75 65 20 74 68 61 74 20 72 65 73  2 value that res
6060: 75 6c 74 73 20 66 72 6f 6d 20 69 6e 74 65 72 70  ults from interp
6070: 72 65 74 69 6e 67 0a 2a 2a 20 74 68 65 20 34 20  reting.** the 4 
6080: 62 79 74 65 73 20 61 73 20 61 20 62 69 67 2d 65  bytes as a big-e
6090: 6e 64 69 61 6e 20 76 61 6c 75 65 2e 20 4f 6e 20  ndian value. On 
60a0: 61 20 62 69 67 2d 65 6e 64 69 61 6e 20 61 72 63  a big-endian arc
60b0: 68 69 74 65 63 74 75 72 65 2c 20 69 74 0a 2a 2a  hitecture, it.**
60c0: 20 72 65 74 75 72 6e 73 20 74 68 65 20 76 61 6c   returns the val
60d0: 75 65 20 74 68 61 74 20 77 6f 75 6c 64 20 62 65  ue that would be
60e0: 20 70 72 6f 64 75 63 65 64 20 62 79 20 69 6e 74   produced by int
60f0: 65 70 72 65 74 69 6e 67 20 74 68 65 20 34 20 62  epreting the 4 b
6100: 79 74 65 73 0a 2a 2a 20 6f 66 20 74 68 65 20 69  ytes.** of the i
6110: 6e 70 75 74 20 76 61 6c 75 65 20 61 73 20 61 20  nput value as a 
6120: 6c 69 74 74 6c 65 2d 65 6e 64 69 61 6e 20 69 6e  little-endian in
6130: 74 65 67 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e  teger..*/.#defin
6140: 65 20 42 59 54 45 53 57 41 50 33 32 28 78 29 20  e BYTESWAP32(x) 
6150: 28 20 5c 0a 20 20 20 20 28 28 28 78 29 26 30 78  ( \.    (((x)&0x
6160: 30 30 30 30 30 30 46 46 29 3c 3c 32 34 29 20 2b  000000FF)<<24) +
6170: 20 28 28 28 78 29 26 30 78 30 30 30 30 46 46 30   (((x)&0x0000FF0
6180: 30 29 3c 3c 38 29 20 20 5c 0a 20 20 2b 20 28 28  0)<<8)  \.  + ((
6190: 28 78 29 26 30 78 30 30 46 46 30 30 30 30 29 3e  (x)&0x00FF0000)>
61a0: 3e 38 29 20 20 2b 20 28 28 28 78 29 26 30 78 46  >8)  + (((x)&0xF
61b0: 46 30 30 30 30 30 30 29 3e 3e 32 34 29 20 5c 0a  F000000)>>24) \.
61c0: 29 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74  )../*.** Generat
61d0: 65 20 6f 72 20 65 78 74 65 6e 64 20 61 6e 20 38  e or extend an 8
61e0: 20 62 79 74 65 20 63 68 65 63 6b 73 75 6d 20 62   byte checksum b
61f0: 61 73 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61  ased on the data
6200: 20 69 6e 20 0a 2a 2a 20 61 72 72 61 79 20 61 42   in .** array aB
6210: 79 74 65 5b 5d 20 61 6e 64 20 74 68 65 20 69 6e  yte[] and the in
6220: 69 74 69 61 6c 20 76 61 6c 75 65 73 20 6f 66 20  itial values of 
6230: 61 49 6e 5b 30 5d 20 61 6e 64 20 61 49 6e 5b 31  aIn[0] and aIn[1
6240: 5d 20 28 6f 72 0a 2a 2a 20 69 6e 69 74 69 61 6c  ] (or.** initial
6250: 20 76 61 6c 75 65 73 20 6f 66 20 30 20 61 6e 64   values of 0 and
6260: 20 30 20 69 66 20 61 49 6e 3d 3d 4e 55 4c 4c 29   0 if aIn==NULL)
6270: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63  ..**.** The chec
6280: 6b 73 75 6d 20 69 73 20 77 72 69 74 74 65 6e 20  ksum is written 
6290: 62 61 63 6b 20 69 6e 74 6f 20 61 4f 75 74 5b 5d  back into aOut[]
62a0: 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
62b0: 67 2e 0a 2a 2a 0a 2a 2a 20 6e 42 79 74 65 20 6d  g..**.** nByte m
62c0: 75 73 74 20 62 65 20 61 20 70 6f 73 69 74 69 76  ust be a positiv
62d0: 65 20 6d 75 6c 74 69 70 6c 65 20 6f 66 20 38 2e  e multiple of 8.
62e0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
62f0: 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73  walChecksumBytes
6300: 28 0a 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b  (.  int nativeCk
6310: 73 75 6d 2c 20 2f 2a 20 54 72 75 65 20 66 6f 72  sum, /* True for
6320: 20 6e 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64   native byte-ord
6330: 65 72 2c 20 66 61 6c 73 65 20 66 6f 72 20 6e 6f  er, false for no
6340: 6e 2d 6e 61 74 69 76 65 20 2a 2f 0a 20 20 75 38  n-native */.  u8
6350: 20 2a 61 2c 20 20 20 20 20 20 20 20 20 20 20 2f   *a,           /
6360: 2a 20 43 6f 6e 74 65 6e 74 20 74 6f 20 62 65 20  * Content to be 
6370: 63 68 65 63 6b 73 75 6d 6d 65 64 20 2a 2f 0a 20  checksummed */. 
6380: 20 69 6e 74 20 6e 42 79 74 65 2c 20 20 20 20 20   int nByte,     
6390: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 63 6f    /* Bytes of co
63a0: 6e 74 65 6e 74 20 69 6e 20 61 5b 5d 2e 20 20 4d  ntent in a[].  M
63b0: 75 73 74 20 62 65 20 61 20 6d 75 6c 74 69 70 6c  ust be a multipl
63c0: 65 20 6f 66 20 38 2e 20 2a 2f 0a 20 20 63 6f 6e  e of 8. */.  con
63d0: 73 74 20 75 33 32 20 2a 61 49 6e 2c 20 20 2f 2a  st u32 *aIn,  /*
63e0: 20 49 6e 69 74 69 61 6c 20 63 68 65 63 6b 73 75   Initial checksu
63f0: 6d 20 76 61 6c 75 65 20 69 6e 70 75 74 20 2a 2f  m value input */
6400: 0a 20 20 75 33 32 20 2a 61 4f 75 74 20 20 20 20  .  u32 *aOut    
6410: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 46 69 6e 61      /* OUT: Fina
6420: 6c 20 63 68 65 63 6b 73 75 6d 20 76 61 6c 75 65  l checksum value
6430: 20 6f 75 74 70 75 74 20 2a 2f 0a 29 7b 0a 20 20   output */.){.  
6440: 75 33 32 20 73 31 2c 20 73 32 3b 0a 20 20 75 33  u32 s1, s2;.  u3
6450: 32 20 2a 61 44 61 74 61 20 3d 20 28 75 33 32 20  2 *aData = (u32 
6460: 2a 29 61 3b 0a 20 20 75 33 32 20 2a 61 45 6e 64  *)a;.  u32 *aEnd
6470: 20 3d 20 28 75 33 32 20 2a 29 26 61 5b 6e 42 79   = (u32 *)&a[nBy
6480: 74 65 5d 3b 0a 0a 20 20 69 66 28 20 61 49 6e 20  te];..  if( aIn 
6490: 29 7b 0a 20 20 20 20 73 31 20 3d 20 61 49 6e 5b  ){.    s1 = aIn[
64a0: 30 5d 3b 0a 20 20 20 20 73 32 20 3d 20 61 49 6e  0];.    s2 = aIn
64b0: 5b 31 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  [1];.  }else{.  
64c0: 20 20 73 31 20 3d 20 73 32 20 3d 20 30 3b 0a 20    s1 = s2 = 0;. 
64d0: 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 42   }..  assert( nB
64e0: 79 74 65 3e 3d 38 20 29 3b 0a 20 20 61 73 73 65  yte>=8 );.  asse
64f0: 72 74 28 20 28 6e 42 79 74 65 26 30 78 30 30 30  rt( (nByte&0x000
6500: 30 30 30 30 37 29 3d 3d 30 20 29 3b 0a 0a 20 20  00007)==0 );..  
6510: 69 66 28 20 6e 61 74 69 76 65 43 6b 73 75 6d 20  if( nativeCksum 
6520: 29 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20  ){.    do {.    
6530: 20 20 73 31 20 2b 3d 20 2a 61 44 61 74 61 2b 2b    s1 += *aData++
6540: 20 2b 20 73 32 3b 0a 20 20 20 20 20 20 73 32 20   + s2;.      s2 
6550: 2b 3d 20 2a 61 44 61 74 61 2b 2b 20 2b 20 73 31  += *aData++ + s1
6560: 3b 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 61 44  ;.    }while( aD
6570: 61 74 61 3c 61 45 6e 64 20 29 3b 0a 20 20 7d 65  ata<aEnd );.  }e
6580: 6c 73 65 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20  lse{.    do {.  
6590: 20 20 20 20 73 31 20 2b 3d 20 42 59 54 45 53 57      s1 += BYTESW
65a0: 41 50 33 32 28 61 44 61 74 61 5b 30 5d 29 20 2b  AP32(aData[0]) +
65b0: 20 73 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d   s2;.      s2 +=
65c0: 20 42 59 54 45 53 57 41 50 33 32 28 61 44 61 74   BYTESWAP32(aDat
65d0: 61 5b 31 5d 29 20 2b 20 73 31 3b 0a 20 20 20 20  a[1]) + s1;.    
65e0: 20 20 61 44 61 74 61 20 2b 3d 20 32 3b 0a 20 20    aData += 2;.  
65f0: 20 20 7d 77 68 69 6c 65 28 20 61 44 61 74 61 3c    }while( aData<
6600: 61 45 6e 64 20 29 3b 0a 20 20 7d 0a 0a 20 20 61  aEnd );.  }..  a
6610: 4f 75 74 5b 30 5d 20 3d 20 73 31 3b 0a 20 20 61  Out[0] = s1;.  a
6620: 4f 75 74 5b 31 5d 20 3d 20 73 32 3b 0a 7d 0a 0a  Out[1] = s2;.}..
6630: 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68 65 20  /*.** Write the 
6640: 68 65 61 64 65 72 20 69 6e 66 6f 72 6d 61 74 69  header informati
6650: 6f 6e 20 69 6e 20 70 57 61 6c 2d 3e 68 64 72 20  on in pWal->hdr 
6660: 69 6e 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64  into the wal-ind
6670: 65 78 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68  ex..**.** The ch
6680: 65 63 6b 73 75 6d 20 6f 6e 20 70 57 61 6c 2d 3e  ecksum on pWal->
6690: 68 64 72 20 69 73 20 75 70 64 61 74 65 64 20 62  hdr is updated b
66a0: 65 66 6f 72 65 20 69 74 20 69 73 20 77 72 69 74  efore it is writ
66b0: 74 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ten..*/.static v
66c0: 6f 69 64 20 77 61 6c 49 6e 64 65 78 57 72 69 74  oid walIndexWrit
66d0: 65 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 29 7b  eHdr(Wal *pWal){
66e0: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 49  .  volatile WalI
66f0: 6e 64 65 78 48 64 72 20 2a 61 48 64 72 20 3d 20  ndexHdr *aHdr = 
6700: 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c  walIndexHdr(pWal
6710: 29 3b 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20 6e  );.  const int n
6720: 43 6b 73 75 6d 20 3d 20 6f 66 66 73 65 74 6f 66  Cksum = offsetof
6730: 28 57 61 6c 49 6e 64 65 78 48 64 72 2c 20 61 43  (WalIndexHdr, aC
6740: 6b 73 75 6d 29 3b 0a 0a 20 20 61 73 73 65 72 74  ksum);..  assert
6750: 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
6760: 6b 20 29 3b 0a 20 20 70 57 61 6c 2d 3e 68 64 72  k );.  pWal->hdr
6770: 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a 20 20 70  .isInit = 1;.  p
6780: 57 61 6c 2d 3e 68 64 72 2e 69 56 65 72 73 69 6f  Wal->hdr.iVersio
6790: 6e 20 3d 20 57 41 4c 49 4e 44 45 58 5f 4d 41 58  n = WALINDEX_MAX
67a0: 5f 56 45 52 53 49 4f 4e 3b 0a 20 20 77 61 6c 43  _VERSION;.  walC
67b0: 68 65 63 6b 73 75 6d 42 79 74 65 73 28 31 2c 20  hecksumBytes(1, 
67c0: 28 75 38 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c  (u8*)&pWal->hdr,
67d0: 20 6e 43 6b 73 75 6d 2c 20 30 2c 20 70 57 61 6c   nCksum, 0, pWal
67e0: 2d 3e 68 64 72 2e 61 43 6b 73 75 6d 29 3b 0a 20  ->hdr.aCksum);. 
67f0: 20 6d 65 6d 63 70 79 28 28 76 6f 69 64 20 2a 29   memcpy((void *)
6800: 26 61 48 64 72 5b 31 5d 2c 20 28 76 6f 69 64 20  &aHdr[1], (void 
6810: 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69  *)&pWal->hdr, si
6820: 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
6830: 29 29 3b 0a 20 20 73 71 6c 69 74 65 33 4f 73 53  ));.  sqlite3OsS
6840: 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c 2d 3e  hmBarrier(pWal->
6850: 70 44 62 46 64 29 3b 0a 20 20 6d 65 6d 63 70 79  pDbFd);.  memcpy
6860: 28 28 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 30  ((void *)&aHdr[0
6870: 5d 2c 20 28 76 6f 69 64 20 2a 29 26 70 57 61 6c  ], (void *)&pWal
6880: 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61  ->hdr, sizeof(Wa
6890: 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 7d 0a 0a  lIndexHdr));.}..
68a0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
68b0: 69 6f 6e 20 65 6e 63 6f 64 65 73 20 61 20 73 69  ion encodes a si
68c0: 6e 67 6c 65 20 66 72 61 6d 65 20 68 65 61 64 65  ngle frame heade
68d0: 72 20 61 6e 64 20 77 72 69 74 65 73 20 69 74 20  r and writes it 
68e0: 74 6f 20 61 20 62 75 66 66 65 72 0a 2a 2a 20 73  to a buffer.** s
68f0: 75 70 70 6c 69 65 64 20 62 79 20 74 68 65 20 63  upplied by the c
6900: 61 6c 6c 65 72 2e 20 41 20 66 72 61 6d 65 2d 68  aller. A frame-h
6910: 65 61 64 65 72 20 69 73 20 6d 61 64 65 20 75 70  eader is made up
6920: 20 6f 66 20 61 20 73 65 72 69 65 73 20 6f 66 20   of a series of 
6930: 0a 2a 2a 20 34 2d 62 79 74 65 20 62 69 67 2d 65  .** 4-byte big-e
6940: 6e 64 69 61 6e 20 69 6e 74 65 67 65 72 73 2c 20  ndian integers, 
6950: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a  as follows:.**.*
6960: 2a 20 20 20 20 20 30 3a 20 50 61 67 65 20 6e 75  *     0: Page nu
6970: 6d 62 65 72 2e 0a 2a 2a 20 20 20 20 20 34 3a 20  mber..**     4: 
6980: 46 6f 72 20 63 6f 6d 6d 69 74 20 72 65 63 6f 72  For commit recor
6990: 64 73 2c 20 74 68 65 20 73 69 7a 65 20 6f 66 20  ds, the size of 
69a0: 74 68 65 20 64 61 74 61 62 61 73 65 20 69 6d 61  the database ima
69b0: 67 65 20 69 6e 20 70 61 67 65 73 20 0a 2a 2a 20  ge in pages .** 
69c0: 20 20 20 20 20 20 20 61 66 74 65 72 20 74 68 65         after the
69d0: 20 63 6f 6d 6d 69 74 2e 20 46 6f 72 20 61 6c 6c   commit. For all
69e0: 20 6f 74 68 65 72 20 72 65 63 6f 72 64 73 2c 20   other records, 
69f0: 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20 20 38 3a 20  zero..**     8: 
6a00: 53 61 6c 74 2d 31 20 28 63 6f 70 69 65 64 20 66  Salt-1 (copied f
6a10: 72 6f 6d 20 74 68 65 20 77 61 6c 2d 68 65 61 64  rom the wal-head
6a20: 65 72 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61  er).**    12: Sa
6a30: 6c 74 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f  lt-2 (copied fro
6a40: 6d 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  m the wal-header
6a50: 29 0a 2a 2a 20 20 20 20 31 36 3a 20 43 68 65 63  ).**    16: Chec
6a60: 6b 73 75 6d 2d 31 2e 0a 2a 2a 20 20 20 20 32 30  ksum-1..**    20
6a70: 3a 20 43 68 65 63 6b 73 75 6d 2d 32 2e 0a 2a 2f  : Checksum-2..*/
6a80: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
6a90: 45 6e 63 6f 64 65 46 72 61 6d 65 28 0a 20 20 57  EncodeFrame(.  W
6aa0: 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20  al *pWal,       
6ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6ac0: 2a 20 54 68 65 20 77 72 69 74 65 2d 61 68 65 61  * The write-ahea
6ad0: 64 20 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 69  d log */.  u32 i
6ae0: 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20  Page,           
6af0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
6b00: 74 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62  tabase page numb
6b10: 65 72 20 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a  er for frame */.
6b20: 20 20 75 33 32 20 6e 54 72 75 6e 63 61 74 65 2c    u32 nTruncate,
6b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b40: 20 20 2f 2a 20 4e 65 77 20 64 62 20 73 69 7a 65    /* New db size
6b50: 20 28 6f 72 20 30 20 66 6f 72 20 6e 6f 6e 2d 63   (or 0 for non-c
6b60: 6f 6d 6d 69 74 20 66 72 61 6d 65 73 29 20 2a 2f  ommit frames) */
6b70: 0a 20 20 75 38 20 2a 61 44 61 74 61 2c 20 20 20  .  u8 *aData,   
6b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b90: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
6ba0: 20 70 61 67 65 20 64 61 74 61 20 2a 2f 0a 20 20   page data */.  
6bb0: 75 38 20 2a 61 46 72 61 6d 65 20 20 20 20 20 20  u8 *aFrame      
6bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6bd0: 2f 2a 20 4f 55 54 3a 20 57 72 69 74 65 20 65 6e  /* OUT: Write en
6be0: 63 6f 64 65 64 20 66 72 61 6d 65 20 68 65 72 65  coded frame here
6bf0: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 61 74   */.){.  int nat
6c00: 69 76 65 43 6b 73 75 6d 3b 20 20 20 20 20 20 20  iveCksum;       
6c10: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
6c20: 20 66 6f 72 20 6e 61 74 69 76 65 20 62 79 74 65   for native byte
6c30: 2d 6f 72 64 65 72 20 63 68 65 63 6b 73 75 6d 73  -order checksums
6c40: 20 2a 2f 0a 20 20 75 33 32 20 2a 61 43 6b 73 75   */.  u32 *aCksu
6c50: 6d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46  m = pWal->hdr.aF
6c60: 72 61 6d 65 43 6b 73 75 6d 3b 0a 20 20 61 73 73  rameCksum;.  ass
6c70: 65 72 74 28 20 57 41 4c 5f 46 52 41 4d 45 5f 48  ert( WAL_FRAME_H
6c80: 44 52 53 49 5a 45 3d 3d 32 34 20 29 3b 0a 20 20  DRSIZE==24 );.  
6c90: 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28  sqlite3Put4byte(
6ca0: 26 61 46 72 61 6d 65 5b 30 5d 2c 20 69 50 61 67  &aFrame[0], iPag
6cb0: 65 29 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74  e);.  sqlite3Put
6cc0: 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 34 5d  4byte(&aFrame[4]
6cd0: 2c 20 6e 54 72 75 6e 63 61 74 65 29 3b 0a 20 20  , nTruncate);.  
6ce0: 6d 65 6d 63 70 79 28 26 61 46 72 61 6d 65 5b 38  memcpy(&aFrame[8
6cf0: 5d 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61  ], pWal->hdr.aSa
6d00: 6c 74 2c 20 38 29 3b 0a 0a 20 20 6e 61 74 69 76  lt, 8);..  nativ
6d10: 65 43 6b 73 75 6d 20 3d 20 28 70 57 61 6c 2d 3e  eCksum = (pWal->
6d20: 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d  hdr.bigEndCksum=
6d30: 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41  =SQLITE_BIGENDIA
6d40: 4e 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75  N);.  walChecksu
6d50: 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73  mBytes(nativeCks
6d60: 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38 2c 20 61  um, aFrame, 8, a
6d70: 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a  Cksum, aCksum);.
6d80: 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74    walChecksumByt
6d90: 65 73 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20  es(nativeCksum, 
6da0: 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e 73 7a 50  aData, pWal->szP
6db0: 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b  age, aCksum, aCk
6dc0: 73 75 6d 29 3b 0a 0a 20 20 73 71 6c 69 74 65 33  sum);..  sqlite3
6dd0: 50 75 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Put4byte(&aFrame
6de0: 5b 31 36 5d 2c 20 61 43 6b 73 75 6d 5b 30 5d 29  [16], aCksum[0])
6df0: 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74 34 62  ;.  sqlite3Put4b
6e00: 79 74 65 28 26 61 46 72 61 6d 65 5b 32 30 5d 2c  yte(&aFrame[20],
6e10: 20 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 7d 0a 0a   aCksum[1]);.}..
6e20: 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 6f 20 73  /*.** Check to s
6e30: 65 65 20 69 66 20 74 68 65 20 66 72 61 6d 65 20  ee if the frame 
6e40: 77 69 74 68 20 68 65 61 64 65 72 20 69 6e 20 61  with header in a
6e50: 46 72 61 6d 65 5b 5d 20 61 6e 64 20 63 6f 6e 74  Frame[] and cont
6e60: 65 6e 74 0a 2a 2a 20 69 6e 20 61 44 61 74 61 5b  ent.** in aData[
6e70: 5d 20 69 73 20 76 61 6c 69 64 2e 20 20 49 66 20  ] is valid.  If 
6e80: 69 74 20 69 73 20 61 20 76 61 6c 69 64 20 66 72  it is a valid fr
6e90: 61 6d 65 2c 20 66 69 6c 6c 20 2a 70 69 50 61 67  ame, fill *piPag
6ea0: 65 20 61 6e 64 0a 2a 2a 20 2a 70 6e 54 72 75 6e  e and.** *pnTrun
6eb0: 63 61 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20  cate and return 
6ec0: 74 72 75 65 2e 20 20 52 65 74 75 72 6e 20 69 66  true.  Return if
6ed0: 20 74 68 65 20 66 72 61 6d 65 20 69 73 20 6e 6f   the frame is no
6ee0: 74 20 76 61 6c 69 64 2e 0a 2a 2f 0a 73 74 61 74  t valid..*/.stat
6ef0: 69 63 20 69 6e 74 20 77 61 6c 44 65 63 6f 64 65  ic int walDecode
6f00: 46 72 61 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57  Frame(.  Wal *pW
6f10: 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
6f20: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
6f30: 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20  write-ahead log 
6f40: 2a 2f 0a 20 20 75 33 32 20 2a 70 69 50 61 67 65  */.  u32 *piPage
6f50: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
6f60: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 44 61 74       /* OUT: Dat
6f70: 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65  abase page numbe
6f80: 72 20 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20  r for frame */. 
6f90: 20 75 33 32 20 2a 70 6e 54 72 75 6e 63 61 74 65   u32 *pnTruncate
6fa0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
6fb0: 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 64 62 20   /* OUT: New db 
6fc0: 73 69 7a 65 20 28 6f 72 20 30 20 69 66 20 6e 6f  size (or 0 if no
6fd0: 74 20 63 6f 6d 6d 69 74 29 20 2a 2f 0a 20 20 75  t commit) */.  u
6fe0: 38 20 2a 61 44 61 74 61 2c 20 20 20 20 20 20 20  8 *aData,       
6ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7000: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 70 61 67  * Pointer to pag
7010: 65 20 64 61 74 61 20 28 66 6f 72 20 63 68 65 63  e data (for chec
7020: 6b 73 75 6d 29 20 2a 2f 0a 20 20 75 38 20 2a 61  ksum) */.  u8 *a
7030: 46 72 61 6d 65 20 20 20 20 20 20 20 20 20 20 20  Frame           
7040: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
7050: 61 6d 65 20 64 61 74 61 20 2a 2f 0a 29 7b 0a 20  ame data */.){. 
7060: 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73 75 6d   int nativeCksum
7070: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
7080: 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e 61 74   /* True for nat
7090: 69 76 65 20 62 79 74 65 2d 6f 72 64 65 72 20 63  ive byte-order c
70a0: 68 65 63 6b 73 75 6d 73 20 2a 2f 0a 20 20 75 33  hecksums */.  u3
70b0: 32 20 2a 61 43 6b 73 75 6d 20 3d 20 70 57 61 6c  2 *aCksum = pWal
70c0: 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
70d0: 6d 3b 0a 20 20 75 33 32 20 70 67 6e 6f 3b 20 20  m;.  u32 pgno;  
70e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
70f0: 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d       /* Page num
7100: 62 65 72 20 6f 66 20 74 68 65 20 66 72 61 6d 65  ber of the frame
7110: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 57 41   */.  assert( WA
7120: 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3d  L_FRAME_HDRSIZE=
7130: 3d 32 34 20 29 3b 0a 0a 20 20 2f 2a 20 41 20 66  =24 );..  /* A f
7140: 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c  rame is only val
7150: 69 64 20 69 66 20 74 68 65 20 73 61 6c 74 20 76  id if the salt v
7160: 61 6c 75 65 73 20 69 6e 20 74 68 65 20 66 72 61  alues in the fra
7170: 6d 65 2d 68 65 61 64 65 72 0a 20 20 2a 2a 20 6d  me-header.  ** m
7180: 61 74 63 68 20 74 68 65 20 73 61 6c 74 20 76 61  atch the salt va
7190: 6c 75 65 73 20 69 6e 20 74 68 65 20 77 61 6c 2d  lues in the wal-
71a0: 68 65 61 64 65 72 2e 20 0a 20 20 2a 2f 0a 20 20  header. .  */.  
71b0: 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c  if( memcmp(&pWal
71c0: 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 26 61 46  ->hdr.aSalt, &aF
71d0: 72 61 6d 65 5b 38 5d 2c 20 38 29 21 3d 30 20 29  rame[8], 8)!=0 )
71e0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  {.    return 0;.
71f0: 20 20 7d 0a 0a 20 20 2f 2a 20 41 20 66 72 61 6d    }..  /* A fram
7200: 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20  e is only valid 
7210: 69 66 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62  if the page numb
7220: 65 72 20 69 73 20 63 72 65 61 74 65 72 20 74 68  er is creater th
7230: 61 6e 20 7a 65 72 6f 2e 0a 20 20 2a 2f 0a 20 20  an zero..  */.  
7240: 70 67 6e 6f 20 3d 20 73 71 6c 69 74 65 33 47 65  pgno = sqlite3Ge
7250: 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 30  t4byte(&aFrame[0
7260: 5d 29 3b 0a 20 20 69 66 28 20 70 67 6e 6f 3d 3d  ]);.  if( pgno==
7270: 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  0 ){.    return 
7280: 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 20 66  0;.  }..  /* A f
7290: 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c  rame is only val
72a0: 69 64 20 69 66 20 61 20 63 68 65 63 6b 73 75 6d  id if a checksum
72b0: 20 6f 66 20 74 68 65 20 66 69 72 73 74 20 31 36   of the first 16
72c0: 20 62 79 74 65 73 0a 20 20 2a 2a 20 6f 66 20 74   bytes.  ** of t
72d0: 68 65 20 66 72 61 6d 65 2d 68 65 61 64 65 72 2c  he frame-header,
72e0: 20 61 6e 64 20 74 68 65 20 66 72 61 6d 65 2d 64   and the frame-d
72f0: 61 74 61 20 6d 61 74 63 68 65 73 0a 20 20 2a 2a  ata matches.  **
7300: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 69 6e   the checksum in
7310: 20 74 68 65 20 6c 61 73 74 20 38 20 62 79 74 65   the last 8 byte
7320: 73 20 6f 66 20 74 68 65 20 66 72 61 6d 65 2d 68  s of the frame-h
7330: 65 61 64 65 72 2e 0a 20 20 2a 2f 0a 20 20 6e 61  eader..  */.  na
7340: 74 69 76 65 43 6b 73 75 6d 20 3d 20 28 70 57 61  tiveCksum = (pWa
7350: 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73  l->hdr.bigEndCks
7360: 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e  um==SQLITE_BIGEN
7370: 44 49 41 4e 29 3b 0a 20 20 77 61 6c 43 68 65 63  DIAN);.  walChec
7380: 6b 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65  ksumBytes(native
7390: 43 6b 73 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38  Cksum, aFrame, 8
73a0: 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d  , aCksum, aCksum
73b0: 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d  );.  walChecksum
73c0: 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75  Bytes(nativeCksu
73d0: 6d 2c 20 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e  m, aData, pWal->
73e0: 73 7a 50 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20  szPage, aCksum, 
73f0: 61 43 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20 61  aCksum);.  if( a
7400: 43 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65  Cksum[0]!=sqlite
7410: 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Get4byte(&aFram
7420: 65 5b 31 36 5d 29 20 0a 20 20 20 7c 7c 20 61 43  e[16]) .   || aC
7430: 6b 73 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33  ksum[1]!=sqlite3
7440: 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Get4byte(&aFrame
7450: 5b 32 30 5d 29 20 0a 20 20 29 7b 0a 20 20 20 20  [20]) .  ){.    
7460: 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66 61 69 6c  /* Checksum fail
7470: 65 64 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72  ed. */.    retur
7480: 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49  n 0;.  }..  /* I
7490: 66 20 77 65 20 72 65 61 63 68 20 74 68 69 73 20  f we reach this 
74a0: 70 6f 69 6e 74 2c 20 74 68 65 20 66 72 61 6d 65  point, the frame
74b0: 20 69 73 20 76 61 6c 69 64 2e 20 20 52 65 74 75   is valid.  Retu
74c0: 72 6e 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62  rn the page numb
74d0: 65 72 0a 20 20 2a 2a 20 61 6e 64 20 74 68 65 20  er.  ** and the 
74e0: 6e 65 77 20 64 61 74 61 62 61 73 65 20 73 69 7a  new database siz
74f0: 65 2e 0a 20 20 2a 2f 0a 20 20 2a 70 69 50 61 67  e..  */.  *piPag
7500: 65 20 3d 20 70 67 6e 6f 3b 0a 20 20 2a 70 6e 54  e = pgno;.  *pnT
7510: 72 75 6e 63 61 74 65 20 3d 20 73 71 6c 69 74 65  runcate = sqlite
7520: 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Get4byte(&aFram
7530: 65 5b 34 5d 29 3b 0a 20 20 72 65 74 75 72 6e 20  e[4]);.  return 
7540: 31 3b 0a 7d 0a 0a 0a 23 69 66 20 64 65 66 69 6e  1;.}...#if defin
7550: 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20  ed(SQLITE_TEST) 
7560: 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  && defined(SQLIT
7570: 45 5f 44 45 42 55 47 29 0a 2f 2a 0a 2a 2a 20 4e  E_DEBUG)./*.** N
7580: 61 6d 65 73 20 6f 66 20 6c 6f 63 6b 73 2e 20 20  ames of locks.  
7590: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20  This routine is 
75a0: 75 73 65 64 20 74 6f 20 70 72 6f 76 69 64 65 20  used to provide 
75b0: 64 65 62 75 67 67 69 6e 67 20 6f 75 74 70 75 74  debugging output
75c0: 20 61 6e 64 20 69 73 20 6e 6f 74 0a 2a 2a 20 61   and is not.** a
75d0: 20 70 61 72 74 20 6f 66 20 61 6e 20 6f 72 64 69   part of an ordi
75e0: 6e 61 72 79 20 62 75 69 6c 64 2e 0a 2a 2f 0a 73  nary build..*/.s
75f0: 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72  tatic const char
7600: 20 2a 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 69 6e   *walLockName(in
7610: 74 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66  t lockIdx){.  if
7620: 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 57  ( lockIdx==WAL_W
7630: 52 49 54 45 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20  RITE_LOCK ){.   
7640: 20 72 65 74 75 72 6e 20 22 57 52 49 54 45 2d 4c   return "WRITE-L
7650: 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66  OCK";.  }else if
7660: 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 43  ( lockIdx==WAL_C
7670: 4b 50 54 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20  KPT_LOCK ){.    
7680: 72 65 74 75 72 6e 20 22 43 4b 50 54 2d 4c 4f 43  return "CKPT-LOC
7690: 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20  K";.  }else if( 
76a0: 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 52 45 43  lockIdx==WAL_REC
76b0: 4f 56 45 52 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20  OVER_LOCK ){.   
76c0: 20 72 65 74 75 72 6e 20 22 52 45 43 4f 56 45 52   return "RECOVER
76d0: 2d 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 7b  -LOCK";.  }else{
76e0: 0a 20 20 20 20 73 74 61 74 69 63 20 63 68 61 72  .    static char
76f0: 20 7a 4e 61 6d 65 5b 31 35 5d 3b 0a 20 20 20 20   zName[15];.    
7700: 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66  sqlite3_snprintf
7710: 28 73 69 7a 65 6f 66 28 7a 4e 61 6d 65 29 2c 20  (sizeof(zName), 
7720: 7a 4e 61 6d 65 2c 20 22 52 45 41 44 2d 4c 4f 43  zName, "READ-LOC
7730: 4b 5b 25 64 5d 22 2c 0a 20 20 20 20 20 20 20 20  K[%d]",.        
7740: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 63               loc
7750: 6b 49 64 78 2d 57 41 4c 5f 52 45 41 44 5f 4c 4f  kIdx-WAL_READ_LO
7760: 43 4b 28 30 29 29 3b 0a 20 20 20 20 72 65 74 75  CK(0));.    retu
7770: 72 6e 20 7a 4e 61 6d 65 3b 0a 20 20 7d 0a 7d 0a  rn zName;.  }.}.
7780: 23 65 6e 64 69 66 20 2f 2a 64 65 66 69 6e 65 64  #endif /*defined
7790: 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 7c 7c  (SQLITE_TEST) ||
77a0: 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
77b0: 44 45 42 55 47 29 20 2a 2f 0a 20 20 20 20 0a 0a  DEBUG) */.    ..
77c0: 2f 2a 0a 2a 2a 20 53 65 74 20 6f 72 20 72 65 6c  /*.** Set or rel
77d0: 65 61 73 65 20 6c 6f 63 6b 73 20 6f 6e 20 74 68  ease locks on th
77e0: 65 20 57 41 4c 2e 20 20 4c 6f 63 6b 73 20 61 72  e WAL.  Locks ar
77f0: 65 20 65 69 74 68 65 72 20 73 68 61 72 65 64 20  e either shared 
7800: 6f 72 20 65 78 63 6c 75 73 69 76 65 2e 0a 2a 2a  or exclusive..**
7810: 20 41 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62   A lock cannot b
7820: 65 20 6d 6f 76 65 64 20 64 69 72 65 63 74 6c 79  e moved directly
7830: 20 62 65 74 77 65 65 6e 20 73 68 61 72 65 64 20   between shared 
7840: 61 6e 64 20 65 78 63 6c 75 73 69 76 65 20 2d 20  and exclusive - 
7850: 69 74 20 6d 75 73 74 20 67 6f 0a 2a 2a 20 74 68  it must go.** th
7860: 72 6f 75 67 68 20 74 68 65 20 75 6e 6c 6f 63 6b  rough the unlock
7870: 65 64 20 73 74 61 74 65 20 66 69 72 73 74 2e 0a  ed state first..
7880: 2a 2a 0a 2a 2a 20 49 6e 20 6c 6f 63 6b 69 6e 67  **.** In locking
7890: 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2c  _mode=EXCLUSIVE,
78a0: 20 61 6c 6c 20 6f 66 20 74 68 65 73 65 20 72 6f   all of these ro
78b0: 75 74 69 6e 65 73 20 62 65 63 6f 6d 65 20 6e 6f  utines become no
78c0: 2d 6f 70 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  -ops..*/.static 
78d0: 69 6e 74 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65  int walLockShare
78e0: 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  d(Wal *pWal, int
78f0: 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 6e 74   lockIdx){.  int
7900: 20 72 63 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d   rc;.  if( pWal-
7910: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29  >exclusiveMode )
7920: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
7930: 4b 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  K;.  rc = sqlite
7940: 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d  3OsShmLock(pWal-
7950: 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c  >pDbFd, lockIdx,
7960: 20 31 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20   1,.            
7970: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
7980: 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51  TE_SHM_LOCK | SQ
7990: 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29  LITE_SHM_SHARED)
79a0: 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
79b0: 41 4c 25 70 3a 20 61 63 71 75 69 72 65 20 53 48  AL%p: acquire SH
79c0: 41 52 45 44 2d 25 73 20 25 73 5c 6e 22 2c 20 70  ARED-%s %s\n", p
79d0: 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20 20  Wal,.           
79e0: 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63   walLockName(loc
79f0: 6b 49 64 78 29 2c 20 72 63 20 3f 20 22 66 61 69  kIdx), rc ? "fai
7a00: 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
7a10: 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d   VVA_ONLY( pWal-
7a20: 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20 28 72 63  >lockError = (rc
7a30: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72  !=SQLITE_OK && r
7a40: 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 29 3b  c!=SQLITE_BUSY);
7a50: 20 29 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   ).  return rc;.
7a60: 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61  }.static void wa
7a70: 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 57 61  lUnlockShared(Wa
7a80: 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f 63  l *pWal, int loc
7a90: 6b 49 64 78 29 7b 0a 20 20 69 66 28 20 70 57 61  kIdx){.  if( pWa
7aa0: 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
7ab0: 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 28 76 6f   ) return;.  (vo
7ac0: 69 64 29 73 71 6c 69 74 65 33 4f 73 53 68 6d 4c  id)sqlite3OsShmL
7ad0: 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  ock(pWal->pDbFd,
7ae0: 20 6c 6f 63 6b 49 64 78 2c 20 31 2c 0a 20 20 20   lockIdx, 1,.   
7af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b00: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53 48 4d        SQLITE_SHM
7b10: 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45  _UNLOCK | SQLITE
7b20: 5f 53 48 4d 5f 53 48 41 52 45 44 29 3b 0a 20 20  _SHM_SHARED);.  
7b30: 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70  WALTRACE(("WAL%p
7b40: 3a 20 72 65 6c 65 61 73 65 20 53 48 41 52 45 44  : release SHARED
7b50: 2d 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 77 61  -%s\n", pWal, wa
7b60: 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64  lLockName(lockId
7b70: 78 29 29 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69  x)));.}.static i
7b80: 6e 74 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73  nt walLockExclus
7b90: 69 76 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69  ive(Wal *pWal, i
7ba0: 6e 74 20 6c 6f 63 6b 49 64 78 2c 20 69 6e 74 20  nt lockIdx, int 
7bb0: 6e 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  n){.  int rc;.  
7bc0: 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  if( pWal->exclus
7bd0: 69 76 65 4d 6f 64 65 20 29 20 72 65 74 75 72 6e  iveMode ) return
7be0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72 63   SQLITE_OK;.  rc
7bf0: 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4c   = sqlite3OsShmL
7c00: 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  ock(pWal->pDbFd,
7c10: 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c 0a 20 20 20   lockIdx, n,.   
7c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7c30: 20 20 20 20 20 53 51 4c 49 54 45 5f 53 48 4d 5f       SQLITE_SHM_
7c40: 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48  LOCK | SQLITE_SH
7c50: 4d 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20  M_EXCLUSIVE);.  
7c60: 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70  WALTRACE(("WAL%p
7c70: 3a 20 61 63 71 75 69 72 65 20 45 58 43 4c 55 53  : acquire EXCLUS
7c80: 49 56 45 2d 25 73 20 63 6e 74 3d 25 64 20 25 73  IVE-%s cnt=%d %s
7c90: 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20 20 20 20 20  \n", pWal,.     
7ca0: 20 20 20 20 20 20 20 77 61 6c 4c 6f 63 6b 4e 61         walLockNa
7cb0: 6d 65 28 6c 6f 63 6b 49 64 78 29 2c 20 6e 2c 20  me(lockIdx), n, 
7cc0: 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20  rc ? "failed" : 
7cd0: 22 6f 6b 22 29 29 3b 0a 20 20 56 56 41 5f 4f 4e  "ok"));.  VVA_ON
7ce0: 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72  LY( pWal->lockEr
7cf0: 72 6f 72 20 3d 20 28 72 63 21 3d 53 51 4c 49 54  ror = (rc!=SQLIT
7d00: 45 5f 4f 4b 20 26 26 20 72 63 21 3d 53 51 4c 49  E_OK && rc!=SQLI
7d10: 54 45 5f 42 55 53 59 29 3b 20 29 0a 20 20 72 65  TE_BUSY); ).  re
7d20: 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69  turn rc;.}.stati
7d30: 63 20 76 6f 69 64 20 77 61 6c 55 6e 6c 6f 63 6b  c void walUnlock
7d40: 45 78 63 6c 75 73 69 76 65 28 57 61 6c 20 2a 70  Exclusive(Wal *p
7d50: 57 61 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78  Wal, int lockIdx
7d60: 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69 66 28 20  , int n){.  if( 
7d70: 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
7d80: 6f 64 65 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ode ) return;.  
7d90: 28 76 6f 69 64 29 73 71 6c 69 74 65 33 4f 73 53  (void)sqlite3OsS
7da0: 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62  hmLock(pWal->pDb
7db0: 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c 0a  Fd, lockIdx, n,.
7dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7dd0: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
7de0: 53 48 4d 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51 4c  SHM_UNLOCK | SQL
7df0: 49 54 45 5f 53 48 4d 5f 45 58 43 4c 55 53 49 56  ITE_SHM_EXCLUSIV
7e00: 45 29 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28  E);.  WALTRACE((
7e10: 22 57 41 4c 25 70 3a 20 72 65 6c 65 61 73 65 20  "WAL%p: release 
7e20: 45 58 43 4c 55 53 49 56 45 2d 25 73 20 63 6e 74  EXCLUSIVE-%s cnt
7e30: 3d 25 64 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20 20  =%d\n", pWal,.  
7e40: 20 20 20 20 20 20 20 20 20 20 20 77 61 6c 4c 6f             walLo
7e50: 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c  ckName(lockIdx),
7e60: 20 6e 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43   n));.}../*.** C
7e70: 6f 6d 70 75 74 65 20 61 20 68 61 73 68 20 6f 6e  ompute a hash on
7e80: 20 61 20 70 61 67 65 20 6e 75 6d 62 65 72 2e 20   a page number. 
7e90: 20 54 68 65 20 72 65 73 75 6c 74 69 6e 67 20 68   The resulting h
7ea0: 61 73 68 20 76 61 6c 75 65 20 6d 75 73 74 20 6c  ash value must l
7eb0: 61 6e 64 0a 2a 2a 20 62 65 74 77 65 65 6e 20 30  and.** between 0
7ec0: 20 61 6e 64 20 28 48 41 53 48 54 41 42 4c 45 5f   and (HASHTABLE_
7ed0: 4e 53 4c 4f 54 2d 31 29 2e 20 20 54 68 65 20 77  NSLOT-1).  The w
7ee0: 61 6c 48 61 73 68 4e 65 78 74 28 29 20 66 75 6e  alHashNext() fun
7ef0: 63 74 69 6f 6e 20 61 64 76 61 6e 63 65 73 0a 2a  ction advances.*
7f00: 2a 20 74 68 65 20 68 61 73 68 20 74 6f 20 74 68  * the hash to th
7f10: 65 20 6e 65 78 74 20 76 61 6c 75 65 20 69 6e 20  e next value in 
7f20: 74 68 65 20 65 76 65 6e 74 20 6f 66 20 61 20 63  the event of a c
7f30: 6f 6c 6c 69 73 69 6f 6e 2e 0a 2a 2f 0a 73 74 61  ollision..*/.sta
7f40: 74 69 63 20 69 6e 74 20 77 61 6c 48 61 73 68 28  tic int walHash(
7f50: 75 33 32 20 69 50 61 67 65 29 7b 0a 20 20 61 73  u32 iPage){.  as
7f60: 73 65 72 74 28 20 69 50 61 67 65 3e 30 20 29 3b  sert( iPage>0 );
7f70: 0a 20 20 61 73 73 65 72 74 28 20 28 48 41 53 48  .  assert( (HASH
7f80: 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 26 20 28 48  TABLE_NSLOT & (H
7f90: 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31  ASHTABLE_NSLOT-1
7fa0: 29 29 3d 3d 30 20 29 3b 0a 20 20 72 65 74 75 72  ))==0 );.  retur
7fb0: 6e 20 28 69 50 61 67 65 2a 48 41 53 48 54 41 42  n (iPage*HASHTAB
7fc0: 4c 45 5f 48 41 53 48 5f 31 29 20 26 20 28 48 41  LE_HASH_1) & (HA
7fd0: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29  SHTABLE_NSLOT-1)
7fe0: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 77  ;.}.static int w
7ff0: 61 6c 4e 65 78 74 48 61 73 68 28 69 6e 74 20 69  alNextHash(int i
8000: 50 72 69 6f 72 48 61 73 68 29 7b 0a 20 20 72 65  PriorHash){.  re
8010: 74 75 72 6e 20 28 69 50 72 69 6f 72 48 61 73 68  turn (iPriorHash
8020: 2b 31 29 26 28 48 41 53 48 54 41 42 4c 45 5f 4e  +1)&(HASHTABLE_N
8030: 53 4c 4f 54 2d 31 29 3b 0a 7d 0a 0a 2f 2a 20 0a  SLOT-1);.}../* .
8040: 2a 2a 20 52 65 74 75 72 6e 20 70 6f 69 6e 74 65  ** Return pointe
8050: 72 73 20 74 6f 20 74 68 65 20 68 61 73 68 20 74  rs to the hash t
8060: 61 62 6c 65 20 61 6e 64 20 70 61 67 65 20 6e 75  able and page nu
8070: 6d 62 65 72 20 61 72 72 61 79 20 73 74 6f 72 65  mber array store
8080: 64 20 6f 6e 0a 2a 2a 20 70 61 67 65 20 69 48 61  d on.** page iHa
8090: 73 68 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  sh of the wal-in
80a0: 64 65 78 2e 20 54 68 65 20 77 61 6c 2d 69 6e 64  dex. The wal-ind
80b0: 65 78 20 69 73 20 62 72 6f 6b 65 6e 20 69 6e 74  ex is broken int
80c0: 6f 20 33 32 4b 42 20 70 61 67 65 73 0a 2a 2a 20  o 32KB pages.** 
80d0: 6e 75 6d 62 65 72 65 64 20 73 74 61 72 74 69 6e  numbered startin
80e0: 67 20 66 72 6f 6d 20 30 2e 0a 2a 2a 0a 2a 2a 20  g from 0..**.** 
80f0: 53 65 74 20 6f 75 74 70 75 74 20 76 61 72 69 61  Set output varia
8100: 62 6c 65 20 2a 70 61 48 61 73 68 20 74 6f 20 70  ble *paHash to p
8110: 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74 61 72  oint to the star
8120: 74 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61  t of the hash ta
8130: 62 6c 65 0a 2a 2a 20 69 6e 20 74 68 65 20 77 61  ble.** in the wa
8140: 6c 2d 69 6e 64 65 78 20 66 69 6c 65 2e 20 53 65  l-index file. Se
8150: 74 20 2a 70 69 5a 65 72 6f 20 74 6f 20 6f 6e 65  t *piZero to one
8160: 20 6c 65 73 73 20 74 68 61 6e 20 74 68 65 20 66   less than the f
8170: 72 61 6d 65 20 0a 2a 2a 20 6e 75 6d 62 65 72 20  rame .** number 
8180: 6f 66 20 74 68 65 20 66 69 72 73 74 20 66 72 61  of the first fra
8190: 6d 65 20 69 6e 64 65 78 65 64 20 62 79 20 74 68  me indexed by th
81a0: 69 73 20 68 61 73 68 20 74 61 62 6c 65 2e 20 49  is hash table. I
81b0: 66 20 61 0a 2a 2a 20 73 6c 6f 74 20 69 6e 20 74  f a.** slot in t
81c0: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 69 73  he hash table is
81d0: 20 73 65 74 20 74 6f 20 4e 2c 20 69 74 20 72 65   set to N, it re
81e0: 66 65 72 73 20 74 6f 20 66 72 61 6d 65 20 6e 75  fers to frame nu
81f0: 6d 62 65 72 20 0a 2a 2a 20 28 2a 70 69 5a 65 72  mber .** (*piZer
8200: 6f 2b 4e 29 20 69 6e 20 74 68 65 20 6c 6f 67 2e  o+N) in the log.
8210: 0a 2a 2a 0a 2a 2a 20 46 69 6e 61 6c 6c 79 2c 20  .**.** Finally, 
8220: 73 65 74 20 2a 70 61 50 67 6e 6f 20 73 6f 20 74  set *paPgno so t
8230: 68 61 74 20 2a 70 61 50 67 6e 6f 5b 31 5d 20 69  hat *paPgno[1] i
8240: 73 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65  s the page numbe
8250: 72 20 6f 66 20 74 68 65 0a 2a 2a 20 66 69 72 73  r of the.** firs
8260: 74 20 66 72 61 6d 65 20 69 6e 64 65 78 65 64 20  t frame indexed 
8270: 62 79 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  by the hash tabl
8280: 65 2c 20 66 72 61 6d 65 20 28 2a 70 69 5a 65 72  e, frame (*piZer
8290: 6f 2b 31 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  o+1)..*/.static 
82a0: 69 6e 74 20 77 61 6c 48 61 73 68 47 65 74 28 0a  int walHashGet(.
82b0: 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
82c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
82d0: 20 20 2f 2a 20 57 41 4c 20 68 61 6e 64 6c 65 20    /* WAL handle 
82e0: 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73 68 2c 20  */.  int iHash, 
82f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8300: 20 20 20 20 20 2f 2a 20 46 69 6e 64 20 74 68 65       /* Find the
8310: 20 69 48 61 73 68 27 74 68 20 74 61 62 6c 65 20   iHash'th table 
8320: 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 68 74  */.  volatile ht
8330: 5f 73 6c 6f 74 20 2a 2a 70 61 48 61 73 68 2c 20  _slot **paHash, 
8340: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69       /* OUT: Poi
8350: 6e 74 65 72 20 74 6f 20 68 61 73 68 20 69 6e 64  nter to hash ind
8360: 65 78 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65  ex */.  volatile
8370: 20 75 33 32 20 2a 2a 70 61 50 67 6e 6f 2c 20 20   u32 **paPgno,  
8380: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
8390: 50 6f 69 6e 74 65 72 20 74 6f 20 70 61 67 65 20  Pointer to page 
83a0: 6e 75 6d 62 65 72 20 61 72 72 61 79 20 2a 2f 0a  number array */.
83b0: 20 20 75 33 32 20 2a 70 69 5a 65 72 6f 20 20 20    u32 *piZero   
83c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
83d0: 20 20 2f 2a 20 4f 55 54 3a 20 46 72 61 6d 65 20    /* OUT: Frame 
83e0: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20  associated with 
83f0: 2a 70 61 50 67 6e 6f 5b 30 5d 20 2a 2f 0a 29 7b  *paPgno[0] */.){
8400: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
8410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8420: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
8430: 65 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20  e */.  volatile 
8440: 75 33 32 20 2a 61 50 67 6e 6f 3b 0a 0a 20 20 72  u32 *aPgno;..  r
8450: 63 20 3d 20 77 61 6c 49 6e 64 65 78 50 61 67 65  c = walIndexPage
8460: 28 70 57 61 6c 2c 20 69 48 61 73 68 2c 20 26 61  (pWal, iHash, &a
8470: 50 67 6e 6f 29 3b 0a 20 20 61 73 73 65 72 74 28  Pgno);.  assert(
8480: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc==SQLITE_OK |
8490: 7c 20 69 48 61 73 68 3e 30 20 29 3b 0a 0a 20 20  | iHash>0 );..  
84a0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
84b0: 4b 20 29 7b 0a 20 20 20 20 75 33 32 20 69 5a 65  K ){.    u32 iZe
84c0: 72 6f 3b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65  ro;.    volatile
84d0: 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b   ht_slot *aHash;
84e0: 0a 0a 20 20 20 20 61 48 61 73 68 20 3d 20 28 76  ..    aHash = (v
84f0: 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20  olatile ht_slot 
8500: 2a 29 26 61 50 67 6e 6f 5b 48 41 53 48 54 41 42  *)&aPgno[HASHTAB
8510: 4c 45 5f 4e 50 41 47 45 5d 3b 0a 20 20 20 20 69  LE_NPAGE];.    i
8520: 66 28 20 69 48 61 73 68 3d 3d 30 20 29 7b 0a 20  f( iHash==0 ){. 
8530: 20 20 20 20 20 61 50 67 6e 6f 20 3d 20 26 61 50       aPgno = &aP
8540: 67 6e 6f 5b 57 41 4c 49 4e 44 45 58 5f 48 44 52  gno[WALINDEX_HDR
8550: 5f 53 49 5a 45 2f 73 69 7a 65 6f 66 28 75 33 32  _SIZE/sizeof(u32
8560: 29 5d 3b 0a 20 20 20 20 20 20 69 5a 65 72 6f 20  )];.      iZero 
8570: 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  = 0;.    }else{.
8580: 20 20 20 20 20 20 69 5a 65 72 6f 20 3d 20 48 41        iZero = HA
8590: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e  SHTABLE_NPAGE_ON
85a0: 45 20 2b 20 28 69 48 61 73 68 2d 31 29 2a 48 41  E + (iHash-1)*HA
85b0: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3b 0a 20  SHTABLE_NPAGE;. 
85c0: 20 20 20 7d 0a 20 20 0a 20 20 20 20 2a 70 61 50     }.  .    *paP
85d0: 67 6e 6f 20 3d 20 26 61 50 67 6e 6f 5b 2d 31 5d  gno = &aPgno[-1]
85e0: 3b 0a 20 20 20 20 2a 70 61 48 61 73 68 20 3d 20  ;.    *paHash = 
85f0: 61 48 61 73 68 3b 0a 20 20 20 20 2a 70 69 5a 65  aHash;.    *piZe
8600: 72 6f 20 3d 20 69 5a 65 72 6f 3b 0a 20 20 7d 0a  ro = iZero;.  }.
8610: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
8620: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
8630: 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 77   number of the w
8640: 61 6c 2d 69 6e 64 65 78 20 70 61 67 65 20 74 68  al-index page th
8650: 61 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  at contains the 
8660: 68 61 73 68 2d 74 61 62 6c 65 0a 2a 2a 20 61 6e  hash-table.** an
8670: 64 20 70 61 67 65 2d 6e 75 6d 62 65 72 20 61 72  d page-number ar
8680: 72 61 79 20 74 68 61 74 20 63 6f 6e 74 61 69 6e  ray that contain
8690: 20 65 6e 74 72 69 65 73 20 63 6f 72 72 65 73 70   entries corresp
86a0: 6f 6e 64 69 6e 67 20 74 6f 20 57 41 4c 20 66 72  onding to WAL fr
86b0: 61 6d 65 0a 2a 2a 20 69 46 72 61 6d 65 2e 20 54  ame.** iFrame. T
86c0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
86d0: 62 72 6f 6b 65 6e 20 75 70 20 69 6e 74 6f 20 33  broken up into 3
86e0: 32 4b 42 20 70 61 67 65 73 2e 20 57 61 6c 2d 69  2KB pages. Wal-i
86f0: 6e 64 65 78 20 70 61 67 65 73 20 0a 2a 2a 20 61  ndex pages .** a
8700: 72 65 20 6e 75 6d 62 65 72 65 64 20 73 74 61 72  re numbered star
8710: 74 69 6e 67 20 66 72 6f 6d 20 30 2e 0a 2a 2f 0a  ting from 0..*/.
8720: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 46 72  static int walFr
8730: 61 6d 65 50 61 67 65 28 75 33 32 20 69 46 72 61  amePage(u32 iFra
8740: 6d 65 29 7b 0a 20 20 69 6e 74 20 69 48 61 73 68  me){.  int iHash
8750: 20 3d 20 28 69 46 72 61 6d 65 2b 48 41 53 48 54   = (iFrame+HASHT
8760: 41 42 4c 45 5f 4e 50 41 47 45 2d 48 41 53 48 54  ABLE_NPAGE-HASHT
8770: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2d 31  ABLE_NPAGE_ONE-1
8780: 29 20 2f 20 48 41 53 48 54 41 42 4c 45 5f 4e 50  ) / HASHTABLE_NP
8790: 41 47 45 3b 0a 20 20 61 73 73 65 72 74 28 20 28  AGE;.  assert( (
87a0: 69 48 61 73 68 3d 3d 30 20 7c 7c 20 69 46 72 61  iHash==0 || iFra
87b0: 6d 65 3e 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  me>HASHTABLE_NPA
87c0: 47 45 5f 4f 4e 45 29 0a 20 20 20 20 20 20 20 26  GE_ONE).       &
87d0: 26 20 28 69 48 61 73 68 3e 3d 31 20 7c 7c 20 69  & (iHash>=1 || i
87e0: 46 72 61 6d 65 3c 3d 48 41 53 48 54 41 42 4c 45  Frame<=HASHTABLE
87f0: 5f 4e 50 41 47 45 5f 4f 4e 45 29 0a 20 20 20 20  _NPAGE_ONE).    
8800: 20 20 20 26 26 20 28 69 48 61 73 68 3c 3d 31 20     && (iHash<=1 
8810: 7c 7c 20 69 46 72 61 6d 65 3e 28 48 41 53 48 54  || iFrame>(HASHT
8820: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 48  ABLE_NPAGE_ONE+H
8830: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 29 29  ASHTABLE_NPAGE))
8840: 0a 20 20 20 20 20 20 20 26 26 20 28 69 48 61 73  .       && (iHas
8850: 68 3e 3d 32 20 7c 7c 20 69 46 72 61 6d 65 3c 3d  h>=2 || iFrame<=
8860: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
8870: 4f 4e 45 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50  ONE+HASHTABLE_NP
8880: 41 47 45 29 0a 20 20 20 20 20 20 20 26 26 20 28  AGE).       && (
8890: 69 48 61 73 68 3c 3d 32 20 7c 7c 20 69 46 72 61  iHash<=2 || iFra
88a0: 6d 65 3e 28 48 41 53 48 54 41 42 4c 45 5f 4e 50  me>(HASHTABLE_NP
88b0: 41 47 45 5f 4f 4e 45 2b 32 2a 48 41 53 48 54 41  AGE_ONE+2*HASHTA
88c0: 42 4c 45 5f 4e 50 41 47 45 29 29 0a 20 20 29 3b  BLE_NPAGE)).  );
88d0: 0a 20 20 72 65 74 75 72 6e 20 69 48 61 73 68 3b  .  return iHash;
88e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
88f0: 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72   the page number
8900: 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
8910: 20 66 72 61 6d 65 20 69 46 72 61 6d 65 20 69 6e   frame iFrame in
8920: 20 74 68 69 73 20 57 41 4c 2e 0a 2a 2f 0a 73 74   this WAL..*/.st
8930: 61 74 69 63 20 75 33 32 20 77 61 6c 46 72 61 6d  atic u32 walFram
8940: 65 50 67 6e 6f 28 57 61 6c 20 2a 70 57 61 6c 2c  ePgno(Wal *pWal,
8950: 20 75 33 32 20 69 46 72 61 6d 65 29 7b 0a 20 20   u32 iFrame){.  
8960: 69 6e 74 20 69 48 61 73 68 20 3d 20 77 61 6c 46  int iHash = walF
8970: 72 61 6d 65 50 61 67 65 28 69 46 72 61 6d 65 29  ramePage(iFrame)
8980: 3b 0a 20 20 69 66 28 20 69 48 61 73 68 3d 3d 30  ;.  if( iHash==0
8990: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
89a0: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
89b0: 5b 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49  [WALINDEX_HDR_SI
89c0: 5a 45 2f 73 69 7a 65 6f 66 28 75 33 32 29 20 2b  ZE/sizeof(u32) +
89d0: 20 69 46 72 61 6d 65 20 2d 20 31 5d 3b 0a 20 20   iFrame - 1];.  
89e0: 7d 0a 20 20 72 65 74 75 72 6e 20 70 57 61 6c 2d  }.  return pWal-
89f0: 3e 61 70 57 69 44 61 74 61 5b 69 48 61 73 68 5d  >apWiData[iHash]
8a00: 5b 28 69 46 72 61 6d 65 2d 31 2d 48 41 53 48 54  [(iFrame-1-HASHT
8a10: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 25  ABLE_NPAGE_ONE)%
8a20: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5d  HASHTABLE_NPAGE]
8a30: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76  ;.}../*.** Remov
8a40: 65 20 65 6e 74 72 69 65 73 20 66 72 6f 6d 20 74  e entries from t
8a50: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 74 68  he hash table th
8a60: 61 74 20 70 6f 69 6e 74 20 74 6f 20 57 41 4c 20  at point to WAL 
8a70: 73 6c 6f 74 73 20 67 72 65 61 74 65 72 0a 2a 2a  slots greater.**
8a80: 20 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e   than pWal->hdr.
8a90: 6d 78 46 72 61 6d 65 2e 0a 2a 2a 0a 2a 2a 20 54  mxFrame..**.** T
8aa0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
8ab0: 63 61 6c 6c 65 64 20 77 68 65 6e 65 76 65 72 20  called whenever 
8ac0: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
8ad0: 65 20 69 73 20 64 65 63 72 65 61 73 65 64 20 64  e is decreased d
8ae0: 75 65 0a 2a 2a 20 74 6f 20 61 20 72 6f 6c 6c 62  ue.** to a rollb
8af0: 61 63 6b 20 6f 72 20 73 61 76 65 70 6f 69 6e 74  ack or savepoint
8b00: 2e 0a 2a 2a 0a 2a 2a 20 41 74 20 6d 6f 73 74 20  ..**.** At most 
8b10: 6f 6e 6c 79 20 74 68 65 20 68 61 73 68 20 74 61  only the hash ta
8b20: 62 6c 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 70  ble containing p
8b30: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
8b40: 20 6e 65 65 64 73 20 74 6f 20 62 65 0a 2a 2a 20   needs to be.** 
8b50: 75 70 64 61 74 65 64 2e 20 20 41 6e 79 20 6c 61  updated.  Any la
8b60: 74 65 72 20 68 61 73 68 20 74 61 62 6c 65 73 20  ter hash tables 
8b70: 77 69 6c 6c 20 62 65 20 61 75 74 6f 6d 61 74 69  will be automati
8b80: 63 61 6c 6c 79 20 63 6c 65 61 72 65 64 20 77 68  cally cleared wh
8b90: 65 6e 0a 2a 2a 20 70 57 61 6c 2d 3e 68 64 72 2e  en.** pWal->hdr.
8ba0: 6d 78 46 72 61 6d 65 20 61 64 76 61 6e 63 65 73  mxFrame advances
8bb0: 20 74 6f 20 74 68 65 20 70 6f 69 6e 74 20 77 68   to the point wh
8bc0: 65 72 65 20 74 68 6f 73 65 20 68 61 73 68 20 74  ere those hash t
8bd0: 61 62 6c 65 73 20 61 72 65 0a 2a 2a 20 61 63 74  ables are.** act
8be0: 75 61 6c 6c 79 20 6e 65 65 64 65 64 2e 0a 2a 2f  ually needed..*/
8bf0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
8c00: 43 6c 65 61 6e 75 70 48 61 73 68 28 57 61 6c 20  CleanupHash(Wal 
8c10: 2a 70 57 61 6c 29 7b 0a 20 20 76 6f 6c 61 74 69  *pWal){.  volati
8c20: 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73  le ht_slot *aHas
8c30: 68 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69  h;        /* Poi
8c40: 6e 74 65 72 20 74 6f 20 68 61 73 68 20 74 61 62  nter to hash tab
8c50: 6c 65 20 74 6f 20 63 6c 65 61 72 20 2a 2f 0a 20  le to clear */. 
8c60: 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61   volatile u32 *a
8c70: 50 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20  Pgno;           
8c80: 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20   /* Page number 
8c90: 61 72 72 61 79 20 66 6f 72 20 68 61 73 68 20 74  array for hash t
8ca0: 61 62 6c 65 20 2a 2f 0a 20 20 75 33 32 20 69 5a  able */.  u32 iZ
8cb0: 65 72 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20  ero;            
8cc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 66 72 61            /* fra
8cd0: 6d 65 20 3d 3d 20 28 61 48 61 73 68 5b 78 5d 2b  me == (aHash[x]+
8ce0: 69 5a 65 72 6f 29 20 2a 2f 0a 20 20 69 6e 74 20  iZero) */.  int 
8cf0: 69 4c 69 6d 69 74 20 3d 20 30 3b 20 20 20 20 20  iLimit = 0;     
8d00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 5a              /* Z
8d10: 65 72 6f 20 76 61 6c 75 65 73 20 67 72 65 61 74  ero values great
8d20: 65 72 20 74 68 61 6e 20 74 68 69 73 20 2a 2f 0a  er than this */.
8d30: 20 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20    int nByte;    
8d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8d50: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
8d60: 79 74 65 73 20 74 6f 20 7a 65 72 6f 20 69 6e 20  ytes to zero in 
8d70: 61 50 67 6e 6f 5b 5d 20 2a 2f 0a 20 20 69 6e 74  aPgno[] */.  int
8d80: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
8d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8da0: 55 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20  Used to iterate 
8db0: 74 68 72 6f 75 67 68 20 61 48 61 73 68 5b 5d 20  through aHash[] 
8dc0: 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57  */..  assert( pW
8dd0: 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
8de0: 0a 20 20 74 65 73 74 63 61 73 65 28 20 70 57 61  .  testcase( pWa
8df0: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d  l->hdr.mxFrame==
8e00: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
8e10: 4f 4e 45 2d 31 20 29 3b 0a 20 20 74 65 73 74 63  ONE-1 );.  testc
8e20: 61 73 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  ase( pWal->hdr.m
8e30: 78 46 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c  xFrame==HASHTABL
8e40: 45 5f 4e 50 41 47 45 5f 4f 4e 45 20 29 3b 0a 20  E_NPAGE_ONE );. 
8e50: 20 74 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d   testcase( pWal-
8e60: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 48 41  >hdr.mxFrame==HA
8e70: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e  SHTABLE_NPAGE_ON
8e80: 45 2b 31 20 29 3b 0a 0a 20 20 69 66 28 20 70 57  E+1 );..  if( pW
8e90: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d  al->hdr.mxFrame=
8ea0: 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 0a 20 20  =0 ) return;..  
8eb0: 2f 2a 20 4f 62 74 61 69 6e 20 70 6f 69 6e 74 65  /* Obtain pointe
8ec0: 72 73 20 74 6f 20 74 68 65 20 68 61 73 68 2d 74  rs to the hash-t
8ed0: 61 62 6c 65 20 61 6e 64 20 70 61 67 65 2d 6e 75  able and page-nu
8ee0: 6d 62 65 72 20 61 72 72 61 79 20 63 6f 6e 74 61  mber array conta
8ef0: 69 6e 69 6e 67 20 0a 20 20 2a 2a 20 74 68 65 20  ining .  ** the 
8f00: 65 6e 74 72 79 20 74 68 61 74 20 63 6f 72 72 65  entry that corre
8f10: 73 70 6f 6e 64 73 20 74 6f 20 66 72 61 6d 65 20  sponds to frame 
8f20: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
8f30: 65 2e 20 49 74 20 69 73 20 67 75 61 72 61 6e 74  e. It is guarant
8f40: 65 65 64 0a 20 20 2a 2a 20 74 68 61 74 20 74 68  eed.  ** that th
8f50: 65 20 70 61 67 65 20 73 61 69 64 20 68 61 73 68  e page said hash
8f60: 2d 74 61 62 6c 65 20 61 6e 64 20 61 72 72 61 79  -table and array
8f70: 20 72 65 73 69 64 65 20 6f 6e 20 69 73 20 61 6c   reside on is al
8f80: 72 65 61 64 79 20 6d 61 70 70 65 64 2e 0a 20 20  ready mapped..  
8f90: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  */.  assert( pWa
8fa0: 6c 2d 3e 6e 57 69 44 61 74 61 3e 77 61 6c 46 72  l->nWiData>walFr
8fb0: 61 6d 65 50 61 67 65 28 70 57 61 6c 2d 3e 68 64  amePage(pWal->hd
8fc0: 72 2e 6d 78 46 72 61 6d 65 29 20 29 3b 0a 20 20  r.mxFrame) );.  
8fd0: 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 61 70  assert( pWal->ap
8fe0: 57 69 44 61 74 61 5b 77 61 6c 46 72 61 6d 65 50  WiData[walFrameP
8ff0: 61 67 65 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  age(pWal->hdr.mx
9000: 46 72 61 6d 65 29 5d 20 29 3b 0a 20 20 77 61 6c  Frame)] );.  wal
9010: 48 61 73 68 47 65 74 28 70 57 61 6c 2c 20 77 61  HashGet(pWal, wa
9020: 6c 46 72 61 6d 65 50 61 67 65 28 70 57 61 6c 2d  lFramePage(pWal-
9030: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 29 2c 20 26  >hdr.mxFrame), &
9040: 61 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20 26  aHash, &aPgno, &
9050: 69 5a 65 72 6f 29 3b 0a 0a 20 20 2f 2a 20 5a 65  iZero);..  /* Ze
9060: 72 6f 20 61 6c 6c 20 68 61 73 68 2d 74 61 62 6c  ro all hash-tabl
9070: 65 20 65 6e 74 72 69 65 73 20 74 68 61 74 20 63  e entries that c
9080: 6f 72 72 65 73 70 6f 6e 64 20 74 6f 20 66 72 61  orrespond to fra
9090: 6d 65 20 6e 75 6d 62 65 72 73 20 67 72 65 61 74  me numbers great
90a0: 65 72 0a 20 20 2a 2a 20 74 68 61 6e 20 70 57 61  er.  ** than pWa
90b0: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a  l->hdr.mxFrame..
90c0: 20 20 2a 2f 0a 20 20 69 4c 69 6d 69 74 20 3d 20    */.  iLimit = 
90d0: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
90e0: 65 20 2d 20 69 5a 65 72 6f 3b 0a 20 20 61 73 73  e - iZero;.  ass
90f0: 65 72 74 28 20 69 4c 69 6d 69 74 3e 30 20 29 3b  ert( iLimit>0 );
9100: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48 41  .  for(i=0; i<HA
9110: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 20 69  SHTABLE_NSLOT; i
9120: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 61 48 61  ++){.    if( aHa
9130: 73 68 5b 69 5d 3e 69 4c 69 6d 69 74 20 29 7b 0a  sh[i]>iLimit ){.
9140: 20 20 20 20 20 20 61 48 61 73 68 5b 69 5d 20 3d        aHash[i] =
9150: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20   0;.    }.  }.  
9160: 0a 20 20 2f 2a 20 5a 65 72 6f 20 74 68 65 20 65  .  /* Zero the e
9170: 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20 61 50  ntries in the aP
9180: 67 6e 6f 20 61 72 72 61 79 20 74 68 61 74 20 63  gno array that c
9190: 6f 72 72 65 73 70 6f 6e 64 20 74 6f 20 66 72 61  orrespond to fra
91a0: 6d 65 73 20 77 69 74 68 0a 20 20 2a 2a 20 66 72  mes with.  ** fr
91b0: 61 6d 65 20 6e 75 6d 62 65 72 73 20 67 72 65 61  ame numbers grea
91c0: 74 65 72 20 74 68 61 6e 20 70 57 61 6c 2d 3e 68  ter than pWal->h
91d0: 64 72 2e 6d 78 46 72 61 6d 65 2e 20 0a 20 20 2a  dr.mxFrame. .  *
91e0: 2f 0a 20 20 6e 42 79 74 65 20 3d 20 28 28 63 68  /.  nByte = ((ch
91f0: 61 72 20 2a 29 61 48 61 73 68 20 2d 20 28 63 68  ar *)aHash - (ch
9200: 61 72 20 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d  ar *)&aPgno[iLim
9210: 69 74 2b 31 5d 29 3b 0a 20 20 6d 65 6d 73 65 74  it+1]);.  memset
9220: 28 28 76 6f 69 64 20 2a 29 26 61 50 67 6e 6f 5b  ((void *)&aPgno[
9230: 69 4c 69 6d 69 74 2b 31 5d 2c 20 30 2c 20 6e 42  iLimit+1], 0, nB
9240: 79 74 65 29 3b 0a 0a 23 69 66 64 65 66 20 53 51  yte);..#ifdef SQ
9250: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45  LITE_ENABLE_EXPE
9260: 4e 53 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f  NSIVE_ASSERT.  /
9270: 2a 20 56 65 72 69 66 79 20 74 68 61 74 20 74 68  * Verify that th
9280: 65 20 65 76 65 72 79 20 65 6e 74 72 79 20 69 6e  e every entry in
9290: 20 74 68 65 20 6d 61 70 70 69 6e 67 20 72 65 67   the mapping reg
92a0: 69 6f 6e 20 69 73 20 73 74 69 6c 6c 20 72 65 61  ion is still rea
92b0: 63 68 61 62 6c 65 0a 20 20 2a 2a 20 76 69 61 20  chable.  ** via 
92c0: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 65  the hash table e
92d0: 76 65 6e 20 61 66 74 65 72 20 74 68 65 20 63 6c  ven after the cl
92e0: 65 61 6e 75 70 2e 0a 20 20 2a 2f 0a 20 20 69 66  eanup..  */.  if
92f0: 28 20 69 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20  ( iLimit ){.    
9300: 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
9310: 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72   /* Loop counter
9320: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 4b 65 79   */.    int iKey
9330: 3b 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68  ;        /* Hash
9340: 20 6b 65 79 20 2a 2f 0a 20 20 20 20 66 6f 72 28   key */.    for(
9350: 69 3d 31 3b 20 69 3c 3d 69 4c 69 6d 69 74 3b 20  i=1; i<=iLimit; 
9360: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 66 6f 72 28  i++){.      for(
9370: 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 61 50 67  iKey=walHash(aPg
9380: 6e 6f 5b 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b  no[i]); aHash[iK
9390: 65 79 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78  ey]; iKey=walNex
93a0: 74 48 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20  tHash(iKey)){.  
93b0: 20 20 20 20 20 20 69 66 28 20 61 48 61 73 68 5b        if( aHash[
93c0: 69 4b 65 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b  iKey]==i ) break
93d0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
93e0: 61 73 73 65 72 74 28 20 61 48 61 73 68 5b 69 4b  assert( aHash[iK
93f0: 65 79 5d 3d 3d 69 20 29 3b 0a 20 20 20 20 7d 0a  ey]==i );.    }.
9400: 20 20 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51    }.#endif /* SQ
9410: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45  LITE_ENABLE_EXPE
9420: 4e 53 49 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a  NSIVE_ASSERT */.
9430: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 6e  }.../*.** Set an
9440: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 77 61   entry in the wa
9450: 6c 2d 69 6e 64 65 78 20 74 68 61 74 20 77 69 6c  l-index that wil
9460: 6c 20 6d 61 70 20 64 61 74 61 62 61 73 65 20 70  l map database p
9470: 61 67 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 70 50  age number.** pP
9480: 61 67 65 20 69 6e 74 6f 20 57 41 4c 20 66 72 61  age into WAL fra
9490: 6d 65 20 69 46 72 61 6d 65 2e 0a 2a 2f 0a 73 74  me iFrame..*/.st
94a0: 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e 64 65  atic int walInde
94b0: 78 41 70 70 65 6e 64 28 57 61 6c 20 2a 70 57 61  xAppend(Wal *pWa
94c0: 6c 2c 20 75 33 32 20 69 46 72 61 6d 65 2c 20 75  l, u32 iFrame, u
94d0: 33 32 20 69 50 61 67 65 29 7b 0a 20 20 69 6e 74  32 iPage){.  int
94e0: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
94f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9500: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
9510: 20 75 33 32 20 69 5a 65 72 6f 3b 20 20 20 20 20   u32 iZero;     
9520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9530: 20 2f 2a 20 4f 6e 65 20 6c 65 73 73 20 74 68 61   /* One less tha
9540: 6e 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 6f  n frame number o
9550: 66 20 61 50 67 6e 6f 5b 31 5d 20 2a 2f 0a 20 20  f aPgno[1] */.  
9560: 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50  volatile u32 *aP
9570: 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20  gno;            
9580: 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20 61  /* Page number a
9590: 72 72 61 79 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  rray */.  volati
95a0: 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73  le ht_slot *aHas
95b0: 68 3b 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73  h;        /* Has
95c0: 68 20 74 61 62 6c 65 20 2a 2f 0a 0a 20 20 72 63  h table */..  rc
95d0: 20 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70 57   = walHashGet(pW
95e0: 61 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61 67 65  al, walFramePage
95f0: 28 69 46 72 61 6d 65 29 2c 20 26 61 48 61 73 68  (iFrame), &aHash
9600: 2c 20 26 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f  , &aPgno, &iZero
9610: 29 3b 0a 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e  );..  /* Assumin
9620: 67 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  g the wal-index 
9630: 66 69 6c 65 20 77 61 73 20 73 75 63 63 65 73 73  file was success
9640: 66 75 6c 6c 79 20 6d 61 70 70 65 64 2c 20 70 6f  fully mapped, po
9650: 70 75 6c 61 74 65 20 74 68 65 0a 20 20 2a 2a 20  pulate the.  ** 
9660: 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61  page number arra
9670: 79 20 61 6e 64 20 68 61 73 68 20 74 61 62 6c 65  y and hash table
9680: 20 65 6e 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 69   entry..  */.  i
9690: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
96a0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 4b 65 79   ){.    int iKey
96b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
96c0: 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61        /* Hash ta
96d0: 62 6c 65 20 6b 65 79 20 2a 2f 0a 20 20 20 20 69  ble key */.    i
96e0: 6e 74 20 69 64 78 3b 20 20 20 20 20 20 20 20 20  nt idx;         
96f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9700: 56 61 6c 75 65 20 74 6f 20 77 72 69 74 65 20 74  Value to write t
9710: 6f 20 68 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f  o hash-table slo
9720: 74 20 2a 2f 0a 20 20 20 20 54 45 53 54 4f 4e 4c  t */.    TESTONL
9730: 59 28 20 69 6e 74 20 6e 43 6f 6c 6c 69 64 65 20  Y( int nCollide 
9740: 3d 20 30 3b 20 20 20 2f 2a 20 4e 75 6d 62 65 72  = 0;   /* Number
9750: 20 6f 66 20 68 61 73 68 20 63 6f 6c 6c 69 73 69   of hash collisi
9760: 6f 6e 73 20 2a 2f 20 29 0a 0a 20 20 20 20 69 64  ons */ )..    id
9770: 78 20 3d 20 69 46 72 61 6d 65 20 2d 20 69 5a 65  x = iFrame - iZe
9780: 72 6f 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  ro;.    assert( 
9790: 69 64 78 20 3c 3d 20 48 41 53 48 54 41 42 4c 45  idx <= HASHTABLE
97a0: 5f 4e 53 4c 4f 54 2f 32 20 2b 20 31 20 29 3b 0a  _NSLOT/2 + 1 );.
97b0: 20 20 20 20 0a 20 20 20 20 2f 2a 20 49 66 20 74      .    /* If t
97c0: 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74  his is the first
97d0: 20 65 6e 74 72 79 20 74 6f 20 62 65 20 61 64 64   entry to be add
97e0: 65 64 20 74 6f 20 74 68 69 73 20 68 61 73 68 2d  ed to this hash-
97f0: 74 61 62 6c 65 2c 20 7a 65 72 6f 20 74 68 65 0a  table, zero the.
9800: 20 20 20 20 2a 2a 20 65 6e 74 69 72 65 20 68 61      ** entire ha
9810: 73 68 20 74 61 62 6c 65 20 61 6e 64 20 61 50 67  sh table and aPg
9820: 6e 6f 5b 5d 20 61 72 72 61 79 20 62 65 66 6f 72  no[] array befor
9830: 65 20 70 72 6f 63 65 64 69 6e 67 2e 20 0a 20 20  e proceding. .  
9840: 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 69 64 78    */.    if( idx
9850: 3d 3d 31 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  ==1 ){.      int
9860: 20 6e 42 79 74 65 20 3d 20 28 75 38 20 2a 29 26   nByte = (u8 *)&
9870: 61 48 61 73 68 5b 48 41 53 48 54 41 42 4c 45 5f  aHash[HASHTABLE_
9880: 4e 53 4c 4f 54 5d 20 2d 20 28 75 38 20 2a 29 26  NSLOT] - (u8 *)&
9890: 61 50 67 6e 6f 5b 31 5d 3b 0a 20 20 20 20 20 20  aPgno[1];.      
98a0: 6d 65 6d 73 65 74 28 28 76 6f 69 64 2a 29 26 61  memset((void*)&a
98b0: 50 67 6e 6f 5b 31 5d 2c 20 30 2c 20 6e 42 79 74  Pgno[1], 0, nByt
98c0: 65 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  e);.    }..    /
98d0: 2a 20 49 66 20 74 68 65 20 65 6e 74 72 79 20 69  * If the entry i
98e0: 6e 20 61 50 67 6e 6f 5b 5d 20 69 73 20 61 6c 72  n aPgno[] is alr
98f0: 65 61 64 79 20 73 65 74 2c 20 74 68 65 6e 20 74  eady set, then t
9900: 68 65 20 70 72 65 76 69 6f 75 73 20 77 72 69 74  he previous writ
9910: 65 72 0a 20 20 20 20 2a 2a 20 6d 75 73 74 20 68  er.    ** must h
9920: 61 76 65 20 65 78 69 74 65 64 20 75 6e 65 78 70  ave exited unexp
9930: 65 63 74 65 64 6c 79 20 69 6e 20 74 68 65 20 6d  ectedly in the m
9940: 69 64 64 6c 65 20 6f 66 20 61 20 74 72 61 6e 73  iddle of a trans
9950: 61 63 74 69 6f 6e 20 28 61 66 74 65 72 0a 20 20  action (after.  
9960: 20 20 2a 2a 20 77 72 69 74 69 6e 67 20 6f 6e 65    ** writing one
9970: 20 6f 72 20 6d 6f 72 65 20 64 69 72 74 79 20 70   or more dirty p
9980: 61 67 65 73 20 74 6f 20 74 68 65 20 57 41 4c 20  ages to the WAL 
9990: 74 6f 20 66 72 65 65 20 75 70 20 6d 65 6d 6f 72  to free up memor
99a0: 79 29 2e 20 0a 20 20 20 20 2a 2a 20 52 65 6d 6f  y). .    ** Remo
99b0: 76 65 20 74 68 65 20 72 65 6d 6e 61 6e 74 73 20  ve the remnants 
99c0: 6f 66 20 74 68 61 74 20 77 72 69 74 65 72 73 20  of that writers 
99d0: 75 6e 63 6f 6d 6d 69 74 74 65 64 20 74 72 61 6e  uncommitted tran
99e0: 73 61 63 74 69 6f 6e 20 66 72 6f 6d 20 0a 20 20  saction from .  
99f0: 20 20 2a 2a 20 74 68 65 20 68 61 73 68 2d 74 61    ** the hash-ta
9a00: 62 6c 65 20 62 65 66 6f 72 65 20 77 72 69 74 69  ble before writi
9a10: 6e 67 20 61 6e 79 20 6e 65 77 20 65 6e 74 72 69  ng any new entri
9a20: 65 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  es..    */.    i
9a30: 66 28 20 61 50 67 6e 6f 5b 69 64 78 5d 20 29 7b  f( aPgno[idx] ){
9a40: 0a 20 20 20 20 20 20 77 61 6c 43 6c 65 61 6e 75  .      walCleanu
9a50: 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 20  pHash(pWal);.   
9a60: 20 20 20 61 73 73 65 72 74 28 20 21 61 50 67 6e     assert( !aPgn
9a70: 6f 5b 69 64 78 5d 20 29 3b 0a 20 20 20 20 7d 0a  o[idx] );.    }.
9a80: 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68  .    /* Write th
9a90: 65 20 61 50 67 6e 6f 5b 5d 20 61 72 72 61 79 20  e aPgno[] array 
9aa0: 65 6e 74 72 79 20 61 6e 64 20 74 68 65 20 68 61  entry and the ha
9ab0: 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 2e 20 2a  sh-table slot. *
9ac0: 2f 0a 20 20 20 20 66 6f 72 28 69 4b 65 79 3d 77  /.    for(iKey=w
9ad0: 61 6c 48 61 73 68 28 69 50 61 67 65 29 3b 20 61  alHash(iPage); a
9ae0: 48 61 73 68 5b 69 4b 65 79 5d 3b 20 69 4b 65 79  Hash[iKey]; iKey
9af0: 3d 77 61 6c 4e 65 78 74 48 61 73 68 28 69 4b 65  =walNextHash(iKe
9b00: 79 29 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72  y)){.      asser
9b10: 74 28 20 6e 43 6f 6c 6c 69 64 65 2b 2b 20 3c 20  t( nCollide++ < 
9b20: 69 64 78 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20  idx );.    }.   
9b30: 20 61 50 67 6e 6f 5b 69 64 78 5d 20 3d 20 69 50   aPgno[idx] = iP
9b40: 61 67 65 3b 0a 20 20 20 20 61 48 61 73 68 5b 69  age;.    aHash[i
9b50: 4b 65 79 5d 20 3d 20 69 64 78 3b 0a 0a 23 69 66  Key] = idx;..#if
9b60: 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c  def SQLITE_ENABL
9b70: 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53 53 45  E_EXPENSIVE_ASSE
9b80: 52 54 0a 20 20 20 20 2f 2a 20 56 65 72 69 66 79  RT.    /* Verify
9b90: 20 74 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72   that the number
9ba0: 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74   of entries in t
9bb0: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 65 78  he hash table ex
9bc0: 61 63 74 6c 79 20 65 71 75 61 6c 73 0a 20 20 20  actly equals.   
9bd0: 20 2a 2a 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   ** the number o
9be0: 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65  f entries in the
9bf0: 20 6d 61 70 70 69 6e 67 20 72 65 67 69 6f 6e 2e   mapping region.
9c00: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7b 0a 20 20  .    */.    {.  
9c10: 20 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20      int i;      
9c20: 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75       /* Loop cou
9c30: 6e 74 65 72 20 2a 2f 0a 20 20 20 20 20 20 69 6e  nter */.      in
9c40: 74 20 6e 45 6e 74 72 79 20 3d 20 30 3b 20 20 2f  t nEntry = 0;  /
9c50: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72  * Number of entr
9c60: 69 65 73 20 69 6e 20 74 68 65 20 68 61 73 68 20  ies in the hash 
9c70: 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20 20 20 66  table */.      f
9c80: 6f 72 28 69 3d 30 3b 20 69 3c 48 41 53 48 54 41  or(i=0; i<HASHTA
9c90: 42 4c 45 5f 4e 53 4c 4f 54 3b 20 69 2b 2b 29 7b  BLE_NSLOT; i++){
9ca0: 20 69 66 28 20 61 48 61 73 68 5b 69 5d 20 29 20   if( aHash[i] ) 
9cb0: 6e 45 6e 74 72 79 2b 2b 3b 20 7d 0a 20 20 20 20  nEntry++; }.    
9cc0: 20 20 61 73 73 65 72 74 28 20 6e 45 6e 74 72 79    assert( nEntry
9cd0: 3d 3d 69 64 78 20 29 3b 0a 20 20 20 20 7d 0a 0a  ==idx );.    }..
9ce0: 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20 74 68      /* Verify th
9cf0: 61 74 20 74 68 65 20 65 76 65 72 79 20 65 6e 74  at the every ent
9d00: 72 79 20 69 6e 20 74 68 65 20 6d 61 70 70 69 6e  ry in the mappin
9d10: 67 20 72 65 67 69 6f 6e 20 69 73 20 72 65 61 63  g region is reac
9d20: 68 61 62 6c 65 0a 20 20 20 20 2a 2a 20 76 69 61  hable.    ** via
9d30: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 2e   the hash table.
9d40: 20 20 54 68 69 73 20 74 75 72 6e 73 20 6f 75 74    This turns out
9d50: 20 74 6f 20 62 65 20 61 20 72 65 61 6c 6c 79 2c   to be a really,
9d60: 20 72 65 61 6c 6c 79 20 65 78 70 65 6e 73 69 76   really expensiv
9d70: 65 0a 20 20 20 20 2a 2a 20 74 68 69 6e 67 20 74  e.    ** thing t
9d80: 6f 20 63 68 65 63 6b 2c 20 73 6f 20 6f 6e 6c 79  o check, so only
9d90: 20 64 6f 20 74 68 69 73 20 6f 63 63 61 73 69 6f   do this occasio
9da0: 6e 61 6c 6c 79 20 2d 20 6e 6f 74 20 6f 6e 20 65  nally - not on e
9db0: 76 65 72 79 0a 20 20 20 20 2a 2a 20 69 74 65 72  very.    ** iter
9dc0: 61 74 69 6f 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20  ation..    */.  
9dd0: 20 20 69 66 28 20 28 69 64 78 26 30 78 33 66 66    if( (idx&0x3ff
9de0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 6e  )==0 ){.      in
9df0: 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 2f  t i;           /
9e00: 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a  * Loop counter *
9e10: 2f 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b  /.      for(i=1;
9e20: 20 69 3c 3d 69 64 78 3b 20 69 2b 2b 29 7b 0a 20   i<=idx; i++){. 
9e30: 20 20 20 20 20 20 20 66 6f 72 28 69 4b 65 79 3d         for(iKey=
9e40: 77 61 6c 48 61 73 68 28 61 50 67 6e 6f 5b 69 5d  walHash(aPgno[i]
9e50: 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20  ); aHash[iKey]; 
9e60: 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68  iKey=walNextHash
9e70: 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 20  (iKey)){.       
9e80: 20 20 20 69 66 28 20 61 48 61 73 68 5b 69 4b 65     if( aHash[iKe
9e90: 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b 3b 0a 20  y]==i ) break;. 
9ea0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
9eb0: 20 61 73 73 65 72 74 28 20 61 48 61 73 68 5b 69   assert( aHash[i
9ec0: 4b 65 79 5d 3d 3d 69 20 29 3b 0a 20 20 20 20 20  Key]==i );.     
9ed0: 20 7d 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66 20   }.    }.#endif 
9ee0: 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45  /* SQLITE_ENABLE
9ef0: 5f 45 58 50 45 4e 53 49 56 45 5f 41 53 53 45 52  _EXPENSIVE_ASSER
9f00: 54 20 2a 2f 0a 20 20 7d 0a 0a 0a 20 20 72 65 74  T */.  }...  ret
9f10: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  urn rc;.}.../*.*
9f20: 2a 20 52 65 63 6f 76 65 72 20 74 68 65 20 77 61  * Recover the wa
9f30: 6c 2d 69 6e 64 65 78 20 62 79 20 72 65 61 64 69  l-index by readi
9f40: 6e 67 20 74 68 65 20 77 72 69 74 65 2d 61 68 65  ng the write-ahe
9f50: 61 64 20 6c 6f 67 20 66 69 6c 65 2e 20 0a 2a 2a  ad log file. .**
9f60: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
9f70: 20 66 69 72 73 74 20 74 72 69 65 73 20 74 6f 20   first tries to 
9f80: 65 73 74 61 62 6c 69 73 68 20 61 6e 20 65 78 63  establish an exc
9f90: 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 74  lusive lock on t
9fa0: 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20  he.** wal-index 
9fb0: 74 6f 20 70 72 65 76 65 6e 74 20 6f 74 68 65 72  to prevent other
9fc0: 20 74 68 72 65 61 64 73 2f 70 72 6f 63 65 73 73   threads/process
9fd0: 65 73 20 66 72 6f 6d 20 64 6f 69 6e 67 20 61 6e  es from doing an
9fe0: 79 74 68 69 6e 67 0a 2a 2a 20 77 69 74 68 20 74  ything.** with t
9ff0: 68 65 20 57 41 4c 20 6f 72 20 77 61 6c 2d 69 6e  he WAL or wal-in
a000: 64 65 78 20 77 68 69 6c 65 20 72 65 63 6f 76 65  dex while recove
a010: 72 79 20 69 73 20 72 75 6e 6e 69 6e 67 2e 20 20  ry is running.  
a020: 54 68 65 0a 2a 2a 20 57 41 4c 5f 52 45 43 4f 56  The.** WAL_RECOV
a030: 45 52 5f 4c 4f 43 4b 20 69 73 20 61 6c 73 6f 20  ER_LOCK is also 
a040: 68 65 6c 64 20 73 6f 20 74 68 61 74 20 6f 74 68  held so that oth
a050: 65 72 20 74 68 72 65 61 64 73 20 77 69 6c 6c 20  er threads will 
a060: 6b 6e 6f 77 0a 2a 2a 20 74 68 61 74 20 74 68 69  know.** that thi
a070: 73 20 74 68 72 65 61 64 20 69 73 20 72 75 6e 6e  s thread is runn
a080: 69 6e 67 20 72 65 63 6f 76 65 72 79 2e 20 20 49  ing recovery.  I
a090: 66 20 75 6e 61 62 6c 65 20 74 6f 20 65 73 74 61  f unable to esta
a0a0: 62 6c 69 73 68 0a 2a 2a 20 74 68 65 20 6e 65 63  blish.** the nec
a0b0: 65 73 73 61 72 79 20 6c 6f 63 6b 73 2c 20 74 68  essary locks, th
a0c0: 69 73 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72  is routine retur
a0d0: 6e 73 20 53 51 4c 49 54 45 5f 42 55 53 59 2e 0a  ns SQLITE_BUSY..
a0e0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  */.static int wa
a0f0: 6c 49 6e 64 65 78 52 65 63 6f 76 65 72 28 57 61  lIndexRecover(Wa
a100: 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20  l *pWal){.  int 
a110: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
a120: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
a130: 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20  eturn Code */.  
a140: 69 36 34 20 6e 53 69 7a 65 3b 20 20 20 20 20 20  i64 nSize;      
a150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a160: 2f 2a 20 53 69 7a 65 20 6f 66 20 6c 6f 67 20 66  /* Size of log f
a170: 69 6c 65 20 2a 2f 0a 20 20 75 33 32 20 61 46 72  ile */.  u32 aFr
a180: 61 6d 65 43 6b 73 75 6d 5b 32 5d 20 3d 20 7b 30  ameCksum[2] = {0
a190: 2c 20 30 7d 3b 0a 20 20 69 6e 74 20 69 4c 6f 63  , 0};.  int iLoc
a1a0: 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
a1b0: 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 63 6b 20          /* Lock 
a1c0: 6f 66 66 73 65 74 20 74 6f 20 6c 6f 63 6b 20 66  offset to lock f
a1d0: 6f 72 20 63 68 65 63 6b 70 6f 69 6e 74 20 2a 2f  or checkpoint */
a1e0: 0a 20 20 69 6e 74 20 6e 4c 6f 63 6b 3b 20 20 20  .  int nLock;   
a1f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a200: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
a210: 6c 6f 63 6b 73 20 74 6f 20 68 6f 6c 64 20 2a 2f  locks to hold */
a220: 0a 0a 20 20 2f 2a 20 4f 62 74 61 69 6e 20 61 6e  ..  /* Obtain an
a230: 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20   exclusive lock 
a240: 6f 6e 20 61 6c 6c 20 62 79 74 65 20 69 6e 20 74  on all byte in t
a250: 68 65 20 6c 6f 63 6b 69 6e 67 20 72 61 6e 67 65  he locking range
a260: 20 6e 6f 74 20 61 6c 72 65 61 64 79 0a 20 20 2a   not already.  *
a270: 2a 20 6c 6f 63 6b 65 64 20 62 79 20 74 68 65 20  * locked by the 
a280: 63 61 6c 6c 65 72 2e 20 54 68 65 20 63 61 6c 6c  caller. The call
a290: 65 72 20 69 73 20 67 75 61 72 61 6e 74 65 65 64  er is guaranteed
a2a0: 20 74 6f 20 68 61 76 65 20 6c 6f 63 6b 65 64 20   to have locked 
a2b0: 74 68 65 0a 20 20 2a 2a 20 57 41 4c 5f 57 52 49  the.  ** WAL_WRI
a2c0: 54 45 5f 4c 4f 43 4b 20 62 79 74 65 2c 20 61 6e  TE_LOCK byte, an
a2d0: 64 20 6d 61 79 20 68 61 76 65 20 61 6c 73 6f 20  d may have also 
a2e0: 6c 6f 63 6b 65 64 20 74 68 65 20 57 41 4c 5f 43  locked the WAL_C
a2f0: 4b 50 54 5f 4c 4f 43 4b 20 62 79 74 65 2e 0a 20  KPT_LOCK byte.. 
a300: 20 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75   ** If successfu
a310: 6c 2c 20 74 68 65 20 73 61 6d 65 20 62 79 74 65  l, the same byte
a320: 73 20 74 68 61 74 20 61 72 65 20 6c 6f 63 6b 65  s that are locke
a330: 64 20 68 65 72 65 20 61 72 65 20 75 6e 6c 6f 63  d here are unloc
a340: 6b 65 64 20 62 65 66 6f 72 65 0a 20 20 2a 2a 20  ked before.  ** 
a350: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65  this function re
a360: 74 75 72 6e 73 2e 0a 20 20 2a 2f 0a 20 20 61 73  turns..  */.  as
a370: 73 65 72 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74  sert( pWal->ckpt
a380: 4c 6f 63 6b 3d 3d 31 20 7c 7c 20 70 57 61 6c 2d  Lock==1 || pWal-
a390: 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 30 20 29 3b 0a  >ckptLock==0 );.
a3a0: 20 20 61 73 73 65 72 74 28 20 57 41 4c 5f 41 4c    assert( WAL_AL
a3b0: 4c 5f 42 55 54 5f 57 52 49 54 45 3d 3d 57 41 4c  L_BUT_WRITE==WAL
a3c0: 5f 57 52 49 54 45 5f 4c 4f 43 4b 2b 31 20 29 3b  _WRITE_LOCK+1 );
a3d0: 0a 20 20 61 73 73 65 72 74 28 20 57 41 4c 5f 43  .  assert( WAL_C
a3e0: 4b 50 54 5f 4c 4f 43 4b 3d 3d 57 41 4c 5f 41 4c  KPT_LOCK==WAL_AL
a3f0: 4c 5f 42 55 54 5f 57 52 49 54 45 20 29 3b 0a 20  L_BUT_WRITE );. 
a400: 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77   assert( pWal->w
a410: 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 69 4c  riteLock );.  iL
a420: 6f 63 6b 20 3d 20 57 41 4c 5f 41 4c 4c 5f 42 55  ock = WAL_ALL_BU
a430: 54 5f 57 52 49 54 45 20 2b 20 70 57 61 6c 2d 3e  T_WRITE + pWal->
a440: 63 6b 70 74 4c 6f 63 6b 3b 0a 20 20 6e 4c 6f 63  ckptLock;.  nLoc
a450: 6b 20 3d 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4e  k = SQLITE_SHM_N
a460: 4c 4f 43 4b 20 2d 20 69 4c 6f 63 6b 3b 0a 20 20  LOCK - iLock;.  
a470: 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
a480: 75 73 69 76 65 28 70 57 61 6c 2c 20 69 4c 6f 63  usive(pWal, iLoc
a490: 6b 2c 20 6e 4c 6f 63 6b 29 3b 0a 20 20 69 66 28  k, nLock);.  if(
a4a0: 20 72 63 20 29 7b 0a 20 20 20 20 72 65 74 75 72   rc ){.    retur
a4b0: 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 57 41 4c 54  n rc;.  }.  WALT
a4c0: 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 72 65  RACE(("WAL%p: re
a4d0: 63 6f 76 65 72 79 20 62 65 67 69 6e 2e 2e 2e 5c  covery begin...\
a4e0: 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 0a 20 20 6d  n", pWal));..  m
a4f0: 65 6d 73 65 74 28 26 70 57 61 6c 2d 3e 68 64 72  emset(&pWal->hdr
a500: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49  , 0, sizeof(WalI
a510: 6e 64 65 78 48 64 72 29 29 3b 0a 0a 20 20 72 63  ndexHdr));..  rc
a520: 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65   = sqlite3OsFile
a530: 53 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46  Size(pWal->pWalF
a540: 64 2c 20 26 6e 53 69 7a 65 29 3b 0a 20 20 69 66  d, &nSize);.  if
a550: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
a560: 29 7b 0a 20 20 20 20 67 6f 74 6f 20 72 65 63 6f  ){.    goto reco
a570: 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20 20 7d 0a  very_error;.  }.
a580: 0a 20 20 69 66 28 20 6e 53 69 7a 65 3e 57 41 4c  .  if( nSize>WAL
a590: 5f 48 44 52 53 49 5a 45 20 29 7b 0a 20 20 20 20  _HDRSIZE ){.    
a5a0: 75 38 20 61 42 75 66 5b 57 41 4c 5f 48 44 52 53  u8 aBuf[WAL_HDRS
a5b0: 49 5a 45 5d 3b 20 20 20 20 20 20 20 20 20 2f 2a  IZE];         /*
a5c0: 20 42 75 66 66 65 72 20 74 6f 20 6c 6f 61 64 20   Buffer to load 
a5d0: 57 41 4c 20 68 65 61 64 65 72 20 69 6e 74 6f 20  WAL header into 
a5e0: 2a 2f 0a 20 20 20 20 75 38 20 2a 61 46 72 61 6d  */.    u8 *aFram
a5f0: 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  e = 0;          
a600: 20 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f 63 27 64       /* Malloc'd
a610: 20 62 75 66 66 65 72 20 74 6f 20 6c 6f 61 64 20   buffer to load 
a620: 65 6e 74 69 72 65 20 66 72 61 6d 65 20 2a 2f 0a  entire frame */.
a630: 20 20 20 20 69 6e 74 20 73 7a 46 72 61 6d 65 3b      int szFrame;
a640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a650: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
a660: 79 74 65 73 20 69 6e 20 62 75 66 66 65 72 20 61  ytes in buffer a
a670: 46 72 61 6d 65 5b 5d 20 2a 2f 0a 20 20 20 20 75  Frame[] */.    u
a680: 38 20 2a 61 44 61 74 61 3b 20 20 20 20 20 20 20  8 *aData;       
a690: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
a6a0: 50 6f 69 6e 74 65 72 20 74 6f 20 64 61 74 61 20  Pointer to data 
a6b0: 70 61 72 74 20 6f 66 20 61 46 72 61 6d 65 20 62  part of aFrame b
a6c0: 75 66 66 65 72 20 2a 2f 0a 20 20 20 20 69 6e 74  uffer */.    int
a6d0: 20 69 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20   iFrame;        
a6e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
a6f0: 64 65 78 20 6f 66 20 6c 61 73 74 20 66 72 61 6d  dex of last fram
a700: 65 20 72 65 61 64 20 2a 2f 0a 20 20 20 20 69 36  e read */.    i6
a710: 34 20 69 4f 66 66 73 65 74 3b 20 20 20 20 20 20  4 iOffset;      
a720: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
a730: 65 78 74 20 6f 66 66 73 65 74 20 74 6f 20 72 65  ext offset to re
a740: 61 64 20 66 72 6f 6d 20 6c 6f 67 20 66 69 6c 65  ad from log file
a750: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 73 7a 50 61   */.    int szPa
a760: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
a770: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69        /* Page si
a780: 7a 65 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20  ze according to 
a790: 74 68 65 20 6c 6f 67 20 2a 2f 0a 20 20 20 20 75  the log */.    u
a7a0: 33 32 20 6d 61 67 69 63 3b 20 20 20 20 20 20 20  32 magic;       
a7b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
a7c0: 4d 61 67 69 63 20 76 61 6c 75 65 20 72 65 61 64  Magic value read
a7d0: 20 66 72 6f 6d 20 57 41 4c 20 68 65 61 64 65 72   from WAL header
a7e0: 20 2a 2f 0a 20 20 20 20 75 33 32 20 76 65 72 73   */.    u32 vers
a7f0: 69 6f 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20  ion;            
a800: 20 20 20 20 20 20 2f 2a 20 4d 61 67 69 63 20 76        /* Magic v
a810: 61 6c 75 65 20 72 65 61 64 20 66 72 6f 6d 20 57  alue read from W
a820: 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20  AL header */..  
a830: 20 20 2f 2a 20 52 65 61 64 20 69 6e 20 74 68 65    /* Read in the
a840: 20 57 41 4c 20 68 65 61 64 65 72 2e 20 2a 2f 0a   WAL header. */.
a850: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
a860: 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61  OsRead(pWal->pWa
a870: 6c 46 64 2c 20 61 42 75 66 2c 20 57 41 4c 5f 48  lFd, aBuf, WAL_H
a880: 44 52 53 49 5a 45 2c 20 30 29 3b 0a 20 20 20 20  DRSIZE, 0);.    
a890: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
a8a0: 4b 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20  K ){.      goto 
a8b0: 72 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a  recovery_error;.
a8c0: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66      }..    /* If
a8d0: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 70 61   the database pa
a8e0: 67 65 20 73 69 7a 65 20 69 73 20 6e 6f 74 20 61  ge size is not a
a8f0: 20 70 6f 77 65 72 20 6f 66 20 74 77 6f 2c 20 6f   power of two, o
a900: 72 20 69 73 20 67 72 65 61 74 65 72 20 74 68 61  r is greater tha
a910: 6e 0a 20 20 20 20 2a 2a 20 53 51 4c 49 54 45 5f  n.    ** SQLITE_
a920: 4d 41 58 5f 50 41 47 45 5f 53 49 5a 45 2c 20 63  MAX_PAGE_SIZE, c
a930: 6f 6e 63 6c 75 64 65 20 74 68 61 74 20 74 68 65  onclude that the
a940: 20 57 41 4c 20 66 69 6c 65 20 63 6f 6e 74 61 69   WAL file contai
a950: 6e 73 20 6e 6f 20 76 61 6c 69 64 20 0a 20 20 20  ns no valid .   
a960: 20 2a 2a 20 64 61 74 61 2e 20 53 69 6d 69 6c 61   ** data. Simila
a970: 72 6c 79 2c 20 69 66 20 74 68 65 20 27 6d 61 67  rly, if the 'mag
a980: 69 63 27 20 76 61 6c 75 65 20 69 73 20 69 6e 76  ic' value is inv
a990: 61 6c 69 64 2c 20 69 67 6e 6f 72 65 20 74 68 65  alid, ignore the
a9a0: 20 77 68 6f 6c 65 0a 20 20 20 20 2a 2a 20 57 41   whole.    ** WA
a9b0: 4c 20 66 69 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20  L file..    */. 
a9c0: 20 20 20 6d 61 67 69 63 20 3d 20 73 71 6c 69 74     magic = sqlit
a9d0: 65 33 47 65 74 34 62 79 74 65 28 26 61 42 75 66  e3Get4byte(&aBuf
a9e0: 5b 30 5d 29 3b 0a 20 20 20 20 73 7a 50 61 67 65  [0]);.    szPage
a9f0: 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62 79   = sqlite3Get4by
aa00: 74 65 28 26 61 42 75 66 5b 38 5d 29 3b 0a 20 20  te(&aBuf[8]);.  
aa10: 20 20 69 66 28 20 28 6d 61 67 69 63 26 30 78 46    if( (magic&0xF
aa20: 46 46 46 46 46 46 45 29 21 3d 57 41 4c 5f 4d 41  FFFFFFE)!=WAL_MA
aa30: 47 49 43 20 0a 20 20 20 20 20 7c 7c 20 73 7a 50  GIC .     || szP
aa40: 61 67 65 26 28 73 7a 50 61 67 65 2d 31 29 20 0a  age&(szPage-1) .
aa50: 20 20 20 20 20 7c 7c 20 73 7a 50 61 67 65 3e 53       || szPage>S
aa60: 51 4c 49 54 45 5f 4d 41 58 5f 50 41 47 45 5f 53  QLITE_MAX_PAGE_S
aa70: 49 5a 45 20 0a 20 20 20 20 20 7c 7c 20 73 7a 50  IZE .     || szP
aa80: 61 67 65 3c 35 31 32 20 0a 20 20 20 20 29 7b 0a  age<512 .    ){.
aa90: 20 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73        goto finis
aaa0: 68 65 64 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  hed;.    }.    p
aab0: 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43  Wal->hdr.bigEndC
aac0: 6b 73 75 6d 20 3d 20 28 6d 61 67 69 63 26 30 78  ksum = (magic&0x
aad0: 30 30 30 30 30 30 30 31 29 3b 0a 20 20 20 20 70  00000001);.    p
aae0: 57 61 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a  Wal->szPage = sz
aaf0: 50 61 67 65 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  Page;.    pWal->
ab00: 6e 43 6b 70 74 20 3d 20 73 71 6c 69 74 65 33 47  nCkpt = sqlite3G
ab10: 65 74 34 62 79 74 65 28 26 61 42 75 66 5b 31 32  et4byte(&aBuf[12
ab20: 5d 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26  ]);.    memcpy(&
ab30: 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c  pWal->hdr.aSalt,
ab40: 20 26 61 42 75 66 5b 31 36 5d 2c 20 38 29 3b 0a   &aBuf[16], 8);.
ab50: 0a 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20 74  .    /* Verify t
ab60: 68 61 74 20 74 68 65 20 57 41 4c 20 68 65 61 64  hat the WAL head
ab70: 65 72 20 63 68 65 63 6b 73 75 6d 20 69 73 20 63  er checksum is c
ab80: 6f 72 72 65 63 74 20 2a 2f 0a 20 20 20 20 77 61  orrect */.    wa
ab90: 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28 70  lChecksumBytes(p
aba0: 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43  Wal->hdr.bigEndC
abb0: 6b 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47  ksum==SQLITE_BIG
abc0: 45 4e 44 49 41 4e 2c 20 0a 20 20 20 20 20 20 20  ENDIAN, .       
abd0: 20 61 42 75 66 2c 20 57 41 4c 5f 48 44 52 53 49   aBuf, WAL_HDRSI
abe0: 5a 45 2d 32 2a 34 2c 20 30 2c 20 70 57 61 6c 2d  ZE-2*4, 0, pWal-
abf0: 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
ac00: 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28 20  .    );.    if( 
ac10: 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
ac20: 43 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65  Cksum[0]!=sqlite
ac30: 33 47 65 74 34 62 79 74 65 28 26 61 42 75 66 5b  3Get4byte(&aBuf[
ac40: 32 34 5d 29 0a 20 20 20 20 20 7c 7c 20 70 57 61  24]).     || pWa
ac50: 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
ac60: 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33 47 65  um[1]!=sqlite3Ge
ac70: 74 34 62 79 74 65 28 26 61 42 75 66 5b 32 38 5d  t4byte(&aBuf[28]
ac80: 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 67  ).    ){.      g
ac90: 6f 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20  oto finished;.  
aca0: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69    }..    /* Veri
acb0: 66 79 20 74 68 61 74 20 74 68 65 20 76 65 72 73  fy that the vers
acc0: 69 6f 6e 20 6e 75 6d 62 65 72 20 6f 6e 20 74 68  ion number on th
acd0: 65 20 57 41 4c 20 66 6f 72 6d 61 74 20 69 73 20  e WAL format is 
ace0: 6f 6e 65 20 74 68 61 74 0a 20 20 20 20 2a 2a 20  one that.    ** 
acf0: 61 72 65 20 61 62 6c 65 20 74 6f 20 75 6e 64 65  are able to unde
ad00: 72 73 74 61 6e 64 20 2a 2f 0a 20 20 20 20 76 65  rstand */.    ve
ad10: 72 73 69 6f 6e 20 3d 20 73 71 6c 69 74 65 33 47  rsion = sqlite3G
ad20: 65 74 34 62 79 74 65 28 26 61 42 75 66 5b 34 5d  et4byte(&aBuf[4]
ad30: 29 3b 0a 20 20 20 20 69 66 28 20 76 65 72 73 69  );.    if( versi
ad40: 6f 6e 21 3d 57 41 4c 5f 4d 41 58 5f 56 45 52 53  on!=WAL_MAX_VERS
ad50: 49 4f 4e 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ION ){.      rc 
ad60: 3d 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45  = SQLITE_CANTOPE
ad70: 4e 5f 42 4b 50 54 3b 0a 20 20 20 20 20 20 67 6f  N_BKPT;.      go
ad80: 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20 20  to finished;.   
ad90: 20 7d 0a 0a 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f   }..    /* Mallo
ada0: 63 20 61 20 62 75 66 66 65 72 20 74 6f 20 72 65  c a buffer to re
adb0: 61 64 20 66 72 61 6d 65 73 20 69 6e 74 6f 2e 20  ad frames into. 
adc0: 2a 2f 0a 20 20 20 20 73 7a 46 72 61 6d 65 20 3d  */.    szFrame =
add0: 20 73 7a 50 61 67 65 20 2b 20 57 41 4c 5f 46 52   szPage + WAL_FR
ade0: 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20 20 20  AME_HDRSIZE;.   
adf0: 20 61 46 72 61 6d 65 20 3d 20 28 75 38 20 2a 29   aFrame = (u8 *)
ae00: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
ae10: 7a 46 72 61 6d 65 29 3b 0a 20 20 20 20 69 66 28  zFrame);.    if(
ae20: 20 21 61 46 72 61 6d 65 20 29 7b 0a 20 20 20 20   !aFrame ){.    
ae30: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
ae40: 4d 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20  MEM;.      goto 
ae50: 72 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a  recovery_error;.
ae60: 20 20 20 20 7d 0a 20 20 20 20 61 44 61 74 61 20      }.    aData 
ae70: 3d 20 26 61 46 72 61 6d 65 5b 57 41 4c 5f 46 52  = &aFrame[WAL_FR
ae80: 41 4d 45 5f 48 44 52 53 49 5a 45 5d 3b 0a 0a 20  AME_HDRSIZE];.. 
ae90: 20 20 20 2f 2a 20 52 65 61 64 20 61 6c 6c 20 66     /* Read all f
aea0: 72 61 6d 65 73 20 66 72 6f 6d 20 74 68 65 20 6c  rames from the l
aeb0: 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 20 20  og file. */.    
aec0: 69 46 72 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20  iFrame = 0;.    
aed0: 66 6f 72 28 69 4f 66 66 73 65 74 3d 57 41 4c 5f  for(iOffset=WAL_
aee0: 48 44 52 53 49 5a 45 3b 20 28 69 4f 66 66 73 65  HDRSIZE; (iOffse
aef0: 74 2b 73 7a 46 72 61 6d 65 29 3c 3d 6e 53 69 7a  t+szFrame)<=nSiz
af00: 65 3b 20 69 4f 66 66 73 65 74 2b 3d 73 7a 46 72  e; iOffset+=szFr
af10: 61 6d 65 29 7b 0a 20 20 20 20 20 20 75 33 32 20  ame){.      u32 
af20: 70 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20  pgno;           
af30: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
af40: 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  ase page number 
af50: 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20 20 20  for frame */.   
af60: 20 20 20 75 33 32 20 6e 54 72 75 6e 63 61 74 65     u32 nTruncate
af70: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
af80: 2a 20 64 62 73 69 7a 65 20 66 69 65 6c 64 20 66  * dbsize field f
af90: 72 6f 6d 20 66 72 61 6d 65 20 68 65 61 64 65 72  rom frame header
afa0: 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 69 73   */.      int is
afb0: 56 61 6c 69 64 3b 20 20 20 20 20 20 20 20 20 20  Valid;          
afc0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
afd0: 20 74 68 69 73 20 66 72 61 6d 65 20 69 73 20 76   this frame is v
afe0: 61 6c 69 64 20 2a 2f 0a 0a 20 20 20 20 20 20 2f  alid */..      /
aff0: 2a 20 52 65 61 64 20 61 6e 64 20 64 65 63 6f 64  * Read and decod
b000: 65 20 74 68 65 20 6e 65 78 74 20 6c 6f 67 20 66  e the next log f
b010: 72 61 6d 65 2e 20 2a 2f 0a 20 20 20 20 20 20 72  rame. */.      r
b020: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61  c = sqlite3OsRea
b030: 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20  d(pWal->pWalFd, 
b040: 61 46 72 61 6d 65 2c 20 73 7a 46 72 61 6d 65 2c  aFrame, szFrame,
b050: 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20   iOffset);.     
b060: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
b070: 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  OK ) break;.    
b080: 20 20 69 73 56 61 6c 69 64 20 3d 20 77 61 6c 44    isValid = walD
b090: 65 63 6f 64 65 46 72 61 6d 65 28 70 57 61 6c 2c  ecodeFrame(pWal,
b0a0: 20 26 70 67 6e 6f 2c 20 26 6e 54 72 75 6e 63 61   &pgno, &nTrunca
b0b0: 74 65 2c 20 61 44 61 74 61 2c 20 61 46 72 61 6d  te, aData, aFram
b0c0: 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 69  e);.      if( !i
b0d0: 73 56 61 6c 69 64 20 29 20 62 72 65 61 6b 3b 0a  sValid ) break;.
b0e0: 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e        rc = walIn
b0f0: 64 65 78 41 70 70 65 6e 64 28 70 57 61 6c 2c 20  dexAppend(pWal, 
b100: 2b 2b 69 46 72 61 6d 65 2c 20 70 67 6e 6f 29 3b  ++iFrame, pgno);
b110: 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
b120: 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
b130: 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 6e  ;..      /* If n
b140: 54 72 75 6e 63 61 74 65 20 69 73 20 6e 6f 6e 2d  Truncate is non-
b150: 7a 65 72 6f 2c 20 74 68 69 73 20 69 73 20 61 20  zero, this is a 
b160: 63 6f 6d 6d 69 74 20 72 65 63 6f 72 64 2e 20 2a  commit record. *
b170: 2f 0a 20 20 20 20 20 20 69 66 28 20 6e 54 72 75  /.      if( nTru
b180: 6e 63 61 74 65 20 29 7b 0a 20 20 20 20 20 20 20  ncate ){.       
b190: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
b1a0: 6d 65 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20  me = iFrame;.   
b1b0: 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6e       pWal->hdr.n
b1c0: 50 61 67 65 20 3d 20 6e 54 72 75 6e 63 61 74 65  Page = nTruncate
b1d0: 3b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e  ;.        pWal->
b1e0: 68 64 72 2e 73 7a 50 61 67 65 20 3d 20 73 7a 50  hdr.szPage = szP
b1f0: 61 67 65 3b 0a 20 20 20 20 20 20 20 20 61 46 72  age;.        aFr
b200: 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 70 57  ameCksum[0] = pW
b210: 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
b220: 73 75 6d 5b 30 5d 3b 0a 20 20 20 20 20 20 20 20  sum[0];.        
b230: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d  aFrameCksum[1] =
b240: 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
b250: 65 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 20 20 20  eCksum[1];.     
b260: 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 71   }.    }..    sq
b270: 6c 69 74 65 33 5f 66 72 65 65 28 61 46 72 61 6d  lite3_free(aFram
b280: 65 29 3b 0a 20 20 7d 0a 0a 66 69 6e 69 73 68 65  e);.  }..finishe
b290: 64 3a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  d:.  if( rc==SQL
b2a0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 6f  ITE_OK ){.    vo
b2b0: 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e  latile WalCkptIn
b2c0: 66 6f 20 2a 70 49 6e 66 6f 3b 0a 20 20 20 20 69  fo *pInfo;.    i
b2d0: 6e 74 20 69 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  nt i;.    pWal->
b2e0: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
b2f0: 30 5d 20 3d 20 61 46 72 61 6d 65 43 6b 73 75 6d  0] = aFrameCksum
b300: 5b 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68  [0];.    pWal->h
b310: 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31  dr.aFrameCksum[1
b320: 5d 20 3d 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b  ] = aFrameCksum[
b330: 31 5d 3b 0a 20 20 20 20 77 61 6c 49 6e 64 65 78  1];.    walIndex
b340: 57 72 69 74 65 48 64 72 28 70 57 61 6c 29 3b 0a  WriteHdr(pWal);.
b350: 0a 20 20 20 20 2f 2a 20 52 65 73 65 74 20 74 68  .    /* Reset th
b360: 65 20 63 68 65 63 6b 70 6f 69 6e 74 2d 68 65 61  e checkpoint-hea
b370: 64 65 72 2e 20 54 68 69 73 20 69 73 20 73 61 66  der. This is saf
b380: 65 20 62 65 63 61 75 73 65 20 74 68 69 73 20 74  e because this t
b390: 68 72 65 61 64 20 69 73 20 0a 20 20 20 20 2a 2a  hread is .    **
b3a0: 20 63 75 72 72 65 6e 74 6c 79 20 68 6f 6c 64 69   currently holdi
b3b0: 6e 67 20 6c 6f 63 6b 73 20 74 68 61 74 20 65 78  ng locks that ex
b3c0: 63 6c 75 64 65 20 61 6c 6c 20 6f 74 68 65 72 20  clude all other 
b3d0: 72 65 61 64 65 72 73 2c 20 77 72 69 74 65 72 73  readers, writers
b3e0: 20 61 6e 64 0a 20 20 20 20 2a 2a 20 63 68 65 63   and.    ** chec
b3f0: 6b 70 6f 69 6e 74 65 72 73 2e 0a 20 20 20 20 2a  kpointers..    *
b400: 2f 0a 20 20 20 20 70 49 6e 66 6f 20 3d 20 77 61  /.    pInfo = wa
b410: 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b  lCkptInfo(pWal);
b420: 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63  .    pInfo->nBac
b430: 6b 66 69 6c 6c 20 3d 20 30 3b 0a 20 20 20 20 70  kfill = 0;.    p
b440: 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b  Info->aReadMark[
b450: 30 5d 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28  0] = 0;.    for(
b460: 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44  i=1; i<WAL_NREAD
b470: 45 52 3b 20 69 2b 2b 29 20 70 49 6e 66 6f 2d 3e  ER; i++) pInfo->
b480: 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 52  aReadMark[i] = R
b490: 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44  EADMARK_NOT_USED
b4a0: 3b 0a 20 20 7d 0a 0a 72 65 63 6f 76 65 72 79 5f  ;.  }..recovery_
b4b0: 65 72 72 6f 72 3a 0a 20 20 57 41 4c 54 52 41 43  error:.  WALTRAC
b4c0: 45 28 28 22 57 41 4c 25 70 3a 20 72 65 63 6f 76  E(("WAL%p: recov
b4d0: 65 72 79 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c  ery %s\n", pWal,
b4e0: 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a   rc ? "failed" :
b4f0: 20 22 6f 6b 22 29 29 3b 0a 20 20 77 61 6c 55 6e   "ok"));.  walUn
b500: 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  lockExclusive(pW
b510: 61 6c 2c 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b  al, iLock, nLock
b520: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
b530: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61  }../*.** Close a
b540: 6e 20 6f 70 65 6e 20 77 61 6c 2d 69 6e 64 65 78  n open wal-index
b550: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
b560: 20 77 61 6c 49 6e 64 65 78 43 6c 6f 73 65 28 57   walIndexClose(W
b570: 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 69 73  al *pWal, int is
b580: 44 65 6c 65 74 65 29 7b 0a 20 20 69 66 28 20 70  Delete){.  if( p
b590: 57 61 6c 2d 3e 69 73 57 49 6e 64 65 78 4f 70 65  Wal->isWIndexOpe
b5a0: 6e 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  n ){.    sqlite3
b5b0: 4f 73 53 68 6d 43 6c 6f 73 65 28 70 57 61 6c 2d  OsShmClose(pWal-
b5c0: 3e 70 44 62 46 64 2c 20 69 73 44 65 6c 65 74 65  >pDbFd, isDelete
b5d0: 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 69 73 57  );.    pWal->isW
b5e0: 49 6e 64 65 78 4f 70 65 6e 20 3d 20 30 3b 0a 20  IndexOpen = 0;. 
b5f0: 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4f 70 65   }.}../* .** Ope
b600: 6e 20 61 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74  n a connection t
b610: 6f 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20 61  o the WAL file a
b620: 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 64  ssociated with d
b630: 61 74 61 62 61 73 65 20 7a 44 62 4e 61 6d 65 2e  atabase zDbName.
b640: 0a 2a 2a 20 54 68 65 20 64 61 74 61 62 61 73 65  .** The database
b650: 20 66 69 6c 65 20 6d 75 73 74 20 61 6c 72 65 61   file must alrea
b660: 64 79 20 62 65 20 6f 70 65 6e 65 64 20 6f 6e 20  dy be opened on 
b670: 63 6f 6e 6e 65 63 74 69 6f 6e 20 70 44 62 46 64  connection pDbFd
b680: 2e 0a 2a 2a 0a 2a 2a 20 41 20 53 48 41 52 45 44  ..**.** A SHARED
b690: 20 6c 6f 63 6b 20 73 68 6f 75 6c 64 20 62 65 20   lock should be 
b6a0: 68 65 6c 64 20 6f 6e 20 74 68 65 20 64 61 74 61  held on the data
b6b0: 62 61 73 65 20 66 69 6c 65 20 77 68 65 6e 20 74  base file when t
b6c0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20  his function.** 
b6d0: 69 73 20 63 61 6c 6c 65 64 2e 20 54 68 65 20 70  is called. The p
b6e0: 75 72 70 6f 73 65 20 6f 66 20 74 68 69 73 20 53  urpose of this S
b6f0: 48 41 52 45 44 20 6c 6f 63 6b 20 69 73 20 74 6f  HARED lock is to
b700: 20 70 72 65 76 65 6e 74 20 61 6e 79 20 6f 74 68   prevent any oth
b710: 65 72 0a 2a 2a 20 63 6c 69 65 6e 74 20 66 72 6f  er.** client fro
b720: 6d 20 75 6e 6c 69 6e 6b 69 6e 67 20 74 68 65 20  m unlinking the 
b730: 57 41 4c 20 6f 72 20 77 61 6c 2d 69 6e 64 65 78  WAL or wal-index
b740: 20 66 69 6c 65 2e 20 49 66 20 61 6e 6f 74 68 65   file. If anothe
b750: 72 20 70 72 6f 63 65 73 73 0a 2a 2a 20 77 65 72  r process.** wer
b760: 65 20 74 6f 20 64 6f 20 74 68 69 73 20 6a 75 73  e to do this jus
b770: 74 20 61 66 74 65 72 20 74 68 69 73 20 63 6c 69  t after this cli
b780: 65 6e 74 20 6f 70 65 6e 65 64 20 6f 6e 65 20 6f  ent opened one o
b790: 66 20 74 68 65 73 65 20 66 69 6c 65 73 2c 20 74  f these files, t
b7a0: 68 65 0a 2a 2a 20 73 79 73 74 65 6d 20 77 6f 75  he.** system wou
b7b0: 6c 64 20 62 65 20 62 61 64 6c 79 20 62 72 6f 6b  ld be badly brok
b7c0: 65 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  en..**.** If the
b7d0: 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 73 75 63   log file is suc
b7e0: 63 65 73 73 66 75 6c 6c 79 20 6f 70 65 6e 65 64  cessfully opened
b7f0: 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  , SQLITE_OK is r
b800: 65 74 75 72 6e 65 64 20 61 6e 64 20 0a 2a 2a 20  eturned and .** 
b810: 2a 70 70 57 61 6c 20 69 73 20 73 65 74 20 74 6f  *ppWal is set to
b820: 20 70 6f 69 6e 74 20 74 6f 20 61 20 6e 65 77 20   point to a new 
b830: 57 41 4c 20 68 61 6e 64 6c 65 2e 20 49 66 20 61  WAL handle. If a
b840: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 0a  n error occurs,.
b850: 2a 2a 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  ** an SQLite err
b860: 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  or code is retur
b870: 6e 65 64 20 61 6e 64 20 2a 70 70 57 61 6c 20 69  ned and *ppWal i
b880: 73 20 6c 65 66 74 20 75 6e 6d 6f 64 69 66 69 65  s left unmodifie
b890: 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  d..*/.int sqlite
b8a0: 33 57 61 6c 4f 70 65 6e 28 0a 20 20 73 71 6c 69  3WalOpen(.  sqli
b8b0: 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 20  te3_vfs *pVfs,  
b8c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 76              /* v
b8d0: 66 73 20 6d 6f 64 75 6c 65 20 74 6f 20 6f 70 65  fs module to ope
b8e0: 6e 20 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e  n wal and wal-in
b8f0: 64 65 78 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  dex */.  sqlite3
b900: 5f 66 69 6c 65 20 2a 70 44 62 46 64 2c 20 20 20  _file *pDbFd,   
b910: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
b920: 6f 70 65 6e 20 64 61 74 61 62 61 73 65 20 66 69  open database fi
b930: 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  le */.  const ch
b940: 61 72 20 2a 7a 44 62 4e 61 6d 65 2c 20 20 20 20  ar *zDbName,    
b950: 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20          /* Name 
b960: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  of the database 
b970: 66 69 6c 65 20 2a 2f 0a 20 20 57 61 6c 20 2a 2a  file */.  Wal **
b980: 70 70 57 61 6c 20 20 20 20 20 20 20 20 20 20 20  ppWal           
b990: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
b9a0: 3a 20 41 6c 6c 6f 63 61 74 65 64 20 57 61 6c 20  : Allocated Wal 
b9b0: 68 61 6e 64 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69  handle */.){.  i
b9c0: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
b9d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
b9e0: 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f  * Return Code */
b9f0: 0a 20 20 57 61 6c 20 2a 70 52 65 74 3b 20 20 20  .  Wal *pRet;   
ba00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ba10: 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 74 6f 20     /* Object to 
ba20: 61 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72 65 74  allocate and ret
ba30: 75 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61  urn */.  int fla
ba40: 67 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  gs;             
ba50: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67           /* Flag
ba60: 73 20 70 61 73 73 65 64 20 74 6f 20 4f 73 4f 70  s passed to OsOp
ba70: 65 6e 28 29 20 2a 2f 0a 20 20 63 68 61 72 20 2a  en() */.  char *
ba80: 7a 57 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20  zWal;           
ba90: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d            /* Nam
baa0: 65 20 6f 66 20 77 72 69 74 65 2d 61 68 65 61 64  e of write-ahead
bab0: 20 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a 20 20 69   log file */.  i
bac0: 6e 74 20 6e 57 61 6c 3b 20 20 20 20 20 20 20 20  nt nWal;        
bad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
bae0: 2a 20 4c 65 6e 67 74 68 20 6f 66 20 7a 57 61 6c  * Length of zWal
baf0: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 0a 20 20   in bytes */..  
bb00: 61 73 73 65 72 74 28 20 7a 44 62 4e 61 6d 65 20  assert( zDbName 
bb10: 26 26 20 7a 44 62 4e 61 6d 65 5b 30 5d 20 29 3b  && zDbName[0] );
bb20: 0a 20 20 61 73 73 65 72 74 28 20 70 44 62 46 64  .  assert( pDbFd
bb30: 20 29 3b 0a 0a 20 20 2f 2a 20 49 6e 20 74 68 65   );..  /* In the
bb40: 20 61 6d 61 6c 67 61 6d 61 74 69 6f 6e 2c 20 74   amalgamation, t
bb50: 68 65 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e 64  he os_unix.c and
bb60: 20 6f 73 5f 77 69 6e 2e 63 20 73 6f 75 72 63 65   os_win.c source
bb70: 20 66 69 6c 65 73 20 63 6f 6d 65 20 62 65 66 6f   files come befo
bb80: 72 65 0a 20 20 2a 2a 20 74 68 69 73 20 73 6f 75  re.  ** this sou
bb90: 72 63 65 20 66 69 6c 65 2e 20 20 56 65 72 69 66  rce file.  Verif
bba0: 79 20 74 68 61 74 20 74 68 65 20 23 64 65 66 69  y that the #defi
bbb0: 6e 65 73 20 6f 66 20 74 68 65 20 6c 6f 63 6b 69  nes of the locki
bbc0: 6e 67 20 62 79 74 65 20 6f 66 66 73 65 74 73 0a  ng byte offsets.
bbd0: 20 20 2a 2a 20 69 6e 20 6f 73 5f 75 6e 69 78 2e    ** in os_unix.
bbe0: 63 20 61 6e 64 20 6f 73 5f 77 69 6e 2e 63 20 61  c and os_win.c a
bbf0: 67 72 65 65 20 77 69 74 68 20 74 68 65 20 57 41  gree with the WA
bc00: 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53  LINDEX_LOCK_OFFS
bc10: 45 54 20 76 61 6c 75 65 2e 0a 20 20 2a 2f 0a 23  ET value..  */.#
bc20: 69 66 64 65 66 20 57 49 4e 5f 53 48 4d 5f 42 41  ifdef WIN_SHM_BA
bc30: 53 45 0a 20 20 61 73 73 65 72 74 28 20 57 49 4e  SE.  assert( WIN
bc40: 5f 53 48 4d 5f 42 41 53 45 3d 3d 57 41 4c 49 4e  _SHM_BASE==WALIN
bc50: 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20  DEX_LOCK_OFFSET 
bc60: 29 3b 0a 23 65 6e 64 69 66 0a 23 69 66 64 65 66  );.#endif.#ifdef
bc70: 20 55 4e 49 58 5f 53 48 4d 5f 42 41 53 45 0a 20   UNIX_SHM_BASE. 
bc80: 20 61 73 73 65 72 74 28 20 55 4e 49 58 5f 53 48   assert( UNIX_SH
bc90: 4d 5f 42 41 53 45 3d 3d 57 41 4c 49 4e 44 45 58  M_BASE==WALINDEX
bca0: 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a  _LOCK_OFFSET );.
bcb0: 23 65 6e 64 69 66 0a 0a 0a 20 20 2f 2a 20 41 6c  #endif...  /* Al
bcc0: 6c 6f 63 61 74 65 20 61 6e 20 69 6e 73 74 61 6e  locate an instan
bcd0: 63 65 20 6f 66 20 73 74 72 75 63 74 20 57 61 6c  ce of struct Wal
bce0: 20 74 6f 20 72 65 74 75 72 6e 2e 20 2a 2f 0a 20   to return. */. 
bcf0: 20 2a 70 70 57 61 6c 20 3d 20 30 3b 0a 20 20 6e   *ppWal = 0;.  n
bd00: 57 61 6c 20 3d 20 73 71 6c 69 74 65 33 53 74 72  Wal = sqlite3Str
bd10: 6c 65 6e 33 30 28 7a 44 62 4e 61 6d 65 29 20 2b  len30(zDbName) +
bd20: 20 35 3b 0a 20 20 70 52 65 74 20 3d 20 28 57 61   5;.  pRet = (Wa
bd30: 6c 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63  l*)sqlite3Malloc
bd40: 5a 65 72 6f 28 73 69 7a 65 6f 66 28 57 61 6c 29  Zero(sizeof(Wal)
bd50: 20 2b 20 70 56 66 73 2d 3e 73 7a 4f 73 46 69 6c   + pVfs->szOsFil
bd60: 65 20 2b 20 6e 57 61 6c 29 3b 0a 20 20 69 66 28  e + nWal);.  if(
bd70: 20 21 70 52 65 74 20 29 7b 0a 20 20 20 20 72 65   !pRet ){.    re
bd80: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
bd90: 4d 3b 0a 20 20 7d 0a 0a 20 20 70 52 65 74 2d 3e  M;.  }..  pRet->
bda0: 70 56 66 73 20 3d 20 70 56 66 73 3b 0a 20 20 70  pVfs = pVfs;.  p
bdb0: 52 65 74 2d 3e 70 57 61 6c 46 64 20 3d 20 28 73  Ret->pWalFd = (s
bdc0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 29 26 70  qlite3_file *)&p
bdd0: 52 65 74 5b 31 5d 3b 0a 20 20 70 52 65 74 2d 3e  Ret[1];.  pRet->
bde0: 70 44 62 46 64 20 3d 20 70 44 62 46 64 3b 0a 20  pDbFd = pDbFd;. 
bdf0: 20 70 52 65 74 2d 3e 72 65 61 64 4c 6f 63 6b 20   pRet->readLock 
be00: 3d 20 2d 31 3b 0a 20 20 73 71 6c 69 74 65 33 5f  = -1;.  sqlite3_
be10: 72 61 6e 64 6f 6d 6e 65 73 73 28 38 2c 20 26 70  randomness(8, &p
be20: 52 65 74 2d 3e 68 64 72 2e 61 53 61 6c 74 29 3b  Ret->hdr.aSalt);
be30: 0a 20 20 70 52 65 74 2d 3e 7a 57 61 6c 4e 61 6d  .  pRet->zWalNam
be40: 65 20 3d 20 7a 57 61 6c 20 3d 20 70 56 66 73 2d  e = zWal = pVfs-
be50: 3e 73 7a 4f 73 46 69 6c 65 20 2b 20 28 63 68 61  >szOsFile + (cha
be60: 72 2a 29 70 52 65 74 2d 3e 70 57 61 6c 46 64 3b  r*)pRet->pWalFd;
be70: 0a 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69  .  sqlite3_snpri
be80: 6e 74 66 28 6e 57 61 6c 2c 20 7a 57 61 6c 2c 20  ntf(nWal, zWal, 
be90: 22 25 73 2d 77 61 6c 22 2c 20 7a 44 62 4e 61 6d  "%s-wal", zDbNam
bea0: 65 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  e);.  rc = sqlit
beb0: 65 33 4f 73 53 68 6d 4f 70 65 6e 28 70 44 62 46  e3OsShmOpen(pDbF
bec0: 64 29 3b 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 66  d);..  /* Open f
bed0: 69 6c 65 20 68 61 6e 64 6c 65 20 6f 6e 20 74 68  ile handle on th
bee0: 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f  e write-ahead lo
bef0: 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 69 66 28  g file. */.  if(
bf00: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
bf10: 7b 0a 20 20 20 20 70 52 65 74 2d 3e 69 73 57 49  {.    pRet->isWI
bf20: 6e 64 65 78 4f 70 65 6e 20 3d 20 31 3b 0a 20 20  ndexOpen = 1;.  
bf30: 20 20 66 6c 61 67 73 20 3d 20 28 53 51 4c 49 54    flags = (SQLIT
bf40: 45 5f 4f 50 45 4e 5f 52 45 41 44 57 52 49 54 45  E_OPEN_READWRITE
bf50: 7c 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 45  |SQLITE_OPEN_CRE
bf60: 41 54 45 7c 53 51 4c 49 54 45 5f 4f 50 45 4e 5f  ATE|SQLITE_OPEN_
bf70: 4d 41 49 4e 5f 4a 4f 55 52 4e 41 4c 29 3b 0a 20  MAIN_JOURNAL);. 
bf80: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
bf90: 73 4f 70 65 6e 28 70 56 66 73 2c 20 7a 57 61 6c  sOpen(pVfs, zWal
bfa0: 2c 20 70 52 65 74 2d 3e 70 57 61 6c 46 64 2c 20  , pRet->pWalFd, 
bfb0: 66 6c 61 67 73 2c 20 26 66 6c 61 67 73 29 3b 0a  flags, &flags);.
bfc0: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53    }..  if( rc!=S
bfd0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
bfe0: 77 61 6c 49 6e 64 65 78 43 6c 6f 73 65 28 70 52  walIndexClose(pR
bff0: 65 74 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69  et, 0);.    sqli
c000: 74 65 33 4f 73 43 6c 6f 73 65 28 70 52 65 74 2d  te3OsClose(pRet-
c010: 3e 70 57 61 6c 46 64 29 3b 0a 20 20 20 20 73 71  >pWalFd);.    sq
c020: 6c 69 74 65 33 5f 66 72 65 65 28 70 52 65 74 29  lite3_free(pRet)
c030: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a  ;.  }else{.    *
c040: 70 70 57 61 6c 20 3d 20 70 52 65 74 3b 0a 20 20  ppWal = pRet;.  
c050: 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c    WALTRACE(("WAL
c060: 25 64 3a 20 6f 70 65 6e 65 64 5c 6e 22 2c 20 70  %d: opened\n", p
c070: 52 65 74 29 29 3b 0a 20 20 7d 0a 20 20 72 65 74  Ret));.  }.  ret
c080: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
c090: 20 46 69 6e 64 20 74 68 65 20 73 6d 61 6c 6c 65   Find the smalle
c0a0: 73 74 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f  st page number o
c0b0: 75 74 20 6f 66 20 61 6c 6c 20 70 61 67 65 73 20  ut of all pages 
c0c0: 68 65 6c 64 20 69 6e 20 74 68 65 20 57 41 4c 20  held in the WAL 
c0d0: 74 68 61 74 0a 2a 2a 20 68 61 73 20 6e 6f 74 20  that.** has not 
c0e0: 62 65 65 6e 20 72 65 74 75 72 6e 65 64 20 62 79  been returned by
c0f0: 20 61 6e 79 20 70 72 69 6f 72 20 69 6e 76 6f 63   any prior invoc
c100: 61 74 69 6f 6e 20 6f 66 20 74 68 69 73 20 6d 65  ation of this me
c110: 74 68 6f 64 20 6f 6e 20 74 68 65 0a 2a 2a 20 73  thod on the.** s
c120: 61 6d 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20  ame WalIterator 
c130: 6f 62 6a 65 63 74 2e 20 20 20 57 72 69 74 65 20  object.   Write 
c140: 69 6e 74 6f 20 2a 70 69 46 72 61 6d 65 20 74 68  into *piFrame th
c150: 65 20 66 72 61 6d 65 20 69 6e 64 65 78 20 77 68  e frame index wh
c160: 65 72 65 0a 2a 2a 20 74 68 61 74 20 70 61 67 65  ere.** that page
c170: 20 77 61 73 20 6c 61 73 74 20 77 72 69 74 74 65   was last writte
c180: 6e 20 69 6e 74 6f 20 74 68 65 20 57 41 4c 2e 20  n into the WAL. 
c190: 20 57 72 69 74 65 20 69 6e 74 6f 20 2a 70 69 50   Write into *piP
c1a0: 61 67 65 20 74 68 65 20 70 61 67 65 0a 2a 2a 20  age the page.** 
c1b0: 6e 75 6d 62 65 72 2e 0a 2a 2a 0a 2a 2a 20 52 65  number..**.** Re
c1c0: 74 75 72 6e 20 30 20 6f 6e 20 73 75 63 63 65 73  turn 0 on succes
c1d0: 73 2e 20 20 49 66 20 74 68 65 72 65 20 61 72 65  s.  If there are
c1e0: 20 6e 6f 20 70 61 67 65 73 20 69 6e 20 74 68 65   no pages in the
c1f0: 20 57 41 4c 20 77 69 74 68 20 61 20 70 61 67 65   WAL with a page
c200: 0a 2a 2a 20 6e 75 6d 62 65 72 20 6c 61 72 67 65  .** number large
c210: 72 20 74 68 61 6e 20 2a 70 69 50 61 67 65 2c 20  r than *piPage, 
c220: 74 68 65 6e 20 72 65 74 75 72 6e 20 31 2e 0a 2a  then return 1..*
c230: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
c240: 49 74 65 72 61 74 6f 72 4e 65 78 74 28 0a 20 20  IteratorNext(.  
c250: 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 2c 20  WalIterator *p, 
c260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c270: 20 49 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 75   Iterator */.  u
c280: 33 32 20 2a 70 69 50 61 67 65 2c 20 20 20 20 20  32 *piPage,     
c290: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c2a0: 4f 55 54 3a 20 54 68 65 20 70 61 67 65 20 6e 75  OUT: The page nu
c2b0: 6d 62 65 72 20 6f 66 20 74 68 65 20 6e 65 78 74  mber of the next
c2c0: 20 70 61 67 65 20 2a 2f 0a 20 20 75 33 32 20 2a   page */.  u32 *
c2d0: 70 69 46 72 61 6d 65 20 20 20 20 20 20 20 20 20  piFrame         
c2e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
c2f0: 20 57 61 6c 20 66 72 61 6d 65 20 69 6e 64 65 78   Wal frame index
c300: 20 6f 66 20 6e 65 78 74 20 70 61 67 65 20 2a 2f   of next page */
c310: 0a 29 7b 0a 20 20 75 33 32 20 69 4d 69 6e 3b 20  .){.  u32 iMin; 
c320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c330: 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 70 67      /* Result pg
c340: 6e 6f 20 6d 75 73 74 20 62 65 20 67 72 65 61 74  no must be great
c350: 65 72 20 74 68 61 6e 20 69 4d 69 6e 20 2a 2f 0a  er than iMin */.
c360: 20 20 75 33 32 20 69 52 65 74 20 3d 20 30 78 46    u32 iRet = 0xF
c370: 46 46 46 46 46 46 46 3b 20 20 20 20 20 20 20 20  FFFFFFF;        
c380: 2f 2a 20 30 78 66 66 66 66 66 66 66 66 20 69 73  /* 0xffffffff is
c390: 20 6e 65 76 65 72 20 61 20 76 61 6c 69 64 20 70   never a valid p
c3a0: 61 67 65 20 6e 75 6d 62 65 72 20 2a 2f 0a 20 20  age number */.  
c3b0: 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
c3c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c3d0: 20 46 6f 72 20 6c 6f 6f 70 69 6e 67 20 74 68 72   For looping thr
c3e0: 6f 75 67 68 20 73 65 67 6d 65 6e 74 73 20 2a 2f  ough segments */
c3f0: 0a 0a 20 20 69 4d 69 6e 20 3d 20 70 2d 3e 69 50  ..  iMin = p->iP
c400: 72 69 6f 72 3b 0a 20 20 61 73 73 65 72 74 28 20  rior;.  assert( 
c410: 69 4d 69 6e 3c 30 78 66 66 66 66 66 66 66 66 20  iMin<0xffffffff 
c420: 29 3b 0a 20 20 66 6f 72 28 69 3d 70 2d 3e 6e 53  );.  for(i=p->nS
c430: 65 67 6d 65 6e 74 2d 31 3b 20 69 3e 3d 30 3b 20  egment-1; i>=0; 
c440: 69 2d 2d 29 7b 0a 20 20 20 20 73 74 72 75 63 74  i--){.    struct
c450: 20 57 61 6c 53 65 67 6d 65 6e 74 20 2a 70 53 65   WalSegment *pSe
c460: 67 6d 65 6e 74 20 3d 20 26 70 2d 3e 61 53 65 67  gment = &p->aSeg
c470: 6d 65 6e 74 5b 69 5d 3b 0a 20 20 20 20 77 68 69  ment[i];.    whi
c480: 6c 65 28 20 70 53 65 67 6d 65 6e 74 2d 3e 69 4e  le( pSegment->iN
c490: 65 78 74 3c 70 53 65 67 6d 65 6e 74 2d 3e 6e 45  ext<pSegment->nE
c4a0: 6e 74 72 79 20 29 7b 0a 20 20 20 20 20 20 75 33  ntry ){.      u3
c4b0: 32 20 69 50 67 20 3d 20 70 53 65 67 6d 65 6e 74  2 iPg = pSegment
c4c0: 2d 3e 61 50 67 6e 6f 5b 70 53 65 67 6d 65 6e 74  ->aPgno[pSegment
c4d0: 2d 3e 61 49 6e 64 65 78 5b 70 53 65 67 6d 65 6e  ->aIndex[pSegmen
c4e0: 74 2d 3e 69 4e 65 78 74 5d 5d 3b 0a 20 20 20 20  t->iNext]];.    
c4f0: 20 20 69 66 28 20 69 50 67 3e 69 4d 69 6e 20 29    if( iPg>iMin )
c500: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 50  {.        if( iP
c510: 67 3c 69 52 65 74 20 29 7b 0a 20 20 20 20 20 20  g<iRet ){.      
c520: 20 20 20 20 69 52 65 74 20 3d 20 69 50 67 3b 0a      iRet = iPg;.
c530: 20 20 20 20 20 20 20 20 20 20 2a 70 69 46 72 61            *piFra
c540: 6d 65 20 3d 20 70 53 65 67 6d 65 6e 74 2d 3e 69  me = pSegment->i
c550: 5a 65 72 6f 20 2b 20 70 53 65 67 6d 65 6e 74 2d  Zero + pSegment-
c560: 3e 61 49 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74  >aIndex[pSegment
c570: 2d 3e 69 4e 65 78 74 5d 3b 0a 20 20 20 20 20 20  ->iNext];.      
c580: 20 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61    }.        brea
c590: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  k;.      }.     
c5a0: 20 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74   pSegment->iNext
c5b0: 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  ++;.    }.  }.. 
c5c0: 20 2a 70 69 50 61 67 65 20 3d 20 70 2d 3e 69 50   *piPage = p->iP
c5d0: 72 69 6f 72 20 3d 20 69 52 65 74 3b 0a 20 20 72  rior = iRet;.  r
c5e0: 65 74 75 72 6e 20 28 69 52 65 74 3d 3d 30 78 46  eturn (iRet==0xF
c5f0: 46 46 46 46 46 46 46 29 3b 0a 7d 0a 0a 0a 73 74  FFFFFFF);.}...st
c600: 61 74 69 63 20 76 6f 69 64 20 77 61 6c 4d 65 72  atic void walMer
c610: 67 65 73 6f 72 74 28 0a 20 20 75 33 32 20 2a 61  gesort(.  u32 *a
c620: 43 6f 6e 74 65 6e 74 2c 20 20 20 20 20 20 20 20  Content,        
c630: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
c640: 65 73 20 69 6e 20 77 61 6c 20 2a 2f 0a 20 20 68  es in wal */.  h
c650: 74 5f 73 6c 6f 74 20 2a 61 42 75 66 66 65 72 2c  t_slot *aBuffer,
c660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c670: 2a 20 42 75 66 66 65 72 20 6f 66 20 61 74 20 6c  * Buffer of at l
c680: 65 61 73 74 20 2a 70 6e 4c 69 73 74 20 69 74 65  east *pnList ite
c690: 6d 73 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20 68  ms to use */.  h
c6a0: 74 5f 73 6c 6f 74 20 2a 61 4c 69 73 74 2c 20 20  t_slot *aList,  
c6b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c6c0: 2a 20 49 4e 2f 4f 55 54 3a 20 4c 69 73 74 20 74  * IN/OUT: List t
c6d0: 6f 20 73 6f 72 74 20 2a 2f 0a 20 20 69 6e 74 20  o sort */.  int 
c6e0: 2a 70 6e 4c 69 73 74 20 20 20 20 20 20 20 20 20  *pnList         
c6f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
c700: 4e 2f 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66  N/OUT: Number of
c710: 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 4c 69   elements in aLi
c720: 73 74 5b 5d 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  st[] */.){.  int
c730: 20 6e 4c 69 73 74 20 3d 20 2a 70 6e 4c 69 73 74   nList = *pnList
c740: 3b 0a 20 20 69 66 28 20 6e 4c 69 73 74 3e 31 20  ;.  if( nList>1 
c750: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 4c 65 66 74  ){.    int nLeft
c760: 20 3d 20 6e 4c 69 73 74 20 2f 20 32 3b 20 20 20   = nList / 2;   
c770: 20 20 20 20 20 2f 2a 20 45 6c 65 6d 65 6e 74 73       /* Elements
c780: 20 69 6e 20 6c 65 66 74 20 6c 69 73 74 20 2a 2f   in left list */
c790: 0a 20 20 20 20 69 6e 74 20 6e 52 69 67 68 74 20  .    int nRight 
c7a0: 3d 20 6e 4c 69 73 74 20 2d 20 6e 4c 65 66 74 3b  = nList - nLeft;
c7b0: 20 20 20 2f 2a 20 45 6c 65 6d 65 6e 74 73 20 69     /* Elements i
c7c0: 6e 20 72 69 67 68 74 20 6c 69 73 74 20 2a 2f 0a  n right list */.
c7d0: 20 20 20 20 69 6e 74 20 69 4c 65 66 74 20 3d 20      int iLeft = 
c7e0: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
c7f0: 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64    /* Current ind
c800: 65 78 20 69 6e 20 61 4c 65 66 74 20 2a 2f 0a 20  ex in aLeft */. 
c810: 20 20 20 69 6e 74 20 69 52 69 67 68 74 20 3d 20     int iRight = 
c820: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
c830: 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65   /* Current inde
c840: 78 20 69 6e 20 61 72 69 67 68 74 20 2a 2f 0a 20  x in aright */. 
c850: 20 20 20 69 6e 74 20 69 4f 75 74 20 3d 20 30 3b     int iOut = 0;
c860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c870: 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65   /* Current inde
c880: 78 20 69 6e 20 6f 75 74 70 75 74 20 62 75 66 66  x in output buff
c890: 65 72 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f  er */.    ht_slo
c8a0: 74 20 2a 61 4c 65 66 74 20 3d 20 61 4c 69 73 74  t *aLeft = aList
c8b0: 3b 20 20 20 20 20 20 20 2f 2a 20 4c 65 66 74 20  ;       /* Left 
c8c0: 6c 69 73 74 20 2a 2f 0a 20 20 20 20 68 74 5f 73  list */.    ht_s
c8d0: 6c 6f 74 20 2a 61 52 69 67 68 74 20 3d 20 61 4c  lot *aRight = aL
c8e0: 69 73 74 2b 6e 4c 65 66 74 3b 2f 2a 20 52 69 67  ist+nLeft;/* Rig
c8f0: 68 74 20 6c 69 73 74 20 2a 2f 0a 0a 20 20 20 20  ht list */..    
c900: 2f 2a 20 54 4f 44 4f 3a 20 43 68 61 6e 67 65 20  /* TODO: Change 
c910: 74 6f 20 6e 6f 6e 2d 72 65 63 75 72 73 69 76 65  to non-recursive
c920: 20 76 65 72 73 69 6f 6e 2e 20 2a 2f 0a 20 20 20   version. */.   
c930: 20 77 61 6c 4d 65 72 67 65 73 6f 72 74 28 61 43   walMergesort(aC
c940: 6f 6e 74 65 6e 74 2c 20 61 42 75 66 66 65 72 2c  ontent, aBuffer,
c950: 20 61 4c 65 66 74 2c 20 26 6e 4c 65 66 74 29 3b   aLeft, &nLeft);
c960: 0a 20 20 20 20 77 61 6c 4d 65 72 67 65 73 6f 72  .    walMergesor
c970: 74 28 61 43 6f 6e 74 65 6e 74 2c 20 61 42 75 66  t(aContent, aBuf
c980: 66 65 72 2c 20 61 52 69 67 68 74 2c 20 26 6e 52  fer, aRight, &nR
c990: 69 67 68 74 29 3b 0a 0a 20 20 20 20 77 68 69 6c  ight);..    whil
c9a0: 65 28 20 69 52 69 67 68 74 3c 6e 52 69 67 68 74  e( iRight<nRight
c9b0: 20 7c 7c 20 69 4c 65 66 74 3c 6e 4c 65 66 74 20   || iLeft<nLeft 
c9c0: 29 7b 0a 20 20 20 20 20 20 68 74 5f 73 6c 6f 74  ){.      ht_slot
c9d0: 20 6c 6f 67 70 61 67 65 3b 0a 20 20 20 20 20 20   logpage;.      
c9e0: 50 67 6e 6f 20 64 62 70 61 67 65 3b 0a 0a 20 20  Pgno dbpage;..  
c9f0: 20 20 20 20 69 66 28 20 28 69 4c 65 66 74 3c 6e      if( (iLeft<n
ca00: 4c 65 66 74 29 20 0a 20 20 20 20 20 20 20 26 26  Left) .       &&
ca10: 20 28 69 52 69 67 68 74 3e 3d 6e 52 69 67 68 74   (iRight>=nRight
ca20: 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65   || aContent[aLe
ca30: 66 74 5b 69 4c 65 66 74 5d 5d 3c 61 43 6f 6e 74  ft[iLeft]]<aCont
ca40: 65 6e 74 5b 61 52 69 67 68 74 5b 69 52 69 67 68  ent[aRight[iRigh
ca50: 74 5d 5d 29 0a 20 20 20 20 20 20 29 7b 0a 20 20  t]]).      ){.  
ca60: 20 20 20 20 20 20 6c 6f 67 70 61 67 65 20 3d 20        logpage = 
ca70: 61 4c 65 66 74 5b 69 4c 65 66 74 2b 2b 5d 3b 0a  aLeft[iLeft++];.
ca80: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
ca90: 20 20 20 20 20 6c 6f 67 70 61 67 65 20 3d 20 61       logpage = a
caa0: 52 69 67 68 74 5b 69 52 69 67 68 74 2b 2b 5d 3b  Right[iRight++];
cab0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 64  .      }.      d
cac0: 62 70 61 67 65 20 3d 20 61 43 6f 6e 74 65 6e 74  bpage = aContent
cad0: 5b 6c 6f 67 70 61 67 65 5d 3b 0a 0a 20 20 20 20  [logpage];..    
cae0: 20 20 61 42 75 66 66 65 72 5b 69 4f 75 74 2b 2b    aBuffer[iOut++
caf0: 5d 20 3d 20 6c 6f 67 70 61 67 65 3b 0a 20 20 20  ] = logpage;.   
cb00: 20 20 20 69 66 28 20 69 4c 65 66 74 3c 6e 4c 65     if( iLeft<nLe
cb10: 66 74 20 26 26 20 61 43 6f 6e 74 65 6e 74 5b 61  ft && aContent[a
cb20: 4c 65 66 74 5b 69 4c 65 66 74 5d 5d 3d 3d 64 62  Left[iLeft]]==db
cb30: 70 61 67 65 20 29 20 69 4c 65 66 74 2b 2b 3b 0a  page ) iLeft++;.
cb40: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69  .      assert( i
cb50: 4c 65 66 74 3e 3d 6e 4c 65 66 74 20 7c 7c 20 61  Left>=nLeft || a
cb60: 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69 4c  Content[aLeft[iL
cb70: 65 66 74 5d 5d 3e 64 62 70 61 67 65 20 29 3b 0a  eft]]>dbpage );.
cb80: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 69 52        assert( iR
cb90: 69 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c 20  ight>=nRight || 
cba0: 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b  aContent[aRight[
cbb0: 69 52 69 67 68 74 5d 5d 3e 64 62 70 61 67 65 20  iRight]]>dbpage 
cbc0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d  );.    }.    mem
cbd0: 63 70 79 28 61 4c 69 73 74 2c 20 61 42 75 66 66  cpy(aList, aBuff
cbe0: 65 72 2c 20 73 69 7a 65 6f 66 28 61 4c 69 73 74  er, sizeof(aList
cbf0: 5b 30 5d 29 2a 69 4f 75 74 29 3b 0a 20 20 20 20  [0])*iOut);.    
cc00: 2a 70 6e 4c 69 73 74 20 3d 20 69 4f 75 74 3b 0a  *pnList = iOut;.
cc10: 20 20 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49    }..#ifdef SQLI
cc20: 54 45 5f 44 45 42 55 47 0a 20 20 7b 0a 20 20 20  TE_DEBUG.  {.   
cc30: 20 69 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72 28   int i;.    for(
cc40: 69 3d 31 3b 20 69 3c 2a 70 6e 4c 69 73 74 3b 20  i=1; i<*pnList; 
cc50: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 61 73 73 65  i++){.      asse
cc60: 72 74 28 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69  rt( aContent[aLi
cc70: 73 74 5b 69 5d 5d 20 3e 20 61 43 6f 6e 74 65 6e  st[i]] > aConten
cc80: 74 5b 61 4c 69 73 74 5b 69 2d 31 5d 5d 20 29 3b  t[aList[i-1]] );
cc90: 0a 20 20 20 20 7d 0a 20 20 7d 0a 23 65 6e 64 69  .    }.  }.#endi
cca0: 66 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 46 72 65 65  f.}../* .** Free
ccb0: 20 61 6e 20 69 74 65 72 61 74 6f 72 20 61 6c 6c   an iterator all
ccc0: 6f 63 61 74 65 64 20 62 79 20 77 61 6c 49 74 65  ocated by walIte
ccd0: 72 61 74 6f 72 49 6e 69 74 28 29 2e 0a 2a 2f 0a  ratorInit()..*/.
cce0: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 49  static void walI
ccf0: 74 65 72 61 74 6f 72 46 72 65 65 28 57 61 6c 49  teratorFree(WalI
cd00: 74 65 72 61 74 6f 72 20 2a 70 29 7b 0a 20 20 73  terator *p){.  s
cd10: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a  qlite3_free(p);.
cd20: 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 70 20 74 68 65  }../*.** Map the
cd30: 20 77 61 6c 2d 69 6e 64 65 78 20 69 6e 74 6f 20   wal-index into 
cd40: 6d 65 6d 6f 72 79 20 6f 77 6e 65 64 20 62 79 20  memory owned by 
cd50: 74 68 69 73 20 74 68 72 65 61 64 2c 20 69 66 20  this thread, if 
cd60: 69 74 20 69 73 20 6e 6f 74 0a 2a 2a 20 6d 61 70  it is not.** map
cd70: 70 65 64 20 61 6c 72 65 61 64 79 2e 20 20 54 68  ped already.  Th
cd80: 65 6e 20 63 6f 6e 73 74 72 75 63 74 20 61 20 57  en construct a W
cd90: 61 6c 49 6e 74 65 72 61 74 6f 72 20 6f 62 6a 65  alInterator obje
cda0: 63 74 20 74 68 61 74 20 63 61 6e 20 62 65 0a 2a  ct that can be.*
cdb0: 2a 20 75 73 65 64 20 74 6f 20 6c 6f 6f 70 20 6f  * used to loop o
cdc0: 76 65 72 20 61 6c 6c 20 70 61 67 65 73 20 69 6e  ver all pages in
cdd0: 20 74 68 65 20 57 41 4c 20 69 6e 20 61 73 63 65   the WAL in asce
cde0: 6e 64 69 6e 67 20 6f 72 64 65 72 2e 20 20 0a 2a  nding order.  .*
cdf0: 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63 65 73 73 2c  *.** On success,
ce00: 20 6d 61 6b 65 20 2a 70 70 20 70 6f 69 6e 74 20   make *pp point 
ce10: 74 6f 20 74 68 65 20 6e 65 77 6c 79 20 61 6c 6c  to the newly all
ce20: 6f 63 61 74 65 64 20 57 61 6c 49 6e 74 65 72 61  ocated WalIntera
ce30: 74 6f 72 20 6f 62 6a 65 63 74 0a 2a 2a 20 72 65  tor object.** re
ce40: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20  turn SQLITE_OK. 
ce50: 20 4f 74 68 65 72 77 69 73 65 2c 20 6c 65 61 76   Otherwise, leav
ce60: 65 20 2a 70 70 20 75 6e 63 68 61 6e 67 65 64 20  e *pp unchanged 
ce70: 61 6e 64 20 72 65 74 75 72 6e 20 61 6e 20 65 72  and return an er
ce80: 72 6f 72 0a 2a 2a 20 63 6f 64 65 2e 0a 2a 2a 0a  ror.** code..**.
ce90: 2a 2a 20 54 68 65 20 63 61 6c 6c 69 6e 67 20 72  ** The calling r
cea0: 6f 75 74 69 6e 65 20 73 68 6f 75 6c 64 20 69 6e  outine should in
ceb0: 76 6f 6b 65 20 77 61 6c 49 74 65 72 61 74 6f 72  voke walIterator
cec0: 46 72 65 65 28 29 20 74 6f 20 64 65 73 74 72 6f  Free() to destro
ced0: 79 20 74 68 65 0a 2a 2a 20 57 61 6c 49 74 65 72  y the.** WalIter
cee0: 61 74 6f 72 20 6f 62 6a 65 63 74 20 77 68 65 6e  ator object when
cef0: 20 69 74 20 68 61 73 20 66 69 6e 69 73 68 65 64   it has finished
cf00: 20 77 69 74 68 20 69 74 2e 20 20 54 68 65 20 63   with it.  The c
cf10: 61 6c 6c 65 72 20 6d 75 73 74 0a 2a 2a 20 61 6c  aller must.** al
cf20: 73 6f 20 75 6e 6d 61 70 20 74 68 65 20 77 61 6c  so unmap the wal
cf30: 2d 69 6e 64 65 78 2e 20 20 42 75 74 20 74 68 65  -index.  But the
cf40: 20 77 61 6c 2d 69 6e 64 65 78 20 6d 75 73 74 20   wal-index must 
cf50: 6e 6f 74 20 62 65 20 75 6e 6d 61 70 70 65 64 0a  not be unmapped.
cf60: 2a 2a 20 70 72 69 6f 72 20 74 6f 20 74 68 65 20  ** prior to the 
cf70: 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65  WalIterator obje
cf80: 63 74 20 62 65 69 6e 67 20 64 65 73 74 72 6f 79  ct being destroy
cf90: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ed..*/.static in
cfa0: 74 20 77 61 6c 49 74 65 72 61 74 6f 72 49 6e 69  t walIteratorIni
cfb0: 74 28 57 61 6c 20 2a 70 57 61 6c 2c 20 57 61 6c  t(Wal *pWal, Wal
cfc0: 49 74 65 72 61 74 6f 72 20 2a 2a 70 70 29 7b 0a  Iterator **pp){.
cfd0: 20 20 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 70    WalIterator *p
cfe0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
cff0: 20 20 2f 2a 20 52 65 74 75 72 6e 20 76 61 6c 75    /* Return valu
d000: 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 65 67 6d  e */.  int nSegm
d010: 65 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ent;            
d020: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
d030: 20 6f 66 20 73 65 67 6d 65 6e 74 73 20 74 6f 20   of segments to 
d040: 6d 65 72 67 65 20 2a 2f 0a 20 20 75 33 32 20 69  merge */.  u32 i
d050: 4c 61 73 74 3b 20 20 20 20 20 20 20 20 20 20 20  Last;           
d060: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
d070: 73 74 20 66 72 61 6d 65 20 69 6e 20 6c 6f 67 20  st frame in log 
d080: 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 20  */.  int nByte; 
d090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d0a0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
d0b0: 66 20 62 79 74 65 73 20 74 6f 20 61 6c 6c 6f 63  f bytes to alloc
d0c0: 61 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20  ate */.  int i; 
d0d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d0e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72           /* Iter
d0f0: 61 74 6f 72 20 76 61 72 69 61 62 6c 65 20 2a 2f  ator variable */
d100: 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 54 6d 70  .  ht_slot *aTmp
d110: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
d120: 20 20 20 2f 2a 20 54 65 6d 70 20 73 70 61 63 65     /* Temp space
d130: 20 75 73 65 64 20 62 79 20 6d 65 72 67 65 2d 73   used by merge-s
d140: 6f 72 74 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74  ort */.  ht_slot
d150: 20 2a 61 53 70 61 63 65 3b 20 20 20 20 20 20 20   *aSpace;       
d160: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 70 61 63           /* Spac
d170: 65 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20  e at the end of 
d180: 74 68 65 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 2a  the allocation *
d190: 2f 0a 0a 20 20 2f 2a 20 54 68 69 73 20 72 6f 75  /..  /* This rou
d1a0: 74 69 6e 65 20 6f 6e 6c 79 20 72 75 6e 73 20 77  tine only runs w
d1b0: 68 69 6c 65 20 68 6f 6c 64 69 6e 67 20 53 51 4c  hile holding SQL
d1c0: 49 54 45 5f 53 48 4d 5f 43 48 45 43 4b 50 4f 49  ITE_SHM_CHECKPOI
d1d0: 4e 54 2e 20 20 4e 6f 20 6f 74 68 65 72 0a 20 20  NT.  No other.  
d1e0: 2a 2a 20 74 68 72 65 61 64 20 69 73 20 61 62 6c  ** thread is abl
d1f0: 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 73 68  e to write to sh
d200: 61 72 65 64 20 6d 65 6d 6f 72 79 20 77 68 69 6c  ared memory whil
d210: 65 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 69  e this routine i
d220: 73 0a 20 20 2a 2a 20 72 75 6e 6e 69 6e 67 20 28  s.  ** running (
d230: 6f 72 2c 20 69 6e 64 65 65 64 2c 20 77 68 69 6c  or, indeed, whil
d240: 65 20 74 68 65 20 57 61 6c 49 74 65 72 61 74 6f  e the WalIterato
d250: 72 20 6f 62 6a 65 63 74 20 65 78 69 73 74 73 29  r object exists)
d260: 2e 20 20 48 65 6e 63 65 2c 0a 20 20 2a 2a 20 77  .  Hence,.  ** w
d270: 65 20 63 61 6e 20 63 61 73 74 20 6f 66 66 20 74  e can cast off t
d280: 68 65 20 76 6f 6c 61 74 69 6c 65 20 71 75 61 6c  he volatile qual
d290: 69 66 69 63 61 74 69 6f 6e 20 66 72 6f 6d 20 73  ification from s
d2a0: 68 61 72 65 64 20 6d 65 6d 6f 72 79 0a 20 20 2a  hared memory.  *
d2b0: 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  /.  assert( pWal
d2c0: 2d 3e 63 6b 70 74 4c 6f 63 6b 20 29 3b 0a 20 20  ->ckptLock );.  
d2d0: 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d 3e 68 64  iLast = pWal->hd
d2e0: 72 2e 6d 78 46 72 61 6d 65 3b 0a 0a 20 20 2f 2a  r.mxFrame;..  /*
d2f0: 20 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20   Allocate space 
d300: 66 6f 72 20 74 68 65 20 57 61 6c 49 74 65 72 61  for the WalItera
d310: 74 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  tor object */.  
d320: 6e 53 65 67 6d 65 6e 74 20 3d 20 77 61 6c 46 72  nSegment = walFr
d330: 61 6d 65 50 61 67 65 28 69 4c 61 73 74 29 20 2b  amePage(iLast) +
d340: 20 31 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73 69   1;.  nByte = si
d350: 7a 65 6f 66 28 57 61 6c 49 74 65 72 61 74 6f 72  zeof(WalIterator
d360: 29 20 0a 20 20 20 20 20 20 20 20 2b 20 6e 53 65  ) .        + nSe
d370: 67 6d 65 6e 74 2a 28 73 69 7a 65 6f 66 28 73 74  gment*(sizeof(st
d380: 72 75 63 74 20 57 61 6c 53 65 67 6d 65 6e 74 29  ruct WalSegment)
d390: 29 0a 20 20 20 20 20 20 20 20 2b 20 28 6e 53 65  ).        + (nSe
d3a0: 67 6d 65 6e 74 2b 31 29 2a 28 48 41 53 48 54 41  gment+1)*(HASHTA
d3b0: 42 4c 45 5f 4e 50 41 47 45 20 2a 20 73 69 7a 65  BLE_NPAGE * size
d3c0: 6f 66 28 68 74 5f 73 6c 6f 74 29 29 3b 0a 20 20  of(ht_slot));.  
d3d0: 70 20 3d 20 28 57 61 6c 49 74 65 72 61 74 6f 72  p = (WalIterator
d3e0: 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   *)sqlite3_mallo
d3f0: 63 28 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20  c(nByte);.  if( 
d400: 21 70 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  !p ){.    return
d410: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
d420: 20 7d 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30   }.  memset(p, 0
d430: 2c 20 6e 42 79 74 65 29 3b 0a 0a 20 20 2f 2a 20  , nByte);..  /* 
d440: 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66  Allocate space f
d450: 6f 72 20 74 68 65 20 57 61 6c 49 74 65 72 61 74  or the WalIterat
d460: 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 70  or object */.  p
d470: 2d 3e 6e 53 65 67 6d 65 6e 74 20 3d 20 6e 53 65  ->nSegment = nSe
d480: 67 6d 65 6e 74 3b 0a 20 20 61 53 70 61 63 65 20  gment;.  aSpace 
d490: 3d 20 28 68 74 5f 73 6c 6f 74 20 2a 29 26 70 2d  = (ht_slot *)&p-
d4a0: 3e 61 53 65 67 6d 65 6e 74 5b 6e 53 65 67 6d 65  >aSegment[nSegme
d4b0: 6e 74 5d 3b 0a 20 20 61 54 6d 70 20 3d 20 26 61  nt];.  aTmp = &a
d4c0: 53 70 61 63 65 5b 48 41 53 48 54 41 42 4c 45 5f  Space[HASHTABLE_
d4d0: 4e 50 41 47 45 2a 6e 53 65 67 6d 65 6e 74 5d 3b  NPAGE*nSegment];
d4e0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 53  .  for(i=0; i<nS
d4f0: 65 67 6d 65 6e 74 3b 20 69 2b 2b 29 7b 0a 20 20  egment; i++){.  
d500: 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c    volatile ht_sl
d510: 6f 74 20 2a 61 48 61 73 68 3b 0a 20 20 20 20 69  ot *aHash;.    i
d520: 6e 74 20 6a 3b 0a 20 20 20 20 75 33 32 20 69 5a  nt j;.    u32 iZ
d530: 65 72 6f 3b 0a 20 20 20 20 69 6e 74 20 6e 45 6e  ero;.    int nEn
d540: 74 72 79 3b 0a 20 20 20 20 76 6f 6c 61 74 69 6c  try;.    volatil
d550: 65 20 75 33 32 20 2a 61 50 67 6e 6f 3b 0a 20 20  e u32 *aPgno;.  
d560: 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 20 20 72    int rc;..    r
d570: 63 20 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70  c = walHashGet(p
d580: 57 61 6c 2c 20 69 2c 20 26 61 48 61 73 68 2c 20  Wal, i, &aHash, 
d590: 26 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b  &aPgno, &iZero);
d5a0: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
d5b0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
d5c0: 77 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28  walIteratorFree(
d5d0: 70 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e  p);.      return
d5e0: 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61   rc;.    }.    a
d5f0: 50 67 6e 6f 2b 2b 3b 0a 20 20 20 20 6e 45 6e 74  Pgno++;.    nEnt
d600: 72 79 20 3d 20 28 28 69 2b 31 29 3d 3d 6e 53 65  ry = ((i+1)==nSe
d610: 67 6d 65 6e 74 29 3f 69 4c 61 73 74 2d 69 5a 65  gment)?iLast-iZe
d620: 72 6f 3a 28 75 33 32 20 2a 29 61 48 61 73 68 2d  ro:(u32 *)aHash-
d630: 28 75 33 32 20 2a 29 61 50 67 6e 6f 3b 0a 20 20  (u32 *)aPgno;.  
d640: 20 20 69 5a 65 72 6f 2b 2b 3b 0a 0a 20 20 20 20    iZero++;..    
d650: 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 45 6e 74 72  for(j=0; j<nEntr
d660: 79 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 61  y; j++){.      a
d670: 53 70 61 63 65 5b 6a 5d 20 3d 20 6a 3b 0a 20 20  Space[j] = j;.  
d680: 20 20 7d 0a 20 20 20 20 77 61 6c 4d 65 72 67 65    }.    walMerge
d690: 73 6f 72 74 28 28 75 33 32 20 2a 29 61 50 67 6e  sort((u32 *)aPgn
d6a0: 6f 2c 20 61 54 6d 70 2c 20 61 53 70 61 63 65 2c  o, aTmp, aSpace,
d6b0: 20 26 6e 45 6e 74 72 79 29 3b 0a 20 20 20 20 70   &nEntry);.    p
d6c0: 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 69 5a  ->aSegment[i].iZ
d6d0: 65 72 6f 20 3d 20 69 5a 65 72 6f 3b 0a 20 20 20  ero = iZero;.   
d6e0: 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e   p->aSegment[i].
d6f0: 6e 45 6e 74 72 79 20 3d 20 6e 45 6e 74 72 79 3b  nEntry = nEntry;
d700: 0a 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74  .    p->aSegment
d710: 5b 69 5d 2e 61 49 6e 64 65 78 20 3d 20 61 53 70  [i].aIndex = aSp
d720: 61 63 65 3b 0a 20 20 20 20 70 2d 3e 61 53 65 67  ace;.    p->aSeg
d730: 6d 65 6e 74 5b 69 5d 2e 61 50 67 6e 6f 20 3d 20  ment[i].aPgno = 
d740: 28 75 33 32 20 2a 29 61 50 67 6e 6f 3b 0a 20 20  (u32 *)aPgno;.  
d750: 20 20 61 53 70 61 63 65 20 2b 3d 20 48 41 53 48    aSpace += HASH
d760: 54 41 42 4c 45 5f 4e 50 41 47 45 3b 0a 20 20 7d  TABLE_NPAGE;.  }
d770: 0a 20 20 61 73 73 65 72 74 28 20 61 53 70 61 63  .  assert( aSpac
d780: 65 3d 3d 61 54 6d 70 20 29 3b 0a 0a 20 20 2f 2a  e==aTmp );..  /*
d790: 20 52 65 74 75 72 6e 20 74 68 65 20 66 75 6c 6c   Return the full
d7a0: 79 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 57 61  y initialized Wa
d7b0: 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74  lIterator object
d7c0: 20 2a 2f 0a 20 20 2a 70 70 20 3d 20 70 3b 0a 20   */.  *pp = p;. 
d7d0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
d7e0: 4b 20 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70  K ;.}../*.** Cop
d7f0: 79 20 61 73 20 6d 75 63 68 20 63 6f 6e 74 65 6e  y as much conten
d800: 74 20 61 73 20 77 65 20 63 61 6e 20 66 72 6f 6d  t as we can from
d810: 20 74 68 65 20 57 41 4c 20 62 61 63 6b 20 69 6e   the WAL back in
d820: 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20  to the database 
d830: 66 69 6c 65 0a 2a 2a 20 69 6e 20 72 65 73 70 6f  file.** in respo
d840: 6e 73 65 20 74 6f 20 61 6e 20 73 71 6c 69 74 65  nse to an sqlite
d850: 33 5f 77 61 6c 5f 63 68 65 63 6b 70 6f 69 6e 74  3_wal_checkpoint
d860: 28 29 20 72 65 71 75 65 73 74 20 6f 72 20 74 68  () request or th
d870: 65 20 65 71 75 69 76 61 6c 65 6e 74 2e 0a 2a 2a  e equivalent..**
d880: 0a 2a 2a 20 54 68 65 20 61 6d 6f 75 6e 74 20 6f  .** The amount o
d890: 66 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 63 6f  f information co
d8a0: 70 69 65 73 20 66 72 6f 6d 20 57 41 4c 20 74 6f  pies from WAL to
d8b0: 20 64 61 74 61 62 61 73 65 20 6d 69 67 68 74 20   database might 
d8c0: 62 65 20 6c 69 6d 69 74 65 64 0a 2a 2a 20 62 79  be limited.** by
d8d0: 20 61 63 74 69 76 65 20 72 65 61 64 65 72 73 2e   active readers.
d8e0: 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77    This routine w
d8f0: 69 6c 6c 20 6e 65 76 65 72 20 6f 76 65 72 77 72  ill never overwr
d900: 69 74 65 20 61 20 64 61 74 61 62 61 73 65 20 70  ite a database p
d910: 61 67 65 0a 2a 2a 20 74 68 61 74 20 61 20 63 6f  age.** that a co
d920: 6e 63 75 72 72 65 6e 74 20 72 65 61 64 65 72 20  ncurrent reader 
d930: 6d 69 67 68 74 20 62 65 20 75 73 69 6e 67 2e 0a  might be using..
d940: 2a 2a 0a 2a 2a 20 41 6c 6c 20 49 2f 4f 20 62 61  **.** All I/O ba
d950: 72 72 69 65 72 20 6f 70 65 72 61 74 69 6f 6e 73  rrier operations
d960: 20 28 61 2e 6b 2e 61 20 66 73 79 6e 63 73 29 20   (a.k.a fsyncs) 
d970: 6f 63 63 75 72 20 69 6e 20 74 68 69 73 20 72 6f  occur in this ro
d980: 75 74 69 6e 65 20 77 68 65 6e 0a 2a 2a 20 53 51  utine when.** SQ
d990: 4c 69 74 65 20 69 73 20 69 6e 20 57 41 4c 2d 6d  Lite is in WAL-m
d9a0: 6f 64 65 20 69 6e 20 73 79 6e 63 68 72 6f 6e 6f  ode in synchrono
d9b0: 75 73 3d 4e 4f 52 4d 41 4c 2e 20 20 54 68 61 74  us=NORMAL.  That
d9c0: 20 6d 65 61 6e 73 20 74 68 61 74 20 69 66 20 0a   means that if .
d9d0: 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 73 20 61  ** checkpoints a
d9e0: 72 65 20 61 6c 77 61 79 73 20 72 75 6e 20 62 79  re always run by
d9f0: 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74 68   a background th
da00: 72 65 61 64 20 6f 72 20 62 61 63 6b 67 72 6f 75  read or backgrou
da10: 6e 64 20 0a 2a 2a 20 70 72 6f 63 65 73 73 2c 20  nd .** process, 
da20: 66 6f 72 65 67 72 6f 75 6e 64 20 74 68 72 65 61  foreground threa
da30: 64 73 20 77 69 6c 6c 20 6e 65 76 65 72 20 62 6c  ds will never bl
da40: 6f 63 6b 20 6f 6e 20 61 20 6c 65 6e 67 74 68 79  ock on a lengthy
da50: 20 66 73 79 6e 63 20 63 61 6c 6c 2e 0a 2a 2a 0a   fsync call..**.
da60: 2a 2a 20 46 73 79 6e 63 20 69 73 20 63 61 6c 6c  ** Fsync is call
da70: 65 64 20 6f 6e 20 74 68 65 20 57 41 4c 20 62 65  ed on the WAL be
da80: 66 6f 72 65 20 77 72 69 74 69 6e 67 20 63 6f 6e  fore writing con
da90: 74 65 6e 74 20 6f 75 74 20 6f 66 20 74 68 65 20  tent out of the 
daa0: 57 41 4c 20 61 6e 64 0a 2a 2a 20 69 6e 74 6f 20  WAL and.** into 
dab0: 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 20 54  the database.  T
dac0: 68 69 73 20 65 6e 73 75 72 65 73 20 74 68 61 74  his ensures that
dad0: 20 69 66 20 74 68 65 20 6e 65 77 20 63 6f 6e 74   if the new cont
dae0: 65 6e 74 20 69 73 20 70 65 72 73 69 73 74 65 6e  ent is persisten
daf0: 74 0a 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c 20  t.** in the WAL 
db00: 61 6e 64 20 63 61 6e 20 62 65 20 72 65 63 6f 76  and can be recov
db10: 65 72 65 64 20 66 6f 6c 6c 6f 77 69 6e 67 20 61  ered following a
db20: 20 70 6f 77 65 72 2d 6c 6f 73 73 20 6f 72 20 68   power-loss or h
db30: 61 72 64 20 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a  ard reset..**.**
db40: 20 46 73 79 6e 63 20 69 73 20 61 6c 73 6f 20 63   Fsync is also c
db50: 61 6c 6c 65 64 20 6f 6e 20 74 68 65 20 64 61 74  alled on the dat
db60: 61 62 61 73 65 20 66 69 6c 65 20 69 66 20 28 61  abase file if (a
db70: 6e 64 20 6f 6e 6c 79 20 69 66 29 20 74 68 65 20  nd only if) the 
db80: 65 6e 74 69 72 65 0a 2a 2a 20 57 41 4c 20 63 6f  entire.** WAL co
db90: 6e 74 65 6e 74 20 69 73 20 63 6f 70 69 65 64 20  ntent is copied 
dba0: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
dbb0: 65 20 66 69 6c 65 2e 20 20 54 68 69 73 20 73 65  e file.  This se
dbc0: 63 6f 6e 64 20 66 73 79 6e 63 20 6d 61 6b 65 73  cond fsync makes
dbd0: 0a 2a 2a 20 69 74 20 73 61 66 65 20 74 6f 20 64  .** it safe to d
dbe0: 65 6c 65 74 65 20 74 68 65 20 57 41 4c 20 73 69  elete the WAL si
dbf0: 6e 63 65 20 74 68 65 20 6e 65 77 20 63 6f 6e 74  nce the new cont
dc00: 65 6e 74 20 77 69 6c 6c 20 70 65 72 73 69 73 74  ent will persist
dc10: 20 69 6e 20 74 68 65 0a 2a 2a 20 64 61 74 61 62   in the.** datab
dc20: 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20  ase file..**.** 
dc30: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 75 73 65  This routine use
dc40: 73 20 61 6e 64 20 75 70 64 61 74 65 73 20 74 68  s and updates th
dc50: 65 20 6e 42 61 63 6b 66 69 6c 6c 20 66 69 65 6c  e nBackfill fiel
dc60: 64 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  d of the wal-ind
dc70: 65 78 20 68 65 61 64 65 72 2e 0a 2a 2a 20 54 68  ex header..** Th
dc80: 69 73 20 69 73 20 74 68 65 20 6f 6e 6c 79 20 72  is is the only r
dc90: 6f 75 74 69 6e 65 20 74 68 61 20 77 69 6c 6c 20  outine tha will 
dca0: 69 6e 63 72 65 61 73 65 20 74 68 65 20 76 61 6c  increase the val
dcb0: 75 65 20 6f 66 20 6e 42 61 63 6b 66 69 6c 6c 2e  ue of nBackfill.
dcc0: 20 20 0a 2a 2a 20 28 41 20 57 41 4c 20 72 65 73    .** (A WAL res
dcd0: 65 74 20 6f 72 20 72 65 63 6f 76 65 72 79 20 77  et or recovery w
dce0: 69 6c 6c 20 72 65 76 65 72 74 20 6e 42 61 63 6b  ill revert nBack
dcf0: 66 69 6c 6c 20 74 6f 20 7a 65 72 6f 2c 20 62 75  fill to zero, bu
dd00: 74 20 6e 6f 74 20 69 6e 63 72 65 61 73 65 0a 2a  t not increase.*
dd10: 2a 20 69 74 73 20 76 61 6c 75 65 2e 29 0a 2a 2a  * its value.).**
dd20: 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 65 72 20 6d  .** The caller m
dd30: 75 73 74 20 62 65 20 68 6f 6c 64 69 6e 67 20 73  ust be holding s
dd40: 75 66 66 69 63 69 65 6e 74 20 6c 6f 63 6b 73 20  ufficient locks 
dd50: 74 6f 20 65 6e 73 75 72 65 20 74 68 61 74 20 6e  to ensure that n
dd60: 6f 20 6f 74 68 65 72 0a 2a 2a 20 63 68 65 63 6b  o other.** check
dd70: 70 6f 69 6e 74 20 69 73 20 72 75 6e 6e 69 6e 67  point is running
dd80: 20 28 69 6e 20 61 6e 79 20 6f 74 68 65 72 20 74   (in any other t
dd90: 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73  hread or process
dda0: 29 20 61 74 20 74 68 65 20 73 61 6d 65 0a 2a 2a  ) at the same.**
ddb0: 20 74 69 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69 63   time..*/.static
ddc0: 20 69 6e 74 20 77 61 6c 43 68 65 63 6b 70 6f 69   int walCheckpoi
ddd0: 6e 74 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c  nt(.  Wal *pWal,
dde0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ddf0: 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 63 6f 6e        /* Wal con
de00: 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74  nection */.  int
de10: 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20   sync_flags,    
de20: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
de30: 46 6c 61 67 73 20 66 6f 72 20 4f 73 53 79 6e 63  Flags for OsSync
de40: 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20 69  () (or 0) */.  i
de50: 6e 74 20 6e 42 75 66 2c 20 20 20 20 20 20 20 20  nt nBuf,        
de60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
de70: 2a 20 53 69 7a 65 20 6f 66 20 7a 42 75 66 20 69  * Size of zBuf i
de80: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 38 20  n bytes */.  u8 
de90: 2a 7a 42 75 66 20 20 20 20 20 20 20 20 20 20 20  *zBuf           
dea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
deb0: 54 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72  Temporary buffer
dec0: 20 74 6f 20 75 73 65 20 2a 2f 0a 29 7b 0a 20 20   to use */.){.  
ded0: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
dee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
def0: 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
df00: 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 20 3d  /.  int szPage =
df10: 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67   pWal->hdr.szPag
df20: 65 3b 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20  e;  /* Database 
df30: 70 61 67 65 2d 73 69 7a 65 20 2a 2f 0a 20 20 57  page-size */.  W
df40: 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 49 74 65  alIterator *pIte
df50: 72 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 2f  r = 0;         /
df60: 2a 20 57 61 6c 20 69 74 65 72 61 74 6f 72 20 63  * Wal iterator c
df70: 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 75 33 32 20  ontext */.  u32 
df80: 69 44 62 70 61 67 65 20 3d 20 30 3b 20 20 20 20  iDbpage = 0;    
df90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
dfa0: 65 78 74 20 64 61 74 61 62 61 73 65 20 70 61 67  ext database pag
dfb0: 65 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20  e to write */.  
dfc0: 75 33 32 20 69 46 72 61 6d 65 20 3d 20 30 3b 20  u32 iFrame = 0; 
dfd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dfe0: 2f 2a 20 57 61 6c 20 66 72 61 6d 65 20 63 6f 6e  /* Wal frame con
dff0: 74 61 69 6e 69 6e 67 20 64 61 74 61 20 66 6f 72  taining data for
e000: 20 69 44 62 70 61 67 65 20 2a 2f 0a 20 20 75 33   iDbpage */.  u3
e010: 32 20 6d 78 53 61 66 65 46 72 61 6d 65 3b 20 20  2 mxSafeFrame;  
e020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
e030: 20 4d 61 78 20 66 72 61 6d 65 20 74 68 61 74 20   Max frame that 
e040: 63 61 6e 20 62 65 20 62 61 63 6b 66 69 6c 6c 65  can be backfille
e050: 64 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  d */.  int i;   
e060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e070: 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63         /* Loop c
e080: 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 76 6f 6c 61  ounter */.  vola
e090: 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f  tile WalCkptInfo
e0a0: 20 2a 70 49 6e 66 6f 3b 20 20 20 20 2f 2a 20 54   *pInfo;    /* T
e0b0: 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 73 74  he checkpoint st
e0c0: 61 74 75 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  atus information
e0d0: 20 2a 2f 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61   */..  /* Alloca
e0e0: 74 65 20 74 68 65 20 69 74 65 72 61 74 6f 72 20  te the iterator 
e0f0: 2a 2f 0a 20 20 72 63 20 3d 20 77 61 6c 49 74 65  */.  rc = walIte
e100: 72 61 74 6f 72 49 6e 69 74 28 70 57 61 6c 2c 20  ratorInit(pWal, 
e110: 26 70 49 74 65 72 29 3b 0a 20 20 69 66 28 20 72  &pIter);.  if( r
e120: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20  c!=SQLITE_OK || 
e130: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
e140: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 67 6f 74 6f  e==0 ){.    goto
e150: 20 77 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f   walcheckpoint_o
e160: 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 2a 2a 20  ut;.  }..  /*** 
e170: 54 4f 44 4f 3a 20 20 4d 6f 76 65 20 74 68 69 73  TODO:  Move this
e180: 20 74 65 73 74 20 6f 75 74 20 74 6f 20 74 68 65   test out to the
e190: 20 63 61 6c 6c 65 72 2e 20 20 4d 61 6b 65 20 69   caller.  Make i
e1a0: 74 20 61 6e 20 61 73 73 65 72 74 28 29 20 68 65  t an assert() he
e1b0: 72 65 20 2a 2a 2a 2f 0a 20 20 69 66 28 20 70 57  re ***/.  if( pW
e1c0: 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 21 3d  al->hdr.szPage!=
e1d0: 6e 42 75 66 20 29 7b 0a 20 20 20 20 72 63 20 3d  nBuf ){.    rc =
e1e0: 20 53 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f   SQLITE_CORRUPT_
e1f0: 42 4b 50 54 3b 0a 20 20 20 20 67 6f 74 6f 20 77  BKPT;.    goto w
e200: 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74  alcheckpoint_out
e210: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6d 70  ;.  }..  /* Comp
e220: 75 74 65 20 69 6e 20 6d 78 53 61 66 65 46 72 61  ute in mxSafeFra
e230: 6d 65 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20  me the index of 
e240: 74 68 65 20 6c 61 73 74 20 66 72 61 6d 65 20 6f  the last frame o
e250: 66 20 74 68 65 20 57 41 4c 20 74 68 61 74 20 69  f the WAL that i
e260: 73 0a 20 20 2a 2a 20 73 61 66 65 20 74 6f 20 77  s.  ** safe to w
e270: 72 69 74 65 20 69 6e 74 6f 20 74 68 65 20 64 61  rite into the da
e280: 74 61 62 61 73 65 2e 20 20 46 72 61 6d 65 73 20  tabase.  Frames 
e290: 62 65 79 6f 6e 64 20 6d 78 53 61 66 65 46 72 61  beyond mxSafeFra
e2a0: 6d 65 20 6d 69 67 68 74 0a 20 20 2a 2a 20 6f 76  me might.  ** ov
e2b0: 65 72 77 72 69 74 65 20 64 61 74 61 62 61 73 65  erwrite database
e2c0: 20 70 61 67 65 73 20 74 68 61 74 20 61 72 65 20   pages that are 
e2d0: 69 6e 20 75 73 65 20 62 79 20 61 63 74 69 76 65  in use by active
e2e0: 20 72 65 61 64 65 72 73 20 61 6e 64 20 74 68 75   readers and thu
e2f0: 73 0a 20 20 2a 2a 20 63 61 6e 6e 6f 74 20 62 65  s.  ** cannot be
e300: 20 62 61 63 6b 66 69 6c 6c 65 64 20 66 72 6f 6d   backfilled from
e310: 20 74 68 65 20 57 41 4c 2e 0a 20 20 2a 2f 0a 20   the WAL..  */. 
e320: 20 6d 78 53 61 66 65 46 72 61 6d 65 20 3d 20 70   mxSafeFrame = p
e330: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
e340: 3b 0a 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43  ;.  pInfo = walC
e350: 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20  kptInfo(pWal);. 
e360: 20 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f   for(i=1; i<WAL_
e370: 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20  NREADER; i++){. 
e380: 20 20 20 75 33 32 20 79 20 3d 20 70 49 6e 66 6f     u32 y = pInfo
e390: 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a  ->aReadMark[i];.
e3a0: 20 20 20 20 69 66 28 20 6d 78 53 61 66 65 46 72      if( mxSafeFr
e3b0: 61 6d 65 3e 3d 79 20 29 7b 0a 20 20 20 20 20 20  ame>=y ){.      
e3c0: 61 73 73 65 72 74 28 20 79 3c 3d 70 57 61 6c 2d  assert( y<=pWal-
e3d0: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a  >hdr.mxFrame );.
e3e0: 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f        rc = walLo
e3f0: 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
e400: 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
e410: 69 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 69 66  i), 1);.      if
e420: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
e430: 29 7b 0a 20 20 20 20 20 20 20 20 70 49 6e 66 6f  ){.        pInfo
e440: 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d  ->aReadMark[i] =
e450: 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53   READMARK_NOT_US
e460: 45 44 3b 0a 20 20 20 20 20 20 20 20 77 61 6c 55  ED;.        walU
e470: 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  nlockExclusive(p
e480: 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
e490: 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20 20 20  CK(i), 1);.     
e4a0: 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53   }else if( rc==S
e4b0: 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20  QLITE_BUSY ){.  
e4c0: 20 20 20 20 20 20 6d 78 53 61 66 65 46 72 61 6d        mxSafeFram
e4d0: 65 20 3d 20 79 3b 0a 20 20 20 20 20 20 7d 65 6c  e = y;.      }el
e4e0: 73 65 7b 0a 20 20 20 20 20 20 20 20 67 6f 74 6f  se{.        goto
e4f0: 20 77 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f   walcheckpoint_o
e500: 75 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ut;.      }.    
e510: 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 49 6e  }.  }..  if( pIn
e520: 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3c 6d 78  fo->nBackfill<mx
e530: 53 61 66 65 46 72 61 6d 65 0a 20 20 20 26 26 20  SafeFrame.   && 
e540: 28 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63  (rc = walLockExc
e550: 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
e560: 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 31  _READ_LOCK(0), 1
e570: 29 29 3d 3d 53 51 4c 49 54 45 5f 4f 4b 0a 20 20  ))==SQLITE_OK.  
e580: 29 7b 0a 20 20 20 20 75 33 32 20 6e 42 61 63 6b  ){.    u32 nBack
e590: 66 69 6c 6c 20 3d 20 70 49 6e 66 6f 2d 3e 6e 42  fill = pInfo->nB
e5a0: 61 63 6b 66 69 6c 6c 3b 0a 0a 20 20 20 20 2f 2a  ackfill;..    /*
e5b0: 20 53 79 6e 63 20 74 68 65 20 57 41 4c 20 74 6f   Sync the WAL to
e5c0: 20 64 69 73 6b 20 2a 2f 0a 20 20 20 20 69 66 28   disk */.    if(
e5d0: 20 73 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a 20   sync_flags ){. 
e5e0: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
e5f0: 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57  3OsSync(pWal->pW
e600: 61 6c 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73  alFd, sync_flags
e610: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
e620: 20 49 74 65 72 61 74 65 20 74 68 72 6f 75 67 68   Iterate through
e630: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
e640: 20 74 68 65 20 57 41 4c 2c 20 63 6f 70 79 69 6e   the WAL, copyin
e650: 67 20 64 61 74 61 20 74 6f 20 74 68 65 20 64 62  g data to the db
e660: 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 20 20 77 68   file. */.    wh
e670: 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ile( rc==SQLITE_
e680: 4f 4b 20 26 26 20 30 3d 3d 77 61 6c 49 74 65 72  OK && 0==walIter
e690: 61 74 6f 72 4e 65 78 74 28 70 49 74 65 72 2c 20  atorNext(pIter, 
e6a0: 26 69 44 62 70 61 67 65 2c 20 26 69 46 72 61 6d  &iDbpage, &iFram
e6b0: 65 29 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65  e) ){.      asse
e6c0: 72 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f  rt( walFramePgno
e6d0: 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 3d 3d  (pWal, iFrame)==
e6e0: 69 44 62 70 61 67 65 20 29 3b 0a 20 20 20 20 20  iDbpage );.     
e6f0: 20 69 66 28 20 69 46 72 61 6d 65 3c 3d 6e 42 61   if( iFrame<=nBa
e700: 63 6b 66 69 6c 6c 20 7c 7c 20 69 46 72 61 6d 65  ckfill || iFrame
e710: 3e 6d 78 53 61 66 65 46 72 61 6d 65 20 29 20 63  >mxSafeFrame ) c
e720: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 72  ontinue;.      r
e730: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61  c = sqlite3OsRea
e740: 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20  d(pWal->pWalFd, 
e750: 7a 42 75 66 2c 20 73 7a 50 61 67 65 2c 20 0a 20  zBuf, szPage, . 
e760: 20 20 20 20 20 20 20 20 20 77 61 6c 46 72 61 6d           walFram
e770: 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2c 20  eOffset(iFrame, 
e780: 73 7a 50 61 67 65 29 20 2b 20 57 41 4c 5f 46 52  szPage) + WAL_FR
e790: 41 4d 45 5f 48 44 52 53 49 5a 45 0a 20 20 20 20  AME_HDRSIZE.    
e7a0: 20 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72    );.      if( r
e7b0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62  c!=SQLITE_OK ) b
e7c0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 72 63 20 3d  reak;.      rc =
e7d0: 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28   sqlite3OsWrite(
e7e0: 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 7a 42 75  pWal->pDbFd, zBu
e7f0: 66 2c 20 73 7a 50 61 67 65 2c 20 28 69 44 62 70  f, szPage, (iDbp
e800: 61 67 65 2d 31 29 2a 73 7a 50 61 67 65 29 3b 0a  age-1)*szPage);.
e810: 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
e820: 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b  LITE_OK ) break;
e830: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49  .    }..    /* I
e840: 66 20 77 6f 72 6b 20 77 61 73 20 61 63 74 75 61  f work was actua
e850: 6c 6c 79 20 61 63 63 6f 6d 70 6c 69 73 68 65 64  lly accomplished
e860: 2e 2e 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 72  ... */.    if( r
e870: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
e880: 20 20 20 20 20 20 69 66 28 20 6d 78 53 61 66 65        if( mxSafe
e890: 46 72 61 6d 65 3d 3d 77 61 6c 49 6e 64 65 78 48  Frame==walIndexH
e8a0: 64 72 28 70 57 61 6c 29 2d 3e 6d 78 46 72 61 6d  dr(pWal)->mxFram
e8b0: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  e ){.        rc 
e8c0: 3d 20 73 71 6c 69 74 65 33 4f 73 54 72 75 6e 63  = sqlite3OsTrunc
e8d0: 61 74 65 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  ate(pWal->pDbFd,
e8e0: 20 28 28 69 36 34 29 70 57 61 6c 2d 3e 68 64 72   ((i64)pWal->hdr
e8f0: 2e 6e 50 61 67 65 2a 28 69 36 34 29 73 7a 50 61  .nPage*(i64)szPa
e900: 67 65 29 29 3b 0a 20 20 20 20 20 20 20 20 69 66  ge));.        if
e910: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
e920: 26 26 20 73 79 6e 63 5f 66 6c 61 67 73 20 29 7b  && sync_flags ){
e930: 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
e940: 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 70 57  sqlite3OsSync(pW
e950: 61 6c 2d 3e 70 44 62 46 64 2c 20 73 79 6e 63 5f  al->pDbFd, sync_
e960: 66 6c 61 67 73 29 3b 0a 20 20 20 20 20 20 20 20  flags);.        
e970: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
e980: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
e990: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49 6e  K ){.        pIn
e9a0: 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 20 3d 20  fo->nBackfill = 
e9b0: 6d 78 53 61 66 65 46 72 61 6d 65 3b 0a 20 20 20  mxSafeFrame;.   
e9c0: 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20     }.    }..    
e9d0: 2f 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20 72  /* Release the r
e9e0: 65 61 64 65 72 20 6c 6f 63 6b 20 68 65 6c 64 20  eader lock held 
e9f0: 77 68 69 6c 65 20 62 61 63 6b 66 69 6c 6c 69 6e  while backfillin
ea00: 67 20 2a 2f 0a 20 20 20 20 77 61 6c 55 6e 6c 6f  g */.    walUnlo
ea10: 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
ea20: 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
ea30: 30 29 2c 20 31 29 3b 0a 20 20 7d 65 6c 73 65 20  0), 1);.  }else 
ea40: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42  if( rc==SQLITE_B
ea50: 55 53 59 20 29 7b 0a 20 20 20 20 2f 2a 20 52 65  USY ){.    /* Re
ea60: 73 65 74 20 74 68 65 20 72 65 74 75 72 6e 20 63  set the return c
ea70: 6f 64 65 20 73 6f 20 61 73 20 6e 6f 74 20 74 6f  ode so as not to
ea80: 20 72 65 70 6f 72 74 20 61 20 63 68 65 63 6b 70   report a checkp
ea90: 6f 69 6e 74 20 66 61 69 6c 75 72 65 0a 20 20 20  oint failure.   
eaa0: 20 2a 2a 20 6a 75 73 74 20 62 65 63 61 75 73 65   ** just because
eab0: 20 61 63 74 69 76 65 20 72 65 61 64 65 72 73 20   active readers 
eac0: 70 72 65 76 65 6e 74 20 61 6e 79 20 62 61 63 6b  prevent any back
ead0: 66 69 6c 6c 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  fill..    */.   
eae0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
eaf0: 0a 20 20 7d 0a 0a 20 77 61 6c 63 68 65 63 6b 70  .  }.. walcheckp
eb00: 6f 69 6e 74 5f 6f 75 74 3a 0a 20 20 77 61 6c 49  oint_out:.  walI
eb10: 74 65 72 61 74 6f 72 46 72 65 65 28 70 49 74 65  teratorFree(pIte
eb20: 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  r);.  return rc;
eb30: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20  .}../*.** Close 
eb40: 61 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20  a connection to 
eb50: 61 20 6c 6f 67 20 66 69 6c 65 2e 0a 2a 2f 0a 69  a log file..*/.i
eb60: 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 43 6c 6f  nt sqlite3WalClo
eb70: 73 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c  se(.  Wal *pWal,
eb80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
eb90: 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 74 6f 20        /* Wal to 
eba0: 63 6c 6f 73 65 20 2a 2f 0a 20 20 69 6e 74 20 73  close */.  int s
ebb0: 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20  ync_flags,      
ebc0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c             /* Fl
ebd0: 61 67 73 20 74 6f 20 70 61 73 73 20 74 6f 20 4f  ags to pass to O
ebe0: 73 53 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a  sSync() (or 0) *
ebf0: 2f 0a 20 20 69 6e 74 20 6e 42 75 66 2c 0a 20 20  /.  int nBuf,.  
ec00: 75 38 20 2a 7a 42 75 66 20 20 20 20 20 20 20 20  u8 *zBuf        
ec10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ec20: 2f 2a 20 42 75 66 66 65 72 20 6f 66 20 61 74 20  /* Buffer of at 
ec30: 6c 65 61 73 74 20 6e 42 75 66 20 62 79 74 65 73  least nBuf bytes
ec40: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20   */.){.  int rc 
ec50: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
ec60: 66 28 20 70 57 61 6c 20 29 7b 0a 20 20 20 20 69  f( pWal ){.    i
ec70: 6e 74 20 69 73 44 65 6c 65 74 65 20 3d 20 30 3b  nt isDelete = 0;
ec80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
ec90: 54 72 75 65 20 74 6f 20 75 6e 6c 69 6e 6b 20 77  True to unlink w
eca0: 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78  al and wal-index
ecb0: 20 66 69 6c 65 73 20 2a 2f 0a 0a 20 20 20 20 2f   files */..    /
ecc0: 2a 20 49 66 20 61 6e 20 45 58 43 4c 55 53 49 56  * If an EXCLUSIV
ecd0: 45 20 6c 6f 63 6b 20 63 61 6e 20 62 65 20 6f 62  E lock can be ob
ece0: 74 61 69 6e 65 64 20 6f 6e 20 74 68 65 20 64 61  tained on the da
ecf0: 74 61 62 61 73 65 20 66 69 6c 65 20 28 75 73 69  tabase file (usi
ed00: 6e 67 20 74 68 65 0a 20 20 20 20 2a 2a 20 6f 72  ng the.    ** or
ed10: 64 69 6e 61 72 79 2c 20 72 6f 6c 6c 62 61 63 6b  dinary, rollback
ed20: 2d 6d 6f 64 65 20 6c 6f 63 6b 69 6e 67 20 6d 65  -mode locking me
ed30: 74 68 6f 64 73 2c 20 74 68 69 73 20 67 75 61 72  thods, this guar
ed40: 61 6e 74 65 65 73 20 74 68 61 74 20 74 68 65 0a  antees that the.
ed50: 20 20 20 20 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f      ** connectio
ed60: 6e 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74  n associated wit
ed70: 68 20 74 68 69 73 20 6c 6f 67 20 66 69 6c 65 20  h this log file 
ed80: 69 73 20 74 68 65 20 6f 6e 6c 79 20 63 6f 6e 6e  is the only conn
ed90: 65 63 74 69 6f 6e 20 74 6f 0a 20 20 20 20 2a 2a  ection to.    **
eda0: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 49   the database. I
edb0: 6e 20 74 68 69 73 20 63 61 73 65 20 63 68 65 63  n this case chec
edc0: 6b 70 6f 69 6e 74 20 74 68 65 20 64 61 74 61 62  kpoint the datab
edd0: 61 73 65 20 61 6e 64 20 75 6e 6c 69 6e 6b 20 62  ase and unlink b
ede0: 6f 74 68 0a 20 20 20 20 2a 2a 20 74 68 65 20 77  oth.    ** the w
edf0: 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78  al and wal-index
ee00: 20 66 69 6c 65 73 2e 0a 20 20 20 20 2a 2a 0a 20   files..    **. 
ee10: 20 20 20 2a 2a 20 54 68 65 20 45 58 43 4c 55 53     ** The EXCLUS
ee20: 49 56 45 20 6c 6f 63 6b 20 69 73 20 6e 6f 74 20  IVE lock is not 
ee30: 72 65 6c 65 61 73 65 64 20 62 65 66 6f 72 65 20  released before 
ee40: 72 65 74 75 72 6e 69 6e 67 2e 0a 20 20 20 20 2a  returning..    *
ee50: 2f 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  /.    rc = sqlit
ee60: 65 33 4f 73 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70  e3OsLock(pWal->p
ee70: 44 62 46 64 2c 20 53 51 4c 49 54 45 5f 4c 4f 43  DbFd, SQLITE_LOC
ee80: 4b 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20  K_EXCLUSIVE);.  
ee90: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
eea0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70 57 61  _OK ){.      pWa
eeb0: 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
eec0: 20 3d 20 31 3b 0a 20 20 20 20 20 20 72 63 20 3d   = 1;.      rc =
eed0: 20 73 71 6c 69 74 65 33 57 61 6c 43 68 65 63 6b   sqlite3WalCheck
eee0: 70 6f 69 6e 74 28 70 57 61 6c 2c 20 73 79 6e 63  point(pWal, sync
eef0: 5f 66 6c 61 67 73 2c 20 6e 42 75 66 2c 20 7a 42  _flags, nBuf, zB
ef00: 75 66 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72  uf);.      if( r
ef10: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
ef20: 20 20 20 20 20 20 20 20 69 73 44 65 6c 65 74 65          isDelete
ef30: 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = 1;.      }.  
ef40: 20 20 7d 0a 0a 20 20 20 20 77 61 6c 49 6e 64 65    }..    walInde
ef50: 78 43 6c 6f 73 65 28 70 57 61 6c 2c 20 69 73 44  xClose(pWal, isD
ef60: 65 6c 65 74 65 29 3b 0a 20 20 20 20 73 71 6c 69  elete);.    sqli
ef70: 74 65 33 4f 73 43 6c 6f 73 65 28 70 57 61 6c 2d  te3OsClose(pWal-
ef80: 3e 70 57 61 6c 46 64 29 3b 0a 20 20 20 20 69 66  >pWalFd);.    if
ef90: 28 20 69 73 44 65 6c 65 74 65 20 29 7b 0a 20 20  ( isDelete ){.  
efa0: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 44 65 6c      sqlite3OsDel
efb0: 65 74 65 28 70 57 61 6c 2d 3e 70 56 66 73 2c 20  ete(pWal->pVfs, 
efc0: 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65 2c 20  pWal->zWalName, 
efd0: 30 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 57 41  0);.    }.    WA
efe0: 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20  LTRACE(("WAL%p: 
eff0: 63 6c 6f 73 65 64 5c 6e 22 2c 20 70 57 61 6c 29  closed\n", pWal)
f000: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
f010: 72 65 65 28 70 57 61 6c 2d 3e 61 70 57 69 44 61  ree(pWal->apWiDa
f020: 74 61 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ta);.    sqlite3
f030: 5f 66 72 65 65 28 70 57 61 6c 29 3b 0a 20 20 7d  _free(pWal);.  }
f040: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
f050: 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74 6f 20 72 65  ./*.** Try to re
f060: 61 64 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  ad the wal-index
f070: 20 68 65 61 64 65 72 2e 20 20 52 65 74 75 72 6e   header.  Return
f080: 20 30 20 6f 6e 20 73 75 63 63 65 73 73 20 61 6e   0 on success an
f090: 64 20 31 20 69 66 0a 2a 2a 20 74 68 65 72 65 20  d 1 if.** there 
f0a0: 69 73 20 61 20 70 72 6f 62 6c 65 6d 2e 0a 2a 2a  is a problem..**
f0b0: 0a 2a 2a 20 54 68 65 20 77 61 6c 2d 69 6e 64 65  .** The wal-inde
f0c0: 78 20 69 73 20 69 6e 20 73 68 61 72 65 64 20 6d  x is in shared m
f0d0: 65 6d 6f 72 79 2e 20 20 41 6e 6f 74 68 65 72 20  emory.  Another 
f0e0: 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73  thread or proces
f0f0: 73 20 6d 69 67 68 74 0a 2a 2a 20 62 65 20 77 72  s might.** be wr
f100: 69 74 69 6e 67 20 74 68 65 20 68 65 61 64 65 72  iting the header
f110: 20 61 74 20 74 68 65 20 73 61 6d 65 20 74 69 6d   at the same tim
f120: 65 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 65  e this procedure
f130: 20 69 73 20 74 72 79 69 6e 67 20 74 6f 0a 2a 2a   is trying to.**
f140: 20 72 65 61 64 20 69 74 2c 20 77 68 69 63 68 20   read it, which 
f150: 6d 69 67 68 74 20 72 65 73 75 6c 74 20 69 6e 20  might result in 
f160: 69 6e 63 6f 6e 73 69 73 74 65 6e 63 79 2e 20 20  inconsistency.  
f170: 41 20 64 69 72 74 79 20 72 65 61 64 20 69 73 20  A dirty read is 
f180: 64 65 74 65 63 74 65 64 0a 2a 2a 20 62 79 20 76  detected.** by v
f190: 65 72 69 66 79 69 6e 67 20 74 68 61 74 20 62 6f  erifying that bo
f1a0: 74 68 20 63 6f 70 69 65 73 20 6f 66 20 74 68 65  th copies of the
f1b0: 20 68 65 61 64 65 72 20 61 72 65 20 74 68 65 20   header are the 
f1c0: 73 61 6d 65 20 61 6e 64 20 61 6c 73 6f 20 62 79  same and also by
f1d0: 0a 2a 2a 20 61 20 63 68 65 63 6b 73 75 6d 20 6f  .** a checksum o
f1e0: 6e 20 74 68 65 20 68 65 61 64 65 72 2e 0a 2a 2a  n the header..**
f1f0: 0a 2a 2a 20 49 66 20 61 6e 64 20 6f 6e 6c 79 20  .** If and only 
f200: 69 66 20 74 68 65 20 72 65 61 64 20 69 73 20 63  if the read is c
f210: 6f 6e 73 69 73 74 65 6e 74 20 61 6e 64 20 74 68  onsistent and th
f220: 65 20 68 65 61 64 65 72 20 69 73 20 64 69 66 66  e header is diff
f230: 65 72 65 6e 74 20 66 72 6f 6d 0a 2a 2a 20 70 57  erent from.** pW
f240: 61 6c 2d 3e 68 64 72 2c 20 74 68 65 6e 20 70 57  al->hdr, then pW
f250: 61 6c 2d 3e 68 64 72 20 69 73 20 75 70 64 61 74  al->hdr is updat
f260: 65 64 20 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e  ed to the conten
f270: 74 20 6f 66 20 74 68 65 20 6e 65 77 20 68 65 61  t of the new hea
f280: 64 65 72 0a 2a 2a 20 61 6e 64 20 2a 70 43 68 61  der.** and *pCha
f290: 6e 67 65 64 20 69 73 20 73 65 74 20 74 6f 20 31  nged is set to 1
f2a0: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 63  ..**.** If the c
f2b0: 68 65 63 6b 73 75 6d 20 63 61 6e 6e 6f 74 20 62  hecksum cannot b
f2c0: 65 20 76 65 72 69 66 69 65 64 20 72 65 74 75 72  e verified retur
f2d0: 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 20 49 66 20 74  n non-zero. If t
f2e0: 68 65 20 68 65 61 64 65 72 0a 2a 2a 20 69 73 20  he header.** is 
f2f0: 72 65 61 64 20 73 75 63 63 65 73 73 66 75 6c 6c  read successfull
f300: 79 20 61 6e 64 20 74 68 65 20 63 68 65 63 6b 73  y and the checks
f310: 75 6d 20 76 65 72 69 66 69 65 64 2c 20 72 65 74  um verified, ret
f320: 75 72 6e 20 7a 65 72 6f 2e 0a 2a 2f 0a 69 6e 74  urn zero..*/.int
f330: 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28   walIndexTryHdr(
f340: 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a  Wal *pWal, int *
f350: 70 43 68 61 6e 67 65 64 29 7b 0a 20 20 75 33 32  pChanged){.  u32
f360: 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20 20 20   aCksum[2];     
f370: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
f380: 43 68 65 63 6b 73 75 6d 20 6f 6e 20 74 68 65 20  Checksum on the 
f390: 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74 20 2a  header content *
f3a0: 2f 0a 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20  /.  WalIndexHdr 
f3b0: 68 31 2c 20 68 32 3b 20 20 20 20 20 20 20 20 20  h1, h2;         
f3c0: 20 20 20 20 2f 2a 20 54 77 6f 20 63 6f 70 69 65      /* Two copie
f3d0: 73 20 6f 66 20 74 68 65 20 68 65 61 64 65 72 20  s of the header 
f3e0: 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 57 61 6c  content */.  Wal
f3f0: 49 6e 64 65 78 48 64 72 20 76 6f 6c 61 74 69 6c  IndexHdr volatil
f400: 65 20 2a 61 48 64 72 3b 20 20 20 20 20 2f 2a 20  e *aHdr;     /* 
f410: 48 65 61 64 65 72 20 69 6e 20 73 68 61 72 65 64  Header in shared
f420: 20 6d 65 6d 6f 72 79 20 2a 2f 0a 0a 20 20 2f 2a   memory */..  /*
f430: 20 54 68 65 20 66 69 72 73 74 20 70 61 67 65 20   The first page 
f440: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
f450: 20 6d 75 73 74 20 62 65 20 6d 61 70 70 65 64 20   must be mapped 
f460: 61 74 20 74 68 69 73 20 70 6f 69 6e 74 2e 20 2a  at this point. *
f470: 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  /.  assert( pWal
f480: 2d 3e 6e 57 69 44 61 74 61 3e 30 20 26 26 20 70  ->nWiData>0 && p
f490: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
f4a0: 20 29 3b 0a 0a 20 20 2f 2a 20 52 65 61 64 20 74   );..  /* Read t
f4b0: 68 65 20 68 65 61 64 65 72 2e 20 54 68 69 73 20  he header. This 
f4c0: 6d 69 67 68 74 20 68 61 70 70 65 6e 20 63 75 72  might happen cur
f4d0: 72 65 6e 74 6c 79 20 77 69 74 68 20 61 20 77 72  rently with a wr
f4e0: 69 74 65 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20  ite to the.  ** 
f4f0: 73 61 6d 65 20 61 72 65 61 20 6f 66 20 73 68 61  same area of sha
f500: 72 65 64 20 6d 65 6d 6f 72 79 20 6f 6e 20 61 20  red memory on a 
f510: 64 69 66 66 65 72 65 6e 74 20 43 50 55 20 69 6e  different CPU in
f520: 20 61 20 53 4d 50 2c 0a 20 20 2a 2a 20 6d 65 61   a SMP,.  ** mea
f530: 6e 69 6e 67 20 69 74 20 69 73 20 70 6f 73 73 69  ning it is possi
f540: 62 6c 65 20 74 68 61 74 20 61 6e 20 69 6e 63 6f  ble that an inco
f550: 6e 73 69 73 74 65 6e 74 20 73 6e 61 70 73 68 6f  nsistent snapsho
f560: 74 20 69 73 20 72 65 61 64 0a 20 20 2a 2a 20 66  t is read.  ** f
f570: 72 6f 6d 20 74 68 65 20 66 69 6c 65 2e 20 49 66  rom the file. If
f580: 20 74 68 69 73 20 68 61 70 70 65 6e 73 2c 20 72   this happens, r
f590: 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a  eturn non-zero..
f5a0: 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 72 65 20    **.  ** There 
f5b0: 61 72 65 20 74 77 6f 20 63 6f 70 69 65 73 20 6f  are two copies o
f5c0: 66 20 74 68 65 20 68 65 61 64 65 72 20 61 74 20  f the header at 
f5d0: 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66  the beginning of
f5e0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a   the wal-index..
f5f0: 20 20 2a 2a 20 57 68 65 6e 20 72 65 61 64 69 6e    ** When readin
f600: 67 2c 20 72 65 61 64 20 5b 30 5d 20 66 69 72 73  g, read [0] firs
f610: 74 20 74 68 65 6e 20 5b 31 5d 2e 20 20 57 72 69  t then [1].  Wri
f620: 74 65 73 20 61 72 65 20 69 6e 20 74 68 65 20 72  tes are in the r
f630: 65 76 65 72 73 65 20 6f 72 64 65 72 2e 0a 20 20  everse order..  
f640: 2a 2a 20 4d 65 6d 6f 72 79 20 62 61 72 72 69 65  ** Memory barrie
f650: 72 73 20 61 72 65 20 75 73 65 64 20 74 6f 20 70  rs are used to p
f660: 72 65 76 65 6e 74 20 74 68 65 20 63 6f 6d 70 69  revent the compi
f670: 6c 65 72 20 6f 72 20 74 68 65 20 68 61 72 64 77  ler or the hardw
f680: 61 72 65 20 66 72 6f 6d 0a 20 20 2a 2a 20 72 65  are from.  ** re
f690: 6f 72 64 65 72 69 6e 67 20 74 68 65 20 72 65 61  ordering the rea
f6a0: 64 73 20 61 6e 64 20 77 72 69 74 65 73 2e 0a 20  ds and writes.. 
f6b0: 20 2a 2f 0a 20 20 61 48 64 72 20 3d 20 77 61 6c   */.  aHdr = wal
f6c0: 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29 3b 0a  IndexHdr(pWal);.
f6d0: 20 20 6d 65 6d 63 70 79 28 26 68 31 2c 20 28 76    memcpy(&h1, (v
f6e0: 6f 69 64 20 2a 29 26 61 48 64 72 5b 30 5d 2c 20  oid *)&aHdr[0], 
f6f0: 73 69 7a 65 6f 66 28 68 31 29 29 3b 0a 20 20 73  sizeof(h1));.  s
f700: 71 6c 69 74 65 33 4f 73 53 68 6d 42 61 72 72 69  qlite3OsShmBarri
f710: 65 72 28 70 57 61 6c 2d 3e 70 44 62 46 64 29 3b  er(pWal->pDbFd);
f720: 0a 20 20 6d 65 6d 63 70 79 28 26 68 32 2c 20 28  .  memcpy(&h2, (
f730: 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 31 5d 2c  void *)&aHdr[1],
f740: 20 73 69 7a 65 6f 66 28 68 32 29 29 3b 0a 0a 20   sizeof(h2));.. 
f750: 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 68 31 2c   if( memcmp(&h1,
f760: 20 26 68 32 2c 20 73 69 7a 65 6f 66 28 68 31 29   &h2, sizeof(h1)
f770: 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )!=0 ){.    retu
f780: 72 6e 20 31 3b 20 20 20 2f 2a 20 44 69 72 74 79  rn 1;   /* Dirty
f790: 20 72 65 61 64 20 2a 2f 0a 20 20 7d 20 20 0a 20   read */.  }  . 
f7a0: 20 69 66 28 20 68 31 2e 69 73 49 6e 69 74 3d 3d   if( h1.isInit==
f7b0: 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  0 ){.    return 
f7c0: 31 3b 20 20 20 2f 2a 20 4d 61 6c 66 6f 72 6d 65  1;   /* Malforme
f7d0: 64 20 68 65 61 64 65 72 20 2d 20 70 72 6f 62 61  d header - proba
f7e0: 62 6c 79 20 61 6c 6c 20 7a 65 72 6f 73 20 2a 2f  bly all zeros */
f7f0: 0a 20 20 7d 0a 20 20 77 61 6c 43 68 65 63 6b 73  .  }.  walChecks
f800: 75 6d 42 79 74 65 73 28 31 2c 20 28 75 38 2a 29  umBytes(1, (u8*)
f810: 26 68 31 2c 20 73 69 7a 65 6f 66 28 68 31 29 2d  &h1, sizeof(h1)-
f820: 73 69 7a 65 6f 66 28 68 31 2e 61 43 6b 73 75 6d  sizeof(h1.aCksum
f830: 29 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b 0a 20  ), 0, aCksum);. 
f840: 20 69 66 28 20 61 43 6b 73 75 6d 5b 30 5d 21 3d   if( aCksum[0]!=
f850: 68 31 2e 61 43 6b 73 75 6d 5b 30 5d 20 7c 7c 20  h1.aCksum[0] || 
f860: 61 43 6b 73 75 6d 5b 31 5d 21 3d 68 31 2e 61 43  aCksum[1]!=h1.aC
f870: 6b 73 75 6d 5b 31 5d 20 29 7b 0a 20 20 20 20 72  ksum[1] ){.    r
f880: 65 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20 43 68  eturn 1;   /* Ch
f890: 65 63 6b 73 75 6d 20 64 6f 65 73 20 6e 6f 74 20  ecksum does not 
f8a0: 6d 61 74 63 68 20 2a 2f 0a 20 20 7d 0a 0a 20 20  match */.  }..  
f8b0: 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c  if( memcmp(&pWal
f8c0: 2d 3e 68 64 72 2c 20 26 68 31 2c 20 73 69 7a 65  ->hdr, &h1, size
f8d0: 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
f8e0: 20 29 7b 0a 20 20 20 20 2a 70 43 68 61 6e 67 65   ){.    *pChange
f8f0: 64 20 3d 20 31 3b 0a 20 20 20 20 6d 65 6d 63 70  d = 1;.    memcp
f900: 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 26 68  y(&pWal->hdr, &h
f910: 31 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64  1, sizeof(WalInd
f920: 65 78 48 64 72 29 29 3b 0a 20 20 20 20 70 57 61  exHdr));.    pWa
f930: 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 70 57 61 6c  l->szPage = pWal
f940: 2d 3e 68 64 72 2e 73 7a 50 61 67 65 3b 0a 20 20  ->hdr.szPage;.  
f950: 7d 0a 0a 20 20 2f 2a 20 54 68 65 20 68 65 61 64  }..  /* The head
f960: 65 72 20 77 61 73 20 73 75 63 63 65 73 73 66 75  er was successfu
f970: 6c 6c 79 20 72 65 61 64 2e 20 52 65 74 75 72 6e  lly read. Return
f980: 20 7a 65 72 6f 2e 20 2a 2f 0a 20 20 72 65 74 75   zero. */.  retu
f990: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  rn 0;.}../*.** R
f9a0: 65 61 64 20 74 68 65 20 77 61 6c 2d 69 6e 64 65  ead the wal-inde
f9b0: 78 20 68 65 61 64 65 72 20 66 72 6f 6d 20 74 68  x header from th
f9c0: 65 20 77 61 6c 2d 69 6e 64 65 78 20 61 6e 64 20  e wal-index and 
f9d0: 69 6e 74 6f 20 70 57 61 6c 2d 3e 68 64 72 2e 0a  into pWal->hdr..
f9e0: 2a 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 68 65  ** If the wal-he
f9f0: 61 64 65 72 20 61 70 70 65 61 72 73 20 74 6f 20  ader appears to 
fa00: 62 65 20 63 6f 72 72 75 70 74 2c 20 74 72 79 20  be corrupt, try 
fa10: 74 6f 20 72 65 63 6f 6e 73 74 72 75 63 74 20 74  to reconstruct t
fa20: 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20  he.** wal-index 
fa30: 66 72 6f 6d 20 74 68 65 20 57 41 4c 20 62 65 66  from the WAL bef
fa40: 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a  ore returning..*
fa50: 2a 0a 2a 2a 20 53 65 74 20 2a 70 43 68 61 6e 67  *.** Set *pChang
fa60: 65 64 20 74 6f 20 31 20 69 66 20 74 68 65 20 77  ed to 1 if the w
fa70: 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
fa80: 76 61 6c 75 65 20 69 6e 20 70 57 61 6c 2d 3e 68  value in pWal->h
fa90: 64 72 20 69 73 0a 2a 2a 20 63 68 61 6e 67 65 64  dr is.** changed
faa0: 20 62 79 20 74 68 69 73 20 6f 70 65 72 74 69 6f   by this opertio
fab0: 6e 2e 20 20 49 66 20 70 57 61 6c 2d 3e 68 64 72  n.  If pWal->hdr
fac0: 20 69 73 20 75 6e 63 68 61 6e 67 65 64 2c 20 73   is unchanged, s
fad0: 65 74 20 2a 70 43 68 61 6e 67 65 64 0a 2a 2a 20  et *pChanged.** 
fae0: 74 6f 20 30 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  to 0..**.** If t
faf0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
fb00: 64 65 72 20 69 73 20 73 75 63 63 65 73 73 66 75  der is successfu
fb10: 6c 6c 79 20 72 65 61 64 2c 20 72 65 74 75 72 6e  lly read, return
fb20: 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 0a 2a 2a 20   SQLITE_OK. .** 
fb30: 4f 74 68 65 72 77 69 73 65 20 61 6e 20 53 51 4c  Otherwise an SQL
fb40: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a  ite error code..
fb50: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  */.static int wa
fb60: 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28 57 61  lIndexReadHdr(Wa
fb70: 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43  l *pWal, int *pC
fb80: 68 61 6e 67 65 64 29 7b 0a 20 20 69 6e 74 20 72  hanged){.  int r
fb90: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
fba0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
fbb0: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69  turn code */.  i
fbc0: 6e 74 20 62 61 64 48 64 72 3b 20 20 20 20 20 20  nt badHdr;      
fbd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
fbe0: 2a 20 54 72 75 65 20 69 66 20 61 20 68 65 61 64  * True if a head
fbf0: 65 72 20 72 65 61 64 20 66 61 69 6c 65 64 20 2a  er read failed *
fc00: 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32  /.  volatile u32
fc10: 20 2a 70 61 67 65 30 3b 20 20 20 20 20 20 20 20   *page0;        
fc20: 20 20 20 20 2f 2a 20 43 68 75 6e 6b 20 6f 66 20      /* Chunk of 
fc30: 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 74 61 69  wal-index contai
fc40: 6e 69 6e 67 20 68 65 61 64 65 72 20 2a 2f 0a 0a  ning header */..
fc50: 20 20 2f 2a 20 45 6e 73 75 72 65 20 74 68 61 74    /* Ensure that
fc60: 20 70 61 67 65 20 30 20 6f 66 20 74 68 65 20 77   page 0 of the w
fc70: 61 6c 2d 69 6e 64 65 78 20 28 74 68 65 20 70 61  al-index (the pa
fc80: 67 65 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73  ge that contains
fc90: 20 74 68 65 20 0a 20 20 2a 2a 20 77 61 6c 2d 69   the .  ** wal-i
fca0: 6e 64 65 78 20 68 65 61 64 65 72 29 20 69 73 20  ndex header) is 
fcb0: 6d 61 70 70 65 64 2e 20 52 65 74 75 72 6e 20 65  mapped. Return e
fcc0: 61 72 6c 79 20 69 66 20 61 6e 20 65 72 72 6f 72  arly if an error
fcd0: 20 6f 63 63 75 72 73 20 68 65 72 65 2e 0a 20 20   occurs here..  
fce0: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 43 68  */.  assert( pCh
fcf0: 61 6e 67 65 64 20 29 3b 0a 20 20 72 63 20 3d 20  anged );.  rc = 
fd00: 77 61 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61  walIndexPage(pWa
fd10: 6c 2c 20 30 2c 20 26 70 61 67 65 30 29 3b 0a 20  l, 0, &page0);. 
fd20: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
fd30: 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  OK ){.    return
fd40: 20 72 63 3b 0a 20 20 7d 3b 0a 20 20 61 73 73 65   rc;.  };.  asse
fd50: 72 74 28 20 70 61 67 65 30 20 7c 7c 20 70 57 61  rt( page0 || pWa
fd60: 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20  l->writeLock==0 
fd70: 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20  );..  /* If the 
fd80: 66 69 72 73 74 20 70 61 67 65 20 6f 66 20 74 68  first page of th
fd90: 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 61 73 20  e wal-index has 
fda0: 62 65 65 6e 20 6d 61 70 70 65 64 2c 20 74 72 79  been mapped, try
fdb0: 20 74 6f 20 72 65 61 64 20 74 68 65 0a 20 20 2a   to read the.  *
fdc0: 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  * wal-index head
fdd0: 65 72 20 69 6d 6d 65 64 69 61 74 65 6c 79 2c 20  er immediately, 
fde0: 77 69 74 68 6f 75 74 20 68 6f 6c 64 69 6e 67 20  without holding 
fdf0: 61 6e 79 20 6c 6f 63 6b 2e 20 54 68 69 73 20 75  any lock. This u
fe00: 73 75 61 6c 6c 79 0a 20 20 2a 2a 20 77 6f 72 6b  sually.  ** work
fe10: 73 2c 20 62 75 74 20 6d 61 79 20 66 61 69 6c 20  s, but may fail 
fe20: 69 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  if the wal-index
fe30: 20 68 65 61 64 65 72 20 69 73 20 63 6f 72 72 75   header is corru
fe40: 70 74 20 6f 72 20 63 75 72 72 65 6e 74 6c 79 20  pt or currently 
fe50: 0a 20 20 2a 2a 20 62 65 69 6e 67 20 6d 6f 64 69  .  ** being modi
fe60: 66 69 65 64 20 62 79 20 61 6e 6f 74 68 65 72 20  fied by another 
fe70: 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73  thread or proces
fe80: 73 2e 0a 20 20 2a 2f 0a 20 20 62 61 64 48 64 72  s..  */.  badHdr
fe90: 20 3d 20 28 70 61 67 65 30 20 3f 20 77 61 6c 49   = (page0 ? walI
fea0: 6e 64 65 78 54 72 79 48 64 72 28 70 57 61 6c 2c  ndexTryHdr(pWal,
feb0: 20 70 43 68 61 6e 67 65 64 29 20 3a 20 31 29 3b   pChanged) : 1);
fec0: 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69  ..  /* If the fi
fed0: 72 73 74 20 61 74 74 65 6d 70 74 20 66 61 69 6c  rst attempt fail
fee0: 65 64 2c 20 69 74 20 6d 69 67 68 74 20 68 61 76  ed, it might hav
fef0: 65 20 62 65 65 6e 20 64 75 65 20 74 6f 20 61 20  e been due to a 
ff00: 72 61 63 65 0a 20 20 2a 2a 20 77 69 74 68 20 61  race.  ** with a
ff10: 20 77 72 69 74 65 72 2e 20 20 53 6f 20 67 65 74   writer.  So get
ff20: 20 61 20 57 52 49 54 45 20 6c 6f 63 6b 20 61 6e   a WRITE lock an
ff30: 64 20 74 72 79 20 61 67 61 69 6e 2e 0a 20 20 2a  d try again..  *
ff40: 2f 0a 20 20 61 73 73 65 72 74 28 20 62 61 64 48  /.  assert( badH
ff50: 64 72 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 77  dr==0 || pWal->w
ff60: 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20  riteLock==0 );. 
ff70: 20 69 66 28 20 62 61 64 48 64 72 20 26 26 20 53   if( badHdr && S
ff80: 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20  QLITE_OK==(rc = 
ff90: 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65  walLockExclusive
ffa0: 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45  (pWal, WAL_WRITE
ffb0: 5f 4c 4f 43 4b 2c 20 31 29 29 20 29 7b 0a 20 20  _LOCK, 1)) ){.  
ffc0: 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63    pWal->writeLoc
ffd0: 6b 20 3d 20 31 3b 0a 20 20 20 20 69 66 28 20 53  k = 1;.    if( S
ffe0: 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20  QLITE_OK==(rc = 
fff0: 77 61 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61  walIndexPage(pWa
10000 6c 2c 20 30 2c 20 26 70 61 67 65 30 29 29 20 29  l, 0, &page0)) )
10010 7b 0a 20 20 20 20 20 20 62 61 64 48 64 72 20 3d  {.      badHdr =
10020 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28   walIndexTryHdr(
10030 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b  pWal, pChanged);
10040 0a 20 20 20 20 20 20 69 66 28 20 62 61 64 48 64  .      if( badHd
10050 72 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20  r ){.        /* 
10060 49 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  If the wal-index
10070 20 68 65 61 64 65 72 20 69 73 20 73 74 69 6c 6c   header is still
10080 20 6d 61 6c 66 6f 72 6d 65 64 20 65 76 65 6e 20   malformed even 
10090 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67 0a 20 20  while holding.  
100a0 20 20 20 20 20 20 2a 2a 20 61 20 57 52 49 54 45        ** a WRITE
100b0 20 6c 6f 63 6b 2c 20 69 74 20 63 61 6e 20 6f 6e   lock, it can on
100c0 6c 79 20 6d 65 61 6e 20 74 68 61 74 20 74 68 65  ly mean that the
100d0 20 68 65 61 64 65 72 20 69 73 20 63 6f 72 72 75   header is corru
100e0 70 74 65 64 20 61 6e 64 0a 20 20 20 20 20 20 20  pted and.       
100f0 20 2a 2a 20 6e 65 65 64 73 20 74 6f 20 62 65 20   ** needs to be 
10100 72 65 63 6f 6e 73 74 72 75 63 74 65 64 2e 20 20  reconstructed.  
10110 53 6f 20 72 75 6e 20 72 65 63 6f 76 65 72 79 20  So run recovery 
10120 74 6f 20 64 6f 20 65 78 61 63 74 6c 79 20 74 68  to do exactly th
10130 61 74 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20  at..        */. 
10140 20 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 49         rc = walI
10150 6e 64 65 78 52 65 63 6f 76 65 72 28 70 57 61 6c  ndexRecover(pWal
10160 29 3b 0a 20 20 20 20 20 20 20 20 2a 70 43 68 61  );.        *pCha
10170 6e 67 65 64 20 3d 20 31 3b 0a 20 20 20 20 20 20  nged = 1;.      
10180 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70 57 61 6c  }.    }.    pWal
10190 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b  ->writeLock = 0;
101a0 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78  .    walUnlockEx
101b0 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
101c0 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29  L_WRITE_LOCK, 1)
101d0 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74  ;.  }..  /* If t
101e0 68 65 20 68 65 61 64 65 72 20 69 73 20 72 65 61  he header is rea
101f0 64 20 73 75 63 63 65 73 73 66 75 6c 6c 79 2c 20  d successfully, 
10200 63 68 65 63 6b 20 74 68 65 20 76 65 72 73 69 6f  check the versio
10210 6e 20 6e 75 6d 62 65 72 20 74 6f 20 6d 61 6b 65  n number to make
10220 0a 20 20 2a 2a 20 73 75 72 65 20 74 68 65 20 77  .  ** sure the w
10230 61 6c 2d 69 6e 64 65 78 20 77 61 73 20 6e 6f 74  al-index was not
10240 20 63 6f 6e 73 74 72 75 63 74 65 64 20 77 69 74   constructed wit
10250 68 20 73 6f 6d 65 20 66 75 74 75 72 65 20 66 6f  h some future fo
10260 72 6d 61 74 20 74 68 61 74 0a 20 20 2a 2a 20 74  rmat that.  ** t
10270 68 69 73 20 76 65 72 73 69 6f 6e 20 6f 66 20 53  his version of S
10280 51 4c 69 74 65 20 63 61 6e 6e 6f 74 20 75 6e 64  QLite cannot und
10290 65 72 73 74 61 6e 64 2e 0a 20 20 2a 2f 0a 20 20  erstand..  */.  
102a0 69 66 28 20 62 61 64 48 64 72 3d 3d 30 20 26 26  if( badHdr==0 &&
102b0 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56 65 72 73   pWal->hdr.iVers
102c0 69 6f 6e 21 3d 57 41 4c 49 4e 44 45 58 5f 4d 41  ion!=WALINDEX_MA
102d0 58 5f 56 45 52 53 49 4f 4e 20 29 7b 0a 20 20 20  X_VERSION ){.   
102e0 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43 41 4e   rc = SQLITE_CAN
102f0 54 4f 50 45 4e 5f 42 4b 50 54 3b 0a 20 20 7d 0a  TOPEN_BKPT;.  }.
10300 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
10310 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74  ./*.** This is t
10320 68 65 20 76 61 6c 75 65 20 74 68 61 74 20 77 61  he value that wa
10330 6c 54 72 79 42 65 67 69 6e 52 65 61 64 20 72 65  lTryBeginRead re
10340 74 75 72 6e 73 20 77 68 65 6e 20 69 74 20 6e 65  turns when it ne
10350 65 64 73 20 74 6f 0a 2a 2a 20 62 65 20 72 65 74  eds to.** be ret
10360 72 69 65 64 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  ried..*/.#define
10370 20 57 41 4c 5f 52 45 54 52 59 20 20 28 2d 31 29   WAL_RETRY  (-1)
10380 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20  ../*.** Attempt 
10390 74 6f 20 73 74 61 72 74 20 61 20 72 65 61 64 20  to start a read 
103a0 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 20 54 68  transaction.  Th
103b0 69 73 20 6d 69 67 68 74 20 66 61 69 6c 20 64 75  is might fail du
103c0 65 20 74 6f 20 61 20 72 61 63 65 20 6f 72 0a 2a  e to a race or.*
103d0 2a 20 6f 74 68 65 72 20 74 72 61 6e 73 69 65 6e  * other transien
103e0 74 20 63 6f 6e 64 69 74 69 6f 6e 2e 20 20 57 68  t condition.  Wh
103f0 65 6e 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c  en that happens,
10400 20 69 74 20 72 65 74 75 72 6e 73 20 57 41 4c 5f   it returns WAL_
10410 52 45 54 52 59 20 74 6f 0a 2a 2a 20 69 6e 64 69  RETRY to.** indi
10420 63 61 74 65 20 74 6f 20 74 68 65 20 63 61 6c 6c  cate to the call
10430 65 72 20 74 68 61 74 20 69 74 20 69 73 20 73 61  er that it is sa
10440 66 65 20 74 6f 20 72 65 74 72 79 20 69 6d 6d 65  fe to retry imme
10450 64 69 61 74 65 6c 79 2e 0a 2a 2a 0a 2a 2a 20 4f  diately..**.** O
10460 6e 20 73 75 63 63 65 73 73 20 72 65 74 75 72 6e  n success return
10470 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 20 4f 6e 20   SQLITE_OK.  On 
10480 61 20 70 65 72 6d 61 6e 65 6e 74 20 66 61 69 6c  a permanent fail
10490 75 72 65 20 28 73 75 63 68 20 61 6e 0a 2a 2a 20  ure (such an.** 
104a0 49 2f 4f 20 65 72 72 6f 72 20 6f 72 20 61 6e 20  I/O error or an 
104b0 53 51 4c 49 54 45 5f 42 55 53 59 20 62 65 63 61  SQLITE_BUSY beca
104c0 75 73 65 20 61 6e 6f 74 68 65 72 20 70 72 6f 63  use another proc
104d0 65 73 73 20 69 73 20 72 75 6e 6e 69 6e 67 0a 2a  ess is running.*
104e0 2a 20 72 65 63 6f 76 65 72 79 29 20 72 65 74 75  * recovery) retu
104f0 72 6e 20 61 20 70 6f 73 69 74 69 76 65 20 65 72  rn a positive er
10500 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20  ror code..**.** 
10510 54 68 65 20 75 73 65 57 61 6c 20 70 61 72 61 6d  The useWal param
10520 65 74 65 72 20 69 73 20 74 72 75 65 20 74 6f 20  eter is true to 
10530 66 6f 72 63 65 20 74 68 65 20 75 73 65 20 6f 66  force the use of
10540 20 74 68 65 20 57 41 4c 20 61 6e 64 20 64 69 73   the WAL and dis
10550 61 62 6c 65 0a 2a 2a 20 74 68 65 20 63 61 73 65  able.** the case
10560 20 77 68 65 72 65 20 74 68 65 20 57 41 4c 20 69   where the WAL i
10570 73 20 62 79 70 61 73 73 65 64 20 62 65 63 61 75  s bypassed becau
10580 73 65 20 69 74 20 68 61 73 20 62 65 65 6e 20 63  se it has been c
10590 6f 6d 70 6c 65 74 65 6c 79 0a 2a 2a 20 63 68 65  ompletely.** che
105a0 63 6b 70 6f 69 6e 74 65 64 2e 20 20 49 66 20 75  ckpointed.  If u
105b0 73 65 57 61 6c 3d 3d 30 20 74 68 65 6e 20 74 68  seWal==0 then th
105c0 69 73 20 72 6f 75 74 69 6e 65 20 63 61 6c 6c 73  is routine calls
105d0 20 77 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72   walIndexReadHdr
105e0 28 29 20 0a 2a 2a 20 74 6f 20 6d 61 6b 65 20 61  () .** to make a
105f0 20 63 6f 70 79 20 6f 66 20 74 68 65 20 77 61 6c   copy of the wal
10600 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 6e  -index header in
10610 74 6f 20 70 57 61 6c 2d 3e 68 64 72 2e 20 20 49  to pWal->hdr.  I
10620 66 20 74 68 65 20 0a 2a 2a 20 77 61 6c 2d 69 6e  f the .** wal-in
10630 64 65 78 20 68 65 61 64 65 72 20 68 61 73 20 63  dex header has c
10640 68 61 6e 67 65 64 2c 20 2a 70 43 68 61 6e 67 65  hanged, *pChange
10650 64 20 69 73 20 73 65 74 20 74 6f 20 31 20 28 61  d is set to 1 (a
10660 73 20 61 6e 20 69 6e 64 69 63 61 74 69 6f 6e 20  s an indication 
10670 0a 2a 2a 20 74 6f 20 74 68 65 20 63 61 6c 6c 65  .** to the calle
10680 72 20 74 68 61 74 20 74 68 65 20 6c 6f 63 61 6c  r that the local
10690 20 70 61 67 65 74 20 63 61 63 68 65 20 69 73 20   paget cache is 
106a0 6f 62 73 6f 6c 65 74 65 20 61 6e 64 20 6e 65 65  obsolete and nee
106b0 64 73 20 74 6f 20 62 65 20 0a 2a 2a 20 66 6c 75  ds to be .** flu
106c0 73 68 65 64 2e 29 20 20 57 68 65 6e 20 75 73 65  shed.)  When use
106d0 57 61 6c 3d 3d 31 2c 20 74 68 65 20 77 61 6c 2d  Wal==1, the wal-
106e0 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20  index header is 
106f0 61 73 73 75 6d 65 64 20 74 6f 20 61 6c 72 65 61  assumed to alrea
10700 64 79 0a 2a 2a 20 62 65 20 6c 6f 61 64 65 64 20  dy.** be loaded 
10710 61 6e 64 20 74 68 65 20 70 43 68 61 6e 67 65 64  and the pChanged
10720 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 75 6e   parameter is un
10730 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  used..**.** The 
10740 63 61 6c 6c 65 72 20 6d 75 73 74 20 73 65 74 20  caller must set 
10750 74 68 65 20 63 6e 74 20 70 61 72 61 6d 65 74 65  the cnt paramete
10760 72 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 20  r to the number 
10770 6f 66 20 70 72 69 6f 72 20 63 61 6c 6c 73 20 74  of prior calls t
10780 6f 0a 2a 2a 20 74 68 69 73 20 72 6f 75 74 69 6e  o.** this routin
10790 65 20 64 75 72 69 6e 67 20 74 68 65 20 63 75 72  e during the cur
107a0 72 65 6e 74 20 72 65 61 64 20 61 74 74 65 6d 70  rent read attemp
107b0 74 20 74 68 61 74 20 72 65 74 75 72 6e 65 64 20  t that returned 
107c0 57 41 4c 5f 52 45 54 52 59 2e 0a 2a 2a 20 54 68  WAL_RETRY..** Th
107d0 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20  is routine will 
107e0 73 74 61 72 74 20 74 61 6b 69 6e 67 20 6d 6f 72  start taking mor
107f0 65 20 61 67 67 72 65 73 73 69 76 65 20 6d 65 61  e aggressive mea
10800 73 75 72 65 73 20 74 6f 20 63 6c 65 61 72 20 74  sures to clear t
10810 68 65 0a 2a 2a 20 72 61 63 65 20 63 6f 6e 64 69  he.** race condi
10820 74 69 6f 6e 73 20 61 66 74 65 72 20 6d 75 6c 74  tions after mult
10830 69 70 6c 65 20 57 41 4c 5f 52 45 54 52 59 20 72  iple WAL_RETRY r
10840 65 74 75 72 6e 73 2c 20 61 6e 64 20 61 66 74 65  eturns, and afte
10850 72 20 61 6e 20 65 78 63 65 73 73 69 76 65 0a 2a  r an excessive.*
10860 2a 20 6e 75 6d 62 65 72 20 6f 66 20 65 72 72 6f  * number of erro
10870 72 73 20 77 69 6c 6c 20 75 6c 74 69 6d 61 74 65  rs will ultimate
10880 6c 79 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  ly return SQLITE
10890 5f 50 52 4f 54 4f 43 4f 4c 2e 20 20 54 68 65 0a  _PROTOCOL.  The.
108a0 2a 2a 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43  ** SQLITE_PROTOC
108b0 4f 4c 20 72 65 74 75 72 6e 20 69 6e 64 69 63 61  OL return indica
108c0 74 65 73 20 74 68 61 74 20 73 6f 6d 65 20 6f 74  tes that some ot
108d0 68 65 72 20 70 72 6f 63 65 73 73 20 68 61 73 20  her process has 
108e0 67 6f 6e 65 20 72 6f 67 75 65 0a 2a 2a 20 61 6e  gone rogue.** an
108f0 64 20 69 73 20 6e 6f 74 20 68 6f 6e 6f 72 69 6e  d is not honorin
10900 67 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 70 72  g the locking pr
10910 6f 74 6f 63 6f 6c 2e 20 20 54 68 65 72 65 20 69  otocol.  There i
10920 73 20 61 20 76 61 6e 69 73 68 69 6e 67 6c 79 20  s a vanishingly 
10930 73 6d 61 6c 6c 0a 2a 2a 20 63 68 61 6e 63 65 20  small.** chance 
10940 74 68 61 74 20 53 51 4c 49 54 45 5f 50 52 4f 54  that SQLITE_PROT
10950 4f 43 4f 4c 20 63 6f 75 6c 64 20 62 65 20 72 65  OCOL could be re
10960 74 75 72 6e 65 64 20 62 65 63 61 75 73 65 20 6f  turned because o
10970 66 20 61 20 72 75 6e 20 6f 66 20 72 65 61 6c 6c  f a run of reall
10980 79 0a 2a 2a 20 62 61 64 20 6c 75 63 6b 20 77 68  y.** bad luck wh
10990 65 6e 20 74 68 65 72 65 20 69 73 20 6c 6f 74 73  en there is lots
109a0 20 6f 66 20 63 6f 6e 74 65 6e 74 69 6f 6e 20 66   of contention f
109b0 6f 72 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  or the wal-index
109c0 2c 20 62 75 74 20 74 68 61 74 0a 2a 2a 20 70 6f  , but that.** po
109d0 73 73 69 62 69 6c 69 74 79 20 69 73 20 73 6f 20  ssibility is so 
109e0 73 6d 61 6c 6c 20 74 68 61 74 20 69 74 20 63 61  small that it ca
109f0 6e 20 62 65 20 73 61 66 65 6c 79 20 6e 65 67 6c  n be safely negl
10a00 65 63 74 65 64 2c 20 77 65 20 62 65 6c 69 65 76  ected, we believ
10a10 65 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63  e..**.** On succ
10a20 65 73 73 2c 20 74 68 69 73 20 72 6f 75 74 69 6e  ess, this routin
10a30 65 20 6f 62 74 61 69 6e 73 20 61 20 72 65 61 64  e obtains a read
10a40 20 6c 6f 63 6b 20 6f 6e 20 0a 2a 2a 20 57 41 4c   lock on .** WAL
10a50 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d  _READ_LOCK(pWal-
10a60 3e 72 65 61 64 4c 6f 63 6b 29 2e 20 20 54 68 65  >readLock).  The
10a70 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20   pWal->readLock 
10a80 69 6e 74 65 67 65 72 20 69 73 0a 2a 2a 20 69 6e  integer is.** in
10a90 20 74 68 65 20 72 61 6e 67 65 20 30 20 3c 3d 20   the range 0 <= 
10aa0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3c  pWal->readLock <
10ab0 20 57 41 4c 5f 4e 52 45 41 44 45 52 2e 20 20 49   WAL_NREADER.  I
10ac0 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  f pWal->readLock
10ad0 3d 3d 28 2d 31 29 0a 2a 2a 20 74 68 61 74 20 6d  ==(-1).** that m
10ae0 65 61 6e 73 20 74 68 65 20 57 61 6c 20 64 6f 65  eans the Wal doe
10af0 73 20 6e 6f 74 20 68 6f 6c 64 20 61 6e 79 20 72  s not hold any r
10b00 65 61 64 20 6c 6f 63 6b 2e 20 20 54 68 65 20 72  ead lock.  The r
10b10 65 61 64 65 72 20 6d 75 73 74 20 6e 6f 74 0a 2a  eader must not.*
10b20 2a 20 61 63 63 65 73 73 20 61 6e 79 20 64 61 74  * access any dat
10b30 61 62 61 73 65 20 70 61 67 65 20 74 68 61 74 20  abase page that 
10b40 69 73 20 6d 6f 64 69 66 69 65 64 20 62 79 20 61  is modified by a
10b50 20 57 41 4c 20 66 72 61 6d 65 20 75 70 20 74 6f   WAL frame up to
10b60 20 61 6e 64 0a 2a 2a 20 69 6e 63 6c 75 64 69 6e   and.** includin
10b70 67 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 61  g frame number a
10b80 52 65 61 64 4d 61 72 6b 5b 70 57 61 6c 2d 3e 72  ReadMark[pWal->r
10b90 65 61 64 4c 6f 63 6b 5d 2e 20 20 54 68 65 20 72  eadLock].  The r
10ba0 65 61 64 65 72 20 77 69 6c 6c 0a 2a 2a 20 75 73  eader will.** us
10bb0 65 20 57 41 4c 20 66 72 61 6d 65 73 20 75 70 20  e WAL frames up 
10bc0 74 6f 20 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67  to and including
10bd0 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
10be0 6d 65 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64  me if pWal->read
10bf0 4c 6f 63 6b 3e 30 0a 2a 2a 20 4f 72 20 69 66 20  Lock>0.** Or if 
10c00 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d  pWal->readLock==
10c10 30 2c 20 74 68 65 6e 20 74 68 65 20 72 65 61 64  0, then the read
10c20 65 72 20 77 69 6c 6c 20 69 67 6e 6f 72 65 20 74  er will ignore t
10c30 68 65 20 57 41 4c 0a 2a 2a 20 63 6f 6d 70 6c 65  he WAL.** comple
10c40 74 65 6c 79 20 61 6e 64 20 67 65 74 20 61 6c 6c  tely and get all
10c50 20 63 6f 6e 74 65 6e 74 20 64 69 72 65 63 74 6c   content directl
10c60 79 20 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62  y from the datab
10c70 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 20 49 66 20  ase file..** If 
10c80 74 68 65 20 75 73 65 57 61 6c 20 70 61 72 61 6d  the useWal param
10c90 65 74 65 72 20 69 73 20 31 20 74 68 65 6e 20 74  eter is 1 then t
10ca0 68 65 20 57 41 4c 20 77 69 6c 6c 20 6e 65 76 65  he WAL will neve
10cb0 72 20 62 65 20 69 67 6e 6f 72 65 64 20 61 6e 64  r be ignored and
10cc0 0a 2a 2a 20 74 68 69 73 20 72 6f 75 74 69 6e 65  .** this routine
10cd0 20 77 69 6c 6c 20 61 6c 77 61 79 73 20 73 65 74   will always set
10ce0 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e   pWal->readLock>
10cf0 30 20 6f 6e 20 73 75 63 63 65 73 73 2e 0a 2a 2a  0 on success..**
10d00 20 57 68 65 6e 20 74 68 65 20 72 65 61 64 20 74   When the read t
10d10 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20 63 6f  ransaction is co
10d20 6d 70 6c 65 74 65 64 2c 20 74 68 65 20 63 61 6c  mpleted, the cal
10d30 6c 65 72 20 6d 75 73 74 20 72 65 6c 65 61 73 65  ler must release
10d40 20 74 68 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20   the.** lock on 
10d50 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57  WAL_READ_LOCK(pW
10d60 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 20 61 6e  al->readLock) an
10d70 64 20 73 65 74 20 70 57 61 6c 2d 3e 72 65 61 64  d set pWal->read
10d80 4c 6f 63 6b 20 74 6f 20 2d 31 2e 0a 2a 2a 0a 2a  Lock to -1..**.*
10d90 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 75  * This routine u
10da0 73 65 73 20 74 68 65 20 6e 42 61 63 6b 66 69 6c  ses the nBackfil
10db0 6c 20 61 6e 64 20 61 52 65 61 64 4d 61 72 6b 5b  l and aReadMark[
10dc0 5d 20 66 69 65 6c 64 73 20 6f 66 20 74 68 65 20  ] fields of the 
10dd0 68 65 61 64 65 72 0a 2a 2a 20 74 6f 20 73 65 6c  header.** to sel
10de0 65 63 74 20 61 20 70 61 72 74 69 63 75 6c 61 72  ect a particular
10df0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 29   WAL_READ_LOCK()
10e00 20 74 68 61 74 20 73 74 72 69 76 65 73 20 74 6f   that strives to
10e10 20 6c 65 74 20 74 68 65 0a 2a 2a 20 63 68 65 63   let the.** chec
10e20 6b 70 6f 69 6e 74 20 70 72 6f 63 65 73 73 20 64  kpoint process d
10e30 6f 20 61 73 20 6d 75 63 68 20 77 6f 72 6b 20 61  o as much work a
10e40 73 20 70 6f 73 73 69 62 6c 65 2e 20 20 54 68 69  s possible.  Thi
10e50 73 20 72 6f 75 74 69 6e 65 20 6d 69 67 68 74 0a  s routine might.
10e60 2a 2a 20 75 70 64 61 74 65 20 76 61 6c 75 65 73  ** update values
10e70 20 6f 66 20 74 68 65 20 61 52 65 61 64 4d 61 72   of the aReadMar
10e80 6b 5b 5d 20 61 72 72 61 79 20 69 6e 20 74 68 65  k[] array in the
10e90 20 68 65 61 64 65 72 2c 20 62 75 74 20 69 66 20   header, but if 
10ea0 69 74 20 64 6f 65 73 0a 2a 2a 20 73 6f 20 69 74  it does.** so it
10eb0 20 74 61 6b 65 73 20 63 61 72 65 20 74 6f 20 68   takes care to h
10ec0 6f 6c 64 20 61 6e 20 65 78 63 6c 75 73 69 76 65  old an exclusive
10ed0 20 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 63 6f 72   lock on the cor
10ee0 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20 57 41  responding.** WA
10ef0 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 29 20 77 68  L_READ_LOCK() wh
10f00 69 6c 65 20 63 68 61 6e 67 69 6e 67 20 76 61 6c  ile changing val
10f10 75 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ues..*/.static i
10f20 6e 74 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65  nt walTryBeginRe
10f30 61 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e  ad(Wal *pWal, in
10f40 74 20 2a 70 43 68 61 6e 67 65 64 2c 20 69 6e 74  t *pChanged, int
10f50 20 75 73 65 57 61 6c 2c 20 69 6e 74 20 63 6e 74   useWal, int cnt
10f60 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57 61  ){.  volatile Wa
10f70 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f  lCkptInfo *pInfo
10f80 3b 20 20 20 20 2f 2a 20 43 68 65 63 6b 70 6f 69  ;    /* Checkpoi
10f90 6e 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69  nt information i
10fa0 6e 20 77 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a 20  n wal-index */. 
10fb0 20 75 33 32 20 6d 78 52 65 61 64 4d 61 72 6b 3b   u32 mxReadMark;
10fc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10fd0 20 2f 2a 20 4c 61 72 67 65 73 74 20 61 52 65 61   /* Largest aRea
10fe0 64 4d 61 72 6b 5b 5d 20 76 61 6c 75 65 20 2a 2f  dMark[] value */
10ff0 0a 20 20 69 6e 74 20 6d 78 49 3b 20 20 20 20 20  .  int mxI;     
11000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11010 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6c     /* Index of l
11020 61 72 67 65 73 74 20 61 52 65 61 64 4d 61 72 6b  argest aReadMark
11030 5b 5d 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e  [] value */.  in
11040 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20  t i;            
11050 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
11060 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f   Loop counter */
11070 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
11080 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
11090 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
110a0 65 20 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28  e  */..  assert(
110b0 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3c   pWal->readLock<
110c0 30 20 29 3b 20 20 20 20 20 2f 2a 20 4e 6f 74 20  0 );     /* Not 
110d0 63 75 72 72 65 6e 74 6c 79 20 6c 6f 63 6b 65 64  currently locked
110e0 20 2a 2f 0a 0a 20 20 2f 2a 20 54 61 6b 65 20 73   */..  /* Take s
110f0 74 65 70 73 20 74 6f 20 61 76 6f 69 64 20 73 70  teps to avoid sp
11100 69 6e 6e 69 6e 67 20 66 6f 72 65 76 65 72 20 69  inning forever i
11110 66 20 74 68 65 72 65 20 69 73 20 61 20 70 72 6f  f there is a pro
11120 74 6f 63 6f 6c 20 65 72 72 6f 72 2e 20 2a 2f 0a  tocol error. */.
11130 20 20 69 66 28 20 63 6e 74 3e 35 20 29 7b 0a 20    if( cnt>5 ){. 
11140 20 20 20 69 66 28 20 63 6e 74 3e 31 30 30 20 29     if( cnt>100 )
11150 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 50   return SQLITE_P
11160 52 4f 54 4f 43 4f 4c 3b 0a 20 20 20 20 73 71 6c  ROTOCOL;.    sql
11170 69 74 65 33 4f 73 53 6c 65 65 70 28 70 57 61 6c  ite3OsSleep(pWal
11180 2d 3e 70 56 66 73 2c 20 31 29 3b 0a 20 20 7d 0a  ->pVfs, 1);.  }.
11190 0a 20 20 69 66 28 20 21 75 73 65 57 61 6c 20 29  .  if( !useWal )
111a0 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e  {.    rc = walIn
111b0 64 65 78 52 65 61 64 48 64 72 28 70 57 61 6c 2c  dexReadHdr(pWal,
111c0 20 70 43 68 61 6e 67 65 64 29 3b 0a 20 20 20 20   pChanged);.    
111d0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42  if( rc==SQLITE_B
111e0 55 53 59 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  USY ){.      /* 
111f0 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 74 20  If there is not 
11200 61 20 72 65 63 6f 76 65 72 79 20 72 75 6e 6e 69  a recovery runni
11210 6e 67 20 69 6e 20 61 6e 6f 74 68 65 72 20 74 68  ng in another th
11220 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 0a  read or process.
11230 20 20 20 20 20 20 2a 2a 20 74 68 65 6e 20 63 6f        ** then co
11240 6e 76 65 72 74 20 42 55 53 59 20 65 72 72 6f 72  nvert BUSY error
11250 73 20 74 6f 20 57 41 4c 5f 52 45 54 52 59 2e 20  s to WAL_RETRY. 
11260 20 49 66 20 72 65 63 6f 76 65 72 79 20 69 73 20   If recovery is 
11270 6b 6e 6f 77 6e 20 74 6f 0a 20 20 20 20 20 20 2a  known to.      *
11280 2a 20 62 65 20 72 75 6e 6e 69 6e 67 2c 20 63 6f  * be running, co
11290 6e 76 65 72 74 20 42 55 53 59 20 74 6f 20 42 55  nvert BUSY to BU
112a0 53 59 5f 52 45 43 4f 56 45 52 59 2e 20 20 54 68  SY_RECOVERY.  Th
112b0 65 72 65 20 69 73 20 61 20 72 61 63 65 20 68 65  ere is a race he
112c0 72 65 0a 20 20 20 20 20 20 2a 2a 20 77 68 69 63  re.      ** whic
112d0 68 20 6d 69 67 68 74 20 63 61 75 73 65 20 57 41  h might cause WA
112e0 4c 5f 52 45 54 52 59 20 74 6f 20 62 65 20 72 65  L_RETRY to be re
112f0 74 75 72 6e 65 64 20 65 76 65 6e 20 69 66 20 42  turned even if B
11300 55 53 59 5f 52 45 43 4f 56 45 52 59 0a 20 20 20  USY_RECOVERY.   
11310 20 20 20 2a 2a 20 77 6f 75 6c 64 20 62 65 20 74     ** would be t
11320 65 63 68 6e 69 63 61 6c 6c 79 20 63 6f 72 72 65  echnically corre
11330 63 74 2e 20 20 42 75 74 20 74 68 65 20 72 61 63  ct.  But the rac
11340 65 20 69 73 20 62 65 6e 69 67 6e 20 73 69 6e 63  e is benign sinc
11350 65 20 77 69 74 68 0a 20 20 20 20 20 20 2a 2a 20  e with.      ** 
11360 57 41 4c 5f 52 45 54 52 59 20 74 68 69 73 20 72  WAL_RETRY this r
11370 6f 75 74 69 6e 65 20 77 69 6c 6c 20 62 65 20 63  outine will be c
11380 61 6c 6c 65 64 20 61 67 61 69 6e 20 61 6e 64 20  alled again and 
11390 77 69 6c 6c 20 70 72 6f 62 61 62 6c 79 20 62 65  will probably be
113a0 0a 20 20 20 20 20 20 2a 2a 20 72 69 67 68 74 20  .      ** right 
113b0 6f 6e 20 74 68 65 20 73 65 63 6f 6e 64 20 69 74  on the second it
113c0 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20 20 20 2a  eration..      *
113d0 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c  /.      rc = wal
113e0 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  LockShared(pWal,
113f0 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43   WAL_RECOVER_LOC
11400 4b 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  K);.      if( rc
11410 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
11420 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b         walUnlock
11430 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c  Shared(pWal, WAL
11440 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 29 3b 0a  _RECOVER_LOCK);.
11450 20 20 20 20 20 20 20 20 72 63 20 3d 20 57 41 4c          rc = WAL
11460 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 65  _RETRY;.      }e
11470 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  lse if( rc==SQLI
11480 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20  TE_BUSY ){.     
11490 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42     rc = SQLITE_B
114a0 55 53 59 5f 52 45 43 4f 56 45 52 59 3b 0a 20 20  USY_RECOVERY;.  
114b0 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
114c0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
114d0 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  K ){.      retur
114e0 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  n rc;.    }.  }.
114f0 0a 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b  .  pInfo = walCk
11500 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20  ptInfo(pWal);.  
11510 69 66 28 20 21 75 73 65 57 61 6c 20 26 26 20 70  if( !useWal && p
11520 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3d  Info->nBackfill=
11530 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  =pWal->hdr.mxFra
11540 6d 65 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65  me ){.    /* The
11550 20 57 41 4c 20 68 61 73 20 62 65 65 6e 20 63 6f   WAL has been co
11560 6d 70 6c 65 74 65 6c 79 20 62 61 63 6b 66 69 6c  mpletely backfil
11570 6c 65 64 20 28 6f 72 20 69 74 20 69 73 20 65 6d  led (or it is em
11580 70 74 79 29 2e 0a 20 20 20 20 2a 2a 20 61 6e 64  pty)..    ** and
11590 20 63 61 6e 20 62 65 20 73 61 66 65 6c 79 20 69   can be safely i
115a0 67 6e 6f 72 65 64 2e 0a 20 20 20 20 2a 2f 0a 20  gnored..    */. 
115b0 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53     rc = walLockS
115c0 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
115d0 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20  READ_LOCK(0));. 
115e0 20 20 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 42     sqlite3OsShmB
115f0 61 72 72 69 65 72 28 70 57 61 6c 2d 3e 70 44 62  arrier(pWal->pDb
11600 46 64 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d  Fd);.    if( rc=
11610 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
11620 20 20 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 28      if( memcmp((
11630 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48  void *)walIndexH
11640 64 72 28 70 57 61 6c 29 2c 20 26 70 57 61 6c 2d  dr(pWal), &pWal-
11650 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c  >hdr, sizeof(Wal
11660 49 6e 64 65 78 48 64 72 29 29 20 29 7b 0a 20 20  IndexHdr)) ){.  
11670 20 20 20 20 20 20 2f 2a 20 49 74 20 69 73 20 6e        /* It is n
11680 6f 74 20 73 61 66 65 20 74 6f 20 61 6c 6c 6f 77  ot safe to allow
11690 20 74 68 65 20 72 65 61 64 65 72 20 74 6f 20 63   the reader to c
116a0 6f 6e 74 69 6e 75 65 20 68 65 72 65 20 69 66 20  ontinue here if 
116b0 66 72 61 6d 65 73 0a 20 20 20 20 20 20 20 20 2a  frames.        *
116c0 2a 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20  * may have been 
116d0 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20  appended to the 
116e0 6c 6f 67 20 62 65 66 6f 72 65 20 52 45 41 44 5f  log before READ_
116f0 4c 4f 43 4b 28 30 29 20 77 61 73 20 6f 62 74 61  LOCK(0) was obta
11700 69 6e 65 64 2e 0a 20 20 20 20 20 20 20 20 2a 2a  ined..        **
11710 20 57 68 65 6e 20 68 6f 6c 64 69 6e 67 20 52 45   When holding RE
11720 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 74 68 65 20  AD_LOCK(0), the 
11730 72 65 61 64 65 72 20 69 67 6e 6f 72 65 73 20 74  reader ignores t
11740 68 65 20 65 6e 74 69 72 65 20 6c 6f 67 20 66 69  he entire log fi
11750 6c 65 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20 77  le,.        ** w
11760 68 69 63 68 20 69 6d 70 6c 69 65 73 20 74 68 61  hich implies tha
11770 74 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  t the database f
11780 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 61 20 74  ile contains a t
11790 72 75 73 74 77 6f 72 74 68 79 0a 20 20 20 20 20  rustworthy.     
117a0 20 20 20 2a 2a 20 73 6e 61 70 73 68 6f 54 2e 20     ** snapshoT. 
117b0 53 69 6e 63 65 20 68 6f 6c 64 69 6e 67 20 52 45  Since holding RE
117c0 41 44 5f 4c 4f 43 4b 28 30 29 20 70 72 65 76 65  AD_LOCK(0) preve
117d0 6e 74 73 20 61 20 63 68 65 63 6b 70 6f 69 6e 74  nts a checkpoint
117e0 20 66 72 6f 6d 0a 20 20 20 20 20 20 20 20 2a 2a   from.        **
117f0 20 68 61 70 70 65 6e 69 6e 67 2c 20 74 68 69 73   happening, this
11800 20 69 73 20 75 73 75 61 6c 6c 79 20 63 6f 72 72   is usually corr
11810 65 63 74 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a  ect..        **.
11820 20 20 20 20 20 20 20 20 2a 2a 20 48 6f 77 65 76          ** Howev
11830 65 72 2c 20 69 66 20 66 72 61 6d 65 73 20 68 61  er, if frames ha
11840 76 65 20 62 65 65 6e 20 61 70 70 65 6e 64 65 64  ve been appended
11850 20 74 6f 20 74 68 65 20 6c 6f 67 20 28 6f 72 20   to the log (or 
11860 69 66 20 74 68 65 20 6c 6f 67 20 0a 20 20 20 20  if the log .    
11870 20 20 20 20 2a 2a 20 69 73 20 77 72 61 70 70 65      ** is wrappe
11880 64 20 61 6e 64 20 77 72 69 74 74 65 6e 20 66 6f  d and written fo
11890 72 20 74 68 61 74 20 6d 61 74 74 65 72 29 20 62  r that matter) b
118a0 65 66 6f 72 65 20 74 68 65 20 52 45 41 44 5f 4c  efore the READ_L
118b0 4f 43 4b 28 30 29 0a 20 20 20 20 20 20 20 20 2a  OCK(0).        *
118c0 2a 20 69 73 20 6f 62 74 61 69 6e 65 64 2c 20 74  * is obtained, t
118d0 68 61 74 20 69 73 20 6e 6f 74 20 6e 65 63 65 73  hat is not neces
118e0 73 61 72 69 6c 79 20 74 72 75 65 2e 20 41 20 63  sarily true. A c
118f0 68 65 63 6b 70 6f 69 6e 74 65 72 20 6d 61 79 0a  heckpointer may.
11900 20 20 20 20 20 20 20 20 2a 2a 20 68 61 76 65 20          ** have 
11910 73 74 61 72 74 65 64 20 74 6f 20 62 61 63 6b 66  started to backf
11920 69 6c 6c 20 74 68 65 20 61 70 70 65 6e 64 65 64  ill the appended
11930 20 66 72 61 6d 65 73 20 62 75 74 20 63 72 61 73   frames but cras
11940 68 65 64 20 62 65 66 6f 72 65 0a 20 20 20 20 20  hed before.     
11950 20 20 20 2a 2a 20 69 74 20 66 69 6e 69 73 68 65     ** it finishe
11960 64 2e 20 4c 65 61 76 69 6e 67 20 61 20 63 6f 72  d. Leaving a cor
11970 72 75 70 74 20 69 6d 61 67 65 20 69 6e 20 74 68  rupt image in th
11980 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e  e database file.
11990 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  .        */.    
119a0 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61      walUnlockSha
119b0 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
119c0 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20  AD_LOCK(0));.   
119d0 20 20 20 20 20 72 65 74 75 72 6e 20 57 41 4c 5f       return WAL_
119e0 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 0a 20  RETRY;.      }. 
119f0 20 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c       pWal->readL
11a00 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 72  ock = 0;.      r
11a10 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
11a20 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72  .    }else if( r
11a30 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29  c!=SQLITE_BUSY )
11a40 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72  {.      return r
11a50 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  c;.    }.  }..  
11a60 2f 2a 20 49 66 20 77 65 20 67 65 74 20 74 68 69  /* If we get thi
11a70 73 20 66 61 72 2c 20 69 74 20 6d 65 61 6e 73 20  s far, it means 
11a80 74 68 61 74 20 74 68 65 20 72 65 61 64 65 72 20  that the reader 
11a90 77 69 6c 6c 20 77 61 6e 74 20 74 6f 20 75 73 65  will want to use
11aa0 0a 20 20 2a 2a 20 74 68 65 20 57 41 4c 20 74 6f  .  ** the WAL to
11ab0 20 67 65 74 20 61 74 20 63 6f 6e 74 65 6e 74 20   get at content 
11ac0 66 72 6f 6d 20 72 65 63 65 6e 74 20 63 6f 6d 6d  from recent comm
11ad0 69 74 73 2e 20 20 54 68 65 20 6a 6f 62 20 6e 6f  its.  The job no
11ae0 77 20 69 73 0a 20 20 2a 2a 20 74 6f 20 73 65 6c  w is.  ** to sel
11af0 65 63 74 20 6f 6e 65 20 6f 66 20 74 68 65 20 61  ect one of the a
11b00 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e 74 72 69  ReadMark[] entri
11b10 65 73 20 74 68 61 74 20 69 73 20 63 6c 6f 73 65  es that is close
11b20 73 74 20 74 6f 0a 20 20 2a 2a 20 62 75 74 20 6e  st to.  ** but n
11b30 6f 74 20 65 78 63 65 65 64 69 6e 67 20 70 57 61  ot exceeding pWa
11b40 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 61  l->hdr.mxFrame a
11b50 6e 64 20 6c 6f 63 6b 20 74 68 61 74 20 65 6e 74  nd lock that ent
11b60 72 79 2e 0a 20 20 2a 2f 0a 20 20 6d 78 52 65 61  ry..  */.  mxRea
11b70 64 4d 61 72 6b 20 3d 20 30 3b 0a 20 20 6d 78 49  dMark = 0;.  mxI
11b80 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 31 3b   = 0;.  for(i=1;
11b90 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
11ba0 69 2b 2b 29 7b 0a 20 20 20 20 75 33 32 20 74 68  i++){.    u32 th
11bb0 69 73 4d 61 72 6b 20 3d 20 70 49 6e 66 6f 2d 3e  isMark = pInfo->
11bc0 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20 20  aReadMark[i];.  
11bd0 20 20 69 66 28 20 6d 78 52 65 61 64 4d 61 72 6b    if( mxReadMark
11be0 3c 3d 74 68 69 73 4d 61 72 6b 20 26 26 20 74 68  <=thisMark && th
11bf0 69 73 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e 68 64  isMark<=pWal->hd
11c00 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20  r.mxFrame ){.   
11c10 20 20 20 61 73 73 65 72 74 28 20 74 68 69 73 4d     assert( thisM
11c20 61 72 6b 21 3d 52 45 41 44 4d 41 52 4b 5f 4e 4f  ark!=READMARK_NO
11c30 54 5f 55 53 45 44 20 29 3b 0a 20 20 20 20 20 20  T_USED );.      
11c40 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20 74 68 69  mxReadMark = thi
11c50 73 4d 61 72 6b 3b 0a 20 20 20 20 20 20 6d 78 49  sMark;.      mxI
11c60 20 3d 20 69 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   = i;.    }.  }.
11c70 20 20 69 66 28 20 6d 78 49 3d 3d 30 20 29 7b 0a    if( mxI==0 ){.
11c80 20 20 20 20 2f 2a 20 49 66 20 77 65 20 67 65 74      /* If we get
11c90 20 68 65 72 65 2c 20 69 74 20 6d 65 61 6e 73 20   here, it means 
11ca0 74 68 61 74 20 61 6c 6c 20 6f 66 20 74 68 65 20  that all of the 
11cb0 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e 74 72  aReadMark[] entr
11cc0 69 65 73 20 62 65 74 77 65 65 6e 0a 20 20 20 20  ies between.    
11cd0 2a 2a 20 31 20 61 6e 64 20 57 41 4c 5f 4e 52 45  ** 1 and WAL_NRE
11ce0 41 44 45 52 2d 31 20 61 72 65 20 7a 65 72 6f 2e  ADER-1 are zero.
11cf0 20 20 54 72 79 20 74 6f 20 69 6e 69 74 69 61 6c    Try to initial
11d00 69 7a 65 20 61 52 65 61 64 4d 61 72 6b 5b 31 5d  ize aReadMark[1]
11d10 20 74 6f 0a 20 20 20 20 2a 2a 20 62 65 20 6d 78   to.    ** be mx
11d20 46 72 61 6d 65 2c 20 74 68 65 6e 20 72 65 74 72  Frame, then retr
11d30 79 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 72 63  y..    */.    rc
11d40 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73   = walLockExclus
11d50 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  ive(pWal, WAL_RE
11d60 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 31 29 3b 0a  AD_LOCK(1), 1);.
11d70 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
11d80 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70  TE_OK ){.      p
11d90 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b  Info->aReadMark[
11da0 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  1] = pWal->hdr.m
11db0 78 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 77 61  xFrame;.      wa
11dc0 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65  lUnlockExclusive
11dd0 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f  (pWal, WAL_READ_
11de0 4c 4f 43 4b 28 31 29 2c 20 31 29 3b 0a 20 20 20  LOCK(1), 1);.   
11df0 20 20 20 72 63 20 3d 20 57 41 4c 5f 52 45 54 52     rc = WAL_RETR
11e00 59 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  Y;.    }else if(
11e10 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc==SQLITE_BUSY
11e20 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 57   ){.      rc = W
11e30 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 7d 0a  AL_RETRY;.    }.
11e40 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
11e50 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66 28 20   }else{.    if( 
11e60 6d 78 52 65 61 64 4d 61 72 6b 20 3c 20 70 57 61  mxReadMark < pWa
11e70 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29  l->hdr.mxFrame )
11e80 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b  {.      for(i=1;
11e90 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
11ea0 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 72 63  i++){.        rc
11eb0 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73   = walLockExclus
11ec0 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  ive(pWal, WAL_RE
11ed0 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a  AD_LOCK(i), 1);.
11ee0 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d          if( rc==
11ef0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
11f00 20 20 20 20 20 20 20 6d 78 52 65 61 64 4d 61 72         mxReadMar
11f10 6b 20 3d 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64  k = pInfo->aRead
11f20 4d 61 72 6b 5b 69 5d 20 3d 20 70 57 61 6c 2d 3e  Mark[i] = pWal->
11f30 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20  hdr.mxFrame;.   
11f40 20 20 20 20 20 20 20 6d 78 49 20 3d 20 69 3b 0a         mxI = i;.
11f50 20 20 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c            walUnl
11f60 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
11f70 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  l, WAL_READ_LOCK
11f80 28 69 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 20  (i), 1);.       
11f90 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
11fa0 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 21 3d    }else if( rc!=
11fb0 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20  SQLITE_BUSY ){. 
11fc0 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
11fd0 72 63 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  rc;.        }.  
11fe0 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20      }.    }..   
11ff0 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61   rc = walLockSha
12000 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
12010 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b 0a 20  AD_LOCK(mxI));. 
12020 20 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20     if( rc ){.   
12030 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d 53 51     return rc==SQ
12040 4c 49 54 45 5f 42 55 53 59 20 3f 20 57 41 4c 5f  LITE_BUSY ? WAL_
12050 52 45 54 52 59 20 3a 20 72 63 3b 0a 20 20 20 20  RETRY : rc;.    
12060 7d 0a 20 20 20 20 2f 2a 20 4e 6f 77 20 74 68 61  }.    /* Now tha
12070 74 20 74 68 65 20 72 65 61 64 2d 6c 6f 63 6b 20  t the read-lock 
12080 68 61 73 20 62 65 65 6e 20 6f 62 74 61 69 6e 65  has been obtaine
12090 64 2c 20 63 68 65 63 6b 20 74 68 61 74 20 6e 65  d, check that ne
120a0 69 74 68 65 72 20 74 68 65 0a 20 20 20 20 2a 2a  ither the.    **
120b0 20 76 61 6c 75 65 20 69 6e 20 74 68 65 20 61 52   value in the aR
120c0 65 61 64 4d 61 72 6b 5b 5d 20 61 72 72 61 79 20  eadMark[] array 
120d0 6f 72 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  or the contents 
120e0 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
120f0 0a 20 20 20 20 2a 2a 20 68 65 61 64 65 72 20 68  .    ** header h
12100 61 76 65 20 63 68 61 6e 67 65 64 2e 0a 20 20 20  ave changed..   
12110 20 2a 2a 0a 20 20 20 20 2a 2a 20 49 74 20 69 73   **.    ** It is
12120 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20 63 68   necessary to ch
12130 65 63 6b 20 74 68 61 74 20 74 68 65 20 77 61 6c  eck that the wal
12140 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 64 69  -index header di
12150 64 20 6e 6f 74 20 63 68 61 6e 67 65 0a 20 20 20  d not change.   
12160 20 2a 2a 20 62 65 74 77 65 65 6e 20 74 68 65 20   ** between the 
12170 74 69 6d 65 20 69 74 20 77 61 73 20 72 65 61 64  time it was read
12180 20 61 6e 64 20 77 68 65 6e 20 74 68 65 20 73 68   and when the sh
12190 61 72 65 64 2d 6c 6f 63 6b 20 77 61 73 20 6f 62  ared-lock was ob
121a0 74 61 69 6e 65 64 0a 20 20 20 20 2a 2a 20 6f 6e  tained.    ** on
121b0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d   WAL_READ_LOCK(m
121c0 78 49 29 20 77 61 73 20 6f 62 74 61 69 6e 65 64  xI) was obtained
121d0 20 74 6f 20 61 63 63 6f 75 6e 74 20 66 6f 72 20   to account for 
121e0 74 68 65 20 70 6f 73 73 69 62 69 6c 69 74 79 0a  the possibility.
121f0 20 20 20 20 2a 2a 20 74 68 61 74 20 74 68 65 20      ** that the 
12200 6c 6f 67 20 66 69 6c 65 20 6d 61 79 20 68 61 76  log file may hav
12210 65 20 62 65 65 6e 20 77 72 61 70 70 65 64 20 62  e been wrapped b
12220 79 20 61 20 77 72 69 74 65 72 2c 20 6f 72 20 74  y a writer, or t
12230 68 61 74 20 66 72 61 6d 65 73 0a 20 20 20 20 2a  hat frames.    *
12240 2a 20 74 68 61 74 20 6f 63 63 75 72 20 6c 61 74  * that occur lat
12250 65 72 20 69 6e 20 74 68 65 20 6c 6f 67 20 74 68  er in the log th
12260 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  an pWal->hdr.mxF
12270 72 61 6d 65 20 6d 61 79 20 68 61 76 65 20 62 65  rame may have be
12280 65 6e 0a 20 20 20 20 2a 2a 20 63 6f 70 69 65 64  en.    ** copied
12290 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
122a0 73 65 20 62 79 20 61 20 63 68 65 63 6b 70 6f 69  se by a checkpoi
122b0 6e 74 65 72 2e 20 49 66 20 65 69 74 68 65 72 20  nter. If either 
122c0 6f 66 20 74 68 65 73 65 20 74 68 69 6e 67 73 0a  of these things.
122d0 20 20 20 20 2a 2a 20 68 61 70 70 65 6e 65 64 2c      ** happened,
122e0 20 74 68 65 6e 20 72 65 61 64 69 6e 67 20 74 68   then reading th
122f0 65 20 64 61 74 61 62 61 73 65 20 77 69 74 68 20  e database with 
12300 74 68 65 20 63 75 72 72 65 6e 74 20 76 61 6c 75  the current valu
12310 65 20 6f 66 0a 20 20 20 20 2a 2a 20 70 57 61 6c  e of.    ** pWal
12320 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 72 69  ->hdr.mxFrame ri
12330 73 6b 73 20 72 65 61 64 69 6e 67 20 61 20 63 6f  sks reading a co
12340 72 72 75 70 74 65 64 20 73 6e 61 70 73 68 6f 74  rrupted snapshot
12350 2e 20 53 6f 2c 20 72 65 74 72 79 0a 20 20 20 20  . So, retry.    
12360 2a 2a 20 69 6e 73 74 65 61 64 2e 0a 20 20 20 20  ** instead..    
12370 2a 2a 0a 20 20 20 20 2a 2a 20 54 68 69 73 20 64  **.    ** This d
12380 6f 65 73 20 6e 6f 74 20 67 75 61 72 61 6e 74 65  oes not guarante
12390 65 20 74 68 61 74 20 74 68 65 20 63 6f 70 79 20  e that the copy 
123a0 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
123b0 20 68 65 61 64 65 72 20 69 73 20 75 70 20 74 6f   header is up to
123c0 0a 20 20 20 20 2a 2a 20 64 61 74 65 20 62 65 66  .    ** date bef
123d0 6f 72 65 20 70 72 6f 63 65 65 64 69 6e 67 2e 20  ore proceeding. 
123e0 54 68 61 74 20 77 6f 75 6c 64 20 6e 6f 74 20 62  That would not b
123f0 65 20 70 6f 73 73 69 62 6c 65 20 77 69 74 68 6f  e possible witho
12400 75 74 20 73 6f 6d 65 68 6f 77 0a 20 20 20 20 2a  ut somehow.    *
12410 2a 20 62 6c 6f 63 6b 69 6e 67 20 77 72 69 74 65  * blocking write
12420 72 73 2e 20 49 74 20 6f 6e 6c 79 20 67 75 61 72  rs. It only guar
12430 61 6e 74 65 65 73 20 74 68 61 74 20 61 20 64 61  antees that a da
12440 6e 67 65 72 6f 75 73 20 63 68 65 63 6b 70 6f 69  ngerous checkpoi
12450 6e 74 20 6f 72 20 0a 20 20 20 20 2a 2a 20 6c 6f  nt or .    ** lo
12460 67 2d 77 72 61 70 20 28 65 69 74 68 65 72 20 6f  g-wrap (either o
12470 66 20 77 68 69 63 68 20 77 6f 75 6c 64 20 72 65  f which would re
12480 71 75 69 72 65 20 61 6e 20 65 78 63 6c 75 73 69  quire an exclusi
12490 76 65 20 6c 6f 63 6b 20 6f 6e 0a 20 20 20 20 2a  ve lock on.    *
124a0 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  * WAL_READ_LOCK(
124b0 6d 78 49 29 29 20 68 61 73 20 6e 6f 74 20 6f 63  mxI)) has not oc
124c0 63 75 72 72 65 64 20 73 69 6e 63 65 20 74 68 65  curred since the
124d0 20 73 6e 61 70 73 68 6f 74 20 77 61 73 20 76 61   snapshot was va
124e0 6c 69 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  lid..    */.    
124f0 73 71 6c 69 74 65 33 4f 73 53 68 6d 42 61 72 72  sqlite3OsShmBarr
12500 69 65 72 28 70 57 61 6c 2d 3e 70 44 62 46 64 29  ier(pWal->pDbFd)
12510 3b 0a 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d  ;.    if( pInfo-
12520 3e 61 52 65 61 64 4d 61 72 6b 5b 6d 78 49 5d 21  >aReadMark[mxI]!
12530 3d 6d 78 52 65 61 64 4d 61 72 6b 0a 20 20 20 20  =mxReadMark.    
12540 20 7c 7c 20 6d 65 6d 63 6d 70 28 28 76 6f 69 64   || memcmp((void
12550 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70   *)walIndexHdr(p
12560 57 61 6c 29 2c 20 26 70 57 61 6c 2d 3e 68 64 72  Wal), &pWal->hdr
12570 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65  , sizeof(WalInde
12580 78 48 64 72 29 29 0a 20 20 20 20 29 7b 0a 20 20  xHdr)).    ){.  
12590 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61      walUnlockSha
125a0 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
125b0 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b 0a 20  AD_LOCK(mxI));. 
125c0 20 20 20 20 20 72 65 74 75 72 6e 20 57 41 4c 5f       return WAL_
125d0 52 45 54 52 59 3b 0a 20 20 20 20 7d 65 6c 73 65  RETRY;.    }else
125e0 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  {.      assert( 
125f0 6d 78 52 65 61 64 4d 61 72 6b 3c 3d 70 57 61 6c  mxReadMark<=pWal
12600 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b  ->hdr.mxFrame );
12610 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 72 65 61  .      pWal->rea
12620 64 4c 6f 63 6b 20 3d 20 6d 78 49 3b 0a 20 20 20  dLock = mxI;.   
12630 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
12640 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42 65 67  rc;.}../*.** Beg
12650 69 6e 20 61 20 72 65 61 64 20 74 72 61 6e 73 61  in a read transa
12660 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20 64 61 74  ction on the dat
12670 61 62 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  abase..**.** Thi
12680 73 20 72 6f 75 74 69 6e 65 20 75 73 65 64 20 74  s routine used t
12690 6f 20 62 65 20 63 61 6c 6c 65 64 20 73 71 6c 69  o be called sqli
126a0 74 65 33 4f 70 65 6e 53 6e 61 70 73 68 6f 74 28  te3OpenSnapshot(
126b0 29 20 61 6e 64 20 77 69 74 68 20 67 6f 6f 64 20  ) and with good 
126c0 72 65 61 73 6f 6e 3a 0a 2a 2a 20 69 74 20 74 61  reason:.** it ta
126d0 6b 65 73 20 61 20 73 6e 61 70 73 68 6f 74 20 6f  kes a snapshot o
126e0 66 20 74 68 65 20 73 74 61 74 65 20 6f 66 20 74  f the state of t
126f0 68 65 20 57 41 4c 20 61 6e 64 20 77 61 6c 2d 69  he WAL and wal-i
12700 6e 64 65 78 20 66 6f 72 20 74 68 65 20 63 75 72  ndex for the cur
12710 72 65 6e 74 0a 2a 2a 20 69 6e 73 74 61 6e 74 20  rent.** instant 
12720 69 6e 20 74 69 6d 65 2e 20 20 54 68 65 20 63 75  in time.  The cu
12730 72 72 65 6e 74 20 74 68 72 65 61 64 20 77 69 6c  rrent thread wil
12740 6c 20 63 6f 6e 74 69 6e 75 65 20 74 6f 20 75 73  l continue to us
12750 65 20 74 68 69 73 20 73 6e 61 70 73 68 6f 74 2e  e this snapshot.
12760 0a 2a 2a 20 4f 74 68 65 72 20 74 68 72 65 61 64  .** Other thread
12770 73 20 6d 69 67 68 74 20 61 70 70 65 6e 64 20 6e  s might append n
12780 65 77 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74 68  ew content to th
12790 65 20 57 41 4c 20 61 6e 64 20 77 61 6c 2d 69 6e  e WAL and wal-in
127a0 64 65 78 20 62 75 74 0a 2a 2a 20 74 68 61 74 20  dex but.** that 
127b0 65 78 74 72 61 20 63 6f 6e 74 65 6e 74 20 69 73  extra content is
127c0 20 69 67 6e 6f 72 65 64 20 62 79 20 74 68 65 20   ignored by the 
127d0 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 2e 0a  current thread..
127e0 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 64 61 74  **.** If the dat
127f0 61 62 61 73 65 20 63 6f 6e 74 65 6e 74 73 20 68  abase contents h
12800 61 76 65 20 63 68 61 6e 67 65 73 20 73 69 6e 63  ave changes sinc
12810 65 20 74 68 65 20 70 72 65 76 69 6f 75 73 20 72  e the previous r
12820 65 61 64 0a 2a 2a 20 74 72 61 6e 73 61 63 74 69  ead.** transacti
12830 6f 6e 2c 20 74 68 65 6e 20 2a 70 43 68 61 6e 67  on, then *pChang
12840 65 64 20 69 73 20 73 65 74 20 74 6f 20 31 20 62  ed is set to 1 b
12850 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
12860 20 20 54 68 65 0a 2a 2a 20 50 61 67 65 72 20 6c    The.** Pager l
12870 61 79 65 72 20 77 69 6c 6c 20 75 73 65 20 74 68  ayer will use th
12880 69 73 20 74 6f 20 6b 6e 6f 77 20 74 68 61 74 20  is to know that 
12890 69 73 20 63 61 63 68 65 20 69 73 20 73 74 61 6c  is cache is stal
128a0 65 20 61 6e 64 0a 2a 2a 20 6e 65 65 64 73 20 74  e and.** needs t
128b0 6f 20 62 65 20 66 6c 75 73 68 65 64 2e 0a 2a 2f  o be flushed..*/
128c0 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 42  .int sqlite3WalB
128d0 65 67 69 6e 52 65 61 64 54 72 61 6e 73 61 63 74  eginReadTransact
128e0 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69  ion(Wal *pWal, i
128f0 6e 74 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a 20  nt *pChanged){. 
12900 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
12910 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12920 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
12930 2a 2f 0a 20 20 69 6e 74 20 63 6e 74 20 3d 20 30  */.  int cnt = 0
12940 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
12950 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
12960 66 20 54 72 79 42 65 67 69 6e 52 65 61 64 20 61  f TryBeginRead a
12970 74 74 65 6d 70 74 73 20 2a 2f 0a 0a 20 20 64 6f  ttempts */..  do
12980 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 54 72  {.    rc = walTr
12990 79 42 65 67 69 6e 52 65 61 64 28 70 57 61 6c 2c  yBeginRead(pWal,
129a0 20 70 43 68 61 6e 67 65 64 2c 20 30 2c 20 2b 2b   pChanged, 0, ++
129b0 63 6e 74 29 3b 0a 20 20 7d 77 68 69 6c 65 28 20  cnt);.  }while( 
129c0 72 63 3d 3d 57 41 4c 5f 52 45 54 52 59 20 29 3b  rc==WAL_RETRY );
129d0 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
129e0 0a 2f 2a 0a 2a 2a 20 46 69 6e 69 73 68 20 77 69  ./*.** Finish wi
129f0 74 68 20 61 20 72 65 61 64 20 74 72 61 6e 73 61  th a read transa
12a00 63 74 69 6f 6e 2e 20 20 41 6c 6c 20 74 68 69 73  ction.  All this
12a10 20 64 6f 65 73 20 69 73 20 72 65 6c 65 61 73 65   does is release
12a20 20 74 68 65 0a 2a 2a 20 72 65 61 64 2d 6c 6f 63   the.** read-loc
12a30 6b 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74  k..*/.void sqlit
12a40 65 33 57 61 6c 45 6e 64 52 65 61 64 54 72 61 6e  e3WalEndReadTran
12a50 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61  saction(Wal *pWa
12a60 6c 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  l){.  if( pWal->
12a70 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 7b 0a 20  readLock>=0 ){. 
12a80 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72     walUnlockShar
12a90 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ed(pWal, WAL_REA
12aa0 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61  D_LOCK(pWal->rea
12ab0 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70 57 61  dLock));.    pWa
12ac0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31  l->readLock = -1
12ad0 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  ;.  }.}../*.** R
12ae0 65 61 64 20 61 20 70 61 67 65 20 66 72 6f 6d 20  ead a page from 
12af0 74 68 65 20 57 41 4c 2c 20 69 66 20 69 74 20 69  the WAL, if it i
12b00 73 20 70 72 65 73 65 6e 74 20 69 6e 20 74 68 65  s present in the
12b10 20 57 41 4c 20 61 6e 64 20 69 66 20 74 68 65 20   WAL and if the 
12b20 0a 2a 2a 20 63 75 72 72 65 6e 74 20 72 65 61 64  .** current read
12b30 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20   transaction is 
12b40 63 6f 6e 66 69 67 75 72 65 64 20 74 6f 20 75 73  configured to us
12b50 65 20 74 68 65 20 57 41 4c 2e 20 20 0a 2a 2a 0a  e the WAL.  .**.
12b60 2a 2a 20 54 68 65 20 2a 70 49 6e 57 61 6c 20 69  ** The *pInWal i
12b70 73 20 73 65 74 20 74 6f 20 31 20 69 66 20 74 68  s set to 1 if th
12b80 65 20 72 65 71 75 65 73 74 65 64 20 70 61 67 65  e requested page
12b90 20 69 73 20 69 6e 20 74 68 65 20 57 41 4c 20 61   is in the WAL a
12ba0 6e 64 0a 2a 2a 20 68 61 73 20 62 65 65 6e 20 6c  nd.** has been l
12bb0 6f 61 64 65 64 2e 20 20 4f 72 20 2a 70 49 6e 57  oaded.  Or *pInW
12bc0 61 6c 20 69 73 20 73 65 74 20 74 6f 20 30 20 69  al is set to 0 i
12bd0 66 20 74 68 65 20 70 61 67 65 20 77 61 73 20 6e  f the page was n
12be0 6f 74 20 69 6e 20 0a 2a 2a 20 74 68 65 20 57 41  ot in .** the WA
12bf0 4c 20 61 6e 64 20 6e 65 65 64 73 20 74 6f 20 62  L and needs to b
12c00 65 20 72 65 61 64 20 6f 75 74 20 6f 66 20 74 68  e read out of th
12c10 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2f 0a 69  e database..*/.i
12c20 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 52 65 61  nt sqlite3WalRea
12c30 64 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20  d(.  Wal *pWal, 
12c40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12c50 20 20 20 20 20 2f 2a 20 57 41 4c 20 68 61 6e 64       /* WAL hand
12c60 6c 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e  le */.  Pgno pgn
12c70 6f 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o,              
12c80 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
12c90 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  ase page number 
12ca0 74 6f 20 72 65 61 64 20 64 61 74 61 20 66 6f 72  to read data for
12cb0 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 49 6e 57 61   */.  int *pInWa
12cc0 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
12cd0 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 72        /* OUT: Tr
12ce0 75 65 20 69 66 20 64 61 74 61 20 69 73 20 72 65  ue if data is re
12cf0 61 64 20 66 72 6f 6d 20 57 41 4c 20 2a 2f 0a 20  ad from WAL */. 
12d00 20 69 6e 74 20 6e 4f 75 74 2c 20 20 20 20 20 20   int nOut,      
12d10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12d20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62 75 66 66   /* Size of buff
12d30 65 72 20 70 4f 75 74 20 69 6e 20 62 79 74 65 73  er pOut in bytes
12d40 20 2a 2f 0a 20 20 75 38 20 2a 70 4f 75 74 20 20   */.  u8 *pOut  
12d50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12d60 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
12d70 74 6f 20 77 72 69 74 65 20 70 61 67 65 20 64 61  to write page da
12d80 74 61 20 74 6f 20 2a 2f 0a 29 7b 0a 20 20 75 33  ta to */.){.  u3
12d90 32 20 69 52 65 61 64 20 3d 20 30 3b 20 20 20 20  2 iRead = 0;    
12da0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
12db0 20 49 66 20 21 3d 30 2c 20 57 41 4c 20 66 72 61   If !=0, WAL fra
12dc0 6d 65 20 74 6f 20 72 65 74 75 72 6e 20 64 61 74  me to return dat
12dd0 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 75 33 32 20  a from */.  u32 
12de0 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d 3e 68 64  iLast = pWal->hd
12df0 72 2e 6d 78 46 72 61 6d 65 3b 20 20 2f 2a 20 4c  r.mxFrame;  /* L
12e00 61 73 74 20 70 61 67 65 20 69 6e 20 57 41 4c 20  ast page in WAL 
12e10 66 6f 72 20 74 68 69 73 20 72 65 61 64 65 72 20  for this reader 
12e20 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73 68 3b 20  */.  int iHash; 
12e30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12e40 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
12e50 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20 4e 20 68  loop through N h
12e60 61 73 68 20 74 61 62 6c 65 73 20 2a 2f 0a 0a 20  ash tables */.. 
12e70 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65   /* This routine
12e80 20 69 73 20 6f 6e 6c 79 20 62 65 20 63 61 6c 6c   is only be call
12e90 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 61  ed from within a
12ea0 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
12eb0 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  n. */.  assert( 
12ec0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
12ed0 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45  0 || pWal->lockE
12ee0 72 72 6f 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66  rror );..  /* If
12ef0 20 74 68 65 20 22 6c 61 73 74 20 70 61 67 65 22   the "last page"
12f00 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20 77 61   field of the wa
12f10 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 73  l-index header s
12f20 6e 61 70 73 68 6f 74 20 69 73 20 30 2c 20 74 68  napshot is 0, th
12f30 65 6e 0a 20 20 2a 2a 20 6e 6f 20 64 61 74 61 20  en.  ** no data 
12f40 77 69 6c 6c 20 62 65 20 72 65 61 64 20 66 72 6f  will be read fro
12f50 6d 20 74 68 65 20 77 61 6c 20 75 6e 64 65 72 20  m the wal under 
12f60 61 6e 79 20 63 69 72 63 75 6d 73 74 61 6e 63 65  any circumstance
12f70 73 2e 20 52 65 74 75 72 6e 20 65 61 72 6c 79 0a  s. Return early.
12f80 20 20 2a 2a 20 69 6e 20 74 68 69 73 20 63 61 73    ** in this cas
12f90 65 20 61 73 20 61 6e 20 6f 70 74 69 6d 69 7a 61  e as an optimiza
12fa0 74 69 6f 6e 2e 20 20 4c 69 6b 65 77 69 73 65 2c  tion.  Likewise,
12fb0 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f   if pWal->readLo
12fc0 63 6b 3d 3d 30 2c 20 0a 20 20 2a 2a 20 74 68 65  ck==0, .  ** the
12fd0 6e 20 74 68 65 20 57 41 4c 20 69 73 20 69 67 6e  n the WAL is ign
12fe0 6f 72 65 64 20 62 79 20 74 68 65 20 72 65 61 64  ored by the read
12ff0 65 72 20 73 6f 20 72 65 74 75 72 6e 20 65 61 72  er so return ear
13000 6c 79 2c 20 61 73 20 69 66 20 74 68 65 20 0a 20  ly, as if the . 
13010 20 2a 2a 20 57 41 4c 20 77 65 72 65 20 65 6d 70   ** WAL were emp
13020 74 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69  ty..  */.  if( i
13030 4c 61 73 74 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d  Last==0 || pWal-
13040 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20 29 7b 0a  >readLock==0 ){.
13050 20 20 20 20 2a 70 49 6e 57 61 6c 20 3d 20 30 3b      *pInWal = 0;
13060 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
13070 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  TE_OK;.  }..  /*
13080 20 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68   Search the hash
13090 20 74 61 62 6c 65 20 6f 72 20 74 61 62 6c 65 73   table or tables
130a0 20 66 6f 72 20 61 6e 20 65 6e 74 72 79 20 6d 61   for an entry ma
130b0 74 63 68 69 6e 67 20 70 61 67 65 20 6e 75 6d 62  tching page numb
130c0 65 72 0a 20 20 2a 2a 20 70 67 6e 6f 2e 20 45 61  er.  ** pgno. Ea
130d0 63 68 20 69 74 65 72 61 74 69 6f 6e 20 6f 66 20  ch iteration of 
130e0 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 66 6f  the following fo
130f0 72 28 29 20 6c 6f 6f 70 20 73 65 61 72 63 68 65  r() loop searche
13100 73 20 6f 6e 65 0a 20 20 2a 2a 20 68 61 73 68 20  s one.  ** hash 
13110 74 61 62 6c 65 20 28 65 61 63 68 20 68 61 73 68  table (each hash
13120 20 74 61 62 6c 65 20 69 6e 64 65 78 65 73 20 75   table indexes u
13130 70 20 74 6f 20 48 41 53 48 54 41 42 4c 45 5f 4e  p to HASHTABLE_N
13140 50 41 47 45 20 66 72 61 6d 65 73 29 2e 0a 20 20  PAGE frames)..  
13150 2a 2a 0a 20 20 2a 2a 20 54 68 69 73 20 63 6f 64  **.  ** This cod
13160 65 20 6d 69 67 68 74 20 72 75 6e 20 63 6f 6e 63  e might run conc
13170 75 72 72 65 6e 74 6c 79 20 74 6f 20 74 68 65 20  urrently to the 
13180 63 6f 64 65 20 69 6e 20 77 61 6c 49 6e 64 65 78  code in walIndex
13190 41 70 70 65 6e 64 28 29 0a 20 20 2a 2a 20 74 68  Append().  ** th
131a0 61 74 20 61 64 64 73 20 65 6e 74 72 69 65 73 20  at adds entries 
131b0 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  to the wal-index
131c0 20 28 61 6e 64 20 70 6f 73 73 69 62 6c 79 20 74   (and possibly t
131d0 6f 20 74 68 69 73 20 68 61 73 68 20 0a 20 20 2a  o this hash .  *
131e0 2a 20 74 61 62 6c 65 29 2e 20 54 68 69 73 20 6d  * table). This m
131f0 65 61 6e 73 20 74 68 65 20 76 61 6c 75 65 20 6a  eans the value j
13200 75 73 74 20 72 65 61 64 20 66 72 6f 6d 20 74 68  ust read from th
13210 65 20 68 61 73 68 20 0a 20 20 2a 2a 20 73 6c 6f  e hash .  ** slo
13220 74 20 28 61 48 61 73 68 5b 69 4b 65 79 5d 29 20  t (aHash[iKey]) 
13230 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 61 64  may have been ad
13240 64 65 64 20 62 65 66 6f 72 65 20 6f 72 20 61 66  ded before or af
13250 74 65 72 20 74 68 65 20 0a 20 20 2a 2a 20 63 75  ter the .  ** cu
13260 72 72 65 6e 74 20 72 65 61 64 20 74 72 61 6e 73  rrent read trans
13270 61 63 74 69 6f 6e 20 77 61 73 20 6f 70 65 6e 65  action was opene
13280 64 2e 20 56 61 6c 75 65 73 20 61 64 64 65 64 20  d. Values added 
13290 61 66 74 65 72 20 74 68 65 0a 20 20 2a 2a 20 72  after the.  ** r
132a0 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
132b0 77 61 73 20 6f 70 65 6e 65 64 20 6d 61 79 20 68  was opened may h
132c0 61 76 65 20 62 65 65 6e 20 77 72 69 74 74 65 6e  ave been written
132d0 20 69 6e 63 6f 72 72 65 63 74 6c 79 20 2d 0a 20   incorrectly -. 
132e0 20 2a 2a 20 69 2e 65 2e 20 74 68 65 73 65 20 73   ** i.e. these s
132f0 6c 6f 74 73 20 6d 61 79 20 63 6f 6e 74 61 69 6e  lots may contain
13300 20 67 61 72 62 61 67 65 20 64 61 74 61 2e 20 48   garbage data. H
13310 6f 77 65 76 65 72 2c 20 77 65 20 61 73 73 75 6d  owever, we assum
13320 65 0a 20 20 2a 2a 20 74 68 61 74 20 61 6e 79 20  e.  ** that any 
13330 73 6c 6f 74 73 20 77 72 69 74 74 65 6e 20 62 65  slots written be
13340 66 6f 72 65 20 74 68 65 20 63 75 72 72 65 6e 74  fore the current
13350 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
13360 6e 20 77 61 73 0a 20 20 2a 2a 20 6f 70 65 6e 65  n was.  ** opene
13370 64 20 72 65 6d 61 69 6e 20 75 6e 6d 6f 64 69 66  d remain unmodif
13380 69 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 46  ied..  **.  ** F
13390 6f 72 20 74 68 65 20 72 65 61 73 6f 6e 73 20 61  or the reasons a
133a0 62 6f 76 65 2c 20 74 68 65 20 69 66 28 2e 2e 2e  bove, the if(...
133b0 29 20 63 6f 6e 64 69 74 69 6f 6e 20 66 65 61 74  ) condition feat
133c0 75 72 65 64 20 69 6e 20 74 68 65 20 69 6e 6e 65  ured in the inne
133d0 72 0a 20 20 2a 2a 20 6c 6f 6f 70 20 6f 66 20 74  r.  ** loop of t
133e0 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62 6c 6f  he following blo
133f0 63 6b 20 69 73 20 6d 6f 72 65 20 73 74 72 69 6e  ck is more strin
13400 67 65 6e 74 20 74 68 61 74 20 77 6f 75 6c 64 20  gent that would 
13410 62 65 20 72 65 71 75 69 72 65 64 20 0a 20 20 2a  be required .  *
13420 2a 20 69 66 20 77 65 20 68 61 64 20 65 78 63 6c  * if we had excl
13430 75 73 69 76 65 20 61 63 63 65 73 73 20 74 6f 20  usive access to 
13440 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65 3a 0a  the hash-table:.
13450 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 28 61 50 67    **.  **   (aPg
13460 6e 6f 5b 69 46 72 61 6d 65 5d 3d 3d 70 67 6e 6f  no[iFrame]==pgno
13470 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69  ): .  **     Thi
13480 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74  s condition filt
13490 65 72 73 20 6f 75 74 20 6e 6f 72 6d 61 6c 20 68  ers out normal h
134a0 61 73 68 2d 74 61 62 6c 65 20 63 6f 6c 6c 69 73  ash-table collis
134b0 69 6f 6e 73 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20  ions..  **.  ** 
134c0 20 20 28 69 46 72 61 6d 65 3c 3d 69 4c 61 73 74    (iFrame<=iLast
134d0 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69  ): .  **     Thi
134e0 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74  s condition filt
134f0 65 72 73 20 6f 75 74 20 65 6e 74 72 69 65 73 20  ers out entries 
13500 74 68 61 74 20 77 65 72 65 20 61 64 64 65 64 20  that were added 
13510 74 6f 20 74 68 65 20 68 61 73 68 0a 20 20 2a 2a  to the hash.  **
13520 20 20 20 20 20 74 61 62 6c 65 20 61 66 74 65 72       table after
13530 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 65 61   the current rea
13540 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e 20 68 61  d-transaction ha
13550 64 20 73 74 61 72 74 65 64 2e 0a 20 20 2a 2f 0a  d started..  */.
13560 20 20 66 6f 72 28 69 48 61 73 68 3d 77 61 6c 46    for(iHash=walF
13570 72 61 6d 65 50 61 67 65 28 69 4c 61 73 74 29 3b  ramePage(iLast);
13580 20 69 48 61 73 68 3e 3d 30 20 26 26 20 69 52 65   iHash>=0 && iRe
13590 61 64 3d 3d 30 3b 20 69 48 61 73 68 2d 2d 29 7b  ad==0; iHash--){
135a0 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 68 74  .    volatile ht
135b0 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b 20 20 20  _slot *aHash;   
135c0 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
135d0 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20   hash table */. 
135e0 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20     volatile u32 
135f0 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20 20 20 20  *aPgno;         
13600 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 61   /* Pointer to a
13610 72 72 61 79 20 6f 66 20 70 61 67 65 20 6e 75 6d  rray of page num
13620 62 65 72 73 20 2a 2f 0a 20 20 20 20 75 33 32 20  bers */.    u32 
13630 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20 20  iZero;          
13640 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72 61            /* Fra
13650 6d 65 20 6e 75 6d 62 65 72 20 63 6f 72 72 65 73  me number corres
13660 70 6f 6e 64 69 6e 67 20 74 6f 20 61 50 67 6e 6f  ponding to aPgno
13670 5b 30 5d 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69  [0] */.    int i
13680 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  Key;            
13690 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68           /* Hash
136a0 20 73 6c 6f 74 20 69 6e 64 65 78 20 2a 2f 0a 20   slot index */. 
136b0 20 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 20 20     int rc;..    
136c0 72 63 20 3d 20 77 61 6c 48 61 73 68 47 65 74 28  rc = walHashGet(
136d0 70 57 61 6c 2c 20 69 48 61 73 68 2c 20 26 61 48  pWal, iHash, &aH
136e0 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20 26 69 5a  ash, &aPgno, &iZ
136f0 65 72 6f 29 3b 0a 20 20 20 20 69 66 28 20 72 63  ero);.    if( rc
13700 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
13710 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a       return rc;.
13720 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69 4b      }.    for(iK
13730 65 79 3d 77 61 6c 48 61 73 68 28 70 67 6e 6f 29  ey=walHash(pgno)
13740 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20 69  ; aHash[iKey]; i
13750 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68 28  Key=walNextHash(
13760 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 75 33  iKey)){.      u3
13770 32 20 69 46 72 61 6d 65 20 3d 20 61 48 61 73 68  2 iFrame = aHash
13780 5b 69 4b 65 79 5d 20 2b 20 69 5a 65 72 6f 3b 0a  [iKey] + iZero;.
13790 20 20 20 20 20 20 69 66 28 20 69 46 72 61 6d 65        if( iFrame
137a0 3c 3d 69 4c 61 73 74 20 26 26 20 61 50 67 6e 6f  <=iLast && aPgno
137b0 5b 61 48 61 73 68 5b 69 4b 65 79 5d 5d 3d 3d 70  [aHash[iKey]]==p
137c0 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20 20 20 61  gno ){.        a
137d0 73 73 65 72 74 28 20 69 46 72 61 6d 65 3e 69 52  ssert( iFrame>iR
137e0 65 61 64 20 29 3b 0a 20 20 20 20 20 20 20 20 69  ead );.        i
137f0 52 65 61 64 20 3d 20 69 46 72 61 6d 65 3b 0a 20  Read = iFrame;. 
13800 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
13810 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
13820 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45  ENABLE_EXPENSIVE
13830 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20 49 66 20  _ASSERT.  /* If 
13840 65 78 70 65 6e 73 69 76 65 20 61 73 73 65 72 74  expensive assert
13850 28 29 20 73 74 61 74 65 6d 65 6e 74 73 20 61 72  () statements ar
13860 65 20 61 76 61 69 6c 61 62 6c 65 2c 20 64 6f 20  e available, do 
13870 61 20 6c 69 6e 65 61 72 20 73 65 61 72 63 68 0a  a linear search.
13880 20 20 2a 2a 20 6f 66 20 74 68 65 20 77 61 6c 2d    ** of the wal-
13890 69 6e 64 65 78 20 66 69 6c 65 20 63 6f 6e 74 65  index file conte
138a0 6e 74 2e 20 4d 61 6b 65 20 73 75 72 65 20 74 68  nt. Make sure th
138b0 65 20 72 65 73 75 6c 74 73 20 61 67 72 65 65 20  e results agree 
138c0 77 69 74 68 20 74 68 65 0a 20 20 2a 2a 20 72 65  with the.  ** re
138d0 73 75 6c 74 20 6f 62 74 61 69 6e 65 64 20 75 73  sult obtained us
138e0 69 6e 67 20 74 68 65 20 68 61 73 68 20 69 6e 64  ing the hash ind
138f0 65 78 65 73 20 61 62 6f 76 65 2e 20 20 2a 2f 0a  exes above.  */.
13900 20 20 7b 0a 20 20 20 20 75 33 32 20 69 52 65 61    {.    u32 iRea
13910 64 32 20 3d 20 30 3b 0a 20 20 20 20 75 33 32 20  d2 = 0;.    u32 
13920 69 54 65 73 74 3b 0a 20 20 20 20 66 6f 72 28 69  iTest;.    for(i
13930 54 65 73 74 3d 69 4c 61 73 74 3b 20 69 54 65 73  Test=iLast; iTes
13940 74 3e 30 3b 20 69 54 65 73 74 2d 2d 29 7b 0a 20  t>0; iTest--){. 
13950 20 20 20 20 20 69 66 28 20 77 61 6c 46 72 61 6d       if( walFram
13960 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 54 65 73  ePgno(pWal, iTes
13970 74 29 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20 20  t)==pgno ){.    
13980 20 20 20 20 69 52 65 61 64 32 20 3d 20 69 54 65      iRead2 = iTe
13990 73 74 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61  st;.        brea
139a0 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k;.      }.    }
139b0 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 52 65  .    assert( iRe
139c0 61 64 3d 3d 69 52 65 61 64 32 20 29 3b 0a 20 20  ad==iRead2 );.  
139d0 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2f 2a 20 49  }.#endif..  /* I
139e0 66 20 69 52 65 61 64 20 69 73 20 6e 6f 6e 2d 7a  f iRead is non-z
139f0 65 72 6f 2c 20 74 68 65 6e 20 69 74 20 69 73 20  ero, then it is 
13a00 74 68 65 20 6c 6f 67 20 66 72 61 6d 65 20 6e 75  the log frame nu
13a10 6d 62 65 72 20 74 68 61 74 20 63 6f 6e 74 61 69  mber that contai
13a20 6e 73 20 74 68 65 0a 20 20 2a 2a 20 72 65 71 75  ns the.  ** requ
13a30 69 72 65 64 20 70 61 67 65 2e 20 52 65 61 64 20  ired page. Read 
13a40 61 6e 64 20 72 65 74 75 72 6e 20 64 61 74 61 20  and return data 
13a50 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20 66 69 6c  from the log fil
13a60 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69 52  e..  */.  if( iR
13a70 65 61 64 20 29 7b 0a 20 20 20 20 69 36 34 20 69  ead ){.    i64 i
13a80 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61 6d  Offset = walFram
13a90 65 4f 66 66 73 65 74 28 69 52 65 61 64 2c 20 70  eOffset(iRead, p
13aa0 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 29  Wal->hdr.szPage)
13ab0 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52   + WAL_FRAME_HDR
13ac0 53 49 5a 45 3b 0a 20 20 20 20 2a 70 49 6e 57 61  SIZE;.    *pInWa
13ad0 6c 20 3d 20 31 3b 0a 20 20 20 20 72 65 74 75 72  l = 1;.    retur
13ae0 6e 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28  n sqlite3OsRead(
13af0 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 70 4f  pWal->pWalFd, pO
13b00 75 74 2c 20 6e 4f 75 74 2c 20 69 4f 66 66 73 65  ut, nOut, iOffse
13b10 74 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 49 6e 57  t);.  }..  *pInW
13b20 61 6c 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e  al = 0;.  return
13b30 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a   SQLITE_OK;.}...
13b40 2f 2a 20 0a 2a 2a 20 53 65 74 20 2a 70 50 67 6e  /* .** Set *pPgn
13b50 6f 20 74 6f 20 74 68 65 20 73 69 7a 65 20 6f 66  o to the size of
13b60 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
13b70 6c 65 20 28 6f 72 20 7a 65 72 6f 2c 20 69 66 20  le (or zero, if 
13b80 75 6e 6b 6e 6f 77 6e 29 2e 0a 2a 2f 0a 76 6f 69  unknown)..*/.voi
13b90 64 20 73 71 6c 69 74 65 33 57 61 6c 44 62 73 69  d sqlite3WalDbsi
13ba0 7a 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 50 67  ze(Wal *pWal, Pg
13bb0 6e 6f 20 2a 70 50 67 6e 6f 29 7b 0a 20 20 61 73  no *pPgno){.  as
13bc0 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64  sert( pWal->read
13bd0 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70 57 61 6c 2d  Lock>=0 || pWal-
13be0 3e 6c 6f 63 6b 45 72 72 6f 72 20 29 3b 0a 20 20  >lockError );.  
13bf0 2a 70 50 67 6e 6f 20 3d 20 70 57 61 6c 2d 3e 68  *pPgno = pWal->h
13c00 64 72 2e 6e 50 61 67 65 3b 0a 7d 0a 0a 0a 2f 2a  dr.nPage;.}.../*
13c10 20 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69   .** This functi
13c20 6f 6e 20 73 74 61 72 74 73 20 61 20 77 72 69 74  on starts a writ
13c30 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e  e transaction on
13c40 20 74 68 65 20 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20   the WAL..**.** 
13c50 41 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  A read transacti
13c60 6f 6e 20 6d 75 73 74 20 68 61 76 65 20 61 6c 72  on must have alr
13c70 65 61 64 79 20 62 65 65 6e 20 73 74 61 72 74 65  eady been starte
13c80 64 20 62 79 20 61 20 70 72 69 6f 72 20 63 61 6c  d by a prior cal
13c90 6c 0a 2a 2a 20 74 6f 20 73 71 6c 69 74 65 33 57  l.** to sqlite3W
13ca0 61 6c 42 65 67 69 6e 52 65 61 64 54 72 61 6e 73  alBeginReadTrans
13cb0 61 63 74 69 6f 6e 28 29 2e 0a 2a 2a 0a 2a 2a 20  action()..**.** 
13cc0 49 66 20 61 6e 6f 74 68 65 72 20 74 68 72 65 61  If another threa
13cd0 64 20 6f 72 20 70 72 6f 63 65 73 73 20 68 61 73  d or process has
13ce0 20 77 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68   written into th
13cf0 65 20 64 61 74 61 62 61 73 65 20 73 69 6e 63 65  e database since
13d00 0a 2a 2a 20 74 68 65 20 72 65 61 64 20 74 72 61  .** the read tra
13d10 6e 73 61 63 74 69 6f 6e 20 77 61 73 20 73 74 61  nsaction was sta
13d20 72 74 65 64 2c 20 74 68 65 6e 20 69 74 20 69 73  rted, then it is
13d30 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20 66 6f   not possible fo
13d40 72 20 74 68 69 73 0a 2a 2a 20 74 68 72 65 61 64  r this.** thread
13d50 20 74 6f 20 77 72 69 74 65 20 61 73 20 64 6f 69   to write as doi
13d60 6e 67 20 73 6f 20 77 6f 75 6c 64 20 63 61 75 73  ng so would caus
13d70 65 20 61 20 66 6f 72 6b 2e 20 20 53 6f 20 74 68  e a fork.  So th
13d80 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65  is routine.** re
13d90 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53  turns SQLITE_BUS
13da0 59 20 69 6e 20 74 68 61 74 20 63 61 73 65 20 61  Y in that case a
13db0 6e 64 20 6e 6f 20 77 72 69 74 65 20 74 72 61 6e  nd no write tran
13dc0 73 61 63 74 69 6f 6e 20 69 73 20 73 74 61 72 74  saction is start
13dd0 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20  ed..**.** There 
13de0 63 61 6e 20 6f 6e 6c 79 20 62 65 20 61 20 73 69  can only be a si
13df0 6e 67 6c 65 20 77 72 69 74 65 72 20 61 63 74 69  ngle writer acti
13e00 76 65 20 61 74 20 61 20 74 69 6d 65 2e 0a 2a 2f  ve at a time..*/
13e10 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 42  .int sqlite3WalB
13e20 65 67 69 6e 57 72 69 74 65 54 72 61 6e 73 61 63  eginWriteTransac
13e30 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 29 7b  tion(Wal *pWal){
13e40 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 2f 2a  .  int rc;..  /*
13e50 20 43 61 6e 6e 6f 74 20 73 74 61 72 74 20 61 20   Cannot start a 
13e60 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f  write transactio
13e70 6e 20 77 69 74 68 6f 75 74 20 66 69 72 73 74 20  n without first 
13e80 68 6f 6c 64 69 6e 67 20 61 20 72 65 61 64 0a 20  holding a read. 
13e90 20 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e   ** transaction.
13ea0 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57   */.  assert( pW
13eb0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20  al->readLock>=0 
13ec0 29 3b 0a 0a 20 20 2f 2a 20 4f 6e 6c 79 20 6f 6e  );..  /* Only on
13ed0 65 20 77 72 69 74 65 72 20 61 6c 6c 6f 77 65 64  e writer allowed
13ee0 20 61 74 20 61 20 74 69 6d 65 2e 20 20 47 65 74   at a time.  Get
13ef0 20 74 68 65 20 77 72 69 74 65 20 6c 6f 63 6b 2e   the write lock.
13f00 20 20 52 65 74 75 72 6e 0a 20 20 2a 2a 20 53 51    Return.  ** SQ
13f10 4c 49 54 45 5f 42 55 53 59 20 69 66 20 75 6e 61  LITE_BUSY if una
13f20 62 6c 65 2e 0a 20 20 2a 2f 0a 20 20 72 63 20 3d  ble..  */.  rc =
13f30 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76   walLockExclusiv
13f40 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54  e(pWal, WAL_WRIT
13f50 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 69 66  E_LOCK, 1);.  if
13f60 28 20 72 63 20 29 7b 0a 20 20 20 20 72 65 74 75  ( rc ){.    retu
13f70 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70 57 61  rn rc;.  }.  pWa
13f80 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 31  l->writeLock = 1
13f90 3b 0a 0a 20 20 2f 2a 20 49 66 20 61 6e 6f 74 68  ;..  /* If anoth
13fa0 65 72 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68 61  er connection ha
13fb0 73 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65  s written to the
13fc0 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 73   database file s
13fd0 69 6e 63 65 20 74 68 65 0a 20 20 2a 2a 20 74 69  ince the.  ** ti
13fe0 6d 65 20 74 68 65 20 72 65 61 64 20 74 72 61 6e  me the read tran
13ff0 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68 69 73 20  saction on this 
14000 63 6f 6e 6e 65 63 74 69 6f 6e 20 77 61 73 20 73  connection was s
14010 74 61 72 74 65 64 2c 20 74 68 65 6e 0a 20 20 2a  tarted, then.  *
14020 2a 20 74 68 65 20 77 72 69 74 65 20 69 73 20 64  * the write is d
14030 69 73 61 6c 6c 6f 77 65 64 2e 0a 20 20 2a 2f 0a  isallowed..  */.
14040 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57    if( memcmp(&pW
14050 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20 2a  al->hdr, (void *
14060 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61  )walIndexHdr(pWa
14070 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  l), sizeof(WalIn
14080 64 65 78 48 64 72 29 29 21 3d 30 20 29 7b 0a 20  dexHdr))!=0 ){. 
14090 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c     walUnlockExcl
140a0 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
140b0 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  WRITE_LOCK, 1);.
140c0 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c      pWal->writeL
140d0 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 72 63 20  ock = 0;.    rc 
140e0 3d 20 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a 20  = SQLITE_BUSY;. 
140f0 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
14100 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 64 20 61 20  .}../*.** End a 
14110 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f  write transactio
14120 6e 2e 20 20 54 68 65 20 63 6f 6d 6d 69 74 20 68  n.  The commit h
14130 61 73 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20  as already been 
14140 64 6f 6e 65 2e 20 20 54 68 69 73 0a 2a 2a 20 72  done.  This.** r
14150 6f 75 74 69 6e 65 20 6d 65 72 65 6c 79 20 72 65  outine merely re
14160 6c 65 61 73 65 73 20 74 68 65 20 6c 6f 63 6b 2e  leases the lock.
14170 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
14180 61 6c 45 6e 64 57 72 69 74 65 54 72 61 6e 73 61  alEndWriteTransa
14190 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 29  ction(Wal *pWal)
141a0 7b 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63  {.  walUnlockExc
141b0 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
141c0 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b  _WRITE_LOCK, 1);
141d0 0a 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  .  pWal->writeLo
141e0 63 6b 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e  ck = 0;.  return
141f0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
14200 2a 0a 2a 2a 20 49 66 20 61 6e 79 20 64 61 74 61  *.** If any data
14210 20 68 61 73 20 62 65 65 6e 20 77 72 69 74 74 65   has been writte
14220 6e 20 28 62 75 74 20 6e 6f 74 20 63 6f 6d 6d 69  n (but not commi
14230 74 74 65 64 29 20 74 6f 20 74 68 65 20 6c 6f 67  tted) to the log
14240 20 66 69 6c 65 2c 20 74 68 69 73 0a 2a 2a 20 66   file, this.** f
14250 75 6e 63 74 69 6f 6e 20 6d 6f 76 65 73 20 74 68  unction moves th
14260 65 20 77 72 69 74 65 2d 70 6f 69 6e 74 65 72 20  e write-pointer 
14270 62 61 63 6b 20 74 6f 20 74 68 65 20 73 74 61 72  back to the star
14280 74 20 6f 66 20 74 68 65 20 74 72 61 6e 73 61 63  t of the transac
14290 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41 64 64 69  tion..**.** Addi
142a0 74 69 6f 6e 61 6c 6c 79 2c 20 74 68 65 20 63 61  tionally, the ca
142b0 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20  llback function 
142c0 69 73 20 69 6e 76 6f 6b 65 64 20 66 6f 72 20 65  is invoked for e
142d0 61 63 68 20 66 72 61 6d 65 20 77 72 69 74 74 65  ach frame writte
142e0 6e 0a 2a 2a 20 74 6f 20 74 68 65 20 57 41 4c 20  n.** to the WAL 
142f0 73 69 6e 63 65 20 74 68 65 20 73 74 61 72 74 20  since the start 
14300 6f 66 20 74 68 65 20 74 72 61 6e 73 61 63 74 69  of the transacti
14310 6f 6e 2e 20 49 66 20 74 68 65 20 63 61 6c 6c 62  on. If the callb
14320 61 63 6b 20 72 65 74 75 72 6e 73 0a 2a 2a 20 6f  ack returns.** o
14330 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45  ther than SQLITE
14340 5f 4f 4b 2c 20 69 74 20 69 73 20 6e 6f 74 20 69  _OK, it is not i
14350 6e 76 6f 6b 65 64 20 61 67 61 69 6e 20 61 6e 64  nvoked again and
14360 20 74 68 65 20 65 72 72 6f 72 20 63 6f 64 65 20   the error code 
14370 69 73 0a 2a 2a 20 72 65 74 75 72 6e 65 64 20 74  is.** returned t
14380 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 0a 2a 2a  o the caller..**
14390 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69  .** Otherwise, i
143a0 66 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 66  f the callback f
143b0 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20 6e 6f 74  unction does not
143c0 20 72 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72   return an error
143d0 2c 20 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69  , this.** functi
143e0 6f 6e 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  on returns SQLIT
143f0 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  E_OK..*/.int sql
14400 69 74 65 33 57 61 6c 55 6e 64 6f 28 57 61 6c 20  ite3WalUndo(Wal 
14410 2a 70 57 61 6c 2c 20 69 6e 74 20 28 2a 78 55 6e  *pWal, int (*xUn
14420 64 6f 29 28 76 6f 69 64 20 2a 2c 20 50 67 6e 6f  do)(void *, Pgno
14430 29 2c 20 76 6f 69 64 20 2a 70 55 6e 64 6f 43 74  ), void *pUndoCt
14440 78 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  x){.  int rc = S
14450 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20  QLITE_OK;.  if( 
14460 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
14470 29 7b 0a 20 20 20 20 50 67 6e 6f 20 69 4d 61 78  ){.    Pgno iMax
14480 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46   = pWal->hdr.mxF
14490 72 61 6d 65 3b 0a 20 20 20 20 50 67 6e 6f 20 69  rame;.    Pgno i
144a0 46 72 61 6d 65 3b 0a 20 20 0a 20 20 20 20 2f 2a  Frame;.  .    /*
144b0 20 52 65 73 74 6f 72 65 20 74 68 65 20 63 6c 69   Restore the cli
144c0 65 6e 74 73 20 63 61 63 68 65 20 6f 66 20 74 68  ents cache of th
144d0 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
144e0 65 72 20 74 6f 20 74 68 65 20 73 74 61 74 65 20  er to the state 
144f0 69 74 0a 20 20 20 20 2a 2a 20 77 61 73 20 69 6e  it.    ** was in
14500 20 62 65 66 6f 72 65 20 74 68 65 20 63 6c 69 65   before the clie
14510 6e 74 20 62 65 67 61 6e 20 77 72 69 74 69 6e 67  nt began writing
14520 20 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65   to the database
14530 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d 65  . .    */.    me
14540 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c  mcpy(&pWal->hdr,
14550 20 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65   (void *)walInde
14560 78 48 64 72 28 70 57 61 6c 29 2c 20 73 69 7a 65  xHdr(pWal), size
14570 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
14580 3b 0a 0a 20 20 20 20 66 6f 72 28 69 46 72 61 6d  ;..    for(iFram
14590 65 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  e=pWal->hdr.mxFr
145a0 61 6d 65 2b 31 3b 20 0a 20 20 20 20 20 20 20 20  ame+1; .        
145b0 41 4c 57 41 59 53 28 72 63 3d 3d 53 51 4c 49 54  ALWAYS(rc==SQLIT
145c0 45 5f 4f 4b 29 20 26 26 20 69 46 72 61 6d 65 3c  E_OK) && iFrame<
145d0 3d 69 4d 61 78 3b 20 0a 20 20 20 20 20 20 20 20  =iMax; .        
145e0 69 46 72 61 6d 65 2b 2b 0a 20 20 20 20 29 7b 0a  iFrame++.    ){.
145f0 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20 63 61        /* This ca
14600 6c 6c 20 63 61 6e 6e 6f 74 20 66 61 69 6c 2e 20  ll cannot fail. 
14610 55 6e 6c 65 73 73 20 74 68 65 20 70 61 67 65 20  Unless the page 
14620 66 6f 72 20 77 68 69 63 68 20 74 68 65 20 70 61  for which the pa
14630 67 65 20 6e 75 6d 62 65 72 0a 20 20 20 20 20 20  ge number.      
14640 2a 2a 20 69 73 20 70 61 73 73 65 64 20 61 73 20  ** is passed as 
14650 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d  the second argum
14660 65 6e 74 20 69 73 20 28 61 29 20 69 6e 20 74 68  ent is (a) in th
14670 65 20 63 61 63 68 65 20 61 6e 64 20 0a 20 20 20  e cache and .   
14680 20 20 20 2a 2a 20 28 62 29 20 68 61 73 20 61 6e     ** (b) has an
14690 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 72 65 66   outstanding ref
146a0 65 72 65 6e 63 65 2c 20 74 68 65 6e 20 78 55 6e  erence, then xUn
146b0 64 6f 20 69 73 20 65 69 74 68 65 72 20 61 20 6e  do is either a n
146c0 6f 2d 6f 70 0a 20 20 20 20 20 20 2a 2a 20 28 69  o-op.      ** (i
146d0 66 20 28 61 29 20 69 73 20 66 61 6c 73 65 29 20  f (a) is false) 
146e0 6f 72 20 73 69 6d 70 6c 79 20 65 78 70 65 6c 73  or simply expels
146f0 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74   the page from t
14700 68 65 20 63 61 63 68 65 20 28 69 66 20 28 62 29  he cache (if (b)
14710 0a 20 20 20 20 20 20 2a 2a 20 69 73 20 66 61 6c  .      ** is fal
14720 73 65 29 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20  se)..      **.  
14730 20 20 20 20 2a 2a 20 49 66 20 74 68 65 20 75 70      ** If the up
14740 70 65 72 20 6c 61 79 65 72 20 69 73 20 64 6f 69  per layer is doi
14750 6e 67 20 61 20 72 6f 6c 6c 62 61 63 6b 2c 20 69  ng a rollback, i
14760 74 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20  t is guaranteed 
14770 74 68 61 74 20 74 68 65 72 65 0a 20 20 20 20 20  that there.     
14780 20 2a 2a 20 61 72 65 20 6e 6f 20 6f 75 74 73 74   ** are no outst
14790 61 6e 64 69 6e 67 20 72 65 66 65 72 65 6e 63 65  anding reference
147a0 73 20 74 6f 20 61 6e 79 20 70 61 67 65 20 6f 74  s to any page ot
147b0 68 65 72 20 74 68 61 6e 20 70 61 67 65 20 31 2e  her than page 1.
147c0 20 41 6e 64 0a 20 20 20 20 20 20 2a 2a 20 70 61   And.      ** pa
147d0 67 65 20 31 20 69 73 20 6e 65 76 65 72 20 77 72  ge 1 is never wr
147e0 69 74 74 65 6e 20 74 6f 20 74 68 65 20 6c 6f 67  itten to the log
147f0 20 75 6e 74 69 6c 20 74 68 65 20 74 72 61 6e 73   until the trans
14800 61 63 74 69 6f 6e 20 69 73 0a 20 20 20 20 20 20  action is.      
14810 2a 2a 20 63 6f 6d 6d 69 74 74 65 64 2e 20 41 73  ** committed. As
14820 20 61 20 72 65 73 75 6c 74 2c 20 74 68 65 20 63   a result, the c
14830 61 6c 6c 20 74 6f 20 78 55 6e 64 6f 20 6d 61 79  all to xUndo may
14840 20 6e 6f 74 20 66 61 69 6c 2e 0a 20 20 20 20 20   not fail..     
14850 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74   */.      assert
14860 28 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70  ( walFramePgno(p
14870 57 61 6c 2c 20 69 46 72 61 6d 65 29 21 3d 31 20  Wal, iFrame)!=1 
14880 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 78 55  );.      rc = xU
14890 6e 64 6f 28 70 55 6e 64 6f 43 74 78 2c 20 77 61  ndo(pUndoCtx, wa
148a0 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c  lFramePgno(pWal,
148b0 20 69 46 72 61 6d 65 29 29 3b 0a 20 20 20 20 7d   iFrame));.    }
148c0 0a 20 20 20 20 77 61 6c 43 6c 65 61 6e 75 70 48  .    walCleanupH
148d0 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20  ash(pWal);.  }. 
148e0 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c   assert( rc==SQL
148f0 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74 75  ITE_OK );.  retu
14900 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
14910 20 41 72 67 75 6d 65 6e 74 20 61 57 61 6c 44 61   Argument aWalDa
14920 74 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f  ta must point to
14930 20 61 6e 20 61 72 72 61 79 20 6f 66 20 57 41 4c   an array of WAL
14940 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54 41  _SAVEPOINT_NDATA
14950 20 75 33 32 20 0a 2a 2a 20 76 61 6c 75 65 73 2e   u32 .** values.
14960 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 70   This function p
14970 6f 70 75 6c 61 74 65 73 20 74 68 65 20 61 72 72  opulates the arr
14980 61 79 20 77 69 74 68 20 76 61 6c 75 65 73 20 72  ay with values r
14990 65 71 75 69 72 65 64 20 74 6f 20 0a 2a 2a 20 22  equired to .** "
149a0 72 6f 6c 6c 62 61 63 6b 22 20 74 68 65 20 77 72  rollback" the wr
149b0 69 74 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66 20  ite position of 
149c0 74 68 65 20 57 41 4c 20 68 61 6e 64 6c 65 20 62  the WAL handle b
149d0 61 63 6b 20 74 6f 20 74 68 65 20 63 75 72 72 65  ack to the curre
149e0 6e 74 20 0a 2a 2a 20 70 6f 69 6e 74 20 69 6e 20  nt .** point in 
149f0 74 68 65 20 65 76 65 6e 74 20 6f 66 20 61 20 73  the event of a s
14a00 61 76 65 70 6f 69 6e 74 20 72 6f 6c 6c 62 61 63  avepoint rollbac
14a10 6b 20 28 76 69 61 20 57 61 6c 53 61 76 65 70 6f  k (via WalSavepo
14a20 69 6e 74 55 6e 64 6f 28 29 29 2e 0a 2a 2f 0a 76  intUndo())..*/.v
14a30 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 53 61  oid sqlite3WalSa
14a40 76 65 70 6f 69 6e 74 28 57 61 6c 20 2a 70 57 61  vepoint(Wal *pWa
14a50 6c 2c 20 75 33 32 20 2a 61 57 61 6c 44 61 74 61  l, u32 *aWalData
14a60 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  ){.  assert( pWa
14a70 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a  l->writeLock );.
14a80 20 20 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d 20    aWalData[0] = 
14a90 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
14aa0 65 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 31 5d  e;.  aWalData[1]
14ab0 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72   = pWal->hdr.aFr
14ac0 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 61  ameCksum[0];.  a
14ad0 57 61 6c 44 61 74 61 5b 32 5d 20 3d 20 70 57 61  WalData[2] = pWa
14ae0 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
14af0 75 6d 5b 31 5d 3b 0a 20 20 61 57 61 6c 44 61 74  um[1];.  aWalDat
14b00 61 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e 6e 43 6b  a[3] = pWal->nCk
14b10 70 74 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4d 6f  pt;.}../* .** Mo
14b20 76 65 20 74 68 65 20 77 72 69 74 65 20 70 6f 73  ve the write pos
14b30 69 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41 4c  ition of the WAL
14b40 20 62 61 63 6b 20 74 6f 20 74 68 65 20 70 6f 69   back to the poi
14b50 6e 74 20 69 64 65 6e 74 69 66 69 65 64 20 62 79  nt identified by
14b60 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 73 20 69  .** the values i
14b70 6e 20 74 68 65 20 61 57 61 6c 44 61 74 61 5b 5d  n the aWalData[]
14b80 20 61 72 72 61 79 2e 20 61 57 61 6c 44 61 74 61   array. aWalData
14b90 20 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f 20 61   must point to a
14ba0 6e 20 61 72 72 61 79 0a 2a 2a 20 6f 66 20 57 41  n array.** of WA
14bb0 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54  L_SAVEPOINT_NDAT
14bc0 41 20 75 33 32 20 76 61 6c 75 65 73 20 74 68 61  A u32 values tha
14bd0 74 20 68 61 73 20 62 65 65 6e 20 70 72 65 76 69  t has been previ
14be0 6f 75 73 6c 79 20 70 6f 70 75 6c 61 74 65 64 0a  ously populated.
14bf0 2a 2a 20 62 79 20 61 20 63 61 6c 6c 20 74 6f 20  ** by a call to 
14c00 57 61 6c 53 61 76 65 70 6f 69 6e 74 28 29 2e 0a  WalSavepoint()..
14c10 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
14c20 6c 53 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28 57  lSavepointUndo(W
14c30 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a 61  al *pWal, u32 *a
14c40 57 61 6c 44 61 74 61 29 7b 0a 20 20 69 6e 74 20  WalData){.  int 
14c50 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
14c60 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
14c70 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20  >writeLock );.  
14c80 61 73 73 65 72 74 28 20 61 57 61 6c 44 61 74 61  assert( aWalData
14c90 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43 6b 70 74  [3]!=pWal->nCkpt
14ca0 20 7c 7c 20 61 57 61 6c 44 61 74 61 5b 30 5d 3c   || aWalData[0]<
14cb0 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  =pWal->hdr.mxFra
14cc0 6d 65 20 29 3b 0a 0a 20 20 69 66 28 20 61 57 61  me );..  if( aWa
14cd0 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e  lData[3]!=pWal->
14ce0 6e 43 6b 70 74 20 29 7b 0a 20 20 20 20 2f 2a 20  nCkpt ){.    /* 
14cf0 54 68 69 73 20 73 61 76 65 70 6f 69 6e 74 20 77  This savepoint w
14d00 61 73 20 6f 70 65 6e 65 64 20 69 6d 6d 65 64 69  as opened immedi
14d10 61 74 65 6c 79 20 61 66 74 65 72 20 74 68 65 20  ately after the 
14d20 77 72 69 74 65 2d 74 72 61 6e 73 61 63 74 69 6f  write-transactio
14d30 6e 0a 20 20 20 20 2a 2a 20 77 61 73 20 73 74 61  n.    ** was sta
14d40 72 74 65 64 2e 20 52 69 67 68 74 20 61 66 74 65  rted. Right afte
14d50 72 20 74 68 61 74 2c 20 74 68 65 20 77 72 69 74  r that, the writ
14d60 65 72 20 64 65 63 69 64 65 64 20 74 6f 20 77 72  er decided to wr
14d70 61 70 20 61 72 6f 75 6e 64 0a 20 20 20 20 2a 2a  ap around.    **
14d80 20 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66   to the start of
14d90 20 74 68 65 20 6c 6f 67 2e 20 55 70 64 61 74 65   the log. Update
14da0 20 74 68 65 20 73 61 76 65 70 6f 69 6e 74 20 76   the savepoint v
14db0 61 6c 75 65 73 20 74 6f 20 6d 61 74 63 68 2e 0a  alues to match..
14dc0 20 20 20 20 2a 2f 0a 20 20 20 20 61 57 61 6c 44      */.    aWalD
14dd0 61 74 61 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20  ata[0] = 0;.    
14de0 61 57 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70 57  aWalData[3] = pW
14df0 61 6c 2d 3e 6e 43 6b 70 74 3b 0a 20 20 7d 0a 0a  al->nCkpt;.  }..
14e00 20 20 69 66 28 20 61 57 61 6c 44 61 74 61 5b 30    if( aWalData[0
14e10 5d 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  ]<pWal->hdr.mxFr
14e20 61 6d 65 20 29 7b 0a 20 20 20 20 70 57 61 6c 2d  ame ){.    pWal-
14e30 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20 61  >hdr.mxFrame = a
14e40 57 61 6c 44 61 74 61 5b 30 5d 3b 0a 20 20 20 20  WalData[0];.    
14e50 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
14e60 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 57 61 6c 44  Cksum[0] = aWalD
14e70 61 74 61 5b 31 5d 3b 0a 20 20 20 20 70 57 61 6c  ata[1];.    pWal
14e80 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
14e90 6d 5b 31 5d 20 3d 20 61 57 61 6c 44 61 74 61 5b  m[1] = aWalData[
14ea0 32 5d 3b 0a 20 20 20 20 77 61 6c 43 6c 65 61 6e  2];.    walClean
14eb0 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20  upHash(pWal);.  
14ec0 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
14ed0 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
14ee0 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
14ef0 20 6a 75 73 74 20 62 65 66 6f 72 65 20 77 72 69   just before wri
14f00 74 69 6e 67 20 61 20 73 65 74 20 6f 66 20 66 72  ting a set of fr
14f10 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67 0a  ames to the log.
14f20 2a 2a 20 66 69 6c 65 20 28 73 65 65 20 73 71 6c  ** file (see sql
14f30 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28 29 29  ite3WalFrames())
14f40 2e 20 49 74 20 63 68 65 63 6b 73 20 74 6f 20 73  . It checks to s
14f50 65 65 20 69 66 2c 20 69 6e 73 74 65 61 64 20 6f  ee if, instead o
14f60 66 20 61 70 70 65 6e 64 69 6e 67 0a 2a 2a 20 74  f appending.** t
14f70 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c 6f  o the current lo
14f80 67 20 66 69 6c 65 2c 20 69 74 20 69 73 20 70 6f  g file, it is po
14f90 73 73 69 62 6c 65 20 74 6f 20 6f 76 65 72 77 72  ssible to overwr
14fa0 69 74 65 20 74 68 65 20 73 74 61 72 74 20 6f 66  ite the start of
14fb0 20 74 68 65 0a 2a 2a 20 65 78 69 73 74 69 6e 67   the.** existing
14fc0 20 6c 6f 67 20 66 69 6c 65 20 77 69 74 68 20 74   log file with t
14fd0 68 65 20 6e 65 77 20 66 72 61 6d 65 73 20 28 69  he new frames (i
14fe0 2e 65 2e 20 22 72 65 73 65 74 22 20 74 68 65 20  .e. "reset" the 
14ff0 6c 6f 67 29 2e 20 49 66 20 73 6f 2c 0a 2a 2a 20  log). If so,.** 
15000 69 74 20 73 65 74 73 20 70 57 61 6c 2d 3e 68 64  it sets pWal->hd
15010 72 2e 6d 78 46 72 61 6d 65 20 74 6f 20 30 2e 20  r.mxFrame to 0. 
15020 4f 74 68 65 72 77 69 73 65 2c 20 70 57 61 6c 2d  Otherwise, pWal-
15030 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20  >hdr.mxFrame is 
15040 6c 65 66 74 0a 2a 2a 20 75 6e 63 68 61 6e 67 65  left.** unchange
15050 64 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f  d..**.** SQLITE_
15060 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 69  OK is returned i
15070 66 20 6e 6f 20 65 72 72 6f 72 20 69 73 20 65 6e  f no error is en
15080 63 6f 75 6e 74 65 72 65 64 20 28 72 65 67 61 72  countered (regar
15090 64 6c 65 73 73 20 6f 66 20 77 68 65 74 68 65 72  dless of whether
150a0 0a 2a 2a 20 6f 72 20 6e 6f 74 20 70 57 61 6c 2d  .** or not pWal-
150b0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20  >hdr.mxFrame is 
150c0 6d 6f 64 69 66 69 65 64 29 2e 20 41 6e 20 53 51  modified). An SQ
150d0 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20  Lite error code 
150e0 69 73 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69  is returned.** i
150f0 66 20 73 6f 6d 65 20 65 72 72 6f 72 20 0a 2a 2f  f some error .*/
15100 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 52  .static int walR
15110 65 73 74 61 72 74 4c 6f 67 28 57 61 6c 20 2a 70  estartLog(Wal *p
15120 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  Wal){.  int rc =
15130 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e   SQLITE_OK;.  in
15140 74 20 63 6e 74 3b 0a 0a 20 20 69 66 28 20 70 57  t cnt;..  if( pW
15150 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20  al->readLock==0 
15160 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  ){.    volatile 
15170 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e  WalCkptInfo *pIn
15180 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f  fo = walCkptInfo
15190 28 70 57 61 6c 29 3b 0a 20 20 20 20 61 73 73 65  (pWal);.    asse
151a0 72 74 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b  rt( pInfo->nBack
151b0 66 69 6c 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e  fill==pWal->hdr.
151c0 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20 20 69  mxFrame );.    i
151d0 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66  f( pInfo->nBackf
151e0 69 6c 6c 3e 30 20 29 7b 0a 20 20 20 20 20 20 72  ill>0 ){.      r
151f0 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75  c = walLockExclu
15200 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52  sive(pWal, WAL_R
15210 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c  EAD_LOCK(1), WAL
15220 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20  _NREADER-1);.   
15230 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
15240 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
15250 2f 2a 20 49 66 20 61 6c 6c 20 72 65 61 64 65 72  /* If all reader
15260 73 20 61 72 65 20 75 73 69 6e 67 20 57 41 4c 5f  s are using WAL_
15270 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20 28 69 6e  READ_LOCK(0) (in
15280 20 6f 74 68 65 72 20 77 6f 72 64 73 20 69 66 20   other words if 
15290 6e 6f 0a 20 20 20 20 20 20 20 20 2a 2a 20 72 65  no.        ** re
152a0 61 64 65 72 73 20 61 72 65 20 63 75 72 72 65 6e  aders are curren
152b0 74 6c 79 20 75 73 69 6e 67 20 74 68 65 20 57 41  tly using the WA
152c0 4c 29 2c 20 74 68 65 6e 20 74 68 65 20 74 72 61  L), then the tra
152d0 6e 73 61 63 74 69 6f 6e 73 0a 20 20 20 20 20 20  nsactions.      
152e0 20 20 2a 2a 20 66 72 61 6d 65 73 20 77 69 6c 6c    ** frames will
152f0 20 6f 76 65 72 77 72 69 74 65 20 74 68 65 20 73   overwrite the s
15300 74 61 72 74 20 6f 66 20 74 68 65 20 65 78 69 73  tart of the exis
15310 74 69 6e 67 20 6c 6f 67 2e 20 55 70 64 61 74 65  ting log. Update
15320 20 74 68 65 0a 20 20 20 20 20 20 20 20 2a 2a 20   the.        ** 
15330 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
15340 20 74 6f 20 72 65 66 6c 65 63 74 20 74 68 69 73   to reflect this
15350 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20 20  ..        **.   
15360 20 20 20 20 20 2a 2a 20 49 6e 20 74 68 65 6f 72       ** In theor
15370 79 20 69 74 20 77 6f 75 6c 64 20 62 65 20 4f 6b  y it would be Ok
15380 20 74 6f 20 75 70 64 61 74 65 20 74 68 65 20 63   to update the c
15390 61 63 68 65 20 6f 66 20 74 68 65 20 68 65 61 64  ache of the head
153a0 65 72 20 6f 6e 6c 79 0a 20 20 20 20 20 20 20 20  er only.        
153b0 2a 2a 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74  ** at this point
153c0 2e 20 42 75 74 20 75 70 64 61 74 69 6e 67 20 74  . But updating t
153d0 68 65 20 61 63 74 75 61 6c 20 77 61 6c 2d 69 6e  he actual wal-in
153e0 64 65 78 20 68 65 61 64 65 72 20 69 73 20 61 6c  dex header is al
153f0 73 6f 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 61  so.        ** sa
15400 66 65 20 61 6e 64 20 6d 65 61 6e 73 20 74 68 65  fe and means the
15410 72 65 20 69 73 20 6e 6f 20 73 70 65 63 69 61 6c  re is no special
15420 20 63 61 73 65 20 66 6f 72 20 73 71 6c 69 74 65   case for sqlite
15430 33 57 61 6c 55 6e 64 6f 28 29 0a 20 20 20 20 20  3WalUndo().     
15440 20 20 20 2a 2a 20 74 6f 20 68 61 6e 64 6c 65 20     ** to handle 
15450 69 66 20 74 68 69 73 20 74 72 61 6e 73 61 63 74  if this transact
15460 69 6f 6e 20 69 73 20 72 6f 6c 6c 65 64 20 62 61  ion is rolled ba
15470 63 6b 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20  ck..        */. 
15480 20 20 20 20 20 20 20 69 6e 74 20 69 3b 20 20 20         int i;   
15490 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
154a0 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72   /* Loop counter
154b0 20 2a 2f 0a 20 20 20 20 20 20 20 20 75 33 32 20   */.        u32 
154c0 2a 61 53 61 6c 74 20 3d 20 70 57 61 6c 2d 3e 68  *aSalt = pWal->h
154d0 64 72 2e 61 53 61 6c 74 3b 20 20 20 20 20 20 20  dr.aSalt;       
154e0 2f 2a 20 42 69 67 2d 65 6e 64 69 61 6e 20 73 61  /* Big-endian sa
154f0 6c 74 20 76 61 6c 75 65 73 20 2a 2f 0a 20 20 20  lt values */.   
15500 20 20 20 20 20 70 57 61 6c 2d 3e 6e 43 6b 70 74       pWal->nCkpt
15510 2b 2b 3b 0a 20 20 20 20 20 20 20 20 70 57 61 6c  ++;.        pWal
15520 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20  ->hdr.mxFrame = 
15530 30 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  0;.        sqlit
15540 65 33 50 75 74 34 62 79 74 65 28 28 75 38 2a 29  e3Put4byte((u8*)
15550 26 61 53 61 6c 74 5b 30 5d 2c 20 31 20 2b 20 73  &aSalt[0], 1 + s
15560 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 28  qlite3Get4byte((
15570 75 38 2a 29 26 61 53 61 6c 74 5b 30 5d 29 29 3b  u8*)&aSalt[0]));
15580 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
15590 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 34 2c 20 26  _randomness(4, &
155a0 61 53 61 6c 74 5b 31 5d 29 3b 0a 20 20 20 20 20  aSalt[1]);.     
155b0 20 20 20 77 61 6c 49 6e 64 65 78 57 72 69 74 65     walIndexWrite
155c0 48 64 72 28 70 57 61 6c 29 3b 0a 20 20 20 20 20  Hdr(pWal);.     
155d0 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66     pInfo->nBackf
155e0 69 6c 6c 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ill = 0;.       
155f0 20 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f   for(i=1; i<WAL_
15600 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29 20 70 49  NREADER; i++) pI
15610 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69  nfo->aReadMark[i
15620 5d 20 3d 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54  ] = READMARK_NOT
15630 5f 55 53 45 44 3b 0a 20 20 20 20 20 20 20 20 61  _USED;.        a
15640 73 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e 61 52  ssert( pInfo->aR
15650 65 61 64 4d 61 72 6b 5b 30 5d 3d 3d 30 20 29 3b  eadMark[0]==0 );
15660 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f  .        walUnlo
15670 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
15680 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
15690 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d  1), WAL_NREADER-
156a0 31 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  1);.      }.    
156b0 7d 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53  }.    walUnlockS
156c0 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
156d0 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20  READ_LOCK(0));. 
156e0 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63     pWal->readLoc
156f0 6b 20 3d 20 2d 31 3b 0a 20 20 20 20 63 6e 74 20  k = -1;.    cnt 
15700 3d 20 30 3b 0a 20 20 20 20 64 6f 7b 0a 20 20 20  = 0;.    do{.   
15710 20 20 20 69 6e 74 20 6e 6f 74 55 73 65 64 3b 0a     int notUsed;.
15720 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 54 72        rc = walTr
15730 79 42 65 67 69 6e 52 65 61 64 28 70 57 61 6c 2c  yBeginRead(pWal,
15740 20 26 6e 6f 74 55 73 65 64 2c 20 31 2c 20 2b 2b   &notUsed, 1, ++
15750 63 6e 74 29 3b 0a 20 20 20 20 7d 77 68 69 6c 65  cnt);.    }while
15760 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54 52 59 20  ( rc==WAL_RETRY 
15770 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
15780 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 57 72  rc;.}../* .** Wr
15790 69 74 65 20 61 20 73 65 74 20 6f 66 20 66 72 61  ite a set of fra
157a0 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67 2e 20  mes to the log. 
157b0 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20  The caller must 
157c0 68 6f 6c 64 20 74 68 65 20 77 72 69 74 65 2d 6c  hold the write-l
157d0 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20 6c 6f  ock.** on the lo
157e0 67 20 66 69 6c 65 20 28 6f 62 74 61 69 6e 65 64  g file (obtained
157f0 20 75 73 69 6e 67 20 73 71 6c 69 74 65 33 57 61   using sqlite3Wa
15800 6c 42 65 67 69 6e 57 72 69 74 65 54 72 61 6e 73  lBeginWriteTrans
15810 61 63 74 69 6f 6e 28 29 29 2e 0a 2a 2f 0a 69 6e  action())..*/.in
15820 74 20 73 71 6c 69 74 65 33 57 61 6c 46 72 61 6d  t sqlite3WalFram
15830 65 73 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c  es(.  Wal *pWal,
15840 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15850 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 68 61 6e        /* Wal han
15860 64 6c 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20  dle to write to 
15870 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 2c  */.  int szPage,
15880 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15890 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
158a0 20 70 61 67 65 2d 73 69 7a 65 20 69 6e 20 62 79   page-size in by
158b0 74 65 73 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a  tes */.  PgHdr *
158c0 70 4c 69 73 74 2c 20 20 20 20 20 20 20 20 20 20  pList,          
158d0 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74           /* List
158e0 20 6f 66 20 64 69 72 74 79 20 70 61 67 65 73 20   of dirty pages 
158f0 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 50 67  to write */.  Pg
15900 6e 6f 20 6e 54 72 75 6e 63 61 74 65 2c 20 20 20  no nTruncate,   
15910 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
15920 20 44 61 74 61 62 61 73 65 20 73 69 7a 65 20 61   Database size a
15930 66 74 65 72 20 74 68 69 73 20 63 6f 6d 6d 69 74  fter this commit
15940 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43 6f 6d 6d   */.  int isComm
15950 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  it,             
15960 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
15970 20 74 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 69   this is a commi
15980 74 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f  t */.  int sync_
15990 66 6c 61 67 73 20 20 20 20 20 20 20 20 20 20 20  flags           
159a0 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20         /* Flags 
159b0 74 6f 20 70 61 73 73 20 74 6f 20 4f 73 53 79 6e  to pass to OsSyn
159c0 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 29 7b  c() (or 0) */.){
159d0 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
159e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
159f0 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 63 61     /* Used to ca
15a00 74 63 68 20 72 65 74 75 72 6e 20 63 6f 64 65 73  tch return codes
15a10 20 2a 2f 0a 20 20 75 33 32 20 69 46 72 61 6d 65   */.  u32 iFrame
15a20 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
15a30 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 66 72        /* Next fr
15a40 61 6d 65 20 61 64 64 72 65 73 73 20 2a 2f 0a 20  ame address */. 
15a50 20 75 38 20 61 46 72 61 6d 65 5b 57 41 4c 5f 46   u8 aFrame[WAL_F
15a60 52 41 4d 45 5f 48 44 52 53 49 5a 45 5d 3b 20 20  RAME_HDRSIZE];  
15a70 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 61 73   /* Buffer to as
15a80 73 65 6d 62 6c 65 20 66 72 61 6d 65 2d 68 65 61  semble frame-hea
15a90 64 65 72 20 69 6e 20 2a 2f 0a 20 20 50 67 48 64  der in */.  PgHd
15aa0 72 20 2a 70 3b 20 20 20 20 20 20 20 20 20 20 20  r *p;           
15ab0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
15ac0 74 65 72 61 74 6f 72 20 74 6f 20 72 75 6e 20 74  terator to run t
15ad0 68 72 6f 75 67 68 20 70 4c 69 73 74 20 77 69 74  hrough pList wit
15ae0 68 2e 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70  h. */.  PgHdr *p
15af0 4c 61 73 74 20 3d 20 30 3b 20 20 20 20 20 20 20  Last = 0;       
15b00 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 73 74 20          /* Last 
15b10 66 72 61 6d 65 20 69 6e 20 6c 69 73 74 20 2a 2f  frame in list */
15b20 0a 20 20 69 6e 74 20 6e 4c 61 73 74 20 3d 20 30  .  int nLast = 0
15b30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
15b40 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
15b50 65 78 74 72 61 20 63 6f 70 69 65 73 20 6f 66 20  extra copies of 
15b60 6c 61 73 74 20 70 61 67 65 20 2a 2f 0a 0a 20 20  last page */..  
15b70 61 73 73 65 72 74 28 20 70 4c 69 73 74 20 29 3b  assert( pList );
15b80 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
15b90 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 0a 23  >writeLock );..#
15ba0 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  if defined(SQLIT
15bb0 45 5f 54 45 53 54 29 20 26 26 20 64 65 66 69 6e  E_TEST) && defin
15bc0 65 64 28 53 51 4c 49 54 45 5f 44 45 42 55 47 29  ed(SQLITE_DEBUG)
15bd0 0a 20 20 7b 20 69 6e 74 20 63 6e 74 3b 20 66 6f  .  { int cnt; fo
15be0 72 28 63 6e 74 3d 30 2c 20 70 3d 70 4c 69 73 74  r(cnt=0, p=pList
15bf0 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79  ; p; p=p->pDirty
15c00 2c 20 63 6e 74 2b 2b 29 7b 7d 0a 20 20 20 20 57  , cnt++){}.    W
15c10 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
15c20 20 66 72 61 6d 65 20 77 72 69 74 65 20 62 65 67   frame write beg
15c30 69 6e 2e 20 25 64 20 66 72 61 6d 65 73 2e 20 6d  in. %d frames. m
15c40 78 46 72 61 6d 65 3d 25 64 2e 20 25 73 5c 6e 22  xFrame=%d. %s\n"
15c50 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
15c60 70 57 61 6c 2c 20 63 6e 74 2c 20 70 57 61 6c 2d  pWal, cnt, pWal-
15c70 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2c 20 69 73  >hdr.mxFrame, is
15c80 43 6f 6d 6d 69 74 20 3f 20 22 43 6f 6d 6d 69 74  Commit ? "Commit
15c90 22 20 3a 20 22 53 70 69 6c 6c 22 29 29 3b 0a 20  " : "Spill"));. 
15ca0 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2f 2a 20   }.#endif..  /* 
15cb0 53 65 65 20 69 66 20 69 74 20 69 73 20 70 6f 73  See if it is pos
15cc0 73 69 62 6c 65 20 74 6f 20 77 72 69 74 65 20 74  sible to write t
15cd0 68 65 73 65 20 66 72 61 6d 65 73 20 69 6e 74 6f  hese frames into
15ce0 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
15cf0 65 0a 20 20 2a 2a 20 6c 6f 67 20 66 69 6c 65 2c  e.  ** log file,
15d00 20 69 6e 73 74 65 61 64 20 6f 66 20 61 70 70 65   instead of appe
15d10 6e 64 69 6e 67 20 74 6f 20 69 74 20 61 74 20 70  nding to it at p
15d20 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
15d30 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 53 51 4c  ..  */.  if( SQL
15d40 49 54 45 5f 4f 4b 21 3d 28 72 63 20 3d 20 77 61  ITE_OK!=(rc = wa
15d50 6c 52 65 73 74 61 72 74 4c 6f 67 28 70 57 61 6c  lRestartLog(pWal
15d60 29 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  )) ){.    return
15d70 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49   rc;.  }..  /* I
15d80 66 20 74 68 69 73 20 69 73 20 74 68 65 20 66 69  f this is the fi
15d90 72 73 74 20 66 72 61 6d 65 20 77 72 69 74 74 65  rst frame writte
15da0 6e 20 69 6e 74 6f 20 74 68 65 20 6c 6f 67 2c 20  n into the log, 
15db0 77 72 69 74 65 20 74 68 65 20 57 41 4c 0a 20 20  write the WAL.  
15dc0 2a 2a 20 68 65 61 64 65 72 20 74 6f 20 74 68 65  ** header to the
15dd0 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 57 41   start of the WA
15de0 4c 20 66 69 6c 65 2e 20 53 65 65 20 63 6f 6d 6d  L file. See comm
15df0 65 6e 74 73 20 61 74 20 74 68 65 20 74 6f 70 20  ents at the top 
15e00 6f 66 0a 20 20 2a 2a 20 74 68 69 73 20 73 6f 75  of.  ** this sou
15e10 72 63 65 20 66 69 6c 65 20 66 6f 72 20 61 20 64  rce file for a d
15e20 65 73 63 72 69 70 74 69 6f 6e 20 6f 66 20 74 68  escription of th
15e30 65 20 57 41 4c 20 68 65 61 64 65 72 20 66 6f 72  e WAL header for
15e40 6d 61 74 2e 0a 20 20 2a 2f 0a 20 20 69 46 72 61  mat..  */.  iFra
15e50 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  me = pWal->hdr.m
15e60 78 46 72 61 6d 65 3b 0a 20 20 69 66 28 20 69 46  xFrame;.  if( iF
15e70 72 61 6d 65 3d 3d 30 20 29 7b 0a 20 20 20 20 75  rame==0 ){.    u
15e80 38 20 61 57 61 6c 48 64 72 5b 57 41 4c 5f 48 44  8 aWalHdr[WAL_HD
15e90 52 53 49 5a 45 5d 3b 20 20 20 20 20 20 2f 2a 20  RSIZE];      /* 
15ea0 42 75 66 66 65 72 20 74 6f 20 61 73 73 65 6d 62  Buffer to assemb
15eb0 6c 65 20 77 61 6c 2d 68 65 61 64 65 72 20 69 6e  le wal-header in
15ec0 20 2a 2f 0a 20 20 20 20 75 33 32 20 61 43 6b 73   */.    u32 aCks
15ed0 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  um[2];          
15ee0 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 73 75        /* Checksu
15ef0 6d 20 66 6f 72 20 77 61 6c 2d 68 65 61 64 65 72  m for wal-header
15f00 20 2a 2f 0a 0a 20 20 20 20 73 71 6c 69 74 65 33   */..    sqlite3
15f10 50 75 74 34 62 79 74 65 28 26 61 57 61 6c 48 64  Put4byte(&aWalHd
15f20 72 5b 30 5d 2c 20 28 57 41 4c 5f 4d 41 47 49 43  r[0], (WAL_MAGIC
15f30 20 7c 20 53 51 4c 49 54 45 5f 42 49 47 45 4e 44   | SQLITE_BIGEND
15f40 49 41 4e 29 29 3b 0a 20 20 20 20 73 71 6c 69 74  IAN));.    sqlit
15f50 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c  e3Put4byte(&aWal
15f60 48 64 72 5b 34 5d 2c 20 57 41 4c 5f 4d 41 58 5f  Hdr[4], WAL_MAX_
15f70 56 45 52 53 49 4f 4e 29 3b 0a 20 20 20 20 73 71  VERSION);.    sq
15f80 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61  lite3Put4byte(&a
15f90 57 61 6c 48 64 72 5b 38 5d 2c 20 73 7a 50 61 67  WalHdr[8], szPag
15fa0 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50  e);.    sqlite3P
15fb0 75 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72  ut4byte(&aWalHdr
15fc0 5b 31 32 5d 2c 20 70 57 61 6c 2d 3e 6e 43 6b 70  [12], pWal->nCkp
15fd0 74 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26  t);.    memcpy(&
15fe0 61 57 61 6c 48 64 72 5b 31 36 5d 2c 20 70 57 61  aWalHdr[16], pWa
15ff0 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 38 29  l->hdr.aSalt, 8)
16000 3b 0a 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75  ;.    walChecksu
16010 6d 42 79 74 65 73 28 31 2c 20 61 57 61 6c 48 64  mBytes(1, aWalHd
16020 72 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2d 32  r, WAL_HDRSIZE-2
16030 2a 34 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b 0a  *4, 0, aCksum);.
16040 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62      sqlite3Put4b
16050 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32 34 5d  yte(&aWalHdr[24]
16060 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b 0a 20 20  , aCksum[0]);.  
16070 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74    sqlite3Put4byt
16080 65 28 26 61 57 61 6c 48 64 72 5b 32 38 5d 2c 20  e(&aWalHdr[28], 
16090 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 20 20 20 20  aCksum[1]);.    
160a0 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50 61 67  .    pWal->szPag
160b0 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20  e = szPage;.    
160c0 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64  pWal->hdr.bigEnd
160d0 43 6b 73 75 6d 20 3d 20 53 51 4c 49 54 45 5f 42  Cksum = SQLITE_B
160e0 49 47 45 4e 44 49 41 4e 3b 0a 20 20 20 20 70 57  IGENDIAN;.    pW
160f0 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
16100 73 75 6d 5b 30 5d 20 3d 20 61 43 6b 73 75 6d 5b  sum[0] = aCksum[
16110 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64  0];.    pWal->hd
16120 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d  r.aFrameCksum[1]
16130 20 3d 20 61 43 6b 73 75 6d 5b 31 5d 3b 0a 0a 20   = aCksum[1];.. 
16140 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
16150 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 57 61  sWrite(pWal->pWa
16160 6c 46 64 2c 20 61 57 61 6c 48 64 72 2c 20 73 69  lFd, aWalHdr, si
16170 7a 65 6f 66 28 61 57 61 6c 48 64 72 29 2c 20 30  zeof(aWalHdr), 0
16180 29 3b 0a 20 20 20 20 57 41 4c 54 52 41 43 45 28  );.    WALTRACE(
16190 28 22 57 41 4c 25 70 3a 20 77 61 6c 2d 68 65 61  ("WAL%p: wal-hea
161a0 64 65 72 20 77 72 69 74 65 20 25 73 5c 6e 22 2c  der write %s\n",
161b0 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69   pWal, rc ? "fai
161c0 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
161d0 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
161e0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65  E_OK ){.      re
161f0 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20  turn rc;.    }. 
16200 20 7d 0a 20 20 61 73 73 65 72 74 28 20 70 57 61   }.  assert( pWa
16210 6c 2d 3e 73 7a 50 61 67 65 3d 3d 73 7a 50 61 67  l->szPage==szPag
16220 65 20 29 3b 0a 0a 20 20 2f 2a 20 57 72 69 74 65  e );..  /* Write
16230 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 20 2a   the log file. *
16240 2f 0a 20 20 66 6f 72 28 70 3d 70 4c 69 73 74 3b  /.  for(p=pList;
16250 20 70 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 29   p; p=p->pDirty)
16260 7b 0a 20 20 20 20 75 33 32 20 6e 44 62 73 69 7a  {.    u32 nDbsiz
16270 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
16280 20 20 20 20 2f 2a 20 44 62 2d 73 69 7a 65 20 66      /* Db-size f
16290 69 65 6c 64 20 66 6f 72 20 66 72 61 6d 65 20 68  ield for frame h
162a0 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 69 36 34  eader */.    i64
162b0 20 69 4f 66 66 73 65 74 3b 20 20 20 20 20 20 20   iOffset;       
162c0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 72             /* Wr
162d0 69 74 65 20 6f 66 66 73 65 74 20 69 6e 20 6c 6f  ite offset in lo
162e0 67 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 76 6f  g file */.    vo
162f0 69 64 20 2a 70 44 61 74 61 3b 0a 20 20 20 0a 20  id *pData;.   . 
16300 20 20 0a 20 20 20 20 69 4f 66 66 73 65 74 20 3d    .    iOffset =
16310 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28   walFrameOffset(
16320 2b 2b 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65  ++iFrame, szPage
16330 29 3b 0a 20 20 20 20 0a 20 20 20 20 2f 2a 20 50  );.    .    /* P
16340 6f 70 75 6c 61 74 65 20 61 6e 64 20 77 72 69 74  opulate and writ
16350 65 20 74 68 65 20 66 72 61 6d 65 20 68 65 61 64  e the frame head
16360 65 72 20 2a 2f 0a 20 20 20 20 6e 44 62 73 69 7a  er */.    nDbsiz
16370 65 20 3d 20 28 69 73 43 6f 6d 6d 69 74 20 26 26  e = (isCommit &&
16380 20 70 2d 3e 70 44 69 72 74 79 3d 3d 30 29 20 3f   p->pDirty==0) ?
16390 20 6e 54 72 75 6e 63 61 74 65 20 3a 20 30 3b 0a   nTruncate : 0;.
163a0 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49  #if defined(SQLI
163b0 54 45 5f 48 41 53 5f 43 4f 44 45 43 29 0a 20 20  TE_HAS_CODEC).  
163c0 20 20 69 66 28 20 28 70 44 61 74 61 20 3d 20 73    if( (pData = s
163d0 71 6c 69 74 65 33 50 61 67 65 72 43 6f 64 65 63  qlite3PagerCodec
163e0 28 70 29 29 3d 3d 30 20 29 20 72 65 74 75 72 6e  (p))==0 ) return
163f0 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 23   SQLITE_NOMEM;.#
16400 65 6c 73 65 0a 20 20 20 20 70 44 61 74 61 20 3d  else.    pData =
16410 20 70 2d 3e 70 44 61 74 61 3b 0a 23 65 6e 64 69   p->pData;.#endi
16420 66 0a 20 20 20 20 77 61 6c 45 6e 63 6f 64 65 46  f.    walEncodeF
16430 72 61 6d 65 28 70 57 61 6c 2c 20 70 2d 3e 70 67  rame(pWal, p->pg
16440 6e 6f 2c 20 6e 44 62 73 69 7a 65 2c 20 70 44 61  no, nDbsize, pDa
16450 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20 20  ta, aFrame);.   
16460 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57   rc = sqlite3OsW
16470 72 69 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46  rite(pWal->pWalF
16480 64 2c 20 61 46 72 61 6d 65 2c 20 73 69 7a 65 6f  d, aFrame, sizeo
16490 66 28 61 46 72 61 6d 65 29 2c 20 69 4f 66 66 73  f(aFrame), iOffs
164a0 65 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21  et);.    if( rc!
164b0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
164c0 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
164d0 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 57 72 69     }..    /* Wri
164e0 74 65 20 74 68 65 20 70 61 67 65 20 64 61 74 61  te the page data
164f0 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   */.    rc = sql
16500 69 74 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c  ite3OsWrite(pWal
16510 2d 3e 70 57 61 6c 46 64 2c 20 70 44 61 74 61 2c  ->pWalFd, pData,
16520 20 73 7a 50 61 67 65 2c 20 69 4f 66 66 73 65 74   szPage, iOffset
16530 2b 73 69 7a 65 6f 66 28 61 46 72 61 6d 65 29 29  +sizeof(aFrame))
16540 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
16550 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
16560 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
16570 7d 0a 20 20 20 20 70 4c 61 73 74 20 3d 20 70 3b  }.    pLast = p;
16580 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 79 6e 63 20  .  }..  /* Sync 
16590 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 69 66 20  the log file if 
165a0 74 68 65 20 27 69 73 53 79 6e 63 27 20 66 6c 61  the 'isSync' fla
165b0 67 20 77 61 73 20 73 70 65 63 69 66 69 65 64 2e  g was specified.
165c0 20 2a 2f 0a 20 20 69 66 28 20 73 79 6e 63 5f 66   */.  if( sync_f
165d0 6c 61 67 73 20 29 7b 0a 20 20 20 20 69 36 34 20  lags ){.    i64 
165e0 69 53 65 67 6d 65 6e 74 20 3d 20 73 71 6c 69 74  iSegment = sqlit
165f0 65 33 4f 73 53 65 63 74 6f 72 53 69 7a 65 28 70  e3OsSectorSize(p
16600 57 61 6c 2d 3e 70 57 61 6c 46 64 29 3b 0a 20 20  Wal->pWalFd);.  
16610 20 20 69 36 34 20 69 4f 66 66 73 65 74 20 3d 20    i64 iOffset = 
16620 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69  walFrameOffset(i
16630 46 72 61 6d 65 2b 31 2c 20 73 7a 50 61 67 65 29  Frame+1, szPage)
16640 3b 0a 0a 20 20 20 20 61 73 73 65 72 74 28 20 69  ;..    assert( i
16650 73 43 6f 6d 6d 69 74 20 29 3b 0a 20 20 20 20 61  sCommit );.    a
16660 73 73 65 72 74 28 20 69 53 65 67 6d 65 6e 74 3e  ssert( iSegment>
16670 30 20 29 3b 0a 0a 20 20 20 20 69 53 65 67 6d 65  0 );..    iSegme
16680 6e 74 20 3d 20 28 28 28 69 4f 66 66 73 65 74 2b  nt = (((iOffset+
16690 69 53 65 67 6d 65 6e 74 2d 31 29 2f 69 53 65 67  iSegment-1)/iSeg
166a0 6d 65 6e 74 29 20 2a 20 69 53 65 67 6d 65 6e 74  ment) * iSegment
166b0 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 4f  );.    while( iO
166c0 66 66 73 65 74 3c 69 53 65 67 6d 65 6e 74 20 29  ffset<iSegment )
166d0 7b 0a 20 20 20 20 20 20 76 6f 69 64 20 2a 70 44  {.      void *pD
166e0 61 74 61 3b 0a 23 69 66 20 64 65 66 69 6e 65 64  ata;.#if defined
166f0 28 53 51 4c 49 54 45 5f 48 41 53 5f 43 4f 44 45  (SQLITE_HAS_CODE
16700 43 29 0a 20 20 20 20 20 20 69 66 28 20 28 70 44  C).      if( (pD
16710 61 74 61 20 3d 20 73 71 6c 69 74 65 33 50 61 67  ata = sqlite3Pag
16720 65 72 43 6f 64 65 63 28 70 4c 61 73 74 29 29 3d  erCodec(pLast))=
16730 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
16740 54 45 5f 4e 4f 4d 45 4d 3b 0a 23 65 6c 73 65 0a  TE_NOMEM;.#else.
16750 20 20 20 20 20 20 70 44 61 74 61 20 3d 20 70 4c        pData = pL
16760 61 73 74 2d 3e 70 44 61 74 61 3b 0a 23 65 6e 64  ast->pData;.#end
16770 69 66 0a 20 20 20 20 20 20 77 61 6c 45 6e 63 6f  if.      walEnco
16780 64 65 46 72 61 6d 65 28 70 57 61 6c 2c 20 70 4c  deFrame(pWal, pL
16790 61 73 74 2d 3e 70 67 6e 6f 2c 20 6e 54 72 75 6e  ast->pgno, nTrun
167a0 63 61 74 65 2c 20 70 44 61 74 61 2c 20 61 46 72  cate, pData, aFr
167b0 61 6d 65 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  ame);.      rc =
167c0 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28   sqlite3OsWrite(
167d0 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 46  pWal->pWalFd, aF
167e0 72 61 6d 65 2c 20 73 69 7a 65 6f 66 28 61 46 72  rame, sizeof(aFr
167f0 61 6d 65 29 2c 20 69 4f 66 66 73 65 74 29 3b 0a  ame), iOffset);.
16800 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
16810 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
16820 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
16830 20 20 20 20 7d 0a 20 20 20 20 20 20 69 4f 66 66      }.      iOff
16840 73 65 74 20 2b 3d 20 57 41 4c 5f 46 52 41 4d 45  set += WAL_FRAME
16850 5f 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 20 20  _HDRSIZE;.      
16860 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72  rc = sqlite3OsWr
16870 69 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ite(pWal->pWalFd
16880 2c 20 70 44 61 74 61 2c 20 73 7a 50 61 67 65 2c  , pData, szPage,
16890 20 69 4f 66 66 73 65 74 29 3b 20 0a 20 20 20 20   iOffset); .    
168a0 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
168b0 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
168c0 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20  eturn rc;.      
168d0 7d 0a 20 20 20 20 20 20 6e 4c 61 73 74 2b 2b 3b  }.      nLast++;
168e0 0a 20 20 20 20 20 20 69 4f 66 66 73 65 74 20 2b  .      iOffset +
168f0 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 7d 0a  = szPage;.    }.
16900 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
16910 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57  3OsSync(pWal->pW
16920 61 6c 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73  alFd, sync_flags
16930 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 70 70  );.  }..  /* App
16940 65 6e 64 20 64 61 74 61 20 74 6f 20 74 68 65 20  end data to the 
16950 77 61 6c 2d 69 6e 64 65 78 2e 20 49 74 20 69 73  wal-index. It is
16960 20 6e 6f 74 20 6e 65 63 65 73 73 61 72 79 20 74   not necessary t
16970 6f 20 6c 6f 63 6b 20 74 68 65 20 0a 20 20 2a 2a  o lock the .  **
16980 20 77 61 6c 2d 69 6e 64 65 78 20 74 6f 20 64 6f   wal-index to do
16990 20 74 68 69 73 20 61 73 20 74 68 65 20 53 51 4c   this as the SQL
169a0 49 54 45 5f 53 48 4d 5f 57 52 49 54 45 20 6c 6f  ITE_SHM_WRITE lo
169b0 63 6b 20 68 65 6c 64 20 6f 6e 20 74 68 65 20 77  ck held on the w
169c0 61 6c 2d 69 6e 64 65 78 0a 20 20 2a 2a 20 67 75  al-index.  ** gu
169d0 61 72 61 6e 74 65 65 73 20 74 68 61 74 20 74 68  arantees that th
169e0 65 72 65 20 61 72 65 20 6e 6f 20 6f 74 68 65 72  ere are no other
169f0 20 77 72 69 74 65 72 73 2c 20 61 6e 64 20 6e 6f   writers, and no
16a00 20 64 61 74 61 20 74 68 61 74 20 6d 61 79 0a 20   data that may. 
16a10 20 2a 2a 20 62 65 20 69 6e 20 75 73 65 20 62 79   ** be in use by
16a20 20 65 78 69 73 74 69 6e 67 20 72 65 61 64 65 72   existing reader
16a30 73 20 69 73 20 62 65 69 6e 67 20 6f 76 65 72 77  s is being overw
16a40 72 69 74 74 65 6e 2e 0a 20 20 2a 2f 0a 20 20 69  ritten..  */.  i
16a50 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64  Frame = pWal->hd
16a60 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 66 6f 72  r.mxFrame;.  for
16a70 28 70 3d 70 4c 69 73 74 3b 20 70 20 26 26 20 72  (p=pList; p && r
16a80 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 70 3d  c==SQLITE_OK; p=
16a90 70 2d 3e 70 44 69 72 74 79 29 7b 0a 20 20 20 20  p->pDirty){.    
16aa0 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 72 63  iFrame++;.    rc
16ab0 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e   = walIndexAppen
16ac0 64 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c 20  d(pWal, iFrame, 
16ad0 70 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 20 20  p->pgno);.  }.  
16ae0 77 68 69 6c 65 28 20 6e 4c 61 73 74 3e 30 20 26  while( nLast>0 &
16af0 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  & rc==SQLITE_OK 
16b00 29 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b 2b 3b  ){.    iFrame++;
16b10 0a 20 20 20 20 6e 4c 61 73 74 2d 2d 3b 0a 20 20  .    nLast--;.  
16b20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 41    rc = walIndexA
16b30 70 70 65 6e 64 28 70 57 61 6c 2c 20 69 46 72 61  ppend(pWal, iFra
16b40 6d 65 2c 20 70 4c 61 73 74 2d 3e 70 67 6e 6f 29  me, pLast->pgno)
16b50 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
16b60 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
16b70 20 20 2f 2a 20 55 70 64 61 74 65 20 74 68 65 20    /* Update the 
16b80 70 72 69 76 61 74 65 20 63 6f 70 79 20 6f 66 20  private copy of 
16b90 74 68 65 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20  the header. */. 
16ba0 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50     pWal->hdr.szP
16bb0 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20  age = szPage;.  
16bc0 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72    pWal->hdr.mxFr
16bd0 61 6d 65 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20  ame = iFrame;.  
16be0 20 20 69 66 28 20 69 73 43 6f 6d 6d 69 74 20 29    if( isCommit )
16bf0 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64  {.      pWal->hd
16c00 72 2e 69 43 68 61 6e 67 65 2b 2b 3b 0a 20 20 20  r.iChange++;.   
16c10 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61     pWal->hdr.nPa
16c20 67 65 20 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a  ge = nTruncate;.
16c30 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20 49 66 20      }.    /* If 
16c40 74 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74  this is a commit
16c50 2c 20 75 70 64 61 74 65 20 74 68 65 20 77 61 6c  , update the wal
16c60 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f  -index header to
16c70 6f 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 69 73  o. */.    if( is
16c80 43 6f 6d 6d 69 74 20 29 7b 0a 20 20 20 20 20 20  Commit ){.      
16c90 77 61 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72  walIndexWriteHdr
16ca0 28 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 70 57  (pWal);.      pW
16cb0 61 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20  al->iCallback = 
16cc0 69 46 72 61 6d 65 3b 0a 20 20 20 20 7d 0a 20 20  iFrame;.    }.  
16cd0 7d 0a 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  }..  WALTRACE(("
16ce0 57 41 4c 25 70 3a 20 66 72 61 6d 65 20 77 72 69  WAL%p: frame wri
16cf0 74 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20  te %s\n", pWal, 
16d00 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20  rc ? "failed" : 
16d10 22 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75 72 6e  "ok"));.  return
16d20 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54   rc;.}../* .** T
16d30 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63  his routine is c
16d40 61 6c 6c 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65  alled to impleme
16d50 6e 74 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63  nt sqlite3_wal_c
16d60 68 65 63 6b 70 6f 69 6e 74 28 29 20 61 6e 64 0a  heckpoint() and.
16d70 2a 2a 20 72 65 6c 61 74 65 64 20 69 6e 74 65 72  ** related inter
16d80 66 61 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74  faces..**.** Obt
16d90 61 69 6e 20 61 20 43 48 45 43 4b 50 4f 49 4e 54  ain a CHECKPOINT
16da0 20 6c 6f 63 6b 20 61 6e 64 20 74 68 65 6e 20 62   lock and then b
16db0 61 63 6b 66 69 6c 6c 20 61 73 20 6d 75 63 68 20  ackfill as much 
16dc0 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 73 0a 2a  information as.*
16dd0 2a 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 57 41  * we can from WA
16de0 4c 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  L into the datab
16df0 61 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ase..*/.int sqli
16e00 74 65 33 57 61 6c 43 68 65 63 6b 70 6f 69 6e 74  te3WalCheckpoint
16e10 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20  (.  Wal *pWal,  
16e20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16e30 20 20 20 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65      /* Wal conne
16e40 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 73  ction */.  int s
16e50 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20  ync_flags,      
16e60 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c             /* Fl
16e70 61 67 73 20 74 6f 20 73 79 6e 63 20 64 62 20 66  ags to sync db f
16e80 69 6c 65 20 77 69 74 68 20 28 6f 72 20 30 29 20  ile with (or 0) 
16e90 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20  */.  int nBuf,  
16ea0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16eb0 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
16ec0 74 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72  temporary buffer
16ed0 20 2a 2f 0a 20 20 75 38 20 2a 7a 42 75 66 20 20   */.  u8 *zBuf  
16ee0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16ef0 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61        /* Tempora
16f00 72 79 20 62 75 66 66 65 72 20 74 6f 20 75 73 65  ry buffer to use
16f10 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b   */.){.  int rc;
16f20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16f30 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
16f40 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74  rn code */.  int
16f50 20 69 73 43 68 61 6e 67 65 64 20 3d 20 30 3b 20   isChanged = 0; 
16f60 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
16f70 54 72 75 65 20 69 66 20 61 20 6e 65 77 20 77 61  True if a new wa
16f80 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69  l-index header i
16f90 73 20 6c 6f 61 64 65 64 20 2a 2f 0a 0a 20 20 61  s loaded */..  a
16fa0 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 63 6b 70  ssert( pWal->ckp
16fb0 74 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 0a 20 20 57  tLock==0 );..  W
16fc0 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
16fd0 20 63 68 65 63 6b 70 6f 69 6e 74 20 62 65 67 69   checkpoint begi
16fe0 6e 73 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 20  ns\n", pWal));. 
16ff0 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63   rc = walLockExc
17000 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
17010 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  _CKPT_LOCK, 1);.
17020 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20    if( rc ){.    
17030 2f 2a 20 55 73 75 61 6c 6c 79 20 74 68 69 73 20  /* Usually this 
17040 69 73 20 53 51 4c 49 54 45 5f 42 55 53 59 20 6d  is SQLITE_BUSY m
17050 65 61 6e 69 6e 67 20 74 68 61 74 20 61 6e 6f 74  eaning that anot
17060 68 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72  her thread or pr
17070 6f 63 65 73 73 0a 20 20 20 20 2a 2a 20 69 73 20  ocess.    ** is 
17080 61 6c 72 65 61 64 79 20 72 75 6e 6e 69 6e 67 20  already running 
17090 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c 20 6f 72  a checkpoint, or
170a0 20 6d 61 79 62 65 20 61 20 72 65 63 6f 76 65 72   maybe a recover
170b0 79 2e 20 20 42 75 74 20 69 74 20 6d 69 67 68 74  y.  But it might
170c0 0a 20 20 20 20 2a 2a 20 61 6c 73 6f 20 62 65 20  .    ** also be 
170d0 53 51 4c 49 54 45 5f 49 4f 45 52 52 2e 20 2a 2f  SQLITE_IOERR. */
170e0 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
170f0 20 20 7d 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74    }.  pWal->ckpt
17100 4c 6f 63 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20  Lock = 1;..  /* 
17110 43 6f 70 79 20 64 61 74 61 20 66 72 6f 6d 20 74  Copy data from t
17120 68 65 20 6c 6f 67 20 74 6f 20 74 68 65 20 64 61  he log to the da
17130 74 61 62 61 73 65 20 66 69 6c 65 2e 20 2a 2f 0a  tabase file. */.
17140 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52    rc = walIndexR
17150 65 61 64 48 64 72 28 70 57 61 6c 2c 20 26 69 73  eadHdr(pWal, &is
17160 43 68 61 6e 67 65 64 29 3b 0a 20 20 69 66 28 20  Changed);.  if( 
17170 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
17180 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 43 68 65  .    rc = walChe
17190 63 6b 70 6f 69 6e 74 28 70 57 61 6c 2c 20 73 79  ckpoint(pWal, sy
171a0 6e 63 5f 66 6c 61 67 73 2c 20 6e 42 75 66 2c 20  nc_flags, nBuf, 
171b0 7a 42 75 66 29 3b 0a 20 20 7d 0a 20 20 69 66 28  zBuf);.  }.  if(
171c0 20 69 73 43 68 61 6e 67 65 64 20 29 7b 0a 20 20   isChanged ){.  
171d0 20 20 2f 2a 20 49 66 20 61 20 6e 65 77 20 77 61    /* If a new wa
171e0 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 77  l-index header w
171f0 61 73 20 6c 6f 61 64 65 64 20 62 65 66 6f 72 65  as loaded before
17200 20 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20   the checkpoint 
17210 77 61 73 20 0a 20 20 20 20 2a 2a 20 70 65 72 66  was .    ** perf
17220 6f 72 6d 65 64 2c 20 74 68 65 6e 20 74 68 65 20  ormed, then the 
17230 70 61 67 65 72 2d 63 61 63 68 65 20 61 73 73 6f  pager-cache asso
17240 63 69 61 74 65 64 20 77 69 74 68 20 70 57 61 6c  ciated with pWal
17250 20 69 73 20 6e 6f 77 0a 20 20 20 20 2a 2a 20 6f   is now.    ** o
17260 75 74 20 6f 66 20 64 61 74 65 2e 20 53 6f 20 7a  ut of date. So z
17270 65 72 6f 20 74 68 65 20 63 61 63 68 65 64 20 77  ero the cached w
17280 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
17290 74 6f 20 65 6e 73 75 72 65 20 74 68 61 74 0a 20  to ensure that. 
172a0 20 20 20 2a 2a 20 6e 65 78 74 20 74 69 6d 65 20     ** next time 
172b0 74 68 65 20 70 61 67 65 72 20 6f 70 65 6e 73 20  the pager opens 
172c0 61 20 73 6e 61 70 73 68 6f 74 20 6f 6e 20 74 68  a snapshot on th
172d0 69 73 20 64 61 74 61 62 61 73 65 20 69 74 20 6b  is database it k
172e0 6e 6f 77 73 20 74 68 61 74 0a 20 20 20 20 2a 2a  nows that.    **
172f0 20 74 68 65 20 63 61 63 68 65 20 6e 65 65 64 73   the cache needs
17300 20 74 6f 20 62 65 20 72 65 73 65 74 2e 0a 20 20   to be reset..  
17310 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 73 65 74 28    */.    memset(
17320 26 70 57 61 6c 2d 3e 68 64 72 2c 20 30 2c 20 73  &pWal->hdr, 0, s
17330 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64  izeof(WalIndexHd
17340 72 29 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52  r));.  }..  /* R
17350 65 6c 65 61 73 65 20 74 68 65 20 6c 6f 63 6b 73  elease the locks
17360 2e 20 2a 2f 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b  . */.  walUnlock
17370 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
17380 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31  WAL_CKPT_LOCK, 1
17390 29 3b 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74 4c  );.  pWal->ckptL
173a0 6f 63 6b 20 3d 20 30 3b 0a 20 20 57 41 4c 54 52  ock = 0;.  WALTR
173b0 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63 68 65  ACE(("WAL%p: che
173c0 63 6b 70 6f 69 6e 74 20 25 73 5c 6e 22 2c 20 70  ckpoint %s\n", p
173d0 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c 65  Wal, rc ? "faile
173e0 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 72  d" : "ok"));.  r
173f0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
17400 52 65 74 75 72 6e 20 74 68 65 20 76 61 6c 75 65  Return the value
17410 20 74 6f 20 70 61 73 73 20 74 6f 20 61 20 73 71   to pass to a sq
17420 6c 69 74 65 33 5f 77 61 6c 5f 68 6f 6f 6b 20 63  lite3_wal_hook c
17430 61 6c 6c 62 61 63 6b 2c 20 74 68 65 0a 2a 2a 20  allback, the.** 
17440 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d 65 73  number of frames
17450 20 69 6e 20 74 68 65 20 57 41 4c 20 61 74 20 74   in the WAL at t
17460 68 65 20 70 6f 69 6e 74 20 6f 66 20 74 68 65 20  he point of the 
17470 6c 61 73 74 20 63 6f 6d 6d 69 74 20 73 69 6e 63  last commit sinc
17480 65 0a 2a 2a 20 73 71 6c 69 74 65 33 57 61 6c 43  e.** sqlite3WalC
17490 61 6c 6c 62 61 63 6b 28 29 20 77 61 73 20 63 61  allback() was ca
174a0 6c 6c 65 64 2e 20 20 49 66 20 6e 6f 20 63 6f 6d  lled.  If no com
174b0 6d 69 74 73 20 68 61 76 65 20 6f 63 63 75 72 72  mits have occurr
174c0 65 64 20 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20  ed since.** the 
174d0 6c 61 73 74 20 63 61 6c 6c 2c 20 74 68 65 6e 20  last call, then 
174e0 72 65 74 75 72 6e 20 30 2e 0a 2a 2f 0a 69 6e 74  return 0..*/.int
174f0 20 73 71 6c 69 74 65 33 57 61 6c 43 61 6c 6c 62   sqlite3WalCallb
17500 61 63 6b 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ack(Wal *pWal){.
17510 20 20 75 33 32 20 72 65 74 20 3d 20 30 3b 0a 20    u32 ret = 0;. 
17520 20 69 66 28 20 70 57 61 6c 20 29 7b 0a 20 20 20   if( pWal ){.   
17530 20 72 65 74 20 3d 20 70 57 61 6c 2d 3e 69 43 61   ret = pWal->iCa
17540 6c 6c 62 61 63 6b 3b 0a 20 20 20 20 70 57 61 6c  llback;.    pWal
17550 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20 30 3b  ->iCallback = 0;
17560 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 28 69  .  }.  return (i
17570 6e 74 29 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  nt)ret;.}../*.**
17580 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
17590 73 20 63 61 6c 6c 65 64 20 74 6f 20 63 68 61 6e  s called to chan
175a0 67 65 20 74 68 65 20 57 41 4c 20 73 75 62 73 79  ge the WAL subsy
175b0 73 74 65 6d 20 69 6e 74 6f 20 6f 72 20 6f 75 74  stem into or out
175c0 0a 2a 2a 20 6f 66 20 6c 6f 63 6b 69 6e 67 5f 6d  .** of locking_m
175d0 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2e 0a 2a  ode=EXCLUSIVE..*
175e0 2a 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20 7a 65  *.** If op is ze
175f0 72 6f 2c 20 74 68 65 6e 20 61 74 74 65 6d 70 74  ro, then attempt
17600 20 74 6f 20 63 68 61 6e 67 65 20 66 72 6f 6d 20   to change from 
17610 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43  locking_mode=EXC
17620 4c 55 53 49 56 45 0a 2a 2a 20 69 6e 74 6f 20 6c  LUSIVE.** into l
17630 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d  ocking_mode=NORM
17640 41 4c 2e 20 20 54 68 69 73 20 6d 65 61 6e 73 20  AL.  This means 
17650 74 68 61 74 20 77 65 20 6d 75 73 74 20 61 63 71  that we must acq
17660 75 69 72 65 20 61 20 6c 6f 63 6b 0a 2a 2a 20 6f  uire a lock.** o
17670 6e 20 74 68 65 20 70 57 61 6c 2d 3e 72 65 61 64  n the pWal->read
17680 4c 6f 63 6b 20 62 79 74 65 2e 20 20 49 66 20 74  Lock byte.  If t
17690 68 65 20 57 41 4c 20 69 73 20 61 6c 72 65 61 64  he WAL is alread
176a0 79 20 69 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64  y in locking_mod
176b0 65 3d 4e 4f 52 4d 41 4c 0a 2a 2a 20 6f 72 20 69  e=NORMAL.** or i
176c0 66 20 74 68 65 20 61 63 71 75 69 73 69 74 69 6f  f the acquisitio
176d0 6e 20 6f 66 20 74 68 65 20 6c 6f 63 6b 20 66 61  n of the lock fa
176e0 69 6c 73 2c 20 74 68 65 6e 20 72 65 74 75 72 6e  ils, then return
176f0 20 30 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 74   0.  If the.** t
17700 72 61 6e 73 69 74 69 6f 6e 20 6f 75 74 20 6f 66  ransition out of
17710 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f 64 65 20   exclusive-mode 
17720 69 73 20 73 75 63 63 65 73 73 66 75 6c 2c 20 72  is successful, r
17730 65 74 75 72 6e 20 31 2e 20 20 54 68 69 73 0a 2a  eturn 1.  This.*
17740 2a 20 6f 70 65 72 61 74 69 6f 6e 20 6d 75 73 74  * operation must
17750 20 6f 63 63 75 72 20 77 68 69 6c 65 20 74 68 65   occur while the
17760 20 70 61 67 65 72 20 69 73 20 73 74 69 6c 6c 20   pager is still 
17770 68 6f 6c 64 69 6e 67 20 74 68 65 20 65 78 63 6c  holding the excl
17780 75 73 69 76 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e  usive.** lock on
17790 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61   the main databa
177a0 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49  se file..**.** I
177b0 66 20 6f 70 20 69 73 20 6f 6e 65 2c 20 74 68 65  f op is one, the
177c0 6e 20 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f  n change from lo
177d0 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41  cking_mode=NORMA
177e0 4c 20 69 6e 74 6f 20 0a 2a 2a 20 6c 6f 63 6b 69  L into .** locki
177f0 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56  ng_mode=EXCLUSIV
17800 45 2e 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74  E.  This means t
17810 68 61 74 20 74 68 65 20 70 57 61 6c 2d 3e 72 65  hat the pWal->re
17820 61 64 4c 6f 63 6b 20 6d 75 73 74 0a 2a 2a 20 62  adLock must.** b
17830 65 20 72 65 6c 65 61 73 65 64 2e 20 20 52 65 74  e released.  Ret
17840 75 72 6e 20 31 20 69 66 20 74 68 65 20 74 72 61  urn 1 if the tra
17850 6e 73 69 74 69 6f 6e 20 69 73 20 6d 61 64 65 20  nsition is made 
17860 61 6e 64 20 30 20 69 66 20 74 68 65 0a 2a 2a 20  and 0 if the.** 
17870 57 41 4c 20 69 73 20 61 6c 72 65 61 64 79 20 69  WAL is already i
17880 6e 20 65 78 63 6c 75 73 69 76 65 2d 6c 6f 63 6b  n exclusive-lock
17890 69 6e 67 20 6d 6f 64 65 20 2d 20 6d 65 61 6e 69  ing mode - meani
178a0 6e 67 20 74 68 61 74 20 74 68 69 73 0a 2a 2a 20  ng that this.** 
178b0 72 6f 75 74 69 6e 65 20 69 73 20 61 20 6e 6f 2d  routine is a no-
178c0 6f 70 2e 20 20 54 68 65 20 70 61 67 65 72 20 6d  op.  The pager m
178d0 75 73 74 20 61 6c 72 65 61 64 79 20 68 6f 6c 64  ust already hold
178e0 20 74 68 65 20 65 78 63 6c 75 73 69 76 65 20 6c   the exclusive l
178f0 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20 6d 61  ock.** on the ma
17900 69 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  in database file
17910 20 62 65 66 6f 72 65 20 69 6e 76 6f 6b 69 6e 67   before invoking
17920 20 74 68 69 73 20 6f 70 65 72 61 74 69 6f 6e 2e   this operation.
17930 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20  .**.** If op is 
17940 6e 65 67 61 74 69 76 65 2c 20 74 68 65 6e 20 64  negative, then d
17950 6f 20 61 20 64 72 79 2d 72 75 6e 20 6f 66 20 74  o a dry-run of t
17960 68 65 20 6f 70 3d 3d 31 20 63 61 73 65 20 62 75  he op==1 case bu
17970 74 20 64 6f 0a 2a 2a 20 6e 6f 74 20 61 63 74 75  t do.** not actu
17980 61 6c 6c 79 20 63 68 61 6e 67 65 20 61 6e 79 74  ally change anyt
17990 68 69 6e 67 2e 20 20 54 68 65 20 70 61 67 65 72  hing.  The pager
179a0 20 75 73 65 73 20 74 68 69 73 20 74 6f 20 73 65   uses this to se
179b0 65 20 69 66 20 69 74 0a 2a 2a 20 73 68 6f 75 6c  e if it.** shoul
179c0 64 20 61 63 71 75 69 72 65 20 74 68 65 20 64 61  d acquire the da
179d0 74 61 62 61 73 65 20 65 78 63 6c 75 73 69 76 65  tabase exclusive
179e0 20 6c 6f 63 6b 20 70 72 69 6f 72 20 74 6f 20 69   lock prior to i
179f0 6e 76 6f 6b 69 6e 67 0a 2a 2a 20 74 68 65 20 6f  nvoking.** the o
17a00 70 3d 3d 31 20 63 61 73 65 2e 0a 2a 2f 0a 69 6e  p==1 case..*/.in
17a10 74 20 73 71 6c 69 74 65 33 57 61 6c 45 78 63 6c  t sqlite3WalExcl
17a20 75 73 69 76 65 4d 6f 64 65 28 57 61 6c 20 2a 70  usiveMode(Wal *p
17a30 57 61 6c 2c 20 69 6e 74 20 6f 70 29 7b 0a 20 20  Wal, int op){.  
17a40 69 6e 74 20 72 63 3b 0a 20 20 61 73 73 65 72 74  int rc;.  assert
17a50 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
17a60 6b 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 70 57  k==0 );..  /* pW
17a70 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69 73 20  al->readLock is 
17a80 75 73 75 61 6c 6c 79 20 73 65 74 2c 20 62 75 74  usually set, but
17a90 20 6d 69 67 68 74 20 62 65 20 2d 31 20 69 66 20   might be -1 if 
17aa0 74 68 65 72 65 20 77 61 73 20 61 20 0a 20 20 2a  there was a .  *
17ab0 2a 20 70 72 69 6f 72 20 65 72 72 6f 72 20 77 68  * prior error wh
17ac0 69 6c 65 20 61 74 74 65 6d 70 74 69 6e 67 20 74  ile attempting t
17ad0 6f 20 61 63 71 75 69 72 65 20 61 72 65 20 72 65  o acquire are re
17ae0 61 64 2d 6c 6f 63 6b 2e 20 54 68 69 73 20 63 61  ad-lock. This ca
17af0 6e 6e 6f 74 20 0a 20 20 2a 2a 20 68 61 70 70 65  nnot .  ** happe
17b00 6e 20 69 66 20 74 68 65 20 63 6f 6e 6e 65 63 74  n if the connect
17b10 69 6f 6e 20 69 73 20 61 63 74 75 61 6c 6c 79 20  ion is actually 
17b20 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f 64  in exclusive mod
17b30 65 20 28 61 73 20 6e 6f 20 78 53 68 6d 4c 6f 63  e (as no xShmLoc
17b40 6b 0a 20 20 2a 2a 20 6c 6f 63 6b 73 20 61 72 65  k.  ** locks are
17b50 20 74 61 6b 65 6e 20 69 6e 20 74 68 69 73 20 63   taken in this c
17b60 61 73 65 29 2e 20 4e 6f 72 20 73 68 6f 75 6c 64  ase). Nor should
17b70 20 74 68 65 20 70 61 67 65 72 20 61 74 74 65 6d   the pager attem
17b80 70 74 20 74 6f 0a 20 20 2a 2a 20 75 70 67 72 61  pt to.  ** upgra
17b90 64 65 20 74 6f 20 65 78 63 6c 75 73 69 76 65 2d  de to exclusive-
17ba0 6d 6f 64 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73  mode following s
17bb0 75 63 68 20 61 6e 20 65 72 72 6f 72 2e 0a 20 20  uch an error..  
17bc0 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  */.  assert( pWa
17bd0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c  l->readLock>=0 |
17be0 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f  | pWal->lockErro
17bf0 72 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  r );.  assert( p
17c00 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30  Wal->readLock>=0
17c10 20 7c 7c 20 28 6f 70 3c 3d 30 20 26 26 20 70 57   || (op<=0 && pW
17c20 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  al->exclusiveMod
17c30 65 3d 3d 30 29 20 29 3b 0a 0a 20 20 69 66 28 20  e==0) );..  if( 
17c40 6f 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28  op==0 ){.    if(
17c50 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
17c60 4d 6f 64 65 20 29 7b 0a 20 20 20 20 20 20 70 57  Mode ){.      pW
17c70 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  al->exclusiveMod
17c80 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28  e = 0;.      if(
17c90 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70   walLockShared(p
17ca0 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
17cb0 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  CK(pWal->readLoc
17cc0 6b 29 29 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29  k))!=SQLITE_OK )
17cd0 7b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e  {.        pWal->
17ce0 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20  exclusiveMode = 
17cf0 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  1;.      }.     
17d00 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c   rc = pWal->excl
17d10 75 73 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20  usiveMode==0;.  
17d20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f    }else{.      /
17d30 2a 20 41 6c 72 65 61 64 79 20 69 6e 20 6c 6f 63  * Already in loc
17d40 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c  king_mode=NORMAL
17d50 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 30   */.      rc = 0
17d60 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20  ;.    }.  }else 
17d70 69 66 28 20 6f 70 3e 30 20 29 7b 0a 20 20 20 20  if( op>0 ){.    
17d80 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 65 78  assert( pWal->ex
17d90 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 20 29  clusiveMode==0 )
17da0 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 57  ;.    assert( pW
17db0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20  al->readLock>=0 
17dc0 29 3b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b  );.    walUnlock
17dd0 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c  Shared(pWal, WAL
17de0 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d  _READ_LOCK(pWal-
17df0 3e 72 65 61 64 4c 6f 63 6b 29 29 3b 0a 20 20 20  >readLock));.   
17e00 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
17e10 4d 6f 64 65 20 3d 20 31 3b 0a 20 20 20 20 72 63  Mode = 1;.    rc
17e20 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20   = 1;.  }else{. 
17e30 20 20 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78     rc = pWal->ex
17e40 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a  clusiveMode==0;.
17e50 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
17e60 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 23 69  .}..#endif /* #i
17e70 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
17e80 54 5f 57 41 4c 20 2a 2f 0a                       T_WAL */.