/ Hex Artifact Content
Login

Artifact f26b8d297bd11cb792e609917f9d4c6718ac8e0e:


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 53 69 7a 65 20 6f 66 20 74 68 65 20   /* Size of the 
54c0: 61 53 65 67 6d 65 6e 74 5b 5d 20 61 72 72 61 79  aSegment[] array
54d0: 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 57 61 6c   */.  struct Wal
54e0: 53 65 67 6d 65 6e 74 20 7b 0a 20 20 20 20 69 6e  Segment {.    in
54f0: 74 20 69 4e 65 78 74 3b 20 20 20 20 20 20 20 20  t iNext;        
5500: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
5510: 65 78 74 20 73 6c 6f 74 20 69 6e 20 61 49 6e 64  ext slot in aInd
5520: 65 78 5b 5d 20 6e 6f 74 20 79 65 74 20 72 65 74  ex[] not yet ret
5530: 75 72 6e 65 64 20 2a 2f 0a 20 20 20 20 68 74 5f  urned */.    ht_
5540: 73 6c 6f 74 20 2a 61 49 6e 64 65 78 3b 20 20 20  slot *aIndex;   
5550: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 30             /* i0
5560: 2c 20 69 31 2c 20 69 32 2e 2e 2e 20 73 75 63 68  , i1, i2... such
5570: 20 74 68 61 74 20 61 50 67 6e 6f 5b 69 4e 5d 20   that aPgno[iN] 
5580: 61 73 63 65 6e 64 20 2a 2f 0a 20 20 20 20 75 33  ascend */.    u3
5590: 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20 20  2 *aPgno;       
55a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
55b0: 72 72 61 79 20 6f 66 20 70 61 67 65 20 6e 75 6d  rray of page num
55c0: 62 65 72 73 2e 20 2a 2f 0a 20 20 20 20 69 6e 74  bers. */.    int
55d0: 20 6e 45 6e 74 72 79 3b 20 20 20 20 20 20 20 20   nEntry;        
55e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
55f0: 78 20 73 69 7a 65 20 6f 66 20 61 50 67 6e 6f 5b  x size of aPgno[
5600: 5d 20 61 6e 64 20 61 49 6e 64 65 78 5b 5d 20 61  ] and aIndex[] a
5610: 72 72 61 79 73 20 2a 2f 0a 20 20 20 20 69 6e 74  rrays */.    int
5620: 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20   iZero;         
5630: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
5640: 61 6d 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63  ame number assoc
5650: 69 61 74 65 64 20 77 69 74 68 20 61 50 67 6e 6f  iated with aPgno
5660: 5b 30 5d 20 2a 2f 0a 20 20 7d 20 61 53 65 67 6d  [0] */.  } aSegm
5670: 65 6e 74 5b 31 5d 3b 20 20 20 20 20 20 20 20 20  ent[1];         
5680: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20           /* One 
5690: 66 6f 72 20 65 76 65 72 79 20 33 32 4b 42 20 70  for every 32KB p
56a0: 61 67 65 20 69 6e 20 74 68 65 20 57 41 4c 20 2a  age in the WAL *
56b0: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 66 69  /.};../*.** Defi
56c0: 6e 65 20 74 68 65 20 70 61 72 61 6d 65 74 65 72  ne the parameter
56d0: 73 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61  s of the hash ta
56e0: 62 6c 65 73 20 69 6e 20 74 68 65 20 77 61 6c 2d  bles in the wal-
56f0: 69 6e 64 65 78 20 66 69 6c 65 2e 20 54 68 65 72  index file. Ther
5700: 65 0a 2a 2a 20 69 73 20 61 20 68 61 73 68 2d 74  e.** is a hash-t
5710: 61 62 6c 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 65  able following e
5720: 76 65 72 79 20 48 41 53 48 54 41 42 4c 45 5f 4e  very HASHTABLE_N
5730: 50 41 47 45 20 70 61 67 65 20 6e 75 6d 62 65 72  PAGE page number
5740: 73 20 69 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d  s in the.** wal-
5750: 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 43 68 61  index..**.** Cha
5760: 6e 67 69 6e 67 20 61 6e 79 20 6f 66 20 74 68 65  nging any of the
5770: 73 65 20 63 6f 6e 73 74 61 6e 74 73 20 77 69 6c  se constants wil
5780: 6c 20 61 6c 74 65 72 20 74 68 65 20 77 61 6c 2d  l alter the wal-
5790: 69 6e 64 65 78 20 66 6f 72 6d 61 74 20 61 6e 64  index format and
57a0: 0a 2a 2a 20 63 72 65 61 74 65 20 69 6e 63 6f 6d  .** create incom
57b0: 70 61 74 69 62 69 6c 69 74 69 65 73 2e 0a 2a 2f  patibilities..*/
57c0: 0a 23 64 65 66 69 6e 65 20 48 41 53 48 54 41 42  .#define HASHTAB
57d0: 4c 45 5f 4e 50 41 47 45 20 20 20 20 20 20 34 30  LE_NPAGE      40
57e0: 39 36 20 20 20 20 20 20 20 20 20 20 20 20 20 20  96              
57f0: 20 20 20 2f 2a 20 4d 75 73 74 20 62 65 20 70 6f     /* Must be po
5800: 77 65 72 20 6f 66 20 32 20 2a 2f 0a 23 64 65 66  wer of 2 */.#def
5810: 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f 48 41  ine HASHTABLE_HA
5820: 53 48 5f 31 20 20 20 20 20 33 38 33 20 20 20 20  SH_1     383    
5830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5840: 20 53 68 6f 75 6c 64 20 62 65 20 70 72 69 6d 65   Should be prime
5850: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48   */.#define HASH
5860: 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 20 20 20 20  TABLE_NSLOT     
5870: 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47   (HASHTABLE_NPAG
5880: 45 2a 32 29 20 20 2f 2a 20 4d 75 73 74 20 62 65  E*2)  /* Must be
5890: 20 61 20 70 6f 77 65 72 20 6f 66 20 32 20 2a 2f   a power of 2 */
58a0: 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 65 20 62 6c 6f  ../* .** The blo
58b0: 63 6b 20 6f 66 20 70 61 67 65 20 6e 75 6d 62 65  ck of page numbe
58c0: 72 73 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  rs associated wi
58d0: 74 68 20 74 68 65 20 66 69 72 73 74 20 68 61 73  th the first has
58e0: 68 2d 74 61 62 6c 65 20 69 6e 20 61 0a 2a 2a 20  h-table in a.** 
58f0: 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 73 6d 61  wal-index is sma
5900: 6c 6c 65 72 20 74 68 61 6e 20 75 73 75 61 6c 2e  ller than usual.
5910: 20 54 68 69 73 20 69 73 20 73 6f 20 74 68 61 74   This is so that
5920: 20 74 68 65 72 65 20 69 73 20 61 20 63 6f 6d 70   there is a comp
5930: 6c 65 74 65 0a 2a 2a 20 68 61 73 68 2d 74 61 62  lete.** hash-tab
5940: 6c 65 20 6f 6e 20 65 61 63 68 20 61 6c 69 67 6e  le on each align
5950: 65 64 20 33 32 4b 42 20 70 61 67 65 20 6f 66 20  ed 32KB page of 
5960: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a  the wal-index..*
5970: 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48 54 41  /.#define HASHTA
5980: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20 20 28  BLE_NPAGE_ONE  (
5990: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20  HASHTABLE_NPAGE 
59a0: 2d 20 28 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f  - (WALINDEX_HDR_
59b0: 53 49 5a 45 2f 73 69 7a 65 6f 66 28 75 33 32 29  SIZE/sizeof(u32)
59c0: 29 29 0a 0a 2f 2a 20 54 68 65 20 77 61 6c 2d 69  ))../* The wal-i
59d0: 6e 64 65 78 20 69 73 20 64 69 76 69 64 65 64 20  ndex is divided 
59e0: 69 6e 74 6f 20 70 61 67 65 73 20 6f 66 20 57 41  into pages of WA
59f0: 4c 49 4e 44 45 58 5f 50 47 53 5a 20 62 79 74 65  LINDEX_PGSZ byte
5a00: 73 20 65 61 63 68 2e 20 2a 2f 0a 23 64 65 66 69  s each. */.#defi
5a10: 6e 65 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a  ne WALINDEX_PGSZ
5a20: 20 20 20 28 20 20 20 20 20 20 20 20 20 20 20 20     (            
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 5c 0a 20               \. 
5a50: 20 20 20 73 69 7a 65 6f 66 28 68 74 5f 73 6c 6f     sizeof(ht_slo
5a60: 74 29 2a 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c  t)*HASHTABLE_NSL
5a70: 4f 54 20 2b 20 48 41 53 48 54 41 42 4c 45 5f 4e  OT + HASHTABLE_N
5a80: 50 41 47 45 2a 73 69 7a 65 6f 66 28 75 33 32 29  PAGE*sizeof(u32)
5a90: 20 5c 0a 29 0a 0a 2f 2a 0a 2a 2a 20 4f 62 74 61   \.)../*.** Obta
5aa0: 69 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  in a pointer to 
5ab0: 74 68 65 20 69 50 61 67 65 27 74 68 20 70 61 67  the iPage'th pag
5ac0: 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  e of the wal-ind
5ad0: 65 78 2e 20 54 68 65 20 77 61 6c 2d 69 6e 64 65  ex. The wal-inde
5ae0: 78 0a 2a 2a 20 69 73 20 62 72 6f 6b 65 6e 20 69  x.** is broken i
5af0: 6e 74 6f 20 70 61 67 65 73 20 6f 66 20 57 41 4c  nto pages of WAL
5b00: 49 4e 44 45 58 5f 50 47 53 5a 20 62 79 74 65 73  INDEX_PGSZ bytes
5b10: 2e 20 57 61 6c 2d 69 6e 64 65 78 20 70 61 67 65  . Wal-index page
5b20: 73 20 61 72 65 0a 2a 2a 20 6e 75 6d 62 65 72 65  s are.** numbere
5b30: 64 20 66 72 6f 6d 20 7a 65 72 6f 2e 0a 2a 2a 0a  d from zero..**.
5b40: 2a 2a 20 49 66 20 74 68 69 73 20 63 61 6c 6c 20  ** If this call 
5b50: 69 73 20 73 75 63 63 65 73 73 66 75 6c 2c 20 2a  is successful, *
5b60: 70 70 50 61 67 65 20 69 73 20 73 65 74 20 74 6f  ppPage is set to
5b70: 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 77 61   point to the wa
5b80: 6c 2d 69 6e 64 65 78 0a 2a 2a 20 70 61 67 65 20  l-index.** page 
5b90: 61 6e 64 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73  and SQLITE_OK is
5ba0: 20 72 65 74 75 72 6e 65 64 2e 20 49 66 20 61 6e   returned. If an
5bb0: 20 65 72 72 6f 72 20 28 61 6e 20 4f 4f 4d 20 6f   error (an OOM o
5bc0: 72 20 56 46 53 20 65 72 72 6f 72 29 20 6f 63 63  r VFS error) occ
5bd0: 75 72 73 2c 0a 2a 2a 20 74 68 65 6e 20 61 6e 20  urs,.** then an 
5be0: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
5bf0: 65 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e  e is returned an
5c00: 64 20 2a 70 70 50 61 67 65 20 69 73 20 73 65 74  d *ppPage is set
5c10: 20 74 6f 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63   to 0..*/.static
5c20: 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 50 61 67   int walIndexPag
5c30: 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  e(Wal *pWal, int
5c40: 20 69 50 61 67 65 2c 20 76 6f 6c 61 74 69 6c 65   iPage, volatile
5c50: 20 75 33 32 20 2a 2a 70 70 50 61 67 65 29 7b 0a   u32 **ppPage){.
5c60: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
5c70: 45 5f 4f 4b 3b 0a 0a 20 20 2f 2a 20 45 6e 6c 61  E_OK;..  /* Enla
5c80: 72 67 65 20 74 68 65 20 70 57 61 6c 2d 3e 61 70  rge the pWal->ap
5c90: 57 69 44 61 74 61 5b 5d 20 61 72 72 61 79 20 69  WiData[] array i
5ca0: 66 20 72 65 71 75 69 72 65 64 20 2a 2f 0a 20 20  f required */.  
5cb0: 69 66 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74  if( pWal->nWiDat
5cc0: 61 3c 3d 69 50 61 67 65 20 29 7b 0a 20 20 20 20  a<=iPage ){.    
5cd0: 69 6e 74 20 6e 42 79 74 65 20 3d 20 73 69 7a 65  int nByte = size
5ce0: 6f 66 28 75 33 32 2a 29 2a 28 69 50 61 67 65 2b  of(u32*)*(iPage+
5cf0: 31 29 3b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65  1);.    volatile
5d00: 20 75 33 32 20 2a 2a 61 70 4e 65 77 3b 0a 20 20   u32 **apNew;.  
5d10: 20 20 61 70 4e 65 77 20 3d 20 28 76 6f 6c 61 74    apNew = (volat
5d20: 69 6c 65 20 75 33 32 20 2a 2a 29 73 71 6c 69 74  ile u32 **)sqlit
5d30: 65 33 5f 72 65 61 6c 6c 6f 63 28 28 76 6f 69 64  e3_realloc((void
5d40: 20 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44 61 74   *)pWal->apWiDat
5d50: 61 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 69  a, nByte);.    i
5d60: 66 28 20 21 61 70 4e 65 77 20 29 7b 0a 20 20 20  f( !apNew ){.   
5d70: 20 20 20 2a 70 70 50 61 67 65 20 3d 20 30 3b 0a     *ppPage = 0;.
5d80: 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c        return SQL
5d90: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
5da0: 0a 20 20 20 20 6d 65 6d 73 65 74 28 28 76 6f 69  .    memset((voi
5db0: 64 2a 29 26 61 70 4e 65 77 5b 70 57 61 6c 2d 3e  d*)&apNew[pWal->
5dc0: 6e 57 69 44 61 74 61 5d 2c 20 30 2c 0a 20 20 20  nWiData], 0,.   
5dd0: 20 20 20 20 20 20 20 20 73 69 7a 65 6f 66 28 75          sizeof(u
5de0: 33 32 2a 29 2a 28 69 50 61 67 65 2b 31 2d 70 57  32*)*(iPage+1-pW
5df0: 61 6c 2d 3e 6e 57 69 44 61 74 61 29 29 3b 0a 20  al->nWiData));. 
5e00: 20 20 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74     pWal->apWiDat
5e10: 61 20 3d 20 61 70 4e 65 77 3b 0a 20 20 20 20 70  a = apNew;.    p
5e20: 57 61 6c 2d 3e 6e 57 69 44 61 74 61 20 3d 20 69  Wal->nWiData = i
5e30: 50 61 67 65 2b 31 3b 0a 20 20 7d 0a 0a 20 20 2f  Page+1;.  }..  /
5e40: 2a 20 52 65 71 75 65 73 74 20 61 20 70 6f 69 6e  * Request a poin
5e50: 74 65 72 20 74 6f 20 74 68 65 20 72 65 71 75 69  ter to the requi
5e60: 72 65 64 20 70 61 67 65 20 66 72 6f 6d 20 74 68  red page from th
5e70: 65 20 56 46 53 20 2a 2f 0a 20 20 69 66 28 20 70  e VFS */.  if( p
5e80: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50  Wal->apWiData[iP
5e90: 61 67 65 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 69  age]==0 ){.    i
5ea0: 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69  f( pWal->exclusi
5eb0: 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48 45 41 50  veMode==WAL_HEAP
5ec0: 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29 7b 0a 20  MEMORY_MODE ){. 
5ed0: 20 20 20 20 20 70 57 61 6c 2d 3e 61 70 57 69 44       pWal->apWiD
5ee0: 61 74 61 5b 69 50 61 67 65 5d 20 3d 20 28 75 33  ata[iPage] = (u3
5ef0: 32 20 76 6f 6c 61 74 69 6c 65 20 2a 29 73 71 6c  2 volatile *)sql
5f00: 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 57  ite3MallocZero(W
5f10: 41 4c 49 4e 44 45 58 5f 50 47 53 5a 29 3b 0a 20  ALINDEX_PGSZ);. 
5f20: 20 20 20 20 20 69 66 28 20 21 70 57 61 6c 2d 3e       if( !pWal->
5f30: 61 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d 20  apWiData[iPage] 
5f40: 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f  ) rc = SQLITE_NO
5f50: 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  MEM;.    }else{.
5f60: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
5f70: 65 33 4f 73 53 68 6d 4d 61 70 28 70 57 61 6c 2d  e3OsShmMap(pWal-
5f80: 3e 70 44 62 46 64 2c 20 69 50 61 67 65 2c 20 57  >pDbFd, iPage, W
5f90: 41 4c 49 4e 44 45 58 5f 50 47 53 5a 2c 20 0a 20  ALINDEX_PGSZ, . 
5fa0: 20 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 77           pWal->w
5fb0: 72 69 74 65 4c 6f 63 6b 2c 20 28 76 6f 69 64 20  riteLock, (void 
5fc0: 76 6f 6c 61 74 69 6c 65 20 2a 2a 29 26 70 57 61  volatile **)&pWa
5fd0: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67  l->apWiData[iPag
5fe0: 65 5d 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20  e].      );.    
5ff0: 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 50 61 67 65  }.  }..  *ppPage
6000: 20 3d 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74   = pWal->apWiDat
6010: 61 5b 69 50 61 67 65 5d 3b 0a 20 20 61 73 73 65  a[iPage];.  asse
6020: 72 74 28 20 69 50 61 67 65 3d 3d 30 20 7c 7c 20  rt( iPage==0 || 
6030: 2a 70 70 50 61 67 65 20 7c 7c 20 72 63 21 3d 53  *ppPage || rc!=S
6040: 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65  QLITE_OK );.  re
6050: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
6060: 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74  * Return a point
6070: 65 72 20 74 6f 20 74 68 65 20 57 61 6c 43 6b 70  er to the WalCkp
6080: 74 49 6e 66 6f 20 73 74 72 75 63 74 75 72 65 20  tInfo structure 
6090: 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  in the wal-index
60a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c 61  ..*/.static vola
60b0: 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f  tile WalCkptInfo
60c0: 20 2a 77 61 6c 43 6b 70 74 49 6e 66 6f 28 57 61   *walCkptInfo(Wa
60d0: 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73 65  l *pWal){.  asse
60e0: 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74  rt( pWal->nWiDat
60f0: 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70 57  a>0 && pWal->apW
6100: 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72 65  iData[0] );.  re
6110: 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20 57  turn (volatile W
6120: 61 6c 43 6b 70 74 49 6e 66 6f 2a 29 26 28 70 57  alCkptInfo*)&(pW
6130: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 5b  al->apWiData[0][
6140: 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48  sizeof(WalIndexH
6150: 64 72 29 2f 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  dr)/2]);.}../*.*
6160: 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74  * Return a point
6170: 65 72 20 74 6f 20 74 68 65 20 57 61 6c 49 6e 64  er to the WalInd
6180: 65 78 48 64 72 20 73 74 72 75 63 74 75 72 65 20  exHdr structure 
6190: 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  in the wal-index
61a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c 61  ..*/.static vola
61b0: 74 69 6c 65 20 57 61 6c 49 6e 64 65 78 48 64 72  tile WalIndexHdr
61c0: 20 2a 77 61 6c 49 6e 64 65 78 48 64 72 28 57 61   *walIndexHdr(Wa
61d0: 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73 65  l *pWal){.  asse
61e0: 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74  rt( pWal->nWiDat
61f0: 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70 57  a>0 && pWal->apW
6200: 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72 65  iData[0] );.  re
6210: 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20 57  turn (volatile W
6220: 61 6c 49 6e 64 65 78 48 64 72 2a 29 70 57 61 6c  alIndexHdr*)pWal
6230: 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 3b 0a 7d  ->apWiData[0];.}
6240: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61 72 67 75  ../*.** The argu
6250: 6d 65 6e 74 20 74 6f 20 74 68 69 73 20 6d 61 63  ment to this mac
6260: 72 6f 20 6d 75 73 74 20 62 65 20 6f 66 20 74 79  ro must be of ty
6270: 70 65 20 75 33 32 2e 20 4f 6e 20 61 20 6c 69 74  pe u32. On a lit
6280: 74 6c 65 2d 65 6e 64 69 61 6e 0a 2a 2a 20 61 72  tle-endian.** ar
6290: 63 68 69 74 65 63 74 75 72 65 2c 20 69 74 20 72  chitecture, it r
62a0: 65 74 75 72 6e 73 20 74 68 65 20 75 33 32 20 76  eturns the u32 v
62b0: 61 6c 75 65 20 74 68 61 74 20 72 65 73 75 6c 74  alue that result
62c0: 73 20 66 72 6f 6d 20 69 6e 74 65 72 70 72 65 74  s from interpret
62d0: 69 6e 67 0a 2a 2a 20 74 68 65 20 34 20 62 79 74  ing.** the 4 byt
62e0: 65 73 20 61 73 20 61 20 62 69 67 2d 65 6e 64 69  es as a big-endi
62f0: 61 6e 20 76 61 6c 75 65 2e 20 4f 6e 20 61 20 62  an value. On a b
6300: 69 67 2d 65 6e 64 69 61 6e 20 61 72 63 68 69 74  ig-endian archit
6310: 65 63 74 75 72 65 2c 20 69 74 0a 2a 2a 20 72 65  ecture, it.** re
6320: 74 75 72 6e 73 20 74 68 65 20 76 61 6c 75 65 20  turns the value 
6330: 74 68 61 74 20 77 6f 75 6c 64 20 62 65 20 70 72  that would be pr
6340: 6f 64 75 63 65 64 20 62 79 20 69 6e 74 65 70 72  oduced by intepr
6350: 65 74 69 6e 67 20 74 68 65 20 34 20 62 79 74 65  eting the 4 byte
6360: 73 0a 2a 2a 20 6f 66 20 74 68 65 20 69 6e 70 75  s.** of the inpu
6370: 74 20 76 61 6c 75 65 20 61 73 20 61 20 6c 69 74  t value as a lit
6380: 74 6c 65 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67  tle-endian integ
6390: 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 42  er..*/.#define B
63a0: 59 54 45 53 57 41 50 33 32 28 78 29 20 28 20 5c  YTESWAP32(x) ( \
63b0: 0a 20 20 20 20 28 28 28 78 29 26 30 78 30 30 30  .    (((x)&0x000
63c0: 30 30 30 46 46 29 3c 3c 32 34 29 20 2b 20 28 28  000FF)<<24) + ((
63d0: 28 78 29 26 30 78 30 30 30 30 46 46 30 30 29 3c  (x)&0x0000FF00)<
63e0: 3c 38 29 20 20 5c 0a 20 20 2b 20 28 28 28 78 29  <8)  \.  + (((x)
63f0: 26 30 78 30 30 46 46 30 30 30 30 29 3e 3e 38 29  &0x00FF0000)>>8)
6400: 20 20 2b 20 28 28 28 78 29 26 30 78 46 46 30 30    + (((x)&0xFF00
6410: 30 30 30 30 29 3e 3e 32 34 29 20 5c 0a 29 0a 0a  0000)>>24) \.)..
6420: 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20 6f  /*.** Generate o
6430: 72 20 65 78 74 65 6e 64 20 61 6e 20 38 20 62 79  r extend an 8 by
6440: 74 65 20 63 68 65 63 6b 73 75 6d 20 62 61 73 65  te checksum base
6450: 64 20 6f 6e 20 74 68 65 20 64 61 74 61 20 69 6e  d on the data in
6460: 20 0a 2a 2a 20 61 72 72 61 79 20 61 42 79 74 65   .** array aByte
6470: 5b 5d 20 61 6e 64 20 74 68 65 20 69 6e 69 74 69  [] and the initi
6480: 61 6c 20 76 61 6c 75 65 73 20 6f 66 20 61 49 6e  al values of aIn
6490: 5b 30 5d 20 61 6e 64 20 61 49 6e 5b 31 5d 20 28  [0] and aIn[1] (
64a0: 6f 72 0a 2a 2a 20 69 6e 69 74 69 61 6c 20 76 61  or.** initial va
64b0: 6c 75 65 73 20 6f 66 20 30 20 61 6e 64 20 30 20  lues of 0 and 0 
64c0: 69 66 20 61 49 6e 3d 3d 4e 55 4c 4c 29 2e 0a 2a  if aIn==NULL)..*
64d0: 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b 73 75  *.** The checksu
64e0: 6d 20 69 73 20 77 72 69 74 74 65 6e 20 62 61 63  m is written bac
64f0: 6b 20 69 6e 74 6f 20 61 4f 75 74 5b 5d 20 62 65  k into aOut[] be
6500: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
6510: 2a 2a 0a 2a 2a 20 6e 42 79 74 65 20 6d 75 73 74  **.** nByte must
6520: 20 62 65 20 61 20 70 6f 73 69 74 69 76 65 20 6d   be a positive m
6530: 75 6c 74 69 70 6c 65 20 6f 66 20 38 2e 0a 2a 2f  ultiple of 8..*/
6540: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
6550: 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28 0a 20  ChecksumBytes(. 
6560: 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73 75 6d   int nativeCksum
6570: 2c 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e 61  , /* True for na
6580: 74 69 76 65 20 62 79 74 65 2d 6f 72 64 65 72 2c  tive byte-order,
6590: 20 66 61 6c 73 65 20 66 6f 72 20 6e 6f 6e 2d 6e   false for non-n
65a0: 61 74 69 76 65 20 2a 2f 0a 20 20 75 38 20 2a 61  ative */.  u8 *a
65b0: 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43  ,           /* C
65c0: 6f 6e 74 65 6e 74 20 74 6f 20 62 65 20 63 68 65  ontent to be che
65d0: 63 6b 73 75 6d 6d 65 64 20 2a 2f 0a 20 20 69 6e  cksummed */.  in
65e0: 74 20 6e 42 79 74 65 2c 20 20 20 20 20 20 20 2f  t nByte,       /
65f0: 2a 20 42 79 74 65 73 20 6f 66 20 63 6f 6e 74 65  * Bytes of conte
6600: 6e 74 20 69 6e 20 61 5b 5d 2e 20 20 4d 75 73 74  nt in a[].  Must
6610: 20 62 65 20 61 20 6d 75 6c 74 69 70 6c 65 20 6f   be a multiple o
6620: 66 20 38 2e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  f 8. */.  const 
6630: 75 33 32 20 2a 61 49 6e 2c 20 20 2f 2a 20 49 6e  u32 *aIn,  /* In
6640: 69 74 69 61 6c 20 63 68 65 63 6b 73 75 6d 20 76  itial checksum v
6650: 61 6c 75 65 20 69 6e 70 75 74 20 2a 2f 0a 20 20  alue input */.  
6660: 75 33 32 20 2a 61 4f 75 74 20 20 20 20 20 20 20  u32 *aOut       
6670: 20 2f 2a 20 4f 55 54 3a 20 46 69 6e 61 6c 20 63   /* OUT: Final c
6680: 68 65 63 6b 73 75 6d 20 76 61 6c 75 65 20 6f 75  hecksum value ou
6690: 74 70 75 74 20 2a 2f 0a 29 7b 0a 20 20 75 33 32  tput */.){.  u32
66a0: 20 73 31 2c 20 73 32 3b 0a 20 20 75 33 32 20 2a   s1, s2;.  u32 *
66b0: 61 44 61 74 61 20 3d 20 28 75 33 32 20 2a 29 61  aData = (u32 *)a
66c0: 3b 0a 20 20 75 33 32 20 2a 61 45 6e 64 20 3d 20  ;.  u32 *aEnd = 
66d0: 28 75 33 32 20 2a 29 26 61 5b 6e 42 79 74 65 5d  (u32 *)&a[nByte]
66e0: 3b 0a 0a 20 20 69 66 28 20 61 49 6e 20 29 7b 0a  ;..  if( aIn ){.
66f0: 20 20 20 20 73 31 20 3d 20 61 49 6e 5b 30 5d 3b      s1 = aIn[0];
6700: 0a 20 20 20 20 73 32 20 3d 20 61 49 6e 5b 31 5d  .    s2 = aIn[1]
6710: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73  ;.  }else{.    s
6720: 31 20 3d 20 73 32 20 3d 20 30 3b 0a 20 20 7d 0a  1 = s2 = 0;.  }.
6730: 0a 20 20 61 73 73 65 72 74 28 20 6e 42 79 74 65  .  assert( nByte
6740: 3e 3d 38 20 29 3b 0a 20 20 61 73 73 65 72 74 28  >=8 );.  assert(
6750: 20 28 6e 42 79 74 65 26 30 78 30 30 30 30 30 30   (nByte&0x000000
6760: 30 37 29 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28  07)==0 );..  if(
6770: 20 6e 61 74 69 76 65 43 6b 73 75 6d 20 29 7b 0a   nativeCksum ){.
6780: 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 20 73      do {.      s
6790: 31 20 2b 3d 20 2a 61 44 61 74 61 2b 2b 20 2b 20  1 += *aData++ + 
67a0: 73 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d 20  s2;.      s2 += 
67b0: 2a 61 44 61 74 61 2b 2b 20 2b 20 73 31 3b 0a 20  *aData++ + s1;. 
67c0: 20 20 20 7d 77 68 69 6c 65 28 20 61 44 61 74 61     }while( aData
67d0: 3c 61 45 6e 64 20 29 3b 0a 20 20 7d 65 6c 73 65  <aEnd );.  }else
67e0: 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 20  {.    do {.     
67f0: 20 73 31 20 2b 3d 20 42 59 54 45 53 57 41 50 33   s1 += BYTESWAP3
6800: 32 28 61 44 61 74 61 5b 30 5d 29 20 2b 20 73 32  2(aData[0]) + s2
6810: 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d 20 42 59  ;.      s2 += BY
6820: 54 45 53 57 41 50 33 32 28 61 44 61 74 61 5b 31  TESWAP32(aData[1
6830: 5d 29 20 2b 20 73 31 3b 0a 20 20 20 20 20 20 61  ]) + s1;.      a
6840: 44 61 74 61 20 2b 3d 20 32 3b 0a 20 20 20 20 7d  Data += 2;.    }
6850: 77 68 69 6c 65 28 20 61 44 61 74 61 3c 61 45 6e  while( aData<aEn
6860: 64 20 29 3b 0a 20 20 7d 0a 0a 20 20 61 4f 75 74  d );.  }..  aOut
6870: 5b 30 5d 20 3d 20 73 31 3b 0a 20 20 61 4f 75 74  [0] = s1;.  aOut
6880: 5b 31 5d 20 3d 20 73 32 3b 0a 7d 0a 0a 73 74 61  [1] = s2;.}..sta
6890: 74 69 63 20 76 6f 69 64 20 77 61 6c 53 68 6d 42  tic void walShmB
68a0: 61 72 72 69 65 72 28 57 61 6c 20 2a 70 57 61 6c  arrier(Wal *pWal
68b0: 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65  ){.  if( pWal->e
68c0: 78 63 6c 75 73 69 76 65 4d 6f 64 65 21 3d 57 41  xclusiveMode!=WA
68d0: 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44  L_HEAPMEMORY_MOD
68e0: 45 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  E ){.    sqlite3
68f0: 4f 73 53 68 6d 42 61 72 72 69 65 72 28 70 57 61  OsShmBarrier(pWa
6900: 6c 2d 3e 70 44 62 46 64 29 3b 0a 20 20 7d 0a 7d  l->pDbFd);.  }.}
6910: 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68  ../*.** Write th
6920: 65 20 68 65 61 64 65 72 20 69 6e 66 6f 72 6d 61  e header informa
6930: 74 69 6f 6e 20 69 6e 20 70 57 61 6c 2d 3e 68 64  tion in pWal->hd
6940: 72 20 69 6e 74 6f 20 74 68 65 20 77 61 6c 2d 69  r into the wal-i
6950: 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ndex..**.** The 
6960: 63 68 65 63 6b 73 75 6d 20 6f 6e 20 70 57 61 6c  checksum on pWal
6970: 2d 3e 68 64 72 20 69 73 20 75 70 64 61 74 65 64  ->hdr is updated
6980: 20 62 65 66 6f 72 65 20 69 74 20 69 73 20 77 72   before it is wr
6990: 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  itten..*/.static
69a0: 20 76 6f 69 64 20 77 61 6c 49 6e 64 65 78 57 72   void walIndexWr
69b0: 69 74 65 48 64 72 28 57 61 6c 20 2a 70 57 61 6c  iteHdr(Wal *pWal
69c0: 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57 61  ){.  volatile Wa
69d0: 6c 49 6e 64 65 78 48 64 72 20 2a 61 48 64 72 20  lIndexHdr *aHdr 
69e0: 3d 20 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57  = walIndexHdr(pW
69f0: 61 6c 29 3b 0a 20 20 63 6f 6e 73 74 20 69 6e 74  al);.  const int
6a00: 20 6e 43 6b 73 75 6d 20 3d 20 6f 66 66 73 65 74   nCksum = offset
6a10: 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 2c 20  of(WalIndexHdr, 
6a20: 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 61 73 73 65  aCksum);..  asse
6a30: 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c  rt( pWal->writeL
6a40: 6f 63 6b 20 29 3b 0a 20 20 70 57 61 6c 2d 3e 68  ock );.  pWal->h
6a50: 64 72 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a 20  dr.isInit = 1;. 
6a60: 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56 65 72 73   pWal->hdr.iVers
6a70: 69 6f 6e 20 3d 20 57 41 4c 49 4e 44 45 58 5f 4d  ion = WALINDEX_M
6a80: 41 58 5f 56 45 52 53 49 4f 4e 3b 0a 20 20 77 61  AX_VERSION;.  wa
6a90: 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28 31  lChecksumBytes(1
6aa0: 2c 20 28 75 38 2a 29 26 70 57 61 6c 2d 3e 68 64  , (u8*)&pWal->hd
6ab0: 72 2c 20 6e 43 6b 73 75 6d 2c 20 30 2c 20 70 57  r, nCksum, 0, pW
6ac0: 61 6c 2d 3e 68 64 72 2e 61 43 6b 73 75 6d 29 3b  al->hdr.aCksum);
6ad0: 0a 20 20 6d 65 6d 63 70 79 28 28 76 6f 69 64 20  .  memcpy((void 
6ae0: 2a 29 26 61 48 64 72 5b 31 5d 2c 20 28 76 6f 69  *)&aHdr[1], (voi
6af0: 64 20 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c 20  d *)&pWal->hdr, 
6b00: 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48  sizeof(WalIndexH
6b10: 64 72 29 29 3b 0a 20 20 77 61 6c 53 68 6d 42 61  dr));.  walShmBa
6b20: 72 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20 6d  rrier(pWal);.  m
6b30: 65 6d 63 70 79 28 28 76 6f 69 64 20 2a 29 26 61  emcpy((void *)&a
6b40: 48 64 72 5b 30 5d 2c 20 28 76 6f 69 64 20 2a 29  Hdr[0], (void *)
6b50: 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69 7a 65  &pWal->hdr, size
6b60: 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
6b70: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
6b80: 66 75 6e 63 74 69 6f 6e 20 65 6e 63 6f 64 65 73  function encodes
6b90: 20 61 20 73 69 6e 67 6c 65 20 66 72 61 6d 65 20   a single frame 
6ba0: 68 65 61 64 65 72 20 61 6e 64 20 77 72 69 74 65  header and write
6bb0: 73 20 69 74 20 74 6f 20 61 20 62 75 66 66 65 72  s it to a buffer
6bc0: 0a 2a 2a 20 73 75 70 70 6c 69 65 64 20 62 79 20  .** supplied by 
6bd0: 74 68 65 20 63 61 6c 6c 65 72 2e 20 41 20 66 72  the caller. A fr
6be0: 61 6d 65 2d 68 65 61 64 65 72 20 69 73 20 6d 61  ame-header is ma
6bf0: 64 65 20 75 70 20 6f 66 20 61 20 73 65 72 69 65  de up of a serie
6c00: 73 20 6f 66 20 0a 2a 2a 20 34 2d 62 79 74 65 20  s of .** 4-byte 
6c10: 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67  big-endian integ
6c20: 65 72 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a  ers, as follows:
6c30: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 30 3a 20 50 61  .**.**     0: Pa
6c40: 67 65 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20 20  ge number..**   
6c50: 20 20 34 3a 20 46 6f 72 20 63 6f 6d 6d 69 74 20    4: For commit 
6c60: 72 65 63 6f 72 64 73 2c 20 74 68 65 20 73 69 7a  records, the siz
6c70: 65 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  e of the databas
6c80: 65 20 69 6d 61 67 65 20 69 6e 20 70 61 67 65 73  e image in pages
6c90: 20 0a 2a 2a 20 20 20 20 20 20 20 20 61 66 74 65   .**        afte
6ca0: 72 20 74 68 65 20 63 6f 6d 6d 69 74 2e 20 46 6f  r the commit. Fo
6cb0: 72 20 61 6c 6c 20 6f 74 68 65 72 20 72 65 63 6f  r all other reco
6cc0: 72 64 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20 20  rds, zero..**   
6cd0: 20 20 38 3a 20 53 61 6c 74 2d 31 20 28 63 6f 70    8: Salt-1 (cop
6ce0: 69 65 64 20 66 72 6f 6d 20 74 68 65 20 77 61 6c  ied from the wal
6cf0: 2d 68 65 61 64 65 72 29 0a 2a 2a 20 20 20 20 31  -header).**    1
6d00: 32 3a 20 53 61 6c 74 2d 32 20 28 63 6f 70 69 65  2: Salt-2 (copie
6d10: 64 20 66 72 6f 6d 20 74 68 65 20 77 61 6c 2d 68  d from the wal-h
6d20: 65 61 64 65 72 29 0a 2a 2a 20 20 20 20 31 36 3a  eader).**    16:
6d30: 20 43 68 65 63 6b 73 75 6d 2d 31 2e 0a 2a 2a 20   Checksum-1..** 
6d40: 20 20 20 32 30 3a 20 43 68 65 63 6b 73 75 6d 2d     20: Checksum-
6d50: 32 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  2..*/.static voi
6d60: 64 20 77 61 6c 45 6e 63 6f 64 65 46 72 61 6d 65  d walEncodeFrame
6d70: 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20  (.  Wal *pWal,  
6d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d90: 20 20 20 20 2f 2a 20 54 68 65 20 77 72 69 74 65      /* The write
6da0: 2d 61 68 65 61 64 20 6c 6f 67 20 2a 2f 0a 20 20  -ahead log */.  
6db0: 75 33 32 20 69 50 61 67 65 2c 20 20 20 20 20 20  u32 iPage,      
6dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6dd0: 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  /* Database page
6de0: 20 6e 75 6d 62 65 72 20 66 6f 72 20 66 72 61 6d   number for fram
6df0: 65 20 2a 2f 0a 20 20 75 33 32 20 6e 54 72 75 6e  e */.  u32 nTrun
6e00: 63 61 74 65 2c 20 20 20 20 20 20 20 20 20 20 20  cate,           
6e10: 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 64 62         /* New db
6e20: 20 73 69 7a 65 20 28 6f 72 20 30 20 66 6f 72 20   size (or 0 for 
6e30: 6e 6f 6e 2d 63 6f 6d 6d 69 74 20 66 72 61 6d 65  non-commit frame
6e40: 73 29 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74  s) */.  u8 *aDat
6e50: 61 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  a,              
6e60: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
6e70: 65 72 20 74 6f 20 70 61 67 65 20 64 61 74 61 20  er to page data 
6e80: 2a 2f 0a 20 20 75 38 20 2a 61 46 72 61 6d 65 20  */.  u8 *aFrame 
6e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ea0: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 57 72 69       /* OUT: Wri
6eb0: 74 65 20 65 6e 63 6f 64 65 64 20 66 72 61 6d 65  te encoded frame
6ec0: 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e   here */.){.  in
6ed0: 74 20 6e 61 74 69 76 65 43 6b 73 75 6d 3b 20 20  t nativeCksum;  
6ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6ef0: 20 54 72 75 65 20 66 6f 72 20 6e 61 74 69 76 65   True for native
6f00: 20 62 79 74 65 2d 6f 72 64 65 72 20 63 68 65 63   byte-order chec
6f10: 6b 73 75 6d 73 20 2a 2f 0a 20 20 75 33 32 20 2a  ksums */.  u32 *
6f20: 61 43 6b 73 75 6d 20 3d 20 70 57 61 6c 2d 3e 68  aCksum = pWal->h
6f30: 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 3b 0a  dr.aFrameCksum;.
6f40: 20 20 61 73 73 65 72 74 28 20 57 41 4c 5f 46 52    assert( WAL_FR
6f50: 41 4d 45 5f 48 44 52 53 49 5a 45 3d 3d 32 34 20  AME_HDRSIZE==24 
6f60: 29 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74 34  );.  sqlite3Put4
6f70: 62 79 74 65 28 26 61 46 72 61 6d 65 5b 30 5d 2c  byte(&aFrame[0],
6f80: 20 69 50 61 67 65 29 3b 0a 20 20 73 71 6c 69 74   iPage);.  sqlit
6f90: 65 33 50 75 74 34 62 79 74 65 28 26 61 46 72 61  e3Put4byte(&aFra
6fa0: 6d 65 5b 34 5d 2c 20 6e 54 72 75 6e 63 61 74 65  me[4], nTruncate
6fb0: 29 3b 0a 20 20 6d 65 6d 63 70 79 28 26 61 46 72  );.  memcpy(&aFr
6fc0: 61 6d 65 5b 38 5d 2c 20 70 57 61 6c 2d 3e 68 64  ame[8], pWal->hd
6fd0: 72 2e 61 53 61 6c 74 2c 20 38 29 3b 0a 0a 20 20  r.aSalt, 8);..  
6fe0: 6e 61 74 69 76 65 43 6b 73 75 6d 20 3d 20 28 70  nativeCksum = (p
6ff0: 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43  Wal->hdr.bigEndC
7000: 6b 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47  ksum==SQLITE_BIG
7010: 45 4e 44 49 41 4e 29 3b 0a 20 20 77 61 6c 43 68  ENDIAN);.  walCh
7020: 65 63 6b 73 75 6d 42 79 74 65 73 28 6e 61 74 69  ecksumBytes(nati
7030: 76 65 43 6b 73 75 6d 2c 20 61 46 72 61 6d 65 2c  veCksum, aFrame,
7040: 20 38 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73   8, aCksum, aCks
7050: 75 6d 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73  um);.  walChecks
7060: 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b  umBytes(nativeCk
7070: 73 75 6d 2c 20 61 44 61 74 61 2c 20 70 57 61 6c  sum, aData, pWal
7080: 2d 3e 73 7a 50 61 67 65 2c 20 61 43 6b 73 75 6d  ->szPage, aCksum
7090: 2c 20 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 73 71  , aCksum);..  sq
70a0: 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61  lite3Put4byte(&a
70b0: 46 72 61 6d 65 5b 31 36 5d 2c 20 61 43 6b 73 75  Frame[16], aCksu
70c0: 6d 5b 30 5d 29 3b 0a 20 20 73 71 6c 69 74 65 33  m[0]);.  sqlite3
70d0: 50 75 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Put4byte(&aFrame
70e0: 5b 32 30 5d 2c 20 61 43 6b 73 75 6d 5b 31 5d 29  [20], aCksum[1])
70f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b  ;.}../*.** Check
7100: 20 74 6f 20 73 65 65 20 69 66 20 74 68 65 20 66   to see if the f
7110: 72 61 6d 65 20 77 69 74 68 20 68 65 61 64 65 72  rame with header
7120: 20 69 6e 20 61 46 72 61 6d 65 5b 5d 20 61 6e 64   in aFrame[] and
7130: 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 69 6e 20 61   content.** in a
7140: 44 61 74 61 5b 5d 20 69 73 20 76 61 6c 69 64 2e  Data[] is valid.
7150: 20 20 49 66 20 69 74 20 69 73 20 61 20 76 61 6c    If it is a val
7160: 69 64 20 66 72 61 6d 65 2c 20 66 69 6c 6c 20 2a  id frame, fill *
7170: 70 69 50 61 67 65 20 61 6e 64 0a 2a 2a 20 2a 70  piPage and.** *p
7180: 6e 54 72 75 6e 63 61 74 65 20 61 6e 64 20 72 65  nTruncate and re
7190: 74 75 72 6e 20 74 72 75 65 2e 20 20 52 65 74 75  turn true.  Retu
71a0: 72 6e 20 69 66 20 74 68 65 20 66 72 61 6d 65 20  rn if the frame 
71b0: 69 73 20 6e 6f 74 20 76 61 6c 69 64 2e 0a 2a 2f  is not valid..*/
71c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 44  .static int walD
71d0: 65 63 6f 64 65 46 72 61 6d 65 28 0a 20 20 57 61  ecodeFrame(.  Wa
71e0: 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20  l *pWal,        
71f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7200: 20 54 68 65 20 77 72 69 74 65 2d 61 68 65 61 64   The write-ahead
7210: 20 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 2a 70   log */.  u32 *p
7220: 69 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20  iPage,          
7230: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
7240: 3a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20  : Database page 
7250: 6e 75 6d 62 65 72 20 66 6f 72 20 66 72 61 6d 65  number for frame
7260: 20 2a 2f 0a 20 20 75 33 32 20 2a 70 6e 54 72 75   */.  u32 *pnTru
7270: 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20 20 20  ncate,          
7280: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65        /* OUT: Ne
7290: 77 20 64 62 20 73 69 7a 65 20 28 6f 72 20 30 20  w db size (or 0 
72a0: 69 66 20 6e 6f 74 20 63 6f 6d 6d 69 74 29 20 2a  if not commit) *
72b0: 2f 0a 20 20 75 38 20 2a 61 44 61 74 61 2c 20 20  /.  u8 *aData,  
72c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
72d0: 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
72e0: 6f 20 70 61 67 65 20 64 61 74 61 20 28 66 6f 72  o page data (for
72f0: 20 63 68 65 63 6b 73 75 6d 29 20 2a 2f 0a 20 20   checksum) */.  
7300: 75 38 20 2a 61 46 72 61 6d 65 20 20 20 20 20 20  u8 *aFrame      
7310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7320: 2f 2a 20 46 72 61 6d 65 20 64 61 74 61 20 2a 2f  /* Frame data */
7330: 0a 29 7b 0a 20 20 69 6e 74 20 6e 61 74 69 76 65  .){.  int native
7340: 43 6b 73 75 6d 3b 20 20 20 20 20 20 20 20 20 20  Cksum;          
7350: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 66 6f        /* True fo
7360: 72 20 6e 61 74 69 76 65 20 62 79 74 65 2d 6f 72  r native byte-or
7370: 64 65 72 20 63 68 65 63 6b 73 75 6d 73 20 2a 2f  der checksums */
7380: 0a 20 20 75 33 32 20 2a 61 43 6b 73 75 6d 20 3d  .  u32 *aCksum =
7390: 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
73a0: 65 43 6b 73 75 6d 3b 0a 20 20 75 33 32 20 70 67  eCksum;.  u32 pg
73b0: 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  no;             
73c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
73d0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20  e number of the 
73e0: 66 72 61 6d 65 20 2a 2f 0a 20 20 61 73 73 65 72  frame */.  asser
73f0: 74 28 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52  t( WAL_FRAME_HDR
7400: 53 49 5a 45 3d 3d 32 34 20 29 3b 0a 0a 20 20 2f  SIZE==24 );..  /
7410: 2a 20 41 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c  * A frame is onl
7420: 79 20 76 61 6c 69 64 20 69 66 20 74 68 65 20 73  y valid if the s
7430: 61 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68  alt values in th
7440: 65 20 66 72 61 6d 65 2d 68 65 61 64 65 72 0a 20  e frame-header. 
7450: 20 2a 2a 20 6d 61 74 63 68 20 74 68 65 20 73 61   ** match the sa
7460: 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  lt values in the
7470: 20 77 61 6c 2d 68 65 61 64 65 72 2e 20 0a 20 20   wal-header. .  
7480: 2a 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28  */.  if( memcmp(
7490: 26 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74  &pWal->hdr.aSalt
74a0: 2c 20 26 61 46 72 61 6d 65 5b 38 5d 2c 20 38 29  , &aFrame[8], 8)
74b0: 21 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  !=0 ){.    retur
74c0: 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41  n 0;.  }..  /* A
74d0: 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20 76   frame is only v
74e0: 61 6c 69 64 20 69 66 20 74 68 65 20 70 61 67 65  alid if the page
74f0: 20 6e 75 6d 62 65 72 20 69 73 20 63 72 65 61 74   number is creat
7500: 65 72 20 74 68 61 6e 20 7a 65 72 6f 2e 0a 20 20  er than zero..  
7510: 2a 2f 0a 20 20 70 67 6e 6f 20 3d 20 73 71 6c 69  */.  pgno = sqli
7520: 74 65 33 47 65 74 34 62 79 74 65 28 26 61 46 72  te3Get4byte(&aFr
7530: 61 6d 65 5b 30 5d 29 3b 0a 20 20 69 66 28 20 70  ame[0]);.  if( p
7540: 67 6e 6f 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65  gno==0 ){.    re
7550: 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f  turn 0;.  }..  /
7560: 2a 20 41 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c  * A frame is onl
7570: 79 20 76 61 6c 69 64 20 69 66 20 61 20 63 68 65  y valid if a che
7580: 63 6b 73 75 6d 20 6f 66 20 74 68 65 20 57 41 4c  cksum of the WAL
7590: 20 68 65 61 64 65 72 2c 0a 20 20 2a 2a 20 61 6c   header,.  ** al
75a0: 6c 20 70 72 69 6f 72 20 66 72 61 6d 73 2c 20 74  l prior frams, t
75b0: 68 65 20 66 69 72 73 74 20 31 36 20 62 79 74 65  he first 16 byte
75c0: 73 20 6f 66 20 74 68 69 73 20 66 72 61 6d 65 2d  s of this frame-
75d0: 68 65 61 64 65 72 2c 20 0a 20 20 2a 2a 20 61 6e  header, .  ** an
75e0: 64 20 74 68 65 20 66 72 61 6d 65 2d 64 61 74 61  d the frame-data
75f0: 20 6d 61 74 63 68 65 73 20 74 68 65 20 63 68 65   matches the che
7600: 63 6b 73 75 6d 20 69 6e 20 74 68 65 20 6c 61 73  cksum in the las
7610: 74 20 38 20 0a 20 20 2a 2a 20 62 79 74 65 73 20  t 8 .  ** bytes 
7620: 6f 66 20 74 68 69 73 20 66 72 61 6d 65 2d 68 65  of this frame-he
7630: 61 64 65 72 2e 0a 20 20 2a 2f 0a 20 20 6e 61 74  ader..  */.  nat
7640: 69 76 65 43 6b 73 75 6d 20 3d 20 28 70 57 61 6c  iveCksum = (pWal
7650: 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75  ->hdr.bigEndCksu
7660: 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e 44  m==SQLITE_BIGEND
7670: 49 41 4e 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b  IAN);.  walCheck
7680: 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43  sumBytes(nativeC
7690: 6b 73 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38 2c  ksum, aFrame, 8,
76a0: 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29   aCksum, aCksum)
76b0: 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42  ;.  walChecksumB
76c0: 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75 6d  ytes(nativeCksum
76d0: 2c 20 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e 73  , aData, pWal->s
76e0: 7a 50 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20 61  zPage, aCksum, a
76f0: 43 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20 61 43  Cksum);.  if( aC
7700: 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65 33  ksum[0]!=sqlite3
7710: 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Get4byte(&aFrame
7720: 5b 31 36 5d 29 20 0a 20 20 20 7c 7c 20 61 43 6b  [16]) .   || aCk
7730: 73 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33 47  sum[1]!=sqlite3G
7740: 65 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b  et4byte(&aFrame[
7750: 32 30 5d 29 20 0a 20 20 29 7b 0a 20 20 20 20 2f  20]) .  ){.    /
7760: 2a 20 43 68 65 63 6b 73 75 6d 20 66 61 69 6c 65  * Checksum faile
7770: 64 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e  d. */.    return
7780: 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66   0;.  }..  /* If
7790: 20 77 65 20 72 65 61 63 68 20 74 68 69 73 20 70   we reach this p
77a0: 6f 69 6e 74 2c 20 74 68 65 20 66 72 61 6d 65 20  oint, the frame 
77b0: 69 73 20 76 61 6c 69 64 2e 20 20 52 65 74 75 72  is valid.  Retur
77c0: 6e 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65  n the page numbe
77d0: 72 0a 20 20 2a 2a 20 61 6e 64 20 74 68 65 20 6e  r.  ** and the n
77e0: 65 77 20 64 61 74 61 62 61 73 65 20 73 69 7a 65  ew database size
77f0: 2e 0a 20 20 2a 2f 0a 20 20 2a 70 69 50 61 67 65  ..  */.  *piPage
7800: 20 3d 20 70 67 6e 6f 3b 0a 20 20 2a 70 6e 54 72   = pgno;.  *pnTr
7810: 75 6e 63 61 74 65 20 3d 20 73 71 6c 69 74 65 33  uncate = sqlite3
7820: 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Get4byte(&aFrame
7830: 5b 34 5d 29 3b 0a 20 20 72 65 74 75 72 6e 20 31  [4]);.  return 1
7840: 3b 0a 7d 0a 0a 0a 23 69 66 20 64 65 66 69 6e 65  ;.}...#if define
7850: 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26  d(SQLITE_TEST) &
7860: 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  & defined(SQLITE
7870: 5f 44 45 42 55 47 29 0a 2f 2a 0a 2a 2a 20 4e 61  _DEBUG)./*.** Na
7880: 6d 65 73 20 6f 66 20 6c 6f 63 6b 73 2e 20 20 54  mes of locks.  T
7890: 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 75  his routine is u
78a0: 73 65 64 20 74 6f 20 70 72 6f 76 69 64 65 20 64  sed to provide d
78b0: 65 62 75 67 67 69 6e 67 20 6f 75 74 70 75 74 20  ebugging output 
78c0: 61 6e 64 20 69 73 20 6e 6f 74 0a 2a 2a 20 61 20  and is not.** a 
78d0: 70 61 72 74 20 6f 66 20 61 6e 20 6f 72 64 69 6e  part of an ordin
78e0: 61 72 79 20 62 75 69 6c 64 2e 0a 2a 2f 0a 73 74  ary build..*/.st
78f0: 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20  atic const char 
7900: 2a 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 69 6e 74  *walLockName(int
7910: 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66 28   lockIdx){.  if(
7920: 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 57 52   lockIdx==WAL_WR
7930: 49 54 45 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20  ITE_LOCK ){.    
7940: 72 65 74 75 72 6e 20 22 57 52 49 54 45 2d 4c 4f  return "WRITE-LO
7950: 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  CK";.  }else if(
7960: 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 43 4b   lockIdx==WAL_CK
7970: 50 54 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 72  PT_LOCK ){.    r
7980: 65 74 75 72 6e 20 22 43 4b 50 54 2d 4c 4f 43 4b  eturn "CKPT-LOCK
7990: 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 6c  ";.  }else if( l
79a0: 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 52 45 43 4f  ockIdx==WAL_RECO
79b0: 56 45 52 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20  VER_LOCK ){.    
79c0: 72 65 74 75 72 6e 20 22 52 45 43 4f 56 45 52 2d  return "RECOVER-
79d0: 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 7b 0a  LOCK";.  }else{.
79e0: 20 20 20 20 73 74 61 74 69 63 20 63 68 61 72 20      static char 
79f0: 7a 4e 61 6d 65 5b 31 35 5d 3b 0a 20 20 20 20 73  zName[15];.    s
7a00: 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 28  qlite3_snprintf(
7a10: 73 69 7a 65 6f 66 28 7a 4e 61 6d 65 29 2c 20 7a  sizeof(zName), z
7a20: 4e 61 6d 65 2c 20 22 52 45 41 44 2d 4c 4f 43 4b  Name, "READ-LOCK
7a30: 5b 25 64 5d 22 2c 0a 20 20 20 20 20 20 20 20 20  [%d]",.         
7a40: 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 63 6b              lock
7a50: 49 64 78 2d 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  Idx-WAL_READ_LOC
7a60: 4b 28 30 29 29 3b 0a 20 20 20 20 72 65 74 75 72  K(0));.    retur
7a70: 6e 20 7a 4e 61 6d 65 3b 0a 20 20 7d 0a 7d 0a 23  n zName;.  }.}.#
7a80: 65 6e 64 69 66 20 2f 2a 64 65 66 69 6e 65 64 28  endif /*defined(
7a90: 53 51 4c 49 54 45 5f 54 45 53 54 29 20 7c 7c 20  SQLITE_TEST) || 
7aa0: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44  defined(SQLITE_D
7ab0: 45 42 55 47 29 20 2a 2f 0a 20 20 20 20 0a 0a 2f  EBUG) */.    ../
7ac0: 2a 0a 2a 2a 20 53 65 74 20 6f 72 20 72 65 6c 65  *.** Set or rele
7ad0: 61 73 65 20 6c 6f 63 6b 73 20 6f 6e 20 74 68 65  ase locks on the
7ae0: 20 57 41 4c 2e 20 20 4c 6f 63 6b 73 20 61 72 65   WAL.  Locks are
7af0: 20 65 69 74 68 65 72 20 73 68 61 72 65 64 20 6f   either shared o
7b00: 72 20 65 78 63 6c 75 73 69 76 65 2e 0a 2a 2a 20  r exclusive..** 
7b10: 41 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62 65  A lock cannot be
7b20: 20 6d 6f 76 65 64 20 64 69 72 65 63 74 6c 79 20   moved directly 
7b30: 62 65 74 77 65 65 6e 20 73 68 61 72 65 64 20 61  between shared a
7b40: 6e 64 20 65 78 63 6c 75 73 69 76 65 20 2d 20 69  nd exclusive - i
7b50: 74 20 6d 75 73 74 20 67 6f 0a 2a 2a 20 74 68 72  t must go.** thr
7b60: 6f 75 67 68 20 74 68 65 20 75 6e 6c 6f 63 6b 65  ough the unlocke
7b70: 64 20 73 74 61 74 65 20 66 69 72 73 74 2e 0a 2a  d state first..*
7b80: 2a 0a 2a 2a 20 49 6e 20 6c 6f 63 6b 69 6e 67 5f  *.** In locking_
7b90: 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2c 20  mode=EXCLUSIVE, 
7ba0: 61 6c 6c 20 6f 66 20 74 68 65 73 65 20 72 6f 75  all of these rou
7bb0: 74 69 6e 65 73 20 62 65 63 6f 6d 65 20 6e 6f 2d  tines become no-
7bc0: 6f 70 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ops..*/.static i
7bd0: 6e 74 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64  nt walLockShared
7be0: 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20  (Wal *pWal, int 
7bf0: 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 6e 74 20  lockIdx){.  int 
7c00: 72 63 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  rc;.  if( pWal->
7c10: 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20  exclusiveMode ) 
7c20: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
7c30: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
7c40: 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e  OsShmLock(pWal->
7c50: 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20  pDbFd, lockIdx, 
7c60: 31 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  1,.             
7c70: 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54             SQLIT
7c80: 45 5f 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51 4c  E_SHM_LOCK | SQL
7c90: 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29 3b  ITE_SHM_SHARED);
7ca0: 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41  .  WALTRACE(("WA
7cb0: 4c 25 70 3a 20 61 63 71 75 69 72 65 20 53 48 41  L%p: acquire SHA
7cc0: 52 45 44 2d 25 73 20 25 73 5c 6e 22 2c 20 70 57  RED-%s %s\n", pW
7cd0: 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  al,.            
7ce0: 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b  walLockName(lock
7cf0: 49 64 78 29 2c 20 72 63 20 3f 20 22 66 61 69 6c  Idx), rc ? "fail
7d00: 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20  ed" : "ok"));.  
7d10: 56 56 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e  VVA_ONLY( pWal->
7d20: 6c 6f 63 6b 45 72 72 6f 72 20 3d 20 28 75 38 29  lockError = (u8)
7d30: 28 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26  (rc!=SQLITE_OK &
7d40: 26 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53  & rc!=SQLITE_BUS
7d50: 59 29 3b 20 29 0a 20 20 72 65 74 75 72 6e 20 72  Y); ).  return r
7d60: 63 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64  c;.}.static void
7d70: 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64   walUnlockShared
7d80: 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20  (Wal *pWal, int 
7d90: 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66 28 20  lockIdx){.  if( 
7da0: 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
7db0: 6f 64 65 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ode ) return;.  
7dc0: 28 76 6f 69 64 29 73 71 6c 69 74 65 33 4f 73 53  (void)sqlite3OsS
7dd0: 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62  hmLock(pWal->pDb
7de0: 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 31 2c 0a  Fd, lockIdx, 1,.
7df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e00: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
7e10: 53 48 4d 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51 4c  SHM_UNLOCK | SQL
7e20: 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29 3b  ITE_SHM_SHARED);
7e30: 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41  .  WALTRACE(("WA
7e40: 4c 25 70 3a 20 72 65 6c 65 61 73 65 20 53 48 41  L%p: release SHA
7e50: 52 45 44 2d 25 73 5c 6e 22 2c 20 70 57 61 6c 2c  RED-%s\n", pWal,
7e60: 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63   walLockName(loc
7e70: 6b 49 64 78 29 29 29 3b 0a 7d 0a 73 74 61 74 69  kIdx)));.}.stati
7e80: 63 20 69 6e 74 20 77 61 6c 4c 6f 63 6b 45 78 63  c int walLockExc
7e90: 6c 75 73 69 76 65 28 57 61 6c 20 2a 70 57 61 6c  lusive(Wal *pWal
7ea0: 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 2c 20 69  , int lockIdx, i
7eb0: 6e 74 20 6e 29 7b 0a 20 20 69 6e 74 20 72 63 3b  nt n){.  int rc;
7ec0: 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63  .  if( pWal->exc
7ed0: 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65 74  lusiveMode ) ret
7ee0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  urn SQLITE_OK;. 
7ef0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53   rc = sqlite3OsS
7f00: 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62  hmLock(pWal->pDb
7f10: 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c 0a  Fd, lockIdx, n,.
7f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7f30: 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53          SQLITE_S
7f40: 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45  HM_LOCK | SQLITE
7f50: 5f 53 48 4d 5f 45 58 43 4c 55 53 49 56 45 29 3b  _SHM_EXCLUSIVE);
7f60: 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41  .  WALTRACE(("WA
7f70: 4c 25 70 3a 20 61 63 71 75 69 72 65 20 45 58 43  L%p: acquire EXC
7f80: 4c 55 53 49 56 45 2d 25 73 20 63 6e 74 3d 25 64  LUSIVE-%s cnt=%d
7f90: 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20 20   %s\n", pWal,.  
7fa0: 20 20 20 20 20 20 20 20 20 20 77 61 6c 4c 6f 63            walLoc
7fb0: 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c 20  kName(lockIdx), 
7fc0: 6e 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22  n, rc ? "failed"
7fd0: 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 56 56 41   : "ok"));.  VVA
7fe0: 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f 63  _ONLY( pWal->loc
7ff0: 6b 45 72 72 6f 72 20 3d 20 28 75 38 29 28 72 63  kError = (u8)(rc
8000: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72  !=SQLITE_OK && r
8010: 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 29 3b  c!=SQLITE_BUSY);
8020: 20 29 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   ).  return rc;.
8030: 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61  }.static void wa
8040: 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65  lUnlockExclusive
8050: 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20  (Wal *pWal, int 
8060: 6c 6f 63 6b 49 64 78 2c 20 69 6e 74 20 6e 29 7b  lockIdx, int n){
8070: 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63  .  if( pWal->exc
8080: 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65 74  lusiveMode ) ret
8090: 75 72 6e 3b 0a 20 20 28 76 6f 69 64 29 73 71 6c  urn;.  (void)sql
80a0: 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57  ite3OsShmLock(pW
80b0: 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49  al->pDbFd, lockI
80c0: 64 78 2c 20 6e 2c 0a 20 20 20 20 20 20 20 20 20  dx, n,.         
80d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
80e0: 53 51 4c 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f 43  SQLITE_SHM_UNLOC
80f0: 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f 45  K | SQLITE_SHM_E
8100: 58 43 4c 55 53 49 56 45 29 3b 0a 20 20 57 41 4c  XCLUSIVE);.  WAL
8110: 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 72  TRACE(("WAL%p: r
8120: 65 6c 65 61 73 65 20 45 58 43 4c 55 53 49 56 45  elease EXCLUSIVE
8130: 2d 25 73 20 63 6e 74 3d 25 64 5c 6e 22 2c 20 70  -%s cnt=%d\n", p
8140: 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20 20  Wal,.           
8150: 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f    walLockName(lo
8160: 63 6b 49 64 78 29 2c 20 6e 29 29 3b 0a 7d 0a 0a  ckIdx), n));.}..
8170: 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20  /*.** Compute a 
8180: 68 61 73 68 20 6f 6e 20 61 20 70 61 67 65 20 6e  hash on a page n
8190: 75 6d 62 65 72 2e 20 20 54 68 65 20 72 65 73 75  umber.  The resu
81a0: 6c 74 69 6e 67 20 68 61 73 68 20 76 61 6c 75 65  lting hash value
81b0: 20 6d 75 73 74 20 6c 61 6e 64 0a 2a 2a 20 62 65   must land.** be
81c0: 74 77 65 65 6e 20 30 20 61 6e 64 20 28 48 41 53  tween 0 and (HAS
81d0: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 2e  HTABLE_NSLOT-1).
81e0: 20 20 54 68 65 20 77 61 6c 48 61 73 68 4e 65 78    The walHashNex
81f0: 74 28 29 20 66 75 6e 63 74 69 6f 6e 20 61 64 76  t() function adv
8200: 61 6e 63 65 73 0a 2a 2a 20 74 68 65 20 68 61 73  ances.** the has
8210: 68 20 74 6f 20 74 68 65 20 6e 65 78 74 20 76 61  h to the next va
8220: 6c 75 65 20 69 6e 20 74 68 65 20 65 76 65 6e 74  lue in the event
8230: 20 6f 66 20 61 20 63 6f 6c 6c 69 73 69 6f 6e 2e   of a collision.
8240: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
8250: 61 6c 48 61 73 68 28 75 33 32 20 69 50 61 67 65  alHash(u32 iPage
8260: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69 50 61  ){.  assert( iPa
8270: 67 65 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74  ge>0 );.  assert
8280: 28 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c  ( (HASHTABLE_NSL
8290: 4f 54 20 26 20 28 48 41 53 48 54 41 42 4c 45 5f  OT & (HASHTABLE_
82a0: 4e 53 4c 4f 54 2d 31 29 29 3d 3d 30 20 29 3b 0a  NSLOT-1))==0 );.
82b0: 20 20 72 65 74 75 72 6e 20 28 69 50 61 67 65 2a    return (iPage*
82c0: 48 41 53 48 54 41 42 4c 45 5f 48 41 53 48 5f 31  HASHTABLE_HASH_1
82d0: 29 20 26 20 28 48 41 53 48 54 41 42 4c 45 5f 4e  ) & (HASHTABLE_N
82e0: 53 4c 4f 54 2d 31 29 3b 0a 7d 0a 73 74 61 74 69  SLOT-1);.}.stati
82f0: 63 20 69 6e 74 20 77 61 6c 4e 65 78 74 48 61 73  c int walNextHas
8300: 68 28 69 6e 74 20 69 50 72 69 6f 72 48 61 73 68  h(int iPriorHash
8310: 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 69 50 72  ){.  return (iPr
8320: 69 6f 72 48 61 73 68 2b 31 29 26 28 48 41 53 48  iorHash+1)&(HASH
8330: 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 3b 0a  TABLE_NSLOT-1);.
8340: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e  }../* .** Return
8350: 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68 65   pointers to the
8360: 20 68 61 73 68 20 74 61 62 6c 65 20 61 6e 64 20   hash table and 
8370: 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61  page number arra
8380: 79 20 73 74 6f 72 65 64 20 6f 6e 0a 2a 2a 20 70  y stored on.** p
8390: 61 67 65 20 69 48 61 73 68 20 6f 66 20 74 68 65  age iHash of the
83a0: 20 77 61 6c 2d 69 6e 64 65 78 2e 20 54 68 65 20   wal-index. The 
83b0: 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 62 72 6f  wal-index is bro
83c0: 6b 65 6e 20 69 6e 74 6f 20 33 32 4b 42 20 70 61  ken into 32KB pa
83d0: 67 65 73 0a 2a 2a 20 6e 75 6d 62 65 72 65 64 20  ges.** numbered 
83e0: 73 74 61 72 74 69 6e 67 20 66 72 6f 6d 20 30 2e  starting from 0.
83f0: 0a 2a 2a 0a 2a 2a 20 53 65 74 20 6f 75 74 70 75  .**.** Set outpu
8400: 74 20 76 61 72 69 61 62 6c 65 20 2a 70 61 48 61  t variable *paHa
8410: 73 68 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74  sh to point to t
8420: 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  he start of the 
8430: 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20 69 6e  hash table.** in
8440: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66   the wal-index f
8450: 69 6c 65 2e 20 53 65 74 20 2a 70 69 5a 65 72 6f  ile. Set *piZero
8460: 20 74 6f 20 6f 6e 65 20 6c 65 73 73 20 74 68 61   to one less tha
8470: 6e 20 74 68 65 20 66 72 61 6d 65 20 0a 2a 2a 20  n the frame .** 
8480: 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 66 69  number of the fi
8490: 72 73 74 20 66 72 61 6d 65 20 69 6e 64 65 78 65  rst frame indexe
84a0: 64 20 62 79 20 74 68 69 73 20 68 61 73 68 20 74  d by this hash t
84b0: 61 62 6c 65 2e 20 49 66 20 61 0a 2a 2a 20 73 6c  able. If a.** sl
84c0: 6f 74 20 69 6e 20 74 68 65 20 68 61 73 68 20 74  ot in the hash t
84d0: 61 62 6c 65 20 69 73 20 73 65 74 20 74 6f 20 4e  able is set to N
84e0: 2c 20 69 74 20 72 65 66 65 72 73 20 74 6f 20 66  , it refers to f
84f0: 72 61 6d 65 20 6e 75 6d 62 65 72 20 0a 2a 2a 20  rame number .** 
8500: 28 2a 70 69 5a 65 72 6f 2b 4e 29 20 69 6e 20 74  (*piZero+N) in t
8510: 68 65 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a 20 46 69  he log..**.** Fi
8520: 6e 61 6c 6c 79 2c 20 73 65 74 20 2a 70 61 50 67  nally, set *paPg
8530: 6e 6f 20 73 6f 20 74 68 61 74 20 2a 70 61 50 67  no so that *paPg
8540: 6e 6f 5b 31 5d 20 69 73 20 74 68 65 20 70 61 67  no[1] is the pag
8550: 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 0a  e number of the.
8560: 2a 2a 20 66 69 72 73 74 20 66 72 61 6d 65 20 69  ** first frame i
8570: 6e 64 65 78 65 64 20 62 79 20 74 68 65 20 68 61  ndexed by the ha
8580: 73 68 20 74 61 62 6c 65 2c 20 66 72 61 6d 65 20  sh table, frame 
8590: 28 2a 70 69 5a 65 72 6f 2b 31 29 2e 0a 2a 2f 0a  (*piZero+1)..*/.
85a0: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 48 61  static int walHa
85b0: 73 68 47 65 74 28 0a 20 20 57 61 6c 20 2a 70 57  shGet(.  Wal *pW
85c0: 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
85d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20           /* WAL 
85e0: 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20  handle */.  int 
85f0: 69 48 61 73 68 2c 20 20 20 20 20 20 20 20 20 20  iHash,          
8600: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
8610: 69 6e 64 20 74 68 65 20 69 48 61 73 68 27 74 68  ind the iHash'th
8620: 20 74 61 62 6c 65 20 2a 2f 0a 20 20 76 6f 6c 61   table */.  vola
8630: 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 2a 70  tile ht_slot **p
8640: 61 48 61 73 68 2c 20 20 20 20 20 20 2f 2a 20 4f  aHash,      /* O
8650: 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20 68  UT: Pointer to h
8660: 61 73 68 20 69 6e 64 65 78 20 2a 2f 0a 20 20 76  ash index */.  v
8670: 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 70 61  olatile u32 **pa
8680: 50 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 2f  Pgno,          /
8690: 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74  * OUT: Pointer t
86a0: 6f 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72  o page number ar
86b0: 72 61 79 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69  ray */.  u32 *pi
86c0: 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20 20 20  Zero            
86d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
86e0: 20 46 72 61 6d 65 20 61 73 73 6f 63 69 61 74 65   Frame associate
86f0: 64 20 77 69 74 68 20 2a 70 61 50 67 6e 6f 5b 30  d with *paPgno[0
8700: 5d 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  ] */.){.  int rc
8710: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
8720: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
8730: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 76 6f  urn code */.  vo
8740: 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e  latile u32 *aPgn
8750: 6f 3b 0a 0a 20 20 72 63 20 3d 20 77 61 6c 49 6e  o;..  rc = walIn
8760: 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20 69 48  dexPage(pWal, iH
8770: 61 73 68 2c 20 26 61 50 67 6e 6f 29 3b 0a 20 20  ash, &aPgno);.  
8780: 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49  assert( rc==SQLI
8790: 54 45 5f 4f 4b 20 7c 7c 20 69 48 61 73 68 3e 30  TE_OK || iHash>0
87a0: 20 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53   );..  if( rc==S
87b0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
87c0: 75 33 32 20 69 5a 65 72 6f 3b 0a 20 20 20 20 76  u32 iZero;.    v
87d0: 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20  olatile ht_slot 
87e0: 2a 61 48 61 73 68 3b 0a 0a 20 20 20 20 61 48 61  *aHash;..    aHa
87f0: 73 68 20 3d 20 28 76 6f 6c 61 74 69 6c 65 20 68  sh = (volatile h
8800: 74 5f 73 6c 6f 74 20 2a 29 26 61 50 67 6e 6f 5b  t_slot *)&aPgno[
8810: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5d  HASHTABLE_NPAGE]
8820: 3b 0a 20 20 20 20 69 66 28 20 69 48 61 73 68 3d  ;.    if( iHash=
8830: 3d 30 20 29 7b 0a 20 20 20 20 20 20 61 50 67 6e  =0 ){.      aPgn
8840: 6f 20 3d 20 26 61 50 67 6e 6f 5b 57 41 4c 49 4e  o = &aPgno[WALIN
8850: 44 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a  DEX_HDR_SIZE/siz
8860: 65 6f 66 28 75 33 32 29 5d 3b 0a 20 20 20 20 20  eof(u32)];.     
8870: 20 69 5a 65 72 6f 20 3d 20 30 3b 0a 20 20 20 20   iZero = 0;.    
8880: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 5a 65  }else{.      iZe
8890: 72 6f 20 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e  ro = HASHTABLE_N
88a0: 50 41 47 45 5f 4f 4e 45 20 2b 20 28 69 48 61 73  PAGE_ONE + (iHas
88b0: 68 2d 31 29 2a 48 41 53 48 54 41 42 4c 45 5f 4e  h-1)*HASHTABLE_N
88c0: 50 41 47 45 3b 0a 20 20 20 20 7d 0a 20 20 0a 20  PAGE;.    }.  . 
88d0: 20 20 20 2a 70 61 50 67 6e 6f 20 3d 20 26 61 50     *paPgno = &aP
88e0: 67 6e 6f 5b 2d 31 5d 3b 0a 20 20 20 20 2a 70 61  gno[-1];.    *pa
88f0: 48 61 73 68 20 3d 20 61 48 61 73 68 3b 0a 20 20  Hash = aHash;.  
8900: 20 20 2a 70 69 5a 65 72 6f 20 3d 20 69 5a 65 72    *piZero = iZer
8910: 6f 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  o;.  }.  return 
8920: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  rc;.}../*.** Ret
8930: 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  urn the number o
8940: 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
8950: 70 61 67 65 20 74 68 61 74 20 63 6f 6e 74 61 69  page that contai
8960: 6e 73 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c  ns the hash-tabl
8970: 65 0a 2a 2a 20 61 6e 64 20 70 61 67 65 2d 6e 75  e.** and page-nu
8980: 6d 62 65 72 20 61 72 72 61 79 20 74 68 61 74 20  mber array that 
8990: 63 6f 6e 74 61 69 6e 20 65 6e 74 72 69 65 73 20  contain entries 
89a0: 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f  corresponding to
89b0: 20 57 41 4c 20 66 72 61 6d 65 0a 2a 2a 20 69 46   WAL frame.** iF
89c0: 72 61 6d 65 2e 20 54 68 65 20 77 61 6c 2d 69 6e  rame. The wal-in
89d0: 64 65 78 20 69 73 20 62 72 6f 6b 65 6e 20 75 70  dex is broken up
89e0: 20 69 6e 74 6f 20 33 32 4b 42 20 70 61 67 65 73   into 32KB pages
89f0: 2e 20 57 61 6c 2d 69 6e 64 65 78 20 70 61 67 65  . Wal-index page
8a00: 73 20 0a 2a 2a 20 61 72 65 20 6e 75 6d 62 65 72  s .** are number
8a10: 65 64 20 73 74 61 72 74 69 6e 67 20 66 72 6f 6d  ed starting from
8a20: 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e   0..*/.static in
8a30: 74 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 75  t walFramePage(u
8a40: 33 32 20 69 46 72 61 6d 65 29 7b 0a 20 20 69 6e  32 iFrame){.  in
8a50: 74 20 69 48 61 73 68 20 3d 20 28 69 46 72 61 6d  t iHash = (iFram
8a60: 65 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  e+HASHTABLE_NPAG
8a70: 45 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  E-HASHTABLE_NPAG
8a80: 45 5f 4f 4e 45 2d 31 29 20 2f 20 48 41 53 48 54  E_ONE-1) / HASHT
8a90: 41 42 4c 45 5f 4e 50 41 47 45 3b 0a 20 20 61 73  ABLE_NPAGE;.  as
8aa0: 73 65 72 74 28 20 28 69 48 61 73 68 3d 3d 30 20  sert( (iHash==0 
8ab0: 7c 7c 20 69 46 72 61 6d 65 3e 48 41 53 48 54 41  || iFrame>HASHTA
8ac0: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 0a 20  BLE_NPAGE_ONE). 
8ad0: 20 20 20 20 20 20 26 26 20 28 69 48 61 73 68 3e        && (iHash>
8ae0: 3d 31 20 7c 7c 20 69 46 72 61 6d 65 3c 3d 48 41  =1 || iFrame<=HA
8af0: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e  SHTABLE_NPAGE_ON
8b00: 45 29 0a 20 20 20 20 20 20 20 26 26 20 28 69 48  E).       && (iH
8b10: 61 73 68 3c 3d 31 20 7c 7c 20 69 46 72 61 6d 65  ash<=1 || iFrame
8b20: 3e 28 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  >(HASHTABLE_NPAG
8b30: 45 5f 4f 4e 45 2b 48 41 53 48 54 41 42 4c 45 5f  E_ONE+HASHTABLE_
8b40: 4e 50 41 47 45 29 29 0a 20 20 20 20 20 20 20 26  NPAGE)).       &
8b50: 26 20 28 69 48 61 73 68 3e 3d 32 20 7c 7c 20 69  & (iHash>=2 || i
8b60: 46 72 61 6d 65 3c 3d 48 41 53 48 54 41 42 4c 45  Frame<=HASHTABLE
8b70: 5f 4e 50 41 47 45 5f 4f 4e 45 2b 48 41 53 48 54  _NPAGE_ONE+HASHT
8b80: 41 42 4c 45 5f 4e 50 41 47 45 29 0a 20 20 20 20  ABLE_NPAGE).    
8b90: 20 20 20 26 26 20 28 69 48 61 73 68 3c 3d 32 20     && (iHash<=2 
8ba0: 7c 7c 20 69 46 72 61 6d 65 3e 28 48 41 53 48 54  || iFrame>(HASHT
8bb0: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 32  ABLE_NPAGE_ONE+2
8bc0: 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  *HASHTABLE_NPAGE
8bd0: 29 29 0a 20 20 29 3b 0a 20 20 72 65 74 75 72 6e  )).  );.  return
8be0: 20 69 48 61 73 68 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   iHash;.}../*.**
8bf0: 20 52 65 74 75 72 6e 20 74 68 65 20 70 61 67 65   Return the page
8c00: 20 6e 75 6d 62 65 72 20 61 73 73 6f 63 69 61 74   number associat
8c10: 65 64 20 77 69 74 68 20 66 72 61 6d 65 20 69 46  ed with frame iF
8c20: 72 61 6d 65 20 69 6e 20 74 68 69 73 20 57 41 4c  rame in this WAL
8c30: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75 33 32 20  ..*/.static u32 
8c40: 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 57 61 6c  walFramePgno(Wal
8c50: 20 2a 70 57 61 6c 2c 20 75 33 32 20 69 46 72 61   *pWal, u32 iFra
8c60: 6d 65 29 7b 0a 20 20 69 6e 74 20 69 48 61 73 68  me){.  int iHash
8c70: 20 3d 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28   = walFramePage(
8c80: 69 46 72 61 6d 65 29 3b 0a 20 20 69 66 28 20 69  iFrame);.  if( i
8c90: 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20 72  Hash==0 ){.    r
8ca0: 65 74 75 72 6e 20 70 57 61 6c 2d 3e 61 70 57 69  eturn pWal->apWi
8cb0: 44 61 74 61 5b 30 5d 5b 57 41 4c 49 4e 44 45 58  Data[0][WALINDEX
8cc0: 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f 66  _HDR_SIZE/sizeof
8cd0: 28 75 33 32 29 20 2b 20 69 46 72 61 6d 65 20 2d  (u32) + iFrame -
8ce0: 20 31 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72   1];.  }.  retur
8cf0: 6e 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61  n pWal->apWiData
8d00: 5b 69 48 61 73 68 5d 5b 28 69 46 72 61 6d 65 2d  [iHash][(iFrame-
8d10: 31 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  1-HASHTABLE_NPAG
8d20: 45 5f 4f 4e 45 29 25 48 41 53 48 54 41 42 4c 45  E_ONE)%HASHTABLE
8d30: 5f 4e 50 41 47 45 5d 3b 0a 7d 0a 0a 2f 2a 0a 2a  _NPAGE];.}../*.*
8d40: 2a 20 52 65 6d 6f 76 65 20 65 6e 74 72 69 65 73  * Remove entries
8d50: 20 66 72 6f 6d 20 74 68 65 20 68 61 73 68 20 74   from the hash t
8d60: 61 62 6c 65 20 74 68 61 74 20 70 6f 69 6e 74 20  able that point 
8d70: 74 6f 20 57 41 4c 20 73 6c 6f 74 73 20 67 72 65  to WAL slots gre
8d80: 61 74 65 72 0a 2a 2a 20 74 68 61 6e 20 70 57 61  ater.** than pWa
8d90: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a  l->hdr.mxFrame..
8da0: 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  **.** This funct
8db0: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 77 68  ion is called wh
8dc0: 65 6e 65 76 65 72 20 70 57 61 6c 2d 3e 68 64 72  enever pWal->hdr
8dd0: 2e 6d 78 46 72 61 6d 65 20 69 73 20 64 65 63 72  .mxFrame is decr
8de0: 65 61 73 65 64 20 64 75 65 0a 2a 2a 20 74 6f 20  eased due.** to 
8df0: 61 20 72 6f 6c 6c 62 61 63 6b 20 6f 72 20 73 61  a rollback or sa
8e00: 76 65 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20 41  vepoint..**.** A
8e10: 74 20 6d 6f 73 74 20 6f 6e 6c 79 20 74 68 65 20  t most only the 
8e20: 68 61 73 68 20 74 61 62 6c 65 20 63 6f 6e 74 61  hash table conta
8e30: 69 6e 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e  ining pWal->hdr.
8e40: 6d 78 46 72 61 6d 65 20 6e 65 65 64 73 20 74 6f  mxFrame needs to
8e50: 20 62 65 0a 2a 2a 20 75 70 64 61 74 65 64 2e 20   be.** updated. 
8e60: 20 41 6e 79 20 6c 61 74 65 72 20 68 61 73 68 20   Any later hash 
8e70: 74 61 62 6c 65 73 20 77 69 6c 6c 20 62 65 20 61  tables will be a
8e80: 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 63 6c 65  utomatically cle
8e90: 61 72 65 64 20 77 68 65 6e 0a 2a 2a 20 70 57 61  ared when.** pWa
8ea0: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 61  l->hdr.mxFrame a
8eb0: 64 76 61 6e 63 65 73 20 74 6f 20 74 68 65 20 70  dvances to the p
8ec0: 6f 69 6e 74 20 77 68 65 72 65 20 74 68 6f 73 65  oint where those
8ed0: 20 68 61 73 68 20 74 61 62 6c 65 73 20 61 72 65   hash tables are
8ee0: 0a 2a 2a 20 61 63 74 75 61 6c 6c 79 20 6e 65 65  .** actually nee
8ef0: 64 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ded..*/.static v
8f00: 6f 69 64 20 77 61 6c 43 6c 65 61 6e 75 70 48 61  oid walCleanupHa
8f10: 73 68 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20  sh(Wal *pWal){. 
8f20: 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f   volatile ht_slo
8f30: 74 20 2a 61 48 61 73 68 20 3d 20 30 3b 20 20 20  t *aHash = 0;   
8f40: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 68   /* Pointer to h
8f50: 61 73 68 20 74 61 62 6c 65 20 74 6f 20 63 6c 65  ash table to cle
8f60: 61 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65  ar */.  volatile
8f70: 20 75 33 32 20 2a 61 50 67 6e 6f 20 3d 20 30 3b   u32 *aPgno = 0;
8f80: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20          /* Page 
8f90: 6e 75 6d 62 65 72 20 61 72 72 61 79 20 66 6f 72  number array for
8fa0: 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20   hash table */. 
8fb0: 20 75 33 32 20 69 5a 65 72 6f 20 3d 20 30 3b 20   u32 iZero = 0; 
8fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8fd0: 20 2f 2a 20 66 72 61 6d 65 20 3d 3d 20 28 61 48   /* frame == (aH
8fe0: 61 73 68 5b 78 5d 2b 69 5a 65 72 6f 29 20 2a 2f  ash[x]+iZero) */
8ff0: 0a 20 20 69 6e 74 20 69 4c 69 6d 69 74 20 3d 20  .  int iLimit = 
9000: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
9010: 20 20 20 2f 2a 20 5a 65 72 6f 20 76 61 6c 75 65     /* Zero value
9020: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 74  s greater than t
9030: 68 69 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79  his */.  int nBy
9040: 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  te;             
9050: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
9060: 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20 7a  er of bytes to z
9070: 65 72 6f 20 69 6e 20 61 50 67 6e 6f 5b 5d 20 2a  ero in aPgno[] *
9080: 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20  /.  int i;      
9090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
90a0: 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69      /* Used to i
90b0: 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61  terate through a
90c0: 48 61 73 68 5b 5d 20 2a 2f 0a 0a 20 20 61 73 73  Hash[] */..  ass
90d0: 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65  ert( pWal->write
90e0: 4c 6f 63 6b 20 29 3b 0a 20 20 74 65 73 74 63 61  Lock );.  testca
90f0: 73 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  se( pWal->hdr.mx
9100: 46 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45  Frame==HASHTABLE
9110: 5f 4e 50 41 47 45 5f 4f 4e 45 2d 31 20 29 3b 0a  _NPAGE_ONE-1 );.
9120: 20 20 74 65 73 74 63 61 73 65 28 20 70 57 61 6c    testcase( pWal
9130: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 48  ->hdr.mxFrame==H
9140: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
9150: 4e 45 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65  NE );.  testcase
9160: 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  ( pWal->hdr.mxFr
9170: 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45 5f 4e  ame==HASHTABLE_N
9180: 50 41 47 45 5f 4f 4e 45 2b 31 20 29 3b 0a 0a 20  PAGE_ONE+1 );.. 
9190: 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d   if( pWal->hdr.m
91a0: 78 46 72 61 6d 65 3d 3d 30 20 29 20 72 65 74 75  xFrame==0 ) retu
91b0: 72 6e 3b 0a 0a 20 20 2f 2a 20 4f 62 74 61 69 6e  rn;..  /* Obtain
91c0: 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68 65   pointers to the
91d0: 20 68 61 73 68 2d 74 61 62 6c 65 20 61 6e 64 20   hash-table and 
91e0: 70 61 67 65 2d 6e 75 6d 62 65 72 20 61 72 72 61  page-number arra
91f0: 79 20 63 6f 6e 74 61 69 6e 69 6e 67 20 0a 20 20  y containing .  
9200: 2a 2a 20 74 68 65 20 65 6e 74 72 79 20 74 68 61  ** the entry tha
9210: 74 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f  t corresponds to
9220: 20 66 72 61 6d 65 20 70 57 61 6c 2d 3e 68 64 72   frame pWal->hdr
9230: 2e 6d 78 46 72 61 6d 65 2e 20 49 74 20 69 73 20  .mxFrame. It is 
9240: 67 75 61 72 61 6e 74 65 65 64 0a 20 20 2a 2a 20  guaranteed.  ** 
9250: 74 68 61 74 20 74 68 65 20 70 61 67 65 20 73 61  that the page sa
9260: 69 64 20 68 61 73 68 2d 74 61 62 6c 65 20 61 6e  id hash-table an
9270: 64 20 61 72 72 61 79 20 72 65 73 69 64 65 20 6f  d array reside o
9280: 6e 20 69 73 20 61 6c 72 65 61 64 79 20 6d 61 70  n is already map
9290: 70 65 64 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65  ped..  */.  asse
92a0: 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74  rt( pWal->nWiDat
92b0: 61 3e 77 61 6c 46 72 61 6d 65 50 61 67 65 28 70  a>walFramePage(p
92c0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
92d0: 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  ) );.  assert( p
92e0: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 77 61  Wal->apWiData[wa
92f0: 6c 46 72 61 6d 65 50 61 67 65 28 70 57 61 6c 2d  lFramePage(pWal-
9300: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 29 5d 20 29  >hdr.mxFrame)] )
9310: 3b 0a 20 20 77 61 6c 48 61 73 68 47 65 74 28 70  ;.  walHashGet(p
9320: 57 61 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61 67  Wal, walFramePag
9330: 65 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  e(pWal->hdr.mxFr
9340: 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20 26 61  ame), &aHash, &a
9350: 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 0a  Pgno, &iZero);..
9360: 20 20 2f 2a 20 5a 65 72 6f 20 61 6c 6c 20 68 61    /* Zero all ha
9370: 73 68 2d 74 61 62 6c 65 20 65 6e 74 72 69 65 73  sh-table entries
9380: 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64   that correspond
9390: 20 74 6f 20 66 72 61 6d 65 20 6e 75 6d 62 65 72   to frame number
93a0: 73 20 67 72 65 61 74 65 72 0a 20 20 2a 2a 20 74  s greater.  ** t
93b0: 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  han pWal->hdr.mx
93c0: 46 72 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 4c  Frame..  */.  iL
93d0: 69 6d 69 74 20 3d 20 70 57 61 6c 2d 3e 68 64 72  imit = pWal->hdr
93e0: 2e 6d 78 46 72 61 6d 65 20 2d 20 69 5a 65 72 6f  .mxFrame - iZero
93f0: 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4c 69 6d  ;.  assert( iLim
9400: 69 74 3e 30 20 29 3b 0a 20 20 66 6f 72 28 69 3d  it>0 );.  for(i=
9410: 30 3b 20 69 3c 48 41 53 48 54 41 42 4c 45 5f 4e  0; i<HASHTABLE_N
9420: 53 4c 4f 54 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  SLOT; i++){.    
9430: 69 66 28 20 61 48 61 73 68 5b 69 5d 3e 69 4c 69  if( aHash[i]>iLi
9440: 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 61 48 61  mit ){.      aHa
9450: 73 68 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d  sh[i] = 0;.    }
9460: 0a 20 20 7d 0a 20 20 0a 20 20 2f 2a 20 5a 65 72  .  }.  .  /* Zer
9470: 6f 20 74 68 65 20 65 6e 74 72 69 65 73 20 69 6e  o the entries in
9480: 20 74 68 65 20 61 50 67 6e 6f 20 61 72 72 61 79   the aPgno array
9490: 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64   that correspond
94a0: 20 74 6f 20 66 72 61 6d 65 73 20 77 69 74 68 0a   to frames with.
94b0: 20 20 2a 2a 20 66 72 61 6d 65 20 6e 75 6d 62 65    ** frame numbe
94c0: 72 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  rs greater than 
94d0: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
94e0: 65 2e 20 0a 20 20 2a 2f 0a 20 20 6e 42 79 74 65  e. .  */.  nByte
94f0: 20 3d 20 28 69 6e 74 29 28 28 63 68 61 72 20 2a   = (int)((char *
9500: 29 61 48 61 73 68 20 2d 20 28 63 68 61 72 20 2a  )aHash - (char *
9510: 29 26 61 50 67 6e 6f 5b 69 4c 69 6d 69 74 2b 31  )&aPgno[iLimit+1
9520: 5d 29 3b 0a 20 20 6d 65 6d 73 65 74 28 28 76 6f  ]);.  memset((vo
9530: 69 64 20 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d  id *)&aPgno[iLim
9540: 69 74 2b 31 5d 2c 20 30 2c 20 6e 42 79 74 65 29  it+1], 0, nByte)
9550: 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  ;..#ifdef SQLITE
9560: 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56  _ENABLE_EXPENSIV
9570: 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20 56 65  E_ASSERT.  /* Ve
9580: 72 69 66 79 20 74 68 61 74 20 74 68 65 20 65 76  rify that the ev
9590: 65 72 79 20 65 6e 74 72 79 20 69 6e 20 74 68 65  ery entry in the
95a0: 20 6d 61 70 70 69 6e 67 20 72 65 67 69 6f 6e 20   mapping region 
95b0: 69 73 20 73 74 69 6c 6c 20 72 65 61 63 68 61 62  is still reachab
95c0: 6c 65 0a 20 20 2a 2a 20 76 69 61 20 74 68 65 20  le.  ** via the 
95d0: 68 61 73 68 20 74 61 62 6c 65 20 65 76 65 6e 20  hash table even 
95e0: 61 66 74 65 72 20 74 68 65 20 63 6c 65 61 6e 75  after the cleanu
95f0: 70 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69 4c  p..  */.  if( iL
9600: 69 6d 69 74 20 29 7b 0a 20 20 20 20 69 6e 74 20  imit ){.    int 
9610: 69 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  i;           /* 
9620: 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a  Loop counter */.
9630: 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20 20      int iKey;   
9640: 20 20 20 20 20 2f 2a 20 48 61 73 68 20 6b 65 79       /* Hash key
9650: 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b   */.    for(i=1;
9660: 20 69 3c 3d 69 4c 69 6d 69 74 3b 20 69 2b 2b 29   i<=iLimit; i++)
9670: 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 4b 65 79  {.      for(iKey
9680: 3d 77 61 6c 48 61 73 68 28 61 50 67 6e 6f 5b 69  =walHash(aPgno[i
9690: 5d 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b  ]); aHash[iKey];
96a0: 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73   iKey=walNextHas
96b0: 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20  h(iKey)){.      
96c0: 20 20 69 66 28 20 61 48 61 73 68 5b 69 4b 65 79    if( aHash[iKey
96d0: 5d 3d 3d 69 20 29 20 62 72 65 61 6b 3b 0a 20 20  ]==i ) break;.  
96e0: 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73 73 65      }.      asse
96f0: 72 74 28 20 61 48 61 73 68 5b 69 4b 65 79 5d 3d  rt( aHash[iKey]=
9700: 3d 69 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  =i );.    }.  }.
9710: 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45  #endif /* SQLITE
9720: 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56  _ENABLE_EXPENSIV
9730: 45 5f 41 53 53 45 52 54 20 2a 2f 0a 7d 0a 0a 0a  E_ASSERT */.}...
9740: 2f 2a 0a 2a 2a 20 53 65 74 20 61 6e 20 65 6e 74  /*.** Set an ent
9750: 72 79 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e  ry in the wal-in
9760: 64 65 78 20 74 68 61 74 20 77 69 6c 6c 20 6d 61  dex that will ma
9770: 70 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20  p database page 
9780: 6e 75 6d 62 65 72 0a 2a 2a 20 70 50 61 67 65 20  number.** pPage 
9790: 69 6e 74 6f 20 57 41 4c 20 66 72 61 6d 65 20 69  into WAL frame i
97a0: 46 72 61 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  Frame..*/.static
97b0: 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 41 70 70   int walIndexApp
97c0: 65 6e 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75  end(Wal *pWal, u
97d0: 33 32 20 69 46 72 61 6d 65 2c 20 75 33 32 20 69  32 iFrame, u32 i
97e0: 50 61 67 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b  Page){.  int rc;
97f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9800: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
9810: 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 75 33 32  rn code */.  u32
9820: 20 69 5a 65 72 6f 20 3d 20 30 3b 20 20 20 20 20   iZero = 0;     
9830: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9840: 4f 6e 65 20 6c 65 73 73 20 74 68 61 6e 20 66 72  One less than fr
9850: 61 6d 65 20 6e 75 6d 62 65 72 20 6f 66 20 61 50  ame number of aP
9860: 67 6e 6f 5b 31 5d 20 2a 2f 0a 20 20 76 6f 6c 61  gno[1] */.  vola
9870: 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 20  tile u32 *aPgno 
9880: 3d 20 30 3b 20 20 20 20 20 20 20 20 2f 2a 20 50  = 0;        /* P
9890: 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79  age number array
98a0: 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 68   */.  volatile h
98b0: 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 20 3d 20  t_slot *aHash = 
98c0: 30 3b 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61  0;    /* Hash ta
98d0: 62 6c 65 20 2a 2f 0a 0a 20 20 72 63 20 3d 20 77  ble */..  rc = w
98e0: 61 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c 20  alHashGet(pWal, 
98f0: 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69 46 72  walFramePage(iFr
9900: 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20 26 61  ame), &aHash, &a
9910: 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 0a  Pgno, &iZero);..
9920: 20 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20 74 68    /* Assuming th
9930: 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65  e wal-index file
9940: 20 77 61 73 20 73 75 63 63 65 73 73 66 75 6c 6c   was successfull
9950: 79 20 6d 61 70 70 65 64 2c 20 70 6f 70 75 6c 61  y mapped, popula
9960: 74 65 20 74 68 65 0a 20 20 2a 2a 20 70 61 67 65  te the.  ** page
9970: 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 61 6e   number array an
9980: 64 20 68 61 73 68 20 74 61 62 6c 65 20 65 6e 74  d hash table ent
9990: 72 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72  ry..  */.  if( r
99a0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
99b0: 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20 20      int iKey;   
99c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
99d0: 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20    /* Hash table 
99e0: 6b 65 79 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69  key */.    int i
99f0: 64 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  dx;             
9a00: 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75           /* Valu
9a10: 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 68 61  e to write to ha
9a20: 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 20 2a 2f  sh-table slot */
9a30: 0a 20 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69 64  .    int nCollid
9a40: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
9a50: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
9a60: 68 61 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73 20  hash collisions 
9a70: 2a 2f 0a 0a 20 20 20 20 69 64 78 20 3d 20 69 46  */..    idx = iF
9a80: 72 61 6d 65 20 2d 20 69 5a 65 72 6f 3b 0a 20 20  rame - iZero;.  
9a90: 20 20 61 73 73 65 72 74 28 20 69 64 78 20 3c 3d    assert( idx <=
9aa0: 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54   HASHTABLE_NSLOT
9ab0: 2f 32 20 2b 20 31 20 29 3b 0a 20 20 20 20 0a 20  /2 + 1 );.    . 
9ac0: 20 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73     /* If this is
9ad0: 20 74 68 65 20 66 69 72 73 74 20 65 6e 74 72 79   the first entry
9ae0: 20 74 6f 20 62 65 20 61 64 64 65 64 20 74 6f 20   to be added to 
9af0: 74 68 69 73 20 68 61 73 68 2d 74 61 62 6c 65 2c  this hash-table,
9b00: 20 7a 65 72 6f 20 74 68 65 0a 20 20 20 20 2a 2a   zero the.    **
9b10: 20 65 6e 74 69 72 65 20 68 61 73 68 20 74 61 62   entire hash tab
9b20: 6c 65 20 61 6e 64 20 61 50 67 6e 6f 5b 5d 20 61  le and aPgno[] a
9b30: 72 72 61 79 20 62 65 66 6f 72 65 20 70 72 6f 63  rray before proc
9b40: 65 64 69 6e 67 2e 20 0a 20 20 20 20 2a 2f 0a 20  eding. .    */. 
9b50: 20 20 20 69 66 28 20 69 64 78 3d 3d 31 20 29 7b     if( idx==1 ){
9b60: 0a 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65  .      int nByte
9b70: 20 3d 20 28 69 6e 74 29 28 28 75 38 20 2a 29 26   = (int)((u8 *)&
9b80: 61 48 61 73 68 5b 48 41 53 48 54 41 42 4c 45 5f  aHash[HASHTABLE_
9b90: 4e 53 4c 4f 54 5d 20 2d 20 28 75 38 20 2a 29 26  NSLOT] - (u8 *)&
9ba0: 61 50 67 6e 6f 5b 31 5d 29 3b 0a 20 20 20 20 20  aPgno[1]);.     
9bb0: 20 6d 65 6d 73 65 74 28 28 76 6f 69 64 2a 29 26   memset((void*)&
9bc0: 61 50 67 6e 6f 5b 31 5d 2c 20 30 2c 20 6e 42 79  aPgno[1], 0, nBy
9bd0: 74 65 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  te);.    }..    
9be0: 2f 2a 20 49 66 20 74 68 65 20 65 6e 74 72 79 20  /* If the entry 
9bf0: 69 6e 20 61 50 67 6e 6f 5b 5d 20 69 73 20 61 6c  in aPgno[] is al
9c00: 72 65 61 64 79 20 73 65 74 2c 20 74 68 65 6e 20  ready set, then 
9c10: 74 68 65 20 70 72 65 76 69 6f 75 73 20 77 72 69  the previous wri
9c20: 74 65 72 0a 20 20 20 20 2a 2a 20 6d 75 73 74 20  ter.    ** must 
9c30: 68 61 76 65 20 65 78 69 74 65 64 20 75 6e 65 78  have exited unex
9c40: 70 65 63 74 65 64 6c 79 20 69 6e 20 74 68 65 20  pectedly in the 
9c50: 6d 69 64 64 6c 65 20 6f 66 20 61 20 74 72 61 6e  middle of a tran
9c60: 73 61 63 74 69 6f 6e 20 28 61 66 74 65 72 0a 20  saction (after. 
9c70: 20 20 20 2a 2a 20 77 72 69 74 69 6e 67 20 6f 6e     ** writing on
9c80: 65 20 6f 72 20 6d 6f 72 65 20 64 69 72 74 79 20  e or more dirty 
9c90: 70 61 67 65 73 20 74 6f 20 74 68 65 20 57 41 4c  pages to the WAL
9ca0: 20 74 6f 20 66 72 65 65 20 75 70 20 6d 65 6d 6f   to free up memo
9cb0: 72 79 29 2e 20 0a 20 20 20 20 2a 2a 20 52 65 6d  ry). .    ** Rem
9cc0: 6f 76 65 20 74 68 65 20 72 65 6d 6e 61 6e 74 73  ove the remnants
9cd0: 20 6f 66 20 74 68 61 74 20 77 72 69 74 65 72 73   of that writers
9ce0: 20 75 6e 63 6f 6d 6d 69 74 74 65 64 20 74 72 61   uncommitted tra
9cf0: 6e 73 61 63 74 69 6f 6e 20 66 72 6f 6d 20 0a 20  nsaction from . 
9d00: 20 20 20 2a 2a 20 74 68 65 20 68 61 73 68 2d 74     ** the hash-t
9d10: 61 62 6c 65 20 62 65 66 6f 72 65 20 77 72 69 74  able before writ
9d20: 69 6e 67 20 61 6e 79 20 6e 65 77 20 65 6e 74 72  ing any new entr
9d30: 69 65 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ies..    */.    
9d40: 69 66 28 20 61 50 67 6e 6f 5b 69 64 78 5d 20 29  if( aPgno[idx] )
9d50: 7b 0a 20 20 20 20 20 20 77 61 6c 43 6c 65 61 6e  {.      walClean
9d60: 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20  upHash(pWal);.  
9d70: 20 20 20 20 61 73 73 65 72 74 28 20 21 61 50 67      assert( !aPg
9d80: 6e 6f 5b 69 64 78 5d 20 29 3b 0a 20 20 20 20 7d  no[idx] );.    }
9d90: 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74  ..    /* Write t
9da0: 68 65 20 61 50 67 6e 6f 5b 5d 20 61 72 72 61 79  he aPgno[] array
9db0: 20 65 6e 74 72 79 20 61 6e 64 20 74 68 65 20 68   entry and the h
9dc0: 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 2e 20  ash-table slot. 
9dd0: 2a 2f 0a 20 20 20 20 6e 43 6f 6c 6c 69 64 65 20  */.    nCollide 
9de0: 3d 20 69 64 78 3b 0a 20 20 20 20 66 6f 72 28 69  = idx;.    for(i
9df0: 4b 65 79 3d 77 61 6c 48 61 73 68 28 69 50 61 67  Key=walHash(iPag
9e00: 65 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b  e); aHash[iKey];
9e10: 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73   iKey=walNextHas
9e20: 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20  h(iKey)){.      
9e30: 69 66 28 20 28 6e 43 6f 6c 6c 69 64 65 2d 2d 29  if( (nCollide--)
9e40: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
9e50: 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54  ITE_CORRUPT_BKPT
9e60: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 50 67 6e  ;.    }.    aPgn
9e70: 6f 5b 69 64 78 5d 20 3d 20 69 50 61 67 65 3b 0a  o[idx] = iPage;.
9e80: 20 20 20 20 61 48 61 73 68 5b 69 4b 65 79 5d 20      aHash[iKey] 
9e90: 3d 20 28 68 74 5f 73 6c 6f 74 29 69 64 78 3b 0a  = (ht_slot)idx;.
9ea0: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45  .#ifdef SQLITE_E
9eb0: 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f  NABLE_EXPENSIVE_
9ec0: 41 53 53 45 52 54 0a 20 20 20 20 2f 2a 20 56 65  ASSERT.    /* Ve
9ed0: 72 69 66 79 20 74 68 61 74 20 74 68 65 20 6e 75  rify that the nu
9ee0: 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20  mber of entries 
9ef0: 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  in the hash tabl
9f00: 65 20 65 78 61 63 74 6c 79 20 65 71 75 61 6c 73  e exactly equals
9f10: 0a 20 20 20 20 2a 2a 20 74 68 65 20 6e 75 6d 62  .    ** the numb
9f20: 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e  er of entries in
9f30: 20 74 68 65 20 6d 61 70 70 69 6e 67 20 72 65 67   the mapping reg
9f40: 69 6f 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ion..    */.    
9f50: 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 20 20  {.      int i;  
9f60: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70           /* Loop
9f70: 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20 20   counter */.    
9f80: 20 20 69 6e 74 20 6e 45 6e 74 72 79 20 3d 20 30    int nEntry = 0
9f90: 3b 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20  ;  /* Number of 
9fa0: 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20 68  entries in the h
9fb0: 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20  ash table */.   
9fc0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48 41     for(i=0; i<HA
9fd0: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 20 69  SHTABLE_NSLOT; i
9fe0: 2b 2b 29 7b 20 69 66 28 20 61 48 61 73 68 5b 69  ++){ if( aHash[i
9ff0: 5d 20 29 20 6e 45 6e 74 72 79 2b 2b 3b 20 7d 0a  ] ) nEntry++; }.
a000: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6e 45        assert( nE
a010: 6e 74 72 79 3d 3d 69 64 78 20 29 3b 0a 20 20 20  ntry==idx );.   
a020: 20 7d 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69 66   }..    /* Verif
a030: 79 20 74 68 61 74 20 74 68 65 20 65 76 65 72 79  y that the every
a040: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61   entry in the ma
a050: 70 70 69 6e 67 20 72 65 67 69 6f 6e 20 69 73 20  pping region is 
a060: 72 65 61 63 68 61 62 6c 65 0a 20 20 20 20 2a 2a  reachable.    **
a070: 20 76 69 61 20 74 68 65 20 68 61 73 68 20 74 61   via the hash ta
a080: 62 6c 65 2e 20 20 54 68 69 73 20 74 75 72 6e 73  ble.  This turns
a090: 20 6f 75 74 20 74 6f 20 62 65 20 61 20 72 65 61   out to be a rea
a0a0: 6c 6c 79 2c 20 72 65 61 6c 6c 79 20 65 78 70 65  lly, really expe
a0b0: 6e 73 69 76 65 0a 20 20 20 20 2a 2a 20 74 68 69  nsive.    ** thi
a0c0: 6e 67 20 74 6f 20 63 68 65 63 6b 2c 20 73 6f 20  ng to check, so 
a0d0: 6f 6e 6c 79 20 64 6f 20 74 68 69 73 20 6f 63 63  only do this occ
a0e0: 61 73 69 6f 6e 61 6c 6c 79 20 2d 20 6e 6f 74 20  asionally - not 
a0f0: 6f 6e 20 65 76 65 72 79 0a 20 20 20 20 2a 2a 20  on every.    ** 
a100: 69 74 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20 2a  iteration..    *
a110: 2f 0a 20 20 20 20 69 66 28 20 28 69 64 78 26 30  /.    if( (idx&0
a120: 78 33 66 66 29 3d 3d 30 20 29 7b 0a 20 20 20 20  x3ff)==0 ){.    
a130: 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
a140: 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74     /* Loop count
a150: 65 72 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28  er */.      for(
a160: 69 3d 31 3b 20 69 3c 3d 69 64 78 3b 20 69 2b 2b  i=1; i<=idx; i++
a170: 29 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69  ){.        for(i
a180: 4b 65 79 3d 77 61 6c 48 61 73 68 28 61 50 67 6e  Key=walHash(aPgn
a190: 6f 5b 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b 65  o[i]); aHash[iKe
a1a0: 79 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74  y]; iKey=walNext
a1b0: 48 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20  Hash(iKey)){.   
a1c0: 20 20 20 20 20 20 20 69 66 28 20 61 48 61 73 68         if( aHash
a1d0: 5b 69 4b 65 79 5d 3d 3d 69 20 29 20 62 72 65 61  [iKey]==i ) brea
a1e0: 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  k;.        }.   
a1f0: 20 20 20 20 20 61 73 73 65 72 74 28 20 61 48 61       assert( aHa
a200: 73 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 3b 0a 20  sh[iKey]==i );. 
a210: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 23 65 6e       }.    }.#en
a220: 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e  dif /* SQLITE_EN
a230: 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41  ABLE_EXPENSIVE_A
a240: 53 53 45 52 54 20 2a 2f 0a 20 20 7d 0a 0a 0a 20  SSERT */.  }... 
a250: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a   return rc;.}...
a260: 2f 2a 0a 2a 2a 20 52 65 63 6f 76 65 72 20 74 68  /*.** Recover th
a270: 65 20 77 61 6c 2d 69 6e 64 65 78 20 62 79 20 72  e wal-index by r
a280: 65 61 64 69 6e 67 20 74 68 65 20 77 72 69 74 65  eading the write
a290: 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65 2e  -ahead log file.
a2a0: 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75   .**.** This rou
a2b0: 74 69 6e 65 20 66 69 72 73 74 20 74 72 69 65 73  tine first tries
a2c0: 20 74 6f 20 65 73 74 61 62 6c 69 73 68 20 61 6e   to establish an
a2d0: 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20   exclusive lock 
a2e0: 6f 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e  on the.** wal-in
a2f0: 64 65 78 20 74 6f 20 70 72 65 76 65 6e 74 20 6f  dex to prevent o
a300: 74 68 65 72 20 74 68 72 65 61 64 73 2f 70 72 6f  ther threads/pro
a310: 63 65 73 73 65 73 20 66 72 6f 6d 20 64 6f 69 6e  cesses from doin
a320: 67 20 61 6e 79 74 68 69 6e 67 0a 2a 2a 20 77 69  g anything.** wi
a330: 74 68 20 74 68 65 20 57 41 4c 20 6f 72 20 77 61  th the WAL or wa
a340: 6c 2d 69 6e 64 65 78 20 77 68 69 6c 65 20 72 65  l-index while re
a350: 63 6f 76 65 72 79 20 69 73 20 72 75 6e 6e 69 6e  covery is runnin
a360: 67 2e 20 20 54 68 65 0a 2a 2a 20 57 41 4c 5f 52  g.  The.** WAL_R
a370: 45 43 4f 56 45 52 5f 4c 4f 43 4b 20 69 73 20 61  ECOVER_LOCK is a
a380: 6c 73 6f 20 68 65 6c 64 20 73 6f 20 74 68 61 74  lso held so that
a390: 20 6f 74 68 65 72 20 74 68 72 65 61 64 73 20 77   other threads w
a3a0: 69 6c 6c 20 6b 6e 6f 77 0a 2a 2a 20 74 68 61 74  ill know.** that
a3b0: 20 74 68 69 73 20 74 68 72 65 61 64 20 69 73 20   this thread is 
a3c0: 72 75 6e 6e 69 6e 67 20 72 65 63 6f 76 65 72 79  running recovery
a3d0: 2e 20 20 49 66 20 75 6e 61 62 6c 65 20 74 6f 20  .  If unable to 
a3e0: 65 73 74 61 62 6c 69 73 68 0a 2a 2a 20 74 68 65  establish.** the
a3f0: 20 6e 65 63 65 73 73 61 72 79 20 6c 6f 63 6b 73   necessary locks
a400: 2c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 72  , this routine r
a410: 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55  eturns SQLITE_BU
a420: 53 59 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  SY..*/.static in
a430: 74 20 77 61 6c 49 6e 64 65 78 52 65 63 6f 76 65  t walIndexRecove
a440: 72 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20  r(Wal *pWal){.  
a450: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
a460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a470: 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a  /* Return Code *
a480: 2f 0a 20 20 69 36 34 20 6e 53 69 7a 65 3b 20 20  /.  i64 nSize;  
a490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a4a0: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 6c      /* Size of l
a4b0: 6f 67 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32  og file */.  u32
a4c0: 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 20   aFrameCksum[2] 
a4d0: 3d 20 7b 30 2c 20 30 7d 3b 0a 20 20 69 6e 74 20  = {0, 0};.  int 
a4e0: 69 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20  iLock;          
a4f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
a500: 6f 63 6b 20 6f 66 66 73 65 74 20 74 6f 20 6c 6f  ock offset to lo
a510: 63 6b 20 66 6f 72 20 63 68 65 63 6b 70 6f 69 6e  ck for checkpoin
a520: 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 6f 63 6b  t */.  int nLock
a530: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
a540: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
a550: 20 6f 66 20 6c 6f 63 6b 73 20 74 6f 20 68 6f 6c   of locks to hol
a560: 64 20 2a 2f 0a 0a 20 20 2f 2a 20 4f 62 74 61 69  d */..  /* Obtai
a570: 6e 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c  n an exclusive l
a580: 6f 63 6b 20 6f 6e 20 61 6c 6c 20 62 79 74 65 20  ock on all byte 
a590: 69 6e 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 72  in the locking r
a5a0: 61 6e 67 65 20 6e 6f 74 20 61 6c 72 65 61 64 79  ange not already
a5b0: 0a 20 20 2a 2a 20 6c 6f 63 6b 65 64 20 62 79 20  .  ** locked by 
a5c0: 74 68 65 20 63 61 6c 6c 65 72 2e 20 54 68 65 20  the caller. The 
a5d0: 63 61 6c 6c 65 72 20 69 73 20 67 75 61 72 61 6e  caller is guaran
a5e0: 74 65 65 64 20 74 6f 20 68 61 76 65 20 6c 6f 63  teed to have loc
a5f0: 6b 65 64 20 74 68 65 0a 20 20 2a 2a 20 57 41 4c  ked the.  ** WAL
a600: 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 62 79 74 65  _WRITE_LOCK byte
a610: 2c 20 61 6e 64 20 6d 61 79 20 68 61 76 65 20 61  , and may have a
a620: 6c 73 6f 20 6c 6f 63 6b 65 64 20 74 68 65 20 57  lso locked the W
a630: 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 62 79 74  AL_CKPT_LOCK byt
a640: 65 2e 0a 20 20 2a 2a 20 49 66 20 73 75 63 63 65  e..  ** If succe
a650: 73 73 66 75 6c 2c 20 74 68 65 20 73 61 6d 65 20  ssful, the same 
a660: 62 79 74 65 73 20 74 68 61 74 20 61 72 65 20 6c  bytes that are l
a670: 6f 63 6b 65 64 20 68 65 72 65 20 61 72 65 20 75  ocked here are u
a680: 6e 6c 6f 63 6b 65 64 20 62 65 66 6f 72 65 0a 20  nlocked before. 
a690: 20 2a 2a 20 74 68 69 73 20 66 75 6e 63 74 69 6f   ** this functio
a6a0: 6e 20 72 65 74 75 72 6e 73 2e 0a 20 20 2a 2f 0a  n returns..  */.
a6b0: 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
a6c0: 63 6b 70 74 4c 6f 63 6b 3d 3d 31 20 7c 7c 20 70  ckptLock==1 || p
a6d0: 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 30  Wal->ckptLock==0
a6e0: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 57 41   );.  assert( WA
a6f0: 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 3d  L_ALL_BUT_WRITE=
a700: 3d 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2b  =WAL_WRITE_LOCK+
a710: 31 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 57  1 );.  assert( W
a720: 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 3d 3d 57 41  AL_CKPT_LOCK==WA
a730: 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20  L_ALL_BUT_WRITE 
a740: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  );.  assert( pWa
a750: 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a  l->writeLock );.
a760: 20 20 69 4c 6f 63 6b 20 3d 20 57 41 4c 5f 41 4c    iLock = WAL_AL
a770: 4c 5f 42 55 54 5f 57 52 49 54 45 20 2b 20 70 57  L_BUT_WRITE + pW
a780: 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3b 0a 20 20  al->ckptLock;.  
a790: 6e 4c 6f 63 6b 20 3d 20 53 51 4c 49 54 45 5f 53  nLock = SQLITE_S
a7a0: 48 4d 5f 4e 4c 4f 43 4b 20 2d 20 69 4c 6f 63 6b  HM_NLOCK - iLock
a7b0: 3b 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b  ;.  rc = walLock
a7c0: 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
a7d0: 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b 0a 20  iLock, nLock);. 
a7e0: 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 72   if( rc ){.    r
a7f0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20  eturn rc;.  }.  
a800: 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70  WALTRACE(("WAL%p
a810: 3a 20 72 65 63 6f 76 65 72 79 20 62 65 67 69 6e  : recovery begin
a820: 2e 2e 2e 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a  ...\n", pWal));.
a830: 0a 20 20 6d 65 6d 73 65 74 28 26 70 57 61 6c 2d  .  memset(&pWal-
a840: 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  >hdr, 0, sizeof(
a850: 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 0a  WalIndexHdr));..
a860: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
a870: 46 69 6c 65 53 69 7a 65 28 70 57 61 6c 2d 3e 70  FileSize(pWal->p
a880: 57 61 6c 46 64 2c 20 26 6e 53 69 7a 65 29 3b 0a  WalFd, &nSize);.
a890: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
a8a0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20  _OK ){.    goto 
a8b0: 72 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a  recovery_error;.
a8c0: 20 20 7d 0a 0a 20 20 69 66 28 20 6e 53 69 7a 65    }..  if( nSize
a8d0: 3e 57 41 4c 5f 48 44 52 53 49 5a 45 20 29 7b 0a  >WAL_HDRSIZE ){.
a8e0: 20 20 20 20 75 38 20 61 42 75 66 5b 57 41 4c 5f      u8 aBuf[WAL_
a8f0: 48 44 52 53 49 5a 45 5d 3b 20 20 20 20 20 20 20  HDRSIZE];       
a900: 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 6c    /* Buffer to l
a910: 6f 61 64 20 57 41 4c 20 68 65 61 64 65 72 20 69  oad WAL header i
a920: 6e 74 6f 20 2a 2f 0a 20 20 20 20 75 38 20 2a 61  nto */.    u8 *a
a930: 46 72 61 6d 65 20 3d 20 30 3b 20 20 20 20 20 20  Frame = 0;      
a940: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 6c 6c           /* Mall
a950: 6f 63 27 64 20 62 75 66 66 65 72 20 74 6f 20 6c  oc'd buffer to l
a960: 6f 61 64 20 65 6e 74 69 72 65 20 66 72 61 6d 65  oad entire frame
a970: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 73 7a 46 72   */.    int szFr
a980: 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ame;            
a990: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
a9a0: 6f 66 20 62 79 74 65 73 20 69 6e 20 62 75 66 66  of bytes in buff
a9b0: 65 72 20 61 46 72 61 6d 65 5b 5d 20 2a 2f 0a 20  er aFrame[] */. 
a9c0: 20 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20 20     u8 *aData;   
a9d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a9e0: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 64   /* Pointer to d
a9f0: 61 74 61 20 70 61 72 74 20 6f 66 20 61 46 72 61  ata part of aFra
aa00: 6d 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 20  me buffer */.   
aa10: 20 69 6e 74 20 69 46 72 61 6d 65 3b 20 20 20 20   int iFrame;    
aa20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
aa30: 2a 20 49 6e 64 65 78 20 6f 66 20 6c 61 73 74 20  * Index of last 
aa40: 66 72 61 6d 65 20 72 65 61 64 20 2a 2f 0a 20 20  frame read */.  
aa50: 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 20 20    i64 iOffset;  
aa60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aa70: 2f 2a 20 4e 65 78 74 20 6f 66 66 73 65 74 20 74  /* Next offset t
aa80: 6f 20 72 65 61 64 20 66 72 6f 6d 20 6c 6f 67 20  o read from log 
aa90: 66 69 6c 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20  file */.    int 
aaa0: 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20  szPage;         
aab0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
aac0: 65 20 73 69 7a 65 20 61 63 63 6f 72 64 69 6e 67  e size according
aad0: 20 74 6f 20 74 68 65 20 6c 6f 67 20 2a 2f 0a 20   to the log */. 
aae0: 20 20 20 75 33 32 20 6d 61 67 69 63 3b 20 20 20     u32 magic;   
aaf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ab00: 20 2f 2a 20 4d 61 67 69 63 20 76 61 6c 75 65 20   /* Magic value 
ab10: 72 65 61 64 20 66 72 6f 6d 20 57 41 4c 20 68 65  read from WAL he
ab20: 61 64 65 72 20 2a 2f 0a 20 20 20 20 75 33 32 20  ader */.    u32 
ab30: 76 65 72 73 69 6f 6e 3b 20 20 20 20 20 20 20 20  version;        
ab40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 67            /* Mag
ab50: 69 63 20 76 61 6c 75 65 20 72 65 61 64 20 66 72  ic value read fr
ab60: 6f 6d 20 57 41 4c 20 68 65 61 64 65 72 20 2a 2f  om WAL header */
ab70: 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64 20 69 6e  ..    /* Read in
ab80: 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72 2e   the WAL header.
ab90: 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   */.    rc = sql
aba0: 69 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d  ite3OsRead(pWal-
abb0: 3e 70 57 61 6c 46 64 2c 20 61 42 75 66 2c 20 57  >pWalFd, aBuf, W
abc0: 41 4c 5f 48 44 52 53 49 5a 45 2c 20 30 29 3b 0a  AL_HDRSIZE, 0);.
abd0: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
abe0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 67  TE_OK ){.      g
abf0: 6f 74 6f 20 72 65 63 6f 76 65 72 79 5f 65 72 72  oto recovery_err
ac00: 6f 72 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  or;.    }..    /
ac10: 2a 20 49 66 20 74 68 65 20 64 61 74 61 62 61 73  * If the databas
ac20: 65 20 70 61 67 65 20 73 69 7a 65 20 69 73 20 6e  e page size is n
ac30: 6f 74 20 61 20 70 6f 77 65 72 20 6f 66 20 74 77  ot a power of tw
ac40: 6f 2c 20 6f 72 20 69 73 20 67 72 65 61 74 65 72  o, or is greater
ac50: 20 74 68 61 6e 0a 20 20 20 20 2a 2a 20 53 51 4c   than.    ** SQL
ac60: 49 54 45 5f 4d 41 58 5f 50 41 47 45 5f 53 49 5a  ITE_MAX_PAGE_SIZ
ac70: 45 2c 20 63 6f 6e 63 6c 75 64 65 20 74 68 61 74  E, conclude that
ac80: 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20 63 6f   the WAL file co
ac90: 6e 74 61 69 6e 73 20 6e 6f 20 76 61 6c 69 64 20  ntains no valid 
aca0: 0a 20 20 20 20 2a 2a 20 64 61 74 61 2e 20 53 69  .    ** data. Si
acb0: 6d 69 6c 61 72 6c 79 2c 20 69 66 20 74 68 65 20  milarly, if the 
acc0: 27 6d 61 67 69 63 27 20 76 61 6c 75 65 20 69 73  'magic' value is
acd0: 20 69 6e 76 61 6c 69 64 2c 20 69 67 6e 6f 72 65   invalid, ignore
ace0: 20 74 68 65 20 77 68 6f 6c 65 0a 20 20 20 20 2a   the whole.    *
acf0: 2a 20 57 41 4c 20 66 69 6c 65 2e 0a 20 20 20 20  * WAL file..    
ad00: 2a 2f 0a 20 20 20 20 6d 61 67 69 63 20 3d 20 73  */.    magic = s
ad10: 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26  qlite3Get4byte(&
ad20: 61 42 75 66 5b 30 5d 29 3b 0a 20 20 20 20 73 7a  aBuf[0]);.    sz
ad30: 50 61 67 65 20 3d 20 73 71 6c 69 74 65 33 47 65  Page = sqlite3Ge
ad40: 74 34 62 79 74 65 28 26 61 42 75 66 5b 38 5d 29  t4byte(&aBuf[8])
ad50: 3b 0a 20 20 20 20 69 66 28 20 28 6d 61 67 69 63  ;.    if( (magic
ad60: 26 30 78 46 46 46 46 46 46 46 45 29 21 3d 57 41  &0xFFFFFFFE)!=WA
ad70: 4c 5f 4d 41 47 49 43 20 0a 20 20 20 20 20 7c 7c  L_MAGIC .     ||
ad80: 20 73 7a 50 61 67 65 26 28 73 7a 50 61 67 65 2d   szPage&(szPage-
ad90: 31 29 20 0a 20 20 20 20 20 7c 7c 20 73 7a 50 61  1) .     || szPa
ada0: 67 65 3e 53 51 4c 49 54 45 5f 4d 41 58 5f 50 41  ge>SQLITE_MAX_PA
adb0: 47 45 5f 53 49 5a 45 20 0a 20 20 20 20 20 7c 7c  GE_SIZE .     ||
adc0: 20 73 7a 50 61 67 65 3c 35 31 32 20 0a 20 20 20   szPage<512 .   
add0: 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 66   ){.      goto f
ade0: 69 6e 69 73 68 65 64 3b 0a 20 20 20 20 7d 0a 20  inished;.    }. 
adf0: 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67     pWal->hdr.big
ae00: 45 6e 64 43 6b 73 75 6d 20 3d 20 28 75 38 29 28  EndCksum = (u8)(
ae10: 6d 61 67 69 63 26 30 78 30 30 30 30 30 30 30 31  magic&0x00000001
ae20: 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50  );.    pWal->szP
ae30: 61 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20  age = szPage;.  
ae40: 20 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 20 3d 20    pWal->nCkpt = 
ae50: 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
ae60: 26 61 42 75 66 5b 31 32 5d 29 3b 0a 20 20 20 20  &aBuf[12]);.    
ae70: 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64  memcpy(&pWal->hd
ae80: 72 2e 61 53 61 6c 74 2c 20 26 61 42 75 66 5b 31  r.aSalt, &aBuf[1
ae90: 36 5d 2c 20 38 29 3b 0a 0a 20 20 20 20 2f 2a 20  6], 8);..    /* 
aea0: 56 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20  Verify that the 
aeb0: 57 41 4c 20 68 65 61 64 65 72 20 63 68 65 63 6b  WAL header check
aec0: 73 75 6d 20 69 73 20 63 6f 72 72 65 63 74 20 2a  sum is correct *
aed0: 2f 0a 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75  /.    walChecksu
aee0: 6d 42 79 74 65 73 28 70 57 61 6c 2d 3e 68 64 72  mBytes(pWal->hdr
aef0: 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d 3d 53 51  .bigEndCksum==SQ
af00: 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e 2c 20  LITE_BIGENDIAN, 
af10: 0a 20 20 20 20 20 20 20 20 61 42 75 66 2c 20 57  .        aBuf, W
af20: 41 4c 5f 48 44 52 53 49 5a 45 2d 32 2a 34 2c 20  AL_HDRSIZE-2*4, 
af30: 30 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72  0, pWal->hdr.aFr
af40: 61 6d 65 43 6b 73 75 6d 0a 20 20 20 20 29 3b 0a  ameCksum.    );.
af50: 20 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64      if( pWal->hd
af60: 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d  r.aFrameCksum[0]
af70: 21 3d 73 71 6c 69 74 65 33 47 65 74 34 62 79 74  !=sqlite3Get4byt
af80: 65 28 26 61 42 75 66 5b 32 34 5d 29 0a 20 20 20  e(&aBuf[24]).   
af90: 20 20 7c 7c 20 70 57 61 6c 2d 3e 68 64 72 2e 61    || pWal->hdr.a
afa0: 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 21 3d 73  FrameCksum[1]!=s
afb0: 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26  qlite3Get4byte(&
afc0: 61 42 75 66 5b 32 38 5d 29 0a 20 20 20 20 29 7b  aBuf[28]).    ){
afd0: 0a 20 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69  .      goto fini
afe0: 73 68 65 64 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  shed;.    }..   
aff0: 20 2f 2a 20 56 65 72 69 66 79 20 74 68 61 74 20   /* Verify that 
b000: 74 68 65 20 76 65 72 73 69 6f 6e 20 6e 75 6d 62  the version numb
b010: 65 72 20 6f 6e 20 74 68 65 20 57 41 4c 20 66 6f  er on the WAL fo
b020: 72 6d 61 74 20 69 73 20 6f 6e 65 20 74 68 61 74  rmat is one that
b030: 0a 20 20 20 20 2a 2a 20 61 72 65 20 61 62 6c 65  .    ** are able
b040: 20 74 6f 20 75 6e 64 65 72 73 74 61 6e 64 20 2a   to understand *
b050: 2f 0a 20 20 20 20 76 65 72 73 69 6f 6e 20 3d 20  /.    version = 
b060: 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
b070: 26 61 42 75 66 5b 34 5d 29 3b 0a 20 20 20 20 69  &aBuf[4]);.    i
b080: 66 28 20 76 65 72 73 69 6f 6e 21 3d 57 41 4c 5f  f( version!=WAL_
b090: 4d 41 58 5f 56 45 52 53 49 4f 4e 20 29 7b 0a 20  MAX_VERSION ){. 
b0a0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
b0b0: 5f 43 41 4e 54 4f 50 45 4e 5f 42 4b 50 54 3b 0a  _CANTOPEN_BKPT;.
b0c0: 20 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73        goto finis
b0d0: 68 65 64 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  hed;.    }..    
b0e0: 2f 2a 20 4d 61 6c 6c 6f 63 20 61 20 62 75 66 66  /* Malloc a buff
b0f0: 65 72 20 74 6f 20 72 65 61 64 20 66 72 61 6d 65  er to read frame
b100: 73 20 69 6e 74 6f 2e 20 2a 2f 0a 20 20 20 20 73  s into. */.    s
b110: 7a 46 72 61 6d 65 20 3d 20 73 7a 50 61 67 65 20  zFrame = szPage 
b120: 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  + WAL_FRAME_HDRS
b130: 49 5a 45 3b 0a 20 20 20 20 61 46 72 61 6d 65 20  IZE;.    aFrame 
b140: 3d 20 28 75 38 20 2a 29 73 71 6c 69 74 65 33 5f  = (u8 *)sqlite3_
b150: 6d 61 6c 6c 6f 63 28 73 7a 46 72 61 6d 65 29 3b  malloc(szFrame);
b160: 0a 20 20 20 20 69 66 28 20 21 61 46 72 61 6d 65  .    if( !aFrame
b170: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
b180: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
b190: 20 20 20 67 6f 74 6f 20 72 65 63 6f 76 65 72 79     goto recovery
b1a0: 5f 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a 20 20  _error;.    }.  
b1b0: 20 20 61 44 61 74 61 20 3d 20 26 61 46 72 61 6d    aData = &aFram
b1c0: 65 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  e[WAL_FRAME_HDRS
b1d0: 49 5a 45 5d 3b 0a 0a 20 20 20 20 2f 2a 20 52 65  IZE];..    /* Re
b1e0: 61 64 20 61 6c 6c 20 66 72 61 6d 65 73 20 66 72  ad all frames fr
b1f0: 6f 6d 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e  om the log file.
b200: 20 2a 2f 0a 20 20 20 20 69 46 72 61 6d 65 20 3d   */.    iFrame =
b210: 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 4f 66 66   0;.    for(iOff
b220: 73 65 74 3d 57 41 4c 5f 48 44 52 53 49 5a 45 3b  set=WAL_HDRSIZE;
b230: 20 28 69 4f 66 66 73 65 74 2b 73 7a 46 72 61 6d   (iOffset+szFram
b240: 65 29 3c 3d 6e 53 69 7a 65 3b 20 69 4f 66 66 73  e)<=nSize; iOffs
b250: 65 74 2b 3d 73 7a 46 72 61 6d 65 29 7b 0a 20 20  et+=szFrame){.  
b260: 20 20 20 20 75 33 32 20 70 67 6e 6f 3b 20 20 20      u32 pgno;   
b270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b280: 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  /* Database page
b290: 20 6e 75 6d 62 65 72 20 66 6f 72 20 66 72 61 6d   number for fram
b2a0: 65 20 2a 2f 0a 20 20 20 20 20 20 75 33 32 20 6e  e */.      u32 n
b2b0: 54 72 75 6e 63 61 74 65 3b 20 20 20 20 20 20 20  Truncate;       
b2c0: 20 20 20 20 20 20 20 2f 2a 20 64 62 73 69 7a 65         /* dbsize
b2d0: 20 66 69 65 6c 64 20 66 72 6f 6d 20 66 72 61 6d   field from fram
b2e0: 65 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 20 20  e header */.    
b2f0: 20 20 69 6e 74 20 69 73 56 61 6c 69 64 3b 20 20    int isValid;  
b300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
b310: 20 54 72 75 65 20 69 66 20 74 68 69 73 20 66 72   True if this fr
b320: 61 6d 65 20 69 73 20 76 61 6c 69 64 20 2a 2f 0a  ame is valid */.
b330: 0a 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20 61  .      /* Read a
b340: 6e 64 20 64 65 63 6f 64 65 20 74 68 65 20 6e 65  nd decode the ne
b350: 78 74 20 6c 6f 67 20 66 72 61 6d 65 2e 20 2a 2f  xt log frame. */
b360: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
b370: 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e  te3OsRead(pWal->
b380: 70 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20  pWalFd, aFrame, 
b390: 73 7a 46 72 61 6d 65 2c 20 69 4f 66 66 73 65 74  szFrame, iOffset
b3a0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  );.      if( rc!
b3b0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65  =SQLITE_OK ) bre
b3c0: 61 6b 3b 0a 20 20 20 20 20 20 69 73 56 61 6c 69  ak;.      isVali
b3d0: 64 20 3d 20 77 61 6c 44 65 63 6f 64 65 46 72 61  d = walDecodeFra
b3e0: 6d 65 28 70 57 61 6c 2c 20 26 70 67 6e 6f 2c 20  me(pWal, &pgno, 
b3f0: 26 6e 54 72 75 6e 63 61 74 65 2c 20 61 44 61 74  &nTruncate, aDat
b400: 61 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20 20 20  a, aFrame);.    
b410: 20 20 69 66 28 20 21 69 73 56 61 6c 69 64 20 29    if( !isValid )
b420: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 72 63   break;.      rc
b430: 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e   = walIndexAppen
b440: 64 28 70 57 61 6c 2c 20 2b 2b 69 46 72 61 6d 65  d(pWal, ++iFrame
b450: 2c 20 70 67 6e 6f 29 3b 0a 20 20 20 20 20 20 69  , pgno);.      i
b460: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
b470: 20 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20   ) break;..     
b480: 20 2f 2a 20 49 66 20 6e 54 72 75 6e 63 61 74 65   /* If nTruncate
b490: 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68   is non-zero, th
b4a0: 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 20 72  is is a commit r
b4b0: 65 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 20 20  ecord. */.      
b4c0: 69 66 28 20 6e 54 72 75 6e 63 61 74 65 20 29 7b  if( nTruncate ){
b4d0: 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 68  .        pWal->h
b4e0: 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20 69 46 72  dr.mxFrame = iFr
b4f0: 61 6d 65 3b 0a 20 20 20 20 20 20 20 20 70 57 61  ame;.        pWa
b500: 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20 3d 20 6e  l->hdr.nPage = n
b510: 54 72 75 6e 63 61 74 65 3b 0a 20 20 20 20 20 20  Truncate;.      
b520: 20 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61    pWal->hdr.szPa
b530: 67 65 20 3d 20 28 75 31 36 29 28 28 73 7a 50 61  ge = (u16)((szPa
b540: 67 65 26 30 78 66 66 30 30 29 20 7c 20 28 73 7a  ge&0xff00) | (sz
b550: 50 61 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20 20  Page>>16));.    
b560: 20 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a      testcase( sz
b570: 50 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20  Page<=32768 );. 
b580: 20 20 20 20 20 20 20 74 65 73 74 63 61 73 65 28         testcase(
b590: 20 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20 29   szPage>=65536 )
b5a0: 3b 0a 20 20 20 20 20 20 20 20 61 46 72 61 6d 65  ;.        aFrame
b5b0: 43 6b 73 75 6d 5b 30 5d 20 3d 20 70 57 61 6c 2d  Cksum[0] = pWal-
b5c0: 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
b5d0: 5b 30 5d 3b 0a 20 20 20 20 20 20 20 20 61 46 72  [0];.        aFr
b5e0: 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 70 57  ameCksum[1] = pW
b5f0: 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
b600: 73 75 6d 5b 31 5d 3b 0a 20 20 20 20 20 20 7d 0a  sum[1];.      }.
b610: 20 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74      }..    sqlit
b620: 65 33 5f 66 72 65 65 28 61 46 72 61 6d 65 29 3b  e3_free(aFrame);
b630: 0a 20 20 7d 0a 0a 66 69 6e 69 73 68 65 64 3a 0a  .  }..finished:.
b640: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
b650: 5f 4f 4b 20 29 7b 0a 20 20 20 20 76 6f 6c 61 74  _OK ){.    volat
b660: 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20  ile WalCkptInfo 
b670: 2a 70 49 6e 66 6f 3b 0a 20 20 20 20 69 6e 74 20  *pInfo;.    int 
b680: 69 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  i;.    pWal->hdr
b690: 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20  .aFrameCksum[0] 
b6a0: 3d 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d  = aFrameCksum[0]
b6b0: 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  ;.    pWal->hdr.
b6c0: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d  aFrameCksum[1] =
b6d0: 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b   aFrameCksum[1];
b6e0: 0a 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72 69  .    walIndexWri
b6f0: 74 65 48 64 72 28 70 57 61 6c 29 3b 0a 0a 20 20  teHdr(pWal);..  
b700: 20 20 2f 2a 20 52 65 73 65 74 20 74 68 65 20 63    /* Reset the c
b710: 68 65 63 6b 70 6f 69 6e 74 2d 68 65 61 64 65 72  heckpoint-header
b720: 2e 20 54 68 69 73 20 69 73 20 73 61 66 65 20 62  . This is safe b
b730: 65 63 61 75 73 65 20 74 68 69 73 20 74 68 72 65  ecause this thre
b740: 61 64 20 69 73 20 0a 20 20 20 20 2a 2a 20 63 75  ad is .    ** cu
b750: 72 72 65 6e 74 6c 79 20 68 6f 6c 64 69 6e 67 20  rrently holding 
b760: 6c 6f 63 6b 73 20 74 68 61 74 20 65 78 63 6c 75  locks that exclu
b770: 64 65 20 61 6c 6c 20 6f 74 68 65 72 20 72 65 61  de all other rea
b780: 64 65 72 73 2c 20 77 72 69 74 65 72 73 20 61 6e  ders, writers an
b790: 64 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f  d.    ** checkpo
b7a0: 69 6e 74 65 72 73 2e 0a 20 20 20 20 2a 2f 0a 20  inters..    */. 
b7b0: 20 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b     pInfo = walCk
b7c0: 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20  ptInfo(pWal);.  
b7d0: 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69    pInfo->nBackfi
b7e0: 6c 6c 20 3d 20 30 3b 0a 20 20 20 20 70 49 6e 66  ll = 0;.    pInf
b7f0: 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20  o->aReadMark[0] 
b800: 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31  = 0;.    for(i=1
b810: 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b  ; i<WAL_NREADER;
b820: 20 69 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65   i++) pInfo->aRe
b830: 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44  adMark[i] = READ
b840: 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 0a  MARK_NOT_USED;..
b850: 20 20 20 20 2f 2a 20 49 66 20 6d 6f 72 65 20 74      /* If more t
b860: 68 61 6e 20 6f 6e 65 20 66 72 61 6d 65 20 77 61  han one frame wa
b870: 73 20 72 65 63 6f 76 65 72 65 64 20 66 72 6f 6d  s recovered from
b880: 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2c 20 72   the log file, r
b890: 65 70 6f 72 74 20 61 6e 0a 20 20 20 20 2a 2a 20  eport an.    ** 
b8a0: 65 76 65 6e 74 20 76 69 61 20 73 71 6c 69 74 65  event via sqlite
b8b0: 33 5f 6c 6f 67 28 29 2e 20 54 68 69 73 20 69 73  3_log(). This is
b8c0: 20 74 6f 20 68 65 6c 70 20 77 69 74 68 20 69 64   to help with id
b8d0: 65 6e 74 69 66 79 69 6e 67 20 70 65 72 66 6f 72  entifying perfor
b8e0: 6d 61 6e 63 65 0a 20 20 20 20 2a 2a 20 70 72 6f  mance.    ** pro
b8f0: 62 6c 65 6d 73 20 63 61 75 73 65 64 20 62 79 20  blems caused by 
b900: 61 70 70 6c 69 63 61 74 69 6f 6e 73 20 72 6f 75  applications rou
b910: 74 69 6e 65 6c 79 20 73 68 75 74 74 69 6e 67 20  tinely shutting 
b920: 64 6f 77 6e 20 77 69 74 68 6f 75 74 0a 20 20 20  down without.   
b930: 20 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 69 6e   ** checkpointin
b940: 67 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 0a  g the log file..
b950: 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 70      */.    if( p
b960: 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20 29  Wal->hdr.nPage )
b970: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
b980: 6c 6f 67 28 53 51 4c 49 54 45 5f 4f 4b 2c 20 22  log(SQLITE_OK, "
b990: 52 65 63 6f 76 65 72 65 64 20 25 64 20 66 72 61  Recovered %d fra
b9a0: 6d 65 73 20 66 72 6f 6d 20 57 41 4c 20 66 69 6c  mes from WAL fil
b9b0: 65 20 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20  e %s",.         
b9c0: 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65   pWal->hdr.nPage
b9d0: 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65  , pWal->zWalName
b9e0: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a  .      );.    }.
b9f0: 20 20 7d 0a 0a 72 65 63 6f 76 65 72 79 5f 65 72    }..recovery_er
ba00: 72 6f 72 3a 0a 20 20 57 41 4c 54 52 41 43 45 28  ror:.  WALTRACE(
ba10: 28 22 57 41 4c 25 70 3a 20 72 65 63 6f 76 65 72  ("WAL%p: recover
ba20: 79 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  y %s\n", pWal, r
ba30: 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
ba40: 6f 6b 22 29 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f  ok"));.  walUnlo
ba50: 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
ba60: 2c 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b  , iLock, nLock);
ba70: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
ba80: 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20  ./*.** Close an 
ba90: 6f 70 65 6e 20 77 61 6c 2d 69 6e 64 65 78 2e 0a  open wal-index..
baa0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
bab0: 61 6c 49 6e 64 65 78 43 6c 6f 73 65 28 57 61 6c  alIndexClose(Wal
bac0: 20 2a 70 57 61 6c 2c 20 69 6e 74 20 69 73 44 65   *pWal, int isDe
bad0: 6c 65 74 65 29 7b 0a 20 20 69 66 28 20 70 57 61  lete){.  if( pWa
bae0: 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
baf0: 3d 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59  ==WAL_HEAPMEMORY
bb00: 5f 4d 4f 44 45 20 29 7b 0a 20 20 20 20 69 6e 74  _MODE ){.    int
bb10: 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b   i;.    for(i=0;
bb20: 20 69 3c 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61   i<pWal->nWiData
bb30: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 71  ; i++){.      sq
bb40: 6c 69 74 65 33 5f 66 72 65 65 28 28 76 6f 69 64  lite3_free((void
bb50: 20 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44 61 74   *)pWal->apWiDat
bb60: 61 5b 69 5d 29 3b 0a 20 20 20 20 20 20 70 57 61  a[i]);.      pWa
bb70: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 5d 20 3d  l->apWiData[i] =
bb80: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73   0;.    }.  }els
bb90: 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  e{.    sqlite3Os
bba0: 53 68 6d 55 6e 6d 61 70 28 70 57 61 6c 2d 3e 70  ShmUnmap(pWal->p
bbb0: 44 62 46 64 2c 20 69 73 44 65 6c 65 74 65 29 3b  DbFd, isDelete);
bbc0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4f  .  }.}../* .** O
bbd0: 70 65 6e 20 61 20 63 6f 6e 6e 65 63 74 69 6f 6e  pen a connection
bbe0: 20 74 6f 20 74 68 65 20 57 41 4c 20 66 69 6c 65   to the WAL file
bbf0: 20 7a 57 61 6c 4e 61 6d 65 2e 20 54 68 65 20 64   zWalName. The d
bc00: 61 74 61 62 61 73 65 20 66 69 6c 65 20 6d 75 73  atabase file mus
bc10: 74 20 0a 2a 2a 20 61 6c 72 65 61 64 79 20 62 65  t .** already be
bc20: 20 6f 70 65 6e 65 64 20 6f 6e 20 63 6f 6e 6e 65   opened on conne
bc30: 63 74 69 6f 6e 20 70 44 62 46 64 2e 20 54 68 65  ction pDbFd. The
bc40: 20 62 75 66 66 65 72 20 74 68 61 74 20 7a 57 61   buffer that zWa
bc50: 6c 4e 61 6d 65 20 70 6f 69 6e 74 73 0a 2a 2a 20  lName points.** 
bc60: 74 6f 20 6d 75 73 74 20 72 65 6d 61 69 6e 20 76  to must remain v
bc70: 61 6c 69 64 20 66 6f 72 20 74 68 65 20 6c 69 66  alid for the lif
bc80: 65 74 69 6d 65 20 6f 66 20 74 68 65 20 72 65 74  etime of the ret
bc90: 75 72 6e 65 64 20 57 61 6c 2a 20 68 61 6e 64 6c  urned Wal* handl
bca0: 65 2e 0a 2a 2a 0a 2a 2a 20 41 20 53 48 41 52 45  e..**.** A SHARE
bcb0: 44 20 6c 6f 63 6b 20 73 68 6f 75 6c 64 20 62 65  D lock should be
bcc0: 20 68 65 6c 64 20 6f 6e 20 74 68 65 20 64 61 74   held on the dat
bcd0: 61 62 61 73 65 20 66 69 6c 65 20 77 68 65 6e 20  abase file when 
bce0: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a  this function.**
bcf0: 20 69 73 20 63 61 6c 6c 65 64 2e 20 54 68 65 20   is called. The 
bd00: 70 75 72 70 6f 73 65 20 6f 66 20 74 68 69 73 20  purpose of this 
bd10: 53 48 41 52 45 44 20 6c 6f 63 6b 20 69 73 20 74  SHARED lock is t
bd20: 6f 20 70 72 65 76 65 6e 74 20 61 6e 79 20 6f 74  o prevent any ot
bd30: 68 65 72 0a 2a 2a 20 63 6c 69 65 6e 74 20 66 72  her.** client fr
bd40: 6f 6d 20 75 6e 6c 69 6e 6b 69 6e 67 20 74 68 65  om unlinking the
bd50: 20 57 41 4c 20 6f 72 20 77 61 6c 2d 69 6e 64 65   WAL or wal-inde
bd60: 78 20 66 69 6c 65 2e 20 49 66 20 61 6e 6f 74 68  x file. If anoth
bd70: 65 72 20 70 72 6f 63 65 73 73 0a 2a 2a 20 77 65  er process.** we
bd80: 72 65 20 74 6f 20 64 6f 20 74 68 69 73 20 6a 75  re to do this ju
bd90: 73 74 20 61 66 74 65 72 20 74 68 69 73 20 63 6c  st after this cl
bda0: 69 65 6e 74 20 6f 70 65 6e 65 64 20 6f 6e 65 20  ient opened one 
bdb0: 6f 66 20 74 68 65 73 65 20 66 69 6c 65 73 2c 20  of these files, 
bdc0: 74 68 65 0a 2a 2a 20 73 79 73 74 65 6d 20 77 6f  the.** system wo
bdd0: 75 6c 64 20 62 65 20 62 61 64 6c 79 20 62 72 6f  uld be badly bro
bde0: 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ken..**.** If th
bdf0: 65 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 73 75  e log file is su
be00: 63 63 65 73 73 66 75 6c 6c 79 20 6f 70 65 6e 65  ccessfully opene
be10: 64 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20  d, SQLITE_OK is 
be20: 72 65 74 75 72 6e 65 64 20 61 6e 64 20 0a 2a 2a  returned and .**
be30: 20 2a 70 70 57 61 6c 20 69 73 20 73 65 74 20 74   *ppWal is set t
be40: 6f 20 70 6f 69 6e 74 20 74 6f 20 61 20 6e 65 77  o point to a new
be50: 20 57 41 4c 20 68 61 6e 64 6c 65 2e 20 49 66 20   WAL handle. If 
be60: 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  an error occurs,
be70: 0a 2a 2a 20 61 6e 20 53 51 4c 69 74 65 20 65 72  .** an SQLite er
be80: 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75  ror code is retu
be90: 72 6e 65 64 20 61 6e 64 20 2a 70 70 57 61 6c 20  rned and *ppWal 
bea0: 69 73 20 6c 65 66 74 20 75 6e 6d 6f 64 69 66 69  is left unmodifi
beb0: 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ed..*/.int sqlit
bec0: 65 33 57 61 6c 4f 70 65 6e 28 0a 20 20 73 71 6c  e3WalOpen(.  sql
bed0: 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20  ite3_vfs *pVfs, 
bee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
bef0: 76 66 73 20 6d 6f 64 75 6c 65 20 74 6f 20 6f 70  vfs module to op
bf00: 65 6e 20 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69  en wal and wal-i
bf10: 6e 64 65 78 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ndex */.  sqlite
bf20: 33 5f 66 69 6c 65 20 2a 70 44 62 46 64 2c 20 20  3_file *pDbFd,  
bf30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
bf40: 20 6f 70 65 6e 20 64 61 74 61 62 61 73 65 20 66   open database f
bf50: 69 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  ile */.  const c
bf60: 68 61 72 20 2a 7a 57 61 6c 4e 61 6d 65 2c 20 20  har *zWalName,  
bf70: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
bf80: 20 6f 66 20 74 68 65 20 57 41 4c 20 66 69 6c 65   of the WAL file
bf90: 20 2a 2f 0a 20 20 69 6e 74 20 62 4e 6f 53 68 6d   */.  int bNoShm
bfa0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
bfb0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f        /* True to
bfc0: 20 72 75 6e 20 69 6e 20 68 65 61 70 2d 6d 65 6d   run in heap-mem
bfd0: 6f 72 79 20 6d 6f 64 65 20 2a 2f 0a 20 20 57 61  ory mode */.  Wa
bfe0: 6c 20 2a 2a 70 70 57 61 6c 20 20 20 20 20 20 20  l **ppWal       
bff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c000: 20 4f 55 54 3a 20 41 6c 6c 6f 63 61 74 65 64 20   OUT: Allocated 
c010: 57 61 6c 20 68 61 6e 64 6c 65 20 2a 2f 0a 29 7b  Wal handle */.){
c020: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
c030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c040: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64     /* Return Cod
c050: 65 20 2a 2f 0a 20 20 57 61 6c 20 2a 70 52 65 74  e */.  Wal *pRet
c060: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
c070: 20 20 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74         /* Object
c080: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64   to allocate and
c090: 20 72 65 74 75 72 6e 20 2a 2f 0a 20 20 69 6e 74   return */.  int
c0a0: 20 66 6c 61 67 73 3b 20 20 20 20 20 20 20 20 20   flags;         
c0b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c0c0: 46 6c 61 67 73 20 70 61 73 73 65 64 20 74 6f 20  Flags passed to 
c0d0: 4f 73 4f 70 65 6e 28 29 20 2a 2f 0a 0a 20 20 61  OsOpen() */..  a
c0e0: 73 73 65 72 74 28 20 7a 57 61 6c 4e 61 6d 65 20  ssert( zWalName 
c0f0: 26 26 20 7a 57 61 6c 4e 61 6d 65 5b 30 5d 20 29  && zWalName[0] )
c100: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 44 62 46  ;.  assert( pDbF
c110: 64 20 29 3b 0a 0a 20 20 2f 2a 20 49 6e 20 74 68  d );..  /* In th
c120: 65 20 61 6d 61 6c 67 61 6d 61 74 69 6f 6e 2c 20  e amalgamation, 
c130: 74 68 65 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e  the os_unix.c an
c140: 64 20 6f 73 5f 77 69 6e 2e 63 20 73 6f 75 72 63  d os_win.c sourc
c150: 65 20 66 69 6c 65 73 20 63 6f 6d 65 20 62 65 66  e files come bef
c160: 6f 72 65 0a 20 20 2a 2a 20 74 68 69 73 20 73 6f  ore.  ** this so
c170: 75 72 63 65 20 66 69 6c 65 2e 20 20 56 65 72 69  urce file.  Veri
c180: 66 79 20 74 68 61 74 20 74 68 65 20 23 64 65 66  fy that the #def
c190: 69 6e 65 73 20 6f 66 20 74 68 65 20 6c 6f 63 6b  ines of the lock
c1a0: 69 6e 67 20 62 79 74 65 20 6f 66 66 73 65 74 73  ing byte offsets
c1b0: 0a 20 20 2a 2a 20 69 6e 20 6f 73 5f 75 6e 69 78  .  ** in os_unix
c1c0: 2e 63 20 61 6e 64 20 6f 73 5f 77 69 6e 2e 63 20  .c and os_win.c 
c1d0: 61 67 72 65 65 20 77 69 74 68 20 74 68 65 20 57  agree with the W
c1e0: 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46  ALINDEX_LOCK_OFF
c1f0: 53 45 54 20 76 61 6c 75 65 2e 0a 20 20 2a 2f 0a  SET value..  */.
c200: 23 69 66 64 65 66 20 57 49 4e 5f 53 48 4d 5f 42  #ifdef WIN_SHM_B
c210: 41 53 45 0a 20 20 61 73 73 65 72 74 28 20 57 49  ASE.  assert( WI
c220: 4e 5f 53 48 4d 5f 42 41 53 45 3d 3d 57 41 4c 49  N_SHM_BASE==WALI
c230: 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54  NDEX_LOCK_OFFSET
c240: 20 29 3b 0a 23 65 6e 64 69 66 0a 23 69 66 64 65   );.#endif.#ifde
c250: 66 20 55 4e 49 58 5f 53 48 4d 5f 42 41 53 45 0a  f UNIX_SHM_BASE.
c260: 20 20 61 73 73 65 72 74 28 20 55 4e 49 58 5f 53    assert( UNIX_S
c270: 48 4d 5f 42 41 53 45 3d 3d 57 41 4c 49 4e 44 45  HM_BASE==WALINDE
c280: 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b  X_LOCK_OFFSET );
c290: 0a 23 65 6e 64 69 66 0a 0a 0a 20 20 2f 2a 20 41  .#endif...  /* A
c2a0: 6c 6c 6f 63 61 74 65 20 61 6e 20 69 6e 73 74 61  llocate an insta
c2b0: 6e 63 65 20 6f 66 20 73 74 72 75 63 74 20 57 61  nce of struct Wa
c2c0: 6c 20 74 6f 20 72 65 74 75 72 6e 2e 20 2a 2f 0a  l to return. */.
c2d0: 20 20 2a 70 70 57 61 6c 20 3d 20 30 3b 0a 20 20    *ppWal = 0;.  
c2e0: 70 52 65 74 20 3d 20 28 57 61 6c 2a 29 73 71 6c  pRet = (Wal*)sql
c2f0: 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73  ite3MallocZero(s
c300: 69 7a 65 6f 66 28 57 61 6c 29 20 2b 20 70 56 66  izeof(Wal) + pVf
c310: 73 2d 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a 20 20  s->szOsFile);.  
c320: 69 66 28 20 21 70 52 65 74 20 29 7b 0a 20 20 20  if( !pRet ){.   
c330: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
c340: 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 70 52 65  OMEM;.  }..  pRe
c350: 74 2d 3e 70 56 66 73 20 3d 20 70 56 66 73 3b 0a  t->pVfs = pVfs;.
c360: 20 20 70 52 65 74 2d 3e 70 57 61 6c 46 64 20 3d    pRet->pWalFd =
c370: 20 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a   (sqlite3_file *
c380: 29 26 70 52 65 74 5b 31 5d 3b 0a 20 20 70 52 65  )&pRet[1];.  pRe
c390: 74 2d 3e 70 44 62 46 64 20 3d 20 70 44 62 46 64  t->pDbFd = pDbFd
c3a0: 3b 0a 20 20 70 52 65 74 2d 3e 72 65 61 64 4c 6f  ;.  pRet->readLo
c3b0: 63 6b 20 3d 20 2d 31 3b 0a 20 20 70 52 65 74 2d  ck = -1;.  pRet-
c3c0: 3e 7a 57 61 6c 4e 61 6d 65 20 3d 20 7a 57 61 6c  >zWalName = zWal
c3d0: 4e 61 6d 65 3b 0a 20 20 70 52 65 74 2d 3e 65 78  Name;.  pRet->ex
c3e0: 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 28 62  clusiveMode = (b
c3f0: 4e 6f 53 68 6d 20 3f 20 57 41 4c 5f 48 45 41 50  NoShm ? WAL_HEAP
c400: 4d 45 4d 4f 52 59 5f 4d 4f 44 45 3a 20 57 41 4c  MEMORY_MODE: WAL
c410: 5f 4e 4f 52 4d 41 4c 5f 4d 4f 44 45 29 3b 0a 0a  _NORMAL_MODE);..
c420: 20 20 2f 2a 20 4f 70 65 6e 20 66 69 6c 65 20 68    /* Open file h
c430: 61 6e 64 6c 65 20 6f 6e 20 74 68 65 20 77 72 69  andle on the wri
c440: 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c  te-ahead log fil
c450: 65 2e 20 2a 2f 0a 20 20 66 6c 61 67 73 20 3d 20  e. */.  flags = 
c460: 28 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41  (SQLITE_OPEN_REA
c470: 44 57 52 49 54 45 7c 53 51 4c 49 54 45 5f 4f 50  DWRITE|SQLITE_OP
c480: 45 4e 5f 43 52 45 41 54 45 7c 53 51 4c 49 54 45  EN_CREATE|SQLITE
c490: 5f 4f 50 45 4e 5f 57 41 4c 29 3b 0a 20 20 72 63  _OPEN_WAL);.  rc
c4a0: 20 3d 20 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e   = sqlite3OsOpen
c4b0: 28 70 56 66 73 2c 20 7a 57 61 6c 4e 61 6d 65 2c  (pVfs, zWalName,
c4c0: 20 70 52 65 74 2d 3e 70 57 61 6c 46 64 2c 20 66   pRet->pWalFd, f
c4d0: 6c 61 67 73 2c 20 26 66 6c 61 67 73 29 3b 0a 20  lags, &flags);. 
c4e0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
c4f0: 4f 4b 20 26 26 20 66 6c 61 67 73 26 53 51 4c 49  OK && flags&SQLI
c500: 54 45 5f 4f 50 45 4e 5f 52 45 41 44 4f 4e 4c 59  TE_OPEN_READONLY
c510: 20 29 7b 0a 20 20 20 20 70 52 65 74 2d 3e 72 65   ){.    pRet->re
c520: 61 64 4f 6e 6c 79 20 3d 20 31 3b 0a 20 20 7d 0a  adOnly = 1;.  }.
c530: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
c540: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49  E_OK ){.    walI
c550: 6e 64 65 78 43 6c 6f 73 65 28 70 52 65 74 2c 20  ndexClose(pRet, 
c560: 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f  0);.    sqlite3O
c570: 73 43 6c 6f 73 65 28 70 52 65 74 2d 3e 70 57 61  sClose(pRet->pWa
c580: 6c 46 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  lFd);.    sqlite
c590: 33 5f 66 72 65 65 28 70 52 65 74 29 3b 0a 20 20  3_free(pRet);.  
c5a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 70 57 61  }else{.    *ppWa
c5b0: 6c 20 3d 20 70 52 65 74 3b 0a 20 20 20 20 57 41  l = pRet;.    WA
c5c0: 4c 54 52 41 43 45 28 28 22 57 41 4c 25 64 3a 20  LTRACE(("WAL%d: 
c5d0: 6f 70 65 6e 65 64 5c 6e 22 2c 20 70 52 65 74 29  opened\n", pRet)
c5e0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
c5f0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e  rc;.}../*.** Fin
c600: 64 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70  d the smallest p
c610: 61 67 65 20 6e 75 6d 62 65 72 20 6f 75 74 20 6f  age number out o
c620: 66 20 61 6c 6c 20 70 61 67 65 73 20 68 65 6c 64  f all pages held
c630: 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68 61 74   in the WAL that
c640: 0a 2a 2a 20 68 61 73 20 6e 6f 74 20 62 65 65 6e  .** has not been
c650: 20 72 65 74 75 72 6e 65 64 20 62 79 20 61 6e 79   returned by any
c660: 20 70 72 69 6f 72 20 69 6e 76 6f 63 61 74 69 6f   prior invocatio
c670: 6e 20 6f 66 20 74 68 69 73 20 6d 65 74 68 6f 64  n of this method
c680: 20 6f 6e 20 74 68 65 0a 2a 2a 20 73 61 6d 65 20   on the.** same 
c690: 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65  WalIterator obje
c6a0: 63 74 2e 20 20 20 57 72 69 74 65 20 69 6e 74 6f  ct.   Write into
c6b0: 20 2a 70 69 46 72 61 6d 65 20 74 68 65 20 66 72   *piFrame the fr
c6c0: 61 6d 65 20 69 6e 64 65 78 20 77 68 65 72 65 0a  ame index where.
c6d0: 2a 2a 20 74 68 61 74 20 70 61 67 65 20 77 61 73  ** that page was
c6e0: 20 6c 61 73 74 20 77 72 69 74 74 65 6e 20 69 6e   last written in
c6f0: 74 6f 20 74 68 65 20 57 41 4c 2e 20 20 57 72 69  to the WAL.  Wri
c700: 74 65 20 69 6e 74 6f 20 2a 70 69 50 61 67 65 20  te into *piPage 
c710: 74 68 65 20 70 61 67 65 0a 2a 2a 20 6e 75 6d 62  the page.** numb
c720: 65 72 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e  er..**.** Return
c730: 20 30 20 6f 6e 20 73 75 63 63 65 73 73 2e 20 20   0 on success.  
c740: 49 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20  If there are no 
c750: 70 61 67 65 73 20 69 6e 20 74 68 65 20 57 41 4c  pages in the WAL
c760: 20 77 69 74 68 20 61 20 70 61 67 65 0a 2a 2a 20   with a page.** 
c770: 6e 75 6d 62 65 72 20 6c 61 72 67 65 72 20 74 68  number larger th
c780: 61 6e 20 2a 70 69 50 61 67 65 2c 20 74 68 65 6e  an *piPage, then
c790: 20 72 65 74 75 72 6e 20 31 2e 0a 2a 2f 0a 73 74   return 1..*/.st
c7a0: 61 74 69 63 20 69 6e 74 20 77 61 6c 49 74 65 72  atic int walIter
c7b0: 61 74 6f 72 4e 65 78 74 28 0a 20 20 57 61 6c 49  atorNext(.  WalI
c7c0: 74 65 72 61 74 6f 72 20 2a 70 2c 20 20 20 20 20  terator *p,     
c7d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65            /* Ite
c7e0: 72 61 74 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a  rator */.  u32 *
c7f0: 70 69 50 61 67 65 2c 20 20 20 20 20 20 20 20 20  piPage,         
c800: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
c810: 20 54 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72   The page number
c820: 20 6f 66 20 74 68 65 20 6e 65 78 74 20 70 61 67   of the next pag
c830: 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 46 72  e */.  u32 *piFr
c840: 61 6d 65 20 20 20 20 20 20 20 20 20 20 20 20 20  ame             
c850: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 57 61 6c       /* OUT: Wal
c860: 20 66 72 61 6d 65 20 69 6e 64 65 78 20 6f 66 20   frame index of 
c870: 6e 65 78 74 20 70 61 67 65 20 2a 2f 0a 29 7b 0a  next page */.){.
c880: 20 20 75 33 32 20 69 4d 69 6e 3b 20 20 20 20 20    u32 iMin;     
c890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c8a0: 2f 2a 20 52 65 73 75 6c 74 20 70 67 6e 6f 20 6d  /* Result pgno m
c8b0: 75 73 74 20 62 65 20 67 72 65 61 74 65 72 20 74  ust be greater t
c8c0: 68 61 6e 20 69 4d 69 6e 20 2a 2f 0a 20 20 75 33  han iMin */.  u3
c8d0: 32 20 69 52 65 74 20 3d 20 30 78 46 46 46 46 46  2 iRet = 0xFFFFF
c8e0: 46 46 46 3b 20 20 20 20 20 20 20 20 2f 2a 20 30  FFF;        /* 0
c8f0: 78 66 66 66 66 66 66 66 66 20 69 73 20 6e 65 76  xffffffff is nev
c900: 65 72 20 61 20 76 61 6c 69 64 20 70 61 67 65 20  er a valid page 
c910: 6e 75 6d 62 65 72 20 2a 2f 0a 20 20 69 6e 74 20  number */.  int 
c920: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
c930: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72            /* For
c940: 20 6c 6f 6f 70 69 6e 67 20 74 68 72 6f 75 67 68   looping through
c950: 20 73 65 67 6d 65 6e 74 73 20 2a 2f 0a 0a 20 20   segments */..  
c960: 69 4d 69 6e 20 3d 20 70 2d 3e 69 50 72 69 6f 72  iMin = p->iPrior
c970: 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4d 69 6e  ;.  assert( iMin
c980: 3c 30 78 66 66 66 66 66 66 66 66 20 29 3b 0a 20  <0xffffffff );. 
c990: 20 66 6f 72 28 69 3d 70 2d 3e 6e 53 65 67 6d 65   for(i=p->nSegme
c9a0: 6e 74 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29  nt-1; i>=0; i--)
c9b0: 7b 0a 20 20 20 20 73 74 72 75 63 74 20 57 61 6c  {.    struct Wal
c9c0: 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 6d 65 6e  Segment *pSegmen
c9d0: 74 20 3d 20 26 70 2d 3e 61 53 65 67 6d 65 6e 74  t = &p->aSegment
c9e0: 5b 69 5d 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  [i];.    while( 
c9f0: 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 3c  pSegment->iNext<
ca00: 70 53 65 67 6d 65 6e 74 2d 3e 6e 45 6e 74 72 79  pSegment->nEntry
ca10: 20 29 7b 0a 20 20 20 20 20 20 75 33 32 20 69 50   ){.      u32 iP
ca20: 67 20 3d 20 70 53 65 67 6d 65 6e 74 2d 3e 61 50  g = pSegment->aP
ca30: 67 6e 6f 5b 70 53 65 67 6d 65 6e 74 2d 3e 61 49  gno[pSegment->aI
ca40: 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69  ndex[pSegment->i
ca50: 4e 65 78 74 5d 5d 3b 0a 20 20 20 20 20 20 69 66  Next]];.      if
ca60: 28 20 69 50 67 3e 69 4d 69 6e 20 29 7b 0a 20 20  ( iPg>iMin ){.  
ca70: 20 20 20 20 20 20 69 66 28 20 69 50 67 3c 69 52        if( iPg<iR
ca80: 65 74 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  et ){.          
ca90: 69 52 65 74 20 3d 20 69 50 67 3b 0a 20 20 20 20  iRet = iPg;.    
caa0: 20 20 20 20 20 20 2a 70 69 46 72 61 6d 65 20 3d        *piFrame =
cab0: 20 70 53 65 67 6d 65 6e 74 2d 3e 69 5a 65 72 6f   pSegment->iZero
cac0: 20 2b 20 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e   + pSegment->aIn
cad0: 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e  dex[pSegment->iN
cae0: 65 78 74 5d 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ext];.        }.
caf0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
cb00: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 53 65       }.      pSe
cb10: 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 2b 2b 3b 0a  gment->iNext++;.
cb20: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 69      }.  }..  *pi
cb30: 50 61 67 65 20 3d 20 70 2d 3e 69 50 72 69 6f 72  Page = p->iPrior
cb40: 20 3d 20 69 52 65 74 3b 0a 20 20 72 65 74 75 72   = iRet;.  retur
cb50: 6e 20 28 69 52 65 74 3d 3d 30 78 46 46 46 46 46  n (iRet==0xFFFFF
cb60: 46 46 46 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  FFF);.}../*.** T
cb70: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d 65 72  his function mer
cb80: 67 65 73 20 74 77 6f 20 73 6f 72 74 65 64 20 6c  ges two sorted l
cb90: 69 73 74 73 20 69 6e 74 6f 20 61 20 73 69 6e 67  ists into a sing
cba0: 6c 65 20 73 6f 72 74 65 64 20 6c 69 73 74 2e 0a  le sorted list..
cbb0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
cbc0: 61 6c 4d 65 72 67 65 28 0a 20 20 75 33 32 20 2a  alMerge(.  u32 *
cbd0: 61 43 6f 6e 74 65 6e 74 2c 20 20 20 20 20 20 20  aContent,       
cbe0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
cbf0: 67 65 73 20 69 6e 20 77 61 6c 20 2a 2f 0a 20 20  ges in wal */.  
cc00: 68 74 5f 73 6c 6f 74 20 2a 61 4c 65 66 74 2c 20  ht_slot *aLeft, 
cc10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cc20: 2f 2a 20 49 4e 3a 20 4c 65 66 74 20 68 61 6e 64  /* IN: Left hand
cc30: 20 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20   input list */. 
cc40: 20 69 6e 74 20 6e 4c 65 66 74 2c 20 20 20 20 20   int nLeft,     
cc50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cc60: 20 2f 2a 20 49 4e 3a 20 45 6c 65 6d 65 6e 74 73   /* IN: Elements
cc70: 20 69 6e 20 61 72 72 61 79 20 2a 70 61 4c 65 66   in array *paLef
cc80: 74 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a  t */.  ht_slot *
cc90: 2a 70 61 52 69 67 68 74 2c 20 20 20 20 20 20 20  *paRight,       
cca0: 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54         /* IN/OUT
ccb0: 3a 20 52 69 67 68 74 20 68 61 6e 64 20 69 6e 70  : Right hand inp
ccc0: 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74  ut list */.  int
ccd0: 20 2a 70 6e 52 69 67 68 74 2c 20 20 20 20 20 20   *pnRight,      
cce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
ccf0: 49 4e 2f 4f 55 54 3a 20 45 6c 65 6d 65 6e 74 73  IN/OUT: Elements
cd00: 20 69 6e 20 2a 70 61 52 69 67 68 74 20 2a 2f 0a   in *paRight */.
cd10: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 54 6d 70 20    ht_slot *aTmp 
cd20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cd30: 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62    /* Temporary b
cd40: 75 66 66 65 72 20 2a 2f 0a 29 7b 0a 20 20 69 6e  uffer */.){.  in
cd50: 74 20 69 4c 65 66 74 20 3d 20 30 3b 20 20 20 20  t iLeft = 0;    
cd60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
cd70: 20 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69   Current index i
cd80: 6e 20 61 4c 65 66 74 20 2a 2f 0a 20 20 69 6e 74  n aLeft */.  int
cd90: 20 69 52 69 67 68 74 20 3d 20 30 3b 20 20 20 20   iRight = 0;    
cda0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
cdb0: 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e  Current index in
cdc0: 20 61 52 69 67 68 74 20 2a 2f 0a 20 20 69 6e 74   aRight */.  int
cdd0: 20 69 4f 75 74 20 3d 20 30 3b 20 20 20 20 20 20   iOut = 0;      
cde0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
cdf0: 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e  Current index in
ce00: 20 6f 75 74 70 75 74 20 62 75 66 66 65 72 20 2a   output buffer *
ce10: 2f 0a 20 20 69 6e 74 20 6e 52 69 67 68 74 20 3d  /.  int nRight =
ce20: 20 2a 70 6e 52 69 67 68 74 3b 0a 20 20 68 74 5f   *pnRight;.  ht_
ce30: 73 6c 6f 74 20 2a 61 52 69 67 68 74 20 3d 20 2a  slot *aRight = *
ce40: 70 61 52 69 67 68 74 3b 0a 0a 20 20 61 73 73 65  paRight;..  asse
ce50: 72 74 28 20 6e 4c 65 66 74 3e 30 20 26 26 20 6e  rt( nLeft>0 && n
ce60: 52 69 67 68 74 3e 30 20 29 3b 0a 20 20 77 68 69  Right>0 );.  whi
ce70: 6c 65 28 20 69 52 69 67 68 74 3c 6e 52 69 67 68  le( iRight<nRigh
ce80: 74 20 7c 7c 20 69 4c 65 66 74 3c 6e 4c 65 66 74  t || iLeft<nLeft
ce90: 20 29 7b 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20   ){.    ht_slot 
cea0: 6c 6f 67 70 61 67 65 3b 0a 20 20 20 20 50 67 6e  logpage;.    Pgn
ceb0: 6f 20 64 62 70 61 67 65 3b 0a 0a 20 20 20 20 69  o dbpage;..    i
cec0: 66 28 20 28 69 4c 65 66 74 3c 6e 4c 65 66 74 29  f( (iLeft<nLeft)
ced0: 20 0a 20 20 20 20 20 26 26 20 28 69 52 69 67 68   .     && (iRigh
cee0: 74 3e 3d 6e 52 69 67 68 74 20 7c 7c 20 61 43 6f  t>=nRight || aCo
cef0: 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66  ntent[aLeft[iLef
cf00: 74 5d 5d 3c 61 43 6f 6e 74 65 6e 74 5b 61 52 69  t]]<aContent[aRi
cf10: 67 68 74 5b 69 52 69 67 68 74 5d 5d 29 0a 20 20  ght[iRight]]).  
cf20: 20 20 29 7b 0a 20 20 20 20 20 20 6c 6f 67 70 61    ){.      logpa
cf30: 67 65 20 3d 20 61 4c 65 66 74 5b 69 4c 65 66 74  ge = aLeft[iLeft
cf40: 2b 2b 5d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  ++];.    }else{.
cf50: 20 20 20 20 20 20 6c 6f 67 70 61 67 65 20 3d 20        logpage = 
cf60: 61 52 69 67 68 74 5b 69 52 69 67 68 74 2b 2b 5d  aRight[iRight++]
cf70: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64 62 70 61  ;.    }.    dbpa
cf80: 67 65 20 3d 20 61 43 6f 6e 74 65 6e 74 5b 6c 6f  ge = aContent[lo
cf90: 67 70 61 67 65 5d 3b 0a 0a 20 20 20 20 61 54 6d  gpage];..    aTm
cfa0: 70 5b 69 4f 75 74 2b 2b 5d 20 3d 20 6c 6f 67 70  p[iOut++] = logp
cfb0: 61 67 65 3b 0a 20 20 20 20 69 66 28 20 69 4c 65  age;.    if( iLe
cfc0: 66 74 3c 6e 4c 65 66 74 20 26 26 20 61 43 6f 6e  ft<nLeft && aCon
cfd0: 74 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74  tent[aLeft[iLeft
cfe0: 5d 5d 3d 3d 64 62 70 61 67 65 20 29 20 69 4c 65  ]]==dbpage ) iLe
cff0: 66 74 2b 2b 3b 0a 0a 20 20 20 20 61 73 73 65 72  ft++;..    asser
d000: 74 28 20 69 4c 65 66 74 3e 3d 6e 4c 65 66 74 20  t( iLeft>=nLeft 
d010: 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66  || aContent[aLef
d020: 74 5b 69 4c 65 66 74 5d 5d 3e 64 62 70 61 67 65  t[iLeft]]>dbpage
d030: 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20   );.    assert( 
d040: 69 52 69 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c  iRight>=nRight |
d050: 7c 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68  | aContent[aRigh
d060: 74 5b 69 52 69 67 68 74 5d 5d 3e 64 62 70 61 67  t[iRight]]>dbpag
d070: 65 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 61 52  e );.  }..  *paR
d080: 69 67 68 74 20 3d 20 61 4c 65 66 74 3b 0a 20 20  ight = aLeft;.  
d090: 2a 70 6e 52 69 67 68 74 20 3d 20 69 4f 75 74 3b  *pnRight = iOut;
d0a0: 0a 20 20 6d 65 6d 63 70 79 28 61 4c 65 66 74 2c  .  memcpy(aLeft,
d0b0: 20 61 54 6d 70 2c 20 73 69 7a 65 6f 66 28 61 54   aTmp, sizeof(aT
d0c0: 6d 70 5b 30 5d 29 2a 69 4f 75 74 29 3b 0a 7d 0a  mp[0])*iOut);.}.
d0d0: 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74 68 65 20  ./*.** Sort the 
d0e0: 65 6c 65 6d 65 6e 74 73 20 69 6e 20 6c 69 73 74  elements in list
d0f0: 20 61 4c 69 73 74 2c 20 72 65 6d 6f 76 69 6e 67   aList, removing
d100: 20 61 6e 79 20 64 75 70 6c 69 63 61 74 65 73 2e   any duplicates.
d110: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
d120: 77 61 6c 4d 65 72 67 65 73 6f 72 74 28 0a 20 20  walMergesort(.  
d130: 75 33 32 20 2a 61 43 6f 6e 74 65 6e 74 2c 20 20  u32 *aContent,  
d140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d150: 2f 2a 20 50 61 67 65 73 20 69 6e 20 77 61 6c 20  /* Pages in wal 
d160: 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 42  */.  ht_slot *aB
d170: 75 66 66 65 72 2c 20 20 20 20 20 20 20 20 20 20  uffer,          
d180: 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 6f       /* Buffer o
d190: 66 20 61 74 20 6c 65 61 73 74 20 2a 70 6e 4c 69  f at least *pnLi
d1a0: 73 74 20 69 74 65 6d 73 20 74 6f 20 75 73 65 20  st items to use 
d1b0: 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c  */.  ht_slot *aL
d1c0: 69 73 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  ist,            
d1d0: 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20       /* IN/OUT: 
d1e0: 4c 69 73 74 20 74 6f 20 73 6f 72 74 20 2a 2f 0a  List to sort */.
d1f0: 20 20 69 6e 74 20 2a 70 6e 4c 69 73 74 20 20 20    int *pnList   
d200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d210: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4e 75 6d    /* IN/OUT: Num
d220: 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20  ber of elements 
d230: 69 6e 20 61 4c 69 73 74 5b 5d 20 2a 2f 0a 29 7b  in aList[] */.){
d240: 0a 20 20 73 74 72 75 63 74 20 53 75 62 6c 69 73  .  struct Sublis
d250: 74 20 7b 0a 20 20 20 20 69 6e 74 20 6e 4c 69 73  t {.    int nLis
d260: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
d270: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
d280: 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61  of elements in a
d290: 4c 69 73 74 20 2a 2f 0a 20 20 20 20 68 74 5f 73  List */.    ht_s
d2a0: 6c 6f 74 20 2a 61 4c 69 73 74 3b 20 20 20 20 20  lot *aList;     
d2b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
d2c0: 6e 74 65 72 20 74 6f 20 73 75 62 2d 6c 69 73 74  nter to sub-list
d2d0: 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 7d 3b   content */.  };
d2e0: 0a 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20 6e 4c  ..  const int nL
d2f0: 69 73 74 20 3d 20 2a 70 6e 4c 69 73 74 3b 20 20  ist = *pnList;  
d300: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 69      /* Size of i
d310: 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69  nput list */.  i
d320: 6e 74 20 6e 4d 65 72 67 65 20 3d 20 30 3b 20 20  nt nMerge = 0;  
d330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
d340: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d  * Number of elem
d350: 65 6e 74 73 20 69 6e 20 6c 69 73 74 20 61 4d 65  ents in list aMe
d360: 72 67 65 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74  rge */.  ht_slot
d370: 20 2a 61 4d 65 72 67 65 20 3d 20 30 3b 20 20 20   *aMerge = 0;   
d380: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74           /* List
d390: 20 74 6f 20 62 65 20 6d 65 72 67 65 64 20 2a 2f   to be merged */
d3a0: 0a 20 20 69 6e 74 20 69 4c 69 73 74 3b 20 20 20  .  int iList;   
d3b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d3c0: 20 20 20 2f 2a 20 49 6e 64 65 78 20 69 6e 74 6f     /* Index into
d3d0: 20 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20   input list */. 
d3e0: 20 69 6e 74 20 69 53 75 62 20 3d 20 30 3b 20 20   int iSub = 0;  
d3f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d400: 20 2f 2a 20 49 6e 64 65 78 20 69 6e 74 6f 20 61   /* Index into a
d410: 53 75 62 20 61 72 72 61 79 20 2a 2f 0a 20 20 73  Sub array */.  s
d420: 74 72 75 63 74 20 53 75 62 6c 69 73 74 20 61 53  truct Sublist aS
d430: 75 62 5b 31 33 5d 3b 20 20 20 20 20 20 20 20 2f  ub[13];        /
d440: 2a 20 41 72 72 61 79 20 6f 66 20 73 75 62 2d 6c  * Array of sub-l
d450: 69 73 74 73 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65  ists */..  memse
d460: 74 28 61 53 75 62 2c 20 30 2c 20 73 69 7a 65 6f  t(aSub, 0, sizeo
d470: 66 28 61 53 75 62 29 29 3b 0a 20 20 61 73 73 65  f(aSub));.  asse
d480: 72 74 28 20 6e 4c 69 73 74 3c 3d 48 41 53 48 54  rt( nList<=HASHT
d490: 41 42 4c 45 5f 4e 50 41 47 45 20 26 26 20 6e 4c  ABLE_NPAGE && nL
d4a0: 69 73 74 3e 30 20 29 3b 0a 20 20 61 73 73 65 72  ist>0 );.  asser
d4b0: 74 28 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  t( HASHTABLE_NPA
d4c0: 47 45 3d 3d 28 31 3c 3c 28 41 72 72 61 79 53 69  GE==(1<<(ArraySi
d4d0: 7a 65 28 61 53 75 62 29 2d 31 29 29 20 29 3b 0a  ze(aSub)-1)) );.
d4e0: 0a 20 20 66 6f 72 28 69 4c 69 73 74 3d 30 3b 20  .  for(iList=0; 
d4f0: 69 4c 69 73 74 3c 6e 4c 69 73 74 3b 20 69 4c 69  iList<nList; iLi
d500: 73 74 2b 2b 29 7b 0a 20 20 20 20 6e 4d 65 72 67  st++){.    nMerg
d510: 65 20 3d 20 31 3b 0a 20 20 20 20 61 4d 65 72 67  e = 1;.    aMerg
d520: 65 20 3d 20 26 61 4c 69 73 74 5b 69 4c 69 73 74  e = &aList[iList
d530: 5d 3b 0a 20 20 20 20 66 6f 72 28 69 53 75 62 3d  ];.    for(iSub=
d540: 30 3b 20 69 4c 69 73 74 20 26 20 28 31 3c 3c 69  0; iList & (1<<i
d550: 53 75 62 29 3b 20 69 53 75 62 2b 2b 29 7b 0a 20  Sub); iSub++){. 
d560: 20 20 20 20 20 73 74 72 75 63 74 20 53 75 62 6c       struct Subl
d570: 69 73 74 20 2a 70 20 3d 20 26 61 53 75 62 5b 69  ist *p = &aSub[i
d580: 53 75 62 5d 3b 0a 20 20 20 20 20 20 61 73 73 65  Sub];.      asse
d590: 72 74 28 20 70 2d 3e 61 4c 69 73 74 20 26 26 20  rt( p->aList && 
d5a0: 70 2d 3e 6e 4c 69 73 74 3c 3d 28 31 3c 3c 69 53  p->nList<=(1<<iS
d5b0: 75 62 29 20 29 3b 0a 20 20 20 20 20 20 61 73 73  ub) );.      ass
d5c0: 65 72 74 28 20 70 2d 3e 61 4c 69 73 74 3d 3d 26  ert( p->aList==&
d5d0: 61 4c 69 73 74 5b 69 4c 69 73 74 26 7e 28 28 32  aList[iList&~((2
d5e0: 3c 3c 69 53 75 62 29 2d 31 29 5d 20 29 3b 0a 20  <<iSub)-1)] );. 
d5f0: 20 20 20 20 20 77 61 6c 4d 65 72 67 65 28 61 43       walMerge(aC
d600: 6f 6e 74 65 6e 74 2c 20 70 2d 3e 61 4c 69 73 74  ontent, p->aList
d610: 2c 20 70 2d 3e 6e 4c 69 73 74 2c 20 26 61 4d 65  , p->nList, &aMe
d620: 72 67 65 2c 20 26 6e 4d 65 72 67 65 2c 20 61 42  rge, &nMerge, aB
d630: 75 66 66 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20  uffer);.    }.  
d640: 20 20 61 53 75 62 5b 69 53 75 62 5d 2e 61 4c 69    aSub[iSub].aLi
d650: 73 74 20 3d 20 61 4d 65 72 67 65 3b 0a 20 20 20  st = aMerge;.   
d660: 20 61 53 75 62 5b 69 53 75 62 5d 2e 6e 4c 69 73   aSub[iSub].nLis
d670: 74 20 3d 20 6e 4d 65 72 67 65 3b 0a 20 20 7d 0a  t = nMerge;.  }.
d680: 0a 20 20 66 6f 72 28 69 53 75 62 2b 2b 3b 20 69  .  for(iSub++; i
d690: 53 75 62 3c 41 72 72 61 79 53 69 7a 65 28 61 53  Sub<ArraySize(aS
d6a0: 75 62 29 3b 20 69 53 75 62 2b 2b 29 7b 0a 20 20  ub); iSub++){.  
d6b0: 20 20 69 66 28 20 6e 4c 69 73 74 20 26 20 28 31    if( nList & (1
d6c0: 3c 3c 69 53 75 62 29 20 29 7b 0a 20 20 20 20 20  <<iSub) ){.     
d6d0: 20 73 74 72 75 63 74 20 53 75 62 6c 69 73 74 20   struct Sublist 
d6e0: 2a 70 20 3d 20 26 61 53 75 62 5b 69 53 75 62 5d  *p = &aSub[iSub]
d6f0: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
d700: 70 2d 3e 6e 4c 69 73 74 3c 3d 28 31 3c 3c 69 53  p->nList<=(1<<iS
d710: 75 62 29 20 29 3b 0a 20 20 20 20 20 20 61 73 73  ub) );.      ass
d720: 65 72 74 28 20 70 2d 3e 61 4c 69 73 74 3d 3d 26  ert( p->aList==&
d730: 61 4c 69 73 74 5b 6e 4c 69 73 74 26 7e 28 28 32  aList[nList&~((2
d740: 3c 3c 69 53 75 62 29 2d 31 29 5d 20 29 3b 0a 20  <<iSub)-1)] );. 
d750: 20 20 20 20 20 77 61 6c 4d 65 72 67 65 28 61 43       walMerge(aC
d760: 6f 6e 74 65 6e 74 2c 20 70 2d 3e 61 4c 69 73 74  ontent, p->aList
d770: 2c 20 70 2d 3e 6e 4c 69 73 74 2c 20 26 61 4d 65  , p->nList, &aMe
d780: 72 67 65 2c 20 26 6e 4d 65 72 67 65 2c 20 61 42  rge, &nMerge, aB
d790: 75 66 66 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20  uffer);.    }.  
d7a0: 7d 0a 20 20 61 73 73 65 72 74 28 20 61 4d 65 72  }.  assert( aMer
d7b0: 67 65 3d 3d 61 4c 69 73 74 20 29 3b 0a 20 20 2a  ge==aList );.  *
d7c0: 70 6e 4c 69 73 74 20 3d 20 6e 4d 65 72 67 65 3b  pnList = nMerge;
d7d0: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
d7e0: 44 45 42 55 47 0a 20 20 7b 0a 20 20 20 20 69 6e  DEBUG.  {.    in
d7f0: 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31  t i;.    for(i=1
d800: 3b 20 69 3c 2a 70 6e 4c 69 73 74 3b 20 69 2b 2b  ; i<*pnList; i++
d810: 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  ){.      assert(
d820: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b   aContent[aList[
d830: 69 5d 5d 20 3e 20 61 43 6f 6e 74 65 6e 74 5b 61  i]] > aContent[a
d840: 4c 69 73 74 5b 69 2d 31 5d 5d 20 29 3b 0a 20 20  List[i-1]] );.  
d850: 20 20 7d 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 7d    }.  }.#endif.}
d860: 0a 0a 2f 2a 20 0a 2a 2a 20 46 72 65 65 20 61 6e  ../* .** Free an
d870: 20 69 74 65 72 61 74 6f 72 20 61 6c 6c 6f 63 61   iterator alloca
d880: 74 65 64 20 62 79 20 77 61 6c 49 74 65 72 61 74  ted by walIterat
d890: 6f 72 49 6e 69 74 28 29 2e 0a 2a 2f 0a 73 74 61  orInit()..*/.sta
d8a0: 74 69 63 20 76 6f 69 64 20 77 61 6c 49 74 65 72  tic void walIter
d8b0: 61 74 6f 72 46 72 65 65 28 57 61 6c 49 74 65 72  atorFree(WalIter
d8c0: 61 74 6f 72 20 2a 70 29 7b 0a 20 20 73 71 6c 69  ator *p){.  sqli
d8d0: 74 65 33 53 63 72 61 74 63 68 46 72 65 65 28 70  te3ScratchFree(p
d8e0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73  );.}../*.** Cons
d8f0: 74 72 75 63 74 20 61 20 57 61 6c 49 6e 74 65 72  truct a WalInter
d900: 61 74 6f 72 20 6f 62 6a 65 63 74 20 74 68 61 74  ator object that
d910: 20 63 61 6e 20 62 65 20 75 73 65 64 20 74 6f 20   can be used to 
d920: 6c 6f 6f 70 20 6f 76 65 72 20 61 6c 6c 20 0a 2a  loop over all .*
d930: 2a 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 57  * pages in the W
d940: 41 4c 20 69 6e 20 61 73 63 65 6e 64 69 6e 67 20  AL in ascending 
d950: 6f 72 64 65 72 2e 20 54 68 65 20 63 61 6c 6c 65  order. The calle
d960: 72 20 6d 75 73 74 20 68 6f 6c 64 20 74 68 65 20  r must hold the 
d970: 63 68 65 63 6b 70 6f 69 6e 74 0a 2a 2a 0a 2a 2a  checkpoint.**.**
d980: 20 4f 6e 20 73 75 63 63 65 73 73 2c 20 6d 61 6b   On success, mak
d990: 65 20 2a 70 70 20 70 6f 69 6e 74 20 74 6f 20 74  e *pp point to t
d9a0: 68 65 20 6e 65 77 6c 79 20 61 6c 6c 6f 63 61 74  he newly allocat
d9b0: 65 64 20 57 61 6c 49 6e 74 65 72 61 74 6f 72 20  ed WalInterator 
d9c0: 6f 62 6a 65 63 74 0a 2a 2a 20 72 65 74 75 72 6e  object.** return
d9d0: 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f 74 68 65   SQLITE_OK. Othe
d9e0: 72 77 69 73 65 2c 20 72 65 74 75 72 6e 20 61 6e  rwise, return an
d9f0: 20 65 72 72 6f 72 20 63 6f 64 65 2e 20 49 66 20   error code. If 
da00: 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20  this routine.** 
da10: 72 65 74 75 72 6e 73 20 61 6e 20 65 72 72 6f 72  returns an error
da20: 2c 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 2a  , the value of *
da30: 70 70 20 69 73 20 75 6e 64 65 66 69 6e 65 64 2e  pp is undefined.
da40: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 69  .**.** The calli
da50: 6e 67 20 72 6f 75 74 69 6e 65 20 73 68 6f 75 6c  ng routine shoul
da60: 64 20 69 6e 76 6f 6b 65 20 77 61 6c 49 74 65 72  d invoke walIter
da70: 61 74 6f 72 46 72 65 65 28 29 20 74 6f 20 64 65  atorFree() to de
da80: 73 74 72 6f 79 20 74 68 65 0a 2a 2a 20 57 61 6c  stroy the.** Wal
da90: 49 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 20  Iterator object 
daa0: 77 68 65 6e 20 69 74 20 68 61 73 20 66 69 6e 69  when it has fini
dab0: 73 68 65 64 20 77 69 74 68 20 69 74 2e 0a 2a 2f  shed with it..*/
dac0: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49  .static int walI
dad0: 74 65 72 61 74 6f 72 49 6e 69 74 28 57 61 6c 20  teratorInit(Wal 
dae0: 2a 70 57 61 6c 2c 20 57 61 6c 49 74 65 72 61 74  *pWal, WalIterat
daf0: 6f 72 20 2a 2a 70 70 29 7b 0a 20 20 57 61 6c 49  or **pp){.  WalI
db00: 74 65 72 61 74 6f 72 20 2a 70 3b 20 20 20 20 20  terator *p;     
db10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
db20: 65 74 75 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 20  eturn value */. 
db30: 20 69 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20   int nSegment;  
db40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
db50: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 65   /* Number of se
db60: 67 6d 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20  gments to merge 
db70: 2a 2f 0a 20 20 75 33 32 20 69 4c 61 73 74 3b 20  */.  u32 iLast; 
db80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
db90: 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 66 72 61       /* Last fra
dba0: 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20 69  me in log */.  i
dbb0: 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20  nt nByte;       
dbc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
dbd0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
dbe0: 73 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f  s to allocate */
dbf0: 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
dc00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dc10: 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 76     /* Iterator v
dc20: 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 68 74 5f  ariable */.  ht_
dc30: 73 6c 6f 74 20 2a 61 54 6d 70 3b 20 20 20 20 20  slot *aTmp;     
dc40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
dc50: 54 65 6d 70 20 73 70 61 63 65 20 75 73 65 64 20  Temp space used 
dc60: 62 79 20 6d 65 72 67 65 2d 73 6f 72 74 20 2a 2f  by merge-sort */
dc70: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
dc80: 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20  TE_OK;          
dc90: 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64     /* Return Cod
dca0: 65 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 69 73 20  e */..  /* This 
dcb0: 72 6f 75 74 69 6e 65 20 6f 6e 6c 79 20 72 75 6e  routine only run
dcc0: 73 20 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67 20  s while holding 
dcd0: 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 6c  the checkpoint l
dce0: 6f 63 6b 2e 20 41 6e 64 0a 20 20 2a 2a 20 69 74  ock. And.  ** it
dcf0: 20 6f 6e 6c 79 20 72 75 6e 73 20 69 66 20 74 68   only runs if th
dd00: 65 72 65 20 69 73 20 61 63 74 75 61 6c 6c 79 20  ere is actually 
dd10: 63 6f 6e 74 65 6e 74 20 69 6e 20 74 68 65 20 6c  content in the l
dd20: 6f 67 20 28 6d 78 46 72 61 6d 65 3e 30 29 2e 0a  og (mxFrame>0)..
dd30: 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
dd40: 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20 26 26  Wal->ckptLock &&
dd50: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
dd60: 6d 65 3e 30 20 29 3b 0a 20 20 69 4c 61 73 74 20  me>0 );.  iLast 
dd70: 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  = pWal->hdr.mxFr
dd80: 61 6d 65 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63  ame;..  /* Alloc
dd90: 61 74 65 20 73 70 61 63 65 20 66 6f 72 20 74 68  ate space for th
dda0: 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62  e WalIterator ob
ddb0: 6a 65 63 74 2e 20 2a 2f 0a 20 20 6e 53 65 67 6d  ject. */.  nSegm
ddc0: 65 6e 74 20 3d 20 77 61 6c 46 72 61 6d 65 50 61  ent = walFramePa
ddd0: 67 65 28 69 4c 61 73 74 29 20 2b 20 31 3b 0a 20  ge(iLast) + 1;. 
dde0: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
ddf0: 57 61 6c 49 74 65 72 61 74 6f 72 29 20 0a 20 20  WalIterator) .  
de00: 20 20 20 20 20 20 2b 20 28 6e 53 65 67 6d 65 6e        + (nSegmen
de10: 74 2d 31 29 2a 73 69 7a 65 6f 66 28 73 74 72 75  t-1)*sizeof(stru
de20: 63 74 20 57 61 6c 53 65 67 6d 65 6e 74 29 0a 20  ct WalSegment). 
de30: 20 20 20 20 20 20 20 2b 20 69 4c 61 73 74 2a 73         + iLast*s
de40: 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 3b 0a  izeof(ht_slot);.
de50: 20 20 70 20 3d 20 28 57 61 6c 49 74 65 72 61 74    p = (WalIterat
de60: 6f 72 20 2a 29 73 71 6c 69 74 65 33 53 63 72 61  or *)sqlite3Scra
de70: 74 63 68 4d 61 6c 6c 6f 63 28 6e 42 79 74 65 29  tchMalloc(nByte)
de80: 3b 0a 20 20 69 66 28 20 21 70 20 29 7b 0a 20 20  ;.  if( !p ){.  
de90: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
dea0: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 6d 65 6d  NOMEM;.  }.  mem
deb0: 73 65 74 28 70 2c 20 30 2c 20 6e 42 79 74 65 29  set(p, 0, nByte)
dec0: 3b 0a 20 20 70 2d 3e 6e 53 65 67 6d 65 6e 74 20  ;.  p->nSegment 
ded0: 3d 20 6e 53 65 67 6d 65 6e 74 3b 0a 0a 20 20 2f  = nSegment;..  /
dee0: 2a 20 41 6c 6c 6f 63 61 74 65 20 74 65 6d 70 6f  * Allocate tempo
def0: 72 61 72 79 20 73 70 61 63 65 20 75 73 65 64 20  rary space used 
df00: 62 79 20 74 68 65 20 6d 65 72 67 65 2d 73 6f 72  by the merge-sor
df10: 74 20 72 6f 75 74 69 6e 65 2e 20 54 68 69 73 20  t routine. This 
df20: 62 6c 6f 63 6b 0a 20 20 2a 2a 20 6f 66 20 6d 65  block.  ** of me
df30: 6d 6f 72 79 20 77 69 6c 6c 20 62 65 20 66 72 65  mory will be fre
df40: 65 64 20 62 65 66 6f 72 65 20 74 68 69 73 20 66  ed before this f
df50: 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e  unction returns.
df60: 0a 20 20 2a 2f 0a 20 20 61 54 6d 70 20 3d 20 28  .  */.  aTmp = (
df70: 68 74 5f 73 6c 6f 74 20 2a 29 73 71 6c 69 74 65  ht_slot *)sqlite
df80: 33 53 63 72 61 74 63 68 4d 61 6c 6c 6f 63 28 0a  3ScratchMalloc(.
df90: 20 20 20 20 20 20 73 69 7a 65 6f 66 28 68 74 5f        sizeof(ht_
dfa0: 73 6c 6f 74 29 20 2a 20 28 69 4c 61 73 74 3e 48  slot) * (iLast>H
dfb0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3f 48  ASHTABLE_NPAGE?H
dfc0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3a 69  ASHTABLE_NPAGE:i
dfd0: 4c 61 73 74 29 0a 20 20 29 3b 0a 20 20 69 66 28  Last).  );.  if(
dfe0: 20 21 61 54 6d 70 20 29 7b 0a 20 20 20 20 72 63   !aTmp ){.    rc
dff0: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
e000: 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 69 3d 30 3b  .  }..  for(i=0;
e010: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
e020: 26 20 69 3c 6e 53 65 67 6d 65 6e 74 3b 20 69 2b  & i<nSegment; i+
e030: 2b 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65  +){.    volatile
e040: 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b   ht_slot *aHash;
e050: 0a 20 20 20 20 75 33 32 20 69 5a 65 72 6f 3b 0a  .    u32 iZero;.
e060: 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32      volatile u32
e070: 20 2a 61 50 67 6e 6f 3b 0a 0a 20 20 20 20 72 63   *aPgno;..    rc
e080: 20 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70 57   = walHashGet(pW
e090: 61 6c 2c 20 69 2c 20 26 61 48 61 73 68 2c 20 26  al, i, &aHash, &
e0a0: 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a  aPgno, &iZero);.
e0b0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
e0c0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69  TE_OK ){.      i
e0d0: 6e 74 20 6a 3b 20 20 20 20 20 20 20 20 20 20 20  nt j;           
e0e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
e0f0: 75 6e 74 65 72 20 76 61 72 69 61 62 6c 65 20 2a  unter variable *
e100: 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 45 6e 74  /.      int nEnt
e110: 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ry;             
e120: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
e130: 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 69 73   entries in this
e140: 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 20 20 20 20   segment */.    
e150: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 49 6e 64 65    ht_slot *aInde
e160: 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  x;            /*
e170: 20 53 6f 72 74 65 64 20 69 6e 64 65 78 20 66 6f   Sorted index fo
e180: 72 20 74 68 69 73 20 73 65 67 6d 65 6e 74 20 2a  r this segment *
e190: 2f 0a 0a 20 20 20 20 20 20 61 50 67 6e 6f 2b 2b  /..      aPgno++
e1a0: 3b 0a 20 20 20 20 20 20 69 66 28 20 28 69 2b 31  ;.      if( (i+1
e1b0: 29 3d 3d 6e 53 65 67 6d 65 6e 74 20 29 7b 0a 20  )==nSegment ){. 
e1c0: 20 20 20 20 20 20 20 6e 45 6e 74 72 79 20 3d 20         nEntry = 
e1d0: 28 69 6e 74 29 28 69 4c 61 73 74 20 2d 20 69 5a  (int)(iLast - iZ
e1e0: 65 72 6f 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  ero);.      }els
e1f0: 65 7b 0a 20 20 20 20 20 20 20 20 6e 45 6e 74 72  e{.        nEntr
e200: 79 20 3d 20 28 69 6e 74 29 28 28 75 33 32 2a 29  y = (int)((u32*)
e210: 61 48 61 73 68 20 2d 20 28 75 33 32 2a 29 61 50  aHash - (u32*)aP
e220: 67 6e 6f 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  gno);.      }.  
e230: 20 20 20 20 61 49 6e 64 65 78 20 3d 20 26 28 28      aIndex = &((
e240: 68 74 5f 73 6c 6f 74 20 2a 29 26 70 2d 3e 61 53  ht_slot *)&p->aS
e250: 65 67 6d 65 6e 74 5b 70 2d 3e 6e 53 65 67 6d 65  egment[p->nSegme
e260: 6e 74 5d 29 5b 69 5a 65 72 6f 5d 3b 0a 20 20 20  nt])[iZero];.   
e270: 20 20 20 69 5a 65 72 6f 2b 2b 3b 0a 20 20 0a 20     iZero++;.  . 
e280: 20 20 20 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c       for(j=0; j<
e290: 6e 45 6e 74 72 79 3b 20 6a 2b 2b 29 7b 0a 20 20  nEntry; j++){.  
e2a0: 20 20 20 20 20 20 61 49 6e 64 65 78 5b 6a 5d 20        aIndex[j] 
e2b0: 3d 20 28 68 74 5f 73 6c 6f 74 29 6a 3b 0a 20 20  = (ht_slot)j;.  
e2c0: 20 20 20 20 7d 0a 20 20 20 20 20 20 77 61 6c 4d      }.      walM
e2d0: 65 72 67 65 73 6f 72 74 28 28 75 33 32 20 2a 29  ergesort((u32 *)
e2e0: 61 50 67 6e 6f 2c 20 61 54 6d 70 2c 20 61 49 6e  aPgno, aTmp, aIn
e2f0: 64 65 78 2c 20 26 6e 45 6e 74 72 79 29 3b 0a 20  dex, &nEntry);. 
e300: 20 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74       p->aSegment
e310: 5b 69 5d 2e 69 5a 65 72 6f 20 3d 20 69 5a 65 72  [i].iZero = iZer
e320: 6f 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65 67  o;.      p->aSeg
e330: 6d 65 6e 74 5b 69 5d 2e 6e 45 6e 74 72 79 20 3d  ment[i].nEntry =
e340: 20 6e 45 6e 74 72 79 3b 0a 20 20 20 20 20 20 70   nEntry;.      p
e350: 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 61 49  ->aSegment[i].aI
e360: 6e 64 65 78 20 3d 20 61 49 6e 64 65 78 3b 0a 20  ndex = aIndex;. 
e370: 20 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74       p->aSegment
e380: 5b 69 5d 2e 61 50 67 6e 6f 20 3d 20 28 75 33 32  [i].aPgno = (u32
e390: 20 2a 29 61 50 67 6e 6f 3b 0a 20 20 20 20 7d 0a   *)aPgno;.    }.
e3a0: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 53 63 72    }.  sqlite3Scr
e3b0: 61 74 63 68 46 72 65 65 28 61 54 6d 70 29 3b 0a  atchFree(aTmp);.
e3c0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
e3d0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49  E_OK ){.    walI
e3e0: 74 65 72 61 74 6f 72 46 72 65 65 28 70 29 3b 0a  teratorFree(p);.
e3f0: 20 20 7d 0a 20 20 2a 70 70 20 3d 20 70 3b 0a 20    }.  *pp = p;. 
e400: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
e410: 2a 0a 2a 2a 20 43 6f 70 79 20 61 73 20 6d 75 63  *.** Copy as muc
e420: 68 20 63 6f 6e 74 65 6e 74 20 61 73 20 77 65 20  h content as we 
e430: 63 61 6e 20 66 72 6f 6d 20 74 68 65 20 57 41 4c  can from the WAL
e440: 20 62 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64   back into the d
e450: 61 74 61 62 61 73 65 20 66 69 6c 65 0a 2a 2a 20  atabase file.** 
e460: 69 6e 20 72 65 73 70 6f 6e 73 65 20 74 6f 20 61  in response to a
e470: 6e 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68  n sqlite3_wal_ch
e480: 65 63 6b 70 6f 69 6e 74 28 29 20 72 65 71 75 65  eckpoint() reque
e490: 73 74 20 6f 72 20 74 68 65 20 65 71 75 69 76 61  st or the equiva
e4a0: 6c 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  lent..**.** The 
e4b0: 61 6d 6f 75 6e 74 20 6f 66 20 69 6e 66 6f 72 6d  amount of inform
e4c0: 61 74 69 6f 6e 20 63 6f 70 69 65 73 20 66 72 6f  ation copies fro
e4d0: 6d 20 57 41 4c 20 74 6f 20 64 61 74 61 62 61 73  m WAL to databas
e4e0: 65 20 6d 69 67 68 74 20 62 65 20 6c 69 6d 69 74  e might be limit
e4f0: 65 64 0a 2a 2a 20 62 79 20 61 63 74 69 76 65 20  ed.** by active 
e500: 72 65 61 64 65 72 73 2e 20 20 54 68 69 73 20 72  readers.  This r
e510: 6f 75 74 69 6e 65 20 77 69 6c 6c 20 6e 65 76 65  outine will neve
e520: 72 20 6f 76 65 72 77 72 69 74 65 20 61 20 64 61  r overwrite a da
e530: 74 61 62 61 73 65 20 70 61 67 65 0a 2a 2a 20 74  tabase page.** t
e540: 68 61 74 20 61 20 63 6f 6e 63 75 72 72 65 6e 74  hat a concurrent
e550: 20 72 65 61 64 65 72 20 6d 69 67 68 74 20 62 65   reader might be
e560: 20 75 73 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 41 6c   using..**.** Al
e570: 6c 20 49 2f 4f 20 62 61 72 72 69 65 72 20 6f 70  l I/O barrier op
e580: 65 72 61 74 69 6f 6e 73 20 28 61 2e 6b 2e 61 20  erations (a.k.a 
e590: 66 73 79 6e 63 73 29 20 6f 63 63 75 72 20 69 6e  fsyncs) occur in
e5a0: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 77 68   this routine wh
e5b0: 65 6e 0a 2a 2a 20 53 51 4c 69 74 65 20 69 73 20  en.** SQLite is 
e5c0: 69 6e 20 57 41 4c 2d 6d 6f 64 65 20 69 6e 20 73  in WAL-mode in s
e5d0: 79 6e 63 68 72 6f 6e 6f 75 73 3d 4e 4f 52 4d 41  ynchronous=NORMA
e5e0: 4c 2e 20 20 54 68 61 74 20 6d 65 61 6e 73 20 74  L.  That means t
e5f0: 68 61 74 20 69 66 20 0a 2a 2a 20 63 68 65 63 6b  hat if .** check
e600: 70 6f 69 6e 74 73 20 61 72 65 20 61 6c 77 61 79  points are alway
e610: 73 20 72 75 6e 20 62 79 20 61 20 62 61 63 6b 67  s run by a backg
e620: 72 6f 75 6e 64 20 74 68 72 65 61 64 20 6f 72 20  round thread or 
e630: 62 61 63 6b 67 72 6f 75 6e 64 20 0a 2a 2a 20 70  background .** p
e640: 72 6f 63 65 73 73 2c 20 66 6f 72 65 67 72 6f 75  rocess, foregrou
e650: 6e 64 20 74 68 72 65 61 64 73 20 77 69 6c 6c 20  nd threads will 
e660: 6e 65 76 65 72 20 62 6c 6f 63 6b 20 6f 6e 20 61  never block on a
e670: 20 6c 65 6e 67 74 68 79 20 66 73 79 6e 63 20 63   lengthy fsync c
e680: 61 6c 6c 2e 0a 2a 2a 0a 2a 2a 20 46 73 79 6e 63  all..**.** Fsync
e690: 20 69 73 20 63 61 6c 6c 65 64 20 6f 6e 20 74 68   is called on th
e6a0: 65 20 57 41 4c 20 62 65 66 6f 72 65 20 77 72 69  e WAL before wri
e6b0: 74 69 6e 67 20 63 6f 6e 74 65 6e 74 20 6f 75 74  ting content out
e6c0: 20 6f 66 20 74 68 65 20 57 41 4c 20 61 6e 64 0a   of the WAL and.
e6d0: 2a 2a 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ** into the data
e6e0: 62 61 73 65 2e 20 20 54 68 69 73 20 65 6e 73 75  base.  This ensu
e6f0: 72 65 73 20 74 68 61 74 20 69 66 20 74 68 65 20  res that if the 
e700: 6e 65 77 20 63 6f 6e 74 65 6e 74 20 69 73 20 70  new content is p
e710: 65 72 73 69 73 74 65 6e 74 0a 2a 2a 20 69 6e 20  ersistent.** in 
e720: 74 68 65 20 57 41 4c 20 61 6e 64 20 63 61 6e 20  the WAL and can 
e730: 62 65 20 72 65 63 6f 76 65 72 65 64 20 66 6f 6c  be recovered fol
e740: 6c 6f 77 69 6e 67 20 61 20 70 6f 77 65 72 2d 6c  lowing a power-l
e750: 6f 73 73 20 6f 72 20 68 61 72 64 20 72 65 73 65  oss or hard rese
e760: 74 2e 0a 2a 2a 0a 2a 2a 20 46 73 79 6e 63 20 69  t..**.** Fsync i
e770: 73 20 61 6c 73 6f 20 63 61 6c 6c 65 64 20 6f 6e  s also called on
e780: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
e790: 6c 65 20 69 66 20 28 61 6e 64 20 6f 6e 6c 79 20  le if (and only 
e7a0: 69 66 29 20 74 68 65 20 65 6e 74 69 72 65 0a 2a  if) the entire.*
e7b0: 2a 20 57 41 4c 20 63 6f 6e 74 65 6e 74 20 69 73  * WAL content is
e7c0: 20 63 6f 70 69 65 64 20 69 6e 74 6f 20 74 68 65   copied into the
e7d0: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 20   database file. 
e7e0: 20 54 68 69 73 20 73 65 63 6f 6e 64 20 66 73 79   This second fsy
e7f0: 6e 63 20 6d 61 6b 65 73 0a 2a 2a 20 69 74 20 73  nc makes.** it s
e800: 61 66 65 20 74 6f 20 64 65 6c 65 74 65 20 74 68  afe to delete th
e810: 65 20 57 41 4c 20 73 69 6e 63 65 20 74 68 65 20  e WAL since the 
e820: 6e 65 77 20 63 6f 6e 74 65 6e 74 20 77 69 6c 6c  new content will
e830: 20 70 65 72 73 69 73 74 20 69 6e 20 74 68 65 0a   persist in the.
e840: 2a 2a 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  ** database file
e850: 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ..**.** This rou
e860: 74 69 6e 65 20 75 73 65 73 20 61 6e 64 20 75 70  tine uses and up
e870: 64 61 74 65 73 20 74 68 65 20 6e 42 61 63 6b 66  dates the nBackf
e880: 69 6c 6c 20 66 69 65 6c 64 20 6f 66 20 74 68 65  ill field of the
e890: 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
e8a0: 72 2e 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68  r..** This is th
e8b0: 65 20 6f 6e 6c 79 20 72 6f 75 74 69 6e 65 20 74  e only routine t
e8c0: 68 61 20 77 69 6c 6c 20 69 6e 63 72 65 61 73 65  ha will increase
e8d0: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 6e 42   the value of nB
e8e0: 61 63 6b 66 69 6c 6c 2e 20 20 0a 2a 2a 20 28 41  ackfill.  .** (A
e8f0: 20 57 41 4c 20 72 65 73 65 74 20 6f 72 20 72 65   WAL reset or re
e900: 63 6f 76 65 72 79 20 77 69 6c 6c 20 72 65 76 65  covery will reve
e910: 72 74 20 6e 42 61 63 6b 66 69 6c 6c 20 74 6f 20  rt nBackfill to 
e920: 7a 65 72 6f 2c 20 62 75 74 20 6e 6f 74 20 69 6e  zero, but not in
e930: 63 72 65 61 73 65 0a 2a 2a 20 69 74 73 20 76 61  crease.** its va
e940: 6c 75 65 2e 29 0a 2a 2a 0a 2a 2a 20 54 68 65 20  lue.).**.** The 
e950: 63 61 6c 6c 65 72 20 6d 75 73 74 20 62 65 20 68  caller must be h
e960: 6f 6c 64 69 6e 67 20 73 75 66 66 69 63 69 65 6e  olding sufficien
e970: 74 20 6c 6f 63 6b 73 20 74 6f 20 65 6e 73 75 72  t locks to ensur
e980: 65 20 74 68 61 74 20 6e 6f 20 6f 74 68 65 72 0a  e that no other.
e990: 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 20 69 73  ** checkpoint is
e9a0: 20 72 75 6e 6e 69 6e 67 20 28 69 6e 20 61 6e 79   running (in any
e9b0: 20 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f 72   other thread or
e9c0: 20 70 72 6f 63 65 73 73 29 20 61 74 20 74 68 65   process) at the
e9d0: 20 73 61 6d 65 0a 2a 2a 20 74 69 6d 65 2e 0a 2a   same.** time..*
e9e0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
e9f0: 43 68 65 63 6b 70 6f 69 6e 74 28 0a 20 20 57 61  Checkpoint(.  Wa
ea00: 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20  l *pWal,        
ea10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
ea20: 20 57 61 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20   Wal connection 
ea30: 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c  */.  int sync_fl
ea40: 61 67 73 2c 20 20 20 20 20 20 20 20 20 20 20 20  ags,            
ea50: 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 66 6f       /* Flags fo
ea60: 72 20 4f 73 53 79 6e 63 28 29 20 28 6f 72 20 30  r OsSync() (or 0
ea70: 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 2c  ) */.  int nBuf,
ea80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ea90: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
eaa0: 66 20 7a 42 75 66 20 69 6e 20 62 79 74 65 73 20  f zBuf in bytes 
eab0: 2a 2f 0a 20 20 75 38 20 2a 7a 42 75 66 20 20 20  */.  u8 *zBuf   
eac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ead0: 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72       /* Temporar
eae0: 79 20 62 75 66 66 65 72 20 74 6f 20 75 73 65 20  y buffer to use 
eaf0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  */.){.  int rc; 
eb00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
eb10: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
eb20: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
eb30: 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20  szPage;         
eb40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
eb50: 61 74 61 62 61 73 65 20 70 61 67 65 2d 73 69 7a  atabase page-siz
eb60: 65 20 2a 2f 0a 20 20 57 61 6c 49 74 65 72 61 74  e */.  WalIterat
eb70: 6f 72 20 2a 70 49 74 65 72 20 3d 20 30 3b 20 20  or *pIter = 0;  
eb80: 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 69 74         /* Wal it
eb90: 65 72 61 74 6f 72 20 63 6f 6e 74 65 78 74 20 2a  erator context *
eba0: 2f 0a 20 20 75 33 32 20 69 44 62 70 61 67 65 20  /.  u32 iDbpage 
ebb0: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
ebc0: 20 20 20 20 2f 2a 20 4e 65 78 74 20 64 61 74 61      /* Next data
ebd0: 62 61 73 65 20 70 61 67 65 20 74 6f 20 77 72 69  base page to wri
ebe0: 74 65 20 2a 2f 0a 20 20 75 33 32 20 69 46 72 61  te */.  u32 iFra
ebf0: 6d 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  me = 0;         
ec00: 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 66          /* Wal f
ec10: 72 61 6d 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20  rame containing 
ec20: 64 61 74 61 20 66 6f 72 20 69 44 62 70 61 67 65  data for iDbpage
ec30: 20 2a 2f 0a 20 20 75 33 32 20 6d 78 53 61 66 65   */.  u32 mxSafe
ec40: 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  Frame;          
ec50: 20 20 20 20 20 20 2f 2a 20 4d 61 78 20 66 72 61        /* Max fra
ec60: 6d 65 20 74 68 61 74 20 63 61 6e 20 62 65 20 62  me that can be b
ec70: 61 63 6b 66 69 6c 6c 65 64 20 2a 2f 0a 20 20 75  ackfilled */.  u
ec80: 33 32 20 6d 78 50 61 67 65 3b 20 20 20 20 20 20  32 mxPage;      
ec90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
eca0: 2a 20 4d 61 78 20 64 61 74 61 62 61 73 65 20 70  * Max database p
ecb0: 61 67 65 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a  age to write */.
ecc0: 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
ecd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ece0: 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65    /* Loop counte
ecf0: 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20  r */.  volatile 
ed00: 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e  WalCkptInfo *pIn
ed10: 66 6f 3b 20 20 20 20 2f 2a 20 54 68 65 20 63 68  fo;    /* The ch
ed20: 65 63 6b 70 6f 69 6e 74 20 73 74 61 74 75 73 20  eckpoint status 
ed30: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 2a 2f 0a 0a  information */..
ed40: 20 20 73 7a 50 61 67 65 20 3d 20 28 70 57 61 6c    szPage = (pWal
ed50: 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26 30 78 66  ->hdr.szPage&0xf
ed60: 65 30 30 29 20 2b 20 28 28 70 57 61 6c 2d 3e 68  e00) + ((pWal->h
ed70: 64 72 2e 73 7a 50 61 67 65 26 30 78 30 30 30 31  dr.szPage&0x0001
ed80: 29 3c 3c 31 36 29 3b 0a 20 20 74 65 73 74 63 61  )<<16);.  testca
ed90: 73 65 28 20 73 7a 50 61 67 65 3c 3d 33 32 37 36  se( szPage<=3276
eda0: 38 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28  8 );.  testcase(
edb0: 20 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20 29   szPage>=65536 )
edc0: 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64  ;.  if( pWal->hd
edd0: 72 2e 6d 78 46 72 61 6d 65 3d 3d 30 20 29 20 72  r.mxFrame==0 ) r
ede0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
edf0: 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20  ..  /* Allocate 
ee00: 74 68 65 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a  the iterator */.
ee10: 20 20 72 63 20 3d 20 77 61 6c 49 74 65 72 61 74    rc = walIterat
ee20: 6f 72 49 6e 69 74 28 70 57 61 6c 2c 20 26 70 49  orInit(pWal, &pI
ee30: 74 65 72 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  ter);.  if( rc!=
ee40: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
ee50: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
ee60: 20 20 61 73 73 65 72 74 28 20 70 49 74 65 72 20    assert( pIter 
ee70: 29 3b 0a 0a 20 20 2f 2a 2a 2a 20 54 4f 44 4f 3a  );..  /*** TODO:
ee80: 20 20 4d 6f 76 65 20 74 68 69 73 20 74 65 73 74    Move this test
ee90: 20 6f 75 74 20 74 6f 20 74 68 65 20 63 61 6c 6c   out to the call
eea0: 65 72 2e 20 20 4d 61 6b 65 20 69 74 20 61 6e 20  er.  Make it an 
eeb0: 61 73 73 65 72 74 28 29 20 68 65 72 65 20 2a 2a  assert() here **
eec0: 2a 2f 0a 20 20 69 66 28 20 73 7a 50 61 67 65 21  */.  if( szPage!
eed0: 3d 6e 42 75 66 20 29 7b 0a 20 20 20 20 72 63 20  =nBuf ){.    rc 
eee0: 3d 20 53 51 4c 49 54 45 5f 43 4f 52 52 55 50 54  = SQLITE_CORRUPT
eef0: 5f 42 4b 50 54 3b 0a 20 20 20 20 67 6f 74 6f 20  _BKPT;.    goto 
ef00: 77 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75  walcheckpoint_ou
ef10: 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6d  t;.  }..  /* Com
ef20: 70 75 74 65 20 69 6e 20 6d 78 53 61 66 65 46 72  pute in mxSafeFr
ef30: 61 6d 65 20 74 68 65 20 69 6e 64 65 78 20 6f 66  ame the index of
ef40: 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d 65 20   the last frame 
ef50: 6f 66 20 74 68 65 20 57 41 4c 20 74 68 61 74 20  of the WAL that 
ef60: 69 73 0a 20 20 2a 2a 20 73 61 66 65 20 74 6f 20  is.  ** safe to 
ef70: 77 72 69 74 65 20 69 6e 74 6f 20 74 68 65 20 64  write into the d
ef80: 61 74 61 62 61 73 65 2e 20 20 46 72 61 6d 65 73  atabase.  Frames
ef90: 20 62 65 79 6f 6e 64 20 6d 78 53 61 66 65 46 72   beyond mxSafeFr
efa0: 61 6d 65 20 6d 69 67 68 74 0a 20 20 2a 2a 20 6f  ame might.  ** o
efb0: 76 65 72 77 72 69 74 65 20 64 61 74 61 62 61 73  verwrite databas
efc0: 65 20 70 61 67 65 73 20 74 68 61 74 20 61 72 65  e pages that are
efd0: 20 69 6e 20 75 73 65 20 62 79 20 61 63 74 69 76   in use by activ
efe0: 65 20 72 65 61 64 65 72 73 20 61 6e 64 20 74 68  e readers and th
eff0: 75 73 0a 20 20 2a 2a 20 63 61 6e 6e 6f 74 20 62  us.  ** cannot b
f000: 65 20 62 61 63 6b 66 69 6c 6c 65 64 20 66 72 6f  e backfilled fro
f010: 6d 20 74 68 65 20 57 41 4c 2e 0a 20 20 2a 2f 0a  m the WAL..  */.
f020: 20 20 6d 78 53 61 66 65 46 72 61 6d 65 20 3d 20    mxSafeFrame = 
f030: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
f040: 65 3b 0a 20 20 6d 78 50 61 67 65 20 3d 20 70 57  e;.  mxPage = pW
f050: 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 3b 0a 20  al->hdr.nPage;. 
f060: 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74   pInfo = walCkpt
f070: 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 66 6f  Info(pWal);.  fo
f080: 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52 45  r(i=1; i<WAL_NRE
f090: 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  ADER; i++){.    
f0a0: 75 33 32 20 79 20 3d 20 70 49 6e 66 6f 2d 3e 61  u32 y = pInfo->a
f0b0: 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20 20 20  ReadMark[i];.   
f0c0: 20 69 66 28 20 6d 78 53 61 66 65 46 72 61 6d 65   if( mxSafeFrame
f0d0: 3e 3d 79 20 29 7b 0a 20 20 20 20 20 20 61 73 73  >=y ){.      ass
f0e0: 65 72 74 28 20 79 3c 3d 70 57 61 6c 2d 3e 68 64  ert( y<=pWal->hd
f0f0: 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20  r.mxFrame );.   
f100: 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45     rc = walLockE
f110: 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
f120: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c  AL_READ_LOCK(i),
f130: 20 31 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72   1);.      if( r
f140: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
f150: 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 61          pInfo->a
f160: 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 52 45  ReadMark[i] = RE
f170: 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b  ADMARK_NOT_USED;
f180: 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f  .        walUnlo
f190: 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
f1a0: 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
f1b0: 69 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 7d 65  i), 1);.      }e
f1c0: 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  lse if( rc==SQLI
f1d0: 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20  TE_BUSY ){.     
f1e0: 20 20 20 6d 78 53 61 66 65 46 72 61 6d 65 20 3d     mxSafeFrame =
f1f0: 20 79 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b   y;.      }else{
f200: 0a 20 20 20 20 20 20 20 20 67 6f 74 6f 20 77 61  .        goto wa
f210: 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74 3b  lcheckpoint_out;
f220: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
f230: 20 7d 0a 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d   }..  if( pInfo-
f240: 3e 6e 42 61 63 6b 66 69 6c 6c 3c 6d 78 53 61 66  >nBackfill<mxSaf
f250: 65 46 72 61 6d 65 0a 20 20 20 26 26 20 28 72 63  eFrame.   && (rc
f260: 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73   = walLockExclus
f270: 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  ive(pWal, WAL_RE
f280: 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 31 29 29 3d  AD_LOCK(0), 1))=
f290: 3d 53 51 4c 49 54 45 5f 4f 4b 0a 20 20 29 7b 0a  =SQLITE_OK.  ){.
f2a0: 20 20 20 20 69 36 34 20 6e 53 69 7a 65 3b 20 20      i64 nSize;  
f2b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f2c0: 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 73 69 7a    /* Current siz
f2d0: 65 20 6f 66 20 64 61 74 61 62 61 73 65 20 66 69  e of database fi
f2e0: 6c 65 20 2a 2f 0a 20 20 20 20 75 33 32 20 6e 42  le */.    u32 nB
f2f0: 61 63 6b 66 69 6c 6c 20 3d 20 70 49 6e 66 6f 2d  ackfill = pInfo-
f300: 3e 6e 42 61 63 6b 66 69 6c 6c 3b 0a 0a 20 20 20  >nBackfill;..   
f310: 20 2f 2a 20 53 79 6e 63 20 74 68 65 20 57 41 4c   /* Sync the WAL
f320: 20 74 6f 20 64 69 73 6b 20 2a 2f 0a 20 20 20 20   to disk */.    
f330: 69 66 28 20 73 79 6e 63 5f 66 6c 61 67 73 20 29  if( sync_flags )
f340: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  {.      rc = sql
f350: 69 74 65 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d  ite3OsSync(pWal-
f360: 3e 70 57 61 6c 46 64 2c 20 73 79 6e 63 5f 66 6c  >pWalFd, sync_fl
f370: 61 67 73 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  ags);.    }..   
f380: 20 2f 2a 20 49 66 20 74 68 65 20 64 61 74 61 62   /* If the datab
f390: 61 73 65 20 66 69 6c 65 20 6d 61 79 20 67 72 6f  ase file may gro
f3a0: 77 20 61 73 20 61 20 72 65 73 75 6c 74 20 6f 66  w as a result of
f3b0: 20 74 68 69 73 20 63 68 65 63 6b 70 6f 69 6e 74   this checkpoint
f3c0: 2c 20 68 69 6e 74 0a 20 20 20 20 2a 2a 20 61 62  , hint.    ** ab
f3d0: 6f 75 74 20 74 68 65 20 65 76 65 6e 74 75 61 6c  out the eventual
f3e0: 20 73 69 7a 65 20 6f 66 20 74 68 65 20 64 62 20   size of the db 
f3f0: 66 69 6c 65 20 74 6f 20 74 68 65 20 56 46 53 20  file to the VFS 
f400: 6c 61 79 65 72 2e 20 0a 20 20 20 20 2a 2f 0a 20  layer. .    */. 
f410: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
f420: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 36  E_OK ){.      i6
f430: 34 20 6e 52 65 71 20 3d 20 28 28 69 36 34 29 6d  4 nReq = ((i64)m
f440: 78 50 61 67 65 20 2a 20 73 7a 50 61 67 65 29 3b  xPage * szPage);
f450: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
f460: 74 65 33 4f 73 46 69 6c 65 53 69 7a 65 28 70 57  te3OsFileSize(pW
f470: 61 6c 2d 3e 70 44 62 46 64 2c 20 26 6e 53 69 7a  al->pDbFd, &nSiz
f480: 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  e);.      if( rc
f490: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 6e  ==SQLITE_OK && n
f4a0: 53 69 7a 65 3c 6e 52 65 71 20 29 7b 0a 20 20 20  Size<nReq ){.   
f4b0: 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73 46 69       sqlite3OsFi
f4c0: 6c 65 43 6f 6e 74 72 6f 6c 28 70 57 61 6c 2d 3e  leControl(pWal->
f4d0: 70 44 62 46 64 2c 20 53 51 4c 49 54 45 5f 46 43  pDbFd, SQLITE_FC
f4e0: 4e 54 4c 5f 53 49 5a 45 5f 48 49 4e 54 2c 20 26  NTL_SIZE_HINT, &
f4f0: 6e 52 65 71 29 3b 0a 20 20 20 20 20 20 7d 0a 20  nReq);.      }. 
f500: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 74 65     }..    /* Ite
f510: 72 61 74 65 20 74 68 72 6f 75 67 68 20 74 68 65  rate through the
f520: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
f530: 20 57 41 4c 2c 20 63 6f 70 79 69 6e 67 20 64 61   WAL, copying da
f540: 74 61 20 74 6f 20 74 68 65 20 64 62 20 66 69 6c  ta to the db fil
f550: 65 2e 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28  e. */.    while(
f560: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
f570: 26 20 30 3d 3d 77 61 6c 49 74 65 72 61 74 6f 72  & 0==walIterator
f580: 4e 65 78 74 28 70 49 74 65 72 2c 20 26 69 44 62  Next(pIter, &iDb
f590: 70 61 67 65 2c 20 26 69 46 72 61 6d 65 29 20 29  page, &iFrame) )
f5a0: 7b 0a 20 20 20 20 20 20 69 36 34 20 69 4f 66 66  {.      i64 iOff
f5b0: 73 65 74 3b 0a 20 20 20 20 20 20 61 73 73 65 72  set;.      asser
f5c0: 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28  t( walFramePgno(
f5d0: 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 3d 3d 69  pWal, iFrame)==i
f5e0: 44 62 70 61 67 65 20 29 3b 0a 20 20 20 20 20 20  Dbpage );.      
f5f0: 69 66 28 20 69 46 72 61 6d 65 3c 3d 6e 42 61 63  if( iFrame<=nBac
f600: 6b 66 69 6c 6c 20 7c 7c 20 69 46 72 61 6d 65 3e  kfill || iFrame>
f610: 6d 78 53 61 66 65 46 72 61 6d 65 20 7c 7c 20 69  mxSafeFrame || i
f620: 44 62 70 61 67 65 3e 6d 78 50 61 67 65 20 29 20  Dbpage>mxPage ) 
f630: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
f640: 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61  iOffset = walFra
f650: 6d 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2c  meOffset(iFrame,
f660: 20 73 7a 50 61 67 65 29 20 2b 20 57 41 4c 5f 46   szPage) + WAL_F
f670: 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20 20  RAME_HDRSIZE;.  
f680: 20 20 20 20 2f 2a 20 74 65 73 74 63 61 73 65 28      /* testcase(
f690: 20 49 53 5f 42 49 47 5f 49 4e 54 28 69 4f 66 66   IS_BIG_INT(iOff
f6a0: 73 65 74 29 20 29 3b 20 2f 2f 20 72 65 71 75 69  set) ); // requi
f6b0: 72 65 73 20 61 20 34 47 69 42 20 57 41 4c 20 66  res a 4GiB WAL f
f6c0: 69 6c 65 20 2a 2f 0a 20 20 20 20 20 20 72 63 20  ile */.      rc 
f6d0: 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28  = sqlite3OsRead(
f6e0: 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 7a 42  pWal->pWalFd, zB
f6f0: 75 66 2c 20 73 7a 50 61 67 65 2c 20 69 4f 66 66  uf, szPage, iOff
f700: 73 65 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20  set);.      if( 
f710: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
f720: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 69 4f 66  break;.      iOf
f730: 66 73 65 74 20 3d 20 28 69 44 62 70 61 67 65 2d  fset = (iDbpage-
f740: 31 29 2a 28 69 36 34 29 73 7a 50 61 67 65 3b 0a  1)*(i64)szPage;.
f750: 20 20 20 20 20 20 74 65 73 74 63 61 73 65 28 20        testcase( 
f760: 49 53 5f 42 49 47 5f 49 4e 54 28 69 4f 66 66 73  IS_BIG_INT(iOffs
f770: 65 74 29 20 29 3b 0a 20 20 20 20 20 20 72 63 20  et) );.      rc 
f780: 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65  = sqlite3OsWrite
f790: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 7a 42  (pWal->pDbFd, zB
f7a0: 75 66 2c 20 73 7a 50 61 67 65 2c 20 69 4f 66 66  uf, szPage, iOff
f7b0: 73 65 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20  set);.      if( 
f7c0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
f7d0: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20  break;.    }..  
f7e0: 20 20 2f 2a 20 49 66 20 77 6f 72 6b 20 77 61 73    /* If work was
f7f0: 20 61 63 74 75 61 6c 6c 79 20 61 63 63 6f 6d 70   actually accomp
f800: 6c 69 73 68 65 64 2e 2e 2e 20 2a 2f 0a 20 20 20  lished... */.   
f810: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
f820: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  OK ){.      if( 
f830: 6d 78 53 61 66 65 46 72 61 6d 65 3d 3d 77 61 6c  mxSafeFrame==wal
f840: 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29 2d 3e  IndexHdr(pWal)->
f850: 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 20  mxFrame ){.     
f860: 20 20 20 69 36 34 20 73 7a 44 62 20 3d 20 70 57     i64 szDb = pW
f870: 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 2a 28 69  al->hdr.nPage*(i
f880: 36 34 29 73 7a 50 61 67 65 3b 0a 20 20 20 20 20  64)szPage;.     
f890: 20 20 20 74 65 73 74 63 61 73 65 28 20 49 53 5f     testcase( IS_
f8a0: 42 49 47 5f 49 4e 54 28 73 7a 44 62 29 20 29 3b  BIG_INT(szDb) );
f8b0: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71  .        rc = sq
f8c0: 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28  lite3OsTruncate(
f8d0: 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 73 7a 44  pWal->pDbFd, szD
f8e0: 62 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  b);.        if( 
f8f0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
f900: 20 73 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a 20   sync_flags ){. 
f910: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71           rc = sq
f920: 6c 69 74 65 33 4f 73 53 79 6e 63 28 70 57 61 6c  lite3OsSync(pWal
f930: 2d 3e 70 44 62 46 64 2c 20 73 79 6e 63 5f 66 6c  ->pDbFd, sync_fl
f940: 61 67 73 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ags);.        }.
f950: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
f960: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
f970: 29 7b 0a 20 20 20 20 20 20 20 20 70 49 6e 66 6f  ){.        pInfo
f980: 2d 3e 6e 42 61 63 6b 66 69 6c 6c 20 3d 20 6d 78  ->nBackfill = mx
f990: 53 61 66 65 46 72 61 6d 65 3b 0a 20 20 20 20 20  SafeFrame;.     
f9a0: 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a   }.    }..    /*
f9b0: 20 52 65 6c 65 61 73 65 20 74 68 65 20 72 65 61   Release the rea
f9c0: 64 65 72 20 6c 6f 63 6b 20 68 65 6c 64 20 77 68  der lock held wh
f9d0: 69 6c 65 20 62 61 63 6b 66 69 6c 6c 69 6e 67 20  ile backfilling 
f9e0: 2a 2f 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b  */.    walUnlock
f9f0: 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
fa00: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29  WAL_READ_LOCK(0)
fa10: 2c 20 31 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66  , 1);.  }else if
fa20: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc==SQLITE_BUS
fa30: 59 20 29 7b 0a 20 20 20 20 2f 2a 20 52 65 73 65  Y ){.    /* Rese
fa40: 74 20 74 68 65 20 72 65 74 75 72 6e 20 63 6f 64  t the return cod
fa50: 65 20 73 6f 20 61 73 20 6e 6f 74 20 74 6f 20 72  e so as not to r
fa60: 65 70 6f 72 74 20 61 20 63 68 65 63 6b 70 6f 69  eport a checkpoi
fa70: 6e 74 20 66 61 69 6c 75 72 65 0a 20 20 20 20 2a  nt failure.    *
fa80: 2a 20 6a 75 73 74 20 62 65 63 61 75 73 65 20 61  * just because a
fa90: 63 74 69 76 65 20 72 65 61 64 65 72 73 20 70 72  ctive readers pr
faa0: 65 76 65 6e 74 20 61 6e 79 20 62 61 63 6b 66 69  event any backfi
fab0: 6c 6c 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 72  ll..    */.    r
fac0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
fad0: 20 7d 0a 0a 20 77 61 6c 63 68 65 63 6b 70 6f 69   }.. walcheckpoi
fae0: 6e 74 5f 6f 75 74 3a 0a 20 20 77 61 6c 49 74 65  nt_out:.  walIte
faf0: 72 61 74 6f 72 46 72 65 65 28 70 49 74 65 72 29  ratorFree(pIter)
fb00: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
fb10: 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20  ../*.** Close a 
fb20: 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 61 20  connection to a 
fb30: 6c 6f 67 20 66 69 6c 65 2e 0a 2a 2f 0a 69 6e 74  log file..*/.int
fb40: 20 73 71 6c 69 74 65 33 57 61 6c 43 6c 6f 73 65   sqlite3WalClose
fb50: 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20  (.  Wal *pWal,  
fb60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
fb70: 20 20 20 20 2f 2a 20 57 61 6c 20 74 6f 20 63 6c      /* Wal to cl
fb80: 6f 73 65 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e  ose */.  int syn
fb90: 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20  c_flags,        
fba0: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67           /* Flag
fbb0: 73 20 74 6f 20 70 61 73 73 20 74 6f 20 4f 73 53  s to pass to OsS
fbc0: 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a  ync() (or 0) */.
fbd0: 20 20 69 6e 74 20 6e 42 75 66 2c 0a 20 20 75 38    int nBuf,.  u8
fbe0: 20 2a 7a 42 75 66 20 20 20 20 20 20 20 20 20 20   *zBuf          
fbf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
fc00: 20 42 75 66 66 65 72 20 6f 66 20 61 74 20 6c 65   Buffer of at le
fc10: 61 73 74 20 6e 42 75 66 20 62 79 74 65 73 20 2a  ast nBuf bytes *
fc20: 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  /.){.  int rc = 
fc30: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28  SQLITE_OK;.  if(
fc40: 20 70 57 61 6c 20 29 7b 0a 20 20 20 20 69 6e 74   pWal ){.    int
fc50: 20 69 73 44 65 6c 65 74 65 20 3d 20 30 3b 20 20   isDelete = 0;  
fc60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
fc70: 75 65 20 74 6f 20 75 6e 6c 69 6e 6b 20 77 61 6c  ue to unlink wal
fc80: 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66   and wal-index f
fc90: 69 6c 65 73 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20  iles */..    /* 
fca0: 49 66 20 61 6e 20 45 58 43 4c 55 53 49 56 45 20  If an EXCLUSIVE 
fcb0: 6c 6f 63 6b 20 63 61 6e 20 62 65 20 6f 62 74 61  lock can be obta
fcc0: 69 6e 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61  ined on the data
fcd0: 62 61 73 65 20 66 69 6c 65 20 28 75 73 69 6e 67  base file (using
fce0: 20 74 68 65 0a 20 20 20 20 2a 2a 20 6f 72 64 69   the.    ** ordi
fcf0: 6e 61 72 79 2c 20 72 6f 6c 6c 62 61 63 6b 2d 6d  nary, rollback-m
fd00: 6f 64 65 20 6c 6f 63 6b 69 6e 67 20 6d 65 74 68  ode locking meth
fd10: 6f 64 73 2c 20 74 68 69 73 20 67 75 61 72 61 6e  ods, this guaran
fd20: 74 65 65 73 20 74 68 61 74 20 74 68 65 0a 20 20  tees that the.  
fd30: 20 20 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e 20    ** connection 
fd40: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20  associated with 
fd50: 74 68 69 73 20 6c 6f 67 20 66 69 6c 65 20 69 73  this log file is
fd60: 20 74 68 65 20 6f 6e 6c 79 20 63 6f 6e 6e 65 63   the only connec
fd70: 74 69 6f 6e 20 74 6f 0a 20 20 20 20 2a 2a 20 74  tion to.    ** t
fd80: 68 65 20 64 61 74 61 62 61 73 65 2e 20 49 6e 20  he database. In 
fd90: 74 68 69 73 20 63 61 73 65 20 63 68 65 63 6b 70  this case checkp
fda0: 6f 69 6e 74 20 74 68 65 20 64 61 74 61 62 61 73  oint the databas
fdb0: 65 20 61 6e 64 20 75 6e 6c 69 6e 6b 20 62 6f 74  e and unlink bot
fdc0: 68 0a 20 20 20 20 2a 2a 20 74 68 65 20 77 61 6c  h.    ** the wal
fdd0: 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66   and wal-index f
fde0: 69 6c 65 73 2e 0a 20 20 20 20 2a 2a 0a 20 20 20  iles..    **.   
fdf0: 20 2a 2a 20 54 68 65 20 45 58 43 4c 55 53 49 56   ** The EXCLUSIV
fe00: 45 20 6c 6f 63 6b 20 69 73 20 6e 6f 74 20 72 65  E lock is not re
fe10: 6c 65 61 73 65 64 20 62 65 66 6f 72 65 20 72 65  leased before re
fe20: 74 75 72 6e 69 6e 67 2e 0a 20 20 20 20 2a 2f 0a  turning..    */.
fe30: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
fe40: 4f 73 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62  OsLock(pWal->pDb
fe50: 46 64 2c 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 5f  Fd, SQLITE_LOCK_
fe60: 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20 20 20  EXCLUSIVE);.    
fe70: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
fe80: 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70  K ){.      if( p
fe90: 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
fea0: 64 65 3d 3d 57 41 4c 5f 4e 4f 52 4d 41 4c 5f 4d  de==WAL_NORMAL_M
feb0: 4f 44 45 20 29 7b 0a 20 20 20 20 20 20 20 20 70  ODE ){.        p
fec0: 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
fed0: 64 65 20 3d 20 57 41 4c 5f 45 58 43 4c 55 53 49  de = WAL_EXCLUSI
fee0: 56 45 5f 4d 4f 44 45 3b 0a 20 20 20 20 20 20 7d  VE_MODE;.      }
fef0: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
ff00: 74 65 33 57 61 6c 43 68 65 63 6b 70 6f 69 6e 74  te3WalCheckpoint
ff10: 28 70 57 61 6c 2c 20 73 79 6e 63 5f 66 6c 61 67  (pWal, sync_flag
ff20: 73 2c 20 6e 42 75 66 2c 20 7a 42 75 66 29 3b 0a  s, nBuf, zBuf);.
ff30: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
ff40: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
ff50: 20 20 20 69 73 44 65 6c 65 74 65 20 3d 20 31 3b     isDelete = 1;
ff60: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
ff70: 20 20 20 20 77 61 6c 49 6e 64 65 78 43 6c 6f 73      walIndexClos
ff80: 65 28 70 57 61 6c 2c 20 69 73 44 65 6c 65 74 65  e(pWal, isDelete
ff90: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  );.    sqlite3Os
ffa0: 43 6c 6f 73 65 28 70 57 61 6c 2d 3e 70 57 61 6c  Close(pWal->pWal
ffb0: 46 64 29 3b 0a 20 20 20 20 69 66 28 20 69 73 44  Fd);.    if( isD
ffc0: 65 6c 65 74 65 20 29 7b 0a 20 20 20 20 20 20 73  elete ){.      s
ffd0: 71 6c 69 74 65 33 4f 73 44 65 6c 65 74 65 28 70  qlite3OsDelete(p
ffe0: 57 61 6c 2d 3e 70 56 66 73 2c 20 70 57 61 6c 2d  Wal->pVfs, pWal-
fff0: 3e 7a 57 61 6c 4e 61 6d 65 2c 20 30 29 3b 0a 20  >zWalName, 0);. 
10000 20 20 20 7d 0a 20 20 20 20 57 41 4c 54 52 41 43     }.    WALTRAC
10010 45 28 28 22 57 41 4c 25 70 3a 20 63 6c 6f 73 65  E(("WAL%p: close
10020 64 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 20 20  d\n", pWal));.  
10030 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 28    sqlite3_free((
10040 76 6f 69 64 20 2a 29 70 57 61 6c 2d 3e 61 70 57  void *)pWal->apW
10050 69 44 61 74 61 29 3b 0a 20 20 20 20 73 71 6c 69  iData);.    sqli
10060 74 65 33 5f 66 72 65 65 28 70 57 61 6c 29 3b 0a  te3_free(pWal);.
10070 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
10080 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20 74 6f  .}../*.** Try to
10090 20 72 65 61 64 20 74 68 65 20 77 61 6c 2d 69 6e   read the wal-in
100a0 64 65 78 20 68 65 61 64 65 72 2e 20 20 52 65 74  dex header.  Ret
100b0 75 72 6e 20 30 20 6f 6e 20 73 75 63 63 65 73 73  urn 0 on success
100c0 20 61 6e 64 20 31 20 69 66 0a 2a 2a 20 74 68 65   and 1 if.** the
100d0 72 65 20 69 73 20 61 20 70 72 6f 62 6c 65 6d 2e  re is a problem.
100e0 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61 6c 2d 69  .**.** The wal-i
100f0 6e 64 65 78 20 69 73 20 69 6e 20 73 68 61 72 65  ndex is in share
10100 64 20 6d 65 6d 6f 72 79 2e 20 20 41 6e 6f 74 68  d memory.  Anoth
10110 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f  er thread or pro
10120 63 65 73 73 20 6d 69 67 68 74 0a 2a 2a 20 62 65  cess might.** be
10130 20 77 72 69 74 69 6e 67 20 74 68 65 20 68 65 61   writing the hea
10140 64 65 72 20 61 74 20 74 68 65 20 73 61 6d 65 20  der at the same 
10150 74 69 6d 65 20 74 68 69 73 20 70 72 6f 63 65 64  time this proced
10160 75 72 65 20 69 73 20 74 72 79 69 6e 67 20 74 6f  ure is trying to
10170 0a 2a 2a 20 72 65 61 64 20 69 74 2c 20 77 68 69  .** read it, whi
10180 63 68 20 6d 69 67 68 74 20 72 65 73 75 6c 74 20  ch might result 
10190 69 6e 20 69 6e 63 6f 6e 73 69 73 74 65 6e 63 79  in inconsistency
101a0 2e 20 20 41 20 64 69 72 74 79 20 72 65 61 64 20  .  A dirty read 
101b0 69 73 20 64 65 74 65 63 74 65 64 0a 2a 2a 20 62  is detected.** b
101c0 79 20 76 65 72 69 66 79 69 6e 67 20 74 68 61 74  y verifying that
101d0 20 62 6f 74 68 20 63 6f 70 69 65 73 20 6f 66 20   both copies of 
101e0 74 68 65 20 68 65 61 64 65 72 20 61 72 65 20 74  the header are t
101f0 68 65 20 73 61 6d 65 20 61 6e 64 20 61 6c 73 6f  he same and also
10200 20 62 79 0a 2a 2a 20 61 20 63 68 65 63 6b 73 75   by.** a checksu
10210 6d 20 6f 6e 20 74 68 65 20 68 65 61 64 65 72 2e  m on the header.
10220 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 64 20 6f 6e  .**.** If and on
10230 6c 79 20 69 66 20 74 68 65 20 72 65 61 64 20 69  ly if the read i
10240 73 20 63 6f 6e 73 69 73 74 65 6e 74 20 61 6e 64  s consistent and
10250 20 74 68 65 20 68 65 61 64 65 72 20 69 73 20 64   the header is d
10260 69 66 66 65 72 65 6e 74 20 66 72 6f 6d 0a 2a 2a  ifferent from.**
10270 20 70 57 61 6c 2d 3e 68 64 72 2c 20 74 68 65 6e   pWal->hdr, then
10280 20 70 57 61 6c 2d 3e 68 64 72 20 69 73 20 75 70   pWal->hdr is up
10290 64 61 74 65 64 20 74 6f 20 74 68 65 20 63 6f 6e  dated to the con
102a0 74 65 6e 74 20 6f 66 20 74 68 65 20 6e 65 77 20  tent of the new 
102b0 68 65 61 64 65 72 0a 2a 2a 20 61 6e 64 20 2a 70  header.** and *p
102c0 43 68 61 6e 67 65 64 20 69 73 20 73 65 74 20 74  Changed is set t
102d0 6f 20 31 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  o 1..**.** If th
102e0 65 20 63 68 65 63 6b 73 75 6d 20 63 61 6e 6e 6f  e checksum canno
102f0 74 20 62 65 20 76 65 72 69 66 69 65 64 20 72 65  t be verified re
10300 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 20 49  turn non-zero. I
10310 66 20 74 68 65 20 68 65 61 64 65 72 0a 2a 2a 20  f the header.** 
10320 69 73 20 72 65 61 64 20 73 75 63 63 65 73 73 66  is read successf
10330 75 6c 6c 79 20 61 6e 64 20 74 68 65 20 63 68 65  ully and the che
10340 63 6b 73 75 6d 20 76 65 72 69 66 69 65 64 2c 20  cksum verified, 
10350 72 65 74 75 72 6e 20 7a 65 72 6f 2e 0a 2a 2f 0a  return zero..*/.
10360 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e  static int walIn
10370 64 65 78 54 72 79 48 64 72 28 57 61 6c 20 2a 70  dexTryHdr(Wal *p
10380 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e 67  Wal, int *pChang
10390 65 64 29 7b 0a 20 20 75 33 32 20 61 43 6b 73 75  ed){.  u32 aCksu
103a0 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20 20  m[2];           
103b0 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 73         /* Checks
103c0 75 6d 20 6f 6e 20 74 68 65 20 68 65 61 64 65 72  um on the header
103d0 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 57 61   content */.  Wa
103e0 6c 49 6e 64 65 78 48 64 72 20 68 31 2c 20 68 32  lIndexHdr h1, h2
103f0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
10400 20 54 77 6f 20 63 6f 70 69 65 73 20 6f 66 20 74   Two copies of t
10410 68 65 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e  he header conten
10420 74 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65 78 48  t */.  WalIndexH
10430 64 72 20 76 6f 6c 61 74 69 6c 65 20 2a 61 48 64  dr volatile *aHd
10440 72 3b 20 20 20 20 20 2f 2a 20 48 65 61 64 65 72  r;     /* Header
10450 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d 6f 72   in shared memor
10460 79 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 65 20 66  y */..  /* The f
10470 69 72 73 74 20 70 61 67 65 20 6f 66 20 74 68 65  irst page of the
10480 20 77 61 6c 2d 69 6e 64 65 78 20 6d 75 73 74 20   wal-index must 
10490 62 65 20 6d 61 70 70 65 64 20 61 74 20 74 68 69  be mapped at thi
104a0 73 20 70 6f 69 6e 74 2e 20 2a 2f 0a 20 20 61 73  s point. */.  as
104b0 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44  sert( pWal->nWiD
104c0 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61  ata>0 && pWal->a
104d0 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 0a 20  pWiData[0] );.. 
104e0 20 2f 2a 20 52 65 61 64 20 74 68 65 20 68 65 61   /* Read the hea
104f0 64 65 72 2e 20 54 68 69 73 20 6d 69 67 68 74 20  der. This might 
10500 68 61 70 70 65 6e 20 63 6f 6e 63 75 72 72 65 6e  happen concurren
10510 74 6c 79 20 77 69 74 68 20 61 20 77 72 69 74 65  tly with a write
10520 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20 73 61 6d   to the.  ** sam
10530 65 20 61 72 65 61 20 6f 66 20 73 68 61 72 65 64  e area of shared
10540 20 6d 65 6d 6f 72 79 20 6f 6e 20 61 20 64 69 66   memory on a dif
10550 66 65 72 65 6e 74 20 43 50 55 20 69 6e 20 61 20  ferent CPU in a 
10560 53 4d 50 2c 0a 20 20 2a 2a 20 6d 65 61 6e 69 6e  SMP,.  ** meanin
10570 67 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c 65  g it is possible
10580 20 74 68 61 74 20 61 6e 20 69 6e 63 6f 6e 73 69   that an inconsi
10590 73 74 65 6e 74 20 73 6e 61 70 73 68 6f 74 20 69  stent snapshot i
105a0 73 20 72 65 61 64 0a 20 20 2a 2a 20 66 72 6f 6d  s read.  ** from
105b0 20 74 68 65 20 66 69 6c 65 2e 20 49 66 20 74 68   the file. If th
105c0 69 73 20 68 61 70 70 65 6e 73 2c 20 72 65 74 75  is happens, retu
105d0 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 20 20 2a  rn non-zero..  *
105e0 2a 0a 20 20 2a 2a 20 54 68 65 72 65 20 61 72 65  *.  ** There are
105f0 20 74 77 6f 20 63 6f 70 69 65 73 20 6f 66 20 74   two copies of t
10600 68 65 20 68 65 61 64 65 72 20 61 74 20 74 68 65  he header at the
10610 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68   beginning of th
10620 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 20 20 2a  e wal-index..  *
10630 2a 20 57 68 65 6e 20 72 65 61 64 69 6e 67 2c 20  * When reading, 
10640 72 65 61 64 20 5b 30 5d 20 66 69 72 73 74 20 74  read [0] first t
10650 68 65 6e 20 5b 31 5d 2e 20 20 57 72 69 74 65 73  hen [1].  Writes
10660 20 61 72 65 20 69 6e 20 74 68 65 20 72 65 76 65   are in the reve
10670 72 73 65 20 6f 72 64 65 72 2e 0a 20 20 2a 2a 20  rse order..  ** 
10680 4d 65 6d 6f 72 79 20 62 61 72 72 69 65 72 73 20  Memory barriers 
10690 61 72 65 20 75 73 65 64 20 74 6f 20 70 72 65 76  are used to prev
106a0 65 6e 74 20 74 68 65 20 63 6f 6d 70 69 6c 65 72  ent the compiler
106b0 20 6f 72 20 74 68 65 20 68 61 72 64 77 61 72 65   or the hardware
106c0 20 66 72 6f 6d 0a 20 20 2a 2a 20 72 65 6f 72 64   from.  ** reord
106d0 65 72 69 6e 67 20 74 68 65 20 72 65 61 64 73 20  ering the reads 
106e0 61 6e 64 20 77 72 69 74 65 73 2e 0a 20 20 2a 2f  and writes..  */
106f0 0a 20 20 61 48 64 72 20 3d 20 77 61 6c 49 6e 64  .  aHdr = walInd
10700 65 78 48 64 72 28 70 57 61 6c 29 3b 0a 20 20 6d  exHdr(pWal);.  m
10710 65 6d 63 70 79 28 26 68 31 2c 20 28 76 6f 69 64  emcpy(&h1, (void
10720 20 2a 29 26 61 48 64 72 5b 30 5d 2c 20 73 69 7a   *)&aHdr[0], siz
10730 65 6f 66 28 68 31 29 29 3b 0a 20 20 77 61 6c 53  eof(h1));.  walS
10740 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c 29 3b  hmBarrier(pWal);
10750 0a 20 20 6d 65 6d 63 70 79 28 26 68 32 2c 20 28  .  memcpy(&h2, (
10760 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 31 5d 2c  void *)&aHdr[1],
10770 20 73 69 7a 65 6f 66 28 68 32 29 29 3b 0a 0a 20   sizeof(h2));.. 
10780 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 68 31 2c   if( memcmp(&h1,
10790 20 26 68 32 2c 20 73 69 7a 65 6f 66 28 68 31 29   &h2, sizeof(h1)
107a0 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )!=0 ){.    retu
107b0 72 6e 20 31 3b 20 20 20 2f 2a 20 44 69 72 74 79  rn 1;   /* Dirty
107c0 20 72 65 61 64 20 2a 2f 0a 20 20 7d 20 20 0a 20   read */.  }  . 
107d0 20 69 66 28 20 68 31 2e 69 73 49 6e 69 74 3d 3d   if( h1.isInit==
107e0 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  0 ){.    return 
107f0 31 3b 20 20 20 2f 2a 20 4d 61 6c 66 6f 72 6d 65  1;   /* Malforme
10800 64 20 68 65 61 64 65 72 20 2d 20 70 72 6f 62 61  d header - proba
10810 62 6c 79 20 61 6c 6c 20 7a 65 72 6f 73 20 2a 2f  bly all zeros */
10820 0a 20 20 7d 0a 20 20 77 61 6c 43 68 65 63 6b 73  .  }.  walChecks
10830 75 6d 42 79 74 65 73 28 31 2c 20 28 75 38 2a 29  umBytes(1, (u8*)
10840 26 68 31 2c 20 73 69 7a 65 6f 66 28 68 31 29 2d  &h1, sizeof(h1)-
10850 73 69 7a 65 6f 66 28 68 31 2e 61 43 6b 73 75 6d  sizeof(h1.aCksum
10860 29 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b 0a 20  ), 0, aCksum);. 
10870 20 69 66 28 20 61 43 6b 73 75 6d 5b 30 5d 21 3d   if( aCksum[0]!=
10880 68 31 2e 61 43 6b 73 75 6d 5b 30 5d 20 7c 7c 20  h1.aCksum[0] || 
10890 61 43 6b 73 75 6d 5b 31 5d 21 3d 68 31 2e 61 43  aCksum[1]!=h1.aC
108a0 6b 73 75 6d 5b 31 5d 20 29 7b 0a 20 20 20 20 72  ksum[1] ){.    r
108b0 65 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20 43 68  eturn 1;   /* Ch
108c0 65 63 6b 73 75 6d 20 64 6f 65 73 20 6e 6f 74 20  ecksum does not 
108d0 6d 61 74 63 68 20 2a 2f 0a 20 20 7d 0a 0a 20 20  match */.  }..  
108e0 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c  if( memcmp(&pWal
108f0 2d 3e 68 64 72 2c 20 26 68 31 2c 20 73 69 7a 65  ->hdr, &h1, size
10900 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
10910 20 29 7b 0a 20 20 20 20 2a 70 43 68 61 6e 67 65   ){.    *pChange
10920 64 20 3d 20 31 3b 0a 20 20 20 20 6d 65 6d 63 70  d = 1;.    memcp
10930 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 26 68  y(&pWal->hdr, &h
10940 31 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64  1, sizeof(WalInd
10950 65 78 48 64 72 29 29 3b 0a 20 20 20 20 70 57 61  exHdr));.    pWa
10960 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 28 70 57 61  l->szPage = (pWa
10970 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26 30 78  l->hdr.szPage&0x
10980 66 65 30 30 29 20 2b 20 28 28 70 57 61 6c 2d 3e  fe00) + ((pWal->
10990 68 64 72 2e 73 7a 50 61 67 65 26 30 78 30 30 30  hdr.szPage&0x000
109a0 31 29 3c 3c 31 36 29 3b 0a 20 20 20 20 74 65 73  1)<<16);.    tes
109b0 74 63 61 73 65 28 20 70 57 61 6c 2d 3e 73 7a 50  tcase( pWal->szP
109c0 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20  age<=32768 );.  
109d0 20 20 74 65 73 74 63 61 73 65 28 20 70 57 61 6c    testcase( pWal
109e0 2d 3e 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20  ->szPage>=65536 
109f0 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 68 65  );.  }..  /* The
10a00 20 68 65 61 64 65 72 20 77 61 73 20 73 75 63 63   header was succ
10a10 65 73 73 66 75 6c 6c 79 20 72 65 61 64 2e 20 52  essfully read. R
10a20 65 74 75 72 6e 20 7a 65 72 6f 2e 20 2a 2f 0a 20  eturn zero. */. 
10a30 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a   return 0;.}../*
10a40 0a 2a 2a 20 52 65 61 64 20 74 68 65 20 77 61 6c  .** Read the wal
10a50 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 66 72  -index header fr
10a60 6f 6d 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  om the wal-index
10a70 20 61 6e 64 20 69 6e 74 6f 20 70 57 61 6c 2d 3e   and into pWal->
10a80 68 64 72 2e 0a 2a 2a 20 49 66 20 74 68 65 20 77  hdr..** If the w
10a90 61 6c 2d 68 65 61 64 65 72 20 61 70 70 65 61 72  al-header appear
10aa0 73 20 74 6f 20 62 65 20 63 6f 72 72 75 70 74 2c  s to be corrupt,
10ab0 20 74 72 79 20 74 6f 20 72 65 63 6f 6e 73 74 72   try to reconstr
10ac0 75 63 74 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69  uct the.** wal-i
10ad0 6e 64 65 78 20 66 72 6f 6d 20 74 68 65 20 57 41  ndex from the WA
10ae0 4c 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69  L before returni
10af0 6e 67 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20 2a 70  ng..**.** Set *p
10b00 43 68 61 6e 67 65 64 20 74 6f 20 31 20 69 66 20  Changed to 1 if 
10b10 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
10b20 61 64 65 72 20 76 61 6c 75 65 20 69 6e 20 70 57  ader value in pW
10b30 61 6c 2d 3e 68 64 72 20 69 73 0a 2a 2a 20 63 68  al->hdr is.** ch
10b40 61 6e 67 65 64 20 62 79 20 74 68 69 73 20 6f 70  anged by this op
10b50 65 72 74 69 6f 6e 2e 20 20 49 66 20 70 57 61 6c  ertion.  If pWal
10b60 2d 3e 68 64 72 20 69 73 20 75 6e 63 68 61 6e 67  ->hdr is unchang
10b70 65 64 2c 20 73 65 74 20 2a 70 43 68 61 6e 67 65  ed, set *pChange
10b80 64 0a 2a 2a 20 74 6f 20 30 2e 0a 2a 2a 0a 2a 2a  d.** to 0..**.**
10b90 20 49 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   If the wal-inde
10ba0 78 20 68 65 61 64 65 72 20 69 73 20 73 75 63 63  x header is succ
10bb0 65 73 73 66 75 6c 6c 79 20 72 65 61 64 2c 20 72  essfully read, r
10bc0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e  eturn SQLITE_OK.
10bd0 20 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 20 61   .** Otherwise a
10be0 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
10bf0 6f 64 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ode..*/.static i
10c00 6e 74 20 77 61 6c 49 6e 64 65 78 52 65 61 64 48  nt walIndexReadH
10c10 64 72 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e  dr(Wal *pWal, in
10c20 74 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a 20 20  t *pChanged){.  
10c30 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
10c40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10c50 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
10c60 2f 0a 20 20 69 6e 74 20 62 61 64 48 64 72 3b 20  /.  int badHdr; 
10c70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10c80 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61      /* True if a
10c90 20 68 65 61 64 65 72 20 72 65 61 64 20 66 61 69   header read fai
10ca0 6c 65 64 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c  led */.  volatil
10cb0 65 20 75 33 32 20 2a 70 61 67 65 30 3b 20 20 20  e u32 *page0;   
10cc0 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 75 6e           /* Chun
10cd0 6b 20 6f 66 20 77 61 6c 2d 69 6e 64 65 78 20 63  k of wal-index c
10ce0 6f 6e 74 61 69 6e 69 6e 67 20 68 65 61 64 65 72  ontaining header
10cf0 20 2a 2f 0a 0a 20 20 2f 2a 20 45 6e 73 75 72 65   */..  /* Ensure
10d00 20 74 68 61 74 20 70 61 67 65 20 30 20 6f 66 20   that page 0 of 
10d10 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 28 74  the wal-index (t
10d20 68 65 20 70 61 67 65 20 74 68 61 74 20 63 6f 6e  he page that con
10d30 74 61 69 6e 73 20 74 68 65 20 0a 20 20 2a 2a 20  tains the .  ** 
10d40 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
10d50 29 20 69 73 20 6d 61 70 70 65 64 2e 20 52 65 74  ) is mapped. Ret
10d60 75 72 6e 20 65 61 72 6c 79 20 69 66 20 61 6e 20  urn early if an 
10d70 65 72 72 6f 72 20 6f 63 63 75 72 73 20 68 65 72  error occurs her
10d80 65 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74  e..  */.  assert
10d90 28 20 70 43 68 61 6e 67 65 64 20 29 3b 0a 20 20  ( pChanged );.  
10da0 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 50 61 67  rc = walIndexPag
10db0 65 28 70 57 61 6c 2c 20 30 2c 20 26 70 61 67 65  e(pWal, 0, &page
10dc0 30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  0);.  if( rc!=SQ
10dd0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
10de0 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 3b 0a 20  eturn rc;.  };. 
10df0 20 61 73 73 65 72 74 28 20 70 61 67 65 30 20 7c   assert( page0 |
10e00 7c 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  | pWal->writeLoc
10e10 6b 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 49 66  k==0 );..  /* If
10e20 20 74 68 65 20 66 69 72 73 74 20 70 61 67 65 20   the first page 
10e30 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
10e40 20 68 61 73 20 62 65 65 6e 20 6d 61 70 70 65 64   has been mapped
10e50 2c 20 74 72 79 20 74 6f 20 72 65 61 64 20 74 68  , try to read th
10e60 65 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78  e.  ** wal-index
10e70 20 68 65 61 64 65 72 20 69 6d 6d 65 64 69 61 74   header immediat
10e80 65 6c 79 2c 20 77 69 74 68 6f 75 74 20 68 6f 6c  ely, without hol
10e90 64 69 6e 67 20 61 6e 79 20 6c 6f 63 6b 2e 20 54  ding any lock. T
10ea0 68 69 73 20 75 73 75 61 6c 6c 79 0a 20 20 2a 2a  his usually.  **
10eb0 20 77 6f 72 6b 73 2c 20 62 75 74 20 6d 61 79 20   works, but may 
10ec0 66 61 69 6c 20 69 66 20 74 68 65 20 77 61 6c 2d  fail if the wal-
10ed0 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20  index header is 
10ee0 63 6f 72 72 75 70 74 20 6f 72 20 63 75 72 72 65  corrupt or curre
10ef0 6e 74 6c 79 20 0a 20 20 2a 2a 20 62 65 69 6e 67  ntly .  ** being
10f00 20 6d 6f 64 69 66 69 65 64 20 62 79 20 61 6e 6f   modified by ano
10f10 74 68 65 72 20 74 68 72 65 61 64 20 6f 72 20 70  ther thread or p
10f20 72 6f 63 65 73 73 2e 0a 20 20 2a 2f 0a 20 20 62  rocess..  */.  b
10f30 61 64 48 64 72 20 3d 20 28 70 61 67 65 30 20 3f  adHdr = (page0 ?
10f40 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28   walIndexTryHdr(
10f50 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 20  pWal, pChanged) 
10f60 3a 20 31 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74  : 1);..  /* If t
10f70 68 65 20 66 69 72 73 74 20 61 74 74 65 6d 70 74  he first attempt
10f80 20 66 61 69 6c 65 64 2c 20 69 74 20 6d 69 67 68   failed, it migh
10f90 74 20 68 61 76 65 20 62 65 65 6e 20 64 75 65 20  t have been due 
10fa0 74 6f 20 61 20 72 61 63 65 0a 20 20 2a 2a 20 77  to a race.  ** w
10fb0 69 74 68 20 61 20 77 72 69 74 65 72 2e 20 20 53  ith a writer.  S
10fc0 6f 20 67 65 74 20 61 20 57 52 49 54 45 20 6c 6f  o get a WRITE lo
10fd0 63 6b 20 61 6e 64 20 74 72 79 20 61 67 61 69 6e  ck and try again
10fe0 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  ..  */.  assert(
10ff0 20 62 61 64 48 64 72 3d 3d 30 20 7c 7c 20 70 57   badHdr==0 || pW
11000 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30  al->writeLock==0
11010 20 29 3b 0a 20 20 69 66 28 20 62 61 64 48 64 72   );.  if( badHdr
11020 20 26 26 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28   && SQLITE_OK==(
11030 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
11040 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
11050 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 29 20  WRITE_LOCK, 1)) 
11060 29 7b 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72 69  ){.    pWal->wri
11070 74 65 4c 6f 63 6b 20 3d 20 31 3b 0a 20 20 20 20  teLock = 1;.    
11080 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28  if( SQLITE_OK==(
11090 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 50 61 67  rc = walIndexPag
110a0 65 28 70 57 61 6c 2c 20 30 2c 20 26 70 61 67 65  e(pWal, 0, &page
110b0 30 29 29 20 29 7b 0a 20 20 20 20 20 20 62 61 64  0)) ){.      bad
110c0 48 64 72 20 3d 20 77 61 6c 49 6e 64 65 78 54 72  Hdr = walIndexTr
110d0 79 48 64 72 28 70 57 61 6c 2c 20 70 43 68 61 6e  yHdr(pWal, pChan
110e0 67 65 64 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ged);.      if( 
110f0 62 61 64 48 64 72 20 29 7b 0a 20 20 20 20 20 20  badHdr ){.      
11100 20 20 2f 2a 20 49 66 20 74 68 65 20 77 61 6c 2d    /* If the wal-
11110 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20  index header is 
11120 73 74 69 6c 6c 20 6d 61 6c 66 6f 72 6d 65 64 20  still malformed 
11130 65 76 65 6e 20 77 68 69 6c 65 20 68 6f 6c 64 69  even while holdi
11140 6e 67 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 20  ng.        ** a 
11150 57 52 49 54 45 20 6c 6f 63 6b 2c 20 69 74 20 63  WRITE lock, it c
11160 61 6e 20 6f 6e 6c 79 20 6d 65 61 6e 20 74 68 61  an only mean tha
11170 74 20 74 68 65 20 68 65 61 64 65 72 20 69 73 20  t the header is 
11180 63 6f 72 72 75 70 74 65 64 20 61 6e 64 0a 20 20  corrupted and.  
11190 20 20 20 20 20 20 2a 2a 20 6e 65 65 64 73 20 74        ** needs t
111a0 6f 20 62 65 20 72 65 63 6f 6e 73 74 72 75 63 74  o be reconstruct
111b0 65 64 2e 20 20 53 6f 20 72 75 6e 20 72 65 63 6f  ed.  So run reco
111c0 76 65 72 79 20 74 6f 20 64 6f 20 65 78 61 63 74  very to do exact
111d0 6c 79 20 74 68 61 74 2e 0a 20 20 20 20 20 20 20  ly that..       
111e0 20 2a 2f 0a 20 20 20 20 20 20 20 20 72 63 20 3d   */.        rc =
111f0 20 77 61 6c 49 6e 64 65 78 52 65 63 6f 76 65 72   walIndexRecover
11200 28 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 20 20  (pWal);.        
11210 2a 70 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20  *pChanged = 1;. 
11220 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
11230 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
11240 20 3d 20 30 3b 0a 20 20 20 20 77 61 6c 55 6e 6c   = 0;.    walUnl
11250 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
11260 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43  l, WAL_WRITE_LOC
11270 4b 2c 20 31 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  K, 1);.  }..  /*
11280 20 49 66 20 74 68 65 20 68 65 61 64 65 72 20 69   If the header i
11290 73 20 72 65 61 64 20 73 75 63 63 65 73 73 66 75  s read successfu
112a0 6c 6c 79 2c 20 63 68 65 63 6b 20 74 68 65 20 76  lly, check the v
112b0 65 72 73 69 6f 6e 20 6e 75 6d 62 65 72 20 74 6f  ersion number to
112c0 20 6d 61 6b 65 0a 20 20 2a 2a 20 73 75 72 65 20   make.  ** sure 
112d0 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 77 61  the wal-index wa
112e0 73 20 6e 6f 74 20 63 6f 6e 73 74 72 75 63 74 65  s not constructe
112f0 64 20 77 69 74 68 20 73 6f 6d 65 20 66 75 74 75  d with some futu
11300 72 65 20 66 6f 72 6d 61 74 20 74 68 61 74 0a 20  re format that. 
11310 20 2a 2a 20 74 68 69 73 20 76 65 72 73 69 6f 6e   ** this version
11320 20 6f 66 20 53 51 4c 69 74 65 20 63 61 6e 6e 6f   of SQLite canno
11330 74 20 75 6e 64 65 72 73 74 61 6e 64 2e 0a 20 20  t understand..  
11340 2a 2f 0a 20 20 69 66 28 20 62 61 64 48 64 72 3d  */.  if( badHdr=
11350 3d 30 20 26 26 20 70 57 61 6c 2d 3e 68 64 72 2e  =0 && pWal->hdr.
11360 69 56 65 72 73 69 6f 6e 21 3d 57 41 4c 49 4e 44  iVersion!=WALIND
11370 45 58 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 20 29  EX_MAX_VERSION )
11380 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  {.    rc = SQLIT
11390 45 5f 43 41 4e 54 4f 50 45 4e 5f 42 4b 50 54 3b  E_CANTOPEN_BKPT;
113a0 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
113b0 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  c;.}../*.** This
113c0 20 69 73 20 74 68 65 20 76 61 6c 75 65 20 74 68   is the value th
113d0 61 74 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65  at walTryBeginRe
113e0 61 64 20 72 65 74 75 72 6e 73 20 77 68 65 6e 20  ad returns when 
113f0 69 74 20 6e 65 65 64 73 20 74 6f 0a 2a 2a 20 62  it needs to.** b
11400 65 20 72 65 74 72 69 65 64 2e 0a 2a 2f 0a 23 64  e retried..*/.#d
11410 65 66 69 6e 65 20 57 41 4c 5f 52 45 54 52 59 20  efine WAL_RETRY 
11420 20 28 2d 31 29 0a 0a 2f 2a 0a 2a 2a 20 41 74 74   (-1)../*.** Att
11430 65 6d 70 74 20 74 6f 20 73 74 61 72 74 20 61 20  empt to start a 
11440 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e  read transaction
11450 2e 20 20 54 68 69 73 20 6d 69 67 68 74 20 66 61  .  This might fa
11460 69 6c 20 64 75 65 20 74 6f 20 61 20 72 61 63 65  il due to a race
11470 20 6f 72 0a 2a 2a 20 6f 74 68 65 72 20 74 72 61   or.** other tra
11480 6e 73 69 65 6e 74 20 63 6f 6e 64 69 74 69 6f 6e  nsient condition
11490 2e 20 20 57 68 65 6e 20 74 68 61 74 20 68 61 70  .  When that hap
114a0 70 65 6e 73 2c 20 69 74 20 72 65 74 75 72 6e 73  pens, it returns
114b0 20 57 41 4c 5f 52 45 54 52 59 20 74 6f 0a 2a 2a   WAL_RETRY to.**
114c0 20 69 6e 64 69 63 61 74 65 20 74 6f 20 74 68 65   indicate to the
114d0 20 63 61 6c 6c 65 72 20 74 68 61 74 20 69 74 20   caller that it 
114e0 69 73 20 73 61 66 65 20 74 6f 20 72 65 74 72 79  is safe to retry
114f0 20 69 6d 6d 65 64 69 61 74 65 6c 79 2e 0a 2a 2a   immediately..**
11500 0a 2a 2a 20 4f 6e 20 73 75 63 63 65 73 73 20 72  .** On success r
11510 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e  eturn SQLITE_OK.
11520 20 20 4f 6e 20 61 20 70 65 72 6d 61 6e 65 6e 74    On a permanent
11530 20 66 61 69 6c 75 72 65 20 28 73 75 63 68 20 61   failure (such a
11540 6e 0a 2a 2a 20 49 2f 4f 20 65 72 72 6f 72 20 6f  n.** I/O error o
11550 72 20 61 6e 20 53 51 4c 49 54 45 5f 42 55 53 59  r an SQLITE_BUSY
11560 20 62 65 63 61 75 73 65 20 61 6e 6f 74 68 65 72   because another
11570 20 70 72 6f 63 65 73 73 20 69 73 20 72 75 6e 6e   process is runn
11580 69 6e 67 0a 2a 2a 20 72 65 63 6f 76 65 72 79 29  ing.** recovery)
11590 20 72 65 74 75 72 6e 20 61 20 70 6f 73 69 74 69   return a positi
115a0 76 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a  ve error code..*
115b0 2a 0a 2a 2a 20 54 68 65 20 75 73 65 57 61 6c 20  *.** The useWal 
115c0 70 61 72 61 6d 65 74 65 72 20 69 73 20 74 72 75  parameter is tru
115d0 65 20 74 6f 20 66 6f 72 63 65 20 74 68 65 20 75  e to force the u
115e0 73 65 20 6f 66 20 74 68 65 20 57 41 4c 20 61 6e  se of the WAL an
115f0 64 20 64 69 73 61 62 6c 65 0a 2a 2a 20 74 68 65  d disable.** the
11600 20 63 61 73 65 20 77 68 65 72 65 20 74 68 65 20   case where the 
11610 57 41 4c 20 69 73 20 62 79 70 61 73 73 65 64 20  WAL is bypassed 
11620 62 65 63 61 75 73 65 20 69 74 20 68 61 73 20 62  because it has b
11630 65 65 6e 20 63 6f 6d 70 6c 65 74 65 6c 79 0a 2a  een completely.*
11640 2a 20 63 68 65 63 6b 70 6f 69 6e 74 65 64 2e 20  * checkpointed. 
11650 20 49 66 20 75 73 65 57 61 6c 3d 3d 30 20 74 68   If useWal==0 th
11660 65 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  en this routine 
11670 63 61 6c 6c 73 20 77 61 6c 49 6e 64 65 78 52 65  calls walIndexRe
11680 61 64 48 64 72 28 29 20 0a 2a 2a 20 74 6f 20 6d  adHdr() .** to m
11690 61 6b 65 20 61 20 63 6f 70 79 20 6f 66 20 74 68  ake a copy of th
116a0 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
116b0 65 72 20 69 6e 74 6f 20 70 57 61 6c 2d 3e 68 64  er into pWal->hd
116c0 72 2e 20 20 49 66 20 74 68 65 20 0a 2a 2a 20 77  r.  If the .** w
116d0 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
116e0 68 61 73 20 63 68 61 6e 67 65 64 2c 20 2a 70 43  has changed, *pC
116f0 68 61 6e 67 65 64 20 69 73 20 73 65 74 20 74 6f  hanged is set to
11700 20 31 20 28 61 73 20 61 6e 20 69 6e 64 69 63 61   1 (as an indica
11710 74 69 6f 6e 20 0a 2a 2a 20 74 6f 20 74 68 65 20  tion .** to the 
11720 63 61 6c 6c 65 72 20 74 68 61 74 20 74 68 65 20  caller that the 
11730 6c 6f 63 61 6c 20 70 61 67 65 74 20 63 61 63 68  local paget cach
11740 65 20 69 73 20 6f 62 73 6f 6c 65 74 65 20 61 6e  e is obsolete an
11750 64 20 6e 65 65 64 73 20 74 6f 20 62 65 20 0a 2a  d needs to be .*
11760 2a 20 66 6c 75 73 68 65 64 2e 29 20 20 57 68 65  * flushed.)  Whe
11770 6e 20 75 73 65 57 61 6c 3d 3d 31 2c 20 74 68 65  n useWal==1, the
11780 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
11790 72 20 69 73 20 61 73 73 75 6d 65 64 20 74 6f 20  r is assumed to 
117a0 61 6c 72 65 61 64 79 0a 2a 2a 20 62 65 20 6c 6f  already.** be lo
117b0 61 64 65 64 20 61 6e 64 20 74 68 65 20 70 43 68  aded and the pCh
117c0 61 6e 67 65 64 20 70 61 72 61 6d 65 74 65 72 20  anged parameter 
117d0 69 73 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a  is unused..**.**
117e0 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74   The caller must
117f0 20 73 65 74 20 74 68 65 20 63 6e 74 20 70 61 72   set the cnt par
11800 61 6d 65 74 65 72 20 74 6f 20 74 68 65 20 6e 75  ameter to the nu
11810 6d 62 65 72 20 6f 66 20 70 72 69 6f 72 20 63 61  mber of prior ca
11820 6c 6c 73 20 74 6f 0a 2a 2a 20 74 68 69 73 20 72  lls to.** this r
11830 6f 75 74 69 6e 65 20 64 75 72 69 6e 67 20 74 68  outine during th
11840 65 20 63 75 72 72 65 6e 74 20 72 65 61 64 20 61  e current read a
11850 74 74 65 6d 70 74 20 74 68 61 74 20 72 65 74 75  ttempt that retu
11860 72 6e 65 64 20 57 41 4c 5f 52 45 54 52 59 2e 0a  rned WAL_RETRY..
11870 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
11880 77 69 6c 6c 20 73 74 61 72 74 20 74 61 6b 69 6e  will start takin
11890 67 20 6d 6f 72 65 20 61 67 67 72 65 73 73 69 76  g more aggressiv
118a0 65 20 6d 65 61 73 75 72 65 73 20 74 6f 20 63 6c  e measures to cl
118b0 65 61 72 20 74 68 65 0a 2a 2a 20 72 61 63 65 20  ear the.** race 
118c0 63 6f 6e 64 69 74 69 6f 6e 73 20 61 66 74 65 72  conditions after
118d0 20 6d 75 6c 74 69 70 6c 65 20 57 41 4c 5f 52 45   multiple WAL_RE
118e0 54 52 59 20 72 65 74 75 72 6e 73 2c 20 61 6e 64  TRY returns, and
118f0 20 61 66 74 65 72 20 61 6e 20 65 78 63 65 73 73   after an excess
11900 69 76 65 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66  ive.** number of
11910 20 65 72 72 6f 72 73 20 77 69 6c 6c 20 75 6c 74   errors will ult
11920 69 6d 61 74 65 6c 79 20 72 65 74 75 72 6e 20 53  imately return S
11930 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 2e 20  QLITE_PROTOCOL. 
11940 20 54 68 65 0a 2a 2a 20 53 51 4c 49 54 45 5f 50   The.** SQLITE_P
11950 52 4f 54 4f 43 4f 4c 20 72 65 74 75 72 6e 20 69  ROTOCOL return i
11960 6e 64 69 63 61 74 65 73 20 74 68 61 74 20 73 6f  ndicates that so
11970 6d 65 20 6f 74 68 65 72 20 70 72 6f 63 65 73 73  me other process
11980 20 68 61 73 20 67 6f 6e 65 20 72 6f 67 75 65 0a   has gone rogue.
11990 2a 2a 20 61 6e 64 20 69 73 20 6e 6f 74 20 68 6f  ** and is not ho
119a0 6e 6f 72 69 6e 67 20 74 68 65 20 6c 6f 63 6b 69  noring the locki
119b0 6e 67 20 70 72 6f 74 6f 63 6f 6c 2e 20 20 54 68  ng protocol.  Th
119c0 65 72 65 20 69 73 20 61 20 76 61 6e 69 73 68 69  ere is a vanishi
119d0 6e 67 6c 79 20 73 6d 61 6c 6c 0a 2a 2a 20 63 68  ngly small.** ch
119e0 61 6e 63 65 20 74 68 61 74 20 53 51 4c 49 54 45  ance that SQLITE
119f0 5f 50 52 4f 54 4f 43 4f 4c 20 63 6f 75 6c 64 20  _PROTOCOL could 
11a00 62 65 20 72 65 74 75 72 6e 65 64 20 62 65 63 61  be returned beca
11a10 75 73 65 20 6f 66 20 61 20 72 75 6e 20 6f 66 20  use of a run of 
11a20 72 65 61 6c 6c 79 0a 2a 2a 20 62 61 64 20 6c 75  really.** bad lu
11a30 63 6b 20 77 68 65 6e 20 74 68 65 72 65 20 69 73  ck when there is
11a40 20 6c 6f 74 73 20 6f 66 20 63 6f 6e 74 65 6e 74   lots of content
11a50 69 6f 6e 20 66 6f 72 20 74 68 65 20 77 61 6c 2d  ion for the wal-
11a60 69 6e 64 65 78 2c 20 62 75 74 20 74 68 61 74 0a  index, but that.
11a70 2a 2a 20 70 6f 73 73 69 62 69 6c 69 74 79 20 69  ** possibility i
11a80 73 20 73 6f 20 73 6d 61 6c 6c 20 74 68 61 74 20  s so small that 
11a90 69 74 20 63 61 6e 20 62 65 20 73 61 66 65 6c 79  it can be safely
11aa0 20 6e 65 67 6c 65 63 74 65 64 2c 20 77 65 20 62   neglected, we b
11ab0 65 6c 69 65 76 65 2e 0a 2a 2a 0a 2a 2a 20 4f 6e  elieve..**.** On
11ac0 20 73 75 63 63 65 73 73 2c 20 74 68 69 73 20 72   success, this r
11ad0 6f 75 74 69 6e 65 20 6f 62 74 61 69 6e 73 20 61  outine obtains a
11ae0 20 72 65 61 64 20 6c 6f 63 6b 20 6f 6e 20 0a 2a   read lock on .*
11af0 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  * WAL_READ_LOCK(
11b00 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 2e  pWal->readLock).
11b10 20 20 54 68 65 20 70 57 61 6c 2d 3e 72 65 61 64    The pWal->read
11b20 4c 6f 63 6b 20 69 6e 74 65 67 65 72 20 69 73 0a  Lock integer is.
11b30 2a 2a 20 69 6e 20 74 68 65 20 72 61 6e 67 65 20  ** in the range 
11b40 30 20 3c 3d 20 70 57 61 6c 2d 3e 72 65 61 64 4c  0 <= pWal->readL
11b50 6f 63 6b 20 3c 20 57 41 4c 5f 4e 52 45 41 44 45  ock < WAL_NREADE
11b60 52 2e 20 20 49 66 20 70 57 61 6c 2d 3e 72 65 61  R.  If pWal->rea
11b70 64 4c 6f 63 6b 3d 3d 28 2d 31 29 0a 2a 2a 20 74  dLock==(-1).** t
11b80 68 61 74 20 6d 65 61 6e 73 20 74 68 65 20 57 61  hat means the Wa
11b90 6c 20 64 6f 65 73 20 6e 6f 74 20 68 6f 6c 64 20  l does not hold 
11ba0 61 6e 79 20 72 65 61 64 20 6c 6f 63 6b 2e 20 20  any read lock.  
11bb0 54 68 65 20 72 65 61 64 65 72 20 6d 75 73 74 20  The reader must 
11bc0 6e 6f 74 0a 2a 2a 20 61 63 63 65 73 73 20 61 6e  not.** access an
11bd0 79 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20  y database page 
11be0 74 68 61 74 20 69 73 20 6d 6f 64 69 66 69 65 64  that is modified
11bf0 20 62 79 20 61 20 57 41 4c 20 66 72 61 6d 65 20   by a WAL frame 
11c00 75 70 20 74 6f 20 61 6e 64 0a 2a 2a 20 69 6e 63  up to and.** inc
11c10 6c 75 64 69 6e 67 20 66 72 61 6d 65 20 6e 75 6d  luding frame num
11c20 62 65 72 20 61 52 65 61 64 4d 61 72 6b 5b 70 57  ber aReadMark[pW
11c30 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 5d 2e 20 20  al->readLock].  
11c40 54 68 65 20 72 65 61 64 65 72 20 77 69 6c 6c 0a  The reader will.
11c50 2a 2a 20 75 73 65 20 57 41 4c 20 66 72 61 6d 65  ** use WAL frame
11c60 73 20 75 70 20 74 6f 20 61 6e 64 20 69 6e 63 6c  s up to and incl
11c70 75 64 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e  uding pWal->hdr.
11c80 6d 78 46 72 61 6d 65 20 69 66 20 70 57 61 6c 2d  mxFrame if pWal-
11c90 3e 72 65 61 64 4c 6f 63 6b 3e 30 0a 2a 2a 20 4f  >readLock>0.** O
11ca0 72 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c  r if pWal->readL
11cb0 6f 63 6b 3d 3d 30 2c 20 74 68 65 6e 20 74 68 65  ock==0, then the
11cc0 20 72 65 61 64 65 72 20 77 69 6c 6c 20 69 67 6e   reader will ign
11cd0 6f 72 65 20 74 68 65 20 57 41 4c 0a 2a 2a 20 63  ore the WAL.** c
11ce0 6f 6d 70 6c 65 74 65 6c 79 20 61 6e 64 20 67 65  ompletely and ge
11cf0 74 20 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69  t all content di
11d00 72 65 63 74 6c 79 20 66 72 6f 6d 20 74 68 65 20  rectly from the 
11d10 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a  database file..*
11d20 2a 20 49 66 20 74 68 65 20 75 73 65 57 61 6c 20  * If the useWal 
11d30 70 61 72 61 6d 65 74 65 72 20 69 73 20 31 20 74  parameter is 1 t
11d40 68 65 6e 20 74 68 65 20 57 41 4c 20 77 69 6c 6c  hen the WAL will
11d50 20 6e 65 76 65 72 20 62 65 20 69 67 6e 6f 72 65   never be ignore
11d60 64 20 61 6e 64 0a 2a 2a 20 74 68 69 73 20 72 6f  d and.** this ro
11d70 75 74 69 6e 65 20 77 69 6c 6c 20 61 6c 77 61 79  utine will alway
11d80 73 20 73 65 74 20 70 57 61 6c 2d 3e 72 65 61 64  s set pWal->read
11d90 4c 6f 63 6b 3e 30 20 6f 6e 20 73 75 63 63 65 73  Lock>0 on succes
11da0 73 2e 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 72  s..** When the r
11db0 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
11dc0 69 73 20 63 6f 6d 70 6c 65 74 65 64 2c 20 74 68  is completed, th
11dd0 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 72 65  e caller must re
11de0 6c 65 61 73 65 20 74 68 65 0a 2a 2a 20 6c 6f 63  lease the.** loc
11df0 6b 20 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  k on WAL_READ_LO
11e00 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  CK(pWal->readLoc
11e10 6b 29 20 61 6e 64 20 73 65 74 20 70 57 61 6c 2d  k) and set pWal-
11e20 3e 72 65 61 64 4c 6f 63 6b 20 74 6f 20 2d 31 2e  >readLock to -1.
11e30 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74  .**.** This rout
11e40 69 6e 65 20 75 73 65 73 20 74 68 65 20 6e 42 61  ine uses the nBa
11e50 63 6b 66 69 6c 6c 20 61 6e 64 20 61 52 65 61 64  ckfill and aRead
11e60 4d 61 72 6b 5b 5d 20 66 69 65 6c 64 73 20 6f 66  Mark[] fields of
11e70 20 74 68 65 20 68 65 61 64 65 72 0a 2a 2a 20 74   the header.** t
11e80 6f 20 73 65 6c 65 63 74 20 61 20 70 61 72 74 69  o select a parti
11e90 63 75 6c 61 72 20 57 41 4c 5f 52 45 41 44 5f 4c  cular WAL_READ_L
11ea0 4f 43 4b 28 29 20 74 68 61 74 20 73 74 72 69 76  OCK() that striv
11eb0 65 73 20 74 6f 20 6c 65 74 20 74 68 65 0a 2a 2a  es to let the.**
11ec0 20 63 68 65 63 6b 70 6f 69 6e 74 20 70 72 6f 63   checkpoint proc
11ed0 65 73 73 20 64 6f 20 61 73 20 6d 75 63 68 20 77  ess do as much w
11ee0 6f 72 6b 20 61 73 20 70 6f 73 73 69 62 6c 65 2e  ork as possible.
11ef0 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 6d    This routine m
11f00 69 67 68 74 0a 2a 2a 20 75 70 64 61 74 65 20 76  ight.** update v
11f10 61 6c 75 65 73 20 6f 66 20 74 68 65 20 61 52 65  alues of the aRe
11f20 61 64 4d 61 72 6b 5b 5d 20 61 72 72 61 79 20 69  adMark[] array i
11f30 6e 20 74 68 65 20 68 65 61 64 65 72 2c 20 62 75  n the header, bu
11f40 74 20 69 66 20 69 74 20 64 6f 65 73 0a 2a 2a 20  t if it does.** 
11f50 73 6f 20 69 74 20 74 61 6b 65 73 20 63 61 72 65  so it takes care
11f60 20 74 6f 20 68 6f 6c 64 20 61 6e 20 65 78 63 6c   to hold an excl
11f70 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 74 68  usive lock on th
11f80 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a  e corresponding.
11f90 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  ** WAL_READ_LOCK
11fa0 28 29 20 77 68 69 6c 65 20 63 68 61 6e 67 69 6e  () while changin
11fb0 67 20 76 61 6c 75 65 73 2e 0a 2a 2f 0a 73 74 61  g values..*/.sta
11fc0 74 69 63 20 69 6e 74 20 77 61 6c 54 72 79 42 65  tic int walTryBe
11fd0 67 69 6e 52 65 61 64 28 57 61 6c 20 2a 70 57 61  ginRead(Wal *pWa
11fe0 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e 67 65 64  l, int *pChanged
11ff0 2c 20 69 6e 74 20 75 73 65 57 61 6c 2c 20 69 6e  , int useWal, in
12000 74 20 63 6e 74 29 7b 0a 20 20 76 6f 6c 61 74 69  t cnt){.  volati
12010 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a  le WalCkptInfo *
12020 70 49 6e 66 6f 3b 20 20 20 20 2f 2a 20 43 68 65  pInfo;    /* Che
12030 63 6b 70 6f 69 6e 74 20 69 6e 66 6f 72 6d 61 74  ckpoint informat
12040 69 6f 6e 20 69 6e 20 77 61 6c 2d 69 6e 64 65 78  ion in wal-index
12050 20 2a 2f 0a 20 20 75 33 32 20 6d 78 52 65 61 64   */.  u32 mxRead
12060 4d 61 72 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Mark;           
12070 20 20 20 20 20 20 2f 2a 20 4c 61 72 67 65 73 74        /* Largest
12080 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 76 61 6c   aReadMark[] val
12090 75 65 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 49 3b  ue */.  int mxI;
120a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
120b0 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78          /* Index
120c0 20 6f 66 20 6c 61 72 67 65 73 74 20 61 52 65 61   of largest aRea
120d0 64 4d 61 72 6b 5b 5d 20 76 61 6c 75 65 20 2a 2f  dMark[] value */
120e0 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
120f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12100 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74     /* Loop count
12110 65 72 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d  er */.  int rc =
12120 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
12130 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
12140 6e 20 63 6f 64 65 20 20 2a 2f 0a 0a 20 20 61 73  n code  */..  as
12150 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64  sert( pWal->read
12160 4c 6f 63 6b 3c 30 20 29 3b 20 20 20 20 20 2f 2a  Lock<0 );     /*
12170 20 4e 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 6c   Not currently l
12180 6f 63 6b 65 64 20 2a 2f 0a 0a 20 20 2f 2a 20 54  ocked */..  /* T
12190 61 6b 65 20 73 74 65 70 73 20 74 6f 20 61 76 6f  ake steps to avo
121a0 69 64 20 73 70 69 6e 6e 69 6e 67 20 66 6f 72 65  id spinning fore
121b0 76 65 72 20 69 66 20 74 68 65 72 65 20 69 73 20  ver if there is 
121c0 61 20 70 72 6f 74 6f 63 6f 6c 20 65 72 72 6f 72  a protocol error
121d0 2e 20 2a 2f 0a 20 20 69 66 28 20 63 6e 74 3e 35  . */.  if( cnt>5
121e0 20 29 7b 0a 20 20 20 20 69 66 28 20 63 6e 74 3e   ){.    if( cnt>
121f0 31 30 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  100 ) return SQL
12200 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 3b 0a 20 20  ITE_PROTOCOL;.  
12210 20 20 73 71 6c 69 74 65 33 4f 73 53 6c 65 65 70    sqlite3OsSleep
12220 28 70 57 61 6c 2d 3e 70 56 66 73 2c 20 31 29 3b  (pWal->pVfs, 1);
12230 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21 75 73 65  .  }..  if( !use
12240 57 61 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  Wal ){.    rc = 
12250 77 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28  walIndexReadHdr(
12260 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b  pWal, pChanged);
12270 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
12280 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20  ITE_BUSY ){.    
12290 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73    /* If there is
122a0 20 6e 6f 74 20 61 20 72 65 63 6f 76 65 72 79 20   not a recovery 
122b0 72 75 6e 6e 69 6e 67 20 69 6e 20 61 6e 6f 74 68  running in anoth
122c0 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f  er thread or pro
122d0 63 65 73 73 0a 20 20 20 20 20 20 2a 2a 20 74 68  cess.      ** th
122e0 65 6e 20 63 6f 6e 76 65 72 74 20 42 55 53 59 20  en convert BUSY 
122f0 65 72 72 6f 72 73 20 74 6f 20 57 41 4c 5f 52 45  errors to WAL_RE
12300 54 52 59 2e 20 20 49 66 20 72 65 63 6f 76 65 72  TRY.  If recover
12310 79 20 69 73 20 6b 6e 6f 77 6e 20 74 6f 0a 20 20  y is known to.  
12320 20 20 20 20 2a 2a 20 62 65 20 72 75 6e 6e 69 6e      ** be runnin
12330 67 2c 20 63 6f 6e 76 65 72 74 20 42 55 53 59 20  g, convert BUSY 
12340 74 6f 20 42 55 53 59 5f 52 45 43 4f 56 45 52 59  to BUSY_RECOVERY
12350 2e 20 20 54 68 65 72 65 20 69 73 20 61 20 72 61  .  There is a ra
12360 63 65 20 68 65 72 65 0a 20 20 20 20 20 20 2a 2a  ce here.      **
12370 20 77 68 69 63 68 20 6d 69 67 68 74 20 63 61 75   which might cau
12380 73 65 20 57 41 4c 5f 52 45 54 52 59 20 74 6f 20  se WAL_RETRY to 
12390 62 65 20 72 65 74 75 72 6e 65 64 20 65 76 65 6e  be returned even
123a0 20 69 66 20 42 55 53 59 5f 52 45 43 4f 56 45 52   if BUSY_RECOVER
123b0 59 0a 20 20 20 20 20 20 2a 2a 20 77 6f 75 6c 64  Y.      ** would
123c0 20 62 65 20 74 65 63 68 6e 69 63 61 6c 6c 79 20   be technically 
123d0 63 6f 72 72 65 63 74 2e 20 20 42 75 74 20 74 68  correct.  But th
123e0 65 20 72 61 63 65 20 69 73 20 62 65 6e 69 67 6e  e race is benign
123f0 20 73 69 6e 63 65 20 77 69 74 68 0a 20 20 20 20   since with.    
12400 20 20 2a 2a 20 57 41 4c 5f 52 45 54 52 59 20 74    ** WAL_RETRY t
12410 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c  his routine will
12420 20 62 65 20 63 61 6c 6c 65 64 20 61 67 61 69 6e   be called again
12430 20 61 6e 64 20 77 69 6c 6c 20 70 72 6f 62 61 62   and will probab
12440 6c 79 20 62 65 0a 20 20 20 20 20 20 2a 2a 20 72  ly be.      ** r
12450 69 67 68 74 20 6f 6e 20 74 68 65 20 73 65 63 6f  ight on the seco
12460 6e 64 20 69 74 65 72 61 74 69 6f 6e 2e 0a 20 20  nd iteration..  
12470 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28      */.      if(
12480 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
12490 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  0]==0 ){.       
124a0 20 2f 2a 20 54 68 69 73 20 62 72 61 6e 63 68 20   /* This branch 
124b0 69 73 20 74 61 6b 65 6e 20 77 68 65 6e 20 74 68  is taken when th
124c0 65 20 78 53 68 6d 4d 61 70 28 29 20 6d 65 74 68  e xShmMap() meth
124d0 6f 64 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  od returns SQLIT
124e0 45 5f 42 55 53 59 2e 0a 20 20 20 20 20 20 20 20  E_BUSY..        
124f0 2a 2a 20 57 65 20 61 73 73 75 6d 65 20 74 68 69  ** We assume thi
12500 73 20 69 73 20 61 20 74 72 61 6e 73 69 65 6e 74  s is a transient
12510 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 73 6f 20 72   condition, so r
12520 65 74 75 72 6e 20 57 41 4c 5f 52 45 54 52 59 2e  eturn WAL_RETRY.
12530 20 54 68 65 0a 20 20 20 20 20 20 20 20 2a 2a 20   The.        ** 
12540 78 53 68 6d 4d 61 70 28 29 20 69 6d 70 6c 65 6d  xShmMap() implem
12550 65 6e 74 61 74 69 6f 6e 20 75 73 65 64 20 62 79  entation used by
12560 20 74 68 65 20 64 65 66 61 75 6c 74 20 75 6e 69   the default uni
12570 78 20 61 6e 64 20 77 69 6e 33 32 20 56 46 53 20  x and win32 VFS 
12580 0a 20 20 20 20 20 20 20 20 2a 2a 20 6d 6f 64 75  .        ** modu
12590 6c 65 73 20 6d 61 79 20 72 65 74 75 72 6e 20 53  les may return S
125a0 51 4c 49 54 45 5f 42 55 53 59 20 64 75 65 20 74  QLITE_BUSY due t
125b0 6f 20 61 20 72 61 63 65 20 63 6f 6e 64 69 74 69  o a race conditi
125c0 6f 6e 20 69 6e 20 74 68 65 20 0a 20 20 20 20 20  on in the .     
125d0 20 20 20 2a 2a 20 63 6f 64 65 20 74 68 61 74 20     ** code that 
125e0 64 65 74 65 72 6d 69 6e 65 73 20 77 68 65 74 68  determines wheth
125f0 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 73 68  er or not the sh
12600 61 72 65 64 2d 6d 65 6d 6f 72 79 20 72 65 67 69  ared-memory regi
12610 6f 6e 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 6d  on .        ** m
12620 75 73 74 20 62 65 20 7a 65 72 6f 65 64 20 62 65  ust be zeroed be
12630 66 6f 72 65 20 74 68 65 20 72 65 71 75 65 73 74  fore the request
12640 65 64 20 70 61 67 65 20 69 73 20 72 65 74 75 72  ed page is retur
12650 6e 65 64 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a  ned..        */.
12660 20 20 20 20 20 20 20 20 72 63 20 3d 20 57 41 4c          rc = WAL
12670 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 65  _RETRY;.      }e
12680 6c 73 65 20 69 66 28 20 53 51 4c 49 54 45 5f 4f  lse if( SQLITE_O
12690 4b 3d 3d 28 72 63 20 3d 20 77 61 6c 4c 6f 63 6b  K==(rc = walLock
126a0 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c  Shared(pWal, WAL
126b0 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 29 29 20  _RECOVER_LOCK)) 
126c0 29 7b 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e  ){.        walUn
126d0 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  lockShared(pWal,
126e0 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43   WAL_RECOVER_LOC
126f0 4b 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  K);.        rc =
12700 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20   WAL_RETRY;.    
12710 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d    }else if( rc==
12720 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20  SQLITE_BUSY ){. 
12730 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
12740 54 45 5f 42 55 53 59 5f 52 45 43 4f 56 45 52 59  TE_BUSY_RECOVERY
12750 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
12760 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
12770 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  TE_OK ){.      r
12780 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
12790 20 20 7d 0a 0a 20 20 70 49 6e 66 6f 20 3d 20 77    }..  pInfo = w
127a0 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29  alCkptInfo(pWal)
127b0 3b 0a 20 20 69 66 28 20 21 75 73 65 57 61 6c 20  ;.  if( !useWal 
127c0 26 26 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66  && pInfo->nBackf
127d0 69 6c 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d  ill==pWal->hdr.m
127e0 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 2f 2a  xFrame ){.    /*
127f0 20 54 68 65 20 57 41 4c 20 68 61 73 20 62 65 65   The WAL has bee
12800 6e 20 63 6f 6d 70 6c 65 74 65 6c 79 20 62 61 63  n completely bac
12810 6b 66 69 6c 6c 65 64 20 28 6f 72 20 69 74 20 69  kfilled (or it i
12820 73 20 65 6d 70 74 79 29 2e 0a 20 20 20 20 2a 2a  s empty)..    **
12830 20 61 6e 64 20 63 61 6e 20 62 65 20 73 61 66 65   and can be safe
12840 6c 79 20 69 67 6e 6f 72 65 64 2e 0a 20 20 20 20  ly ignored..    
12850 2a 2f 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 4c  */.    rc = walL
12860 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20  ockShared(pWal, 
12870 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29  WAL_READ_LOCK(0)
12880 29 3b 0a 20 20 20 20 77 61 6c 53 68 6d 42 61 72  );.    walShmBar
12890 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20 20 20  rier(pWal);.    
128a0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
128b0 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 6d  K ){.      if( m
128c0 65 6d 63 6d 70 28 28 76 6f 69 64 20 2a 29 77 61  emcmp((void *)wa
128d0 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29 2c  lIndexHdr(pWal),
128e0 20 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69 7a   &pWal->hdr, siz
128f0 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29  eof(WalIndexHdr)
12900 29 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20  ) ){.        /* 
12910 49 74 20 69 73 20 6e 6f 74 20 73 61 66 65 20 74  It is not safe t
12920 6f 20 61 6c 6c 6f 77 20 74 68 65 20 72 65 61 64  o allow the read
12930 65 72 20 74 6f 20 63 6f 6e 74 69 6e 75 65 20 68  er to continue h
12940 65 72 65 20 69 66 20 66 72 61 6d 65 73 0a 20 20  ere if frames.  
12950 20 20 20 20 20 20 2a 2a 20 6d 61 79 20 68 61 76        ** may hav
12960 65 20 62 65 65 6e 20 61 70 70 65 6e 64 65 64 20  e been appended 
12970 74 6f 20 74 68 65 20 6c 6f 67 20 62 65 66 6f 72  to the log befor
12980 65 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20 77  e READ_LOCK(0) w
12990 61 73 20 6f 62 74 61 69 6e 65 64 2e 0a 20 20 20  as obtained..   
129a0 20 20 20 20 20 2a 2a 20 57 68 65 6e 20 68 6f 6c       ** When hol
129b0 64 69 6e 67 20 52 45 41 44 5f 4c 4f 43 4b 28 30  ding READ_LOCK(0
129c0 29 2c 20 74 68 65 20 72 65 61 64 65 72 20 69 67  ), the reader ig
129d0 6e 6f 72 65 73 20 74 68 65 20 65 6e 74 69 72 65  nores the entire
129e0 20 6c 6f 67 20 66 69 6c 65 2c 0a 20 20 20 20 20   log file,.     
129f0 20 20 20 2a 2a 20 77 68 69 63 68 20 69 6d 70 6c     ** which impl
12a00 69 65 73 20 74 68 61 74 20 74 68 65 20 64 61 74  ies that the dat
12a10 61 62 61 73 65 20 66 69 6c 65 20 63 6f 6e 74 61  abase file conta
12a20 69 6e 73 20 61 20 74 72 75 73 74 77 6f 72 74 68  ins a trustworth
12a30 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 6e 61  y.        ** sna
12a40 70 73 68 6f 54 2e 20 53 69 6e 63 65 20 68 6f 6c  pshoT. Since hol
12a50 64 69 6e 67 20 52 45 41 44 5f 4c 4f 43 4b 28 30  ding READ_LOCK(0
12a60 29 20 70 72 65 76 65 6e 74 73 20 61 20 63 68 65  ) prevents a che
12a70 63 6b 70 6f 69 6e 74 20 66 72 6f 6d 0a 20 20 20  ckpoint from.   
12a80 20 20 20 20 20 2a 2a 20 68 61 70 70 65 6e 69 6e       ** happenin
12a90 67 2c 20 74 68 69 73 20 69 73 20 75 73 75 61 6c  g, this is usual
12aa0 6c 79 20 63 6f 72 72 65 63 74 2e 0a 20 20 20 20  ly correct..    
12ab0 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a      **.        *
12ac0 2a 20 48 6f 77 65 76 65 72 2c 20 69 66 20 66 72  * However, if fr
12ad0 61 6d 65 73 20 68 61 76 65 20 62 65 65 6e 20 61  ames have been a
12ae0 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 6c  ppended to the l
12af0 6f 67 20 28 6f 72 20 69 66 20 74 68 65 20 6c 6f  og (or if the lo
12b00 67 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 69 73  g .        ** is
12b10 20 77 72 61 70 70 65 64 20 61 6e 64 20 77 72 69   wrapped and wri
12b20 74 74 65 6e 20 66 6f 72 20 74 68 61 74 20 6d 61  tten for that ma
12b30 74 74 65 72 29 20 62 65 66 6f 72 65 20 74 68 65  tter) before the
12b40 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29 0a 20 20   READ_LOCK(0).  
12b50 20 20 20 20 20 20 2a 2a 20 69 73 20 6f 62 74 61        ** is obta
12b60 69 6e 65 64 2c 20 74 68 61 74 20 69 73 20 6e 6f  ined, that is no
12b70 74 20 6e 65 63 65 73 73 61 72 69 6c 79 20 74 72  t necessarily tr
12b80 75 65 2e 20 41 20 63 68 65 63 6b 70 6f 69 6e 74  ue. A checkpoint
12b90 65 72 20 6d 61 79 0a 20 20 20 20 20 20 20 20 2a  er may.        *
12ba0 2a 20 68 61 76 65 20 73 74 61 72 74 65 64 20 74  * have started t
12bb0 6f 20 62 61 63 6b 66 69 6c 6c 20 74 68 65 20 61  o backfill the a
12bc0 70 70 65 6e 64 65 64 20 66 72 61 6d 65 73 20 62  ppended frames b
12bd0 75 74 20 63 72 61 73 68 65 64 20 62 65 66 6f 72  ut crashed befor
12be0 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 69 74 20  e.        ** it 
12bf0 66 69 6e 69 73 68 65 64 2e 20 4c 65 61 76 69 6e  finished. Leavin
12c00 67 20 61 20 63 6f 72 72 75 70 74 20 69 6d 61 67  g a corrupt imag
12c10 65 20 69 6e 20 74 68 65 20 64 61 74 61 62 61 73  e in the databas
12c20 65 20 66 69 6c 65 2e 0a 20 20 20 20 20 20 20 20  e file..        
12c30 2a 2f 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e  */.        walUn
12c40 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  lockShared(pWal,
12c50 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
12c60 29 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75  ));.        retu
12c70 72 6e 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20  rn WAL_RETRY;.  
12c80 20 20 20 20 7d 0a 20 20 20 20 20 20 70 57 61 6c      }.      pWal
12c90 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 30 3b 0a  ->readLock = 0;.
12ca0 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c        return SQL
12cb0 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 65 6c 73  ITE_OK;.    }els
12cc0 65 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45  e if( rc!=SQLITE
12cd0 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20 72  _BUSY ){.      r
12ce0 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
12cf0 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 77 65 20    }..  /* If we 
12d00 67 65 74 20 74 68 69 73 20 66 61 72 2c 20 69 74  get this far, it
12d10 20 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65 20   means that the 
12d20 72 65 61 64 65 72 20 77 69 6c 6c 20 77 61 6e 74  reader will want
12d30 20 74 6f 20 75 73 65 0a 20 20 2a 2a 20 74 68 65   to use.  ** the
12d40 20 57 41 4c 20 74 6f 20 67 65 74 20 61 74 20 63   WAL to get at c
12d50 6f 6e 74 65 6e 74 20 66 72 6f 6d 20 72 65 63 65  ontent from rece
12d60 6e 74 20 63 6f 6d 6d 69 74 73 2e 20 20 54 68 65  nt commits.  The
12d70 20 6a 6f 62 20 6e 6f 77 20 69 73 0a 20 20 2a 2a   job now is.  **
12d80 20 74 6f 20 73 65 6c 65 63 74 20 6f 6e 65 20 6f   to select one o
12d90 66 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b  f the aReadMark[
12da0 5d 20 65 6e 74 72 69 65 73 20 74 68 61 74 20 69  ] entries that i
12db0 73 20 63 6c 6f 73 65 73 74 20 74 6f 0a 20 20 2a  s closest to.  *
12dc0 2a 20 62 75 74 20 6e 6f 74 20 65 78 63 65 65 64  * but not exceed
12dd0 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  ing pWal->hdr.mx
12de0 46 72 61 6d 65 20 61 6e 64 20 6c 6f 63 6b 20 74  Frame and lock t
12df0 68 61 74 20 65 6e 74 72 79 2e 0a 20 20 2a 2f 0a  hat entry..  */.
12e00 20 20 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20 30    mxReadMark = 0
12e10 3b 0a 20 20 6d 78 49 20 3d 20 30 3b 0a 20 20 66  ;.  mxI = 0;.  f
12e20 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52  or(i=1; i<WAL_NR
12e30 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20  EADER; i++){.   
12e40 20 75 33 32 20 74 68 69 73 4d 61 72 6b 20 3d 20   u32 thisMark = 
12e50 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b  pInfo->aReadMark
12e60 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 6d 78 52  [i];.    if( mxR
12e70 65 61 64 4d 61 72 6b 3c 3d 74 68 69 73 4d 61 72  eadMark<=thisMar
12e80 6b 20 26 26 20 74 68 69 73 4d 61 72 6b 3c 3d 70  k && thisMark<=p
12e90 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
12ea0 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74   ){.      assert
12eb0 28 20 74 68 69 73 4d 61 72 6b 21 3d 52 45 41 44  ( thisMark!=READ
12ec0 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 20 29 3b  MARK_NOT_USED );
12ed0 0a 20 20 20 20 20 20 6d 78 52 65 61 64 4d 61 72  .      mxReadMar
12ee0 6b 20 3d 20 74 68 69 73 4d 61 72 6b 3b 0a 20 20  k = thisMark;.  
12ef0 20 20 20 20 6d 78 49 20 3d 20 69 3b 0a 20 20 20      mxI = i;.   
12f00 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 6d 78 49   }.  }.  if( mxI
12f10 3d 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20 49 66  ==0 ){.    /* If
12f20 20 77 65 20 67 65 74 20 68 65 72 65 2c 20 69 74   we get here, it
12f30 20 6d 65 61 6e 73 20 74 68 61 74 20 61 6c 6c 20   means that all 
12f40 6f 66 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b  of the aReadMark
12f50 5b 5d 20 65 6e 74 72 69 65 73 20 62 65 74 77 65  [] entries betwe
12f60 65 6e 0a 20 20 20 20 2a 2a 20 31 20 61 6e 64 20  en.    ** 1 and 
12f70 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31 20 61 72  WAL_NREADER-1 ar
12f80 65 20 7a 65 72 6f 2e 20 20 54 72 79 20 74 6f 20  e zero.  Try to 
12f90 69 6e 69 74 69 61 6c 69 7a 65 20 61 52 65 61 64  initialize aRead
12fa0 4d 61 72 6b 5b 31 5d 20 74 6f 0a 20 20 20 20 2a  Mark[1] to.    *
12fb0 2a 20 62 65 20 6d 78 46 72 61 6d 65 2c 20 74 68  * be mxFrame, th
12fc0 65 6e 20 72 65 74 72 79 2e 0a 20 20 20 20 2a 2f  en retry..    */
12fd0 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63  .    rc = walLoc
12fe0 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
12ff0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31   WAL_READ_LOCK(1
13000 29 2c 20 31 29 3b 0a 20 20 20 20 69 66 28 20 72  ), 1);.    if( r
13010 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
13020 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 61 52 65        pInfo->aRe
13030 61 64 4d 61 72 6b 5b 31 5d 20 3d 20 70 57 61 6c  adMark[1] = pWal
13040 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20  ->hdr.mxFrame;. 
13050 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78       walUnlockEx
13060 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
13070 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20  L_READ_LOCK(1), 
13080 31 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 57  1);.      rc = W
13090 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 7d 65  AL_RETRY;.    }e
130a0 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  lse if( rc==SQLI
130b0 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20  TE_BUSY ){.     
130c0 20 72 63 20 3d 20 57 41 4c 5f 52 45 54 52 59 3b   rc = WAL_RETRY;
130d0 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72  .    }.    retur
130e0 6e 20 72 63 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  n rc;.  }else{. 
130f0 20 20 20 69 66 28 20 6d 78 52 65 61 64 4d 61 72     if( mxReadMar
13100 6b 20 3c 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  k < pWal->hdr.mx
13110 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 20 20 66  Frame ){.      f
13120 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52  or(i=1; i<WAL_NR
13130 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20  EADER; i++){.   
13140 20 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63       rc = walLoc
13150 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
13160 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69   WAL_READ_LOCK(i
13170 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20 69  ), 1);.        i
13180 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
13190 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6d 78   ){.          mx
131a0 52 65 61 64 4d 61 72 6b 20 3d 20 70 49 6e 66 6f  ReadMark = pInfo
131b0 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d  ->aReadMark[i] =
131c0 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
131d0 6d 65 3b 0a 20 20 20 20 20 20 20 20 20 20 6d 78  me;.          mx
131e0 49 20 3d 20 69 3b 0a 20 20 20 20 20 20 20 20 20  I = i;.         
131f0 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
13200 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  ive(pWal, WAL_RE
13210 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a  AD_LOCK(i), 1);.
13220 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
13230 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69  .        }else i
13240 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55  f( rc!=SQLITE_BU
13250 53 59 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  SY ){.          
13260 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20  return rc;.     
13270 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
13280 20 7d 0a 0a 20 20 20 20 72 63 20 3d 20 77 61 6c   }..    rc = wal
13290 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  LockShared(pWal,
132a0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d   WAL_READ_LOCK(m
132b0 78 49 29 29 3b 0a 20 20 20 20 69 66 28 20 72 63  xI));.    if( rc
132c0 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
132d0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc==SQLITE_BUSY
132e0 20 3f 20 57 41 4c 5f 52 45 54 52 59 20 3a 20 72   ? WAL_RETRY : r
132f0 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20  c;.    }.    /* 
13300 4e 6f 77 20 74 68 61 74 20 74 68 65 20 72 65 61  Now that the rea
13310 64 2d 6c 6f 63 6b 20 68 61 73 20 62 65 65 6e 20  d-lock has been 
13320 6f 62 74 61 69 6e 65 64 2c 20 63 68 65 63 6b 20  obtained, check 
13330 74 68 61 74 20 6e 65 69 74 68 65 72 20 74 68 65  that neither the
13340 0a 20 20 20 20 2a 2a 20 76 61 6c 75 65 20 69 6e  .    ** value in
13350 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d   the aReadMark[]
13360 20 61 72 72 61 79 20 6f 72 20 74 68 65 20 63 6f   array or the co
13370 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 77 61  ntents of the wa
13380 6c 2d 69 6e 64 65 78 0a 20 20 20 20 2a 2a 20 68  l-index.    ** h
13390 65 61 64 65 72 20 68 61 76 65 20 63 68 61 6e 67  eader have chang
133a0 65 64 2e 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a  ed..    **.    *
133b0 2a 20 49 74 20 69 73 20 6e 65 63 65 73 73 61 72  * It is necessar
133c0 79 20 74 6f 20 63 68 65 63 6b 20 74 68 61 74 20  y to check that 
133d0 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
133e0 61 64 65 72 20 64 69 64 20 6e 6f 74 20 63 68 61  ader did not cha
133f0 6e 67 65 0a 20 20 20 20 2a 2a 20 62 65 74 77 65  nge.    ** betwe
13400 65 6e 20 74 68 65 20 74 69 6d 65 20 69 74 20 77  en the time it w
13410 61 73 20 72 65 61 64 20 61 6e 64 20 77 68 65 6e  as read and when
13420 20 74 68 65 20 73 68 61 72 65 64 2d 6c 6f 63 6b   the shared-lock
13430 20 77 61 73 20 6f 62 74 61 69 6e 65 64 0a 20 20   was obtained.  
13440 20 20 2a 2a 20 6f 6e 20 57 41 4c 5f 52 45 41 44    ** on WAL_READ
13450 5f 4c 4f 43 4b 28 6d 78 49 29 20 77 61 73 20 6f  _LOCK(mxI) was o
13460 62 74 61 69 6e 65 64 20 74 6f 20 61 63 63 6f 75  btained to accou
13470 6e 74 20 66 6f 72 20 74 68 65 20 70 6f 73 73 69  nt for the possi
13480 62 69 6c 69 74 79 0a 20 20 20 20 2a 2a 20 74 68  bility.    ** th
13490 61 74 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 20  at the log file 
134a0 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 77 72  may have been wr
134b0 61 70 70 65 64 20 62 79 20 61 20 77 72 69 74 65  apped by a write
134c0 72 2c 20 6f 72 20 74 68 61 74 20 66 72 61 6d 65  r, or that frame
134d0 73 0a 20 20 20 20 2a 2a 20 74 68 61 74 20 6f 63  s.    ** that oc
134e0 63 75 72 20 6c 61 74 65 72 20 69 6e 20 74 68 65  cur later in the
134f0 20 6c 6f 67 20 74 68 61 6e 20 70 57 61 6c 2d 3e   log than pWal->
13500 68 64 72 2e 6d 78 46 72 61 6d 65 20 6d 61 79 20  hdr.mxFrame may 
13510 68 61 76 65 20 62 65 65 6e 0a 20 20 20 20 2a 2a  have been.    **
13520 20 63 6f 70 69 65 64 20 69 6e 74 6f 20 74 68 65   copied into the
13530 20 64 61 74 61 62 61 73 65 20 62 79 20 61 20 63   database by a c
13540 68 65 63 6b 70 6f 69 6e 74 65 72 2e 20 49 66 20  heckpointer. If 
13550 65 69 74 68 65 72 20 6f 66 20 74 68 65 73 65 20  either of these 
13560 74 68 69 6e 67 73 0a 20 20 20 20 2a 2a 20 68 61  things.    ** ha
13570 70 70 65 6e 65 64 2c 20 74 68 65 6e 20 72 65 61  ppened, then rea
13580 64 69 6e 67 20 74 68 65 20 64 61 74 61 62 61 73  ding the databas
13590 65 20 77 69 74 68 20 74 68 65 20 63 75 72 72 65  e with the curre
135a0 6e 74 20 76 61 6c 75 65 20 6f 66 0a 20 20 20 20  nt value of.    
135b0 2a 2a 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ** pWal->hdr.mxF
135c0 72 61 6d 65 20 72 69 73 6b 73 20 72 65 61 64 69  rame risks readi
135d0 6e 67 20 61 20 63 6f 72 72 75 70 74 65 64 20 73  ng a corrupted s
135e0 6e 61 70 73 68 6f 74 2e 20 53 6f 2c 20 72 65 74  napshot. So, ret
135f0 72 79 0a 20 20 20 20 2a 2a 20 69 6e 73 74 65 61  ry.    ** instea
13600 64 2e 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a  d..    **.    **
13610 20 54 68 69 73 20 64 6f 65 73 20 6e 6f 74 20 67   This does not g
13620 75 61 72 61 6e 74 65 65 20 74 68 61 74 20 74 68  uarantee that th
13630 65 20 63 6f 70 79 20 6f 66 20 74 68 65 20 77 61  e copy of the wa
13640 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69  l-index header i
13650 73 20 75 70 20 74 6f 0a 20 20 20 20 2a 2a 20 64  s up to.    ** d
13660 61 74 65 20 62 65 66 6f 72 65 20 70 72 6f 63 65  ate before proce
13670 65 64 69 6e 67 2e 20 54 68 61 74 20 77 6f 75 6c  eding. That woul
13680 64 20 6e 6f 74 20 62 65 20 70 6f 73 73 69 62 6c  d not be possibl
13690 65 20 77 69 74 68 6f 75 74 20 73 6f 6d 65 68 6f  e without someho
136a0 77 0a 20 20 20 20 2a 2a 20 62 6c 6f 63 6b 69 6e  w.    ** blockin
136b0 67 20 77 72 69 74 65 72 73 2e 20 49 74 20 6f 6e  g writers. It on
136c0 6c 79 20 67 75 61 72 61 6e 74 65 65 73 20 74 68  ly guarantees th
136d0 61 74 20 61 20 64 61 6e 67 65 72 6f 75 73 20 63  at a dangerous c
136e0 68 65 63 6b 70 6f 69 6e 74 20 6f 72 20 0a 20 20  heckpoint or .  
136f0 20 20 2a 2a 20 6c 6f 67 2d 77 72 61 70 20 28 65    ** log-wrap (e
13700 69 74 68 65 72 20 6f 66 20 77 68 69 63 68 20 77  ither of which w
13710 6f 75 6c 64 20 72 65 71 75 69 72 65 20 61 6e 20  ould require an 
13720 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f  exclusive lock o
13730 6e 0a 20 20 20 20 2a 2a 20 57 41 4c 5f 52 45 41  n.    ** WAL_REA
13740 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 20 68 61 73  D_LOCK(mxI)) has
13750 20 6e 6f 74 20 6f 63 63 75 72 72 65 64 20 73 69   not occurred si
13760 6e 63 65 20 74 68 65 20 73 6e 61 70 73 68 6f 74  nce the snapshot
13770 20 77 61 73 20 76 61 6c 69 64 2e 0a 20 20 20 20   was valid..    
13780 2a 2f 0a 20 20 20 20 77 61 6c 53 68 6d 42 61 72  */.    walShmBar
13790 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20 20 20  rier(pWal);.    
137a0 69 66 28 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64  if( pInfo->aRead
137b0 4d 61 72 6b 5b 6d 78 49 5d 21 3d 6d 78 52 65 61  Mark[mxI]!=mxRea
137c0 64 4d 61 72 6b 0a 20 20 20 20 20 7c 7c 20 6d 65  dMark.     || me
137d0 6d 63 6d 70 28 28 76 6f 69 64 20 2a 29 77 61 6c  mcmp((void *)wal
137e0 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29 2c 20  IndexHdr(pWal), 
137f0 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69 7a 65  &pWal->hdr, size
13800 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
13810 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 77 61  .    ){.      wa
13820 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57  lUnlockShared(pW
13830 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  al, WAL_READ_LOC
13840 4b 28 6d 78 49 29 29 3b 0a 20 20 20 20 20 20 72  K(mxI));.      r
13850 65 74 75 72 6e 20 57 41 4c 5f 52 45 54 52 59 3b  eturn WAL_RETRY;
13860 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
13870 20 20 61 73 73 65 72 74 28 20 6d 78 52 65 61 64    assert( mxRead
13880 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e  Mark<=pWal->hdr.
13890 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20 20 20  mxFrame );.     
138a0 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20   pWal->readLock 
138b0 3d 20 28 69 31 36 29 6d 78 49 3b 0a 20 20 20 20  = (i16)mxI;.    
138c0 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  }.  }.  return r
138d0 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42 65 67 69  c;.}../*.** Begi
138e0 6e 20 61 20 72 65 61 64 20 74 72 61 6e 73 61 63  n a read transac
138f0 74 69 6f 6e 20 6f 6e 20 74 68 65 20 64 61 74 61  tion on the data
13900 62 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  base..**.** This
13910 20 72 6f 75 74 69 6e 65 20 75 73 65 64 20 74 6f   routine used to
13920 20 62 65 20 63 61 6c 6c 65 64 20 73 71 6c 69 74   be called sqlit
13930 65 33 4f 70 65 6e 53 6e 61 70 73 68 6f 74 28 29  e3OpenSnapshot()
13940 20 61 6e 64 20 77 69 74 68 20 67 6f 6f 64 20 72   and with good r
13950 65 61 73 6f 6e 3a 0a 2a 2a 20 69 74 20 74 61 6b  eason:.** it tak
13960 65 73 20 61 20 73 6e 61 70 73 68 6f 74 20 6f 66  es a snapshot of
13970 20 74 68 65 20 73 74 61 74 65 20 6f 66 20 74 68   the state of th
13980 65 20 57 41 4c 20 61 6e 64 20 77 61 6c 2d 69 6e  e WAL and wal-in
13990 64 65 78 20 66 6f 72 20 74 68 65 20 63 75 72 72  dex for the curr
139a0 65 6e 74 0a 2a 2a 20 69 6e 73 74 61 6e 74 20 69  ent.** instant i
139b0 6e 20 74 69 6d 65 2e 20 20 54 68 65 20 63 75 72  n time.  The cur
139c0 72 65 6e 74 20 74 68 72 65 61 64 20 77 69 6c 6c  rent thread will
139d0 20 63 6f 6e 74 69 6e 75 65 20 74 6f 20 75 73 65   continue to use
139e0 20 74 68 69 73 20 73 6e 61 70 73 68 6f 74 2e 0a   this snapshot..
139f0 2a 2a 20 4f 74 68 65 72 20 74 68 72 65 61 64 73  ** Other threads
13a00 20 6d 69 67 68 74 20 61 70 70 65 6e 64 20 6e 65   might append ne
13a10 77 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74 68 65  w content to the
13a20 20 57 41 4c 20 61 6e 64 20 77 61 6c 2d 69 6e 64   WAL and wal-ind
13a30 65 78 20 62 75 74 0a 2a 2a 20 74 68 61 74 20 65  ex but.** that e
13a40 78 74 72 61 20 63 6f 6e 74 65 6e 74 20 69 73 20  xtra content is 
13a50 69 67 6e 6f 72 65 64 20 62 79 20 74 68 65 20 63  ignored by the c
13a60 75 72 72 65 6e 74 20 74 68 72 65 61 64 2e 0a 2a  urrent thread..*
13a70 2a 0a 2a 2a 20 49 66 20 74 68 65 20 64 61 74 61  *.** If the data
13a80 62 61 73 65 20 63 6f 6e 74 65 6e 74 73 20 68 61  base contents ha
13a90 76 65 20 63 68 61 6e 67 65 73 20 73 69 6e 63 65  ve changes since
13aa0 20 74 68 65 20 70 72 65 76 69 6f 75 73 20 72 65   the previous re
13ab0 61 64 0a 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f  ad.** transactio
13ac0 6e 2c 20 74 68 65 6e 20 2a 70 43 68 61 6e 67 65  n, then *pChange
13ad0 64 20 69 73 20 73 65 74 20 74 6f 20 31 20 62 65  d is set to 1 be
13ae0 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 20  fore returning. 
13af0 20 54 68 65 0a 2a 2a 20 50 61 67 65 72 20 6c 61   The.** Pager la
13b00 79 65 72 20 77 69 6c 6c 20 75 73 65 20 74 68 69  yer will use thi
13b10 73 20 74 6f 20 6b 6e 6f 77 20 74 68 61 74 20 69  s to know that i
13b20 73 20 63 61 63 68 65 20 69 73 20 73 74 61 6c 65  s cache is stale
13b30 20 61 6e 64 0a 2a 2a 20 6e 65 65 64 73 20 74 6f   and.** needs to
13b40 20 62 65 20 66 6c 75 73 68 65 64 2e 0a 2a 2f 0a   be flushed..*/.
13b50 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 42 65  int sqlite3WalBe
13b60 67 69 6e 52 65 61 64 54 72 61 6e 73 61 63 74 69  ginReadTransacti
13b70 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e  on(Wal *pWal, in
13b80 74 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a 20 20  t *pChanged){.  
13b90 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
13ba0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13bb0 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
13bc0 2f 0a 20 20 69 6e 74 20 63 6e 74 20 3d 20 30 3b  /.  int cnt = 0;
13bd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13be0 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
13bf0 20 54 72 79 42 65 67 69 6e 52 65 61 64 20 61 74   TryBeginRead at
13c00 74 65 6d 70 74 73 20 2a 2f 0a 0a 20 20 64 6f 7b  tempts */..  do{
13c10 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 54 72 79  .    rc = walTry
13c20 42 65 67 69 6e 52 65 61 64 28 70 57 61 6c 2c 20  BeginRead(pWal, 
13c30 70 43 68 61 6e 67 65 64 2c 20 30 2c 20 2b 2b 63  pChanged, 0, ++c
13c40 6e 74 29 3b 0a 20 20 7d 77 68 69 6c 65 28 20 72  nt);.  }while( r
13c50 63 3d 3d 57 41 4c 5f 52 45 54 52 59 20 29 3b 0a  c==WAL_RETRY );.
13c60 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
13c70 2f 2a 0a 2a 2a 20 46 69 6e 69 73 68 20 77 69 74  /*.** Finish wit
13c80 68 20 61 20 72 65 61 64 20 74 72 61 6e 73 61 63  h a read transac
13c90 74 69 6f 6e 2e 20 20 41 6c 6c 20 74 68 69 73 20  tion.  All this 
13ca0 64 6f 65 73 20 69 73 20 72 65 6c 65 61 73 65 20  does is release 
13cb0 74 68 65 0a 2a 2a 20 72 65 61 64 2d 6c 6f 63 6b  the.** read-lock
13cc0 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
13cd0 33 57 61 6c 45 6e 64 52 65 61 64 54 72 61 6e 73  3WalEndReadTrans
13ce0 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c  action(Wal *pWal
13cf0 29 7b 0a 20 20 73 71 6c 69 74 65 33 57 61 6c 45  ){.  sqlite3WalE
13d00 6e 64 57 72 69 74 65 54 72 61 6e 73 61 63 74 69  ndWriteTransacti
13d10 6f 6e 28 70 57 61 6c 29 3b 0a 20 20 69 66 28 20  on(pWal);.  if( 
13d20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
13d30 30 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f  0 ){.    walUnlo
13d40 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
13d50 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61  AL_READ_LOCK(pWa
13d60 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 3b 0a 20  l->readLock));. 
13d70 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63     pWal->readLoc
13d80 6b 20 3d 20 2d 31 3b 0a 20 20 7d 0a 7d 0a 0a 2f  k = -1;.  }.}../
13d90 2a 0a 2a 2a 20 52 65 61 64 20 61 20 70 61 67 65  *.** Read a page
13da0 20 66 72 6f 6d 20 74 68 65 20 57 41 4c 2c 20 69   from the WAL, i
13db0 66 20 69 74 20 69 73 20 70 72 65 73 65 6e 74 20  f it is present 
13dc0 69 6e 20 74 68 65 20 57 41 4c 20 61 6e 64 20 69  in the WAL and i
13dd0 66 20 74 68 65 20 0a 2a 2a 20 63 75 72 72 65 6e  f the .** curren
13de0 74 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  t read transacti
13df0 6f 6e 20 69 73 20 63 6f 6e 66 69 67 75 72 65 64  on is configured
13e00 20 74 6f 20 75 73 65 20 74 68 65 20 57 41 4c 2e   to use the WAL.
13e10 20 20 0a 2a 2a 0a 2a 2a 20 54 68 65 20 2a 70 49    .**.** The *pI
13e20 6e 57 61 6c 20 69 73 20 73 65 74 20 74 6f 20 31  nWal is set to 1
13e30 20 69 66 20 74 68 65 20 72 65 71 75 65 73 74 65   if the requeste
13e40 64 20 70 61 67 65 20 69 73 20 69 6e 20 74 68 65  d page is in the
13e50 20 57 41 4c 20 61 6e 64 0a 2a 2a 20 68 61 73 20   WAL and.** has 
13e60 62 65 65 6e 20 6c 6f 61 64 65 64 2e 20 20 4f 72  been loaded.  Or
13e70 20 2a 70 49 6e 57 61 6c 20 69 73 20 73 65 74 20   *pInWal is set 
13e80 74 6f 20 30 20 69 66 20 74 68 65 20 70 61 67 65  to 0 if the page
13e90 20 77 61 73 20 6e 6f 74 20 69 6e 20 0a 2a 2a 20   was not in .** 
13ea0 74 68 65 20 57 41 4c 20 61 6e 64 20 6e 65 65 64  the WAL and need
13eb0 73 20 74 6f 20 62 65 20 72 65 61 64 20 6f 75 74  s to be read out
13ec0 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65   of the database
13ed0 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
13ee0 57 61 6c 52 65 61 64 28 0a 20 20 57 61 6c 20 2a  WalRead(.  Wal *
13ef0 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  pWal,           
13f00 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41             /* WA
13f10 4c 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 50 67  L handle */.  Pg
13f20 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20 20 20  no pgno,        
13f30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
13f40 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20 6e   Database page n
13f50 75 6d 62 65 72 20 74 6f 20 72 65 61 64 20 64 61  umber to read da
13f60 74 61 20 66 6f 72 20 2a 2f 0a 20 20 69 6e 74 20  ta for */.  int 
13f70 2a 70 49 6e 57 61 6c 2c 20 20 20 20 20 20 20 20  *pInWal,        
13f80 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
13f90 55 54 3a 20 54 72 75 65 20 69 66 20 64 61 74 61  UT: True if data
13fa0 20 69 73 20 72 65 61 64 20 66 72 6f 6d 20 57 41   is read from WA
13fb0 4c 20 2a 2f 0a 20 20 69 6e 74 20 6e 4f 75 74 2c  L */.  int nOut,
13fc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13fd0 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
13fe0 66 20 62 75 66 66 65 72 20 70 4f 75 74 20 69 6e  f buffer pOut in
13ff0 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 38 20 2a   bytes */.  u8 *
14000 70 4f 75 74 20 20 20 20 20 20 20 20 20 20 20 20  pOut            
14010 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
14020 75 66 66 65 72 20 74 6f 20 77 72 69 74 65 20 70  uffer to write p
14030 61 67 65 20 64 61 74 61 20 74 6f 20 2a 2f 0a 29  age data to */.)
14040 7b 0a 20 20 75 33 32 20 69 52 65 61 64 20 3d 20  {.  u32 iRead = 
14050 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
14060 20 20 20 20 2f 2a 20 49 66 20 21 3d 30 2c 20 57      /* If !=0, W
14070 41 4c 20 66 72 61 6d 65 20 74 6f 20 72 65 74 75  AL frame to retu
14080 72 6e 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f 0a  rn data from */.
14090 20 20 75 33 32 20 69 4c 61 73 74 20 3d 20 70 57    u32 iLast = pW
140a0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b  al->hdr.mxFrame;
140b0 20 20 2f 2a 20 4c 61 73 74 20 70 61 67 65 20 69    /* Last page i
140c0 6e 20 57 41 4c 20 66 6f 72 20 74 68 69 73 20 72  n WAL for this r
140d0 65 61 64 65 72 20 2a 2f 0a 20 20 69 6e 74 20 69  eader */.  int i
140e0 48 61 73 68 3b 20 20 20 20 20 20 20 20 20 20 20  Hash;           
140f0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73             /* Us
14100 65 64 20 74 6f 20 6c 6f 6f 70 20 74 68 72 6f 75  ed to loop throu
14110 67 68 20 4e 20 68 61 73 68 20 74 61 62 6c 65 73  gh N hash tables
14120 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 69 73 20 72   */..  /* This r
14130 6f 75 74 69 6e 65 20 69 73 20 6f 6e 6c 79 20 62  outine is only b
14140 65 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69  e called from wi
14150 74 68 69 6e 20 61 20 72 65 61 64 20 74 72 61 6e  thin a read tran
14160 73 61 63 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73  saction. */.  as
14170 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64  sert( pWal->read
14180 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70 57 61 6c 2d  Lock>=0 || pWal-
14190 3e 6c 6f 63 6b 45 72 72 6f 72 20 29 3b 0a 0a 20  >lockError );.. 
141a0 20 2f 2a 20 49 66 20 74 68 65 20 22 6c 61 73 74   /* If the "last
141b0 20 70 61 67 65 22 20 66 69 65 6c 64 20 6f 66 20   page" field of 
141c0 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
141d0 61 64 65 72 20 73 6e 61 70 73 68 6f 74 20 69 73  ader snapshot is
141e0 20 30 2c 20 74 68 65 6e 0a 20 20 2a 2a 20 6e 6f   0, then.  ** no
141f0 20 64 61 74 61 20 77 69 6c 6c 20 62 65 20 72 65   data will be re
14200 61 64 20 66 72 6f 6d 20 74 68 65 20 77 61 6c 20  ad from the wal 
14210 75 6e 64 65 72 20 61 6e 79 20 63 69 72 63 75 6d  under any circum
14220 73 74 61 6e 63 65 73 2e 20 52 65 74 75 72 6e 20  stances. Return 
14230 65 61 72 6c 79 0a 20 20 2a 2a 20 69 6e 20 74 68  early.  ** in th
14240 69 73 20 63 61 73 65 20 61 73 20 61 6e 20 6f 70  is case as an op
14250 74 69 6d 69 7a 61 74 69 6f 6e 2e 20 20 4c 69 6b  timization.  Lik
14260 65 77 69 73 65 2c 20 69 66 20 70 57 61 6c 2d 3e  ewise, if pWal->
14270 72 65 61 64 4c 6f 63 6b 3d 3d 30 2c 20 0a 20 20  readLock==0, .  
14280 2a 2a 20 74 68 65 6e 20 74 68 65 20 57 41 4c 20  ** then the WAL 
14290 69 73 20 69 67 6e 6f 72 65 64 20 62 79 20 74 68  is ignored by th
142a0 65 20 72 65 61 64 65 72 20 73 6f 20 72 65 74 75  e reader so retu
142b0 72 6e 20 65 61 72 6c 79 2c 20 61 73 20 69 66 20  rn early, as if 
142c0 74 68 65 20 0a 20 20 2a 2a 20 57 41 4c 20 77 65  the .  ** WAL we
142d0 72 65 20 65 6d 70 74 79 2e 0a 20 20 2a 2f 0a 20  re empty..  */. 
142e0 20 69 66 28 20 69 4c 61 73 74 3d 3d 30 20 7c 7c   if( iLast==0 ||
142f0 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d   pWal->readLock=
14300 3d 30 20 29 7b 0a 20 20 20 20 2a 70 49 6e 57 61  =0 ){.    *pInWa
14310 6c 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75 72  l = 0;.    retur
14320 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d  n SQLITE_OK;.  }
14330 0a 0a 20 20 2f 2a 20 53 65 61 72 63 68 20 74 68  ..  /* Search th
14340 65 20 68 61 73 68 20 74 61 62 6c 65 20 6f 72 20  e hash table or 
14350 74 61 62 6c 65 73 20 66 6f 72 20 61 6e 20 65 6e  tables for an en
14360 74 72 79 20 6d 61 74 63 68 69 6e 67 20 70 61 67  try matching pag
14370 65 20 6e 75 6d 62 65 72 0a 20 20 2a 2a 20 70 67  e number.  ** pg
14380 6e 6f 2e 20 45 61 63 68 20 69 74 65 72 61 74 69  no. Each iterati
14390 6f 6e 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77  on of the follow
143a0 69 6e 67 20 66 6f 72 28 29 20 6c 6f 6f 70 20 73  ing for() loop s
143b0 65 61 72 63 68 65 73 20 6f 6e 65 0a 20 20 2a 2a  earches one.  **
143c0 20 68 61 73 68 20 74 61 62 6c 65 20 28 65 61 63   hash table (eac
143d0 68 20 68 61 73 68 20 74 61 62 6c 65 20 69 6e 64  h hash table ind
143e0 65 78 65 73 20 75 70 20 74 6f 20 48 41 53 48 54  exes up to HASHT
143f0 41 42 4c 45 5f 4e 50 41 47 45 20 66 72 61 6d 65  ABLE_NPAGE frame
14400 73 29 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68  s)..  **.  ** Th
14410 69 73 20 63 6f 64 65 20 6d 69 67 68 74 20 72 75  is code might ru
14420 6e 20 63 6f 6e 63 75 72 72 65 6e 74 6c 79 20 74  n concurrently t
14430 6f 20 74 68 65 20 63 6f 64 65 20 69 6e 20 77 61  o the code in wa
14440 6c 49 6e 64 65 78 41 70 70 65 6e 64 28 29 0a 20  lIndexAppend(). 
14450 20 2a 2a 20 74 68 61 74 20 61 64 64 73 20 65 6e   ** that adds en
14460 74 72 69 65 73 20 74 6f 20 74 68 65 20 77 61 6c  tries to the wal
14470 2d 69 6e 64 65 78 20 28 61 6e 64 20 70 6f 73 73  -index (and poss
14480 69 62 6c 79 20 74 6f 20 74 68 69 73 20 68 61 73  ibly to this has
14490 68 20 0a 20 20 2a 2a 20 74 61 62 6c 65 29 2e 20  h .  ** table). 
144a0 54 68 69 73 20 6d 65 61 6e 73 20 74 68 65 20 76  This means the v
144b0 61 6c 75 65 20 6a 75 73 74 20 72 65 61 64 20 66  alue just read f
144c0 72 6f 6d 20 74 68 65 20 68 61 73 68 20 0a 20 20  rom the hash .  
144d0 2a 2a 20 73 6c 6f 74 20 28 61 48 61 73 68 5b 69  ** slot (aHash[i
144e0 4b 65 79 5d 29 20 6d 61 79 20 68 61 76 65 20 62  Key]) may have b
144f0 65 65 6e 20 61 64 64 65 64 20 62 65 66 6f 72 65  een added before
14500 20 6f 72 20 61 66 74 65 72 20 74 68 65 20 0a 20   or after the . 
14510 20 2a 2a 20 63 75 72 72 65 6e 74 20 72 65 61 64   ** current read
14520 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61 73   transaction was
14530 20 6f 70 65 6e 65 64 2e 20 56 61 6c 75 65 73 20   opened. Values 
14540 61 64 64 65 64 20 61 66 74 65 72 20 74 68 65 0a  added after the.
14550 20 20 2a 2a 20 72 65 61 64 20 74 72 61 6e 73 61    ** read transa
14560 63 74 69 6f 6e 20 77 61 73 20 6f 70 65 6e 65 64  ction was opened
14570 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 77   may have been w
14580 72 69 74 74 65 6e 20 69 6e 63 6f 72 72 65 63 74  ritten incorrect
14590 6c 79 20 2d 0a 20 20 2a 2a 20 69 2e 65 2e 20 74  ly -.  ** i.e. t
145a0 68 65 73 65 20 73 6c 6f 74 73 20 6d 61 79 20 63  hese slots may c
145b0 6f 6e 74 61 69 6e 20 67 61 72 62 61 67 65 20 64  ontain garbage d
145c0 61 74 61 2e 20 48 6f 77 65 76 65 72 2c 20 77 65  ata. However, we
145d0 20 61 73 73 75 6d 65 0a 20 20 2a 2a 20 74 68 61   assume.  ** tha
145e0 74 20 61 6e 79 20 73 6c 6f 74 73 20 77 72 69 74  t any slots writ
145f0 74 65 6e 20 62 65 66 6f 72 65 20 74 68 65 20 63  ten before the c
14600 75 72 72 65 6e 74 20 72 65 61 64 20 74 72 61 6e  urrent read tran
14610 73 61 63 74 69 6f 6e 20 77 61 73 0a 20 20 2a 2a  saction was.  **
14620 20 6f 70 65 6e 65 64 20 72 65 6d 61 69 6e 20 75   opened remain u
14630 6e 6d 6f 64 69 66 69 65 64 2e 0a 20 20 2a 2a 0a  nmodified..  **.
14640 20 20 2a 2a 20 46 6f 72 20 74 68 65 20 72 65 61    ** For the rea
14650 73 6f 6e 73 20 61 62 6f 76 65 2c 20 74 68 65 20  sons above, the 
14660 69 66 28 2e 2e 2e 29 20 63 6f 6e 64 69 74 69 6f  if(...) conditio
14670 6e 20 66 65 61 74 75 72 65 64 20 69 6e 20 74 68  n featured in th
14680 65 20 69 6e 6e 65 72 0a 20 20 2a 2a 20 6c 6f 6f  e inner.  ** loo
14690 70 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  p of the followi
146a0 6e 67 20 62 6c 6f 63 6b 20 69 73 20 6d 6f 72 65  ng block is more
146b0 20 73 74 72 69 6e 67 65 6e 74 20 74 68 61 74 20   stringent that 
146c0 77 6f 75 6c 64 20 62 65 20 72 65 71 75 69 72 65  would be require
146d0 64 20 0a 20 20 2a 2a 20 69 66 20 77 65 20 68 61  d .  ** if we ha
146e0 64 20 65 78 63 6c 75 73 69 76 65 20 61 63 63 65  d exclusive acce
146f0 73 73 20 74 6f 20 74 68 65 20 68 61 73 68 2d 74  ss to the hash-t
14700 61 62 6c 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20  able:.  **.  ** 
14710 20 20 28 61 50 67 6e 6f 5b 69 46 72 61 6d 65 5d    (aPgno[iFrame]
14720 3d 3d 70 67 6e 6f 29 3a 20 0a 20 20 2a 2a 20 20  ==pgno): .  **  
14730 20 20 20 54 68 69 73 20 63 6f 6e 64 69 74 69 6f     This conditio
14740 6e 20 66 69 6c 74 65 72 73 20 6f 75 74 20 6e 6f  n filters out no
14750 72 6d 61 6c 20 68 61 73 68 2d 74 61 62 6c 65 20  rmal hash-table 
14760 63 6f 6c 6c 69 73 69 6f 6e 73 2e 0a 20 20 2a 2a  collisions..  **
14770 0a 20 20 2a 2a 20 20 20 28 69 46 72 61 6d 65 3c  .  **   (iFrame<
14780 3d 69 4c 61 73 74 29 3a 20 0a 20 20 2a 2a 20 20  =iLast): .  **  
14790 20 20 20 54 68 69 73 20 63 6f 6e 64 69 74 69 6f     This conditio
147a0 6e 20 66 69 6c 74 65 72 73 20 6f 75 74 20 65 6e  n filters out en
147b0 74 72 69 65 73 20 74 68 61 74 20 77 65 72 65 20  tries that were 
147c0 61 64 64 65 64 20 74 6f 20 74 68 65 20 68 61 73  added to the has
147d0 68 0a 20 20 2a 2a 20 20 20 20 20 74 61 62 6c 65  h.  **     table
147e0 20 61 66 74 65 72 20 74 68 65 20 63 75 72 72 65   after the curre
147f0 6e 74 20 72 65 61 64 2d 74 72 61 6e 73 61 63 74  nt read-transact
14800 69 6f 6e 20 68 61 64 20 73 74 61 72 74 65 64 2e  ion had started.
14810 0a 20 20 2a 2f 0a 20 20 66 6f 72 28 69 48 61 73  .  */.  for(iHas
14820 68 3d 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69  h=walFramePage(i
14830 4c 61 73 74 29 3b 20 69 48 61 73 68 3e 3d 30 20  Last); iHash>=0 
14840 26 26 20 69 52 65 61 64 3d 3d 30 3b 20 69 48 61  && iRead==0; iHa
14850 73 68 2d 2d 29 7b 0a 20 20 20 20 76 6f 6c 61 74  sh--){.    volat
14860 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61  ile ht_slot *aHa
14870 73 68 3b 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e  sh;      /* Poin
14880 74 65 72 20 74 6f 20 68 61 73 68 20 74 61 62 6c  ter to hash tabl
14890 65 20 2a 2f 0a 20 20 20 20 76 6f 6c 61 74 69 6c  e */.    volatil
148a0 65 20 75 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20  e u32 *aPgno;   
148b0 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
148c0 72 20 74 6f 20 61 72 72 61 79 20 6f 66 20 70 61  r to array of pa
148d0 67 65 20 6e 75 6d 62 65 72 73 20 2a 2f 0a 20 20  ge numbers */.  
148e0 20 20 75 33 32 20 69 5a 65 72 6f 3b 20 20 20 20    u32 iZero;    
148f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14900 2f 2a 20 46 72 61 6d 65 20 6e 75 6d 62 65 72 20  /* Frame number 
14910 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f  corresponding to
14920 20 61 50 67 6e 6f 5b 30 5d 20 2a 2f 0a 20 20 20   aPgno[0] */.   
14930 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20 20   int iKey;      
14940 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
14950 2a 20 48 61 73 68 20 73 6c 6f 74 20 69 6e 64 65  * Hash slot inde
14960 78 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 43 6f  x */.    int nCo
14970 6c 6c 69 64 65 3b 20 20 20 20 20 20 20 20 20 20  llide;          
14980 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
14990 20 6f 66 20 68 61 73 68 20 63 6f 6c 6c 69 73 69   of hash collisi
149a0 6f 6e 73 20 72 65 6d 61 69 6e 69 6e 67 20 2a 2f  ons remaining */
149b0 0a 20 20 20 20 69 6e 74 20 72 63 3b 20 20 20 20  .    int rc;    
149c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
149d0 20 20 20 2f 2a 20 45 72 72 6f 72 20 63 6f 64 65     /* Error code
149e0 20 2a 2f 0a 0a 20 20 20 20 72 63 20 3d 20 77 61   */..    rc = wa
149f0 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c 20 69  lHashGet(pWal, i
14a00 48 61 73 68 2c 20 26 61 48 61 73 68 2c 20 26 61  Hash, &aHash, &a
14a10 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 20  Pgno, &iZero);. 
14a20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
14a30 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65  E_OK ){.      re
14a40 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20  turn rc;.    }. 
14a50 20 20 20 6e 43 6f 6c 6c 69 64 65 20 3d 20 48 41     nCollide = HA
14a60 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 0a 20  SHTABLE_NSLOT;. 
14a70 20 20 20 66 6f 72 28 69 4b 65 79 3d 77 61 6c 48     for(iKey=walH
14a80 61 73 68 28 70 67 6e 6f 29 3b 20 61 48 61 73 68  ash(pgno); aHash
14a90 5b 69 4b 65 79 5d 3b 20 69 4b 65 79 3d 77 61 6c  [iKey]; iKey=wal
14aa0 4e 65 78 74 48 61 73 68 28 69 4b 65 79 29 29 7b  NextHash(iKey)){
14ab0 0a 20 20 20 20 20 20 75 33 32 20 69 46 72 61 6d  .      u32 iFram
14ac0 65 20 3d 20 61 48 61 73 68 5b 69 4b 65 79 5d 20  e = aHash[iKey] 
14ad0 2b 20 69 5a 65 72 6f 3b 0a 20 20 20 20 20 20 69  + iZero;.      i
14ae0 66 28 20 69 46 72 61 6d 65 3c 3d 69 4c 61 73 74  f( iFrame<=iLast
14af0 20 26 26 20 61 50 67 6e 6f 5b 61 48 61 73 68 5b   && aPgno[aHash[
14b00 69 4b 65 79 5d 5d 3d 3d 70 67 6e 6f 20 29 7b 0a  iKey]]==pgno ){.
14b10 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28 20          assert( 
14b20 69 46 72 61 6d 65 3e 69 52 65 61 64 20 29 3b 0a  iFrame>iRead );.
14b30 20 20 20 20 20 20 20 20 69 52 65 61 64 20 3d 20          iRead = 
14b40 69 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 7d 0a  iFrame;.      }.
14b50 20 20 20 20 20 20 69 66 28 20 28 6e 43 6f 6c 6c        if( (nColl
14b60 69 64 65 2d 2d 29 3d 3d 30 20 29 7b 0a 20 20 20  ide--)==0 ){.   
14b70 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
14b80 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b  TE_CORRUPT_BKPT;
14b90 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
14ba0 20 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54   }..#ifdef SQLIT
14bb0 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
14bc0 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20 49  VE_ASSERT.  /* I
14bd0 66 20 65 78 70 65 6e 73 69 76 65 20 61 73 73 65  f expensive asse
14be0 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74 73 20  rt() statements 
14bf0 61 72 65 20 61 76 61 69 6c 61 62 6c 65 2c 20 64  are available, d
14c00 6f 20 61 20 6c 69 6e 65 61 72 20 73 65 61 72 63  o a linear searc
14c10 68 0a 20 20 2a 2a 20 6f 66 20 74 68 65 20 77 61  h.  ** of the wa
14c20 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20 63 6f 6e  l-index file con
14c30 74 65 6e 74 2e 20 4d 61 6b 65 20 73 75 72 65 20  tent. Make sure 
14c40 74 68 65 20 72 65 73 75 6c 74 73 20 61 67 72 65  the results agre
14c50 65 20 77 69 74 68 20 74 68 65 0a 20 20 2a 2a 20  e with the.  ** 
14c60 72 65 73 75 6c 74 20 6f 62 74 61 69 6e 65 64 20  result obtained 
14c70 75 73 69 6e 67 20 74 68 65 20 68 61 73 68 20 69  using the hash i
14c80 6e 64 65 78 65 73 20 61 62 6f 76 65 2e 20 20 2a  ndexes above.  *
14c90 2f 0a 20 20 7b 0a 20 20 20 20 75 33 32 20 69 52  /.  {.    u32 iR
14ca0 65 61 64 32 20 3d 20 30 3b 0a 20 20 20 20 75 33  ead2 = 0;.    u3
14cb0 32 20 69 54 65 73 74 3b 0a 20 20 20 20 66 6f 72  2 iTest;.    for
14cc0 28 69 54 65 73 74 3d 69 4c 61 73 74 3b 20 69 54  (iTest=iLast; iT
14cd0 65 73 74 3e 30 3b 20 69 54 65 73 74 2d 2d 29 7b  est>0; iTest--){
14ce0 0a 20 20 20 20 20 20 69 66 28 20 77 61 6c 46 72  .      if( walFr
14cf0 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 54  amePgno(pWal, iT
14d00 65 73 74 29 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20  est)==pgno ){.  
14d10 20 20 20 20 20 20 69 52 65 61 64 32 20 3d 20 69        iRead2 = i
14d20 54 65 73 74 3b 0a 20 20 20 20 20 20 20 20 62 72  Test;.        br
14d30 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
14d40 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 69   }.    assert( i
14d50 52 65 61 64 3d 3d 69 52 65 61 64 32 20 29 3b 0a  Read==iRead2 );.
14d60 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2f 2a    }.#endif..  /*
14d70 20 49 66 20 69 52 65 61 64 20 69 73 20 6e 6f 6e   If iRead is non
14d80 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 69 74 20 69  -zero, then it i
14d90 73 20 74 68 65 20 6c 6f 67 20 66 72 61 6d 65 20  s the log frame 
14da0 6e 75 6d 62 65 72 20 74 68 61 74 20 63 6f 6e 74  number that cont
14db0 61 69 6e 73 20 74 68 65 0a 20 20 2a 2a 20 72 65  ains the.  ** re
14dc0 71 75 69 72 65 64 20 70 61 67 65 2e 20 52 65 61  quired page. Rea
14dd0 64 20 61 6e 64 20 72 65 74 75 72 6e 20 64 61 74  d and return dat
14de0 61 20 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20 66  a from the log f
14df0 69 6c 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  ile..  */.  if( 
14e00 69 52 65 61 64 20 29 7b 0a 20 20 20 20 69 6e 74  iRead ){.    int
14e10 20 73 7a 3b 0a 20 20 20 20 69 36 34 20 69 4f 66   sz;.    i64 iOf
14e20 66 73 65 74 3b 0a 20 20 20 20 73 7a 20 3d 20 70  fset;.    sz = p
14e30 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 3b  Wal->hdr.szPage;
14e40 0a 20 20 20 20 73 7a 20 3d 20 28 70 57 61 6c 2d  .    sz = (pWal-
14e50 3e 68 64 72 2e 73 7a 50 61 67 65 26 30 78 66 65  >hdr.szPage&0xfe
14e60 30 30 29 20 2b 20 28 28 70 57 61 6c 2d 3e 68 64  00) + ((pWal->hd
14e70 72 2e 73 7a 50 61 67 65 26 30 78 30 30 30 31 29  r.szPage&0x0001)
14e80 3c 3c 31 36 29 3b 0a 20 20 20 20 74 65 73 74 63  <<16);.    testc
14e90 61 73 65 28 20 73 7a 3c 3d 33 32 37 36 38 20 29  ase( sz<=32768 )
14ea0 3b 0a 20 20 20 20 74 65 73 74 63 61 73 65 28 20  ;.    testcase( 
14eb0 73 7a 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 20  sz>=65536 );.   
14ec0 20 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72   iOffset = walFr
14ed0 61 6d 65 4f 66 66 73 65 74 28 69 52 65 61 64 2c  ameOffset(iRead,
14ee0 20 73 7a 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45   sz) + WAL_FRAME
14ef0 5f 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 2a 70  _HDRSIZE;.    *p
14f00 49 6e 57 61 6c 20 3d 20 31 3b 0a 20 20 20 20 2f  InWal = 1;.    /
14f10 2a 20 74 65 73 74 63 61 73 65 28 20 49 53 5f 42  * testcase( IS_B
14f20 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20  IG_INT(iOffset) 
14f30 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73 20 61  ); // requires a
14f40 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20 20 20   4GiB WAL */.   
14f50 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f   return sqlite3O
14f60 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c  sRead(pWal->pWal
14f70 46 64 2c 20 70 4f 75 74 2c 20 6e 4f 75 74 2c 20  Fd, pOut, nOut, 
14f80 69 4f 66 66 73 65 74 29 3b 0a 20 20 7d 0a 0a 20  iOffset);.  }.. 
14f90 20 2a 70 49 6e 57 61 6c 20 3d 20 30 3b 0a 20 20   *pInWal = 0;.  
14fa0 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
14fb0 3b 0a 7d 0a 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74  ;.}.../* .** Ret
14fc0 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20  urn the size of 
14fd0 74 68 65 20 64 61 74 61 62 61 73 65 20 69 6e 20  the database in 
14fe0 70 61 67 65 73 20 28 6f 72 20 7a 65 72 6f 2c 20  pages (or zero, 
14ff0 69 66 20 75 6e 6b 6e 6f 77 6e 29 2e 0a 2a 2f 0a  if unknown)..*/.
15000 50 67 6e 6f 20 73 71 6c 69 74 65 33 57 61 6c 44  Pgno sqlite3WalD
15010 62 73 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c 29  bsize(Wal *pWal)
15020 7b 0a 20 20 69 66 28 20 70 57 61 6c 20 26 26 20  {.  if( pWal && 
15030 41 4c 57 41 59 53 28 70 57 61 6c 2d 3e 72 65 61  ALWAYS(pWal->rea
15040 64 4c 6f 63 6b 3e 3d 30 29 20 29 7b 0a 20 20 20  dLock>=0) ){.   
15050 20 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e 68 64   return pWal->hd
15060 72 2e 6e 50 61 67 65 3b 0a 20 20 7d 0a 20 20 72  r.nPage;.  }.  r
15070 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 0a 2f 2a 20  eturn 0;.}.../* 
15080 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
15090 6e 20 73 74 61 72 74 73 20 61 20 77 72 69 74 65  n starts a write
150a0 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20   transaction on 
150b0 74 68 65 20 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20 41  the WAL..**.** A
150c0 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
150d0 6e 20 6d 75 73 74 20 68 61 76 65 20 61 6c 72 65  n must have alre
150e0 61 64 79 20 62 65 65 6e 20 73 74 61 72 74 65 64  ady been started
150f0 20 62 79 20 61 20 70 72 69 6f 72 20 63 61 6c 6c   by a prior call
15100 0a 2a 2a 20 74 6f 20 73 71 6c 69 74 65 33 57 61  .** to sqlite3Wa
15110 6c 42 65 67 69 6e 52 65 61 64 54 72 61 6e 73 61  lBeginReadTransa
15120 63 74 69 6f 6e 28 29 2e 0a 2a 2a 0a 2a 2a 20 49  ction()..**.** I
15130 66 20 61 6e 6f 74 68 65 72 20 74 68 72 65 61 64  f another thread
15140 20 6f 72 20 70 72 6f 63 65 73 73 20 68 61 73 20   or process has 
15150 77 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65  written into the
15160 20 64 61 74 61 62 61 73 65 20 73 69 6e 63 65 0a   database since.
15170 2a 2a 20 74 68 65 20 72 65 61 64 20 74 72 61 6e  ** the read tran
15180 73 61 63 74 69 6f 6e 20 77 61 73 20 73 74 61 72  saction was star
15190 74 65 64 2c 20 74 68 65 6e 20 69 74 20 69 73 20  ted, then it is 
151a0 6e 6f 74 20 70 6f 73 73 69 62 6c 65 20 66 6f 72  not possible for
151b0 20 74 68 69 73 0a 2a 2a 20 74 68 72 65 61 64 20   this.** thread 
151c0 74 6f 20 77 72 69 74 65 20 61 73 20 64 6f 69 6e  to write as doin
151d0 67 20 73 6f 20 77 6f 75 6c 64 20 63 61 75 73 65  g so would cause
151e0 20 61 20 66 6f 72 6b 2e 20 20 53 6f 20 74 68 69   a fork.  So thi
151f0 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65 74  s routine.** ret
15200 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53 59  urns SQLITE_BUSY
15210 20 69 6e 20 74 68 61 74 20 63 61 73 65 20 61 6e   in that case an
15220 64 20 6e 6f 20 77 72 69 74 65 20 74 72 61 6e 73  d no write trans
15230 61 63 74 69 6f 6e 20 69 73 20 73 74 61 72 74 65  action is starte
15240 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 63  d..**.** There c
15250 61 6e 20 6f 6e 6c 79 20 62 65 20 61 20 73 69 6e  an only be a sin
15260 67 6c 65 20 77 72 69 74 65 72 20 61 63 74 69 76  gle writer activ
15270 65 20 61 74 20 61 20 74 69 6d 65 2e 0a 2a 2f 0a  e at a time..*/.
15280 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 42 65  int sqlite3WalBe
15290 67 69 6e 57 72 69 74 65 54 72 61 6e 73 61 63 74  ginWriteTransact
152a0 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ion(Wal *pWal){.
152b0 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 2f 2a 20    int rc;..  /* 
152c0 43 61 6e 6e 6f 74 20 73 74 61 72 74 20 61 20 77  Cannot start a w
152d0 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  rite transaction
152e0 20 77 69 74 68 6f 75 74 20 66 69 72 73 74 20 68   without first h
152f0 6f 6c 64 69 6e 67 20 61 20 72 65 61 64 0a 20 20  olding a read.  
15300 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20  ** transaction. 
15310 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  */.  assert( pWa
15320 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29  l->readLock>=0 )
15330 3b 0a 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 72  ;..  if( pWal->r
15340 65 61 64 4f 6e 6c 79 20 29 7b 0a 20 20 20 20 72  eadOnly ){.    r
15350 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 52 45 41  eturn SQLITE_REA
15360 44 4f 4e 4c 59 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  DONLY;.  }..  /*
15370 20 4f 6e 6c 79 20 6f 6e 65 20 77 72 69 74 65 72   Only one writer
15380 20 61 6c 6c 6f 77 65 64 20 61 74 20 61 20 74 69   allowed at a ti
15390 6d 65 2e 20 20 47 65 74 20 74 68 65 20 77 72 69  me.  Get the wri
153a0 74 65 20 6c 6f 63 6b 2e 20 20 52 65 74 75 72 6e  te lock.  Return
153b0 0a 20 20 2a 2a 20 53 51 4c 49 54 45 5f 42 55 53  .  ** SQLITE_BUS
153c0 59 20 69 66 20 75 6e 61 62 6c 65 2e 0a 20 20 2a  Y if unable..  *
153d0 2f 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b  /.  rc = walLock
153e0 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
153f0 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20  WAL_WRITE_LOCK, 
15400 31 29 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a  1);.  if( rc ){.
15410 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
15420 20 7d 0a 20 20 70 57 61 6c 2d 3e 77 72 69 74 65   }.  pWal->write
15430 4c 6f 63 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20  Lock = 1;..  /* 
15440 49 66 20 61 6e 6f 74 68 65 72 20 63 6f 6e 6e 65  If another conne
15450 63 74 69 6f 6e 20 68 61 73 20 77 72 69 74 74 65  ction has writte
15460 6e 20 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  n to the databas
15470 65 20 66 69 6c 65 20 73 69 6e 63 65 20 74 68 65  e file since the
15480 0a 20 20 2a 2a 20 74 69 6d 65 20 74 68 65 20 72  .  ** time the r
15490 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
154a0 6f 6e 20 74 68 69 73 20 63 6f 6e 6e 65 63 74 69  on this connecti
154b0 6f 6e 20 77 61 73 20 73 74 61 72 74 65 64 2c 20  on was started, 
154c0 74 68 65 6e 0a 20 20 2a 2a 20 74 68 65 20 77 72  then.  ** the wr
154d0 69 74 65 20 69 73 20 64 69 73 61 6c 6c 6f 77 65  ite is disallowe
154e0 64 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 6d 65  d..  */.  if( me
154f0 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72 2c  mcmp(&pWal->hdr,
15500 20 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65   (void *)walInde
15510 78 48 64 72 28 70 57 61 6c 29 2c 20 73 69 7a 65  xHdr(pWal), size
15520 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
15530 21 3d 30 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e  !=0 ){.    walUn
15540 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  lockExclusive(pW
15550 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f  al, WAL_WRITE_LO
15560 43 4b 2c 20 31 29 3b 0a 20 20 20 20 70 57 61 6c  CK, 1);.    pWal
15570 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b  ->writeLock = 0;
15580 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
15590 5f 42 55 53 59 3b 0a 20 20 7d 0a 0a 20 20 72 65  _BUSY;.  }..  re
155a0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
155b0 2a 20 45 6e 64 20 61 20 77 72 69 74 65 20 74 72  * End a write tr
155c0 61 6e 73 61 63 74 69 6f 6e 2e 20 20 54 68 65 20  ansaction.  The 
155d0 63 6f 6d 6d 69 74 20 68 61 73 20 61 6c 72 65 61  commit has alrea
155e0 64 79 20 62 65 65 6e 20 64 6f 6e 65 2e 20 20 54  dy been done.  T
155f0 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 6d  his.** routine m
15600 65 72 65 6c 79 20 72 65 6c 65 61 73 65 73 20 74  erely releases t
15610 68 65 20 6c 6f 63 6b 2e 0a 2a 2f 0a 69 6e 74 20  he lock..*/.int 
15620 73 71 6c 69 74 65 33 57 61 6c 45 6e 64 57 72 69  sqlite3WalEndWri
15630 74 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 57 61  teTransaction(Wa
15640 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28 20  l *pWal){.  if( 
15650 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
15660 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b  ){.    walUnlock
15670 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
15680 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20  WAL_WRITE_LOCK, 
15690 31 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72  1);.    pWal->wr
156a0 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 7d  iteLock = 0;.  }
156b0 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
156c0 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66  _OK;.}../*.** If
156d0 20 61 6e 79 20 64 61 74 61 20 68 61 73 20 62 65   any data has be
156e0 65 6e 20 77 72 69 74 74 65 6e 20 28 62 75 74 20  en written (but 
156f0 6e 6f 74 20 63 6f 6d 6d 69 74 74 65 64 29 20 74  not committed) t
15700 6f 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2c 20  o the log file, 
15710 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e  this.** function
15720 20 6d 6f 76 65 73 20 74 68 65 20 77 72 69 74 65   moves the write
15730 2d 70 6f 69 6e 74 65 72 20 62 61 63 6b 20 74 6f  -pointer back to
15740 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
15750 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a  e transaction..*
15760 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c 6c  *.** Additionall
15770 79 2c 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20  y, the callback 
15780 66 75 6e 63 74 69 6f 6e 20 69 73 20 69 6e 76 6f  function is invo
15790 6b 65 64 20 66 6f 72 20 65 61 63 68 20 66 72 61  ked for each fra
157a0 6d 65 20 77 72 69 74 74 65 6e 0a 2a 2a 20 74 6f  me written.** to
157b0 20 74 68 65 20 57 41 4c 20 73 69 6e 63 65 20 74   the WAL since t
157c0 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  he start of the 
157d0 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 49 66 20  transaction. If 
157e0 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 72 65 74  the callback ret
157f0 75 72 6e 73 0a 2a 2a 20 6f 74 68 65 72 20 74 68  urns.** other th
15800 61 6e 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 69 74  an SQLITE_OK, it
15810 20 69 73 20 6e 6f 74 20 69 6e 76 6f 6b 65 64 20   is not invoked 
15820 61 67 61 69 6e 20 61 6e 64 20 74 68 65 20 65 72  again and the er
15830 72 6f 72 20 63 6f 64 65 20 69 73 0a 2a 2a 20 72  ror code is.** r
15840 65 74 75 72 6e 65 64 20 74 6f 20 74 68 65 20 63  eturned to the c
15850 61 6c 6c 65 72 2e 0a 2a 2a 0a 2a 2a 20 4f 74 68  aller..**.** Oth
15860 65 72 77 69 73 65 2c 20 69 66 20 74 68 65 20 63  erwise, if the c
15870 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e  allback function
15880 20 64 6f 65 73 20 6e 6f 74 20 72 65 74 75 72 6e   does not return
15890 20 61 6e 20 65 72 72 6f 72 2c 20 74 68 69 73 0a   an error, this.
158a0 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75  ** function retu
158b0 72 6e 73 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a  rns SQLITE_OK..*
158c0 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c  /.int sqlite3Wal
158d0 55 6e 64 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Undo(Wal *pWal, 
158e0 69 6e 74 20 28 2a 78 55 6e 64 6f 29 28 76 6f 69  int (*xUndo)(voi
158f0 64 20 2a 2c 20 50 67 6e 6f 29 2c 20 76 6f 69 64  d *, Pgno), void
15900 20 2a 70 55 6e 64 6f 43 74 78 29 7b 0a 20 20 69   *pUndoCtx){.  i
15910 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
15920 4b 3b 0a 20 20 69 66 28 20 41 4c 57 41 59 53 28  K;.  if( ALWAYS(
15930 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 29  pWal->writeLock)
15940 20 29 7b 0a 20 20 20 20 50 67 6e 6f 20 69 4d 61   ){.    Pgno iMa
15950 78 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  x = pWal->hdr.mx
15960 46 72 61 6d 65 3b 0a 20 20 20 20 50 67 6e 6f 20  Frame;.    Pgno 
15970 69 46 72 61 6d 65 3b 0a 20 20 0a 20 20 20 20 2f  iFrame;.  .    /
15980 2a 20 52 65 73 74 6f 72 65 20 74 68 65 20 63 6c  * Restore the cl
15990 69 65 6e 74 73 20 63 61 63 68 65 20 6f 66 20 74  ients cache of t
159a0 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
159b0 64 65 72 20 74 6f 20 74 68 65 20 73 74 61 74 65  der to the state
159c0 20 69 74 0a 20 20 20 20 2a 2a 20 77 61 73 20 69   it.    ** was i
159d0 6e 20 62 65 66 6f 72 65 20 74 68 65 20 63 6c 69  n before the cli
159e0 65 6e 74 20 62 65 67 61 6e 20 77 72 69 74 69 6e  ent began writin
159f0 67 20 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  g to the databas
15a00 65 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d  e. .    */.    m
15a10 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72  emcpy(&pWal->hdr
15a20 2c 20 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64  , (void *)walInd
15a30 65 78 48 64 72 28 70 57 61 6c 29 2c 20 73 69 7a  exHdr(pWal), siz
15a40 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29  eof(WalIndexHdr)
15a50 29 3b 0a 0a 20 20 20 20 66 6f 72 28 69 46 72 61  );..    for(iFra
15a60 6d 65 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  me=pWal->hdr.mxF
15a70 72 61 6d 65 2b 31 3b 20 0a 20 20 20 20 20 20 20  rame+1; .       
15a80 20 41 4c 57 41 59 53 28 72 63 3d 3d 53 51 4c 49   ALWAYS(rc==SQLI
15a90 54 45 5f 4f 4b 29 20 26 26 20 69 46 72 61 6d 65  TE_OK) && iFrame
15aa0 3c 3d 69 4d 61 78 3b 20 0a 20 20 20 20 20 20 20  <=iMax; .       
15ab0 20 69 46 72 61 6d 65 2b 2b 0a 20 20 20 20 29 7b   iFrame++.    ){
15ac0 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20 63  .      /* This c
15ad0 61 6c 6c 20 63 61 6e 6e 6f 74 20 66 61 69 6c 2e  all cannot fail.
15ae0 20 55 6e 6c 65 73 73 20 74 68 65 20 70 61 67 65   Unless the page
15af0 20 66 6f 72 20 77 68 69 63 68 20 74 68 65 20 70   for which the p
15b00 61 67 65 20 6e 75 6d 62 65 72 0a 20 20 20 20 20  age number.     
15b10 20 2a 2a 20 69 73 20 70 61 73 73 65 64 20 61 73   ** is passed as
15b20 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75   the second argu
15b30 6d 65 6e 74 20 69 73 20 28 61 29 20 69 6e 20 74  ment is (a) in t
15b40 68 65 20 63 61 63 68 65 20 61 6e 64 20 0a 20 20  he cache and .  
15b50 20 20 20 20 2a 2a 20 28 62 29 20 68 61 73 20 61      ** (b) has a
15b60 6e 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 72 65  n outstanding re
15b70 66 65 72 65 6e 63 65 2c 20 74 68 65 6e 20 78 55  ference, then xU
15b80 6e 64 6f 20 69 73 20 65 69 74 68 65 72 20 61 20  ndo is either a 
15b90 6e 6f 2d 6f 70 0a 20 20 20 20 20 20 2a 2a 20 28  no-op.      ** (
15ba0 69 66 20 28 61 29 20 69 73 20 66 61 6c 73 65 29  if (a) is false)
15bb0 20 6f 72 20 73 69 6d 70 6c 79 20 65 78 70 65 6c   or simply expel
15bc0 73 20 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20  s the page from 
15bd0 74 68 65 20 63 61 63 68 65 20 28 69 66 20 28 62  the cache (if (b
15be0 29 0a 20 20 20 20 20 20 2a 2a 20 69 73 20 66 61  ).      ** is fa
15bf0 6c 73 65 29 2e 0a 20 20 20 20 20 20 2a 2a 0a 20  lse)..      **. 
15c00 20 20 20 20 20 2a 2a 20 49 66 20 74 68 65 20 75       ** If the u
15c10 70 70 65 72 20 6c 61 79 65 72 20 69 73 20 64 6f  pper layer is do
15c20 69 6e 67 20 61 20 72 6f 6c 6c 62 61 63 6b 2c 20  ing a rollback, 
15c30 69 74 20 69 73 20 67 75 61 72 61 6e 74 65 65 64  it is guaranteed
15c40 20 74 68 61 74 20 74 68 65 72 65 0a 20 20 20 20   that there.    
15c50 20 20 2a 2a 20 61 72 65 20 6e 6f 20 6f 75 74 73    ** are no outs
15c60 74 61 6e 64 69 6e 67 20 72 65 66 65 72 65 6e 63  tanding referenc
15c70 65 73 20 74 6f 20 61 6e 79 20 70 61 67 65 20 6f  es to any page o
15c80 74 68 65 72 20 74 68 61 6e 20 70 61 67 65 20 31  ther than page 1
15c90 2e 20 41 6e 64 0a 20 20 20 20 20 20 2a 2a 20 70  . And.      ** p
15ca0 61 67 65 20 31 20 69 73 20 6e 65 76 65 72 20 77  age 1 is never w
15cb0 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20 6c 6f  ritten to the lo
15cc0 67 20 75 6e 74 69 6c 20 74 68 65 20 74 72 61 6e  g until the tran
15cd0 73 61 63 74 69 6f 6e 20 69 73 0a 20 20 20 20 20  saction is.     
15ce0 20 2a 2a 20 63 6f 6d 6d 69 74 74 65 64 2e 20 41   ** committed. A
15cf0 73 20 61 20 72 65 73 75 6c 74 2c 20 74 68 65 20  s a result, the 
15d00 63 61 6c 6c 20 74 6f 20 78 55 6e 64 6f 20 6d 61  call to xUndo ma
15d10 79 20 6e 6f 74 20 66 61 69 6c 2e 0a 20 20 20 20  y not fail..    
15d20 20 20 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72    */.      asser
15d30 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28  t( walFramePgno(
15d40 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 21 3d 31  pWal, iFrame)!=1
15d50 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 78   );.      rc = x
15d60 55 6e 64 6f 28 70 55 6e 64 6f 43 74 78 2c 20 77  Undo(pUndoCtx, w
15d70 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c  alFramePgno(pWal
15d80 2c 20 69 46 72 61 6d 65 29 29 3b 0a 20 20 20 20  , iFrame));.    
15d90 7d 0a 20 20 20 20 77 61 6c 43 6c 65 61 6e 75 70  }.    walCleanup
15da0 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 7d 0a  Hash(pWal);.  }.
15db0 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
15dc0 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74  LITE_OK );.  ret
15dd0 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  urn rc;.}../* .*
15de0 2a 20 41 72 67 75 6d 65 6e 74 20 61 57 61 6c 44  * Argument aWalD
15df0 61 74 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74  ata must point t
15e00 6f 20 61 6e 20 61 72 72 61 79 20 6f 66 20 57 41  o an array of WA
15e10 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54  L_SAVEPOINT_NDAT
15e20 41 20 75 33 32 20 0a 2a 2a 20 76 61 6c 75 65 73  A u32 .** values
15e30 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
15e40 70 6f 70 75 6c 61 74 65 73 20 74 68 65 20 61 72  populates the ar
15e50 72 61 79 20 77 69 74 68 20 76 61 6c 75 65 73 20  ray with values 
15e60 72 65 71 75 69 72 65 64 20 74 6f 20 0a 2a 2a 20  required to .** 
15e70 22 72 6f 6c 6c 62 61 63 6b 22 20 74 68 65 20 77  "rollback" the w
15e80 72 69 74 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66  rite position of
15e90 20 74 68 65 20 57 41 4c 20 68 61 6e 64 6c 65 20   the WAL handle 
15ea0 62 61 63 6b 20 74 6f 20 74 68 65 20 63 75 72 72  back to the curr
15eb0 65 6e 74 20 0a 2a 2a 20 70 6f 69 6e 74 20 69 6e  ent .** point in
15ec0 20 74 68 65 20 65 76 65 6e 74 20 6f 66 20 61 20   the event of a 
15ed0 73 61 76 65 70 6f 69 6e 74 20 72 6f 6c 6c 62 61  savepoint rollba
15ee0 63 6b 20 28 76 69 61 20 57 61 6c 53 61 76 65 70  ck (via WalSavep
15ef0 6f 69 6e 74 55 6e 64 6f 28 29 29 2e 0a 2a 2f 0a  ointUndo())..*/.
15f00 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 53  void sqlite3WalS
15f10 61 76 65 70 6f 69 6e 74 28 57 61 6c 20 2a 70 57  avepoint(Wal *pW
15f20 61 6c 2c 20 75 33 32 20 2a 61 57 61 6c 44 61 74  al, u32 *aWalDat
15f30 61 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57  a){.  assert( pW
15f40 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
15f50 0a 20 20 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d  .  aWalData[0] =
15f60 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
15f70 6d 65 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 31  me;.  aWalData[1
15f80 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46  ] = pWal->hdr.aF
15f90 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20  rameCksum[0];.  
15fa0 61 57 61 6c 44 61 74 61 5b 32 5d 20 3d 20 70 57  aWalData[2] = pW
15fb0 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
15fc0 73 75 6d 5b 31 5d 3b 0a 20 20 61 57 61 6c 44 61  sum[1];.  aWalDa
15fd0 74 61 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e 6e 43  ta[3] = pWal->nC
15fe0 6b 70 74 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4d  kpt;.}../* .** M
15ff0 6f 76 65 20 74 68 65 20 77 72 69 74 65 20 70 6f  ove the write po
16000 73 69 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41  sition of the WA
16010 4c 20 62 61 63 6b 20 74 6f 20 74 68 65 20 70 6f  L back to the po
16020 69 6e 74 20 69 64 65 6e 74 69 66 69 65 64 20 62  int identified b
16030 79 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 73 20  y.** the values 
16040 69 6e 20 74 68 65 20 61 57 61 6c 44 61 74 61 5b  in the aWalData[
16050 5d 20 61 72 72 61 79 2e 20 61 57 61 6c 44 61 74  ] array. aWalDat
16060 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f 20  a must point to 
16070 61 6e 20 61 72 72 61 79 0a 2a 2a 20 6f 66 20 57  an array.** of W
16080 41 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41  AL_SAVEPOINT_NDA
16090 54 41 20 75 33 32 20 76 61 6c 75 65 73 20 74 68  TA u32 values th
160a0 61 74 20 68 61 73 20 62 65 65 6e 20 70 72 65 76  at has been prev
160b0 69 6f 75 73 6c 79 20 70 6f 70 75 6c 61 74 65 64  iously populated
160c0 0a 2a 2a 20 62 79 20 61 20 63 61 6c 6c 20 74 6f  .** by a call to
160d0 20 57 61 6c 53 61 76 65 70 6f 69 6e 74 28 29 2e   WalSavepoint().
160e0 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
160f0 61 6c 53 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28  alSavepointUndo(
16100 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a  Wal *pWal, u32 *
16110 61 57 61 6c 44 61 74 61 29 7b 0a 20 20 69 6e 74  aWalData){.  int
16120 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
16130 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ..  assert( pWal
16140 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20  ->writeLock );. 
16150 20 61 73 73 65 72 74 28 20 61 57 61 6c 44 61 74   assert( aWalDat
16160 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43 6b 70  a[3]!=pWal->nCkp
16170 74 20 7c 7c 20 61 57 61 6c 44 61 74 61 5b 30 5d  t || aWalData[0]
16180 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  <=pWal->hdr.mxFr
16190 61 6d 65 20 29 3b 0a 0a 20 20 69 66 28 20 61 57  ame );..  if( aW
161a0 61 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d  alData[3]!=pWal-
161b0 3e 6e 43 6b 70 74 20 29 7b 0a 20 20 20 20 2f 2a  >nCkpt ){.    /*
161c0 20 54 68 69 73 20 73 61 76 65 70 6f 69 6e 74 20   This savepoint 
161d0 77 61 73 20 6f 70 65 6e 65 64 20 69 6d 6d 65 64  was opened immed
161e0 69 61 74 65 6c 79 20 61 66 74 65 72 20 74 68 65  iately after the
161f0 20 77 72 69 74 65 2d 74 72 61 6e 73 61 63 74 69   write-transacti
16200 6f 6e 0a 20 20 20 20 2a 2a 20 77 61 73 20 73 74  on.    ** was st
16210 61 72 74 65 64 2e 20 52 69 67 68 74 20 61 66 74  arted. Right aft
16220 65 72 20 74 68 61 74 2c 20 74 68 65 20 77 72 69  er that, the wri
16230 74 65 72 20 64 65 63 69 64 65 64 20 74 6f 20 77  ter decided to w
16240 72 61 70 20 61 72 6f 75 6e 64 0a 20 20 20 20 2a  rap around.    *
16250 2a 20 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f  * to the start o
16260 66 20 74 68 65 20 6c 6f 67 2e 20 55 70 64 61 74  f the log. Updat
16270 65 20 74 68 65 20 73 61 76 65 70 6f 69 6e 74 20  e the savepoint 
16280 76 61 6c 75 65 73 20 74 6f 20 6d 61 74 63 68 2e  values to match.
16290 0a 20 20 20 20 2a 2f 0a 20 20 20 20 61 57 61 6c  .    */.    aWal
162a0 44 61 74 61 5b 30 5d 20 3d 20 30 3b 0a 20 20 20  Data[0] = 0;.   
162b0 20 61 57 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70   aWalData[3] = p
162c0 57 61 6c 2d 3e 6e 43 6b 70 74 3b 0a 20 20 7d 0a  Wal->nCkpt;.  }.
162d0 0a 20 20 69 66 28 20 61 57 61 6c 44 61 74 61 5b  .  if( aWalData[
162e0 30 5d 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  0]<pWal->hdr.mxF
162f0 72 61 6d 65 20 29 7b 0a 20 20 20 20 70 57 61 6c  rame ){.    pWal
16300 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20  ->hdr.mxFrame = 
16310 61 57 61 6c 44 61 74 61 5b 30 5d 3b 0a 20 20 20  aWalData[0];.   
16320 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
16330 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 57 61 6c  eCksum[0] = aWal
16340 44 61 74 61 5b 31 5d 3b 0a 20 20 20 20 70 57 61  Data[1];.    pWa
16350 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
16360 75 6d 5b 31 5d 20 3d 20 61 57 61 6c 44 61 74 61  um[1] = aWalData
16370 5b 32 5d 3b 0a 20 20 20 20 77 61 6c 43 6c 65 61  [2];.    walClea
16380 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20  nupHash(pWal);. 
16390 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
163a0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
163b0 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
163c0 64 20 6a 75 73 74 20 62 65 66 6f 72 65 20 77 72  d just before wr
163d0 69 74 69 6e 67 20 61 20 73 65 74 20 6f 66 20 66  iting a set of f
163e0 72 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67  rames to the log
163f0 0a 2a 2a 20 66 69 6c 65 20 28 73 65 65 20 73 71  .** file (see sq
16400 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28 29  lite3WalFrames()
16410 29 2e 20 49 74 20 63 68 65 63 6b 73 20 74 6f 20  ). It checks to 
16420 73 65 65 20 69 66 2c 20 69 6e 73 74 65 61 64 20  see if, instead 
16430 6f 66 20 61 70 70 65 6e 64 69 6e 67 0a 2a 2a 20  of appending.** 
16440 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c  to the current l
16450 6f 67 20 66 69 6c 65 2c 20 69 74 20 69 73 20 70  og file, it is p
16460 6f 73 73 69 62 6c 65 20 74 6f 20 6f 76 65 72 77  ossible to overw
16470 72 69 74 65 20 74 68 65 20 73 74 61 72 74 20 6f  rite the start o
16480 66 20 74 68 65 0a 2a 2a 20 65 78 69 73 74 69 6e  f the.** existin
16490 67 20 6c 6f 67 20 66 69 6c 65 20 77 69 74 68 20  g log file with 
164a0 74 68 65 20 6e 65 77 20 66 72 61 6d 65 73 20 28  the new frames (
164b0 69 2e 65 2e 20 22 72 65 73 65 74 22 20 74 68 65  i.e. "reset" the
164c0 20 6c 6f 67 29 2e 20 49 66 20 73 6f 2c 0a 2a 2a   log). If so,.**
164d0 20 69 74 20 73 65 74 73 20 70 57 61 6c 2d 3e 68   it sets pWal->h
164e0 64 72 2e 6d 78 46 72 61 6d 65 20 74 6f 20 30 2e  dr.mxFrame to 0.
164f0 20 4f 74 68 65 72 77 69 73 65 2c 20 70 57 61 6c   Otherwise, pWal
16500 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73  ->hdr.mxFrame is
16510 20 6c 65 66 74 0a 2a 2a 20 75 6e 63 68 61 6e 67   left.** unchang
16520 65 64 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45  ed..**.** SQLITE
16530 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20  _OK is returned 
16540 69 66 20 6e 6f 20 65 72 72 6f 72 20 69 73 20 65  if no error is e
16550 6e 63 6f 75 6e 74 65 72 65 64 20 28 72 65 67 61  ncountered (rega
16560 72 64 6c 65 73 73 20 6f 66 20 77 68 65 74 68 65  rdless of whethe
16570 72 0a 2a 2a 20 6f 72 20 6e 6f 74 20 70 57 61 6c  r.** or not pWal
16580 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73  ->hdr.mxFrame is
16590 20 6d 6f 64 69 66 69 65 64 29 2e 20 41 6e 20 53   modified). An S
165a0 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
165b0 20 69 73 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20   is returned.** 
165c0 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  if an error occu
165d0 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  rs..*/.static in
165e0 74 20 77 61 6c 52 65 73 74 61 72 74 4c 6f 67 28  t walRestartLog(
165f0 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e  Wal *pWal){.  in
16600 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
16610 3b 0a 20 20 69 6e 74 20 63 6e 74 3b 0a 0a 20 20  ;.  int cnt;..  
16620 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  if( pWal->readLo
16630 63 6b 3d 3d 30 20 29 7b 0a 20 20 20 20 76 6f 6c  ck==0 ){.    vol
16640 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66  atile WalCkptInf
16650 6f 20 2a 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b  o *pInfo = walCk
16660 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20  ptInfo(pWal);.  
16670 20 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d    assert( pInfo-
16680 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70 57 61 6c  >nBackfill==pWal
16690 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b  ->hdr.mxFrame );
166a0 0a 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e  .    if( pInfo->
166b0 6e 42 61 63 6b 66 69 6c 6c 3e 30 20 29 7b 0a 20  nBackfill>0 ){. 
166c0 20 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63       rc = walLoc
166d0 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
166e0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31   WAL_READ_LOCK(1
166f0 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31  ), WAL_NREADER-1
16700 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
16710 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
16720 20 20 20 20 20 20 2f 2a 20 49 66 20 61 6c 6c 20        /* If all 
16730 72 65 61 64 65 72 73 20 61 72 65 20 75 73 69 6e  readers are usin
16740 67 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  g WAL_READ_LOCK(
16750 30 29 20 28 69 6e 20 6f 74 68 65 72 20 77 6f 72  0) (in other wor
16760 64 73 20 69 66 20 6e 6f 0a 20 20 20 20 20 20 20  ds if no.       
16770 20 2a 2a 20 72 65 61 64 65 72 73 20 61 72 65 20   ** readers are 
16780 63 75 72 72 65 6e 74 6c 79 20 75 73 69 6e 67 20  currently using 
16790 74 68 65 20 57 41 4c 29 2c 20 74 68 65 6e 20 74  the WAL), then t
167a0 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 0a  he transactions.
167b0 20 20 20 20 20 20 20 20 2a 2a 20 66 72 61 6d 65          ** frame
167c0 73 20 77 69 6c 6c 20 6f 76 65 72 77 72 69 74 65  s will overwrite
167d0 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
167e0 65 20 65 78 69 73 74 69 6e 67 20 6c 6f 67 2e 20  e existing log. 
167f0 55 70 64 61 74 65 20 74 68 65 0a 20 20 20 20 20  Update the.     
16800 20 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20     ** wal-index 
16810 68 65 61 64 65 72 20 74 6f 20 72 65 66 6c 65 63  header to reflec
16820 74 20 74 68 69 73 2e 0a 20 20 20 20 20 20 20 20  t this..        
16830 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 49 6e  **.        ** In
16840 20 74 68 65 6f 72 79 20 69 74 20 77 6f 75 6c 64   theory it would
16850 20 62 65 20 4f 6b 20 74 6f 20 75 70 64 61 74 65   be Ok to update
16860 20 74 68 65 20 63 61 63 68 65 20 6f 66 20 74 68   the cache of th
16870 65 20 68 65 61 64 65 72 20 6f 6e 6c 79 0a 20 20  e header only.  
16880 20 20 20 20 20 20 2a 2a 20 61 74 20 74 68 69 73        ** at this
16890 20 70 6f 69 6e 74 2e 20 42 75 74 20 75 70 64 61   point. But upda
168a0 74 69 6e 67 20 74 68 65 20 61 63 74 75 61 6c 20  ting the actual 
168b0 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
168c0 20 69 73 20 61 6c 73 6f 0a 20 20 20 20 20 20 20   is also.       
168d0 20 2a 2a 20 73 61 66 65 20 61 6e 64 20 6d 65 61   ** safe and mea
168e0 6e 73 20 74 68 65 72 65 20 69 73 20 6e 6f 20 73  ns there is no s
168f0 70 65 63 69 61 6c 20 63 61 73 65 20 66 6f 72 20  pecial case for 
16900 73 71 6c 69 74 65 33 57 61 6c 55 6e 64 6f 28 29  sqlite3WalUndo()
16910 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 6f 20 68  .        ** to h
16920 61 6e 64 6c 65 20 69 66 20 74 68 69 73 20 74 72  andle if this tr
16930 61 6e 73 61 63 74 69 6f 6e 20 69 73 20 72 6f 6c  ansaction is rol
16940 6c 65 64 20 62 61 63 6b 2e 0a 20 20 20 20 20 20  led back..      
16950 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 6e 74    */.        int
16960 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
16970 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63         /* Loop c
16980 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20 20 20 20  ounter */.      
16990 20 20 75 33 32 20 2a 61 53 61 6c 74 20 3d 20 70    u32 *aSalt = p
169a0 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 3b 20  Wal->hdr.aSalt; 
169b0 20 20 20 20 20 20 2f 2a 20 42 69 67 2d 65 6e 64        /* Big-end
169c0 69 61 6e 20 73 61 6c 74 20 76 61 6c 75 65 73 20  ian salt values 
169d0 2a 2f 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d  */.        pWal-
169e0 3e 6e 43 6b 70 74 2b 2b 3b 0a 20 20 20 20 20 20  >nCkpt++;.      
169f0 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72    pWal->hdr.mxFr
16a00 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ame = 0;.       
16a10 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65   sqlite3Put4byte
16a20 28 28 75 38 2a 29 26 61 53 61 6c 74 5b 30 5d 2c  ((u8*)&aSalt[0],
16a30 20 31 20 2b 20 73 71 6c 69 74 65 33 47 65 74 34   1 + sqlite3Get4
16a40 62 79 74 65 28 28 75 38 2a 29 26 61 53 61 6c 74  byte((u8*)&aSalt
16a50 5b 30 5d 29 29 3b 0a 20 20 20 20 20 20 20 20 73  [0]));.        s
16a60 71 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73  qlite3_randomnes
16a70 73 28 34 2c 20 26 61 53 61 6c 74 5b 31 5d 29 3b  s(4, &aSalt[1]);
16a80 0a 20 20 20 20 20 20 20 20 77 61 6c 49 6e 64 65  .        walInde
16a90 78 57 72 69 74 65 48 64 72 28 70 57 61 6c 29 3b  xWriteHdr(pWal);
16aa0 0a 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e  .        pInfo->
16ab0 6e 42 61 63 6b 66 69 6c 6c 20 3d 20 30 3b 0a 20  nBackfill = 0;. 
16ac0 20 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20         for(i=1; 
16ad0 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69  i<WAL_NREADER; i
16ae0 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64  ++) pInfo->aRead
16af0 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41  Mark[i] = READMA
16b00 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 20  RK_NOT_USED;.   
16b10 20 20 20 20 20 61 73 73 65 72 74 28 20 70 49 6e       assert( pIn
16b20 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d  fo->aReadMark[0]
16b30 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 20 20 77  ==0 );.        w
16b40 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
16b50 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
16b60 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52  _LOCK(1), WAL_NR
16b70 45 41 44 45 52 2d 31 29 3b 0a 20 20 20 20 20 20  EADER-1);.      
16b80 7d 65 6c 73 65 20 69 66 28 20 72 63 21 3d 53 51  }else if( rc!=SQ
16b90 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
16ba0 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a       return rc;.
16bb0 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
16bc0 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65    walUnlockShare
16bd0 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  d(pWal, WAL_READ
16be0 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20 20 70  _LOCK(0));.    p
16bf0 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20  Wal->readLock = 
16c00 2d 31 3b 0a 20 20 20 20 63 6e 74 20 3d 20 30 3b  -1;.    cnt = 0;
16c10 0a 20 20 20 20 64 6f 7b 0a 20 20 20 20 20 20 69  .    do{.      i
16c20 6e 74 20 6e 6f 74 55 73 65 64 3b 0a 20 20 20 20  nt notUsed;.    
16c30 20 20 72 63 20 3d 20 77 61 6c 54 72 79 42 65 67    rc = walTryBeg
16c40 69 6e 52 65 61 64 28 70 57 61 6c 2c 20 26 6e 6f  inRead(pWal, &no
16c50 74 55 73 65 64 2c 20 31 2c 20 2b 2b 63 6e 74 29  tUsed, 1, ++cnt)
16c60 3b 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 72 63  ;.    }while( rc
16c70 3d 3d 57 41 4c 5f 52 45 54 52 59 20 29 3b 0a 20  ==WAL_RETRY );. 
16c80 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
16c90 7d 0a 0a 2f 2a 20 0a 2a 2a 20 57 72 69 74 65 20  }../* .** Write 
16ca0 61 20 73 65 74 20 6f 66 20 66 72 61 6d 65 73 20  a set of frames 
16cb0 74 6f 20 74 68 65 20 6c 6f 67 2e 20 54 68 65 20  to the log. The 
16cc0 63 61 6c 6c 65 72 20 6d 75 73 74 20 68 6f 6c 64  caller must hold
16cd0 20 74 68 65 20 77 72 69 74 65 2d 6c 6f 63 6b 0a   the write-lock.
16ce0 2a 2a 20 6f 6e 20 74 68 65 20 6c 6f 67 20 66 69  ** on the log fi
16cf0 6c 65 20 28 6f 62 74 61 69 6e 65 64 20 75 73 69  le (obtained usi
16d00 6e 67 20 73 71 6c 69 74 65 33 57 61 6c 42 65 67  ng sqlite3WalBeg
16d10 69 6e 57 72 69 74 65 54 72 61 6e 73 61 63 74 69  inWriteTransacti
16d20 6f 6e 28 29 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71  on())..*/.int sq
16d30 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28 0a  lite3WalFrames(.
16d40 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
16d50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16d60 20 20 2f 2a 20 57 61 6c 20 68 61 6e 64 6c 65 20    /* Wal handle 
16d70 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20  to write to */. 
16d80 20 69 6e 74 20 73 7a 50 61 67 65 2c 20 20 20 20   int szPage,    
16d90 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16da0 20 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67   /* Database pag
16db0 65 2d 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20  e-size in bytes 
16dc0 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 4c 69 73  */.  PgHdr *pLis
16dd0 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
16de0 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20       /* List of 
16df0 64 69 72 74 79 20 70 61 67 65 73 20 74 6f 20 77  dirty pages to w
16e00 72 69 74 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 6e  rite */.  Pgno n
16e10 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20  Truncate,       
16e20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
16e30 61 62 61 73 65 20 73 69 7a 65 20 61 66 74 65 72  abase size after
16e40 20 74 68 69 73 20 63 6f 6d 6d 69 74 20 2a 2f 0a   this commit */.
16e50 20 20 69 6e 74 20 69 73 43 6f 6d 6d 69 74 2c 20    int isCommit, 
16e60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16e70 20 20 2f 2a 20 54 72 75 65 20 69 66 20 74 68 69    /* True if thi
16e80 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 20 2a 2f  s is a commit */
16e90 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67  .  int sync_flag
16ea0 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s               
16eb0 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20 70     /* Flags to p
16ec0 61 73 73 20 74 6f 20 4f 73 53 79 6e 63 28 29 20  ass to OsSync() 
16ed0 28 6f 72 20 30 29 20 2a 2f 0a 29 7b 0a 20 20 69  (or 0) */.){.  i
16ee0 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
16ef0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
16f00 2a 20 55 73 65 64 20 74 6f 20 63 61 74 63 68 20  * Used to catch 
16f10 72 65 74 75 72 6e 20 63 6f 64 65 73 20 2a 2f 0a  return codes */.
16f20 20 20 75 33 32 20 69 46 72 61 6d 65 3b 20 20 20    u32 iFrame;   
16f30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16f40 20 20 2f 2a 20 4e 65 78 74 20 66 72 61 6d 65 20    /* Next frame 
16f50 61 64 64 72 65 73 73 20 2a 2f 0a 20 20 75 38 20  address */.  u8 
16f60 61 46 72 61 6d 65 5b 57 41 4c 5f 46 52 41 4d 45  aFrame[WAL_FRAME
16f70 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20 2f 2a 20  _HDRSIZE];   /* 
16f80 42 75 66 66 65 72 20 74 6f 20 61 73 73 65 6d 62  Buffer to assemb
16f90 6c 65 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20  le frame-header 
16fa0 69 6e 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70  in */.  PgHdr *p
16fb0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
16fc0 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61          /* Itera
16fd0 74 6f 72 20 74 6f 20 72 75 6e 20 74 68 72 6f 75  tor to run throu
16fe0 67 68 20 70 4c 69 73 74 20 77 69 74 68 2e 20 2a  gh pList with. *
16ff0 2f 0a 20 20 50 67 48 64 72 20 2a 70 4c 61 73 74  /.  PgHdr *pLast
17000 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
17010 20 20 20 20 2f 2a 20 4c 61 73 74 20 66 72 61 6d      /* Last fram
17020 65 20 69 6e 20 6c 69 73 74 20 2a 2f 0a 20 20 69  e in list */.  i
17030 6e 74 20 6e 4c 61 73 74 20 3d 20 30 3b 20 20 20  nt nLast = 0;   
17040 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
17050 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 78 74 72  * Number of extr
17060 61 20 63 6f 70 69 65 73 20 6f 66 20 6c 61 73 74  a copies of last
17070 20 70 61 67 65 20 2a 2f 0a 0a 20 20 61 73 73 65   page */..  asse
17080 72 74 28 20 70 4c 69 73 74 20 29 3b 0a 20 20 61  rt( pList );.  a
17090 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69  ssert( pWal->wri
170a0 74 65 4c 6f 63 6b 20 29 3b 0a 0a 23 69 66 20 64  teLock );..#if d
170b0 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54 45  efined(SQLITE_TE
170c0 53 54 29 20 26 26 20 64 65 66 69 6e 65 64 28 53  ST) && defined(S
170d0 51 4c 49 54 45 5f 44 45 42 55 47 29 0a 20 20 7b  QLITE_DEBUG).  {
170e0 20 69 6e 74 20 63 6e 74 3b 20 66 6f 72 28 63 6e   int cnt; for(cn
170f0 74 3d 30 2c 20 70 3d 70 4c 69 73 74 3b 20 70 3b  t=0, p=pList; p;
17100 20 70 3d 70 2d 3e 70 44 69 72 74 79 2c 20 63 6e   p=p->pDirty, cn
17110 74 2b 2b 29 7b 7d 0a 20 20 20 20 57 41 4c 54 52  t++){}.    WALTR
17120 41 43 45 28 28 22 57 41 4c 25 70 3a 20 66 72 61  ACE(("WAL%p: fra
17130 6d 65 20 77 72 69 74 65 20 62 65 67 69 6e 2e 20  me write begin. 
17140 25 64 20 66 72 61 6d 65 73 2e 20 6d 78 46 72 61  %d frames. mxFra
17150 6d 65 3d 25 64 2e 20 25 73 5c 6e 22 2c 0a 20 20  me=%d. %s\n",.  
17160 20 20 20 20 20 20 20 20 20 20 20 20 70 57 61 6c              pWal
17170 2c 20 63 6e 74 2c 20 70 57 61 6c 2d 3e 68 64 72  , cnt, pWal->hdr
17180 2e 6d 78 46 72 61 6d 65 2c 20 69 73 43 6f 6d 6d  .mxFrame, isComm
17190 69 74 20 3f 20 22 43 6f 6d 6d 69 74 22 20 3a 20  it ? "Commit" : 
171a0 22 53 70 69 6c 6c 22 29 29 3b 0a 20 20 7d 0a 23  "Spill"));.  }.#
171b0 65 6e 64 69 66 0a 0a 20 20 2f 2a 20 53 65 65 20  endif..  /* See 
171c0 69 66 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c  if it is possibl
171d0 65 20 74 6f 20 77 72 69 74 65 20 74 68 65 73 65  e to write these
171e0 20 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68 65   frames into the
171f0 20 73 74 61 72 74 20 6f 66 20 74 68 65 0a 20 20   start of the.  
17200 2a 2a 20 6c 6f 67 20 66 69 6c 65 2c 20 69 6e 73  ** log file, ins
17210 74 65 61 64 20 6f 66 20 61 70 70 65 6e 64 69 6e  tead of appendin
17220 67 20 74 6f 20 69 74 20 61 74 20 70 57 61 6c 2d  g to it at pWal-
17230 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a 20 20  >hdr.mxFrame..  
17240 2a 2f 0a 20 20 69 66 28 20 53 51 4c 49 54 45 5f  */.  if( SQLITE_
17250 4f 4b 21 3d 28 72 63 20 3d 20 77 61 6c 52 65 73  OK!=(rc = walRes
17260 74 61 72 74 4c 6f 67 28 70 57 61 6c 29 29 20 29  tartLog(pWal)) )
17270 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  {.    return rc;
17280 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68  .  }..  /* If th
17290 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20  is is the first 
172a0 66 72 61 6d 65 20 77 72 69 74 74 65 6e 20 69 6e  frame written in
172b0 74 6f 20 74 68 65 20 6c 6f 67 2c 20 77 72 69 74  to the log, writ
172c0 65 20 74 68 65 20 57 41 4c 0a 20 20 2a 2a 20 68  e the WAL.  ** h
172d0 65 61 64 65 72 20 74 6f 20 74 68 65 20 73 74 61  eader to the sta
172e0 72 74 20 6f 66 20 74 68 65 20 57 41 4c 20 66 69  rt of the WAL fi
172f0 6c 65 2e 20 53 65 65 20 63 6f 6d 6d 65 6e 74 73  le. See comments
17300 20 61 74 20 74 68 65 20 74 6f 70 20 6f 66 0a 20   at the top of. 
17310 20 2a 2a 20 74 68 69 73 20 73 6f 75 72 63 65 20   ** this source 
17320 66 69 6c 65 20 66 6f 72 20 61 20 64 65 73 63 72  file for a descr
17330 69 70 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41  iption of the WA
17340 4c 20 68 65 61 64 65 72 20 66 6f 72 6d 61 74 2e  L header format.
17350 0a 20 20 2a 2f 0a 20 20 69 46 72 61 6d 65 20 3d  .  */.  iFrame =
17360 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
17370 6d 65 3b 0a 20 20 69 66 28 20 69 46 72 61 6d 65  me;.  if( iFrame
17380 3d 3d 30 20 29 7b 0a 20 20 20 20 75 38 20 61 57  ==0 ){.    u8 aW
17390 61 6c 48 64 72 5b 57 41 4c 5f 48 44 52 53 49 5a  alHdr[WAL_HDRSIZ
173a0 45 5d 3b 20 20 20 20 20 20 2f 2a 20 42 75 66 66  E];      /* Buff
173b0 65 72 20 74 6f 20 61 73 73 65 6d 62 6c 65 20 77  er to assemble w
173c0 61 6c 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f 0a  al-header in */.
173d0 20 20 20 20 75 33 32 20 61 43 6b 73 75 6d 5b 32      u32 aCksum[2
173e0 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ];              
173f0 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66 6f    /* Checksum fo
17400 72 20 77 61 6c 2d 68 65 61 64 65 72 20 2a 2f 0a  r wal-header */.
17410 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34  .    sqlite3Put4
17420 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 30 5d  byte(&aWalHdr[0]
17430 2c 20 28 57 41 4c 5f 4d 41 47 49 43 20 7c 20 53  , (WAL_MAGIC | S
17440 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e 29  QLITE_BIGENDIAN)
17450 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75  );.    sqlite3Pu
17460 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b  t4byte(&aWalHdr[
17470 34 5d 2c 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53  4], WAL_MAX_VERS
17480 49 4f 4e 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  ION);.    sqlite
17490 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c 48  3Put4byte(&aWalH
174a0 64 72 5b 38 5d 2c 20 73 7a 50 61 67 65 29 3b 0a  dr[8], szPage);.
174b0 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62      sqlite3Put4b
174c0 79 74 65 28 26 61 57 61 6c 48 64 72 5b 31 32 5d  yte(&aWalHdr[12]
174d0 2c 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 29 3b 0a  , pWal->nCkpt);.
174e0 20 20 20 20 73 71 6c 69 74 65 33 5f 72 61 6e 64      sqlite3_rand
174f0 6f 6d 6e 65 73 73 28 38 2c 20 70 57 61 6c 2d 3e  omness(8, pWal->
17500 68 64 72 2e 61 53 61 6c 74 29 3b 0a 20 20 20 20  hdr.aSalt);.    
17510 6d 65 6d 63 70 79 28 26 61 57 61 6c 48 64 72 5b  memcpy(&aWalHdr[
17520 31 36 5d 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61  16], pWal->hdr.a
17530 53 61 6c 74 2c 20 38 29 3b 0a 20 20 20 20 77 61  Salt, 8);.    wa
17540 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28 31  lChecksumBytes(1
17550 2c 20 61 57 61 6c 48 64 72 2c 20 57 41 4c 5f 48  , aWalHdr, WAL_H
17560 44 52 53 49 5a 45 2d 32 2a 34 2c 20 30 2c 20 61  DRSIZE-2*4, 0, a
17570 43 6b 73 75 6d 29 3b 0a 20 20 20 20 73 71 6c 69  Cksum);.    sqli
17580 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61  te3Put4byte(&aWa
17590 6c 48 64 72 5b 32 34 5d 2c 20 61 43 6b 73 75 6d  lHdr[24], aCksum
175a0 5b 30 5d 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  [0]);.    sqlite
175b0 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c 48  3Put4byte(&aWalH
175c0 64 72 5b 32 38 5d 2c 20 61 43 6b 73 75 6d 5b 31  dr[28], aCksum[1
175d0 5d 29 3b 0a 20 20 20 20 0a 20 20 20 20 70 57 61  ]);.    .    pWa
175e0 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50 61  l->szPage = szPa
175f0 67 65 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64  ge;.    pWal->hd
17600 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 20 3d 20  r.bigEndCksum = 
17610 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e  SQLITE_BIGENDIAN
17620 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  ;.    pWal->hdr.
17630 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d  aFrameCksum[0] =
17640 20 61 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 20 20   aCksum[0];.    
17650 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
17660 43 6b 73 75 6d 5b 31 5d 20 3d 20 61 43 6b 73 75  Cksum[1] = aCksu
17670 6d 5b 31 5d 3b 0a 0a 20 20 20 20 72 63 20 3d 20  m[1];..    rc = 
17680 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70  sqlite3OsWrite(p
17690 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 57 61  Wal->pWalFd, aWa
176a0 6c 48 64 72 2c 20 73 69 7a 65 6f 66 28 61 57 61  lHdr, sizeof(aWa
176b0 6c 48 64 72 29 2c 20 30 29 3b 0a 20 20 20 20 57  lHdr), 0);.    W
176c0 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
176d0 20 77 61 6c 2d 68 65 61 64 65 72 20 77 72 69 74   wal-header writ
176e0 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  e %s\n", pWal, r
176f0 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
17700 6f 6b 22 29 29 3b 0a 20 20 20 20 69 66 28 20 72  ok"));.    if( r
17710 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
17720 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
17730 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73  .    }.  }.  ass
17740 65 72 74 28 20 28 69 6e 74 29 70 57 61 6c 2d 3e  ert( (int)pWal->
17750 73 7a 50 61 67 65 3d 3d 73 7a 50 61 67 65 20 29  szPage==szPage )
17760 3b 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20 74 68  ;..  /* Write th
17770 65 20 6c 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a 20  e log file. */. 
17780 20 66 6f 72 28 70 3d 70 4c 69 73 74 3b 20 70 3b   for(p=pList; p;
17790 20 70 3d 70 2d 3e 70 44 69 72 74 79 29 7b 0a 20   p=p->pDirty){. 
177a0 20 20 20 75 33 32 20 6e 44 62 73 69 7a 65 3b 20     u32 nDbsize; 
177b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
177c0 20 2f 2a 20 44 62 2d 73 69 7a 65 20 66 69 65 6c   /* Db-size fiel
177d0 64 20 66 6f 72 20 66 72 61 6d 65 20 68 65 61 64  d for frame head
177e0 65 72 20 2a 2f 0a 20 20 20 20 69 36 34 20 69 4f  er */.    i64 iO
177f0 66 66 73 65 74 3b 20 20 20 20 20 20 20 20 20 20  ffset;          
17800 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65          /* Write
17810 20 6f 66 66 73 65 74 20 69 6e 20 6c 6f 67 20 66   offset in log f
17820 69 6c 65 20 2a 2f 0a 20 20 20 20 76 6f 69 64 20  ile */.    void 
17830 2a 70 44 61 74 61 3b 0a 20 20 20 0a 20 20 20 20  *pData;.   .    
17840 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61  iOffset = walFra
17850 6d 65 4f 66 66 73 65 74 28 2b 2b 69 46 72 61 6d  meOffset(++iFram
17860 65 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20 20 20  e, szPage);.    
17870 2f 2a 20 74 65 73 74 63 61 73 65 28 20 49 53 5f  /* testcase( IS_
17880 42 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29  BIG_INT(iOffset)
17890 20 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73 20   ); // requires 
178a0 61 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20 20  a 4GiB WAL */.  
178b0 20 20 0a 20 20 20 20 2f 2a 20 50 6f 70 75 6c 61    .    /* Popula
178c0 74 65 20 61 6e 64 20 77 72 69 74 65 20 74 68 65  te and write the
178d0 20 66 72 61 6d 65 20 68 65 61 64 65 72 20 2a 2f   frame header */
178e0 0a 20 20 20 20 6e 44 62 73 69 7a 65 20 3d 20 28  .    nDbsize = (
178f0 69 73 43 6f 6d 6d 69 74 20 26 26 20 70 2d 3e 70  isCommit && p->p
17900 44 69 72 74 79 3d 3d 30 29 20 3f 20 6e 54 72 75  Dirty==0) ? nTru
17910 6e 63 61 74 65 20 3a 20 30 3b 0a 23 69 66 20 64  ncate : 0;.#if d
17920 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 48 41  efined(SQLITE_HA
17930 53 5f 43 4f 44 45 43 29 0a 20 20 20 20 69 66 28  S_CODEC).    if(
17940 20 28 70 44 61 74 61 20 3d 20 73 71 6c 69 74 65   (pData = sqlite
17950 33 50 61 67 65 72 43 6f 64 65 63 28 70 29 29 3d  3PagerCodec(p))=
17960 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
17970 54 45 5f 4e 4f 4d 45 4d 3b 0a 23 65 6c 73 65 0a  TE_NOMEM;.#else.
17980 20 20 20 20 70 44 61 74 61 20 3d 20 70 2d 3e 70      pData = p->p
17990 44 61 74 61 3b 0a 23 65 6e 64 69 66 0a 20 20 20  Data;.#endif.   
179a0 20 77 61 6c 45 6e 63 6f 64 65 46 72 61 6d 65 28   walEncodeFrame(
179b0 70 57 61 6c 2c 20 70 2d 3e 70 67 6e 6f 2c 20 6e  pWal, p->pgno, n
179c0 44 62 73 69 7a 65 2c 20 70 44 61 74 61 2c 20 61  Dbsize, pData, a
179d0 46 72 61 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d  Frame);.    rc =
179e0 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28   sqlite3OsWrite(
179f0 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 46  pWal->pWalFd, aF
17a00 72 61 6d 65 2c 20 73 69 7a 65 6f 66 28 61 46 72  rame, sizeof(aFr
17a10 61 6d 65 29 2c 20 69 4f 66 66 73 65 74 29 3b 0a  ame), iOffset);.
17a20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
17a30 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  TE_OK ){.      r
17a40 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
17a50 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68  .    /* Write th
17a60 65 20 70 61 67 65 20 64 61 74 61 20 2a 2f 0a 20  e page data */. 
17a70 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
17a80 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 57 61  sWrite(pWal->pWa
17a90 6c 46 64 2c 20 70 44 61 74 61 2c 20 73 7a 50 61  lFd, pData, szPa
17aa0 67 65 2c 20 69 4f 66 66 73 65 74 2b 73 69 7a 65  ge, iOffset+size
17ab0 6f 66 28 61 46 72 61 6d 65 29 29 3b 0a 20 20 20  of(aFrame));.   
17ac0 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
17ad0 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75  OK ){.      retu
17ae0 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20  rn rc;.    }.   
17af0 20 70 4c 61 73 74 20 3d 20 70 3b 0a 20 20 7d 0a   pLast = p;.  }.
17b00 0a 20 20 2f 2a 20 53 79 6e 63 20 74 68 65 20 6c  .  /* Sync the l
17b10 6f 67 20 66 69 6c 65 20 69 66 20 74 68 65 20 27  og file if the '
17b20 69 73 53 79 6e 63 27 20 66 6c 61 67 20 77 61 73  isSync' flag was
17b30 20 73 70 65 63 69 66 69 65 64 2e 20 2a 2f 0a 20   specified. */. 
17b40 20 69 66 28 20 73 79 6e 63 5f 66 6c 61 67 73 20   if( sync_flags 
17b50 29 7b 0a 20 20 20 20 69 36 34 20 69 53 65 67 6d  ){.    i64 iSegm
17b60 65 6e 74 20 3d 20 73 71 6c 69 74 65 33 4f 73 53  ent = sqlite3OsS
17b70 65 63 74 6f 72 53 69 7a 65 28 70 57 61 6c 2d 3e  ectorSize(pWal->
17b80 70 57 61 6c 46 64 29 3b 0a 20 20 20 20 69 36 34  pWalFd);.    i64
17b90 20 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72   iOffset = walFr
17ba0 61 6d 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65  ameOffset(iFrame
17bb0 2b 31 2c 20 73 7a 50 61 67 65 29 3b 0a 0a 20 20  +1, szPage);..  
17bc0 20 20 61 73 73 65 72 74 28 20 69 73 43 6f 6d 6d    assert( isComm
17bd0 69 74 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  it );.    assert
17be0 28 20 69 53 65 67 6d 65 6e 74 3e 30 20 29 3b 0a  ( iSegment>0 );.
17bf0 0a 20 20 20 20 69 53 65 67 6d 65 6e 74 20 3d 20  .    iSegment = 
17c00 28 28 28 69 4f 66 66 73 65 74 2b 69 53 65 67 6d  (((iOffset+iSegm
17c10 65 6e 74 2d 31 29 2f 69 53 65 67 6d 65 6e 74 29  ent-1)/iSegment)
17c20 20 2a 20 69 53 65 67 6d 65 6e 74 29 3b 0a 20 20   * iSegment);.  
17c30 20 20 77 68 69 6c 65 28 20 69 4f 66 66 73 65 74    while( iOffset
17c40 3c 69 53 65 67 6d 65 6e 74 20 29 7b 0a 20 20 20  <iSegment ){.   
17c50 20 20 20 76 6f 69 64 20 2a 70 44 61 74 61 3b 0a     void *pData;.
17c60 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49  #if defined(SQLI
17c70 54 45 5f 48 41 53 5f 43 4f 44 45 43 29 0a 20 20  TE_HAS_CODEC).  
17c80 20 20 20 20 69 66 28 20 28 70 44 61 74 61 20 3d      if( (pData =
17c90 20 73 71 6c 69 74 65 33 50 61 67 65 72 43 6f 64   sqlite3PagerCod
17ca0 65 63 28 70 4c 61 73 74 29 29 3d 3d 30 20 29 20  ec(pLast))==0 ) 
17cb0 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
17cc0 4d 45 4d 3b 0a 23 65 6c 73 65 0a 20 20 20 20 20  MEM;.#else.     
17cd0 20 70 44 61 74 61 20 3d 20 70 4c 61 73 74 2d 3e   pData = pLast->
17ce0 70 44 61 74 61 3b 0a 23 65 6e 64 69 66 0a 20 20  pData;.#endif.  
17cf0 20 20 20 20 77 61 6c 45 6e 63 6f 64 65 46 72 61      walEncodeFra
17d00 6d 65 28 70 57 61 6c 2c 20 70 4c 61 73 74 2d 3e  me(pWal, pLast->
17d10 70 67 6e 6f 2c 20 6e 54 72 75 6e 63 61 74 65 2c  pgno, nTruncate,
17d20 20 70 44 61 74 61 2c 20 61 46 72 61 6d 65 29 3b   pData, aFrame);
17d30 0a 20 20 20 20 20 20 2f 2a 20 74 65 73 74 63 61  .      /* testca
17d40 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28 69  se( IS_BIG_INT(i
17d50 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f 20 72 65  Offset) ); // re
17d60 71 75 69 72 65 73 20 61 20 34 47 69 42 20 57 41  quires a 4GiB WA
17d70 4c 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20  L */.      rc = 
17d80 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70  sqlite3OsWrite(p
17d90 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 46 72  Wal->pWalFd, aFr
17da0 61 6d 65 2c 20 73 69 7a 65 6f 66 28 61 46 72 61  ame, sizeof(aFra
17db0 6d 65 29 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20  me), iOffset);. 
17dc0 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c       if( rc!=SQL
17dd0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
17de0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20    return rc;.   
17df0 20 20 20 7d 0a 20 20 20 20 20 20 69 4f 66 66 73     }.      iOffs
17e00 65 74 20 2b 3d 20 57 41 4c 5f 46 52 41 4d 45 5f  et += WAL_FRAME_
17e10 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 20 20 72  HDRSIZE;.      r
17e20 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69  c = sqlite3OsWri
17e30 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  te(pWal->pWalFd,
17e40 20 70 44 61 74 61 2c 20 73 7a 50 61 67 65 2c 20   pData, szPage, 
17e50 69 4f 66 66 73 65 74 29 3b 20 0a 20 20 20 20 20  iOffset); .     
17e60 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
17e70 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65  OK ){.        re
17e80 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d  turn rc;.      }
17e90 0a 20 20 20 20 20 20 6e 4c 61 73 74 2b 2b 3b 0a  .      nLast++;.
17ea0 20 20 20 20 20 20 69 4f 66 66 73 65 74 20 2b 3d        iOffset +=
17eb0 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 7d 0a 0a   szPage;.    }..
17ec0 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
17ed0 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57 61  OsSync(pWal->pWa
17ee0 6c 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73 29  lFd, sync_flags)
17ef0 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 70 70 65  ;.  }..  /* Appe
17f00 6e 64 20 64 61 74 61 20 74 6f 20 74 68 65 20 77  nd data to the w
17f10 61 6c 2d 69 6e 64 65 78 2e 20 49 74 20 69 73 20  al-index. It is 
17f20 6e 6f 74 20 6e 65 63 65 73 73 61 72 79 20 74 6f  not necessary to
17f30 20 6c 6f 63 6b 20 74 68 65 20 0a 20 20 2a 2a 20   lock the .  ** 
17f40 77 61 6c 2d 69 6e 64 65 78 20 74 6f 20 64 6f 20  wal-index to do 
17f50 74 68 69 73 20 61 73 20 74 68 65 20 53 51 4c 49  this as the SQLI
17f60 54 45 5f 53 48 4d 5f 57 52 49 54 45 20 6c 6f 63  TE_SHM_WRITE loc
17f70 6b 20 68 65 6c 64 20 6f 6e 20 74 68 65 20 77 61  k held on the wa
17f80 6c 2d 69 6e 64 65 78 0a 20 20 2a 2a 20 67 75 61  l-index.  ** gua
17f90 72 61 6e 74 65 65 73 20 74 68 61 74 20 74 68 65  rantees that the
17fa0 72 65 20 61 72 65 20 6e 6f 20 6f 74 68 65 72 20  re are no other 
17fb0 77 72 69 74 65 72 73 2c 20 61 6e 64 20 6e 6f 20  writers, and no 
17fc0 64 61 74 61 20 74 68 61 74 20 6d 61 79 0a 20 20  data that may.  
17fd0 2a 2a 20 62 65 20 69 6e 20 75 73 65 20 62 79 20  ** be in use by 
17fe0 65 78 69 73 74 69 6e 67 20 72 65 61 64 65 72 73  existing readers
17ff0 20 69 73 20 62 65 69 6e 67 20 6f 76 65 72 77 72   is being overwr
18000 69 74 74 65 6e 2e 0a 20 20 2a 2f 0a 20 20 69 46  itten..  */.  iF
18010 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72  rame = pWal->hdr
18020 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 66 6f 72 28  .mxFrame;.  for(
18030 70 3d 70 4c 69 73 74 3b 20 70 20 26 26 20 72 63  p=pList; p && rc
18040 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 70 3d 70  ==SQLITE_OK; p=p
18050 2d 3e 70 44 69 72 74 79 29 7b 0a 20 20 20 20 69  ->pDirty){.    i
18060 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 72 63 20  Frame++;.    rc 
18070 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64  = walIndexAppend
18080 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c 20 70  (pWal, iFrame, p
18090 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 20 20 77  ->pgno);.  }.  w
180a0 68 69 6c 65 28 20 6e 4c 61 73 74 3e 30 20 26 26  hile( nLast>0 &&
180b0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
180c0 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b 2b 3b 0a  {.    iFrame++;.
180d0 20 20 20 20 6e 4c 61 73 74 2d 2d 3b 0a 20 20 20      nLast--;.   
180e0 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70   rc = walIndexAp
180f0 70 65 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d  pend(pWal, iFram
18100 65 2c 20 70 4c 61 73 74 2d 3e 70 67 6e 6f 29 3b  e, pLast->pgno);
18110 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
18120 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
18130 20 2f 2a 20 55 70 64 61 74 65 20 74 68 65 20 70   /* Update the p
18140 72 69 76 61 74 65 20 63 6f 70 79 20 6f 66 20 74  rivate copy of t
18150 68 65 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20 20  he header. */.  
18160 20 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61    pWal->hdr.szPa
18170 67 65 20 3d 20 28 75 31 36 29 28 28 73 7a 50 61  ge = (u16)((szPa
18180 67 65 26 30 78 66 66 30 30 29 20 7c 20 28 73 7a  ge&0xff00) | (sz
18190 50 61 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20 20  Page>>16));.    
181a0 74 65 73 74 63 61 73 65 28 20 73 7a 50 61 67 65  testcase( szPage
181b0 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20 20 20 74  <=32768 );.    t
181c0 65 73 74 63 61 73 65 28 20 73 7a 50 61 67 65 3e  estcase( szPage>
181d0 3d 36 35 35 33 36 20 29 3b 0a 20 20 20 20 70 57  =65536 );.    pW
181e0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
181f0 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20 20 69 66  = iFrame;.    if
18200 28 20 69 73 43 6f 6d 6d 69 74 20 29 7b 0a 20 20  ( isCommit ){.  
18210 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69 43      pWal->hdr.iC
18220 68 61 6e 67 65 2b 2b 3b 0a 20 20 20 20 20 20 70  hange++;.      p
18230 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20 3d  Wal->hdr.nPage =
18240 20 6e 54 72 75 6e 63 61 74 65 3b 0a 20 20 20 20   nTruncate;.    
18250 7d 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73  }.    /* If this
18260 20 69 73 20 61 20 63 6f 6d 6d 69 74 2c 20 75 70   is a commit, up
18270 64 61 74 65 20 74 68 65 20 77 61 6c 2d 69 6e 64  date the wal-ind
18280 65 78 20 68 65 61 64 65 72 20 74 6f 6f 2e 20 2a  ex header too. *
18290 2f 0a 20 20 20 20 69 66 28 20 69 73 43 6f 6d 6d  /.    if( isComm
182a0 69 74 20 29 7b 0a 20 20 20 20 20 20 77 61 6c 49  it ){.      walI
182b0 6e 64 65 78 57 72 69 74 65 48 64 72 28 70 57 61  ndexWriteHdr(pWa
182c0 6c 29 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e  l);.      pWal->
182d0 69 43 61 6c 6c 62 61 63 6b 20 3d 20 69 46 72 61  iCallback = iFra
182e0 6d 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  me;.    }.  }.. 
182f0 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
18300 70 3a 20 66 72 61 6d 65 20 77 72 69 74 65 20 25  p: frame write %
18310 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72 63 20 3f  s\n", pWal, rc ?
18320 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22   "failed" : "ok"
18330 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ));.  return rc;
18340 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20  .}../* .** This 
18350 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65  routine is calle
18360 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 73  d to implement s
18370 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68 65 63 6b  qlite3_wal_check
18380 70 6f 69 6e 74 28 29 20 61 6e 64 0a 2a 2a 20 72  point() and.** r
18390 65 6c 61 74 65 64 20 69 6e 74 65 72 66 61 63 65  elated interface
183a0 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20  s..**.** Obtain 
183b0 61 20 43 48 45 43 4b 50 4f 49 4e 54 20 6c 6f 63  a CHECKPOINT loc
183c0 6b 20 61 6e 64 20 74 68 65 6e 20 62 61 63 6b 66  k and then backf
183d0 69 6c 6c 20 61 73 20 6d 75 63 68 20 69 6e 66 6f  ill as much info
183e0 72 6d 61 74 69 6f 6e 20 61 73 0a 2a 2a 20 77 65  rmation as.** we
183f0 20 63 61 6e 20 66 72 6f 6d 20 57 41 4c 20 69 6e   can from WAL in
18400 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 2e  to the database.
18410 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
18420 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a 20 20  alCheckpoint(.  
18430 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20  Wal *pWal,      
18440 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18450 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65 63 74 69 6f  /* Wal connectio
18460 6e 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f  n */.  int sync_
18470 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20 20 20  flags,          
18480 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20         /* Flags 
18490 74 6f 20 73 79 6e 63 20 64 62 20 66 69 6c 65 20  to sync db file 
184a0 77 69 74 68 20 28 6f 72 20 30 29 20 2a 2f 0a 20  with (or 0) */. 
184b0 20 69 6e 74 20 6e 42 75 66 2c 20 20 20 20 20 20   int nBuf,      
184c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
184d0 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74 65 6d 70   /* Size of temp
184e0 6f 72 61 72 79 20 62 75 66 66 65 72 20 2a 2f 0a  orary buffer */.
184f0 20 20 75 38 20 2a 7a 42 75 66 20 20 20 20 20 20    u8 *zBuf      
18500 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18510 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62    /* Temporary b
18520 75 66 66 65 72 20 74 6f 20 75 73 65 20 2a 2f 0a  uffer to use */.
18530 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  ){.  int rc;    
18540 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18550 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
18560 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43  ode */.  int isC
18570 68 61 6e 67 65 64 20 3d 20 30 3b 20 20 20 20 20  hanged = 0;     
18580 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
18590 20 69 66 20 61 20 6e 65 77 20 77 61 6c 2d 69 6e   if a new wal-in
185a0 64 65 78 20 68 65 61 64 65 72 20 69 73 20 6c 6f  dex header is lo
185b0 61 64 65 64 20 2a 2f 0a 0a 20 20 61 73 73 65 72  aded */..  asser
185c0 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63  t( pWal->ckptLoc
185d0 6b 3d 3d 30 20 29 3b 0a 0a 20 20 57 41 4c 54 52  k==0 );..  WALTR
185e0 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63 68 65  ACE(("WAL%p: che
185f0 63 6b 70 6f 69 6e 74 20 62 65 67 69 6e 73 5c 6e  ckpoint begins\n
18600 22 2c 20 70 57 61 6c 29 29 3b 0a 20 20 72 63 20  ", pWal));.  rc 
18610 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69  = walLockExclusi
18620 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 43 4b 50  ve(pWal, WAL_CKP
18630 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 69 66  T_LOCK, 1);.  if
18640 28 20 72 63 20 29 7b 0a 20 20 20 20 2f 2a 20 55  ( rc ){.    /* U
18650 73 75 61 6c 6c 79 20 74 68 69 73 20 69 73 20 53  sually this is S
18660 51 4c 49 54 45 5f 42 55 53 59 20 6d 65 61 6e 69  QLITE_BUSY meani
18670 6e 67 20 74 68 61 74 20 61 6e 6f 74 68 65 72 20  ng that another 
18680 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73  thread or proces
18690 73 0a 20 20 20 20 2a 2a 20 69 73 20 61 6c 72 65  s.    ** is alre
186a0 61 64 79 20 72 75 6e 6e 69 6e 67 20 61 20 63 68  ady running a ch
186b0 65 63 6b 70 6f 69 6e 74 2c 20 6f 72 20 6d 61 79  eckpoint, or may
186c0 62 65 20 61 20 72 65 63 6f 76 65 72 79 2e 20 20  be a recovery.  
186d0 42 75 74 20 69 74 20 6d 69 67 68 74 0a 20 20 20  But it might.   
186e0 20 2a 2a 20 61 6c 73 6f 20 62 65 20 53 51 4c 49   ** also be SQLI
186f0 54 45 5f 49 4f 45 52 52 2e 20 2a 2f 0a 20 20 20  TE_IOERR. */.   
18700 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
18710 20 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b    pWal->ckptLock
18720 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 43 6f 70 79   = 1;..  /* Copy
18730 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 6c   data from the l
18740 6f 67 20 74 6f 20 74 68 65 20 64 61 74 61 62 61  og to the databa
18750 73 65 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 72 63  se file. */.  rc
18760 20 3d 20 77 61 6c 49 6e 64 65 78 52 65 61 64 48   = walIndexReadH
18770 64 72 28 70 57 61 6c 2c 20 26 69 73 43 68 61 6e  dr(pWal, &isChan
18780 67 65 64 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d  ged);.  if( rc==
18790 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
187a0 20 72 63 20 3d 20 77 61 6c 43 68 65 63 6b 70 6f   rc = walCheckpo
187b0 69 6e 74 28 70 57 61 6c 2c 20 73 79 6e 63 5f 66  int(pWal, sync_f
187c0 6c 61 67 73 2c 20 6e 42 75 66 2c 20 7a 42 75 66  lags, nBuf, zBuf
187d0 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 73 43  );.  }.  if( isC
187e0 68 61 6e 67 65 64 20 29 7b 0a 20 20 20 20 2f 2a  hanged ){.    /*
187f0 20 49 66 20 61 20 6e 65 77 20 77 61 6c 2d 69 6e   If a new wal-in
18800 64 65 78 20 68 65 61 64 65 72 20 77 61 73 20 6c  dex header was l
18810 6f 61 64 65 64 20 62 65 66 6f 72 65 20 74 68 65  oaded before the
18820 20 63 68 65 63 6b 70 6f 69 6e 74 20 77 61 73 20   checkpoint was 
18830 0a 20 20 20 20 2a 2a 20 70 65 72 66 6f 72 6d 65  .    ** performe
18840 64 2c 20 74 68 65 6e 20 74 68 65 20 70 61 67 65  d, then the page
18850 72 2d 63 61 63 68 65 20 61 73 73 6f 63 69 61 74  r-cache associat
18860 65 64 20 77 69 74 68 20 70 57 61 6c 20 69 73 20  ed with pWal is 
18870 6e 6f 77 0a 20 20 20 20 2a 2a 20 6f 75 74 20 6f  now.    ** out o
18880 66 20 64 61 74 65 2e 20 53 6f 20 7a 65 72 6f 20  f date. So zero 
18890 74 68 65 20 63 61 63 68 65 64 20 77 61 6c 2d 69  the cached wal-i
188a0 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f 20 65  ndex header to e
188b0 6e 73 75 72 65 20 74 68 61 74 0a 20 20 20 20 2a  nsure that.    *
188c0 2a 20 6e 65 78 74 20 74 69 6d 65 20 74 68 65 20  * next time the 
188d0 70 61 67 65 72 20 6f 70 65 6e 73 20 61 20 73 6e  pager opens a sn
188e0 61 70 73 68 6f 74 20 6f 6e 20 74 68 69 73 20 64  apshot on this d
188f0 61 74 61 62 61 73 65 20 69 74 20 6b 6e 6f 77 73  atabase it knows
18900 20 74 68 61 74 0a 20 20 20 20 2a 2a 20 74 68 65   that.    ** the
18910 20 63 61 63 68 65 20 6e 65 65 64 73 20 74 6f 20   cache needs to 
18920 62 65 20 72 65 73 65 74 2e 0a 20 20 20 20 2a 2f  be reset..    */
18930 0a 20 20 20 20 6d 65 6d 73 65 74 28 26 70 57 61  .    memset(&pWa
18940 6c 2d 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f  l->hdr, 0, sizeo
18950 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b  f(WalIndexHdr));
18960 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 6c 65 61  .  }..  /* Relea
18970 73 65 20 74 68 65 20 6c 6f 63 6b 73 2e 20 2a 2f  se the locks. */
18980 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c  .  walUnlockExcl
18990 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
189a0 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  CKPT_LOCK, 1);. 
189b0 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20   pWal->ckptLock 
189c0 3d 20 30 3b 0a 20 20 57 41 4c 54 52 41 43 45 28  = 0;.  WALTRACE(
189d0 28 22 57 41 4c 25 70 3a 20 63 68 65 63 6b 70 6f  ("WAL%p: checkpo
189e0 69 6e 74 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c  int %s\n", pWal,
189f0 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a   rc ? "failed" :
18a00 20 22 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75 72   "ok"));.  retur
18a10 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 52 65 74 75  n rc;.}../* Retu
18a20 72 6e 20 74 68 65 20 76 61 6c 75 65 20 74 6f 20  rn the value to 
18a30 70 61 73 73 20 74 6f 20 61 20 73 71 6c 69 74 65  pass to a sqlite
18a40 33 5f 77 61 6c 5f 68 6f 6f 6b 20 63 61 6c 6c 62  3_wal_hook callb
18a50 61 63 6b 2c 20 74 68 65 0a 2a 2a 20 6e 75 6d 62  ack, the.** numb
18a60 65 72 20 6f 66 20 66 72 61 6d 65 73 20 69 6e 20  er of frames in 
18a70 74 68 65 20 57 41 4c 20 61 74 20 74 68 65 20 70  the WAL at the p
18a80 6f 69 6e 74 20 6f 66 20 74 68 65 20 6c 61 73 74  oint of the last
18a90 20 63 6f 6d 6d 69 74 20 73 69 6e 63 65 0a 2a 2a   commit since.**
18aa0 20 73 71 6c 69 74 65 33 57 61 6c 43 61 6c 6c 62   sqlite3WalCallb
18ab0 61 63 6b 28 29 20 77 61 73 20 63 61 6c 6c 65 64  ack() was called
18ac0 2e 20 20 49 66 20 6e 6f 20 63 6f 6d 6d 69 74 73  .  If no commits
18ad0 20 68 61 76 65 20 6f 63 63 75 72 72 65 64 20 73   have occurred s
18ae0 69 6e 63 65 0a 2a 2a 20 74 68 65 20 6c 61 73 74  ince.** the last
18af0 20 63 61 6c 6c 2c 20 74 68 65 6e 20 72 65 74 75   call, then retu
18b00 72 6e 20 30 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  rn 0..*/.int sql
18b10 69 74 65 33 57 61 6c 43 61 6c 6c 62 61 63 6b 28  ite3WalCallback(
18b20 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 75 33  Wal *pWal){.  u3
18b30 32 20 72 65 74 20 3d 20 30 3b 0a 20 20 69 66 28  2 ret = 0;.  if(
18b40 20 70 57 61 6c 20 29 7b 0a 20 20 20 20 72 65 74   pWal ){.    ret
18b50 20 3d 20 70 57 61 6c 2d 3e 69 43 61 6c 6c 62 61   = pWal->iCallba
18b60 63 6b 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 69 43  ck;.    pWal->iC
18b70 61 6c 6c 62 61 63 6b 20 3d 20 30 3b 0a 20 20 7d  allback = 0;.  }
18b80 0a 20 20 72 65 74 75 72 6e 20 28 69 6e 74 29 72  .  return (int)r
18b90 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  et;.}../*.** Thi
18ba0 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61  s function is ca
18bb0 6c 6c 65 64 20 74 6f 20 63 68 61 6e 67 65 20 74  lled to change t
18bc0 68 65 20 57 41 4c 20 73 75 62 73 79 73 74 65 6d  he WAL subsystem
18bd0 20 69 6e 74 6f 20 6f 72 20 6f 75 74 0a 2a 2a 20   into or out.** 
18be0 6f 66 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d  of locking_mode=
18bf0 45 58 43 4c 55 53 49 56 45 2e 0a 2a 2a 0a 2a 2a  EXCLUSIVE..**.**
18c00 20 49 66 20 6f 70 20 69 73 20 7a 65 72 6f 2c 20   If op is zero, 
18c10 74 68 65 6e 20 61 74 74 65 6d 70 74 20 74 6f 20  then attempt to 
18c20 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63 6b  change from lock
18c30 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49  ing_mode=EXCLUSI
18c40 56 45 0a 2a 2a 20 69 6e 74 6f 20 6c 6f 63 6b 69  VE.** into locki
18c50 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 2e 20  ng_mode=NORMAL. 
18c60 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68 61 74   This means that
18c70 20 77 65 20 6d 75 73 74 20 61 63 71 75 69 72 65   we must acquire
18c80 20 61 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68   a lock.** on th
18c90 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  e pWal->readLock
18ca0 20 62 79 74 65 2e 20 20 49 66 20 74 68 65 20 57   byte.  If the W
18cb0 41 4c 20 69 73 20 61 6c 72 65 61 64 79 20 69 6e  AL is already in
18cc0 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f   locking_mode=NO
18cd0 52 4d 41 4c 0a 2a 2a 20 6f 72 20 69 66 20 74 68  RMAL.** or if th
18ce0 65 20 61 63 71 75 69 73 69 74 69 6f 6e 20 6f 66  e acquisition of
18cf0 20 74 68 65 20 6c 6f 63 6b 20 66 61 69 6c 73 2c   the lock fails,
18d00 20 74 68 65 6e 20 72 65 74 75 72 6e 20 30 2e 20   then return 0. 
18d10 20 49 66 20 74 68 65 0a 2a 2a 20 74 72 61 6e 73   If the.** trans
18d20 69 74 69 6f 6e 20 6f 75 74 20 6f 66 20 65 78 63  ition out of exc
18d30 6c 75 73 69 76 65 2d 6d 6f 64 65 20 69 73 20 73  lusive-mode is s
18d40 75 63 63 65 73 73 66 75 6c 2c 20 72 65 74 75 72  uccessful, retur
18d50 6e 20 31 2e 20 20 54 68 69 73 0a 2a 2a 20 6f 70  n 1.  This.** op
18d60 65 72 61 74 69 6f 6e 20 6d 75 73 74 20 6f 63 63  eration must occ
18d70 75 72 20 77 68 69 6c 65 20 74 68 65 20 70 61 67  ur while the pag
18d80 65 72 20 69 73 20 73 74 69 6c 6c 20 68 6f 6c 64  er is still hold
18d90 69 6e 67 20 74 68 65 20 65 78 63 6c 75 73 69 76  ing the exclusiv
18da0 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20 74 68 65  e.** lock on the
18db0 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 66   main database f
18dc0 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70  ile..**.** If op
18dd0 20 69 73 20 6f 6e 65 2c 20 74 68 65 6e 20 63 68   is one, then ch
18de0 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63 6b 69 6e  ange from lockin
18df0 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 69 6e  g_mode=NORMAL in
18e00 74 6f 20 0a 2a 2a 20 6c 6f 63 6b 69 6e 67 5f 6d  to .** locking_m
18e10 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2e 20 20  ode=EXCLUSIVE.  
18e20 54 68 69 73 20 6d 65 61 6e 73 20 74 68 61 74 20  This means that 
18e30 74 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  the pWal->readLo
18e40 63 6b 20 6d 75 73 74 0a 2a 2a 20 62 65 20 72 65  ck must.** be re
18e50 6c 65 61 73 65 64 2e 20 20 52 65 74 75 72 6e 20  leased.  Return 
18e60 31 20 69 66 20 74 68 65 20 74 72 61 6e 73 69 74  1 if the transit
18e70 69 6f 6e 20 69 73 20 6d 61 64 65 20 61 6e 64 20  ion is made and 
18e80 30 20 69 66 20 74 68 65 0a 2a 2a 20 57 41 4c 20  0 if the.** WAL 
18e90 69 73 20 61 6c 72 65 61 64 79 20 69 6e 20 65 78  is already in ex
18ea0 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69 6e 67 20  clusive-locking 
18eb0 6d 6f 64 65 20 2d 20 6d 65 61 6e 69 6e 67 20 74  mode - meaning t
18ec0 68 61 74 20 74 68 69 73 0a 2a 2a 20 72 6f 75 74  hat this.** rout
18ed0 69 6e 65 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 20  ine is a no-op. 
18ee0 20 54 68 65 20 70 61 67 65 72 20 6d 75 73 74 20   The pager must 
18ef0 61 6c 72 65 61 64 79 20 68 6f 6c 64 20 74 68 65  already hold the
18f00 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 0a   exclusive lock.
18f10 2a 2a 20 6f 6e 20 74 68 65 20 6d 61 69 6e 20 64  ** on the main d
18f20 61 74 61 62 61 73 65 20 66 69 6c 65 20 62 65 66  atabase file bef
18f30 6f 72 65 20 69 6e 76 6f 6b 69 6e 67 20 74 68 69  ore invoking thi
18f40 73 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 2a 2a 0a  s operation..**.
18f50 2a 2a 20 49 66 20 6f 70 20 69 73 20 6e 65 67 61  ** If op is nega
18f60 74 69 76 65 2c 20 74 68 65 6e 20 64 6f 20 61 20  tive, then do a 
18f70 64 72 79 2d 72 75 6e 20 6f 66 20 74 68 65 20 6f  dry-run of the o
18f80 70 3d 3d 31 20 63 61 73 65 20 62 75 74 20 64 6f  p==1 case but do
18f90 0a 2a 2a 20 6e 6f 74 20 61 63 74 75 61 6c 6c 79  .** not actually
18fa0 20 63 68 61 6e 67 65 20 61 6e 79 74 68 69 6e 67   change anything
18fb0 2e 20 54 68 65 20 70 61 67 65 72 20 75 73 65 73  . The pager uses
18fc0 20 74 68 69 73 20 74 6f 20 73 65 65 20 69 66 20   this to see if 
18fd0 69 74 0a 2a 2a 20 73 68 6f 75 6c 64 20 61 63 71  it.** should acq
18fe0 75 69 72 65 20 74 68 65 20 64 61 74 61 62 61 73  uire the databas
18ff0 65 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b  e exclusive lock
19000 20 70 72 69 6f 72 20 74 6f 20 69 6e 76 6f 6b 69   prior to invoki
19010 6e 67 0a 2a 2a 20 74 68 65 20 6f 70 3d 3d 31 20  ng.** the op==1 
19020 63 61 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  case..*/.int sql
19030 69 74 65 33 57 61 6c 45 78 63 6c 75 73 69 76 65  ite3WalExclusive
19040 4d 6f 64 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Mode(Wal *pWal, 
19050 69 6e 74 20 6f 70 29 7b 0a 20 20 69 6e 74 20 72  int op){.  int r
19060 63 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  c;.  assert( pWa
19070 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20  l->writeLock==0 
19080 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  );.  assert( pWa
19090 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
190a0 21 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59  !=WAL_HEAPMEMORY
190b0 5f 4d 4f 44 45 20 7c 7c 20 6f 70 3d 3d 2d 31 20  _MODE || op==-1 
190c0 29 3b 0a 0a 20 20 2f 2a 20 70 57 61 6c 2d 3e 72  );..  /* pWal->r
190d0 65 61 64 4c 6f 63 6b 20 69 73 20 75 73 75 61 6c  eadLock is usual
190e0 6c 79 20 73 65 74 2c 20 62 75 74 20 6d 69 67 68  ly set, but migh
190f0 74 20 62 65 20 2d 31 20 69 66 20 74 68 65 72 65  t be -1 if there
19100 20 77 61 73 20 61 20 0a 20 20 2a 2a 20 70 72 69   was a .  ** pri
19110 6f 72 20 65 72 72 6f 72 20 77 68 69 6c 65 20 61  or error while a
19120 74 74 65 6d 70 74 69 6e 67 20 74 6f 20 61 63 71  ttempting to acq
19130 75 69 72 65 20 61 72 65 20 72 65 61 64 2d 6c 6f  uire are read-lo
19140 63 6b 2e 20 54 68 69 73 20 63 61 6e 6e 6f 74 20  ck. This cannot 
19150 0a 20 20 2a 2a 20 68 61 70 70 65 6e 20 69 66 20  .  ** happen if 
19160 74 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69  the connection i
19170 73 20 61 63 74 75 61 6c 6c 79 20 69 6e 20 65 78  s actually in ex
19180 63 6c 75 73 69 76 65 20 6d 6f 64 65 20 28 61 73  clusive mode (as
19190 20 6e 6f 20 78 53 68 6d 4c 6f 63 6b 0a 20 20 2a   no xShmLock.  *
191a0 2a 20 6c 6f 63 6b 73 20 61 72 65 20 74 61 6b 65  * locks are take
191b0 6e 20 69 6e 20 74 68 69 73 20 63 61 73 65 29 2e  n in this case).
191c0 20 4e 6f 72 20 73 68 6f 75 6c 64 20 74 68 65 20   Nor should the 
191d0 70 61 67 65 72 20 61 74 74 65 6d 70 74 20 74 6f  pager attempt to
191e0 0a 20 20 2a 2a 20 75 70 67 72 61 64 65 20 74 6f  .  ** upgrade to
191f0 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f 64 65 20   exclusive-mode 
19200 66 6f 6c 6c 6f 77 69 6e 67 20 73 75 63 68 20 61  following such a
19210 6e 20 65 72 72 6f 72 2e 0a 20 20 2a 2f 0a 20 20  n error..  */.  
19220 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65  assert( pWal->re
19230 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70 57 61  adLock>=0 || pWa
19240 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 29 3b 0a  l->lockError );.
19250 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
19260 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 28  readLock>=0 || (
19270 6f 70 3c 3d 30 20 26 26 20 70 57 61 6c 2d 3e 65  op<=0 && pWal->e
19280 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 29  xclusiveMode==0)
19290 20 29 3b 0a 0a 20 20 69 66 28 20 6f 70 3d 3d 30   );..  if( op==0
192a0 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57 61 6c   ){.    if( pWal
192b0 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20  ->exclusiveMode 
192c0 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 65  ){.      pWal->e
192d0 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 30  xclusiveMode = 0
192e0 3b 0a 20 20 20 20 20 20 69 66 28 20 77 61 6c 4c  ;.      if( walL
192f0 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20  ockShared(pWal, 
19300 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57  WAL_READ_LOCK(pW
19310 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 21 3d  al->readLock))!=
19320 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
19330 20 20 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c 75       pWal->exclu
19340 73 69 76 65 4d 6f 64 65 20 3d 20 31 3b 0a 20 20  siveMode = 1;.  
19350 20 20 20 20 7d 0a 20 20 20 20 20 20 72 63 20 3d      }.      rc =
19360 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
19370 4d 6f 64 65 3d 3d 30 3b 0a 20 20 20 20 7d 65 6c  Mode==0;.    }el
19380 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20 41 6c 72  se{.      /* Alr
19390 65 61 64 79 20 69 6e 20 6c 6f 63 6b 69 6e 67 5f  eady in locking_
193a0 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 2a 2f 0a 20  mode=NORMAL */. 
193b0 20 20 20 20 20 72 63 20 3d 20 30 3b 0a 20 20 20       rc = 0;.   
193c0 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 6f   }.  }else if( o
193d0 70 3e 30 20 29 7b 0a 20 20 20 20 61 73 73 65 72  p>0 ){.    asser
193e0 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69  t( pWal->exclusi
193f0 76 65 4d 6f 64 65 3d 3d 30 20 29 3b 0a 20 20 20  veMode==0 );.   
19400 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72   assert( pWal->r
19410 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b 0a 20 20  eadLock>=0 );.  
19420 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65    walUnlockShare
19430 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  d(pWal, WAL_READ
19440 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64  _LOCK(pWal->read
19450 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70 57 61 6c  Lock));.    pWal
19460 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20  ->exclusiveMode 
19470 3d 20 31 3b 0a 20 20 20 20 72 63 20 3d 20 31 3b  = 1;.    rc = 1;
19480 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63  .  }else{.    rc
19490 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69   = pWal->exclusi
194a0 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 7d 0a 20  veMode==0;.  }. 
194b0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
194c0 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75  * .** Return tru
194d0 65 20 69 66 20 74 68 65 20 61 72 67 75 6d 65 6e  e if the argumen
194e0 74 20 69 73 20 6e 6f 6e 2d 4e 55 4c 4c 20 61 6e  t is non-NULL an
194f0 64 20 74 68 65 20 57 41 4c 20 6d 6f 64 75 6c 65  d the WAL module
19500 20 69 73 20 75 73 69 6e 67 0a 2a 2a 20 68 65 61   is using.** hea
19510 70 2d 6d 65 6d 6f 72 79 20 66 6f 72 20 74 68 65  p-memory for the
19520 20 77 61 6c 2d 69 6e 64 65 78 2e 20 4f 74 68 65   wal-index. Othe
19530 72 77 69 73 65 2c 20 69 66 20 74 68 65 20 61 72  rwise, if the ar
19540 67 75 6d 65 6e 74 20 69 73 20 4e 55 4c 4c 20 6f  gument is NULL o
19550 72 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6d 6f 64  r the.** WAL mod
19560 75 6c 65 20 69 73 20 75 73 69 6e 67 20 73 68 61  ule is using sha
19570 72 65 64 2d 6d 65 6d 6f 72 79 2c 20 72 65 74 75  red-memory, retu
19580 72 6e 20 66 61 6c 73 65 2e 20 0a 2a 2f 0a 69 6e  rn false. .*/.in
19590 74 20 73 71 6c 69 74 65 33 57 61 6c 48 65 61 70  t sqlite3WalHeap
195a0 4d 65 6d 6f 72 79 28 57 61 6c 20 2a 70 57 61 6c  Memory(Wal *pWal
195b0 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 70 57 61  ){.  return (pWa
195c0 6c 20 26 26 20 70 57 61 6c 2d 3e 65 78 63 6c 75  l && pWal->exclu
195d0 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48 45  siveMode==WAL_HE
195e0 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29 3b  APMEMORY_MODE );
195f0 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 23 69  .}..#endif /* #i
19600 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
19610 54 5f 57 41 4c 20 2a 2f 0a                       T_WAL */.