/ Hex Artifact Content
Login

Artifact dbca424f71678f663a286ab2a98f947af1d412a7:


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 2a 0a 2a 2a 20 54 68 65 20 73  ect..**.** The s
36a0: 7a 50 61 67 65 20 76 61 6c 75 65 20 63 61 6e 20  zPage value can 
36b0: 62 65 20 61 6e 79 20 70 6f 77 65 72 20 6f 66 20  be any power of 
36c0: 32 20 62 65 74 77 65 65 6e 20 35 31 32 20 61 6e  2 between 512 an
36d0: 64 20 33 32 37 36 38 2c 20 69 6e 63 6c 75 73 69  d 32768, inclusi
36e0: 76 65 2e 0a 2a 2a 20 4f 72 20 69 74 20 63 61 6e  ve..** Or it can
36f0: 20 62 65 20 31 20 74 6f 20 72 65 70 72 65 73 65   be 1 to represe
3700: 6e 74 20 61 20 36 35 35 33 36 2d 62 79 74 65 20  nt a 65536-byte 
3710: 70 61 67 65 2e 20 20 54 68 65 20 6c 61 74 74 65  page.  The latte
3720: 72 20 63 61 73 65 20 77 61 73 0a 2a 2a 20 61 64  r case was.** ad
3730: 64 65 64 20 69 6e 20 33 2e 37 2e 31 20 77 68 65  ded in 3.7.1 whe
3740: 6e 20 73 75 70 70 6f 72 74 20 66 6f 72 20 36 34  n support for 64
3750: 4b 20 70 61 67 65 73 20 77 61 73 20 61 64 64 65  K pages was adde
3760: 64 2e 20 20 0a 2a 2f 0a 73 74 72 75 63 74 20 57  d.  .*/.struct W
3770: 61 6c 49 6e 64 65 78 48 64 72 20 7b 0a 20 20 75  alIndexHdr {.  u
3780: 33 32 20 69 56 65 72 73 69 6f 6e 3b 20 20 20 20  32 iVersion;    
3790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
37a0: 2a 20 57 61 6c 2d 69 6e 64 65 78 20 76 65 72 73  * Wal-index vers
37b0: 69 6f 6e 20 2a 2f 0a 20 20 75 33 32 20 75 6e 75  ion */.  u32 unu
37c0: 73 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  sed;            
37d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 75 73           /* Unus
37e0: 65 64 20 28 70 61 64 64 69 6e 67 29 20 66 69 65  ed (padding) fie
37f0: 6c 64 20 2a 2f 0a 20 20 75 33 32 20 69 43 68 61  ld */.  u32 iCha
3800: 6e 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  nge;            
3810: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74          /* Count
3820: 65 72 20 69 6e 63 72 65 6d 65 6e 74 65 64 20 65  er incremented e
3830: 61 63 68 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ach transaction 
3840: 2a 2f 0a 20 20 75 38 20 69 73 49 6e 69 74 3b 20  */.  u8 isInit; 
3850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3860: 20 20 20 20 20 2f 2a 20 31 20 77 68 65 6e 20 69       /* 1 when i
3870: 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20  nitialized */.  
3880: 75 38 20 62 69 67 45 6e 64 43 6b 73 75 6d 3b 20  u8 bigEndCksum; 
3890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38a0: 2f 2a 20 54 72 75 65 20 69 66 20 63 68 65 63 6b  /* True if check
38b0: 73 75 6d 73 20 69 6e 20 57 41 4c 20 61 72 65 20  sums in WAL are 
38c0: 62 69 67 2d 65 6e 64 69 61 6e 20 2a 2f 0a 20 20  big-endian */.  
38d0: 75 31 36 20 73 7a 50 61 67 65 3b 20 20 20 20 20  u16 szPage;     
38e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38f0: 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  /* Database page
3900: 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 2e 20   size in bytes. 
3910: 31 3d 3d 36 34 4b 20 2a 2f 0a 20 20 75 33 32 20  1==64K */.  u32 
3920: 6d 78 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20  mxFrame;        
3930: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
3940: 6e 64 65 78 20 6f 66 20 6c 61 73 74 20 76 61 6c  ndex of last val
3950: 69 64 20 66 72 61 6d 65 20 69 6e 20 74 68 65 20  id frame in the 
3960: 57 41 4c 20 2a 2f 0a 20 20 75 33 32 20 6e 50 61  WAL */.  u32 nPa
3970: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
3980: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
3990: 20 6f 66 20 64 61 74 61 62 61 73 65 20 69 6e 20   of database in 
39a0: 70 61 67 65 73 20 2a 2f 0a 20 20 75 33 32 20 61  pages */.  u32 a
39b0: 46 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 3b 20 20  FrameCksum[2];  
39c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68             /* Ch
39d0: 65 63 6b 73 75 6d 20 6f 66 20 6c 61 73 74 20 66  ecksum of last f
39e0: 72 61 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20  rame in log */. 
39f0: 20 75 33 32 20 61 53 61 6c 74 5b 32 5d 3b 20 20   u32 aSalt[2];  
3a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a10: 20 2f 2a 20 54 77 6f 20 73 61 6c 74 20 76 61 6c   /* Two salt val
3a20: 75 65 73 20 63 6f 70 69 65 64 20 66 72 6f 6d 20  ues copied from 
3a30: 57 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a 20 20  WAL header */.  
3a40: 75 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20  u32 aCksum[2];  
3a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a60: 2f 2a 20 43 68 65 63 6b 73 75 6d 20 6f 76 65 72  /* Checksum over
3a70: 20 61 6c 6c 20 70 72 69 6f 72 20 66 69 65 6c 64   all prior field
3a80: 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41  s */.};../*.** A
3a90: 20 63 6f 70 79 20 6f 66 20 74 68 65 20 66 6f 6c   copy of the fol
3aa0: 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 6f 63  lowing object oc
3ab0: 63 75 72 73 20 69 6e 20 74 68 65 20 77 61 6c 2d  curs in the wal-
3ac0: 69 6e 64 65 78 20 69 6d 6d 65 64 69 61 74 65 6c  index immediatel
3ad0: 79 0a 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20 74  y.** following t
3ae0: 68 65 20 73 65 63 6f 6e 64 20 63 6f 70 79 20 6f  he second copy o
3af0: 66 20 74 68 65 20 57 61 6c 49 6e 64 65 78 48 64  f the WalIndexHd
3b00: 72 2e 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20  r.  This object 
3b10: 73 74 6f 72 65 73 0a 2a 2a 20 69 6e 66 6f 72 6d  stores.** inform
3b20: 61 74 69 6f 6e 20 75 73 65 64 20 62 79 20 63 68  ation used by ch
3b30: 65 63 6b 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20  eckpoint..**.** 
3b40: 6e 42 61 63 6b 66 69 6c 6c 20 69 73 20 74 68 65  nBackfill is the
3b50: 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d 65   number of frame
3b60: 73 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68 61  s in the WAL tha
3b70: 74 20 68 61 76 65 20 62 65 65 6e 20 77 72 69 74  t have been writ
3b80: 74 65 6e 0a 2a 2a 20 62 61 63 6b 20 69 6e 74 6f  ten.** back into
3b90: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 28   the database. (
3ba0: 57 65 20 63 61 6c 6c 20 74 68 65 20 61 63 74 20  We call the act 
3bb0: 6f 66 20 6d 6f 76 69 6e 67 20 63 6f 6e 74 65 6e  of moving conten
3bc0: 74 20 66 72 6f 6d 20 57 41 4c 20 74 6f 0a 2a 2a  t from WAL to.**
3bd0: 20 64 61 74 61 62 61 73 65 20 22 62 61 63 6b 66   database "backf
3be0: 69 6c 6c 69 6e 67 22 2e 29 20 20 54 68 65 20 6e  illing".)  The n
3bf0: 42 61 63 6b 66 69 6c 6c 20 6e 75 6d 62 65 72 20  Backfill number 
3c00: 69 73 20 6e 65 76 65 72 20 67 72 65 61 74 65 72  is never greater
3c10: 20 74 68 61 6e 0a 2a 2a 20 57 61 6c 49 6e 64 65   than.** WalInde
3c20: 78 48 64 72 2e 6d 78 46 72 61 6d 65 2e 20 20 6e  xHdr.mxFrame.  n
3c30: 42 61 63 6b 66 69 6c 6c 20 63 61 6e 20 6f 6e 6c  Backfill can onl
3c40: 79 20 62 65 20 69 6e 63 72 65 61 73 65 64 20 62  y be increased b
3c50: 79 20 74 68 72 65 61 64 73 0a 2a 2a 20 68 6f 6c  y threads.** hol
3c60: 64 69 6e 67 20 74 68 65 20 57 41 4c 5f 43 4b 50  ding the WAL_CKP
3c70: 54 5f 4c 4f 43 4b 20 6c 6f 63 6b 20 28 77 68 69  T_LOCK lock (whi
3c80: 63 68 20 69 6e 63 6c 75 64 65 73 20 61 20 72 65  ch includes a re
3c90: 63 6f 76 65 72 79 20 74 68 72 65 61 64 29 2e 0a  covery thread)..
3ca0: 2a 2a 20 48 6f 77 65 76 65 72 2c 20 61 20 57 41  ** However, a WA
3cb0: 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 74 68 72  L_WRITE_LOCK thr
3cc0: 65 61 64 20 63 61 6e 20 6d 6f 76 65 20 74 68 65  ead can move the
3cd0: 20 76 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b 66   value of nBackf
3ce0: 69 6c 6c 20 66 72 6f 6d 0a 2a 2a 20 6d 78 46 72  ill from.** mxFr
3cf0: 61 6d 65 20 62 61 63 6b 20 74 6f 20 7a 65 72 6f  ame back to zero
3d00: 20 77 68 65 6e 20 74 68 65 20 57 41 4c 20 69 73   when the WAL is
3d10: 20 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 54 68   reset..**.** Th
3d20: 65 72 65 20 69 73 20 6f 6e 65 20 65 6e 74 72 79  ere is one entry
3d30: 20 69 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20   in aReadMark[] 
3d40: 66 6f 72 20 65 61 63 68 20 72 65 61 64 65 72 20  for each reader 
3d50: 6c 6f 63 6b 2e 20 20 49 66 20 61 20 72 65 61 64  lock.  If a read
3d60: 65 72 0a 2a 2a 20 68 6f 6c 64 73 20 72 65 61 64  er.** holds read
3d70: 2d 6c 6f 63 6b 20 4b 2c 20 74 68 65 6e 20 74 68  -lock K, then th
3d80: 65 20 76 61 6c 75 65 20 69 6e 20 61 52 65 61 64  e value in aRead
3d90: 4d 61 72 6b 5b 4b 5d 20 69 73 20 6e 6f 20 67 72  Mark[K] is no gr
3da0: 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 74 68  eater than.** th
3db0: 65 20 6d 78 46 72 61 6d 65 20 66 6f 72 20 74 68  e mxFrame for th
3dc0: 61 74 20 72 65 61 64 65 72 2e 20 20 54 68 65 20  at reader.  The 
3dd0: 76 61 6c 75 65 20 52 45 41 44 4d 41 52 4b 5f 4e  value READMARK_N
3de0: 4f 54 5f 55 53 45 44 20 28 30 78 66 66 66 66 66  OT_USED (0xfffff
3df0: 66 66 66 29 0a 2a 2a 20 66 6f 72 20 61 6e 79 20  fff).** for any 
3e00: 61 52 65 61 64 4d 61 72 6b 5b 5d 20 6d 65 61 6e  aReadMark[] mean
3e10: 73 20 74 68 61 74 20 65 6e 74 72 79 20 69 73 20  s that entry is 
3e20: 75 6e 75 73 65 64 2e 20 20 61 52 65 61 64 4d 61  unused.  aReadMa
3e30: 72 6b 5b 30 5d 20 69 73 20 0a 2a 2a 20 61 20 73  rk[0] is .** a s
3e40: 70 65 63 69 61 6c 20 63 61 73 65 3b 20 69 74 73  pecial case; its
3e50: 20 76 61 6c 75 65 20 69 73 20 6e 65 76 65 72 20   value is never 
3e60: 75 73 65 64 20 61 6e 64 20 69 74 20 65 78 69 73  used and it exis
3e70: 74 73 20 61 73 20 61 20 70 6c 61 63 65 2d 68 6f  ts as a place-ho
3e80: 6c 64 65 72 0a 2a 2a 20 74 6f 20 61 76 6f 69 64  lder.** to avoid
3e90: 20 68 61 76 69 6e 67 20 74 6f 20 6f 66 66 73 65   having to offse
3ea0: 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 69 6e  t aReadMark[] in
3eb0: 64 65 78 73 20 62 79 20 6f 6e 65 2e 20 20 52 65  dexs by one.  Re
3ec0: 61 64 65 72 73 20 68 6f 6c 64 69 6e 67 0a 2a 2a  aders holding.**
3ed0: 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
3ee0: 29 20 61 6c 77 61 79 73 20 69 67 6e 6f 72 65 20  ) always ignore 
3ef0: 74 68 65 20 65 6e 74 69 72 65 20 57 41 4c 20 61  the entire WAL a
3f00: 6e 64 20 72 65 61 64 20 61 6c 6c 20 63 6f 6e 74  nd read all cont
3f10: 65 6e 74 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20  ent.** directly 
3f20: 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
3f30: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c  e..**.** The val
3f40: 75 65 20 6f 66 20 61 52 65 61 64 4d 61 72 6b 5b  ue of aReadMark[
3f50: 4b 5d 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63  K] may only be c
3f60: 68 61 6e 67 65 64 20 62 79 20 61 20 74 68 72 65  hanged by a thre
3f70: 61 64 20 74 68 61 74 0a 2a 2a 20 69 73 20 68 6f  ad that.** is ho
3f80: 6c 64 69 6e 67 20 61 6e 20 65 78 63 6c 75 73 69  lding an exclusi
3f90: 76 65 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52  ve lock on WAL_R
3fa0: 45 41 44 5f 4c 4f 43 4b 28 4b 29 2e 20 20 54 68  EAD_LOCK(K).  Th
3fb0: 75 73 2c 20 74 68 65 20 76 61 6c 75 65 20 6f 66  us, the value of
3fc0: 0a 2a 2a 20 61 52 65 61 64 4d 61 72 6b 5b 4b 5d  .** aReadMark[K]
3fd0: 20 63 61 6e 6e 6f 74 20 63 68 61 6e 67 65 64 20   cannot changed 
3fe0: 77 68 69 6c 65 20 74 68 65 72 65 20 69 73 20 61  while there is a
3ff0: 20 72 65 61 64 65 72 20 69 73 20 75 73 69 6e 67   reader is using
4000: 20 74 68 61 74 20 6d 61 72 6b 0a 2a 2a 20 73 69   that mark.** si
4010: 6e 63 65 20 74 68 65 20 72 65 61 64 65 72 20 77  nce the reader w
4020: 69 6c 6c 20 62 65 20 68 6f 6c 64 69 6e 67 20 61  ill be holding a
4030: 20 73 68 61 72 65 64 20 6c 6f 63 6b 20 6f 6e 20   shared lock on 
4040: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 4b 29  WAL_READ_LOCK(K)
4050: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63  ..**.** The chec
4060: 6b 70 6f 69 6e 74 65 72 20 6d 61 79 20 6f 6e 6c  kpointer may onl
4070: 79 20 74 72 61 6e 73 66 65 72 20 66 72 61 6d 65  y transfer frame
4080: 73 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64 61  s from WAL to da
4090: 74 61 62 61 73 65 20 77 68 65 72 65 0a 2a 2a 20  tabase where.** 
40a0: 74 68 65 20 66 72 61 6d 65 20 6e 75 6d 62 65 72  the frame number
40b0: 73 20 61 72 65 20 6c 65 73 73 20 74 68 61 6e 20  s are less than 
40c0: 6f 72 20 65 71 75 61 6c 20 74 6f 20 65 76 65 72  or equal to ever
40d0: 79 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 74 68  y aReadMark[] th
40e0: 61 74 20 69 73 0a 2a 2a 20 69 6e 20 75 73 65 20  at is.** in use 
40f0: 28 74 68 61 74 20 69 73 2c 20 65 76 65 72 79 20  (that is, every 
4100: 61 52 65 61 64 4d 61 72 6b 5b 6a 5d 20 66 6f 72  aReadMark[j] for
4110: 20 77 68 69 63 68 20 74 68 65 72 65 20 69 73 20   which there is 
4120: 61 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a  a corresponding.
4130: 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  ** WAL_READ_LOCK
4140: 28 6a 29 29 2e 20 20 4e 65 77 20 72 65 61 64 65  (j)).  New reade
4150: 72 73 20 28 75 73 75 61 6c 6c 79 29 20 70 69 63  rs (usually) pic
4160: 6b 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b  k the aReadMark[
4170: 5d 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 6c 61  ] with the.** la
4180: 72 67 65 73 74 20 76 61 6c 75 65 20 61 6e 64 20  rgest value and 
4190: 77 69 6c 6c 20 69 6e 63 72 65 61 73 65 20 61 6e  will increase an
41a0: 20 75 6e 75 73 65 64 20 61 52 65 61 64 4d 61 72   unused aReadMar
41b0: 6b 5b 5d 20 74 6f 20 6d 78 46 72 61 6d 65 20 69  k[] to mxFrame i
41c0: 66 20 74 68 65 72 65 0a 2a 2a 20 69 73 20 6e 6f  f there.** is no
41d0: 74 20 61 6c 72 65 61 64 79 20 61 6e 20 61 52 65  t already an aRe
41e0: 61 64 4d 61 72 6b 5b 5d 20 65 71 75 61 6c 20 74  adMark[] equal t
41f0: 6f 20 6d 78 46 72 61 6d 65 2e 20 20 54 68 65 20  o mxFrame.  The 
4200: 65 78 63 65 70 74 69 6f 6e 20 74 6f 20 74 68 65  exception to the
4210: 0a 2a 2a 20 70 72 65 76 69 6f 75 73 20 73 65 6e  .** previous sen
4220: 74 65 6e 63 65 20 69 73 20 77 68 65 6e 20 6e 42  tence is when nB
4230: 61 63 6b 66 69 6c 6c 20 65 71 75 61 6c 73 20 6d  ackfill equals m
4240: 78 46 72 61 6d 65 20 28 6d 65 61 6e 69 6e 67 20  xFrame (meaning 
4250: 74 68 61 74 20 65 76 65 72 79 74 68 69 6e 67 0a  that everything.
4260: 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 68 61  ** in the WAL ha
4270: 73 20 62 65 65 6e 20 62 61 63 6b 66 69 6c 6c 65  s been backfille
4280: 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  d into the datab
4290: 61 73 65 29 20 74 68 65 6e 20 6e 65 77 20 72 65  ase) then new re
42a0: 61 64 65 72 73 0a 2a 2a 20 77 69 6c 6c 20 63 68  aders.** will ch
42b0: 6f 6f 73 65 20 61 52 65 61 64 4d 61 72 6b 5b 30  oose aReadMark[0
42c0: 5d 20 77 68 69 63 68 20 68 61 73 20 76 61 6c 75  ] which has valu
42d0: 65 20 30 20 61 6e 64 20 68 65 6e 63 65 20 73 75  e 0 and hence su
42e0: 63 68 20 72 65 61 64 65 72 20 77 69 6c 6c 0a 2a  ch reader will.*
42f0: 2a 20 67 65 74 20 61 6c 6c 20 74 68 65 69 72 20  * get all their 
4300: 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72 65  all content dire
4310: 63 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61  ctly from the da
4320: 74 61 62 61 73 65 20 66 69 6c 65 20 61 6e 64 20  tabase file and 
4330: 69 67 6e 6f 72 65 20 0a 2a 2a 20 74 68 65 20 57  ignore .** the W
4340: 41 4c 2e 0a 2a 2a 0a 2a 2a 20 57 72 69 74 65 72  AL..**.** Writer
4350: 73 20 6e 6f 72 6d 61 6c 6c 79 20 61 70 70 65 6e  s normally appen
4360: 64 20 6e 65 77 20 66 72 61 6d 65 73 20 74 6f 20  d new frames to 
4370: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 57  the end of the W
4380: 41 4c 2e 20 20 48 6f 77 65 76 65 72 2c 0a 2a 2a  AL.  However,.**
4390: 20 69 66 20 6e 42 61 63 6b 66 69 6c 6c 20 65 71   if nBackfill eq
43a0: 75 61 6c 73 20 6d 78 46 72 61 6d 65 20 28 6d 65  uals mxFrame (me
43b0: 61 6e 69 6e 67 20 74 68 61 74 20 61 6c 6c 20 57  aning that all W
43c0: 41 4c 20 63 6f 6e 74 65 6e 74 20 68 61 73 20 62  AL content has b
43d0: 65 65 6e 0a 2a 2a 20 77 72 69 74 74 65 6e 20 62  een.** written b
43e0: 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74  ack into the dat
43f0: 61 62 61 73 65 29 20 61 6e 64 20 69 66 20 6e 6f  abase) and if no
4400: 20 72 65 61 64 65 72 73 20 61 72 65 20 75 73 69   readers are usi
4410: 6e 67 20 74 68 65 20 57 41 4c 0a 2a 2a 20 28 69  ng the WAL.** (i
4420: 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 69  n other words, i
4430: 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 57  f there are no W
4440: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 20  AL_READ_LOCK(i) 
4450: 77 68 65 72 65 20 69 3e 30 29 20 74 68 65 6e 0a  where i>0) then.
4460: 2a 2a 20 74 68 65 20 77 72 69 74 65 72 20 77 69  ** the writer wi
4470: 6c 6c 20 66 69 72 73 74 20 22 72 65 73 65 74 22  ll first "reset"
4480: 20 74 68 65 20 57 41 4c 20 62 61 63 6b 20 74 6f   the WAL back to
4490: 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 61   the beginning a
44a0: 6e 64 20 73 74 61 72 74 0a 2a 2a 20 77 72 69 74  nd start.** writ
44b0: 69 6e 67 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20  ing new content 
44c0: 62 65 67 69 6e 6e 69 6e 67 20 61 74 20 66 72 61  beginning at fra
44d0: 6d 65 20 31 2e 0a 2a 2a 0a 2a 2a 20 57 65 20 61  me 1..**.** We a
44e0: 73 73 75 6d 65 20 74 68 61 74 20 33 32 2d 62 69  ssume that 32-bi
44f0: 74 20 6c 6f 61 64 73 20 61 72 65 20 61 74 6f 6d  t loads are atom
4500: 69 63 20 61 6e 64 20 73 6f 20 6e 6f 20 6c 6f 63  ic and so no loc
4510: 6b 73 20 61 72 65 20 6e 65 65 64 65 64 20 69 6e  ks are needed in
4520: 0a 2a 2a 20 6f 72 64 65 72 20 74 6f 20 72 65 61  .** order to rea
4530: 64 20 66 72 6f 6d 20 61 6e 79 20 61 52 65 61 64  d from any aRead
4540: 4d 61 72 6b 5b 5d 20 65 6e 74 72 69 65 73 2e 0a  Mark[] entries..
4550: 2a 2f 0a 73 74 72 75 63 74 20 57 61 6c 43 6b 70  */.struct WalCkp
4560: 74 49 6e 66 6f 20 7b 0a 20 20 75 33 32 20 6e 42  tInfo {.  u32 nB
4570: 61 63 6b 66 69 6c 6c 3b 20 20 20 20 20 20 20 20  ackfill;        
4580: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
4590: 62 65 72 20 6f 66 20 57 41 4c 20 66 72 61 6d 65  ber of WAL frame
45a0: 73 20 62 61 63 6b 66 69 6c 6c 65 64 20 69 6e 74  s backfilled int
45b0: 6f 20 44 42 20 2a 2f 0a 20 20 75 33 32 20 61 52  o DB */.  u32 aR
45c0: 65 61 64 4d 61 72 6b 5b 57 41 4c 5f 4e 52 45 41  eadMark[WAL_NREA
45d0: 44 45 52 5d 3b 20 20 20 20 20 2f 2a 20 52 65 61  DER];     /* Rea
45e0: 64 65 72 20 6d 61 72 6b 73 20 2a 2f 0a 7d 3b 0a  der marks */.};.
45f0: 23 64 65 66 69 6e 65 20 52 45 41 44 4d 41 52 4b  #define READMARK
4600: 5f 4e 4f 54 5f 55 53 45 44 20 20 30 78 66 66 66  _NOT_USED  0xfff
4610: 66 66 66 66 66 0a 0a 0a 2f 2a 20 41 20 62 6c 6f  fffff.../* A blo
4620: 63 6b 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 4c  ck of WALINDEX_L
4630: 4f 43 4b 5f 52 45 53 45 52 56 45 44 20 62 79 74  OCK_RESERVED byt
4640: 65 73 20 62 65 67 69 6e 6e 69 6e 67 20 61 74 0a  es beginning at.
4650: 2a 2a 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b  ** WALINDEX_LOCK
4660: 5f 4f 46 46 53 45 54 20 69 73 20 72 65 73 65 72  _OFFSET is reser
4670: 76 65 64 20 66 6f 72 20 6c 6f 63 6b 73 2e 20 53  ved for locks. S
4680: 69 6e 63 65 20 73 6f 6d 65 20 73 79 73 74 65 6d  ince some system
4690: 73 0a 2a 2a 20 6f 6e 6c 79 20 73 75 70 70 6f 72  s.** only suppor
46a0: 74 20 6d 61 6e 64 61 74 6f 72 79 20 66 69 6c 65  t mandatory file
46b0: 2d 6c 6f 63 6b 73 2c 20 77 65 20 64 6f 20 6e 6f  -locks, we do no
46c0: 74 20 72 65 61 64 20 6f 72 20 77 72 69 74 65 20  t read or write 
46d0: 64 61 74 61 0a 2a 2a 20 66 72 6f 6d 20 74 68 65  data.** from the
46e0: 20 72 65 67 69 6f 6e 20 6f 66 20 74 68 65 20 66   region of the f
46f0: 69 6c 65 20 6f 6e 20 77 68 69 63 68 20 6c 6f 63  ile on which loc
4700: 6b 73 20 61 72 65 20 61 70 70 6c 69 65 64 2e 0a  ks are applied..
4710: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e  */.#define WALIN
4720: 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20  DEX_LOCK_OFFSET 
4730: 20 20 28 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64    (sizeof(WalInd
4740: 65 78 48 64 72 29 2a 32 20 2b 20 73 69 7a 65 6f  exHdr)*2 + sizeo
4750: 66 28 57 61 6c 43 6b 70 74 49 6e 66 6f 29 29 0a  f(WalCkptInfo)).
4760: 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58  #define WALINDEX
4770: 5f 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 20 31  _LOCK_RESERVED 1
4780: 36 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44  6.#define WALIND
4790: 45 58 5f 48 44 52 5f 53 49 5a 45 20 20 20 20 20  EX_HDR_SIZE     
47a0: 20 28 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f   (WALINDEX_LOCK_
47b0: 4f 46 46 53 45 54 2b 57 41 4c 49 4e 44 45 58 5f  OFFSET+WALINDEX_
47c0: 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 29 0a 0a  LOCK_RESERVED)..
47d0: 2f 2a 20 53 69 7a 65 20 6f 66 20 68 65 61 64 65  /* Size of heade
47e0: 72 20 62 65 66 6f 72 65 20 65 61 63 68 20 66 72  r before each fr
47f0: 61 6d 65 20 69 6e 20 77 61 6c 20 2a 2f 0a 23 64  ame in wal */.#d
4800: 65 66 69 6e 65 20 57 41 4c 5f 46 52 41 4d 45 5f  efine WAL_FRAME_
4810: 48 44 52 53 49 5a 45 20 32 34 0a 0a 2f 2a 20 53  HDRSIZE 24../* S
4820: 69 7a 65 20 6f 66 20 77 72 69 74 65 20 61 68 65  ize of write ahe
4830: 61 64 20 6c 6f 67 20 68 65 61 64 65 72 2c 20 69  ad log header, i
4840: 6e 63 6c 75 64 69 6e 67 20 63 68 65 63 6b 73 75  ncluding checksu
4850: 6d 2e 20 2a 2f 0a 2f 2a 20 23 64 65 66 69 6e 65  m. */./* #define
4860: 20 57 41 4c 5f 48 44 52 53 49 5a 45 20 32 34 20   WAL_HDRSIZE 24 
4870: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48  */.#define WAL_H
4880: 44 52 53 49 5a 45 20 33 32 0a 0a 2f 2a 20 57 41  DRSIZE 32../* WA
4890: 4c 20 6d 61 67 69 63 20 76 61 6c 75 65 2e 20 45  L magic value. E
48a0: 69 74 68 65 72 20 74 68 69 73 20 76 61 6c 75 65  ither this value
48b0: 2c 20 6f 72 20 74 68 65 20 73 61 6d 65 20 76 61  , or the same va
48c0: 6c 75 65 20 77 69 74 68 20 74 68 65 20 6c 65 61  lue with the lea
48d0: 73 74 0a 2a 2a 20 73 69 67 6e 69 66 69 63 61 6e  st.** significan
48e0: 74 20 62 69 74 20 61 6c 73 6f 20 73 65 74 20 28  t bit also set (
48f0: 57 41 4c 5f 4d 41 47 49 43 20 7c 20 30 78 30 30  WAL_MAGIC | 0x00
4900: 30 30 30 30 30 31 29 20 69 73 20 73 74 6f 72 65  000001) is store
4910: 64 20 69 6e 20 33 32 2d 62 69 74 0a 2a 2a 20 62  d in 32-bit.** b
4920: 69 67 2d 65 6e 64 69 61 6e 20 66 6f 72 6d 61 74  ig-endian format
4930: 20 69 6e 20 74 68 65 20 66 69 72 73 74 20 34 20   in the first 4 
4940: 62 79 74 65 73 20 6f 66 20 61 20 57 41 4c 20 66  bytes of a WAL f
4950: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ile..**.** If th
4960: 65 20 4c 53 42 20 69 73 20 73 65 74 2c 20 74 68  e LSB is set, th
4970: 65 6e 20 74 68 65 20 63 68 65 63 6b 73 75 6d 73  en the checksums
4980: 20 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65 20   for each frame 
4990: 77 69 74 68 69 6e 20 74 68 65 20 57 41 4c 0a 2a  within the WAL.*
49a0: 2a 20 66 69 6c 65 20 61 72 65 20 63 61 6c 63 75  * file are calcu
49b0: 6c 61 74 65 64 20 62 79 20 74 72 65 61 74 69 6e  lated by treatin
49c0: 67 20 61 6c 6c 20 64 61 74 61 20 61 73 20 61 6e  g all data as an
49d0: 20 61 72 72 61 79 20 6f 66 20 33 32 2d 62 69 74   array of 32-bit
49e0: 20 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20   .** big-endian 
49f0: 77 6f 72 64 73 2e 20 4f 74 68 65 72 77 69 73 65  words. Otherwise
4a00: 2c 20 74 68 65 79 20 61 72 65 20 63 61 6c 63 75  , they are calcu
4a10: 6c 61 74 65 64 20 62 79 20 69 6e 74 65 72 70 72  lated by interpr
4a20: 65 74 69 6e 67 20 0a 2a 2a 20 61 6c 6c 20 64 61  eting .** all da
4a30: 74 61 20 61 73 20 33 32 2d 62 69 74 20 6c 69 74  ta as 32-bit lit
4a40: 74 6c 65 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73  tle-endian words
4a50: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c  ..*/.#define WAL
4a60: 5f 4d 41 47 49 43 20 30 78 33 37 37 66 30 36 38  _MAGIC 0x377f068
4a70: 32 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  2../*.** Return 
4a80: 74 68 65 20 6f 66 66 73 65 74 20 6f 66 20 66 72  the offset of fr
4a90: 61 6d 65 20 69 46 72 61 6d 65 20 69 6e 20 74 68  ame iFrame in th
4aa0: 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f  e write-ahead lo
4ab0: 67 20 66 69 6c 65 2c 20 0a 2a 2a 20 61 73 73 75  g file, .** assu
4ac0: 6d 69 6e 67 20 61 20 64 61 74 61 62 61 73 65 20  ming a database 
4ad0: 70 61 67 65 20 73 69 7a 65 20 6f 66 20 73 7a 50  page size of szP
4ae0: 61 67 65 20 62 79 74 65 73 2e 20 54 68 65 20 6f  age bytes. The o
4af0: 66 66 73 65 74 20 72 65 74 75 72 6e 65 64 0a 2a  ffset returned.*
4b00: 2a 20 69 73 20 74 6f 20 74 68 65 20 73 74 61 72  * is to the star
4b10: 74 20 6f 66 20 74 68 65 20 77 72 69 74 65 2d 61  t of the write-a
4b20: 68 65 61 64 20 6c 6f 67 20 66 72 61 6d 65 2d 68  head log frame-h
4b30: 65 61 64 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e  eader..*/.#defin
4b40: 65 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74  e walFrameOffset
4b50: 28 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29  (iFrame, szPage)
4b60: 20 28 20 20 20 20 20 20 20 20 20 20 20 20 20 20   (              
4b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4b80: 20 5c 0a 20 20 57 41 4c 5f 48 44 52 53 49 5a 45   \.  WAL_HDRSIZE
4b90: 20 2b 20 28 28 69 46 72 61 6d 65 29 2d 31 29 2a   + ((iFrame)-1)*
4ba0: 28 69 36 34 29 28 28 73 7a 50 61 67 65 29 2b 57  (i64)((szPage)+W
4bb0: 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
4bc0: 29 20 20 20 20 20 20 20 20 20 5c 0a 29 0a 0a 2f  )         \.)../
4bd0: 2a 0a 2a 2a 20 41 6e 20 6f 70 65 6e 20 77 72 69  *.** An open wri
4be0: 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c  te-ahead log fil
4bf0: 65 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64  e is represented
4c00: 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   by an instance 
4c10: 6f 66 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c 6f 77  of the.** follow
4c20: 69 6e 67 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73  ing object..*/.s
4c30: 74 72 75 63 74 20 57 61 6c 20 7b 0a 20 20 73 71  truct Wal {.  sq
4c40: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 3b  lite3_vfs *pVfs;
4c50: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
4c60: 56 46 53 20 75 73 65 64 20 74 6f 20 63 72 65 61  VFS used to crea
4c70: 74 65 20 70 44 62 46 64 20 2a 2f 0a 20 20 73 71  te pDbFd */.  sq
4c80: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 44 62 46  lite3_file *pDbF
4c90: 64 3b 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65  d;       /* File
4ca0: 20 68 61 6e 64 6c 65 20 66 6f 72 20 74 68 65 20   handle for the 
4cb0: 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f  database file */
4cc0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
4cd0: 2a 70 57 61 6c 46 64 3b 20 20 20 20 20 20 2f 2a  *pWalFd;      /*
4ce0: 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 66 6f 72   File handle for
4cf0: 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 75   WAL file */.  u
4d00: 33 32 20 69 43 61 6c 6c 62 61 63 6b 3b 20 20 20  32 iCallback;   
4d10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
4d20: 75 65 20 74 6f 20 70 61 73 73 20 74 6f 20 6c 6f  ue to pass to lo
4d30: 67 20 63 61 6c 6c 62 61 63 6b 20 28 6f 72 20 30  g callback (or 0
4d40: 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 57 69 44 61  ) */.  int nWiDa
4d50: 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ta;             
4d60: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 72 72    /* Size of arr
4d70: 61 79 20 61 70 57 69 44 61 74 61 20 2a 2f 0a 20  ay apWiData */. 
4d80: 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a   volatile u32 **
4d90: 61 70 57 69 44 61 74 61 3b 20 20 20 2f 2a 20 50  apWiData;   /* P
4da0: 6f 69 6e 74 65 72 20 74 6f 20 77 61 6c 2d 69 6e  ointer to wal-in
4db0: 64 65 78 20 63 6f 6e 74 65 6e 74 20 69 6e 20 6d  dex content in m
4dc0: 65 6d 6f 72 79 20 2a 2f 0a 20 20 75 33 32 20 73  emory */.  u32 s
4dd0: 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  zPage;          
4de0: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
4df0: 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f 0a 20  e page size */. 
4e00: 20 69 31 36 20 72 65 61 64 4c 6f 63 6b 3b 20 20   i16 readLock;  
4e10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
4e20: 68 69 63 68 20 72 65 61 64 20 6c 6f 63 6b 20 69  hich read lock i
4e30: 73 20 62 65 69 6e 67 20 68 65 6c 64 2e 20 20 2d  s being held.  -
4e40: 31 20 66 6f 72 20 6e 6f 6e 65 20 2a 2f 0a 20 20  1 for none */.  
4e50: 75 38 20 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  u8 exclusiveMode
4e60: 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f  ;          /* No
4e70: 6e 2d 7a 65 72 6f 20 69 66 20 63 6f 6e 6e 65 63  n-zero if connec
4e80: 74 69 6f 6e 20 69 73 20 69 6e 20 65 78 63 6c 75  tion is in exclu
4e90: 73 69 76 65 20 6d 6f 64 65 20 2a 2f 0a 20 20 75  sive mode */.  u
4ea0: 38 20 77 72 69 74 65 4c 6f 63 6b 3b 20 20 20 20  8 writeLock;    
4eb0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
4ec0: 65 20 69 66 20 69 6e 20 61 20 77 72 69 74 65 20  e if in a write 
4ed0: 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20  transaction */. 
4ee0: 20 75 38 20 63 6b 70 74 4c 6f 63 6b 3b 20 20 20   u8 ckptLock;   
4ef0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
4f00: 72 75 65 20 69 66 20 68 6f 6c 64 69 6e 67 20 61  rue if holding a
4f10: 20 63 68 65 63 6b 70 6f 69 6e 74 20 6c 6f 63 6b   checkpoint lock
4f20: 20 2a 2f 0a 20 20 75 38 20 72 65 61 64 4f 6e 6c   */.  u8 readOnl
4f30: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y;              
4f40: 20 2f 2a 20 54 72 75 65 20 69 66 20 74 68 65 20   /* True if the 
4f50: 57 41 4c 20 66 69 6c 65 20 69 73 20 6f 70 65 6e  WAL file is open
4f60: 20 72 65 61 64 2d 6f 6e 6c 79 20 2a 2f 0a 20 20   read-only */.  
4f70: 57 61 6c 49 6e 64 65 78 48 64 72 20 68 64 72 3b  WalIndexHdr hdr;
4f80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61             /* Wa
4f90: 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 66  l-index header f
4fa0: 6f 72 20 63 75 72 72 65 6e 74 20 74 72 61 6e 73  or current trans
4fb0: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73  action */.  cons
4fc0: 74 20 63 68 61 72 20 2a 7a 57 61 6c 4e 61 6d 65  t char *zWalName
4fd0: 3b 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f  ;      /* Name o
4fe0: 66 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20  f WAL file */.  
4ff0: 75 33 32 20 6e 43 6b 70 74 3b 20 20 20 20 20 20  u32 nCkpt;      
5000: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68             /* Ch
5010: 65 63 6b 70 6f 69 6e 74 20 73 65 71 75 65 6e 63  eckpoint sequenc
5020: 65 20 63 6f 75 6e 74 65 72 20 69 6e 20 74 68 65  e counter in the
5030: 20 77 61 6c 2d 68 65 61 64 65 72 20 2a 2f 0a 23   wal-header */.#
5040: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42  ifdef SQLITE_DEB
5050: 55 47 0a 20 20 75 38 20 6c 6f 63 6b 45 72 72 6f  UG.  u8 lockErro
5060: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
5070: 2f 2a 20 54 72 75 65 20 69 66 20 61 20 6c 6f 63  /* True if a loc
5080: 6b 69 6e 67 20 65 72 72 6f 72 20 68 61 73 20 6f  king error has o
5090: 63 63 75 72 72 65 64 20 2a 2f 0a 23 65 6e 64 69  ccurred */.#endi
50a0: 66 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 43 61 6e 64  f.};../*.** Cand
50b0: 69 64 61 74 65 20 76 61 6c 75 65 73 20 66 6f 72  idate values for
50c0: 20 57 61 6c 2e 65 78 63 6c 75 73 69 76 65 4d 6f   Wal.exclusiveMo
50d0: 64 65 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57  de..*/.#define W
50e0: 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 20 20  AL_NORMAL_MODE  
50f0: 20 20 20 30 0a 23 64 65 66 69 6e 65 20 57 41 4c     0.#define WAL
5100: 5f 45 58 43 4c 55 53 49 56 45 5f 4d 4f 44 45 20  _EXCLUSIVE_MODE 
5110: 20 31 20 20 20 20 20 0a 23 64 65 66 69 6e 65 20   1     .#define 
5120: 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d  WAL_HEAPMEMORY_M
5130: 4f 44 45 20 32 0a 0a 2f 2a 0a 2a 2a 20 45 61 63  ODE 2../*.** Eac
5140: 68 20 70 61 67 65 20 6f 66 20 74 68 65 20 77 61  h page of the wa
5150: 6c 2d 69 6e 64 65 78 20 6d 61 70 70 69 6e 67 20  l-index mapping 
5160: 63 6f 6e 74 61 69 6e 73 20 61 20 68 61 73 68 2d  contains a hash-
5170: 74 61 62 6c 65 20 6d 61 64 65 20 75 70 20 6f 66  table made up of
5180: 0a 2a 2a 20 61 6e 20 61 72 72 61 79 20 6f 66 20  .** an array of 
5190: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20  HASHTABLE_NSLOT 
51a0: 65 6c 65 6d 65 6e 74 73 20 6f 66 20 74 68 65 20  elements of the 
51b0: 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70 65 2e 0a  following type..
51c0: 2a 2f 0a 74 79 70 65 64 65 66 20 75 31 36 20 68  */.typedef u16 h
51d0: 74 5f 73 6c 6f 74 3b 0a 0a 2f 2a 0a 2a 2a 20 54  t_slot;../*.** T
51e0: 68 69 73 20 73 74 72 75 63 74 75 72 65 20 69 73  his structure is
51f0: 20 75 73 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65   used to impleme
5200: 6e 74 20 61 6e 20 69 74 65 72 61 74 6f 72 20 74  nt an iterator t
5210: 68 61 74 20 6c 6f 6f 70 73 20 74 68 72 6f 75 67  hat loops throug
5220: 68 0a 2a 2a 20 61 6c 6c 20 66 72 61 6d 65 73 20  h.** all frames 
5230: 69 6e 20 74 68 65 20 57 41 4c 20 69 6e 20 64 61  in the WAL in da
5240: 74 61 62 61 73 65 20 70 61 67 65 20 6f 72 64 65  tabase page orde
5250: 72 2e 20 57 68 65 72 65 20 74 77 6f 20 6f 72 20  r. Where two or 
5260: 6d 6f 72 65 20 66 72 61 6d 65 73 0a 2a 2a 20 63  more frames.** c
5270: 6f 72 72 65 73 70 6f 6e 64 20 74 6f 20 74 68 65  orrespond to the
5280: 20 73 61 6d 65 20 64 61 74 61 62 61 73 65 20 70   same database p
5290: 61 67 65 2c 20 74 68 65 20 69 74 65 72 61 74 6f  age, the iterato
52a0: 72 20 76 69 73 69 74 73 20 6f 6e 6c 79 20 74 68  r visits only th
52b0: 65 20 0a 2a 2a 20 66 72 61 6d 65 20 6d 6f 73 74  e .** frame most
52c0: 20 72 65 63 65 6e 74 6c 79 20 77 72 69 74 74 65   recently writte
52d0: 6e 20 74 6f 20 74 68 65 20 57 41 4c 20 28 69 6e  n to the WAL (in
52e0: 20 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68   other words, th
52f0: 65 20 66 72 61 6d 65 20 77 69 74 68 0a 2a 2a 20  e frame with.** 
5300: 74 68 65 20 6c 61 72 67 65 73 74 20 69 6e 64 65  the largest inde
5310: 78 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e  x)..**.** The in
5320: 74 65 72 6e 61 6c 73 20 6f 66 20 74 68 69 73 20  ternals of this 
5330: 73 74 72 75 63 74 75 72 65 20 61 72 65 20 6f 6e  structure are on
5340: 6c 79 20 61 63 63 65 73 73 65 64 20 62 79 3a 0a  ly accessed by:.
5350: 2a 2a 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61  **.**   walItera
5360: 74 6f 72 49 6e 69 74 28 29 20 2d 20 43 72 65 61  torInit() - Crea
5370: 74 65 20 61 20 6e 65 77 20 69 74 65 72 61 74 6f  te a new iterato
5380: 72 2c 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61  r,.**   walItera
5390: 74 6f 72 4e 65 78 74 28 29 20 2d 20 53 74 65 70  torNext() - Step
53a0: 20 61 6e 20 69 74 65 72 61 74 6f 72 2c 0a 2a 2a   an iterator,.**
53b0: 20 20 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72     walIteratorFr
53c0: 65 65 28 29 20 2d 20 46 72 65 65 20 61 6e 20 69  ee() - Free an i
53d0: 74 65 72 61 74 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54  terator..**.** T
53e0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 61 6c 69 74  his functionalit
53f0: 79 20 69 73 20 75 73 65 64 20 62 79 20 74 68 65  y is used by the
5400: 20 63 68 65 63 6b 70 6f 69 6e 74 20 63 6f 64 65   checkpoint code
5410: 20 28 73 65 65 20 77 61 6c 43 68 65 63 6b 70 6f   (see walCheckpo
5420: 69 6e 74 28 29 29 2e 0a 2a 2f 0a 73 74 72 75 63  int())..*/.struc
5430: 74 20 57 61 6c 49 74 65 72 61 74 6f 72 20 7b 0a  t WalIterator {.
5440: 20 20 69 6e 74 20 69 50 72 69 6f 72 3b 20 20 20    int iPrior;   
5450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5460: 20 20 2f 2a 20 4c 61 73 74 20 72 65 73 75 6c 74    /* Last result
5470: 20 72 65 74 75 72 6e 65 64 20 66 72 6f 6d 20 74   returned from t
5480: 68 65 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20  he iterator */. 
5490: 20 69 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20   int nSegment;  
54a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
54b0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e   /* Number of en
54c0: 74 72 69 65 73 20 69 6e 20 61 53 65 67 6d 65 6e  tries in aSegmen
54d0: 74 5b 5d 20 2a 2f 0a 20 20 73 74 72 75 63 74 20  t[] */.  struct 
54e0: 57 61 6c 53 65 67 6d 65 6e 74 20 7b 0a 20 20 20  WalSegment {.   
54f0: 20 69 6e 74 20 69 4e 65 78 74 3b 20 20 20 20 20   int iNext;     
5500: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5510: 2a 20 4e 65 78 74 20 73 6c 6f 74 20 69 6e 20 61  * Next slot in a
5520: 49 6e 64 65 78 5b 5d 20 6e 6f 74 20 79 65 74 20  Index[] not yet 
5530: 72 65 74 75 72 6e 65 64 20 2a 2f 0a 20 20 20 20  returned */.    
5540: 68 74 5f 73 6c 6f 74 20 2a 61 49 6e 64 65 78 3b  ht_slot *aIndex;
5550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5560: 20 69 30 2c 20 69 31 2c 20 69 32 2e 2e 2e 20 73   i0, i1, i2... s
5570: 75 63 68 20 74 68 61 74 20 61 50 67 6e 6f 5b 69  uch that aPgno[i
5580: 4e 5d 20 61 73 63 65 6e 64 20 2a 2f 0a 20 20 20  N] ascend */.   
5590: 20 75 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20   u32 *aPgno;    
55a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
55b0: 2a 20 41 72 72 61 79 20 6f 66 20 70 61 67 65 20  * Array of page 
55c0: 6e 75 6d 62 65 72 73 2e 20 2a 2f 0a 20 20 20 20  numbers. */.    
55d0: 69 6e 74 20 6e 45 6e 74 72 79 3b 20 20 20 20 20  int nEntry;     
55e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
55f0: 20 4e 72 2e 20 6f 66 20 65 6e 74 72 69 65 73 20   Nr. of entries 
5600: 69 6e 20 61 50 67 6e 6f 5b 5d 20 61 6e 64 20 61  in aPgno[] and a
5610: 49 6e 64 65 78 5b 5d 20 2a 2f 0a 20 20 20 20 69  Index[] */.    i
5620: 6e 74 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20  nt iZero;       
5630: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5640: 46 72 61 6d 65 20 6e 75 6d 62 65 72 20 61 73 73  Frame number ass
5650: 6f 63 69 61 74 65 64 20 77 69 74 68 20 61 50 67  ociated with aPg
5660: 6e 6f 5b 30 5d 20 2a 2f 0a 20 20 7d 20 61 53 65  no[0] */.  } aSe
5670: 67 6d 65 6e 74 5b 31 5d 3b 20 20 20 20 20 20 20  gment[1];       
5680: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e             /* On
5690: 65 20 66 6f 72 20 65 76 65 72 79 20 33 32 4b 42  e for every 32KB
56a0: 20 70 61 67 65 20 69 6e 20 74 68 65 20 77 61 6c   page in the wal
56b0: 2d 69 6e 64 65 78 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  -index */.};../*
56c0: 0a 2a 2a 20 44 65 66 69 6e 65 20 74 68 65 20 70  .** Define the p
56d0: 61 72 61 6d 65 74 65 72 73 20 6f 66 20 74 68 65  arameters of the
56e0: 20 68 61 73 68 20 74 61 62 6c 65 73 20 69 6e 20   hash tables in 
56f0: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69  the wal-index fi
5700: 6c 65 2e 20 54 68 65 72 65 0a 2a 2a 20 69 73 20  le. There.** is 
5710: 61 20 68 61 73 68 2d 74 61 62 6c 65 20 66 6f 6c  a hash-table fol
5720: 6c 6f 77 69 6e 67 20 65 76 65 72 79 20 48 41 53  lowing every HAS
5730: 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 70 61 67  HTABLE_NPAGE pag
5740: 65 20 6e 75 6d 62 65 72 73 20 69 6e 20 74 68 65  e numbers in the
5750: 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a  .** wal-index..*
5760: 2a 0a 2a 2a 20 43 68 61 6e 67 69 6e 67 20 61 6e  *.** Changing an
5770: 79 20 6f 66 20 74 68 65 73 65 20 63 6f 6e 73 74  y of these const
5780: 61 6e 74 73 20 77 69 6c 6c 20 61 6c 74 65 72 20  ants will alter 
5790: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 6f  the wal-index fo
57a0: 72 6d 61 74 20 61 6e 64 0a 2a 2a 20 63 72 65 61  rmat and.** crea
57b0: 74 65 20 69 6e 63 6f 6d 70 61 74 69 62 69 6c 69  te incompatibili
57c0: 74 69 65 73 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  ties..*/.#define
57d0: 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45   HASHTABLE_NPAGE
57e0: 20 20 20 20 20 20 34 30 39 36 20 20 20 20 20 20        4096      
57f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 75             /* Mu
5800: 73 74 20 62 65 20 70 6f 77 65 72 20 6f 66 20 32  st be power of 2
5810: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48   */.#define HASH
5820: 54 41 42 4c 45 5f 48 41 53 48 5f 31 20 20 20 20  TABLE_HASH_1    
5830: 20 33 38 33 20 20 20 20 20 20 20 20 20 20 20 20   383            
5840: 20 20 20 20 20 20 2f 2a 20 53 68 6f 75 6c 64 20        /* Should 
5850: 62 65 20 70 72 69 6d 65 20 2a 2f 0a 23 64 65 66  be prime */.#def
5860: 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f 4e 53  ine HASHTABLE_NS
5870: 4c 4f 54 20 20 20 20 20 20 28 48 41 53 48 54 41  LOT      (HASHTA
5880: 42 4c 45 5f 4e 50 41 47 45 2a 32 29 20 20 2f 2a  BLE_NPAGE*2)  /*
5890: 20 4d 75 73 74 20 62 65 20 61 20 70 6f 77 65 72   Must be a power
58a0: 20 6f 66 20 32 20 2a 2f 0a 0a 2f 2a 20 0a 2a 2a   of 2 */../* .**
58b0: 20 54 68 65 20 62 6c 6f 63 6b 20 6f 66 20 70 61   The block of pa
58c0: 67 65 20 6e 75 6d 62 65 72 73 20 61 73 73 6f 63  ge numbers assoc
58d0: 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20 66  iated with the f
58e0: 69 72 73 74 20 68 61 73 68 2d 74 61 62 6c 65 20  irst hash-table 
58f0: 69 6e 20 61 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65  in a.** wal-inde
5900: 78 20 69 73 20 73 6d 61 6c 6c 65 72 20 74 68 61  x is smaller tha
5910: 6e 20 75 73 75 61 6c 2e 20 54 68 69 73 20 69 73  n usual. This is
5920: 20 73 6f 20 74 68 61 74 20 74 68 65 72 65 20 69   so that there i
5930: 73 20 61 20 63 6f 6d 70 6c 65 74 65 0a 2a 2a 20  s a complete.** 
5940: 68 61 73 68 2d 74 61 62 6c 65 20 6f 6e 20 65 61  hash-table on ea
5950: 63 68 20 61 6c 69 67 6e 65 64 20 33 32 4b 42 20  ch aligned 32KB 
5960: 70 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d  page of the wal-
5970: 69 6e 64 65 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e  index..*/.#defin
5980: 65 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  e HASHTABLE_NPAG
5990: 45 5f 4f 4e 45 20 20 28 48 41 53 48 54 41 42 4c  E_ONE  (HASHTABL
59a0: 45 5f 4e 50 41 47 45 20 2d 20 28 57 41 4c 49 4e  E_NPAGE - (WALIN
59b0: 44 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a  DEX_HDR_SIZE/siz
59c0: 65 6f 66 28 75 33 32 29 29 29 0a 0a 2f 2a 20 54  eof(u32)))../* T
59d0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
59e0: 64 69 76 69 64 65 64 20 69 6e 74 6f 20 70 61 67  divided into pag
59f0: 65 73 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 50  es of WALINDEX_P
5a00: 47 53 5a 20 62 79 74 65 73 20 65 61 63 68 2e 20  GSZ bytes each. 
5a10: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e  */.#define WALIN
5a20: 44 45 58 5f 50 47 53 5a 20 20 20 28 20 20 20 20  DEX_PGSZ   (    
5a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a50: 20 20 20 20 20 5c 0a 20 20 20 20 73 69 7a 65 6f       \.    sizeo
5a60: 66 28 68 74 5f 73 6c 6f 74 29 2a 48 41 53 48 54  f(ht_slot)*HASHT
5a70: 41 42 4c 45 5f 4e 53 4c 4f 54 20 2b 20 48 41 53  ABLE_NSLOT + HAS
5a80: 48 54 41 42 4c 45 5f 4e 50 41 47 45 2a 73 69 7a  HTABLE_NPAGE*siz
5a90: 65 6f 66 28 75 33 32 29 20 5c 0a 29 0a 0a 2f 2a  eof(u32) \.)../*
5aa0: 0a 2a 2a 20 4f 62 74 61 69 6e 20 61 20 70 6f 69  .** Obtain a poi
5ab0: 6e 74 65 72 20 74 6f 20 74 68 65 20 69 50 61 67  nter to the iPag
5ac0: 65 27 74 68 20 70 61 67 65 20 6f 66 20 74 68 65  e'th page of the
5ad0: 20 77 61 6c 2d 69 6e 64 65 78 2e 20 54 68 65 20   wal-index. The 
5ae0: 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a 20 69 73 20  wal-index.** is 
5af0: 62 72 6f 6b 65 6e 20 69 6e 74 6f 20 70 61 67 65  broken into page
5b00: 73 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 50 47  s of WALINDEX_PG
5b10: 53 5a 20 62 79 74 65 73 2e 20 57 61 6c 2d 69 6e  SZ bytes. Wal-in
5b20: 64 65 78 20 70 61 67 65 73 20 61 72 65 0a 2a 2a  dex pages are.**
5b30: 20 6e 75 6d 62 65 72 65 64 20 66 72 6f 6d 20 7a   numbered from z
5b40: 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ero..**.** If th
5b50: 69 73 20 63 61 6c 6c 20 69 73 20 73 75 63 63 65  is call is succe
5b60: 73 73 66 75 6c 2c 20 2a 70 70 50 61 67 65 20 69  ssful, *ppPage i
5b70: 73 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74  s set to point t
5b80: 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a  o the wal-index.
5b90: 2a 2a 20 70 61 67 65 20 61 6e 64 20 53 51 4c 49  ** page and SQLI
5ba0: 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
5bb0: 64 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 20 28  d. If an error (
5bc0: 61 6e 20 4f 4f 4d 20 6f 72 20 56 46 53 20 65 72  an OOM or VFS er
5bd0: 72 6f 72 29 20 6f 63 63 75 72 73 2c 0a 2a 2a 20  ror) occurs,.** 
5be0: 74 68 65 6e 20 61 6e 20 53 51 4c 69 74 65 20 65  then an SQLite e
5bf0: 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74  rror code is ret
5c00: 75 72 6e 65 64 20 61 6e 64 20 2a 70 70 50 61 67  urned and *ppPag
5c10: 65 20 69 73 20 73 65 74 20 74 6f 20 30 2e 0a 2a  e is set to 0..*
5c20: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
5c30: 49 6e 64 65 78 50 61 67 65 28 57 61 6c 20 2a 70  IndexPage(Wal *p
5c40: 57 61 6c 2c 20 69 6e 74 20 69 50 61 67 65 2c 20  Wal, int iPage, 
5c50: 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 70  volatile u32 **p
5c60: 70 50 61 67 65 29 7b 0a 20 20 69 6e 74 20 72 63  pPage){.  int rc
5c70: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20   = SQLITE_OK;.. 
5c80: 20 2f 2a 20 45 6e 6c 61 72 67 65 20 74 68 65 20   /* Enlarge the 
5c90: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 5d  pWal->apWiData[]
5ca0: 20 61 72 72 61 79 20 69 66 20 72 65 71 75 69 72   array if requir
5cb0: 65 64 20 2a 2f 0a 20 20 69 66 28 20 70 57 61 6c  ed */.  if( pWal
5cc0: 2d 3e 6e 57 69 44 61 74 61 3c 3d 69 50 61 67 65  ->nWiData<=iPage
5cd0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 42 79 74   ){.    int nByt
5ce0: 65 20 3d 20 73 69 7a 65 6f 66 28 75 33 32 2a 29  e = sizeof(u32*)
5cf0: 2a 28 69 50 61 67 65 2b 31 29 3b 0a 20 20 20 20  *(iPage+1);.    
5d00: 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 61  volatile u32 **a
5d10: 70 4e 65 77 3b 0a 20 20 20 20 61 70 4e 65 77 20  pNew;.    apNew 
5d20: 3d 20 28 76 6f 6c 61 74 69 6c 65 20 75 33 32 20  = (volatile u32 
5d30: 2a 2a 29 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c  **)sqlite3_reall
5d40: 6f 63 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d  oc((void *)pWal-
5d50: 3e 61 70 57 69 44 61 74 61 2c 20 6e 42 79 74 65  >apWiData, nByte
5d60: 29 3b 0a 20 20 20 20 69 66 28 20 21 61 70 4e 65  );.    if( !apNe
5d70: 77 20 29 7b 0a 20 20 20 20 20 20 2a 70 70 50 61  w ){.      *ppPa
5d80: 67 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 65  ge = 0;.      re
5d90: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
5da0: 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d  M;.    }.    mem
5db0: 73 65 74 28 28 76 6f 69 64 2a 29 26 61 70 4e 65  set((void*)&apNe
5dc0: 77 5b 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 5d  w[pWal->nWiData]
5dd0: 2c 20 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20  , 0,.           
5de0: 73 69 7a 65 6f 66 28 75 33 32 2a 29 2a 28 69 50  sizeof(u32*)*(iP
5df0: 61 67 65 2b 31 2d 70 57 61 6c 2d 3e 6e 57 69 44  age+1-pWal->nWiD
5e00: 61 74 61 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d  ata));.    pWal-
5e10: 3e 61 70 57 69 44 61 74 61 20 3d 20 61 70 4e 65  >apWiData = apNe
5e20: 77 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 6e 57 69  w;.    pWal->nWi
5e30: 44 61 74 61 20 3d 20 69 50 61 67 65 2b 31 3b 0a  Data = iPage+1;.
5e40: 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 71 75 65 73    }..  /* Reques
5e50: 74 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74  t a pointer to t
5e60: 68 65 20 72 65 71 75 69 72 65 64 20 70 61 67 65  he required page
5e70: 20 66 72 6f 6d 20 74 68 65 20 56 46 53 20 2a 2f   from the VFS */
5e80: 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 61 70 57  .  if( pWal->apW
5e90: 69 44 61 74 61 5b 69 50 61 67 65 5d 3d 3d 30 20  iData[iPage]==0 
5ea0: 29 7b 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d  ){.    if( pWal-
5eb0: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d  >exclusiveMode==
5ec0: 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d  WAL_HEAPMEMORY_M
5ed0: 4f 44 45 20 29 7b 0a 20 20 20 20 20 20 70 57 61  ODE ){.      pWa
5ee0: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67  l->apWiData[iPag
5ef0: 65 5d 20 3d 20 28 75 33 32 20 76 6f 6c 61 74 69  e] = (u32 volati
5f00: 6c 65 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c  le *)sqlite3Mall
5f10: 6f 63 5a 65 72 6f 28 57 41 4c 49 4e 44 45 58 5f  ocZero(WALINDEX_
5f20: 50 47 53 5a 29 3b 0a 20 20 20 20 20 20 69 66 28  PGSZ);.      if(
5f30: 20 21 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61   !pWal->apWiData
5f40: 5b 69 50 61 67 65 5d 20 29 20 72 63 20 3d 20 53  [iPage] ) rc = S
5f50: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
5f60: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
5f70: 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4d   = sqlite3OsShmM
5f80: 61 70 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20  ap(pWal->pDbFd, 
5f90: 69 50 61 67 65 2c 20 57 41 4c 49 4e 44 45 58 5f  iPage, WALINDEX_
5fa0: 50 47 53 5a 2c 20 0a 20 20 20 20 20 20 20 20 20  PGSZ, .         
5fb0: 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
5fc0: 2c 20 28 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65  , (void volatile
5fd0: 20 2a 2a 29 26 70 57 61 6c 2d 3e 61 70 57 69 44   **)&pWal->apWiD
5fe0: 61 74 61 5b 69 50 61 67 65 5d 0a 20 20 20 20 20  ata[iPage].     
5ff0: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20   );.    }.  }.. 
6000: 20 2a 70 70 50 61 67 65 20 3d 20 70 57 61 6c 2d   *ppPage = pWal-
6010: 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d  >apWiData[iPage]
6020: 3b 0a 20 20 61 73 73 65 72 74 28 20 69 50 61 67  ;.  assert( iPag
6030: 65 3d 3d 30 20 7c 7c 20 2a 70 70 50 61 67 65 20  e==0 || *ppPage 
6040: 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  || rc!=SQLITE_OK
6050: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   );.  return rc;
6060: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
6070: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
6080: 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 73 74  e WalCkptInfo st
6090: 72 75 63 74 75 72 65 20 69 6e 20 74 68 65 20 77  ructure in the w
60a0: 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 73 74 61  al-index..*/.sta
60b0: 74 69 63 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c  tic volatile Wal
60c0: 43 6b 70 74 49 6e 66 6f 20 2a 77 61 6c 43 6b 70  CkptInfo *walCkp
60d0: 74 49 6e 66 6f 28 57 61 6c 20 2a 70 57 61 6c 29  tInfo(Wal *pWal)
60e0: 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  {.  assert( pWal
60f0: 2d 3e 6e 57 69 44 61 74 61 3e 30 20 26 26 20 70  ->nWiData>0 && p
6100: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
6110: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 76 6f   );.  return (vo
6120: 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e  latile WalCkptIn
6130: 66 6f 2a 29 26 28 70 57 61 6c 2d 3e 61 70 57 69  fo*)&(pWal->apWi
6140: 44 61 74 61 5b 30 5d 5b 73 69 7a 65 6f 66 28 57  Data[0][sizeof(W
6150: 61 6c 49 6e 64 65 78 48 64 72 29 2f 32 5d 29 3b  alIndexHdr)/2]);
6160: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
6170: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
6180: 65 20 57 61 6c 49 6e 64 65 78 48 64 72 20 73 74  e WalIndexHdr st
6190: 72 75 63 74 75 72 65 20 69 6e 20 74 68 65 20 77  ructure in the w
61a0: 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 73 74 61  al-index..*/.sta
61b0: 74 69 63 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c  tic volatile Wal
61c0: 49 6e 64 65 78 48 64 72 20 2a 77 61 6c 49 6e 64  IndexHdr *walInd
61d0: 65 78 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 29  exHdr(Wal *pWal)
61e0: 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  {.  assert( pWal
61f0: 2d 3e 6e 57 69 44 61 74 61 3e 30 20 26 26 20 70  ->nWiData>0 && p
6200: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
6210: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 76 6f   );.  return (vo
6220: 6c 61 74 69 6c 65 20 57 61 6c 49 6e 64 65 78 48  latile WalIndexH
6230: 64 72 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44 61  dr*)pWal->apWiDa
6240: 74 61 5b 30 5d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  ta[0];.}../*.** 
6250: 54 68 65 20 61 72 67 75 6d 65 6e 74 20 74 6f 20  The argument to 
6260: 74 68 69 73 20 6d 61 63 72 6f 20 6d 75 73 74 20  this macro must 
6270: 62 65 20 6f 66 20 74 79 70 65 20 75 33 32 2e 20  be of type u32. 
6280: 4f 6e 20 61 20 6c 69 74 74 6c 65 2d 65 6e 64 69  On a little-endi
6290: 61 6e 0a 2a 2a 20 61 72 63 68 69 74 65 63 74 75  an.** architectu
62a0: 72 65 2c 20 69 74 20 72 65 74 75 72 6e 73 20 74  re, it returns t
62b0: 68 65 20 75 33 32 20 76 61 6c 75 65 20 74 68 61  he u32 value tha
62c0: 74 20 72 65 73 75 6c 74 73 20 66 72 6f 6d 20 69  t results from i
62d0: 6e 74 65 72 70 72 65 74 69 6e 67 0a 2a 2a 20 74  nterpreting.** t
62e0: 68 65 20 34 20 62 79 74 65 73 20 61 73 20 61 20  he 4 bytes as a 
62f0: 62 69 67 2d 65 6e 64 69 61 6e 20 76 61 6c 75 65  big-endian value
6300: 2e 20 4f 6e 20 61 20 62 69 67 2d 65 6e 64 69 61  . On a big-endia
6310: 6e 20 61 72 63 68 69 74 65 63 74 75 72 65 2c 20  n architecture, 
6320: 69 74 0a 2a 2a 20 72 65 74 75 72 6e 73 20 74 68  it.** returns th
6330: 65 20 76 61 6c 75 65 20 74 68 61 74 20 77 6f 75  e value that wou
6340: 6c 64 20 62 65 20 70 72 6f 64 75 63 65 64 20 62  ld be produced b
6350: 79 20 69 6e 74 65 70 72 65 74 69 6e 67 20 74 68  y intepreting th
6360: 65 20 34 20 62 79 74 65 73 0a 2a 2a 20 6f 66 20  e 4 bytes.** of 
6370: 74 68 65 20 69 6e 70 75 74 20 76 61 6c 75 65 20  the input value 
6380: 61 73 20 61 20 6c 69 74 74 6c 65 2d 65 6e 64 69  as a little-endi
6390: 61 6e 20 69 6e 74 65 67 65 72 2e 0a 2a 2f 0a 23  an integer..*/.#
63a0: 64 65 66 69 6e 65 20 42 59 54 45 53 57 41 50 33  define BYTESWAP3
63b0: 32 28 78 29 20 28 20 5c 0a 20 20 20 20 28 28 28  2(x) ( \.    (((
63c0: 78 29 26 30 78 30 30 30 30 30 30 46 46 29 3c 3c  x)&0x000000FF)<<
63d0: 32 34 29 20 2b 20 28 28 28 78 29 26 30 78 30 30  24) + (((x)&0x00
63e0: 30 30 46 46 30 30 29 3c 3c 38 29 20 20 5c 0a 20  00FF00)<<8)  \. 
63f0: 20 2b 20 28 28 28 78 29 26 30 78 30 30 46 46 30   + (((x)&0x00FF0
6400: 30 30 30 29 3e 3e 38 29 20 20 2b 20 28 28 28 78  000)>>8)  + (((x
6410: 29 26 30 78 46 46 30 30 30 30 30 30 29 3e 3e 32  )&0xFF000000)>>2
6420: 34 29 20 5c 0a 29 0a 0a 2f 2a 0a 2a 2a 20 47 65  4) \.)../*.** Ge
6430: 6e 65 72 61 74 65 20 6f 72 20 65 78 74 65 6e 64  nerate or extend
6440: 20 61 6e 20 38 20 62 79 74 65 20 63 68 65 63 6b   an 8 byte check
6450: 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74 68 65  sum based on the
6460: 20 64 61 74 61 20 69 6e 20 0a 2a 2a 20 61 72 72   data in .** arr
6470: 61 79 20 61 42 79 74 65 5b 5d 20 61 6e 64 20 74  ay aByte[] and t
6480: 68 65 20 69 6e 69 74 69 61 6c 20 76 61 6c 75 65  he initial value
6490: 73 20 6f 66 20 61 49 6e 5b 30 5d 20 61 6e 64 20  s of aIn[0] and 
64a0: 61 49 6e 5b 31 5d 20 28 6f 72 0a 2a 2a 20 69 6e  aIn[1] (or.** in
64b0: 69 74 69 61 6c 20 76 61 6c 75 65 73 20 6f 66 20  itial values of 
64c0: 30 20 61 6e 64 20 30 20 69 66 20 61 49 6e 3d 3d  0 and 0 if aIn==
64d0: 4e 55 4c 4c 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  NULL)..**.** The
64e0: 20 63 68 65 63 6b 73 75 6d 20 69 73 20 77 72 69   checksum is wri
64f0: 74 74 65 6e 20 62 61 63 6b 20 69 6e 74 6f 20 61  tten back into a
6500: 4f 75 74 5b 5d 20 62 65 66 6f 72 65 20 72 65 74  Out[] before ret
6510: 75 72 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 6e 42  urning..**.** nB
6520: 79 74 65 20 6d 75 73 74 20 62 65 20 61 20 70 6f  yte must be a po
6530: 73 69 74 69 76 65 20 6d 75 6c 74 69 70 6c 65 20  sitive multiple 
6540: 6f 66 20 38 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  of 8..*/.static 
6550: 76 6f 69 64 20 77 61 6c 43 68 65 63 6b 73 75 6d  void walChecksum
6560: 42 79 74 65 73 28 0a 20 20 69 6e 74 20 6e 61 74  Bytes(.  int nat
6570: 69 76 65 43 6b 73 75 6d 2c 20 2f 2a 20 54 72 75  iveCksum, /* Tru
6580: 65 20 66 6f 72 20 6e 61 74 69 76 65 20 62 79 74  e for native byt
6590: 65 2d 6f 72 64 65 72 2c 20 66 61 6c 73 65 20 66  e-order, false f
65a0: 6f 72 20 6e 6f 6e 2d 6e 61 74 69 76 65 20 2a 2f  or non-native */
65b0: 0a 20 20 75 38 20 2a 61 2c 20 20 20 20 20 20 20  .  u8 *a,       
65c0: 20 20 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 74      /* Content t
65d0: 6f 20 62 65 20 63 68 65 63 6b 73 75 6d 6d 65 64  o be checksummed
65e0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 2c   */.  int nByte,
65f0: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
6600: 6f 66 20 63 6f 6e 74 65 6e 74 20 69 6e 20 61 5b  of content in a[
6610: 5d 2e 20 20 4d 75 73 74 20 62 65 20 61 20 6d 75  ].  Must be a mu
6620: 6c 74 69 70 6c 65 20 6f 66 20 38 2e 20 2a 2f 0a  ltiple of 8. */.
6630: 20 20 63 6f 6e 73 74 20 75 33 32 20 2a 61 49 6e    const u32 *aIn
6640: 2c 20 20 2f 2a 20 49 6e 69 74 69 61 6c 20 63 68  ,  /* Initial ch
6650: 65 63 6b 73 75 6d 20 76 61 6c 75 65 20 69 6e 70  ecksum value inp
6660: 75 74 20 2a 2f 0a 20 20 75 33 32 20 2a 61 4f 75  ut */.  u32 *aOu
6670: 74 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a  t        /* OUT:
6680: 20 46 69 6e 61 6c 20 63 68 65 63 6b 73 75 6d 20   Final checksum 
6690: 76 61 6c 75 65 20 6f 75 74 70 75 74 20 2a 2f 0a  value output */.
66a0: 29 7b 0a 20 20 75 33 32 20 73 31 2c 20 73 32 3b  ){.  u32 s1, s2;
66b0: 0a 20 20 75 33 32 20 2a 61 44 61 74 61 20 3d 20  .  u32 *aData = 
66c0: 28 75 33 32 20 2a 29 61 3b 0a 20 20 75 33 32 20  (u32 *)a;.  u32 
66d0: 2a 61 45 6e 64 20 3d 20 28 75 33 32 20 2a 29 26  *aEnd = (u32 *)&
66e0: 61 5b 6e 42 79 74 65 5d 3b 0a 0a 20 20 69 66 28  a[nByte];..  if(
66f0: 20 61 49 6e 20 29 7b 0a 20 20 20 20 73 31 20 3d   aIn ){.    s1 =
6700: 20 61 49 6e 5b 30 5d 3b 0a 20 20 20 20 73 32 20   aIn[0];.    s2 
6710: 3d 20 61 49 6e 5b 31 5d 3b 0a 20 20 7d 65 6c 73  = aIn[1];.  }els
6720: 65 7b 0a 20 20 20 20 73 31 20 3d 20 73 32 20 3d  e{.    s1 = s2 =
6730: 20 30 3b 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72   0;.  }..  asser
6740: 74 28 20 6e 42 79 74 65 3e 3d 38 20 29 3b 0a 20  t( nByte>=8 );. 
6750: 20 61 73 73 65 72 74 28 20 28 6e 42 79 74 65 26   assert( (nByte&
6760: 30 78 30 30 30 30 30 30 30 37 29 3d 3d 30 20 29  0x00000007)==0 )
6770: 3b 0a 0a 20 20 69 66 28 20 6e 61 74 69 76 65 43  ;..  if( nativeC
6780: 6b 73 75 6d 20 29 7b 0a 20 20 20 20 64 6f 20 7b  ksum ){.    do {
6790: 0a 20 20 20 20 20 20 73 31 20 2b 3d 20 2a 61 44  .      s1 += *aD
67a0: 61 74 61 2b 2b 20 2b 20 73 32 3b 0a 20 20 20 20  ata++ + s2;.    
67b0: 20 20 73 32 20 2b 3d 20 2a 61 44 61 74 61 2b 2b    s2 += *aData++
67c0: 20 2b 20 73 31 3b 0a 20 20 20 20 7d 77 68 69 6c   + s1;.    }whil
67d0: 65 28 20 61 44 61 74 61 3c 61 45 6e 64 20 29 3b  e( aData<aEnd );
67e0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 64 6f  .  }else{.    do
67f0: 20 7b 0a 20 20 20 20 20 20 73 31 20 2b 3d 20 42   {.      s1 += B
6800: 59 54 45 53 57 41 50 33 32 28 61 44 61 74 61 5b  YTESWAP32(aData[
6810: 30 5d 29 20 2b 20 73 32 3b 0a 20 20 20 20 20 20  0]) + s2;.      
6820: 73 32 20 2b 3d 20 42 59 54 45 53 57 41 50 33 32  s2 += BYTESWAP32
6830: 28 61 44 61 74 61 5b 31 5d 29 20 2b 20 73 31 3b  (aData[1]) + s1;
6840: 0a 20 20 20 20 20 20 61 44 61 74 61 20 2b 3d 20  .      aData += 
6850: 32 3b 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 61  2;.    }while( a
6860: 44 61 74 61 3c 61 45 6e 64 20 29 3b 0a 20 20 7d  Data<aEnd );.  }
6870: 0a 0a 20 20 61 4f 75 74 5b 30 5d 20 3d 20 73 31  ..  aOut[0] = s1
6880: 3b 0a 20 20 61 4f 75 74 5b 31 5d 20 3d 20 73 32  ;.  aOut[1] = s2
6890: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
68a0: 20 77 61 6c 53 68 6d 42 61 72 72 69 65 72 28 57   walShmBarrier(W
68b0: 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28  al *pWal){.  if(
68c0: 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
68d0: 4d 6f 64 65 21 3d 57 41 4c 5f 48 45 41 50 4d 45  Mode!=WAL_HEAPME
68e0: 4d 4f 52 59 5f 4d 4f 44 45 20 29 7b 0a 20 20 20  MORY_MODE ){.   
68f0: 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 42 61 72   sqlite3OsShmBar
6900: 72 69 65 72 28 70 57 61 6c 2d 3e 70 44 62 46 64  rier(pWal->pDbFd
6910: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
6920: 57 72 69 74 65 20 74 68 65 20 68 65 61 64 65 72  Write the header
6930: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e 20   information in 
6940: 70 57 61 6c 2d 3e 68 64 72 20 69 6e 74 6f 20 74  pWal->hdr into t
6950: 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2a  he wal-index..**
6960: 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b 73 75 6d  .** The checksum
6970: 20 6f 6e 20 70 57 61 6c 2d 3e 68 64 72 20 69 73   on pWal->hdr is
6980: 20 75 70 64 61 74 65 64 20 62 65 66 6f 72 65 20   updated before 
6990: 69 74 20 69 73 20 77 72 69 74 74 65 6e 2e 0a 2a  it is written..*
69a0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61  /.static void wa
69b0: 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72 28 57  lIndexWriteHdr(W
69c0: 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 76 6f 6c  al *pWal){.  vol
69d0: 61 74 69 6c 65 20 57 61 6c 49 6e 64 65 78 48 64  atile WalIndexHd
69e0: 72 20 2a 61 48 64 72 20 3d 20 77 61 6c 49 6e 64  r *aHdr = walInd
69f0: 65 78 48 64 72 28 70 57 61 6c 29 3b 0a 20 20 63  exHdr(pWal);.  c
6a00: 6f 6e 73 74 20 69 6e 74 20 6e 43 6b 73 75 6d 20  onst int nCksum 
6a10: 3d 20 6f 66 66 73 65 74 6f 66 28 57 61 6c 49 6e  = offsetof(WalIn
6a20: 64 65 78 48 64 72 2c 20 61 43 6b 73 75 6d 29 3b  dexHdr, aCksum);
6a30: 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ..  assert( pWal
6a40: 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20  ->writeLock );. 
6a50: 20 70 57 61 6c 2d 3e 68 64 72 2e 69 73 49 6e 69   pWal->hdr.isIni
6a60: 74 20 3d 20 31 3b 0a 20 20 70 57 61 6c 2d 3e 68  t = 1;.  pWal->h
6a70: 64 72 2e 69 56 65 72 73 69 6f 6e 20 3d 20 57 41  dr.iVersion = WA
6a80: 4c 49 4e 44 45 58 5f 4d 41 58 5f 56 45 52 53 49  LINDEX_MAX_VERSI
6a90: 4f 4e 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75  ON;.  walChecksu
6aa0: 6d 42 79 74 65 73 28 31 2c 20 28 75 38 2a 29 26  mBytes(1, (u8*)&
6ab0: 70 57 61 6c 2d 3e 68 64 72 2c 20 6e 43 6b 73 75  pWal->hdr, nCksu
6ac0: 6d 2c 20 30 2c 20 70 57 61 6c 2d 3e 68 64 72 2e  m, 0, pWal->hdr.
6ad0: 61 43 6b 73 75 6d 29 3b 0a 20 20 6d 65 6d 63 70  aCksum);.  memcp
6ae0: 79 28 28 76 6f 69 64 20 2a 29 26 61 48 64 72 5b  y((void *)&aHdr[
6af0: 31 5d 2c 20 28 76 6f 69 64 20 2a 29 26 70 57 61  1], (void *)&pWa
6b00: 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57  l->hdr, sizeof(W
6b10: 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 20 20  alIndexHdr));.  
6b20: 77 61 6c 53 68 6d 42 61 72 72 69 65 72 28 70 57  walShmBarrier(pW
6b30: 61 6c 29 3b 0a 20 20 6d 65 6d 63 70 79 28 28 76  al);.  memcpy((v
6b40: 6f 69 64 20 2a 29 26 61 48 64 72 5b 30 5d 2c 20  oid *)&aHdr[0], 
6b50: 28 76 6f 69 64 20 2a 29 26 70 57 61 6c 2d 3e 68  (void *)&pWal->h
6b60: 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  dr, sizeof(WalIn
6b70: 64 65 78 48 64 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a  dexHdr));.}../*.
6b80: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
6b90: 20 65 6e 63 6f 64 65 73 20 61 20 73 69 6e 67 6c   encodes a singl
6ba0: 65 20 66 72 61 6d 65 20 68 65 61 64 65 72 20 61  e frame header a
6bb0: 6e 64 20 77 72 69 74 65 73 20 69 74 20 74 6f 20  nd writes it to 
6bc0: 61 20 62 75 66 66 65 72 0a 2a 2a 20 73 75 70 70  a buffer.** supp
6bd0: 6c 69 65 64 20 62 79 20 74 68 65 20 63 61 6c 6c  lied by the call
6be0: 65 72 2e 20 41 20 66 72 61 6d 65 2d 68 65 61 64  er. A frame-head
6bf0: 65 72 20 69 73 20 6d 61 64 65 20 75 70 20 6f 66  er is made up of
6c00: 20 61 20 73 65 72 69 65 73 20 6f 66 20 0a 2a 2a   a series of .**
6c10: 20 34 2d 62 79 74 65 20 62 69 67 2d 65 6e 64 69   4-byte big-endi
6c20: 61 6e 20 69 6e 74 65 67 65 72 73 2c 20 61 73 20  an integers, as 
6c30: 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
6c40: 20 20 20 30 3a 20 50 61 67 65 20 6e 75 6d 62 65     0: Page numbe
6c50: 72 2e 0a 2a 2a 20 20 20 20 20 34 3a 20 46 6f 72  r..**     4: For
6c60: 20 63 6f 6d 6d 69 74 20 72 65 63 6f 72 64 73 2c   commit records,
6c70: 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65   the size of the
6c80: 20 64 61 74 61 62 61 73 65 20 69 6d 61 67 65 20   database image 
6c90: 69 6e 20 70 61 67 65 73 20 0a 2a 2a 20 20 20 20  in pages .**    
6ca0: 20 20 20 20 61 66 74 65 72 20 74 68 65 20 63 6f      after the co
6cb0: 6d 6d 69 74 2e 20 46 6f 72 20 61 6c 6c 20 6f 74  mmit. For all ot
6cc0: 68 65 72 20 72 65 63 6f 72 64 73 2c 20 7a 65 72  her records, zer
6cd0: 6f 2e 0a 2a 2a 20 20 20 20 20 38 3a 20 53 61 6c  o..**     8: Sal
6ce0: 74 2d 31 20 28 63 6f 70 69 65 64 20 66 72 6f 6d  t-1 (copied from
6cf0: 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72 29   the wal-header)
6d00: 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61 6c 74 2d  .**    12: Salt-
6d10: 32 20 28 63 6f 70 69 65 64 20 66 72 6f 6d 20 74  2 (copied from t
6d20: 68 65 20 77 61 6c 2d 68 65 61 64 65 72 29 0a 2a  he wal-header).*
6d30: 2a 20 20 20 20 31 36 3a 20 43 68 65 63 6b 73 75  *    16: Checksu
6d40: 6d 2d 31 2e 0a 2a 2a 20 20 20 20 32 30 3a 20 43  m-1..**    20: C
6d50: 68 65 63 6b 73 75 6d 2d 32 2e 0a 2a 2f 0a 73 74  hecksum-2..*/.st
6d60: 61 74 69 63 20 76 6f 69 64 20 77 61 6c 45 6e 63  atic void walEnc
6d70: 6f 64 65 46 72 61 6d 65 28 0a 20 20 57 61 6c 20  odeFrame(.  Wal 
6d80: 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20  *pWal,          
6d90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
6da0: 68 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c  he write-ahead l
6db0: 6f 67 20 2a 2f 0a 20 20 75 33 32 20 69 50 61 67  og */.  u32 iPag
6dc0: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
6dd0: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
6de0: 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  ase page number 
6df0: 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20 20 75  for frame */.  u
6e00: 33 32 20 6e 54 72 75 6e 63 61 74 65 2c 20 20 20  32 nTruncate,   
6e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6e20: 2a 20 4e 65 77 20 64 62 20 73 69 7a 65 20 28 6f  * New db size (o
6e30: 72 20 30 20 66 6f 72 20 6e 6f 6e 2d 63 6f 6d 6d  r 0 for non-comm
6e40: 69 74 20 66 72 61 6d 65 73 29 20 2a 2f 0a 20 20  it frames) */.  
6e50: 75 38 20 2a 61 44 61 74 61 2c 20 20 20 20 20 20  u8 *aData,      
6e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e70: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 70 61  /* Pointer to pa
6e80: 67 65 20 64 61 74 61 20 2a 2f 0a 20 20 75 38 20  ge data */.  u8 
6e90: 2a 61 46 72 61 6d 65 20 20 20 20 20 20 20 20 20  *aFrame         
6ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6eb0: 4f 55 54 3a 20 57 72 69 74 65 20 65 6e 63 6f 64  OUT: Write encod
6ec0: 65 64 20 66 72 61 6d 65 20 68 65 72 65 20 2a 2f  ed frame here */
6ed0: 0a 29 7b 0a 20 20 69 6e 74 20 6e 61 74 69 76 65  .){.  int native
6ee0: 43 6b 73 75 6d 3b 20 20 20 20 20 20 20 20 20 20  Cksum;          
6ef0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 66 6f        /* True fo
6f00: 72 20 6e 61 74 69 76 65 20 62 79 74 65 2d 6f 72  r native byte-or
6f10: 64 65 72 20 63 68 65 63 6b 73 75 6d 73 20 2a 2f  der checksums */
6f20: 0a 20 20 75 33 32 20 2a 61 43 6b 73 75 6d 20 3d  .  u32 *aCksum =
6f30: 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
6f40: 65 43 6b 73 75 6d 3b 0a 20 20 61 73 73 65 72 74  eCksum;.  assert
6f50: 28 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  ( WAL_FRAME_HDRS
6f60: 49 5a 45 3d 3d 32 34 20 29 3b 0a 20 20 73 71 6c  IZE==24 );.  sql
6f70: 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 46  ite3Put4byte(&aF
6f80: 72 61 6d 65 5b 30 5d 2c 20 69 50 61 67 65 29 3b  rame[0], iPage);
6f90: 0a 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79  .  sqlite3Put4by
6fa0: 74 65 28 26 61 46 72 61 6d 65 5b 34 5d 2c 20 6e  te(&aFrame[4], n
6fb0: 54 72 75 6e 63 61 74 65 29 3b 0a 20 20 6d 65 6d  Truncate);.  mem
6fc0: 63 70 79 28 26 61 46 72 61 6d 65 5b 38 5d 2c 20  cpy(&aFrame[8], 
6fd0: 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c  pWal->hdr.aSalt,
6fe0: 20 38 29 3b 0a 0a 20 20 6e 61 74 69 76 65 43 6b   8);..  nativeCk
6ff0: 73 75 6d 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72  sum = (pWal->hdr
7000: 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d 3d 53 51  .bigEndCksum==SQ
7010: 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e 29 3b  LITE_BIGENDIAN);
7020: 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79  .  walChecksumBy
7030: 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c  tes(nativeCksum,
7040: 20 61 46 72 61 6d 65 2c 20 38 2c 20 61 43 6b 73   aFrame, 8, aCks
7050: 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a 20 20 77  um, aCksum);.  w
7060: 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
7070: 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 61 44 61  nativeCksum, aDa
7080: 74 61 2c 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65  ta, pWal->szPage
7090: 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d  , aCksum, aCksum
70a0: 29 3b 0a 0a 20 20 73 71 6c 69 74 65 33 50 75 74  );..  sqlite3Put
70b0: 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 31 36  4byte(&aFrame[16
70c0: 5d 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b 0a 20  ], aCksum[0]);. 
70d0: 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65   sqlite3Put4byte
70e0: 28 26 61 46 72 61 6d 65 5b 32 30 5d 2c 20 61 43  (&aFrame[20], aC
70f0: 6b 73 75 6d 5b 31 5d 29 3b 0a 7d 0a 0a 2f 2a 0a  ksum[1]);.}../*.
7100: 2a 2a 20 43 68 65 63 6b 20 74 6f 20 73 65 65 20  ** Check to see 
7110: 69 66 20 74 68 65 20 66 72 61 6d 65 20 77 69 74  if the frame wit
7120: 68 20 68 65 61 64 65 72 20 69 6e 20 61 46 72 61  h header in aFra
7130: 6d 65 5b 5d 20 61 6e 64 20 63 6f 6e 74 65 6e 74  me[] and content
7140: 0a 2a 2a 20 69 6e 20 61 44 61 74 61 5b 5d 20 69  .** in aData[] i
7150: 73 20 76 61 6c 69 64 2e 20 20 49 66 20 69 74 20  s valid.  If it 
7160: 69 73 20 61 20 76 61 6c 69 64 20 66 72 61 6d 65  is a valid frame
7170: 2c 20 66 69 6c 6c 20 2a 70 69 50 61 67 65 20 61  , fill *piPage a
7180: 6e 64 0a 2a 2a 20 2a 70 6e 54 72 75 6e 63 61 74  nd.** *pnTruncat
7190: 65 20 61 6e 64 20 72 65 74 75 72 6e 20 74 72 75  e and return tru
71a0: 65 2e 20 20 52 65 74 75 72 6e 20 69 66 20 74 68  e.  Return if th
71b0: 65 20 66 72 61 6d 65 20 69 73 20 6e 6f 74 20 76  e frame is not v
71c0: 61 6c 69 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  alid..*/.static 
71d0: 69 6e 74 20 77 61 6c 44 65 63 6f 64 65 46 72 61  int walDecodeFra
71e0: 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c  me(.  Wal *pWal,
71f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7200: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 77 72 69        /* The wri
7210: 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 2a 2f 0a  te-ahead log */.
7220: 20 20 75 33 32 20 2a 70 69 50 61 67 65 2c 20 20    u32 *piPage,  
7230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7240: 20 20 2f 2a 20 4f 55 54 3a 20 44 61 74 61 62 61    /* OUT: Databa
7250: 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 66  se page number f
7260: 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20 20 75 33  or frame */.  u3
7270: 32 20 2a 70 6e 54 72 75 6e 63 61 74 65 2c 20 20  2 *pnTruncate,  
7280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7290: 20 4f 55 54 3a 20 4e 65 77 20 64 62 20 73 69 7a   OUT: New db siz
72a0: 65 20 28 6f 72 20 30 20 69 66 20 6e 6f 74 20 63  e (or 0 if not c
72b0: 6f 6d 6d 69 74 29 20 2a 2f 0a 20 20 75 38 20 2a  ommit) */.  u8 *
72c0: 61 44 61 74 61 2c 20 20 20 20 20 20 20 20 20 20  aData,          
72d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
72e0: 6f 69 6e 74 65 72 20 74 6f 20 70 61 67 65 20 64  ointer to page d
72f0: 61 74 61 20 28 66 6f 72 20 63 68 65 63 6b 73 75  ata (for checksu
7300: 6d 29 20 2a 2f 0a 20 20 75 38 20 2a 61 46 72 61  m) */.  u8 *aFra
7310: 6d 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20  me              
7320: 20 20 20 20 20 20 20 20 2f 2a 20 46 72 61 6d 65          /* Frame
7330: 20 64 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e   data */.){.  in
7340: 74 20 6e 61 74 69 76 65 43 6b 73 75 6d 3b 20 20  t nativeCksum;  
7350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7360: 20 54 72 75 65 20 66 6f 72 20 6e 61 74 69 76 65   True for native
7370: 20 62 79 74 65 2d 6f 72 64 65 72 20 63 68 65 63   byte-order chec
7380: 6b 73 75 6d 73 20 2a 2f 0a 20 20 75 33 32 20 2a  ksums */.  u32 *
7390: 61 43 6b 73 75 6d 20 3d 20 70 57 61 6c 2d 3e 68  aCksum = pWal->h
73a0: 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 3b 0a  dr.aFrameCksum;.
73b0: 20 20 75 33 32 20 70 67 6e 6f 3b 20 20 20 20 20    u32 pgno;     
73c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
73d0: 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72    /* Page number
73e0: 20 6f 66 20 74 68 65 20 66 72 61 6d 65 20 2a 2f   of the frame */
73f0: 0a 20 20 61 73 73 65 72 74 28 20 57 41 4c 5f 46  .  assert( WAL_F
7400: 52 41 4d 45 5f 48 44 52 53 49 5a 45 3d 3d 32 34  RAME_HDRSIZE==24
7410: 20 29 3b 0a 0a 20 20 2f 2a 20 41 20 66 72 61 6d   );..  /* A fram
7420: 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20  e is only valid 
7430: 69 66 20 74 68 65 20 73 61 6c 74 20 76 61 6c 75  if the salt valu
7440: 65 73 20 69 6e 20 74 68 65 20 66 72 61 6d 65 2d  es in the frame-
7450: 68 65 61 64 65 72 0a 20 20 2a 2a 20 6d 61 74 63  header.  ** matc
7460: 68 20 74 68 65 20 73 61 6c 74 20 76 61 6c 75 65  h the salt value
7470: 73 20 69 6e 20 74 68 65 20 77 61 6c 2d 68 65 61  s in the wal-hea
7480: 64 65 72 2e 20 0a 20 20 2a 2f 0a 20 20 69 66 28  der. .  */.  if(
7490: 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68   memcmp(&pWal->h
74a0: 64 72 2e 61 53 61 6c 74 2c 20 26 61 46 72 61 6d  dr.aSalt, &aFram
74b0: 65 5b 38 5d 2c 20 38 29 21 3d 30 20 29 7b 0a 20  e[8], 8)!=0 ){. 
74c0: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d     return 0;.  }
74d0: 0a 0a 20 20 2f 2a 20 41 20 66 72 61 6d 65 20 69  ..  /* A frame i
74e0: 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20 69 66 20  s only valid if 
74f0: 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  the page number 
7500: 69 73 20 63 72 65 61 74 65 72 20 74 68 61 6e 20  is creater than 
7510: 7a 65 72 6f 2e 0a 20 20 2a 2f 0a 20 20 70 67 6e  zero..  */.  pgn
7520: 6f 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62  o = sqlite3Get4b
7530: 79 74 65 28 26 61 46 72 61 6d 65 5b 30 5d 29 3b  yte(&aFrame[0]);
7540: 0a 20 20 69 66 28 20 70 67 6e 6f 3d 3d 30 20 29  .  if( pgno==0 )
7550: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  {.    return 0;.
7560: 20 20 7d 0a 0a 20 20 2f 2a 20 41 20 66 72 61 6d    }..  /* A fram
7570: 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20  e is only valid 
7580: 69 66 20 61 20 63 68 65 63 6b 73 75 6d 20 6f 66  if a checksum of
7590: 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72 2c   the WAL header,
75a0: 0a 20 20 2a 2a 20 61 6c 6c 20 70 72 69 6f 72 20  .  ** all prior 
75b0: 66 72 61 6d 73 2c 20 74 68 65 20 66 69 72 73 74  frams, the first
75c0: 20 31 36 20 62 79 74 65 73 20 6f 66 20 74 68 69   16 bytes of thi
75d0: 73 20 66 72 61 6d 65 2d 68 65 61 64 65 72 2c 20  s frame-header, 
75e0: 0a 20 20 2a 2a 20 61 6e 64 20 74 68 65 20 66 72  .  ** and the fr
75f0: 61 6d 65 2d 64 61 74 61 20 6d 61 74 63 68 65 73  ame-data matches
7600: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 69 6e   the checksum in
7610: 20 74 68 65 20 6c 61 73 74 20 38 20 0a 20 20 2a   the last 8 .  *
7620: 2a 20 62 79 74 65 73 20 6f 66 20 74 68 69 73 20  * bytes of this 
7630: 66 72 61 6d 65 2d 68 65 61 64 65 72 2e 0a 20 20  frame-header..  
7640: 2a 2f 0a 20 20 6e 61 74 69 76 65 43 6b 73 75 6d  */.  nativeCksum
7650: 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72 2e 62 69   = (pWal->hdr.bi
7660: 67 45 6e 64 43 6b 73 75 6d 3d 3d 53 51 4c 49 54  gEndCksum==SQLIT
7670: 45 5f 42 49 47 45 4e 44 49 41 4e 29 3b 0a 20 20  E_BIGENDIAN);.  
7680: 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73  walChecksumBytes
7690: 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 61 46  (nativeCksum, aF
76a0: 72 61 6d 65 2c 20 38 2c 20 61 43 6b 73 75 6d 2c  rame, 8, aCksum,
76b0: 20 61 43 6b 73 75 6d 29 3b 0a 20 20 77 61 6c 43   aCksum);.  walC
76c0: 68 65 63 6b 73 75 6d 42 79 74 65 73 28 6e 61 74  hecksumBytes(nat
76d0: 69 76 65 43 6b 73 75 6d 2c 20 61 44 61 74 61 2c  iveCksum, aData,
76e0: 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 2c 20 61   pWal->szPage, a
76f0: 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a  Cksum, aCksum);.
7700: 20 20 69 66 28 20 61 43 6b 73 75 6d 5b 30 5d 21    if( aCksum[0]!
7710: 3d 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65  =sqlite3Get4byte
7720: 28 26 61 46 72 61 6d 65 5b 31 36 5d 29 20 0a 20  (&aFrame[16]) . 
7730: 20 20 7c 7c 20 61 43 6b 73 75 6d 5b 31 5d 21 3d    || aCksum[1]!=
7740: 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
7750: 26 61 46 72 61 6d 65 5b 32 30 5d 29 20 0a 20 20  &aFrame[20]) .  
7760: 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65 63 6b 73  ){.    /* Checks
7770: 75 6d 20 66 61 69 6c 65 64 2e 20 2a 2f 0a 20 20  um failed. */.  
7780: 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a    return 0;.  }.
7790: 0a 20 20 2f 2a 20 49 66 20 77 65 20 72 65 61 63  .  /* If we reac
77a0: 68 20 74 68 69 73 20 70 6f 69 6e 74 2c 20 74 68  h this point, th
77b0: 65 20 66 72 61 6d 65 20 69 73 20 76 61 6c 69 64  e frame is valid
77c0: 2e 20 20 52 65 74 75 72 6e 20 74 68 65 20 70 61  .  Return the pa
77d0: 67 65 20 6e 75 6d 62 65 72 0a 20 20 2a 2a 20 61  ge number.  ** a
77e0: 6e 64 20 74 68 65 20 6e 65 77 20 64 61 74 61 62  nd the new datab
77f0: 61 73 65 20 73 69 7a 65 2e 0a 20 20 2a 2f 0a 20  ase size..  */. 
7800: 20 2a 70 69 50 61 67 65 20 3d 20 70 67 6e 6f 3b   *piPage = pgno;
7810: 0a 20 20 2a 70 6e 54 72 75 6e 63 61 74 65 20 3d  .  *pnTruncate =
7820: 20 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65   sqlite3Get4byte
7830: 28 26 61 46 72 61 6d 65 5b 34 5d 29 3b 0a 20 20  (&aFrame[4]);.  
7840: 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 0a 23 69  return 1;.}...#i
7850: 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  f defined(SQLITE
7860: 5f 54 45 53 54 29 20 26 26 20 64 65 66 69 6e 65  _TEST) && define
7870: 64 28 53 51 4c 49 54 45 5f 44 45 42 55 47 29 0a  d(SQLITE_DEBUG).
7880: 2f 2a 0a 2a 2a 20 4e 61 6d 65 73 20 6f 66 20 6c  /*.** Names of l
7890: 6f 63 6b 73 2e 20 20 54 68 69 73 20 72 6f 75 74  ocks.  This rout
78a0: 69 6e 65 20 69 73 20 75 73 65 64 20 74 6f 20 70  ine is used to p
78b0: 72 6f 76 69 64 65 20 64 65 62 75 67 67 69 6e 67  rovide debugging
78c0: 20 6f 75 74 70 75 74 20 61 6e 64 20 69 73 20 6e   output and is n
78d0: 6f 74 0a 2a 2a 20 61 20 70 61 72 74 20 6f 66 20  ot.** a part of 
78e0: 61 6e 20 6f 72 64 69 6e 61 72 79 20 62 75 69 6c  an ordinary buil
78f0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e  d..*/.static con
7900: 73 74 20 63 68 61 72 20 2a 77 61 6c 4c 6f 63 6b  st char *walLock
7910: 4e 61 6d 65 28 69 6e 74 20 6c 6f 63 6b 49 64 78  Name(int lockIdx
7920: 29 7b 0a 20 20 69 66 28 20 6c 6f 63 6b 49 64 78  ){.  if( lockIdx
7930: 3d 3d 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b  ==WAL_WRITE_LOCK
7940: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 22   ){.    return "
7950: 57 52 49 54 45 2d 4c 4f 43 4b 22 3b 0a 20 20 7d  WRITE-LOCK";.  }
7960: 65 6c 73 65 20 69 66 28 20 6c 6f 63 6b 49 64 78  else if( lockIdx
7970: 3d 3d 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20  ==WAL_CKPT_LOCK 
7980: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 22 43  ){.    return "C
7990: 4b 50 54 2d 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c  KPT-LOCK";.  }el
79a0: 73 65 20 69 66 28 20 6c 6f 63 6b 49 64 78 3d 3d  se if( lockIdx==
79b0: 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b  WAL_RECOVER_LOCK
79c0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 22   ){.    return "
79d0: 52 45 43 4f 56 45 52 2d 4c 4f 43 4b 22 3b 0a 20  RECOVER-LOCK";. 
79e0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 74 61 74   }else{.    stat
79f0: 69 63 20 63 68 61 72 20 7a 4e 61 6d 65 5b 31 35  ic char zName[15
7a00: 5d 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73  ];.    sqlite3_s
7a10: 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f 66 28 7a  nprintf(sizeof(z
7a20: 4e 61 6d 65 29 2c 20 7a 4e 61 6d 65 2c 20 22 52  Name), zName, "R
7a30: 45 41 44 2d 4c 4f 43 4b 5b 25 64 5d 22 2c 0a 20  EAD-LOCK[%d]",. 
7a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7a50: 20 20 20 20 6c 6f 63 6b 49 64 78 2d 57 41 4c 5f      lockIdx-WAL_
7a60: 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20  READ_LOCK(0));. 
7a70: 20 20 20 72 65 74 75 72 6e 20 7a 4e 61 6d 65 3b     return zName;
7a80: 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a  .  }.}.#endif /*
7a90: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54  defined(SQLITE_T
7aa0: 45 53 54 29 20 7c 7c 20 64 65 66 69 6e 65 64 28  EST) || defined(
7ab0: 53 51 4c 49 54 45 5f 44 45 42 55 47 29 20 2a 2f  SQLITE_DEBUG) */
7ac0: 0a 20 20 20 20 0a 0a 2f 2a 0a 2a 2a 20 53 65 74  .    ../*.** Set
7ad0: 20 6f 72 20 72 65 6c 65 61 73 65 20 6c 6f 63 6b   or release lock
7ae0: 73 20 6f 6e 20 74 68 65 20 57 41 4c 2e 20 20 4c  s on the WAL.  L
7af0: 6f 63 6b 73 20 61 72 65 20 65 69 74 68 65 72 20  ocks are either 
7b00: 73 68 61 72 65 64 20 6f 72 20 65 78 63 6c 75 73  shared or exclus
7b10: 69 76 65 2e 0a 2a 2a 20 41 20 6c 6f 63 6b 20 63  ive..** A lock c
7b20: 61 6e 6e 6f 74 20 62 65 20 6d 6f 76 65 64 20 64  annot be moved d
7b30: 69 72 65 63 74 6c 79 20 62 65 74 77 65 65 6e 20  irectly between 
7b40: 73 68 61 72 65 64 20 61 6e 64 20 65 78 63 6c 75  shared and exclu
7b50: 73 69 76 65 20 2d 20 69 74 20 6d 75 73 74 20 67  sive - it must g
7b60: 6f 0a 2a 2a 20 74 68 72 6f 75 67 68 20 74 68 65  o.** through the
7b70: 20 75 6e 6c 6f 63 6b 65 64 20 73 74 61 74 65 20   unlocked state 
7b80: 66 69 72 73 74 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20  first..**.** In 
7b90: 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43  locking_mode=EXC
7ba0: 4c 55 53 49 56 45 2c 20 61 6c 6c 20 6f 66 20 74  LUSIVE, all of t
7bb0: 68 65 73 65 20 72 6f 75 74 69 6e 65 73 20 62 65  hese routines be
7bc0: 63 6f 6d 65 20 6e 6f 2d 6f 70 73 2e 0a 2a 2f 0a  come no-ops..*/.
7bd0: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 4c 6f  static int walLo
7be0: 63 6b 53 68 61 72 65 64 28 57 61 6c 20 2a 70 57  ckShared(Wal *pW
7bf0: 61 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 29  al, int lockIdx)
7c00: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 66  {.  int rc;.  if
7c10: 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76  ( pWal->exclusiv
7c20: 65 4d 6f 64 65 20 29 20 72 65 74 75 72 6e 20 53  eMode ) return S
7c30: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72 63 20 3d  QLITE_OK;.  rc =
7c40: 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63   sqlite3OsShmLoc
7c50: 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c  k(pWal->pDbFd, l
7c60: 6f 63 6b 49 64 78 2c 20 31 2c 0a 20 20 20 20 20  ockIdx, 1,.     
7c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7c80: 20 20 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f     SQLITE_SHM_LO
7c90: 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f  CK | SQLITE_SHM_
7ca0: 53 48 41 52 45 44 29 3b 0a 20 20 57 41 4c 54 52  SHARED);.  WALTR
7cb0: 41 43 45 28 28 22 57 41 4c 25 70 3a 20 61 63 71  ACE(("WAL%p: acq
7cc0: 75 69 72 65 20 53 48 41 52 45 44 2d 25 73 20 25  uire SHARED-%s %
7cd0: 73 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20 20 20 20  s\n", pWal,.    
7ce0: 20 20 20 20 20 20 20 20 77 61 6c 4c 6f 63 6b 4e          walLockN
7cf0: 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c 20 72 63  ame(lockIdx), rc
7d00: 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f   ? "failed" : "o
7d10: 6b 22 29 29 3b 0a 20 20 56 56 41 5f 4f 4e 4c 59  k"));.  VVA_ONLY
7d20: 28 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f  ( pWal->lockErro
7d30: 72 20 3d 20 28 75 38 29 28 72 63 21 3d 53 51 4c  r = (u8)(rc!=SQL
7d40: 49 54 45 5f 4f 4b 20 26 26 20 72 63 21 3d 53 51  ITE_OK && rc!=SQ
7d50: 4c 49 54 45 5f 42 55 53 59 29 3b 20 29 0a 20 20  LITE_BUSY); ).  
7d60: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61  return rc;.}.sta
7d70: 74 69 63 20 76 6f 69 64 20 77 61 6c 55 6e 6c 6f  tic void walUnlo
7d80: 63 6b 53 68 61 72 65 64 28 57 61 6c 20 2a 70 57  ckShared(Wal *pW
7d90: 61 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 29  al, int lockIdx)
7da0: 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78  {.  if( pWal->ex
7db0: 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65  clusiveMode ) re
7dc0: 74 75 72 6e 3b 0a 20 20 28 76 6f 69 64 29 73 71  turn;.  (void)sq
7dd0: 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70  lite3OsShmLock(p
7de0: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b  Wal->pDbFd, lock
7df0: 49 64 78 2c 20 31 2c 0a 20 20 20 20 20 20 20 20  Idx, 1,.        
7e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e10: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f   SQLITE_SHM_UNLO
7e20: 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f  CK | SQLITE_SHM_
7e30: 53 48 41 52 45 44 29 3b 0a 20 20 57 41 4c 54 52  SHARED);.  WALTR
7e40: 41 43 45 28 28 22 57 41 4c 25 70 3a 20 72 65 6c  ACE(("WAL%p: rel
7e50: 65 61 73 65 20 53 48 41 52 45 44 2d 25 73 5c 6e  ease SHARED-%s\n
7e60: 22 2c 20 70 57 61 6c 2c 20 77 61 6c 4c 6f 63 6b  ", pWal, walLock
7e70: 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 29 29 3b  Name(lockIdx)));
7e80: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  .}.static int wa
7e90: 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 57  lLockExclusive(W
7ea0: 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f  al *pWal, int lo
7eb0: 63 6b 49 64 78 2c 20 69 6e 74 20 6e 29 7b 0a 20  ckIdx, int n){. 
7ec0: 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 70   int rc;.  if( p
7ed0: 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
7ee0: 64 65 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  de ) return SQLI
7ef0: 54 45 5f 4f 4b 3b 0a 20 20 72 63 20 3d 20 73 71  TE_OK;.  rc = sq
7f00: 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70  lite3OsShmLock(p
7f10: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b  Wal->pDbFd, lock
7f20: 49 64 78 2c 20 6e 2c 0a 20 20 20 20 20 20 20 20  Idx, n,.        
7f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7f40: 53 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20  SQLITE_SHM_LOCK 
7f50: 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f 45 58 43  | SQLITE_SHM_EXC
7f60: 4c 55 53 49 56 45 29 3b 0a 20 20 57 41 4c 54 52  LUSIVE);.  WALTR
7f70: 41 43 45 28 28 22 57 41 4c 25 70 3a 20 61 63 71  ACE(("WAL%p: acq
7f80: 75 69 72 65 20 45 58 43 4c 55 53 49 56 45 2d 25  uire EXCLUSIVE-%
7f90: 73 20 63 6e 74 3d 25 64 20 25 73 5c 6e 22 2c 20  s cnt=%d %s\n", 
7fa0: 70 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20  pWal,.          
7fb0: 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f    walLockName(lo
7fc0: 63 6b 49 64 78 29 2c 20 6e 2c 20 72 63 20 3f 20  ckIdx), n, rc ? 
7fd0: 22 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29  "failed" : "ok")
7fe0: 29 3b 0a 20 20 56 56 41 5f 4f 4e 4c 59 28 20 70  );.  VVA_ONLY( p
7ff0: 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d  Wal->lockError =
8000: 20 28 75 38 29 28 72 63 21 3d 53 51 4c 49 54 45   (u8)(rc!=SQLITE
8010: 5f 4f 4b 20 26 26 20 72 63 21 3d 53 51 4c 49 54  _OK && rc!=SQLIT
8020: 45 5f 42 55 53 59 29 3b 20 29 0a 20 20 72 65 74  E_BUSY); ).  ret
8030: 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63  urn rc;.}.static
8040: 20 76 6f 69 64 20 77 61 6c 55 6e 6c 6f 63 6b 45   void walUnlockE
8050: 78 63 6c 75 73 69 76 65 28 57 61 6c 20 2a 70 57  xclusive(Wal *pW
8060: 61 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 2c  al, int lockIdx,
8070: 20 69 6e 74 20 6e 29 7b 0a 20 20 69 66 28 20 70   int n){.  if( p
8080: 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
8090: 64 65 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 28  de ) return;.  (
80a0: 76 6f 69 64 29 73 71 6c 69 74 65 33 4f 73 53 68  void)sqlite3OsSh
80b0: 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46  mLock(pWal->pDbF
80c0: 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c 0a 20  d, lockIdx, n,. 
80d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
80e0: 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53          SQLITE_S
80f0: 48 4d 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51 4c 49  HM_UNLOCK | SQLI
8100: 54 45 5f 53 48 4d 5f 45 58 43 4c 55 53 49 56 45  TE_SHM_EXCLUSIVE
8110: 29 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  );.  WALTRACE(("
8120: 57 41 4c 25 70 3a 20 72 65 6c 65 61 73 65 20 45  WAL%p: release E
8130: 58 43 4c 55 53 49 56 45 2d 25 73 20 63 6e 74 3d  XCLUSIVE-%s cnt=
8140: 25 64 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20 20 20  %d\n", pWal,.   
8150: 20 20 20 20 20 20 20 20 20 20 77 61 6c 4c 6f 63            walLoc
8160: 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c 20  kName(lockIdx), 
8170: 6e 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f  n));.}../*.** Co
8180: 6d 70 75 74 65 20 61 20 68 61 73 68 20 6f 6e 20  mpute a hash on 
8190: 61 20 70 61 67 65 20 6e 75 6d 62 65 72 2e 20 20  a page number.  
81a0: 54 68 65 20 72 65 73 75 6c 74 69 6e 67 20 68 61  The resulting ha
81b0: 73 68 20 76 61 6c 75 65 20 6d 75 73 74 20 6c 61  sh value must la
81c0: 6e 64 0a 2a 2a 20 62 65 74 77 65 65 6e 20 30 20  nd.** between 0 
81d0: 61 6e 64 20 28 48 41 53 48 54 41 42 4c 45 5f 4e  and (HASHTABLE_N
81e0: 53 4c 4f 54 2d 31 29 2e 20 20 54 68 65 20 77 61  SLOT-1).  The wa
81f0: 6c 48 61 73 68 4e 65 78 74 28 29 20 66 75 6e 63  lHashNext() func
8200: 74 69 6f 6e 20 61 64 76 61 6e 63 65 73 0a 2a 2a  tion advances.**
8210: 20 74 68 65 20 68 61 73 68 20 74 6f 20 74 68 65   the hash to the
8220: 20 6e 65 78 74 20 76 61 6c 75 65 20 69 6e 20 74   next value in t
8230: 68 65 20 65 76 65 6e 74 20 6f 66 20 61 20 63 6f  he event of a co
8240: 6c 6c 69 73 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74  llision..*/.stat
8250: 69 63 20 69 6e 74 20 77 61 6c 48 61 73 68 28 75  ic int walHash(u
8260: 33 32 20 69 50 61 67 65 29 7b 0a 20 20 61 73 73  32 iPage){.  ass
8270: 65 72 74 28 20 69 50 61 67 65 3e 30 20 29 3b 0a  ert( iPage>0 );.
8280: 20 20 61 73 73 65 72 74 28 20 28 48 41 53 48 54    assert( (HASHT
8290: 41 42 4c 45 5f 4e 53 4c 4f 54 20 26 20 28 48 41  ABLE_NSLOT & (HA
82a0: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29  SHTABLE_NSLOT-1)
82b0: 29 3d 3d 30 20 29 3b 0a 20 20 72 65 74 75 72 6e  )==0 );.  return
82c0: 20 28 69 50 61 67 65 2a 48 41 53 48 54 41 42 4c   (iPage*HASHTABL
82d0: 45 5f 48 41 53 48 5f 31 29 20 26 20 28 48 41 53  E_HASH_1) & (HAS
82e0: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 3b  HTABLE_NSLOT-1);
82f0: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  .}.static int wa
8300: 6c 4e 65 78 74 48 61 73 68 28 69 6e 74 20 69 50  lNextHash(int iP
8310: 72 69 6f 72 48 61 73 68 29 7b 0a 20 20 72 65 74  riorHash){.  ret
8320: 75 72 6e 20 28 69 50 72 69 6f 72 48 61 73 68 2b  urn (iPriorHash+
8330: 31 29 26 28 48 41 53 48 54 41 42 4c 45 5f 4e 53  1)&(HASHTABLE_NS
8340: 4c 4f 54 2d 31 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  LOT-1);.}../* .*
8350: 2a 20 52 65 74 75 72 6e 20 70 6f 69 6e 74 65 72  * Return pointer
8360: 73 20 74 6f 20 74 68 65 20 68 61 73 68 20 74 61  s to the hash ta
8370: 62 6c 65 20 61 6e 64 20 70 61 67 65 20 6e 75 6d  ble and page num
8380: 62 65 72 20 61 72 72 61 79 20 73 74 6f 72 65 64  ber array stored
8390: 20 6f 6e 0a 2a 2a 20 70 61 67 65 20 69 48 61 73   on.** page iHas
83a0: 68 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  h of the wal-ind
83b0: 65 78 2e 20 54 68 65 20 77 61 6c 2d 69 6e 64 65  ex. The wal-inde
83c0: 78 20 69 73 20 62 72 6f 6b 65 6e 20 69 6e 74 6f  x is broken into
83d0: 20 33 32 4b 42 20 70 61 67 65 73 0a 2a 2a 20 6e   32KB pages.** n
83e0: 75 6d 62 65 72 65 64 20 73 74 61 72 74 69 6e 67  umbered starting
83f0: 20 66 72 6f 6d 20 30 2e 0a 2a 2a 0a 2a 2a 20 53   from 0..**.** S
8400: 65 74 20 6f 75 74 70 75 74 20 76 61 72 69 61 62  et output variab
8410: 6c 65 20 2a 70 61 48 61 73 68 20 74 6f 20 70 6f  le *paHash to po
8420: 69 6e 74 20 74 6f 20 74 68 65 20 73 74 61 72 74  int to the start
8430: 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61 62   of the hash tab
8440: 6c 65 0a 2a 2a 20 69 6e 20 74 68 65 20 77 61 6c  le.** in the wal
8450: 2d 69 6e 64 65 78 20 66 69 6c 65 2e 20 53 65 74  -index file. Set
8460: 20 2a 70 69 5a 65 72 6f 20 74 6f 20 6f 6e 65 20   *piZero to one 
8470: 6c 65 73 73 20 74 68 61 6e 20 74 68 65 20 66 72  less than the fr
8480: 61 6d 65 20 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f  ame .** number o
8490: 66 20 74 68 65 20 66 69 72 73 74 20 66 72 61 6d  f the first fram
84a0: 65 20 69 6e 64 65 78 65 64 20 62 79 20 74 68 69  e indexed by thi
84b0: 73 20 68 61 73 68 20 74 61 62 6c 65 2e 20 49 66  s hash table. If
84c0: 20 61 0a 2a 2a 20 73 6c 6f 74 20 69 6e 20 74 68   a.** slot in th
84d0: 65 20 68 61 73 68 20 74 61 62 6c 65 20 69 73 20  e hash table is 
84e0: 73 65 74 20 74 6f 20 4e 2c 20 69 74 20 72 65 66  set to N, it ref
84f0: 65 72 73 20 74 6f 20 66 72 61 6d 65 20 6e 75 6d  ers to frame num
8500: 62 65 72 20 0a 2a 2a 20 28 2a 70 69 5a 65 72 6f  ber .** (*piZero
8510: 2b 4e 29 20 69 6e 20 74 68 65 20 6c 6f 67 2e 0a  +N) in the log..
8520: 2a 2a 0a 2a 2a 20 46 69 6e 61 6c 6c 79 2c 20 73  **.** Finally, s
8530: 65 74 20 2a 70 61 50 67 6e 6f 20 73 6f 20 74 68  et *paPgno so th
8540: 61 74 20 2a 70 61 50 67 6e 6f 5b 31 5d 20 69 73  at *paPgno[1] is
8550: 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72   the page number
8560: 20 6f 66 20 74 68 65 0a 2a 2a 20 66 69 72 73 74   of the.** first
8570: 20 66 72 61 6d 65 20 69 6e 64 65 78 65 64 20 62   frame indexed b
8580: 79 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  y the hash table
8590: 2c 20 66 72 61 6d 65 20 28 2a 70 69 5a 65 72 6f  , frame (*piZero
85a0: 2b 31 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  +1)..*/.static i
85b0: 6e 74 20 77 61 6c 48 61 73 68 47 65 74 28 0a 20  nt walHashGet(. 
85c0: 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20   Wal *pWal,     
85d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
85e0: 20 2f 2a 20 57 41 4c 20 68 61 6e 64 6c 65 20 2a   /* WAL handle *
85f0: 2f 0a 20 20 69 6e 74 20 69 48 61 73 68 2c 20 20  /.  int iHash,  
8600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8610: 20 20 20 20 2f 2a 20 46 69 6e 64 20 74 68 65 20      /* Find the 
8620: 69 48 61 73 68 27 74 68 20 74 61 62 6c 65 20 2a  iHash'th table *
8630: 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f  /.  volatile ht_
8640: 73 6c 6f 74 20 2a 2a 70 61 48 61 73 68 2c 20 20  slot **paHash,  
8650: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e      /* OUT: Poin
8660: 74 65 72 20 74 6f 20 68 61 73 68 20 69 6e 64 65  ter to hash inde
8670: 78 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20  x */.  volatile 
8680: 75 33 32 20 2a 2a 70 61 50 67 6e 6f 2c 20 20 20  u32 **paPgno,   
8690: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 50         /* OUT: P
86a0: 6f 69 6e 74 65 72 20 74 6f 20 70 61 67 65 20 6e  ointer to page n
86b0: 75 6d 62 65 72 20 61 72 72 61 79 20 2a 2f 0a 20  umber array */. 
86c0: 20 75 33 32 20 2a 70 69 5a 65 72 6f 20 20 20 20   u32 *piZero    
86d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
86e0: 20 2f 2a 20 4f 55 54 3a 20 46 72 61 6d 65 20 61   /* OUT: Frame a
86f0: 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 2a  ssociated with *
8700: 70 61 50 67 6e 6f 5b 30 5d 20 2a 2f 0a 29 7b 0a  paPgno[0] */.){.
8710: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
8720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8730: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
8740: 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75   */.  volatile u
8750: 33 32 20 2a 61 50 67 6e 6f 3b 0a 0a 20 20 72 63  32 *aPgno;..  rc
8760: 20 3d 20 77 61 6c 49 6e 64 65 78 50 61 67 65 28   = walIndexPage(
8770: 70 57 61 6c 2c 20 69 48 61 73 68 2c 20 26 61 50  pWal, iHash, &aP
8780: 67 6e 6f 29 3b 0a 20 20 61 73 73 65 72 74 28 20  gno);.  assert( 
8790: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c  rc==SQLITE_OK ||
87a0: 20 69 48 61 73 68 3e 30 20 29 3b 0a 0a 20 20 69   iHash>0 );..  i
87b0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
87c0: 20 29 7b 0a 20 20 20 20 75 33 32 20 69 5a 65 72   ){.    u32 iZer
87d0: 6f 3b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  o;.    volatile 
87e0: 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b 0a  ht_slot *aHash;.
87f0: 0a 20 20 20 20 61 48 61 73 68 20 3d 20 28 76 6f  .    aHash = (vo
8800: 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a  latile ht_slot *
8810: 29 26 61 50 67 6e 6f 5b 48 41 53 48 54 41 42 4c  )&aPgno[HASHTABL
8820: 45 5f 4e 50 41 47 45 5d 3b 0a 20 20 20 20 69 66  E_NPAGE];.    if
8830: 28 20 69 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20  ( iHash==0 ){.  
8840: 20 20 20 20 61 50 67 6e 6f 20 3d 20 26 61 50 67      aPgno = &aPg
8850: 6e 6f 5b 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f  no[WALINDEX_HDR_
8860: 53 49 5a 45 2f 73 69 7a 65 6f 66 28 75 33 32 29  SIZE/sizeof(u32)
8870: 5d 3b 0a 20 20 20 20 20 20 69 5a 65 72 6f 20 3d  ];.      iZero =
8880: 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   0;.    }else{. 
8890: 20 20 20 20 20 69 5a 65 72 6f 20 3d 20 48 41 53       iZero = HAS
88a0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45  HTABLE_NPAGE_ONE
88b0: 20 2b 20 28 69 48 61 73 68 2d 31 29 2a 48 41 53   + (iHash-1)*HAS
88c0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 3b 0a 20 20  HTABLE_NPAGE;.  
88d0: 20 20 7d 0a 20 20 0a 20 20 20 20 2a 70 61 50 67    }.  .    *paPg
88e0: 6e 6f 20 3d 20 26 61 50 67 6e 6f 5b 2d 31 5d 3b  no = &aPgno[-1];
88f0: 0a 20 20 20 20 2a 70 61 48 61 73 68 20 3d 20 61  .    *paHash = a
8900: 48 61 73 68 3b 0a 20 20 20 20 2a 70 69 5a 65 72  Hash;.    *piZer
8910: 6f 20 3d 20 69 5a 65 72 6f 3b 0a 20 20 7d 0a 20  o = iZero;.  }. 
8920: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
8930: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
8940: 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 77 61  number of the wa
8950: 6c 2d 69 6e 64 65 78 20 70 61 67 65 20 74 68 61  l-index page tha
8960: 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 68  t contains the h
8970: 61 73 68 2d 74 61 62 6c 65 0a 2a 2a 20 61 6e 64  ash-table.** and
8980: 20 70 61 67 65 2d 6e 75 6d 62 65 72 20 61 72 72   page-number arr
8990: 61 79 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 20  ay that contain 
89a0: 65 6e 74 72 69 65 73 20 63 6f 72 72 65 73 70 6f  entries correspo
89b0: 6e 64 69 6e 67 20 74 6f 20 57 41 4c 20 66 72 61  nding to WAL fra
89c0: 6d 65 0a 2a 2a 20 69 46 72 61 6d 65 2e 20 54 68  me.** iFrame. Th
89d0: 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 62  e wal-index is b
89e0: 72 6f 6b 65 6e 20 75 70 20 69 6e 74 6f 20 33 32  roken up into 32
89f0: 4b 42 20 70 61 67 65 73 2e 20 57 61 6c 2d 69 6e  KB pages. Wal-in
8a00: 64 65 78 20 70 61 67 65 73 20 0a 2a 2a 20 61 72  dex pages .** ar
8a10: 65 20 6e 75 6d 62 65 72 65 64 20 73 74 61 72 74  e numbered start
8a20: 69 6e 67 20 66 72 6f 6d 20 30 2e 0a 2a 2f 0a 73  ing from 0..*/.s
8a30: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 46 72 61  tatic int walFra
8a40: 6d 65 50 61 67 65 28 75 33 32 20 69 46 72 61 6d  mePage(u32 iFram
8a50: 65 29 7b 0a 20 20 69 6e 74 20 69 48 61 73 68 20  e){.  int iHash 
8a60: 3d 20 28 69 46 72 61 6d 65 2b 48 41 53 48 54 41  = (iFrame+HASHTA
8a70: 42 4c 45 5f 4e 50 41 47 45 2d 48 41 53 48 54 41  BLE_NPAGE-HASHTA
8a80: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2d 31 29  BLE_NPAGE_ONE-1)
8a90: 20 2f 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41   / HASHTABLE_NPA
8aa0: 47 45 3b 0a 20 20 61 73 73 65 72 74 28 20 28 69  GE;.  assert( (i
8ab0: 48 61 73 68 3d 3d 30 20 7c 7c 20 69 46 72 61 6d  Hash==0 || iFram
8ac0: 65 3e 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  e>HASHTABLE_NPAG
8ad0: 45 5f 4f 4e 45 29 0a 20 20 20 20 20 20 20 26 26  E_ONE).       &&
8ae0: 20 28 69 48 61 73 68 3e 3d 31 20 7c 7c 20 69 46   (iHash>=1 || iF
8af0: 72 61 6d 65 3c 3d 48 41 53 48 54 41 42 4c 45 5f  rame<=HASHTABLE_
8b00: 4e 50 41 47 45 5f 4f 4e 45 29 0a 20 20 20 20 20  NPAGE_ONE).     
8b10: 20 20 26 26 20 28 69 48 61 73 68 3c 3d 31 20 7c    && (iHash<=1 |
8b20: 7c 20 69 46 72 61 6d 65 3e 28 48 41 53 48 54 41  | iFrame>(HASHTA
8b30: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 48 41  BLE_NPAGE_ONE+HA
8b40: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 29 29 0a  SHTABLE_NPAGE)).
8b50: 20 20 20 20 20 20 20 26 26 20 28 69 48 61 73 68         && (iHash
8b60: 3e 3d 32 20 7c 7c 20 69 46 72 61 6d 65 3c 3d 48  >=2 || iFrame<=H
8b70: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
8b80: 4e 45 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  NE+HASHTABLE_NPA
8b90: 47 45 29 0a 20 20 20 20 20 20 20 26 26 20 28 69  GE).       && (i
8ba0: 48 61 73 68 3c 3d 32 20 7c 7c 20 69 46 72 61 6d  Hash<=2 || iFram
8bb0: 65 3e 28 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  e>(HASHTABLE_NPA
8bc0: 47 45 5f 4f 4e 45 2b 32 2a 48 41 53 48 54 41 42  GE_ONE+2*HASHTAB
8bd0: 4c 45 5f 4e 50 41 47 45 29 29 0a 20 20 29 3b 0a  LE_NPAGE)).  );.
8be0: 20 20 72 65 74 75 72 6e 20 69 48 61 73 68 3b 0a    return iHash;.
8bf0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
8c00: 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  the page number 
8c10: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20  associated with 
8c20: 66 72 61 6d 65 20 69 46 72 61 6d 65 20 69 6e 20  frame iFrame in 
8c30: 74 68 69 73 20 57 41 4c 2e 0a 2a 2f 0a 73 74 61  this WAL..*/.sta
8c40: 74 69 63 20 75 33 32 20 77 61 6c 46 72 61 6d 65  tic u32 walFrame
8c50: 50 67 6e 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Pgno(Wal *pWal, 
8c60: 75 33 32 20 69 46 72 61 6d 65 29 7b 0a 20 20 69  u32 iFrame){.  i
8c70: 6e 74 20 69 48 61 73 68 20 3d 20 77 61 6c 46 72  nt iHash = walFr
8c80: 61 6d 65 50 61 67 65 28 69 46 72 61 6d 65 29 3b  amePage(iFrame);
8c90: 0a 20 20 69 66 28 20 69 48 61 73 68 3d 3d 30 20  .  if( iHash==0 
8ca0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70 57  ){.    return pW
8cb0: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 5b  al->apWiData[0][
8cc0: 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a  WALINDEX_HDR_SIZ
8cd0: 45 2f 73 69 7a 65 6f 66 28 75 33 32 29 20 2b 20  E/sizeof(u32) + 
8ce0: 69 46 72 61 6d 65 20 2d 20 31 5d 3b 0a 20 20 7d  iFrame - 1];.  }
8cf0: 0a 20 20 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e  .  return pWal->
8d00: 61 70 57 69 44 61 74 61 5b 69 48 61 73 68 5d 5b  apWiData[iHash][
8d10: 28 69 46 72 61 6d 65 2d 31 2d 48 41 53 48 54 41  (iFrame-1-HASHTA
8d20: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 25 48  BLE_NPAGE_ONE)%H
8d30: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5d 3b  ASHTABLE_NPAGE];
8d40: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65  .}../*.** Remove
8d50: 20 65 6e 74 72 69 65 73 20 66 72 6f 6d 20 74 68   entries from th
8d60: 65 20 68 61 73 68 20 74 61 62 6c 65 20 74 68 61  e hash table tha
8d70: 74 20 70 6f 69 6e 74 20 74 6f 20 57 41 4c 20 73  t point to WAL s
8d80: 6c 6f 74 73 20 67 72 65 61 74 65 72 0a 2a 2a 20  lots greater.** 
8d90: 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  than pWal->hdr.m
8da0: 78 46 72 61 6d 65 2e 0a 2a 2a 0a 2a 2a 20 54 68  xFrame..**.** Th
8db0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
8dc0: 61 6c 6c 65 64 20 77 68 65 6e 65 76 65 72 20 70  alled whenever p
8dd0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
8de0: 20 69 73 20 64 65 63 72 65 61 73 65 64 20 64 75   is decreased du
8df0: 65 0a 2a 2a 20 74 6f 20 61 20 72 6f 6c 6c 62 61  e.** to a rollba
8e00: 63 6b 20 6f 72 20 73 61 76 65 70 6f 69 6e 74 2e  ck or savepoint.
8e10: 0a 2a 2a 0a 2a 2a 20 41 74 20 6d 6f 73 74 20 6f  .**.** At most o
8e20: 6e 6c 79 20 74 68 65 20 68 61 73 68 20 74 61 62  nly the hash tab
8e30: 6c 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 70 57  le containing pW
8e40: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
8e50: 6e 65 65 64 73 20 74 6f 20 62 65 0a 2a 2a 20 75  needs to be.** u
8e60: 70 64 61 74 65 64 2e 20 20 41 6e 79 20 6c 61 74  pdated.  Any lat
8e70: 65 72 20 68 61 73 68 20 74 61 62 6c 65 73 20 77  er hash tables w
8e80: 69 6c 6c 20 62 65 20 61 75 74 6f 6d 61 74 69 63  ill be automatic
8e90: 61 6c 6c 79 20 63 6c 65 61 72 65 64 20 77 68 65  ally cleared whe
8ea0: 6e 0a 2a 2a 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  n.** pWal->hdr.m
8eb0: 78 46 72 61 6d 65 20 61 64 76 61 6e 63 65 73 20  xFrame advances 
8ec0: 74 6f 20 74 68 65 20 70 6f 69 6e 74 20 77 68 65  to the point whe
8ed0: 72 65 20 74 68 6f 73 65 20 68 61 73 68 20 74 61  re those hash ta
8ee0: 62 6c 65 73 20 61 72 65 0a 2a 2a 20 61 63 74 75  bles are.** actu
8ef0: 61 6c 6c 79 20 6e 65 65 64 65 64 2e 0a 2a 2f 0a  ally needed..*/.
8f00: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 43  static void walC
8f10: 6c 65 61 6e 75 70 48 61 73 68 28 57 61 6c 20 2a  leanupHash(Wal *
8f20: 70 57 61 6c 29 7b 0a 20 20 76 6f 6c 61 74 69 6c  pWal){.  volatil
8f30: 65 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68  e ht_slot *aHash
8f40: 20 3d 20 30 3b 20 20 20 20 2f 2a 20 50 6f 69 6e   = 0;    /* Poin
8f50: 74 65 72 20 74 6f 20 68 61 73 68 20 74 61 62 6c  ter to hash tabl
8f60: 65 20 74 6f 20 63 6c 65 61 72 20 2a 2f 0a 20 20  e to clear */.  
8f70: 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50  volatile u32 *aP
8f80: 67 6e 6f 20 3d 20 30 3b 20 20 20 20 20 20 20 20  gno = 0;        
8f90: 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20 61  /* Page number a
8fa0: 72 72 61 79 20 66 6f 72 20 68 61 73 68 20 74 61  rray for hash ta
8fb0: 62 6c 65 20 2a 2f 0a 20 20 75 33 32 20 69 5a 65  ble */.  u32 iZe
8fc0: 72 6f 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  ro = 0;         
8fd0: 20 20 20 20 20 20 20 20 20 2f 2a 20 66 72 61 6d           /* fram
8fe0: 65 20 3d 3d 20 28 61 48 61 73 68 5b 78 5d 2b 69  e == (aHash[x]+i
8ff0: 5a 65 72 6f 29 20 2a 2f 0a 20 20 69 6e 74 20 69  Zero) */.  int i
9000: 4c 69 6d 69 74 20 3d 20 30 3b 20 20 20 20 20 20  Limit = 0;      
9010: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 5a 65             /* Ze
9020: 72 6f 20 76 61 6c 75 65 73 20 67 72 65 61 74 65  ro values greate
9030: 72 20 74 68 61 6e 20 74 68 69 73 20 2a 2f 0a 20  r than this */. 
9040: 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20   int nByte;     
9050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9060: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
9070: 74 65 73 20 74 6f 20 7a 65 72 6f 20 69 6e 20 61  tes to zero in a
9080: 50 67 6e 6f 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20  Pgno[] */.  int 
9090: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
90a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55              /* U
90b0: 73 65 64 20 74 6f 20 69 74 65 72 61 74 65 20 74  sed to iterate t
90c0: 68 72 6f 75 67 68 20 61 48 61 73 68 5b 5d 20 2a  hrough aHash[] *
90d0: 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  /..  assert( pWa
90e0: 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a  l->writeLock );.
90f0: 20 20 74 65 73 74 63 61 73 65 28 20 70 57 61 6c    testcase( pWal
9100: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 48  ->hdr.mxFrame==H
9110: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
9120: 4e 45 2d 31 20 29 3b 0a 20 20 74 65 73 74 63 61  NE-1 );.  testca
9130: 73 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  se( pWal->hdr.mx
9140: 46 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45  Frame==HASHTABLE
9150: 5f 4e 50 41 47 45 5f 4f 4e 45 20 29 3b 0a 20 20  _NPAGE_ONE );.  
9160: 74 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d 3e  testcase( pWal->
9170: 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 48 41 53  hdr.mxFrame==HAS
9180: 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45  HTABLE_NPAGE_ONE
9190: 2b 31 20 29 3b 0a 0a 20 20 69 66 28 20 70 57 61  +1 );..  if( pWa
91a0: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d  l->hdr.mxFrame==
91b0: 30 20 29 20 72 65 74 75 72 6e 3b 0a 0a 20 20 2f  0 ) return;..  /
91c0: 2a 20 4f 62 74 61 69 6e 20 70 6f 69 6e 74 65 72  * Obtain pointer
91d0: 73 20 74 6f 20 74 68 65 20 68 61 73 68 2d 74 61  s to the hash-ta
91e0: 62 6c 65 20 61 6e 64 20 70 61 67 65 2d 6e 75 6d  ble and page-num
91f0: 62 65 72 20 61 72 72 61 79 20 63 6f 6e 74 61 69  ber array contai
9200: 6e 69 6e 67 20 0a 20 20 2a 2a 20 74 68 65 20 65  ning .  ** the e
9210: 6e 74 72 79 20 74 68 61 74 20 63 6f 72 72 65 73  ntry that corres
9220: 70 6f 6e 64 73 20 74 6f 20 66 72 61 6d 65 20 70  ponds to frame p
9230: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
9240: 2e 20 49 74 20 69 73 20 67 75 61 72 61 6e 74 65  . It is guarante
9250: 65 64 0a 20 20 2a 2a 20 74 68 61 74 20 74 68 65  ed.  ** that the
9260: 20 70 61 67 65 20 73 61 69 64 20 68 61 73 68 2d   page said hash-
9270: 74 61 62 6c 65 20 61 6e 64 20 61 72 72 61 79 20  table and array 
9280: 72 65 73 69 64 65 20 6f 6e 20 69 73 20 61 6c 72  reside on is alr
9290: 65 61 64 79 20 6d 61 70 70 65 64 2e 0a 20 20 2a  eady mapped..  *
92a0: 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  /.  assert( pWal
92b0: 2d 3e 6e 57 69 44 61 74 61 3e 77 61 6c 46 72 61  ->nWiData>walFra
92c0: 6d 65 50 61 67 65 28 70 57 61 6c 2d 3e 68 64 72  mePage(pWal->hdr
92d0: 2e 6d 78 46 72 61 6d 65 29 20 29 3b 0a 20 20 61  .mxFrame) );.  a
92e0: 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 61 70 57  ssert( pWal->apW
92f0: 69 44 61 74 61 5b 77 61 6c 46 72 61 6d 65 50 61  iData[walFramePa
9300: 67 65 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ge(pWal->hdr.mxF
9310: 72 61 6d 65 29 5d 20 29 3b 0a 20 20 77 61 6c 48  rame)] );.  walH
9320: 61 73 68 47 65 74 28 70 57 61 6c 2c 20 77 61 6c  ashGet(pWal, wal
9330: 46 72 61 6d 65 50 61 67 65 28 70 57 61 6c 2d 3e  FramePage(pWal->
9340: 68 64 72 2e 6d 78 46 72 61 6d 65 29 2c 20 26 61  hdr.mxFrame), &a
9350: 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20 26 69  Hash, &aPgno, &i
9360: 5a 65 72 6f 29 3b 0a 0a 20 20 2f 2a 20 5a 65 72  Zero);..  /* Zer
9370: 6f 20 61 6c 6c 20 68 61 73 68 2d 74 61 62 6c 65  o all hash-table
9380: 20 65 6e 74 72 69 65 73 20 74 68 61 74 20 63 6f   entries that co
9390: 72 72 65 73 70 6f 6e 64 20 74 6f 20 66 72 61 6d  rrespond to fram
93a0: 65 20 6e 75 6d 62 65 72 73 20 67 72 65 61 74 65  e numbers greate
93b0: 72 0a 20 20 2a 2a 20 74 68 61 6e 20 70 57 61 6c  r.  ** than pWal
93c0: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a 20  ->hdr.mxFrame.. 
93d0: 20 2a 2f 0a 20 20 69 4c 69 6d 69 74 20 3d 20 70   */.  iLimit = p
93e0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
93f0: 20 2d 20 69 5a 65 72 6f 3b 0a 20 20 61 73 73 65   - iZero;.  asse
9400: 72 74 28 20 69 4c 69 6d 69 74 3e 30 20 29 3b 0a  rt( iLimit>0 );.
9410: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48 41 53    for(i=0; i<HAS
9420: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 20 69 2b  HTABLE_NSLOT; i+
9430: 2b 29 7b 0a 20 20 20 20 69 66 28 20 61 48 61 73  +){.    if( aHas
9440: 68 5b 69 5d 3e 69 4c 69 6d 69 74 20 29 7b 0a 20  h[i]>iLimit ){. 
9450: 20 20 20 20 20 61 48 61 73 68 5b 69 5d 20 3d 20       aHash[i] = 
9460: 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 0a  0;.    }.  }.  .
9470: 20 20 2f 2a 20 5a 65 72 6f 20 74 68 65 20 65 6e    /* Zero the en
9480: 74 72 69 65 73 20 69 6e 20 74 68 65 20 61 50 67  tries in the aPg
9490: 6e 6f 20 61 72 72 61 79 20 74 68 61 74 20 63 6f  no array that co
94a0: 72 72 65 73 70 6f 6e 64 20 74 6f 20 66 72 61 6d  rrespond to fram
94b0: 65 73 20 77 69 74 68 0a 20 20 2a 2a 20 66 72 61  es with.  ** fra
94c0: 6d 65 20 6e 75 6d 62 65 72 73 20 67 72 65 61 74  me numbers great
94d0: 65 72 20 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64  er than pWal->hd
94e0: 72 2e 6d 78 46 72 61 6d 65 2e 20 0a 20 20 2a 2f  r.mxFrame. .  */
94f0: 0a 20 20 6e 42 79 74 65 20 3d 20 28 69 6e 74 29  .  nByte = (int)
9500: 28 28 63 68 61 72 20 2a 29 61 48 61 73 68 20 2d  ((char *)aHash -
9510: 20 28 63 68 61 72 20 2a 29 26 61 50 67 6e 6f 5b   (char *)&aPgno[
9520: 69 4c 69 6d 69 74 2b 31 5d 29 3b 0a 20 20 6d 65  iLimit+1]);.  me
9530: 6d 73 65 74 28 28 76 6f 69 64 20 2a 29 26 61 50  mset((void *)&aP
9540: 67 6e 6f 5b 69 4c 69 6d 69 74 2b 31 5d 2c 20 30  gno[iLimit+1], 0
9550: 2c 20 6e 42 79 74 65 29 3b 0a 0a 23 69 66 64 65  , nByte);..#ifde
9560: 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
9570: 45 58 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54  EXPENSIVE_ASSERT
9580: 0a 20 20 2f 2a 20 56 65 72 69 66 79 20 74 68 61  .  /* Verify tha
9590: 74 20 74 68 65 20 65 76 65 72 79 20 65 6e 74 72  t the every entr
95a0: 79 20 69 6e 20 74 68 65 20 6d 61 70 70 69 6e 67  y in the mapping
95b0: 20 72 65 67 69 6f 6e 20 69 73 20 73 74 69 6c 6c   region is still
95c0: 20 72 65 61 63 68 61 62 6c 65 0a 20 20 2a 2a 20   reachable.  ** 
95d0: 76 69 61 20 74 68 65 20 68 61 73 68 20 74 61 62  via the hash tab
95e0: 6c 65 20 65 76 65 6e 20 61 66 74 65 72 20 74 68  le even after th
95f0: 65 20 63 6c 65 61 6e 75 70 2e 0a 20 20 2a 2f 0a  e cleanup..  */.
9600: 20 20 69 66 28 20 69 4c 69 6d 69 74 20 29 7b 0a    if( iLimit ){.
9610: 20 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20      int i;      
9620: 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75       /* Loop cou
9630: 6e 74 65 72 20 2a 2f 0a 20 20 20 20 69 6e 74 20  nter */.    int 
9640: 69 4b 65 79 3b 20 20 20 20 20 20 20 20 2f 2a 20  iKey;        /* 
9650: 48 61 73 68 20 6b 65 79 20 2a 2f 0a 20 20 20 20  Hash key */.    
9660: 66 6f 72 28 69 3d 31 3b 20 69 3c 3d 69 4c 69 6d  for(i=1; i<=iLim
9670: 69 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  it; i++){.      
9680: 66 6f 72 28 69 4b 65 79 3d 77 61 6c 48 61 73 68  for(iKey=walHash
9690: 28 61 50 67 6e 6f 5b 69 5d 29 3b 20 61 48 61 73  (aPgno[i]); aHas
96a0: 68 5b 69 4b 65 79 5d 3b 20 69 4b 65 79 3d 77 61  h[iKey]; iKey=wa
96b0: 6c 4e 65 78 74 48 61 73 68 28 69 4b 65 79 29 29  lNextHash(iKey))
96c0: 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 61 48  {.        if( aH
96d0: 61 73 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 20 62  ash[iKey]==i ) b
96e0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
96f0: 20 20 20 20 61 73 73 65 72 74 28 20 61 48 61 73      assert( aHas
9700: 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 3b 0a 20 20  h[iKey]==i );.  
9710: 20 20 7d 0a 20 20 7d 0a 23 65 6e 64 69 66 20 2f    }.  }.#endif /
9720: 2a 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  * SQLITE_ENABLE_
9730: 45 58 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54  EXPENSIVE_ASSERT
9740: 20 2a 2f 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 53 65   */.}.../*.** Se
9750: 74 20 61 6e 20 65 6e 74 72 79 20 69 6e 20 74 68  t an entry in th
9760: 65 20 77 61 6c 2d 69 6e 64 65 78 20 74 68 61 74  e wal-index that
9770: 20 77 69 6c 6c 20 6d 61 70 20 64 61 74 61 62 61   will map databa
9780: 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 2a  se page number.*
9790: 2a 20 70 50 61 67 65 20 69 6e 74 6f 20 57 41 4c  * pPage into WAL
97a0: 20 66 72 61 6d 65 20 69 46 72 61 6d 65 2e 0a 2a   frame iFrame..*
97b0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
97c0: 49 6e 64 65 78 41 70 70 65 6e 64 28 57 61 6c 20  IndexAppend(Wal 
97d0: 2a 70 57 61 6c 2c 20 75 33 32 20 69 46 72 61 6d  *pWal, u32 iFram
97e0: 65 2c 20 75 33 32 20 69 50 61 67 65 29 7b 0a 20  e, u32 iPage){. 
97f0: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
9800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9810: 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
9820: 2a 2f 0a 20 20 75 33 32 20 69 5a 65 72 6f 20 3d  */.  u32 iZero =
9830: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
9840: 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6c 65 73 73       /* One less
9850: 20 74 68 61 6e 20 66 72 61 6d 65 20 6e 75 6d 62   than frame numb
9860: 65 72 20 6f 66 20 61 50 67 6e 6f 5b 31 5d 20 2a  er of aPgno[1] *
9870: 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32  /.  volatile u32
9880: 20 2a 61 50 67 6e 6f 20 3d 20 30 3b 20 20 20 20   *aPgno = 0;    
9890: 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d 62      /* Page numb
98a0: 65 72 20 61 72 72 61 79 20 2a 2f 0a 20 20 76 6f  er array */.  vo
98b0: 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a  latile ht_slot *
98c0: 61 48 61 73 68 20 3d 20 30 3b 20 20 20 20 2f 2a  aHash = 0;    /*
98d0: 20 48 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 0a   Hash table */..
98e0: 20 20 72 63 20 3d 20 77 61 6c 48 61 73 68 47 65    rc = walHashGe
98f0: 74 28 70 57 61 6c 2c 20 77 61 6c 46 72 61 6d 65  t(pWal, walFrame
9900: 50 61 67 65 28 69 46 72 61 6d 65 29 2c 20 26 61  Page(iFrame), &a
9910: 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20 26 69  Hash, &aPgno, &i
9920: 5a 65 72 6f 29 3b 0a 0a 20 20 2f 2a 20 41 73 73  Zero);..  /* Ass
9930: 75 6d 69 6e 67 20 74 68 65 20 77 61 6c 2d 69 6e  uming the wal-in
9940: 64 65 78 20 66 69 6c 65 20 77 61 73 20 73 75 63  dex file was suc
9950: 63 65 73 73 66 75 6c 6c 79 20 6d 61 70 70 65 64  cessfully mapped
9960: 2c 20 70 6f 70 75 6c 61 74 65 20 74 68 65 0a 20  , populate the. 
9970: 20 2a 2a 20 70 61 67 65 20 6e 75 6d 62 65 72 20   ** page number 
9980: 61 72 72 61 79 20 61 6e 64 20 68 61 73 68 20 74  array and hash t
9990: 61 62 6c 65 20 65 6e 74 72 79 2e 0a 20 20 2a 2f  able entry..  */
99a0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
99b0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20  E_OK ){.    int 
99c0: 69 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20  iKey;           
99d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73            /* Has
99e0: 68 20 74 61 62 6c 65 20 6b 65 79 20 2a 2f 0a 20  h table key */. 
99f0: 20 20 20 69 6e 74 20 69 64 78 3b 20 20 20 20 20     int idx;     
9a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9a10: 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20 77 72 69   /* Value to wri
9a20: 74 65 20 74 6f 20 68 61 73 68 2d 74 61 62 6c 65  te to hash-table
9a30: 20 73 6c 6f 74 20 2a 2f 0a 20 20 20 20 69 6e 74   slot */.    int
9a40: 20 6e 43 6f 6c 6c 69 64 65 3b 20 20 20 20 20 20   nCollide;      
9a50: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
9a60: 6d 62 65 72 20 6f 66 20 68 61 73 68 20 63 6f 6c  mber of hash col
9a70: 6c 69 73 69 6f 6e 73 20 2a 2f 0a 0a 20 20 20 20  lisions */..    
9a80: 69 64 78 20 3d 20 69 46 72 61 6d 65 20 2d 20 69  idx = iFrame - i
9a90: 5a 65 72 6f 3b 0a 20 20 20 20 61 73 73 65 72 74  Zero;.    assert
9aa0: 28 20 69 64 78 20 3c 3d 20 48 41 53 48 54 41 42  ( idx <= HASHTAB
9ab0: 4c 45 5f 4e 53 4c 4f 54 2f 32 20 2b 20 31 20 29  LE_NSLOT/2 + 1 )
9ac0: 3b 0a 20 20 20 20 0a 20 20 20 20 2f 2a 20 49 66  ;.    .    /* If
9ad0: 20 74 68 69 73 20 69 73 20 74 68 65 20 66 69 72   this is the fir
9ae0: 73 74 20 65 6e 74 72 79 20 74 6f 20 62 65 20 61  st entry to be a
9af0: 64 64 65 64 20 74 6f 20 74 68 69 73 20 68 61 73  dded to this has
9b00: 68 2d 74 61 62 6c 65 2c 20 7a 65 72 6f 20 74 68  h-table, zero th
9b10: 65 0a 20 20 20 20 2a 2a 20 65 6e 74 69 72 65 20  e.    ** entire 
9b20: 68 61 73 68 20 74 61 62 6c 65 20 61 6e 64 20 61  hash table and a
9b30: 50 67 6e 6f 5b 5d 20 61 72 72 61 79 20 62 65 66  Pgno[] array bef
9b40: 6f 72 65 20 70 72 6f 63 65 64 69 6e 67 2e 20 0a  ore proceding. .
9b50: 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 69      */.    if( i
9b60: 64 78 3d 3d 31 20 29 7b 0a 20 20 20 20 20 20 69  dx==1 ){.      i
9b70: 6e 74 20 6e 42 79 74 65 20 3d 20 28 69 6e 74 29  nt nByte = (int)
9b80: 28 28 75 38 20 2a 29 26 61 48 61 73 68 5b 48 41  ((u8 *)&aHash[HA
9b90: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 5d 20 2d  SHTABLE_NSLOT] -
9ba0: 20 28 75 38 20 2a 29 26 61 50 67 6e 6f 5b 31 5d   (u8 *)&aPgno[1]
9bb0: 29 3b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28  );.      memset(
9bc0: 28 76 6f 69 64 2a 29 26 61 50 67 6e 6f 5b 31 5d  (void*)&aPgno[1]
9bd0: 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20  , 0, nByte);.   
9be0: 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68   }..    /* If th
9bf0: 65 20 65 6e 74 72 79 20 69 6e 20 61 50 67 6e 6f  e entry in aPgno
9c00: 5b 5d 20 69 73 20 61 6c 72 65 61 64 79 20 73 65  [] is already se
9c10: 74 2c 20 74 68 65 6e 20 74 68 65 20 70 72 65 76  t, then the prev
9c20: 69 6f 75 73 20 77 72 69 74 65 72 0a 20 20 20 20  ious writer.    
9c30: 2a 2a 20 6d 75 73 74 20 68 61 76 65 20 65 78 69  ** must have exi
9c40: 74 65 64 20 75 6e 65 78 70 65 63 74 65 64 6c 79  ted unexpectedly
9c50: 20 69 6e 20 74 68 65 20 6d 69 64 64 6c 65 20 6f   in the middle o
9c60: 66 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  f a transaction 
9c70: 28 61 66 74 65 72 0a 20 20 20 20 2a 2a 20 77 72  (after.    ** wr
9c80: 69 74 69 6e 67 20 6f 6e 65 20 6f 72 20 6d 6f 72  iting one or mor
9c90: 65 20 64 69 72 74 79 20 70 61 67 65 73 20 74 6f  e dirty pages to
9ca0: 20 74 68 65 20 57 41 4c 20 74 6f 20 66 72 65 65   the WAL to free
9cb0: 20 75 70 20 6d 65 6d 6f 72 79 29 2e 20 0a 20 20   up memory). .  
9cc0: 20 20 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65 20    ** Remove the 
9cd0: 72 65 6d 6e 61 6e 74 73 20 6f 66 20 74 68 61 74  remnants of that
9ce0: 20 77 72 69 74 65 72 73 20 75 6e 63 6f 6d 6d 69   writers uncommi
9cf0: 74 74 65 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  tted transaction
9d00: 20 66 72 6f 6d 20 0a 20 20 20 20 2a 2a 20 74 68   from .    ** th
9d10: 65 20 68 61 73 68 2d 74 61 62 6c 65 20 62 65 66  e hash-table bef
9d20: 6f 72 65 20 77 72 69 74 69 6e 67 20 61 6e 79 20  ore writing any 
9d30: 6e 65 77 20 65 6e 74 72 69 65 73 2e 0a 20 20 20  new entries..   
9d40: 20 2a 2f 0a 20 20 20 20 69 66 28 20 61 50 67 6e   */.    if( aPgn
9d50: 6f 5b 69 64 78 5d 20 29 7b 0a 20 20 20 20 20 20  o[idx] ){.      
9d60: 77 61 6c 43 6c 65 61 6e 75 70 48 61 73 68 28 70  walCleanupHash(p
9d70: 57 61 6c 29 3b 0a 20 20 20 20 20 20 61 73 73 65  Wal);.      asse
9d80: 72 74 28 20 21 61 50 67 6e 6f 5b 69 64 78 5d 20  rt( !aPgno[idx] 
9d90: 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  );.    }..    /*
9da0: 20 57 72 69 74 65 20 74 68 65 20 61 50 67 6e 6f   Write the aPgno
9db0: 5b 5d 20 61 72 72 61 79 20 65 6e 74 72 79 20 61  [] array entry a
9dc0: 6e 64 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c  nd the hash-tabl
9dd0: 65 20 73 6c 6f 74 2e 20 2a 2f 0a 20 20 20 20 6e  e slot. */.    n
9de0: 43 6f 6c 6c 69 64 65 20 3d 20 69 64 78 3b 0a 20  Collide = idx;. 
9df0: 20 20 20 66 6f 72 28 69 4b 65 79 3d 77 61 6c 48     for(iKey=walH
9e00: 61 73 68 28 69 50 61 67 65 29 3b 20 61 48 61 73  ash(iPage); aHas
9e10: 68 5b 69 4b 65 79 5d 3b 20 69 4b 65 79 3d 77 61  h[iKey]; iKey=wa
9e20: 6c 4e 65 78 74 48 61 73 68 28 69 4b 65 79 29 29  lNextHash(iKey))
9e30: 7b 0a 20 20 20 20 20 20 69 66 28 20 28 6e 43 6f  {.      if( (nCo
9e40: 6c 6c 69 64 65 2d 2d 29 3d 3d 30 20 29 20 72 65  llide--)==0 ) re
9e50: 74 75 72 6e 20 53 51 4c 49 54 45 5f 43 4f 52 52  turn SQLITE_CORR
9e60: 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20 20 7d 0a  UPT_BKPT;.    }.
9e70: 20 20 20 20 61 50 67 6e 6f 5b 69 64 78 5d 20 3d      aPgno[idx] =
9e80: 20 69 50 61 67 65 3b 0a 20 20 20 20 61 48 61 73   iPage;.    aHas
9e90: 68 5b 69 4b 65 79 5d 20 3d 20 28 68 74 5f 73 6c  h[iKey] = (ht_sl
9ea0: 6f 74 29 69 64 78 3b 0a 0a 23 69 66 64 65 66 20  ot)idx;..#ifdef 
9eb0: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58  SQLITE_ENABLE_EX
9ec0: 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54 0a 20  PENSIVE_ASSERT. 
9ed0: 20 20 20 2f 2a 20 56 65 72 69 66 79 20 74 68 61     /* Verify tha
9ee0: 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  t the number of 
9ef0: 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20 68  entries in the h
9f00: 61 73 68 20 74 61 62 6c 65 20 65 78 61 63 74 6c  ash table exactl
9f10: 79 20 65 71 75 61 6c 73 0a 20 20 20 20 2a 2a 20  y equals.    ** 
9f20: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e  the number of en
9f30: 74 72 69 65 73 20 69 6e 20 74 68 65 20 6d 61 70  tries in the map
9f40: 70 69 6e 67 20 72 65 67 69 6f 6e 2e 0a 20 20 20  ping region..   
9f50: 20 2a 2f 0a 20 20 20 20 7b 0a 20 20 20 20 20 20   */.    {.      
9f60: 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
9f70: 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72   /* Loop counter
9f80: 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 45   */.      int nE
9f90: 6e 74 72 79 20 3d 20 30 3b 20 20 2f 2a 20 4e 75  ntry = 0;  /* Nu
9fa0: 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20  mber of entries 
9fb0: 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  in the hash tabl
9fc0: 65 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28 69  e */.      for(i
9fd0: 3d 30 3b 20 69 3c 48 41 53 48 54 41 42 4c 45 5f  =0; i<HASHTABLE_
9fe0: 4e 53 4c 4f 54 3b 20 69 2b 2b 29 7b 20 69 66 28  NSLOT; i++){ if(
9ff0: 20 61 48 61 73 68 5b 69 5d 20 29 20 6e 45 6e 74   aHash[i] ) nEnt
a000: 72 79 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 61 73  ry++; }.      as
a010: 73 65 72 74 28 20 6e 45 6e 74 72 79 3d 3d 69 64  sert( nEntry==id
a020: 78 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  x );.    }..    
a030: 2f 2a 20 56 65 72 69 66 79 20 74 68 61 74 20 74  /* Verify that t
a040: 68 65 20 65 76 65 72 79 20 65 6e 74 72 79 20 69  he every entry i
a050: 6e 20 74 68 65 20 6d 61 70 70 69 6e 67 20 72 65  n the mapping re
a060: 67 69 6f 6e 20 69 73 20 72 65 61 63 68 61 62 6c  gion is reachabl
a070: 65 0a 20 20 20 20 2a 2a 20 76 69 61 20 74 68 65  e.    ** via the
a080: 20 68 61 73 68 20 74 61 62 6c 65 2e 20 20 54 68   hash table.  Th
a090: 69 73 20 74 75 72 6e 73 20 6f 75 74 20 74 6f 20  is turns out to 
a0a0: 62 65 20 61 20 72 65 61 6c 6c 79 2c 20 72 65 61  be a really, rea
a0b0: 6c 6c 79 20 65 78 70 65 6e 73 69 76 65 0a 20 20  lly expensive.  
a0c0: 20 20 2a 2a 20 74 68 69 6e 67 20 74 6f 20 63 68    ** thing to ch
a0d0: 65 63 6b 2c 20 73 6f 20 6f 6e 6c 79 20 64 6f 20  eck, so only do 
a0e0: 74 68 69 73 20 6f 63 63 61 73 69 6f 6e 61 6c 6c  this occasionall
a0f0: 79 20 2d 20 6e 6f 74 20 6f 6e 20 65 76 65 72 79  y - not on every
a100: 0a 20 20 20 20 2a 2a 20 69 74 65 72 61 74 69 6f  .    ** iteratio
a110: 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66  n..    */.    if
a120: 28 20 28 69 64 78 26 30 78 33 66 66 29 3d 3d 30  ( (idx&0x3ff)==0
a130: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b   ){.      int i;
a140: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f             /* Lo
a150: 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20  op counter */.  
a160: 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 3d      for(i=1; i<=
a170: 69 64 78 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  idx; i++){.     
a180: 20 20 20 66 6f 72 28 69 4b 65 79 3d 77 61 6c 48     for(iKey=walH
a190: 61 73 68 28 61 50 67 6e 6f 5b 69 5d 29 3b 20 61  ash(aPgno[i]); a
a1a0: 48 61 73 68 5b 69 4b 65 79 5d 3b 20 69 4b 65 79  Hash[iKey]; iKey
a1b0: 3d 77 61 6c 4e 65 78 74 48 61 73 68 28 69 4b 65  =walNextHash(iKe
a1c0: 79 29 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  y)){.          i
a1d0: 66 28 20 61 48 61 73 68 5b 69 4b 65 79 5d 3d 3d  f( aHash[iKey]==
a1e0: 69 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  i ) break;.     
a1f0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 61 73 73     }.        ass
a200: 65 72 74 28 20 61 48 61 73 68 5b 69 4b 65 79 5d  ert( aHash[iKey]
a210: 3d 3d 69 20 29 3b 0a 20 20 20 20 20 20 7d 0a 20  ==i );.      }. 
a220: 20 20 20 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53     }.#endif /* S
a230: 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50  QLITE_ENABLE_EXP
a240: 45 4e 53 49 56 45 5f 41 53 53 45 52 54 20 2a 2f  ENSIVE_ASSERT */
a250: 0a 20 20 7d 0a 0a 0a 20 20 72 65 74 75 72 6e 20  .  }...  return 
a260: 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65  rc;.}.../*.** Re
a270: 63 6f 76 65 72 20 74 68 65 20 77 61 6c 2d 69 6e  cover the wal-in
a280: 64 65 78 20 62 79 20 72 65 61 64 69 6e 67 20 74  dex by reading t
a290: 68 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c  he write-ahead l
a2a0: 6f 67 20 66 69 6c 65 2e 20 0a 2a 2a 0a 2a 2a 20  og file. .**.** 
a2b0: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 66 69 72  This routine fir
a2c0: 73 74 20 74 72 69 65 73 20 74 6f 20 65 73 74 61  st tries to esta
a2d0: 62 6c 69 73 68 20 61 6e 20 65 78 63 6c 75 73 69  blish an exclusi
a2e0: 76 65 20 6c 6f 63 6b 20 6f 6e 20 74 68 65 0a 2a  ve lock on the.*
a2f0: 2a 20 77 61 6c 2d 69 6e 64 65 78 20 74 6f 20 70  * wal-index to p
a300: 72 65 76 65 6e 74 20 6f 74 68 65 72 20 74 68 72  revent other thr
a310: 65 61 64 73 2f 70 72 6f 63 65 73 73 65 73 20 66  eads/processes f
a320: 72 6f 6d 20 64 6f 69 6e 67 20 61 6e 79 74 68 69  rom doing anythi
a330: 6e 67 0a 2a 2a 20 77 69 74 68 20 74 68 65 20 57  ng.** with the W
a340: 41 4c 20 6f 72 20 77 61 6c 2d 69 6e 64 65 78 20  AL or wal-index 
a350: 77 68 69 6c 65 20 72 65 63 6f 76 65 72 79 20 69  while recovery i
a360: 73 20 72 75 6e 6e 69 6e 67 2e 20 20 54 68 65 0a  s running.  The.
a370: 2a 2a 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c  ** WAL_RECOVER_L
a380: 4f 43 4b 20 69 73 20 61 6c 73 6f 20 68 65 6c 64  OCK is also held
a390: 20 73 6f 20 74 68 61 74 20 6f 74 68 65 72 20 74   so that other t
a3a0: 68 72 65 61 64 73 20 77 69 6c 6c 20 6b 6e 6f 77  hreads will know
a3b0: 0a 2a 2a 20 74 68 61 74 20 74 68 69 73 20 74 68  .** that this th
a3c0: 72 65 61 64 20 69 73 20 72 75 6e 6e 69 6e 67 20  read is running 
a3d0: 72 65 63 6f 76 65 72 79 2e 20 20 49 66 20 75 6e  recovery.  If un
a3e0: 61 62 6c 65 20 74 6f 20 65 73 74 61 62 6c 69 73  able to establis
a3f0: 68 0a 2a 2a 20 74 68 65 20 6e 65 63 65 73 73 61  h.** the necessa
a400: 72 79 20 6c 6f 63 6b 73 2c 20 74 68 69 73 20 72  ry locks, this r
a410: 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73 20 53  outine returns S
a420: 51 4c 49 54 45 5f 42 55 53 59 2e 0a 2a 2f 0a 73  QLITE_BUSY..*/.s
a430: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e 64  tatic int walInd
a440: 65 78 52 65 63 6f 76 65 72 28 57 61 6c 20 2a 70  exRecover(Wal *p
a450: 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  Wal){.  int rc; 
a460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a470: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
a480: 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 69 36 34 20  n Code */.  i64 
a490: 6e 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20  nSize;          
a4a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
a4b0: 69 7a 65 20 6f 66 20 6c 6f 67 20 66 69 6c 65 20  ize of log file 
a4c0: 2a 2f 0a 20 20 75 33 32 20 61 46 72 61 6d 65 43  */.  u32 aFrameC
a4d0: 6b 73 75 6d 5b 32 5d 20 3d 20 7b 30 2c 20 30 7d  ksum[2] = {0, 0}
a4e0: 3b 0a 20 20 69 6e 74 20 69 4c 6f 63 6b 3b 20 20  ;.  int iLock;  
a4f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a500: 20 20 20 20 2f 2a 20 4c 6f 63 6b 20 6f 66 66 73      /* Lock offs
a510: 65 74 20 74 6f 20 6c 6f 63 6b 20 66 6f 72 20 63  et to lock for c
a520: 68 65 63 6b 70 6f 69 6e 74 20 2a 2f 0a 20 20 69  heckpoint */.  i
a530: 6e 74 20 6e 4c 6f 63 6b 3b 20 20 20 20 20 20 20  nt nLock;       
a540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
a550: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6c 6f 63 6b  * Number of lock
a560: 73 20 74 6f 20 68 6f 6c 64 20 2a 2f 0a 0a 20 20  s to hold */..  
a570: 2f 2a 20 4f 62 74 61 69 6e 20 61 6e 20 65 78 63  /* Obtain an exc
a580: 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 61  lusive lock on a
a590: 6c 6c 20 62 79 74 65 20 69 6e 20 74 68 65 20 6c  ll byte in the l
a5a0: 6f 63 6b 69 6e 67 20 72 61 6e 67 65 20 6e 6f 74  ocking range not
a5b0: 20 61 6c 72 65 61 64 79 0a 20 20 2a 2a 20 6c 6f   already.  ** lo
a5c0: 63 6b 65 64 20 62 79 20 74 68 65 20 63 61 6c 6c  cked by the call
a5d0: 65 72 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 69  er. The caller i
a5e0: 73 20 67 75 61 72 61 6e 74 65 65 64 20 74 6f 20  s guaranteed to 
a5f0: 68 61 76 65 20 6c 6f 63 6b 65 64 20 74 68 65 0a  have locked the.
a600: 20 20 2a 2a 20 57 41 4c 5f 57 52 49 54 45 5f 4c    ** WAL_WRITE_L
a610: 4f 43 4b 20 62 79 74 65 2c 20 61 6e 64 20 6d 61  OCK byte, and ma
a620: 79 20 68 61 76 65 20 61 6c 73 6f 20 6c 6f 63 6b  y have also lock
a630: 65 64 20 74 68 65 20 57 41 4c 5f 43 4b 50 54 5f  ed the WAL_CKPT_
a640: 4c 4f 43 4b 20 62 79 74 65 2e 0a 20 20 2a 2a 20  LOCK byte..  ** 
a650: 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 74  If successful, t
a660: 68 65 20 73 61 6d 65 20 62 79 74 65 73 20 74 68  he same bytes th
a670: 61 74 20 61 72 65 20 6c 6f 63 6b 65 64 20 68 65  at are locked he
a680: 72 65 20 61 72 65 20 75 6e 6c 6f 63 6b 65 64 20  re are unlocked 
a690: 62 65 66 6f 72 65 0a 20 20 2a 2a 20 74 68 69 73  before.  ** this
a6a0: 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e   function return
a6b0: 73 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74  s..  */.  assert
a6c0: 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b  ( pWal->ckptLock
a6d0: 3d 3d 31 20 7c 7c 20 70 57 61 6c 2d 3e 63 6b 70  ==1 || pWal->ckp
a6e0: 74 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 61 73  tLock==0 );.  as
a6f0: 73 65 72 74 28 20 57 41 4c 5f 41 4c 4c 5f 42 55  sert( WAL_ALL_BU
a700: 54 5f 57 52 49 54 45 3d 3d 57 41 4c 5f 57 52 49  T_WRITE==WAL_WRI
a710: 54 45 5f 4c 4f 43 4b 2b 31 20 29 3b 0a 20 20 61  TE_LOCK+1 );.  a
a720: 73 73 65 72 74 28 20 57 41 4c 5f 43 4b 50 54 5f  ssert( WAL_CKPT_
a730: 4c 4f 43 4b 3d 3d 57 41 4c 5f 41 4c 4c 5f 42 55  LOCK==WAL_ALL_BU
a740: 54 5f 57 52 49 54 45 20 29 3b 0a 20 20 61 73 73  T_WRITE );.  ass
a750: 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65  ert( pWal->write
a760: 4c 6f 63 6b 20 29 3b 0a 20 20 69 4c 6f 63 6b 20  Lock );.  iLock 
a770: 3d 20 57 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52  = WAL_ALL_BUT_WR
a780: 49 54 45 20 2b 20 70 57 61 6c 2d 3e 63 6b 70 74  ITE + pWal->ckpt
a790: 4c 6f 63 6b 3b 0a 20 20 6e 4c 6f 63 6b 20 3d 20  Lock;.  nLock = 
a7a0: 53 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43 4b  SQLITE_SHM_NLOCK
a7b0: 20 2d 20 69 4c 6f 63 6b 3b 0a 20 20 72 63 20 3d   - iLock;.  rc =
a7c0: 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76   walLockExclusiv
a7d0: 65 28 70 57 61 6c 2c 20 69 4c 6f 63 6b 2c 20 6e  e(pWal, iLock, n
a7e0: 4c 6f 63 6b 29 3b 0a 20 20 69 66 28 20 72 63 20  Lock);.  if( rc 
a7f0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  ){.    return rc
a800: 3b 0a 20 20 7d 0a 20 20 57 41 4c 54 52 41 43 45  ;.  }.  WALTRACE
a810: 28 28 22 57 41 4c 25 70 3a 20 72 65 63 6f 76 65  (("WAL%p: recove
a820: 72 79 20 62 65 67 69 6e 2e 2e 2e 5c 6e 22 2c 20  ry begin...\n", 
a830: 70 57 61 6c 29 29 3b 0a 0a 20 20 6d 65 6d 73 65  pWal));..  memse
a840: 74 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 30 2c  t(&pWal->hdr, 0,
a850: 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
a860: 48 64 72 29 29 3b 0a 0a 20 20 72 63 20 3d 20 73  Hdr));..  rc = s
a870: 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a 65  qlite3OsFileSize
a880: 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 26  (pWal->pWalFd, &
a890: 6e 53 69 7a 65 29 3b 0a 20 20 69 66 28 20 72 63  nSize);.  if( rc
a8a0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
a8b0: 20 20 20 67 6f 74 6f 20 72 65 63 6f 76 65 72 79     goto recovery
a8c0: 5f 65 72 72 6f 72 3b 0a 20 20 7d 0a 0a 20 20 69  _error;.  }..  i
a8d0: 66 28 20 6e 53 69 7a 65 3e 57 41 4c 5f 48 44 52  f( nSize>WAL_HDR
a8e0: 53 49 5a 45 20 29 7b 0a 20 20 20 20 75 38 20 61  SIZE ){.    u8 a
a8f0: 42 75 66 5b 57 41 4c 5f 48 44 52 53 49 5a 45 5d  Buf[WAL_HDRSIZE]
a900: 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66  ;         /* Buf
a910: 66 65 72 20 74 6f 20 6c 6f 61 64 20 57 41 4c 20  fer to load WAL 
a920: 68 65 61 64 65 72 20 69 6e 74 6f 20 2a 2f 0a 20  header into */. 
a930: 20 20 20 75 38 20 2a 61 46 72 61 6d 65 20 3d 20     u8 *aFrame = 
a940: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
a950: 20 2f 2a 20 4d 61 6c 6c 6f 63 27 64 20 62 75 66   /* Malloc'd buf
a960: 66 65 72 20 74 6f 20 6c 6f 61 64 20 65 6e 74 69  fer to load enti
a970: 72 65 20 66 72 61 6d 65 20 2a 2f 0a 20 20 20 20  re frame */.    
a980: 69 6e 74 20 73 7a 46 72 61 6d 65 3b 20 20 20 20  int szFrame;    
a990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
a9a0: 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   Number of bytes
a9b0: 20 69 6e 20 62 75 66 66 65 72 20 61 46 72 61 6d   in buffer aFram
a9c0: 65 5b 5d 20 2a 2f 0a 20 20 20 20 75 38 20 2a 61  e[] */.    u8 *a
a9d0: 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
a9e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
a9f0: 74 65 72 20 74 6f 20 64 61 74 61 20 70 61 72 74  ter to data part
aa00: 20 6f 66 20 61 46 72 61 6d 65 20 62 75 66 66 65   of aFrame buffe
aa10: 72 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 46 72  r */.    int iFr
aa20: 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ame;            
aa30: 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20         /* Index 
aa40: 6f 66 20 6c 61 73 74 20 66 72 61 6d 65 20 72 65  of last frame re
aa50: 61 64 20 2a 2f 0a 20 20 20 20 69 36 34 20 69 4f  ad */.    i64 iO
aa60: 66 66 73 65 74 3b 20 20 20 20 20 20 20 20 20 20  ffset;          
aa70: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
aa80: 6f 66 66 73 65 74 20 74 6f 20 72 65 61 64 20 66  offset to read f
aa90: 72 6f 6d 20 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a  rom log file */.
aaa0: 20 20 20 20 69 6e 74 20 73 7a 50 61 67 65 3b 20      int szPage; 
aab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aac0: 20 20 2f 2a 20 50 61 67 65 20 73 69 7a 65 20 61    /* Page size a
aad0: 63 63 6f 72 64 69 6e 67 20 74 6f 20 74 68 65 20  ccording to the 
aae0: 6c 6f 67 20 2a 2f 0a 20 20 20 20 75 33 32 20 6d  log */.    u32 m
aaf0: 61 67 69 63 3b 20 20 20 20 20 20 20 20 20 20 20  agic;           
ab00: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 67 69           /* Magi
ab10: 63 20 76 61 6c 75 65 20 72 65 61 64 20 66 72 6f  c value read fro
ab20: 6d 20 57 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a  m WAL header */.
ab30: 20 20 20 20 75 33 32 20 76 65 72 73 69 6f 6e 3b      u32 version;
ab40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ab50: 20 20 2f 2a 20 4d 61 67 69 63 20 76 61 6c 75 65    /* Magic value
ab60: 20 72 65 61 64 20 66 72 6f 6d 20 57 41 4c 20 68   read from WAL h
ab70: 65 61 64 65 72 20 2a 2f 0a 0a 20 20 20 20 2f 2a  eader */..    /*
ab80: 20 52 65 61 64 20 69 6e 20 74 68 65 20 57 41 4c   Read in the WAL
ab90: 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20 20 20 20   header. */.    
aba0: 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65  rc = sqlite3OsRe
abb0: 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  ad(pWal->pWalFd,
abc0: 20 61 42 75 66 2c 20 57 41 4c 5f 48 44 52 53 49   aBuf, WAL_HDRSI
abd0: 5a 45 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20  ZE, 0);.    if( 
abe0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
abf0: 0a 20 20 20 20 20 20 67 6f 74 6f 20 72 65 63 6f  .      goto reco
ac00: 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20 20 20 20  very_error;.    
ac10: 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 65  }..    /* If the
ac20: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20 73   database page s
ac30: 69 7a 65 20 69 73 20 6e 6f 74 20 61 20 70 6f 77  ize is not a pow
ac40: 65 72 20 6f 66 20 74 77 6f 2c 20 6f 72 20 69 73  er of two, or is
ac50: 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 20 20   greater than.  
ac60: 20 20 2a 2a 20 53 51 4c 49 54 45 5f 4d 41 58 5f    ** SQLITE_MAX_
ac70: 50 41 47 45 5f 53 49 5a 45 2c 20 63 6f 6e 63 6c  PAGE_SIZE, concl
ac80: 75 64 65 20 74 68 61 74 20 74 68 65 20 57 41 4c  ude that the WAL
ac90: 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 6e   file contains n
aca0: 6f 20 76 61 6c 69 64 20 0a 20 20 20 20 2a 2a 20  o valid .    ** 
acb0: 64 61 74 61 2e 20 53 69 6d 69 6c 61 72 6c 79 2c  data. Similarly,
acc0: 20 69 66 20 74 68 65 20 27 6d 61 67 69 63 27 20   if the 'magic' 
acd0: 76 61 6c 75 65 20 69 73 20 69 6e 76 61 6c 69 64  value is invalid
ace0: 2c 20 69 67 6e 6f 72 65 20 74 68 65 20 77 68 6f  , ignore the who
acf0: 6c 65 0a 20 20 20 20 2a 2a 20 57 41 4c 20 66 69  le.    ** WAL fi
ad00: 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d  le..    */.    m
ad10: 61 67 69 63 20 3d 20 73 71 6c 69 74 65 33 47 65  agic = sqlite3Ge
ad20: 74 34 62 79 74 65 28 26 61 42 75 66 5b 30 5d 29  t4byte(&aBuf[0])
ad30: 3b 0a 20 20 20 20 73 7a 50 61 67 65 20 3d 20 73  ;.    szPage = s
ad40: 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26  qlite3Get4byte(&
ad50: 61 42 75 66 5b 38 5d 29 3b 0a 20 20 20 20 69 66  aBuf[8]);.    if
ad60: 28 20 28 6d 61 67 69 63 26 30 78 46 46 46 46 46  ( (magic&0xFFFFF
ad70: 46 46 45 29 21 3d 57 41 4c 5f 4d 41 47 49 43 20  FFE)!=WAL_MAGIC 
ad80: 0a 20 20 20 20 20 7c 7c 20 73 7a 50 61 67 65 26  .     || szPage&
ad90: 28 73 7a 50 61 67 65 2d 31 29 20 0a 20 20 20 20  (szPage-1) .    
ada0: 20 7c 7c 20 73 7a 50 61 67 65 3e 53 51 4c 49 54   || szPage>SQLIT
adb0: 45 5f 4d 41 58 5f 50 41 47 45 5f 53 49 5a 45 20  E_MAX_PAGE_SIZE 
adc0: 0a 20 20 20 20 20 7c 7c 20 73 7a 50 61 67 65 3c  .     || szPage<
add0: 35 31 32 20 0a 20 20 20 20 29 7b 0a 20 20 20 20  512 .    ){.    
ade0: 20 20 67 6f 74 6f 20 66 69 6e 69 73 68 65 64 3b    goto finished;
adf0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 57 61 6c 2d  .    }.    pWal-
ae00: 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d  >hdr.bigEndCksum
ae10: 20 3d 20 28 75 38 29 28 6d 61 67 69 63 26 30 78   = (u8)(magic&0x
ae20: 30 30 30 30 30 30 30 31 29 3b 0a 20 20 20 20 70  00000001);.    p
ae30: 57 61 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a  Wal->szPage = sz
ae40: 50 61 67 65 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  Page;.    pWal->
ae50: 6e 43 6b 70 74 20 3d 20 73 71 6c 69 74 65 33 47  nCkpt = sqlite3G
ae60: 65 74 34 62 79 74 65 28 26 61 42 75 66 5b 31 32  et4byte(&aBuf[12
ae70: 5d 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26  ]);.    memcpy(&
ae80: 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c  pWal->hdr.aSalt,
ae90: 20 26 61 42 75 66 5b 31 36 5d 2c 20 38 29 3b 0a   &aBuf[16], 8);.
aea0: 0a 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20 74  .    /* Verify t
aeb0: 68 61 74 20 74 68 65 20 57 41 4c 20 68 65 61 64  hat the WAL head
aec0: 65 72 20 63 68 65 63 6b 73 75 6d 20 69 73 20 63  er checksum is c
aed0: 6f 72 72 65 63 74 20 2a 2f 0a 20 20 20 20 77 61  orrect */.    wa
aee0: 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28 70  lChecksumBytes(p
aef0: 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43  Wal->hdr.bigEndC
af00: 6b 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47  ksum==SQLITE_BIG
af10: 45 4e 44 49 41 4e 2c 20 0a 20 20 20 20 20 20 20  ENDIAN, .       
af20: 20 61 42 75 66 2c 20 57 41 4c 5f 48 44 52 53 49   aBuf, WAL_HDRSI
af30: 5a 45 2d 32 2a 34 2c 20 30 2c 20 70 57 61 6c 2d  ZE-2*4, 0, pWal-
af40: 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
af50: 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28 20  .    );.    if( 
af60: 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
af70: 43 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65  Cksum[0]!=sqlite
af80: 33 47 65 74 34 62 79 74 65 28 26 61 42 75 66 5b  3Get4byte(&aBuf[
af90: 32 34 5d 29 0a 20 20 20 20 20 7c 7c 20 70 57 61  24]).     || pWa
afa0: 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
afb0: 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33 47 65  um[1]!=sqlite3Ge
afc0: 74 34 62 79 74 65 28 26 61 42 75 66 5b 32 38 5d  t4byte(&aBuf[28]
afd0: 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 67  ).    ){.      g
afe0: 6f 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20  oto finished;.  
aff0: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69    }..    /* Veri
b000: 66 79 20 74 68 61 74 20 74 68 65 20 76 65 72 73  fy that the vers
b010: 69 6f 6e 20 6e 75 6d 62 65 72 20 6f 6e 20 74 68  ion number on th
b020: 65 20 57 41 4c 20 66 6f 72 6d 61 74 20 69 73 20  e WAL format is 
b030: 6f 6e 65 20 74 68 61 74 0a 20 20 20 20 2a 2a 20  one that.    ** 
b040: 61 72 65 20 61 62 6c 65 20 74 6f 20 75 6e 64 65  are able to unde
b050: 72 73 74 61 6e 64 20 2a 2f 0a 20 20 20 20 76 65  rstand */.    ve
b060: 72 73 69 6f 6e 20 3d 20 73 71 6c 69 74 65 33 47  rsion = sqlite3G
b070: 65 74 34 62 79 74 65 28 26 61 42 75 66 5b 34 5d  et4byte(&aBuf[4]
b080: 29 3b 0a 20 20 20 20 69 66 28 20 76 65 72 73 69  );.    if( versi
b090: 6f 6e 21 3d 57 41 4c 5f 4d 41 58 5f 56 45 52 53  on!=WAL_MAX_VERS
b0a0: 49 4f 4e 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ION ){.      rc 
b0b0: 3d 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50 45  = SQLITE_CANTOPE
b0c0: 4e 5f 42 4b 50 54 3b 0a 20 20 20 20 20 20 67 6f  N_BKPT;.      go
b0d0: 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20 20  to finished;.   
b0e0: 20 7d 0a 0a 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f   }..    /* Mallo
b0f0: 63 20 61 20 62 75 66 66 65 72 20 74 6f 20 72 65  c a buffer to re
b100: 61 64 20 66 72 61 6d 65 73 20 69 6e 74 6f 2e 20  ad frames into. 
b110: 2a 2f 0a 20 20 20 20 73 7a 46 72 61 6d 65 20 3d  */.    szFrame =
b120: 20 73 7a 50 61 67 65 20 2b 20 57 41 4c 5f 46 52   szPage + WAL_FR
b130: 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20 20 20  AME_HDRSIZE;.   
b140: 20 61 46 72 61 6d 65 20 3d 20 28 75 38 20 2a 29   aFrame = (u8 *)
b150: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
b160: 7a 46 72 61 6d 65 29 3b 0a 20 20 20 20 69 66 28  zFrame);.    if(
b170: 20 21 61 46 72 61 6d 65 20 29 7b 0a 20 20 20 20   !aFrame ){.    
b180: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
b190: 4d 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20  MEM;.      goto 
b1a0: 72 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a  recovery_error;.
b1b0: 20 20 20 20 7d 0a 20 20 20 20 61 44 61 74 61 20      }.    aData 
b1c0: 3d 20 26 61 46 72 61 6d 65 5b 57 41 4c 5f 46 52  = &aFrame[WAL_FR
b1d0: 41 4d 45 5f 48 44 52 53 49 5a 45 5d 3b 0a 0a 20  AME_HDRSIZE];.. 
b1e0: 20 20 20 2f 2a 20 52 65 61 64 20 61 6c 6c 20 66     /* Read all f
b1f0: 72 61 6d 65 73 20 66 72 6f 6d 20 74 68 65 20 6c  rames from the l
b200: 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 20 20  og file. */.    
b210: 69 46 72 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20  iFrame = 0;.    
b220: 66 6f 72 28 69 4f 66 66 73 65 74 3d 57 41 4c 5f  for(iOffset=WAL_
b230: 48 44 52 53 49 5a 45 3b 20 28 69 4f 66 66 73 65  HDRSIZE; (iOffse
b240: 74 2b 73 7a 46 72 61 6d 65 29 3c 3d 6e 53 69 7a  t+szFrame)<=nSiz
b250: 65 3b 20 69 4f 66 66 73 65 74 2b 3d 73 7a 46 72  e; iOffset+=szFr
b260: 61 6d 65 29 7b 0a 20 20 20 20 20 20 75 33 32 20  ame){.      u32 
b270: 70 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20  pgno;           
b280: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
b290: 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  ase page number 
b2a0: 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20 20 20  for frame */.   
b2b0: 20 20 20 75 33 32 20 6e 54 72 75 6e 63 61 74 65     u32 nTruncate
b2c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ;              /
b2d0: 2a 20 64 62 73 69 7a 65 20 66 69 65 6c 64 20 66  * dbsize field f
b2e0: 72 6f 6d 20 66 72 61 6d 65 20 68 65 61 64 65 72  rom frame header
b2f0: 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 69 73   */.      int is
b300: 56 61 6c 69 64 3b 20 20 20 20 20 20 20 20 20 20  Valid;          
b310: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
b320: 20 74 68 69 73 20 66 72 61 6d 65 20 69 73 20 76   this frame is v
b330: 61 6c 69 64 20 2a 2f 0a 0a 20 20 20 20 20 20 2f  alid */..      /
b340: 2a 20 52 65 61 64 20 61 6e 64 20 64 65 63 6f 64  * Read and decod
b350: 65 20 74 68 65 20 6e 65 78 74 20 6c 6f 67 20 66  e the next log f
b360: 72 61 6d 65 2e 20 2a 2f 0a 20 20 20 20 20 20 72  rame. */.      r
b370: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61  c = sqlite3OsRea
b380: 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20  d(pWal->pWalFd, 
b390: 61 46 72 61 6d 65 2c 20 73 7a 46 72 61 6d 65 2c  aFrame, szFrame,
b3a0: 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20   iOffset);.     
b3b0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
b3c0: 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  OK ) break;.    
b3d0: 20 20 69 73 56 61 6c 69 64 20 3d 20 77 61 6c 44    isValid = walD
b3e0: 65 63 6f 64 65 46 72 61 6d 65 28 70 57 61 6c 2c  ecodeFrame(pWal,
b3f0: 20 26 70 67 6e 6f 2c 20 26 6e 54 72 75 6e 63 61   &pgno, &nTrunca
b400: 74 65 2c 20 61 44 61 74 61 2c 20 61 46 72 61 6d  te, aData, aFram
b410: 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 69  e);.      if( !i
b420: 73 56 61 6c 69 64 20 29 20 62 72 65 61 6b 3b 0a  sValid ) break;.
b430: 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e        rc = walIn
b440: 64 65 78 41 70 70 65 6e 64 28 70 57 61 6c 2c 20  dexAppend(pWal, 
b450: 2b 2b 69 46 72 61 6d 65 2c 20 70 67 6e 6f 29 3b  ++iFrame, pgno);
b460: 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
b470: 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
b480: 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 6e  ;..      /* If n
b490: 54 72 75 6e 63 61 74 65 20 69 73 20 6e 6f 6e 2d  Truncate is non-
b4a0: 7a 65 72 6f 2c 20 74 68 69 73 20 69 73 20 61 20  zero, this is a 
b4b0: 63 6f 6d 6d 69 74 20 72 65 63 6f 72 64 2e 20 2a  commit record. *
b4c0: 2f 0a 20 20 20 20 20 20 69 66 28 20 6e 54 72 75  /.      if( nTru
b4d0: 6e 63 61 74 65 20 29 7b 0a 20 20 20 20 20 20 20  ncate ){.       
b4e0: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
b4f0: 6d 65 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20  me = iFrame;.   
b500: 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6e       pWal->hdr.n
b510: 50 61 67 65 20 3d 20 6e 54 72 75 6e 63 61 74 65  Page = nTruncate
b520: 3b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e  ;.        pWal->
b530: 68 64 72 2e 73 7a 50 61 67 65 20 3d 20 28 75 31  hdr.szPage = (u1
b540: 36 29 28 28 73 7a 50 61 67 65 26 30 78 66 66 30  6)((szPage&0xff0
b550: 30 29 20 7c 20 28 73 7a 50 61 67 65 3e 3e 31 36  0) | (szPage>>16
b560: 29 29 3b 0a 20 20 20 20 20 20 20 20 74 65 73 74  ));.        test
b570: 63 61 73 65 28 20 73 7a 50 61 67 65 3c 3d 33 32  case( szPage<=32
b580: 37 36 38 20 29 3b 0a 20 20 20 20 20 20 20 20 74  768 );.        t
b590: 65 73 74 63 61 73 65 28 20 73 7a 50 61 67 65 3e  estcase( szPage>
b5a0: 3d 36 35 35 33 36 20 29 3b 0a 20 20 20 20 20 20  =65536 );.      
b5b0: 20 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d    aFrameCksum[0]
b5c0: 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72   = pWal->hdr.aFr
b5d0: 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 20  ameCksum[0];.   
b5e0: 20 20 20 20 20 61 46 72 61 6d 65 43 6b 73 75 6d       aFrameCksum
b5f0: 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  [1] = pWal->hdr.
b600: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a  aFrameCksum[1];.
b610: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
b620: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
b630: 61 46 72 61 6d 65 29 3b 0a 20 20 7d 0a 0a 66 69  aFrame);.  }..fi
b640: 6e 69 73 68 65 64 3a 0a 20 20 69 66 28 20 72 63  nished:.  if( rc
b650: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
b660: 20 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43     volatile WalC
b670: 6b 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b 0a  kptInfo *pInfo;.
b680: 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20 70      int i;.    p
b690: 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
b6a0: 6b 73 75 6d 5b 30 5d 20 3d 20 61 46 72 61 6d 65  ksum[0] = aFrame
b6b0: 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 20 20 70 57  Cksum[0];.    pW
b6c0: 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
b6d0: 73 75 6d 5b 31 5d 20 3d 20 61 46 72 61 6d 65 43  sum[1] = aFrameC
b6e0: 6b 73 75 6d 5b 31 5d 3b 0a 20 20 20 20 77 61 6c  ksum[1];.    wal
b6f0: 49 6e 64 65 78 57 72 69 74 65 48 64 72 28 70 57  IndexWriteHdr(pW
b700: 61 6c 29 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 73  al);..    /* Res
b710: 65 74 20 74 68 65 20 63 68 65 63 6b 70 6f 69 6e  et the checkpoin
b720: 74 2d 68 65 61 64 65 72 2e 20 54 68 69 73 20 69  t-header. This i
b730: 73 20 73 61 66 65 20 62 65 63 61 75 73 65 20 74  s safe because t
b740: 68 69 73 20 74 68 72 65 61 64 20 69 73 20 0a 20  his thread is . 
b750: 20 20 20 2a 2a 20 63 75 72 72 65 6e 74 6c 79 20     ** currently 
b760: 68 6f 6c 64 69 6e 67 20 6c 6f 63 6b 73 20 74 68  holding locks th
b770: 61 74 20 65 78 63 6c 75 64 65 20 61 6c 6c 20 6f  at exclude all o
b780: 74 68 65 72 20 72 65 61 64 65 72 73 2c 20 77 72  ther readers, wr
b790: 69 74 65 72 73 20 61 6e 64 0a 20 20 20 20 2a 2a  iters and.    **
b7a0: 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 73 2e 0a   checkpointers..
b7b0: 20 20 20 20 2a 2f 0a 20 20 20 20 70 49 6e 66 6f      */.    pInfo
b7c0: 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f 28 70   = walCkptInfo(p
b7d0: 57 61 6c 29 3b 0a 20 20 20 20 70 49 6e 66 6f 2d  Wal);.    pInfo-
b7e0: 3e 6e 42 61 63 6b 66 69 6c 6c 20 3d 20 30 3b 0a  >nBackfill = 0;.
b7f0: 20 20 20 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64      pInfo->aRead
b800: 4d 61 72 6b 5b 30 5d 20 3d 20 30 3b 0a 20 20 20  Mark[0] = 0;.   
b810: 20 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f   for(i=1; i<WAL_
b820: 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29 20 70 49  NREADER; i++) pI
b830: 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69  nfo->aReadMark[i
b840: 5d 20 3d 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54  ] = READMARK_NOT
b850: 5f 55 53 45 44 3b 0a 0a 20 20 20 20 2f 2a 20 49  _USED;..    /* I
b860: 66 20 6d 6f 72 65 20 74 68 61 6e 20 6f 6e 65 20  f more than one 
b870: 66 72 61 6d 65 20 77 61 73 20 72 65 63 6f 76 65  frame was recove
b880: 72 65 64 20 66 72 6f 6d 20 74 68 65 20 6c 6f 67  red from the log
b890: 20 66 69 6c 65 2c 20 72 65 70 6f 72 74 20 61 6e   file, report an
b8a0: 0a 20 20 20 20 2a 2a 20 65 76 65 6e 74 20 76 69  .    ** event vi
b8b0: 61 20 73 71 6c 69 74 65 33 5f 6c 6f 67 28 29 2e  a sqlite3_log().
b8c0: 20 54 68 69 73 20 69 73 20 74 6f 20 68 65 6c 70   This is to help
b8d0: 20 77 69 74 68 20 69 64 65 6e 74 69 66 79 69 6e   with identifyin
b8e0: 67 20 70 65 72 66 6f 72 6d 61 6e 63 65 0a 20 20  g performance.  
b8f0: 20 20 2a 2a 20 70 72 6f 62 6c 65 6d 73 20 63 61    ** problems ca
b900: 75 73 65 64 20 62 79 20 61 70 70 6c 69 63 61 74  used by applicat
b910: 69 6f 6e 73 20 72 6f 75 74 69 6e 65 6c 79 20 73  ions routinely s
b920: 68 75 74 74 69 6e 67 20 64 6f 77 6e 20 77 69 74  hutting down wit
b930: 68 6f 75 74 0a 20 20 20 20 2a 2a 20 63 68 65 63  hout.    ** chec
b940: 6b 70 6f 69 6e 74 69 6e 67 20 74 68 65 20 6c 6f  kpointing the lo
b950: 67 20 66 69 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20  g file..    */. 
b960: 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72     if( pWal->hdr
b970: 2e 6e 50 61 67 65 20 29 7b 0a 20 20 20 20 20 20  .nPage ){.      
b980: 73 71 6c 69 74 65 33 5f 6c 6f 67 28 53 51 4c 49  sqlite3_log(SQLI
b990: 54 45 5f 4f 4b 2c 20 22 52 65 63 6f 76 65 72 65  TE_OK, "Recovere
b9a0: 64 20 25 64 20 66 72 61 6d 65 73 20 66 72 6f 6d  d %d frames from
b9b0: 20 57 41 4c 20 66 69 6c 65 20 25 73 22 2c 0a 20   WAL file %s",. 
b9c0: 20 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 68           pWal->h
b9d0: 64 72 2e 6e 50 61 67 65 2c 20 70 57 61 6c 2d 3e  dr.nPage, pWal->
b9e0: 7a 57 61 6c 4e 61 6d 65 0a 20 20 20 20 20 20 29  zWalName.      )
b9f0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 72 65 63  ;.    }.  }..rec
ba00: 6f 76 65 72 79 5f 65 72 72 6f 72 3a 0a 20 20 57  overy_error:.  W
ba10: 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
ba20: 20 72 65 63 6f 76 65 72 79 20 25 73 5c 6e 22 2c   recovery %s\n",
ba30: 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69   pWal, rc ? "fai
ba40: 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
ba50: 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
ba60: 69 76 65 28 70 57 61 6c 2c 20 69 4c 6f 63 6b 2c  ive(pWal, iLock,
ba70: 20 6e 4c 6f 63 6b 29 3b 0a 20 20 72 65 74 75 72   nLock);.  retur
ba80: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  n rc;.}../*.** C
ba90: 6c 6f 73 65 20 61 6e 20 6f 70 65 6e 20 77 61 6c  lose an open wal
baa0: 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 73 74 61 74 69  -index..*/.stati
bab0: 63 20 76 6f 69 64 20 77 61 6c 49 6e 64 65 78 43  c void walIndexC
bac0: 6c 6f 73 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20  lose(Wal *pWal, 
bad0: 69 6e 74 20 69 73 44 65 6c 65 74 65 29 7b 0a 20  int isDelete){. 
bae0: 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75   if( pWal->exclu
baf0: 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48 45  siveMode==WAL_HE
bb00: 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29 7b  APMEMORY_MODE ){
bb10: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
bb20: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 57 61 6c 2d  for(i=0; i<pWal-
bb30: 3e 6e 57 69 44 61 74 61 3b 20 69 2b 2b 29 7b 0a  >nWiData; i++){.
bb40: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
bb50: 65 65 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d  ee((void *)pWal-
bb60: 3e 61 70 57 69 44 61 74 61 5b 69 5d 29 3b 0a 20  >apWiData[i]);. 
bb70: 20 20 20 20 20 70 57 61 6c 2d 3e 61 70 57 69 44       pWal->apWiD
bb80: 61 74 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20  ata[i] = 0;.    
bb90: 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73  }.  }else{.    s
bba0: 71 6c 69 74 65 33 4f 73 53 68 6d 55 6e 6d 61 70  qlite3OsShmUnmap
bbb0: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 73  (pWal->pDbFd, is
bbc0: 44 65 6c 65 74 65 29 3b 0a 20 20 7d 0a 7d 0a 0a  Delete);.  }.}..
bbd0: 2f 2a 20 0a 2a 2a 20 4f 70 65 6e 20 61 20 63 6f  /* .** Open a co
bbe0: 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 74 68 65 20  nnection to the 
bbf0: 57 41 4c 20 66 69 6c 65 20 7a 57 61 6c 4e 61 6d  WAL file zWalNam
bc00: 65 2e 20 54 68 65 20 64 61 74 61 62 61 73 65 20  e. The database 
bc10: 66 69 6c 65 20 6d 75 73 74 20 0a 2a 2a 20 61 6c  file must .** al
bc20: 72 65 61 64 79 20 62 65 20 6f 70 65 6e 65 64 20  ready be opened 
bc30: 6f 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 70 44  on connection pD
bc40: 62 46 64 2e 20 54 68 65 20 62 75 66 66 65 72 20  bFd. The buffer 
bc50: 74 68 61 74 20 7a 57 61 6c 4e 61 6d 65 20 70 6f  that zWalName po
bc60: 69 6e 74 73 0a 2a 2a 20 74 6f 20 6d 75 73 74 20  ints.** to must 
bc70: 72 65 6d 61 69 6e 20 76 61 6c 69 64 20 66 6f 72  remain valid for
bc80: 20 74 68 65 20 6c 69 66 65 74 69 6d 65 20 6f 66   the lifetime of
bc90: 20 74 68 65 20 72 65 74 75 72 6e 65 64 20 57 61   the returned Wa
bca0: 6c 2a 20 68 61 6e 64 6c 65 2e 0a 2a 2a 0a 2a 2a  l* handle..**.**
bcb0: 20 41 20 53 48 41 52 45 44 20 6c 6f 63 6b 20 73   A SHARED lock s
bcc0: 68 6f 75 6c 64 20 62 65 20 68 65 6c 64 20 6f 6e  hould be held on
bcd0: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
bce0: 6c 65 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e  le when this fun
bcf0: 63 74 69 6f 6e 0a 2a 2a 20 69 73 20 63 61 6c 6c  ction.** is call
bd00: 65 64 2e 20 54 68 65 20 70 75 72 70 6f 73 65 20  ed. The purpose 
bd10: 6f 66 20 74 68 69 73 20 53 48 41 52 45 44 20 6c  of this SHARED l
bd20: 6f 63 6b 20 69 73 20 74 6f 20 70 72 65 76 65 6e  ock is to preven
bd30: 74 20 61 6e 79 20 6f 74 68 65 72 0a 2a 2a 20 63  t any other.** c
bd40: 6c 69 65 6e 74 20 66 72 6f 6d 20 75 6e 6c 69 6e  lient from unlin
bd50: 6b 69 6e 67 20 74 68 65 20 57 41 4c 20 6f 72 20  king the WAL or 
bd60: 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 2e 20  wal-index file. 
bd70: 49 66 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65  If another proce
bd80: 73 73 0a 2a 2a 20 77 65 72 65 20 74 6f 20 64 6f  ss.** were to do
bd90: 20 74 68 69 73 20 6a 75 73 74 20 61 66 74 65 72   this just after
bda0: 20 74 68 69 73 20 63 6c 69 65 6e 74 20 6f 70 65   this client ope
bdb0: 6e 65 64 20 6f 6e 65 20 6f 66 20 74 68 65 73 65  ned one of these
bdc0: 20 66 69 6c 65 73 2c 20 74 68 65 0a 2a 2a 20 73   files, the.** s
bdd0: 79 73 74 65 6d 20 77 6f 75 6c 64 20 62 65 20 62  ystem would be b
bde0: 61 64 6c 79 20 62 72 6f 6b 65 6e 2e 0a 2a 2a 0a  adly broken..**.
bdf0: 2a 2a 20 49 66 20 74 68 65 20 6c 6f 67 20 66 69  ** If the log fi
be00: 6c 65 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  le is successful
be10: 6c 79 20 6f 70 65 6e 65 64 2c 20 53 51 4c 49 54  ly opened, SQLIT
be20: 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  E_OK is returned
be30: 20 61 6e 64 20 0a 2a 2a 20 2a 70 70 57 61 6c 20   and .** *ppWal 
be40: 69 73 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20  is set to point 
be50: 74 6f 20 61 20 6e 65 77 20 57 41 4c 20 68 61 6e  to a new WAL han
be60: 64 6c 65 2e 20 49 66 20 61 6e 20 65 72 72 6f 72  dle. If an error
be70: 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 61 6e 20 53   occurs,.** an S
be80: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
be90: 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64   is returned and
bea0: 20 2a 70 70 57 61 6c 20 69 73 20 6c 65 66 74 20   *ppWal is left 
beb0: 75 6e 6d 6f 64 69 66 69 65 64 2e 0a 2a 2f 0a 69  unmodified..*/.i
bec0: 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 4f 70 65  nt sqlite3WalOpe
bed0: 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  n(.  sqlite3_vfs
bee0: 20 2a 70 56 66 73 2c 20 20 20 20 20 20 20 20 20   *pVfs,         
bef0: 20 20 20 20 20 2f 2a 20 76 66 73 20 6d 6f 64 75       /* vfs modu
bf00: 6c 65 20 74 6f 20 6f 70 65 6e 20 77 61 6c 20 61  le to open wal a
bf10: 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a  nd wal-index */.
bf20: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
bf30: 70 44 62 46 64 2c 20 20 20 20 20 20 20 20 20 20  pDbFd,          
bf40: 20 20 2f 2a 20 54 68 65 20 6f 70 65 6e 20 64 61    /* The open da
bf50: 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20  tabase file */. 
bf60: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 57 61   const char *zWa
bf70: 6c 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20  lName,          
bf80: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20   /* Name of the 
bf90: 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e  WAL file */.  in
bfa0: 74 20 62 4e 6f 53 68 6d 2c 20 20 20 20 20 20 20  t bNoShm,       
bfb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
bfc0: 20 54 72 75 65 20 74 6f 20 72 75 6e 20 69 6e 20   True to run in 
bfd0: 68 65 61 70 2d 6d 65 6d 6f 72 79 20 6d 6f 64 65  heap-memory mode
bfe0: 20 2a 2f 0a 20 20 57 61 6c 20 2a 2a 70 70 57 61   */.  Wal **ppWa
bff0: 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l               
c000: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 41 6c        /* OUT: Al
c010: 6c 6f 63 61 74 65 64 20 57 61 6c 20 68 61 6e 64  located Wal hand
c020: 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  le */.){.  int r
c030: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
c040: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
c050: 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 57  turn Code */.  W
c060: 61 6c 20 2a 70 52 65 74 3b 20 20 20 20 20 20 20  al *pRet;       
c070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c080: 2a 20 4f 62 6a 65 63 74 20 74 6f 20 61 6c 6c 6f  * Object to allo
c090: 63 61 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20  cate and return 
c0a0: 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73 3b 20  */.  int flags; 
c0b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c0c0: 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 70 61       /* Flags pa
c0d0: 73 73 65 64 20 74 6f 20 4f 73 4f 70 65 6e 28 29  ssed to OsOpen()
c0e0: 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 7a   */..  assert( z
c0f0: 57 61 6c 4e 61 6d 65 20 26 26 20 7a 57 61 6c 4e  WalName && zWalN
c100: 61 6d 65 5b 30 5d 20 29 3b 0a 20 20 61 73 73 65  ame[0] );.  asse
c110: 72 74 28 20 70 44 62 46 64 20 29 3b 0a 0a 20 20  rt( pDbFd );..  
c120: 2f 2a 20 49 6e 20 74 68 65 20 61 6d 61 6c 67 61  /* In the amalga
c130: 6d 61 74 69 6f 6e 2c 20 74 68 65 20 6f 73 5f 75  mation, the os_u
c140: 6e 69 78 2e 63 20 61 6e 64 20 6f 73 5f 77 69 6e  nix.c and os_win
c150: 2e 63 20 73 6f 75 72 63 65 20 66 69 6c 65 73 20  .c source files 
c160: 63 6f 6d 65 20 62 65 66 6f 72 65 0a 20 20 2a 2a  come before.  **
c170: 20 74 68 69 73 20 73 6f 75 72 63 65 20 66 69 6c   this source fil
c180: 65 2e 20 20 56 65 72 69 66 79 20 74 68 61 74 20  e.  Verify that 
c190: 74 68 65 20 23 64 65 66 69 6e 65 73 20 6f 66 20  the #defines of 
c1a0: 74 68 65 20 6c 6f 63 6b 69 6e 67 20 62 79 74 65  the locking byte
c1b0: 20 6f 66 66 73 65 74 73 0a 20 20 2a 2a 20 69 6e   offsets.  ** in
c1c0: 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e 64 20 6f   os_unix.c and o
c1d0: 73 5f 77 69 6e 2e 63 20 61 67 72 65 65 20 77 69  s_win.c agree wi
c1e0: 74 68 20 74 68 65 20 57 41 4c 49 4e 44 45 58 5f  th the WALINDEX_
c1f0: 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 76 61 6c 75  LOCK_OFFSET valu
c200: 65 2e 0a 20 20 2a 2f 0a 23 69 66 64 65 66 20 57  e..  */.#ifdef W
c210: 49 4e 5f 53 48 4d 5f 42 41 53 45 0a 20 20 61 73  IN_SHM_BASE.  as
c220: 73 65 72 74 28 20 57 49 4e 5f 53 48 4d 5f 42 41  sert( WIN_SHM_BA
c230: 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f 43  SE==WALINDEX_LOC
c240: 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65 6e 64  K_OFFSET );.#end
c250: 69 66 0a 23 69 66 64 65 66 20 55 4e 49 58 5f 53  if.#ifdef UNIX_S
c260: 48 4d 5f 42 41 53 45 0a 20 20 61 73 73 65 72 74  HM_BASE.  assert
c270: 28 20 55 4e 49 58 5f 53 48 4d 5f 42 41 53 45 3d  ( UNIX_SHM_BASE=
c280: 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f  =WALINDEX_LOCK_O
c290: 46 46 53 45 54 20 29 3b 0a 23 65 6e 64 69 66 0a  FFSET );.#endif.
c2a0: 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20  ..  /* Allocate 
c2b0: 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 73  an instance of s
c2c0: 74 72 75 63 74 20 57 61 6c 20 74 6f 20 72 65 74  truct Wal to ret
c2d0: 75 72 6e 2e 20 2a 2f 0a 20 20 2a 70 70 57 61 6c  urn. */.  *ppWal
c2e0: 20 3d 20 30 3b 0a 20 20 70 52 65 74 20 3d 20 28   = 0;.  pRet = (
c2f0: 57 61 6c 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c  Wal*)sqlite3Mall
c300: 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 57 61  ocZero(sizeof(Wa
c310: 6c 29 20 2b 20 70 56 66 73 2d 3e 73 7a 4f 73 46  l) + pVfs->szOsF
c320: 69 6c 65 29 3b 0a 20 20 69 66 28 20 21 70 52 65  ile);.  if( !pRe
c330: 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  t ){.    return 
c340: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
c350: 7d 0a 0a 20 20 70 52 65 74 2d 3e 70 56 66 73 20  }..  pRet->pVfs 
c360: 3d 20 70 56 66 73 3b 0a 20 20 70 52 65 74 2d 3e  = pVfs;.  pRet->
c370: 70 57 61 6c 46 64 20 3d 20 28 73 71 6c 69 74 65  pWalFd = (sqlite
c380: 33 5f 66 69 6c 65 20 2a 29 26 70 52 65 74 5b 31  3_file *)&pRet[1
c390: 5d 3b 0a 20 20 70 52 65 74 2d 3e 70 44 62 46 64  ];.  pRet->pDbFd
c3a0: 20 3d 20 70 44 62 46 64 3b 0a 20 20 70 52 65 74   = pDbFd;.  pRet
c3b0: 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31 3b  ->readLock = -1;
c3c0: 0a 20 20 70 52 65 74 2d 3e 7a 57 61 6c 4e 61 6d  .  pRet->zWalNam
c3d0: 65 20 3d 20 7a 57 61 6c 4e 61 6d 65 3b 0a 20 20  e = zWalName;.  
c3e0: 70 52 65 74 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pRet->exclusiveM
c3f0: 6f 64 65 20 3d 20 28 62 4e 6f 53 68 6d 20 3f 20  ode = (bNoShm ? 
c400: 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d  WAL_HEAPMEMORY_M
c410: 4f 44 45 3a 20 57 41 4c 5f 4e 4f 52 4d 41 4c 5f  ODE: WAL_NORMAL_
c420: 4d 4f 44 45 29 3b 0a 0a 20 20 2f 2a 20 4f 70 65  MODE);..  /* Ope
c430: 6e 20 66 69 6c 65 20 68 61 6e 64 6c 65 20 6f 6e  n file handle on
c440: 20 74 68 65 20 77 72 69 74 65 2d 61 68 65 61 64   the write-ahead
c450: 20 6c 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20   log file. */.  
c460: 66 6c 61 67 73 20 3d 20 28 53 51 4c 49 54 45 5f  flags = (SQLITE_
c470: 4f 50 45 4e 5f 52 45 41 44 57 52 49 54 45 7c 53  OPEN_READWRITE|S
c480: 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54  QLITE_OPEN_CREAT
c490: 45 7c 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 57 41  E|SQLITE_OPEN_WA
c4a0: 4c 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  L);.  rc = sqlit
c4b0: 65 33 4f 73 4f 70 65 6e 28 70 56 66 73 2c 20 7a  e3OsOpen(pVfs, z
c4c0: 57 61 6c 4e 61 6d 65 2c 20 70 52 65 74 2d 3e 70  WalName, pRet->p
c4d0: 57 61 6c 46 64 2c 20 66 6c 61 67 73 2c 20 26 66  WalFd, flags, &f
c4e0: 6c 61 67 73 29 3b 0a 20 20 69 66 28 20 72 63 3d  lags);.  if( rc=
c4f0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 66 6c  =SQLITE_OK && fl
c500: 61 67 73 26 53 51 4c 49 54 45 5f 4f 50 45 4e 5f  ags&SQLITE_OPEN_
c510: 52 45 41 44 4f 4e 4c 59 20 29 7b 0a 20 20 20 20  READONLY ){.    
c520: 70 52 65 74 2d 3e 72 65 61 64 4f 6e 6c 79 20 3d  pRet->readOnly =
c530: 20 31 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72   1;.  }..  if( r
c540: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
c550: 20 20 20 20 77 61 6c 49 6e 64 65 78 43 6c 6f 73      walIndexClos
c560: 65 28 70 52 65 74 2c 20 30 29 3b 0a 20 20 20 20  e(pRet, 0);.    
c570: 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 28 70  sqlite3OsClose(p
c580: 52 65 74 2d 3e 70 57 61 6c 46 64 29 3b 0a 20 20  Ret->pWalFd);.  
c590: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
c5a0: 52 65 74 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Ret);.  }else{. 
c5b0: 20 20 20 2a 70 70 57 61 6c 20 3d 20 70 52 65 74     *ppWal = pRet
c5c0: 3b 0a 20 20 20 20 57 41 4c 54 52 41 43 45 28 28  ;.    WALTRACE((
c5d0: 22 57 41 4c 25 64 3a 20 6f 70 65 6e 65 64 5c 6e  "WAL%d: opened\n
c5e0: 22 2c 20 70 52 65 74 29 29 3b 0a 20 20 7d 0a 20  ", pRet));.  }. 
c5f0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
c600: 2a 0a 2a 2a 20 46 69 6e 64 20 74 68 65 20 73 6d  *.** Find the sm
c610: 61 6c 6c 65 73 74 20 70 61 67 65 20 6e 75 6d 62  allest page numb
c620: 65 72 20 6f 75 74 20 6f 66 20 61 6c 6c 20 70 61  er out of all pa
c630: 67 65 73 20 68 65 6c 64 20 69 6e 20 74 68 65 20  ges held in the 
c640: 57 41 4c 20 74 68 61 74 0a 2a 2a 20 68 61 73 20  WAL that.** has 
c650: 6e 6f 74 20 62 65 65 6e 20 72 65 74 75 72 6e 65  not been returne
c660: 64 20 62 79 20 61 6e 79 20 70 72 69 6f 72 20 69  d by any prior i
c670: 6e 76 6f 63 61 74 69 6f 6e 20 6f 66 20 74 68 69  nvocation of thi
c680: 73 20 6d 65 74 68 6f 64 20 6f 6e 20 74 68 65 0a  s method on the.
c690: 2a 2a 20 73 61 6d 65 20 57 61 6c 49 74 65 72 61  ** same WalItera
c6a0: 74 6f 72 20 6f 62 6a 65 63 74 2e 20 20 20 57 72  tor object.   Wr
c6b0: 69 74 65 20 69 6e 74 6f 20 2a 70 69 46 72 61 6d  ite into *piFram
c6c0: 65 20 74 68 65 20 66 72 61 6d 65 20 69 6e 64 65  e the frame inde
c6d0: 78 20 77 68 65 72 65 0a 2a 2a 20 74 68 61 74 20  x where.** that 
c6e0: 70 61 67 65 20 77 61 73 20 6c 61 73 74 20 77 72  page was last wr
c6f0: 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65 20 57  itten into the W
c700: 41 4c 2e 20 20 57 72 69 74 65 20 69 6e 74 6f 20  AL.  Write into 
c710: 2a 70 69 50 61 67 65 20 74 68 65 20 70 61 67 65  *piPage the page
c720: 0a 2a 2a 20 6e 75 6d 62 65 72 2e 0a 2a 2a 0a 2a  .** number..**.*
c730: 2a 20 52 65 74 75 72 6e 20 30 20 6f 6e 20 73 75  * Return 0 on su
c740: 63 63 65 73 73 2e 20 20 49 66 20 74 68 65 72 65  ccess.  If there
c750: 20 61 72 65 20 6e 6f 20 70 61 67 65 73 20 69 6e   are no pages in
c760: 20 74 68 65 20 57 41 4c 20 77 69 74 68 20 61 20   the WAL with a 
c770: 70 61 67 65 0a 2a 2a 20 6e 75 6d 62 65 72 20 6c  page.** number l
c780: 61 72 67 65 72 20 74 68 61 6e 20 2a 70 69 50 61  arger than *piPa
c790: 67 65 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20  ge, then return 
c7a0: 31 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  1..*/.static int
c7b0: 20 77 61 6c 49 74 65 72 61 74 6f 72 4e 65 78 74   walIteratorNext
c7c0: 28 0a 20 20 57 61 6c 49 74 65 72 61 74 6f 72 20  (.  WalIterator 
c7d0: 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  *p,             
c7e0: 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 2a 2f    /* Iterator */
c7f0: 0a 20 20 75 33 32 20 2a 70 69 50 61 67 65 2c 20  .  u32 *piPage, 
c800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c810: 20 2f 2a 20 4f 55 54 3a 20 54 68 65 20 70 61 67   /* OUT: The pag
c820: 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20  e number of the 
c830: 6e 65 78 74 20 70 61 67 65 20 2a 2f 0a 20 20 75  next page */.  u
c840: 33 32 20 2a 70 69 46 72 61 6d 65 20 20 20 20 20  32 *piFrame     
c850: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c860: 4f 55 54 3a 20 57 61 6c 20 66 72 61 6d 65 20 69  OUT: Wal frame i
c870: 6e 64 65 78 20 6f 66 20 6e 65 78 74 20 70 61 67  ndex of next pag
c880: 65 20 2a 2f 0a 29 7b 0a 20 20 75 33 32 20 69 4d  e */.){.  u32 iM
c890: 69 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  in;             
c8a0: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c          /* Resul
c8b0: 74 20 70 67 6e 6f 20 6d 75 73 74 20 62 65 20 67  t pgno must be g
c8c0: 72 65 61 74 65 72 20 74 68 61 6e 20 69 4d 69 6e  reater than iMin
c8d0: 20 2a 2f 0a 20 20 75 33 32 20 69 52 65 74 20 3d   */.  u32 iRet =
c8e0: 20 30 78 46 46 46 46 46 46 46 46 3b 20 20 20 20   0xFFFFFFFF;    
c8f0: 20 20 20 20 2f 2a 20 30 78 66 66 66 66 66 66 66      /* 0xfffffff
c900: 66 20 69 73 20 6e 65 76 65 72 20 61 20 76 61 6c  f is never a val
c910: 69 64 20 70 61 67 65 20 6e 75 6d 62 65 72 20 2a  id page number *
c920: 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20  /.  int i;      
c930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c940: 20 20 2f 2a 20 46 6f 72 20 6c 6f 6f 70 69 6e 67    /* For looping
c950: 20 74 68 72 6f 75 67 68 20 73 65 67 6d 65 6e 74   through segment
c960: 73 20 2a 2f 0a 0a 20 20 69 4d 69 6e 20 3d 20 70  s */..  iMin = p
c970: 2d 3e 69 50 72 69 6f 72 3b 0a 20 20 61 73 73 65  ->iPrior;.  asse
c980: 72 74 28 20 69 4d 69 6e 3c 30 78 66 66 66 66 66  rt( iMin<0xfffff
c990: 66 66 66 20 29 3b 0a 20 20 66 6f 72 28 69 3d 70  fff );.  for(i=p
c9a0: 2d 3e 6e 53 65 67 6d 65 6e 74 2d 31 3b 20 69 3e  ->nSegment-1; i>
c9b0: 3d 30 3b 20 69 2d 2d 29 7b 0a 20 20 20 20 73 74  =0; i--){.    st
c9c0: 72 75 63 74 20 57 61 6c 53 65 67 6d 65 6e 74 20  ruct WalSegment 
c9d0: 2a 70 53 65 67 6d 65 6e 74 20 3d 20 26 70 2d 3e  *pSegment = &p->
c9e0: 61 53 65 67 6d 65 6e 74 5b 69 5d 3b 0a 20 20 20  aSegment[i];.   
c9f0: 20 77 68 69 6c 65 28 20 70 53 65 67 6d 65 6e 74   while( pSegment
ca00: 2d 3e 69 4e 65 78 74 3c 70 53 65 67 6d 65 6e 74  ->iNext<pSegment
ca10: 2d 3e 6e 45 6e 74 72 79 20 29 7b 0a 20 20 20 20  ->nEntry ){.    
ca20: 20 20 75 33 32 20 69 50 67 20 3d 20 70 53 65 67    u32 iPg = pSeg
ca30: 6d 65 6e 74 2d 3e 61 50 67 6e 6f 5b 70 53 65 67  ment->aPgno[pSeg
ca40: 6d 65 6e 74 2d 3e 61 49 6e 64 65 78 5b 70 53 65  ment->aIndex[pSe
ca50: 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 5d 5d 3b 0a  gment->iNext]];.
ca60: 20 20 20 20 20 20 69 66 28 20 69 50 67 3e 69 4d        if( iPg>iM
ca70: 69 6e 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  in ){.        if
ca80: 28 20 69 50 67 3c 69 52 65 74 20 29 7b 0a 20 20  ( iPg<iRet ){.  
ca90: 20 20 20 20 20 20 20 20 69 52 65 74 20 3d 20 69          iRet = i
caa0: 50 67 3b 0a 20 20 20 20 20 20 20 20 20 20 2a 70  Pg;.          *p
cab0: 69 46 72 61 6d 65 20 3d 20 70 53 65 67 6d 65 6e  iFrame = pSegmen
cac0: 74 2d 3e 69 5a 65 72 6f 20 2b 20 70 53 65 67 6d  t->iZero + pSegm
cad0: 65 6e 74 2d 3e 61 49 6e 64 65 78 5b 70 53 65 67  ent->aIndex[pSeg
cae0: 6d 65 6e 74 2d 3e 69 4e 65 78 74 5d 3b 0a 20 20  ment->iNext];.  
caf0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
cb00: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
cb10: 20 20 20 20 20 70 53 65 67 6d 65 6e 74 2d 3e 69       pSegment->i
cb20: 4e 65 78 74 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20  Next++;.    }.  
cb30: 7d 0a 0a 20 20 2a 70 69 50 61 67 65 20 3d 20 70  }..  *piPage = p
cb40: 2d 3e 69 50 72 69 6f 72 20 3d 20 69 52 65 74 3b  ->iPrior = iRet;
cb50: 0a 20 20 72 65 74 75 72 6e 20 28 69 52 65 74 3d  .  return (iRet=
cb60: 3d 30 78 46 46 46 46 46 46 46 46 29 3b 0a 7d 0a  =0xFFFFFFFF);.}.
cb70: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
cb80: 74 69 6f 6e 20 6d 65 72 67 65 73 20 74 77 6f 20  tion merges two 
cb90: 73 6f 72 74 65 64 20 6c 69 73 74 73 20 69 6e 74  sorted lists int
cba0: 6f 20 61 20 73 69 6e 67 6c 65 20 73 6f 72 74 65  o a single sorte
cbb0: 64 20 6c 69 73 74 2e 0a 2a 2a 0a 2a 2a 20 61 4c  d list..**.** aL
cbc0: 65 66 74 5b 5d 20 61 6e 64 20 61 52 69 67 68 74  eft[] and aRight
cbd0: 5b 5d 20 61 72 65 20 61 72 72 61 79 73 20 6f 66  [] are arrays of
cbe0: 20 69 6e 64 69 63 65 73 2e 20 20 54 68 65 20 73   indices.  The s
cbf0: 6f 72 74 20 6b 65 79 20 69 73 0a 2a 2a 20 61 43  ort key is.** aC
cc00: 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 5d 5d 20  ontent[aLeft[]] 
cc10: 61 6e 64 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69  and aContent[aRi
cc20: 67 68 74 5b 5d 5d 2e 20 20 55 70 6f 6e 20 65 6e  ght[]].  Upon en
cc30: 74 72 79 2c 20 74 68 65 20 66 6f 6c 6c 6f 77 69  try, the followi
cc40: 6e 67 0a 2a 2a 20 69 73 20 67 75 61 72 61 6e 74  ng.** is guarant
cc50: 65 65 64 20 66 6f 72 20 61 6c 6c 20 4a 3c 4b 3a  eed for all J<K:
cc60: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 20 61 43  .**.**        aC
cc70: 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 4a 5d 5d  ontent[aLeft[J]]
cc80: 20 3c 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66   < aContent[aLef
cc90: 74 5b 4b 5d 5d 0a 2a 2a 20 20 20 20 20 20 20 20  t[K]].**        
cca0: 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b  aContent[aRight[
ccb0: 4a 5d 5d 20 3c 20 61 43 6f 6e 74 65 6e 74 5b 61  J]] < aContent[a
ccc0: 52 69 67 68 74 5b 4b 5d 5d 0a 2a 2a 0a 2a 2a 20  Right[K]].**.** 
ccd0: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 6f 76 65  This routine ove
cce0: 72 77 72 69 74 65 73 20 61 52 69 67 68 74 5b 5d  rwrites aRight[]
ccf0: 20 77 69 74 68 20 61 20 6e 65 77 20 28 70 72 6f   with a new (pro
cd00: 62 61 62 6c 79 20 6c 6f 6e 67 65 72 29 20 73 65  bably longer) se
cd10: 71 75 65 6e 63 65 0a 2a 2a 20 6f 66 20 69 6e 64  quence.** of ind
cd20: 69 63 65 73 20 73 75 63 68 20 74 68 61 74 20 74  ices such that t
cd30: 68 65 20 61 52 69 67 68 74 5b 5d 20 63 6f 6e 74  he aRight[] cont
cd40: 61 69 6e 73 20 65 76 65 72 79 20 69 6e 64 65 78  ains every index
cd50: 20 74 68 61 74 20 61 70 70 65 61 72 73 20 69 6e   that appears in
cd60: 0a 2a 2a 20 65 69 74 68 65 72 20 61 4c 65 66 74  .** either aLeft
cd70: 5b 5d 20 6f 72 20 74 68 65 20 6f 6c 64 20 61 52  [] or the old aR
cd80: 69 67 68 74 5b 5d 20 61 6e 64 20 73 75 63 68 20  ight[] and such 
cd90: 74 68 61 74 20 74 68 65 20 73 65 63 6f 6e 64 20  that the second 
cda0: 63 6f 6e 64 69 74 69 6f 6e 0a 2a 2a 20 61 62 6f  condition.** abo
cdb0: 76 65 20 69 73 20 73 74 69 6c 6c 20 6d 65 74 2e  ve is still met.
cdc0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 43 6f 6e 74  .**.** The aCont
cdd0: 65 6e 74 5b 61 4c 65 66 74 5b 58 5d 5d 20 76 61  ent[aLeft[X]] va
cde0: 6c 75 65 73 20 77 69 6c 6c 20 62 65 20 75 6e 69  lues will be uni
cdf0: 71 75 65 20 66 6f 72 20 61 6c 6c 20 58 2e 20 20  que for all X.  
ce00: 41 6e 64 20 74 68 65 0a 2a 2a 20 61 43 6f 6e 74  And the.** aCont
ce10: 65 6e 74 5b 61 52 69 67 68 74 5b 58 5d 5d 20 76  ent[aRight[X]] v
ce20: 61 6c 75 65 73 20 77 69 6c 6c 20 62 65 20 75 6e  alues will be un
ce30: 69 71 75 65 20 74 6f 6f 2e 20 20 42 75 74 20 74  ique too.  But t
ce40: 68 65 72 65 20 6d 69 67 68 74 20 62 65 0a 2a 2a  here might be.**
ce50: 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 63 6f 6d   one or more com
ce60: 62 69 6e 61 74 69 6f 6e 73 20 6f 66 20 58 20 61  binations of X a
ce70: 6e 64 20 59 20 73 75 63 68 20 74 68 61 74 0a 2a  nd Y such that.*
ce80: 2a 0a 2a 2a 20 20 20 20 20 20 61 4c 65 66 74 5b  *.**      aLeft[
ce90: 58 5d 21 3d 61 52 69 67 68 74 5b 59 5d 20 20 26  X]!=aRight[Y]  &
cea0: 26 20 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66  &  aContent[aLef
ceb0: 74 5b 58 5d 5d 20 3d 3d 20 61 43 6f 6e 74 65 6e  t[X]] == aConten
cec0: 74 5b 61 52 69 67 68 74 5b 59 5d 5d 0a 2a 2a 0a  t[aRight[Y]].**.
ced0: 2a 2a 20 57 68 65 6e 20 74 68 61 74 20 68 61 70  ** When that hap
cee0: 70 65 6e 73 2c 20 6f 6d 69 74 20 74 68 65 20 61  pens, omit the a
cef0: 4c 65 66 74 5b 58 5d 20 61 6e 64 20 75 73 65 20  Left[X] and use 
cf00: 74 68 65 20 61 52 69 67 68 74 5b 59 5d 20 69 6e  the aRight[Y] in
cf10: 64 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  dex..*/.static v
cf20: 6f 69 64 20 77 61 6c 4d 65 72 67 65 28 0a 20 20  oid walMerge(.  
cf30: 63 6f 6e 73 74 20 75 33 32 20 2a 61 43 6f 6e 74  const u32 *aCont
cf40: 65 6e 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  ent,            
cf50: 2f 2a 20 50 61 67 65 73 20 69 6e 20 77 61 6c 20  /* Pages in wal 
cf60: 2d 20 6b 65 79 73 20 66 6f 72 20 74 68 65 20 73  - keys for the s
cf70: 6f 72 74 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74  ort */.  ht_slot
cf80: 20 2a 61 4c 65 66 74 2c 20 20 20 20 20 20 20 20   *aLeft,        
cf90: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 3a 20           /* IN: 
cfa0: 4c 65 66 74 20 68 61 6e 64 20 69 6e 70 75 74 20  Left hand input 
cfb0: 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c  list */.  int nL
cfc0: 65 66 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  eft,            
cfd0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 3a            /* IN:
cfe0: 20 45 6c 65 6d 65 6e 74 73 20 69 6e 20 61 72 72   Elements in arr
cff0: 61 79 20 2a 70 61 4c 65 66 74 20 2a 2f 0a 20 20  ay *paLeft */.  
d000: 68 74 5f 73 6c 6f 74 20 2a 2a 70 61 52 69 67 68  ht_slot **paRigh
d010: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
d020: 2f 2a 20 49 4e 2f 4f 55 54 3a 20 52 69 67 68 74  /* IN/OUT: Right
d030: 20 68 61 6e 64 20 69 6e 70 75 74 20 6c 69 73 74   hand input list
d040: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 52 69 67   */.  int *pnRig
d050: 68 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ht,             
d060: 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a        /* IN/OUT:
d070: 20 45 6c 65 6d 65 6e 74 73 20 69 6e 20 2a 70 61   Elements in *pa
d080: 52 69 67 68 74 20 2a 2f 0a 20 20 68 74 5f 73 6c  Right */.  ht_sl
d090: 6f 74 20 2a 61 54 6d 70 20 20 20 20 20 20 20 20  ot *aTmp        
d0a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 65             /* Te
d0b0: 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72 20 2a  mporary buffer *
d0c0: 2f 0a 29 7b 0a 20 20 69 6e 74 20 69 4c 65 66 74  /.){.  int iLeft
d0d0: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
d0e0: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
d0f0: 74 20 69 6e 64 65 78 20 69 6e 20 61 4c 65 66 74  t index in aLeft
d100: 20 2a 2f 0a 20 20 69 6e 74 20 69 52 69 67 68 74   */.  int iRight
d110: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
d120: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
d130: 20 69 6e 64 65 78 20 69 6e 20 61 52 69 67 68 74   index in aRight
d140: 20 2a 2f 0a 20 20 69 6e 74 20 69 4f 75 74 20 3d   */.  int iOut =
d150: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
d160: 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74        /* Current
d170: 20 69 6e 64 65 78 20 69 6e 20 6f 75 74 70 75 74   index in output
d180: 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74   buffer */.  int
d190: 20 6e 52 69 67 68 74 20 3d 20 2a 70 6e 52 69 67   nRight = *pnRig
d1a0: 68 74 3b 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61  ht;.  ht_slot *a
d1b0: 52 69 67 68 74 20 3d 20 2a 70 61 52 69 67 68 74  Right = *paRight
d1c0: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 4c 65  ;..  assert( nLe
d1d0: 66 74 3e 30 20 26 26 20 6e 52 69 67 68 74 3e 30  ft>0 && nRight>0
d1e0: 20 29 3b 0a 20 20 77 68 69 6c 65 28 20 69 52 69   );.  while( iRi
d1f0: 67 68 74 3c 6e 52 69 67 68 74 20 7c 7c 20 69 4c  ght<nRight || iL
d200: 65 66 74 3c 6e 4c 65 66 74 20 29 7b 0a 20 20 20  eft<nLeft ){.   
d210: 20 68 74 5f 73 6c 6f 74 20 6c 6f 67 70 61 67 65   ht_slot logpage
d220: 3b 0a 20 20 20 20 50 67 6e 6f 20 64 62 70 61 67  ;.    Pgno dbpag
d230: 65 3b 0a 0a 20 20 20 20 69 66 28 20 28 69 4c 65  e;..    if( (iLe
d240: 66 74 3c 6e 4c 65 66 74 29 20 0a 20 20 20 20 20  ft<nLeft) .     
d250: 26 26 20 28 69 52 69 67 68 74 3e 3d 6e 52 69 67  && (iRight>=nRig
d260: 68 74 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61  ht || aContent[a
d270: 4c 65 66 74 5b 69 4c 65 66 74 5d 5d 3c 61 43 6f  Left[iLeft]]<aCo
d280: 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b 69 52 69  ntent[aRight[iRi
d290: 67 68 74 5d 5d 29 0a 20 20 20 20 29 7b 0a 20 20  ght]]).    ){.  
d2a0: 20 20 20 20 6c 6f 67 70 61 67 65 20 3d 20 61 4c      logpage = aL
d2b0: 65 66 74 5b 69 4c 65 66 74 2b 2b 5d 3b 0a 20 20  eft[iLeft++];.  
d2c0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6c    }else{.      l
d2d0: 6f 67 70 61 67 65 20 3d 20 61 52 69 67 68 74 5b  ogpage = aRight[
d2e0: 69 52 69 67 68 74 2b 2b 5d 3b 0a 20 20 20 20 7d  iRight++];.    }
d2f0: 0a 20 20 20 20 64 62 70 61 67 65 20 3d 20 61 43  .    dbpage = aC
d300: 6f 6e 74 65 6e 74 5b 6c 6f 67 70 61 67 65 5d 3b  ontent[logpage];
d310: 0a 0a 20 20 20 20 61 54 6d 70 5b 69 4f 75 74 2b  ..    aTmp[iOut+
d320: 2b 5d 20 3d 20 6c 6f 67 70 61 67 65 3b 0a 20 20  +] = logpage;.  
d330: 20 20 69 66 28 20 69 4c 65 66 74 3c 6e 4c 65 66    if( iLeft<nLef
d340: 74 20 26 26 20 61 43 6f 6e 74 65 6e 74 5b 61 4c  t && aContent[aL
d350: 65 66 74 5b 69 4c 65 66 74 5d 5d 3d 3d 64 62 70  eft[iLeft]]==dbp
d360: 61 67 65 20 29 20 69 4c 65 66 74 2b 2b 3b 0a 0a  age ) iLeft++;..
d370: 20 20 20 20 61 73 73 65 72 74 28 20 69 4c 65 66      assert( iLef
d380: 74 3e 3d 6e 4c 65 66 74 20 7c 7c 20 61 43 6f 6e  t>=nLeft || aCon
d390: 74 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74  tent[aLeft[iLeft
d3a0: 5d 5d 3e 64 62 70 61 67 65 20 29 3b 0a 20 20 20  ]]>dbpage );.   
d3b0: 20 61 73 73 65 72 74 28 20 69 52 69 67 68 74 3e   assert( iRight>
d3c0: 3d 6e 52 69 67 68 74 20 7c 7c 20 61 43 6f 6e 74  =nRight || aCont
d3d0: 65 6e 74 5b 61 52 69 67 68 74 5b 69 52 69 67 68  ent[aRight[iRigh
d3e0: 74 5d 5d 3e 64 62 70 61 67 65 20 29 3b 0a 20 20  t]]>dbpage );.  
d3f0: 7d 0a 0a 20 20 2a 70 61 52 69 67 68 74 20 3d 20  }..  *paRight = 
d400: 61 4c 65 66 74 3b 0a 20 20 2a 70 6e 52 69 67 68  aLeft;.  *pnRigh
d410: 74 20 3d 20 69 4f 75 74 3b 0a 20 20 6d 65 6d 63  t = iOut;.  memc
d420: 70 79 28 61 4c 65 66 74 2c 20 61 54 6d 70 2c 20  py(aLeft, aTmp, 
d430: 73 69 7a 65 6f 66 28 61 54 6d 70 5b 30 5d 29 2a  sizeof(aTmp[0])*
d440: 69 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  iOut);.}../*.** 
d450: 53 6f 72 74 20 74 68 65 20 65 6c 65 6d 65 6e 74  Sort the element
d460: 73 20 69 6e 20 6c 69 73 74 20 61 4c 69 73 74 20  s in list aList 
d470: 75 73 69 6e 67 20 61 43 6f 6e 74 65 6e 74 5b 5d  using aContent[]
d480: 20 61 73 20 74 68 65 20 73 6f 72 74 20 6b 65 79   as the sort key
d490: 2e 0a 2a 2a 20 52 65 6d 6f 76 65 20 65 6c 65 6d  ..** Remove elem
d4a0: 65 6e 74 73 20 77 69 74 68 20 64 75 70 6c 69 63  ents with duplic
d4b0: 61 74 65 20 6b 65 79 73 2c 20 70 72 65 66 65 72  ate keys, prefer
d4c0: 72 69 6e 67 20 74 6f 20 6b 65 65 70 20 74 68 65  ring to keep the
d4d0: 0a 2a 2a 20 6c 61 72 67 65 72 20 61 4c 69 73 74  .** larger aList
d4e0: 5b 5d 20 76 61 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a  [] values..**.**
d4f0: 20 54 68 65 20 61 4c 69 73 74 5b 5d 20 65 6e 74   The aList[] ent
d500: 72 69 65 73 20 61 72 65 20 69 6e 64 69 63 65 73  ries are indices
d510: 20 69 6e 74 6f 20 61 43 6f 6e 74 65 6e 74 5b 5d   into aContent[]
d520: 2e 20 20 54 68 65 20 76 61 6c 75 65 73 20 69 6e  .  The values in
d530: 0a 2a 2a 20 61 4c 69 73 74 5b 5d 20 61 72 65 20  .** aList[] are 
d540: 74 6f 20 62 65 20 73 6f 72 74 65 64 20 73 6f 20  to be sorted so 
d550: 74 68 61 74 20 66 6f 72 20 61 6c 6c 20 4a 3c 4b  that for all J<K
d560: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 61 43 6f  :.**.**      aCo
d570: 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 4a 5d 5d 20  ntent[aList[J]] 
d580: 3c 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74  < aContent[aList
d590: 5b 4b 5d 5d 0a 2a 2a 0a 2a 2a 20 46 6f 72 20 61  [K]].**.** For a
d5a0: 6e 79 20 58 20 61 6e 64 20 59 20 73 75 63 68 20  ny X and Y such 
d5b0: 74 68 61 74 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  that.**.**      
d5c0: 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 58  aContent[aList[X
d5d0: 5d 5d 20 3d 3d 20 61 43 6f 6e 74 65 6e 74 5b 61  ]] == aContent[a
d5e0: 4c 69 73 74 5b 59 5d 5d 0a 2a 2a 0a 2a 2a 20 4b  List[Y]].**.** K
d5f0: 65 65 70 20 74 68 65 20 6c 61 72 67 65 72 20 6f  eep the larger o
d600: 66 20 74 68 65 20 74 77 6f 20 76 61 6c 75 65 73  f the two values
d610: 20 61 4c 69 73 74 5b 58 5d 20 61 6e 64 20 61 4c   aList[X] and aL
d620: 69 73 74 5b 59 5d 20 61 6e 64 20 64 69 73 63 61  ist[Y] and disca
d630: 72 64 0a 2a 2a 20 74 68 65 20 73 6d 61 6c 6c 65  rd.** the smalle
d640: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  r..*/.static voi
d650: 64 20 77 61 6c 4d 65 72 67 65 73 6f 72 74 28 0a  d walMergesort(.
d660: 20 20 63 6f 6e 73 74 20 75 33 32 20 2a 61 43 6f    const u32 *aCo
d670: 6e 74 65 6e 74 2c 20 20 20 20 20 20 20 20 20 20  ntent,          
d680: 20 20 2f 2a 20 50 61 67 65 73 20 69 6e 20 77 61    /* Pages in wa
d690: 6c 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a  l */.  ht_slot *
d6a0: 61 42 75 66 66 65 72 2c 20 20 20 20 20 20 20 20  aBuffer,        
d6b0: 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72         /* Buffer
d6c0: 20 6f 66 20 61 74 20 6c 65 61 73 74 20 2a 70 6e   of at least *pn
d6d0: 4c 69 73 74 20 69 74 65 6d 73 20 74 6f 20 75 73  List items to us
d6e0: 65 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a  e */.  ht_slot *
d6f0: 61 4c 69 73 74 2c 20 20 20 20 20 20 20 20 20 20  aList,          
d700: 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54         /* IN/OUT
d710: 3a 20 4c 69 73 74 20 74 6f 20 73 6f 72 74 20 2a  : List to sort *
d720: 2f 0a 20 20 69 6e 74 20 2a 70 6e 4c 69 73 74 20  /.  int *pnList 
d730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d740: 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4e      /* IN/OUT: N
d750: 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74  umber of element
d760: 73 20 69 6e 20 61 4c 69 73 74 5b 5d 20 2a 2f 0a  s in aList[] */.
d770: 29 7b 0a 20 20 73 74 72 75 63 74 20 53 75 62 6c  ){.  struct Subl
d780: 69 73 74 20 7b 0a 20 20 20 20 69 6e 74 20 6e 4c  ist {.    int nL
d790: 69 73 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ist;            
d7a0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
d7b0: 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e  r of elements in
d7c0: 20 61 4c 69 73 74 20 2a 2f 0a 20 20 20 20 68 74   aList */.    ht
d7d0: 5f 73 6c 6f 74 20 2a 61 4c 69 73 74 3b 20 20 20  _slot *aList;   
d7e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
d7f0: 6f 69 6e 74 65 72 20 74 6f 20 73 75 62 2d 6c 69  ointer to sub-li
d800: 73 74 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20  st content */.  
d810: 7d 3b 0a 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20  };..  const int 
d820: 6e 4c 69 73 74 20 3d 20 2a 70 6e 4c 69 73 74 3b  nList = *pnList;
d830: 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66        /* Size of
d840: 20 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20   input list */. 
d850: 20 69 6e 74 20 6e 4d 65 72 67 65 20 3d 20 30 3b   int nMerge = 0;
d860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d870: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c   /* Number of el
d880: 65 6d 65 6e 74 73 20 69 6e 20 6c 69 73 74 20 61  ements in list a
d890: 4d 65 72 67 65 20 2a 2f 0a 20 20 68 74 5f 73 6c  Merge */.  ht_sl
d8a0: 6f 74 20 2a 61 4d 65 72 67 65 20 3d 20 30 3b 20  ot *aMerge = 0; 
d8b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69             /* Li
d8c0: 73 74 20 74 6f 20 62 65 20 6d 65 72 67 65 64 20  st to be merged 
d8d0: 2a 2f 0a 20 20 69 6e 74 20 69 4c 69 73 74 3b 20  */.  int iList; 
d8e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d8f0: 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 69 6e       /* Index in
d900: 74 6f 20 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f  to input list */
d910: 0a 20 20 69 6e 74 20 69 53 75 62 20 3d 20 30 3b  .  int iSub = 0;
d920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d930: 20 20 20 2f 2a 20 49 6e 64 65 78 20 69 6e 74 6f     /* Index into
d940: 20 61 53 75 62 20 61 72 72 61 79 20 2a 2f 0a 20   aSub array */. 
d950: 20 73 74 72 75 63 74 20 53 75 62 6c 69 73 74 20   struct Sublist 
d960: 61 53 75 62 5b 31 33 5d 3b 20 20 20 20 20 20 20  aSub[13];       
d970: 20 2f 2a 20 41 72 72 61 79 20 6f 66 20 73 75 62   /* Array of sub
d980: 2d 6c 69 73 74 73 20 2a 2f 0a 0a 20 20 6d 65 6d  -lists */..  mem
d990: 73 65 74 28 61 53 75 62 2c 20 30 2c 20 73 69 7a  set(aSub, 0, siz
d9a0: 65 6f 66 28 61 53 75 62 29 29 3b 0a 20 20 61 73  eof(aSub));.  as
d9b0: 73 65 72 74 28 20 6e 4c 69 73 74 3c 3d 48 41 53  sert( nList<=HAS
d9c0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 26 26 20  HTABLE_NPAGE && 
d9d0: 6e 4c 69 73 74 3e 30 20 29 3b 0a 20 20 61 73 73  nList>0 );.  ass
d9e0: 65 72 74 28 20 48 41 53 48 54 41 42 4c 45 5f 4e  ert( HASHTABLE_N
d9f0: 50 41 47 45 3d 3d 28 31 3c 3c 28 41 72 72 61 79  PAGE==(1<<(Array
da00: 53 69 7a 65 28 61 53 75 62 29 2d 31 29 29 20 29  Size(aSub)-1)) )
da10: 3b 0a 0a 20 20 66 6f 72 28 69 4c 69 73 74 3d 30  ;..  for(iList=0
da20: 3b 20 69 4c 69 73 74 3c 6e 4c 69 73 74 3b 20 69  ; iList<nList; i
da30: 4c 69 73 74 2b 2b 29 7b 0a 20 20 20 20 6e 4d 65  List++){.    nMe
da40: 72 67 65 20 3d 20 31 3b 0a 20 20 20 20 61 4d 65  rge = 1;.    aMe
da50: 72 67 65 20 3d 20 26 61 4c 69 73 74 5b 69 4c 69  rge = &aList[iLi
da60: 73 74 5d 3b 0a 20 20 20 20 66 6f 72 28 69 53 75  st];.    for(iSu
da70: 62 3d 30 3b 20 69 4c 69 73 74 20 26 20 28 31 3c  b=0; iList & (1<
da80: 3c 69 53 75 62 29 3b 20 69 53 75 62 2b 2b 29 7b  <iSub); iSub++){
da90: 0a 20 20 20 20 20 20 73 74 72 75 63 74 20 53 75  .      struct Su
daa0: 62 6c 69 73 74 20 2a 70 20 3d 20 26 61 53 75 62  blist *p = &aSub
dab0: 5b 69 53 75 62 5d 3b 0a 20 20 20 20 20 20 61 73  [iSub];.      as
dac0: 73 65 72 74 28 20 70 2d 3e 61 4c 69 73 74 20 26  sert( p->aList &
dad0: 26 20 70 2d 3e 6e 4c 69 73 74 3c 3d 28 31 3c 3c  & p->nList<=(1<<
dae0: 69 53 75 62 29 20 29 3b 0a 20 20 20 20 20 20 61  iSub) );.      a
daf0: 73 73 65 72 74 28 20 70 2d 3e 61 4c 69 73 74 3d  ssert( p->aList=
db00: 3d 26 61 4c 69 73 74 5b 69 4c 69 73 74 26 7e 28  =&aList[iList&~(
db10: 28 32 3c 3c 69 53 75 62 29 2d 31 29 5d 20 29 3b  (2<<iSub)-1)] );
db20: 0a 20 20 20 20 20 20 77 61 6c 4d 65 72 67 65 28  .      walMerge(
db30: 61 43 6f 6e 74 65 6e 74 2c 20 70 2d 3e 61 4c 69  aContent, p->aLi
db40: 73 74 2c 20 70 2d 3e 6e 4c 69 73 74 2c 20 26 61  st, p->nList, &a
db50: 4d 65 72 67 65 2c 20 26 6e 4d 65 72 67 65 2c 20  Merge, &nMerge, 
db60: 61 42 75 66 66 65 72 29 3b 0a 20 20 20 20 7d 0a  aBuffer);.    }.
db70: 20 20 20 20 61 53 75 62 5b 69 53 75 62 5d 2e 61      aSub[iSub].a
db80: 4c 69 73 74 20 3d 20 61 4d 65 72 67 65 3b 0a 20  List = aMerge;. 
db90: 20 20 20 61 53 75 62 5b 69 53 75 62 5d 2e 6e 4c     aSub[iSub].nL
dba0: 69 73 74 20 3d 20 6e 4d 65 72 67 65 3b 0a 20 20  ist = nMerge;.  
dbb0: 7d 0a 0a 20 20 66 6f 72 28 69 53 75 62 2b 2b 3b  }..  for(iSub++;
dbc0: 20 69 53 75 62 3c 41 72 72 61 79 53 69 7a 65 28   iSub<ArraySize(
dbd0: 61 53 75 62 29 3b 20 69 53 75 62 2b 2b 29 7b 0a  aSub); iSub++){.
dbe0: 20 20 20 20 69 66 28 20 6e 4c 69 73 74 20 26 20      if( nList & 
dbf0: 28 31 3c 3c 69 53 75 62 29 20 29 7b 0a 20 20 20  (1<<iSub) ){.   
dc00: 20 20 20 73 74 72 75 63 74 20 53 75 62 6c 69 73     struct Sublis
dc10: 74 20 2a 70 20 3d 20 26 61 53 75 62 5b 69 53 75  t *p = &aSub[iSu
dc20: 62 5d 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74  b];.      assert
dc30: 28 20 70 2d 3e 6e 4c 69 73 74 3c 3d 28 31 3c 3c  ( p->nList<=(1<<
dc40: 69 53 75 62 29 20 29 3b 0a 20 20 20 20 20 20 61  iSub) );.      a
dc50: 73 73 65 72 74 28 20 70 2d 3e 61 4c 69 73 74 3d  ssert( p->aList=
dc60: 3d 26 61 4c 69 73 74 5b 6e 4c 69 73 74 26 7e 28  =&aList[nList&~(
dc70: 28 32 3c 3c 69 53 75 62 29 2d 31 29 5d 20 29 3b  (2<<iSub)-1)] );
dc80: 0a 20 20 20 20 20 20 77 61 6c 4d 65 72 67 65 28  .      walMerge(
dc90: 61 43 6f 6e 74 65 6e 74 2c 20 70 2d 3e 61 4c 69  aContent, p->aLi
dca0: 73 74 2c 20 70 2d 3e 6e 4c 69 73 74 2c 20 26 61  st, p->nList, &a
dcb0: 4d 65 72 67 65 2c 20 26 6e 4d 65 72 67 65 2c 20  Merge, &nMerge, 
dcc0: 61 42 75 66 66 65 72 29 3b 0a 20 20 20 20 7d 0a  aBuffer);.    }.
dcd0: 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20 61 4d    }.  assert( aM
dce0: 65 72 67 65 3d 3d 61 4c 69 73 74 20 29 3b 0a 20  erge==aList );. 
dcf0: 20 2a 70 6e 4c 69 73 74 20 3d 20 6e 4d 65 72 67   *pnList = nMerg
dd00: 65 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  e;..#ifdef SQLIT
dd10: 45 5f 44 45 42 55 47 0a 20 20 7b 0a 20 20 20 20  E_DEBUG.  {.    
dd20: 69 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69  int i;.    for(i
dd30: 3d 31 3b 20 69 3c 2a 70 6e 4c 69 73 74 3b 20 69  =1; i<*pnList; i
dd40: 2b 2b 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72  ++){.      asser
dd50: 74 28 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73  t( aContent[aLis
dd60: 74 5b 69 5d 5d 20 3e 20 61 43 6f 6e 74 65 6e 74  t[i]] > aContent
dd70: 5b 61 4c 69 73 74 5b 69 2d 31 5d 5d 20 29 3b 0a  [aList[i-1]] );.
dd80: 20 20 20 20 7d 0a 20 20 7d 0a 23 65 6e 64 69 66      }.  }.#endif
dd90: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 46 72 65 65 20  .}../* .** Free 
dda0: 61 6e 20 69 74 65 72 61 74 6f 72 20 61 6c 6c 6f  an iterator allo
ddb0: 63 61 74 65 64 20 62 79 20 77 61 6c 49 74 65 72  cated by walIter
ddc0: 61 74 6f 72 49 6e 69 74 28 29 2e 0a 2a 2f 0a 73  atorInit()..*/.s
ddd0: 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 49 74  tatic void walIt
dde0: 65 72 61 74 6f 72 46 72 65 65 28 57 61 6c 49 74  eratorFree(WalIt
ddf0: 65 72 61 74 6f 72 20 2a 70 29 7b 0a 20 20 73 71  erator *p){.  sq
de00: 6c 69 74 65 33 53 63 72 61 74 63 68 46 72 65 65  lite3ScratchFree
de10: 28 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f  (p);.}../*.** Co
de20: 6e 73 74 72 75 63 74 20 61 20 57 61 6c 49 6e 74  nstruct a WalInt
de30: 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 20 74 68  erator object th
de40: 61 74 20 63 61 6e 20 62 65 20 75 73 65 64 20 74  at can be used t
de50: 6f 20 6c 6f 6f 70 20 6f 76 65 72 20 61 6c 6c 20  o loop over all 
de60: 0a 2a 2a 20 70 61 67 65 73 20 69 6e 20 74 68 65  .** pages in the
de70: 20 57 41 4c 20 69 6e 20 61 73 63 65 6e 64 69 6e   WAL in ascendin
de80: 67 20 6f 72 64 65 72 2e 20 54 68 65 20 63 61 6c  g order. The cal
de90: 6c 65 72 20 6d 75 73 74 20 68 6f 6c 64 20 74 68  ler must hold th
dea0: 65 20 63 68 65 63 6b 70 6f 69 6e 74 0a 2a 2a 20  e checkpoint.** 
deb0: 6c 6f 63 6b 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73  lock..**.** On s
dec0: 75 63 63 65 73 73 2c 20 6d 61 6b 65 20 2a 70 70  uccess, make *pp
ded0: 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 6e 65   point to the ne
dee0: 77 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20 57 61  wly allocated Wa
def0: 6c 49 6e 74 65 72 61 74 6f 72 20 6f 62 6a 65 63  lInterator objec
df00: 74 0a 2a 2a 20 72 65 74 75 72 6e 20 53 51 4c 49  t.** return SQLI
df10: 54 45 5f 4f 4b 2e 20 4f 74 68 65 72 77 69 73 65  TE_OK. Otherwise
df20: 2c 20 72 65 74 75 72 6e 20 61 6e 20 65 72 72 6f  , return an erro
df30: 72 20 63 6f 64 65 2e 20 49 66 20 74 68 69 73 20  r code. If this 
df40: 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65 74 75 72  routine.** retur
df50: 6e 73 20 61 6e 20 65 72 72 6f 72 2c 20 74 68 65  ns an error, the
df60: 20 76 61 6c 75 65 20 6f 66 20 2a 70 70 20 69 73   value of *pp is
df70: 20 75 6e 64 65 66 69 6e 65 64 2e 0a 2a 2a 0a 2a   undefined..**.*
df80: 2a 20 54 68 65 20 63 61 6c 6c 69 6e 67 20 72 6f  * The calling ro
df90: 75 74 69 6e 65 20 73 68 6f 75 6c 64 20 69 6e 76  utine should inv
dfa0: 6f 6b 65 20 77 61 6c 49 74 65 72 61 74 6f 72 46  oke walIteratorF
dfb0: 72 65 65 28 29 20 74 6f 20 64 65 73 74 72 6f 79  ree() to destroy
dfc0: 20 74 68 65 0a 2a 2a 20 57 61 6c 49 74 65 72 61   the.** WalItera
dfd0: 74 6f 72 20 6f 62 6a 65 63 74 20 77 68 65 6e 20  tor object when 
dfe0: 69 74 20 68 61 73 20 66 69 6e 69 73 68 65 64 20  it has finished 
dff0: 77 69 74 68 20 69 74 2e 0a 2a 2f 0a 73 74 61 74  with it..*/.stat
e000: 69 63 20 69 6e 74 20 77 61 6c 49 74 65 72 61 74  ic int walIterat
e010: 6f 72 49 6e 69 74 28 57 61 6c 20 2a 70 57 61 6c  orInit(Wal *pWal
e020: 2c 20 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 2a  , WalIterator **
e030: 70 70 29 7b 0a 20 20 57 61 6c 49 74 65 72 61 74  pp){.  WalIterat
e040: 6f 72 20 2a 70 3b 20 20 20 20 20 20 20 20 20 20  or *p;          
e050: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
e060: 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20   value */.  int 
e070: 6e 53 65 67 6d 65 6e 74 3b 20 20 20 20 20 20 20  nSegment;       
e080: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
e090: 75 6d 62 65 72 20 6f 66 20 73 65 67 6d 65 6e 74  umber of segment
e0a0: 73 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a 20 20  s to merge */.  
e0b0: 75 33 32 20 69 4c 61 73 74 3b 20 20 20 20 20 20  u32 iLast;      
e0c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e0d0: 2f 2a 20 4c 61 73 74 20 66 72 61 6d 65 20 69 6e  /* Last frame in
e0e0: 20 6c 6f 67 20 2a 2f 0a 20 20 69 6e 74 20 6e 42   log */.  int nB
e0f0: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
e100: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
e110: 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20  ber of bytes to 
e120: 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20 69 6e  allocate */.  in
e130: 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20  t i;            
e140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
e150: 20 49 74 65 72 61 74 6f 72 20 76 61 72 69 61 62   Iterator variab
e160: 6c 65 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20  le */.  ht_slot 
e170: 2a 61 54 6d 70 3b 20 20 20 20 20 20 20 20 20 20  *aTmp;          
e180: 20 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 20          /* Temp 
e190: 73 70 61 63 65 20 75 73 65 64 20 62 79 20 6d 65  space used by me
e1a0: 72 67 65 2d 73 6f 72 74 20 2a 2f 0a 20 20 69 6e  rge-sort */.  in
e1b0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
e1c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
e1d0: 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a   Return Code */.
e1e0: 0a 20 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69  .  /* This routi
e1f0: 6e 65 20 6f 6e 6c 79 20 72 75 6e 73 20 77 68 69  ne only runs whi
e200: 6c 65 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 63  le holding the c
e210: 68 65 63 6b 70 6f 69 6e 74 20 6c 6f 63 6b 2e 20  heckpoint lock. 
e220: 41 6e 64 0a 20 20 2a 2a 20 69 74 20 6f 6e 6c 79  And.  ** it only
e230: 20 72 75 6e 73 20 69 66 20 74 68 65 72 65 20 69   runs if there i
e240: 73 20 61 63 74 75 61 6c 6c 79 20 63 6f 6e 74 65  s actually conte
e250: 6e 74 20 69 6e 20 74 68 65 20 6c 6f 67 20 28 6d  nt in the log (m
e260: 78 46 72 61 6d 65 3e 30 29 2e 0a 20 20 2a 2f 0a  xFrame>0)..  */.
e270: 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
e280: 63 6b 70 74 4c 6f 63 6b 20 26 26 20 70 57 61 6c  ckptLock && pWal
e290: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3e 30 20  ->hdr.mxFrame>0 
e2a0: 29 3b 0a 20 20 69 4c 61 73 74 20 3d 20 70 57 61  );.  iLast = pWa
e2b0: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a  l->hdr.mxFrame;.
e2c0: 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 73  .  /* Allocate s
e2d0: 70 61 63 65 20 66 6f 72 20 74 68 65 20 57 61 6c  pace for the Wal
e2e0: 49 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 2e  Iterator object.
e2f0: 20 2a 2f 0a 20 20 6e 53 65 67 6d 65 6e 74 20 3d   */.  nSegment =
e300: 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69 4c   walFramePage(iL
e310: 61 73 74 29 20 2b 20 31 3b 0a 20 20 6e 42 79 74  ast) + 1;.  nByt
e320: 65 20 3d 20 73 69 7a 65 6f 66 28 57 61 6c 49 74  e = sizeof(WalIt
e330: 65 72 61 74 6f 72 29 20 0a 20 20 20 20 20 20 20  erator) .       
e340: 20 2b 20 28 6e 53 65 67 6d 65 6e 74 2d 31 29 2a   + (nSegment-1)*
e350: 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20 57 61  sizeof(struct Wa
e360: 6c 53 65 67 6d 65 6e 74 29 0a 20 20 20 20 20 20  lSegment).      
e370: 20 20 2b 20 69 4c 61 73 74 2a 73 69 7a 65 6f 66    + iLast*sizeof
e380: 28 68 74 5f 73 6c 6f 74 29 3b 0a 20 20 70 20 3d  (ht_slot);.  p =
e390: 20 28 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 29   (WalIterator *)
e3a0: 73 71 6c 69 74 65 33 53 63 72 61 74 63 68 4d 61  sqlite3ScratchMa
e3b0: 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20 20 69  lloc(nByte);.  i
e3c0: 66 28 20 21 70 20 29 7b 0a 20 20 20 20 72 65 74  f( !p ){.    ret
e3d0: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
e3e0: 3b 0a 20 20 7d 0a 20 20 6d 65 6d 73 65 74 28 70  ;.  }.  memset(p
e3f0: 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 70  , 0, nByte);.  p
e400: 2d 3e 6e 53 65 67 6d 65 6e 74 20 3d 20 6e 53 65  ->nSegment = nSe
e410: 67 6d 65 6e 74 3b 0a 0a 20 20 2f 2a 20 41 6c 6c  gment;..  /* All
e420: 6f 63 61 74 65 20 74 65 6d 70 6f 72 61 72 79 20  ocate temporary 
e430: 73 70 61 63 65 20 75 73 65 64 20 62 79 20 74 68  space used by th
e440: 65 20 6d 65 72 67 65 2d 73 6f 72 74 20 72 6f 75  e merge-sort rou
e450: 74 69 6e 65 2e 20 54 68 69 73 20 62 6c 6f 63 6b  tine. This block
e460: 0a 20 20 2a 2a 20 6f 66 20 6d 65 6d 6f 72 79 20  .  ** of memory 
e470: 77 69 6c 6c 20 62 65 20 66 72 65 65 64 20 62 65  will be freed be
e480: 66 6f 72 65 20 74 68 69 73 20 66 75 6e 63 74 69  fore this functi
e490: 6f 6e 20 72 65 74 75 72 6e 73 2e 0a 20 20 2a 2f  on returns..  */
e4a0: 0a 20 20 61 54 6d 70 20 3d 20 28 68 74 5f 73 6c  .  aTmp = (ht_sl
e4b0: 6f 74 20 2a 29 73 71 6c 69 74 65 33 53 63 72 61  ot *)sqlite3Scra
e4c0: 74 63 68 4d 61 6c 6c 6f 63 28 0a 20 20 20 20 20  tchMalloc(.     
e4d0: 20 73 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29   sizeof(ht_slot)
e4e0: 20 2a 20 28 69 4c 61 73 74 3e 48 41 53 48 54 41   * (iLast>HASHTA
e4f0: 42 4c 45 5f 4e 50 41 47 45 3f 48 41 53 48 54 41  BLE_NPAGE?HASHTA
e500: 42 4c 45 5f 4e 50 41 47 45 3a 69 4c 61 73 74 29  BLE_NPAGE:iLast)
e510: 0a 20 20 29 3b 0a 20 20 69 66 28 20 21 61 54 6d  .  );.  if( !aTm
e520: 70 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  p ){.    rc = SQ
e530: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
e540: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d  .  for(i=0; rc==
e550: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 6e  SQLITE_OK && i<n
e560: 53 65 67 6d 65 6e 74 3b 20 69 2b 2b 29 7b 0a 20  Segment; i++){. 
e570: 20 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73     volatile ht_s
e580: 6c 6f 74 20 2a 61 48 61 73 68 3b 0a 20 20 20 20  lot *aHash;.    
e590: 75 33 32 20 69 5a 65 72 6f 3b 0a 20 20 20 20 76  u32 iZero;.    v
e5a0: 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67  olatile u32 *aPg
e5b0: 6e 6f 3b 0a 0a 20 20 20 20 72 63 20 3d 20 77 61  no;..    rc = wa
e5c0: 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c 20 69  lHashGet(pWal, i
e5d0: 2c 20 26 61 48 61 73 68 2c 20 26 61 50 67 6e 6f  , &aHash, &aPgno
e5e0: 2c 20 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20 69  , &iZero);.    i
e5f0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
e600: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6a 3b   ){.      int j;
e610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e620: 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65 72        /* Counter
e630: 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 20   variable */.   
e640: 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 3b 20 20     int nEntry;  
e650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e660: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72  * Number of entr
e670: 69 65 73 20 69 6e 20 74 68 69 73 20 73 65 67 6d  ies in this segm
e680: 65 6e 74 20 2a 2f 0a 20 20 20 20 20 20 68 74 5f  ent */.      ht_
e690: 73 6c 6f 74 20 2a 61 49 6e 64 65 78 3b 20 20 20  slot *aIndex;   
e6a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74           /* Sort
e6b0: 65 64 20 69 6e 64 65 78 20 66 6f 72 20 74 68 69  ed index for thi
e6c0: 73 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 0a 20 20  s segment */..  
e6d0: 20 20 20 20 61 50 67 6e 6f 2b 2b 3b 0a 20 20 20      aPgno++;.   
e6e0: 20 20 20 69 66 28 20 28 69 2b 31 29 3d 3d 6e 53     if( (i+1)==nS
e6f0: 65 67 6d 65 6e 74 20 29 7b 0a 20 20 20 20 20 20  egment ){.      
e700: 20 20 6e 45 6e 74 72 79 20 3d 20 28 69 6e 74 29    nEntry = (int)
e710: 28 69 4c 61 73 74 20 2d 20 69 5a 65 72 6f 29 3b  (iLast - iZero);
e720: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
e730: 20 20 20 20 20 20 6e 45 6e 74 72 79 20 3d 20 28        nEntry = (
e740: 69 6e 74 29 28 28 75 33 32 2a 29 61 48 61 73 68  int)((u32*)aHash
e750: 20 2d 20 28 75 33 32 2a 29 61 50 67 6e 6f 29 3b   - (u32*)aPgno);
e760: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61  .      }.      a
e770: 49 6e 64 65 78 20 3d 20 26 28 28 68 74 5f 73 6c  Index = &((ht_sl
e780: 6f 74 20 2a 29 26 70 2d 3e 61 53 65 67 6d 65 6e  ot *)&p->aSegmen
e790: 74 5b 70 2d 3e 6e 53 65 67 6d 65 6e 74 5d 29 5b  t[p->nSegment])[
e7a0: 69 5a 65 72 6f 5d 3b 0a 20 20 20 20 20 20 69 5a  iZero];.      iZ
e7b0: 65 72 6f 2b 2b 3b 0a 20 20 0a 20 20 20 20 20 20  ero++;.  .      
e7c0: 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 45 6e 74 72  for(j=0; j<nEntr
e7d0: 79 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20  y; j++){.       
e7e0: 20 61 49 6e 64 65 78 5b 6a 5d 20 3d 20 28 68 74   aIndex[j] = (ht
e7f0: 5f 73 6c 6f 74 29 6a 3b 0a 20 20 20 20 20 20 7d  _slot)j;.      }
e800: 0a 20 20 20 20 20 20 77 61 6c 4d 65 72 67 65 73  .      walMerges
e810: 6f 72 74 28 28 75 33 32 20 2a 29 61 50 67 6e 6f  ort((u32 *)aPgno
e820: 2c 20 61 54 6d 70 2c 20 61 49 6e 64 65 78 2c 20  , aTmp, aIndex, 
e830: 26 6e 45 6e 74 72 79 29 3b 0a 20 20 20 20 20 20  &nEntry);.      
e840: 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 69  p->aSegment[i].i
e850: 5a 65 72 6f 20 3d 20 69 5a 65 72 6f 3b 0a 20 20  Zero = iZero;.  
e860: 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b      p->aSegment[
e870: 69 5d 2e 6e 45 6e 74 72 79 20 3d 20 6e 45 6e 74  i].nEntry = nEnt
e880: 72 79 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65  ry;.      p->aSe
e890: 67 6d 65 6e 74 5b 69 5d 2e 61 49 6e 64 65 78 20  gment[i].aIndex 
e8a0: 3d 20 61 49 6e 64 65 78 3b 0a 20 20 20 20 20 20  = aIndex;.      
e8b0: 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 61  p->aSegment[i].a
e8c0: 50 67 6e 6f 20 3d 20 28 75 33 32 20 2a 29 61 50  Pgno = (u32 *)aP
e8d0: 67 6e 6f 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  gno;.    }.  }. 
e8e0: 20 73 71 6c 69 74 65 33 53 63 72 61 74 63 68 46   sqlite3ScratchF
e8f0: 72 65 65 28 61 54 6d 70 29 3b 0a 0a 20 20 69 66  ree(aTmp);..  if
e900: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
e910: 29 7b 0a 20 20 20 20 77 61 6c 49 74 65 72 61 74  ){.    walIterat
e920: 6f 72 46 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20  orFree(p);.  }. 
e930: 20 2a 70 70 20 3d 20 70 3b 0a 20 20 72 65 74 75   *pp = p;.  retu
e940: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
e950: 43 6f 70 79 20 61 73 20 6d 75 63 68 20 63 6f 6e  Copy as much con
e960: 74 65 6e 74 20 61 73 20 77 65 20 63 61 6e 20 66  tent as we can f
e970: 72 6f 6d 20 74 68 65 20 57 41 4c 20 62 61 63 6b  rom the WAL back
e980: 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
e990: 73 65 20 66 69 6c 65 0a 2a 2a 20 69 6e 20 72 65  se file.** in re
e9a0: 73 70 6f 6e 73 65 20 74 6f 20 61 6e 20 73 71 6c  sponse to an sql
e9b0: 69 74 65 33 5f 77 61 6c 5f 63 68 65 63 6b 70 6f  ite3_wal_checkpo
e9c0: 69 6e 74 28 29 20 72 65 71 75 65 73 74 20 6f 72  int() request or
e9d0: 20 74 68 65 20 65 71 75 69 76 61 6c 65 6e 74 2e   the equivalent.
e9e0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 6d 6f 75 6e  .**.** The amoun
e9f0: 74 20 6f 66 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  t of information
ea00: 20 63 6f 70 69 65 73 20 66 72 6f 6d 20 57 41 4c   copies from WAL
ea10: 20 74 6f 20 64 61 74 61 62 61 73 65 20 6d 69 67   to database mig
ea20: 68 74 20 62 65 20 6c 69 6d 69 74 65 64 0a 2a 2a  ht be limited.**
ea30: 20 62 79 20 61 63 74 69 76 65 20 72 65 61 64 65   by active reade
ea40: 72 73 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e  rs.  This routin
ea50: 65 20 77 69 6c 6c 20 6e 65 76 65 72 20 6f 76 65  e will never ove
ea60: 72 77 72 69 74 65 20 61 20 64 61 74 61 62 61 73  rwrite a databas
ea70: 65 20 70 61 67 65 0a 2a 2a 20 74 68 61 74 20 61  e page.** that a
ea80: 20 63 6f 6e 63 75 72 72 65 6e 74 20 72 65 61 64   concurrent read
ea90: 65 72 20 6d 69 67 68 74 20 62 65 20 75 73 69 6e  er might be usin
eaa0: 67 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 20 49 2f 4f  g..**.** All I/O
eab0: 20 62 61 72 72 69 65 72 20 6f 70 65 72 61 74 69   barrier operati
eac0: 6f 6e 73 20 28 61 2e 6b 2e 61 20 66 73 79 6e 63  ons (a.k.a fsync
ead0: 73 29 20 6f 63 63 75 72 20 69 6e 20 74 68 69 73  s) occur in this
eae0: 20 72 6f 75 74 69 6e 65 20 77 68 65 6e 0a 2a 2a   routine when.**
eaf0: 20 53 51 4c 69 74 65 20 69 73 20 69 6e 20 57 41   SQLite is in WA
eb00: 4c 2d 6d 6f 64 65 20 69 6e 20 73 79 6e 63 68 72  L-mode in synchr
eb10: 6f 6e 6f 75 73 3d 4e 4f 52 4d 41 4c 2e 20 20 54  onous=NORMAL.  T
eb20: 68 61 74 20 6d 65 61 6e 73 20 74 68 61 74 20 69  hat means that i
eb30: 66 20 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74  f .** checkpoint
eb40: 73 20 61 72 65 20 61 6c 77 61 79 73 20 72 75 6e  s are always run
eb50: 20 62 79 20 61 20 62 61 63 6b 67 72 6f 75 6e 64   by a background
eb60: 20 74 68 72 65 61 64 20 6f 72 20 62 61 63 6b 67   thread or backg
eb70: 72 6f 75 6e 64 20 0a 2a 2a 20 70 72 6f 63 65 73  round .** proces
eb80: 73 2c 20 66 6f 72 65 67 72 6f 75 6e 64 20 74 68  s, foreground th
eb90: 72 65 61 64 73 20 77 69 6c 6c 20 6e 65 76 65 72  reads will never
eba0: 20 62 6c 6f 63 6b 20 6f 6e 20 61 20 6c 65 6e 67   block on a leng
ebb0: 74 68 79 20 66 73 79 6e 63 20 63 61 6c 6c 2e 0a  thy fsync call..
ebc0: 2a 2a 0a 2a 2a 20 46 73 79 6e 63 20 69 73 20 63  **.** Fsync is c
ebd0: 61 6c 6c 65 64 20 6f 6e 20 74 68 65 20 57 41 4c  alled on the WAL
ebe0: 20 62 65 66 6f 72 65 20 77 72 69 74 69 6e 67 20   before writing 
ebf0: 63 6f 6e 74 65 6e 74 20 6f 75 74 20 6f 66 20 74  content out of t
ec00: 68 65 20 57 41 4c 20 61 6e 64 0a 2a 2a 20 69 6e  he WAL and.** in
ec10: 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 2e  to the database.
ec20: 20 20 54 68 69 73 20 65 6e 73 75 72 65 73 20 74    This ensures t
ec30: 68 61 74 20 69 66 20 74 68 65 20 6e 65 77 20 63  hat if the new c
ec40: 6f 6e 74 65 6e 74 20 69 73 20 70 65 72 73 69 73  ontent is persis
ec50: 74 65 6e 74 0a 2a 2a 20 69 6e 20 74 68 65 20 57  tent.** in the W
ec60: 41 4c 20 61 6e 64 20 63 61 6e 20 62 65 20 72 65  AL and can be re
ec70: 63 6f 76 65 72 65 64 20 66 6f 6c 6c 6f 77 69 6e  covered followin
ec80: 67 20 61 20 70 6f 77 65 72 2d 6c 6f 73 73 20 6f  g a power-loss o
ec90: 72 20 68 61 72 64 20 72 65 73 65 74 2e 0a 2a 2a  r hard reset..**
eca0: 0a 2a 2a 20 46 73 79 6e 63 20 69 73 20 61 6c 73  .** Fsync is als
ecb0: 6f 20 63 61 6c 6c 65 64 20 6f 6e 20 74 68 65 20  o called on the 
ecc0: 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 69 66  database file if
ecd0: 20 28 61 6e 64 20 6f 6e 6c 79 20 69 66 29 20 74   (and only if) t
ece0: 68 65 20 65 6e 74 69 72 65 0a 2a 2a 20 57 41 4c  he entire.** WAL
ecf0: 20 63 6f 6e 74 65 6e 74 20 69 73 20 63 6f 70 69   content is copi
ed00: 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ed into the data
ed10: 62 61 73 65 20 66 69 6c 65 2e 20 20 54 68 69 73  base file.  This
ed20: 20 73 65 63 6f 6e 64 20 66 73 79 6e 63 20 6d 61   second fsync ma
ed30: 6b 65 73 0a 2a 2a 20 69 74 20 73 61 66 65 20 74  kes.** it safe t
ed40: 6f 20 64 65 6c 65 74 65 20 74 68 65 20 57 41 4c  o delete the WAL
ed50: 20 73 69 6e 63 65 20 74 68 65 20 6e 65 77 20 63   since the new c
ed60: 6f 6e 74 65 6e 74 20 77 69 6c 6c 20 70 65 72 73  ontent will pers
ed70: 69 73 74 20 69 6e 20 74 68 65 0a 2a 2a 20 64 61  ist in the.** da
ed80: 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a  tabase file..**.
ed90: 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
eda0: 75 73 65 73 20 61 6e 64 20 75 70 64 61 74 65 73  uses and updates
edb0: 20 74 68 65 20 6e 42 61 63 6b 66 69 6c 6c 20 66   the nBackfill f
edc0: 69 65 6c 64 20 6f 66 20 74 68 65 20 77 61 6c 2d  ield of the wal-
edd0: 69 6e 64 65 78 20 68 65 61 64 65 72 2e 0a 2a 2a  index header..**
ede0: 20 54 68 69 73 20 69 73 20 74 68 65 20 6f 6e 6c   This is the onl
edf0: 79 20 72 6f 75 74 69 6e 65 20 74 68 61 20 77 69  y routine tha wi
ee00: 6c 6c 20 69 6e 63 72 65 61 73 65 20 74 68 65 20  ll increase the 
ee10: 76 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b 66 69  value of nBackfi
ee20: 6c 6c 2e 20 20 0a 2a 2a 20 28 41 20 57 41 4c 20  ll.  .** (A WAL 
ee30: 72 65 73 65 74 20 6f 72 20 72 65 63 6f 76 65 72  reset or recover
ee40: 79 20 77 69 6c 6c 20 72 65 76 65 72 74 20 6e 42  y will revert nB
ee50: 61 63 6b 66 69 6c 6c 20 74 6f 20 7a 65 72 6f 2c  ackfill to zero,
ee60: 20 62 75 74 20 6e 6f 74 20 69 6e 63 72 65 61 73   but not increas
ee70: 65 0a 2a 2a 20 69 74 73 20 76 61 6c 75 65 2e 29  e.** its value.)
ee80: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 65  .**.** The calle
ee90: 72 20 6d 75 73 74 20 62 65 20 68 6f 6c 64 69 6e  r must be holdin
eea0: 67 20 73 75 66 66 69 63 69 65 6e 74 20 6c 6f 63  g sufficient loc
eeb0: 6b 73 20 74 6f 20 65 6e 73 75 72 65 20 74 68 61  ks to ensure tha
eec0: 74 20 6e 6f 20 6f 74 68 65 72 0a 2a 2a 20 63 68  t no other.** ch
eed0: 65 63 6b 70 6f 69 6e 74 20 69 73 20 72 75 6e 6e  eckpoint is runn
eee0: 69 6e 67 20 28 69 6e 20 61 6e 79 20 6f 74 68 65  ing (in any othe
eef0: 72 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63  r thread or proc
ef00: 65 73 73 29 20 61 74 20 74 68 65 20 73 61 6d 65  ess) at the same
ef10: 0a 2a 2a 20 74 69 6d 65 2e 0a 2a 2f 0a 73 74 61  .** time..*/.sta
ef20: 74 69 63 20 69 6e 74 20 77 61 6c 43 68 65 63 6b  tic int walCheck
ef30: 70 6f 69 6e 74 28 0a 20 20 57 61 6c 20 2a 70 57  point(.  Wal *pW
ef40: 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
ef50: 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20           /* Wal 
ef60: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20  connection */.  
ef70: 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20  int sync_flags, 
ef80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ef90: 2f 2a 20 46 6c 61 67 73 20 66 6f 72 20 4f 73 53  /* Flags for OsS
efa0: 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a  ync() (or 0) */.
efb0: 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20 20 20    int nBuf,     
efc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
efd0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 7a 42 75    /* Size of zBu
efe0: 66 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  f in bytes */.  
eff0: 75 38 20 2a 7a 42 75 66 20 20 20 20 20 20 20 20  u8 *zBuf        
f000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f010: 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62 75 66  /* Temporary buf
f020: 66 65 72 20 74 6f 20 75 73 65 20 2a 2f 0a 29 7b  fer to use */.){
f030: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
f040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f050: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
f060: 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67  e */.  int szPag
f070: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
f080: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
f090: 73 65 20 70 61 67 65 2d 73 69 7a 65 20 2a 2f 0a  se page-size */.
f0a0: 20 20 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 70    WalIterator *p
f0b0: 49 74 65 72 20 3d 20 30 3b 20 20 20 20 20 20 20  Iter = 0;       
f0c0: 20 20 2f 2a 20 57 61 6c 20 69 74 65 72 61 74 6f    /* Wal iterato
f0d0: 72 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 75  r context */.  u
f0e0: 33 32 20 69 44 62 70 61 67 65 20 3d 20 30 3b 20  32 iDbpage = 0; 
f0f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
f100: 2a 20 4e 65 78 74 20 64 61 74 61 62 61 73 65 20  * Next database 
f110: 70 61 67 65 20 74 6f 20 77 72 69 74 65 20 2a 2f  page to write */
f120: 0a 20 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20  .  u32 iFrame = 
f130: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
f140: 20 20 20 2f 2a 20 57 61 6c 20 66 72 61 6d 65 20     /* Wal frame 
f150: 63 6f 6e 74 61 69 6e 69 6e 67 20 64 61 74 61 20  containing data 
f160: 66 6f 72 20 69 44 62 70 61 67 65 20 2a 2f 0a 20  for iDbpage */. 
f170: 20 75 33 32 20 6d 78 53 61 66 65 46 72 61 6d 65   u32 mxSafeFrame
f180: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
f190: 20 2f 2a 20 4d 61 78 20 66 72 61 6d 65 20 74 68   /* Max frame th
f1a0: 61 74 20 63 61 6e 20 62 65 20 62 61 63 6b 66 69  at can be backfi
f1b0: 6c 6c 65 64 20 2a 2f 0a 20 20 75 33 32 20 6d 78  lled */.  u32 mx
f1c0: 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20  Page;           
f1d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78            /* Max
f1e0: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20 74   database page t
f1f0: 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 69 6e 74  o write */.  int
f200: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
f210: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
f220: 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a  Loop counter */.
f230: 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b    volatile WalCk
f240: 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b 20 20  ptInfo *pInfo;  
f250: 20 20 2f 2a 20 54 68 65 20 63 68 65 63 6b 70 6f    /* The checkpo
f260: 69 6e 74 20 73 74 61 74 75 73 20 69 6e 66 6f 72  int status infor
f270: 6d 61 74 69 6f 6e 20 2a 2f 0a 0a 20 20 73 7a 50  mation */..  szP
f280: 61 67 65 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72  age = (pWal->hdr
f290: 2e 73 7a 50 61 67 65 26 30 78 66 65 30 30 29 20  .szPage&0xfe00) 
f2a0: 2b 20 28 28 70 57 61 6c 2d 3e 68 64 72 2e 73 7a  + ((pWal->hdr.sz
f2b0: 50 61 67 65 26 30 78 30 30 30 31 29 3c 3c 31 36  Page&0x0001)<<16
f2c0: 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 73  );.  testcase( s
f2d0: 7a 50 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a  zPage<=32768 );.
f2e0: 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50 61    testcase( szPa
f2f0: 67 65 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 70  ge>=65536 );.  p
f300: 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e  Info = walCkptIn
f310: 66 6f 28 70 57 61 6c 29 3b 0a 20 20 69 66 28 20  fo(pWal);.  if( 
f320: 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
f330: 3e 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  >=pWal->hdr.mxFr
f340: 61 6d 65 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ame ) return SQL
f350: 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f 2a 20 41 6c  ITE_OK;..  /* Al
f360: 6c 6f 63 61 74 65 20 74 68 65 20 69 74 65 72 61  locate the itera
f370: 74 6f 72 20 2a 2f 0a 20 20 72 63 20 3d 20 77 61  tor */.  rc = wa
f380: 6c 49 74 65 72 61 74 6f 72 49 6e 69 74 28 70 57  lIteratorInit(pW
f390: 61 6c 2c 20 26 70 49 74 65 72 29 3b 0a 20 20 69  al, &pIter);.  i
f3a0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
f3b0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72   ){.    return r
f3c0: 63 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28  c;.  }.  assert(
f3d0: 20 70 49 74 65 72 20 29 3b 0a 0a 20 20 2f 2a 2a   pIter );..  /**
f3e0: 2a 20 54 4f 44 4f 3a 20 20 4d 6f 76 65 20 74 68  * TODO:  Move th
f3f0: 69 73 20 74 65 73 74 20 6f 75 74 20 74 6f 20 74  is test out to t
f400: 68 65 20 63 61 6c 6c 65 72 2e 20 20 4d 61 6b 65  he caller.  Make
f410: 20 69 74 20 61 6e 20 61 73 73 65 72 74 28 29 20   it an assert() 
f420: 68 65 72 65 20 2a 2a 2a 2f 0a 20 20 69 66 28 20  here ***/.  if( 
f430: 73 7a 50 61 67 65 21 3d 6e 42 75 66 20 29 7b 0a  szPage!=nBuf ){.
f440: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
f450: 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20  CORRUPT_BKPT;.  
f460: 20 20 67 6f 74 6f 20 77 61 6c 63 68 65 63 6b 70    goto walcheckp
f470: 6f 69 6e 74 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20  oint_out;.  }.. 
f480: 20 2f 2a 20 43 6f 6d 70 75 74 65 20 69 6e 20 6d   /* Compute in m
f490: 78 53 61 66 65 46 72 61 6d 65 20 74 68 65 20 69  xSafeFrame the i
f4a0: 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 73 74  ndex of the last
f4b0: 20 66 72 61 6d 65 20 6f 66 20 74 68 65 20 57 41   frame of the WA
f4c0: 4c 20 74 68 61 74 20 69 73 0a 20 20 2a 2a 20 73  L that is.  ** s
f4d0: 61 66 65 20 74 6f 20 77 72 69 74 65 20 69 6e 74  afe to write int
f4e0: 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20  o the database. 
f4f0: 20 46 72 61 6d 65 73 20 62 65 79 6f 6e 64 20 6d   Frames beyond m
f500: 78 53 61 66 65 46 72 61 6d 65 20 6d 69 67 68 74  xSafeFrame might
f510: 0a 20 20 2a 2a 20 6f 76 65 72 77 72 69 74 65 20  .  ** overwrite 
f520: 64 61 74 61 62 61 73 65 20 70 61 67 65 73 20 74  database pages t
f530: 68 61 74 20 61 72 65 20 69 6e 20 75 73 65 20 62  hat are in use b
f540: 79 20 61 63 74 69 76 65 20 72 65 61 64 65 72 73  y active readers
f550: 20 61 6e 64 20 74 68 75 73 0a 20 20 2a 2a 20 63   and thus.  ** c
f560: 61 6e 6e 6f 74 20 62 65 20 62 61 63 6b 66 69 6c  annot be backfil
f570: 6c 65 64 20 66 72 6f 6d 20 74 68 65 20 57 41 4c  led from the WAL
f580: 2e 0a 20 20 2a 2f 0a 20 20 6d 78 53 61 66 65 46  ..  */.  mxSafeF
f590: 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72  rame = pWal->hdr
f5a0: 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 6d 78 50 61  .mxFrame;.  mxPa
f5b0: 67 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6e  ge = pWal->hdr.n
f5c0: 50 61 67 65 3b 0a 20 20 66 6f 72 28 69 3d 31 3b  Page;.  for(i=1;
f5d0: 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
f5e0: 69 2b 2b 29 7b 0a 20 20 20 20 75 33 32 20 79 20  i++){.    u32 y 
f5f0: 3d 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61  = pInfo->aReadMa
f600: 72 6b 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 6d  rk[i];.    if( m
f610: 78 53 61 66 65 46 72 61 6d 65 3e 3d 79 20 29 7b  xSafeFrame>=y ){
f620: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 79  .      assert( y
f630: 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  <=pWal->hdr.mxFr
f640: 61 6d 65 20 29 3b 0a 20 20 20 20 20 20 72 63 20  ame );.      rc 
f650: 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69  = walLockExclusi
f660: 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ve(pWal, WAL_REA
f670: 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20  D_LOCK(i), 1);. 
f680: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
f690: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
f6a0: 20 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61    pInfo->aReadMa
f6b0: 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41 52 4b  rk[i] = READMARK
f6c0: 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 20 20 20  _NOT_USED;.     
f6d0: 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c     walUnlockExcl
f6e0: 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
f6f0: 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29  READ_LOCK(i), 1)
f700: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  ;.      }else if
f710: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc==SQLITE_BUS
f720: 59 20 29 7b 0a 20 20 20 20 20 20 20 20 6d 78 53  Y ){.        mxS
f730: 61 66 65 46 72 61 6d 65 20 3d 20 79 3b 0a 20 20  afeFrame = y;.  
f740: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
f750: 20 20 20 67 6f 74 6f 20 77 61 6c 63 68 65 63 6b     goto walcheck
f760: 70 6f 69 6e 74 5f 6f 75 74 3b 0a 20 20 20 20 20  point_out;.     
f770: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
f780: 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b  if( pInfo->nBack
f790: 66 69 6c 6c 3c 6d 78 53 61 66 65 46 72 61 6d 65  fill<mxSafeFrame
f7a0: 0a 20 20 20 26 26 20 28 72 63 20 3d 20 77 61 6c  .   && (rc = wal
f7b0: 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  LockExclusive(pW
f7c0: 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  al, WAL_READ_LOC
f7d0: 4b 28 30 29 2c 20 31 29 29 3d 3d 53 51 4c 49 54  K(0), 1))==SQLIT
f7e0: 45 5f 4f 4b 0a 20 20 29 7b 0a 20 20 20 20 69 36  E_OK.  ){.    i6
f7f0: 34 20 6e 53 69 7a 65 3b 20 20 20 20 20 20 20 20  4 nSize;        
f800: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
f810: 75 72 72 65 6e 74 20 73 69 7a 65 20 6f 66 20 64  urrent size of d
f820: 61 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a  atabase file */.
f830: 20 20 20 20 75 33 32 20 6e 42 61 63 6b 66 69 6c      u32 nBackfil
f840: 6c 20 3d 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b  l = pInfo->nBack
f850: 66 69 6c 6c 3b 0a 0a 20 20 20 20 2f 2a 20 53 79  fill;..    /* Sy
f860: 6e 63 20 74 68 65 20 57 41 4c 20 74 6f 20 64 69  nc the WAL to di
f870: 73 6b 20 2a 2f 0a 20 20 20 20 69 66 28 20 73 79  sk */.    if( sy
f880: 6e 63 5f 66 6c 61 67 73 20 29 7b 0a 20 20 20 20  nc_flags ){.    
f890: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
f8a0: 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57 61 6c 46  Sync(pWal->pWalF
f8b0: 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73 29 3b 0a  d, sync_flags);.
f8c0: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66      }..    /* If
f8d0: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
f8e0: 6c 65 20 6d 61 79 20 67 72 6f 77 20 61 73 20 61  le may grow as a
f8f0: 20 72 65 73 75 6c 74 20 6f 66 20 74 68 69 73 20   result of this 
f900: 63 68 65 63 6b 70 6f 69 6e 74 2c 20 68 69 6e 74  checkpoint, hint
f910: 0a 20 20 20 20 2a 2a 20 61 62 6f 75 74 20 74 68  .    ** about th
f920: 65 20 65 76 65 6e 74 75 61 6c 20 73 69 7a 65 20  e eventual size 
f930: 6f 66 20 74 68 65 20 64 62 20 66 69 6c 65 20 74  of the db file t
f940: 6f 20 74 68 65 20 56 46 53 20 6c 61 79 65 72 2e  o the VFS layer.
f950: 20 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28   .    */.    if(
f960: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
f970: 7b 0a 20 20 20 20 20 20 69 36 34 20 6e 52 65 71  {.      i64 nReq
f980: 20 3d 20 28 28 69 36 34 29 6d 78 50 61 67 65 20   = ((i64)mxPage 
f990: 2a 20 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 20  * szPage);.     
f9a0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 46   rc = sqlite3OsF
f9b0: 69 6c 65 53 69 7a 65 28 70 57 61 6c 2d 3e 70 44  ileSize(pWal->pD
f9c0: 62 46 64 2c 20 26 6e 53 69 7a 65 29 3b 0a 20 20  bFd, &nSize);.  
f9d0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
f9e0: 54 45 5f 4f 4b 20 26 26 20 6e 53 69 7a 65 3c 6e  TE_OK && nSize<n
f9f0: 52 65 71 20 29 7b 0a 20 20 20 20 20 20 20 20 73  Req ){.        s
fa00: 71 6c 69 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74  qlite3OsFileCont
fa10: 72 6f 6c 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  rol(pWal->pDbFd,
fa20: 20 53 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 53 49   SQLITE_FCNTL_SI
fa30: 5a 45 5f 48 49 4e 54 2c 20 26 6e 52 65 71 29 3b  ZE_HINT, &nReq);
fa40: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
fa50: 20 20 20 20 2f 2a 20 49 74 65 72 61 74 65 20 74      /* Iterate t
fa60: 68 72 6f 75 67 68 20 74 68 65 20 63 6f 6e 74 65  hrough the conte
fa70: 6e 74 73 20 6f 66 20 74 68 65 20 57 41 4c 2c 20  nts of the WAL, 
fa80: 63 6f 70 79 69 6e 67 20 64 61 74 61 20 74 6f 20  copying data to 
fa90: 74 68 65 20 64 62 20 66 69 6c 65 2e 20 2a 2f 0a  the db file. */.
faa0: 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53      while( rc==S
fab0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 30 3d 3d 77  QLITE_OK && 0==w
fac0: 61 6c 49 74 65 72 61 74 6f 72 4e 65 78 74 28 70  alIteratorNext(p
fad0: 49 74 65 72 2c 20 26 69 44 62 70 61 67 65 2c 20  Iter, &iDbpage, 
fae0: 26 69 46 72 61 6d 65 29 20 29 7b 0a 20 20 20 20  &iFrame) ){.    
faf0: 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 0a 20    i64 iOffset;. 
fb00: 20 20 20 20 20 61 73 73 65 72 74 28 20 77 61 6c       assert( wal
fb10: 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20  FramePgno(pWal, 
fb20: 69 46 72 61 6d 65 29 3d 3d 69 44 62 70 61 67 65  iFrame)==iDbpage
fb30: 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 69 46   );.      if( iF
fb40: 72 61 6d 65 3c 3d 6e 42 61 63 6b 66 69 6c 6c 20  rame<=nBackfill 
fb50: 7c 7c 20 69 46 72 61 6d 65 3e 6d 78 53 61 66 65  || iFrame>mxSafe
fb60: 46 72 61 6d 65 20 7c 7c 20 69 44 62 70 61 67 65  Frame || iDbpage
fb70: 3e 6d 78 50 61 67 65 20 29 20 63 6f 6e 74 69 6e  >mxPage ) contin
fb80: 75 65 3b 0a 20 20 20 20 20 20 69 4f 66 66 73 65  ue;.      iOffse
fb90: 74 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73  t = walFrameOffs
fba0: 65 74 28 69 46 72 61 6d 65 2c 20 73 7a 50 61 67  et(iFrame, szPag
fbb0: 65 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48  e) + WAL_FRAME_H
fbc0: 44 52 53 49 5a 45 3b 0a 20 20 20 20 20 20 2f 2a  DRSIZE;.      /*
fbd0: 20 74 65 73 74 63 61 73 65 28 20 49 53 5f 42 49   testcase( IS_BI
fbe0: 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20 29  G_INT(iOffset) )
fbf0: 3b 20 2f 2f 20 72 65 71 75 69 72 65 73 20 61 20  ; // requires a 
fc00: 34 47 69 42 20 57 41 4c 20 66 69 6c 65 20 2a 2f  4GiB WAL file */
fc10: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
fc20: 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e  te3OsRead(pWal->
fc30: 70 57 61 6c 46 64 2c 20 7a 42 75 66 2c 20 73 7a  pWalFd, zBuf, sz
fc40: 50 61 67 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a  Page, iOffset);.
fc50: 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
fc60: 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b  LITE_OK ) break;
fc70: 0a 20 20 20 20 20 20 69 4f 66 66 73 65 74 20 3d  .      iOffset =
fc80: 20 28 69 44 62 70 61 67 65 2d 31 29 2a 28 69 36   (iDbpage-1)*(i6
fc90: 34 29 73 7a 50 61 67 65 3b 0a 20 20 20 20 20 20  4)szPage;.      
fca0: 74 65 73 74 63 61 73 65 28 20 49 53 5f 42 49 47  testcase( IS_BIG
fcb0: 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20 29 3b  _INT(iOffset) );
fcc0: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
fcd0: 74 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d  te3OsWrite(pWal-
fce0: 3e 70 44 62 46 64 2c 20 7a 42 75 66 2c 20 73 7a  >pDbFd, zBuf, sz
fcf0: 50 61 67 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a  Page, iOffset);.
fd00: 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
fd10: 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b  LITE_OK ) break;
fd20: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49  .    }..    /* I
fd30: 66 20 77 6f 72 6b 20 77 61 73 20 61 63 74 75 61  f work was actua
fd40: 6c 6c 79 20 61 63 63 6f 6d 70 6c 69 73 68 65 64  lly accomplished
fd50: 2e 2e 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 72  ... */.    if( r
fd60: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
fd70: 20 20 20 20 20 20 69 66 28 20 6d 78 53 61 66 65        if( mxSafe
fd80: 46 72 61 6d 65 3d 3d 77 61 6c 49 6e 64 65 78 48  Frame==walIndexH
fd90: 64 72 28 70 57 61 6c 29 2d 3e 6d 78 46 72 61 6d  dr(pWal)->mxFram
fda0: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 69 36 34  e ){.        i64
fdb0: 20 73 7a 44 62 20 3d 20 70 57 61 6c 2d 3e 68 64   szDb = pWal->hd
fdc0: 72 2e 6e 50 61 67 65 2a 28 69 36 34 29 73 7a 50  r.nPage*(i64)szP
fdd0: 61 67 65 3b 0a 20 20 20 20 20 20 20 20 74 65 73  age;.        tes
fde0: 74 63 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e  tcase( IS_BIG_IN
fdf0: 54 28 73 7a 44 62 29 20 29 3b 0a 20 20 20 20 20  T(szDb) );.     
fe00: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
fe10: 73 54 72 75 6e 63 61 74 65 28 70 57 61 6c 2d 3e  sTruncate(pWal->
fe20: 70 44 62 46 64 2c 20 73 7a 44 62 29 3b 0a 20 20  pDbFd, szDb);.  
fe30: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
fe40: 4c 49 54 45 5f 4f 4b 20 26 26 20 73 79 6e 63 5f  LITE_OK && sync_
fe50: 66 6c 61 67 73 20 29 7b 0a 20 20 20 20 20 20 20  flags ){.       
fe60: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
fe70: 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 44 62 46  sSync(pWal->pDbF
fe80: 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73 29 3b 0a  d, sync_flags);.
fe90: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
fea0: 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  }.      if( rc==
feb0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
fec0: 20 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63       pInfo->nBac
fed0: 6b 66 69 6c 6c 20 3d 20 6d 78 53 61 66 65 46 72  kfill = mxSafeFr
fee0: 61 6d 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ame;.      }.   
fef0: 20 7d 0a 0a 20 20 20 20 2f 2a 20 52 65 6c 65 61   }..    /* Relea
ff00: 73 65 20 74 68 65 20 72 65 61 64 65 72 20 6c 6f  se the reader lo
ff10: 63 6b 20 68 65 6c 64 20 77 68 69 6c 65 20 62 61  ck held while ba
ff20: 63 6b 66 69 6c 6c 69 6e 67 20 2a 2f 0a 20 20 20  ckfilling */.   
ff30: 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
ff40: 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  ive(pWal, WAL_RE
ff50: 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 31 29 3b 0a  AD_LOCK(0), 1);.
ff60: 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d    }else if( rc==
ff70: 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20  SQLITE_BUSY ){. 
ff80: 20 20 20 2f 2a 20 52 65 73 65 74 20 74 68 65 20     /* Reset the 
ff90: 72 65 74 75 72 6e 20 63 6f 64 65 20 73 6f 20 61  return code so a
ffa0: 73 20 6e 6f 74 20 74 6f 20 72 65 70 6f 72 74 20  s not to report 
ffb0: 61 20 63 68 65 63 6b 70 6f 69 6e 74 20 66 61 69  a checkpoint fai
ffc0: 6c 75 72 65 0a 20 20 20 20 2a 2a 20 6a 75 73 74  lure.    ** just
ffd0: 20 62 65 63 61 75 73 65 20 61 63 74 69 76 65 20   because active 
ffe0: 72 65 61 64 65 72 73 20 70 72 65 76 65 6e 74 20  readers prevent 
fff0: 61 6e 79 20 62 61 63 6b 66 69 6c 6c 2e 0a 20 20  any backfill..  
10000 20 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 53 51    */.    rc = SQ
10010 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 77  LITE_OK;.  }.. w
10020 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74  alcheckpoint_out
10030 3a 0a 20 20 77 61 6c 49 74 65 72 61 74 6f 72 46  :.  walIteratorF
10040 72 65 65 28 70 49 74 65 72 29 3b 0a 20 20 72 65  ree(pIter);.  re
10050 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
10060 2a 20 43 6c 6f 73 65 20 61 20 63 6f 6e 6e 65 63  * Close a connec
10070 74 69 6f 6e 20 74 6f 20 61 20 6c 6f 67 20 66 69  tion to a log fi
10080 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  le..*/.int sqlit
10090 65 33 57 61 6c 43 6c 6f 73 65 28 0a 20 20 57 61  e3WalClose(.  Wa
100a0 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20  l *pWal,        
100b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
100c0 20 57 61 6c 20 74 6f 20 63 6c 6f 73 65 20 2a 2f   Wal to close */
100d0 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67  .  int sync_flag
100e0 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s,              
100f0 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20 70     /* Flags to p
10100 61 73 73 20 74 6f 20 4f 73 53 79 6e 63 28 29 20  ass to OsSync() 
10110 28 6f 72 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20  (or 0) */.  int 
10120 6e 42 75 66 2c 0a 20 20 75 38 20 2a 7a 42 75 66  nBuf,.  u8 *zBuf
10130 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10140 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65          /* Buffe
10150 72 20 6f 66 20 61 74 20 6c 65 61 73 74 20 6e 42  r of at least nB
10160 75 66 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a 20  uf bytes */.){. 
10170 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
10180 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 57 61 6c 20  _OK;.  if( pWal 
10190 29 7b 0a 20 20 20 20 69 6e 74 20 69 73 44 65 6c  ){.    int isDel
101a0 65 74 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ete = 0;        
101b0 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20       /* True to 
101c0 75 6e 6c 69 6e 6b 20 77 61 6c 20 61 6e 64 20 77  unlink wal and w
101d0 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 73 20 2a  al-index files *
101e0 2f 0a 0a 20 20 20 20 2f 2a 20 49 66 20 61 6e 20  /..    /* If an 
101f0 45 58 43 4c 55 53 49 56 45 20 6c 6f 63 6b 20 63  EXCLUSIVE lock c
10200 61 6e 20 62 65 20 6f 62 74 61 69 6e 65 64 20 6f  an be obtained o
10210 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  n the database f
10220 69 6c 65 20 28 75 73 69 6e 67 20 74 68 65 0a 20  ile (using the. 
10230 20 20 20 2a 2a 20 6f 72 64 69 6e 61 72 79 2c 20     ** ordinary, 
10240 72 6f 6c 6c 62 61 63 6b 2d 6d 6f 64 65 20 6c 6f  rollback-mode lo
10250 63 6b 69 6e 67 20 6d 65 74 68 6f 64 73 2c 20 74  cking methods, t
10260 68 69 73 20 67 75 61 72 61 6e 74 65 65 73 20 74  his guarantees t
10270 68 61 74 20 74 68 65 0a 20 20 20 20 2a 2a 20 63  hat the.    ** c
10280 6f 6e 6e 65 63 74 69 6f 6e 20 61 73 73 6f 63 69  onnection associ
10290 61 74 65 64 20 77 69 74 68 20 74 68 69 73 20 6c  ated with this l
102a0 6f 67 20 66 69 6c 65 20 69 73 20 74 68 65 20 6f  og file is the o
102b0 6e 6c 79 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74  nly connection t
102c0 6f 0a 20 20 20 20 2a 2a 20 74 68 65 20 64 61 74  o.    ** the dat
102d0 61 62 61 73 65 2e 20 49 6e 20 74 68 69 73 20 63  abase. In this c
102e0 61 73 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 74  ase checkpoint t
102f0 68 65 20 64 61 74 61 62 61 73 65 20 61 6e 64 20  he database and 
10300 75 6e 6c 69 6e 6b 20 62 6f 74 68 0a 20 20 20 20  unlink both.    
10310 2a 2a 20 74 68 65 20 77 61 6c 20 61 6e 64 20 77  ** the wal and w
10320 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 73 2e 0a  al-index files..
10330 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68      **.    ** Th
10340 65 20 45 58 43 4c 55 53 49 56 45 20 6c 6f 63 6b  e EXCLUSIVE lock
10350 20 69 73 20 6e 6f 74 20 72 65 6c 65 61 73 65 64   is not released
10360 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
10370 67 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 72 63  g..    */.    rc
10380 20 3d 20 73 71 6c 69 74 65 33 4f 73 4c 6f 63 6b   = sqlite3OsLock
10390 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 53 51  (pWal->pDbFd, SQ
103a0 4c 49 54 45 5f 4c 4f 43 4b 5f 45 58 43 4c 55 53  LITE_LOCK_EXCLUS
103b0 49 56 45 29 3b 0a 20 20 20 20 69 66 28 20 72 63  IVE);.    if( rc
103c0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
103d0 20 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 65       if( pWal->e
103e0 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41  xclusiveMode==WA
103f0 4c 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 20 29 7b  L_NORMAL_MODE ){
10400 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 65  .        pWal->e
10410 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 57  xclusiveMode = W
10420 41 4c 5f 45 58 43 4c 55 53 49 56 45 5f 4d 4f 44  AL_EXCLUSIVE_MOD
10430 45 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  E;.      }.     
10440 20 72 63 20 3d 20 73 71 6c 69 74 65 33 57 61 6c   rc = sqlite3Wal
10450 43 68 65 63 6b 70 6f 69 6e 74 28 70 57 61 6c 2c  Checkpoint(pWal,
10460 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20 6e 42 75   sync_flags, nBu
10470 66 2c 20 7a 42 75 66 29 3b 0a 20 20 20 20 20 20  f, zBuf);.      
10480 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
10490 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69 73 44  K ){.        isD
104a0 65 6c 65 74 65 20 3d 20 31 3b 0a 20 20 20 20 20  elete = 1;.     
104b0 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 77 61   }.    }..    wa
104c0 6c 49 6e 64 65 78 43 6c 6f 73 65 28 70 57 61 6c  lIndexClose(pWal
104d0 2c 20 69 73 44 65 6c 65 74 65 29 3b 0a 20 20 20  , isDelete);.   
104e0 20 73 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 28   sqlite3OsClose(
104f0 70 57 61 6c 2d 3e 70 57 61 6c 46 64 29 3b 0a 20  pWal->pWalFd);. 
10500 20 20 20 69 66 28 20 69 73 44 65 6c 65 74 65 20     if( isDelete 
10510 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
10520 4f 73 44 65 6c 65 74 65 28 70 57 61 6c 2d 3e 70  OsDelete(pWal->p
10530 56 66 73 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e  Vfs, pWal->zWalN
10540 61 6d 65 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 20  ame, 0);.    }. 
10550 20 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41     WALTRACE(("WA
10560 4c 25 70 3a 20 63 6c 6f 73 65 64 5c 6e 22 2c 20  L%p: closed\n", 
10570 70 57 61 6c 29 29 3b 0a 20 20 20 20 73 71 6c 69  pWal));.    sqli
10580 74 65 33 5f 66 72 65 65 28 28 76 6f 69 64 20 2a  te3_free((void *
10590 29 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 29  )pWal->apWiData)
105a0 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
105b0 65 65 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20 20  ee(pWal);.  }.  
105c0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
105d0 0a 2a 2a 20 54 72 79 20 74 6f 20 72 65 61 64 20  .** Try to read 
105e0 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
105f0 61 64 65 72 2e 20 20 52 65 74 75 72 6e 20 30 20  ader.  Return 0 
10600 6f 6e 20 73 75 63 63 65 73 73 20 61 6e 64 20 31  on success and 1
10610 20 69 66 0a 2a 2a 20 74 68 65 72 65 20 69 73 20   if.** there is 
10620 61 20 70 72 6f 62 6c 65 6d 2e 0a 2a 2a 0a 2a 2a  a problem..**.**
10630 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69   The wal-index i
10640 73 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d 6f  s in shared memo
10650 72 79 2e 20 20 41 6e 6f 74 68 65 72 20 74 68 72  ry.  Another thr
10660 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 20 6d  ead or process m
10670 69 67 68 74 0a 2a 2a 20 62 65 20 77 72 69 74 69  ight.** be writi
10680 6e 67 20 74 68 65 20 68 65 61 64 65 72 20 61 74  ng the header at
10690 20 74 68 65 20 73 61 6d 65 20 74 69 6d 65 20 74   the same time t
106a0 68 69 73 20 70 72 6f 63 65 64 75 72 65 20 69 73  his procedure is
106b0 20 74 72 79 69 6e 67 20 74 6f 0a 2a 2a 20 72 65   trying to.** re
106c0 61 64 20 69 74 2c 20 77 68 69 63 68 20 6d 69 67  ad it, which mig
106d0 68 74 20 72 65 73 75 6c 74 20 69 6e 20 69 6e 63  ht result in inc
106e0 6f 6e 73 69 73 74 65 6e 63 79 2e 20 20 41 20 64  onsistency.  A d
106f0 69 72 74 79 20 72 65 61 64 20 69 73 20 64 65 74  irty read is det
10700 65 63 74 65 64 0a 2a 2a 20 62 79 20 76 65 72 69  ected.** by veri
10710 66 79 69 6e 67 20 74 68 61 74 20 62 6f 74 68 20  fying that both 
10720 63 6f 70 69 65 73 20 6f 66 20 74 68 65 20 68 65  copies of the he
10730 61 64 65 72 20 61 72 65 20 74 68 65 20 73 61 6d  ader are the sam
10740 65 20 61 6e 64 20 61 6c 73 6f 20 62 79 0a 2a 2a  e and also by.**
10750 20 61 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20 74   a checksum on t
10760 68 65 20 68 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a  he header..**.**
10770 20 49 66 20 61 6e 64 20 6f 6e 6c 79 20 69 66 20   If and only if 
10780 74 68 65 20 72 65 61 64 20 69 73 20 63 6f 6e 73  the read is cons
10790 69 73 74 65 6e 74 20 61 6e 64 20 74 68 65 20 68  istent and the h
107a0 65 61 64 65 72 20 69 73 20 64 69 66 66 65 72 65  eader is differe
107b0 6e 74 20 66 72 6f 6d 0a 2a 2a 20 70 57 61 6c 2d  nt from.** pWal-
107c0 3e 68 64 72 2c 20 74 68 65 6e 20 70 57 61 6c 2d  >hdr, then pWal-
107d0 3e 68 64 72 20 69 73 20 75 70 64 61 74 65 64 20  >hdr is updated 
107e0 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f  to the content o
107f0 66 20 74 68 65 20 6e 65 77 20 68 65 61 64 65 72  f the new header
10800 0a 2a 2a 20 61 6e 64 20 2a 70 43 68 61 6e 67 65  .** and *pChange
10810 64 20 69 73 20 73 65 74 20 74 6f 20 31 2e 0a 2a  d is set to 1..*
10820 2a 0a 2a 2a 20 49 66 20 74 68 65 20 63 68 65 63  *.** If the chec
10830 6b 73 75 6d 20 63 61 6e 6e 6f 74 20 62 65 20 76  ksum cannot be v
10840 65 72 69 66 69 65 64 20 72 65 74 75 72 6e 20 6e  erified return n
10850 6f 6e 2d 7a 65 72 6f 2e 20 49 66 20 74 68 65 20  on-zero. If the 
10860 68 65 61 64 65 72 0a 2a 2a 20 69 73 20 72 65 61  header.** is rea
10870 64 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20 61  d successfully a
10880 6e 64 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20  nd the checksum 
10890 76 65 72 69 66 69 65 64 2c 20 72 65 74 75 72 6e  verified, return
108a0 20 7a 65 72 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63   zero..*/.static
108b0 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 54 72 79   int walIndexTry
108c0 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69  Hdr(Wal *pWal, i
108d0 6e 74 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a 20  nt *pChanged){. 
108e0 20 75 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20   u32 aCksum[2]; 
108f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10900 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 6f 6e 20   /* Checksum on 
10910 74 68 65 20 68 65 61 64 65 72 20 63 6f 6e 74 65  the header conte
10920 6e 74 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65 78  nt */.  WalIndex
10930 48 64 72 20 68 31 2c 20 68 32 3b 20 20 20 20 20  Hdr h1, h2;     
10940 20 20 20 20 20 20 20 20 2f 2a 20 54 77 6f 20 63          /* Two c
10950 6f 70 69 65 73 20 6f 66 20 74 68 65 20 68 65 61  opies of the hea
10960 64 65 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20  der content */. 
10970 20 57 61 6c 49 6e 64 65 78 48 64 72 20 76 6f 6c   WalIndexHdr vol
10980 61 74 69 6c 65 20 2a 61 48 64 72 3b 20 20 20 20  atile *aHdr;    
10990 20 2f 2a 20 48 65 61 64 65 72 20 69 6e 20 73 68   /* Header in sh
109a0 61 72 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a 0a  ared memory */..
109b0 20 20 2f 2a 20 54 68 65 20 66 69 72 73 74 20 70    /* The first p
109c0 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69  age of the wal-i
109d0 6e 64 65 78 20 6d 75 73 74 20 62 65 20 6d 61 70  ndex must be map
109e0 70 65 64 20 61 74 20 74 68 69 73 20 70 6f 69 6e  ped at this poin
109f0 74 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  t. */.  assert( 
10a00 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20  pWal->nWiData>0 
10a10 26 26 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  && pWal->apWiDat
10a20 61 5b 30 5d 20 29 3b 0a 0a 20 20 2f 2a 20 52 65  a[0] );..  /* Re
10a30 61 64 20 74 68 65 20 68 65 61 64 65 72 2e 20 54  ad the header. T
10a40 68 69 73 20 6d 69 67 68 74 20 68 61 70 70 65 6e  his might happen
10a50 20 63 6f 6e 63 75 72 72 65 6e 74 6c 79 20 77 69   concurrently wi
10a60 74 68 20 61 20 77 72 69 74 65 20 74 6f 20 74 68  th a write to th
10a70 65 0a 20 20 2a 2a 20 73 61 6d 65 20 61 72 65 61  e.  ** same area
10a80 20 6f 66 20 73 68 61 72 65 64 20 6d 65 6d 6f 72   of shared memor
10a90 79 20 6f 6e 20 61 20 64 69 66 66 65 72 65 6e 74  y on a different
10aa0 20 43 50 55 20 69 6e 20 61 20 53 4d 50 2c 0a 20   CPU in a SMP,. 
10ab0 20 2a 2a 20 6d 65 61 6e 69 6e 67 20 69 74 20 69   ** meaning it i
10ac0 73 20 70 6f 73 73 69 62 6c 65 20 74 68 61 74 20  s possible that 
10ad0 61 6e 20 69 6e 63 6f 6e 73 69 73 74 65 6e 74 20  an inconsistent 
10ae0 73 6e 61 70 73 68 6f 74 20 69 73 20 72 65 61 64  snapshot is read
10af0 0a 20 20 2a 2a 20 66 72 6f 6d 20 74 68 65 20 66  .  ** from the f
10b00 69 6c 65 2e 20 49 66 20 74 68 69 73 20 68 61 70  ile. If this hap
10b10 70 65 6e 73 2c 20 72 65 74 75 72 6e 20 6e 6f 6e  pens, return non
10b20 2d 7a 65 72 6f 2e 0a 20 20 2a 2a 0a 20 20 2a 2a  -zero..  **.  **
10b30 20 54 68 65 72 65 20 61 72 65 20 74 77 6f 20 63   There are two c
10b40 6f 70 69 65 73 20 6f 66 20 74 68 65 20 68 65 61  opies of the hea
10b50 64 65 72 20 61 74 20 74 68 65 20 62 65 67 69 6e  der at the begin
10b60 6e 69 6e 67 20 6f 66 20 74 68 65 20 77 61 6c 2d  ning of the wal-
10b70 69 6e 64 65 78 2e 0a 20 20 2a 2a 20 57 68 65 6e  index..  ** When
10b80 20 72 65 61 64 69 6e 67 2c 20 72 65 61 64 20 5b   reading, read [
10b90 30 5d 20 66 69 72 73 74 20 74 68 65 6e 20 5b 31  0] first then [1
10ba0 5d 2e 20 20 57 72 69 74 65 73 20 61 72 65 20 69  ].  Writes are i
10bb0 6e 20 74 68 65 20 72 65 76 65 72 73 65 20 6f 72  n the reverse or
10bc0 64 65 72 2e 0a 20 20 2a 2a 20 4d 65 6d 6f 72 79  der..  ** Memory
10bd0 20 62 61 72 72 69 65 72 73 20 61 72 65 20 75 73   barriers are us
10be0 65 64 20 74 6f 20 70 72 65 76 65 6e 74 20 74 68  ed to prevent th
10bf0 65 20 63 6f 6d 70 69 6c 65 72 20 6f 72 20 74 68  e compiler or th
10c00 65 20 68 61 72 64 77 61 72 65 20 66 72 6f 6d 0a  e hardware from.
10c10 20 20 2a 2a 20 72 65 6f 72 64 65 72 69 6e 67 20    ** reordering 
10c20 74 68 65 20 72 65 61 64 73 20 61 6e 64 20 77 72  the reads and wr
10c30 69 74 65 73 2e 0a 20 20 2a 2f 0a 20 20 61 48 64  ites..  */.  aHd
10c40 72 20 3d 20 77 61 6c 49 6e 64 65 78 48 64 72 28  r = walIndexHdr(
10c50 70 57 61 6c 29 3b 0a 20 20 6d 65 6d 63 70 79 28  pWal);.  memcpy(
10c60 26 68 31 2c 20 28 76 6f 69 64 20 2a 29 26 61 48  &h1, (void *)&aH
10c70 64 72 5b 30 5d 2c 20 73 69 7a 65 6f 66 28 68 31  dr[0], sizeof(h1
10c80 29 29 3b 0a 20 20 77 61 6c 53 68 6d 42 61 72 72  ));.  walShmBarr
10c90 69 65 72 28 70 57 61 6c 29 3b 0a 20 20 6d 65 6d  ier(pWal);.  mem
10ca0 63 70 79 28 26 68 32 2c 20 28 76 6f 69 64 20 2a  cpy(&h2, (void *
10cb0 29 26 61 48 64 72 5b 31 5d 2c 20 73 69 7a 65 6f  )&aHdr[1], sizeo
10cc0 66 28 68 32 29 29 3b 0a 0a 20 20 69 66 28 20 6d  f(h2));..  if( m
10cd0 65 6d 63 6d 70 28 26 68 31 2c 20 26 68 32 2c 20  emcmp(&h1, &h2, 
10ce0 73 69 7a 65 6f 66 28 68 31 29 29 21 3d 30 20 29  sizeof(h1))!=0 )
10cf0 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b 20  {.    return 1; 
10d00 20 20 2f 2a 20 44 69 72 74 79 20 72 65 61 64 20    /* Dirty read 
10d10 2a 2f 0a 20 20 7d 20 20 0a 20 20 69 66 28 20 68  */.  }  .  if( h
10d20 31 2e 69 73 49 6e 69 74 3d 3d 30 20 29 7b 0a 20  1.isInit==0 ){. 
10d30 20 20 20 72 65 74 75 72 6e 20 31 3b 20 20 20 2f     return 1;   /
10d40 2a 20 4d 61 6c 66 6f 72 6d 65 64 20 68 65 61 64  * Malformed head
10d50 65 72 20 2d 20 70 72 6f 62 61 62 6c 79 20 61 6c  er - probably al
10d60 6c 20 7a 65 72 6f 73 20 2a 2f 0a 20 20 7d 0a 20  l zeros */.  }. 
10d70 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65   walChecksumByte
10d80 73 28 31 2c 20 28 75 38 2a 29 26 68 31 2c 20 73  s(1, (u8*)&h1, s
10d90 69 7a 65 6f 66 28 68 31 29 2d 73 69 7a 65 6f 66  izeof(h1)-sizeof
10da0 28 68 31 2e 61 43 6b 73 75 6d 29 2c 20 30 2c 20  (h1.aCksum), 0, 
10db0 61 43 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20 61  aCksum);.  if( a
10dc0 43 6b 73 75 6d 5b 30 5d 21 3d 68 31 2e 61 43 6b  Cksum[0]!=h1.aCk
10dd0 73 75 6d 5b 30 5d 20 7c 7c 20 61 43 6b 73 75 6d  sum[0] || aCksum
10de0 5b 31 5d 21 3d 68 31 2e 61 43 6b 73 75 6d 5b 31  [1]!=h1.aCksum[1
10df0 5d 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ] ){.    return 
10e00 31 3b 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d  1;   /* Checksum
10e10 20 64 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68 20   does not match 
10e20 2a 2f 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6d 65  */.  }..  if( me
10e30 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72 2c  mcmp(&pWal->hdr,
10e40 20 26 68 31 2c 20 73 69 7a 65 6f 66 28 57 61 6c   &h1, sizeof(Wal
10e50 49 6e 64 65 78 48 64 72 29 29 20 29 7b 0a 20 20  IndexHdr)) ){.  
10e60 20 20 2a 70 43 68 61 6e 67 65 64 20 3d 20 31 3b    *pChanged = 1;
10e70 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 57 61  .    memcpy(&pWa
10e80 6c 2d 3e 68 64 72 2c 20 26 68 31 2c 20 73 69 7a  l->hdr, &h1, siz
10e90 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29  eof(WalIndexHdr)
10ea0 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50  );.    pWal->szP
10eb0 61 67 65 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72  age = (pWal->hdr
10ec0 2e 73 7a 50 61 67 65 26 30 78 66 65 30 30 29 20  .szPage&0xfe00) 
10ed0 2b 20 28 28 70 57 61 6c 2d 3e 68 64 72 2e 73 7a  + ((pWal->hdr.sz
10ee0 50 61 67 65 26 30 78 30 30 30 31 29 3c 3c 31 36  Page&0x0001)<<16
10ef0 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73 65 28  );.    testcase(
10f00 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 3c 3d 33   pWal->szPage<=3
10f10 32 37 36 38 20 29 3b 0a 20 20 20 20 74 65 73 74  2768 );.    test
10f20 63 61 73 65 28 20 70 57 61 6c 2d 3e 73 7a 50 61  case( pWal->szPa
10f30 67 65 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 7d  ge>=65536 );.  }
10f40 0a 0a 20 20 2f 2a 20 54 68 65 20 68 65 61 64 65  ..  /* The heade
10f50 72 20 77 61 73 20 73 75 63 63 65 73 73 66 75 6c  r was successful
10f60 6c 79 20 72 65 61 64 2e 20 52 65 74 75 72 6e 20  ly read. Return 
10f70 7a 65 72 6f 2e 20 2a 2f 0a 20 20 72 65 74 75 72  zero. */.  retur
10f80 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  n 0;.}../*.** Re
10f90 61 64 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  ad the wal-index
10fa0 20 68 65 61 64 65 72 20 66 72 6f 6d 20 74 68 65   header from the
10fb0 20 77 61 6c 2d 69 6e 64 65 78 20 61 6e 64 20 69   wal-index and i
10fc0 6e 74 6f 20 70 57 61 6c 2d 3e 68 64 72 2e 0a 2a  nto pWal->hdr..*
10fd0 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 68 65 61  * If the wal-hea
10fe0 64 65 72 20 61 70 70 65 61 72 73 20 74 6f 20 62  der appears to b
10ff0 65 20 63 6f 72 72 75 70 74 2c 20 74 72 79 20 74  e corrupt, try t
11000 6f 20 72 65 63 6f 6e 73 74 72 75 63 74 20 74 68  o reconstruct th
11010 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 66  e.** wal-index f
11020 72 6f 6d 20 74 68 65 20 57 41 4c 20 62 65 66 6f  rom the WAL befo
11030 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2a  re returning..**
11040 0a 2a 2a 20 53 65 74 20 2a 70 43 68 61 6e 67 65  .** Set *pChange
11050 64 20 74 6f 20 31 20 69 66 20 74 68 65 20 77 61  d to 1 if the wa
11060 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 76  l-index header v
11070 61 6c 75 65 20 69 6e 20 70 57 61 6c 2d 3e 68 64  alue in pWal->hd
11080 72 20 69 73 0a 2a 2a 20 63 68 61 6e 67 65 64 20  r is.** changed 
11090 62 79 20 74 68 69 73 20 6f 70 65 72 74 69 6f 6e  by this opertion
110a0 2e 20 20 49 66 20 70 57 61 6c 2d 3e 68 64 72 20  .  If pWal->hdr 
110b0 69 73 20 75 6e 63 68 61 6e 67 65 64 2c 20 73 65  is unchanged, se
110c0 74 20 2a 70 43 68 61 6e 67 65 64 0a 2a 2a 20 74  t *pChanged.** t
110d0 6f 20 30 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  o 0..**.** If th
110e0 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
110f0 65 72 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  er is successful
11100 6c 79 20 72 65 61 64 2c 20 72 65 74 75 72 6e 20  ly read, return 
11110 53 51 4c 49 54 45 5f 4f 4b 2e 20 0a 2a 2a 20 4f  SQLITE_OK. .** O
11120 74 68 65 72 77 69 73 65 20 61 6e 20 53 51 4c 69  therwise an SQLi
11130 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a  te error code..*
11140 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
11150 49 6e 64 65 78 52 65 61 64 48 64 72 28 57 61 6c  IndexReadHdr(Wal
11160 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68   *pWal, int *pCh
11170 61 6e 67 65 64 29 7b 0a 20 20 69 6e 74 20 72 63  anged){.  int rc
11180 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
11190 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
111a0 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e  urn code */.  in
111b0 74 20 62 61 64 48 64 72 3b 20 20 20 20 20 20 20  t badHdr;       
111c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
111d0 20 54 72 75 65 20 69 66 20 61 20 68 65 61 64 65   True if a heade
111e0 72 20 72 65 61 64 20 66 61 69 6c 65 64 20 2a 2f  r read failed */
111f0 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20  .  volatile u32 
11200 2a 70 61 67 65 30 3b 20 20 20 20 20 20 20 20 20  *page0;         
11210 20 20 20 2f 2a 20 43 68 75 6e 6b 20 6f 66 20 77     /* Chunk of w
11220 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 74 61 69 6e  al-index contain
11230 69 6e 67 20 68 65 61 64 65 72 20 2a 2f 0a 0a 20  ing header */.. 
11240 20 2f 2a 20 45 6e 73 75 72 65 20 74 68 61 74 20   /* Ensure that 
11250 70 61 67 65 20 30 20 6f 66 20 74 68 65 20 77 61  page 0 of the wa
11260 6c 2d 69 6e 64 65 78 20 28 74 68 65 20 70 61 67  l-index (the pag
11270 65 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  e that contains 
11280 74 68 65 20 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e  the .  ** wal-in
11290 64 65 78 20 68 65 61 64 65 72 29 20 69 73 20 6d  dex header) is m
112a0 61 70 70 65 64 2e 20 52 65 74 75 72 6e 20 65 61  apped. Return ea
112b0 72 6c 79 20 69 66 20 61 6e 20 65 72 72 6f 72 20  rly if an error 
112c0 6f 63 63 75 72 73 20 68 65 72 65 2e 0a 20 20 2a  occurs here..  *
112d0 2f 0a 20 20 61 73 73 65 72 74 28 20 70 43 68 61  /.  assert( pCha
112e0 6e 67 65 64 20 29 3b 0a 20 20 72 63 20 3d 20 77  nged );.  rc = w
112f0 61 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c  alIndexPage(pWal
11300 2c 20 30 2c 20 26 70 61 67 65 30 29 3b 0a 20 20  , 0, &page0);.  
11310 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
11320 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  K ){.    return 
11330 72 63 3b 0a 20 20 7d 3b 0a 20 20 61 73 73 65 72  rc;.  };.  asser
11340 74 28 20 70 61 67 65 30 20 7c 7c 20 70 57 61 6c  t( page0 || pWal
11350 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29  ->writeLock==0 )
11360 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66  ;..  /* If the f
11370 69 72 73 74 20 70 61 67 65 20 6f 66 20 74 68 65  irst page of the
11380 20 77 61 6c 2d 69 6e 64 65 78 20 68 61 73 20 62   wal-index has b
11390 65 65 6e 20 6d 61 70 70 65 64 2c 20 74 72 79 20  een mapped, try 
113a0 74 6f 20 72 65 61 64 20 74 68 65 0a 20 20 2a 2a  to read the.  **
113b0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
113c0 72 20 69 6d 6d 65 64 69 61 74 65 6c 79 2c 20 77  r immediately, w
113d0 69 74 68 6f 75 74 20 68 6f 6c 64 69 6e 67 20 61  ithout holding a
113e0 6e 79 20 6c 6f 63 6b 2e 20 54 68 69 73 20 75 73  ny lock. This us
113f0 75 61 6c 6c 79 0a 20 20 2a 2a 20 77 6f 72 6b 73  ually.  ** works
11400 2c 20 62 75 74 20 6d 61 79 20 66 61 69 6c 20 69  , but may fail i
11410 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
11420 68 65 61 64 65 72 20 69 73 20 63 6f 72 72 75 70  header is corrup
11430 74 20 6f 72 20 63 75 72 72 65 6e 74 6c 79 20 0a  t or currently .
11440 20 20 2a 2a 20 62 65 69 6e 67 20 6d 6f 64 69 66    ** being modif
11450 69 65 64 20 62 79 20 61 6e 6f 74 68 65 72 20 74  ied by another t
11460 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73  hread or process
11470 2e 0a 20 20 2a 2f 0a 20 20 62 61 64 48 64 72 20  ..  */.  badHdr 
11480 3d 20 28 70 61 67 65 30 20 3f 20 77 61 6c 49 6e  = (page0 ? walIn
11490 64 65 78 54 72 79 48 64 72 28 70 57 61 6c 2c 20  dexTryHdr(pWal, 
114a0 70 43 68 61 6e 67 65 64 29 20 3a 20 31 29 3b 0a  pChanged) : 1);.
114b0 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72  .  /* If the fir
114c0 73 74 20 61 74 74 65 6d 70 74 20 66 61 69 6c 65  st attempt faile
114d0 64 2c 20 69 74 20 6d 69 67 68 74 20 68 61 76 65  d, it might have
114e0 20 62 65 65 6e 20 64 75 65 20 74 6f 20 61 20 72   been due to a r
114f0 61 63 65 0a 20 20 2a 2a 20 77 69 74 68 20 61 20  ace.  ** with a 
11500 77 72 69 74 65 72 2e 20 20 53 6f 20 67 65 74 20  writer.  So get 
11510 61 20 57 52 49 54 45 20 6c 6f 63 6b 20 61 6e 64  a WRITE lock and
11520 20 74 72 79 20 61 67 61 69 6e 2e 0a 20 20 2a 2f   try again..  */
11530 0a 20 20 61 73 73 65 72 74 28 20 62 61 64 48 64  .  assert( badHd
11540 72 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 77 72  r==0 || pWal->wr
11550 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20  iteLock==0 );.  
11560 69 66 28 20 62 61 64 48 64 72 20 26 26 20 53 51  if( badHdr && SQ
11570 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77  LITE_OK==(rc = w
11580 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  alLockExclusive(
11590 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f  pWal, WAL_WRITE_
115a0 4c 4f 43 4b 2c 20 31 29 29 20 29 7b 0a 20 20 20  LOCK, 1)) ){.   
115b0 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
115c0 20 3d 20 31 3b 0a 20 20 20 20 69 66 28 20 53 51   = 1;.    if( SQ
115d0 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77  LITE_OK==(rc = w
115e0 61 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c  alIndexPage(pWal
115f0 2c 20 30 2c 20 26 70 61 67 65 30 29 29 20 29 7b  , 0, &page0)) ){
11600 0a 20 20 20 20 20 20 62 61 64 48 64 72 20 3d 20  .      badHdr = 
11610 77 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28 70  walIndexTryHdr(p
11620 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b 0a  Wal, pChanged);.
11630 20 20 20 20 20 20 69 66 28 20 62 61 64 48 64 72        if( badHdr
11640 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49   ){.        /* I
11650 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
11660 68 65 61 64 65 72 20 69 73 20 73 74 69 6c 6c 20  header is still 
11670 6d 61 6c 66 6f 72 6d 65 64 20 65 76 65 6e 20 77  malformed even w
11680 68 69 6c 65 20 68 6f 6c 64 69 6e 67 0a 20 20 20  hile holding.   
11690 20 20 20 20 20 2a 2a 20 61 20 57 52 49 54 45 20       ** a WRITE 
116a0 6c 6f 63 6b 2c 20 69 74 20 63 61 6e 20 6f 6e 6c  lock, it can onl
116b0 79 20 6d 65 61 6e 20 74 68 61 74 20 74 68 65 20  y mean that the 
116c0 68 65 61 64 65 72 20 69 73 20 63 6f 72 72 75 70  header is corrup
116d0 74 65 64 20 61 6e 64 0a 20 20 20 20 20 20 20 20  ted and.        
116e0 2a 2a 20 6e 65 65 64 73 20 74 6f 20 62 65 20 72  ** needs to be r
116f0 65 63 6f 6e 73 74 72 75 63 74 65 64 2e 20 20 53  econstructed.  S
11700 6f 20 72 75 6e 20 72 65 63 6f 76 65 72 79 20 74  o run recovery t
11710 6f 20 64 6f 20 65 78 61 63 74 6c 79 20 74 68 61  o do exactly tha
11720 74 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20  t..        */.  
11730 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e        rc = walIn
11740 64 65 78 52 65 63 6f 76 65 72 28 70 57 61 6c 29  dexRecover(pWal)
11750 3b 0a 20 20 20 20 20 20 20 20 2a 70 43 68 61 6e  ;.        *pChan
11760 67 65 64 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d  ged = 1;.      }
11770 0a 20 20 20 20 7d 0a 20 20 20 20 70 57 61 6c 2d  .    }.    pWal-
11780 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a  >writeLock = 0;.
11790 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63      walUnlockExc
117a0 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
117b0 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b  _WRITE_LOCK, 1);
117c0 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68  .  }..  /* If th
117d0 65 20 68 65 61 64 65 72 20 69 73 20 72 65 61 64  e header is read
117e0 20 73 75 63 63 65 73 73 66 75 6c 6c 79 2c 20 63   successfully, c
117f0 68 65 63 6b 20 74 68 65 20 76 65 72 73 69 6f 6e  heck the version
11800 20 6e 75 6d 62 65 72 20 74 6f 20 6d 61 6b 65 0a   number to make.
11810 20 20 2a 2a 20 73 75 72 65 20 74 68 65 20 77 61    ** sure the wa
11820 6c 2d 69 6e 64 65 78 20 77 61 73 20 6e 6f 74 20  l-index was not 
11830 63 6f 6e 73 74 72 75 63 74 65 64 20 77 69 74 68  constructed with
11840 20 73 6f 6d 65 20 66 75 74 75 72 65 20 66 6f 72   some future for
11850 6d 61 74 20 74 68 61 74 0a 20 20 2a 2a 20 74 68  mat that.  ** th
11860 69 73 20 76 65 72 73 69 6f 6e 20 6f 66 20 53 51  is version of SQ
11870 4c 69 74 65 20 63 61 6e 6e 6f 74 20 75 6e 64 65  Lite cannot unde
11880 72 73 74 61 6e 64 2e 0a 20 20 2a 2f 0a 20 20 69  rstand..  */.  i
11890 66 28 20 62 61 64 48 64 72 3d 3d 30 20 26 26 20  f( badHdr==0 && 
118a0 70 57 61 6c 2d 3e 68 64 72 2e 69 56 65 72 73 69  pWal->hdr.iVersi
118b0 6f 6e 21 3d 57 41 4c 49 4e 44 45 58 5f 4d 41 58  on!=WALINDEX_MAX
118c0 5f 56 45 52 53 49 4f 4e 20 29 7b 0a 20 20 20 20  _VERSION ){.    
118d0 72 63 20 3d 20 53 51 4c 49 54 45 5f 43 41 4e 54  rc = SQLITE_CANT
118e0 4f 50 45 4e 5f 42 4b 50 54 3b 0a 20 20 7d 0a 0a  OPEN_BKPT;.  }..
118f0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
11900 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68  /*.** This is th
11910 65 20 76 61 6c 75 65 20 74 68 61 74 20 77 61 6c  e value that wal
11920 54 72 79 42 65 67 69 6e 52 65 61 64 20 72 65 74  TryBeginRead ret
11930 75 72 6e 73 20 77 68 65 6e 20 69 74 20 6e 65 65  urns when it nee
11940 64 73 20 74 6f 0a 2a 2a 20 62 65 20 72 65 74 72  ds to.** be retr
11950 69 65 64 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  ied..*/.#define 
11960 57 41 4c 5f 52 45 54 52 59 20 20 28 2d 31 29 0a  WAL_RETRY  (-1).
11970 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74  ./*.** Attempt t
11980 6f 20 73 74 61 72 74 20 61 20 72 65 61 64 20 74  o start a read t
11990 72 61 6e 73 61 63 74 69 6f 6e 2e 20 20 54 68 69  ransaction.  Thi
119a0 73 20 6d 69 67 68 74 20 66 61 69 6c 20 64 75 65  s might fail due
119b0 20 74 6f 20 61 20 72 61 63 65 20 6f 72 0a 2a 2a   to a race or.**
119c0 20 6f 74 68 65 72 20 74 72 61 6e 73 69 65 6e 74   other transient
119d0 20 63 6f 6e 64 69 74 69 6f 6e 2e 20 20 57 68 65   condition.  Whe
119e0 6e 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c 20  n that happens, 
119f0 69 74 20 72 65 74 75 72 6e 73 20 57 41 4c 5f 52  it returns WAL_R
11a00 45 54 52 59 20 74 6f 0a 2a 2a 20 69 6e 64 69 63  ETRY to.** indic
11a10 61 74 65 20 74 6f 20 74 68 65 20 63 61 6c 6c 65  ate to the calle
11a20 72 20 74 68 61 74 20 69 74 20 69 73 20 73 61 66  r that it is saf
11a30 65 20 74 6f 20 72 65 74 72 79 20 69 6d 6d 65 64  e to retry immed
11a40 69 61 74 65 6c 79 2e 0a 2a 2a 0a 2a 2a 20 4f 6e  iately..**.** On
11a50 20 73 75 63 63 65 73 73 20 72 65 74 75 72 6e 20   success return 
11a60 53 51 4c 49 54 45 5f 4f 4b 2e 20 20 4f 6e 20 61  SQLITE_OK.  On a
11a70 20 70 65 72 6d 61 6e 65 6e 74 20 66 61 69 6c 75   permanent failu
11a80 72 65 20 28 73 75 63 68 20 61 6e 0a 2a 2a 20 49  re (such an.** I
11a90 2f 4f 20 65 72 72 6f 72 20 6f 72 20 61 6e 20 53  /O error or an S
11aa0 51 4c 49 54 45 5f 42 55 53 59 20 62 65 63 61 75  QLITE_BUSY becau
11ab0 73 65 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65  se another proce
11ac0 73 73 20 69 73 20 72 75 6e 6e 69 6e 67 0a 2a 2a  ss is running.**
11ad0 20 72 65 63 6f 76 65 72 79 29 20 72 65 74 75 72   recovery) retur
11ae0 6e 20 61 20 70 6f 73 69 74 69 76 65 20 65 72 72  n a positive err
11af0 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 54  or code..**.** T
11b00 68 65 20 75 73 65 57 61 6c 20 70 61 72 61 6d 65  he useWal parame
11b10 74 65 72 20 69 73 20 74 72 75 65 20 74 6f 20 66  ter is true to f
11b20 6f 72 63 65 20 74 68 65 20 75 73 65 20 6f 66 20  orce the use of 
11b30 74 68 65 20 57 41 4c 20 61 6e 64 20 64 69 73 61  the WAL and disa
11b40 62 6c 65 0a 2a 2a 20 74 68 65 20 63 61 73 65 20  ble.** the case 
11b50 77 68 65 72 65 20 74 68 65 20 57 41 4c 20 69 73  where the WAL is
11b60 20 62 79 70 61 73 73 65 64 20 62 65 63 61 75 73   bypassed becaus
11b70 65 20 69 74 20 68 61 73 20 62 65 65 6e 20 63 6f  e it has been co
11b80 6d 70 6c 65 74 65 6c 79 0a 2a 2a 20 63 68 65 63  mpletely.** chec
11b90 6b 70 6f 69 6e 74 65 64 2e 20 20 49 66 20 75 73  kpointed.  If us
11ba0 65 57 61 6c 3d 3d 30 20 74 68 65 6e 20 74 68 69  eWal==0 then thi
11bb0 73 20 72 6f 75 74 69 6e 65 20 63 61 6c 6c 73 20  s routine calls 
11bc0 77 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28  walIndexReadHdr(
11bd0 29 20 0a 2a 2a 20 74 6f 20 6d 61 6b 65 20 61 20  ) .** to make a 
11be0 63 6f 70 79 20 6f 66 20 74 68 65 20 77 61 6c 2d  copy of the wal-
11bf0 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 6e 74  index header int
11c00 6f 20 70 57 61 6c 2d 3e 68 64 72 2e 20 20 49 66  o pWal->hdr.  If
11c10 20 74 68 65 20 0a 2a 2a 20 77 61 6c 2d 69 6e 64   the .** wal-ind
11c20 65 78 20 68 65 61 64 65 72 20 68 61 73 20 63 68  ex header has ch
11c30 61 6e 67 65 64 2c 20 2a 70 43 68 61 6e 67 65 64  anged, *pChanged
11c40 20 69 73 20 73 65 74 20 74 6f 20 31 20 28 61 73   is set to 1 (as
11c50 20 61 6e 20 69 6e 64 69 63 61 74 69 6f 6e 20 0a   an indication .
11c60 2a 2a 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72  ** to the caller
11c70 20 74 68 61 74 20 74 68 65 20 6c 6f 63 61 6c 20   that the local 
11c80 70 61 67 65 74 20 63 61 63 68 65 20 69 73 20 6f  paget cache is o
11c90 62 73 6f 6c 65 74 65 20 61 6e 64 20 6e 65 65 64  bsolete and need
11ca0 73 20 74 6f 20 62 65 20 0a 2a 2a 20 66 6c 75 73  s to be .** flus
11cb0 68 65 64 2e 29 20 20 57 68 65 6e 20 75 73 65 57  hed.)  When useW
11cc0 61 6c 3d 3d 31 2c 20 74 68 65 20 77 61 6c 2d 69  al==1, the wal-i
11cd0 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20 61  ndex header is a
11ce0 73 73 75 6d 65 64 20 74 6f 20 61 6c 72 65 61 64  ssumed to alread
11cf0 79 0a 2a 2a 20 62 65 20 6c 6f 61 64 65 64 20 61  y.** be loaded a
11d00 6e 64 20 74 68 65 20 70 43 68 61 6e 67 65 64 20  nd the pChanged 
11d10 70 61 72 61 6d 65 74 65 72 20 69 73 20 75 6e 75  parameter is unu
11d20 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63  sed..**.** The c
11d30 61 6c 6c 65 72 20 6d 75 73 74 20 73 65 74 20 74  aller must set t
11d40 68 65 20 63 6e 74 20 70 61 72 61 6d 65 74 65 72  he cnt parameter
11d50 20 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 20 6f   to the number o
11d60 66 20 70 72 69 6f 72 20 63 61 6c 6c 73 20 74 6f  f prior calls to
11d70 0a 2a 2a 20 74 68 69 73 20 72 6f 75 74 69 6e 65  .** this routine
11d80 20 64 75 72 69 6e 67 20 74 68 65 20 63 75 72 72   during the curr
11d90 65 6e 74 20 72 65 61 64 20 61 74 74 65 6d 70 74  ent read attempt
11da0 20 74 68 61 74 20 72 65 74 75 72 6e 65 64 20 57   that returned W
11db0 41 4c 5f 52 45 54 52 59 2e 0a 2a 2a 20 54 68 69  AL_RETRY..** Thi
11dc0 73 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20 73  s routine will s
11dd0 74 61 72 74 20 74 61 6b 69 6e 67 20 6d 6f 72 65  tart taking more
11de0 20 61 67 67 72 65 73 73 69 76 65 20 6d 65 61 73   aggressive meas
11df0 75 72 65 73 20 74 6f 20 63 6c 65 61 72 20 74 68  ures to clear th
11e00 65 0a 2a 2a 20 72 61 63 65 20 63 6f 6e 64 69 74  e.** race condit
11e10 69 6f 6e 73 20 61 66 74 65 72 20 6d 75 6c 74 69  ions after multi
11e20 70 6c 65 20 57 41 4c 5f 52 45 54 52 59 20 72 65  ple WAL_RETRY re
11e30 74 75 72 6e 73 2c 20 61 6e 64 20 61 66 74 65 72  turns, and after
11e40 20 61 6e 20 65 78 63 65 73 73 69 76 65 0a 2a 2a   an excessive.**
11e50 20 6e 75 6d 62 65 72 20 6f 66 20 65 72 72 6f 72   number of error
11e60 73 20 77 69 6c 6c 20 75 6c 74 69 6d 61 74 65 6c  s will ultimatel
11e70 79 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  y return SQLITE_
11e80 50 52 4f 54 4f 43 4f 4c 2e 20 20 54 68 65 0a 2a  PROTOCOL.  The.*
11e90 2a 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f  * SQLITE_PROTOCO
11ea0 4c 20 72 65 74 75 72 6e 20 69 6e 64 69 63 61 74  L return indicat
11eb0 65 73 20 74 68 61 74 20 73 6f 6d 65 20 6f 74 68  es that some oth
11ec0 65 72 20 70 72 6f 63 65 73 73 20 68 61 73 20 67  er process has g
11ed0 6f 6e 65 20 72 6f 67 75 65 0a 2a 2a 20 61 6e 64  one rogue.** and
11ee0 20 69 73 20 6e 6f 74 20 68 6f 6e 6f 72 69 6e 67   is not honoring
11ef0 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 70 72 6f   the locking pro
11f00 74 6f 63 6f 6c 2e 20 20 54 68 65 72 65 20 69 73  tocol.  There is
11f10 20 61 20 76 61 6e 69 73 68 69 6e 67 6c 79 20 73   a vanishingly s
11f20 6d 61 6c 6c 0a 2a 2a 20 63 68 61 6e 63 65 20 74  mall.** chance t
11f30 68 61 74 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f  hat SQLITE_PROTO
11f40 43 4f 4c 20 63 6f 75 6c 64 20 62 65 20 72 65 74  COL could be ret
11f50 75 72 6e 65 64 20 62 65 63 61 75 73 65 20 6f 66  urned because of
11f60 20 61 20 72 75 6e 20 6f 66 20 72 65 61 6c 6c 79   a run of really
11f70 0a 2a 2a 20 62 61 64 20 6c 75 63 6b 20 77 68 65  .** bad luck whe
11f80 6e 20 74 68 65 72 65 20 69 73 20 6c 6f 74 73 20  n there is lots 
11f90 6f 66 20 63 6f 6e 74 65 6e 74 69 6f 6e 20 66 6f  of contention fo
11fa0 72 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2c  r the wal-index,
11fb0 20 62 75 74 20 74 68 61 74 0a 2a 2a 20 70 6f 73   but that.** pos
11fc0 73 69 62 69 6c 69 74 79 20 69 73 20 73 6f 20 73  sibility is so s
11fd0 6d 61 6c 6c 20 74 68 61 74 20 69 74 20 63 61 6e  mall that it can
11fe0 20 62 65 20 73 61 66 65 6c 79 20 6e 65 67 6c 65   be safely negle
11ff0 63 74 65 64 2c 20 77 65 20 62 65 6c 69 65 76 65  cted, we believe
12000 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63 65  ..**.** On succe
12010 73 73 2c 20 74 68 69 73 20 72 6f 75 74 69 6e 65  ss, this routine
12020 20 6f 62 74 61 69 6e 73 20 61 20 72 65 61 64 20   obtains a read 
12030 6c 6f 63 6b 20 6f 6e 20 0a 2a 2a 20 57 41 4c 5f  lock on .** WAL_
12040 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e  READ_LOCK(pWal->
12050 72 65 61 64 4c 6f 63 6b 29 2e 20 20 54 68 65 20  readLock).  The 
12060 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69  pWal->readLock i
12070 6e 74 65 67 65 72 20 69 73 0a 2a 2a 20 69 6e 20  nteger is.** in 
12080 74 68 65 20 72 61 6e 67 65 20 30 20 3c 3d 20 70  the range 0 <= p
12090 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3c 20  Wal->readLock < 
120a0 57 41 4c 5f 4e 52 45 41 44 45 52 2e 20 20 49 66  WAL_NREADER.  If
120b0 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d   pWal->readLock=
120c0 3d 28 2d 31 29 0a 2a 2a 20 74 68 61 74 20 6d 65  =(-1).** that me
120d0 61 6e 73 20 74 68 65 20 57 61 6c 20 64 6f 65 73  ans the Wal does
120e0 20 6e 6f 74 20 68 6f 6c 64 20 61 6e 79 20 72 65   not hold any re
120f0 61 64 20 6c 6f 63 6b 2e 20 20 54 68 65 20 72 65  ad lock.  The re
12100 61 64 65 72 20 6d 75 73 74 20 6e 6f 74 0a 2a 2a  ader must not.**
12110 20 61 63 63 65 73 73 20 61 6e 79 20 64 61 74 61   access any data
12120 62 61 73 65 20 70 61 67 65 20 74 68 61 74 20 69  base page that i
12130 73 20 6d 6f 64 69 66 69 65 64 20 62 79 20 61 20  s modified by a 
12140 57 41 4c 20 66 72 61 6d 65 20 75 70 20 74 6f 20  WAL frame up to 
12150 61 6e 64 0a 2a 2a 20 69 6e 63 6c 75 64 69 6e 67  and.** including
12160 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 61 52   frame number aR
12170 65 61 64 4d 61 72 6b 5b 70 57 61 6c 2d 3e 72 65  eadMark[pWal->re
12180 61 64 4c 6f 63 6b 5d 2e 20 20 54 68 65 20 72 65  adLock].  The re
12190 61 64 65 72 20 77 69 6c 6c 0a 2a 2a 20 75 73 65  ader will.** use
121a0 20 57 41 4c 20 66 72 61 6d 65 73 20 75 70 20 74   WAL frames up t
121b0 6f 20 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20  o and including 
121c0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
121d0 65 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c  e if pWal->readL
121e0 6f 63 6b 3e 30 0a 2a 2a 20 4f 72 20 69 66 20 70  ock>0.** Or if p
121f0 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30  Wal->readLock==0
12200 2c 20 74 68 65 6e 20 74 68 65 20 72 65 61 64 65  , then the reade
12210 72 20 77 69 6c 6c 20 69 67 6e 6f 72 65 20 74 68  r will ignore th
12220 65 20 57 41 4c 0a 2a 2a 20 63 6f 6d 70 6c 65 74  e WAL.** complet
12230 65 6c 79 20 61 6e 64 20 67 65 74 20 61 6c 6c 20  ely and get all 
12240 63 6f 6e 74 65 6e 74 20 64 69 72 65 63 74 6c 79  content directly
12250 20 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61   from the databa
12260 73 65 20 66 69 6c 65 2e 0a 2a 2a 20 49 66 20 74  se file..** If t
12270 68 65 20 75 73 65 57 61 6c 20 70 61 72 61 6d 65  he useWal parame
12280 74 65 72 20 69 73 20 31 20 74 68 65 6e 20 74 68  ter is 1 then th
12290 65 20 57 41 4c 20 77 69 6c 6c 20 6e 65 76 65 72  e WAL will never
122a0 20 62 65 20 69 67 6e 6f 72 65 64 20 61 6e 64 0a   be ignored and.
122b0 2a 2a 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  ** this routine 
122c0 77 69 6c 6c 20 61 6c 77 61 79 73 20 73 65 74 20  will always set 
122d0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 30  pWal->readLock>0
122e0 20 6f 6e 20 73 75 63 63 65 73 73 2e 0a 2a 2a 20   on success..** 
122f0 57 68 65 6e 20 74 68 65 20 72 65 61 64 20 74 72  When the read tr
12300 61 6e 73 61 63 74 69 6f 6e 20 69 73 20 63 6f 6d  ansaction is com
12310 70 6c 65 74 65 64 2c 20 74 68 65 20 63 61 6c 6c  pleted, the call
12320 65 72 20 6d 75 73 74 20 72 65 6c 65 61 73 65 20  er must release 
12330 74 68 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20 57  the.** lock on W
12340 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61  AL_READ_LOCK(pWa
12350 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 20 61 6e 64  l->readLock) and
12360 20 73 65 74 20 70 57 61 6c 2d 3e 72 65 61 64 4c   set pWal->readL
12370 6f 63 6b 20 74 6f 20 2d 31 2e 0a 2a 2a 0a 2a 2a  ock to -1..**.**
12380 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 75 73   This routine us
12390 65 73 20 74 68 65 20 6e 42 61 63 6b 66 69 6c 6c  es the nBackfill
123a0 20 61 6e 64 20 61 52 65 61 64 4d 61 72 6b 5b 5d   and aReadMark[]
123b0 20 66 69 65 6c 64 73 20 6f 66 20 74 68 65 20 68   fields of the h
123c0 65 61 64 65 72 0a 2a 2a 20 74 6f 20 73 65 6c 65  eader.** to sele
123d0 63 74 20 61 20 70 61 72 74 69 63 75 6c 61 72 20  ct a particular 
123e0 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 29 20  WAL_READ_LOCK() 
123f0 74 68 61 74 20 73 74 72 69 76 65 73 20 74 6f 20  that strives to 
12400 6c 65 74 20 74 68 65 0a 2a 2a 20 63 68 65 63 6b  let the.** check
12410 70 6f 69 6e 74 20 70 72 6f 63 65 73 73 20 64 6f  point process do
12420 20 61 73 20 6d 75 63 68 20 77 6f 72 6b 20 61 73   as much work as
12430 20 70 6f 73 73 69 62 6c 65 2e 20 20 54 68 69 73   possible.  This
12440 20 72 6f 75 74 69 6e 65 20 6d 69 67 68 74 0a 2a   routine might.*
12450 2a 20 75 70 64 61 74 65 20 76 61 6c 75 65 73 20  * update values 
12460 6f 66 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b  of the aReadMark
12470 5b 5d 20 61 72 72 61 79 20 69 6e 20 74 68 65 20  [] array in the 
12480 68 65 61 64 65 72 2c 20 62 75 74 20 69 66 20 69  header, but if i
12490 74 20 64 6f 65 73 0a 2a 2a 20 73 6f 20 69 74 20  t does.** so it 
124a0 74 61 6b 65 73 20 63 61 72 65 20 74 6f 20 68 6f  takes care to ho
124b0 6c 64 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20  ld an exclusive 
124c0 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 63 6f 72 72  lock on the corr
124d0 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20 57 41 4c  esponding.** WAL
124e0 5f 52 45 41 44 5f 4c 4f 43 4b 28 29 20 77 68 69  _READ_LOCK() whi
124f0 6c 65 20 63 68 61 6e 67 69 6e 67 20 76 61 6c 75  le changing valu
12500 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  es..*/.static in
12510 74 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61  t walTryBeginRea
12520 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  d(Wal *pWal, int
12530 20 2a 70 43 68 61 6e 67 65 64 2c 20 69 6e 74 20   *pChanged, int 
12540 75 73 65 57 61 6c 2c 20 69 6e 74 20 63 6e 74 29  useWal, int cnt)
12550 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c  {.  volatile Wal
12560 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b  CkptInfo *pInfo;
12570 20 20 20 20 2f 2a 20 43 68 65 63 6b 70 6f 69 6e      /* Checkpoin
12580 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e  t information in
12590 20 77 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a 20 20   wal-index */.  
125a0 75 33 32 20 6d 78 52 65 61 64 4d 61 72 6b 3b 20  u32 mxReadMark; 
125b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
125c0 2f 2a 20 4c 61 72 67 65 73 74 20 61 52 65 61 64  /* Largest aRead
125d0 4d 61 72 6b 5b 5d 20 76 61 6c 75 65 20 2a 2f 0a  Mark[] value */.
125e0 20 20 69 6e 74 20 6d 78 49 3b 20 20 20 20 20 20    int mxI;      
125f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12600 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6c 61    /* Index of la
12610 72 67 65 73 74 20 61 52 65 61 64 4d 61 72 6b 5b  rgest aReadMark[
12620 5d 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74  ] value */.  int
12630 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
12640 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12650 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a  Loop counter */.
12660 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
12670 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  E_OK;           
12680 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
12690 20 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20    */..  assert( 
126a0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3c 30  pWal->readLock<0
126b0 20 29 3b 20 20 20 20 20 2f 2a 20 4e 6f 74 20 63   );     /* Not c
126c0 75 72 72 65 6e 74 6c 79 20 6c 6f 63 6b 65 64 20  urrently locked 
126d0 2a 2f 0a 0a 20 20 2f 2a 20 54 61 6b 65 20 73 74  */..  /* Take st
126e0 65 70 73 20 74 6f 20 61 76 6f 69 64 20 73 70 69  eps to avoid spi
126f0 6e 6e 69 6e 67 20 66 6f 72 65 76 65 72 20 69 66  nning forever if
12700 20 74 68 65 72 65 20 69 73 20 61 20 70 72 6f 74   there is a prot
12710 6f 63 6f 6c 20 65 72 72 6f 72 2e 20 2a 2f 0a 20  ocol error. */. 
12720 20 69 66 28 20 63 6e 74 3e 35 20 29 7b 0a 20 20   if( cnt>5 ){.  
12730 20 20 69 66 28 20 63 6e 74 3e 31 30 30 20 29 20    if( cnt>100 ) 
12740 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 50 52  return SQLITE_PR
12750 4f 54 4f 43 4f 4c 3b 0a 20 20 20 20 73 71 6c 69  OTOCOL;.    sqli
12760 74 65 33 4f 73 53 6c 65 65 70 28 70 57 61 6c 2d  te3OsSleep(pWal-
12770 3e 70 56 66 73 2c 20 31 29 3b 0a 20 20 7d 0a 0a  >pVfs, 1);.  }..
12780 20 20 69 66 28 20 21 75 73 65 57 61 6c 20 29 7b    if( !useWal ){
12790 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64  .    rc = walInd
127a0 65 78 52 65 61 64 48 64 72 28 70 57 61 6c 2c 20  exReadHdr(pWal, 
127b0 70 43 68 61 6e 67 65 64 29 3b 0a 20 20 20 20 69  pChanged);.    i
127c0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  f( rc==SQLITE_BU
127d0 53 59 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 49  SY ){.      /* I
127e0 66 20 74 68 65 72 65 20 69 73 20 6e 6f 74 20 61  f there is not a
127f0 20 72 65 63 6f 76 65 72 79 20 72 75 6e 6e 69 6e   recovery runnin
12800 67 20 69 6e 20 61 6e 6f 74 68 65 72 20 74 68 72  g in another thr
12810 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 0a 20  ead or process. 
12820 20 20 20 20 20 2a 2a 20 74 68 65 6e 20 63 6f 6e       ** then con
12830 76 65 72 74 20 42 55 53 59 20 65 72 72 6f 72 73  vert BUSY errors
12840 20 74 6f 20 57 41 4c 5f 52 45 54 52 59 2e 20 20   to WAL_RETRY.  
12850 49 66 20 72 65 63 6f 76 65 72 79 20 69 73 20 6b  If recovery is k
12860 6e 6f 77 6e 20 74 6f 0a 20 20 20 20 20 20 2a 2a  nown to.      **
12870 20 62 65 20 72 75 6e 6e 69 6e 67 2c 20 63 6f 6e   be running, con
12880 76 65 72 74 20 42 55 53 59 20 74 6f 20 42 55 53  vert BUSY to BUS
12890 59 5f 52 45 43 4f 56 45 52 59 2e 20 20 54 68 65  Y_RECOVERY.  The
128a0 72 65 20 69 73 20 61 20 72 61 63 65 20 68 65 72  re is a race her
128b0 65 0a 20 20 20 20 20 20 2a 2a 20 77 68 69 63 68  e.      ** which
128c0 20 6d 69 67 68 74 20 63 61 75 73 65 20 57 41 4c   might cause WAL
128d0 5f 52 45 54 52 59 20 74 6f 20 62 65 20 72 65 74  _RETRY to be ret
128e0 75 72 6e 65 64 20 65 76 65 6e 20 69 66 20 42 55  urned even if BU
128f0 53 59 5f 52 45 43 4f 56 45 52 59 0a 20 20 20 20  SY_RECOVERY.    
12900 20 20 2a 2a 20 77 6f 75 6c 64 20 62 65 20 74 65    ** would be te
12910 63 68 6e 69 63 61 6c 6c 79 20 63 6f 72 72 65 63  chnically correc
12920 74 2e 20 20 42 75 74 20 74 68 65 20 72 61 63 65  t.  But the race
12930 20 69 73 20 62 65 6e 69 67 6e 20 73 69 6e 63 65   is benign since
12940 20 77 69 74 68 0a 20 20 20 20 20 20 2a 2a 20 57   with.      ** W
12950 41 4c 5f 52 45 54 52 59 20 74 68 69 73 20 72 6f  AL_RETRY this ro
12960 75 74 69 6e 65 20 77 69 6c 6c 20 62 65 20 63 61  utine will be ca
12970 6c 6c 65 64 20 61 67 61 69 6e 20 61 6e 64 20 77  lled again and w
12980 69 6c 6c 20 70 72 6f 62 61 62 6c 79 20 62 65 0a  ill probably be.
12990 20 20 20 20 20 20 2a 2a 20 72 69 67 68 74 20 6f        ** right o
129a0 6e 20 74 68 65 20 73 65 63 6f 6e 64 20 69 74 65  n the second ite
129b0 72 61 74 69 6f 6e 2e 0a 20 20 20 20 20 20 2a 2f  ration..      */
129c0 0a 20 20 20 20 20 20 69 66 28 20 70 57 61 6c 2d  .      if( pWal-
129d0 3e 61 70 57 69 44 61 74 61 5b 30 5d 3d 3d 30 20  >apWiData[0]==0 
129e0 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 54 68  ){.        /* Th
129f0 69 73 20 62 72 61 6e 63 68 20 69 73 20 74 61 6b  is branch is tak
12a00 65 6e 20 77 68 65 6e 20 74 68 65 20 78 53 68 6d  en when the xShm
12a10 4d 61 70 28 29 20 6d 65 74 68 6f 64 20 72 65 74  Map() method ret
12a20 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53 59  urns SQLITE_BUSY
12a30 2e 0a 20 20 20 20 20 20 20 20 2a 2a 20 57 65 20  ..        ** We 
12a40 61 73 73 75 6d 65 20 74 68 69 73 20 69 73 20 61  assume this is a
12a50 20 74 72 61 6e 73 69 65 6e 74 20 63 6f 6e 64 69   transient condi
12a60 74 69 6f 6e 2c 20 73 6f 20 72 65 74 75 72 6e 20  tion, so return 
12a70 57 41 4c 5f 52 45 54 52 59 2e 20 54 68 65 0a 20  WAL_RETRY. The. 
12a80 20 20 20 20 20 20 20 2a 2a 20 78 53 68 6d 4d 61         ** xShmMa
12a90 70 28 29 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  p() implementati
12aa0 6f 6e 20 75 73 65 64 20 62 79 20 74 68 65 20 64  on used by the d
12ab0 65 66 61 75 6c 74 20 75 6e 69 78 20 61 6e 64 20  efault unix and 
12ac0 77 69 6e 33 32 20 56 46 53 20 0a 20 20 20 20 20  win32 VFS .     
12ad0 20 20 20 2a 2a 20 6d 6f 64 75 6c 65 73 20 6d 61     ** modules ma
12ae0 79 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  y return SQLITE_
12af0 42 55 53 59 20 64 75 65 20 74 6f 20 61 20 72 61  BUSY due to a ra
12b00 63 65 20 63 6f 6e 64 69 74 69 6f 6e 20 69 6e 20  ce condition in 
12b10 74 68 65 20 0a 20 20 20 20 20 20 20 20 2a 2a 20  the .        ** 
12b20 63 6f 64 65 20 74 68 61 74 20 64 65 74 65 72 6d  code that determ
12b30 69 6e 65 73 20 77 68 65 74 68 65 72 20 6f 72 20  ines whether or 
12b40 6e 6f 74 20 74 68 65 20 73 68 61 72 65 64 2d 6d  not the shared-m
12b50 65 6d 6f 72 79 20 72 65 67 69 6f 6e 20 0a 20 20  emory region .  
12b60 20 20 20 20 20 20 2a 2a 20 6d 75 73 74 20 62 65        ** must be
12b70 20 7a 65 72 6f 65 64 20 62 65 66 6f 72 65 20 74   zeroed before t
12b80 68 65 20 72 65 71 75 65 73 74 65 64 20 70 61 67  he requested pag
12b90 65 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 20  e is returned.. 
12ba0 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20         */.      
12bb0 20 20 72 63 20 3d 20 57 41 4c 5f 52 45 54 52 59    rc = WAL_RETRY
12bc0 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  ;.      }else if
12bd0 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63  ( SQLITE_OK==(rc
12be0 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64   = walLockShared
12bf0 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 43 4f 56  (pWal, WAL_RECOV
12c00 45 52 5f 4c 4f 43 4b 29 29 20 29 7b 0a 20 20 20  ER_LOCK)) ){.   
12c10 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68       walUnlockSh
12c20 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
12c30 45 43 4f 56 45 52 5f 4c 4f 43 4b 29 3b 0a 20 20  ECOVER_LOCK);.  
12c40 20 20 20 20 20 20 72 63 20 3d 20 57 41 4c 5f 52        rc = WAL_R
12c50 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 65 6c 73  ETRY;.      }els
12c60 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45  e if( rc==SQLITE
12c70 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20 20  _BUSY ){.       
12c80 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55 53   rc = SQLITE_BUS
12c90 59 5f 52 45 43 4f 56 45 52 59 3b 0a 20 20 20 20  Y_RECOVERY;.    
12ca0 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
12cb0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
12cc0 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
12cd0 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  rc;.    }.  }.. 
12ce0 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74   pInfo = walCkpt
12cf0 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 69 66  Info(pWal);.  if
12d00 28 20 21 75 73 65 57 61 6c 20 26 26 20 70 49 6e  ( !useWal && pIn
12d10 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70  fo->nBackfill==p
12d20 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
12d30 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 57   ){.    /* The W
12d40 41 4c 20 68 61 73 20 62 65 65 6e 20 63 6f 6d 70  AL has been comp
12d50 6c 65 74 65 6c 79 20 62 61 63 6b 66 69 6c 6c 65  letely backfille
12d60 64 20 28 6f 72 20 69 74 20 69 73 20 65 6d 70 74  d (or it is empt
12d70 79 29 2e 0a 20 20 20 20 2a 2a 20 61 6e 64 20 63  y)..    ** and c
12d80 61 6e 20 62 65 20 73 61 66 65 6c 79 20 69 67 6e  an be safely ign
12d90 6f 72 65 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  ored..    */.   
12da0 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61   rc = walLockSha
12db0 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
12dc0 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20  AD_LOCK(0));.   
12dd0 20 77 61 6c 53 68 6d 42 61 72 72 69 65 72 28 70   walShmBarrier(p
12de0 57 61 6c 29 3b 0a 20 20 20 20 69 66 28 20 72 63  Wal);.    if( rc
12df0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
12e00 20 20 20 20 20 69 66 28 20 6d 65 6d 63 6d 70 28       if( memcmp(
12e10 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78  (void *)walIndex
12e20 48 64 72 28 70 57 61 6c 29 2c 20 26 70 57 61 6c  Hdr(pWal), &pWal
12e30 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61  ->hdr, sizeof(Wa
12e40 6c 49 6e 64 65 78 48 64 72 29 29 20 29 7b 0a 20  lIndexHdr)) ){. 
12e50 20 20 20 20 20 20 20 2f 2a 20 49 74 20 69 73 20         /* It is 
12e60 6e 6f 74 20 73 61 66 65 20 74 6f 20 61 6c 6c 6f  not safe to allo
12e70 77 20 74 68 65 20 72 65 61 64 65 72 20 74 6f 20  w the reader to 
12e80 63 6f 6e 74 69 6e 75 65 20 68 65 72 65 20 69 66  continue here if
12e90 20 66 72 61 6d 65 73 0a 20 20 20 20 20 20 20 20   frames.        
12ea0 2a 2a 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e  ** may have been
12eb0 20 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65   appended to the
12ec0 20 6c 6f 67 20 62 65 66 6f 72 65 20 52 45 41 44   log before READ
12ed0 5f 4c 4f 43 4b 28 30 29 20 77 61 73 20 6f 62 74  _LOCK(0) was obt
12ee0 61 69 6e 65 64 2e 0a 20 20 20 20 20 20 20 20 2a  ained..        *
12ef0 2a 20 57 68 65 6e 20 68 6f 6c 64 69 6e 67 20 52  * When holding R
12f00 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 74 68 65  EAD_LOCK(0), the
12f10 20 72 65 61 64 65 72 20 69 67 6e 6f 72 65 73 20   reader ignores 
12f20 74 68 65 20 65 6e 74 69 72 65 20 6c 6f 67 20 66  the entire log f
12f30 69 6c 65 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20  ile,.        ** 
12f40 77 68 69 63 68 20 69 6d 70 6c 69 65 73 20 74 68  which implies th
12f50 61 74 20 74 68 65 20 64 61 74 61 62 61 73 65 20  at the database 
12f60 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 61 20  file contains a 
12f70 74 72 75 73 74 77 6f 72 74 68 79 0a 20 20 20 20  trustworthy.    
12f80 20 20 20 20 2a 2a 20 73 6e 61 70 73 68 6f 54 2e      ** snapshoT.
12f90 20 53 69 6e 63 65 20 68 6f 6c 64 69 6e 67 20 52   Since holding R
12fa0 45 41 44 5f 4c 4f 43 4b 28 30 29 20 70 72 65 76  EAD_LOCK(0) prev
12fb0 65 6e 74 73 20 61 20 63 68 65 63 6b 70 6f 69 6e  ents a checkpoin
12fc0 74 20 66 72 6f 6d 0a 20 20 20 20 20 20 20 20 2a  t from.        *
12fd0 2a 20 68 61 70 70 65 6e 69 6e 67 2c 20 74 68 69  * happening, thi
12fe0 73 20 69 73 20 75 73 75 61 6c 6c 79 20 63 6f 72  s is usually cor
12ff0 72 65 63 74 2e 0a 20 20 20 20 20 20 20 20 2a 2a  rect..        **
13000 0a 20 20 20 20 20 20 20 20 2a 2a 20 48 6f 77 65  .        ** Howe
13010 76 65 72 2c 20 69 66 20 66 72 61 6d 65 73 20 68  ver, if frames h
13020 61 76 65 20 62 65 65 6e 20 61 70 70 65 6e 64 65  ave been appende
13030 64 20 74 6f 20 74 68 65 20 6c 6f 67 20 28 6f 72  d to the log (or
13040 20 69 66 20 74 68 65 20 6c 6f 67 20 0a 20 20 20   if the log .   
13050 20 20 20 20 20 2a 2a 20 69 73 20 77 72 61 70 70       ** is wrapp
13060 65 64 20 61 6e 64 20 77 72 69 74 74 65 6e 20 66  ed and written f
13070 6f 72 20 74 68 61 74 20 6d 61 74 74 65 72 29 20  or that matter) 
13080 62 65 66 6f 72 65 20 74 68 65 20 52 45 41 44 5f  before the READ_
13090 4c 4f 43 4b 28 30 29 0a 20 20 20 20 20 20 20 20  LOCK(0).        
130a0 2a 2a 20 69 73 20 6f 62 74 61 69 6e 65 64 2c 20  ** is obtained, 
130b0 74 68 61 74 20 69 73 20 6e 6f 74 20 6e 65 63 65  that is not nece
130c0 73 73 61 72 69 6c 79 20 74 72 75 65 2e 20 41 20  ssarily true. A 
130d0 63 68 65 63 6b 70 6f 69 6e 74 65 72 20 6d 61 79  checkpointer may
130e0 0a 20 20 20 20 20 20 20 20 2a 2a 20 68 61 76 65  .        ** have
130f0 20 73 74 61 72 74 65 64 20 74 6f 20 62 61 63 6b   started to back
13100 66 69 6c 6c 20 74 68 65 20 61 70 70 65 6e 64 65  fill the appende
13110 64 20 66 72 61 6d 65 73 20 62 75 74 20 63 72 61  d frames but cra
13120 73 68 65 64 20 62 65 66 6f 72 65 0a 20 20 20 20  shed before.    
13130 20 20 20 20 2a 2a 20 69 74 20 66 69 6e 69 73 68      ** it finish
13140 65 64 2e 20 4c 65 61 76 69 6e 67 20 61 20 63 6f  ed. Leaving a co
13150 72 72 75 70 74 20 69 6d 61 67 65 20 69 6e 20 74  rrupt image in t
13160 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
13170 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20  ..        */.   
13180 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68       walUnlockSh
13190 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
131a0 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20  EAD_LOCK(0));.  
131b0 20 20 20 20 20 20 72 65 74 75 72 6e 20 57 41 4c        return WAL
131c0 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 0a  _RETRY;.      }.
131d0 20 20 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64        pWal->read
131e0 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20  Lock = 0;.      
131f0 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
13200 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  ;.    }else if( 
13210 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc!=SQLITE_BUSY 
13220 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
13230 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  rc;.    }.  }.. 
13240 20 2f 2a 20 49 66 20 77 65 20 67 65 74 20 74 68   /* If we get th
13250 69 73 20 66 61 72 2c 20 69 74 20 6d 65 61 6e 73  is far, it means
13260 20 74 68 61 74 20 74 68 65 20 72 65 61 64 65 72   that the reader
13270 20 77 69 6c 6c 20 77 61 6e 74 20 74 6f 20 75 73   will want to us
13280 65 0a 20 20 2a 2a 20 74 68 65 20 57 41 4c 20 74  e.  ** the WAL t
13290 6f 20 67 65 74 20 61 74 20 63 6f 6e 74 65 6e 74  o get at content
132a0 20 66 72 6f 6d 20 72 65 63 65 6e 74 20 63 6f 6d   from recent com
132b0 6d 69 74 73 2e 20 20 54 68 65 20 6a 6f 62 20 6e  mits.  The job n
132c0 6f 77 20 69 73 0a 20 20 2a 2a 20 74 6f 20 73 65  ow is.  ** to se
132d0 6c 65 63 74 20 6f 6e 65 20 6f 66 20 74 68 65 20  lect one of the 
132e0 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e 74 72  aReadMark[] entr
132f0 69 65 73 20 74 68 61 74 20 69 73 20 63 6c 6f 73  ies that is clos
13300 65 73 74 20 74 6f 0a 20 20 2a 2a 20 62 75 74 20  est to.  ** but 
13310 6e 6f 74 20 65 78 63 65 65 64 69 6e 67 20 70 57  not exceeding pW
13320 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
13330 61 6e 64 20 6c 6f 63 6b 20 74 68 61 74 20 65 6e  and lock that en
13340 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 6d 78 52 65  try..  */.  mxRe
13350 61 64 4d 61 72 6b 20 3d 20 30 3b 0a 20 20 6d 78  adMark = 0;.  mx
13360 49 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d 31  I = 0;.  for(i=1
13370 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b  ; i<WAL_NREADER;
13380 20 69 2b 2b 29 7b 0a 20 20 20 20 75 33 32 20 74   i++){.    u32 t
13390 68 69 73 4d 61 72 6b 20 3d 20 70 49 6e 66 6f 2d  hisMark = pInfo-
133a0 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20  >aReadMark[i];. 
133b0 20 20 20 69 66 28 20 6d 78 52 65 61 64 4d 61 72     if( mxReadMar
133c0 6b 3c 3d 74 68 69 73 4d 61 72 6b 20 26 26 20 74  k<=thisMark && t
133d0 68 69 73 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e 68  hisMark<=pWal->h
133e0 64 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20  dr.mxFrame ){.  
133f0 20 20 20 20 61 73 73 65 72 74 28 20 74 68 69 73      assert( this
13400 4d 61 72 6b 21 3d 52 45 41 44 4d 41 52 4b 5f 4e  Mark!=READMARK_N
13410 4f 54 5f 55 53 45 44 20 29 3b 0a 20 20 20 20 20  OT_USED );.     
13420 20 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20 74 68   mxReadMark = th
13430 69 73 4d 61 72 6b 3b 0a 20 20 20 20 20 20 6d 78  isMark;.      mx
13440 49 20 3d 20 69 3b 0a 20 20 20 20 7d 0a 20 20 7d  I = i;.    }.  }
13450 0a 20 20 69 66 28 20 6d 78 49 3d 3d 30 20 29 7b  .  if( mxI==0 ){
13460 0a 20 20 20 20 2f 2a 20 49 66 20 77 65 20 67 65  .    /* If we ge
13470 74 20 68 65 72 65 2c 20 69 74 20 6d 65 61 6e 73  t here, it means
13480 20 74 68 61 74 20 61 6c 6c 20 6f 66 20 74 68 65   that all of the
13490 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e 74   aReadMark[] ent
134a0 72 69 65 73 20 62 65 74 77 65 65 6e 0a 20 20 20  ries between.   
134b0 20 2a 2a 20 31 20 61 6e 64 20 57 41 4c 5f 4e 52   ** 1 and WAL_NR
134c0 45 41 44 45 52 2d 31 20 61 72 65 20 7a 65 72 6f  EADER-1 are zero
134d0 2e 20 20 54 72 79 20 74 6f 20 69 6e 69 74 69 61  .  Try to initia
134e0 6c 69 7a 65 20 61 52 65 61 64 4d 61 72 6b 5b 31  lize aReadMark[1
134f0 5d 20 74 6f 0a 20 20 20 20 2a 2a 20 62 65 20 6d  ] to.    ** be m
13500 78 46 72 61 6d 65 2c 20 74 68 65 6e 20 72 65 74  xFrame, then ret
13510 72 79 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 72  ry..    */.    r
13520 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75  c = walLockExclu
13530 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52  sive(pWal, WAL_R
13540 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 31 29 3b  EAD_LOCK(1), 1);
13550 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
13560 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
13570 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b  pInfo->aReadMark
13580 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  [1] = pWal->hdr.
13590 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 77  mxFrame;.      w
135a0 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
135b0 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
135c0 5f 4c 4f 43 4b 28 31 29 2c 20 31 29 3b 0a 20 20  _LOCK(1), 1);.  
135d0 20 20 20 20 72 63 20 3d 20 57 41 4c 5f 52 45 54      rc = WAL_RET
135e0 52 59 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  RY;.    }else if
135f0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc==SQLITE_BUS
13600 59 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  Y ){.      rc = 
13610 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 7d  WAL_RETRY;.    }
13620 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
13630 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66 28    }else{.    if(
13640 20 6d 78 52 65 61 64 4d 61 72 6b 20 3c 20 70 57   mxReadMark < pW
13650 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
13660 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 31  ){.      for(i=1
13670 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b  ; i<WAL_NREADER;
13680 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 72   i++){.        r
13690 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75  c = walLockExclu
136a0 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52  sive(pWal, WAL_R
136b0 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b  EAD_LOCK(i), 1);
136c0 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d  .        if( rc=
136d0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
136e0 20 20 20 20 20 20 20 20 6d 78 52 65 61 64 4d 61          mxReadMa
136f0 72 6b 20 3d 20 70 49 6e 66 6f 2d 3e 61 52 65 61  rk = pInfo->aRea
13700 64 4d 61 72 6b 5b 69 5d 20 3d 20 70 57 61 6c 2d  dMark[i] = pWal-
13710 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20  >hdr.mxFrame;.  
13720 20 20 20 20 20 20 20 20 6d 78 49 20 3d 20 69 3b          mxI = i;
13730 0a 20 20 20 20 20 20 20 20 20 20 77 61 6c 55 6e  .          walUn
13740 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  lockExclusive(pW
13750 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  al, WAL_READ_LOC
13760 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20 20 20 20  K(i), 1);.      
13770 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20      break;.     
13780 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 21     }else if( rc!
13790 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a  =SQLITE_BUSY ){.
137a0 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
137b0 20 72 63 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20   rc;.        }. 
137c0 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
137d0 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68    rc = walLockSh
137e0 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
137f0 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b 0a  EAD_LOCK(mxI));.
13800 20 20 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20      if( rc ){.  
13810 20 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d 53      return rc==S
13820 51 4c 49 54 45 5f 42 55 53 59 20 3f 20 57 41 4c  QLITE_BUSY ? WAL
13830 5f 52 45 54 52 59 20 3a 20 72 63 3b 0a 20 20 20  _RETRY : rc;.   
13840 20 7d 0a 20 20 20 20 2f 2a 20 4e 6f 77 20 74 68   }.    /* Now th
13850 61 74 20 74 68 65 20 72 65 61 64 2d 6c 6f 63 6b  at the read-lock
13860 20 68 61 73 20 62 65 65 6e 20 6f 62 74 61 69 6e   has been obtain
13870 65 64 2c 20 63 68 65 63 6b 20 74 68 61 74 20 6e  ed, check that n
13880 65 69 74 68 65 72 20 74 68 65 0a 20 20 20 20 2a  either the.    *
13890 2a 20 76 61 6c 75 65 20 69 6e 20 74 68 65 20 61  * value in the a
138a0 52 65 61 64 4d 61 72 6b 5b 5d 20 61 72 72 61 79  ReadMark[] array
138b0 20 6f 72 20 74 68 65 20 63 6f 6e 74 65 6e 74 73   or the contents
138c0 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
138d0 78 0a 20 20 20 20 2a 2a 20 68 65 61 64 65 72 20  x.    ** header 
138e0 68 61 76 65 20 63 68 61 6e 67 65 64 2e 0a 20 20  have changed..  
138f0 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 49 74 20 69    **.    ** It i
13900 73 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20 63  s necessary to c
13910 68 65 63 6b 20 74 68 61 74 20 74 68 65 20 77 61  heck that the wa
13920 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 64  l-index header d
13930 69 64 20 6e 6f 74 20 63 68 61 6e 67 65 0a 20 20  id not change.  
13940 20 20 2a 2a 20 62 65 74 77 65 65 6e 20 74 68 65    ** between the
13950 20 74 69 6d 65 20 69 74 20 77 61 73 20 72 65 61   time it was rea
13960 64 20 61 6e 64 20 77 68 65 6e 20 74 68 65 20 73  d and when the s
13970 68 61 72 65 64 2d 6c 6f 63 6b 20 77 61 73 20 6f  hared-lock was o
13980 62 74 61 69 6e 65 64 0a 20 20 20 20 2a 2a 20 6f  btained.    ** o
13990 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  n WAL_READ_LOCK(
139a0 6d 78 49 29 20 77 61 73 20 6f 62 74 61 69 6e 65  mxI) was obtaine
139b0 64 20 74 6f 20 61 63 63 6f 75 6e 74 20 66 6f 72  d to account for
139c0 20 74 68 65 20 70 6f 73 73 69 62 69 6c 69 74 79   the possibility
139d0 0a 20 20 20 20 2a 2a 20 74 68 61 74 20 74 68 65  .    ** that the
139e0 20 6c 6f 67 20 66 69 6c 65 20 6d 61 79 20 68 61   log file may ha
139f0 76 65 20 62 65 65 6e 20 77 72 61 70 70 65 64 20  ve been wrapped 
13a00 62 79 20 61 20 77 72 69 74 65 72 2c 20 6f 72 20  by a writer, or 
13a10 74 68 61 74 20 66 72 61 6d 65 73 0a 20 20 20 20  that frames.    
13a20 2a 2a 20 74 68 61 74 20 6f 63 63 75 72 20 6c 61  ** that occur la
13a30 74 65 72 20 69 6e 20 74 68 65 20 6c 6f 67 20 74  ter in the log t
13a40 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  han pWal->hdr.mx
13a50 46 72 61 6d 65 20 6d 61 79 20 68 61 76 65 20 62  Frame may have b
13a60 65 65 6e 0a 20 20 20 20 2a 2a 20 63 6f 70 69 65  een.    ** copie
13a70 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  d into the datab
13a80 61 73 65 20 62 79 20 61 20 63 68 65 63 6b 70 6f  ase by a checkpo
13a90 69 6e 74 65 72 2e 20 49 66 20 65 69 74 68 65 72  inter. If either
13aa0 20 6f 66 20 74 68 65 73 65 20 74 68 69 6e 67 73   of these things
13ab0 0a 20 20 20 20 2a 2a 20 68 61 70 70 65 6e 65 64  .    ** happened
13ac0 2c 20 74 68 65 6e 20 72 65 61 64 69 6e 67 20 74  , then reading t
13ad0 68 65 20 64 61 74 61 62 61 73 65 20 77 69 74 68  he database with
13ae0 20 74 68 65 20 63 75 72 72 65 6e 74 20 76 61 6c   the current val
13af0 75 65 20 6f 66 0a 20 20 20 20 2a 2a 20 70 57 61  ue of.    ** pWa
13b00 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 72  l->hdr.mxFrame r
13b10 69 73 6b 73 20 72 65 61 64 69 6e 67 20 61 20 63  isks reading a c
13b20 6f 72 72 75 70 74 65 64 20 73 6e 61 70 73 68 6f  orrupted snapsho
13b30 74 2e 20 53 6f 2c 20 72 65 74 72 79 0a 20 20 20  t. So, retry.   
13b40 20 2a 2a 20 69 6e 73 74 65 61 64 2e 0a 20 20 20   ** instead..   
13b50 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68 69 73 20   **.    ** This 
13b60 64 6f 65 73 20 6e 6f 74 20 67 75 61 72 61 6e 74  does not guarant
13b70 65 65 20 74 68 61 74 20 74 68 65 20 63 6f 70 79  ee that the copy
13b80 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
13b90 78 20 68 65 61 64 65 72 20 69 73 20 75 70 20 74  x header is up t
13ba0 6f 0a 20 20 20 20 2a 2a 20 64 61 74 65 20 62 65  o.    ** date be
13bb0 66 6f 72 65 20 70 72 6f 63 65 65 64 69 6e 67 2e  fore proceeding.
13bc0 20 54 68 61 74 20 77 6f 75 6c 64 20 6e 6f 74 20   That would not 
13bd0 62 65 20 70 6f 73 73 69 62 6c 65 20 77 69 74 68  be possible with
13be0 6f 75 74 20 73 6f 6d 65 68 6f 77 0a 20 20 20 20  out somehow.    
13bf0 2a 2a 20 62 6c 6f 63 6b 69 6e 67 20 77 72 69 74  ** blocking writ
13c00 65 72 73 2e 20 49 74 20 6f 6e 6c 79 20 67 75 61  ers. It only gua
13c10 72 61 6e 74 65 65 73 20 74 68 61 74 20 61 20 64  rantees that a d
13c20 61 6e 67 65 72 6f 75 73 20 63 68 65 63 6b 70 6f  angerous checkpo
13c30 69 6e 74 20 6f 72 20 0a 20 20 20 20 2a 2a 20 6c  int or .    ** l
13c40 6f 67 2d 77 72 61 70 20 28 65 69 74 68 65 72 20  og-wrap (either 
13c50 6f 66 20 77 68 69 63 68 20 77 6f 75 6c 64 20 72  of which would r
13c60 65 71 75 69 72 65 20 61 6e 20 65 78 63 6c 75 73  equire an exclus
13c70 69 76 65 20 6c 6f 63 6b 20 6f 6e 0a 20 20 20 20  ive lock on.    
13c80 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  ** WAL_READ_LOCK
13c90 28 6d 78 49 29 29 20 68 61 73 20 6e 6f 74 20 6f  (mxI)) has not o
13ca0 63 63 75 72 72 65 64 20 73 69 6e 63 65 20 74 68  ccurred since th
13cb0 65 20 73 6e 61 70 73 68 6f 74 20 77 61 73 20 76  e snapshot was v
13cc0 61 6c 69 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  alid..    */.   
13cd0 20 77 61 6c 53 68 6d 42 61 72 72 69 65 72 28 70   walShmBarrier(p
13ce0 57 61 6c 29 3b 0a 20 20 20 20 69 66 28 20 70 49  Wal);.    if( pI
13cf0 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 6d  nfo->aReadMark[m
13d00 78 49 5d 21 3d 6d 78 52 65 61 64 4d 61 72 6b 0a  xI]!=mxReadMark.
13d10 20 20 20 20 20 7c 7c 20 6d 65 6d 63 6d 70 28 28       || memcmp((
13d20 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48  void *)walIndexH
13d30 64 72 28 70 57 61 6c 29 2c 20 26 70 57 61 6c 2d  dr(pWal), &pWal-
13d40 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c  >hdr, sizeof(Wal
13d50 49 6e 64 65 78 48 64 72 29 29 0a 20 20 20 20 29  IndexHdr)).    )
13d60 7b 0a 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63  {.      walUnloc
13d70 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
13d80 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29  L_READ_LOCK(mxI)
13d90 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  );.      return 
13da0 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 7d  WAL_RETRY;.    }
13db0 65 6c 73 65 7b 0a 20 20 20 20 20 20 61 73 73 65  else{.      asse
13dc0 72 74 28 20 6d 78 52 65 61 64 4d 61 72 6b 3c 3d  rt( mxReadMark<=
13dd0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
13de0 65 20 29 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d  e );.      pWal-
13df0 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 28 69 31 36  >readLock = (i16
13e00 29 6d 78 49 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  )mxI;.    }.  }.
13e10 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
13e20 2f 2a 0a 2a 2a 20 42 65 67 69 6e 20 61 20 72 65  /*.** Begin a re
13e30 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f  ad transaction o
13e40 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a  n the database..
13e50 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  **.** This routi
13e60 6e 65 20 75 73 65 64 20 74 6f 20 62 65 20 63 61  ne used to be ca
13e70 6c 6c 65 64 20 73 71 6c 69 74 65 33 4f 70 65 6e  lled sqlite3Open
13e80 53 6e 61 70 73 68 6f 74 28 29 20 61 6e 64 20 77  Snapshot() and w
13e90 69 74 68 20 67 6f 6f 64 20 72 65 61 73 6f 6e 3a  ith good reason:
13ea0 0a 2a 2a 20 69 74 20 74 61 6b 65 73 20 61 20 73  .** it takes a s
13eb0 6e 61 70 73 68 6f 74 20 6f 66 20 74 68 65 20 73  napshot of the s
13ec0 74 61 74 65 20 6f 66 20 74 68 65 20 57 41 4c 20  tate of the WAL 
13ed0 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 6f  and wal-index fo
13ee0 72 20 74 68 65 20 63 75 72 72 65 6e 74 0a 2a 2a  r the current.**
13ef0 20 69 6e 73 74 61 6e 74 20 69 6e 20 74 69 6d 65   instant in time
13f00 2e 20 20 54 68 65 20 63 75 72 72 65 6e 74 20 74  .  The current t
13f10 68 72 65 61 64 20 77 69 6c 6c 20 63 6f 6e 74 69  hread will conti
13f20 6e 75 65 20 74 6f 20 75 73 65 20 74 68 69 73 20  nue to use this 
13f30 73 6e 61 70 73 68 6f 74 2e 0a 2a 2a 20 4f 74 68  snapshot..** Oth
13f40 65 72 20 74 68 72 65 61 64 73 20 6d 69 67 68 74  er threads might
13f50 20 61 70 70 65 6e 64 20 6e 65 77 20 63 6f 6e 74   append new cont
13f60 65 6e 74 20 74 6f 20 74 68 65 20 57 41 4c 20 61  ent to the WAL a
13f70 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 62 75 74  nd wal-index but
13f80 0a 2a 2a 20 74 68 61 74 20 65 78 74 72 61 20 63  .** that extra c
13f90 6f 6e 74 65 6e 74 20 69 73 20 69 67 6e 6f 72 65  ontent is ignore
13fa0 64 20 62 79 20 74 68 65 20 63 75 72 72 65 6e 74  d by the current
13fb0 20 74 68 72 65 61 64 2e 0a 2a 2a 0a 2a 2a 20 49   thread..**.** I
13fc0 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20 63  f the database c
13fd0 6f 6e 74 65 6e 74 73 20 68 61 76 65 20 63 68 61  ontents have cha
13fe0 6e 67 65 73 20 73 69 6e 63 65 20 74 68 65 20 70  nges since the p
13ff0 72 65 76 69 6f 75 73 20 72 65 61 64 0a 2a 2a 20  revious read.** 
14000 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20 74 68 65  transaction, the
14010 6e 20 2a 70 43 68 61 6e 67 65 64 20 69 73 20 73  n *pChanged is s
14020 65 74 20 74 6f 20 31 20 62 65 66 6f 72 65 20 72  et to 1 before r
14030 65 74 75 72 6e 69 6e 67 2e 20 20 54 68 65 0a 2a  eturning.  The.*
14040 2a 20 50 61 67 65 72 20 6c 61 79 65 72 20 77 69  * Pager layer wi
14050 6c 6c 20 75 73 65 20 74 68 69 73 20 74 6f 20 6b  ll use this to k
14060 6e 6f 77 20 74 68 61 74 20 69 73 20 63 61 63 68  now that is cach
14070 65 20 69 73 20 73 74 61 6c 65 20 61 6e 64 0a 2a  e is stale and.*
14080 2a 20 6e 65 65 64 73 20 74 6f 20 62 65 20 66 6c  * needs to be fl
14090 75 73 68 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71  ushed..*/.int sq
140a0 6c 69 74 65 33 57 61 6c 42 65 67 69 6e 52 65 61  lite3WalBeginRea
140b0 64 54 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c  dTransaction(Wal
140c0 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68   *pWal, int *pCh
140d0 61 6e 67 65 64 29 7b 0a 20 20 69 6e 74 20 72 63  anged){.  int rc
140e0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
140f0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
14100 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e  urn code */.  in
14110 74 20 63 6e 74 20 3d 20 30 3b 20 20 20 20 20 20  t cnt = 0;      
14120 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
14130 20 4e 75 6d 62 65 72 20 6f 66 20 54 72 79 42 65   Number of TryBe
14140 67 69 6e 52 65 61 64 20 61 74 74 65 6d 70 74 73  ginRead attempts
14150 20 2a 2f 0a 0a 20 20 64 6f 7b 0a 20 20 20 20 72   */..  do{.    r
14160 63 20 3d 20 77 61 6c 54 72 79 42 65 67 69 6e 52  c = walTryBeginR
14170 65 61 64 28 70 57 61 6c 2c 20 70 43 68 61 6e 67  ead(pWal, pChang
14180 65 64 2c 20 30 2c 20 2b 2b 63 6e 74 29 3b 0a 20  ed, 0, ++cnt);. 
14190 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d 57 41 4c   }while( rc==WAL
141a0 5f 52 45 54 52 59 20 29 3b 0a 20 20 72 65 74 75  _RETRY );.  retu
141b0 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
141c0 46 69 6e 69 73 68 20 77 69 74 68 20 61 20 72 65  Finish with a re
141d0 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20  ad transaction. 
141e0 20 41 6c 6c 20 74 68 69 73 20 64 6f 65 73 20 69   All this does i
141f0 73 20 72 65 6c 65 61 73 65 20 74 68 65 0a 2a 2a  s release the.**
14200 20 72 65 61 64 2d 6c 6f 63 6b 2e 0a 2a 2f 0a 76   read-lock..*/.v
14210 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 45 6e  oid sqlite3WalEn
14220 64 52 65 61 64 54 72 61 6e 73 61 63 74 69 6f 6e  dReadTransaction
14230 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 73  (Wal *pWal){.  s
14240 71 6c 69 74 65 33 57 61 6c 45 6e 64 57 72 69 74  qlite3WalEndWrit
14250 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 70 57 61  eTransaction(pWa
14260 6c 29 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  l);.  if( pWal->
14270 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 7b 0a 20  readLock>=0 ){. 
14280 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72     walUnlockShar
14290 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ed(pWal, WAL_REA
142a0 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61  D_LOCK(pWal->rea
142b0 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70 57 61  dLock));.    pWa
142c0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31  l->readLock = -1
142d0 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  ;.  }.}../*.** R
142e0 65 61 64 20 61 20 70 61 67 65 20 66 72 6f 6d 20  ead a page from 
142f0 74 68 65 20 57 41 4c 2c 20 69 66 20 69 74 20 69  the WAL, if it i
14300 73 20 70 72 65 73 65 6e 74 20 69 6e 20 74 68 65  s present in the
14310 20 57 41 4c 20 61 6e 64 20 69 66 20 74 68 65 20   WAL and if the 
14320 0a 2a 2a 20 63 75 72 72 65 6e 74 20 72 65 61 64  .** current read
14330 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20   transaction is 
14340 63 6f 6e 66 69 67 75 72 65 64 20 74 6f 20 75 73  configured to us
14350 65 20 74 68 65 20 57 41 4c 2e 20 20 0a 2a 2a 0a  e the WAL.  .**.
14360 2a 2a 20 54 68 65 20 2a 70 49 6e 57 61 6c 20 69  ** The *pInWal i
14370 73 20 73 65 74 20 74 6f 20 31 20 69 66 20 74 68  s set to 1 if th
14380 65 20 72 65 71 75 65 73 74 65 64 20 70 61 67 65  e requested page
14390 20 69 73 20 69 6e 20 74 68 65 20 57 41 4c 20 61   is in the WAL a
143a0 6e 64 0a 2a 2a 20 68 61 73 20 62 65 65 6e 20 6c  nd.** has been l
143b0 6f 61 64 65 64 2e 20 20 4f 72 20 2a 70 49 6e 57  oaded.  Or *pInW
143c0 61 6c 20 69 73 20 73 65 74 20 74 6f 20 30 20 69  al is set to 0 i
143d0 66 20 74 68 65 20 70 61 67 65 20 77 61 73 20 6e  f the page was n
143e0 6f 74 20 69 6e 20 0a 2a 2a 20 74 68 65 20 57 41  ot in .** the WA
143f0 4c 20 61 6e 64 20 6e 65 65 64 73 20 74 6f 20 62  L and needs to b
14400 65 20 72 65 61 64 20 6f 75 74 20 6f 66 20 74 68  e read out of th
14410 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2f 0a 69  e database..*/.i
14420 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 52 65 61  nt sqlite3WalRea
14430 64 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20  d(.  Wal *pWal, 
14440 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14450 20 20 20 20 20 2f 2a 20 57 41 4c 20 68 61 6e 64       /* WAL hand
14460 6c 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e  le */.  Pgno pgn
14470 6f 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o,              
14480 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
14490 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  ase page number 
144a0 74 6f 20 72 65 61 64 20 64 61 74 61 20 66 6f 72  to read data for
144b0 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 49 6e 57 61   */.  int *pInWa
144c0 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
144d0 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 72        /* OUT: Tr
144e0 75 65 20 69 66 20 64 61 74 61 20 69 73 20 72 65  ue if data is re
144f0 61 64 20 66 72 6f 6d 20 57 41 4c 20 2a 2f 0a 20  ad from WAL */. 
14500 20 69 6e 74 20 6e 4f 75 74 2c 20 20 20 20 20 20   int nOut,      
14510 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14520 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62 75 66 66   /* Size of buff
14530 65 72 20 70 4f 75 74 20 69 6e 20 62 79 74 65 73  er pOut in bytes
14540 20 2a 2f 0a 20 20 75 38 20 2a 70 4f 75 74 20 20   */.  u8 *pOut  
14550 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14560 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
14570 74 6f 20 77 72 69 74 65 20 70 61 67 65 20 64 61  to write page da
14580 74 61 20 74 6f 20 2a 2f 0a 29 7b 0a 20 20 75 33  ta to */.){.  u3
14590 32 20 69 52 65 61 64 20 3d 20 30 3b 20 20 20 20  2 iRead = 0;    
145a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
145b0 20 49 66 20 21 3d 30 2c 20 57 41 4c 20 66 72 61   If !=0, WAL fra
145c0 6d 65 20 74 6f 20 72 65 74 75 72 6e 20 64 61 74  me to return dat
145d0 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 75 33 32 20  a from */.  u32 
145e0 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d 3e 68 64  iLast = pWal->hd
145f0 72 2e 6d 78 46 72 61 6d 65 3b 20 20 2f 2a 20 4c  r.mxFrame;  /* L
14600 61 73 74 20 70 61 67 65 20 69 6e 20 57 41 4c 20  ast page in WAL 
14610 66 6f 72 20 74 68 69 73 20 72 65 61 64 65 72 20  for this reader 
14620 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73 68 3b 20  */.  int iHash; 
14630 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14640 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
14650 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20 4e 20 68  loop through N h
14660 61 73 68 20 74 61 62 6c 65 73 20 2a 2f 0a 0a 20  ash tables */.. 
14670 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65   /* This routine
14680 20 69 73 20 6f 6e 6c 79 20 62 65 20 63 61 6c 6c   is only be call
14690 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 61  ed from within a
146a0 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
146b0 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  n. */.  assert( 
146c0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
146d0 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45  0 || pWal->lockE
146e0 72 72 6f 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66  rror );..  /* If
146f0 20 74 68 65 20 22 6c 61 73 74 20 70 61 67 65 22   the "last page"
14700 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20 77 61   field of the wa
14710 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 73  l-index header s
14720 6e 61 70 73 68 6f 74 20 69 73 20 30 2c 20 74 68  napshot is 0, th
14730 65 6e 0a 20 20 2a 2a 20 6e 6f 20 64 61 74 61 20  en.  ** no data 
14740 77 69 6c 6c 20 62 65 20 72 65 61 64 20 66 72 6f  will be read fro
14750 6d 20 74 68 65 20 77 61 6c 20 75 6e 64 65 72 20  m the wal under 
14760 61 6e 79 20 63 69 72 63 75 6d 73 74 61 6e 63 65  any circumstance
14770 73 2e 20 52 65 74 75 72 6e 20 65 61 72 6c 79 0a  s. Return early.
14780 20 20 2a 2a 20 69 6e 20 74 68 69 73 20 63 61 73    ** in this cas
14790 65 20 61 73 20 61 6e 20 6f 70 74 69 6d 69 7a 61  e as an optimiza
147a0 74 69 6f 6e 2e 20 20 4c 69 6b 65 77 69 73 65 2c  tion.  Likewise,
147b0 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f   if pWal->readLo
147c0 63 6b 3d 3d 30 2c 20 0a 20 20 2a 2a 20 74 68 65  ck==0, .  ** the
147d0 6e 20 74 68 65 20 57 41 4c 20 69 73 20 69 67 6e  n the WAL is ign
147e0 6f 72 65 64 20 62 79 20 74 68 65 20 72 65 61 64  ored by the read
147f0 65 72 20 73 6f 20 72 65 74 75 72 6e 20 65 61 72  er so return ear
14800 6c 79 2c 20 61 73 20 69 66 20 74 68 65 20 0a 20  ly, as if the . 
14810 20 2a 2a 20 57 41 4c 20 77 65 72 65 20 65 6d 70   ** WAL were emp
14820 74 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69  ty..  */.  if( i
14830 4c 61 73 74 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d  Last==0 || pWal-
14840 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20 29 7b 0a  >readLock==0 ){.
14850 20 20 20 20 2a 70 49 6e 57 61 6c 20 3d 20 30 3b      *pInWal = 0;
14860 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
14870 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  TE_OK;.  }..  /*
14880 20 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68   Search the hash
14890 20 74 61 62 6c 65 20 6f 72 20 74 61 62 6c 65 73   table or tables
148a0 20 66 6f 72 20 61 6e 20 65 6e 74 72 79 20 6d 61   for an entry ma
148b0 74 63 68 69 6e 67 20 70 61 67 65 20 6e 75 6d 62  tching page numb
148c0 65 72 0a 20 20 2a 2a 20 70 67 6e 6f 2e 20 45 61  er.  ** pgno. Ea
148d0 63 68 20 69 74 65 72 61 74 69 6f 6e 20 6f 66 20  ch iteration of 
148e0 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 66 6f  the following fo
148f0 72 28 29 20 6c 6f 6f 70 20 73 65 61 72 63 68 65  r() loop searche
14900 73 20 6f 6e 65 0a 20 20 2a 2a 20 68 61 73 68 20  s one.  ** hash 
14910 74 61 62 6c 65 20 28 65 61 63 68 20 68 61 73 68  table (each hash
14920 20 74 61 62 6c 65 20 69 6e 64 65 78 65 73 20 75   table indexes u
14930 70 20 74 6f 20 48 41 53 48 54 41 42 4c 45 5f 4e  p to HASHTABLE_N
14940 50 41 47 45 20 66 72 61 6d 65 73 29 2e 0a 20 20  PAGE frames)..  
14950 2a 2a 0a 20 20 2a 2a 20 54 68 69 73 20 63 6f 64  **.  ** This cod
14960 65 20 6d 69 67 68 74 20 72 75 6e 20 63 6f 6e 63  e might run conc
14970 75 72 72 65 6e 74 6c 79 20 74 6f 20 74 68 65 20  urrently to the 
14980 63 6f 64 65 20 69 6e 20 77 61 6c 49 6e 64 65 78  code in walIndex
14990 41 70 70 65 6e 64 28 29 0a 20 20 2a 2a 20 74 68  Append().  ** th
149a0 61 74 20 61 64 64 73 20 65 6e 74 72 69 65 73 20  at adds entries 
149b0 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  to the wal-index
149c0 20 28 61 6e 64 20 70 6f 73 73 69 62 6c 79 20 74   (and possibly t
149d0 6f 20 74 68 69 73 20 68 61 73 68 20 0a 20 20 2a  o this hash .  *
149e0 2a 20 74 61 62 6c 65 29 2e 20 54 68 69 73 20 6d  * table). This m
149f0 65 61 6e 73 20 74 68 65 20 76 61 6c 75 65 20 6a  eans the value j
14a00 75 73 74 20 72 65 61 64 20 66 72 6f 6d 20 74 68  ust read from th
14a10 65 20 68 61 73 68 20 0a 20 20 2a 2a 20 73 6c 6f  e hash .  ** slo
14a20 74 20 28 61 48 61 73 68 5b 69 4b 65 79 5d 29 20  t (aHash[iKey]) 
14a30 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 61 64  may have been ad
14a40 64 65 64 20 62 65 66 6f 72 65 20 6f 72 20 61 66  ded before or af
14a50 74 65 72 20 74 68 65 20 0a 20 20 2a 2a 20 63 75  ter the .  ** cu
14a60 72 72 65 6e 74 20 72 65 61 64 20 74 72 61 6e 73  rrent read trans
14a70 61 63 74 69 6f 6e 20 77 61 73 20 6f 70 65 6e 65  action was opene
14a80 64 2e 20 56 61 6c 75 65 73 20 61 64 64 65 64 20  d. Values added 
14a90 61 66 74 65 72 20 74 68 65 0a 20 20 2a 2a 20 72  after the.  ** r
14aa0 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
14ab0 77 61 73 20 6f 70 65 6e 65 64 20 6d 61 79 20 68  was opened may h
14ac0 61 76 65 20 62 65 65 6e 20 77 72 69 74 74 65 6e  ave been written
14ad0 20 69 6e 63 6f 72 72 65 63 74 6c 79 20 2d 0a 20   incorrectly -. 
14ae0 20 2a 2a 20 69 2e 65 2e 20 74 68 65 73 65 20 73   ** i.e. these s
14af0 6c 6f 74 73 20 6d 61 79 20 63 6f 6e 74 61 69 6e  lots may contain
14b00 20 67 61 72 62 61 67 65 20 64 61 74 61 2e 20 48   garbage data. H
14b10 6f 77 65 76 65 72 2c 20 77 65 20 61 73 73 75 6d  owever, we assum
14b20 65 0a 20 20 2a 2a 20 74 68 61 74 20 61 6e 79 20  e.  ** that any 
14b30 73 6c 6f 74 73 20 77 72 69 74 74 65 6e 20 62 65  slots written be
14b40 66 6f 72 65 20 74 68 65 20 63 75 72 72 65 6e 74  fore the current
14b50 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
14b60 6e 20 77 61 73 0a 20 20 2a 2a 20 6f 70 65 6e 65  n was.  ** opene
14b70 64 20 72 65 6d 61 69 6e 20 75 6e 6d 6f 64 69 66  d remain unmodif
14b80 69 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 46  ied..  **.  ** F
14b90 6f 72 20 74 68 65 20 72 65 61 73 6f 6e 73 20 61  or the reasons a
14ba0 62 6f 76 65 2c 20 74 68 65 20 69 66 28 2e 2e 2e  bove, the if(...
14bb0 29 20 63 6f 6e 64 69 74 69 6f 6e 20 66 65 61 74  ) condition feat
14bc0 75 72 65 64 20 69 6e 20 74 68 65 20 69 6e 6e 65  ured in the inne
14bd0 72 0a 20 20 2a 2a 20 6c 6f 6f 70 20 6f 66 20 74  r.  ** loop of t
14be0 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62 6c 6f  he following blo
14bf0 63 6b 20 69 73 20 6d 6f 72 65 20 73 74 72 69 6e  ck is more strin
14c00 67 65 6e 74 20 74 68 61 74 20 77 6f 75 6c 64 20  gent that would 
14c10 62 65 20 72 65 71 75 69 72 65 64 20 0a 20 20 2a  be required .  *
14c20 2a 20 69 66 20 77 65 20 68 61 64 20 65 78 63 6c  * if we had excl
14c30 75 73 69 76 65 20 61 63 63 65 73 73 20 74 6f 20  usive access to 
14c40 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65 3a 0a  the hash-table:.
14c50 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 28 61 50 67    **.  **   (aPg
14c60 6e 6f 5b 69 46 72 61 6d 65 5d 3d 3d 70 67 6e 6f  no[iFrame]==pgno
14c70 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69  ): .  **     Thi
14c80 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74  s condition filt
14c90 65 72 73 20 6f 75 74 20 6e 6f 72 6d 61 6c 20 68  ers out normal h
14ca0 61 73 68 2d 74 61 62 6c 65 20 63 6f 6c 6c 69 73  ash-table collis
14cb0 69 6f 6e 73 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20  ions..  **.  ** 
14cc0 20 20 28 69 46 72 61 6d 65 3c 3d 69 4c 61 73 74    (iFrame<=iLast
14cd0 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69  ): .  **     Thi
14ce0 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74  s condition filt
14cf0 65 72 73 20 6f 75 74 20 65 6e 74 72 69 65 73 20  ers out entries 
14d00 74 68 61 74 20 77 65 72 65 20 61 64 64 65 64 20  that were added 
14d10 74 6f 20 74 68 65 20 68 61 73 68 0a 20 20 2a 2a  to the hash.  **
14d20 20 20 20 20 20 74 61 62 6c 65 20 61 66 74 65 72       table after
14d30 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 65 61   the current rea
14d40 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e 20 68 61  d-transaction ha
14d50 64 20 73 74 61 72 74 65 64 2e 0a 20 20 2a 2f 0a  d started..  */.
14d60 20 20 66 6f 72 28 69 48 61 73 68 3d 77 61 6c 46    for(iHash=walF
14d70 72 61 6d 65 50 61 67 65 28 69 4c 61 73 74 29 3b  ramePage(iLast);
14d80 20 69 48 61 73 68 3e 3d 30 20 26 26 20 69 52 65   iHash>=0 && iRe
14d90 61 64 3d 3d 30 3b 20 69 48 61 73 68 2d 2d 29 7b  ad==0; iHash--){
14da0 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 68 74  .    volatile ht
14db0 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b 20 20 20  _slot *aHash;   
14dc0 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
14dd0 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20   hash table */. 
14de0 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20     volatile u32 
14df0 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20 20 20 20  *aPgno;         
14e00 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 61   /* Pointer to a
14e10 72 72 61 79 20 6f 66 20 70 61 67 65 20 6e 75 6d  rray of page num
14e20 62 65 72 73 20 2a 2f 0a 20 20 20 20 75 33 32 20  bers */.    u32 
14e30 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20 20  iZero;          
14e40 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72 61            /* Fra
14e50 6d 65 20 6e 75 6d 62 65 72 20 63 6f 72 72 65 73  me number corres
14e60 70 6f 6e 64 69 6e 67 20 74 6f 20 61 50 67 6e 6f  ponding to aPgno
14e70 5b 30 5d 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69  [0] */.    int i
14e80 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  Key;            
14e90 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68           /* Hash
14ea0 20 73 6c 6f 74 20 69 6e 64 65 78 20 2a 2f 0a 20   slot index */. 
14eb0 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69 64 65 3b     int nCollide;
14ec0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14ed0 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 68 61   /* Number of ha
14ee0 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73 20 72 65  sh collisions re
14ef0 6d 61 69 6e 69 6e 67 20 2a 2f 0a 20 20 20 20 69  maining */.    i
14f00 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
14f10 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
14f20 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 0a 20  Error code */.. 
14f30 20 20 20 72 63 20 3d 20 77 61 6c 48 61 73 68 47     rc = walHashG
14f40 65 74 28 70 57 61 6c 2c 20 69 48 61 73 68 2c 20  et(pWal, iHash, 
14f50 26 61 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20  &aHash, &aPgno, 
14f60 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20 69 66 28  &iZero);.    if(
14f70 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
14f80 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72  {.      return r
14f90 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e 43 6f  c;.    }.    nCo
14fa0 6c 6c 69 64 65 20 3d 20 48 41 53 48 54 41 42 4c  llide = HASHTABL
14fb0 45 5f 4e 53 4c 4f 54 3b 0a 20 20 20 20 66 6f 72  E_NSLOT;.    for
14fc0 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 70 67  (iKey=walHash(pg
14fd0 6e 6f 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  no); aHash[iKey]
14fe0 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
14ff0 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
15000 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20 61 48   u32 iFrame = aH
15010 61 73 68 5b 69 4b 65 79 5d 20 2b 20 69 5a 65 72  ash[iKey] + iZer
15020 6f 3b 0a 20 20 20 20 20 20 69 66 28 20 69 46 72  o;.      if( iFr
15030 61 6d 65 3c 3d 69 4c 61 73 74 20 26 26 20 61 50  ame<=iLast && aP
15040 67 6e 6f 5b 61 48 61 73 68 5b 69 4b 65 79 5d 5d  gno[aHash[iKey]]
15050 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20  ==pgno ){.      
15060 20 20 61 73 73 65 72 74 28 20 69 46 72 61 6d 65    assert( iFrame
15070 3e 69 52 65 61 64 20 29 3b 0a 20 20 20 20 20 20  >iRead );.      
15080 20 20 69 52 65 61 64 20 3d 20 69 46 72 61 6d 65    iRead = iFrame
15090 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
150a0 69 66 28 20 28 6e 43 6f 6c 6c 69 64 65 2d 2d 29  if( (nCollide--)
150b0 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72  ==0 ){.        r
150c0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 43 4f 52  eturn SQLITE_COR
150d0 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20 20 20  RUPT_BKPT;.     
150e0 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 23 69   }.    }.  }..#i
150f0 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42  fdef SQLITE_ENAB
15100 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53 53  LE_EXPENSIVE_ASS
15110 45 52 54 0a 20 20 2f 2a 20 49 66 20 65 78 70 65  ERT.  /* If expe
15120 6e 73 69 76 65 20 61 73 73 65 72 74 28 29 20 73  nsive assert() s
15130 74 61 74 65 6d 65 6e 74 73 20 61 72 65 20 61 76  tatements are av
15140 61 69 6c 61 62 6c 65 2c 20 64 6f 20 61 20 6c 69  ailable, do a li
15150 6e 65 61 72 20 73 65 61 72 63 68 0a 20 20 2a 2a  near search.  **
15160 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
15170 78 20 66 69 6c 65 20 63 6f 6e 74 65 6e 74 2e 20  x file content. 
15180 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20 72 65  Make sure the re
15190 73 75 6c 74 73 20 61 67 72 65 65 20 77 69 74 68  sults agree with
151a0 20 74 68 65 0a 20 20 2a 2a 20 72 65 73 75 6c 74   the.  ** result
151b0 20 6f 62 74 61 69 6e 65 64 20 75 73 69 6e 67 20   obtained using 
151c0 74 68 65 20 68 61 73 68 20 69 6e 64 65 78 65 73  the hash indexes
151d0 20 61 62 6f 76 65 2e 20 20 2a 2f 0a 20 20 7b 0a   above.  */.  {.
151e0 20 20 20 20 75 33 32 20 69 52 65 61 64 32 20 3d      u32 iRead2 =
151f0 20 30 3b 0a 20 20 20 20 75 33 32 20 69 54 65 73   0;.    u32 iTes
15200 74 3b 0a 20 20 20 20 66 6f 72 28 69 54 65 73 74  t;.    for(iTest
15210 3d 69 4c 61 73 74 3b 20 69 54 65 73 74 3e 30 3b  =iLast; iTest>0;
15220 20 69 54 65 73 74 2d 2d 29 7b 0a 20 20 20 20 20   iTest--){.     
15230 20 69 66 28 20 77 61 6c 46 72 61 6d 65 50 67 6e   if( walFramePgn
15240 6f 28 70 57 61 6c 2c 20 69 54 65 73 74 29 3d 3d  o(pWal, iTest)==
15250 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20 20 20  pgno ){.        
15260 69 52 65 61 64 32 20 3d 20 69 54 65 73 74 3b 0a  iRead2 = iTest;.
15270 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
15280 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
15290 20 61 73 73 65 72 74 28 20 69 52 65 61 64 3d 3d   assert( iRead==
152a0 69 52 65 61 64 32 20 29 3b 0a 20 20 7d 0a 23 65  iRead2 );.  }.#e
152b0 6e 64 69 66 0a 0a 20 20 2f 2a 20 49 66 20 69 52  ndif..  /* If iR
152c0 65 61 64 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c  ead is non-zero,
152d0 20 74 68 65 6e 20 69 74 20 69 73 20 74 68 65 20   then it is the 
152e0 6c 6f 67 20 66 72 61 6d 65 20 6e 75 6d 62 65 72  log frame number
152f0 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74   that contains t
15300 68 65 0a 20 20 2a 2a 20 72 65 71 75 69 72 65 64  he.  ** required
15310 20 70 61 67 65 2e 20 52 65 61 64 20 61 6e 64 20   page. Read and 
15320 72 65 74 75 72 6e 20 64 61 74 61 20 66 72 6f 6d  return data from
15330 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 0a 20   the log file.. 
15340 20 2a 2f 0a 20 20 69 66 28 20 69 52 65 61 64 20   */.  if( iRead 
15350 29 7b 0a 20 20 20 20 69 6e 74 20 73 7a 3b 0a 20  ){.    int sz;. 
15360 20 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 0a     i64 iOffset;.
15370 20 20 20 20 73 7a 20 3d 20 70 57 61 6c 2d 3e 68      sz = pWal->h
15380 64 72 2e 73 7a 50 61 67 65 3b 0a 20 20 20 20 73  dr.szPage;.    s
15390 7a 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72 2e 73  z = (pWal->hdr.s
153a0 7a 50 61 67 65 26 30 78 66 65 30 30 29 20 2b 20  zPage&0xfe00) + 
153b0 28 28 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61  ((pWal->hdr.szPa
153c0 67 65 26 30 78 30 30 30 31 29 3c 3c 31 36 29 3b  ge&0x0001)<<16);
153d0 0a 20 20 20 20 74 65 73 74 63 61 73 65 28 20 73  .    testcase( s
153e0 7a 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20 20 20  z<=32768 );.    
153f0 74 65 73 74 63 61 73 65 28 20 73 7a 3e 3d 36 35  testcase( sz>=65
15400 35 33 36 20 29 3b 0a 20 20 20 20 69 4f 66 66 73  536 );.    iOffs
15410 65 74 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66  et = walFrameOff
15420 73 65 74 28 69 52 65 61 64 2c 20 73 7a 29 20 2b  set(iRead, sz) +
15430 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49   WAL_FRAME_HDRSI
15440 5a 45 3b 0a 20 20 20 20 2a 70 49 6e 57 61 6c 20  ZE;.    *pInWal 
15450 3d 20 31 3b 0a 20 20 20 20 2f 2a 20 74 65 73 74  = 1;.    /* test
15460 63 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54  case( IS_BIG_INT
15470 28 69 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f 20  (iOffset) ); // 
15480 72 65 71 75 69 72 65 73 20 61 20 34 47 69 42 20  requires a 4GiB 
15490 57 41 4c 20 2a 2f 0a 20 20 20 20 72 65 74 75 72  WAL */.    retur
154a0 6e 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28  n sqlite3OsRead(
154b0 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 70 4f  pWal->pWalFd, pO
154c0 75 74 2c 20 6e 4f 75 74 2c 20 69 4f 66 66 73 65  ut, nOut, iOffse
154d0 74 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 49 6e 57  t);.  }..  *pInW
154e0 61 6c 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e  al = 0;.  return
154f0 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a   SQLITE_OK;.}...
15500 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  /* .** Return th
15510 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 64 61  e size of the da
15520 74 61 62 61 73 65 20 69 6e 20 70 61 67 65 73 20  tabase in pages 
15530 28 6f 72 20 7a 65 72 6f 2c 20 69 66 20 75 6e 6b  (or zero, if unk
15540 6e 6f 77 6e 29 2e 0a 2a 2f 0a 50 67 6e 6f 20 73  nown)..*/.Pgno s
15550 71 6c 69 74 65 33 57 61 6c 44 62 73 69 7a 65 28  qlite3WalDbsize(
15560 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66  Wal *pWal){.  if
15570 28 20 70 57 61 6c 20 26 26 20 41 4c 57 41 59 53  ( pWal && ALWAYS
15580 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e  (pWal->readLock>
15590 3d 30 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72  =0) ){.    retur
155a0 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67  n pWal->hdr.nPag
155b0 65 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  e;.  }.  return 
155c0 30 3b 0a 7d 0a 0a 0a 2f 2a 20 0a 2a 2a 20 54 68  0;.}.../* .** Th
155d0 69 73 20 66 75 6e 63 74 69 6f 6e 20 73 74 61 72  is function star
155e0 74 73 20 61 20 77 72 69 74 65 20 74 72 61 6e 73  ts a write trans
155f0 61 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20 57 41  action on the WA
15600 4c 2e 0a 2a 2a 0a 2a 2a 20 41 20 72 65 61 64 20  L..**.** A read 
15610 74 72 61 6e 73 61 63 74 69 6f 6e 20 6d 75 73 74  transaction must
15620 20 68 61 76 65 20 61 6c 72 65 61 64 79 20 62 65   have already be
15630 65 6e 20 73 74 61 72 74 65 64 20 62 79 20 61 20  en started by a 
15640 70 72 69 6f 72 20 63 61 6c 6c 0a 2a 2a 20 74 6f  prior call.** to
15650 20 73 71 6c 69 74 65 33 57 61 6c 42 65 67 69 6e   sqlite3WalBegin
15660 52 65 61 64 54 72 61 6e 73 61 63 74 69 6f 6e 28  ReadTransaction(
15670 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 6f 74  )..**.** If anot
15680 68 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72  her thread or pr
15690 6f 63 65 73 73 20 68 61 73 20 77 72 69 74 74 65  ocess has writte
156a0 6e 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  n into the datab
156b0 61 73 65 20 73 69 6e 63 65 0a 2a 2a 20 74 68 65  ase since.** the
156c0 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
156d0 6e 20 77 61 73 20 73 74 61 72 74 65 64 2c 20 74  n was started, t
156e0 68 65 6e 20 69 74 20 69 73 20 6e 6f 74 20 70 6f  hen it is not po
156f0 73 73 69 62 6c 65 20 66 6f 72 20 74 68 69 73 0a  ssible for this.
15700 2a 2a 20 74 68 72 65 61 64 20 74 6f 20 77 72 69  ** thread to wri
15710 74 65 20 61 73 20 64 6f 69 6e 67 20 73 6f 20 77  te as doing so w
15720 6f 75 6c 64 20 63 61 75 73 65 20 61 20 66 6f 72  ould cause a for
15730 6b 2e 20 20 53 6f 20 74 68 69 73 20 72 6f 75 74  k.  So this rout
15740 69 6e 65 0a 2a 2a 20 72 65 74 75 72 6e 73 20 53  ine.** returns S
15750 51 4c 49 54 45 5f 42 55 53 59 20 69 6e 20 74 68  QLITE_BUSY in th
15760 61 74 20 63 61 73 65 20 61 6e 64 20 6e 6f 20 77  at case and no w
15770 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  rite transaction
15780 20 69 73 20 73 74 61 72 74 65 64 2e 0a 2a 2a 0a   is started..**.
15790 2a 2a 20 54 68 65 72 65 20 63 61 6e 20 6f 6e 6c  ** There can onl
157a0 79 20 62 65 20 61 20 73 69 6e 67 6c 65 20 77 72  y be a single wr
157b0 69 74 65 72 20 61 63 74 69 76 65 20 61 74 20 61  iter active at a
157c0 20 74 69 6d 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71   time..*/.int sq
157d0 6c 69 74 65 33 57 61 6c 42 65 67 69 6e 57 72 69  lite3WalBeginWri
157e0 74 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 57 61  teTransaction(Wa
157f0 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20  l *pWal){.  int 
15800 72 63 3b 0a 0a 20 20 2f 2a 20 43 61 6e 6e 6f 74  rc;..  /* Cannot
15810 20 73 74 61 72 74 20 61 20 77 72 69 74 65 20 74   start a write t
15820 72 61 6e 73 61 63 74 69 6f 6e 20 77 69 74 68 6f  ransaction witho
15830 75 74 20 66 69 72 73 74 20 68 6f 6c 64 69 6e 67  ut first holding
15840 20 61 20 72 65 61 64 0a 20 20 2a 2a 20 74 72 61   a read.  ** tra
15850 6e 73 61 63 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61  nsaction. */.  a
15860 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65 61  ssert( pWal->rea
15870 64 4c 6f 63 6b 3e 3d 30 20 29 3b 0a 0a 20 20 69  dLock>=0 );..  i
15880 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4f 6e 6c  f( pWal->readOnl
15890 79 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  y ){.    return 
158a0 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 3b  SQLITE_READONLY;
158b0 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4f 6e 6c 79 20  .  }..  /* Only 
158c0 6f 6e 65 20 77 72 69 74 65 72 20 61 6c 6c 6f 77  one writer allow
158d0 65 64 20 61 74 20 61 20 74 69 6d 65 2e 20 20 47  ed at a time.  G
158e0 65 74 20 74 68 65 20 77 72 69 74 65 20 6c 6f 63  et the write loc
158f0 6b 2e 20 20 52 65 74 75 72 6e 0a 20 20 2a 2a 20  k.  Return.  ** 
15900 53 51 4c 49 54 45 5f 42 55 53 59 20 69 66 20 75  SQLITE_BUSY if u
15910 6e 61 62 6c 65 2e 0a 20 20 2a 2f 0a 20 20 72 63  nable..  */.  rc
15920 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73   = walLockExclus
15930 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52  ive(pWal, WAL_WR
15940 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20  ITE_LOCK, 1);.  
15950 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 72 65  if( rc ){.    re
15960 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70  turn rc;.  }.  p
15970 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d  Wal->writeLock =
15980 20 31 3b 0a 0a 20 20 2f 2a 20 49 66 20 61 6e 6f   1;..  /* If ano
15990 74 68 65 72 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  ther connection 
159a0 68 61 73 20 77 72 69 74 74 65 6e 20 74 6f 20 74  has written to t
159b0 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
159c0 20 73 69 6e 63 65 20 74 68 65 0a 20 20 2a 2a 20   since the.  ** 
159d0 74 69 6d 65 20 74 68 65 20 72 65 61 64 20 74 72  time the read tr
159e0 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68 69  ansaction on thi
159f0 73 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 77 61 73  s connection was
15a00 20 73 74 61 72 74 65 64 2c 20 74 68 65 6e 0a 20   started, then. 
15a10 20 2a 2a 20 74 68 65 20 77 72 69 74 65 20 69 73   ** the write is
15a20 20 64 69 73 61 6c 6c 6f 77 65 64 2e 0a 20 20 2a   disallowed..  *
15a30 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26  /.  if( memcmp(&
15a40 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69 64  pWal->hdr, (void
15a50 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70   *)walIndexHdr(p
15a60 57 61 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61 6c  Wal), sizeof(Wal
15a70 49 6e 64 65 78 48 64 72 29 29 21 3d 30 20 29 7b  IndexHdr))!=0 ){
15a80 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78  .    walUnlockEx
15a90 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
15aa0 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29  L_WRITE_LOCK, 1)
15ab0 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74  ;.    pWal->writ
15ac0 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 72  eLock = 0;.    r
15ad0 63 20 3d 20 53 51 4c 49 54 45 5f 42 55 53 59 3b  c = SQLITE_BUSY;
15ae0 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
15af0 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 64 20  c;.}../*.** End 
15b00 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74  a write transact
15b10 69 6f 6e 2e 20 20 54 68 65 20 63 6f 6d 6d 69 74  ion.  The commit
15b20 20 68 61 73 20 61 6c 72 65 61 64 79 20 62 65 65   has already bee
15b30 6e 20 64 6f 6e 65 2e 20 20 54 68 69 73 0a 2a 2a  n done.  This.**
15b40 20 72 6f 75 74 69 6e 65 20 6d 65 72 65 6c 79 20   routine merely 
15b50 72 65 6c 65 61 73 65 73 20 74 68 65 20 6c 6f 63  releases the loc
15b60 6b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  k..*/.int sqlite
15b70 33 57 61 6c 45 6e 64 57 72 69 74 65 54 72 61 6e  3WalEndWriteTran
15b80 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61  saction(Wal *pWa
15b90 6c 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  l){.  if( pWal->
15ba0 77 72 69 74 65 4c 6f 63 6b 20 29 7b 0a 20 20 20  writeLock ){.   
15bb0 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
15bc0 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52  ive(pWal, WAL_WR
15bd0 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20  ITE_LOCK, 1);.  
15be0 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63    pWal->writeLoc
15bf0 6b 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74  k = 0;.  }.  ret
15c00 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
15c10 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 61 6e 79 20 64  ../*.** If any d
15c20 61 74 61 20 68 61 73 20 62 65 65 6e 20 77 72 69  ata has been wri
15c30 74 74 65 6e 20 28 62 75 74 20 6e 6f 74 20 63 6f  tten (but not co
15c40 6d 6d 69 74 74 65 64 29 20 74 6f 20 74 68 65 20  mmitted) to the 
15c50 6c 6f 67 20 66 69 6c 65 2c 20 74 68 69 73 0a 2a  log file, this.*
15c60 2a 20 66 75 6e 63 74 69 6f 6e 20 6d 6f 76 65 73  * function moves
15c70 20 74 68 65 20 77 72 69 74 65 2d 70 6f 69 6e 74   the write-point
15c80 65 72 20 62 61 63 6b 20 74 6f 20 74 68 65 20 73  er back to the s
15c90 74 61 72 74 20 6f 66 20 74 68 65 20 74 72 61 6e  tart of the tran
15ca0 73 61 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41  saction..**.** A
15cb0 64 64 69 74 69 6f 6e 61 6c 6c 79 2c 20 74 68 65  dditionally, the
15cc0 20 63 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69   callback functi
15cd0 6f 6e 20 69 73 20 69 6e 76 6f 6b 65 64 20 66 6f  on is invoked fo
15ce0 72 20 65 61 63 68 20 66 72 61 6d 65 20 77 72 69  r each frame wri
15cf0 74 74 65 6e 0a 2a 2a 20 74 6f 20 74 68 65 20 57  tten.** to the W
15d00 41 4c 20 73 69 6e 63 65 20 74 68 65 20 73 74 61  AL since the sta
15d10 72 74 20 6f 66 20 74 68 65 20 74 72 61 6e 73 61  rt of the transa
15d20 63 74 69 6f 6e 2e 20 49 66 20 74 68 65 20 63 61  ction. If the ca
15d30 6c 6c 62 61 63 6b 20 72 65 74 75 72 6e 73 0a 2a  llback returns.*
15d40 2a 20 6f 74 68 65 72 20 74 68 61 6e 20 53 51 4c  * other than SQL
15d50 49 54 45 5f 4f 4b 2c 20 69 74 20 69 73 20 6e 6f  ITE_OK, it is no
15d60 74 20 69 6e 76 6f 6b 65 64 20 61 67 61 69 6e 20  t invoked again 
15d70 61 6e 64 20 74 68 65 20 65 72 72 6f 72 20 63 6f  and the error co
15d80 64 65 20 69 73 0a 2a 2a 20 72 65 74 75 72 6e 65  de is.** returne
15d90 64 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e  d to the caller.
15da0 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  .**.** Otherwise
15db0 2c 20 69 66 20 74 68 65 20 63 61 6c 6c 62 61 63  , if the callbac
15dc0 6b 20 66 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20  k function does 
15dd0 6e 6f 74 20 72 65 74 75 72 6e 20 61 6e 20 65 72  not return an er
15de0 72 6f 72 2c 20 74 68 69 73 0a 2a 2a 20 66 75 6e  ror, this.** fun
15df0 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 53 51  ction returns SQ
15e00 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20  LITE_OK..*/.int 
15e10 73 71 6c 69 74 65 33 57 61 6c 55 6e 64 6f 28 57  sqlite3WalUndo(W
15e20 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 28 2a  al *pWal, int (*
15e30 78 55 6e 64 6f 29 28 76 6f 69 64 20 2a 2c 20 50  xUndo)(void *, P
15e40 67 6e 6f 29 2c 20 76 6f 69 64 20 2a 70 55 6e 64  gno), void *pUnd
15e50 6f 43 74 78 29 7b 0a 20 20 69 6e 74 20 72 63 20  oCtx){.  int rc 
15e60 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
15e70 66 28 20 41 4c 57 41 59 53 28 70 57 61 6c 2d 3e  f( ALWAYS(pWal->
15e80 77 72 69 74 65 4c 6f 63 6b 29 20 29 7b 0a 20 20  writeLock) ){.  
15e90 20 20 50 67 6e 6f 20 69 4d 61 78 20 3d 20 70 57    Pgno iMax = pW
15ea0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b  al->hdr.mxFrame;
15eb0 0a 20 20 20 20 50 67 6e 6f 20 69 46 72 61 6d 65  .    Pgno iFrame
15ec0 3b 0a 20 20 0a 20 20 20 20 2f 2a 20 52 65 73 74  ;.  .    /* Rest
15ed0 6f 72 65 20 74 68 65 20 63 6c 69 65 6e 74 73 20  ore the clients 
15ee0 63 61 63 68 65 20 6f 66 20 74 68 65 20 77 61 6c  cache of the wal
15ef0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f  -index header to
15f00 20 74 68 65 20 73 74 61 74 65 20 69 74 0a 20 20   the state it.  
15f10 20 20 2a 2a 20 77 61 73 20 69 6e 20 62 65 66 6f    ** was in befo
15f20 72 65 20 74 68 65 20 63 6c 69 65 6e 74 20 62 65  re the client be
15f30 67 61 6e 20 77 72 69 74 69 6e 67 20 74 6f 20 74  gan writing to t
15f40 68 65 20 64 61 74 61 62 61 73 65 2e 20 0a 20 20  he database. .  
15f50 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 63 70 79 28    */.    memcpy(
15f60 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69  &pWal->hdr, (voi
15f70 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28  d *)walIndexHdr(
15f80 70 57 61 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61  pWal), sizeof(Wa
15f90 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 0a 20 20  lIndexHdr));..  
15fa0 20 20 66 6f 72 28 69 46 72 61 6d 65 3d 70 57 61    for(iFrame=pWa
15fb0 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2b 31  l->hdr.mxFrame+1
15fc0 3b 20 0a 20 20 20 20 20 20 20 20 41 4c 57 41 59  ; .        ALWAY
15fd0 53 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29  S(rc==SQLITE_OK)
15fe0 20 26 26 20 69 46 72 61 6d 65 3c 3d 69 4d 61 78   && iFrame<=iMax
15ff0 3b 20 0a 20 20 20 20 20 20 20 20 69 46 72 61 6d  ; .        iFram
16000 65 2b 2b 0a 20 20 20 20 29 7b 0a 20 20 20 20 20  e++.    ){.     
16010 20 2f 2a 20 54 68 69 73 20 63 61 6c 6c 20 63 61   /* This call ca
16020 6e 6e 6f 74 20 66 61 69 6c 2e 20 55 6e 6c 65 73  nnot fail. Unles
16030 73 20 74 68 65 20 70 61 67 65 20 66 6f 72 20 77  s the page for w
16040 68 69 63 68 20 74 68 65 20 70 61 67 65 20 6e 75  hich the page nu
16050 6d 62 65 72 0a 20 20 20 20 20 20 2a 2a 20 69 73  mber.      ** is
16060 20 70 61 73 73 65 64 20 61 73 20 74 68 65 20 73   passed as the s
16070 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 69  econd argument i
16080 73 20 28 61 29 20 69 6e 20 74 68 65 20 63 61 63  s (a) in the cac
16090 68 65 20 61 6e 64 20 0a 20 20 20 20 20 20 2a 2a  he and .      **
160a0 20 28 62 29 20 68 61 73 20 61 6e 20 6f 75 74 73   (b) has an outs
160b0 74 61 6e 64 69 6e 67 20 72 65 66 65 72 65 6e 63  tanding referenc
160c0 65 2c 20 74 68 65 6e 20 78 55 6e 64 6f 20 69 73  e, then xUndo is
160d0 20 65 69 74 68 65 72 20 61 20 6e 6f 2d 6f 70 0a   either a no-op.
160e0 20 20 20 20 20 20 2a 2a 20 28 69 66 20 28 61 29        ** (if (a)
160f0 20 69 73 20 66 61 6c 73 65 29 20 6f 72 20 73 69   is false) or si
16100 6d 70 6c 79 20 65 78 70 65 6c 73 20 74 68 65 20  mply expels the 
16110 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20 63 61  page from the ca
16120 63 68 65 20 28 69 66 20 28 62 29 0a 20 20 20 20  che (if (b).    
16130 20 20 2a 2a 20 69 73 20 66 61 6c 73 65 29 2e 0a    ** is false)..
16140 20 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a        **.      *
16150 2a 20 49 66 20 74 68 65 20 75 70 70 65 72 20 6c  * If the upper l
16160 61 79 65 72 20 69 73 20 64 6f 69 6e 67 20 61 20  ayer is doing a 
16170 72 6f 6c 6c 62 61 63 6b 2c 20 69 74 20 69 73 20  rollback, it is 
16180 67 75 61 72 61 6e 74 65 65 64 20 74 68 61 74 20  guaranteed that 
16190 74 68 65 72 65 0a 20 20 20 20 20 20 2a 2a 20 61  there.      ** a
161a0 72 65 20 6e 6f 20 6f 75 74 73 74 61 6e 64 69 6e  re no outstandin
161b0 67 20 72 65 66 65 72 65 6e 63 65 73 20 74 6f 20  g references to 
161c0 61 6e 79 20 70 61 67 65 20 6f 74 68 65 72 20 74  any page other t
161d0 68 61 6e 20 70 61 67 65 20 31 2e 20 41 6e 64 0a  han page 1. And.
161e0 20 20 20 20 20 20 2a 2a 20 70 61 67 65 20 31 20        ** page 1 
161f0 69 73 20 6e 65 76 65 72 20 77 72 69 74 74 65 6e  is never written
16200 20 74 6f 20 74 68 65 20 6c 6f 67 20 75 6e 74 69   to the log unti
16210 6c 20 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f  l the transactio
16220 6e 20 69 73 0a 20 20 20 20 20 20 2a 2a 20 63 6f  n is.      ** co
16230 6d 6d 69 74 74 65 64 2e 20 41 73 20 61 20 72 65  mmitted. As a re
16240 73 75 6c 74 2c 20 74 68 65 20 63 61 6c 6c 20 74  sult, the call t
16250 6f 20 78 55 6e 64 6f 20 6d 61 79 20 6e 6f 74 20  o xUndo may not 
16260 66 61 69 6c 2e 0a 20 20 20 20 20 20 2a 2f 0a 20  fail..      */. 
16270 20 20 20 20 20 61 73 73 65 72 74 28 20 77 61 6c       assert( wal
16280 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20  FramePgno(pWal, 
16290 69 46 72 61 6d 65 29 21 3d 31 20 29 3b 0a 20 20  iFrame)!=1 );.  
162a0 20 20 20 20 72 63 20 3d 20 78 55 6e 64 6f 28 70      rc = xUndo(p
162b0 55 6e 64 6f 43 74 78 2c 20 77 61 6c 46 72 61 6d  UndoCtx, walFram
162c0 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 46 72 61  ePgno(pWal, iFra
162d0 6d 65 29 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  me));.    }.    
162e0 77 61 6c 43 6c 65 61 6e 75 70 48 61 73 68 28 70  walCleanupHash(p
162f0 57 61 6c 29 3b 0a 20 20 7d 0a 20 20 61 73 73 65  Wal);.  }.  asse
16300 72 74 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  rt( rc==SQLITE_O
16310 4b 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  K );.  return rc
16320 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 41 72 67 75  ;.}../* .** Argu
16330 6d 65 6e 74 20 61 57 61 6c 44 61 74 61 20 6d 75  ment aWalData mu
16340 73 74 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 61  st point to an a
16350 72 72 61 79 20 6f 66 20 57 41 4c 5f 53 41 56 45  rray of WAL_SAVE
16360 50 4f 49 4e 54 5f 4e 44 41 54 41 20 75 33 32 20  POINT_NDATA u32 
16370 0a 2a 2a 20 76 61 6c 75 65 73 2e 20 54 68 69 73  .** values. This
16380 20 66 75 6e 63 74 69 6f 6e 20 70 6f 70 75 6c 61   function popula
16390 74 65 73 20 74 68 65 20 61 72 72 61 79 20 77 69  tes the array wi
163a0 74 68 20 76 61 6c 75 65 73 20 72 65 71 75 69 72  th values requir
163b0 65 64 20 74 6f 20 0a 2a 2a 20 22 72 6f 6c 6c 62  ed to .** "rollb
163c0 61 63 6b 22 20 74 68 65 20 77 72 69 74 65 20 70  ack" the write p
163d0 6f 73 69 74 69 6f 6e 20 6f 66 20 74 68 65 20 57  osition of the W
163e0 41 4c 20 68 61 6e 64 6c 65 20 62 61 63 6b 20 74  AL handle back t
163f0 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20 0a 2a  o the current .*
16400 2a 20 70 6f 69 6e 74 20 69 6e 20 74 68 65 20 65  * point in the e
16410 76 65 6e 74 20 6f 66 20 61 20 73 61 76 65 70 6f  vent of a savepo
16420 69 6e 74 20 72 6f 6c 6c 62 61 63 6b 20 28 76 69  int rollback (vi
16430 61 20 57 61 6c 53 61 76 65 70 6f 69 6e 74 55 6e  a WalSavepointUn
16440 64 6f 28 29 29 2e 0a 2a 2f 0a 76 6f 69 64 20 73  do())..*/.void s
16450 71 6c 69 74 65 33 57 61 6c 53 61 76 65 70 6f 69  qlite3WalSavepoi
16460 6e 74 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33  nt(Wal *pWal, u3
16470 32 20 2a 61 57 61 6c 44 61 74 61 29 7b 0a 20 20  2 *aWalData){.  
16480 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72  assert( pWal->wr
16490 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 61 57 61  iteLock );.  aWa
164a0 6c 44 61 74 61 5b 30 5d 20 3d 20 70 57 61 6c 2d  lData[0] = pWal-
164b0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20  >hdr.mxFrame;.  
164c0 61 57 61 6c 44 61 74 61 5b 31 5d 20 3d 20 70 57  aWalData[1] = pW
164d0 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
164e0 73 75 6d 5b 30 5d 3b 0a 20 20 61 57 61 6c 44 61  sum[0];.  aWalDa
164f0 74 61 5b 32 5d 20 3d 20 70 57 61 6c 2d 3e 68 64  ta[2] = pWal->hd
16500 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d  r.aFrameCksum[1]
16510 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 33 5d 20  ;.  aWalData[3] 
16520 3d 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 3b 0a 7d  = pWal->nCkpt;.}
16530 0a 0a 2f 2a 20 0a 2a 2a 20 4d 6f 76 65 20 74 68  ../* .** Move th
16540 65 20 77 72 69 74 65 20 70 6f 73 69 74 69 6f 6e  e write position
16550 20 6f 66 20 74 68 65 20 57 41 4c 20 62 61 63 6b   of the WAL back
16560 20 74 6f 20 74 68 65 20 70 6f 69 6e 74 20 69 64   to the point id
16570 65 6e 74 69 66 69 65 64 20 62 79 0a 2a 2a 20 74  entified by.** t
16580 68 65 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  he values in the
16590 20 61 57 61 6c 44 61 74 61 5b 5d 20 61 72 72 61   aWalData[] arra
165a0 79 2e 20 61 57 61 6c 44 61 74 61 20 6d 75 73 74  y. aWalData must
165b0 20 70 6f 69 6e 74 20 74 6f 20 61 6e 20 61 72 72   point to an arr
165c0 61 79 0a 2a 2a 20 6f 66 20 57 41 4c 5f 53 41 56  ay.** of WAL_SAV
165d0 45 50 4f 49 4e 54 5f 4e 44 41 54 41 20 75 33 32  EPOINT_NDATA u32
165e0 20 76 61 6c 75 65 73 20 74 68 61 74 20 68 61 73   values that has
165f0 20 62 65 65 6e 20 70 72 65 76 69 6f 75 73 6c 79   been previously
16600 20 70 6f 70 75 6c 61 74 65 64 0a 2a 2a 20 62 79   populated.** by
16610 20 61 20 63 61 6c 6c 20 74 6f 20 57 61 6c 53 61   a call to WalSa
16620 76 65 70 6f 69 6e 74 28 29 2e 0a 2a 2f 0a 69 6e  vepoint()..*/.in
16630 74 20 73 71 6c 69 74 65 33 57 61 6c 53 61 76 65  t sqlite3WalSave
16640 70 6f 69 6e 74 55 6e 64 6f 28 57 61 6c 20 2a 70  pointUndo(Wal *p
16650 57 61 6c 2c 20 75 33 32 20 2a 61 57 61 6c 44 61  Wal, u32 *aWalDa
16660 74 61 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  ta){.  int rc = 
16670 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 61 73  SQLITE_OK;..  as
16680 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74  sert( pWal->writ
16690 65 4c 6f 63 6b 20 29 3b 0a 20 20 61 73 73 65 72  eLock );.  asser
166a0 74 28 20 61 57 61 6c 44 61 74 61 5b 33 5d 21 3d  t( aWalData[3]!=
166b0 70 57 61 6c 2d 3e 6e 43 6b 70 74 20 7c 7c 20 61  pWal->nCkpt || a
166c0 57 61 6c 44 61 74 61 5b 30 5d 3c 3d 70 57 61 6c  WalData[0]<=pWal
166d0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b  ->hdr.mxFrame );
166e0 0a 0a 20 20 69 66 28 20 61 57 61 6c 44 61 74 61  ..  if( aWalData
166f0 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43 6b 70 74  [3]!=pWal->nCkpt
16700 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 69 73 20   ){.    /* This 
16710 73 61 76 65 70 6f 69 6e 74 20 77 61 73 20 6f 70  savepoint was op
16720 65 6e 65 64 20 69 6d 6d 65 64 69 61 74 65 6c 79  ened immediately
16730 20 61 66 74 65 72 20 74 68 65 20 77 72 69 74 65   after the write
16740 2d 74 72 61 6e 73 61 63 74 69 6f 6e 0a 20 20 20  -transaction.   
16750 20 2a 2a 20 77 61 73 20 73 74 61 72 74 65 64 2e   ** was started.
16760 20 52 69 67 68 74 20 61 66 74 65 72 20 74 68 61   Right after tha
16770 74 2c 20 74 68 65 20 77 72 69 74 65 72 20 64 65  t, the writer de
16780 63 69 64 65 64 20 74 6f 20 77 72 61 70 20 61 72  cided to wrap ar
16790 6f 75 6e 64 0a 20 20 20 20 2a 2a 20 74 6f 20 74  ound.    ** to t
167a0 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  he start of the 
167b0 6c 6f 67 2e 20 55 70 64 61 74 65 20 74 68 65 20  log. Update the 
167c0 73 61 76 65 70 6f 69 6e 74 20 76 61 6c 75 65 73  savepoint values
167d0 20 74 6f 20 6d 61 74 63 68 2e 0a 20 20 20 20 2a   to match..    *
167e0 2f 0a 20 20 20 20 61 57 61 6c 44 61 74 61 5b 30  /.    aWalData[0
167f0 5d 20 3d 20 30 3b 0a 20 20 20 20 61 57 61 6c 44  ] = 0;.    aWalD
16800 61 74 61 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e 6e  ata[3] = pWal->n
16810 43 6b 70 74 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  Ckpt;.  }..  if(
16820 20 61 57 61 6c 44 61 74 61 5b 30 5d 3c 70 57 61   aWalData[0]<pWa
16830 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29  l->hdr.mxFrame )
16840 7b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  {.    pWal->hdr.
16850 6d 78 46 72 61 6d 65 20 3d 20 61 57 61 6c 44 61  mxFrame = aWalDa
16860 74 61 5b 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d  ta[0];.    pWal-
16870 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
16880 5b 30 5d 20 3d 20 61 57 61 6c 44 61 74 61 5b 31  [0] = aWalData[1
16890 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  ];.    pWal->hdr
168a0 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20  .aFrameCksum[1] 
168b0 3d 20 61 57 61 6c 44 61 74 61 5b 32 5d 3b 0a 20  = aWalData[2];. 
168c0 20 20 20 77 61 6c 43 6c 65 61 6e 75 70 48 61 73     walCleanupHas
168d0 68 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 0a 20 20  h(pWal);.  }..  
168e0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
168f0 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
16900 6e 20 69 73 20 63 61 6c 6c 65 64 20 6a 75 73 74  n is called just
16910 20 62 65 66 6f 72 65 20 77 72 69 74 69 6e 67 20   before writing 
16920 61 20 73 65 74 20 6f 66 20 66 72 61 6d 65 73 20  a set of frames 
16930 74 6f 20 74 68 65 20 6c 6f 67 0a 2a 2a 20 66 69  to the log.** fi
16940 6c 65 20 28 73 65 65 20 73 71 6c 69 74 65 33 57  le (see sqlite3W
16950 61 6c 46 72 61 6d 65 73 28 29 29 2e 20 49 74 20  alFrames()). It 
16960 63 68 65 63 6b 73 20 74 6f 20 73 65 65 20 69 66  checks to see if
16970 2c 20 69 6e 73 74 65 61 64 20 6f 66 20 61 70 70  , instead of app
16980 65 6e 64 69 6e 67 0a 2a 2a 20 74 6f 20 74 68 65  ending.** to the
16990 20 63 75 72 72 65 6e 74 20 6c 6f 67 20 66 69 6c   current log fil
169a0 65 2c 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c  e, it is possibl
169b0 65 20 74 6f 20 6f 76 65 72 77 72 69 74 65 20 74  e to overwrite t
169c0 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 0a  he start of the.
169d0 2a 2a 20 65 78 69 73 74 69 6e 67 20 6c 6f 67 20  ** existing log 
169e0 66 69 6c 65 20 77 69 74 68 20 74 68 65 20 6e 65  file with the ne
169f0 77 20 66 72 61 6d 65 73 20 28 69 2e 65 2e 20 22  w frames (i.e. "
16a00 72 65 73 65 74 22 20 74 68 65 20 6c 6f 67 29 2e  reset" the log).
16a10 20 49 66 20 73 6f 2c 0a 2a 2a 20 69 74 20 73 65   If so,.** it se
16a20 74 73 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ts pWal->hdr.mxF
16a30 72 61 6d 65 20 74 6f 20 30 2e 20 4f 74 68 65 72  rame to 0. Other
16a40 77 69 73 65 2c 20 70 57 61 6c 2d 3e 68 64 72 2e  wise, pWal->hdr.
16a50 6d 78 46 72 61 6d 65 20 69 73 20 6c 65 66 74 0a  mxFrame is left.
16a60 2a 2a 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2a  ** unchanged..**
16a70 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73  .** SQLITE_OK is
16a80 20 72 65 74 75 72 6e 65 64 20 69 66 20 6e 6f 20   returned if no 
16a90 65 72 72 6f 72 20 69 73 20 65 6e 63 6f 75 6e 74  error is encount
16aa0 65 72 65 64 20 28 72 65 67 61 72 64 6c 65 73 73  ered (regardless
16ab0 20 6f 66 20 77 68 65 74 68 65 72 0a 2a 2a 20 6f   of whether.** o
16ac0 72 20 6e 6f 74 20 70 57 61 6c 2d 3e 68 64 72 2e  r not pWal->hdr.
16ad0 6d 78 46 72 61 6d 65 20 69 73 20 6d 6f 64 69 66  mxFrame is modif
16ae0 69 65 64 29 2e 20 41 6e 20 53 51 4c 69 74 65 20  ied). An SQLite 
16af0 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65  error code is re
16b00 74 75 72 6e 65 64 0a 2a 2a 20 69 66 20 61 6e 20  turned.** if an 
16b10 65 72 72 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f  error occurs..*/
16b20 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 52  .static int walR
16b30 65 73 74 61 72 74 4c 6f 67 28 57 61 6c 20 2a 70  estartLog(Wal *p
16b40 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  Wal){.  int rc =
16b50 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e   SQLITE_OK;.  in
16b60 74 20 63 6e 74 3b 0a 0a 20 20 69 66 28 20 70 57  t cnt;..  if( pW
16b70 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20  al->readLock==0 
16b80 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  ){.    volatile 
16b90 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e  WalCkptInfo *pIn
16ba0 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f  fo = walCkptInfo
16bb0 28 70 57 61 6c 29 3b 0a 20 20 20 20 61 73 73 65  (pWal);.    asse
16bc0 72 74 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b  rt( pInfo->nBack
16bd0 66 69 6c 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e  fill==pWal->hdr.
16be0 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20 20 69  mxFrame );.    i
16bf0 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66  f( pInfo->nBackf
16c00 69 6c 6c 3e 30 20 29 7b 0a 20 20 20 20 20 20 72  ill>0 ){.      r
16c10 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75  c = walLockExclu
16c20 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52  sive(pWal, WAL_R
16c30 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c  EAD_LOCK(1), WAL
16c40 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20  _NREADER-1);.   
16c50 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
16c60 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
16c70 2f 2a 20 49 66 20 61 6c 6c 20 72 65 61 64 65 72  /* If all reader
16c80 73 20 61 72 65 20 75 73 69 6e 67 20 57 41 4c 5f  s are using WAL_
16c90 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20 28 69 6e  READ_LOCK(0) (in
16ca0 20 6f 74 68 65 72 20 77 6f 72 64 73 20 69 66 20   other words if 
16cb0 6e 6f 0a 20 20 20 20 20 20 20 20 2a 2a 20 72 65  no.        ** re
16cc0 61 64 65 72 73 20 61 72 65 20 63 75 72 72 65 6e  aders are curren
16cd0 74 6c 79 20 75 73 69 6e 67 20 74 68 65 20 57 41  tly using the WA
16ce0 4c 29 2c 20 74 68 65 6e 20 74 68 65 20 74 72 61  L), then the tra
16cf0 6e 73 61 63 74 69 6f 6e 73 0a 20 20 20 20 20 20  nsactions.      
16d00 20 20 2a 2a 20 66 72 61 6d 65 73 20 77 69 6c 6c    ** frames will
16d10 20 6f 76 65 72 77 72 69 74 65 20 74 68 65 20 73   overwrite the s
16d20 74 61 72 74 20 6f 66 20 74 68 65 20 65 78 69 73  tart of the exis
16d30 74 69 6e 67 20 6c 6f 67 2e 20 55 70 64 61 74 65  ting log. Update
16d40 20 74 68 65 0a 20 20 20 20 20 20 20 20 2a 2a 20   the.        ** 
16d50 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
16d60 20 74 6f 20 72 65 66 6c 65 63 74 20 74 68 69 73   to reflect this
16d70 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20 20  ..        **.   
16d80 20 20 20 20 20 2a 2a 20 49 6e 20 74 68 65 6f 72       ** In theor
16d90 79 20 69 74 20 77 6f 75 6c 64 20 62 65 20 4f 6b  y it would be Ok
16da0 20 74 6f 20 75 70 64 61 74 65 20 74 68 65 20 63   to update the c
16db0 61 63 68 65 20 6f 66 20 74 68 65 20 68 65 61 64  ache of the head
16dc0 65 72 20 6f 6e 6c 79 0a 20 20 20 20 20 20 20 20  er only.        
16dd0 2a 2a 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74  ** at this point
16de0 2e 20 42 75 74 20 75 70 64 61 74 69 6e 67 20 74  . But updating t
16df0 68 65 20 61 63 74 75 61 6c 20 77 61 6c 2d 69 6e  he actual wal-in
16e00 64 65 78 20 68 65 61 64 65 72 20 69 73 20 61 6c  dex header is al
16e10 73 6f 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 61  so.        ** sa
16e20 66 65 20 61 6e 64 20 6d 65 61 6e 73 20 74 68 65  fe and means the
16e30 72 65 20 69 73 20 6e 6f 20 73 70 65 63 69 61 6c  re is no special
16e40 20 63 61 73 65 20 66 6f 72 20 73 71 6c 69 74 65   case for sqlite
16e50 33 57 61 6c 55 6e 64 6f 28 29 0a 20 20 20 20 20  3WalUndo().     
16e60 20 20 20 2a 2a 20 74 6f 20 68 61 6e 64 6c 65 20     ** to handle 
16e70 69 66 20 74 68 69 73 20 74 72 61 6e 73 61 63 74  if this transact
16e80 69 6f 6e 20 69 73 20 72 6f 6c 6c 65 64 20 62 61  ion is rolled ba
16e90 63 6b 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20  ck..        */. 
16ea0 20 20 20 20 20 20 20 69 6e 74 20 69 3b 20 20 20         int i;   
16eb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16ec0 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72   /* Loop counter
16ed0 20 2a 2f 0a 20 20 20 20 20 20 20 20 75 33 32 20   */.        u32 
16ee0 2a 61 53 61 6c 74 20 3d 20 70 57 61 6c 2d 3e 68  *aSalt = pWal->h
16ef0 64 72 2e 61 53 61 6c 74 3b 20 20 20 20 20 20 20  dr.aSalt;       
16f00 2f 2a 20 42 69 67 2d 65 6e 64 69 61 6e 20 73 61  /* Big-endian sa
16f10 6c 74 20 76 61 6c 75 65 73 20 2a 2f 0a 20 20 20  lt values */.   
16f20 20 20 20 20 20 70 57 61 6c 2d 3e 6e 43 6b 70 74       pWal->nCkpt
16f30 2b 2b 3b 0a 20 20 20 20 20 20 20 20 70 57 61 6c  ++;.        pWal
16f40 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20  ->hdr.mxFrame = 
16f50 30 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  0;.        sqlit
16f60 65 33 50 75 74 34 62 79 74 65 28 28 75 38 2a 29  e3Put4byte((u8*)
16f70 26 61 53 61 6c 74 5b 30 5d 2c 20 31 20 2b 20 73  &aSalt[0], 1 + s
16f80 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 28  qlite3Get4byte((
16f90 75 38 2a 29 26 61 53 61 6c 74 5b 30 5d 29 29 3b  u8*)&aSalt[0]));
16fa0 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
16fb0 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 34 2c 20 26  _randomness(4, &
16fc0 61 53 61 6c 74 5b 31 5d 29 3b 0a 20 20 20 20 20  aSalt[1]);.     
16fd0 20 20 20 77 61 6c 49 6e 64 65 78 57 72 69 74 65     walIndexWrite
16fe0 48 64 72 28 70 57 61 6c 29 3b 0a 20 20 20 20 20  Hdr(pWal);.     
16ff0 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66     pInfo->nBackf
17000 69 6c 6c 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ill = 0;.       
17010 20 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f   for(i=1; i<WAL_
17020 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29 20 70 49  NREADER; i++) pI
17030 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69  nfo->aReadMark[i
17040 5d 20 3d 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54  ] = READMARK_NOT
17050 5f 55 53 45 44 3b 0a 20 20 20 20 20 20 20 20 61  _USED;.        a
17060 73 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e 61 52  ssert( pInfo->aR
17070 65 61 64 4d 61 72 6b 5b 30 5d 3d 3d 30 20 29 3b  eadMark[0]==0 );
17080 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f  .        walUnlo
17090 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
170a0 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
170b0 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d  1), WAL_NREADER-
170c0 31 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20  1);.      }else 
170d0 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 42  if( rc!=SQLITE_B
170e0 55 53 59 20 29 7b 0a 20 20 20 20 20 20 20 20 72  USY ){.        r
170f0 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20  eturn rc;.      
17100 7d 0a 20 20 20 20 7d 0a 20 20 20 20 77 61 6c 55  }.    }.    walU
17110 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
17120 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
17130 30 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 72  0));.    pWal->r
17140 65 61 64 4c 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20  eadLock = -1;.  
17150 20 20 63 6e 74 20 3d 20 30 3b 0a 20 20 20 20 64    cnt = 0;.    d
17160 6f 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 6f 74  o{.      int not
17170 55 73 65 64 3b 0a 20 20 20 20 20 20 72 63 20 3d  Used;.      rc =
17180 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64   walTryBeginRead
17190 28 70 57 61 6c 2c 20 26 6e 6f 74 55 73 65 64 2c  (pWal, &notUsed,
171a0 20 31 2c 20 2b 2b 63 6e 74 29 3b 0a 20 20 20 20   1, ++cnt);.    
171b0 7d 77 68 69 6c 65 28 20 72 63 3d 3d 57 41 4c 5f  }while( rc==WAL_
171c0 52 45 54 52 59 20 29 3b 0a 20 20 7d 0a 20 20 72  RETRY );.  }.  r
171d0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
171e0 0a 2a 2a 20 57 72 69 74 65 20 61 20 73 65 74 20  .** Write a set 
171f0 6f 66 20 66 72 61 6d 65 73 20 74 6f 20 74 68 65  of frames to the
17200 20 6c 6f 67 2e 20 54 68 65 20 63 61 6c 6c 65 72   log. The caller
17210 20 6d 75 73 74 20 68 6f 6c 64 20 74 68 65 20 77   must hold the w
17220 72 69 74 65 2d 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20  rite-lock.** on 
17230 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 28 6f 62  the log file (ob
17240 74 61 69 6e 65 64 20 75 73 69 6e 67 20 73 71 6c  tained using sql
17250 69 74 65 33 57 61 6c 42 65 67 69 6e 57 72 69 74  ite3WalBeginWrit
17260 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 29 29 2e  eTransaction()).
17270 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
17280 61 6c 46 72 61 6d 65 73 28 0a 20 20 57 61 6c 20  alFrames(.  Wal 
17290 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20  *pWal,          
172a0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
172b0 61 6c 20 68 61 6e 64 6c 65 20 74 6f 20 77 72 69  al handle to wri
172c0 74 65 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73  te to */.  int s
172d0 7a 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20  zPage,          
172e0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
172f0 74 61 62 61 73 65 20 70 61 67 65 2d 73 69 7a 65  tabase page-size
17300 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 50   in bytes */.  P
17310 67 48 64 72 20 2a 70 4c 69 73 74 2c 20 20 20 20  gHdr *pList,    
17320 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
17330 2a 20 4c 69 73 74 20 6f 66 20 64 69 72 74 79 20  * List of dirty 
17340 70 61 67 65 73 20 74 6f 20 77 72 69 74 65 20 2a  pages to write *
17350 2f 0a 20 20 50 67 6e 6f 20 6e 54 72 75 6e 63 61  /.  Pgno nTrunca
17360 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  te,             
17370 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
17380 73 69 7a 65 20 61 66 74 65 72 20 74 68 69 73 20  size after this 
17390 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20  commit */.  int 
173a0 69 73 43 6f 6d 6d 69 74 2c 20 20 20 20 20 20 20  isCommit,       
173b0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
173c0 72 75 65 20 69 66 20 74 68 69 73 20 69 73 20 61  rue if this is a
173d0 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20 69 6e 74   commit */.  int
173e0 20 73 79 6e 63 5f 66 6c 61 67 73 20 20 20 20 20   sync_flags     
173f0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
17400 46 6c 61 67 73 20 74 6f 20 70 61 73 73 20 74 6f  Flags to pass to
17410 20 4f 73 53 79 6e 63 28 29 20 28 6f 72 20 30 29   OsSync() (or 0)
17420 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b   */.){.  int rc;
17430 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17440 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64           /* Used
17450 20 74 6f 20 63 61 74 63 68 20 72 65 74 75 72 6e   to catch return
17460 20 63 6f 64 65 73 20 2a 2f 0a 20 20 75 33 32 20   codes */.  u32 
17470 69 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20  iFrame;         
17480 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
17490 65 78 74 20 66 72 61 6d 65 20 61 64 64 72 65 73  ext frame addres
174a0 73 20 2a 2f 0a 20 20 75 38 20 61 46 72 61 6d 65  s */.  u8 aFrame
174b0 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49  [WAL_FRAME_HDRSI
174c0 5a 45 5d 3b 20 20 20 2f 2a 20 42 75 66 66 65 72  ZE];   /* Buffer
174d0 20 74 6f 20 61 73 73 65 6d 62 6c 65 20 66 72 61   to assemble fra
174e0 6d 65 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f 0a  me-header in */.
174f0 20 20 50 67 48 64 72 20 2a 70 3b 20 20 20 20 20    PgHdr *p;     
17500 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17510 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f    /* Iterator to
17520 20 72 75 6e 20 74 68 72 6f 75 67 68 20 70 4c 69   run through pLi
17530 73 74 20 77 69 74 68 2e 20 2a 2f 0a 20 20 50 67  st with. */.  Pg
17540 48 64 72 20 2a 70 4c 61 73 74 20 3d 20 30 3b 20  Hdr *pLast = 0; 
17550 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
17560 20 4c 61 73 74 20 66 72 61 6d 65 20 69 6e 20 6c   Last frame in l
17570 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 61  ist */.  int nLa
17580 73 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  st = 0;         
17590 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
175a0 65 72 20 6f 66 20 65 78 74 72 61 20 63 6f 70 69  er of extra copi
175b0 65 73 20 6f 66 20 6c 61 73 74 20 70 61 67 65 20  es of last page 
175c0 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 4c  */..  assert( pL
175d0 69 73 74 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ist );.  assert(
175e0 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
175f0 20 29 3b 0a 0a 23 69 66 20 64 65 66 69 6e 65 64   );..#if defined
17600 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26 26  (SQLITE_TEST) &&
17610 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
17620 44 45 42 55 47 29 0a 20 20 7b 20 69 6e 74 20 63  DEBUG).  { int c
17630 6e 74 3b 20 66 6f 72 28 63 6e 74 3d 30 2c 20 70  nt; for(cnt=0, p
17640 3d 70 4c 69 73 74 3b 20 70 3b 20 70 3d 70 2d 3e  =pList; p; p=p->
17650 70 44 69 72 74 79 2c 20 63 6e 74 2b 2b 29 7b 7d  pDirty, cnt++){}
17660 0a 20 20 20 20 57 41 4c 54 52 41 43 45 28 28 22  .    WALTRACE(("
17670 57 41 4c 25 70 3a 20 66 72 61 6d 65 20 77 72 69  WAL%p: frame wri
17680 74 65 20 62 65 67 69 6e 2e 20 25 64 20 66 72 61  te begin. %d fra
17690 6d 65 73 2e 20 6d 78 46 72 61 6d 65 3d 25 64 2e  mes. mxFrame=%d.
176a0 20 25 73 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20   %s\n",.        
176b0 20 20 20 20 20 20 70 57 61 6c 2c 20 63 6e 74 2c        pWal, cnt,
176c0 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
176d0 6d 65 2c 20 69 73 43 6f 6d 6d 69 74 20 3f 20 22  me, isCommit ? "
176e0 43 6f 6d 6d 69 74 22 20 3a 20 22 53 70 69 6c 6c  Commit" : "Spill
176f0 22 29 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a  "));.  }.#endif.
17700 0a 20 20 2f 2a 20 53 65 65 20 69 66 20 69 74 20  .  /* See if it 
17710 69 73 20 70 6f 73 73 69 62 6c 65 20 74 6f 20 77  is possible to w
17720 72 69 74 65 20 74 68 65 73 65 20 66 72 61 6d 65  rite these frame
17730 73 20 69 6e 74 6f 20 74 68 65 20 73 74 61 72 74  s into the start
17740 20 6f 66 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 67   of the.  ** log
17750 20 66 69 6c 65 2c 20 69 6e 73 74 65 61 64 20 6f   file, instead o
17760 66 20 61 70 70 65 6e 64 69 6e 67 20 74 6f 20 69  f appending to i
17770 74 20 61 74 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  t at pWal->hdr.m
17780 78 46 72 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69  xFrame..  */.  i
17790 66 28 20 53 51 4c 49 54 45 5f 4f 4b 21 3d 28 72  f( SQLITE_OK!=(r
177a0 63 20 3d 20 77 61 6c 52 65 73 74 61 72 74 4c 6f  c = walRestartLo
177b0 67 28 70 57 61 6c 29 29 20 29 7b 0a 20 20 20 20  g(pWal)) ){.    
177c0 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a  return rc;.  }..
177d0 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20    /* If this is 
177e0 74 68 65 20 66 69 72 73 74 20 66 72 61 6d 65 20  the first frame 
177f0 77 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65  written into the
17800 20 6c 6f 67 2c 20 77 72 69 74 65 20 74 68 65 20   log, write the 
17810 57 41 4c 0a 20 20 2a 2a 20 68 65 61 64 65 72 20  WAL.  ** header 
17820 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  to the start of 
17830 74 68 65 20 57 41 4c 20 66 69 6c 65 2e 20 53 65  the WAL file. Se
17840 65 20 63 6f 6d 6d 65 6e 74 73 20 61 74 20 74 68  e comments at th
17850 65 20 74 6f 70 20 6f 66 0a 20 20 2a 2a 20 74 68  e top of.  ** th
17860 69 73 20 73 6f 75 72 63 65 20 66 69 6c 65 20 66  is source file f
17870 6f 72 20 61 20 64 65 73 63 72 69 70 74 69 6f 6e  or a description
17880 20 6f 66 20 74 68 65 20 57 41 4c 20 68 65 61 64   of the WAL head
17890 65 72 20 66 6f 72 6d 61 74 2e 0a 20 20 2a 2f 0a  er format..  */.
178a0 20 20 69 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d    iFrame = pWal-
178b0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20  >hdr.mxFrame;.  
178c0 69 66 28 20 69 46 72 61 6d 65 3d 3d 30 20 29 7b  if( iFrame==0 ){
178d0 0a 20 20 20 20 75 38 20 61 57 61 6c 48 64 72 5b  .    u8 aWalHdr[
178e0 57 41 4c 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20  WAL_HDRSIZE];   
178f0 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20     /* Buffer to 
17900 61 73 73 65 6d 62 6c 65 20 77 61 6c 2d 68 65 61  assemble wal-hea
17910 64 65 72 20 69 6e 20 2a 2f 0a 20 20 20 20 75 33  der in */.    u3
17920 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20 20  2 aCksum[2];    
17930 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
17940 68 65 63 6b 73 75 6d 20 66 6f 72 20 77 61 6c 2d  hecksum for wal-
17950 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20 20 20 73  header */..    s
17960 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
17970 61 57 61 6c 48 64 72 5b 30 5d 2c 20 28 57 41 4c  aWalHdr[0], (WAL
17980 5f 4d 41 47 49 43 20 7c 20 53 51 4c 49 54 45 5f  _MAGIC | SQLITE_
17990 42 49 47 45 4e 44 49 41 4e 29 29 3b 0a 20 20 20  BIGENDIAN));.   
179a0 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65   sqlite3Put4byte
179b0 28 26 61 57 61 6c 48 64 72 5b 34 5d 2c 20 57 41  (&aWalHdr[4], WA
179c0 4c 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 29 3b 0a  L_MAX_VERSION);.
179d0 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62      sqlite3Put4b
179e0 79 74 65 28 26 61 57 61 6c 48 64 72 5b 38 5d 2c  yte(&aWalHdr[8],
179f0 20 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 73 71   szPage);.    sq
17a00 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61  lite3Put4byte(&a
17a10 57 61 6c 48 64 72 5b 31 32 5d 2c 20 70 57 61 6c  WalHdr[12], pWal
17a20 2d 3e 6e 43 6b 70 74 29 3b 0a 20 20 20 20 73 71  ->nCkpt);.    sq
17a30 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73  lite3_randomness
17a40 28 38 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53  (8, pWal->hdr.aS
17a50 61 6c 74 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79  alt);.    memcpy
17a60 28 26 61 57 61 6c 48 64 72 5b 31 36 5d 2c 20 70  (&aWalHdr[16], p
17a70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20  Wal->hdr.aSalt, 
17a80 38 29 3b 0a 20 20 20 20 77 61 6c 43 68 65 63 6b  8);.    walCheck
17a90 73 75 6d 42 79 74 65 73 28 31 2c 20 61 57 61 6c  sumBytes(1, aWal
17aa0 48 64 72 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45  Hdr, WAL_HDRSIZE
17ab0 2d 32 2a 34 2c 20 30 2c 20 61 43 6b 73 75 6d 29  -2*4, 0, aCksum)
17ac0 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74  ;.    sqlite3Put
17ad0 34 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32  4byte(&aWalHdr[2
17ae0 34 5d 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b 0a  4], aCksum[0]);.
17af0 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62      sqlite3Put4b
17b00 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32 38 5d  yte(&aWalHdr[28]
17b10 2c 20 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 20 20  , aCksum[1]);.  
17b20 20 20 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50    .    pWal->szP
17b30 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20  age = szPage;.  
17b40 20 20 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45    pWal->hdr.bigE
17b50 6e 64 43 6b 73 75 6d 20 3d 20 53 51 4c 49 54 45  ndCksum = SQLITE
17b60 5f 42 49 47 45 4e 44 49 41 4e 3b 0a 20 20 20 20  _BIGENDIAN;.    
17b70 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
17b80 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 43 6b 73 75  Cksum[0] = aCksu
17b90 6d 5b 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  m[0];.    pWal->
17ba0 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
17bb0 31 5d 20 3d 20 61 43 6b 73 75 6d 5b 31 5d 3b 0a  1] = aCksum[1];.
17bc0 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
17bd0 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70  3OsWrite(pWal->p
17be0 57 61 6c 46 64 2c 20 61 57 61 6c 48 64 72 2c 20  WalFd, aWalHdr, 
17bf0 73 69 7a 65 6f 66 28 61 57 61 6c 48 64 72 29 2c  sizeof(aWalHdr),
17c00 20 30 29 3b 0a 20 20 20 20 57 41 4c 54 52 41 43   0);.    WALTRAC
17c10 45 28 28 22 57 41 4c 25 70 3a 20 77 61 6c 2d 68  E(("WAL%p: wal-h
17c20 65 61 64 65 72 20 77 72 69 74 65 20 25 73 5c 6e  eader write %s\n
17c30 22 2c 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66  ", pWal, rc ? "f
17c40 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b  ailed" : "ok"));
17c50 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
17c60 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
17c70 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
17c80 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20 28  .  }.  assert( (
17c90 69 6e 74 29 70 57 61 6c 2d 3e 73 7a 50 61 67 65  int)pWal->szPage
17ca0 3d 3d 73 7a 50 61 67 65 20 29 3b 0a 0a 20 20 2f  ==szPage );..  /
17cb0 2a 20 57 72 69 74 65 20 74 68 65 20 6c 6f 67 20  * Write the log 
17cc0 66 69 6c 65 2e 20 2a 2f 0a 20 20 66 6f 72 28 70  file. */.  for(p
17cd0 3d 70 4c 69 73 74 3b 20 70 3b 20 70 3d 70 2d 3e  =pList; p; p=p->
17ce0 70 44 69 72 74 79 29 7b 0a 20 20 20 20 75 33 32  pDirty){.    u32
17cf0 20 6e 44 62 73 69 7a 65 3b 20 20 20 20 20 20 20   nDbsize;       
17d00 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 62             /* Db
17d10 2d 73 69 7a 65 20 66 69 65 6c 64 20 66 6f 72 20  -size field for 
17d20 66 72 61 6d 65 20 68 65 61 64 65 72 20 2a 2f 0a  frame header */.
17d30 20 20 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b      i64 iOffset;
17d40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17d50 20 20 2f 2a 20 57 72 69 74 65 20 6f 66 66 73 65    /* Write offse
17d60 74 20 69 6e 20 6c 6f 67 20 66 69 6c 65 20 2a 2f  t in log file */
17d70 0a 20 20 20 20 76 6f 69 64 20 2a 70 44 61 74 61  .    void *pData
17d80 3b 0a 20 20 20 0a 20 20 20 20 69 4f 66 66 73 65  ;.   .    iOffse
17d90 74 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73  t = walFrameOffs
17da0 65 74 28 2b 2b 69 46 72 61 6d 65 2c 20 73 7a 50  et(++iFrame, szP
17db0 61 67 65 29 3b 0a 20 20 20 20 2f 2a 20 74 65 73  age);.    /* tes
17dc0 74 63 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e  tcase( IS_BIG_IN
17dd0 54 28 69 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f  T(iOffset) ); //
17de0 20 72 65 71 75 69 72 65 73 20 61 20 34 47 69 42   requires a 4GiB
17df0 20 57 41 4c 20 2a 2f 0a 20 20 20 20 0a 20 20 20   WAL */.    .   
17e00 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20 61 6e 64   /* Populate and
17e10 20 77 72 69 74 65 20 74 68 65 20 66 72 61 6d 65   write the frame
17e20 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 6e   header */.    n
17e30 44 62 73 69 7a 65 20 3d 20 28 69 73 43 6f 6d 6d  Dbsize = (isComm
17e40 69 74 20 26 26 20 70 2d 3e 70 44 69 72 74 79 3d  it && p->pDirty=
17e50 3d 30 29 20 3f 20 6e 54 72 75 6e 63 61 74 65 20  =0) ? nTruncate 
17e60 3a 20 30 3b 0a 23 69 66 20 64 65 66 69 6e 65 64  : 0;.#if defined
17e70 28 53 51 4c 49 54 45 5f 48 41 53 5f 43 4f 44 45  (SQLITE_HAS_CODE
17e80 43 29 0a 20 20 20 20 69 66 28 20 28 70 44 61 74  C).    if( (pDat
17e90 61 20 3d 20 73 71 6c 69 74 65 33 50 61 67 65 72  a = sqlite3Pager
17ea0 43 6f 64 65 63 28 70 29 29 3d 3d 30 20 29 20 72  Codec(p))==0 ) r
17eb0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
17ec0 45 4d 3b 0a 23 65 6c 73 65 0a 20 20 20 20 70 44  EM;.#else.    pD
17ed0 61 74 61 20 3d 20 70 2d 3e 70 44 61 74 61 3b 0a  ata = p->pData;.
17ee0 23 65 6e 64 69 66 0a 20 20 20 20 77 61 6c 45 6e  #endif.    walEn
17ef0 63 6f 64 65 46 72 61 6d 65 28 70 57 61 6c 2c 20  codeFrame(pWal, 
17f00 70 2d 3e 70 67 6e 6f 2c 20 6e 44 62 73 69 7a 65  p->pgno, nDbsize
17f10 2c 20 70 44 61 74 61 2c 20 61 46 72 61 6d 65 29  , pData, aFrame)
17f20 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
17f30 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e  e3OsWrite(pWal->
17f40 70 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20  pWalFd, aFrame, 
17f50 73 69 7a 65 6f 66 28 61 46 72 61 6d 65 29 2c 20  sizeof(aFrame), 
17f60 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 69 66  iOffset);.    if
17f70 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
17f80 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
17f90 72 63 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  rc;.    }..    /
17fa0 2a 20 57 72 69 74 65 20 74 68 65 20 70 61 67 65  * Write the page
17fb0 20 64 61 74 61 20 2a 2f 0a 20 20 20 20 72 63 20   data */.    rc 
17fc0 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65  = sqlite3OsWrite
17fd0 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 70  (pWal->pWalFd, p
17fe0 44 61 74 61 2c 20 73 7a 50 61 67 65 2c 20 69 4f  Data, szPage, iO
17ff0 66 66 73 65 74 2b 73 69 7a 65 6f 66 28 61 46 72  ffset+sizeof(aFr
18000 61 6d 65 29 29 3b 0a 20 20 20 20 69 66 28 20 72  ame));.    if( r
18010 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
18020 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
18030 0a 20 20 20 20 7d 0a 20 20 20 20 70 4c 61 73 74  .    }.    pLast
18040 20 3d 20 70 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20   = p;.  }..  /* 
18050 53 79 6e 63 20 74 68 65 20 6c 6f 67 20 66 69 6c  Sync the log fil
18060 65 20 69 66 20 74 68 65 20 27 69 73 53 79 6e 63  e if the 'isSync
18070 27 20 66 6c 61 67 20 77 61 73 20 73 70 65 63 69  ' flag was speci
18080 66 69 65 64 2e 20 2a 2f 0a 20 20 69 66 28 20 73  fied. */.  if( s
18090 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a 20 20 20  ync_flags ){.   
180a0 20 69 36 34 20 69 53 65 67 6d 65 6e 74 20 3d 20   i64 iSegment = 
180b0 73 71 6c 69 74 65 33 4f 73 53 65 63 74 6f 72 53  sqlite3OsSectorS
180c0 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ize(pWal->pWalFd
180d0 29 3b 0a 20 20 20 20 69 36 34 20 69 4f 66 66 73  );.    i64 iOffs
180e0 65 74 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66  et = walFrameOff
180f0 73 65 74 28 69 46 72 61 6d 65 2b 31 2c 20 73 7a  set(iFrame+1, sz
18100 50 61 67 65 29 3b 0a 0a 20 20 20 20 61 73 73 65  Page);..    asse
18110 72 74 28 20 69 73 43 6f 6d 6d 69 74 20 29 3b 0a  rt( isCommit );.
18120 20 20 20 20 61 73 73 65 72 74 28 20 69 53 65 67      assert( iSeg
18130 6d 65 6e 74 3e 30 20 29 3b 0a 0a 20 20 20 20 69  ment>0 );..    i
18140 53 65 67 6d 65 6e 74 20 3d 20 28 28 28 69 4f 66  Segment = (((iOf
18150 66 73 65 74 2b 69 53 65 67 6d 65 6e 74 2d 31 29  fset+iSegment-1)
18160 2f 69 53 65 67 6d 65 6e 74 29 20 2a 20 69 53 65  /iSegment) * iSe
18170 67 6d 65 6e 74 29 3b 0a 20 20 20 20 77 68 69 6c  gment);.    whil
18180 65 28 20 69 4f 66 66 73 65 74 3c 69 53 65 67 6d  e( iOffset<iSegm
18190 65 6e 74 20 29 7b 0a 20 20 20 20 20 20 76 6f 69  ent ){.      voi
181a0 64 20 2a 70 44 61 74 61 3b 0a 23 69 66 20 64 65  d *pData;.#if de
181b0 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 48 41 53  fined(SQLITE_HAS
181c0 5f 43 4f 44 45 43 29 0a 20 20 20 20 20 20 69 66  _CODEC).      if
181d0 28 20 28 70 44 61 74 61 20 3d 20 73 71 6c 69 74  ( (pData = sqlit
181e0 65 33 50 61 67 65 72 43 6f 64 65 63 28 70 4c 61  e3PagerCodec(pLa
181f0 73 74 29 29 3d 3d 30 20 29 20 72 65 74 75 72 6e  st))==0 ) return
18200 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 23   SQLITE_NOMEM;.#
18210 65 6c 73 65 0a 20 20 20 20 20 20 70 44 61 74 61  else.      pData
18220 20 3d 20 70 4c 61 73 74 2d 3e 70 44 61 74 61 3b   = pLast->pData;
18230 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 77 61  .#endif.      wa
18240 6c 45 6e 63 6f 64 65 46 72 61 6d 65 28 70 57 61  lEncodeFrame(pWa
18250 6c 2c 20 70 4c 61 73 74 2d 3e 70 67 6e 6f 2c 20  l, pLast->pgno, 
18260 6e 54 72 75 6e 63 61 74 65 2c 20 70 44 61 74 61  nTruncate, pData
18270 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20 20 20 20  , aFrame);.     
18280 20 2f 2a 20 74 65 73 74 63 61 73 65 28 20 49 53   /* testcase( IS
18290 5f 42 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74  _BIG_INT(iOffset
182a0 29 20 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73  ) ); // requires
182b0 20 61 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20   a 4GiB WAL */. 
182c0 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
182d0 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70  3OsWrite(pWal->p
182e0 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20 73  WalFd, aFrame, s
182f0 69 7a 65 6f 66 28 61 46 72 61 6d 65 29 2c 20 69  izeof(aFrame), i
18300 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 69  Offset);.      i
18310 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
18320 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75   ){.        retu
18330 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20  rn rc;.      }. 
18340 20 20 20 20 20 69 4f 66 66 73 65 74 20 2b 3d 20       iOffset += 
18350 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a  WAL_FRAME_HDRSIZ
18360 45 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  E;.      rc = sq
18370 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 57 61  lite3OsWrite(pWa
18380 6c 2d 3e 70 57 61 6c 46 64 2c 20 70 44 61 74 61  l->pWalFd, pData
18390 2c 20 73 7a 50 61 67 65 2c 20 69 4f 66 66 73 65  , szPage, iOffse
183a0 74 29 3b 20 0a 20 20 20 20 20 20 69 66 28 20 72  t); .      if( r
183b0 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
183c0 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72          return r
183d0 63 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  c;.      }.     
183e0 20 6e 4c 61 73 74 2b 2b 3b 0a 20 20 20 20 20 20   nLast++;.      
183f0 69 4f 66 66 73 65 74 20 2b 3d 20 73 7a 50 61 67  iOffset += szPag
18400 65 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 63  e;.    }..    rc
18410 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63   = sqlite3OsSync
18420 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 73  (pWal->pWalFd, s
18430 79 6e 63 5f 66 6c 61 67 73 29 3b 0a 20 20 7d 0a  ync_flags);.  }.
18440 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 64 61 74  .  /* Append dat
18450 61 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64  a to the wal-ind
18460 65 78 2e 20 49 74 20 69 73 20 6e 6f 74 20 6e 65  ex. It is not ne
18470 63 65 73 73 61 72 79 20 74 6f 20 6c 6f 63 6b 20  cessary to lock 
18480 74 68 65 20 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e  the .  ** wal-in
18490 64 65 78 20 74 6f 20 64 6f 20 74 68 69 73 20 61  dex to do this a
184a0 73 20 74 68 65 20 53 51 4c 49 54 45 5f 53 48 4d  s the SQLITE_SHM
184b0 5f 57 52 49 54 45 20 6c 6f 63 6b 20 68 65 6c 64  _WRITE lock held
184c0 20 6f 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   on the wal-inde
184d0 78 0a 20 20 2a 2a 20 67 75 61 72 61 6e 74 65 65  x.  ** guarantee
184e0 73 20 74 68 61 74 20 74 68 65 72 65 20 61 72 65  s that there are
184f0 20 6e 6f 20 6f 74 68 65 72 20 77 72 69 74 65 72   no other writer
18500 73 2c 20 61 6e 64 20 6e 6f 20 64 61 74 61 20 74  s, and no data t
18510 68 61 74 20 6d 61 79 0a 20 20 2a 2a 20 62 65 20  hat may.  ** be 
18520 69 6e 20 75 73 65 20 62 79 20 65 78 69 73 74 69  in use by existi
18530 6e 67 20 72 65 61 64 65 72 73 20 69 73 20 62 65  ng readers is be
18540 69 6e 67 20 6f 76 65 72 77 72 69 74 74 65 6e 2e  ing overwritten.
18550 0a 20 20 2a 2f 0a 20 20 69 46 72 61 6d 65 20 3d  .  */.  iFrame =
18560 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
18570 6d 65 3b 0a 20 20 66 6f 72 28 70 3d 70 4c 69 73  me;.  for(p=pLis
18580 74 3b 20 70 20 26 26 20 72 63 3d 3d 53 51 4c 49  t; p && rc==SQLI
18590 54 45 5f 4f 4b 3b 20 70 3d 70 2d 3e 70 44 69 72  TE_OK; p=p->pDir
185a0 74 79 29 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b  ty){.    iFrame+
185b0 2b 3b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49  +;.    rc = walI
185c0 6e 64 65 78 41 70 70 65 6e 64 28 70 57 61 6c 2c  ndexAppend(pWal,
185d0 20 69 46 72 61 6d 65 2c 20 70 2d 3e 70 67 6e 6f   iFrame, p->pgno
185e0 29 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20  );.  }.  while( 
185f0 6e 4c 61 73 74 3e 30 20 26 26 20 72 63 3d 3d 53  nLast>0 && rc==S
18600 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
18610 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 6e 4c  iFrame++;.    nL
18620 61 73 74 2d 2d 3b 0a 20 20 20 20 72 63 20 3d 20  ast--;.    rc = 
18630 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64 28 70  walIndexAppend(p
18640 57 61 6c 2c 20 69 46 72 61 6d 65 2c 20 70 4c 61  Wal, iFrame, pLa
18650 73 74 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 0a  st->pgno);.  }..
18660 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
18670 5f 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 55 70  _OK ){.    /* Up
18680 64 61 74 65 20 74 68 65 20 70 72 69 76 61 74 65  date the private
18690 20 63 6f 70 79 20 6f 66 20 74 68 65 20 68 65 61   copy of the hea
186a0 64 65 72 2e 20 2a 2f 0a 20 20 20 20 70 57 61 6c  der. */.    pWal
186b0 2d 3e 68 64 72 2e 73 7a 50 61 67 65 20 3d 20 28  ->hdr.szPage = (
186c0 75 31 36 29 28 28 73 7a 50 61 67 65 26 30 78 66  u16)((szPage&0xf
186d0 66 30 30 29 20 7c 20 28 73 7a 50 61 67 65 3e 3e  f00) | (szPage>>
186e0 31 36 29 29 3b 0a 20 20 20 20 74 65 73 74 63 61  16));.    testca
186f0 73 65 28 20 73 7a 50 61 67 65 3c 3d 33 32 37 36  se( szPage<=3276
18700 38 20 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73  8 );.    testcas
18710 65 28 20 73 7a 50 61 67 65 3e 3d 36 35 35 33 36  e( szPage>=65536
18720 20 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64   );.    pWal->hd
18730 72 2e 6d 78 46 72 61 6d 65 20 3d 20 69 46 72 61  r.mxFrame = iFra
18740 6d 65 3b 0a 20 20 20 20 69 66 28 20 69 73 43 6f  me;.    if( isCo
18750 6d 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 70 57  mmit ){.      pW
18760 61 6c 2d 3e 68 64 72 2e 69 43 68 61 6e 67 65 2b  al->hdr.iChange+
18770 2b 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 68  +;.      pWal->h
18780 64 72 2e 6e 50 61 67 65 20 3d 20 6e 54 72 75 6e  dr.nPage = nTrun
18790 63 61 74 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20  cate;.    }.    
187a0 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20 61 20  /* If this is a 
187b0 63 6f 6d 6d 69 74 2c 20 75 70 64 61 74 65 20 74  commit, update t
187c0 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
187d0 64 65 72 20 74 6f 6f 2e 20 2a 2f 0a 20 20 20 20  der too. */.    
187e0 69 66 28 20 69 73 43 6f 6d 6d 69 74 20 29 7b 0a  if( isCommit ){.
187f0 20 20 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72        walIndexWr
18800 69 74 65 48 64 72 28 70 57 61 6c 29 3b 0a 20 20  iteHdr(pWal);.  
18810 20 20 20 20 70 57 61 6c 2d 3e 69 43 61 6c 6c 62      pWal->iCallb
18820 61 63 6b 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20  ack = iFrame;.  
18830 20 20 7d 0a 20 20 7d 0a 0a 20 20 57 41 4c 54 52    }.  }..  WALTR
18840 41 43 45 28 28 22 57 41 4c 25 70 3a 20 66 72 61  ACE(("WAL%p: fra
18850 6d 65 20 77 72 69 74 65 20 25 73 5c 6e 22 2c 20  me write %s\n", 
18860 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c  pWal, rc ? "fail
18870 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20  ed" : "ok"));.  
18880 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
18890 20 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e   .** This routin
188a0 65 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 69  e is called to i
188b0 6d 70 6c 65 6d 65 6e 74 20 73 71 6c 69 74 65 33  mplement sqlite3
188c0 5f 77 61 6c 5f 63 68 65 63 6b 70 6f 69 6e 74 28  _wal_checkpoint(
188d0 29 20 61 6e 64 0a 2a 2a 20 72 65 6c 61 74 65 64  ) and.** related
188e0 20 69 6e 74 65 72 66 61 63 65 73 2e 0a 2a 2a 0a   interfaces..**.
188f0 2a 2a 20 4f 62 74 61 69 6e 20 61 20 43 48 45 43  ** Obtain a CHEC
18900 4b 50 4f 49 4e 54 20 6c 6f 63 6b 20 61 6e 64 20  KPOINT lock and 
18910 74 68 65 6e 20 62 61 63 6b 66 69 6c 6c 20 61 73  then backfill as
18920 20 6d 75 63 68 20 69 6e 66 6f 72 6d 61 74 69 6f   much informatio
18930 6e 20 61 73 0a 2a 2a 20 77 65 20 63 61 6e 20 66  n as.** we can f
18940 72 6f 6d 20 57 41 4c 20 69 6e 74 6f 20 74 68 65  rom WAL into the
18950 20 64 61 74 61 62 61 73 65 2e 0a 2a 2f 0a 69 6e   database..*/.in
18960 74 20 73 71 6c 69 74 65 33 57 61 6c 43 68 65 63  t sqlite3WalChec
18970 6b 70 6f 69 6e 74 28 0a 20 20 57 61 6c 20 2a 70  kpoint(.  Wal *p
18980 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Wal,            
18990 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c            /* Wal
189a0 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20   connection */. 
189b0 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67 73 2c   int sync_flags,
189c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
189d0 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20 73 79 6e   /* Flags to syn
189e0 63 20 64 62 20 66 69 6c 65 20 77 69 74 68 20 28  c db file with (
189f0 6f 72 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20 6e  or 0) */.  int n
18a00 42 75 66 2c 20 20 20 20 20 20 20 20 20 20 20 20  Buf,            
18a10 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
18a20 7a 65 20 6f 66 20 74 65 6d 70 6f 72 61 72 79 20  ze of temporary 
18a30 62 75 66 66 65 72 20 2a 2f 0a 20 20 75 38 20 2a  buffer */.  u8 *
18a40 7a 42 75 66 20 20 20 20 20 20 20 20 20 20 20 20  zBuf            
18a50 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
18a60 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72 20  emporary buffer 
18a70 74 6f 20 75 73 65 20 2a 2f 0a 29 7b 0a 20 20 69  to use */.){.  i
18a80 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
18a90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
18aa0 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
18ab0 0a 20 20 69 6e 74 20 69 73 43 68 61 6e 67 65 64  .  int isChanged
18ac0 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
18ad0 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61 20     /* True if a 
18ae0 6e 65 77 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  new wal-index he
18af0 61 64 65 72 20 69 73 20 6c 6f 61 64 65 64 20 2a  ader is loaded *
18b00 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  /..  assert( pWa
18b10 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 30 20 29  l->ckptLock==0 )
18b20 3b 0a 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  ;..  WALTRACE(("
18b30 57 41 4c 25 70 3a 20 63 68 65 63 6b 70 6f 69 6e  WAL%p: checkpoin
18b40 74 20 62 65 67 69 6e 73 5c 6e 22 2c 20 70 57 61  t begins\n", pWa
18b50 6c 29 29 3b 0a 20 20 72 63 20 3d 20 77 61 6c 4c  l));.  rc = walL
18b60 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
18b70 6c 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b  l, WAL_CKPT_LOCK
18b80 2c 20 31 29 3b 0a 20 20 69 66 28 20 72 63 20 29  , 1);.  if( rc )
18b90 7b 0a 20 20 20 20 2f 2a 20 55 73 75 61 6c 6c 79  {.    /* Usually
18ba0 20 74 68 69 73 20 69 73 20 53 51 4c 49 54 45 5f   this is SQLITE_
18bb0 42 55 53 59 20 6d 65 61 6e 69 6e 67 20 74 68 61  BUSY meaning tha
18bc0 74 20 61 6e 6f 74 68 65 72 20 74 68 72 65 61 64  t another thread
18bd0 20 6f 72 20 70 72 6f 63 65 73 73 0a 20 20 20 20   or process.    
18be0 2a 2a 20 69 73 20 61 6c 72 65 61 64 79 20 72 75  ** is already ru
18bf0 6e 6e 69 6e 67 20 61 20 63 68 65 63 6b 70 6f 69  nning a checkpoi
18c00 6e 74 2c 20 6f 72 20 6d 61 79 62 65 20 61 20 72  nt, or maybe a r
18c10 65 63 6f 76 65 72 79 2e 20 20 42 75 74 20 69 74  ecovery.  But it
18c20 20 6d 69 67 68 74 0a 20 20 20 20 2a 2a 20 61 6c   might.    ** al
18c30 73 6f 20 62 65 20 53 51 4c 49 54 45 5f 49 4f 45  so be SQLITE_IOE
18c40 52 52 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72  RR. */.    retur
18c50 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70 57 61 6c  n rc;.  }.  pWal
18c60 2d 3e 63 6b 70 74 4c 6f 63 6b 20 3d 20 31 3b 0a  ->ckptLock = 1;.
18c70 0a 20 20 2f 2a 20 43 6f 70 79 20 64 61 74 61 20  .  /* Copy data 
18c80 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20 74 6f 20  from the log to 
18c90 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
18ca0 65 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 77 61 6c  e. */.  rc = wal
18cb0 49 6e 64 65 78 52 65 61 64 48 64 72 28 70 57 61  IndexReadHdr(pWa
18cc0 6c 2c 20 26 69 73 43 68 61 6e 67 65 64 29 3b 0a  l, &isChanged);.
18cd0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
18ce0 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
18cf0 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 70 57  walCheckpoint(pW
18d00 61 6c 2c 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20  al, sync_flags, 
18d10 6e 42 75 66 2c 20 7a 42 75 66 29 3b 0a 20 20 7d  nBuf, zBuf);.  }
18d20 0a 20 20 69 66 28 20 69 73 43 68 61 6e 67 65 64  .  if( isChanged
18d30 20 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 61 20   ){.    /* If a 
18d40 6e 65 77 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  new wal-index he
18d50 61 64 65 72 20 77 61 73 20 6c 6f 61 64 65 64 20  ader was loaded 
18d60 62 65 66 6f 72 65 20 74 68 65 20 63 68 65 63 6b  before the check
18d70 70 6f 69 6e 74 20 77 61 73 20 0a 20 20 20 20 2a  point was .    *
18d80 2a 20 70 65 72 66 6f 72 6d 65 64 2c 20 74 68 65  * performed, the
18d90 6e 20 74 68 65 20 70 61 67 65 72 2d 63 61 63 68  n the pager-cach
18da0 65 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74  e associated wit
18db0 68 20 70 57 61 6c 20 69 73 20 6e 6f 77 0a 20 20  h pWal is now.  
18dc0 20 20 2a 2a 20 6f 75 74 20 6f 66 20 64 61 74 65    ** out of date
18dd0 2e 20 53 6f 20 7a 65 72 6f 20 74 68 65 20 63 61  . So zero the ca
18de0 63 68 65 64 20 77 61 6c 2d 69 6e 64 65 78 20 68  ched wal-index h
18df0 65 61 64 65 72 20 74 6f 20 65 6e 73 75 72 65 20  eader to ensure 
18e00 74 68 61 74 0a 20 20 20 20 2a 2a 20 6e 65 78 74  that.    ** next
18e10 20 74 69 6d 65 20 74 68 65 20 70 61 67 65 72 20   time the pager 
18e20 6f 70 65 6e 73 20 61 20 73 6e 61 70 73 68 6f 74  opens a snapshot
18e30 20 6f 6e 20 74 68 69 73 20 64 61 74 61 62 61 73   on this databas
18e40 65 20 69 74 20 6b 6e 6f 77 73 20 74 68 61 74 0a  e it knows that.
18e50 20 20 20 20 2a 2a 20 74 68 65 20 63 61 63 68 65      ** the cache
18e60 20 6e 65 65 64 73 20 74 6f 20 62 65 20 72 65 73   needs to be res
18e70 65 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d  et..    */.    m
18e80 65 6d 73 65 74 28 26 70 57 61 6c 2d 3e 68 64 72  emset(&pWal->hdr
18e90 2c 20 30 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49  , 0, sizeof(WalI
18ea0 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 7d 0a 0a  ndexHdr));.  }..
18eb0 20 20 2f 2a 20 52 65 6c 65 61 73 65 20 74 68 65    /* Release the
18ec0 20 6c 6f 63 6b 73 2e 20 2a 2f 0a 20 20 77 61 6c   locks. */.  wal
18ed0 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  UnlockExclusive(
18ee0 70 57 61 6c 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c  pWal, WAL_CKPT_L
18ef0 4f 43 4b 2c 20 31 29 3b 0a 20 20 70 57 61 6c 2d  OCK, 1);.  pWal-
18f00 3e 63 6b 70 74 4c 6f 63 6b 20 3d 20 30 3b 0a 20  >ckptLock = 0;. 
18f10 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
18f20 70 3a 20 63 68 65 63 6b 70 6f 69 6e 74 20 25 73  p: checkpoint %s
18f30 5c 6e 22 2c 20 70 57 61 6c 2c 20 72 63 20 3f 20  \n", pWal, rc ? 
18f40 22 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29  "failed" : "ok")
18f50 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
18f60 7d 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 74 68 65  }../* Return the
18f70 20 76 61 6c 75 65 20 74 6f 20 70 61 73 73 20 74   value to pass t
18f80 6f 20 61 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f  o a sqlite3_wal_
18f90 68 6f 6f 6b 20 63 61 6c 6c 62 61 63 6b 2c 20 74  hook callback, t
18fa0 68 65 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20  he.** number of 
18fb0 66 72 61 6d 65 73 20 69 6e 20 74 68 65 20 57 41  frames in the WA
18fc0 4c 20 61 74 20 74 68 65 20 70 6f 69 6e 74 20 6f  L at the point o
18fd0 66 20 74 68 65 20 6c 61 73 74 20 63 6f 6d 6d 69  f the last commi
18fe0 74 20 73 69 6e 63 65 0a 2a 2a 20 73 71 6c 69 74  t since.** sqlit
18ff0 65 33 57 61 6c 43 61 6c 6c 62 61 63 6b 28 29 20  e3WalCallback() 
19000 77 61 73 20 63 61 6c 6c 65 64 2e 20 20 49 66 20  was called.  If 
19010 6e 6f 20 63 6f 6d 6d 69 74 73 20 68 61 76 65 20  no commits have 
19020 6f 63 63 75 72 72 65 64 20 73 69 6e 63 65 0a 2a  occurred since.*
19030 2a 20 74 68 65 20 6c 61 73 74 20 63 61 6c 6c 2c  * the last call,
19040 20 74 68 65 6e 20 72 65 74 75 72 6e 20 30 2e 0a   then return 0..
19050 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
19060 6c 43 61 6c 6c 62 61 63 6b 28 57 61 6c 20 2a 70  lCallback(Wal *p
19070 57 61 6c 29 7b 0a 20 20 75 33 32 20 72 65 74 20  Wal){.  u32 ret 
19080 3d 20 30 3b 0a 20 20 69 66 28 20 70 57 61 6c 20  = 0;.  if( pWal 
19090 29 7b 0a 20 20 20 20 72 65 74 20 3d 20 70 57 61  ){.    ret = pWa
190a0 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 3b 0a 20 20  l->iCallback;.  
190b0 20 20 70 57 61 6c 2d 3e 69 43 61 6c 6c 62 61 63    pWal->iCallbac
190c0 6b 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74  k = 0;.  }.  ret
190d0 75 72 6e 20 28 69 6e 74 29 72 65 74 3b 0a 7d 0a  urn (int)ret;.}.
190e0 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
190f0 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74  tion is called t
19100 6f 20 63 68 61 6e 67 65 20 74 68 65 20 57 41 4c  o change the WAL
19110 20 73 75 62 73 79 73 74 65 6d 20 69 6e 74 6f 20   subsystem into 
19120 6f 72 20 6f 75 74 0a 2a 2a 20 6f 66 20 6c 6f 63  or out.** of loc
19130 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53  king_mode=EXCLUS
19140 49 56 45 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70  IVE..**.** If op
19150 20 69 73 20 7a 65 72 6f 2c 20 74 68 65 6e 20 61   is zero, then a
19160 74 74 65 6d 70 74 20 74 6f 20 63 68 61 6e 67 65  ttempt to change
19170 20 66 72 6f 6d 20 6c 6f 63 6b 69 6e 67 5f 6d 6f   from locking_mo
19180 64 65 3d 45 58 43 4c 55 53 49 56 45 0a 2a 2a 20  de=EXCLUSIVE.** 
19190 69 6e 74 6f 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64  into locking_mod
191a0 65 3d 4e 4f 52 4d 41 4c 2e 20 20 54 68 69 73 20  e=NORMAL.  This 
191b0 6d 65 61 6e 73 20 74 68 61 74 20 77 65 20 6d 75  means that we mu
191c0 73 74 20 61 63 71 75 69 72 65 20 61 20 6c 6f 63  st acquire a loc
191d0 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20 70 57 61 6c  k.** on the pWal
191e0 2d 3e 72 65 61 64 4c 6f 63 6b 20 62 79 74 65 2e  ->readLock byte.
191f0 20 20 49 66 20 74 68 65 20 57 41 4c 20 69 73 20    If the WAL is 
19200 61 6c 72 65 61 64 79 20 69 6e 20 6c 6f 63 6b 69  already in locki
19210 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 0a 2a  ng_mode=NORMAL.*
19220 2a 20 6f 72 20 69 66 20 74 68 65 20 61 63 71 75  * or if the acqu
19230 69 73 69 74 69 6f 6e 20 6f 66 20 74 68 65 20 6c  isition of the l
19240 6f 63 6b 20 66 61 69 6c 73 2c 20 74 68 65 6e 20  ock fails, then 
19250 72 65 74 75 72 6e 20 30 2e 20 20 49 66 20 74 68  return 0.  If th
19260 65 0a 2a 2a 20 74 72 61 6e 73 69 74 69 6f 6e 20  e.** transition 
19270 6f 75 74 20 6f 66 20 65 78 63 6c 75 73 69 76 65  out of exclusive
19280 2d 6d 6f 64 65 20 69 73 20 73 75 63 63 65 73 73  -mode is success
19290 66 75 6c 2c 20 72 65 74 75 72 6e 20 31 2e 20 20  ful, return 1.  
192a0 54 68 69 73 0a 2a 2a 20 6f 70 65 72 61 74 69 6f  This.** operatio
192b0 6e 20 6d 75 73 74 20 6f 63 63 75 72 20 77 68 69  n must occur whi
192c0 6c 65 20 74 68 65 20 70 61 67 65 72 20 69 73 20  le the pager is 
192d0 73 74 69 6c 6c 20 68 6f 6c 64 69 6e 67 20 74 68  still holding th
192e0 65 20 65 78 63 6c 75 73 69 76 65 0a 2a 2a 20 6c  e exclusive.** l
192f0 6f 63 6b 20 6f 6e 20 74 68 65 20 6d 61 69 6e 20  ock on the main 
19300 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a  database file..*
19310 2a 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20 6f 6e  *.** If op is on
19320 65 2c 20 74 68 65 6e 20 63 68 61 6e 67 65 20 66  e, then change f
19330 72 6f 6d 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65  rom locking_mode
19340 3d 4e 4f 52 4d 41 4c 20 69 6e 74 6f 20 0a 2a 2a  =NORMAL into .**
19350 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58   locking_mode=EX
19360 43 4c 55 53 49 56 45 2e 20 20 54 68 69 73 20 6d  CLUSIVE.  This m
19370 65 61 6e 73 20 74 68 61 74 20 74 68 65 20 70 57  eans that the pW
19380 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 6d 75 73  al->readLock mus
19390 74 0a 2a 2a 20 62 65 20 72 65 6c 65 61 73 65 64  t.** be released
193a0 2e 20 20 52 65 74 75 72 6e 20 31 20 69 66 20 74  .  Return 1 if t
193b0 68 65 20 74 72 61 6e 73 69 74 69 6f 6e 20 69 73  he transition is
193c0 20 6d 61 64 65 20 61 6e 64 20 30 20 69 66 20 74   made and 0 if t
193d0 68 65 0a 2a 2a 20 57 41 4c 20 69 73 20 61 6c 72  he.** WAL is alr
193e0 65 61 64 79 20 69 6e 20 65 78 63 6c 75 73 69 76  eady in exclusiv
193f0 65 2d 6c 6f 63 6b 69 6e 67 20 6d 6f 64 65 20 2d  e-locking mode -
19400 20 6d 65 61 6e 69 6e 67 20 74 68 61 74 20 74 68   meaning that th
19410 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 69 73  is.** routine is
19420 20 61 20 6e 6f 2d 6f 70 2e 20 20 54 68 65 20 70   a no-op.  The p
19430 61 67 65 72 20 6d 75 73 74 20 61 6c 72 65 61 64  ager must alread
19440 79 20 68 6f 6c 64 20 74 68 65 20 65 78 63 6c 75  y hold the exclu
19450 73 69 76 65 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20  sive lock.** on 
19460 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73  the main databas
19470 65 20 66 69 6c 65 20 62 65 66 6f 72 65 20 69 6e  e file before in
19480 76 6f 6b 69 6e 67 20 74 68 69 73 20 6f 70 65 72  voking this oper
19490 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  ation..**.** If 
194a0 6f 70 20 69 73 20 6e 65 67 61 74 69 76 65 2c 20  op is negative, 
194b0 74 68 65 6e 20 64 6f 20 61 20 64 72 79 2d 72 75  then do a dry-ru
194c0 6e 20 6f 66 20 74 68 65 20 6f 70 3d 3d 31 20 63  n of the op==1 c
194d0 61 73 65 20 62 75 74 20 64 6f 0a 2a 2a 20 6e 6f  ase but do.** no
194e0 74 20 61 63 74 75 61 6c 6c 79 20 63 68 61 6e 67  t actually chang
194f0 65 20 61 6e 79 74 68 69 6e 67 2e 20 54 68 65 20  e anything. The 
19500 70 61 67 65 72 20 75 73 65 73 20 74 68 69 73 20  pager uses this 
19510 74 6f 20 73 65 65 20 69 66 20 69 74 0a 2a 2a 20  to see if it.** 
19520 73 68 6f 75 6c 64 20 61 63 71 75 69 72 65 20 74  should acquire t
19530 68 65 20 64 61 74 61 62 61 73 65 20 65 78 63 6c  he database excl
19540 75 73 69 76 65 20 6c 6f 63 6b 20 70 72 69 6f 72  usive lock prior
19550 20 74 6f 20 69 6e 76 6f 6b 69 6e 67 0a 2a 2a 20   to invoking.** 
19560 74 68 65 20 6f 70 3d 3d 31 20 63 61 73 65 2e 0a  the op==1 case..
19570 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
19580 6c 45 78 63 6c 75 73 69 76 65 4d 6f 64 65 28 57  lExclusiveMode(W
19590 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6f 70  al *pWal, int op
195a0 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 61  ){.  int rc;.  a
195b0 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69  ssert( pWal->wri
195c0 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 61  teLock==0 );.  a
195d0 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 65 78 63  ssert( pWal->exc
195e0 6c 75 73 69 76 65 4d 6f 64 65 21 3d 57 41 4c 5f  lusiveMode!=WAL_
195f0 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20  HEAPMEMORY_MODE 
19600 7c 7c 20 6f 70 3d 3d 2d 31 20 29 3b 0a 0a 20 20  || op==-1 );..  
19610 2f 2a 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  /* pWal->readLoc
19620 6b 20 69 73 20 75 73 75 61 6c 6c 79 20 73 65 74  k is usually set
19630 2c 20 62 75 74 20 6d 69 67 68 74 20 62 65 20 2d  , but might be -
19640 31 20 69 66 20 74 68 65 72 65 20 77 61 73 20 61  1 if there was a
19650 20 0a 20 20 2a 2a 20 70 72 69 6f 72 20 65 72 72   .  ** prior err
19660 6f 72 20 77 68 69 6c 65 20 61 74 74 65 6d 70 74  or while attempt
19670 69 6e 67 20 74 6f 20 61 63 71 75 69 72 65 20 61  ing to acquire a
19680 72 65 20 72 65 61 64 2d 6c 6f 63 6b 2e 20 54 68  re read-lock. Th
19690 69 73 20 63 61 6e 6e 6f 74 20 0a 20 20 2a 2a 20  is cannot .  ** 
196a0 68 61 70 70 65 6e 20 69 66 20 74 68 65 20 63 6f  happen if the co
196b0 6e 6e 65 63 74 69 6f 6e 20 69 73 20 61 63 74 75  nnection is actu
196c0 61 6c 6c 79 20 69 6e 20 65 78 63 6c 75 73 69 76  ally in exclusiv
196d0 65 20 6d 6f 64 65 20 28 61 73 20 6e 6f 20 78 53  e mode (as no xS
196e0 68 6d 4c 6f 63 6b 0a 20 20 2a 2a 20 6c 6f 63 6b  hmLock.  ** lock
196f0 73 20 61 72 65 20 74 61 6b 65 6e 20 69 6e 20 74  s are taken in t
19700 68 69 73 20 63 61 73 65 29 2e 20 4e 6f 72 20 73  his case). Nor s
19710 68 6f 75 6c 64 20 74 68 65 20 70 61 67 65 72 20  hould the pager 
19720 61 74 74 65 6d 70 74 20 74 6f 0a 20 20 2a 2a 20  attempt to.  ** 
19730 75 70 67 72 61 64 65 20 74 6f 20 65 78 63 6c 75  upgrade to exclu
19740 73 69 76 65 2d 6d 6f 64 65 20 66 6f 6c 6c 6f 77  sive-mode follow
19750 69 6e 67 20 73 75 63 68 20 61 6e 20 65 72 72 6f  ing such an erro
19760 72 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74  r..  */.  assert
19770 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  ( pWal->readLock
19780 3e 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63  >=0 || pWal->loc
19790 6b 45 72 72 6f 72 20 29 3b 0a 20 20 61 73 73 65  kError );.  asse
197a0 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  rt( pWal->readLo
197b0 63 6b 3e 3d 30 20 7c 7c 20 28 6f 70 3c 3d 30 20  ck>=0 || (op<=0 
197c0 26 26 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69  && pWal->exclusi
197d0 76 65 4d 6f 64 65 3d 3d 30 29 20 29 3b 0a 0a 20  veMode==0) );.. 
197e0 20 69 66 28 20 6f 70 3d 3d 30 20 29 7b 0a 20 20   if( op==0 ){.  
197f0 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c    if( pWal->excl
19800 75 73 69 76 65 4d 6f 64 65 20 29 7b 0a 20 20 20  usiveMode ){.   
19810 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69     pWal->exclusi
19820 76 65 4d 6f 64 65 20 3d 20 30 3b 0a 20 20 20 20  veMode = 0;.    
19830 20 20 69 66 28 20 77 61 6c 4c 6f 63 6b 53 68 61    if( walLockSha
19840 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
19850 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65  AD_LOCK(pWal->re
19860 61 64 4c 6f 63 6b 29 29 21 3d 53 51 4c 49 54 45  adLock))!=SQLITE
19870 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 70  _OK ){.        p
19880 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
19890 64 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a  de = 1;.      }.
198a0 20 20 20 20 20 20 72 63 20 3d 20 70 57 61 6c 2d        rc = pWal-
198b0 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d  >exclusiveMode==
198c0 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  0;.    }else{.  
198d0 20 20 20 20 2f 2a 20 41 6c 72 65 61 64 79 20 69      /* Already i
198e0 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e  n locking_mode=N
198f0 4f 52 4d 41 4c 20 2a 2f 0a 20 20 20 20 20 20 72  ORMAL */.      r
19900 63 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d  c = 0;.    }.  }
19910 65 6c 73 65 20 69 66 28 20 6f 70 3e 30 20 29 7b  else if( op>0 ){
19920 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 57 61  .    assert( pWa
19930 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
19940 3d 3d 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72  ==0 );.    asser
19950 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  t( pWal->readLoc
19960 6b 3e 3d 30 20 29 3b 0a 20 20 20 20 77 61 6c 55  k>=0 );.    walU
19970 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
19980 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
19990 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29  pWal->readLock))
199a0 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c  ;.    pWal->excl
199b0 75 73 69 76 65 4d 6f 64 65 20 3d 20 31 3b 0a 20  usiveMode = 1;. 
199c0 20 20 20 72 63 20 3d 20 31 3b 0a 20 20 7d 65 6c     rc = 1;.  }el
199d0 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 70 57 61  se{.    rc = pWa
199e0 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
199f0 3d 3d 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ==0;.  }.  retur
19a00 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  n rc;.}../* .** 
19a10 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 74  Return true if t
19a20 68 65 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e  he argument is n
19a30 6f 6e 2d 4e 55 4c 4c 20 61 6e 64 20 74 68 65 20  on-NULL and the 
19a40 57 41 4c 20 6d 6f 64 75 6c 65 20 69 73 20 75 73  WAL module is us
19a50 69 6e 67 0a 2a 2a 20 68 65 61 70 2d 6d 65 6d 6f  ing.** heap-memo
19a60 72 79 20 66 6f 72 20 74 68 65 20 77 61 6c 2d 69  ry for the wal-i
19a70 6e 64 65 78 2e 20 4f 74 68 65 72 77 69 73 65 2c  ndex. Otherwise,
19a80 20 69 66 20 74 68 65 20 61 72 67 75 6d 65 6e 74   if the argument
19a90 20 69 73 20 4e 55 4c 4c 20 6f 72 20 74 68 65 0a   is NULL or the.
19aa0 2a 2a 20 57 41 4c 20 6d 6f 64 75 6c 65 20 69 73  ** WAL module is
19ab0 20 75 73 69 6e 67 20 73 68 61 72 65 64 2d 6d 65   using shared-me
19ac0 6d 6f 72 79 2c 20 72 65 74 75 72 6e 20 66 61 6c  mory, return fal
19ad0 73 65 2e 20 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  se. .*/.int sqli
19ae0 74 65 33 57 61 6c 48 65 61 70 4d 65 6d 6f 72 79  te3WalHeapMemory
19af0 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 72  (Wal *pWal){.  r
19b00 65 74 75 72 6e 20 28 70 57 61 6c 20 26 26 20 70  eturn (pWal && p
19b10 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
19b20 64 65 3d 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f  de==WAL_HEAPMEMO
19b30 52 59 5f 4d 4f 44 45 20 29 3b 0a 7d 0a 0a 23 65  RY_MODE );.}..#e
19b40 6e 64 69 66 20 2f 2a 20 23 69 66 6e 64 65 66 20  ndif /* #ifndef 
19b50 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 57 41 4c 20  SQLITE_OMIT_WAL 
19b60 2a 2f 0a                                         */.