/ Hex Artifact Content
Login

Artifact 1a63156c661ff22c4c5fc2e6e3ee054017ea8493:


0000: 2f 2a 0a 2a 2a 20 32 30 31 30 20 46 65 62 72 75  /*.** 2010 Febru
0010: 61 72 79 20 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ary 1.**.** The 
0020: 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73  author disclaims
0030: 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68   copyright to th
0040: 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20  is source code. 
0050: 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20   In place of.** 
0060: 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20  a legal notice, 
0070: 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69  here is a blessi
0080: 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79  ng:.**.**    May
0090: 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64   you do good and
00a0: 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20   not evil..**   
00b0: 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f   May you find fo
00c0: 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f  rgiveness for yo
00d0: 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69  urself and forgi
00e0: 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20  ve others..**   
00f0: 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66   May you share f
0100: 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b  reely, never tak
0110: 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f  ing more than yo
0120: 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a  u give..**.*****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 74 68  file contains th
0190: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
01a0: 20 6f 66 20 61 20 77 72 69 74 65 2d 61 68 65 61   of a write-ahea
01b0: 64 20 6c 6f 67 20 28 57 41 4c 29 20 75 73 65 64  d log (WAL) used
01c0: 20 69 6e 20 0a 2a 2a 20 22 6a 6f 75 72 6e 61 6c   in .** "journal
01d0: 5f 6d 6f 64 65 3d 57 41 4c 22 20 6d 6f 64 65 2e  _mode=WAL" mode.
01e0: 0a 2a 2a 0a 2a 2a 20 57 52 49 54 45 2d 41 48 45  .**.** WRITE-AHE
01f0: 41 44 20 4c 4f 47 20 28 57 41 4c 29 20 46 49 4c  AD LOG (WAL) FIL
0200: 45 20 46 4f 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 41  E FORMAT.**.** A
0210: 20 57 41 4c 20 66 69 6c 65 20 63 6f 6e 73 69 73   WAL file consis
0220: 74 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 66  ts of a header f
0230: 6f 6c 6c 6f 77 65 64 20 62 79 20 7a 65 72 6f 20  ollowed by zero 
0240: 6f 72 20 6d 6f 72 65 20 22 66 72 61 6d 65 73 22  or more "frames"
0250: 2e 0a 2a 2a 20 45 61 63 68 20 66 72 61 6d 65 20  ..** Each frame 
0260: 72 65 63 6f 72 64 73 20 74 68 65 20 72 65 76 69  records the revi
0270: 73 65 64 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  sed content of a
0280: 20 73 69 6e 67 6c 65 20 70 61 67 65 20 66 72 6f   single page fro
0290: 6d 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73  m the.** databas
02a0: 65 20 66 69 6c 65 2e 20 20 41 6c 6c 20 63 68 61  e file.  All cha
02b0: 6e 67 65 73 20 74 6f 20 74 68 65 20 64 61 74 61  nges to the data
02c0: 62 61 73 65 20 61 72 65 20 72 65 63 6f 72 64 65  base are recorde
02d0: 64 20 62 79 20 77 72 69 74 69 6e 67 0a 2a 2a 20  d by writing.** 
02e0: 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20  frames into the 
02f0: 57 41 4c 2e 20 20 54 72 61 6e 73 61 63 74 69 6f  WAL.  Transactio
0300: 6e 73 20 63 6f 6d 6d 69 74 20 77 68 65 6e 20 61  ns commit when a
0310: 20 66 72 61 6d 65 20 69 73 20 77 72 69 74 74 65   frame is writte
0320: 6e 20 74 68 61 74 0a 2a 2a 20 63 6f 6e 74 61 69  n that.** contai
0330: 6e 73 20 61 20 63 6f 6d 6d 69 74 20 6d 61 72 6b  ns a commit mark
0340: 65 72 2e 20 20 41 20 73 69 6e 67 6c 65 20 57 41  er.  A single WA
0350: 4c 20 63 61 6e 20 61 6e 64 20 75 73 75 61 6c 6c  L can and usuall
0360: 79 20 64 6f 65 73 20 72 65 63 6f 72 64 20 0a 2a  y does record .*
0370: 2a 20 6d 75 6c 74 69 70 6c 65 20 74 72 61 6e 73  * multiple trans
0380: 61 63 74 69 6f 6e 73 2e 20 20 50 65 72 69 6f 64  actions.  Period
0390: 69 63 61 6c 6c 79 2c 20 74 68 65 20 63 6f 6e 74  ically, the cont
03a0: 65 6e 74 20 6f 66 20 74 68 65 20 57 41 4c 20 69  ent of the WAL i
03b0: 73 0a 2a 2a 20 74 72 61 6e 73 66 65 72 72 65 64  s.** transferred
03c0: 20 62 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64   back into the d
03d0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 69 6e 20  atabase file in 
03e0: 61 6e 20 6f 70 65 72 61 74 69 6f 6e 20 63 61 6c  an operation cal
03f0: 6c 65 64 20 61 0a 2a 2a 20 22 63 68 65 63 6b 70  led a.** "checkp
0400: 6f 69 6e 74 22 2e 0a 2a 2a 0a 2a 2a 20 41 20 73  oint"..**.** A s
0410: 69 6e 67 6c 65 20 57 41 4c 20 66 69 6c 65 20 63  ingle WAL file c
0420: 61 6e 20 62 65 20 75 73 65 64 20 6d 75 6c 74 69  an be used multi
0430: 70 6c 65 20 74 69 6d 65 73 2e 20 20 49 6e 20 6f  ple times.  In o
0440: 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68 65 0a  ther words, the.
0450: 2a 2a 20 57 41 4c 20 63 61 6e 20 66 69 6c 6c 20  ** WAL can fill 
0460: 75 70 20 77 69 74 68 20 66 72 61 6d 65 73 20 61  up with frames a
0470: 6e 64 20 74 68 65 6e 20 62 65 20 63 68 65 63 6b  nd then be check
0480: 70 6f 69 6e 74 65 64 20 61 6e 64 20 74 68 65 6e  pointed and then
0490: 20 6e 65 77 0a 2a 2a 20 66 72 61 6d 65 73 20 63   new.** frames c
04a0: 61 6e 20 6f 76 65 72 77 72 69 74 65 20 74 68 65  an overwrite the
04b0: 20 6f 6c 64 20 6f 6e 65 73 2e 20 20 41 20 57 41   old ones.  A WA
04c0: 4c 20 61 6c 77 61 79 73 20 67 72 6f 77 73 20 66  L always grows f
04d0: 72 6f 6d 20 62 65 67 69 6e 6e 69 6e 67 0a 2a 2a  rom beginning.**
04e0: 20 74 6f 77 61 72 64 20 74 68 65 20 65 6e 64 2e   toward the end.
04f0: 20 20 43 68 65 63 6b 73 75 6d 73 20 61 6e 64 20    Checksums and 
0500: 63 6f 75 6e 74 65 72 73 20 61 74 74 61 63 68 65  counters attache
0510: 64 20 74 6f 20 65 61 63 68 20 66 72 61 6d 65 20  d to each frame 
0520: 61 72 65 0a 2a 2a 20 75 73 65 64 20 74 6f 20 64  are.** used to d
0530: 65 74 65 72 6d 69 6e 65 20 77 68 69 63 68 20 66  etermine which f
0540: 72 61 6d 65 73 20 77 69 74 68 69 6e 20 74 68 65  rames within the
0550: 20 57 41 4c 20 61 72 65 20 76 61 6c 69 64 20 61   WAL are valid a
0560: 6e 64 20 77 68 69 63 68 0a 2a 2a 20 61 72 65 20  nd which.** are 
0570: 6c 65 66 74 6f 76 65 72 73 20 66 72 6f 6d 20 70  leftovers from p
0580: 72 69 6f 72 20 63 68 65 63 6b 70 6f 69 6e 74 73  rior checkpoints
0590: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 57 41 4c 20  ..**.** The WAL 
05a0: 68 65 61 64 65 72 20 69 73 20 33 32 20 62 79 74  header is 32 byt
05b0: 65 73 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 63  es in size and c
05c0: 6f 6e 73 69 73 74 73 20 6f 66 20 74 68 65 20 66  onsists of the f
05d0: 6f 6c 6c 6f 77 69 6e 67 20 65 69 67 68 74 0a 2a  ollowing eight.*
05e0: 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 33 32 2d  * big-endian 32-
05f0: 62 69 74 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  bit unsigned int
0600: 65 67 65 72 20 76 61 6c 75 65 73 3a 0a 2a 2a 0a  eger values:.**.
0610: 2a 2a 20 20 20 20 20 30 3a 20 4d 61 67 69 63 20  **     0: Magic 
0620: 6e 75 6d 62 65 72 2e 20 20 30 78 33 37 37 66 30  number.  0x377f0
0630: 36 38 32 20 6f 72 20 30 78 33 37 37 66 30 36 38  682 or 0x377f068
0640: 33 0a 2a 2a 20 20 20 20 20 34 3a 20 46 69 6c 65  3.**     4: File
0650: 20 66 6f 72 6d 61 74 20 76 65 72 73 69 6f 6e 2e   format version.
0660: 20 20 43 75 72 72 65 6e 74 6c 79 20 33 30 30 37    Currently 3007
0670: 30 30 30 0a 2a 2a 20 20 20 20 20 38 3a 20 44 61  000.**     8: Da
0680: 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65  tabase page size
0690: 2e 20 20 45 78 61 6d 70 6c 65 3a 20 31 30 32 34  .  Example: 1024
06a0: 0a 2a 2a 20 20 20 20 31 32 3a 20 43 68 65 63 6b  .**    12: Check
06b0: 70 6f 69 6e 74 20 73 65 71 75 65 6e 63 65 20 6e  point sequence n
06c0: 75 6d 62 65 72 0a 2a 2a 20 20 20 20 31 36 3a 20  umber.**    16: 
06d0: 53 61 6c 74 2d 31 2c 20 72 61 6e 64 6f 6d 20 69  Salt-1, random i
06e0: 6e 74 65 67 65 72 20 69 6e 63 72 65 6d 65 6e 74  nteger increment
06f0: 65 64 20 77 69 74 68 20 65 61 63 68 20 63 68 65  ed with each che
0700: 63 6b 70 6f 69 6e 74 0a 2a 2a 20 20 20 20 32 30  ckpoint.**    20
0710: 3a 20 53 61 6c 74 2d 32 2c 20 61 20 64 69 66 66  : Salt-2, a diff
0720: 65 72 65 6e 74 20 72 61 6e 64 6f 6d 20 69 6e 74  erent random int
0730: 65 67 65 72 20 63 68 61 6e 67 69 6e 67 20 77 69  eger changing wi
0740: 74 68 20 65 61 63 68 20 63 6b 70 74 0a 2a 2a 20  th each ckpt.** 
0750: 20 20 20 32 34 3a 20 43 68 65 63 6b 73 75 6d 2d     24: Checksum-
0760: 31 20 28 66 69 72 73 74 20 70 61 72 74 20 6f 66  1 (first part of
0770: 20 63 68 65 63 6b 73 75 6d 20 66 6f 72 20 66 69   checksum for fi
0780: 72 73 74 20 32 34 20 62 79 74 65 73 20 6f 66 20  rst 24 bytes of 
0790: 68 65 61 64 65 72 29 2e 0a 2a 2a 20 20 20 20 32  header)..**    2
07a0: 38 3a 20 43 68 65 63 6b 73 75 6d 2d 32 20 28 73  8: Checksum-2 (s
07b0: 65 63 6f 6e 64 20 70 61 72 74 20 6f 66 20 63 68  econd part of ch
07c0: 65 63 6b 73 75 6d 20 66 6f 72 20 66 69 72 73 74  ecksum for first
07d0: 20 32 34 20 62 79 74 65 73 20 6f 66 20 68 65 61   24 bytes of hea
07e0: 64 65 72 29 2e 0a 2a 2a 0a 2a 2a 20 49 6d 6d 65  der)..**.** Imme
07f0: 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e  diately followin
0800: 67 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  g the wal-header
0810: 20 61 72 65 20 7a 65 72 6f 20 6f 72 20 6d 6f 72   are zero or mor
0820: 65 20 66 72 61 6d 65 73 2e 20 45 61 63 68 0a 2a  e frames. Each.*
0830: 2a 20 66 72 61 6d 65 20 63 6f 6e 73 69 73 74 73  * frame consists
0840: 20 6f 66 20 61 20 32 34 2d 62 79 74 65 20 66 72   of a 24-byte fr
0850: 61 6d 65 2d 68 65 61 64 65 72 20 66 6f 6c 6c 6f  ame-header follo
0860: 77 65 64 20 62 79 20 61 20 3c 70 61 67 65 2d 73  wed by a <page-s
0870: 69 7a 65 3e 20 62 79 74 65 73 0a 2a 2a 20 6f 66  ize> bytes.** of
0880: 20 70 61 67 65 20 64 61 74 61 2e 20 54 68 65 20   page data. The 
0890: 66 72 61 6d 65 2d 68 65 61 64 65 72 20 69 73 20  frame-header is 
08a0: 73 69 78 20 62 69 67 2d 65 6e 64 69 61 6e 20 33  six big-endian 3
08b0: 32 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20 0a  2-bit unsigned .
08c0: 2a 2a 20 69 6e 74 65 67 65 72 20 76 61 6c 75 65  ** integer value
08d0: 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  s, as follows:.*
08e0: 2a 0a 2a 2a 20 20 20 20 20 30 3a 20 50 61 67 65  *.**     0: Page
08f0: 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20 20 20 20   number..**     
0900: 34 3a 20 46 6f 72 20 63 6f 6d 6d 69 74 20 72 65  4: For commit re
0910: 63 6f 72 64 73 2c 20 74 68 65 20 73 69 7a 65 20  cords, the size 
0920: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  of the database 
0930: 69 6d 61 67 65 20 69 6e 20 70 61 67 65 73 20 0a  image in pages .
0940: 2a 2a 20 20 20 20 20 20 20 20 61 66 74 65 72 20  **        after 
0950: 74 68 65 20 63 6f 6d 6d 69 74 2e 20 46 6f 72 20  the commit. For 
0960: 61 6c 6c 20 6f 74 68 65 72 20 72 65 63 6f 72 64  all other record
0970: 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20 20  s, zero..**     
0980: 38 3a 20 53 61 6c 74 2d 31 20 28 63 6f 70 69 65  8: Salt-1 (copie
0990: 64 20 66 72 6f 6d 20 74 68 65 20 68 65 61 64 65  d from the heade
09a0: 72 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61 6c  r).**    12: Sal
09b0: 74 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f 6d  t-2 (copied from
09c0: 20 74 68 65 20 68 65 61 64 65 72 29 0a 2a 2a 20   the header).** 
09d0: 20 20 20 31 36 3a 20 43 68 65 63 6b 73 75 6d 2d     16: Checksum-
09e0: 31 2e 0a 2a 2a 20 20 20 20 32 30 3a 20 43 68 65  1..**    20: Che
09f0: 63 6b 73 75 6d 2d 32 2e 0a 2a 2a 0a 2a 2a 20 41  cksum-2..**.** A
0a00: 20 66 72 61 6d 65 20 69 73 20 63 6f 6e 73 69 64   frame is consid
0a10: 65 72 65 64 20 76 61 6c 69 64 20 69 66 20 61 6e  ered valid if an
0a20: 64 20 6f 6e 6c 79 20 69 66 20 74 68 65 20 66 6f  d only if the fo
0a30: 6c 6c 6f 77 69 6e 67 20 63 6f 6e 64 69 74 69 6f  llowing conditio
0a40: 6e 73 20 61 72 65 0a 2a 2a 20 74 72 75 65 3a 0a  ns are.** true:.
0a50: 2a 2a 0a 2a 2a 20 20 20 20 28 31 29 20 54 68 65  **.**    (1) The
0a60: 20 73 61 6c 74 2d 31 20 61 6e 64 20 73 61 6c 74   salt-1 and salt
0a70: 2d 32 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  -2 values in the
0a80: 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20 6d 61   frame-header ma
0a90: 74 63 68 0a 2a 2a 20 20 20 20 20 20 20 20 73 61  tch.**        sa
0aa0: 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  lt values in the
0ab0: 20 77 61 6c 2d 68 65 61 64 65 72 0a 2a 2a 0a 2a   wal-header.**.*
0ac0: 2a 20 20 20 20 28 32 29 20 54 68 65 20 63 68 65  *    (2) The che
0ad0: 63 6b 73 75 6d 20 76 61 6c 75 65 73 20 69 6e 20  cksum values in 
0ae0: 74 68 65 20 66 69 6e 61 6c 20 38 20 62 79 74 65  the final 8 byte
0af0: 73 20 6f 66 20 74 68 65 20 66 72 61 6d 65 2d 68  s of the frame-h
0b00: 65 61 64 65 72 0a 2a 2a 20 20 20 20 20 20 20 20  eader.**        
0b10: 65 78 61 63 74 6c 79 20 6d 61 74 63 68 20 74 68  exactly match th
0b20: 65 20 63 68 65 63 6b 73 75 6d 20 63 6f 6d 70 75  e checksum compu
0b30: 74 65 64 20 63 6f 6e 73 65 63 75 74 69 76 65 6c  ted consecutivel
0b40: 79 20 6f 6e 20 74 68 65 0a 2a 2a 20 20 20 20 20  y on the.**     
0b50: 20 20 20 57 41 4c 20 68 65 61 64 65 72 20 61 6e     WAL header an
0b60: 64 20 74 68 65 20 66 69 72 73 74 20 38 20 62 79  d the first 8 by
0b70: 74 65 73 20 61 6e 64 20 74 68 65 20 63 6f 6e 74  tes and the cont
0b80: 65 6e 74 20 6f 66 20 61 6c 6c 20 66 72 61 6d 65  ent of all frame
0b90: 73 0a 2a 2a 20 20 20 20 20 20 20 20 75 70 20 74  s.**        up t
0ba0: 6f 20 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20  o and including 
0bb0: 74 68 65 20 63 75 72 72 65 6e 74 20 66 72 61 6d  the current fram
0bc0: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65  e..**.** The che
0bd0: 63 6b 73 75 6d 20 69 73 20 63 6f 6d 70 75 74 65  cksum is compute
0be0: 64 20 75 73 69 6e 67 20 33 32 2d 62 69 74 20 62  d using 32-bit b
0bf0: 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65  ig-endian intege
0c00: 72 73 20 69 66 20 74 68 65 0a 2a 2a 20 6d 61 67  rs if the.** mag
0c10: 69 63 20 6e 75 6d 62 65 72 20 69 6e 20 74 68 65  ic number in the
0c20: 20 66 69 72 73 74 20 34 20 62 79 74 65 73 20 6f   first 4 bytes o
0c30: 66 20 74 68 65 20 57 41 4c 20 69 73 20 30 78 33  f the WAL is 0x3
0c40: 37 37 66 30 36 38 33 20 61 6e 64 20 69 74 0a 2a  77f0683 and it.*
0c50: 2a 20 69 73 20 63 6f 6d 70 75 74 65 64 20 75 73  * is computed us
0c60: 69 6e 67 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61  ing little-endia
0c70: 6e 20 69 66 20 74 68 65 20 6d 61 67 69 63 20 6e  n if the magic n
0c80: 75 6d 62 65 72 20 69 73 20 30 78 33 37 37 66 30  umber is 0x377f0
0c90: 36 38 32 2e 0a 2a 2a 20 54 68 65 20 63 68 65 63  682..** The chec
0ca0: 6b 73 75 6d 20 76 61 6c 75 65 73 20 61 72 65 20  ksum values are 
0cb0: 61 6c 77 61 79 73 20 73 74 6f 72 65 64 20 69 6e  always stored in
0cc0: 20 74 68 65 20 66 72 61 6d 65 20 68 65 61 64 65   the frame heade
0cd0: 72 20 69 6e 20 61 0a 2a 2a 20 62 69 67 2d 65 6e  r in a.** big-en
0ce0: 64 69 61 6e 20 66 6f 72 6d 61 74 20 72 65 67 61  dian format rega
0cf0: 72 64 6c 65 73 73 20 6f 66 20 77 68 69 63 68 20  rdless of which 
0d00: 62 79 74 65 20 6f 72 64 65 72 20 69 73 20 75 73  byte order is us
0d10: 65 64 20 74 6f 20 63 6f 6d 70 75 74 65 0a 2a 2a  ed to compute.**
0d20: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 2e 20 20   the checksum.  
0d30: 54 68 65 20 63 68 65 63 6b 73 75 6d 20 69 73 20  The checksum is 
0d40: 63 6f 6d 70 75 74 65 64 20 62 79 20 69 6e 74 65  computed by inte
0d50: 72 70 72 65 74 69 6e 67 20 74 68 65 20 69 6e 70  rpreting the inp
0d60: 75 74 20 61 73 0a 2a 2a 20 61 6e 20 65 76 65 6e  ut as.** an even
0d70: 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 73 69 67   number of unsig
0d80: 6e 65 64 20 33 32 2d 62 69 74 20 69 6e 74 65 67  ned 32-bit integ
0d90: 65 72 73 3a 20 78 5b 30 5d 20 74 68 72 6f 75 67  ers: x[0] throug
0da0: 68 20 78 5b 4e 5d 2e 20 20 54 68 65 0a 2a 2a 20  h x[N].  The.** 
0db0: 61 6c 67 6f 72 69 74 68 6d 20 75 73 65 64 20 66  algorithm used f
0dc0: 6f 72 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20  or the checksum 
0dd0: 69 73 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  is as follows:.*
0de0: 2a 20 0a 2a 2a 20 20 20 66 6f 72 20 69 20 66 72  * .**   for i fr
0df0: 6f 6d 20 30 20 74 6f 20 6e 2d 31 20 73 74 65 70  om 0 to n-1 step
0e00: 20 32 3a 0a 2a 2a 20 20 20 20 20 73 30 20 2b 3d   2:.**     s0 +=
0e10: 20 78 5b 69 5d 20 2b 20 73 31 3b 0a 2a 2a 20 20   x[i] + s1;.**  
0e20: 20 20 20 73 31 20 2b 3d 20 78 5b 69 2b 31 5d 20     s1 += x[i+1] 
0e30: 2b 20 73 30 3b 0a 2a 2a 20 20 20 65 6e 64 66 6f  + s0;.**   endfo
0e40: 72 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61  r.**.** Note tha
0e50: 74 20 73 30 20 61 6e 64 20 73 31 20 61 72 65 20  t s0 and s1 are 
0e60: 62 6f 74 68 20 77 65 69 67 68 74 65 64 20 63 68  both weighted ch
0e70: 65 63 6b 73 75 6d 73 20 75 73 69 6e 67 20 66 69  ecksums using fi
0e80: 62 6f 6e 61 63 63 69 20 77 65 69 67 68 74 73 0a  bonacci weights.
0e90: 2a 2a 20 69 6e 20 72 65 76 65 72 73 65 20 6f 72  ** in reverse or
0ea0: 64 65 72 20 28 74 68 65 20 6c 61 72 67 65 73 74  der (the largest
0eb0: 20 66 69 62 6f 6e 61 63 63 69 20 77 65 69 67 68   fibonacci weigh
0ec0: 74 20 6f 63 63 75 72 73 20 6f 6e 20 74 68 65 20  t occurs on the 
0ed0: 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 0a 2a 2a  first element.**
0ee0: 20 6f 66 20 74 68 65 20 73 65 71 75 65 6e 63 65   of the sequence
0ef0: 20 62 65 69 6e 67 20 73 75 6d 6d 65 64 2e 29 20   being summed.) 
0f00: 20 54 68 65 20 73 31 20 76 61 6c 75 65 20 73 70   The s1 value sp
0f10: 61 6e 73 20 61 6c 6c 20 33 32 2d 62 69 74 20 0a  ans all 32-bit .
0f20: 2a 2a 20 74 65 72 6d 73 20 6f 66 20 74 68 65 20  ** terms of the 
0f30: 73 65 71 75 65 6e 63 65 20 77 68 65 72 65 61 73  sequence whereas
0f40: 20 73 30 20 6f 6d 69 74 73 20 74 68 65 20 66 69   s0 omits the fi
0f50: 6e 61 6c 20 74 65 72 6d 2e 0a 2a 2a 0a 2a 2a 20  nal term..**.** 
0f60: 4f 6e 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c  On a checkpoint,
0f70: 20 74 68 65 20 57 41 4c 20 69 73 20 66 69 72 73   the WAL is firs
0f80: 74 20 56 46 53 2e 78 53 79 6e 63 2d 65 64 2c 20  t VFS.xSync-ed, 
0f90: 74 68 65 6e 20 76 61 6c 69 64 20 63 6f 6e 74 65  then valid conte
0fa0: 6e 74 20 6f 66 20 74 68 65 0a 2a 2a 20 57 41 4c  nt of the.** WAL
0fb0: 20 69 73 20 74 72 61 6e 73 66 65 72 72 65 64 20   is transferred 
0fc0: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
0fd0: 65 2c 20 74 68 65 6e 20 74 68 65 20 64 61 74 61  e, then the data
0fe0: 62 61 73 65 20 69 73 20 56 46 53 2e 78 53 79 6e  base is VFS.xSyn
0ff0: 63 2d 65 64 2e 0a 2a 2a 20 54 68 65 20 56 46 53  c-ed..** The VFS
1000: 2e 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e  .xSync operation
1010: 73 20 73 65 72 76 65 20 61 73 20 77 72 69 74 65  s serve as write
1020: 20 62 61 72 72 69 65 72 73 20 2d 20 61 6c 6c 20   barriers - all 
1030: 77 72 69 74 65 73 20 6c 61 75 6e 63 68 65 64 0a  writes launched.
1040: 2a 2a 20 62 65 66 6f 72 65 20 74 68 65 20 78 53  ** before the xS
1050: 79 6e 63 20 6d 75 73 74 20 63 6f 6d 70 6c 65 74  ync must complet
1060: 65 20 62 65 66 6f 72 65 20 61 6e 79 20 77 72 69  e before any wri
1070: 74 65 20 74 68 61 74 20 6c 61 75 6e 63 68 65 73  te that launches
1080: 20 61 66 74 65 72 20 74 68 65 0a 2a 2a 20 78 53   after the.** xS
1090: 79 6e 63 20 62 65 67 69 6e 73 2e 0a 2a 2a 0a 2a  ync begins..**.*
10a0: 2a 20 41 66 74 65 72 20 65 61 63 68 20 63 68 65  * After each che
10b0: 63 6b 70 6f 69 6e 74 2c 20 74 68 65 20 73 61 6c  ckpoint, the sal
10c0: 74 2d 31 20 76 61 6c 75 65 20 69 73 20 69 6e 63  t-1 value is inc
10d0: 72 65 6d 65 6e 74 65 64 20 61 6e 64 20 74 68 65  remented and the
10e0: 20 73 61 6c 74 2d 32 0a 2a 2a 20 76 61 6c 75 65   salt-2.** value
10f0: 20 69 73 20 72 61 6e 64 6f 6d 69 7a 65 64 2e 20   is randomized. 
1100: 20 54 68 69 73 20 70 72 65 76 65 6e 74 73 20 6f   This prevents o
1110: 6c 64 20 61 6e 64 20 6e 65 77 20 66 72 61 6d 65  ld and new frame
1120: 73 20 69 6e 20 74 68 65 20 57 41 4c 20 66 72 6f  s in the WAL fro
1130: 6d 0a 2a 2a 20 62 65 69 6e 67 20 63 6f 6e 73 69  m.** being consi
1140: 64 65 72 65 64 20 76 61 6c 69 64 20 61 74 20 74  dered valid at t
1150: 68 65 20 73 61 6d 65 20 74 69 6d 65 20 61 6e 64  he same time and
1160: 20 62 65 69 6e 67 20 63 68 65 63 6b 70 6f 69 6e   being checkpoin
1170: 74 69 6e 67 20 74 6f 67 65 74 68 65 72 0a 2a 2a  ting together.**
1180: 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 63 72 61   following a cra
1190: 73 68 2e 0a 2a 2a 0a 2a 2a 20 52 45 41 44 45 52  sh..**.** READER
11a0: 20 41 4c 47 4f 52 49 54 48 4d 0a 2a 2a 0a 2a 2a   ALGORITHM.**.**
11b0: 20 54 6f 20 72 65 61 64 20 61 20 70 61 67 65 20   To read a page 
11c0: 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
11d0: 65 20 28 63 61 6c 6c 20 69 74 20 70 61 67 65 20  e (call it page 
11e0: 6e 75 6d 62 65 72 20 50 29 2c 20 61 20 72 65 61  number P), a rea
11f0: 64 65 72 0a 2a 2a 20 66 69 72 73 74 20 63 68 65  der.** first che
1200: 63 6b 73 20 74 68 65 20 57 41 4c 20 74 6f 20 73  cks the WAL to s
1210: 65 65 20 69 66 20 69 74 20 63 6f 6e 74 61 69 6e  ee if it contain
1220: 73 20 70 61 67 65 20 50 2e 20 20 49 66 20 73 6f  s page P.  If so
1230: 2c 20 74 68 65 6e 20 74 68 65 0a 2a 2a 20 6c 61  , then the.** la
1240: 73 74 20 76 61 6c 69 64 20 69 6e 73 74 61 6e 63  st valid instanc
1250: 65 20 6f 66 20 70 61 67 65 20 50 20 74 68 61 74  e of page P that
1260: 20 69 73 20 61 20 66 6f 6c 6c 6f 77 65 64 20 62   is a followed b
1270: 79 20 61 20 63 6f 6d 6d 69 74 20 66 72 61 6d 65  y a commit frame
1280: 0a 2a 2a 20 6f 72 20 69 73 20 61 20 63 6f 6d 6d  .** or is a comm
1290: 69 74 20 66 72 61 6d 65 20 69 74 73 65 6c 66 20  it frame itself 
12a0: 62 65 63 6f 6d 65 73 20 74 68 65 20 76 61 6c 75  becomes the valu
12b0: 65 20 72 65 61 64 2e 20 20 49 66 20 74 68 65 20  e read.  If the 
12c0: 57 41 4c 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20  WAL.** contains 
12d0: 6e 6f 20 63 6f 70 69 65 73 20 6f 66 20 70 61 67  no copies of pag
12e0: 65 20 50 20 74 68 61 74 20 61 72 65 20 76 61 6c  e P that are val
12f0: 69 64 20 61 6e 64 20 77 68 69 63 68 20 61 72 65  id and which are
1300: 20 61 20 63 6f 6d 6d 69 74 0a 2a 2a 20 66 72 61   a commit.** fra
1310: 6d 65 20 6f 72 20 61 72 65 20 66 6f 6c 6c 6f 77  me or are follow
1320: 65 64 20 62 79 20 61 20 63 6f 6d 6d 69 74 20 66  ed by a commit f
1330: 72 61 6d 65 2c 20 74 68 65 6e 20 70 61 67 65 20  rame, then page 
1340: 50 20 69 73 20 72 65 61 64 20 66 72 6f 6d 0a 2a  P is read from.*
1350: 2a 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  * the database f
1360: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 73 74  ile..**.** To st
1370: 61 72 74 20 61 20 72 65 61 64 20 74 72 61 6e 73  art a read trans
1380: 61 63 74 69 6f 6e 2c 20 74 68 65 20 72 65 61 64  action, the read
1390: 65 72 20 72 65 63 6f 72 64 73 20 74 68 65 20 69  er records the i
13a0: 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 73 74  ndex of the last
13b0: 0a 2a 2a 20 76 61 6c 69 64 20 66 72 61 6d 65 20  .** valid frame 
13c0: 69 6e 20 74 68 65 20 57 41 4c 2e 20 20 54 68 65  in the WAL.  The
13d0: 20 72 65 61 64 65 72 20 75 73 65 73 20 74 68 69   reader uses thi
13e0: 73 20 72 65 63 6f 72 64 65 64 20 22 6d 78 46 72  s recorded "mxFr
13f0: 61 6d 65 22 20 76 61 6c 75 65 0a 2a 2a 20 66 6f  ame" value.** fo
1400: 72 20 61 6c 6c 20 73 75 62 73 65 71 75 65 6e 74  r all subsequent
1410: 20 72 65 61 64 20 6f 70 65 72 61 74 69 6f 6e 73   read operations
1420: 2e 20 20 4e 65 77 20 74 72 61 6e 73 61 63 74 69  .  New transacti
1430: 6f 6e 73 20 63 61 6e 20 62 65 20 61 70 70 65 6e  ons can be appen
1440: 64 65 64 0a 2a 2a 20 74 6f 20 74 68 65 20 57 41  ded.** to the WA
1450: 4c 2c 20 62 75 74 20 61 73 20 6c 6f 6e 67 20 61  L, but as long a
1460: 73 20 74 68 65 20 72 65 61 64 65 72 20 75 73 65  s the reader use
1470: 73 20 69 74 73 20 6f 72 69 67 69 6e 61 6c 20 6d  s its original m
1480: 78 46 72 61 6d 65 20 76 61 6c 75 65 0a 2a 2a 20  xFrame value.** 
1490: 61 6e 64 20 69 67 6e 6f 72 65 73 20 74 68 65 20  and ignores the 
14a0: 6e 65 77 6c 79 20 61 70 70 65 6e 64 65 64 20 63  newly appended c
14b0: 6f 6e 74 65 6e 74 2c 20 69 74 20 77 69 6c 6c 20  ontent, it will 
14c0: 73 65 65 20 61 20 63 6f 6e 73 69 73 74 65 6e 74  see a consistent
14d0: 20 73 6e 61 70 73 68 6f 74 0a 2a 2a 20 6f 66 20   snapshot.** of 
14e0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 72 6f  the database fro
14f0: 6d 20 61 20 73 69 6e 67 6c 65 20 70 6f 69 6e 74  m a single point
1500: 20 69 6e 20 74 69 6d 65 2e 20 20 54 68 69 73 20   in time.  This 
1510: 74 65 63 68 6e 69 71 75 65 20 61 6c 6c 6f 77 73  technique allows
1520: 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 63 6f 6e  .** multiple con
1530: 63 75 72 72 65 6e 74 20 72 65 61 64 65 72 73 20  current readers 
1540: 74 6f 20 76 69 65 77 20 64 69 66 66 65 72 65 6e  to view differen
1550: 74 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68  t versions of th
1560: 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 63 6f  e database.** co
1570: 6e 74 65 6e 74 20 73 69 6d 75 6c 74 61 6e 65 6f  ntent simultaneo
1580: 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  usly..**.** The 
1590: 72 65 61 64 65 72 20 61 6c 67 6f 72 69 74 68 6d  reader algorithm
15a0: 20 69 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73   in the previous
15b0: 20 70 61 72 61 67 72 61 70 68 73 20 77 6f 72 6b   paragraphs work
15c0: 73 20 63 6f 72 72 65 63 74 6c 79 2c 20 62 75 74  s correctly, but
15d0: 20 0a 2a 2a 20 62 65 63 61 75 73 65 20 66 72 61   .** because fra
15e0: 6d 65 73 20 66 6f 72 20 70 61 67 65 20 50 20 63  mes for page P c
15f0: 61 6e 20 61 70 70 65 61 72 20 61 6e 79 77 68 65  an appear anywhe
1600: 72 65 20 77 69 74 68 69 6e 20 74 68 65 20 57 41  re within the WA
1610: 4c 2c 20 74 68 65 0a 2a 2a 20 72 65 61 64 65 72  L, the.** reader
1620: 20 68 61 73 20 74 6f 20 73 63 61 6e 20 74 68 65   has to scan the
1630: 20 65 6e 74 69 72 65 20 57 41 4c 20 6c 6f 6f 6b   entire WAL look
1640: 69 6e 67 20 66 6f 72 20 70 61 67 65 20 50 20 66  ing for page P f
1650: 72 61 6d 65 73 2e 20 20 49 66 20 74 68 65 0a 2a  rames.  If the.*
1660: 2a 20 57 41 4c 20 69 73 20 6c 61 72 67 65 20 28  * WAL is large (
1670: 6d 75 6c 74 69 70 6c 65 20 6d 65 67 61 62 79 74  multiple megabyt
1680: 65 73 20 69 73 20 74 79 70 69 63 61 6c 29 20 74  es is typical) t
1690: 68 61 74 20 73 63 61 6e 20 63 61 6e 20 62 65 20  hat scan can be 
16a0: 73 6c 6f 77 2c 0a 2a 2a 20 61 6e 64 20 72 65 61  slow,.** and rea
16b0: 64 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 73 75  d performance su
16c0: 66 66 65 72 73 2e 20 20 54 6f 20 6f 76 65 72 63  ffers.  To overc
16d0: 6f 6d 65 20 74 68 69 73 20 70 72 6f 62 6c 65 6d  ome this problem
16e0: 2c 20 61 20 73 65 70 61 72 61 74 65 0a 2a 2a 20  , a separate.** 
16f0: 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20 63  data structure c
1700: 61 6c 6c 65 64 20 74 68 65 20 77 61 6c 2d 69 6e  alled the wal-in
1710: 64 65 78 20 69 73 20 6d 61 69 6e 74 61 69 6e 65  dex is maintaine
1720: 64 20 74 6f 20 65 78 70 65 64 69 74 65 20 74 68  d to expedite th
1730: 65 0a 2a 2a 20 73 65 61 72 63 68 20 66 6f 72 20  e.** search for 
1740: 66 72 61 6d 65 73 20 6f 66 20 61 20 70 61 72 74  frames of a part
1750: 69 63 75 6c 61 72 20 70 61 67 65 2e 0a 2a 2a 20  icular page..** 
1760: 0a 2a 2a 20 57 41 4c 2d 49 4e 44 45 58 20 46 4f  .** WAL-INDEX FO
1770: 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 43 6f 6e 63 65  RMAT.**.** Conce
1780: 70 74 75 61 6c 6c 79 2c 20 74 68 65 20 77 61 6c  ptually, the wal
1790: 2d 69 6e 64 65 78 20 69 73 20 73 68 61 72 65 64  -index is shared
17a0: 20 6d 65 6d 6f 72 79 2c 20 74 68 6f 75 67 68 20   memory, though 
17b0: 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  VFS implementati
17c0: 6f 6e 73 0a 2a 2a 20 6d 69 67 68 74 20 63 68 6f  ons.** might cho
17d0: 6f 73 65 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  ose to implement
17e0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 75   the wal-index u
17f0: 73 69 6e 67 20 61 20 6d 6d 61 70 70 65 64 20 66  sing a mmapped f
1800: 69 6c 65 2e 20 20 42 65 63 61 75 73 65 0a 2a 2a  ile.  Because.**
1810: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69   the wal-index i
1820: 73 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 2c  s shared memory,
1830: 20 53 51 4c 69 74 65 20 64 6f 65 73 20 6e 6f 74   SQLite does not
1840: 20 73 75 70 70 6f 72 74 20 6a 6f 75 72 6e 61 6c   support journal
1850: 5f 6d 6f 64 65 3d 57 41 4c 20 0a 2a 2a 20 6f 6e  _mode=WAL .** on
1860: 20 61 20 6e 65 74 77 6f 72 6b 20 66 69 6c 65 73   a network files
1870: 79 73 74 65 6d 2e 20 20 41 6c 6c 20 75 73 65 72  ystem.  All user
1880: 73 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  s of the databas
1890: 65 20 6d 75 73 74 20 62 65 20 61 62 6c 65 20 74  e must be able t
18a0: 6f 0a 2a 2a 20 73 68 61 72 65 20 6d 65 6d 6f 72  o.** share memor
18b0: 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61 6c  y..**.** The wal
18c0: 2d 69 6e 64 65 78 20 69 73 20 74 72 61 6e 73 69  -index is transi
18d0: 65 6e 74 2e 20 20 41 66 74 65 72 20 61 20 63 72  ent.  After a cr
18e0: 61 73 68 2c 20 74 68 65 20 77 61 6c 2d 69 6e 64  ash, the wal-ind
18f0: 65 78 20 63 61 6e 20 28 61 6e 64 20 73 68 6f 75  ex can (and shou
1900: 6c 64 0a 2a 2a 20 62 65 29 20 72 65 63 6f 6e 73  ld.** be) recons
1910: 74 72 75 63 74 65 64 20 66 72 6f 6d 20 74 68 65  tructed from the
1920: 20 6f 72 69 67 69 6e 61 6c 20 57 41 4c 20 66 69   original WAL fi
1930: 6c 65 2e 20 20 49 6e 20 66 61 63 74 2c 20 74 68  le.  In fact, th
1940: 65 20 56 46 53 20 69 73 20 72 65 71 75 69 72 65  e VFS is require
1950: 64 0a 2a 2a 20 74 6f 20 65 69 74 68 65 72 20 74  d.** to either t
1960: 72 75 6e 63 61 74 65 20 6f 72 20 7a 65 72 6f 20  runcate or zero 
1970: 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 74 68  the header of th
1980: 65 20 77 61 6c 2d 69 6e 64 65 78 20 77 68 65 6e  e wal-index when
1990: 20 74 68 65 20 6c 61 73 74 0a 2a 2a 20 63 6f 6e   the last.** con
19a0: 6e 65 63 74 69 6f 6e 20 74 6f 20 69 74 20 63 6c  nection to it cl
19b0: 6f 73 65 73 2e 20 20 42 65 63 61 75 73 65 20 74  oses.  Because t
19c0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
19d0: 74 72 61 6e 73 69 65 6e 74 2c 20 69 74 20 63 61  transient, it ca
19e0: 6e 0a 2a 2a 20 75 73 65 20 61 6e 20 61 72 63 68  n.** use an arch
19f0: 69 74 65 63 74 75 72 65 2d 73 70 65 63 69 66 69  itecture-specifi
1a00: 63 20 66 6f 72 6d 61 74 3b 20 69 74 20 64 6f 65  c format; it doe
1a10: 73 20 6e 6f 74 20 68 61 76 65 20 74 6f 20 62 65  s not have to be
1a20: 20 63 72 6f 73 73 2d 70 6c 61 74 66 6f 72 6d 2e   cross-platform.
1a30: 0a 2a 2a 20 48 65 6e 63 65 2c 20 75 6e 6c 69 6b  .** Hence, unlik
1a40: 65 20 74 68 65 20 64 61 74 61 62 61 73 65 20 61  e the database a
1a50: 6e 64 20 57 41 4c 20 66 69 6c 65 20 66 6f 72 6d  nd WAL file form
1a60: 61 74 73 20 77 68 69 63 68 20 73 74 6f 72 65 20  ats which store 
1a70: 61 6c 6c 20 76 61 6c 75 65 73 0a 2a 2a 20 61 73  all values.** as
1a80: 20 62 69 67 20 65 6e 64 69 61 6e 2c 20 74 68 65   big endian, the
1a90: 20 77 61 6c 2d 69 6e 64 65 78 20 63 61 6e 20 73   wal-index can s
1aa0: 74 6f 72 65 20 6d 75 6c 74 69 2d 62 79 74 65 20  tore multi-byte 
1ab0: 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 6e 61  values in the na
1ac0: 74 69 76 65 0a 2a 2a 20 62 79 74 65 20 6f 72 64  tive.** byte ord
1ad0: 65 72 20 6f 66 20 74 68 65 20 68 6f 73 74 20 63  er of the host c
1ae0: 6f 6d 70 75 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54  omputer..**.** T
1af0: 68 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74 68  he purpose of th
1b00: 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 74  e wal-index is t
1b10: 6f 20 61 6e 73 77 65 72 20 74 68 69 73 20 71 75  o answer this qu
1b20: 65 73 74 69 6f 6e 20 71 75 69 63 6b 6c 79 3a 20  estion quickly: 
1b30: 20 47 69 76 65 6e 0a 2a 2a 20 61 20 70 61 67 65   Given.** a page
1b40: 20 6e 75 6d 62 65 72 20 50 2c 20 72 65 74 75 72   number P, retur
1b50: 6e 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74  n the index of t
1b60: 68 65 20 6c 61 73 74 20 66 72 61 6d 65 20 66 6f  he last frame fo
1b70: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
1b80: 57 41 4c 2c 0a 2a 2a 20 6f 72 20 72 65 74 75 72  WAL,.** or retur
1b90: 6e 20 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20  n NULL if there 
1ba0: 61 72 65 20 6e 6f 20 66 72 61 6d 65 73 20 66 6f  are no frames fo
1bb0: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
1bc0: 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77  WAL..**.** The w
1bd0: 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69 73 74  al-index consist
1be0: 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 72 65  s of a header re
1bf0: 67 69 6f 6e 2c 20 66 6f 6c 6c 6f 77 65 64 20 62  gion, followed b
1c00: 79 20 61 6e 20 6f 6e 65 20 6f 72 0a 2a 2a 20 6d  y an one or.** m
1c10: 6f 72 65 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73  ore index blocks
1c20: 2e 20 20 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61  .  .**.** The wa
1c30: 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 63  l-index header c
1c40: 6f 6e 74 61 69 6e 73 20 74 68 65 20 74 6f 74 61  ontains the tota
1c50: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d  l number of fram
1c60: 65 73 20 77 69 74 68 69 6e 20 74 68 65 20 57 41  es within the WA
1c70: 4c 0a 2a 2a 20 69 6e 20 74 68 65 20 74 68 65 20  L.** in the the 
1c80: 6d 78 46 72 61 6d 65 20 66 69 65 6c 64 2e 20 20  mxFrame field.  
1c90: 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 69 6e 64 65  .**.** Each inde
1ca0: 78 20 62 6c 6f 63 6b 20 65 78 63 65 70 74 20 66  x block except f
1cb0: 6f 72 20 74 68 65 20 66 69 72 73 74 20 63 6f 6e  or the first con
1cc0: 74 61 69 6e 73 20 69 6e 66 6f 72 6d 61 74 69 6f  tains informatio
1cd0: 6e 20 6f 6e 20 0a 2a 2a 20 48 41 53 48 54 41 42  n on .** HASHTAB
1ce0: 4c 45 5f 4e 50 41 47 45 20 66 72 61 6d 65 73 2e  LE_NPAGE frames.
1cf0: 20 54 68 65 20 66 69 72 73 74 20 69 6e 64 65 78   The first index
1d00: 20 62 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20   block contains 
1d10: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f 6e 0a 2a  information on.*
1d20: 2a 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  * HASHTABLE_NPAG
1d30: 45 5f 4f 4e 45 20 66 72 61 6d 65 73 2e 20 54 68  E_ONE frames. Th
1d40: 65 20 76 61 6c 75 65 73 20 6f 66 20 48 41 53 48  e values of HASH
1d50: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20  TABLE_NPAGE_ONE 
1d60: 61 6e 64 20 0a 2a 2a 20 48 41 53 48 54 41 42 4c  and .** HASHTABL
1d70: 45 5f 4e 50 41 47 45 20 61 72 65 20 73 65 6c 65  E_NPAGE are sele
1d80: 63 74 65 64 20 73 6f 20 74 68 61 74 20 74 6f 67  cted so that tog
1d90: 65 74 68 65 72 20 74 68 65 20 77 61 6c 2d 69 6e  ether the wal-in
1da0: 64 65 78 20 68 65 61 64 65 72 20 61 6e 64 0a 2a  dex header and.*
1db0: 2a 20 66 69 72 73 74 20 69 6e 64 65 78 20 62 6c  * first index bl
1dc0: 6f 63 6b 20 61 72 65 20 74 68 65 20 73 61 6d 65  ock are the same
1dd0: 20 73 69 7a 65 20 61 73 20 61 6c 6c 20 6f 74 68   size as all oth
1de0: 65 72 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73 20  er index blocks 
1df0: 69 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e  in the.** wal-in
1e00: 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20  dex..**.** Each 
1e10: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 63 6f 6e 74  index block cont
1e20: 61 69 6e 73 20 74 77 6f 20 73 65 63 74 69 6f 6e  ains two section
1e30: 73 2c 20 61 20 70 61 67 65 2d 6d 61 70 70 69 6e  s, a page-mappin
1e40: 67 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  g that contains 
1e50: 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20  the.** database 
1e60: 70 61 67 65 20 6e 75 6d 62 65 72 20 61 73 73 6f  page number asso
1e70: 63 69 61 74 65 64 20 77 69 74 68 20 65 61 63 68  ciated with each
1e80: 20 77 61 6c 20 66 72 61 6d 65 2c 20 61 6e 64 20   wal frame, and 
1e90: 61 20 68 61 73 68 2d 74 61 62 6c 65 20 0a 2a 2a  a hash-table .**
1ea0: 20 74 68 61 74 20 61 6c 6c 6f 77 73 20 72 65 61   that allows rea
1eb0: 64 65 72 73 20 74 6f 20 71 75 65 72 79 20 61 6e  ders to query an
1ec0: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 66 6f 72   index block for
1ed0: 20 61 20 73 70 65 63 69 66 69 63 20 70 61 67 65   a specific page
1ee0: 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 54 68 65 20   number..** The 
1ef0: 70 61 67 65 2d 6d 61 70 70 69 6e 67 20 69 73 20  page-mapping is 
1f00: 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53 48  an array of HASH
1f10: 54 41 42 4c 45 5f 4e 50 41 47 45 20 28 6f 72 20  TABLE_NPAGE (or 
1f20: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
1f30: 4f 4e 45 0a 2a 2a 20 66 6f 72 20 74 68 65 20 66  ONE.** for the f
1f40: 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b  irst index block
1f50: 29 20 33 32 2d 62 69 74 20 70 61 67 65 20 6e 75  ) 32-bit page nu
1f60: 6d 62 65 72 73 2e 20 54 68 65 20 66 69 72 73 74  mbers. The first
1f70: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 0a 2a   entry in the .*
1f80: 2a 20 66 69 72 73 74 20 69 6e 64 65 78 2d 62 6c  * first index-bl
1f90: 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  ock contains the
1fa0: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6e   database page n
1fb0: 75 6d 62 65 72 20 63 6f 72 72 65 73 70 6f 6e 64  umber correspond
1fc0: 69 6e 67 20 74 6f 20 74 68 65 0a 2a 2a 20 66 69  ing to the.** fi
1fd0: 72 73 74 20 66 72 61 6d 65 20 69 6e 20 74 68 65  rst frame in the
1fe0: 20 57 41 4c 20 66 69 6c 65 2e 20 54 68 65 20 66   WAL file. The f
1ff0: 69 72 73 74 20 65 6e 74 72 79 20 69 6e 20 74 68  irst entry in th
2000: 65 20 73 65 63 6f 6e 64 20 69 6e 64 65 78 20 62  e second index b
2010: 6c 6f 63 6b 0a 2a 2a 20 69 6e 20 74 68 65 20 57  lock.** in the W
2020: 41 4c 20 66 69 6c 65 20 63 6f 72 72 65 73 70 6f  AL file correspo
2030: 6e 64 73 20 74 6f 20 74 68 65 20 28 48 41 53 48  nds to the (HASH
2040: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b  TABLE_NPAGE_ONE+
2050: 31 29 74 68 20 66 72 61 6d 65 20 69 6e 0a 2a 2a  1)th frame in.**
2060: 20 74 68 65 20 6c 6f 67 2c 20 61 6e 64 20 73 6f   the log, and so
2070: 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c   on..**.** The l
2080: 61 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20  ast index block 
2090: 69 6e 20 61 20 77 61 6c 2d 69 6e 64 65 78 20 75  in a wal-index u
20a0: 73 75 61 6c 6c 79 20 63 6f 6e 74 61 69 6e 73 20  sually contains 
20b0: 6c 65 73 73 20 74 68 61 6e 20 74 68 65 20 66 75  less than the fu
20c0: 6c 6c 0a 2a 2a 20 63 6f 6d 70 6c 65 6d 65 6e 74  ll.** complement
20d0: 20 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e 50   of HASHTABLE_NP
20e0: 41 47 45 20 28 6f 72 20 48 41 53 48 54 41 42 4c  AGE (or HASHTABL
20f0: 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 20 70 61 67  E_NPAGE_ONE) pag
2100: 65 2d 6e 75 6d 62 65 72 73 2c 0a 2a 2a 20 64 65  e-numbers,.** de
2110: 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20 63  pending on the c
2120: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 57  ontents of the W
2130: 41 4c 20 66 69 6c 65 2e 20 54 68 69 73 20 64 6f  AL file. This do
2140: 65 73 20 6e 6f 74 20 63 68 61 6e 67 65 20 74 68  es not change th
2150: 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74 65 64 20 73  e.** allocated s
2160: 69 7a 65 20 6f 66 20 74 68 65 20 70 61 67 65 2d  ize of the page-
2170: 6d 61 70 70 69 6e 67 20 61 72 72 61 79 20 2d 20  mapping array - 
2180: 74 68 65 20 70 61 67 65 2d 6d 61 70 70 69 6e 67  the page-mapping
2190: 20 61 72 72 61 79 20 6d 65 72 65 6c 79 0a 2a 2a   array merely.**
21a0: 20 63 6f 6e 74 61 69 6e 73 20 75 6e 75 73 65 64   contains unused
21b0: 20 65 6e 74 72 69 65 73 2e 0a 2a 2a 0a 2a 2a 20   entries..**.** 
21c0: 45 76 65 6e 20 77 69 74 68 6f 75 74 20 75 73 69  Even without usi
21d0: 6e 67 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ng the hash tabl
21e0: 65 2c 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d  e, the last fram
21f0: 65 20 66 6f 72 20 70 61 67 65 20 50 0a 2a 2a 20  e for page P.** 
2200: 63 61 6e 20 62 65 20 66 6f 75 6e 64 20 62 79 20  can be found by 
2210: 73 63 61 6e 6e 69 6e 67 20 74 68 65 20 70 61 67  scanning the pag
2220: 65 2d 6d 61 70 70 69 6e 67 20 73 65 63 74 69 6f  e-mapping sectio
2230: 6e 73 20 6f 66 20 65 61 63 68 20 69 6e 64 65 78  ns of each index
2240: 20 62 6c 6f 63 6b 0a 2a 2a 20 73 74 61 72 74 69   block.** starti
2250: 6e 67 20 77 69 74 68 20 74 68 65 20 6c 61 73 74  ng with the last
2260: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 61 6e 64   index block and
2270: 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20 74   moving toward t
2280: 68 65 20 66 69 72 73 74 2c 20 61 6e 64 0a 2a 2a  he first, and.**
2290: 20 77 69 74 68 69 6e 20 65 61 63 68 20 69 6e 64   within each ind
22a0: 65 78 20 62 6c 6f 63 6b 2c 20 73 74 61 72 74 69  ex block, starti
22b0: 6e 67 20 61 74 20 74 68 65 20 65 6e 64 20 61 6e  ng at the end an
22c0: 64 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20  d moving toward 
22d0: 74 68 65 0a 2a 2a 20 62 65 67 69 6e 6e 69 6e 67  the.** beginning
22e0: 2e 20 20 54 68 65 20 66 69 72 73 74 20 65 6e 74  .  The first ent
22f0: 72 79 20 74 68 61 74 20 65 71 75 61 6c 73 20 50  ry that equals P
2300: 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20   corresponds to 
2310: 74 68 65 20 66 72 61 6d 65 0a 2a 2a 20 68 6f 6c  the frame.** hol
2320: 64 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74  ding the content
2330: 20 66 6f 72 20 74 68 61 74 20 70 61 67 65 2e 0a   for that page..
2340: 2a 2a 0a 2a 2a 20 54 68 65 20 68 61 73 68 20 74  **.** The hash t
2350: 61 62 6c 65 20 63 6f 6e 73 69 73 74 73 20 6f 66  able consists of
2360: 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54   HASHTABLE_NSLOT
2370: 20 31 36 2d 62 69 74 20 75 6e 73 69 67 6e 65 64   16-bit unsigned
2380: 20 69 6e 74 65 67 65 72 73 2e 0a 2a 2a 20 48 41   integers..** HA
2390: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 3d 20  SHTABLE_NSLOT = 
23a0: 32 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  2*HASHTABLE_NPAG
23b0: 45 2c 20 61 6e 64 20 74 68 65 72 65 20 69 73 20  E, and there is 
23c0: 6f 6e 65 20 65 6e 74 72 79 20 69 6e 20 74 68 65  one entry in the
23d0: 0a 2a 2a 20 68 61 73 68 20 74 61 62 6c 65 20 66  .** hash table f
23e0: 6f 72 20 65 61 63 68 20 70 61 67 65 20 6e 75 6d  or each page num
23f0: 62 65 72 20 69 6e 20 74 68 65 20 6d 61 70 70 69  ber in the mappi
2400: 6e 67 20 73 65 63 74 69 6f 6e 2c 20 73 6f 20 74  ng section, so t
2410: 68 65 20 68 61 73 68 20 0a 2a 2a 20 74 61 62 6c  he hash .** tabl
2420: 65 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20  e is never more 
2430: 74 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2e 20  than half full. 
2440: 20 54 68 65 20 65 78 70 65 63 74 65 64 20 6e 75   The expected nu
2450: 6d 62 65 72 20 6f 66 20 63 6f 6c 6c 69 73 69 6f  mber of collisio
2460: 6e 73 20 0a 2a 2a 20 70 72 69 6f 72 20 74 6f 20  ns .** prior to 
2470: 66 69 6e 64 69 6e 67 20 61 20 6d 61 74 63 68 20  finding a match 
2480: 69 73 20 31 2e 20 20 45 61 63 68 20 65 6e 74 72  is 1.  Each entr
2490: 79 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61  y of the hash ta
24a0: 62 6c 65 20 69 73 20 61 6e 0a 2a 2a 20 31 2d 62  ble is an.** 1-b
24b0: 61 73 65 64 20 69 6e 64 65 78 20 6f 66 20 61 6e  ased index of an
24c0: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61   entry in the ma
24d0: 70 70 69 6e 67 20 73 65 63 74 69 6f 6e 20 6f 66  pping section of
24e0: 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20 69 6e 64   the same.** ind
24f0: 65 78 20 62 6c 6f 63 6b 2e 20 20 20 4c 65 74 20  ex block.   Let 
2500: 4b 20 62 65 20 74 68 65 20 31 2d 62 61 73 65 64  K be the 1-based
2510: 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61   index of the la
2520: 72 67 65 73 74 20 65 6e 74 72 79 20 69 6e 0a 2a  rgest entry in.*
2530: 2a 20 74 68 65 20 6d 61 70 70 69 6e 67 20 73 65  * the mapping se
2540: 63 74 69 6f 6e 2e 20 20 28 46 6f 72 20 69 6e 64  ction.  (For ind
2550: 65 78 20 62 6c 6f 63 6b 73 20 6f 74 68 65 72 20  ex blocks other 
2560: 74 68 61 6e 20 74 68 65 20 6c 61 73 74 2c 20 4b  than the last, K
2570: 20 77 69 6c 6c 0a 2a 2a 20 61 6c 77 61 79 73 20   will.** always 
2580: 62 65 20 65 78 61 63 74 6c 79 20 48 41 53 48 54  be exactly HASHT
2590: 41 42 4c 45 5f 4e 50 41 47 45 20 28 34 30 39 36  ABLE_NPAGE (4096
25a0: 29 20 61 6e 64 20 66 6f 72 20 74 68 65 20 6c 61  ) and for the la
25b0: 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 0a 2a  st index block.*
25c0: 2a 20 4b 20 77 69 6c 6c 20 62 65 20 28 6d 78 46  * K will be (mxF
25d0: 72 61 6d 65 25 48 41 53 48 54 41 42 4c 45 5f 4e  rame%HASHTABLE_N
25e0: 50 41 47 45 29 2e 29 20 20 55 6e 75 73 65 64 20  PAGE).)  Unused 
25f0: 73 6c 6f 74 73 20 6f 66 20 74 68 65 20 68 61 73  slots of the has
2600: 68 20 74 61 62 6c 65 0a 2a 2a 20 63 6f 6e 74 61  h table.** conta
2610: 69 6e 20 61 20 76 61 6c 75 65 20 6f 66 20 30 2e  in a value of 0.
2620: 0a 2a 2a 0a 2a 2a 20 54 6f 20 6c 6f 6f 6b 20 66  .**.** To look f
2630: 6f 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65  or page P in the
2640: 20 68 61 73 68 20 74 61 62 6c 65 2c 20 66 69 72   hash table, fir
2650: 73 74 20 63 6f 6d 70 75 74 65 20 61 20 68 61 73  st compute a has
2660: 68 20 69 4b 65 79 20 6f 6e 0a 2a 2a 20 50 20 61  h iKey on.** P a
2670: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a  s follows:.**.**
2680: 20 20 20 20 20 20 69 4b 65 79 20 3d 20 28 50 20        iKey = (P 
2690: 2a 20 33 38 33 29 20 25 20 48 41 53 48 54 41 42  * 383) % HASHTAB
26a0: 4c 45 5f 4e 53 4c 4f 54 0a 2a 2a 0a 2a 2a 20 54  LE_NSLOT.**.** T
26b0: 68 65 6e 20 73 74 61 72 74 20 73 63 61 6e 6e 69  hen start scanni
26c0: 6e 67 20 65 6e 74 72 69 65 73 20 6f 66 20 74 68  ng entries of th
26d0: 65 20 68 61 73 68 20 74 61 62 6c 65 2c 20 73 74  e hash table, st
26e0: 61 72 74 69 6e 67 20 77 69 74 68 20 69 4b 65 79  arting with iKey
26f0: 0a 2a 2a 20 28 77 72 61 70 70 69 6e 67 20 61 72  .** (wrapping ar
2700: 6f 75 6e 64 20 74 6f 20 74 68 65 20 62 65 67 69  ound to the begi
2710: 6e 6e 69 6e 67 20 77 68 65 6e 20 74 68 65 20 65  nning when the e
2720: 6e 64 20 6f 66 20 74 68 65 20 68 61 73 68 20 74  nd of the hash t
2730: 61 62 6c 65 20 69 73 0a 2a 2a 20 72 65 61 63 68  able is.** reach
2740: 65 64 29 20 75 6e 74 69 6c 20 61 6e 20 75 6e 75  ed) until an unu
2750: 73 65 64 20 68 61 73 68 20 73 6c 6f 74 20 69 73  sed hash slot is
2760: 20 66 6f 75 6e 64 2e 20 4c 65 74 20 74 68 65 20   found. Let the 
2770: 66 69 72 73 74 20 75 6e 75 73 65 64 20 73 6c 6f  first unused slo
2780: 74 0a 2a 2a 20 62 65 20 61 74 20 69 6e 64 65 78  t.** be at index
2790: 20 69 55 6e 75 73 65 64 2e 20 20 28 69 55 6e 75   iUnused.  (iUnu
27a0: 73 65 64 20 6d 69 67 68 74 20 62 65 20 6c 65 73  sed might be les
27b0: 73 20 74 68 61 6e 20 69 4b 65 79 20 69 66 20 74  s than iKey if t
27c0: 68 65 72 65 20 77 61 73 0a 2a 2a 20 77 72 61 70  here was.** wrap
27d0: 2d 61 72 6f 75 6e 64 2e 29 20 42 65 63 61 75 73  -around.) Becaus
27e0: 65 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  e the hash table
27f0: 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20 74   is never more t
2800: 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2c 0a 2a  han half full,.*
2810: 2a 20 74 68 65 20 73 65 61 72 63 68 20 69 73 20  * the search is 
2820: 67 75 61 72 61 6e 74 65 65 64 20 74 6f 20 65 76  guaranteed to ev
2830: 65 6e 74 75 61 6c 6c 79 20 68 69 74 20 61 6e 20  entually hit an 
2840: 75 6e 75 73 65 64 20 65 6e 74 72 79 2e 20 20 4c  unused entry.  L
2850: 65 74 20 0a 2a 2a 20 69 4d 61 78 20 62 65 20 74  et .** iMax be t
2860: 68 65 20 76 61 6c 75 65 20 62 65 74 77 65 65 6e  he value between
2870: 20 69 4b 65 79 20 61 6e 64 20 69 55 6e 75 73 65   iKey and iUnuse
2880: 64 2c 20 63 6c 6f 73 65 73 74 20 74 6f 20 69 55  d, closest to iU
2890: 6e 75 73 65 64 2c 0a 2a 2a 20 77 68 65 72 65 20  nused,.** where 
28a0: 61 48 61 73 68 5b 69 4d 61 78 5d 3d 3d 50 2e 20  aHash[iMax]==P. 
28b0: 20 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20   If there is no 
28c0: 69 4d 61 78 20 65 6e 74 72 79 20 28 69 66 20 74  iMax entry (if t
28d0: 68 65 72 65 20 65 78 69 73 74 73 0a 2a 2a 20 6e  here exists.** n
28e0: 6f 20 68 61 73 68 20 73 6c 6f 74 20 73 75 63 68  o hash slot such
28f0: 20 74 68 61 74 20 61 48 61 73 68 5b 69 5d 3d 3d   that aHash[i]==
2900: 70 29 20 74 68 65 6e 20 70 61 67 65 20 50 20 69  p) then page P i
2910: 73 20 6e 6f 74 20 69 6e 20 74 68 65 0a 2a 2a 20  s not in the.** 
2920: 63 75 72 72 65 6e 74 20 69 6e 64 65 78 20 62 6c  current index bl
2930: 6f 63 6b 2e 20 20 4f 74 68 65 72 77 69 73 65 20  ock.  Otherwise 
2940: 74 68 65 20 69 4d 61 78 2d 74 68 20 6d 61 70 70  the iMax-th mapp
2950: 69 6e 67 20 65 6e 74 72 79 20 6f 66 20 74 68 65  ing entry of the
2960: 0a 2a 2a 20 63 75 72 72 65 6e 74 20 69 6e 64 65  .** current inde
2970: 78 20 62 6c 6f 63 6b 20 63 6f 72 72 65 73 70 6f  x block correspo
2980: 6e 64 73 20 74 6f 20 74 68 65 20 6c 61 73 74 20  nds to the last 
2990: 65 6e 74 72 79 20 74 68 61 74 20 72 65 66 65 72  entry that refer
29a0: 65 6e 63 65 73 20 0a 2a 2a 20 70 61 67 65 20 50  ences .** page P
29b0: 2e 0a 2a 2a 0a 2a 2a 20 41 20 68 61 73 68 20 73  ..**.** A hash s
29c0: 65 61 72 63 68 20 62 65 67 69 6e 73 20 77 69 74  earch begins wit
29d0: 68 20 74 68 65 20 6c 61 73 74 20 69 6e 64 65 78  h the last index
29e0: 20 62 6c 6f 63 6b 20 61 6e 64 20 6d 6f 76 65 73   block and moves
29f0: 20 74 6f 77 61 72 64 20 74 68 65 0a 2a 2a 20 66   toward the.** f
2a00: 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b  irst index block
2a10: 2c 20 6c 6f 6f 6b 69 6e 67 20 66 6f 72 20 65 6e  , looking for en
2a20: 74 72 69 65 73 20 63 6f 72 72 65 73 70 6f 6e 64  tries correspond
2a30: 69 6e 67 20 74 6f 20 70 61 67 65 20 50 2e 20 20  ing to page P.  
2a40: 4f 6e 0a 2a 2a 20 61 76 65 72 61 67 65 2c 20 6f  On.** average, o
2a50: 6e 6c 79 20 74 77 6f 20 6f 72 20 74 68 72 65 65  nly two or three
2a60: 20 73 6c 6f 74 73 20 69 6e 20 65 61 63 68 20 69   slots in each i
2a70: 6e 64 65 78 20 62 6c 6f 63 6b 20 6e 65 65 64 20  ndex block need 
2a80: 74 6f 20 62 65 0a 2a 2a 20 65 78 61 6d 69 6e 65  to be.** examine
2a90: 64 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 65 69  d in order to ei
2aa0: 74 68 65 72 20 66 69 6e 64 20 74 68 65 20 6c 61  ther find the la
2ab0: 73 74 20 65 6e 74 72 79 20 66 6f 72 20 70 61 67  st entry for pag
2ac0: 65 20 50 2c 20 6f 72 20 74 6f 0a 2a 2a 20 65 73  e P, or to.** es
2ad0: 74 61 62 6c 69 73 68 20 74 68 61 74 20 6e 6f 20  tablish that no 
2ae0: 73 75 63 68 20 65 6e 74 72 79 20 65 78 69 73 74  such entry exist
2af0: 73 20 69 6e 20 74 68 65 20 62 6c 6f 63 6b 2e 20  s in the block. 
2b00: 20 45 61 63 68 20 69 6e 64 65 78 20 62 6c 6f 63   Each index bloc
2b10: 6b 0a 2a 2a 20 68 6f 6c 64 73 20 6f 76 65 72 20  k.** holds over 
2b20: 34 30 30 30 20 65 6e 74 72 69 65 73 2e 20 20 53  4000 entries.  S
2b30: 6f 20 74 77 6f 20 6f 72 20 74 68 72 65 65 20 69  o two or three i
2b40: 6e 64 65 78 20 62 6c 6f 63 6b 73 20 61 72 65 20  ndex blocks are 
2b50: 73 75 66 66 69 63 69 65 6e 74 0a 2a 2a 20 74 6f  sufficient.** to
2b60: 20 63 6f 76 65 72 20 61 20 74 79 70 69 63 61 6c   cover a typical
2b70: 20 31 30 20 6d 65 67 61 62 79 74 65 20 57 41 4c   10 megabyte WAL
2b80: 20 66 69 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20   file, assuming 
2b90: 31 4b 20 70 61 67 65 73 2e 20 20 38 20 6f 72 20  1K pages.  8 or 
2ba0: 31 30 0a 2a 2a 20 63 6f 6d 70 61 72 69 73 6f 6e  10.** comparison
2bb0: 73 20 28 6f 6e 20 61 76 65 72 61 67 65 29 20 73  s (on average) s
2bc0: 75 66 66 69 63 65 20 74 6f 20 65 69 74 68 65 72  uffice to either
2bd0: 20 6c 6f 63 61 74 65 20 61 20 66 72 61 6d 65 20   locate a frame 
2be0: 69 6e 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6f 72  in the.** WAL or
2bf0: 20 74 6f 20 65 73 74 61 62 6c 69 73 68 20 74 68   to establish th
2c00: 61 74 20 74 68 65 20 66 72 61 6d 65 20 64 6f 65  at the frame doe
2c10: 73 20 6e 6f 74 20 65 78 69 73 74 20 69 6e 20 74  s not exist in t
2c20: 68 65 20 57 41 4c 2e 20 20 54 68 69 73 0a 2a 2a  he WAL.  This.**
2c30: 20 69 73 20 6d 75 63 68 20 66 61 73 74 65 72 20   is much faster 
2c40: 74 68 61 6e 20 73 63 61 6e 6e 69 6e 67 20 74 68  than scanning th
2c50: 65 20 65 6e 74 69 72 65 20 31 30 4d 42 20 57 41  e entire 10MB WA
2c60: 4c 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68  L..**.** Note th
2c70: 61 74 20 65 6e 74 72 69 65 73 20 61 72 65 20 61  at entries are a
2c80: 64 64 65 64 20 69 6e 20 6f 72 64 65 72 20 6f 66  dded in order of
2c90: 20 69 6e 63 72 65 61 73 69 6e 67 20 4b 2e 20 20   increasing K.  
2ca0: 48 65 6e 63 65 2c 20 6f 6e 65 0a 2a 2a 20 72 65  Hence, one.** re
2cb0: 61 64 65 72 20 6d 69 67 68 74 20 62 65 20 75 73  ader might be us
2cc0: 69 6e 67 20 73 6f 6d 65 20 76 61 6c 75 65 20 4b  ing some value K
2cd0: 30 20 61 6e 64 20 61 20 73 65 63 6f 6e 64 20 72  0 and a second r
2ce0: 65 61 64 65 72 20 74 68 61 74 20 73 74 61 72 74  eader that start
2cf0: 65 64 0a 2a 2a 20 61 74 20 61 20 6c 61 74 65 72  ed.** at a later
2d00: 20 74 69 6d 65 20 28 61 66 74 65 72 20 61 64 64   time (after add
2d10: 69 74 69 6f 6e 61 6c 20 74 72 61 6e 73 61 63 74  itional transact
2d20: 69 6f 6e 73 20 77 65 72 65 20 61 64 64 65 64 20  ions were added 
2d30: 74 6f 20 74 68 65 20 57 41 4c 0a 2a 2a 20 61 6e  to the WAL.** an
2d40: 64 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64  d to the wal-ind
2d50: 65 78 29 20 6d 69 67 68 74 20 62 65 20 75 73 69  ex) might be usi
2d60: 6e 67 20 61 20 64 69 66 66 65 72 65 6e 74 20 76  ng a different v
2d70: 61 6c 75 65 20 4b 31 2c 20 77 68 65 72 65 20 4b  alue K1, where K
2d80: 31 3e 4b 30 2e 0a 2a 2a 20 42 6f 74 68 20 72 65  1>K0..** Both re
2d90: 61 64 65 72 73 20 63 61 6e 20 75 73 65 20 74 68  aders can use th
2da0: 65 20 73 61 6d 65 20 68 61 73 68 20 74 61 62 6c  e same hash tabl
2db0: 65 20 61 6e 64 20 6d 61 70 70 69 6e 67 20 73 65  e and mapping se
2dc0: 63 74 69 6f 6e 20 74 6f 20 67 65 74 0a 2a 2a 20  ction to get.** 
2dd0: 74 68 65 20 63 6f 72 72 65 63 74 20 72 65 73 75  the correct resu
2de0: 6c 74 2e 20 20 54 68 65 72 65 20 6d 61 79 20 62  lt.  There may b
2df0: 65 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65  e entries in the
2e00: 20 68 61 73 68 20 74 61 62 6c 65 20 77 69 74 68   hash table with
2e10: 0a 2a 2a 20 4b 3e 4b 30 20 62 75 74 20 74 6f 20  .** K>K0 but to 
2e20: 74 68 65 20 66 69 72 73 74 20 72 65 61 64 65 72  the first reader
2e30: 2c 20 74 68 6f 73 65 20 65 6e 74 72 69 65 73 20  , those entries 
2e40: 77 69 6c 6c 20 61 70 70 65 61 72 20 74 6f 20 62  will appear to b
2e50: 65 20 75 6e 75 73 65 64 0a 2a 2a 20 73 6c 6f 74  e unused.** slot
2e60: 73 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61  s in the hash ta
2e70: 62 6c 65 20 61 6e 64 20 73 6f 20 74 68 65 20 66  ble and so the f
2e80: 69 72 73 74 20 72 65 61 64 65 72 20 77 69 6c 6c  irst reader will
2e90: 20 67 65 74 20 61 6e 20 61 6e 73 77 65 72 20 61   get an answer a
2ea0: 73 0a 2a 2a 20 69 66 20 6e 6f 20 76 61 6c 75 65  s.** if no value
2eb0: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 4b  s greater than K
2ec0: 30 20 68 61 64 20 65 76 65 72 20 62 65 65 6e 20  0 had ever been 
2ed0: 69 6e 73 65 72 74 65 64 20 69 6e 74 6f 20 74 68  inserted into th
2ee0: 65 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20  e hash table.** 
2ef0: 69 6e 20 74 68 65 20 66 69 72 73 74 20 70 6c 61  in the first pla
2f00: 63 65 20 2d 20 77 68 69 63 68 20 69 73 20 77 68  ce - which is wh
2f10: 61 74 20 72 65 61 64 65 72 20 6f 6e 65 20 77 61  at reader one wa
2f20: 6e 74 73 2e 20 20 4d 65 61 6e 77 68 69 6c 65 2c  nts.  Meanwhile,
2f30: 20 74 68 65 0a 2a 2a 20 73 65 63 6f 6e 64 20 72   the.** second r
2f40: 65 61 64 65 72 20 75 73 69 6e 67 20 4b 31 20 77  eader using K1 w
2f50: 69 6c 6c 20 73 65 65 20 61 64 64 69 74 69 6f 6e  ill see addition
2f60: 61 6c 20 76 61 6c 75 65 73 20 74 68 61 74 20 77  al values that w
2f70: 65 72 65 20 69 6e 73 65 72 74 65 64 0a 2a 2a 20  ere inserted.** 
2f80: 6c 61 74 65 72 2c 20 77 68 69 63 68 20 69 73 20  later, which is 
2f90: 65 78 61 63 74 6c 79 20 77 68 61 74 20 72 65 61  exactly what rea
2fa0: 64 65 72 20 74 77 6f 20 77 61 6e 74 73 2e 20 20  der two wants.  
2fb0: 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 61 20 72 6f  .**.** When a ro
2fc0: 6c 6c 62 61 63 6b 20 6f 63 63 75 72 73 2c 20 74  llback occurs, t
2fd0: 68 65 20 76 61 6c 75 65 20 6f 66 20 4b 20 69 73  he value of K is
2fe0: 20 64 65 63 72 65 61 73 65 64 2e 20 48 61 73 68   decreased. Hash
2ff0: 20 74 61 62 6c 65 20 65 6e 74 72 69 65 73 0a 2a   table entries.*
3000: 2a 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  * that correspon
3010: 64 20 74 6f 20 66 72 61 6d 65 73 20 67 72 65 61  d to frames grea
3020: 74 65 72 20 74 68 61 6e 20 74 68 65 20 6e 65 77  ter than the new
3030: 20 4b 20 76 61 6c 75 65 20 61 72 65 20 72 65 6d   K value are rem
3040: 6f 76 65 64 0a 2a 2a 20 66 72 6f 6d 20 74 68 65  oved.** from the
3050: 20 68 61 73 68 20 74 61 62 6c 65 20 61 74 20 74   hash table at t
3060: 68 69 73 20 70 6f 69 6e 74 2e 0a 2a 2f 0a 23 69  his point..*/.#i
3070: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
3080: 54 5f 57 41 4c 0a 0a 23 69 6e 63 6c 75 64 65 20  T_WAL..#include 
3090: 22 77 61 6c 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 54  "wal.h"../*.** T
30a0: 72 61 63 65 20 6f 75 74 70 75 74 20 6d 61 63 72  race output macr
30b0: 6f 73 0a 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65  os.*/.#if define
30c0: 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26  d(SQLITE_TEST) &
30d0: 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  & defined(SQLITE
30e0: 5f 44 45 42 55 47 29 0a 69 6e 74 20 73 71 6c 69  _DEBUG).int sqli
30f0: 74 65 33 57 61 6c 54 72 61 63 65 20 3d 20 30 3b  te3WalTrace = 0;
3100: 0a 23 20 64 65 66 69 6e 65 20 57 41 4c 54 52 41  .# define WALTRA
3110: 43 45 28 58 29 20 20 69 66 28 73 71 6c 69 74 65  CE(X)  if(sqlite
3120: 33 57 61 6c 54 72 61 63 65 29 20 73 71 6c 69 74  3WalTrace) sqlit
3130: 65 33 44 65 62 75 67 50 72 69 6e 74 66 20 58 0a  e3DebugPrintf X.
3140: 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 57  #else.# define W
3150: 41 4c 54 52 41 43 45 28 58 29 0a 23 65 6e 64 69  ALTRACE(X).#endi
3160: 66 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 78  f../*.** The max
3170: 69 6d 75 6d 20 28 61 6e 64 20 6f 6e 6c 79 29 20  imum (and only) 
3180: 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68 65 20  versions of the 
3190: 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65  wal and wal-inde
31a0: 78 20 66 6f 72 6d 61 74 73 0a 2a 2a 20 74 68 61  x formats.** tha
31b0: 74 20 6d 61 79 20 62 65 20 69 6e 74 65 72 70 72  t may be interpr
31c0: 65 74 65 64 20 62 79 20 74 68 69 73 20 76 65 72  eted by this ver
31d0: 73 69 6f 6e 20 6f 66 20 53 51 4c 69 74 65 2e 0a  sion of SQLite..
31e0: 2a 2a 0a 2a 2a 20 49 66 20 61 20 63 6c 69 65 6e  **.** If a clien
31f0: 74 20 62 65 67 69 6e 73 20 72 65 63 6f 76 65 72  t begins recover
3200: 69 6e 67 20 61 20 57 41 4c 20 66 69 6c 65 20 61  ing a WAL file a
3210: 6e 64 20 66 69 6e 64 73 20 74 68 61 74 20 28 61  nd finds that (a
3220: 29 20 74 68 65 20 63 68 65 63 6b 73 75 6d 0a 2a  ) the checksum.*
3230: 2a 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20  * values in the 
3240: 77 61 6c 2d 68 65 61 64 65 72 20 61 72 65 20 63  wal-header are c
3250: 6f 72 72 65 63 74 20 61 6e 64 20 28 62 29 20 74  orrect and (b) t
3260: 68 65 20 76 65 72 73 69 6f 6e 20 66 69 65 6c 64  he version field
3270: 20 69 73 20 6e 6f 74 0a 2a 2a 20 57 41 4c 5f 4d   is not.** WAL_M
3280: 41 58 5f 56 45 52 53 49 4f 4e 2c 20 72 65 63 6f  AX_VERSION, reco
3290: 76 65 72 79 20 66 61 69 6c 73 20 61 6e 64 20 53  very fails and S
32a0: 51 4c 69 74 65 20 72 65 74 75 72 6e 73 20 53 51  QLite returns SQ
32b0: 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2e 0a 2a  LITE_CANTOPEN..*
32c0: 2a 0a 2a 2a 20 53 69 6d 69 6c 61 72 6c 79 2c 20  *.** Similarly, 
32d0: 69 66 20 61 20 63 6c 69 65 6e 74 20 73 75 63 63  if a client succ
32e0: 65 73 73 66 75 6c 6c 79 20 72 65 61 64 73 20 61  essfully reads a
32f0: 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
3300: 72 20 28 69 2e 65 2e 20 74 68 65 20 0a 2a 2a 20  r (i.e. the .** 
3310: 63 68 65 63 6b 73 75 6d 20 74 65 73 74 20 69 73  checksum test is
3320: 20 73 75 63 63 65 73 73 66 75 6c 29 20 61 6e 64   successful) and
3330: 20 66 69 6e 64 73 20 74 68 61 74 20 74 68 65 20   finds that the 
3340: 76 65 72 73 69 6f 6e 20 66 69 65 6c 64 20 69 73  version field is
3350: 20 6e 6f 74 0a 2a 2a 20 57 41 4c 49 4e 44 45 58   not.** WALINDEX
3360: 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 2c 20 74 68  _MAX_VERSION, th
3370: 65 6e 20 6e 6f 20 72 65 61 64 2d 74 72 61 6e 73  en no read-trans
3380: 61 63 74 69 6f 6e 20 69 73 20 6f 70 65 6e 65 64  action is opened
3390: 20 61 6e 64 20 53 51 4c 69 74 65 0a 2a 2a 20 72   and SQLite.** r
33a0: 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 43 41  eturns SQLITE_CA
33b0: 4e 54 4f 50 45 4e 2e 0a 2a 2f 0a 23 64 65 66 69  NTOPEN..*/.#defi
33c0: 6e 65 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49  ne WAL_MAX_VERSI
33d0: 4f 4e 20 20 20 20 20 20 33 30 30 37 30 30 30 0a  ON      3007000.
33e0: 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58  #define WALINDEX
33f0: 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 20 33 30 30  _MAX_VERSION 300
3400: 37 30 30 30 0a 0a 2f 2a 0a 2a 2a 20 49 6e 64 69  7000../*.** Indi
3410: 63 65 73 20 6f 66 20 76 61 72 69 6f 75 73 20 6c  ces of various l
3420: 6f 63 6b 69 6e 67 20 62 79 74 65 73 2e 20 20 20  ocking bytes.   
3430: 57 41 4c 5f 4e 52 45 41 44 45 52 20 69 73 20 74  WAL_NREADER is t
3440: 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20  he number.** of 
3450: 61 76 61 69 6c 61 62 6c 65 20 72 65 61 64 65 72  available reader
3460: 20 6c 6f 63 6b 73 20 61 6e 64 20 73 68 6f 75 6c   locks and shoul
3470: 64 20 62 65 20 61 74 20 6c 65 61 73 74 20 33 2e  d be at least 3.
3480: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f  .*/.#define WAL_
3490: 57 52 49 54 45 5f 4c 4f 43 4b 20 20 20 20 20 20  WRITE_LOCK      
34a0: 20 20 20 30 0a 23 64 65 66 69 6e 65 20 57 41 4c     0.#define WAL
34b0: 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 20  _ALL_BUT_WRITE  
34c0: 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41      1.#define WA
34d0: 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 20 20 20 20  L_CKPT_LOCK     
34e0: 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57       1.#define W
34f0: 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20  AL_RECOVER_LOCK 
3500: 20 20 20 20 20 20 32 0a 23 64 65 66 69 6e 65 20        2.#define 
3510: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 49 29  WAL_READ_LOCK(I)
3520: 20 20 20 20 20 20 20 28 33 2b 28 49 29 29 0a 23         (3+(I)).#
3530: 64 65 66 69 6e 65 20 57 41 4c 5f 4e 52 45 41 44  define WAL_NREAD
3540: 45 52 20 20 20 20 20 20 20 20 20 20 20 20 28 53  ER            (S
3550: 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 2d  QLITE_SHM_NLOCK-
3560: 33 29 0a 0a 0a 2f 2a 20 4f 62 6a 65 63 74 20 64  3).../* Object d
3570: 65 63 6c 61 72 61 74 69 6f 6e 73 20 2a 2f 0a 74  eclarations */.t
3580: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61  ypedef struct Wa
3590: 6c 49 6e 64 65 78 48 64 72 20 57 61 6c 49 6e 64  lIndexHdr WalInd
35a0: 65 78 48 64 72 3b 0a 74 79 70 65 64 65 66 20 73  exHdr;.typedef s
35b0: 74 72 75 63 74 20 57 61 6c 49 74 65 72 61 74 6f  truct WalIterato
35c0: 72 20 57 61 6c 49 74 65 72 61 74 6f 72 3b 0a 74  r WalIterator;.t
35d0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61  ypedef struct Wa
35e0: 6c 43 6b 70 74 49 6e 66 6f 20 57 61 6c 43 6b 70  lCkptInfo WalCkp
35f0: 74 49 6e 66 6f 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54  tInfo;.../*.** T
3600: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a  he following obj
3610: 65 63 74 20 68 6f 6c 64 73 20 61 20 63 6f 70 79  ect holds a copy
3620: 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
3630: 78 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74  x header content
3640: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63 74 75  ..**.** The actu
3650: 61 6c 20 68 65 61 64 65 72 20 69 6e 20 74 68 65  al header in the
3660: 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69   wal-index consi
3670: 73 74 73 20 6f 66 20 74 77 6f 20 63 6f 70 69 65  sts of two copie
3680: 73 20 6f 66 20 74 68 69 73 0a 2a 2a 20 6f 62 6a  s of this.** obj
3690: 65 63 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57  ect..*/.struct W
36a0: 61 6c 49 6e 64 65 78 48 64 72 20 7b 0a 20 20 75  alIndexHdr {.  u
36b0: 33 32 20 69 56 65 72 73 69 6f 6e 3b 20 20 20 20  32 iVersion;    
36c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
36d0: 2a 20 57 61 6c 2d 69 6e 64 65 78 20 76 65 72 73  * Wal-index vers
36e0: 69 6f 6e 20 2a 2f 0a 20 20 75 33 32 20 75 6e 75  ion */.  u32 unu
36f0: 73 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  sed;            
3700: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 75 73           /* Unus
3710: 65 64 20 28 70 61 64 64 69 6e 67 29 20 66 69 65  ed (padding) fie
3720: 6c 64 20 2a 2f 0a 20 20 75 33 32 20 69 43 68 61  ld */.  u32 iCha
3730: 6e 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  nge;            
3740: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74          /* Count
3750: 65 72 20 69 6e 63 72 65 6d 65 6e 74 65 64 20 65  er incremented e
3760: 61 63 68 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ach transaction 
3770: 2a 2f 0a 20 20 75 38 20 69 73 49 6e 69 74 3b 20  */.  u8 isInit; 
3780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3790: 20 20 20 20 20 2f 2a 20 31 20 77 68 65 6e 20 69       /* 1 when i
37a0: 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20  nitialized */.  
37b0: 75 38 20 62 69 67 45 6e 64 43 6b 73 75 6d 3b 20  u8 bigEndCksum; 
37c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
37d0: 2f 2a 20 54 72 75 65 20 69 66 20 63 68 65 63 6b  /* True if check
37e0: 73 75 6d 73 20 69 6e 20 57 41 4c 20 61 72 65 20  sums in WAL are 
37f0: 62 69 67 2d 65 6e 64 69 61 6e 20 2a 2f 0a 20 20  big-endian */.  
3800: 75 31 36 20 73 7a 50 61 67 65 3b 20 20 20 20 20  u16 szPage;     
3810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3820: 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  /* Database page
3830: 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20 2a   size in bytes *
3840: 2f 0a 20 20 75 33 32 20 6d 78 46 72 61 6d 65 3b  /.  u32 mxFrame;
3850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3860: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20      /* Index of 
3870: 6c 61 73 74 20 76 61 6c 69 64 20 66 72 61 6d 65  last valid frame
3880: 20 69 6e 20 74 68 65 20 57 41 4c 20 2a 2f 0a 20   in the WAL */. 
3890: 20 75 33 32 20 6e 50 61 67 65 3b 20 20 20 20 20   u32 nPage;     
38a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38b0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 64 61 74 61   /* Size of data
38c0: 62 61 73 65 20 69 6e 20 70 61 67 65 73 20 2a 2f  base in pages */
38d0: 0a 20 20 75 33 32 20 61 46 72 61 6d 65 43 6b 73  .  u32 aFrameCks
38e0: 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  um[2];          
38f0: 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 6f     /* Checksum o
3900: 66 20 6c 61 73 74 20 66 72 61 6d 65 20 69 6e 20  f last frame in 
3910: 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 61 53 61  log */.  u32 aSa
3920: 6c 74 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  lt[2];          
3930: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 77 6f 20           /* Two 
3940: 73 61 6c 74 20 76 61 6c 75 65 73 20 63 6f 70 69  salt values copi
3950: 65 64 20 66 72 6f 6d 20 57 41 4c 20 68 65 61 64  ed from WAL head
3960: 65 72 20 2a 2f 0a 20 20 75 33 32 20 61 43 6b 73  er */.  u32 aCks
3970: 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  um[2];          
3980: 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b          /* Check
3990: 73 75 6d 20 6f 76 65 72 20 61 6c 6c 20 70 72 69  sum over all pri
39a0: 6f 72 20 66 69 65 6c 64 73 20 2a 2f 0a 7d 3b 0a  or fields */.};.
39b0: 0a 2f 2a 0a 2a 2a 20 41 20 63 6f 70 79 20 6f 66  ./*.** A copy of
39c0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f   the following o
39d0: 62 6a 65 63 74 20 6f 63 63 75 72 73 20 69 6e 20  bject occurs in 
39e0: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 6d  the wal-index im
39f0: 6d 65 64 69 61 74 65 6c 79 0a 2a 2a 20 66 6f 6c  mediately.** fol
3a00: 6c 6f 77 69 6e 67 20 74 68 65 20 73 65 63 6f 6e  lowing the secon
3a10: 64 20 63 6f 70 79 20 6f 66 20 74 68 65 20 57 61  d copy of the Wa
3a20: 6c 49 6e 64 65 78 48 64 72 2e 20 20 54 68 69 73  lIndexHdr.  This
3a30: 20 6f 62 6a 65 63 74 20 73 74 6f 72 65 73 0a 2a   object stores.*
3a40: 2a 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73  * information us
3a50: 65 64 20 62 79 20 63 68 65 63 6b 70 6f 69 6e 74  ed by checkpoint
3a60: 2e 0a 2a 2a 0a 2a 2a 20 6e 42 61 63 6b 66 69 6c  ..**.** nBackfil
3a70: 6c 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  l is the number 
3a80: 6f 66 20 66 72 61 6d 65 73 20 69 6e 20 74 68 65  of frames in the
3a90: 20 57 41 4c 20 74 68 61 74 20 68 61 76 65 20 62   WAL that have b
3aa0: 65 65 6e 20 77 72 69 74 74 65 6e 0a 2a 2a 20 62  een written.** b
3ab0: 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74  ack into the dat
3ac0: 61 62 61 73 65 2e 20 28 57 65 20 63 61 6c 6c 20  abase. (We call 
3ad0: 74 68 65 20 61 63 74 20 6f 66 20 6d 6f 76 69 6e  the act of movin
3ae0: 67 20 63 6f 6e 74 65 6e 74 20 66 72 6f 6d 20 57  g content from W
3af0: 41 4c 20 74 6f 0a 2a 2a 20 64 61 74 61 62 61 73  AL to.** databas
3b00: 65 20 22 62 61 63 6b 66 69 6c 6c 69 6e 67 22 2e  e "backfilling".
3b10: 29 20 20 54 68 65 20 6e 42 61 63 6b 66 69 6c 6c  )  The nBackfill
3b20: 20 6e 75 6d 62 65 72 20 69 73 20 6e 65 76 65 72   number is never
3b30: 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a   greater than.**
3b40: 20 57 61 6c 49 6e 64 65 78 48 64 72 2e 6d 78 46   WalIndexHdr.mxF
3b50: 72 61 6d 65 2e 20 20 6e 42 61 63 6b 66 69 6c 6c  rame.  nBackfill
3b60: 20 63 61 6e 20 6f 6e 6c 79 20 62 65 20 69 6e 63   can only be inc
3b70: 72 65 61 73 65 64 20 62 79 20 74 68 72 65 61 64  reased by thread
3b80: 73 0a 2a 2a 20 68 6f 6c 64 69 6e 67 20 74 68 65  s.** holding the
3b90: 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 6c   WAL_CKPT_LOCK l
3ba0: 6f 63 6b 20 28 77 68 69 63 68 20 69 6e 63 6c 75  ock (which inclu
3bb0: 64 65 73 20 61 20 72 65 63 6f 76 65 72 79 20 74  des a recovery t
3bc0: 68 72 65 61 64 29 2e 0a 2a 2a 20 48 6f 77 65 76  hread)..** Howev
3bd0: 65 72 2c 20 61 20 57 41 4c 5f 57 52 49 54 45 5f  er, a WAL_WRITE_
3be0: 4c 4f 43 4b 20 74 68 72 65 61 64 20 63 61 6e 20  LOCK thread can 
3bf0: 6d 6f 76 65 20 74 68 65 20 76 61 6c 75 65 20 6f  move the value o
3c00: 66 20 6e 42 61 63 6b 66 69 6c 6c 20 66 72 6f 6d  f nBackfill from
3c10: 0a 2a 2a 20 6d 78 46 72 61 6d 65 20 62 61 63 6b  .** mxFrame back
3c20: 20 74 6f 20 7a 65 72 6f 20 77 68 65 6e 20 74 68   to zero when th
3c30: 65 20 57 41 4c 20 69 73 20 72 65 73 65 74 2e 0a  e WAL is reset..
3c40: 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 69 73 20 6f  **.** There is o
3c50: 6e 65 20 65 6e 74 72 79 20 69 6e 20 61 52 65 61  ne entry in aRea
3c60: 64 4d 61 72 6b 5b 5d 20 66 6f 72 20 65 61 63 68  dMark[] for each
3c70: 20 72 65 61 64 65 72 20 6c 6f 63 6b 2e 20 20 49   reader lock.  I
3c80: 66 20 61 20 72 65 61 64 65 72 0a 2a 2a 20 68 6f  f a reader.** ho
3c90: 6c 64 73 20 72 65 61 64 2d 6c 6f 63 6b 20 4b 2c  lds read-lock K,
3ca0: 20 74 68 65 6e 20 74 68 65 20 76 61 6c 75 65 20   then the value 
3cb0: 69 6e 20 61 52 65 61 64 4d 61 72 6b 5b 4b 5d 20  in aReadMark[K] 
3cc0: 69 73 20 6e 6f 20 67 72 65 61 74 65 72 20 74 68  is no greater th
3cd0: 61 6e 0a 2a 2a 20 74 68 65 20 6d 78 46 72 61 6d  an.** the mxFram
3ce0: 65 20 66 6f 72 20 74 68 61 74 20 72 65 61 64 65  e for that reade
3cf0: 72 2e 20 20 54 68 65 20 76 61 6c 75 65 20 52 45  r.  The value RE
3d00: 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 20  ADMARK_NOT_USED 
3d10: 28 30 78 66 66 66 66 66 66 66 66 29 0a 2a 2a 20  (0xffffffff).** 
3d20: 66 6f 72 20 61 6e 79 20 61 52 65 61 64 4d 61 72  for any aReadMar
3d30: 6b 5b 5d 20 6d 65 61 6e 73 20 74 68 61 74 20 65  k[] means that e
3d40: 6e 74 72 79 20 69 73 20 75 6e 75 73 65 64 2e 20  ntry is unused. 
3d50: 20 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20 69 73   aReadMark[0] is
3d60: 20 0a 2a 2a 20 61 20 73 70 65 63 69 61 6c 20 63   .** a special c
3d70: 61 73 65 3b 20 69 74 73 20 76 61 6c 75 65 20 69  ase; its value i
3d80: 73 20 6e 65 76 65 72 20 75 73 65 64 20 61 6e 64  s never used and
3d90: 20 69 74 20 65 78 69 73 74 73 20 61 73 20 61 20   it exists as a 
3da0: 70 6c 61 63 65 2d 68 6f 6c 64 65 72 0a 2a 2a 20  place-holder.** 
3db0: 74 6f 20 61 76 6f 69 64 20 68 61 76 69 6e 67 20  to avoid having 
3dc0: 74 6f 20 6f 66 66 73 65 74 20 61 52 65 61 64 4d  to offset aReadM
3dd0: 61 72 6b 5b 5d 20 69 6e 64 65 78 73 20 62 79 20  ark[] indexs by 
3de0: 6f 6e 65 2e 20 20 52 65 61 64 65 72 73 20 68 6f  one.  Readers ho
3df0: 6c 64 69 6e 67 0a 2a 2a 20 57 41 4c 5f 52 45 41  lding.** WAL_REA
3e00: 44 5f 4c 4f 43 4b 28 30 29 20 61 6c 77 61 79 73  D_LOCK(0) always
3e10: 20 69 67 6e 6f 72 65 20 74 68 65 20 65 6e 74 69   ignore the enti
3e20: 72 65 20 57 41 4c 20 61 6e 64 20 72 65 61 64 20  re WAL and read 
3e30: 61 6c 6c 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 64  all content.** d
3e40: 69 72 65 63 74 6c 79 20 66 72 6f 6d 20 74 68 65  irectly from the
3e50: 20 64 61 74 61 62 61 73 65 2e 0a 2a 2a 0a 2a 2a   database..**.**
3e60: 20 54 68 65 20 76 61 6c 75 65 20 6f 66 20 61 52   The value of aR
3e70: 65 61 64 4d 61 72 6b 5b 4b 5d 20 6d 61 79 20 6f  eadMark[K] may o
3e80: 6e 6c 79 20 62 65 20 63 68 61 6e 67 65 64 20 62  nly be changed b
3e90: 79 20 61 20 74 68 72 65 61 64 20 74 68 61 74 0a  y a thread that.
3ea0: 2a 2a 20 69 73 20 68 6f 6c 64 69 6e 67 20 61 6e  ** is holding an
3eb0: 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20   exclusive lock 
3ec0: 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  on WAL_READ_LOCK
3ed0: 28 4b 29 2e 20 20 54 68 75 73 2c 20 74 68 65 20  (K).  Thus, the 
3ee0: 76 61 6c 75 65 20 6f 66 0a 2a 2a 20 61 52 65 61  value of.** aRea
3ef0: 64 4d 61 72 6b 5b 4b 5d 20 63 61 6e 6e 6f 74 20  dMark[K] cannot 
3f00: 63 68 61 6e 67 65 64 20 77 68 69 6c 65 20 74 68  changed while th
3f10: 65 72 65 20 69 73 20 61 20 72 65 61 64 65 72 20  ere is a reader 
3f20: 69 73 20 75 73 69 6e 67 20 74 68 61 74 20 6d 61  is using that ma
3f30: 72 6b 0a 2a 2a 20 73 69 6e 63 65 20 74 68 65 20  rk.** since the 
3f40: 72 65 61 64 65 72 20 77 69 6c 6c 20 62 65 20 68  reader will be h
3f50: 6f 6c 64 69 6e 67 20 61 20 73 68 61 72 65 64 20  olding a shared 
3f60: 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52 45 41 44  lock on WAL_READ
3f70: 5f 4c 4f 43 4b 28 4b 29 2e 0a 2a 2a 0a 2a 2a 20  _LOCK(K)..**.** 
3f80: 54 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 65 72  The checkpointer
3f90: 20 6d 61 79 20 6f 6e 6c 79 20 74 72 61 6e 73 66   may only transf
3fa0: 65 72 20 66 72 61 6d 65 73 20 66 72 6f 6d 20 57  er frames from W
3fb0: 41 4c 20 74 6f 20 64 61 74 61 62 61 73 65 20 77  AL to database w
3fc0: 68 65 72 65 0a 2a 2a 20 74 68 65 20 66 72 61 6d  here.** the fram
3fd0: 65 20 6e 75 6d 62 65 72 73 20 61 72 65 20 6c 65  e numbers are le
3fe0: 73 73 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c  ss than or equal
3ff0: 20 74 6f 20 65 76 65 72 79 20 61 52 65 61 64 4d   to every aReadM
4000: 61 72 6b 5b 5d 20 74 68 61 74 20 69 73 0a 2a 2a  ark[] that is.**
4010: 20 69 6e 20 75 73 65 20 28 74 68 61 74 20 69 73   in use (that is
4020: 2c 20 65 76 65 72 79 20 61 52 65 61 64 4d 61 72  , every aReadMar
4030: 6b 5b 6a 5d 20 66 6f 72 20 77 68 69 63 68 20 74  k[j] for which t
4040: 68 65 72 65 20 69 73 20 61 20 63 6f 72 72 65 73  here is a corres
4050: 70 6f 6e 64 69 6e 67 0a 2a 2a 20 57 41 4c 5f 52  ponding.** WAL_R
4060: 45 41 44 5f 4c 4f 43 4b 28 6a 29 29 2e 20 20 4e  EAD_LOCK(j)).  N
4070: 65 77 20 72 65 61 64 65 72 73 20 28 75 73 75 61  ew readers (usua
4080: 6c 6c 79 29 20 70 69 63 6b 20 74 68 65 20 61 52  lly) pick the aR
4090: 65 61 64 4d 61 72 6b 5b 5d 20 77 69 74 68 20 74  eadMark[] with t
40a0: 68 65 0a 2a 2a 20 6c 61 72 67 65 73 74 20 76 61  he.** largest va
40b0: 6c 75 65 20 61 6e 64 20 77 69 6c 6c 20 69 6e 63  lue and will inc
40c0: 72 65 61 73 65 20 61 6e 20 75 6e 75 73 65 64 20  rease an unused 
40d0: 61 52 65 61 64 4d 61 72 6b 5b 5d 20 74 6f 20 6d  aReadMark[] to m
40e0: 78 46 72 61 6d 65 20 69 66 20 74 68 65 72 65 0a  xFrame if there.
40f0: 2a 2a 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  ** is not alread
4100: 79 20 61 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d  y an aReadMark[]
4110: 20 65 71 75 61 6c 20 74 6f 20 6d 78 46 72 61 6d   equal to mxFram
4120: 65 2e 20 20 54 68 65 20 65 78 63 65 70 74 69 6f  e.  The exceptio
4130: 6e 20 74 6f 20 74 68 65 0a 2a 2a 20 70 72 65 76  n to the.** prev
4140: 69 6f 75 73 20 73 65 6e 74 65 6e 63 65 20 69 73  ious sentence is
4150: 20 77 68 65 6e 20 6e 42 61 63 6b 66 69 6c 6c 20   when nBackfill 
4160: 65 71 75 61 6c 73 20 6d 78 46 72 61 6d 65 20 28  equals mxFrame (
4170: 6d 65 61 6e 69 6e 67 20 74 68 61 74 20 65 76 65  meaning that eve
4180: 72 79 74 68 69 6e 67 0a 2a 2a 20 69 6e 20 74 68  rything.** in th
4190: 65 20 57 41 4c 20 68 61 73 20 62 65 65 6e 20 62  e WAL has been b
41a0: 61 63 6b 66 69 6c 6c 65 64 20 69 6e 74 6f 20 74  ackfilled into t
41b0: 68 65 20 64 61 74 61 62 61 73 65 29 20 74 68 65  he database) the
41c0: 6e 20 6e 65 77 20 72 65 61 64 65 72 73 0a 2a 2a  n new readers.**
41d0: 20 77 69 6c 6c 20 63 68 6f 6f 73 65 20 61 52 65   will choose aRe
41e0: 61 64 4d 61 72 6b 5b 30 5d 20 77 68 69 63 68 20  adMark[0] which 
41f0: 68 61 73 20 76 61 6c 75 65 20 30 20 61 6e 64 20  has value 0 and 
4200: 68 65 6e 63 65 20 73 75 63 68 20 72 65 61 64 65  hence such reade
4210: 72 20 77 69 6c 6c 0a 2a 2a 20 67 65 74 20 61 6c  r will.** get al
4220: 6c 20 74 68 65 69 72 20 61 6c 6c 20 63 6f 6e 74  l their all cont
4230: 65 6e 74 20 64 69 72 65 63 74 6c 79 20 66 72 6f  ent directly fro
4240: 6d 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  m the database f
4250: 69 6c 65 20 61 6e 64 20 69 67 6e 6f 72 65 20 0a  ile and ignore .
4260: 2a 2a 20 74 68 65 20 57 41 4c 2e 0a 2a 2a 0a 2a  ** the WAL..**.*
4270: 2a 20 57 72 69 74 65 72 73 20 6e 6f 72 6d 61 6c  * Writers normal
4280: 6c 79 20 61 70 70 65 6e 64 20 6e 65 77 20 66 72  ly append new fr
4290: 61 6d 65 73 20 74 6f 20 74 68 65 20 65 6e 64 20  ames to the end 
42a0: 6f 66 20 74 68 65 20 57 41 4c 2e 20 20 48 6f 77  of the WAL.  How
42b0: 65 76 65 72 2c 0a 2a 2a 20 69 66 20 6e 42 61 63  ever,.** if nBac
42c0: 6b 66 69 6c 6c 20 65 71 75 61 6c 73 20 6d 78 46  kfill equals mxF
42d0: 72 61 6d 65 20 28 6d 65 61 6e 69 6e 67 20 74 68  rame (meaning th
42e0: 61 74 20 61 6c 6c 20 57 41 4c 20 63 6f 6e 74 65  at all WAL conte
42f0: 6e 74 20 68 61 73 20 62 65 65 6e 0a 2a 2a 20 77  nt has been.** w
4300: 72 69 74 74 65 6e 20 62 61 63 6b 20 69 6e 74 6f  ritten back into
4310: 20 74 68 65 20 64 61 74 61 62 61 73 65 29 20 61   the database) a
4320: 6e 64 20 69 66 20 6e 6f 20 72 65 61 64 65 72 73  nd if no readers
4330: 20 61 72 65 20 75 73 69 6e 67 20 74 68 65 20 57   are using the W
4340: 41 4c 0a 2a 2a 20 28 69 6e 20 6f 74 68 65 72 20  AL.** (in other 
4350: 77 6f 72 64 73 2c 20 69 66 20 74 68 65 72 65 20  words, if there 
4360: 61 72 65 20 6e 6f 20 57 41 4c 5f 52 45 41 44 5f  are no WAL_READ_
4370: 4c 4f 43 4b 28 69 29 20 77 68 65 72 65 20 69 3e  LOCK(i) where i>
4380: 30 29 20 74 68 65 6e 0a 2a 2a 20 74 68 65 20 77  0) then.** the w
4390: 72 69 74 65 72 20 77 69 6c 6c 20 66 69 72 73 74  riter will first
43a0: 20 22 72 65 73 65 74 22 20 74 68 65 20 57 41 4c   "reset" the WAL
43b0: 20 62 61 63 6b 20 74 6f 20 74 68 65 20 62 65 67   back to the beg
43c0: 69 6e 6e 69 6e 67 20 61 6e 64 20 73 74 61 72 74  inning and start
43d0: 0a 2a 2a 20 77 72 69 74 69 6e 67 20 6e 65 77 20  .** writing new 
43e0: 63 6f 6e 74 65 6e 74 20 62 65 67 69 6e 6e 69 6e  content beginnin
43f0: 67 20 61 74 20 66 72 61 6d 65 20 31 2e 0a 2a 2a  g at frame 1..**
4400: 0a 2a 2a 20 57 65 20 61 73 73 75 6d 65 20 74 68  .** We assume th
4410: 61 74 20 33 32 2d 62 69 74 20 6c 6f 61 64 73 20  at 32-bit loads 
4420: 61 72 65 20 61 74 6f 6d 69 63 20 61 6e 64 20 73  are atomic and s
4430: 6f 20 6e 6f 20 6c 6f 63 6b 73 20 61 72 65 20 6e  o no locks are n
4440: 65 65 64 65 64 20 69 6e 0a 2a 2a 20 6f 72 64 65  eeded in.** orde
4450: 72 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 61  r to read from a
4460: 6e 79 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65  ny aReadMark[] e
4470: 6e 74 72 69 65 73 2e 0a 2a 2f 0a 73 74 72 75 63  ntries..*/.struc
4480: 74 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 7b 0a  t WalCkptInfo {.
4490: 20 20 75 33 32 20 6e 42 61 63 6b 66 69 6c 6c 3b    u32 nBackfill;
44a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
44b0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 57    /* Number of W
44c0: 41 4c 20 66 72 61 6d 65 73 20 62 61 63 6b 66 69  AL frames backfi
44d0: 6c 6c 65 64 20 69 6e 74 6f 20 44 42 20 2a 2f 0a  lled into DB */.
44e0: 20 20 75 33 32 20 61 52 65 61 64 4d 61 72 6b 5b    u32 aReadMark[
44f0: 57 41 4c 5f 4e 52 45 41 44 45 52 5d 3b 20 20 20  WAL_NREADER];   
4500: 20 20 2f 2a 20 52 65 61 64 65 72 20 6d 61 72 6b    /* Reader mark
4510: 73 20 2a 2f 0a 7d 3b 0a 23 64 65 66 69 6e 65 20  s */.};.#define 
4520: 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45  READMARK_NOT_USE
4530: 44 20 20 30 78 66 66 66 66 66 66 66 66 0a 0a 0a  D  0xffffffff...
4540: 2f 2a 20 41 20 62 6c 6f 63 6b 20 6f 66 20 57 41  /* A block of WA
4550: 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 52 45 53 45  LINDEX_LOCK_RESE
4560: 52 56 45 44 20 62 79 74 65 73 20 62 65 67 69 6e  RVED bytes begin
4570: 6e 69 6e 67 20 61 74 0a 2a 2a 20 57 41 4c 49 4e  ning at.** WALIN
4580: 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20  DEX_LOCK_OFFSET 
4590: 69 73 20 72 65 73 65 72 76 65 64 20 66 6f 72 20  is reserved for 
45a0: 6c 6f 63 6b 73 2e 20 53 69 6e 63 65 20 73 6f 6d  locks. Since som
45b0: 65 20 73 79 73 74 65 6d 73 0a 2a 2a 20 6f 6e 6c  e systems.** onl
45c0: 79 20 73 75 70 70 6f 72 74 20 6d 61 6e 64 61 74  y support mandat
45d0: 6f 72 79 20 66 69 6c 65 2d 6c 6f 63 6b 73 2c 20  ory file-locks, 
45e0: 77 65 20 64 6f 20 6e 6f 74 20 72 65 61 64 20 6f  we do not read o
45f0: 72 20 77 72 69 74 65 20 64 61 74 61 0a 2a 2a 20  r write data.** 
4600: 66 72 6f 6d 20 74 68 65 20 72 65 67 69 6f 6e 20  from the region 
4610: 6f 66 20 74 68 65 20 66 69 6c 65 20 6f 6e 20 77  of the file on w
4620: 68 69 63 68 20 6c 6f 63 6b 73 20 61 72 65 20 61  hich locks are a
4630: 70 70 6c 69 65 64 2e 0a 2a 2f 0a 23 64 65 66 69  pplied..*/.#defi
4640: 6e 65 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b  ne WALINDEX_LOCK
4650: 5f 4f 46 46 53 45 54 20 20 20 28 73 69 7a 65 6f  _OFFSET   (sizeo
4660: 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 2a 32  f(WalIndexHdr)*2
4670: 20 2b 20 73 69 7a 65 6f 66 28 57 61 6c 43 6b 70   + sizeof(WalCkp
4680: 74 49 6e 66 6f 29 29 0a 23 64 65 66 69 6e 65 20  tInfo)).#define 
4690: 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 52 45  WALINDEX_LOCK_RE
46a0: 53 45 52 56 45 44 20 31 36 0a 23 64 65 66 69 6e  SERVED 16.#defin
46b0: 65 20 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53  e WALINDEX_HDR_S
46c0: 49 5a 45 20 20 20 20 20 20 28 57 41 4c 49 4e 44  IZE      (WALIND
46d0: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 2b 57  EX_LOCK_OFFSET+W
46e0: 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 52 45 53  ALINDEX_LOCK_RES
46f0: 45 52 56 45 44 29 0a 0a 2f 2a 20 53 69 7a 65 20  ERVED)../* Size 
4700: 6f 66 20 68 65 61 64 65 72 20 62 65 66 6f 72 65  of header before
4710: 20 65 61 63 68 20 66 72 61 6d 65 20 69 6e 20 77   each frame in w
4720: 61 6c 20 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41  al */.#define WA
4730: 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 20  L_FRAME_HDRSIZE 
4740: 32 34 0a 0a 2f 2a 20 53 69 7a 65 20 6f 66 20 77  24../* Size of w
4750: 72 69 74 65 20 61 68 65 61 64 20 6c 6f 67 20 68  rite ahead log h
4760: 65 61 64 65 72 2c 20 69 6e 63 6c 75 64 69 6e 67  eader, including
4770: 20 63 68 65 63 6b 73 75 6d 2e 20 2a 2f 0a 2f 2a   checksum. */./*
4780: 20 23 64 65 66 69 6e 65 20 57 41 4c 5f 48 44 52   #define WAL_HDR
4790: 53 49 5a 45 20 32 34 20 2a 2f 0a 23 64 65 66 69  SIZE 24 */.#defi
47a0: 6e 65 20 57 41 4c 5f 48 44 52 53 49 5a 45 20 33  ne WAL_HDRSIZE 3
47b0: 32 0a 0a 2f 2a 20 57 41 4c 20 6d 61 67 69 63 20  2../* WAL magic 
47c0: 76 61 6c 75 65 2e 20 45 69 74 68 65 72 20 74 68  value. Either th
47d0: 69 73 20 76 61 6c 75 65 2c 20 6f 72 20 74 68 65  is value, or the
47e0: 20 73 61 6d 65 20 76 61 6c 75 65 20 77 69 74 68   same value with
47f0: 20 74 68 65 20 6c 65 61 73 74 0a 2a 2a 20 73 69   the least.** si
4800: 67 6e 69 66 69 63 61 6e 74 20 62 69 74 20 61 6c  gnificant bit al
4810: 73 6f 20 73 65 74 20 28 57 41 4c 5f 4d 41 47 49  so set (WAL_MAGI
4820: 43 20 7c 20 30 78 30 30 30 30 30 30 30 31 29 20  C | 0x00000001) 
4830: 69 73 20 73 74 6f 72 65 64 20 69 6e 20 33 32 2d  is stored in 32-
4840: 62 69 74 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61  bit.** big-endia
4850: 6e 20 66 6f 72 6d 61 74 20 69 6e 20 74 68 65 20  n format in the 
4860: 66 69 72 73 74 20 34 20 62 79 74 65 73 20 6f 66  first 4 bytes of
4870: 20 61 20 57 41 4c 20 66 69 6c 65 2e 0a 2a 2a 0a   a WAL file..**.
4880: 2a 2a 20 49 66 20 74 68 65 20 4c 53 42 20 69 73  ** If the LSB is
4890: 20 73 65 74 2c 20 74 68 65 6e 20 74 68 65 20 63   set, then the c
48a0: 68 65 63 6b 73 75 6d 73 20 66 6f 72 20 65 61 63  hecksums for eac
48b0: 68 20 66 72 61 6d 65 20 77 69 74 68 69 6e 20 74  h frame within t
48c0: 68 65 20 57 41 4c 0a 2a 2a 20 66 69 6c 65 20 61  he WAL.** file a
48d0: 72 65 20 63 61 6c 63 75 6c 61 74 65 64 20 62 79  re calculated by
48e0: 20 74 72 65 61 74 69 6e 67 20 61 6c 6c 20 64 61   treating all da
48f0: 74 61 20 61 73 20 61 6e 20 61 72 72 61 79 20 6f  ta as an array o
4900: 66 20 33 32 2d 62 69 74 20 0a 2a 2a 20 62 69 67  f 32-bit .** big
4910: 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73 2e 20 4f  -endian words. O
4920: 74 68 65 72 77 69 73 65 2c 20 74 68 65 79 20 61  therwise, they a
4930: 72 65 20 63 61 6c 63 75 6c 61 74 65 64 20 62 79  re calculated by
4940: 20 69 6e 74 65 72 70 72 65 74 69 6e 67 20 0a 2a   interpreting .*
4950: 2a 20 61 6c 6c 20 64 61 74 61 20 61 73 20 33 32  * all data as 32
4960: 2d 62 69 74 20 6c 69 74 74 6c 65 2d 65 6e 64 69  -bit little-endi
4970: 61 6e 20 77 6f 72 64 73 2e 0a 2a 2f 0a 23 64 65  an words..*/.#de
4980: 66 69 6e 65 20 57 41 4c 5f 4d 41 47 49 43 20 30  fine WAL_MAGIC 0
4990: 78 33 37 37 66 30 36 38 32 0a 0a 2f 2a 0a 2a 2a  x377f0682../*.**
49a0: 20 52 65 74 75 72 6e 20 74 68 65 20 6f 66 66 73   Return the offs
49b0: 65 74 20 6f 66 20 66 72 61 6d 65 20 69 46 72 61  et of frame iFra
49c0: 6d 65 20 69 6e 20 74 68 65 20 77 72 69 74 65 2d  me in the write-
49d0: 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65 2c 20  ahead log file, 
49e0: 0a 2a 2a 20 61 73 73 75 6d 69 6e 67 20 61 20 64  .** assuming a d
49f0: 61 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a  atabase page siz
4a00: 65 20 6f 66 20 73 7a 50 61 67 65 20 62 79 74 65  e of szPage byte
4a10: 73 2e 20 54 68 65 20 6f 66 66 73 65 74 20 72 65  s. The offset re
4a20: 74 75 72 6e 65 64 0a 2a 2a 20 69 73 20 74 6f 20  turned.** is to 
4a30: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
4a40: 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67   write-ahead log
4a50: 20 66 72 61 6d 65 2d 68 65 61 64 65 72 2e 0a 2a   frame-header..*
4a60: 2f 0a 23 64 65 66 69 6e 65 20 77 61 6c 46 72 61  /.#define walFra
4a70: 6d 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2c  meOffset(iFrame,
4a80: 20 73 7a 50 61 67 65 29 20 28 20 20 20 20 20 20   szPage) (      
4a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4aa0: 20 20 20 20 20 20 20 20 20 5c 0a 20 20 57 41 4c           \.  WAL
4ab0: 5f 48 44 52 53 49 5a 45 20 2b 20 28 28 69 46 72  _HDRSIZE + ((iFr
4ac0: 61 6d 65 29 2d 31 29 2a 28 69 36 34 29 28 28 73  ame)-1)*(i64)((s
4ad0: 7a 50 61 67 65 29 2b 57 41 4c 5f 46 52 41 4d 45  zPage)+WAL_FRAME
4ae0: 5f 48 44 52 53 49 5a 45 29 20 20 20 20 20 20 20  _HDRSIZE)       
4af0: 20 20 5c 0a 29 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20    \.)../*.** An 
4b00: 6f 70 65 6e 20 77 72 69 74 65 2d 61 68 65 61 64  open write-ahead
4b10: 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 72 65 70   log file is rep
4b20: 72 65 73 65 6e 74 65 64 20 62 79 20 61 6e 20 69  resented by an i
4b30: 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 0a 2a  nstance of the.*
4b40: 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65  * following obje
4b50: 63 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61  ct..*/.struct Wa
4b60: 6c 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 66  l {.  sqlite3_vf
4b70: 73 20 2a 70 56 66 73 3b 20 20 20 20 20 20 20 20  s *pVfs;        
4b80: 20 2f 2a 20 54 68 65 20 56 46 53 20 75 73 65 64   /* The VFS used
4b90: 20 74 6f 20 63 72 65 61 74 65 20 70 44 62 46 64   to create pDbFd
4ba0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69   */.  sqlite3_fi
4bb0: 6c 65 20 2a 70 44 62 46 64 3b 20 20 20 20 20 20  le *pDbFd;      
4bc0: 20 2f 2a 20 46 69 6c 65 20 68 61 6e 64 6c 65 20   /* File handle 
4bd0: 66 6f 72 20 74 68 65 20 64 61 74 61 62 61 73 65  for the database
4be0: 20 66 69 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74   file */.  sqlit
4bf0: 65 33 5f 66 69 6c 65 20 2a 70 57 61 6c 46 64 3b  e3_file *pWalFd;
4c00: 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 68 61        /* File ha
4c10: 6e 64 6c 65 20 66 6f 72 20 57 41 4c 20 66 69 6c  ndle for WAL fil
4c20: 65 20 2a 2f 0a 20 20 75 33 32 20 69 43 61 6c 6c  e */.  u32 iCall
4c30: 62 61 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  back;           
4c40: 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20 70 61    /* Value to pa
4c50: 73 73 20 74 6f 20 6c 6f 67 20 63 61 6c 6c 62 61  ss to log callba
4c60: 63 6b 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20 69  ck (or 0) */.  i
4c70: 6e 74 20 6e 57 69 44 61 74 61 3b 20 20 20 20 20  nt nWiData;     
4c80: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
4c90: 65 20 6f 66 20 61 72 72 61 79 20 61 70 57 69 44  e of array apWiD
4ca0: 61 74 61 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c  ata */.  volatil
4cb0: 65 20 75 33 32 20 2a 2a 61 70 57 69 44 61 74 61  e u32 **apWiData
4cc0: 3b 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74  ;   /* Pointer t
4cd0: 6f 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 74  o wal-index cont
4ce0: 65 6e 74 20 69 6e 20 6d 65 6d 6f 72 79 20 2a 2f  ent in memory */
4cf0: 0a 20 20 75 31 36 20 73 7a 50 61 67 65 3b 20 20  .  u16 szPage;  
4d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4d10: 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20 73   Database page s
4d20: 69 7a 65 20 2a 2f 0a 20 20 69 31 36 20 72 65 61  ize */.  i16 rea
4d30: 64 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20  dLock;          
4d40: 20 20 20 20 2f 2a 20 57 68 69 63 68 20 72 65 61      /* Which rea
4d50: 64 20 6c 6f 63 6b 20 69 73 20 62 65 69 6e 67 20  d lock is being 
4d60: 68 65 6c 64 2e 20 20 2d 31 20 66 6f 72 20 6e 6f  held.  -1 for no
4d70: 6e 65 20 2a 2f 0a 20 20 75 38 20 65 78 63 6c 75  ne */.  u8 exclu
4d80: 73 69 76 65 4d 6f 64 65 3b 20 20 20 20 20 20 20  siveMode;       
4d90: 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69     /* Non-zero i
4da0: 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20  f connection is 
4db0: 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f 64  in exclusive mod
4dc0: 65 20 2a 2f 0a 20 20 75 38 20 77 72 69 74 65 4c  e */.  u8 writeL
4dd0: 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ock;            
4de0: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 20    /* True if in 
4df0: 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74  a write transact
4e00: 69 6f 6e 20 2a 2f 0a 20 20 75 38 20 63 6b 70 74  ion */.  u8 ckpt
4e10: 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Lock;           
4e20: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 68      /* True if h
4e30: 6f 6c 64 69 6e 67 20 61 20 63 68 65 63 6b 70 6f  olding a checkpo
4e40: 69 6e 74 20 6c 6f 63 6b 20 2a 2f 0a 20 20 57 61  int lock */.  Wa
4e50: 6c 49 6e 64 65 78 48 64 72 20 68 64 72 3b 20 20  lIndexHdr hdr;  
4e60: 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 2d           /* Wal-
4e70: 69 6e 64 65 78 20 68 65 61 64 65 72 20 66 6f 72  index header for
4e80: 20 63 75 72 72 65 6e 74 20 74 72 61 6e 73 61 63   current transac
4e90: 74 69 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  tion */.  const 
4ea0: 63 68 61 72 20 2a 7a 57 61 6c 4e 61 6d 65 3b 20  char *zWalName; 
4eb0: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
4ec0: 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33  WAL file */.  u3
4ed0: 32 20 6e 43 6b 70 74 3b 20 20 20 20 20 20 20 20  2 nCkpt;        
4ee0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63           /* Chec
4ef0: 6b 70 6f 69 6e 74 20 73 65 71 75 65 6e 63 65 20  kpoint sequence 
4f00: 63 6f 75 6e 74 65 72 20 69 6e 20 74 68 65 20 77  counter in the w
4f10: 61 6c 2d 68 65 61 64 65 72 20 2a 2f 0a 23 69 66  al-header */.#if
4f20: 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47  def SQLITE_DEBUG
4f30: 0a 20 20 75 38 20 6c 6f 63 6b 45 72 72 6f 72 3b  .  u8 lockError;
4f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4f50: 20 54 72 75 65 20 69 66 20 61 20 6c 6f 63 6b 69   True if a locki
4f60: 6e 67 20 65 72 72 6f 72 20 68 61 73 20 6f 63 63  ng error has occ
4f70: 75 72 72 65 64 20 2a 2f 0a 23 65 6e 64 69 66 0a  urred */.#endif.
4f80: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 70  };../*.** Each p
4f90: 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69  age of the wal-i
4fa0: 6e 64 65 78 20 6d 61 70 70 69 6e 67 20 63 6f 6e  ndex mapping con
4fb0: 74 61 69 6e 73 20 61 20 68 61 73 68 2d 74 61 62  tains a hash-tab
4fc0: 6c 65 20 6d 61 64 65 20 75 70 20 6f 66 0a 2a 2a  le made up of.**
4fd0: 20 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53   an array of HAS
4fe0: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 65 6c 65  HTABLE_NSLOT ele
4ff0: 6d 65 6e 74 73 20 6f 66 20 74 68 65 20 66 6f 6c  ments of the fol
5000: 6c 6f 77 69 6e 67 20 74 79 70 65 2e 0a 2a 2f 0a  lowing type..*/.
5010: 74 79 70 65 64 65 66 20 75 31 36 20 68 74 5f 73  typedef u16 ht_s
5020: 6c 6f 74 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  lot;../*.** This
5030: 20 73 74 72 75 63 74 75 72 65 20 69 73 20 75 73   structure is us
5040: 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20  ed to implement 
5050: 61 6e 20 69 74 65 72 61 74 6f 72 20 74 68 61 74  an iterator that
5060: 20 6c 6f 6f 70 73 20 74 68 72 6f 75 67 68 0a 2a   loops through.*
5070: 2a 20 61 6c 6c 20 66 72 61 6d 65 73 20 69 6e 20  * all frames in 
5080: 74 68 65 20 57 41 4c 20 69 6e 20 64 61 74 61 62  the WAL in datab
5090: 61 73 65 20 70 61 67 65 20 6f 72 64 65 72 2e 20  ase page order. 
50a0: 57 68 65 72 65 20 74 77 6f 20 6f 72 20 6d 6f 72  Where two or mor
50b0: 65 20 66 72 61 6d 65 73 0a 2a 2a 20 63 6f 72 72  e frames.** corr
50c0: 65 73 70 6f 6e 64 20 74 6f 20 74 68 65 20 73 61  espond to the sa
50d0: 6d 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65  me database page
50e0: 2c 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 76  , the iterator v
50f0: 69 73 69 74 73 20 6f 6e 6c 79 20 74 68 65 20 0a  isits only the .
5100: 2a 2a 20 66 72 61 6d 65 20 6d 6f 73 74 20 72 65  ** frame most re
5110: 63 65 6e 74 6c 79 20 77 72 69 74 74 65 6e 20 74  cently written t
5120: 6f 20 74 68 65 20 57 41 4c 20 28 69 6e 20 6f 74  o the WAL (in ot
5130: 68 65 72 20 77 6f 72 64 73 2c 20 74 68 65 20 66  her words, the f
5140: 72 61 6d 65 20 77 69 74 68 0a 2a 2a 20 74 68 65  rame with.** the
5150: 20 6c 61 72 67 65 73 74 20 69 6e 64 65 78 29 2e   largest index).
5160: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e 74 65 72  .**.** The inter
5170: 6e 61 6c 73 20 6f 66 20 74 68 69 73 20 73 74 72  nals of this str
5180: 75 63 74 75 72 65 20 61 72 65 20 6f 6e 6c 79 20  ucture are only 
5190: 61 63 63 65 73 73 65 64 20 62 79 3a 0a 2a 2a 0a  accessed by:.**.
51a0: 2a 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f 72  **   walIterator
51b0: 49 6e 69 74 28 29 20 2d 20 43 72 65 61 74 65 20  Init() - Create 
51c0: 61 20 6e 65 77 20 69 74 65 72 61 74 6f 72 2c 0a  a new iterator,.
51d0: 2a 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f 72  **   walIterator
51e0: 4e 65 78 74 28 29 20 2d 20 53 74 65 70 20 61 6e  Next() - Step an
51f0: 20 69 74 65 72 61 74 6f 72 2c 0a 2a 2a 20 20 20   iterator,.**   
5200: 77 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28  walIteratorFree(
5210: 29 20 2d 20 46 72 65 65 20 61 6e 20 69 74 65 72  ) - Free an iter
5220: 61 74 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  ator..**.** This
5230: 20 66 75 6e 63 74 69 6f 6e 61 6c 69 74 79 20 69   functionality i
5240: 73 20 75 73 65 64 20 62 79 20 74 68 65 20 63 68  s used by the ch
5250: 65 63 6b 70 6f 69 6e 74 20 63 6f 64 65 20 28 73  eckpoint code (s
5260: 65 65 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74  ee walCheckpoint
5270: 28 29 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57  ())..*/.struct W
5280: 61 6c 49 74 65 72 61 74 6f 72 20 7b 0a 20 20 69  alIterator {.  i
5290: 6e 74 20 69 50 72 69 6f 72 3b 20 20 20 20 20 20  nt iPrior;      
52a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
52b0: 2a 20 4c 61 73 74 20 72 65 73 75 6c 74 20 72 65  * Last result re
52c0: 74 75 72 6e 65 64 20 66 72 6f 6d 20 74 68 65 20  turned from the 
52d0: 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e  iterator */.  in
52e0: 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20 20 20  t nSegment;     
52f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5300: 20 53 69 7a 65 20 6f 66 20 74 68 65 20 61 53 65   Size of the aSe
5310: 67 6d 65 6e 74 5b 5d 20 61 72 72 61 79 20 2a 2f  gment[] array */
5320: 0a 20 20 73 74 72 75 63 74 20 57 61 6c 53 65 67  .  struct WalSeg
5330: 6d 65 6e 74 20 7b 0a 20 20 20 20 69 6e 74 20 69  ment {.    int i
5340: 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20  Next;           
5350: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
5360: 20 73 6c 6f 74 20 69 6e 20 61 49 6e 64 65 78 5b   slot in aIndex[
5370: 5d 20 6e 6f 74 20 79 65 74 20 72 65 74 75 72 6e  ] not yet return
5380: 65 64 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f  ed */.    ht_slo
5390: 74 20 2a 61 49 6e 64 65 78 3b 20 20 20 20 20 20  t *aIndex;      
53a0: 20 20 20 20 20 20 20 20 2f 2a 20 69 30 2c 20 69          /* i0, i
53b0: 31 2c 20 69 32 2e 2e 2e 20 73 75 63 68 20 74 68  1, i2... such th
53c0: 61 74 20 61 50 67 6e 6f 5b 69 4e 5d 20 61 73 63  at aPgno[iN] asc
53d0: 65 6e 64 20 2a 2f 0a 20 20 20 20 75 33 32 20 2a  end */.    u32 *
53e0: 61 50 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20  aPgno;          
53f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61           /* Arra
5400: 79 20 6f 66 20 70 61 67 65 20 6e 75 6d 62 65 72  y of page number
5410: 73 2e 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 45  s. */.    int nE
5420: 6e 74 72 79 3b 20 20 20 20 20 20 20 20 20 20 20  ntry;           
5430: 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78 20 73          /* Max s
5440: 69 7a 65 20 6f 66 20 61 50 67 6e 6f 5b 5d 20 61  ize of aPgno[] a
5450: 6e 64 20 61 49 6e 64 65 78 5b 5d 20 61 72 72 61  nd aIndex[] arra
5460: 79 73 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 5a  ys */.    int iZ
5470: 65 72 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20  ero;            
5480: 20 20 20 20 20 20 20 20 2f 2a 20 46 72 61 6d 65          /* Frame
5490: 20 6e 75 6d 62 65 72 20 61 73 73 6f 63 69 61 74   number associat
54a0: 65 64 20 77 69 74 68 20 61 50 67 6e 6f 5b 30 5d  ed with aPgno[0]
54b0: 20 2a 2f 0a 20 20 7d 20 61 53 65 67 6d 65 6e 74   */.  } aSegment
54c0: 5b 31 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20  [1];            
54d0: 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20 66 6f 72        /* One for
54e0: 20 65 76 65 72 79 20 33 32 4b 42 20 70 61 67 65   every 32KB page
54f0: 20 69 6e 20 74 68 65 20 57 41 4c 20 2a 2f 0a 7d   in the WAL */.}
5500: 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 66 69 6e 65 20  ;../*.** Define 
5510: 74 68 65 20 70 61 72 61 6d 65 74 65 72 73 20 6f  the parameters o
5520: 66 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  f the hash table
5530: 73 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64  s in the wal-ind
5540: 65 78 20 66 69 6c 65 2e 20 54 68 65 72 65 0a 2a  ex file. There.*
5550: 2a 20 69 73 20 61 20 68 61 73 68 2d 74 61 62 6c  * is a hash-tabl
5560: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 65 76 65 72  e following ever
5570: 79 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  y HASHTABLE_NPAG
5580: 45 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20 69  E page numbers i
5590: 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64  n the.** wal-ind
55a0: 65 78 2e 0a 2a 2a 0a 2a 2a 20 43 68 61 6e 67 69  ex..**.** Changi
55b0: 6e 67 20 61 6e 79 20 6f 66 20 74 68 65 73 65 20  ng any of these 
55c0: 63 6f 6e 73 74 61 6e 74 73 20 77 69 6c 6c 20 61  constants will a
55d0: 6c 74 65 72 20 74 68 65 20 77 61 6c 2d 69 6e 64  lter the wal-ind
55e0: 65 78 20 66 6f 72 6d 61 74 20 61 6e 64 0a 2a 2a  ex format and.**
55f0: 20 63 72 65 61 74 65 20 69 6e 63 6f 6d 70 61 74   create incompat
5600: 69 62 69 6c 69 74 69 65 73 2e 0a 2a 2f 0a 23 64  ibilities..*/.#d
5610: 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f  efine HASHTABLE_
5620: 4e 50 41 47 45 20 20 20 20 20 20 34 30 39 36 20  NPAGE      4096 
5630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5640: 2f 2a 20 4d 75 73 74 20 62 65 20 70 6f 77 65 72  /* Must be power
5650: 20 6f 66 20 32 20 2a 2f 0a 23 64 65 66 69 6e 65   of 2 */.#define
5660: 20 48 41 53 48 54 41 42 4c 45 5f 48 41 53 48 5f   HASHTABLE_HASH_
5670: 31 20 20 20 20 20 33 38 33 20 20 20 20 20 20 20  1     383       
5680: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 68             /* Sh
5690: 6f 75 6c 64 20 62 65 20 70 72 69 6d 65 20 2a 2f  ould be prime */
56a0: 0a 23 64 65 66 69 6e 65 20 48 41 53 48 54 41 42  .#define HASHTAB
56b0: 4c 45 5f 4e 53 4c 4f 54 20 20 20 20 20 20 28 48  LE_NSLOT      (H
56c0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 2a 32  ASHTABLE_NPAGE*2
56d0: 29 20 20 2f 2a 20 4d 75 73 74 20 62 65 20 61 20  )  /* Must be a 
56e0: 70 6f 77 65 72 20 6f 66 20 32 20 2a 2f 0a 0a 2f  power of 2 */../
56f0: 2a 20 0a 2a 2a 20 54 68 65 20 62 6c 6f 63 6b 20  * .** The block 
5700: 6f 66 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20  of page numbers 
5710: 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20  associated with 
5720: 74 68 65 20 66 69 72 73 74 20 68 61 73 68 2d 74  the first hash-t
5730: 61 62 6c 65 20 69 6e 20 61 0a 2a 2a 20 77 61 6c  able in a.** wal
5740: 2d 69 6e 64 65 78 20 69 73 20 73 6d 61 6c 6c 65  -index is smalle
5750: 72 20 74 68 61 6e 20 75 73 75 61 6c 2e 20 54 68  r than usual. Th
5760: 69 73 20 69 73 20 73 6f 20 74 68 61 74 20 74 68  is is so that th
5770: 65 72 65 20 69 73 20 61 20 63 6f 6d 70 6c 65 74  ere is a complet
5780: 65 0a 2a 2a 20 68 61 73 68 2d 74 61 62 6c 65 20  e.** hash-table 
5790: 6f 6e 20 65 61 63 68 20 61 6c 69 67 6e 65 64 20  on each aligned 
57a0: 33 32 4b 42 20 70 61 67 65 20 6f 66 20 74 68 65  32KB page of the
57b0: 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 23   wal-index..*/.#
57c0: 64 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45  define HASHTABLE
57d0: 5f 4e 50 41 47 45 5f 4f 4e 45 20 20 28 48 41 53  _NPAGE_ONE  (HAS
57e0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 2d 20 28  HTABLE_NPAGE - (
57f0: 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a  WALINDEX_HDR_SIZ
5800: 45 2f 73 69 7a 65 6f 66 28 75 33 32 29 29 29 0a  E/sizeof(u32))).
5810: 0a 2f 2a 20 54 68 65 20 77 61 6c 2d 69 6e 64 65  ./* The wal-inde
5820: 78 20 69 73 20 64 69 76 69 64 65 64 20 69 6e 74  x is divided int
5830: 6f 20 70 61 67 65 73 20 6f 66 20 57 41 4c 49 4e  o pages of WALIN
5840: 44 45 58 5f 50 47 53 5a 20 62 79 74 65 73 20 65  DEX_PGSZ bytes e
5850: 61 63 68 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20  ach. */.#define 
5860: 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a 20 20 20  WALINDEX_PGSZ   
5870: 28 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (               
5880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5890: 20 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20            \.    
58a0: 73 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 2a  sizeof(ht_slot)*
58b0: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20  HASHTABLE_NSLOT 
58c0: 2b 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  + HASHTABLE_NPAG
58d0: 45 2a 73 69 7a 65 6f 66 28 75 33 32 29 20 5c 0a  E*sizeof(u32) \.
58e0: 29 0a 0a 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20  )../*.** Obtain 
58f0: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65  a pointer to the
5900: 20 69 50 61 67 65 27 74 68 20 70 61 67 65 20 6f   iPage'th page o
5910: 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e  f the wal-index.
5920: 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 2a   The wal-index.*
5930: 2a 20 69 73 20 62 72 6f 6b 65 6e 20 69 6e 74 6f  * is broken into
5940: 20 70 61 67 65 73 20 6f 66 20 57 41 4c 49 4e 44   pages of WALIND
5950: 45 58 5f 50 47 53 5a 20 62 79 74 65 73 2e 20 57  EX_PGSZ bytes. W
5960: 61 6c 2d 69 6e 64 65 78 20 70 61 67 65 73 20 61  al-index pages a
5970: 72 65 0a 2a 2a 20 6e 75 6d 62 65 72 65 64 20 66  re.** numbered f
5980: 72 6f 6d 20 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20  rom zero..**.** 
5990: 49 66 20 74 68 69 73 20 63 61 6c 6c 20 69 73 20  If this call is 
59a0: 73 75 63 63 65 73 73 66 75 6c 2c 20 2a 70 70 50  successful, *ppP
59b0: 61 67 65 20 69 73 20 73 65 74 20 74 6f 20 70 6f  age is set to po
59c0: 69 6e 74 20 74 6f 20 74 68 65 20 77 61 6c 2d 69  int to the wal-i
59d0: 6e 64 65 78 0a 2a 2a 20 70 61 67 65 20 61 6e 64  ndex.** page and
59e0: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65   SQLITE_OK is re
59f0: 74 75 72 6e 65 64 2e 20 49 66 20 61 6e 20 65 72  turned. If an er
5a00: 72 6f 72 20 28 61 6e 20 4f 4f 4d 20 6f 72 20 56  ror (an OOM or V
5a10: 46 53 20 65 72 72 6f 72 29 20 6f 63 63 75 72 73  FS error) occurs
5a20: 2c 0a 2a 2a 20 74 68 65 6e 20 61 6e 20 53 51 4c  ,.** then an SQL
5a30: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
5a40: 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 2a  s returned and *
5a50: 70 70 50 61 67 65 20 69 73 20 73 65 74 20 74 6f  ppPage is set to
5a60: 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e   0..*/.static in
5a70: 74 20 77 61 6c 49 6e 64 65 78 50 61 67 65 28 57  t walIndexPage(W
5a80: 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 69 50  al *pWal, int iP
5a90: 61 67 65 2c 20 76 6f 6c 61 74 69 6c 65 20 75 33  age, volatile u3
5aa0: 32 20 2a 2a 70 70 50 61 67 65 29 7b 0a 20 20 69  2 **ppPage){.  i
5ab0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
5ac0: 4b 3b 0a 0a 20 20 2f 2a 20 45 6e 6c 61 72 67 65  K;..  /* Enlarge
5ad0: 20 74 68 65 20 70 57 61 6c 2d 3e 61 70 57 69 44   the pWal->apWiD
5ae0: 61 74 61 5b 5d 20 61 72 72 61 79 20 69 66 20 72  ata[] array if r
5af0: 65 71 75 69 72 65 64 20 2a 2f 0a 20 20 69 66 28  equired */.  if(
5b00: 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3c 3d   pWal->nWiData<=
5b10: 69 50 61 67 65 20 29 7b 0a 20 20 20 20 69 6e 74  iPage ){.    int
5b20: 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28   nByte = sizeof(
5b30: 75 33 32 2a 29 2a 28 69 50 61 67 65 2b 31 29 3b  u32*)*(iPage+1);
5b40: 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33  .    volatile u3
5b50: 32 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 20 20 61  2 **apNew;.    a
5b60: 70 4e 65 77 20 3d 20 28 76 6f 6c 61 74 69 6c 65  pNew = (volatile
5b70: 20 75 33 32 20 2a 2a 29 73 71 6c 69 74 65 33 5f   u32 **)sqlite3_
5b80: 72 65 61 6c 6c 6f 63 28 28 76 6f 69 64 20 2a 29  realloc((void *)
5b90: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 2c 20  pWal->apWiData, 
5ba0: 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20  nByte);.    if( 
5bb0: 21 61 70 4e 65 77 20 29 7b 0a 20 20 20 20 20 20  !apNew ){.      
5bc0: 2a 70 70 50 61 67 65 20 3d 20 30 3b 0a 20 20 20  *ppPage = 0;.   
5bd0: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
5be0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20  _NOMEM;.    }.  
5bf0: 20 20 6d 65 6d 73 65 74 28 28 76 6f 69 64 2a 29    memset((void*)
5c00: 26 61 70 4e 65 77 5b 70 57 61 6c 2d 3e 6e 57 69  &apNew[pWal->nWi
5c10: 44 61 74 61 5d 2c 20 30 2c 0a 20 20 20 20 20 20  Data], 0,.      
5c20: 20 20 20 20 20 73 69 7a 65 6f 66 28 75 33 32 2a       sizeof(u32*
5c30: 29 2a 28 69 50 61 67 65 2b 31 2d 70 57 61 6c 2d  )*(iPage+1-pWal-
5c40: 3e 6e 57 69 44 61 74 61 29 29 3b 0a 20 20 20 20  >nWiData));.    
5c50: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 20 3d  pWal->apWiData =
5c60: 20 61 70 4e 65 77 3b 0a 20 20 20 20 70 57 61 6c   apNew;.    pWal
5c70: 2d 3e 6e 57 69 44 61 74 61 20 3d 20 69 50 61 67  ->nWiData = iPag
5c80: 65 2b 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52  e+1;.  }..  /* R
5c90: 65 71 75 65 73 74 20 61 20 70 6f 69 6e 74 65 72  equest a pointer
5ca0: 20 74 6f 20 74 68 65 20 72 65 71 75 69 72 65 64   to the required
5cb0: 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20 56   page from the V
5cc0: 46 53 20 2a 2f 0a 20 20 69 66 28 20 70 57 61 6c  FS */.  if( pWal
5cd0: 2d 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67 65  ->apWiData[iPage
5ce0: 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d  ]==0 ){.    rc =
5cf0: 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 4d 61 70   sqlite3OsShmMap
5d00: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 50  (pWal->pDbFd, iP
5d10: 61 67 65 2c 20 57 41 4c 49 4e 44 45 58 5f 50 47  age, WALINDEX_PG
5d20: 53 5a 2c 20 0a 20 20 20 20 20 20 20 20 70 57 61  SZ, .        pWa
5d30: 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 2c 20 28 76  l->writeLock, (v
5d40: 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a 2a 29  oid volatile **)
5d50: 26 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b  &pWal->apWiData[
5d60: 69 50 61 67 65 5d 0a 20 20 20 20 29 3b 0a 20 20  iPage].    );.  
5d70: 7d 0a 0a 20 20 2a 70 70 50 61 67 65 20 3d 20 70  }..  *ppPage = p
5d80: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50  Wal->apWiData[iP
5d90: 61 67 65 5d 3b 0a 20 20 61 73 73 65 72 74 28 20  age];.  assert( 
5da0: 69 50 61 67 65 3d 3d 30 20 7c 7c 20 2a 70 70 50  iPage==0 || *ppP
5db0: 61 67 65 20 7c 7c 20 72 63 21 3d 53 51 4c 49 54  age || rc!=SQLIT
5dc0: 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74 75 72 6e  E_OK );.  return
5dd0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65   rc;.}../*.** Re
5de0: 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
5df0: 6f 20 74 68 65 20 57 61 6c 43 6b 70 74 49 6e 66  o the WalCkptInf
5e00: 6f 20 73 74 72 75 63 74 75 72 65 20 69 6e 20 74  o structure in t
5e10: 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f  he wal-index..*/
5e20: 0a 73 74 61 74 69 63 20 76 6f 6c 61 74 69 6c 65  .static volatile
5e30: 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 77 61   WalCkptInfo *wa
5e40: 6c 43 6b 70 74 49 6e 66 6f 28 57 61 6c 20 2a 70  lCkptInfo(Wal *p
5e50: 57 61 6c 29 7b 0a 20 20 61 73 73 65 72 74 28 20  Wal){.  assert( 
5e60: 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20  pWal->nWiData>0 
5e70: 26 26 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  && pWal->apWiDat
5e80: 61 5b 30 5d 20 29 3b 0a 20 20 72 65 74 75 72 6e  a[0] );.  return
5e90: 20 28 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b   (volatile WalCk
5ea0: 70 74 49 6e 66 6f 2a 29 26 28 70 57 61 6c 2d 3e  ptInfo*)&(pWal->
5eb0: 61 70 57 69 44 61 74 61 5b 30 5d 5b 73 69 7a 65  apWiData[0][size
5ec0: 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 2f  of(WalIndexHdr)/
5ed0: 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  2]);.}../*.** Re
5ee0: 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
5ef0: 6f 20 74 68 65 20 57 61 6c 49 6e 64 65 78 48 64  o the WalIndexHd
5f00: 72 20 73 74 72 75 63 74 75 72 65 20 69 6e 20 74  r structure in t
5f10: 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f  he wal-index..*/
5f20: 0a 73 74 61 74 69 63 20 76 6f 6c 61 74 69 6c 65  .static volatile
5f30: 20 57 61 6c 49 6e 64 65 78 48 64 72 20 2a 77 61   WalIndexHdr *wa
5f40: 6c 49 6e 64 65 78 48 64 72 28 57 61 6c 20 2a 70  lIndexHdr(Wal *p
5f50: 57 61 6c 29 7b 0a 20 20 61 73 73 65 72 74 28 20  Wal){.  assert( 
5f60: 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20  pWal->nWiData>0 
5f70: 26 26 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  && pWal->apWiDat
5f80: 61 5b 30 5d 20 29 3b 0a 20 20 72 65 74 75 72 6e  a[0] );.  return
5f90: 20 28 76 6f 6c 61 74 69 6c 65 20 57 61 6c 49 6e   (volatile WalIn
5fa0: 64 65 78 48 64 72 2a 29 70 57 61 6c 2d 3e 61 70  dexHdr*)pWal->ap
5fb0: 57 69 44 61 74 61 5b 30 5d 3b 0a 7d 0a 0a 2f 2a  WiData[0];.}../*
5fc0: 0a 2a 2a 20 54 68 65 20 61 72 67 75 6d 65 6e 74  .** The argument
5fd0: 20 74 6f 20 74 68 69 73 20 6d 61 63 72 6f 20 6d   to this macro m
5fe0: 75 73 74 20 62 65 20 6f 66 20 74 79 70 65 20 75  ust be of type u
5ff0: 33 32 2e 20 4f 6e 20 61 20 6c 69 74 74 6c 65 2d  32. On a little-
6000: 65 6e 64 69 61 6e 0a 2a 2a 20 61 72 63 68 69 74  endian.** archit
6010: 65 63 74 75 72 65 2c 20 69 74 20 72 65 74 75 72  ecture, it retur
6020: 6e 73 20 74 68 65 20 75 33 32 20 76 61 6c 75 65  ns the u32 value
6030: 20 74 68 61 74 20 72 65 73 75 6c 74 73 20 66 72   that results fr
6040: 6f 6d 20 69 6e 74 65 72 70 72 65 74 69 6e 67 0a  om interpreting.
6050: 2a 2a 20 74 68 65 20 34 20 62 79 74 65 73 20 61  ** the 4 bytes a
6060: 73 20 61 20 62 69 67 2d 65 6e 64 69 61 6e 20 76  s a big-endian v
6070: 61 6c 75 65 2e 20 4f 6e 20 61 20 62 69 67 2d 65  alue. On a big-e
6080: 6e 64 69 61 6e 20 61 72 63 68 69 74 65 63 74 75  ndian architectu
6090: 72 65 2c 20 69 74 0a 2a 2a 20 72 65 74 75 72 6e  re, it.** return
60a0: 73 20 74 68 65 20 76 61 6c 75 65 20 74 68 61 74  s the value that
60b0: 20 77 6f 75 6c 64 20 62 65 20 70 72 6f 64 75 63   would be produc
60c0: 65 64 20 62 79 20 69 6e 74 65 70 72 65 74 69 6e  ed by intepretin
60d0: 67 20 74 68 65 20 34 20 62 79 74 65 73 0a 2a 2a  g the 4 bytes.**
60e0: 20 6f 66 20 74 68 65 20 69 6e 70 75 74 20 76 61   of the input va
60f0: 6c 75 65 20 61 73 20 61 20 6c 69 74 74 6c 65 2d  lue as a little-
6100: 65 6e 64 69 61 6e 20 69 6e 74 65 67 65 72 2e 0a  endian integer..
6110: 2a 2f 0a 23 64 65 66 69 6e 65 20 42 59 54 45 53  */.#define BYTES
6120: 57 41 50 33 32 28 78 29 20 28 20 5c 0a 20 20 20  WAP32(x) ( \.   
6130: 20 28 28 28 78 29 26 30 78 30 30 30 30 30 30 46   (((x)&0x000000F
6140: 46 29 3c 3c 32 34 29 20 2b 20 28 28 28 78 29 26  F)<<24) + (((x)&
6150: 30 78 30 30 30 30 46 46 30 30 29 3c 3c 38 29 20  0x0000FF00)<<8) 
6160: 20 5c 0a 20 20 2b 20 28 28 28 78 29 26 30 78 30   \.  + (((x)&0x0
6170: 30 46 46 30 30 30 30 29 3e 3e 38 29 20 20 2b 20  0FF0000)>>8)  + 
6180: 28 28 28 78 29 26 30 78 46 46 30 30 30 30 30 30  (((x)&0xFF000000
6190: 29 3e 3e 32 34 29 20 5c 0a 29 0a 0a 2f 2a 0a 2a  )>>24) \.)../*.*
61a0: 2a 20 47 65 6e 65 72 61 74 65 20 6f 72 20 65 78  * Generate or ex
61b0: 74 65 6e 64 20 61 6e 20 38 20 62 79 74 65 20 63  tend an 8 byte c
61c0: 68 65 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e  hecksum based on
61d0: 20 74 68 65 20 64 61 74 61 20 69 6e 20 0a 2a 2a   the data in .**
61e0: 20 61 72 72 61 79 20 61 42 79 74 65 5b 5d 20 61   array aByte[] a
61f0: 6e 64 20 74 68 65 20 69 6e 69 74 69 61 6c 20 76  nd the initial v
6200: 61 6c 75 65 73 20 6f 66 20 61 49 6e 5b 30 5d 20  alues of aIn[0] 
6210: 61 6e 64 20 61 49 6e 5b 31 5d 20 28 6f 72 0a 2a  and aIn[1] (or.*
6220: 2a 20 69 6e 69 74 69 61 6c 20 76 61 6c 75 65 73  * initial values
6230: 20 6f 66 20 30 20 61 6e 64 20 30 20 69 66 20 61   of 0 and 0 if a
6240: 49 6e 3d 3d 4e 55 4c 4c 29 2e 0a 2a 2a 0a 2a 2a  In==NULL)..**.**
6250: 20 54 68 65 20 63 68 65 63 6b 73 75 6d 20 69 73   The checksum is
6260: 20 77 72 69 74 74 65 6e 20 62 61 63 6b 20 69 6e   written back in
6270: 74 6f 20 61 4f 75 74 5b 5d 20 62 65 66 6f 72 65  to aOut[] before
6280: 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2a 0a 2a   returning..**.*
6290: 2a 20 6e 42 79 74 65 20 6d 75 73 74 20 62 65 20  * nByte must be 
62a0: 61 20 70 6f 73 69 74 69 76 65 20 6d 75 6c 74 69  a positive multi
62b0: 70 6c 65 20 6f 66 20 38 2e 0a 2a 2f 0a 73 74 61  ple of 8..*/.sta
62c0: 74 69 63 20 76 6f 69 64 20 77 61 6c 43 68 65 63  tic void walChec
62d0: 6b 73 75 6d 42 79 74 65 73 28 0a 20 20 69 6e 74  ksumBytes(.  int
62e0: 20 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 2f 2a   nativeCksum, /*
62f0: 20 54 72 75 65 20 66 6f 72 20 6e 61 74 69 76 65   True for native
6300: 20 62 79 74 65 2d 6f 72 64 65 72 2c 20 66 61 6c   byte-order, fal
6310: 73 65 20 66 6f 72 20 6e 6f 6e 2d 6e 61 74 69 76  se for non-nativ
6320: 65 20 2a 2f 0a 20 20 75 38 20 2a 61 2c 20 20 20  e */.  u8 *a,   
6330: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65          /* Conte
6340: 6e 74 20 74 6f 20 62 65 20 63 68 65 63 6b 73 75  nt to be checksu
6350: 6d 6d 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  mmed */.  int nB
6360: 79 74 65 2c 20 20 20 20 20 20 20 2f 2a 20 42 79  yte,       /* By
6370: 74 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74 20 69  tes of content i
6380: 6e 20 61 5b 5d 2e 20 20 4d 75 73 74 20 62 65 20  n a[].  Must be 
6390: 61 20 6d 75 6c 74 69 70 6c 65 20 6f 66 20 38 2e  a multiple of 8.
63a0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 75 33 32 20   */.  const u32 
63b0: 2a 61 49 6e 2c 20 20 2f 2a 20 49 6e 69 74 69 61  *aIn,  /* Initia
63c0: 6c 20 63 68 65 63 6b 73 75 6d 20 76 61 6c 75 65  l checksum value
63d0: 20 69 6e 70 75 74 20 2a 2f 0a 20 20 75 33 32 20   input */.  u32 
63e0: 2a 61 4f 75 74 20 20 20 20 20 20 20 20 2f 2a 20  *aOut        /* 
63f0: 4f 55 54 3a 20 46 69 6e 61 6c 20 63 68 65 63 6b  OUT: Final check
6400: 73 75 6d 20 76 61 6c 75 65 20 6f 75 74 70 75 74  sum value output
6410: 20 2a 2f 0a 29 7b 0a 20 20 75 33 32 20 73 31 2c   */.){.  u32 s1,
6420: 20 73 32 3b 0a 20 20 75 33 32 20 2a 61 44 61 74   s2;.  u32 *aDat
6430: 61 20 3d 20 28 75 33 32 20 2a 29 61 3b 0a 20 20  a = (u32 *)a;.  
6440: 75 33 32 20 2a 61 45 6e 64 20 3d 20 28 75 33 32  u32 *aEnd = (u32
6450: 20 2a 29 26 61 5b 6e 42 79 74 65 5d 3b 0a 0a 20   *)&a[nByte];.. 
6460: 20 69 66 28 20 61 49 6e 20 29 7b 0a 20 20 20 20   if( aIn ){.    
6470: 73 31 20 3d 20 61 49 6e 5b 30 5d 3b 0a 20 20 20  s1 = aIn[0];.   
6480: 20 73 32 20 3d 20 61 49 6e 5b 31 5d 3b 0a 20 20   s2 = aIn[1];.  
6490: 7d 65 6c 73 65 7b 0a 20 20 20 20 73 31 20 3d 20  }else{.    s1 = 
64a0: 73 32 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 61  s2 = 0;.  }..  a
64b0: 73 73 65 72 74 28 20 6e 42 79 74 65 3e 3d 38 20  ssert( nByte>=8 
64c0: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 28 6e 42  );.  assert( (nB
64d0: 79 74 65 26 30 78 30 30 30 30 30 30 30 37 29 3d  yte&0x00000007)=
64e0: 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 6e 61 74  =0 );..  if( nat
64f0: 69 76 65 43 6b 73 75 6d 20 29 7b 0a 20 20 20 20  iveCksum ){.    
6500: 64 6f 20 7b 0a 20 20 20 20 20 20 73 31 20 2b 3d  do {.      s1 +=
6510: 20 2a 61 44 61 74 61 2b 2b 20 2b 20 73 32 3b 0a   *aData++ + s2;.
6520: 20 20 20 20 20 20 73 32 20 2b 3d 20 2a 61 44 61        s2 += *aDa
6530: 74 61 2b 2b 20 2b 20 73 31 3b 0a 20 20 20 20 7d  ta++ + s1;.    }
6540: 77 68 69 6c 65 28 20 61 44 61 74 61 3c 61 45 6e  while( aData<aEn
6550: 64 20 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  d );.  }else{.  
6560: 20 20 64 6f 20 7b 0a 20 20 20 20 20 20 73 31 20    do {.      s1 
6570: 2b 3d 20 42 59 54 45 53 57 41 50 33 32 28 61 44  += BYTESWAP32(aD
6580: 61 74 61 5b 30 5d 29 20 2b 20 73 32 3b 0a 20 20  ata[0]) + s2;.  
6590: 20 20 20 20 73 32 20 2b 3d 20 42 59 54 45 53 57      s2 += BYTESW
65a0: 41 50 33 32 28 61 44 61 74 61 5b 31 5d 29 20 2b  AP32(aData[1]) +
65b0: 20 73 31 3b 0a 20 20 20 20 20 20 61 44 61 74 61   s1;.      aData
65c0: 20 2b 3d 20 32 3b 0a 20 20 20 20 7d 77 68 69 6c   += 2;.    }whil
65d0: 65 28 20 61 44 61 74 61 3c 61 45 6e 64 20 29 3b  e( aData<aEnd );
65e0: 0a 20 20 7d 0a 0a 20 20 61 4f 75 74 5b 30 5d 20  .  }..  aOut[0] 
65f0: 3d 20 73 31 3b 0a 20 20 61 4f 75 74 5b 31 5d 20  = s1;.  aOut[1] 
6600: 3d 20 73 32 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  = s2;.}../*.** W
6610: 72 69 74 65 20 74 68 65 20 68 65 61 64 65 72 20  rite the header 
6620: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e 20 70  information in p
6630: 57 61 6c 2d 3e 68 64 72 20 69 6e 74 6f 20 74 68  Wal->hdr into th
6640: 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2a 0a  e wal-index..**.
6650: 2a 2a 20 54 68 65 20 63 68 65 63 6b 73 75 6d 20  ** The checksum 
6660: 6f 6e 20 70 57 61 6c 2d 3e 68 64 72 20 69 73 20  on pWal->hdr is 
6670: 75 70 64 61 74 65 64 20 62 65 66 6f 72 65 20 69  updated before i
6680: 74 20 69 73 20 77 72 69 74 74 65 6e 2e 0a 2a 2f  t is written..*/
6690: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
66a0: 49 6e 64 65 78 57 72 69 74 65 48 64 72 28 57 61  IndexWriteHdr(Wa
66b0: 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 76 6f 6c 61  l *pWal){.  vola
66c0: 74 69 6c 65 20 57 61 6c 49 6e 64 65 78 48 64 72  tile WalIndexHdr
66d0: 20 2a 61 48 64 72 20 3d 20 77 61 6c 49 6e 64 65   *aHdr = walInde
66e0: 78 48 64 72 28 70 57 61 6c 29 3b 0a 20 20 63 6f  xHdr(pWal);.  co
66f0: 6e 73 74 20 69 6e 74 20 6e 43 6b 73 75 6d 20 3d  nst int nCksum =
6700: 20 6f 66 66 73 65 74 6f 66 28 57 61 6c 49 6e 64   offsetof(WalInd
6710: 65 78 48 64 72 2c 20 61 43 6b 73 75 6d 29 3b 0a  exHdr, aCksum);.
6720: 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
6730: 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20  >writeLock );.  
6740: 70 57 61 6c 2d 3e 68 64 72 2e 69 73 49 6e 69 74  pWal->hdr.isInit
6750: 20 3d 20 31 3b 0a 20 20 70 57 61 6c 2d 3e 68 64   = 1;.  pWal->hd
6760: 72 2e 69 56 65 72 73 69 6f 6e 20 3d 20 57 41 4c  r.iVersion = WAL
6770: 49 4e 44 45 58 5f 4d 41 58 5f 56 45 52 53 49 4f  INDEX_MAX_VERSIO
6780: 4e 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d  N;.  walChecksum
6790: 42 79 74 65 73 28 31 2c 20 28 75 38 2a 29 26 70  Bytes(1, (u8*)&p
67a0: 57 61 6c 2d 3e 68 64 72 2c 20 6e 43 6b 73 75 6d  Wal->hdr, nCksum
67b0: 2c 20 30 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61  , 0, pWal->hdr.a
67c0: 43 6b 73 75 6d 29 3b 0a 20 20 6d 65 6d 63 70 79  Cksum);.  memcpy
67d0: 28 28 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 31  ((void *)&aHdr[1
67e0: 5d 2c 20 28 76 6f 69 64 20 2a 29 26 70 57 61 6c  ], (void *)&pWal
67f0: 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61  ->hdr, sizeof(Wa
6800: 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 73  lIndexHdr));.  s
6810: 71 6c 69 74 65 33 4f 73 53 68 6d 42 61 72 72 69  qlite3OsShmBarri
6820: 65 72 28 70 57 61 6c 2d 3e 70 44 62 46 64 29 3b  er(pWal->pDbFd);
6830: 0a 20 20 6d 65 6d 63 70 79 28 28 76 6f 69 64 20  .  memcpy((void 
6840: 2a 29 26 61 48 64 72 5b 30 5d 2c 20 28 76 6f 69  *)&aHdr[0], (voi
6850: 64 20 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c 20  d *)&pWal->hdr, 
6860: 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48  sizeof(WalIndexH
6870: 64 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  dr));.}../*.** T
6880: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 65 6e 63  his function enc
6890: 6f 64 65 73 20 61 20 73 69 6e 67 6c 65 20 66 72  odes a single fr
68a0: 61 6d 65 20 68 65 61 64 65 72 20 61 6e 64 20 77  ame header and w
68b0: 72 69 74 65 73 20 69 74 20 74 6f 20 61 20 62 75  rites it to a bu
68c0: 66 66 65 72 0a 2a 2a 20 73 75 70 70 6c 69 65 64  ffer.** supplied
68d0: 20 62 79 20 74 68 65 20 63 61 6c 6c 65 72 2e 20   by the caller. 
68e0: 41 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20 69  A frame-header i
68f0: 73 20 6d 61 64 65 20 75 70 20 6f 66 20 61 20 73  s made up of a s
6900: 65 72 69 65 73 20 6f 66 20 0a 2a 2a 20 34 2d 62  eries of .** 4-b
6910: 79 74 65 20 62 69 67 2d 65 6e 64 69 61 6e 20 69  yte big-endian i
6920: 6e 74 65 67 65 72 73 2c 20 61 73 20 66 6f 6c 6c  ntegers, as foll
6930: 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 30  ows:.**.**     0
6940: 3a 20 50 61 67 65 20 6e 75 6d 62 65 72 2e 0a 2a  : Page number..*
6950: 2a 20 20 20 20 20 34 3a 20 46 6f 72 20 63 6f 6d  *     4: For com
6960: 6d 69 74 20 72 65 63 6f 72 64 73 2c 20 74 68 65  mit records, the
6970: 20 73 69 7a 65 20 6f 66 20 74 68 65 20 64 61 74   size of the dat
6980: 61 62 61 73 65 20 69 6d 61 67 65 20 69 6e 20 70  abase image in p
6990: 61 67 65 73 20 0a 2a 2a 20 20 20 20 20 20 20 20  ages .**        
69a0: 61 66 74 65 72 20 74 68 65 20 63 6f 6d 6d 69 74  after the commit
69b0: 2e 20 46 6f 72 20 61 6c 6c 20 6f 74 68 65 72 20  . For all other 
69c0: 72 65 63 6f 72 64 73 2c 20 7a 65 72 6f 2e 0a 2a  records, zero..*
69d0: 2a 20 20 20 20 20 38 3a 20 53 61 6c 74 2d 31 20  *     8: Salt-1 
69e0: 28 63 6f 70 69 65 64 20 66 72 6f 6d 20 74 68 65  (copied from the
69f0: 20 77 61 6c 2d 68 65 61 64 65 72 29 0a 2a 2a 20   wal-header).** 
6a00: 20 20 20 31 32 3a 20 53 61 6c 74 2d 32 20 28 63     12: Salt-2 (c
6a10: 6f 70 69 65 64 20 66 72 6f 6d 20 74 68 65 20 77  opied from the w
6a20: 61 6c 2d 68 65 61 64 65 72 29 0a 2a 2a 20 20 20  al-header).**   
6a30: 20 31 36 3a 20 43 68 65 63 6b 73 75 6d 2d 31 2e   16: Checksum-1.
6a40: 0a 2a 2a 20 20 20 20 32 30 3a 20 43 68 65 63 6b  .**    20: Check
6a50: 73 75 6d 2d 32 2e 0a 2a 2f 0a 73 74 61 74 69 63  sum-2..*/.static
6a60: 20 76 6f 69 64 20 77 61 6c 45 6e 63 6f 64 65 46   void walEncodeF
6a70: 72 61 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57 61  rame(.  Wal *pWa
6a80: 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
6a90: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 77          /* The w
6aa0: 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 2a  rite-ahead log *
6ab0: 2f 0a 20 20 75 33 32 20 69 50 61 67 65 2c 20 20  /.  u32 iPage,  
6ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ad0: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
6ae0: 70 61 67 65 20 6e 75 6d 62 65 72 20 66 6f 72 20  page number for 
6af0: 66 72 61 6d 65 20 2a 2f 0a 20 20 75 33 32 20 6e  frame */.  u32 n
6b00: 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20  Truncate,       
6b10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65             /* Ne
6b20: 77 20 64 62 20 73 69 7a 65 20 28 6f 72 20 30 20  w db size (or 0 
6b30: 66 6f 72 20 6e 6f 6e 2d 63 6f 6d 6d 69 74 20 66  for non-commit f
6b40: 72 61 6d 65 73 29 20 2a 2f 0a 20 20 75 38 20 2a  rames) */.  u8 *
6b50: 61 44 61 74 61 2c 20 20 20 20 20 20 20 20 20 20  aData,          
6b60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50              /* P
6b70: 6f 69 6e 74 65 72 20 74 6f 20 70 61 67 65 20 64  ointer to page d
6b80: 61 74 61 20 2a 2f 0a 20 20 75 38 20 2a 61 46 72  ata */.  u8 *aFr
6b90: 61 6d 65 20 20 20 20 20 20 20 20 20 20 20 20 20  ame             
6ba0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
6bb0: 20 57 72 69 74 65 20 65 6e 63 6f 64 65 64 20 66   Write encoded f
6bc0: 72 61 6d 65 20 68 65 72 65 20 2a 2f 0a 29 7b 0a  rame here */.){.
6bd0: 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73 75    int nativeCksu
6be0: 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  m;              
6bf0: 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e 61    /* True for na
6c00: 74 69 76 65 20 62 79 74 65 2d 6f 72 64 65 72 20  tive byte-order 
6c10: 63 68 65 63 6b 73 75 6d 73 20 2a 2f 0a 20 20 75  checksums */.  u
6c20: 33 32 20 2a 61 43 6b 73 75 6d 20 3d 20 70 57 61  32 *aCksum = pWa
6c30: 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
6c40: 75 6d 3b 0a 20 20 61 73 73 65 72 74 28 20 57 41  um;.  assert( WA
6c50: 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3d  L_FRAME_HDRSIZE=
6c60: 3d 32 34 20 29 3b 0a 20 20 73 71 6c 69 74 65 33  =24 );.  sqlite3
6c70: 50 75 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Put4byte(&aFrame
6c80: 5b 30 5d 2c 20 69 50 61 67 65 29 3b 0a 20 20 73  [0], iPage);.  s
6c90: 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
6ca0: 61 46 72 61 6d 65 5b 34 5d 2c 20 6e 54 72 75 6e  aFrame[4], nTrun
6cb0: 63 61 74 65 29 3b 0a 20 20 6d 65 6d 63 70 79 28  cate);.  memcpy(
6cc0: 26 61 46 72 61 6d 65 5b 38 5d 2c 20 70 57 61 6c  &aFrame[8], pWal
6cd0: 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 38 29 3b  ->hdr.aSalt, 8);
6ce0: 0a 0a 20 20 6e 61 74 69 76 65 43 6b 73 75 6d 20  ..  nativeCksum 
6cf0: 3d 20 28 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67  = (pWal->hdr.big
6d00: 45 6e 64 43 6b 73 75 6d 3d 3d 53 51 4c 49 54 45  EndCksum==SQLITE
6d10: 5f 42 49 47 45 4e 44 49 41 4e 29 3b 0a 20 20 77  _BIGENDIAN);.  w
6d20: 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
6d30: 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 61 46 72  nativeCksum, aFr
6d40: 61 6d 65 2c 20 38 2c 20 61 43 6b 73 75 6d 2c 20  ame, 8, aCksum, 
6d50: 61 43 6b 73 75 6d 29 3b 0a 20 20 77 61 6c 43 68  aCksum);.  walCh
6d60: 65 63 6b 73 75 6d 42 79 74 65 73 28 6e 61 74 69  ecksumBytes(nati
6d70: 76 65 43 6b 73 75 6d 2c 20 61 44 61 74 61 2c 20  veCksum, aData, 
6d80: 70 57 61 6c 2d 3e 73 7a 50 61 67 65 2c 20 61 43  pWal->szPage, aC
6d90: 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a 0a  ksum, aCksum);..
6da0: 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74    sqlite3Put4byt
6db0: 65 28 26 61 46 72 61 6d 65 5b 31 36 5d 2c 20 61  e(&aFrame[16], a
6dc0: 43 6b 73 75 6d 5b 30 5d 29 3b 0a 20 20 73 71 6c  Cksum[0]);.  sql
6dd0: 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 46  ite3Put4byte(&aF
6de0: 72 61 6d 65 5b 32 30 5d 2c 20 61 43 6b 73 75 6d  rame[20], aCksum
6df0: 5b 31 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  [1]);.}../*.** C
6e00: 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20 74  heck to see if t
6e10: 68 65 20 66 72 61 6d 65 20 77 69 74 68 20 68 65  he frame with he
6e20: 61 64 65 72 20 69 6e 20 61 46 72 61 6d 65 5b 5d  ader in aFrame[]
6e30: 20 61 6e 64 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20   and content.** 
6e40: 69 6e 20 61 44 61 74 61 5b 5d 20 69 73 20 76 61  in aData[] is va
6e50: 6c 69 64 2e 20 20 49 66 20 69 74 20 69 73 20 61  lid.  If it is a
6e60: 20 76 61 6c 69 64 20 66 72 61 6d 65 2c 20 66 69   valid frame, fi
6e70: 6c 6c 20 2a 70 69 50 61 67 65 20 61 6e 64 0a 2a  ll *piPage and.*
6e80: 2a 20 2a 70 6e 54 72 75 6e 63 61 74 65 20 61 6e  * *pnTruncate an
6e90: 64 20 72 65 74 75 72 6e 20 74 72 75 65 2e 20 20  d return true.  
6ea0: 52 65 74 75 72 6e 20 69 66 20 74 68 65 20 66 72  Return if the fr
6eb0: 61 6d 65 20 69 73 20 6e 6f 74 20 76 61 6c 69 64  ame is not valid
6ec0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
6ed0: 77 61 6c 44 65 63 6f 64 65 46 72 61 6d 65 28 0a  walDecodeFrame(.
6ee0: 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
6ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6f00: 20 20 2f 2a 20 54 68 65 20 77 72 69 74 65 2d 61    /* The write-a
6f10: 68 65 61 64 20 6c 6f 67 20 2a 2f 0a 20 20 75 33  head log */.  u3
6f20: 32 20 2a 70 69 50 61 67 65 2c 20 20 20 20 20 20  2 *piPage,      
6f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6f40: 20 4f 55 54 3a 20 44 61 74 61 62 61 73 65 20 70   OUT: Database p
6f50: 61 67 65 20 6e 75 6d 62 65 72 20 66 6f 72 20 66  age number for f
6f60: 72 61 6d 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70  rame */.  u32 *p
6f70: 6e 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20  nTruncate,      
6f80: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
6f90: 3a 20 4e 65 77 20 64 62 20 73 69 7a 65 20 28 6f  : New db size (o
6fa0: 72 20 30 20 69 66 20 6e 6f 74 20 63 6f 6d 6d 69  r 0 if not commi
6fb0: 74 29 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74  t) */.  u8 *aDat
6fc0: 61 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  a,              
6fd0: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
6fe0: 65 72 20 74 6f 20 70 61 67 65 20 64 61 74 61 20  er to page data 
6ff0: 28 66 6f 72 20 63 68 65 63 6b 73 75 6d 29 20 2a  (for checksum) *
7000: 2f 0a 20 20 75 38 20 2a 61 46 72 61 6d 65 20 20  /.  u8 *aFrame  
7010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7020: 20 20 20 20 2f 2a 20 46 72 61 6d 65 20 64 61 74      /* Frame dat
7030: 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 61  a */.){.  int na
7040: 74 69 76 65 43 6b 73 75 6d 3b 20 20 20 20 20 20  tiveCksum;      
7050: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
7060: 65 20 66 6f 72 20 6e 61 74 69 76 65 20 62 79 74  e for native byt
7070: 65 2d 6f 72 64 65 72 20 63 68 65 63 6b 73 75 6d  e-order checksum
7080: 73 20 2a 2f 0a 20 20 75 33 32 20 2a 61 43 6b 73  s */.  u32 *aCks
7090: 75 6d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61  um = pWal->hdr.a
70a0: 46 72 61 6d 65 43 6b 73 75 6d 3b 0a 20 20 75 33  FrameCksum;.  u3
70b0: 32 20 70 67 6e 6f 3b 20 20 20 20 20 20 20 20 20  2 pgno;         
70c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
70d0: 20 50 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20   Page number of 
70e0: 74 68 65 20 66 72 61 6d 65 20 2a 2f 0a 20 20 61  the frame */.  a
70f0: 73 73 65 72 74 28 20 57 41 4c 5f 46 52 41 4d 45  ssert( WAL_FRAME
7100: 5f 48 44 52 53 49 5a 45 3d 3d 32 34 20 29 3b 0a  _HDRSIZE==24 );.
7110: 0a 20 20 2f 2a 20 41 20 66 72 61 6d 65 20 69 73  .  /* A frame is
7120: 20 6f 6e 6c 79 20 76 61 6c 69 64 20 69 66 20 74   only valid if t
7130: 68 65 20 73 61 6c 74 20 76 61 6c 75 65 73 20 69  he salt values i
7140: 6e 20 74 68 65 20 66 72 61 6d 65 2d 68 65 61 64  n the frame-head
7150: 65 72 0a 20 20 2a 2a 20 6d 61 74 63 68 20 74 68  er.  ** match th
7160: 65 20 73 61 6c 74 20 76 61 6c 75 65 73 20 69 6e  e salt values in
7170: 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72 2e   the wal-header.
7180: 20 0a 20 20 2a 2f 0a 20 20 69 66 28 20 6d 65 6d   .  */.  if( mem
7190: 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72 2e 61  cmp(&pWal->hdr.a
71a0: 53 61 6c 74 2c 20 26 61 46 72 61 6d 65 5b 38 5d  Salt, &aFrame[8]
71b0: 2c 20 38 29 21 3d 30 20 29 7b 0a 20 20 20 20 72  , 8)!=0 ){.    r
71c0: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20  eturn 0;.  }..  
71d0: 2f 2a 20 41 20 66 72 61 6d 65 20 69 73 20 6f 6e  /* A frame is on
71e0: 6c 79 20 76 61 6c 69 64 20 69 66 20 74 68 65 20  ly valid if the 
71f0: 70 61 67 65 20 6e 75 6d 62 65 72 20 69 73 20 63  page number is c
7200: 72 65 61 74 65 72 20 74 68 61 6e 20 7a 65 72 6f  reater than zero
7210: 2e 0a 20 20 2a 2f 0a 20 20 70 67 6e 6f 20 3d 20  ..  */.  pgno = 
7220: 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
7230: 26 61 46 72 61 6d 65 5b 30 5d 29 3b 0a 20 20 69  &aFrame[0]);.  i
7240: 66 28 20 70 67 6e 6f 3d 3d 30 20 29 7b 0a 20 20  f( pgno==0 ){.  
7250: 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a    return 0;.  }.
7260: 0a 20 20 2f 2a 20 41 20 66 72 61 6d 65 20 69 73  .  /* A frame is
7270: 20 6f 6e 6c 79 20 76 61 6c 69 64 20 69 66 20 61   only valid if a
7280: 20 63 68 65 63 6b 73 75 6d 20 6f 66 20 74 68 65   checksum of the
7290: 20 57 41 4c 20 68 65 61 64 65 72 2c 0a 20 20 2a   WAL header,.  *
72a0: 2a 20 61 6c 6c 20 70 72 69 6f 72 20 66 72 61 6d  * all prior fram
72b0: 73 2c 20 74 68 65 20 66 69 72 73 74 20 31 36 20  s, the first 16 
72c0: 62 79 74 65 73 20 6f 66 20 74 68 69 73 20 66 72  bytes of this fr
72d0: 61 6d 65 2d 68 65 61 64 65 72 2c 20 0a 20 20 2a  ame-header, .  *
72e0: 2a 20 61 6e 64 20 74 68 65 20 66 72 61 6d 65 2d  * and the frame-
72f0: 64 61 74 61 20 6d 61 74 63 68 65 73 20 74 68 65  data matches the
7300: 20 63 68 65 63 6b 73 75 6d 20 69 6e 20 74 68 65   checksum in the
7310: 20 6c 61 73 74 20 38 20 0a 20 20 2a 2a 20 62 79   last 8 .  ** by
7320: 74 65 73 20 6f 66 20 74 68 69 73 20 66 72 61 6d  tes of this fram
7330: 65 2d 68 65 61 64 65 72 2e 0a 20 20 2a 2f 0a 20  e-header..  */. 
7340: 20 6e 61 74 69 76 65 43 6b 73 75 6d 20 3d 20 28   nativeCksum = (
7350: 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64  pWal->hdr.bigEnd
7360: 43 6b 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49  Cksum==SQLITE_BI
7370: 47 45 4e 44 49 41 4e 29 3b 0a 20 20 77 61 6c 43  GENDIAN);.  walC
7380: 68 65 63 6b 73 75 6d 42 79 74 65 73 28 6e 61 74  hecksumBytes(nat
7390: 69 76 65 43 6b 73 75 6d 2c 20 61 46 72 61 6d 65  iveCksum, aFrame
73a0: 2c 20 38 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b  , 8, aCksum, aCk
73b0: 73 75 6d 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b  sum);.  walCheck
73c0: 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43  sumBytes(nativeC
73d0: 6b 73 75 6d 2c 20 61 44 61 74 61 2c 20 70 57 61  ksum, aData, pWa
73e0: 6c 2d 3e 73 7a 50 61 67 65 2c 20 61 43 6b 73 75  l->szPage, aCksu
73f0: 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a 20 20 69 66  m, aCksum);.  if
7400: 28 20 61 43 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c  ( aCksum[0]!=sql
7410: 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61 46  ite3Get4byte(&aF
7420: 72 61 6d 65 5b 31 36 5d 29 20 0a 20 20 20 7c 7c  rame[16]) .   ||
7430: 20 61 43 6b 73 75 6d 5b 31 5d 21 3d 73 71 6c 69   aCksum[1]!=sqli
7440: 74 65 33 47 65 74 34 62 79 74 65 28 26 61 46 72  te3Get4byte(&aFr
7450: 61 6d 65 5b 32 30 5d 29 20 0a 20 20 29 7b 0a 20  ame[20]) .  ){. 
7460: 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66     /* Checksum f
7470: 61 69 6c 65 64 2e 20 2a 2f 0a 20 20 20 20 72 65  ailed. */.    re
7480: 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f  turn 0;.  }..  /
7490: 2a 20 49 66 20 77 65 20 72 65 61 63 68 20 74 68  * If we reach th
74a0: 69 73 20 70 6f 69 6e 74 2c 20 74 68 65 20 66 72  is point, the fr
74b0: 61 6d 65 20 69 73 20 76 61 6c 69 64 2e 20 20 52  ame is valid.  R
74c0: 65 74 75 72 6e 20 74 68 65 20 70 61 67 65 20 6e  eturn the page n
74d0: 75 6d 62 65 72 0a 20 20 2a 2a 20 61 6e 64 20 74  umber.  ** and t
74e0: 68 65 20 6e 65 77 20 64 61 74 61 62 61 73 65 20  he new database 
74f0: 73 69 7a 65 2e 0a 20 20 2a 2f 0a 20 20 2a 70 69  size..  */.  *pi
7500: 50 61 67 65 20 3d 20 70 67 6e 6f 3b 0a 20 20 2a  Page = pgno;.  *
7510: 70 6e 54 72 75 6e 63 61 74 65 20 3d 20 73 71 6c  pnTruncate = sql
7520: 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61 46  ite3Get4byte(&aF
7530: 72 61 6d 65 5b 34 5d 29 3b 0a 20 20 72 65 74 75  rame[4]);.  retu
7540: 72 6e 20 31 3b 0a 7d 0a 0a 0a 23 69 66 20 64 65  rn 1;.}...#if de
7550: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54 45 53  fined(SQLITE_TES
7560: 54 29 20 26 26 20 64 65 66 69 6e 65 64 28 53 51  T) && defined(SQ
7570: 4c 49 54 45 5f 44 45 42 55 47 29 0a 2f 2a 0a 2a  LITE_DEBUG)./*.*
7580: 2a 20 4e 61 6d 65 73 20 6f 66 20 6c 6f 63 6b 73  * Names of locks
7590: 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  .  This routine 
75a0: 69 73 20 75 73 65 64 20 74 6f 20 70 72 6f 76 69  is used to provi
75b0: 64 65 20 64 65 62 75 67 67 69 6e 67 20 6f 75 74  de debugging out
75c0: 70 75 74 20 61 6e 64 20 69 73 20 6e 6f 74 0a 2a  put and is not.*
75d0: 2a 20 61 20 70 61 72 74 20 6f 66 20 61 6e 20 6f  * a part of an o
75e0: 72 64 69 6e 61 72 79 20 62 75 69 6c 64 2e 0a 2a  rdinary build..*
75f0: 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63  /.static const c
7600: 68 61 72 20 2a 77 61 6c 4c 6f 63 6b 4e 61 6d 65  har *walLockName
7610: 28 69 6e 74 20 6c 6f 63 6b 49 64 78 29 7b 0a 20  (int lockIdx){. 
7620: 20 69 66 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41   if( lockIdx==WA
7630: 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 29 7b 0a  L_WRITE_LOCK ){.
7640: 20 20 20 20 72 65 74 75 72 6e 20 22 57 52 49 54      return "WRIT
7650: 45 2d 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65  E-LOCK";.  }else
7660: 20 69 66 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41   if( lockIdx==WA
7670: 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 29 7b 0a 20  L_CKPT_LOCK ){. 
7680: 20 20 20 72 65 74 75 72 6e 20 22 43 4b 50 54 2d     return "CKPT-
7690: 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69  LOCK";.  }else i
76a0: 66 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f  f( lockIdx==WAL_
76b0: 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20 29 7b 0a  RECOVER_LOCK ){.
76c0: 20 20 20 20 72 65 74 75 72 6e 20 22 52 45 43 4f      return "RECO
76d0: 56 45 52 2d 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c  VER-LOCK";.  }el
76e0: 73 65 7b 0a 20 20 20 20 73 74 61 74 69 63 20 63  se{.    static c
76f0: 68 61 72 20 7a 4e 61 6d 65 5b 31 35 5d 3b 0a 20  har zName[15];. 
7700: 20 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69     sqlite3_snpri
7710: 6e 74 66 28 73 69 7a 65 6f 66 28 7a 4e 61 6d 65  ntf(sizeof(zName
7720: 29 2c 20 7a 4e 61 6d 65 2c 20 22 52 45 41 44 2d  ), zName, "READ-
7730: 4c 4f 43 4b 5b 25 64 5d 22 2c 0a 20 20 20 20 20  LOCK[%d]",.     
7740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7750: 6c 6f 63 6b 49 64 78 2d 57 41 4c 5f 52 45 41 44  lockIdx-WAL_READ
7760: 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20 20 72  _LOCK(0));.    r
7770: 65 74 75 72 6e 20 7a 4e 61 6d 65 3b 0a 20 20 7d  eturn zName;.  }
7780: 0a 7d 0a 23 65 6e 64 69 66 20 2f 2a 64 65 66 69  .}.#endif /*defi
7790: 6e 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29  ned(SQLITE_TEST)
77a0: 20 7c 7c 20 64 65 66 69 6e 65 64 28 53 51 4c 49   || defined(SQLI
77b0: 54 45 5f 44 45 42 55 47 29 20 2a 2f 0a 20 20 20  TE_DEBUG) */.   
77c0: 20 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 6f 72 20   ../*.** Set or 
77d0: 72 65 6c 65 61 73 65 20 6c 6f 63 6b 73 20 6f 6e  release locks on
77e0: 20 74 68 65 20 57 41 4c 2e 20 20 4c 6f 63 6b 73   the WAL.  Locks
77f0: 20 61 72 65 20 65 69 74 68 65 72 20 73 68 61 72   are either shar
7800: 65 64 20 6f 72 20 65 78 63 6c 75 73 69 76 65 2e  ed or exclusive.
7810: 0a 2a 2a 20 41 20 6c 6f 63 6b 20 63 61 6e 6e 6f  .** A lock canno
7820: 74 20 62 65 20 6d 6f 76 65 64 20 64 69 72 65 63  t be moved direc
7830: 74 6c 79 20 62 65 74 77 65 65 6e 20 73 68 61 72  tly between shar
7840: 65 64 20 61 6e 64 20 65 78 63 6c 75 73 69 76 65  ed and exclusive
7850: 20 2d 20 69 74 20 6d 75 73 74 20 67 6f 0a 2a 2a   - it must go.**
7860: 20 74 68 72 6f 75 67 68 20 74 68 65 20 75 6e 6c   through the unl
7870: 6f 63 6b 65 64 20 73 74 61 74 65 20 66 69 72 73  ocked state firs
7880: 74 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20 6c 6f 63 6b  t..**.** In lock
7890: 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49  ing_mode=EXCLUSI
78a0: 56 45 2c 20 61 6c 6c 20 6f 66 20 74 68 65 73 65  VE, all of these
78b0: 20 72 6f 75 74 69 6e 65 73 20 62 65 63 6f 6d 65   routines become
78c0: 20 6e 6f 2d 6f 70 73 2e 0a 2a 2f 0a 73 74 61 74   no-ops..*/.stat
78d0: 69 63 20 69 6e 74 20 77 61 6c 4c 6f 63 6b 53 68  ic int walLockSh
78e0: 61 72 65 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20  ared(Wal *pWal, 
78f0: 69 6e 74 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20  int lockIdx){.  
7900: 69 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 70 57  int rc;.  if( pW
7910: 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  al->exclusiveMod
7920: 65 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  e ) return SQLIT
7930: 45 5f 4f 4b 3b 0a 20 20 72 63 20 3d 20 73 71 6c  E_OK;.  rc = sql
7940: 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57  ite3OsShmLock(pW
7950: 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49  al->pDbFd, lockI
7960: 64 78 2c 20 31 2c 0a 20 20 20 20 20 20 20 20 20  dx, 1,.         
7970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53                 S
7980: 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20 7c  QLITE_SHM_LOCK |
7990: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52   SQLITE_SHM_SHAR
79a0: 45 44 29 3b 0a 20 20 57 41 4c 54 52 41 43 45 28  ED);.  WALTRACE(
79b0: 28 22 57 41 4c 25 70 3a 20 61 63 71 75 69 72 65  ("WAL%p: acquire
79c0: 20 53 48 41 52 45 44 2d 25 73 20 25 73 5c 6e 22   SHARED-%s %s\n"
79d0: 2c 20 70 57 61 6c 2c 0a 20 20 20 20 20 20 20 20  , pWal,.        
79e0: 20 20 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28      walLockName(
79f0: 6c 6f 63 6b 49 64 78 29 2c 20 72 63 20 3f 20 22  lockIdx), rc ? "
7a00: 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29  failed" : "ok"))
7a10: 3b 0a 20 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57  ;.  VVA_ONLY( pW
7a20: 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20  al->lockError = 
7a30: 28 75 38 29 28 72 63 21 3d 53 51 4c 49 54 45 5f  (u8)(rc!=SQLITE_
7a40: 4f 4b 20 26 26 20 72 63 21 3d 53 51 4c 49 54 45  OK && rc!=SQLITE
7a50: 5f 42 55 53 59 29 3b 20 29 0a 20 20 72 65 74 75  _BUSY); ).  retu
7a60: 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20  rn rc;.}.static 
7a70: 76 6f 69 64 20 77 61 6c 55 6e 6c 6f 63 6b 53 68  void walUnlockSh
7a80: 61 72 65 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20  ared(Wal *pWal, 
7a90: 69 6e 74 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20  int lockIdx){.  
7aa0: 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  if( pWal->exclus
7ab0: 69 76 65 4d 6f 64 65 20 29 20 72 65 74 75 72 6e  iveMode ) return
7ac0: 3b 0a 20 20 28 76 6f 69 64 29 73 71 6c 69 74 65  ;.  (void)sqlite
7ad0: 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d  3OsShmLock(pWal-
7ae0: 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c  >pDbFd, lockIdx,
7af0: 20 31 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20   1,.            
7b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c               SQL
7b10: 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f 43 4b 20 7c  ITE_SHM_UNLOCK |
7b20: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52   SQLITE_SHM_SHAR
7b30: 45 44 29 3b 0a 20 20 57 41 4c 54 52 41 43 45 28  ED);.  WALTRACE(
7b40: 28 22 57 41 4c 25 70 3a 20 72 65 6c 65 61 73 65  ("WAL%p: release
7b50: 20 53 48 41 52 45 44 2d 25 73 5c 6e 22 2c 20 70   SHARED-%s\n", p
7b60: 57 61 6c 2c 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65  Wal, walLockName
7b70: 28 6c 6f 63 6b 49 64 78 29 29 29 3b 0a 7d 0a 73  (lockIdx)));.}.s
7b80: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 4c 6f 63  tatic int walLoc
7b90: 6b 45 78 63 6c 75 73 69 76 65 28 57 61 6c 20 2a  kExclusive(Wal *
7ba0: 70 57 61 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64  pWal, int lockId
7bb0: 78 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69 6e 74  x, int n){.  int
7bc0: 20 72 63 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d   rc;.  if( pWal-
7bd0: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29  >exclusiveMode )
7be0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
7bf0: 4b 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  K;.  rc = sqlite
7c00: 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d  3OsShmLock(pWal-
7c10: 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c  >pDbFd, lockIdx,
7c20: 20 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20   n,.            
7c30: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
7c40: 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51  TE_SHM_LOCK | SQ
7c50: 4c 49 54 45 5f 53 48 4d 5f 45 58 43 4c 55 53 49  LITE_SHM_EXCLUSI
7c60: 56 45 29 3b 0a 20 20 57 41 4c 54 52 41 43 45 28  VE);.  WALTRACE(
7c70: 28 22 57 41 4c 25 70 3a 20 61 63 71 75 69 72 65  ("WAL%p: acquire
7c80: 20 45 58 43 4c 55 53 49 56 45 2d 25 73 20 63 6e   EXCLUSIVE-%s cn
7c90: 74 3d 25 64 20 25 73 5c 6e 22 2c 20 70 57 61 6c  t=%d %s\n", pWal
7ca0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 77 61  ,.            wa
7cb0: 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64  lLockName(lockId
7cc0: 78 29 2c 20 6e 2c 20 72 63 20 3f 20 22 66 61 69  x), n, rc ? "fai
7cd0: 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
7ce0: 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d   VVA_ONLY( pWal-
7cf0: 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20 28 75 38  >lockError = (u8
7d00: 29 28 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  )(rc!=SQLITE_OK 
7d10: 26 26 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55  && rc!=SQLITE_BU
7d20: 53 59 29 3b 20 29 0a 20 20 72 65 74 75 72 6e 20  SY); ).  return 
7d30: 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  rc;.}.static voi
7d40: 64 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75  d walUnlockExclu
7d50: 73 69 76 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20  sive(Wal *pWal, 
7d60: 69 6e 74 20 6c 6f 63 6b 49 64 78 2c 20 69 6e 74  int lockIdx, int
7d70: 20 6e 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d   n){.  if( pWal-
7d80: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29  >exclusiveMode )
7d90: 20 72 65 74 75 72 6e 3b 0a 20 20 28 76 6f 69 64   return;.  (void
7da0: 29 73 71 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63  )sqlite3OsShmLoc
7db0: 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c  k(pWal->pDbFd, l
7dc0: 6f 63 6b 49 64 78 2c 20 6e 2c 0a 20 20 20 20 20  ockIdx, n,.     
7dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7de0: 20 20 20 20 53 51 4c 49 54 45 5f 53 48 4d 5f 55      SQLITE_SHM_U
7df0: 4e 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53  NLOCK | SQLITE_S
7e00: 48 4d 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20  HM_EXCLUSIVE);. 
7e10: 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
7e20: 70 3a 20 72 65 6c 65 61 73 65 20 45 58 43 4c 55  p: release EXCLU
7e30: 53 49 56 45 2d 25 73 20 63 6e 74 3d 25 64 5c 6e  SIVE-%s cnt=%d\n
7e40: 22 2c 20 70 57 61 6c 2c 0a 20 20 20 20 20 20 20  ", pWal,.       
7e50: 20 20 20 20 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d        walLockNam
7e60: 65 28 6c 6f 63 6b 49 64 78 29 2c 20 6e 29 29 3b  e(lockIdx), n));
7e70: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74  .}../*.** Comput
7e80: 65 20 61 20 68 61 73 68 20 6f 6e 20 61 20 70 61  e a hash on a pa
7e90: 67 65 20 6e 75 6d 62 65 72 2e 20 20 54 68 65 20  ge number.  The 
7ea0: 72 65 73 75 6c 74 69 6e 67 20 68 61 73 68 20 76  resulting hash v
7eb0: 61 6c 75 65 20 6d 75 73 74 20 6c 61 6e 64 0a 2a  alue must land.*
7ec0: 2a 20 62 65 74 77 65 65 6e 20 30 20 61 6e 64 20  * between 0 and 
7ed0: 28 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54  (HASHTABLE_NSLOT
7ee0: 2d 31 29 2e 20 20 54 68 65 20 77 61 6c 48 61 73  -1).  The walHas
7ef0: 68 4e 65 78 74 28 29 20 66 75 6e 63 74 69 6f 6e  hNext() function
7f00: 20 61 64 76 61 6e 63 65 73 0a 2a 2a 20 74 68 65   advances.** the
7f10: 20 68 61 73 68 20 74 6f 20 74 68 65 20 6e 65 78   hash to the nex
7f20: 74 20 76 61 6c 75 65 20 69 6e 20 74 68 65 20 65  t value in the e
7f30: 76 65 6e 74 20 6f 66 20 61 20 63 6f 6c 6c 69 73  vent of a collis
7f40: 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ion..*/.static i
7f50: 6e 74 20 77 61 6c 48 61 73 68 28 75 33 32 20 69  nt walHash(u32 i
7f60: 50 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74 28  Page){.  assert(
7f70: 20 69 50 61 67 65 3e 30 20 29 3b 0a 20 20 61 73   iPage>0 );.  as
7f80: 73 65 72 74 28 20 28 48 41 53 48 54 41 42 4c 45  sert( (HASHTABLE
7f90: 5f 4e 53 4c 4f 54 20 26 20 28 48 41 53 48 54 41  _NSLOT & (HASHTA
7fa0: 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 29 3d 3d 30  BLE_NSLOT-1))==0
7fb0: 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 69 50   );.  return (iP
7fc0: 61 67 65 2a 48 41 53 48 54 41 42 4c 45 5f 48 41  age*HASHTABLE_HA
7fd0: 53 48 5f 31 29 20 26 20 28 48 41 53 48 54 41 42  SH_1) & (HASHTAB
7fe0: 4c 45 5f 4e 53 4c 4f 54 2d 31 29 3b 0a 7d 0a 73  LE_NSLOT-1);.}.s
7ff0: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 4e 65 78  tatic int walNex
8000: 74 48 61 73 68 28 69 6e 74 20 69 50 72 69 6f 72  tHash(int iPrior
8010: 48 61 73 68 29 7b 0a 20 20 72 65 74 75 72 6e 20  Hash){.  return 
8020: 28 69 50 72 69 6f 72 48 61 73 68 2b 31 29 26 28  (iPriorHash+1)&(
8030: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d  HASHTABLE_NSLOT-
8040: 31 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65  1);.}../* .** Re
8050: 74 75 72 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f  turn pointers to
8060: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
8070: 61 6e 64 20 70 61 67 65 20 6e 75 6d 62 65 72 20  and page number 
8080: 61 72 72 61 79 20 73 74 6f 72 65 64 20 6f 6e 0a  array stored on.
8090: 2a 2a 20 70 61 67 65 20 69 48 61 73 68 20 6f 66  ** page iHash of
80a0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20   the wal-index. 
80b0: 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73  The wal-index is
80c0: 20 62 72 6f 6b 65 6e 20 69 6e 74 6f 20 33 32 4b   broken into 32K
80d0: 42 20 70 61 67 65 73 0a 2a 2a 20 6e 75 6d 62 65  B pages.** numbe
80e0: 72 65 64 20 73 74 61 72 74 69 6e 67 20 66 72 6f  red starting fro
80f0: 6d 20 30 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20 6f  m 0..**.** Set o
8100: 75 74 70 75 74 20 76 61 72 69 61 62 6c 65 20 2a  utput variable *
8110: 70 61 48 61 73 68 20 74 6f 20 70 6f 69 6e 74 20  paHash to point 
8120: 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  to the start of 
8130: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 0a 2a  the hash table.*
8140: 2a 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64  * in the wal-ind
8150: 65 78 20 66 69 6c 65 2e 20 53 65 74 20 2a 70 69  ex file. Set *pi
8160: 5a 65 72 6f 20 74 6f 20 6f 6e 65 20 6c 65 73 73  Zero to one less
8170: 20 74 68 61 6e 20 74 68 65 20 66 72 61 6d 65 20   than the frame 
8180: 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 74 68  .** number of th
8190: 65 20 66 69 72 73 74 20 66 72 61 6d 65 20 69 6e  e first frame in
81a0: 64 65 78 65 64 20 62 79 20 74 68 69 73 20 68 61  dexed by this ha
81b0: 73 68 20 74 61 62 6c 65 2e 20 49 66 20 61 0a 2a  sh table. If a.*
81c0: 2a 20 73 6c 6f 74 20 69 6e 20 74 68 65 20 68 61  * slot in the ha
81d0: 73 68 20 74 61 62 6c 65 20 69 73 20 73 65 74 20  sh table is set 
81e0: 74 6f 20 4e 2c 20 69 74 20 72 65 66 65 72 73 20  to N, it refers 
81f0: 74 6f 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 20  to frame number 
8200: 0a 2a 2a 20 28 2a 70 69 5a 65 72 6f 2b 4e 29 20  .** (*piZero+N) 
8210: 69 6e 20 74 68 65 20 6c 6f 67 2e 0a 2a 2a 0a 2a  in the log..**.*
8220: 2a 20 46 69 6e 61 6c 6c 79 2c 20 73 65 74 20 2a  * Finally, set *
8230: 70 61 50 67 6e 6f 20 73 6f 20 74 68 61 74 20 2a  paPgno so that *
8240: 70 61 50 67 6e 6f 5b 31 5d 20 69 73 20 74 68 65  paPgno[1] is the
8250: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20   page number of 
8260: 74 68 65 0a 2a 2a 20 66 69 72 73 74 20 66 72 61  the.** first fra
8270: 6d 65 20 69 6e 64 65 78 65 64 20 62 79 20 74 68  me indexed by th
8280: 65 20 68 61 73 68 20 74 61 62 6c 65 2c 20 66 72  e hash table, fr
8290: 61 6d 65 20 28 2a 70 69 5a 65 72 6f 2b 31 29 2e  ame (*piZero+1).
82a0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
82b0: 61 6c 48 61 73 68 47 65 74 28 0a 20 20 57 61 6c  alHashGet(.  Wal
82c0: 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20   *pWal,         
82d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
82e0: 57 41 4c 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20  WAL handle */.  
82f0: 69 6e 74 20 69 48 61 73 68 2c 20 20 20 20 20 20  int iHash,      
8300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8310: 2f 2a 20 46 69 6e 64 20 74 68 65 20 69 48 61 73  /* Find the iHas
8320: 68 27 74 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20  h'th table */.  
8330: 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74  volatile ht_slot
8340: 20 2a 2a 70 61 48 61 73 68 2c 20 20 20 20 20 20   **paHash,      
8350: 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20  /* OUT: Pointer 
8360: 74 6f 20 68 61 73 68 20 69 6e 64 65 78 20 2a 2f  to hash index */
8370: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20  .  volatile u32 
8380: 2a 2a 70 61 50 67 6e 6f 2c 20 20 20 20 20 20 20  **paPgno,       
8390: 20 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74     /* OUT: Point
83a0: 65 72 20 74 6f 20 70 61 67 65 20 6e 75 6d 62 65  er to page numbe
83b0: 72 20 61 72 72 61 79 20 2a 2f 0a 20 20 75 33 32  r array */.  u32
83c0: 20 2a 70 69 5a 65 72 6f 20 20 20 20 20 20 20 20   *piZero        
83d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
83e0: 4f 55 54 3a 20 46 72 61 6d 65 20 61 73 73 6f 63  OUT: Frame assoc
83f0: 69 61 74 65 64 20 77 69 74 68 20 2a 70 61 50 67  iated with *paPg
8400: 6e 6f 5b 30 5d 20 2a 2f 0a 29 7b 0a 20 20 69 6e  no[0] */.){.  in
8410: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
8420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8430: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
8440: 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a    volatile u32 *
8450: 61 50 67 6e 6f 3b 0a 0a 20 20 72 63 20 3d 20 77  aPgno;..  rc = w
8460: 61 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c  alIndexPage(pWal
8470: 2c 20 69 48 61 73 68 2c 20 26 61 50 67 6e 6f 29  , iHash, &aPgno)
8480: 3b 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d  ;.  assert( rc==
8490: 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 69 48 61  SQLITE_OK || iHa
84a0: 73 68 3e 30 20 29 3b 0a 0a 20 20 69 66 28 20 72  sh>0 );..  if( r
84b0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
84c0: 20 20 20 20 75 33 32 20 69 5a 65 72 6f 3b 0a 20      u32 iZero;. 
84d0: 20 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73     volatile ht_s
84e0: 6c 6f 74 20 2a 61 48 61 73 68 3b 0a 0a 20 20 20  lot *aHash;..   
84f0: 20 61 48 61 73 68 20 3d 20 28 76 6f 6c 61 74 69   aHash = (volati
8500: 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 29 26 61 50  le ht_slot *)&aP
8510: 67 6e 6f 5b 48 41 53 48 54 41 42 4c 45 5f 4e 50  gno[HASHTABLE_NP
8520: 41 47 45 5d 3b 0a 20 20 20 20 69 66 28 20 69 48  AGE];.    if( iH
8530: 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ash==0 ){.      
8540: 61 50 67 6e 6f 20 3d 20 26 61 50 67 6e 6f 5b 57  aPgno = &aPgno[W
8550: 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45  ALINDEX_HDR_SIZE
8560: 2f 73 69 7a 65 6f 66 28 75 33 32 29 5d 3b 0a 20  /sizeof(u32)];. 
8570: 20 20 20 20 20 69 5a 65 72 6f 20 3d 20 30 3b 0a       iZero = 0;.
8580: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
8590: 20 69 5a 65 72 6f 20 3d 20 48 41 53 48 54 41 42   iZero = HASHTAB
85a0: 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20 2b 20 28  LE_NPAGE_ONE + (
85b0: 69 48 61 73 68 2d 31 29 2a 48 41 53 48 54 41 42  iHash-1)*HASHTAB
85c0: 4c 45 5f 4e 50 41 47 45 3b 0a 20 20 20 20 7d 0a  LE_NPAGE;.    }.
85d0: 20 20 0a 20 20 20 20 2a 70 61 50 67 6e 6f 20 3d    .    *paPgno =
85e0: 20 26 61 50 67 6e 6f 5b 2d 31 5d 3b 0a 20 20 20   &aPgno[-1];.   
85f0: 20 2a 70 61 48 61 73 68 20 3d 20 61 48 61 73 68   *paHash = aHash
8600: 3b 0a 20 20 20 20 2a 70 69 5a 65 72 6f 20 3d 20  ;.    *piZero = 
8610: 69 5a 65 72 6f 3b 0a 20 20 7d 0a 20 20 72 65 74  iZero;.  }.  ret
8620: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
8630: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62   Return the numb
8640: 65 72 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  er of the wal-in
8650: 64 65 78 20 70 61 67 65 20 74 68 61 74 20 63 6f  dex page that co
8660: 6e 74 61 69 6e 73 20 74 68 65 20 68 61 73 68 2d  ntains the hash-
8670: 74 61 62 6c 65 0a 2a 2a 20 61 6e 64 20 70 61 67  table.** and pag
8680: 65 2d 6e 75 6d 62 65 72 20 61 72 72 61 79 20 74  e-number array t
8690: 68 61 74 20 63 6f 6e 74 61 69 6e 20 65 6e 74 72  hat contain entr
86a0: 69 65 73 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e  ies correspondin
86b0: 67 20 74 6f 20 57 41 4c 20 66 72 61 6d 65 0a 2a  g to WAL frame.*
86c0: 2a 20 69 46 72 61 6d 65 2e 20 54 68 65 20 77 61  * iFrame. The wa
86d0: 6c 2d 69 6e 64 65 78 20 69 73 20 62 72 6f 6b 65  l-index is broke
86e0: 6e 20 75 70 20 69 6e 74 6f 20 33 32 4b 42 20 70  n up into 32KB p
86f0: 61 67 65 73 2e 20 57 61 6c 2d 69 6e 64 65 78 20  ages. Wal-index 
8700: 70 61 67 65 73 20 0a 2a 2a 20 61 72 65 20 6e 75  pages .** are nu
8710: 6d 62 65 72 65 64 20 73 74 61 72 74 69 6e 67 20  mbered starting 
8720: 66 72 6f 6d 20 30 2e 0a 2a 2f 0a 73 74 61 74 69  from 0..*/.stati
8730: 63 20 69 6e 74 20 77 61 6c 46 72 61 6d 65 50 61  c int walFramePa
8740: 67 65 28 75 33 32 20 69 46 72 61 6d 65 29 7b 0a  ge(u32 iFrame){.
8750: 20 20 69 6e 74 20 69 48 61 73 68 20 3d 20 28 69    int iHash = (i
8760: 46 72 61 6d 65 2b 48 41 53 48 54 41 42 4c 45 5f  Frame+HASHTABLE_
8770: 4e 50 41 47 45 2d 48 41 53 48 54 41 42 4c 45 5f  NPAGE-HASHTABLE_
8780: 4e 50 41 47 45 5f 4f 4e 45 2d 31 29 20 2f 20 48  NPAGE_ONE-1) / H
8790: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3b 0a  ASHTABLE_NPAGE;.
87a0: 20 20 61 73 73 65 72 74 28 20 28 69 48 61 73 68    assert( (iHash
87b0: 3d 3d 30 20 7c 7c 20 69 46 72 61 6d 65 3e 48 41  ==0 || iFrame>HA
87c0: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e  SHTABLE_NPAGE_ON
87d0: 45 29 0a 20 20 20 20 20 20 20 26 26 20 28 69 48  E).       && (iH
87e0: 61 73 68 3e 3d 31 20 7c 7c 20 69 46 72 61 6d 65  ash>=1 || iFrame
87f0: 3c 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  <=HASHTABLE_NPAG
8800: 45 5f 4f 4e 45 29 0a 20 20 20 20 20 20 20 26 26  E_ONE).       &&
8810: 20 28 69 48 61 73 68 3c 3d 31 20 7c 7c 20 69 46   (iHash<=1 || iF
8820: 72 61 6d 65 3e 28 48 41 53 48 54 41 42 4c 45 5f  rame>(HASHTABLE_
8830: 4e 50 41 47 45 5f 4f 4e 45 2b 48 41 53 48 54 41  NPAGE_ONE+HASHTA
8840: 42 4c 45 5f 4e 50 41 47 45 29 29 0a 20 20 20 20  BLE_NPAGE)).    
8850: 20 20 20 26 26 20 28 69 48 61 73 68 3e 3d 32 20     && (iHash>=2 
8860: 7c 7c 20 69 46 72 61 6d 65 3c 3d 48 41 53 48 54  || iFrame<=HASHT
8870: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 48  ABLE_NPAGE_ONE+H
8880: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 29 0a  ASHTABLE_NPAGE).
8890: 20 20 20 20 20 20 20 26 26 20 28 69 48 61 73 68         && (iHash
88a0: 3c 3d 32 20 7c 7c 20 69 46 72 61 6d 65 3e 28 48  <=2 || iFrame>(H
88b0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
88c0: 4e 45 2b 32 2a 48 41 53 48 54 41 42 4c 45 5f 4e  NE+2*HASHTABLE_N
88d0: 50 41 47 45 29 29 0a 20 20 29 3b 0a 20 20 72 65  PAGE)).  );.  re
88e0: 74 75 72 6e 20 69 48 61 73 68 3b 0a 7d 0a 0a 2f  turn iHash;.}../
88f0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
8900: 70 61 67 65 20 6e 75 6d 62 65 72 20 61 73 73 6f  page number asso
8910: 63 69 61 74 65 64 20 77 69 74 68 20 66 72 61 6d  ciated with fram
8920: 65 20 69 46 72 61 6d 65 20 69 6e 20 74 68 69 73  e iFrame in this
8930: 20 57 41 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20   WAL..*/.static 
8940: 75 33 32 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f  u32 walFramePgno
8950: 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20  (Wal *pWal, u32 
8960: 69 46 72 61 6d 65 29 7b 0a 20 20 69 6e 74 20 69  iFrame){.  int i
8970: 48 61 73 68 20 3d 20 77 61 6c 46 72 61 6d 65 50  Hash = walFrameP
8980: 61 67 65 28 69 46 72 61 6d 65 29 3b 0a 20 20 69  age(iFrame);.  i
8990: 66 28 20 69 48 61 73 68 3d 3d 30 20 29 7b 0a 20  f( iHash==0 ){. 
89a0: 20 20 20 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e     return pWal->
89b0: 61 70 57 69 44 61 74 61 5b 30 5d 5b 57 41 4c 49  apWiData[0][WALI
89c0: 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69  NDEX_HDR_SIZE/si
89d0: 7a 65 6f 66 28 75 33 32 29 20 2b 20 69 46 72 61  zeof(u32) + iFra
89e0: 6d 65 20 2d 20 31 5d 3b 0a 20 20 7d 0a 20 20 72  me - 1];.  }.  r
89f0: 65 74 75 72 6e 20 70 57 61 6c 2d 3e 61 70 57 69  eturn pWal->apWi
8a00: 44 61 74 61 5b 69 48 61 73 68 5d 5b 28 69 46 72  Data[iHash][(iFr
8a10: 61 6d 65 2d 31 2d 48 41 53 48 54 41 42 4c 45 5f  ame-1-HASHTABLE_
8a20: 4e 50 41 47 45 5f 4f 4e 45 29 25 48 41 53 48 54  NPAGE_ONE)%HASHT
8a30: 41 42 4c 45 5f 4e 50 41 47 45 5d 3b 0a 7d 0a 0a  ABLE_NPAGE];.}..
8a40: 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 65 6e 74  /*.** Remove ent
8a50: 72 69 65 73 20 66 72 6f 6d 20 74 68 65 20 68 61  ries from the ha
8a60: 73 68 20 74 61 62 6c 65 20 74 68 61 74 20 70 6f  sh table that po
8a70: 69 6e 74 20 74 6f 20 57 41 4c 20 73 6c 6f 74 73  int to WAL slots
8a80: 20 67 72 65 61 74 65 72 0a 2a 2a 20 74 68 61 6e   greater.** than
8a90: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
8aa0: 6d 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66  me..**.** This f
8ab0: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
8ac0: 64 20 77 68 65 6e 65 76 65 72 20 70 57 61 6c 2d  d whenever pWal-
8ad0: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20  >hdr.mxFrame is 
8ae0: 64 65 63 72 65 61 73 65 64 20 64 75 65 0a 2a 2a  decreased due.**
8af0: 20 74 6f 20 61 20 72 6f 6c 6c 62 61 63 6b 20 6f   to a rollback o
8b00: 72 20 73 61 76 65 70 6f 69 6e 74 2e 0a 2a 2a 0a  r savepoint..**.
8b10: 2a 2a 20 41 74 20 6d 6f 73 74 20 6f 6e 6c 79 20  ** At most only 
8b20: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 63  the hash table c
8b30: 6f 6e 74 61 69 6e 69 6e 67 20 70 57 61 6c 2d 3e  ontaining pWal->
8b40: 68 64 72 2e 6d 78 46 72 61 6d 65 20 6e 65 65 64  hdr.mxFrame need
8b50: 73 20 74 6f 20 62 65 0a 2a 2a 20 75 70 64 61 74  s to be.** updat
8b60: 65 64 2e 20 20 41 6e 79 20 6c 61 74 65 72 20 68  ed.  Any later h
8b70: 61 73 68 20 74 61 62 6c 65 73 20 77 69 6c 6c 20  ash tables will 
8b80: 62 65 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79  be automatically
8b90: 20 63 6c 65 61 72 65 64 20 77 68 65 6e 0a 2a 2a   cleared when.**
8ba0: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
8bb0: 6d 65 20 61 64 76 61 6e 63 65 73 20 74 6f 20 74  me advances to t
8bc0: 68 65 20 70 6f 69 6e 74 20 77 68 65 72 65 20 74  he point where t
8bd0: 68 6f 73 65 20 68 61 73 68 20 74 61 62 6c 65 73  hose hash tables
8be0: 20 61 72 65 0a 2a 2a 20 61 63 74 75 61 6c 6c 79   are.** actually
8bf0: 20 6e 65 65 64 65 64 2e 0a 2a 2f 0a 73 74 61 74   needed..*/.stat
8c00: 69 63 20 76 6f 69 64 20 77 61 6c 43 6c 65 61 6e  ic void walClean
8c10: 75 70 48 61 73 68 28 57 61 6c 20 2a 70 57 61 6c  upHash(Wal *pWal
8c20: 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 68 74  ){.  volatile ht
8c30: 5f 73 6c 6f 74 20 2a 61 48 61 73 68 20 3d 20 30  _slot *aHash = 0
8c40: 3b 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20  ;    /* Pointer 
8c50: 74 6f 20 68 61 73 68 20 74 61 62 6c 65 20 74 6f  to hash table to
8c60: 20 63 6c 65 61 72 20 2a 2f 0a 20 20 76 6f 6c 61   clear */.  vola
8c70: 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 20  tile u32 *aPgno 
8c80: 3d 20 30 3b 20 20 20 20 20 20 20 20 2f 2a 20 50  = 0;        /* P
8c90: 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79  age number array
8ca0: 20 66 6f 72 20 68 61 73 68 20 74 61 62 6c 65 20   for hash table 
8cb0: 2a 2f 0a 20 20 75 33 32 20 69 5a 65 72 6f 20 3d  */.  u32 iZero =
8cc0: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
8cd0: 20 20 20 20 20 2f 2a 20 66 72 61 6d 65 20 3d 3d       /* frame ==
8ce0: 20 28 61 48 61 73 68 5b 78 5d 2b 69 5a 65 72 6f   (aHash[x]+iZero
8cf0: 29 20 2a 2f 0a 20 20 69 6e 74 20 69 4c 69 6d 69  ) */.  int iLimi
8d00: 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  t = 0;          
8d10: 20 20 20 20 20 20 20 2f 2a 20 5a 65 72 6f 20 76         /* Zero v
8d20: 61 6c 75 65 73 20 67 72 65 61 74 65 72 20 74 68  alues greater th
8d30: 61 6e 20 74 68 69 73 20 2a 2f 0a 20 20 69 6e 74  an this */.  int
8d40: 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20   nByte;         
8d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8d60: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
8d70: 74 6f 20 7a 65 72 6f 20 69 6e 20 61 50 67 6e 6f  to zero in aPgno
8d80: 5b 5d 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20  [] */.  int i;  
8d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8da0: 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20          /* Used 
8db0: 74 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75  to iterate throu
8dc0: 67 68 20 61 48 61 73 68 5b 5d 20 2a 2f 0a 0a 20  gh aHash[] */.. 
8dd0: 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77   assert( pWal->w
8de0: 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 74 65  riteLock );.  te
8df0: 73 74 63 61 73 65 28 20 70 57 61 6c 2d 3e 68 64  stcase( pWal->hd
8e00: 72 2e 6d 78 46 72 61 6d 65 3d 3d 48 41 53 48 54  r.mxFrame==HASHT
8e10: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2d 31  ABLE_NPAGE_ONE-1
8e20: 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20   );.  testcase( 
8e30: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
8e40: 65 3d 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  e==HASHTABLE_NPA
8e50: 47 45 5f 4f 4e 45 20 29 3b 0a 20 20 74 65 73 74  GE_ONE );.  test
8e60: 63 61 73 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e  case( pWal->hdr.
8e70: 6d 78 46 72 61 6d 65 3d 3d 48 41 53 48 54 41 42  mxFrame==HASHTAB
8e80: 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 31 20 29  LE_NPAGE_ONE+1 )
8e90: 3b 0a 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 68  ;..  if( pWal->h
8ea0: 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 30 20 29 20  dr.mxFrame==0 ) 
8eb0: 72 65 74 75 72 6e 3b 0a 0a 20 20 2f 2a 20 4f 62  return;..  /* Ob
8ec0: 74 61 69 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f  tain pointers to
8ed0: 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65 20   the hash-table 
8ee0: 61 6e 64 20 70 61 67 65 2d 6e 75 6d 62 65 72 20  and page-number 
8ef0: 61 72 72 61 79 20 63 6f 6e 74 61 69 6e 69 6e 67  array containing
8f00: 20 0a 20 20 2a 2a 20 74 68 65 20 65 6e 74 72 79   .  ** the entry
8f10: 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64   that correspond
8f20: 73 20 74 6f 20 66 72 61 6d 65 20 70 57 61 6c 2d  s to frame pWal-
8f30: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 20 49 74  >hdr.mxFrame. It
8f40: 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 0a 20   is guaranteed. 
8f50: 20 2a 2a 20 74 68 61 74 20 74 68 65 20 70 61 67   ** that the pag
8f60: 65 20 73 61 69 64 20 68 61 73 68 2d 74 61 62 6c  e said hash-tabl
8f70: 65 20 61 6e 64 20 61 72 72 61 79 20 72 65 73 69  e and array resi
8f80: 64 65 20 6f 6e 20 69 73 20 61 6c 72 65 61 64 79  de on is already
8f90: 20 6d 61 70 70 65 64 2e 0a 20 20 2a 2f 0a 20 20   mapped..  */.  
8fa0: 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57  assert( pWal->nW
8fb0: 69 44 61 74 61 3e 77 61 6c 46 72 61 6d 65 50 61  iData>walFramePa
8fc0: 67 65 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ge(pWal->hdr.mxF
8fd0: 72 61 6d 65 29 20 29 3b 0a 20 20 61 73 73 65 72  rame) );.  asser
8fe0: 74 28 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  t( pWal->apWiDat
8ff0: 61 5b 77 61 6c 46 72 61 6d 65 50 61 67 65 28 70  a[walFramePage(p
9000: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
9010: 29 5d 20 29 3b 0a 20 20 77 61 6c 48 61 73 68 47  )] );.  walHashG
9020: 65 74 28 70 57 61 6c 2c 20 77 61 6c 46 72 61 6d  et(pWal, walFram
9030: 65 50 61 67 65 28 70 57 61 6c 2d 3e 68 64 72 2e  ePage(pWal->hdr.
9040: 6d 78 46 72 61 6d 65 29 2c 20 26 61 48 61 73 68  mxFrame), &aHash
9050: 2c 20 26 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f  , &aPgno, &iZero
9060: 29 3b 0a 0a 20 20 2f 2a 20 5a 65 72 6f 20 61 6c  );..  /* Zero al
9070: 6c 20 68 61 73 68 2d 74 61 62 6c 65 20 65 6e 74  l hash-table ent
9080: 72 69 65 73 20 74 68 61 74 20 63 6f 72 72 65 73  ries that corres
9090: 70 6f 6e 64 20 74 6f 20 66 72 61 6d 65 20 6e 75  pond to frame nu
90a0: 6d 62 65 72 73 20 67 72 65 61 74 65 72 0a 20 20  mbers greater.  
90b0: 2a 2a 20 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64  ** than pWal->hd
90c0: 72 2e 6d 78 46 72 61 6d 65 2e 0a 20 20 2a 2f 0a  r.mxFrame..  */.
90d0: 20 20 69 4c 69 6d 69 74 20 3d 20 70 57 61 6c 2d    iLimit = pWal-
90e0: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 2d 20 69  >hdr.mxFrame - i
90f0: 5a 65 72 6f 3b 0a 20 20 61 73 73 65 72 74 28 20  Zero;.  assert( 
9100: 69 4c 69 6d 69 74 3e 30 20 29 3b 0a 20 20 66 6f  iLimit>0 );.  fo
9110: 72 28 69 3d 30 3b 20 69 3c 48 41 53 48 54 41 42  r(i=0; i<HASHTAB
9120: 4c 45 5f 4e 53 4c 4f 54 3b 20 69 2b 2b 29 7b 0a  LE_NSLOT; i++){.
9130: 20 20 20 20 69 66 28 20 61 48 61 73 68 5b 69 5d      if( aHash[i]
9140: 3e 69 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20 20  >iLimit ){.     
9150: 20 61 48 61 73 68 5b 69 5d 20 3d 20 30 3b 0a 20   aHash[i] = 0;. 
9160: 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 2f 2a     }.  }.  .  /*
9170: 20 5a 65 72 6f 20 74 68 65 20 65 6e 74 72 69 65   Zero the entrie
9180: 73 20 69 6e 20 74 68 65 20 61 50 67 6e 6f 20 61  s in the aPgno a
9190: 72 72 61 79 20 74 68 61 74 20 63 6f 72 72 65 73  rray that corres
91a0: 70 6f 6e 64 20 74 6f 20 66 72 61 6d 65 73 20 77  pond to frames w
91b0: 69 74 68 0a 20 20 2a 2a 20 66 72 61 6d 65 20 6e  ith.  ** frame n
91c0: 75 6d 62 65 72 73 20 67 72 65 61 74 65 72 20 74  umbers greater t
91d0: 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  han pWal->hdr.mx
91e0: 46 72 61 6d 65 2e 20 0a 20 20 2a 2f 0a 20 20 6e  Frame. .  */.  n
91f0: 42 79 74 65 20 3d 20 28 69 6e 74 29 28 28 63 68  Byte = (int)((ch
9200: 61 72 20 2a 29 61 48 61 73 68 20 2d 20 28 63 68  ar *)aHash - (ch
9210: 61 72 20 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d  ar *)&aPgno[iLim
9220: 69 74 2b 31 5d 29 3b 0a 20 20 6d 65 6d 73 65 74  it+1]);.  memset
9230: 28 28 76 6f 69 64 20 2a 29 26 61 50 67 6e 6f 5b  ((void *)&aPgno[
9240: 69 4c 69 6d 69 74 2b 31 5d 2c 20 30 2c 20 6e 42  iLimit+1], 0, nB
9250: 79 74 65 29 3b 0a 0a 23 69 66 64 65 66 20 53 51  yte);..#ifdef SQ
9260: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45  LITE_ENABLE_EXPE
9270: 4e 53 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f  NSIVE_ASSERT.  /
9280: 2a 20 56 65 72 69 66 79 20 74 68 61 74 20 74 68  * Verify that th
9290: 65 20 65 76 65 72 79 20 65 6e 74 72 79 20 69 6e  e every entry in
92a0: 20 74 68 65 20 6d 61 70 70 69 6e 67 20 72 65 67   the mapping reg
92b0: 69 6f 6e 20 69 73 20 73 74 69 6c 6c 20 72 65 61  ion is still rea
92c0: 63 68 61 62 6c 65 0a 20 20 2a 2a 20 76 69 61 20  chable.  ** via 
92d0: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 65  the hash table e
92e0: 76 65 6e 20 61 66 74 65 72 20 74 68 65 20 63 6c  ven after the cl
92f0: 65 61 6e 75 70 2e 0a 20 20 2a 2f 0a 20 20 69 66  eanup..  */.  if
9300: 28 20 69 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20  ( iLimit ){.    
9310: 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
9320: 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72   /* Loop counter
9330: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 4b 65 79   */.    int iKey
9340: 3b 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68  ;        /* Hash
9350: 20 6b 65 79 20 2a 2f 0a 20 20 20 20 66 6f 72 28   key */.    for(
9360: 69 3d 31 3b 20 69 3c 3d 69 4c 69 6d 69 74 3b 20  i=1; i<=iLimit; 
9370: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 66 6f 72 28  i++){.      for(
9380: 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 61 50 67  iKey=walHash(aPg
9390: 6e 6f 5b 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b  no[i]); aHash[iK
93a0: 65 79 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78  ey]; iKey=walNex
93b0: 74 48 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20  tHash(iKey)){.  
93c0: 20 20 20 20 20 20 69 66 28 20 61 48 61 73 68 5b        if( aHash[
93d0: 69 4b 65 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b  iKey]==i ) break
93e0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
93f0: 61 73 73 65 72 74 28 20 61 48 61 73 68 5b 69 4b  assert( aHash[iK
9400: 65 79 5d 3d 3d 69 20 29 3b 0a 20 20 20 20 7d 0a  ey]==i );.    }.
9410: 20 20 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51    }.#endif /* SQ
9420: 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45  LITE_ENABLE_EXPE
9430: 4e 53 49 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a  NSIVE_ASSERT */.
9440: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 6e  }.../*.** Set an
9450: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 77 61   entry in the wa
9460: 6c 2d 69 6e 64 65 78 20 74 68 61 74 20 77 69 6c  l-index that wil
9470: 6c 20 6d 61 70 20 64 61 74 61 62 61 73 65 20 70  l map database p
9480: 61 67 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 70 50  age number.** pP
9490: 61 67 65 20 69 6e 74 6f 20 57 41 4c 20 66 72 61  age into WAL fra
94a0: 6d 65 20 69 46 72 61 6d 65 2e 0a 2a 2f 0a 73 74  me iFrame..*/.st
94b0: 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e 64 65  atic int walInde
94c0: 78 41 70 70 65 6e 64 28 57 61 6c 20 2a 70 57 61  xAppend(Wal *pWa
94d0: 6c 2c 20 75 33 32 20 69 46 72 61 6d 65 2c 20 75  l, u32 iFrame, u
94e0: 33 32 20 69 50 61 67 65 29 7b 0a 20 20 69 6e 74  32 iPage){.  int
94f0: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
9500: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9510: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
9520: 20 75 33 32 20 69 5a 65 72 6f 20 3d 20 30 3b 20   u32 iZero = 0; 
9530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9540: 20 2f 2a 20 4f 6e 65 20 6c 65 73 73 20 74 68 61   /* One less tha
9550: 6e 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 6f  n frame number o
9560: 66 20 61 50 67 6e 6f 5b 31 5d 20 2a 2f 0a 20 20  f aPgno[1] */.  
9570: 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50  volatile u32 *aP
9580: 67 6e 6f 20 3d 20 30 3b 20 20 20 20 20 20 20 20  gno = 0;        
9590: 2f 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20 61  /* Page number a
95a0: 72 72 61 79 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  rray */.  volati
95b0: 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73  le ht_slot *aHas
95c0: 68 20 3d 20 30 3b 20 20 20 20 2f 2a 20 48 61 73  h = 0;    /* Has
95d0: 68 20 74 61 62 6c 65 20 2a 2f 0a 0a 20 20 72 63  h table */..  rc
95e0: 20 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70 57   = walHashGet(pW
95f0: 61 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61 67 65  al, walFramePage
9600: 28 69 46 72 61 6d 65 29 2c 20 26 61 48 61 73 68  (iFrame), &aHash
9610: 2c 20 26 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f  , &aPgno, &iZero
9620: 29 3b 0a 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e  );..  /* Assumin
9630: 67 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  g the wal-index 
9640: 66 69 6c 65 20 77 61 73 20 73 75 63 63 65 73 73  file was success
9650: 66 75 6c 6c 79 20 6d 61 70 70 65 64 2c 20 70 6f  fully mapped, po
9660: 70 75 6c 61 74 65 20 74 68 65 0a 20 20 2a 2a 20  pulate the.  ** 
9670: 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61  page number arra
9680: 79 20 61 6e 64 20 68 61 73 68 20 74 61 62 6c 65  y and hash table
9690: 20 65 6e 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 69   entry..  */.  i
96a0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
96b0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 4b 65 79   ){.    int iKey
96c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
96d0: 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61        /* Hash ta
96e0: 62 6c 65 20 6b 65 79 20 2a 2f 0a 20 20 20 20 69  ble key */.    i
96f0: 6e 74 20 69 64 78 3b 20 20 20 20 20 20 20 20 20  nt idx;         
9700: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9710: 56 61 6c 75 65 20 74 6f 20 77 72 69 74 65 20 74  Value to write t
9720: 6f 20 68 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f  o hash-table slo
9730: 74 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 43 6f  t */.    int nCo
9740: 6c 6c 69 64 65 3b 20 20 20 20 20 20 20 20 20 20  llide;          
9750: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
9760: 20 6f 66 20 68 61 73 68 20 63 6f 6c 6c 69 73 69   of hash collisi
9770: 6f 6e 73 20 2a 2f 0a 0a 20 20 20 20 69 64 78 20  ons */..    idx 
9780: 3d 20 69 46 72 61 6d 65 20 2d 20 69 5a 65 72 6f  = iFrame - iZero
9790: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 64  ;.    assert( id
97a0: 78 20 3c 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e  x <= HASHTABLE_N
97b0: 53 4c 4f 54 2f 32 20 2b 20 31 20 29 3b 0a 20 20  SLOT/2 + 1 );.  
97c0: 20 20 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 69    .    /* If thi
97d0: 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 65  s is the first e
97e0: 6e 74 72 79 20 74 6f 20 62 65 20 61 64 64 65 64  ntry to be added
97f0: 20 74 6f 20 74 68 69 73 20 68 61 73 68 2d 74 61   to this hash-ta
9800: 62 6c 65 2c 20 7a 65 72 6f 20 74 68 65 0a 20 20  ble, zero the.  
9810: 20 20 2a 2a 20 65 6e 74 69 72 65 20 68 61 73 68    ** entire hash
9820: 20 74 61 62 6c 65 20 61 6e 64 20 61 50 67 6e 6f   table and aPgno
9830: 5b 5d 20 61 72 72 61 79 20 62 65 66 6f 72 65 20  [] array before 
9840: 70 72 6f 63 65 64 69 6e 67 2e 20 0a 20 20 20 20  proceding. .    
9850: 2a 2f 0a 20 20 20 20 69 66 28 20 69 64 78 3d 3d  */.    if( idx==
9860: 31 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e  1 ){.      int n
9870: 42 79 74 65 20 3d 20 28 69 6e 74 29 28 28 75 38  Byte = (int)((u8
9880: 20 2a 29 26 61 48 61 73 68 5b 48 41 53 48 54 41   *)&aHash[HASHTA
9890: 42 4c 45 5f 4e 53 4c 4f 54 5d 20 2d 20 28 75 38  BLE_NSLOT] - (u8
98a0: 20 2a 29 26 61 50 67 6e 6f 5b 31 5d 29 3b 0a 20   *)&aPgno[1]);. 
98b0: 20 20 20 20 20 6d 65 6d 73 65 74 28 28 76 6f 69       memset((voi
98c0: 64 2a 29 26 61 50 67 6e 6f 5b 31 5d 2c 20 30 2c  d*)&aPgno[1], 0,
98d0: 20 6e 42 79 74 65 29 3b 0a 20 20 20 20 7d 0a 0a   nByte);.    }..
98e0: 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 65 6e      /* If the en
98f0: 74 72 79 20 69 6e 20 61 50 67 6e 6f 5b 5d 20 69  try in aPgno[] i
9900: 73 20 61 6c 72 65 61 64 79 20 73 65 74 2c 20 74  s already set, t
9910: 68 65 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73  hen the previous
9920: 20 77 72 69 74 65 72 0a 20 20 20 20 2a 2a 20 6d   writer.    ** m
9930: 75 73 74 20 68 61 76 65 20 65 78 69 74 65 64 20  ust have exited 
9940: 75 6e 65 78 70 65 63 74 65 64 6c 79 20 69 6e 20  unexpectedly in 
9950: 74 68 65 20 6d 69 64 64 6c 65 20 6f 66 20 61 20  the middle of a 
9960: 74 72 61 6e 73 61 63 74 69 6f 6e 20 28 61 66 74  transaction (aft
9970: 65 72 0a 20 20 20 20 2a 2a 20 77 72 69 74 69 6e  er.    ** writin
9980: 67 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 64 69  g one or more di
9990: 72 74 79 20 70 61 67 65 73 20 74 6f 20 74 68 65  rty pages to the
99a0: 20 57 41 4c 20 74 6f 20 66 72 65 65 20 75 70 20   WAL to free up 
99b0: 6d 65 6d 6f 72 79 29 2e 20 0a 20 20 20 20 2a 2a  memory). .    **
99c0: 20 52 65 6d 6f 76 65 20 74 68 65 20 72 65 6d 6e   Remove the remn
99d0: 61 6e 74 73 20 6f 66 20 74 68 61 74 20 77 72 69  ants of that wri
99e0: 74 65 72 73 20 75 6e 63 6f 6d 6d 69 74 74 65 64  ters uncommitted
99f0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 66 72 6f   transaction fro
9a00: 6d 20 0a 20 20 20 20 2a 2a 20 74 68 65 20 68 61  m .    ** the ha
9a10: 73 68 2d 74 61 62 6c 65 20 62 65 66 6f 72 65 20  sh-table before 
9a20: 77 72 69 74 69 6e 67 20 61 6e 79 20 6e 65 77 20  writing any new 
9a30: 65 6e 74 72 69 65 73 2e 0a 20 20 20 20 2a 2f 0a  entries..    */.
9a40: 20 20 20 20 69 66 28 20 61 50 67 6e 6f 5b 69 64      if( aPgno[id
9a50: 78 5d 20 29 7b 0a 20 20 20 20 20 20 77 61 6c 43  x] ){.      walC
9a60: 6c 65 61 6e 75 70 48 61 73 68 28 70 57 61 6c 29  leanupHash(pWal)
9a70: 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  ;.      assert( 
9a80: 21 61 50 67 6e 6f 5b 69 64 78 5d 20 29 3b 0a 20  !aPgno[idx] );. 
9a90: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 57 72 69     }..    /* Wri
9aa0: 74 65 20 74 68 65 20 61 50 67 6e 6f 5b 5d 20 61  te the aPgno[] a
9ab0: 72 72 61 79 20 65 6e 74 72 79 20 61 6e 64 20 74  rray entry and t
9ac0: 68 65 20 68 61 73 68 2d 74 61 62 6c 65 20 73 6c  he hash-table sl
9ad0: 6f 74 2e 20 2a 2f 0a 20 20 20 20 6e 43 6f 6c 6c  ot. */.    nColl
9ae0: 69 64 65 20 3d 20 69 64 78 3b 0a 20 20 20 20 66  ide = idx;.    f
9af0: 6f 72 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28  or(iKey=walHash(
9b00: 69 50 61 67 65 29 3b 20 61 48 61 73 68 5b 69 4b  iPage); aHash[iK
9b10: 65 79 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78  ey]; iKey=walNex
9b20: 74 48 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20  tHash(iKey)){.  
9b30: 20 20 20 20 69 66 28 20 28 6e 43 6f 6c 6c 69 64      if( (nCollid
9b40: 65 2d 2d 29 3d 3d 30 20 29 20 72 65 74 75 72 6e  e--)==0 ) return
9b50: 20 53 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f   SQLITE_CORRUPT_
9b60: 42 4b 50 54 3b 0a 20 20 20 20 7d 0a 20 20 20 20  BKPT;.    }.    
9b70: 61 50 67 6e 6f 5b 69 64 78 5d 20 3d 20 69 50 61  aPgno[idx] = iPa
9b80: 67 65 3b 0a 20 20 20 20 61 48 61 73 68 5b 69 4b  ge;.    aHash[iK
9b90: 65 79 5d 20 3d 20 28 68 74 5f 73 6c 6f 74 29 69  ey] = (ht_slot)i
9ba0: 64 78 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49  dx;..#ifdef SQLI
9bb0: 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53  TE_ENABLE_EXPENS
9bc0: 49 56 45 5f 41 53 53 45 52 54 0a 20 20 20 20 2f  IVE_ASSERT.    /
9bd0: 2a 20 56 65 72 69 66 79 20 74 68 61 74 20 74 68  * Verify that th
9be0: 65 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72  e number of entr
9bf0: 69 65 73 20 69 6e 20 74 68 65 20 68 61 73 68 20  ies in the hash 
9c00: 74 61 62 6c 65 20 65 78 61 63 74 6c 79 20 65 71  table exactly eq
9c10: 75 61 6c 73 0a 20 20 20 20 2a 2a 20 74 68 65 20  uals.    ** the 
9c20: 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  number of entrie
9c30: 73 20 69 6e 20 74 68 65 20 6d 61 70 70 69 6e 67  s in the mapping
9c40: 20 72 65 67 69 6f 6e 2e 0a 20 20 20 20 2a 2f 0a   region..    */.
9c50: 20 20 20 20 7b 0a 20 20 20 20 20 20 69 6e 74 20      {.      int 
9c60: 69 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  i;           /* 
9c70: 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a  Loop counter */.
9c80: 20 20 20 20 20 20 69 6e 74 20 6e 45 6e 74 72 79        int nEntry
9c90: 20 3d 20 30 3b 20 20 2f 2a 20 4e 75 6d 62 65 72   = 0;  /* Number
9ca0: 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74   of entries in t
9cb0: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f  he hash table */
9cc0: 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  .      for(i=0; 
9cd0: 69 3c 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f  i<HASHTABLE_NSLO
9ce0: 54 3b 20 69 2b 2b 29 7b 20 69 66 28 20 61 48 61  T; i++){ if( aHa
9cf0: 73 68 5b 69 5d 20 29 20 6e 45 6e 74 72 79 2b 2b  sh[i] ) nEntry++
9d00: 3b 20 7d 0a 20 20 20 20 20 20 61 73 73 65 72 74  ; }.      assert
9d10: 28 20 6e 45 6e 74 72 79 3d 3d 69 64 78 20 29 3b  ( nEntry==idx );
9d20: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 56  .    }..    /* V
9d30: 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20 65  erify that the e
9d40: 76 65 72 79 20 65 6e 74 72 79 20 69 6e 20 74 68  very entry in th
9d50: 65 20 6d 61 70 70 69 6e 67 20 72 65 67 69 6f 6e  e mapping region
9d60: 20 69 73 20 72 65 61 63 68 61 62 6c 65 0a 20 20   is reachable.  
9d70: 20 20 2a 2a 20 76 69 61 20 74 68 65 20 68 61 73    ** via the has
9d80: 68 20 74 61 62 6c 65 2e 20 20 54 68 69 73 20 74  h table.  This t
9d90: 75 72 6e 73 20 6f 75 74 20 74 6f 20 62 65 20 61  urns out to be a
9da0: 20 72 65 61 6c 6c 79 2c 20 72 65 61 6c 6c 79 20   really, really 
9db0: 65 78 70 65 6e 73 69 76 65 0a 20 20 20 20 2a 2a  expensive.    **
9dc0: 20 74 68 69 6e 67 20 74 6f 20 63 68 65 63 6b 2c   thing to check,
9dd0: 20 73 6f 20 6f 6e 6c 79 20 64 6f 20 74 68 69 73   so only do this
9de0: 20 6f 63 63 61 73 69 6f 6e 61 6c 6c 79 20 2d 20   occasionally - 
9df0: 6e 6f 74 20 6f 6e 20 65 76 65 72 79 0a 20 20 20  not on every.   
9e00: 20 2a 2a 20 69 74 65 72 61 74 69 6f 6e 2e 0a 20   ** iteration.. 
9e10: 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 28 69     */.    if( (i
9e20: 64 78 26 30 78 33 66 66 29 3d 3d 30 20 29 7b 0a  dx&0x3ff)==0 ){.
9e30: 20 20 20 20 20 20 69 6e 74 20 69 3b 20 20 20 20        int i;    
9e40: 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63         /* Loop c
9e50: 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20 20 20 20  ounter */.      
9e60: 66 6f 72 28 69 3d 31 3b 20 69 3c 3d 69 64 78 3b  for(i=1; i<=idx;
9e70: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 66   i++){.        f
9e80: 6f 72 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28  or(iKey=walHash(
9e90: 61 50 67 6e 6f 5b 69 5d 29 3b 20 61 48 61 73 68  aPgno[i]); aHash
9ea0: 5b 69 4b 65 79 5d 3b 20 69 4b 65 79 3d 77 61 6c  [iKey]; iKey=wal
9eb0: 4e 65 78 74 48 61 73 68 28 69 4b 65 79 29 29 7b  NextHash(iKey)){
9ec0: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 61  .          if( a
9ed0: 48 61 73 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 20  Hash[iKey]==i ) 
9ee0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d  break;.        }
9ef0: 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28  .        assert(
9f00: 20 61 48 61 73 68 5b 69 4b 65 79 5d 3d 3d 69 20   aHash[iKey]==i 
9f10: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
9f20: 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54  .#endif /* SQLIT
9f30: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
9f40: 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a 20 20 7d  VE_ASSERT */.  }
9f50: 0a 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  ...  return rc;.
9f60: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 63 6f 76 65  }.../*.** Recove
9f70: 72 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  r the wal-index 
9f80: 62 79 20 72 65 61 64 69 6e 67 20 74 68 65 20 77  by reading the w
9f90: 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66  rite-ahead log f
9fa0: 69 6c 65 2e 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73  ile. .**.** This
9fb0: 20 72 6f 75 74 69 6e 65 20 66 69 72 73 74 20 74   routine first t
9fc0: 72 69 65 73 20 74 6f 20 65 73 74 61 62 6c 69 73  ries to establis
9fd0: 68 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c  h an exclusive l
9fe0: 6f 63 6b 20 6f 6e 20 74 68 65 0a 2a 2a 20 77 61  ock on the.** wa
9ff0: 6c 2d 69 6e 64 65 78 20 74 6f 20 70 72 65 76 65  l-index to preve
a000: 6e 74 20 6f 74 68 65 72 20 74 68 72 65 61 64 73  nt other threads
a010: 2f 70 72 6f 63 65 73 73 65 73 20 66 72 6f 6d 20  /processes from 
a020: 64 6f 69 6e 67 20 61 6e 79 74 68 69 6e 67 0a 2a  doing anything.*
a030: 2a 20 77 69 74 68 20 74 68 65 20 57 41 4c 20 6f  * with the WAL o
a040: 72 20 77 61 6c 2d 69 6e 64 65 78 20 77 68 69 6c  r wal-index whil
a050: 65 20 72 65 63 6f 76 65 72 79 20 69 73 20 72 75  e recovery is ru
a060: 6e 6e 69 6e 67 2e 20 20 54 68 65 0a 2a 2a 20 57  nning.  The.** W
a070: 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20  AL_RECOVER_LOCK 
a080: 69 73 20 61 6c 73 6f 20 68 65 6c 64 20 73 6f 20  is also held so 
a090: 74 68 61 74 20 6f 74 68 65 72 20 74 68 72 65 61  that other threa
a0a0: 64 73 20 77 69 6c 6c 20 6b 6e 6f 77 0a 2a 2a 20  ds will know.** 
a0b0: 74 68 61 74 20 74 68 69 73 20 74 68 72 65 61 64  that this thread
a0c0: 20 69 73 20 72 75 6e 6e 69 6e 67 20 72 65 63 6f   is running reco
a0d0: 76 65 72 79 2e 20 20 49 66 20 75 6e 61 62 6c 65  very.  If unable
a0e0: 20 74 6f 20 65 73 74 61 62 6c 69 73 68 0a 2a 2a   to establish.**
a0f0: 20 74 68 65 20 6e 65 63 65 73 73 61 72 79 20 6c   the necessary l
a100: 6f 63 6b 73 2c 20 74 68 69 73 20 72 6f 75 74 69  ocks, this routi
a110: 6e 65 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  ne returns SQLIT
a120: 45 5f 42 55 53 59 2e 0a 2a 2f 0a 73 74 61 74 69  E_BUSY..*/.stati
a130: 63 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 52 65  c int walIndexRe
a140: 63 6f 76 65 72 28 57 61 6c 20 2a 70 57 61 6c 29  cover(Wal *pWal)
a150: 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  {.  int rc;     
a160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a170: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f      /* Return Co
a180: 64 65 20 2a 2f 0a 20 20 69 36 34 20 6e 53 69 7a  de */.  i64 nSiz
a190: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
a1a0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
a1b0: 6f 66 20 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a 20  of log file */. 
a1c0: 20 75 33 32 20 61 46 72 61 6d 65 43 6b 73 75 6d   u32 aFrameCksum
a1d0: 5b 32 5d 20 3d 20 7b 30 2c 20 30 7d 3b 0a 20 20  [2] = {0, 0};.  
a1e0: 69 6e 74 20 69 4c 6f 63 6b 3b 20 20 20 20 20 20  int iLock;      
a1f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a200: 2f 2a 20 4c 6f 63 6b 20 6f 66 66 73 65 74 20 74  /* Lock offset t
a210: 6f 20 6c 6f 63 6b 20 66 6f 72 20 63 68 65 63 6b  o lock for check
a220: 70 6f 69 6e 74 20 2a 2f 0a 20 20 69 6e 74 20 6e  point */.  int n
a230: 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Lock;           
a240: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
a250: 6d 62 65 72 20 6f 66 20 6c 6f 63 6b 73 20 74 6f  mber of locks to
a260: 20 68 6f 6c 64 20 2a 2f 0a 0a 20 20 2f 2a 20 4f   hold */..  /* O
a270: 62 74 61 69 6e 20 61 6e 20 65 78 63 6c 75 73 69  btain an exclusi
a280: 76 65 20 6c 6f 63 6b 20 6f 6e 20 61 6c 6c 20 62  ve lock on all b
a290: 79 74 65 20 69 6e 20 74 68 65 20 6c 6f 63 6b 69  yte in the locki
a2a0: 6e 67 20 72 61 6e 67 65 20 6e 6f 74 20 61 6c 72  ng range not alr
a2b0: 65 61 64 79 0a 20 20 2a 2a 20 6c 6f 63 6b 65 64  eady.  ** locked
a2c0: 20 62 79 20 74 68 65 20 63 61 6c 6c 65 72 2e 20   by the caller. 
a2d0: 54 68 65 20 63 61 6c 6c 65 72 20 69 73 20 67 75  The caller is gu
a2e0: 61 72 61 6e 74 65 65 64 20 74 6f 20 68 61 76 65  aranteed to have
a2f0: 20 6c 6f 63 6b 65 64 20 74 68 65 0a 20 20 2a 2a   locked the.  **
a300: 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20   WAL_WRITE_LOCK 
a310: 62 79 74 65 2c 20 61 6e 64 20 6d 61 79 20 68 61  byte, and may ha
a320: 76 65 20 61 6c 73 6f 20 6c 6f 63 6b 65 64 20 74  ve also locked t
a330: 68 65 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b  he WAL_CKPT_LOCK
a340: 20 62 79 74 65 2e 0a 20 20 2a 2a 20 49 66 20 73   byte..  ** If s
a350: 75 63 63 65 73 73 66 75 6c 2c 20 74 68 65 20 73  uccessful, the s
a360: 61 6d 65 20 62 79 74 65 73 20 74 68 61 74 20 61  ame bytes that a
a370: 72 65 20 6c 6f 63 6b 65 64 20 68 65 72 65 20 61  re locked here a
a380: 72 65 20 75 6e 6c 6f 63 6b 65 64 20 62 65 66 6f  re unlocked befo
a390: 72 65 0a 20 20 2a 2a 20 74 68 69 73 20 66 75 6e  re.  ** this fun
a3a0: 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e 0a 20  ction returns.. 
a3b0: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57   */.  assert( pW
a3c0: 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 31 20  al->ckptLock==1 
a3d0: 7c 7c 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63  || pWal->ckptLoc
a3e0: 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74  k==0 );.  assert
a3f0: 28 20 57 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52  ( WAL_ALL_BUT_WR
a400: 49 54 45 3d 3d 57 41 4c 5f 57 52 49 54 45 5f 4c  ITE==WAL_WRITE_L
a410: 4f 43 4b 2b 31 20 29 3b 0a 20 20 61 73 73 65 72  OCK+1 );.  asser
a420: 74 28 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b  t( WAL_CKPT_LOCK
a430: 3d 3d 57 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52  ==WAL_ALL_BUT_WR
a440: 49 54 45 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ITE );.  assert(
a450: 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
a460: 20 29 3b 0a 20 20 69 4c 6f 63 6b 20 3d 20 57 41   );.  iLock = WA
a470: 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20  L_ALL_BUT_WRITE 
a480: 2b 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b  + pWal->ckptLock
a490: 3b 0a 20 20 6e 4c 6f 63 6b 20 3d 20 53 51 4c 49  ;.  nLock = SQLI
a4a0: 54 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 20 2d 20 69  TE_SHM_NLOCK - i
a4b0: 4c 6f 63 6b 3b 0a 20 20 72 63 20 3d 20 77 61 6c  Lock;.  rc = wal
a4c0: 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  LockExclusive(pW
a4d0: 61 6c 2c 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b  al, iLock, nLock
a4e0: 29 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20  );.  if( rc ){. 
a4f0: 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
a500: 7d 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  }.  WALTRACE(("W
a510: 41 4c 25 70 3a 20 72 65 63 6f 76 65 72 79 20 62  AL%p: recovery b
a520: 65 67 69 6e 2e 2e 2e 5c 6e 22 2c 20 70 57 61 6c  egin...\n", pWal
a530: 29 29 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 70  ));..  memset(&p
a540: 57 61 6c 2d 3e 68 64 72 2c 20 30 2c 20 73 69 7a  Wal->hdr, 0, siz
a550: 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29  eof(WalIndexHdr)
a560: 29 3b 0a 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  );..  rc = sqlit
a570: 65 33 4f 73 46 69 6c 65 53 69 7a 65 28 70 57 61  e3OsFileSize(pWa
a580: 6c 2d 3e 70 57 61 6c 46 64 2c 20 26 6e 53 69 7a  l->pWalFd, &nSiz
a590: 65 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  e);.  if( rc!=SQ
a5a0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 67  LITE_OK ){.    g
a5b0: 6f 74 6f 20 72 65 63 6f 76 65 72 79 5f 65 72 72  oto recovery_err
a5c0: 6f 72 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6e  or;.  }..  if( n
a5d0: 53 69 7a 65 3e 57 41 4c 5f 48 44 52 53 49 5a 45  Size>WAL_HDRSIZE
a5e0: 20 29 7b 0a 20 20 20 20 75 38 20 61 42 75 66 5b   ){.    u8 aBuf[
a5f0: 57 41 4c 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20  WAL_HDRSIZE];   
a600: 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
a610: 74 6f 20 6c 6f 61 64 20 57 41 4c 20 68 65 61 64  to load WAL head
a620: 65 72 20 69 6e 74 6f 20 2a 2f 0a 20 20 20 20 75  er into */.    u
a630: 38 20 2a 61 46 72 61 6d 65 20 3d 20 30 3b 20 20  8 *aFrame = 0;  
a640: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
a650: 4d 61 6c 6c 6f 63 27 64 20 62 75 66 66 65 72 20  Malloc'd buffer 
a660: 74 6f 20 6c 6f 61 64 20 65 6e 74 69 72 65 20 66  to load entire f
a670: 72 61 6d 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20  rame */.    int 
a680: 73 7a 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20  szFrame;        
a690: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
a6a0: 62 65 72 20 6f 66 20 62 79 74 65 73 20 69 6e 20  ber of bytes in 
a6b0: 62 75 66 66 65 72 20 61 46 72 61 6d 65 5b 5d 20  buffer aFrame[] 
a6c0: 2a 2f 0a 20 20 20 20 75 38 20 2a 61 44 61 74 61  */.    u8 *aData
a6d0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
a6e0: 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20       /* Pointer 
a6f0: 74 6f 20 64 61 74 61 20 70 61 72 74 20 6f 66 20  to data part of 
a700: 61 46 72 61 6d 65 20 62 75 66 66 65 72 20 2a 2f  aFrame buffer */
a710: 0a 20 20 20 20 69 6e 74 20 69 46 72 61 6d 65 3b  .    int iFrame;
a720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a730: 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6c     /* Index of l
a740: 61 73 74 20 66 72 61 6d 65 20 72 65 61 64 20 2a  ast frame read *
a750: 2f 0a 20 20 20 20 69 36 34 20 69 4f 66 66 73 65  /.    i64 iOffse
a760: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
a770: 20 20 20 20 2f 2a 20 4e 65 78 74 20 6f 66 66 73      /* Next offs
a780: 65 74 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20  et to read from 
a790: 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20  log file */.    
a7a0: 69 6e 74 20 73 7a 50 61 67 65 3b 20 20 20 20 20  int szPage;     
a7b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
a7c0: 20 50 61 67 65 20 73 69 7a 65 20 61 63 63 6f 72   Page size accor
a7d0: 64 69 6e 67 20 74 6f 20 74 68 65 20 6c 6f 67 20  ding to the log 
a7e0: 2a 2f 0a 20 20 20 20 75 33 32 20 6d 61 67 69 63  */.    u32 magic
a7f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
a800: 20 20 20 20 20 2f 2a 20 4d 61 67 69 63 20 76 61       /* Magic va
a810: 6c 75 65 20 72 65 61 64 20 66 72 6f 6d 20 57 41  lue read from WA
a820: 4c 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 20 20  L header */.    
a830: 75 33 32 20 76 65 72 73 69 6f 6e 3b 20 20 20 20  u32 version;    
a840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
a850: 20 4d 61 67 69 63 20 76 61 6c 75 65 20 72 65 61   Magic value rea
a860: 64 20 66 72 6f 6d 20 57 41 4c 20 68 65 61 64 65  d from WAL heade
a870: 72 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 52 65 61  r */..    /* Rea
a880: 64 20 69 6e 20 74 68 65 20 57 41 4c 20 68 65 61  d in the WAL hea
a890: 64 65 72 2e 20 2a 2f 0a 20 20 20 20 72 63 20 3d  der. */.    rc =
a8a0: 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70   sqlite3OsRead(p
a8b0: 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 42 75  Wal->pWalFd, aBu
a8c0: 66 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2c 20  f, WAL_HDRSIZE, 
a8d0: 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  0);.    if( rc!=
a8e0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
a8f0: 20 20 20 67 6f 74 6f 20 72 65 63 6f 76 65 72 79     goto recovery
a900: 5f 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a 0a 20  _error;.    }.. 
a910: 20 20 20 2f 2a 20 49 66 20 74 68 65 20 64 61 74     /* If the dat
a920: 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65 20  abase page size 
a930: 69 73 20 6e 6f 74 20 61 20 70 6f 77 65 72 20 6f  is not a power o
a940: 66 20 74 77 6f 2c 20 6f 72 20 69 73 20 67 72 65  f two, or is gre
a950: 61 74 65 72 20 74 68 61 6e 0a 20 20 20 20 2a 2a  ater than.    **
a960: 20 53 51 4c 49 54 45 5f 4d 41 58 5f 50 41 47 45   SQLITE_MAX_PAGE
a970: 5f 53 49 5a 45 2c 20 63 6f 6e 63 6c 75 64 65 20  _SIZE, conclude 
a980: 74 68 61 74 20 74 68 65 20 57 41 4c 20 66 69 6c  that the WAL fil
a990: 65 20 63 6f 6e 74 61 69 6e 73 20 6e 6f 20 76 61  e contains no va
a9a0: 6c 69 64 20 0a 20 20 20 20 2a 2a 20 64 61 74 61  lid .    ** data
a9b0: 2e 20 53 69 6d 69 6c 61 72 6c 79 2c 20 69 66 20  . Similarly, if 
a9c0: 74 68 65 20 27 6d 61 67 69 63 27 20 76 61 6c 75  the 'magic' valu
a9d0: 65 20 69 73 20 69 6e 76 61 6c 69 64 2c 20 69 67  e is invalid, ig
a9e0: 6e 6f 72 65 20 74 68 65 20 77 68 6f 6c 65 0a 20  nore the whole. 
a9f0: 20 20 20 2a 2a 20 57 41 4c 20 66 69 6c 65 2e 0a     ** WAL file..
aa00: 20 20 20 20 2a 2f 0a 20 20 20 20 6d 61 67 69 63      */.    magic
aa10: 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62 79   = sqlite3Get4by
aa20: 74 65 28 26 61 42 75 66 5b 30 5d 29 3b 0a 20 20  te(&aBuf[0]);.  
aa30: 20 20 73 7a 50 61 67 65 20 3d 20 73 71 6c 69 74    szPage = sqlit
aa40: 65 33 47 65 74 34 62 79 74 65 28 26 61 42 75 66  e3Get4byte(&aBuf
aa50: 5b 38 5d 29 3b 0a 20 20 20 20 69 66 28 20 28 6d  [8]);.    if( (m
aa60: 61 67 69 63 26 30 78 46 46 46 46 46 46 46 45 29  agic&0xFFFFFFFE)
aa70: 21 3d 57 41 4c 5f 4d 41 47 49 43 20 0a 20 20 20  !=WAL_MAGIC .   
aa80: 20 20 7c 7c 20 73 7a 50 61 67 65 26 28 73 7a 50    || szPage&(szP
aa90: 61 67 65 2d 31 29 20 0a 20 20 20 20 20 7c 7c 20  age-1) .     || 
aaa0: 73 7a 50 61 67 65 3e 53 51 4c 49 54 45 5f 4d 41  szPage>SQLITE_MA
aab0: 58 5f 50 41 47 45 5f 53 49 5a 45 20 0a 20 20 20  X_PAGE_SIZE .   
aac0: 20 20 7c 7c 20 73 7a 50 61 67 65 3c 35 31 32 20    || szPage<512 
aad0: 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 67 6f  .    ){.      go
aae0: 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20 20  to finished;.   
aaf0: 20 7d 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72   }.    pWal->hdr
ab00: 2e 62 69 67 45 6e 64 43 6b 73 75 6d 20 3d 20 28  .bigEndCksum = (
ab10: 75 38 29 28 6d 61 67 69 63 26 30 78 30 30 30 30  u8)(magic&0x0000
ab20: 30 30 30 31 29 3b 0a 20 20 20 20 70 57 61 6c 2d  0001);.    pWal-
ab30: 3e 73 7a 50 61 67 65 20 3d 20 28 75 31 36 29 73  >szPage = (u16)s
ab40: 7a 50 61 67 65 3b 0a 20 20 20 20 70 57 61 6c 2d  zPage;.    pWal-
ab50: 3e 6e 43 6b 70 74 20 3d 20 73 71 6c 69 74 65 33  >nCkpt = sqlite3
ab60: 47 65 74 34 62 79 74 65 28 26 61 42 75 66 5b 31  Get4byte(&aBuf[1
ab70: 32 5d 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28  2]);.    memcpy(
ab80: 26 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74  &pWal->hdr.aSalt
ab90: 2c 20 26 61 42 75 66 5b 31 36 5d 2c 20 38 29 3b  , &aBuf[16], 8);
aba0: 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20  ..    /* Verify 
abb0: 74 68 61 74 20 74 68 65 20 57 41 4c 20 68 65 61  that the WAL hea
abc0: 64 65 72 20 63 68 65 63 6b 73 75 6d 20 69 73 20  der checksum is 
abd0: 63 6f 72 72 65 63 74 20 2a 2f 0a 20 20 20 20 77  correct */.    w
abe0: 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
abf0: 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64  pWal->hdr.bigEnd
ac00: 43 6b 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49  Cksum==SQLITE_BI
ac10: 47 45 4e 44 49 41 4e 2c 20 0a 20 20 20 20 20 20  GENDIAN, .      
ac20: 20 20 61 42 75 66 2c 20 57 41 4c 5f 48 44 52 53    aBuf, WAL_HDRS
ac30: 49 5a 45 2d 32 2a 34 2c 20 30 2c 20 70 57 61 6c  IZE-2*4, 0, pWal
ac40: 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
ac50: 6d 0a 20 20 20 20 29 3b 0a 20 20 20 20 69 66 28  m.    );.    if(
ac60: 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
ac70: 65 43 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74  eCksum[0]!=sqlit
ac80: 65 33 47 65 74 34 62 79 74 65 28 26 61 42 75 66  e3Get4byte(&aBuf
ac90: 5b 32 34 5d 29 0a 20 20 20 20 20 7c 7c 20 70 57  [24]).     || pW
aca0: 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
acb0: 73 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33 47  sum[1]!=sqlite3G
acc0: 65 74 34 62 79 74 65 28 26 61 42 75 66 5b 32 38  et4byte(&aBuf[28
acd0: 5d 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20  ]).    ){.      
ace0: 67 6f 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20  goto finished;. 
acf0: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 56 65 72     }..    /* Ver
ad00: 69 66 79 20 74 68 61 74 20 74 68 65 20 76 65 72  ify that the ver
ad10: 73 69 6f 6e 20 6e 75 6d 62 65 72 20 6f 6e 20 74  sion number on t
ad20: 68 65 20 57 41 4c 20 66 6f 72 6d 61 74 20 69 73  he WAL format is
ad30: 20 6f 6e 65 20 74 68 61 74 0a 20 20 20 20 2a 2a   one that.    **
ad40: 20 61 72 65 20 61 62 6c 65 20 74 6f 20 75 6e 64   are able to und
ad50: 65 72 73 74 61 6e 64 20 2a 2f 0a 20 20 20 20 76  erstand */.    v
ad60: 65 72 73 69 6f 6e 20 3d 20 73 71 6c 69 74 65 33  ersion = sqlite3
ad70: 47 65 74 34 62 79 74 65 28 26 61 42 75 66 5b 34  Get4byte(&aBuf[4
ad80: 5d 29 3b 0a 20 20 20 20 69 66 28 20 76 65 72 73  ]);.    if( vers
ad90: 69 6f 6e 21 3d 57 41 4c 5f 4d 41 58 5f 56 45 52  ion!=WAL_MAX_VER
ada0: 53 49 4f 4e 20 29 7b 0a 20 20 20 20 20 20 72 63  SION ){.      rc
adb0: 20 3d 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f 50   = SQLITE_CANTOP
adc0: 45 4e 5f 42 4b 50 54 3b 0a 20 20 20 20 20 20 67  EN_BKPT;.      g
add0: 6f 74 6f 20 66 69 6e 69 73 68 65 64 3b 0a 20 20  oto finished;.  
ade0: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 4d 61 6c 6c    }..    /* Mall
adf0: 6f 63 20 61 20 62 75 66 66 65 72 20 74 6f 20 72  oc a buffer to r
ae00: 65 61 64 20 66 72 61 6d 65 73 20 69 6e 74 6f 2e  ead frames into.
ae10: 20 2a 2f 0a 20 20 20 20 73 7a 46 72 61 6d 65 20   */.    szFrame 
ae20: 3d 20 73 7a 50 61 67 65 20 2b 20 57 41 4c 5f 46  = szPage + WAL_F
ae30: 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b 0a 20 20  RAME_HDRSIZE;.  
ae40: 20 20 61 46 72 61 6d 65 20 3d 20 28 75 38 20 2a    aFrame = (u8 *
ae50: 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28  )sqlite3_malloc(
ae60: 73 7a 46 72 61 6d 65 29 3b 0a 20 20 20 20 69 66  szFrame);.    if
ae70: 28 20 21 61 46 72 61 6d 65 20 29 7b 0a 20 20 20  ( !aFrame ){.   
ae80: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
ae90: 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f  OMEM;.      goto
aea0: 20 72 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b   recovery_error;
aeb0: 0a 20 20 20 20 7d 0a 20 20 20 20 61 44 61 74 61  .    }.    aData
aec0: 20 3d 20 26 61 46 72 61 6d 65 5b 57 41 4c 5f 46   = &aFrame[WAL_F
aed0: 52 41 4d 45 5f 48 44 52 53 49 5a 45 5d 3b 0a 0a  RAME_HDRSIZE];..
aee0: 20 20 20 20 2f 2a 20 52 65 61 64 20 61 6c 6c 20      /* Read all 
aef0: 66 72 61 6d 65 73 20 66 72 6f 6d 20 74 68 65 20  frames from the 
af00: 6c 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 20  log file. */.   
af10: 20 69 46 72 61 6d 65 20 3d 20 30 3b 0a 20 20 20   iFrame = 0;.   
af20: 20 66 6f 72 28 69 4f 66 66 73 65 74 3d 57 41 4c   for(iOffset=WAL
af30: 5f 48 44 52 53 49 5a 45 3b 20 28 69 4f 66 66 73  _HDRSIZE; (iOffs
af40: 65 74 2b 73 7a 46 72 61 6d 65 29 3c 3d 6e 53 69  et+szFrame)<=nSi
af50: 7a 65 3b 20 69 4f 66 66 73 65 74 2b 3d 73 7a 46  ze; iOffset+=szF
af60: 72 61 6d 65 29 7b 0a 20 20 20 20 20 20 75 33 32  rame){.      u32
af70: 20 70 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20   pgno;          
af80: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
af90: 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72  base page number
afa0: 20 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20 20   for frame */.  
afb0: 20 20 20 20 75 33 32 20 6e 54 72 75 6e 63 61 74      u32 nTruncat
afc0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
afd0: 2f 2a 20 64 62 73 69 7a 65 20 66 69 65 6c 64 20  /* dbsize field 
afe0: 66 72 6f 6d 20 66 72 61 6d 65 20 68 65 61 64 65  from frame heade
aff0: 72 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 69  r */.      int i
b000: 73 56 61 6c 69 64 3b 20 20 20 20 20 20 20 20 20  sValid;         
b010: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69         /* True i
b020: 66 20 74 68 69 73 20 66 72 61 6d 65 20 69 73 20  f this frame is 
b030: 76 61 6c 69 64 20 2a 2f 0a 0a 20 20 20 20 20 20  valid */..      
b040: 2f 2a 20 52 65 61 64 20 61 6e 64 20 64 65 63 6f  /* Read and deco
b050: 64 65 20 74 68 65 20 6e 65 78 74 20 6c 6f 67 20  de the next log 
b060: 66 72 61 6d 65 2e 20 2a 2f 0a 20 20 20 20 20 20  frame. */.      
b070: 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65  rc = sqlite3OsRe
b080: 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  ad(pWal->pWalFd,
b090: 20 61 46 72 61 6d 65 2c 20 73 7a 46 72 61 6d 65   aFrame, szFrame
b0a0: 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20  , iOffset);.    
b0b0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
b0c0: 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  _OK ) break;.   
b0d0: 20 20 20 69 73 56 61 6c 69 64 20 3d 20 77 61 6c     isValid = wal
b0e0: 44 65 63 6f 64 65 46 72 61 6d 65 28 70 57 61 6c  DecodeFrame(pWal
b0f0: 2c 20 26 70 67 6e 6f 2c 20 26 6e 54 72 75 6e 63  , &pgno, &nTrunc
b100: 61 74 65 2c 20 61 44 61 74 61 2c 20 61 46 72 61  ate, aData, aFra
b110: 6d 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21  me);.      if( !
b120: 69 73 56 61 6c 69 64 20 29 20 62 72 65 61 6b 3b  isValid ) break;
b130: 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 49  .      rc = walI
b140: 6e 64 65 78 41 70 70 65 6e 64 28 70 57 61 6c 2c  ndexAppend(pWal,
b150: 20 2b 2b 69 46 72 61 6d 65 2c 20 70 67 6e 6f 29   ++iFrame, pgno)
b160: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
b170: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61  SQLITE_OK ) brea
b180: 6b 3b 0a 0a 20 20 20 20 20 20 2f 2a 20 49 66 20  k;..      /* If 
b190: 6e 54 72 75 6e 63 61 74 65 20 69 73 20 6e 6f 6e  nTruncate is non
b1a0: 2d 7a 65 72 6f 2c 20 74 68 69 73 20 69 73 20 61  -zero, this is a
b1b0: 20 63 6f 6d 6d 69 74 20 72 65 63 6f 72 64 2e 20   commit record. 
b1c0: 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 6e 54 72  */.      if( nTr
b1d0: 75 6e 63 61 74 65 20 29 7b 0a 20 20 20 20 20 20  uncate ){.      
b1e0: 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72    pWal->hdr.mxFr
b1f0: 61 6d 65 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20  ame = iFrame;.  
b200: 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e        pWal->hdr.
b210: 6e 50 61 67 65 20 3d 20 6e 54 72 75 6e 63 61 74  nPage = nTruncat
b220: 65 3b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d  e;.        pWal-
b230: 3e 68 64 72 2e 73 7a 50 61 67 65 20 3d 20 28 75  >hdr.szPage = (u
b240: 31 36 29 73 7a 50 61 67 65 3b 0a 20 20 20 20 20  16)szPage;.     
b250: 20 20 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30     aFrameCksum[0
b260: 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46  ] = pWal->hdr.aF
b270: 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20  rameCksum[0];.  
b280: 20 20 20 20 20 20 61 46 72 61 6d 65 43 6b 73 75        aFrameCksu
b290: 6d 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72  m[1] = pWal->hdr
b2a0: 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b  .aFrameCksum[1];
b2b0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
b2c0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
b2d0: 28 61 46 72 61 6d 65 29 3b 0a 20 20 7d 0a 0a 66  (aFrame);.  }..f
b2e0: 69 6e 69 73 68 65 64 3a 0a 20 20 69 66 28 20 72  inished:.  if( r
b2f0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
b300: 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c      volatile Wal
b310: 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b  CkptInfo *pInfo;
b320: 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20 20  .    int i;.    
b330: 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
b340: 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 46 72 61 6d  Cksum[0] = aFram
b350: 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 20 20 70  eCksum[0];.    p
b360: 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
b370: 6b 73 75 6d 5b 31 5d 20 3d 20 61 46 72 61 6d 65  ksum[1] = aFrame
b380: 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 20 20 77 61  Cksum[1];.    wa
b390: 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72 28 70  lIndexWriteHdr(p
b3a0: 57 61 6c 29 3b 0a 0a 20 20 20 20 2f 2a 20 52 65  Wal);..    /* Re
b3b0: 73 65 74 20 74 68 65 20 63 68 65 63 6b 70 6f 69  set the checkpoi
b3c0: 6e 74 2d 68 65 61 64 65 72 2e 20 54 68 69 73 20  nt-header. This 
b3d0: 69 73 20 73 61 66 65 20 62 65 63 61 75 73 65 20  is safe because 
b3e0: 74 68 69 73 20 74 68 72 65 61 64 20 69 73 20 0a  this thread is .
b3f0: 20 20 20 20 2a 2a 20 63 75 72 72 65 6e 74 6c 79      ** currently
b400: 20 68 6f 6c 64 69 6e 67 20 6c 6f 63 6b 73 20 74   holding locks t
b410: 68 61 74 20 65 78 63 6c 75 64 65 20 61 6c 6c 20  hat exclude all 
b420: 6f 74 68 65 72 20 72 65 61 64 65 72 73 2c 20 77  other readers, w
b430: 72 69 74 65 72 73 20 61 6e 64 0a 20 20 20 20 2a  riters and.    *
b440: 2a 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 73 2e  * checkpointers.
b450: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 70 49 6e 66  .    */.    pInf
b460: 6f 20 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f 28  o = walCkptInfo(
b470: 70 57 61 6c 29 3b 0a 20 20 20 20 70 49 6e 66 6f  pWal);.    pInfo
b480: 2d 3e 6e 42 61 63 6b 66 69 6c 6c 20 3d 20 30 3b  ->nBackfill = 0;
b490: 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 61 52 65 61  .    pInfo->aRea
b4a0: 64 4d 61 72 6b 5b 30 5d 20 3d 20 30 3b 0a 20 20  dMark[0] = 0;.  
b4b0: 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c    for(i=1; i<WAL
b4c0: 5f 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29 20 70  _NREADER; i++) p
b4d0: 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b  Info->aReadMark[
b4e0: 69 5d 20 3d 20 52 45 41 44 4d 41 52 4b 5f 4e 4f  i] = READMARK_NO
b4f0: 54 5f 55 53 45 44 3b 0a 20 20 7d 0a 0a 72 65 63  T_USED;.  }..rec
b500: 6f 76 65 72 79 5f 65 72 72 6f 72 3a 0a 20 20 57  overy_error:.  W
b510: 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
b520: 20 72 65 63 6f 76 65 72 79 20 25 73 5c 6e 22 2c   recovery %s\n",
b530: 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69   pWal, rc ? "fai
b540: 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
b550: 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
b560: 69 76 65 28 70 57 61 6c 2c 20 69 4c 6f 63 6b 2c  ive(pWal, iLock,
b570: 20 6e 4c 6f 63 6b 29 3b 0a 20 20 72 65 74 75 72   nLock);.  retur
b580: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  n rc;.}../*.** C
b590: 6c 6f 73 65 20 61 6e 20 6f 70 65 6e 20 77 61 6c  lose an open wal
b5a0: 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 73 74 61 74 69  -index..*/.stati
b5b0: 63 20 76 6f 69 64 20 77 61 6c 49 6e 64 65 78 43  c void walIndexC
b5c0: 6c 6f 73 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20  lose(Wal *pWal, 
b5d0: 69 6e 74 20 69 73 44 65 6c 65 74 65 29 7b 0a 20  int isDelete){. 
b5e0: 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 43 6c 6f   sqlite3OsShmClo
b5f0: 73 65 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20  se(pWal->pDbFd, 
b600: 69 73 44 65 6c 65 74 65 29 3b 0a 7d 0a 0a 2f 2a  isDelete);.}../*
b610: 20 0a 2a 2a 20 4f 70 65 6e 20 61 20 63 6f 6e 6e   .** Open a conn
b620: 65 63 74 69 6f 6e 20 74 6f 20 74 68 65 20 57 41  ection to the WA
b630: 4c 20 66 69 6c 65 20 7a 57 61 6c 4e 61 6d 65 2e  L file zWalName.
b640: 20 54 68 65 20 64 61 74 61 62 61 73 65 20 66 69   The database fi
b650: 6c 65 20 6d 75 73 74 20 0a 2a 2a 20 61 6c 72 65  le must .** alre
b660: 61 64 79 20 62 65 20 6f 70 65 6e 65 64 20 6f 6e  ady be opened on
b670: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 70 44 62 46   connection pDbF
b680: 64 2e 20 54 68 65 20 62 75 66 66 65 72 20 74 68  d. The buffer th
b690: 61 74 20 7a 57 61 6c 4e 61 6d 65 20 70 6f 69 6e  at zWalName poin
b6a0: 74 73 0a 2a 2a 20 74 6f 20 6d 75 73 74 20 72 65  ts.** to must re
b6b0: 6d 61 69 6e 20 76 61 6c 69 64 20 66 6f 72 20 74  main valid for t
b6c0: 68 65 20 6c 69 66 65 74 69 6d 65 20 6f 66 20 74  he lifetime of t
b6d0: 68 65 20 72 65 74 75 72 6e 65 64 20 57 61 6c 2a  he returned Wal*
b6e0: 20 68 61 6e 64 6c 65 2e 0a 2a 2a 0a 2a 2a 20 41   handle..**.** A
b6f0: 20 53 48 41 52 45 44 20 6c 6f 63 6b 20 73 68 6f   SHARED lock sho
b700: 75 6c 64 20 62 65 20 68 65 6c 64 20 6f 6e 20 74  uld be held on t
b710: 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
b720: 20 77 68 65 6e 20 74 68 69 73 20 66 75 6e 63 74   when this funct
b730: 69 6f 6e 0a 2a 2a 20 69 73 20 63 61 6c 6c 65 64  ion.** is called
b740: 2e 20 54 68 65 20 70 75 72 70 6f 73 65 20 6f 66  . The purpose of
b750: 20 74 68 69 73 20 53 48 41 52 45 44 20 6c 6f 63   this SHARED loc
b760: 6b 20 69 73 20 74 6f 20 70 72 65 76 65 6e 74 20  k is to prevent 
b770: 61 6e 79 20 6f 74 68 65 72 0a 2a 2a 20 63 6c 69  any other.** cli
b780: 65 6e 74 20 66 72 6f 6d 20 75 6e 6c 69 6e 6b 69  ent from unlinki
b790: 6e 67 20 74 68 65 20 57 41 4c 20 6f 72 20 77 61  ng the WAL or wa
b7a0: 6c 2d 69 6e 64 65 78 20 66 69 6c 65 2e 20 49 66  l-index file. If
b7b0: 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65 73 73   another process
b7c0: 0a 2a 2a 20 77 65 72 65 20 74 6f 20 64 6f 20 74  .** were to do t
b7d0: 68 69 73 20 6a 75 73 74 20 61 66 74 65 72 20 74  his just after t
b7e0: 68 69 73 20 63 6c 69 65 6e 74 20 6f 70 65 6e 65  his client opene
b7f0: 64 20 6f 6e 65 20 6f 66 20 74 68 65 73 65 20 66  d one of these f
b800: 69 6c 65 73 2c 20 74 68 65 0a 2a 2a 20 73 79 73  iles, the.** sys
b810: 74 65 6d 20 77 6f 75 6c 64 20 62 65 20 62 61 64  tem would be bad
b820: 6c 79 20 62 72 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a  ly broken..**.**
b830: 20 49 66 20 74 68 65 20 6c 6f 67 20 66 69 6c 65   If the log file
b840: 20 69 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79   is successfully
b850: 20 6f 70 65 6e 65 64 2c 20 53 51 4c 49 54 45 5f   opened, SQLITE_
b860: 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 61  OK is returned a
b870: 6e 64 20 0a 2a 2a 20 2a 70 70 57 61 6c 20 69 73  nd .** *ppWal is
b880: 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f   set to point to
b890: 20 61 20 6e 65 77 20 57 41 4c 20 68 61 6e 64 6c   a new WAL handl
b8a0: 65 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f  e. If an error o
b8b0: 63 63 75 72 73 2c 0a 2a 2a 20 61 6e 20 53 51 4c  ccurs,.** an SQL
b8c0: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
b8d0: 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 2a  s returned and *
b8e0: 70 70 57 61 6c 20 69 73 20 6c 65 66 74 20 75 6e  ppWal is left un
b8f0: 6d 6f 64 69 66 69 65 64 2e 0a 2a 2f 0a 69 6e 74  modified..*/.int
b900: 20 73 71 6c 69 74 65 33 57 61 6c 4f 70 65 6e 28   sqlite3WalOpen(
b910: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
b920: 70 56 66 73 2c 20 20 20 20 20 20 20 20 20 20 20  pVfs,           
b930: 20 20 20 2f 2a 20 76 66 73 20 6d 6f 64 75 6c 65     /* vfs module
b940: 20 74 6f 20 6f 70 65 6e 20 77 61 6c 20 61 6e 64   to open wal and
b950: 20 77 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a 20 20   wal-index */.  
b960: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 44  sqlite3_file *pD
b970: 62 46 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  bFd,            
b980: 2f 2a 20 54 68 65 20 6f 70 65 6e 20 64 61 74 61  /* The open data
b990: 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20 63  base file */.  c
b9a0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 57 61 6c 4e  onst char *zWalN
b9b0: 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 2f  ame,           /
b9c0: 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 57 41  * Name of the WA
b9d0: 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 57 61 6c 20  L file */.  Wal 
b9e0: 2a 2a 70 70 57 61 6c 20 20 20 20 20 20 20 20 20  **ppWal         
b9f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
ba00: 55 54 3a 20 41 6c 6c 6f 63 61 74 65 64 20 57 61  UT: Allocated Wa
ba10: 6c 20 68 61 6e 64 6c 65 20 2a 2f 0a 29 7b 0a 20  l handle */.){. 
ba20: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
ba30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ba40: 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20   /* Return Code 
ba50: 2a 2f 0a 20 20 57 61 6c 20 2a 70 52 65 74 3b 20  */.  Wal *pRet; 
ba60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ba70: 20 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 74       /* Object t
ba80: 6f 20 61 6c 6c 6f 63 61 74 65 20 61 6e 64 20 72  o allocate and r
ba90: 65 74 75 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 66  eturn */.  int f
baa0: 6c 61 67 73 3b 20 20 20 20 20 20 20 20 20 20 20  lags;           
bab0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c             /* Fl
bac0: 61 67 73 20 70 61 73 73 65 64 20 74 6f 20 4f 73  ags passed to Os
bad0: 4f 70 65 6e 28 29 20 2a 2f 0a 0a 20 20 61 73 73  Open() */..  ass
bae0: 65 72 74 28 20 7a 57 61 6c 4e 61 6d 65 20 26 26  ert( zWalName &&
baf0: 20 7a 57 61 6c 4e 61 6d 65 5b 30 5d 20 29 3b 0a   zWalName[0] );.
bb00: 20 20 61 73 73 65 72 74 28 20 70 44 62 46 64 20    assert( pDbFd 
bb10: 29 3b 0a 0a 20 20 2f 2a 20 49 6e 20 74 68 65 20  );..  /* In the 
bb20: 61 6d 61 6c 67 61 6d 61 74 69 6f 6e 2c 20 74 68  amalgamation, th
bb30: 65 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e 64 20  e os_unix.c and 
bb40: 6f 73 5f 77 69 6e 2e 63 20 73 6f 75 72 63 65 20  os_win.c source 
bb50: 66 69 6c 65 73 20 63 6f 6d 65 20 62 65 66 6f 72  files come befor
bb60: 65 0a 20 20 2a 2a 20 74 68 69 73 20 73 6f 75 72  e.  ** this sour
bb70: 63 65 20 66 69 6c 65 2e 20 20 56 65 72 69 66 79  ce file.  Verify
bb80: 20 74 68 61 74 20 74 68 65 20 23 64 65 66 69 6e   that the #defin
bb90: 65 73 20 6f 66 20 74 68 65 20 6c 6f 63 6b 69 6e  es of the lockin
bba0: 67 20 62 79 74 65 20 6f 66 66 73 65 74 73 0a 20  g byte offsets. 
bbb0: 20 2a 2a 20 69 6e 20 6f 73 5f 75 6e 69 78 2e 63   ** in os_unix.c
bbc0: 20 61 6e 64 20 6f 73 5f 77 69 6e 2e 63 20 61 67   and os_win.c ag
bbd0: 72 65 65 20 77 69 74 68 20 74 68 65 20 57 41 4c  ree with the WAL
bbe0: 49 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45  INDEX_LOCK_OFFSE
bbf0: 54 20 76 61 6c 75 65 2e 0a 20 20 2a 2f 0a 23 69  T value..  */.#i
bc00: 66 64 65 66 20 57 49 4e 5f 53 48 4d 5f 42 41 53  fdef WIN_SHM_BAS
bc10: 45 0a 20 20 61 73 73 65 72 74 28 20 57 49 4e 5f  E.  assert( WIN_
bc20: 53 48 4d 5f 42 41 53 45 3d 3d 57 41 4c 49 4e 44  SHM_BASE==WALIND
bc30: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 29  EX_LOCK_OFFSET )
bc40: 3b 0a 23 65 6e 64 69 66 0a 23 69 66 64 65 66 20  ;.#endif.#ifdef 
bc50: 55 4e 49 58 5f 53 48 4d 5f 42 41 53 45 0a 20 20  UNIX_SHM_BASE.  
bc60: 61 73 73 65 72 74 28 20 55 4e 49 58 5f 53 48 4d  assert( UNIX_SHM
bc70: 5f 42 41 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f  _BASE==WALINDEX_
bc80: 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23  LOCK_OFFSET );.#
bc90: 65 6e 64 69 66 0a 0a 0a 20 20 2f 2a 20 41 6c 6c  endif...  /* All
bca0: 6f 63 61 74 65 20 61 6e 20 69 6e 73 74 61 6e 63  ocate an instanc
bcb0: 65 20 6f 66 20 73 74 72 75 63 74 20 57 61 6c 20  e of struct Wal 
bcc0: 74 6f 20 72 65 74 75 72 6e 2e 20 2a 2f 0a 20 20  to return. */.  
bcd0: 2a 70 70 57 61 6c 20 3d 20 30 3b 0a 20 20 70 52  *ppWal = 0;.  pR
bce0: 65 74 20 3d 20 28 57 61 6c 2a 29 73 71 6c 69 74  et = (Wal*)sqlit
bcf0: 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a  e3MallocZero(siz
bd00: 65 6f 66 28 57 61 6c 29 20 2b 20 70 56 66 73 2d  eof(Wal) + pVfs-
bd10: 3e 73 7a 4f 73 46 69 6c 65 29 3b 0a 20 20 69 66  >szOsFile);.  if
bd20: 28 20 21 70 52 65 74 20 29 7b 0a 20 20 20 20 72  ( !pRet ){.    r
bd30: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
bd40: 45 4d 3b 0a 20 20 7d 0a 0a 20 20 70 52 65 74 2d  EM;.  }..  pRet-
bd50: 3e 70 56 66 73 20 3d 20 70 56 66 73 3b 0a 20 20  >pVfs = pVfs;.  
bd60: 70 52 65 74 2d 3e 70 57 61 6c 46 64 20 3d 20 28  pRet->pWalFd = (
bd70: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 29 26  sqlite3_file *)&
bd80: 70 52 65 74 5b 31 5d 3b 0a 20 20 70 52 65 74 2d  pRet[1];.  pRet-
bd90: 3e 70 44 62 46 64 20 3d 20 70 44 62 46 64 3b 0a  >pDbFd = pDbFd;.
bda0: 20 20 70 52 65 74 2d 3e 72 65 61 64 4c 6f 63 6b    pRet->readLock
bdb0: 20 3d 20 2d 31 3b 0a 20 20 70 52 65 74 2d 3e 7a   = -1;.  pRet->z
bdc0: 57 61 6c 4e 61 6d 65 20 3d 20 7a 57 61 6c 4e 61  WalName = zWalNa
bdd0: 6d 65 3b 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20 66  me;..  /* Open f
bde0: 69 6c 65 20 68 61 6e 64 6c 65 20 6f 6e 20 74 68  ile handle on th
bdf0: 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f  e write-ahead lo
be00: 67 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 66 6c 61  g file. */.  fla
be10: 67 73 20 3d 20 28 53 51 4c 49 54 45 5f 4f 50 45  gs = (SQLITE_OPE
be20: 4e 5f 52 45 41 44 57 52 49 54 45 7c 53 51 4c 49  N_READWRITE|SQLI
be30: 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54 45 7c 53  TE_OPEN_CREATE|S
be40: 51 4c 49 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f  QLITE_OPEN_MAIN_
be50: 4a 4f 55 52 4e 41 4c 29 3b 0a 20 20 72 63 20 3d  JOURNAL);.  rc =
be60: 20 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e 28 70   sqlite3OsOpen(p
be70: 56 66 73 2c 20 7a 57 61 6c 4e 61 6d 65 2c 20 70  Vfs, zWalName, p
be80: 52 65 74 2d 3e 70 57 61 6c 46 64 2c 20 66 6c 61  Ret->pWalFd, fla
be90: 67 73 2c 20 26 66 6c 61 67 73 29 3b 0a 0a 20 20  gs, &flags);..  
bea0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
beb0: 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49 6e 64 65  K ){.    walInde
bec0: 78 43 6c 6f 73 65 28 70 52 65 74 2c 20 30 29 3b  xClose(pRet, 0);
bed0: 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 43 6c  .    sqlite3OsCl
bee0: 6f 73 65 28 70 52 65 74 2d 3e 70 57 61 6c 46 64  ose(pRet->pWalFd
bef0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
bf00: 72 65 65 28 70 52 65 74 29 3b 0a 20 20 7d 65 6c  ree(pRet);.  }el
bf10: 73 65 7b 0a 20 20 20 20 2a 70 70 57 61 6c 20 3d  se{.    *ppWal =
bf20: 20 70 52 65 74 3b 0a 20 20 20 20 57 41 4c 54 52   pRet;.    WALTR
bf30: 41 43 45 28 28 22 57 41 4c 25 64 3a 20 6f 70 65  ACE(("WAL%d: ope
bf40: 6e 65 64 5c 6e 22 2c 20 70 52 65 74 29 29 3b 0a  ned\n", pRet));.
bf50: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
bf60: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 64 20 74  .}../*.** Find t
bf70: 68 65 20 73 6d 61 6c 6c 65 73 74 20 70 61 67 65  he smallest page
bf80: 20 6e 75 6d 62 65 72 20 6f 75 74 20 6f 66 20 61   number out of a
bf90: 6c 6c 20 70 61 67 65 73 20 68 65 6c 64 20 69 6e  ll pages held in
bfa0: 20 74 68 65 20 57 41 4c 20 74 68 61 74 0a 2a 2a   the WAL that.**
bfb0: 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20 72 65   has not been re
bfc0: 74 75 72 6e 65 64 20 62 79 20 61 6e 79 20 70 72  turned by any pr
bfd0: 69 6f 72 20 69 6e 76 6f 63 61 74 69 6f 6e 20 6f  ior invocation o
bfe0: 66 20 74 68 69 73 20 6d 65 74 68 6f 64 20 6f 6e  f this method on
bff0: 20 74 68 65 0a 2a 2a 20 73 61 6d 65 20 57 61 6c   the.** same Wal
c000: 49 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 2e  Iterator object.
c010: 20 20 20 57 72 69 74 65 20 69 6e 74 6f 20 2a 70     Write into *p
c020: 69 46 72 61 6d 65 20 74 68 65 20 66 72 61 6d 65  iFrame the frame
c030: 20 69 6e 64 65 78 20 77 68 65 72 65 0a 2a 2a 20   index where.** 
c040: 74 68 61 74 20 70 61 67 65 20 77 61 73 20 6c 61  that page was la
c050: 73 74 20 77 72 69 74 74 65 6e 20 69 6e 74 6f 20  st written into 
c060: 74 68 65 20 57 41 4c 2e 20 20 57 72 69 74 65 20  the WAL.  Write 
c070: 69 6e 74 6f 20 2a 70 69 50 61 67 65 20 74 68 65  into *piPage the
c080: 20 70 61 67 65 0a 2a 2a 20 6e 75 6d 62 65 72 2e   page.** number.
c090: 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 30 20  .**.** Return 0 
c0a0: 6f 6e 20 73 75 63 63 65 73 73 2e 20 20 49 66 20  on success.  If 
c0b0: 74 68 65 72 65 20 61 72 65 20 6e 6f 20 70 61 67  there are no pag
c0c0: 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20 77 69  es in the WAL wi
c0d0: 74 68 20 61 20 70 61 67 65 0a 2a 2a 20 6e 75 6d  th a page.** num
c0e0: 62 65 72 20 6c 61 72 67 65 72 20 74 68 61 6e 20  ber larger than 
c0f0: 2a 70 69 50 61 67 65 2c 20 74 68 65 6e 20 72 65  *piPage, then re
c100: 74 75 72 6e 20 31 2e 0a 2a 2f 0a 73 74 61 74 69  turn 1..*/.stati
c110: 63 20 69 6e 74 20 77 61 6c 49 74 65 72 61 74 6f  c int walIterato
c120: 72 4e 65 78 74 28 0a 20 20 57 61 6c 49 74 65 72  rNext(.  WalIter
c130: 61 74 6f 72 20 2a 70 2c 20 20 20 20 20 20 20 20  ator *p,        
c140: 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74         /* Iterat
c150: 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 50  or */.  u32 *piP
c160: 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  age,            
c170: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 68        /* OUT: Th
c180: 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 66  e page number of
c190: 20 74 68 65 20 6e 65 78 74 20 70 61 67 65 20 2a   the next page *
c1a0: 2f 0a 20 20 75 33 32 20 2a 70 69 46 72 61 6d 65  /.  u32 *piFrame
c1b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c1c0: 20 20 2f 2a 20 4f 55 54 3a 20 57 61 6c 20 66 72    /* OUT: Wal fr
c1d0: 61 6d 65 20 69 6e 64 65 78 20 6f 66 20 6e 65 78  ame index of nex
c1e0: 74 20 70 61 67 65 20 2a 2f 0a 29 7b 0a 20 20 75  t page */.){.  u
c1f0: 33 32 20 69 4d 69 6e 3b 20 20 20 20 20 20 20 20  32 iMin;        
c200: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c210: 52 65 73 75 6c 74 20 70 67 6e 6f 20 6d 75 73 74  Result pgno must
c220: 20 62 65 20 67 72 65 61 74 65 72 20 74 68 61 6e   be greater than
c230: 20 69 4d 69 6e 20 2a 2f 0a 20 20 75 33 32 20 69   iMin */.  u32 i
c240: 52 65 74 20 3d 20 30 78 46 46 46 46 46 46 46 46  Ret = 0xFFFFFFFF
c250: 3b 20 20 20 20 20 20 20 20 2f 2a 20 30 78 66 66  ;        /* 0xff
c260: 66 66 66 66 66 66 20 69 73 20 6e 65 76 65 72 20  ffffff is never 
c270: 61 20 76 61 6c 69 64 20 70 61 67 65 20 6e 75 6d  a valid page num
c280: 62 65 72 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20  ber */.  int i; 
c290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c2a0: 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 6c 6f         /* For lo
c2b0: 6f 70 69 6e 67 20 74 68 72 6f 75 67 68 20 73 65  oping through se
c2c0: 67 6d 65 6e 74 73 20 2a 2f 0a 0a 20 20 69 4d 69  gments */..  iMi
c2d0: 6e 20 3d 20 70 2d 3e 69 50 72 69 6f 72 3b 0a 20  n = p->iPrior;. 
c2e0: 20 61 73 73 65 72 74 28 20 69 4d 69 6e 3c 30 78   assert( iMin<0x
c2f0: 66 66 66 66 66 66 66 66 20 29 3b 0a 20 20 66 6f  ffffffff );.  fo
c300: 72 28 69 3d 70 2d 3e 6e 53 65 67 6d 65 6e 74 2d  r(i=p->nSegment-
c310: 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29 7b 0a 20  1; i>=0; i--){. 
c320: 20 20 20 73 74 72 75 63 74 20 57 61 6c 53 65 67     struct WalSeg
c330: 6d 65 6e 74 20 2a 70 53 65 67 6d 65 6e 74 20 3d  ment *pSegment =
c340: 20 26 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d   &p->aSegment[i]
c350: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 70 53 65  ;.    while( pSe
c360: 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 3c 70 53 65  gment->iNext<pSe
c370: 67 6d 65 6e 74 2d 3e 6e 45 6e 74 72 79 20 29 7b  gment->nEntry ){
c380: 0a 20 20 20 20 20 20 75 33 32 20 69 50 67 20 3d  .      u32 iPg =
c390: 20 70 53 65 67 6d 65 6e 74 2d 3e 61 50 67 6e 6f   pSegment->aPgno
c3a0: 5b 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e 64 65  [pSegment->aInde
c3b0: 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78  x[pSegment->iNex
c3c0: 74 5d 5d 3b 0a 20 20 20 20 20 20 69 66 28 20 69  t]];.      if( i
c3d0: 50 67 3e 69 4d 69 6e 20 29 7b 0a 20 20 20 20 20  Pg>iMin ){.     
c3e0: 20 20 20 69 66 28 20 69 50 67 3c 69 52 65 74 20     if( iPg<iRet 
c3f0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 52 65  ){.          iRe
c400: 74 20 3d 20 69 50 67 3b 0a 20 20 20 20 20 20 20  t = iPg;.       
c410: 20 20 20 2a 70 69 46 72 61 6d 65 20 3d 20 70 53     *piFrame = pS
c420: 65 67 6d 65 6e 74 2d 3e 69 5a 65 72 6f 20 2b 20  egment->iZero + 
c430: 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e 64 65 78  pSegment->aIndex
c440: 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74  [pSegment->iNext
c450: 5d 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  ];.        }.   
c460: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
c470: 20 20 7d 0a 20 20 20 20 20 20 70 53 65 67 6d 65    }.      pSegme
c480: 6e 74 2d 3e 69 4e 65 78 74 2b 2b 3b 0a 20 20 20  nt->iNext++;.   
c490: 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 69 50 61 67   }.  }..  *piPag
c4a0: 65 20 3d 20 70 2d 3e 69 50 72 69 6f 72 20 3d 20  e = p->iPrior = 
c4b0: 69 52 65 74 3b 0a 20 20 72 65 74 75 72 6e 20 28  iRet;.  return (
c4c0: 69 52 65 74 3d 3d 30 78 46 46 46 46 46 46 46 46  iRet==0xFFFFFFFF
c4d0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  );.}../*.** This
c4e0: 20 66 75 6e 63 74 69 6f 6e 20 6d 65 72 67 65 73   function merges
c4f0: 20 74 77 6f 20 73 6f 72 74 65 64 20 6c 69 73 74   two sorted list
c500: 73 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20  s into a single 
c510: 73 6f 72 74 65 64 20 6c 69 73 74 2e 0a 2a 2f 0a  sorted list..*/.
c520: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 4d  static void walM
c530: 65 72 67 65 28 0a 20 20 75 33 32 20 2a 61 43 6f  erge(.  u32 *aCo
c540: 6e 74 65 6e 74 2c 20 20 20 20 20 20 20 20 20 20  ntent,          
c550: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 73          /* Pages
c560: 20 69 6e 20 77 61 6c 20 2a 2f 0a 20 20 68 74 5f   in wal */.  ht_
c570: 73 6c 6f 74 20 2a 61 4c 65 66 74 2c 20 20 20 20  slot *aLeft,    
c580: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c590: 49 4e 3a 20 4c 65 66 74 20 68 61 6e 64 20 69 6e  IN: Left hand in
c5a0: 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e  put list */.  in
c5b0: 74 20 6e 4c 65 66 74 2c 20 20 20 20 20 20 20 20  t nLeft,        
c5c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c5d0: 20 49 4e 3a 20 45 6c 65 6d 65 6e 74 73 20 69 6e   IN: Elements in
c5e0: 20 61 72 72 61 79 20 2a 70 61 4c 65 66 74 20 2a   array *paLeft *
c5f0: 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 2a 70 61  /.  ht_slot **pa
c600: 52 69 67 68 74 2c 20 20 20 20 20 20 20 20 20 20  Right,          
c610: 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 52      /* IN/OUT: R
c620: 69 67 68 74 20 68 61 6e 64 20 69 6e 70 75 74 20  ight hand input 
c630: 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  list */.  int *p
c640: 6e 52 69 67 68 74 2c 20 20 20 20 20 20 20 20 20  nRight,         
c650: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f            /* IN/
c660: 4f 55 54 3a 20 45 6c 65 6d 65 6e 74 73 20 69 6e  OUT: Elements in
c670: 20 2a 70 61 52 69 67 68 74 20 2a 2f 0a 20 20 68   *paRight */.  h
c680: 74 5f 73 6c 6f 74 20 2a 61 54 6d 70 20 20 20 20  t_slot *aTmp    
c690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c6a0: 2a 20 54 65 6d 70 6f 72 61 72 79 20 62 75 66 66  * Temporary buff
c6b0: 65 72 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 69  er */.){.  int i
c6c0: 4c 65 66 74 20 3d 20 30 3b 20 20 20 20 20 20 20  Left = 0;       
c6d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
c6e0: 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e 20 61  rrent index in a
c6f0: 4c 65 66 74 20 2a 2f 0a 20 20 69 6e 74 20 69 52  Left */.  int iR
c700: 69 67 68 74 20 3d 20 30 3b 20 20 20 20 20 20 20  ight = 0;       
c710: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72            /* Cur
c720: 72 65 6e 74 20 69 6e 64 65 78 20 69 6e 20 61 52  rent index in aR
c730: 69 67 68 74 20 2a 2f 0a 20 20 69 6e 74 20 69 4f  ight */.  int iO
c740: 75 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  ut = 0;         
c750: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72            /* Cur
c760: 72 65 6e 74 20 69 6e 64 65 78 20 69 6e 20 6f 75  rent index in ou
c770: 74 70 75 74 20 62 75 66 66 65 72 20 2a 2f 0a 20  tput buffer */. 
c780: 20 69 6e 74 20 6e 52 69 67 68 74 20 3d 20 2a 70   int nRight = *p
c790: 6e 52 69 67 68 74 3b 0a 20 20 68 74 5f 73 6c 6f  nRight;.  ht_slo
c7a0: 74 20 2a 61 52 69 67 68 74 20 3d 20 2a 70 61 52  t *aRight = *paR
c7b0: 69 67 68 74 3b 0a 0a 20 20 61 73 73 65 72 74 28  ight;..  assert(
c7c0: 20 6e 4c 65 66 74 3e 30 20 26 26 20 6e 52 69 67   nLeft>0 && nRig
c7d0: 68 74 3e 30 20 29 3b 0a 20 20 77 68 69 6c 65 28  ht>0 );.  while(
c7e0: 20 69 52 69 67 68 74 3c 6e 52 69 67 68 74 20 7c   iRight<nRight |
c7f0: 7c 20 69 4c 65 66 74 3c 6e 4c 65 66 74 20 29 7b  | iLeft<nLeft ){
c800: 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20 6c 6f 67  .    ht_slot log
c810: 70 61 67 65 3b 0a 20 20 20 20 50 67 6e 6f 20 64  page;.    Pgno d
c820: 62 70 61 67 65 3b 0a 0a 20 20 20 20 69 66 28 20  bpage;..    if( 
c830: 28 69 4c 65 66 74 3c 6e 4c 65 66 74 29 20 0a 20  (iLeft<nLeft) . 
c840: 20 20 20 20 26 26 20 28 69 52 69 67 68 74 3e 3d      && (iRight>=
c850: 6e 52 69 67 68 74 20 7c 7c 20 61 43 6f 6e 74 65  nRight || aConte
c860: 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74 5d 5d  nt[aLeft[iLeft]]
c870: 3c 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74  <aContent[aRight
c880: 5b 69 52 69 67 68 74 5d 5d 29 0a 20 20 20 20 29  [iRight]]).    )
c890: 7b 0a 20 20 20 20 20 20 6c 6f 67 70 61 67 65 20  {.      logpage 
c8a0: 3d 20 61 4c 65 66 74 5b 69 4c 65 66 74 2b 2b 5d  = aLeft[iLeft++]
c8b0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
c8c0: 20 20 20 6c 6f 67 70 61 67 65 20 3d 20 61 52 69     logpage = aRi
c8d0: 67 68 74 5b 69 52 69 67 68 74 2b 2b 5d 3b 0a 20  ght[iRight++];. 
c8e0: 20 20 20 7d 0a 20 20 20 20 64 62 70 61 67 65 20     }.    dbpage 
c8f0: 3d 20 61 43 6f 6e 74 65 6e 74 5b 6c 6f 67 70 61  = aContent[logpa
c900: 67 65 5d 3b 0a 0a 20 20 20 20 61 54 6d 70 5b 69  ge];..    aTmp[i
c910: 4f 75 74 2b 2b 5d 20 3d 20 6c 6f 67 70 61 67 65  Out++] = logpage
c920: 3b 0a 20 20 20 20 69 66 28 20 69 4c 65 66 74 3c  ;.    if( iLeft<
c930: 6e 4c 65 66 74 20 26 26 20 61 43 6f 6e 74 65 6e  nLeft && aConten
c940: 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74 5d 5d 3d  t[aLeft[iLeft]]=
c950: 3d 64 62 70 61 67 65 20 29 20 69 4c 65 66 74 2b  =dbpage ) iLeft+
c960: 2b 3b 0a 0a 20 20 20 20 61 73 73 65 72 74 28 20  +;..    assert( 
c970: 69 4c 65 66 74 3e 3d 6e 4c 65 66 74 20 7c 7c 20  iLeft>=nLeft || 
c980: 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69  aContent[aLeft[i
c990: 4c 65 66 74 5d 5d 3e 64 62 70 61 67 65 20 29 3b  Left]]>dbpage );
c9a0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 52 69  .    assert( iRi
c9b0: 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c 20 61  ght>=nRight || a
c9c0: 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b 69  Content[aRight[i
c9d0: 52 69 67 68 74 5d 5d 3e 64 62 70 61 67 65 20 29  Right]]>dbpage )
c9e0: 3b 0a 20 20 7d 0a 0a 20 20 2a 70 61 52 69 67 68  ;.  }..  *paRigh
c9f0: 74 20 3d 20 61 4c 65 66 74 3b 0a 20 20 2a 70 6e  t = aLeft;.  *pn
ca00: 52 69 67 68 74 20 3d 20 69 4f 75 74 3b 0a 20 20  Right = iOut;.  
ca10: 6d 65 6d 63 70 79 28 61 4c 65 66 74 2c 20 61 54  memcpy(aLeft, aT
ca20: 6d 70 2c 20 73 69 7a 65 6f 66 28 61 54 6d 70 5b  mp, sizeof(aTmp[
ca30: 30 5d 29 2a 69 4f 75 74 29 3b 0a 7d 0a 0a 2f 2a  0])*iOut);.}../*
ca40: 0a 2a 2a 20 53 6f 72 74 20 74 68 65 20 65 6c 65  .** Sort the ele
ca50: 6d 65 6e 74 73 20 69 6e 20 6c 69 73 74 20 61 4c  ments in list aL
ca60: 69 73 74 2c 20 72 65 6d 6f 76 69 6e 67 20 61 6e  ist, removing an
ca70: 79 20 64 75 70 6c 69 63 61 74 65 73 2e 0a 2a 2f  y duplicates..*/
ca80: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
ca90: 4d 65 72 67 65 73 6f 72 74 28 0a 20 20 75 33 32  Mergesort(.  u32
caa0: 20 2a 61 43 6f 6e 74 65 6e 74 2c 20 20 20 20 20   *aContent,     
cab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
cac0: 50 61 67 65 73 20 69 6e 20 77 61 6c 20 2a 2f 0a  Pages in wal */.
cad0: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 42 75 66 66    ht_slot *aBuff
cae0: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
caf0: 20 20 2f 2a 20 42 75 66 66 65 72 20 6f 66 20 61    /* Buffer of a
cb00: 74 20 6c 65 61 73 74 20 2a 70 6e 4c 69 73 74 20  t least *pnList 
cb10: 69 74 65 6d 73 20 74 6f 20 75 73 65 20 2a 2f 0a  items to use */.
cb20: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 69 73 74    ht_slot *aList
cb30: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
cb40: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4c 69 73    /* IN/OUT: Lis
cb50: 74 20 74 6f 20 73 6f 72 74 20 2a 2f 0a 20 20 69  t to sort */.  i
cb60: 6e 74 20 2a 70 6e 4c 69 73 74 20 20 20 20 20 20  nt *pnList      
cb70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
cb80: 2a 20 49 4e 2f 4f 55 54 3a 20 4e 75 6d 62 65 72  * IN/OUT: Number
cb90: 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20   of elements in 
cba0: 61 4c 69 73 74 5b 5d 20 2a 2f 0a 29 7b 0a 20 20  aList[] */.){.  
cbb0: 73 74 72 75 63 74 20 53 75 62 6c 69 73 74 20 7b  struct Sublist {
cbc0: 0a 20 20 20 20 69 6e 74 20 6e 4c 69 73 74 3b 20  .    int nList; 
cbd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cbe0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
cbf0: 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 4c 69 73  elements in aLis
cc00: 74 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74  t */.    ht_slot
cc10: 20 2a 61 4c 69 73 74 3b 20 20 20 20 20 20 20 20   *aList;        
cc20: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
cc30: 72 20 74 6f 20 73 75 62 2d 6c 69 73 74 20 63 6f  r to sub-list co
cc40: 6e 74 65 6e 74 20 2a 2f 0a 20 20 7d 3b 0a 0a 20  ntent */.  };.. 
cc50: 20 63 6f 6e 73 74 20 69 6e 74 20 6e 4c 69 73 74   const int nList
cc60: 20 3d 20 2a 70 6e 4c 69 73 74 3b 20 20 20 20 20   = *pnList;     
cc70: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 69 6e 70 75   /* Size of inpu
cc80: 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20  t list */.  int 
cc90: 6e 4d 65 72 67 65 20 3d 20 30 3b 20 20 20 20 20  nMerge = 0;     
cca0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
ccb0: 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74  umber of element
ccc0: 73 20 69 6e 20 6c 69 73 74 20 61 4d 65 72 67 65  s in list aMerge
ccd0: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61   */.  ht_slot *a
cce0: 4d 65 72 67 65 20 3d 20 30 3b 20 20 20 20 20 20  Merge = 0;      
ccf0: 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 74 6f        /* List to
cd00: 20 62 65 20 6d 65 72 67 65 64 20 2a 2f 0a 20 20   be merged */.  
cd10: 69 6e 74 20 69 4c 69 73 74 3b 20 20 20 20 20 20  int iList;      
cd20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cd30: 2f 2a 20 49 6e 64 65 78 20 69 6e 74 6f 20 69 6e  /* Index into in
cd40: 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e  put list */.  in
cd50: 74 20 69 53 75 62 20 3d 20 30 3b 20 20 20 20 20  t iSub = 0;     
cd60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
cd70: 20 49 6e 64 65 78 20 69 6e 74 6f 20 61 53 75 62   Index into aSub
cd80: 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 74 72 75   array */.  stru
cd90: 63 74 20 53 75 62 6c 69 73 74 20 61 53 75 62 5b  ct Sublist aSub[
cda0: 31 33 5d 3b 20 20 20 20 20 20 20 20 2f 2a 20 41  13];        /* A
cdb0: 72 72 61 79 20 6f 66 20 73 75 62 2d 6c 69 73 74  rray of sub-list
cdc0: 73 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65 74 28 61  s */..  memset(a
cdd0: 53 75 62 2c 20 30 2c 20 73 69 7a 65 6f 66 28 61  Sub, 0, sizeof(a
cde0: 53 75 62 29 29 3b 0a 20 20 61 73 73 65 72 74 28  Sub));.  assert(
cdf0: 20 6e 4c 69 73 74 3c 3d 48 41 53 48 54 41 42 4c   nList<=HASHTABL
ce00: 45 5f 4e 50 41 47 45 20 26 26 20 6e 4c 69 73 74  E_NPAGE && nList
ce10: 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  >0 );.  assert( 
ce20: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3d  HASHTABLE_NPAGE=
ce30: 3d 28 31 3c 3c 28 41 72 72 61 79 53 69 7a 65 28  =(1<<(ArraySize(
ce40: 61 53 75 62 29 2d 31 29 29 20 29 3b 0a 0a 20 20  aSub)-1)) );..  
ce50: 66 6f 72 28 69 4c 69 73 74 3d 30 3b 20 69 4c 69  for(iList=0; iLi
ce60: 73 74 3c 6e 4c 69 73 74 3b 20 69 4c 69 73 74 2b  st<nList; iList+
ce70: 2b 29 7b 0a 20 20 20 20 6e 4d 65 72 67 65 20 3d  +){.    nMerge =
ce80: 20 31 3b 0a 20 20 20 20 61 4d 65 72 67 65 20 3d   1;.    aMerge =
ce90: 20 26 61 4c 69 73 74 5b 69 4c 69 73 74 5d 3b 0a   &aList[iList];.
cea0: 20 20 20 20 66 6f 72 28 69 53 75 62 3d 30 3b 20      for(iSub=0; 
ceb0: 69 4c 69 73 74 20 26 20 28 31 3c 3c 69 53 75 62  iList & (1<<iSub
cec0: 29 3b 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20  ); iSub++){.    
ced0: 20 20 73 74 72 75 63 74 20 53 75 62 6c 69 73 74    struct Sublist
cee0: 20 2a 70 20 3d 20 26 61 53 75 62 5b 69 53 75 62   *p = &aSub[iSub
cef0: 5d 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  ];.      assert(
cf00: 20 70 2d 3e 61 4c 69 73 74 20 26 26 20 70 2d 3e   p->aList && p->
cf10: 6e 4c 69 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29  nList<=(1<<iSub)
cf20: 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74   );.      assert
cf30: 28 20 70 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69  ( p->aList==&aLi
cf40: 73 74 5b 69 4c 69 73 74 26 7e 28 28 32 3c 3c 69  st[iList&~((2<<i
cf50: 53 75 62 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20  Sub)-1)] );.    
cf60: 20 20 77 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74    walMerge(aCont
cf70: 65 6e 74 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70  ent, p->aList, p
cf80: 2d 3e 6e 4c 69 73 74 2c 20 26 61 4d 65 72 67 65  ->nList, &aMerge
cf90: 2c 20 26 6e 4d 65 72 67 65 2c 20 61 42 75 66 66  , &nMerge, aBuff
cfa0: 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  er);.    }.    a
cfb0: 53 75 62 5b 69 53 75 62 5d 2e 61 4c 69 73 74 20  Sub[iSub].aList 
cfc0: 3d 20 61 4d 65 72 67 65 3b 0a 20 20 20 20 61 53  = aMerge;.    aS
cfd0: 75 62 5b 69 53 75 62 5d 2e 6e 4c 69 73 74 20 3d  ub[iSub].nList =
cfe0: 20 6e 4d 65 72 67 65 3b 0a 20 20 7d 0a 0a 20 20   nMerge;.  }..  
cff0: 66 6f 72 28 69 53 75 62 2b 2b 3b 20 69 53 75 62  for(iSub++; iSub
d000: 3c 41 72 72 61 79 53 69 7a 65 28 61 53 75 62 29  <ArraySize(aSub)
d010: 3b 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20 69  ; iSub++){.    i
d020: 66 28 20 6e 4c 69 73 74 20 26 20 28 31 3c 3c 69  f( nList & (1<<i
d030: 53 75 62 29 20 29 7b 0a 20 20 20 20 20 20 73 74  Sub) ){.      st
d040: 72 75 63 74 20 53 75 62 6c 69 73 74 20 2a 70 20  ruct Sublist *p 
d050: 3d 20 26 61 53 75 62 5b 69 53 75 62 5d 3b 0a 20  = &aSub[iSub];. 
d060: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e       assert( p->
d070: 6e 4c 69 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29  nList<=(1<<iSub)
d080: 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74   );.      assert
d090: 28 20 70 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69  ( p->aList==&aLi
d0a0: 73 74 5b 6e 4c 69 73 74 26 7e 28 28 32 3c 3c 69  st[nList&~((2<<i
d0b0: 53 75 62 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20  Sub)-1)] );.    
d0c0: 20 20 77 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74    walMerge(aCont
d0d0: 65 6e 74 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70  ent, p->aList, p
d0e0: 2d 3e 6e 4c 69 73 74 2c 20 26 61 4d 65 72 67 65  ->nList, &aMerge
d0f0: 2c 20 26 6e 4d 65 72 67 65 2c 20 61 42 75 66 66  , &nMerge, aBuff
d100: 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  er);.    }.  }. 
d110: 20 61 73 73 65 72 74 28 20 61 4d 65 72 67 65 3d   assert( aMerge=
d120: 3d 61 4c 69 73 74 20 29 3b 0a 20 20 2a 70 6e 4c  =aList );.  *pnL
d130: 69 73 74 20 3d 20 6e 4d 65 72 67 65 3b 0a 0a 23  ist = nMerge;..#
d140: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42  ifdef SQLITE_DEB
d150: 55 47 0a 20 20 7b 0a 20 20 20 20 69 6e 74 20 69  UG.  {.    int i
d160: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69  ;.    for(i=1; i
d170: 3c 2a 70 6e 4c 69 73 74 3b 20 69 2b 2b 29 7b 0a  <*pnList; i++){.
d180: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 61 43        assert( aC
d190: 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 69 5d 5d  ontent[aList[i]]
d1a0: 20 3e 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73   > aContent[aLis
d1b0: 74 5b 69 2d 31 5d 5d 20 29 3b 0a 20 20 20 20 7d  t[i-1]] );.    }
d1c0: 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f  .  }.#endif.}../
d1d0: 2a 20 0a 2a 2a 20 46 72 65 65 20 61 6e 20 69 74  * .** Free an it
d1e0: 65 72 61 74 6f 72 20 61 6c 6c 6f 63 61 74 65 64  erator allocated
d1f0: 20 62 79 20 77 61 6c 49 74 65 72 61 74 6f 72 49   by walIteratorI
d200: 6e 69 74 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  nit()..*/.static
d210: 20 76 6f 69 64 20 77 61 6c 49 74 65 72 61 74 6f   void walIterato
d220: 72 46 72 65 65 28 57 61 6c 49 74 65 72 61 74 6f  rFree(WalIterato
d230: 72 20 2a 70 29 7b 0a 20 20 73 71 6c 69 74 65 33  r *p){.  sqlite3
d240: 53 63 72 61 74 63 68 46 72 65 65 28 70 29 3b 0a  ScratchFree(p);.
d250: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 72 75  }../*.** Constru
d260: 63 74 20 61 20 57 61 6c 49 6e 74 65 72 61 74 6f  ct a WalInterato
d270: 72 20 6f 62 6a 65 63 74 20 74 68 61 74 20 63 61  r object that ca
d280: 6e 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f  n be used to loo
d290: 70 20 6f 76 65 72 20 61 6c 6c 20 0a 2a 2a 20 70  p over all .** p
d2a0: 61 67 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20  ages in the WAL 
d2b0: 69 6e 20 61 73 63 65 6e 64 69 6e 67 20 6f 72 64  in ascending ord
d2c0: 65 72 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 6d  er. The caller m
d2d0: 75 73 74 20 68 6f 6c 64 20 74 68 65 20 63 68 65  ust hold the che
d2e0: 63 6b 70 6f 69 6e 74 0a 2a 2a 0a 2a 2a 20 4f 6e  ckpoint.**.** On
d2f0: 20 73 75 63 63 65 73 73 2c 20 6d 61 6b 65 20 2a   success, make *
d300: 70 70 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20  pp point to the 
d310: 6e 65 77 6c 79 20 61 6c 6c 6f 63 61 74 65 64 20  newly allocated 
d320: 57 61 6c 49 6e 74 65 72 61 74 6f 72 20 6f 62 6a  WalInterator obj
d330: 65 63 74 0a 2a 2a 20 72 65 74 75 72 6e 20 53 51  ect.** return SQ
d340: 4c 49 54 45 5f 4f 4b 2e 20 4f 74 68 65 72 77 69  LITE_OK. Otherwi
d350: 73 65 2c 20 72 65 74 75 72 6e 20 61 6e 20 65 72  se, return an er
d360: 72 6f 72 20 63 6f 64 65 2e 20 49 66 20 74 68 69  ror code. If thi
d370: 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65 74  s routine.** ret
d380: 75 72 6e 73 20 61 6e 20 65 72 72 6f 72 2c 20 74  urns an error, t
d390: 68 65 20 76 61 6c 75 65 20 6f 66 20 2a 70 70 20  he value of *pp 
d3a0: 69 73 20 75 6e 64 65 66 69 6e 65 64 2e 0a 2a 2a  is undefined..**
d3b0: 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 69 6e 67 20  .** The calling 
d3c0: 72 6f 75 74 69 6e 65 20 73 68 6f 75 6c 64 20 69  routine should i
d3d0: 6e 76 6f 6b 65 20 77 61 6c 49 74 65 72 61 74 6f  nvoke walIterato
d3e0: 72 46 72 65 65 28 29 20 74 6f 20 64 65 73 74 72  rFree() to destr
d3f0: 6f 79 20 74 68 65 0a 2a 2a 20 57 61 6c 49 74 65  oy the.** WalIte
d400: 72 61 74 6f 72 20 6f 62 6a 65 63 74 20 77 68 65  rator object whe
d410: 6e 20 69 74 20 68 61 73 20 66 69 6e 69 73 68 65  n it has finishe
d420: 64 20 77 69 74 68 20 69 74 2e 0a 2a 2f 0a 73 74  d with it..*/.st
d430: 61 74 69 63 20 69 6e 74 20 77 61 6c 49 74 65 72  atic int walIter
d440: 61 74 6f 72 49 6e 69 74 28 57 61 6c 20 2a 70 57  atorInit(Wal *pW
d450: 61 6c 2c 20 57 61 6c 49 74 65 72 61 74 6f 72 20  al, WalIterator 
d460: 2a 2a 70 70 29 7b 0a 20 20 57 61 6c 49 74 65 72  **pp){.  WalIter
d470: 61 74 6f 72 20 2a 70 3b 20 20 20 20 20 20 20 20  ator *p;        
d480: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
d490: 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e  rn value */.  in
d4a0: 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20 20 20  t nSegment;     
d4b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d4c0: 20 4e 75 6d 62 65 72 20 6f 66 20 73 65 67 6d 65   Number of segme
d4d0: 6e 74 73 20 74 6f 20 6d 65 72 67 65 20 2a 2f 0a  nts to merge */.
d4e0: 20 20 75 33 32 20 69 4c 61 73 74 3b 20 20 20 20    u32 iLast;    
d4f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d500: 20 20 2f 2a 20 4c 61 73 74 20 66 72 61 6d 65 20    /* Last frame 
d510: 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20 69 6e 74 20  in log */.  int 
d520: 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20  nByte;          
d530: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
d540: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 74  umber of bytes t
d550: 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 20 20  o allocate */.  
d560: 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
d570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d580: 2f 2a 20 49 74 65 72 61 74 6f 72 20 76 61 72 69  /* Iterator vari
d590: 61 62 6c 65 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f  able */.  ht_slo
d5a0: 74 20 2a 61 54 6d 70 3b 20 20 20 20 20 20 20 20  t *aTmp;        
d5b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 65 6d            /* Tem
d5c0: 70 20 73 70 61 63 65 20 75 73 65 64 20 62 79 20  p space used by 
d5d0: 6d 65 72 67 65 2d 73 6f 72 74 20 2a 2f 0a 20 20  merge-sort */.  
d5e0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
d5f0: 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
d600: 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a  /* Return Code *
d610: 2f 0a 0a 20 20 2f 2a 20 54 68 69 73 20 72 6f 75  /..  /* This rou
d620: 74 69 6e 65 20 6f 6e 6c 79 20 72 75 6e 73 20 77  tine only runs w
d630: 68 69 6c 65 20 68 6f 6c 64 69 6e 67 20 74 68 65  hile holding the
d640: 20 63 68 65 63 6b 70 6f 69 6e 74 20 6c 6f 63 6b   checkpoint lock
d650: 2e 20 41 6e 64 0a 20 20 2a 2a 20 69 74 20 6f 6e  . And.  ** it on
d660: 6c 79 20 72 75 6e 73 20 69 66 20 74 68 65 72 65  ly runs if there
d670: 20 69 73 20 61 63 74 75 61 6c 6c 79 20 63 6f 6e   is actually con
d680: 74 65 6e 74 20 69 6e 20 74 68 65 20 6c 6f 67 20  tent in the log 
d690: 28 6d 78 46 72 61 6d 65 3e 30 29 2e 0a 20 20 2a  (mxFrame>0)..  *
d6a0: 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  /.  assert( pWal
d6b0: 2d 3e 63 6b 70 74 4c 6f 63 6b 20 26 26 20 70 57  ->ckptLock && pW
d6c0: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3e  al->hdr.mxFrame>
d6d0: 30 20 29 3b 0a 20 20 69 4c 61 73 74 20 3d 20 70  0 );.  iLast = p
d6e0: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
d6f0: 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65  ;..  /* Allocate
d700: 20 73 70 61 63 65 20 66 6f 72 20 74 68 65 20 57   space for the W
d710: 61 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65 63  alIterator objec
d720: 74 2e 20 2a 2f 0a 20 20 6e 53 65 67 6d 65 6e 74  t. */.  nSegment
d730: 20 3d 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28   = walFramePage(
d740: 69 4c 61 73 74 29 20 2b 20 31 3b 0a 20 20 6e 42  iLast) + 1;.  nB
d750: 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 57 61 6c  yte = sizeof(Wal
d760: 49 74 65 72 61 74 6f 72 29 20 0a 20 20 20 20 20  Iterator) .     
d770: 20 20 20 2b 20 28 6e 53 65 67 6d 65 6e 74 2d 31     + (nSegment-1
d780: 29 2a 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20  )*sizeof(struct 
d790: 57 61 6c 53 65 67 6d 65 6e 74 29 0a 20 20 20 20  WalSegment).    
d7a0: 20 20 20 20 2b 20 69 4c 61 73 74 2a 73 69 7a 65      + iLast*size
d7b0: 6f 66 28 68 74 5f 73 6c 6f 74 29 3b 0a 20 20 70  of(ht_slot);.  p
d7c0: 20 3d 20 28 57 61 6c 49 74 65 72 61 74 6f 72 20   = (WalIterator 
d7d0: 2a 29 73 71 6c 69 74 65 33 53 63 72 61 74 63 68  *)sqlite3Scratch
d7e0: 4d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b 0a 20  Malloc(nByte);. 
d7f0: 20 69 66 28 20 21 70 20 29 7b 0a 20 20 20 20 72   if( !p ){.    r
d800: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
d810: 45 4d 3b 0a 20 20 7d 0a 20 20 6d 65 6d 73 65 74  EM;.  }.  memset
d820: 28 70 2c 20 30 2c 20 6e 42 79 74 65 29 3b 0a 20  (p, 0, nByte);. 
d830: 20 70 2d 3e 6e 53 65 67 6d 65 6e 74 20 3d 20 6e   p->nSegment = n
d840: 53 65 67 6d 65 6e 74 3b 0a 0a 20 20 2f 2a 20 41  Segment;..  /* A
d850: 6c 6c 6f 63 61 74 65 20 74 65 6d 70 6f 72 61 72  llocate temporar
d860: 79 20 73 70 61 63 65 20 75 73 65 64 20 62 79 20  y space used by 
d870: 74 68 65 20 6d 65 72 67 65 2d 73 6f 72 74 20 72  the merge-sort r
d880: 6f 75 74 69 6e 65 2e 20 54 68 69 73 20 62 6c 6f  outine. This blo
d890: 63 6b 0a 20 20 2a 2a 20 6f 66 20 6d 65 6d 6f 72  ck.  ** of memor
d8a0: 79 20 77 69 6c 6c 20 62 65 20 66 72 65 65 64 20  y will be freed 
d8b0: 62 65 66 6f 72 65 20 74 68 69 73 20 66 75 6e 63  before this func
d8c0: 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e 0a 20 20  tion returns..  
d8d0: 2a 2f 0a 20 20 61 54 6d 70 20 3d 20 28 68 74 5f  */.  aTmp = (ht_
d8e0: 73 6c 6f 74 20 2a 29 73 71 6c 69 74 65 33 53 63  slot *)sqlite3Sc
d8f0: 72 61 74 63 68 4d 61 6c 6c 6f 63 28 0a 20 20 20  ratchMalloc(.   
d900: 20 20 20 73 69 7a 65 6f 66 28 68 74 5f 73 6c 6f     sizeof(ht_slo
d910: 74 29 20 2a 20 28 69 4c 61 73 74 3e 48 41 53 48  t) * (iLast>HASH
d920: 54 41 42 4c 45 5f 4e 50 41 47 45 3f 48 41 53 48  TABLE_NPAGE?HASH
d930: 54 41 42 4c 45 5f 4e 50 41 47 45 3a 69 4c 61 73  TABLE_NPAGE:iLas
d940: 74 29 0a 20 20 29 3b 0a 20 20 69 66 28 20 21 61  t).  );.  if( !a
d950: 54 6d 70 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  Tmp ){.    rc = 
d960: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
d970: 7d 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72 63  }..  for(i=0; rc
d980: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69  ==SQLITE_OK && i
d990: 3c 6e 53 65 67 6d 65 6e 74 3b 20 69 2b 2b 29 7b  <nSegment; i++){
d9a0: 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 68 74  .    volatile ht
d9b0: 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b 0a 20 20  _slot *aHash;.  
d9c0: 20 20 75 33 32 20 69 5a 65 72 6f 3b 0a 20 20 20    u32 iZero;.   
d9d0: 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61   volatile u32 *a
d9e0: 50 67 6e 6f 3b 0a 0a 20 20 20 20 72 63 20 3d 20  Pgno;..    rc = 
d9f0: 77 61 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c  walHashGet(pWal,
da00: 20 69 2c 20 26 61 48 61 73 68 2c 20 26 61 50 67   i, &aHash, &aPg
da10: 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 20 20 20  no, &iZero);.   
da20: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
da30: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  OK ){.      int 
da40: 6a 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  j;              
da50: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74          /* Count
da60: 65 72 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20  er variable */. 
da70: 20 20 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 3b       int nEntry;
da80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
da90: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e   /* Number of en
daa0: 74 72 69 65 73 20 69 6e 20 74 68 69 73 20 73 65  tries in this se
dab0: 67 6d 65 6e 74 20 2a 2f 0a 20 20 20 20 20 20 68  gment */.      h
dac0: 74 5f 73 6c 6f 74 20 2a 61 49 6e 64 65 78 3b 20  t_slot *aIndex; 
dad0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 6f             /* So
dae0: 72 74 65 64 20 69 6e 64 65 78 20 66 6f 72 20 74  rted index for t
daf0: 68 69 73 20 73 65 67 6d 65 6e 74 20 2a 2f 0a 0a  his segment */..
db00: 20 20 20 20 20 20 61 50 67 6e 6f 2b 2b 3b 0a 20        aPgno++;. 
db10: 20 20 20 20 20 69 66 28 20 28 69 2b 31 29 3d 3d       if( (i+1)==
db20: 6e 53 65 67 6d 65 6e 74 20 29 7b 0a 20 20 20 20  nSegment ){.    
db30: 20 20 20 20 6e 45 6e 74 72 79 20 3d 20 28 69 6e      nEntry = (in
db40: 74 29 28 69 4c 61 73 74 20 2d 20 69 5a 65 72 6f  t)(iLast - iZero
db50: 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  );.      }else{.
db60: 20 20 20 20 20 20 20 20 6e 45 6e 74 72 79 20 3d          nEntry =
db70: 20 28 69 6e 74 29 28 28 75 33 32 2a 29 61 48 61   (int)((u32*)aHa
db80: 73 68 20 2d 20 28 75 33 32 2a 29 61 50 67 6e 6f  sh - (u32*)aPgno
db90: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
dba0: 20 61 49 6e 64 65 78 20 3d 20 26 28 28 68 74 5f   aIndex = &((ht_
dbb0: 73 6c 6f 74 20 2a 29 26 70 2d 3e 61 53 65 67 6d  slot *)&p->aSegm
dbc0: 65 6e 74 5b 70 2d 3e 6e 53 65 67 6d 65 6e 74 5d  ent[p->nSegment]
dbd0: 29 5b 69 5a 65 72 6f 5d 3b 0a 20 20 20 20 20 20  )[iZero];.      
dbe0: 69 5a 65 72 6f 2b 2b 3b 0a 20 20 0a 20 20 20 20  iZero++;.  .    
dbf0: 20 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 45 6e    for(j=0; j<nEn
dc00: 74 72 79 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20  try; j++){.     
dc10: 20 20 20 61 49 6e 64 65 78 5b 6a 5d 20 3d 20 28     aIndex[j] = (
dc20: 68 74 5f 73 6c 6f 74 29 6a 3b 0a 20 20 20 20 20  ht_slot)j;.     
dc30: 20 7d 0a 20 20 20 20 20 20 77 61 6c 4d 65 72 67   }.      walMerg
dc40: 65 73 6f 72 74 28 28 75 33 32 20 2a 29 61 50 67  esort((u32 *)aPg
dc50: 6e 6f 2c 20 61 54 6d 70 2c 20 61 49 6e 64 65 78  no, aTmp, aIndex
dc60: 2c 20 26 6e 45 6e 74 72 79 29 3b 0a 20 20 20 20  , &nEntry);.    
dc70: 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d    p->aSegment[i]
dc80: 2e 69 5a 65 72 6f 20 3d 20 69 5a 65 72 6f 3b 0a  .iZero = iZero;.
dc90: 20 20 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e        p->aSegmen
dca0: 74 5b 69 5d 2e 6e 45 6e 74 72 79 20 3d 20 6e 45  t[i].nEntry = nE
dcb0: 6e 74 72 79 3b 0a 20 20 20 20 20 20 70 2d 3e 61  ntry;.      p->a
dcc0: 53 65 67 6d 65 6e 74 5b 69 5d 2e 61 49 6e 64 65  Segment[i].aInde
dcd0: 78 20 3d 20 61 49 6e 64 65 78 3b 0a 20 20 20 20  x = aIndex;.    
dce0: 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d    p->aSegment[i]
dcf0: 2e 61 50 67 6e 6f 20 3d 20 28 75 33 32 20 2a 29  .aPgno = (u32 *)
dd00: 61 50 67 6e 6f 3b 0a 20 20 20 20 7d 0a 20 20 7d  aPgno;.    }.  }
dd10: 0a 20 20 73 71 6c 69 74 65 33 53 63 72 61 74 63  .  sqlite3Scratc
dd20: 68 46 72 65 65 28 61 54 6d 70 29 3b 0a 0a 20 20  hFree(aTmp);..  
dd30: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
dd40: 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49 74 65 72  K ){.    walIter
dd50: 61 74 6f 72 46 72 65 65 28 70 29 3b 0a 20 20 7d  atorFree(p);.  }
dd60: 0a 20 20 2a 70 70 20 3d 20 70 3b 0a 20 20 72 65  .  *pp = p;.  re
dd70: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
dd80: 2a 20 43 6f 70 79 20 61 73 20 6d 75 63 68 20 63  * Copy as much c
dd90: 6f 6e 74 65 6e 74 20 61 73 20 77 65 20 63 61 6e  ontent as we can
dda0: 20 66 72 6f 6d 20 74 68 65 20 57 41 4c 20 62 61   from the WAL ba
ddb0: 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ck into the data
ddc0: 62 61 73 65 20 66 69 6c 65 0a 2a 2a 20 69 6e 20  base file.** in 
ddd0: 72 65 73 70 6f 6e 73 65 20 74 6f 20 61 6e 20 73  response to an s
dde0: 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68 65 63 6b  qlite3_wal_check
ddf0: 70 6f 69 6e 74 28 29 20 72 65 71 75 65 73 74 20  point() request 
de00: 6f 72 20 74 68 65 20 65 71 75 69 76 61 6c 65 6e  or the equivalen
de10: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 6d 6f  t..**.** The amo
de20: 75 6e 74 20 6f 66 20 69 6e 66 6f 72 6d 61 74 69  unt of informati
de30: 6f 6e 20 63 6f 70 69 65 73 20 66 72 6f 6d 20 57  on copies from W
de40: 41 4c 20 74 6f 20 64 61 74 61 62 61 73 65 20 6d  AL to database m
de50: 69 67 68 74 20 62 65 20 6c 69 6d 69 74 65 64 0a  ight be limited.
de60: 2a 2a 20 62 79 20 61 63 74 69 76 65 20 72 65 61  ** by active rea
de70: 64 65 72 73 2e 20 20 54 68 69 73 20 72 6f 75 74  ders.  This rout
de80: 69 6e 65 20 77 69 6c 6c 20 6e 65 76 65 72 20 6f  ine will never o
de90: 76 65 72 77 72 69 74 65 20 61 20 64 61 74 61 62  verwrite a datab
dea0: 61 73 65 20 70 61 67 65 0a 2a 2a 20 74 68 61 74  ase page.** that
deb0: 20 61 20 63 6f 6e 63 75 72 72 65 6e 74 20 72 65   a concurrent re
dec0: 61 64 65 72 20 6d 69 67 68 74 20 62 65 20 75 73  ader might be us
ded0: 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 20 49  ing..**.** All I
dee0: 2f 4f 20 62 61 72 72 69 65 72 20 6f 70 65 72 61  /O barrier opera
def0: 74 69 6f 6e 73 20 28 61 2e 6b 2e 61 20 66 73 79  tions (a.k.a fsy
df00: 6e 63 73 29 20 6f 63 63 75 72 20 69 6e 20 74 68  ncs) occur in th
df10: 69 73 20 72 6f 75 74 69 6e 65 20 77 68 65 6e 0a  is routine when.
df20: 2a 2a 20 53 51 4c 69 74 65 20 69 73 20 69 6e 20  ** SQLite is in 
df30: 57 41 4c 2d 6d 6f 64 65 20 69 6e 20 73 79 6e 63  WAL-mode in sync
df40: 68 72 6f 6e 6f 75 73 3d 4e 4f 52 4d 41 4c 2e 20  hronous=NORMAL. 
df50: 20 54 68 61 74 20 6d 65 61 6e 73 20 74 68 61 74   That means that
df60: 20 69 66 20 0a 2a 2a 20 63 68 65 63 6b 70 6f 69   if .** checkpoi
df70: 6e 74 73 20 61 72 65 20 61 6c 77 61 79 73 20 72  nts are always r
df80: 75 6e 20 62 79 20 61 20 62 61 63 6b 67 72 6f 75  un by a backgrou
df90: 6e 64 20 74 68 72 65 61 64 20 6f 72 20 62 61 63  nd thread or bac
dfa0: 6b 67 72 6f 75 6e 64 20 0a 2a 2a 20 70 72 6f 63  kground .** proc
dfb0: 65 73 73 2c 20 66 6f 72 65 67 72 6f 75 6e 64 20  ess, foreground 
dfc0: 74 68 72 65 61 64 73 20 77 69 6c 6c 20 6e 65 76  threads will nev
dfd0: 65 72 20 62 6c 6f 63 6b 20 6f 6e 20 61 20 6c 65  er block on a le
dfe0: 6e 67 74 68 79 20 66 73 79 6e 63 20 63 61 6c 6c  ngthy fsync call
dff0: 2e 0a 2a 2a 0a 2a 2a 20 46 73 79 6e 63 20 69 73  ..**.** Fsync is
e000: 20 63 61 6c 6c 65 64 20 6f 6e 20 74 68 65 20 57   called on the W
e010: 41 4c 20 62 65 66 6f 72 65 20 77 72 69 74 69 6e  AL before writin
e020: 67 20 63 6f 6e 74 65 6e 74 20 6f 75 74 20 6f 66  g content out of
e030: 20 74 68 65 20 57 41 4c 20 61 6e 64 0a 2a 2a 20   the WAL and.** 
e040: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
e050: 65 2e 20 20 54 68 69 73 20 65 6e 73 75 72 65 73  e.  This ensures
e060: 20 74 68 61 74 20 69 66 20 74 68 65 20 6e 65 77   that if the new
e070: 20 63 6f 6e 74 65 6e 74 20 69 73 20 70 65 72 73   content is pers
e080: 69 73 74 65 6e 74 0a 2a 2a 20 69 6e 20 74 68 65  istent.** in the
e090: 20 57 41 4c 20 61 6e 64 20 63 61 6e 20 62 65 20   WAL and can be 
e0a0: 72 65 63 6f 76 65 72 65 64 20 66 6f 6c 6c 6f 77  recovered follow
e0b0: 69 6e 67 20 61 20 70 6f 77 65 72 2d 6c 6f 73 73  ing a power-loss
e0c0: 20 6f 72 20 68 61 72 64 20 72 65 73 65 74 2e 0a   or hard reset..
e0d0: 2a 2a 0a 2a 2a 20 46 73 79 6e 63 20 69 73 20 61  **.** Fsync is a
e0e0: 6c 73 6f 20 63 61 6c 6c 65 64 20 6f 6e 20 74 68  lso called on th
e0f0: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  e database file 
e100: 69 66 20 28 61 6e 64 20 6f 6e 6c 79 20 69 66 29  if (and only if)
e110: 20 74 68 65 20 65 6e 74 69 72 65 0a 2a 2a 20 57   the entire.** W
e120: 41 4c 20 63 6f 6e 74 65 6e 74 20 69 73 20 63 6f  AL content is co
e130: 70 69 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61  pied into the da
e140: 74 61 62 61 73 65 20 66 69 6c 65 2e 20 20 54 68  tabase file.  Th
e150: 69 73 20 73 65 63 6f 6e 64 20 66 73 79 6e 63 20  is second fsync 
e160: 6d 61 6b 65 73 0a 2a 2a 20 69 74 20 73 61 66 65  makes.** it safe
e170: 20 74 6f 20 64 65 6c 65 74 65 20 74 68 65 20 57   to delete the W
e180: 41 4c 20 73 69 6e 63 65 20 74 68 65 20 6e 65 77  AL since the new
e190: 20 63 6f 6e 74 65 6e 74 20 77 69 6c 6c 20 70 65   content will pe
e1a0: 72 73 69 73 74 20 69 6e 20 74 68 65 0a 2a 2a 20  rsist in the.** 
e1b0: 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a  database file..*
e1c0: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  *.** This routin
e1d0: 65 20 75 73 65 73 20 61 6e 64 20 75 70 64 61 74  e uses and updat
e1e0: 65 73 20 74 68 65 20 6e 42 61 63 6b 66 69 6c 6c  es the nBackfill
e1f0: 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20 77 61   field of the wa
e200: 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 2e 0a  l-index header..
e210: 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 6f  ** This is the o
e220: 6e 6c 79 20 72 6f 75 74 69 6e 65 20 74 68 61 20  nly routine tha 
e230: 77 69 6c 6c 20 69 6e 63 72 65 61 73 65 20 74 68  will increase th
e240: 65 20 76 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b  e value of nBack
e250: 66 69 6c 6c 2e 20 20 0a 2a 2a 20 28 41 20 57 41  fill.  .** (A WA
e260: 4c 20 72 65 73 65 74 20 6f 72 20 72 65 63 6f 76  L reset or recov
e270: 65 72 79 20 77 69 6c 6c 20 72 65 76 65 72 74 20  ery will revert 
e280: 6e 42 61 63 6b 66 69 6c 6c 20 74 6f 20 7a 65 72  nBackfill to zer
e290: 6f 2c 20 62 75 74 20 6e 6f 74 20 69 6e 63 72 65  o, but not incre
e2a0: 61 73 65 0a 2a 2a 20 69 74 73 20 76 61 6c 75 65  ase.** its value
e2b0: 2e 29 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c  .).**.** The cal
e2c0: 6c 65 72 20 6d 75 73 74 20 62 65 20 68 6f 6c 64  ler must be hold
e2d0: 69 6e 67 20 73 75 66 66 69 63 69 65 6e 74 20 6c  ing sufficient l
e2e0: 6f 63 6b 73 20 74 6f 20 65 6e 73 75 72 65 20 74  ocks to ensure t
e2f0: 68 61 74 20 6e 6f 20 6f 74 68 65 72 0a 2a 2a 20  hat no other.** 
e300: 63 68 65 63 6b 70 6f 69 6e 74 20 69 73 20 72 75  checkpoint is ru
e310: 6e 6e 69 6e 67 20 28 69 6e 20 61 6e 79 20 6f 74  nning (in any ot
e320: 68 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72  her thread or pr
e330: 6f 63 65 73 73 29 20 61 74 20 74 68 65 20 73 61  ocess) at the sa
e340: 6d 65 0a 2a 2a 20 74 69 6d 65 2e 0a 2a 2f 0a 73  me.** time..*/.s
e350: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 43 68 65  tatic int walChe
e360: 63 6b 70 6f 69 6e 74 28 0a 20 20 57 61 6c 20 2a  ckpoint(.  Wal *
e370: 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  pWal,           
e380: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61             /* Wa
e390: 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a  l connection */.
e3a0: 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67 73    int sync_flags
e3b0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
e3c0: 20 20 2f 2a 20 46 6c 61 67 73 20 66 6f 72 20 4f    /* Flags for O
e3d0: 73 53 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a  sSync() (or 0) *
e3e0: 2f 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20  /.  int nBuf,   
e3f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e400: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 7a      /* Size of z
e410: 42 75 66 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  Buf in bytes */.
e420: 20 20 75 38 20 2a 7a 42 75 66 20 20 20 20 20 20    u8 *zBuf      
e430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e440: 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62    /* Temporary b
e450: 75 66 66 65 72 20 74 6f 20 75 73 65 20 2a 2f 0a  uffer to use */.
e460: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  ){.  int rc;    
e470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e480: 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
e490: 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50  ode */.  int szP
e4a0: 61 67 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  age = pWal->hdr.
e4b0: 73 7a 50 61 67 65 3b 20 20 2f 2a 20 44 61 74 61  szPage;  /* Data
e4c0: 62 61 73 65 20 70 61 67 65 2d 73 69 7a 65 20 2a  base page-size *
e4d0: 2f 0a 20 20 57 61 6c 49 74 65 72 61 74 6f 72 20  /.  WalIterator 
e4e0: 2a 70 49 74 65 72 20 3d 20 30 3b 20 20 20 20 20  *pIter = 0;     
e4f0: 20 20 20 20 2f 2a 20 57 61 6c 20 69 74 65 72 61      /* Wal itera
e500: 74 6f 72 20 63 6f 6e 74 65 78 74 20 2a 2f 0a 20  tor context */. 
e510: 20 75 33 32 20 69 44 62 70 61 67 65 20 3d 20 30   u32 iDbpage = 0
e520: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
e530: 20 2f 2a 20 4e 65 78 74 20 64 61 74 61 62 61 73   /* Next databas
e540: 65 20 70 61 67 65 20 74 6f 20 77 72 69 74 65 20  e page to write 
e550: 2a 2f 0a 20 20 75 33 32 20 69 46 72 61 6d 65 20  */.  u32 iFrame 
e560: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
e570: 20 20 20 20 20 2f 2a 20 57 61 6c 20 66 72 61 6d       /* Wal fram
e580: 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64 61 74  e containing dat
e590: 61 20 66 6f 72 20 69 44 62 70 61 67 65 20 2a 2f  a for iDbpage */
e5a0: 0a 20 20 75 33 32 20 6d 78 53 61 66 65 46 72 61  .  u32 mxSafeFra
e5b0: 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  me;             
e5c0: 20 20 20 2f 2a 20 4d 61 78 20 66 72 61 6d 65 20     /* Max frame 
e5d0: 74 68 61 74 20 63 61 6e 20 62 65 20 62 61 63 6b  that can be back
e5e0: 66 69 6c 6c 65 64 20 2a 2f 0a 20 20 69 6e 74 20  filled */.  int 
e5f0: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
e600: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
e610: 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20  oop counter */. 
e620: 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70   volatile WalCkp
e630: 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b 20 20 20  tInfo *pInfo;   
e640: 20 2f 2a 20 54 68 65 20 63 68 65 63 6b 70 6f 69   /* The checkpoi
e650: 6e 74 20 73 74 61 74 75 73 20 69 6e 66 6f 72 6d  nt status inform
e660: 61 74 69 6f 6e 20 2a 2f 0a 0a 20 20 69 66 28 20  ation */..  if( 
e670: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
e680: 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  e==0 ) return SQ
e690: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f 2a 20 41  LITE_OK;..  /* A
e6a0: 6c 6c 6f 63 61 74 65 20 74 68 65 20 69 74 65 72  llocate the iter
e6b0: 61 74 6f 72 20 2a 2f 0a 20 20 72 63 20 3d 20 77  ator */.  rc = w
e6c0: 61 6c 49 74 65 72 61 74 6f 72 49 6e 69 74 28 70  alIteratorInit(p
e6d0: 57 61 6c 2c 20 26 70 49 74 65 72 29 3b 0a 20 20  Wal, &pIter);.  
e6e0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
e6f0: 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  K ){.    return 
e700: 72 63 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74  rc;.  }.  assert
e710: 28 20 70 49 74 65 72 20 29 3b 0a 0a 20 20 2f 2a  ( pIter );..  /*
e720: 2a 2a 20 54 4f 44 4f 3a 20 20 4d 6f 76 65 20 74  ** TODO:  Move t
e730: 68 69 73 20 74 65 73 74 20 6f 75 74 20 74 6f 20  his test out to 
e740: 74 68 65 20 63 61 6c 6c 65 72 2e 20 20 4d 61 6b  the caller.  Mak
e750: 65 20 69 74 20 61 6e 20 61 73 73 65 72 74 28 29  e it an assert()
e760: 20 68 65 72 65 20 2a 2a 2a 2f 0a 20 20 69 66 28   here ***/.  if(
e770: 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67   pWal->hdr.szPag
e780: 65 21 3d 6e 42 75 66 20 29 7b 0a 20 20 20 20 72  e!=nBuf ){.    r
e790: 63 20 3d 20 53 51 4c 49 54 45 5f 43 4f 52 52 55  c = SQLITE_CORRU
e7a0: 50 54 5f 42 4b 50 54 3b 0a 20 20 20 20 67 6f 74  PT_BKPT;.    got
e7b0: 6f 20 77 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f  o walcheckpoint_
e7c0: 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43  out;.  }..  /* C
e7d0: 6f 6d 70 75 74 65 20 69 6e 20 6d 78 53 61 66 65  ompute in mxSafe
e7e0: 46 72 61 6d 65 20 74 68 65 20 69 6e 64 65 78 20  Frame the index 
e7f0: 6f 66 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d  of the last fram
e800: 65 20 6f 66 20 74 68 65 20 57 41 4c 20 74 68 61  e of the WAL tha
e810: 74 20 69 73 0a 20 20 2a 2a 20 73 61 66 65 20 74  t is.  ** safe t
e820: 6f 20 77 72 69 74 65 20 69 6e 74 6f 20 74 68 65  o write into the
e830: 20 64 61 74 61 62 61 73 65 2e 20 20 46 72 61 6d   database.  Fram
e840: 65 73 20 62 65 79 6f 6e 64 20 6d 78 53 61 66 65  es beyond mxSafe
e850: 46 72 61 6d 65 20 6d 69 67 68 74 0a 20 20 2a 2a  Frame might.  **
e860: 20 6f 76 65 72 77 72 69 74 65 20 64 61 74 61 62   overwrite datab
e870: 61 73 65 20 70 61 67 65 73 20 74 68 61 74 20 61  ase pages that a
e880: 72 65 20 69 6e 20 75 73 65 20 62 79 20 61 63 74  re in use by act
e890: 69 76 65 20 72 65 61 64 65 72 73 20 61 6e 64 20  ive readers and 
e8a0: 74 68 75 73 0a 20 20 2a 2a 20 63 61 6e 6e 6f 74  thus.  ** cannot
e8b0: 20 62 65 20 62 61 63 6b 66 69 6c 6c 65 64 20 66   be backfilled f
e8c0: 72 6f 6d 20 74 68 65 20 57 41 4c 2e 0a 20 20 2a  rom the WAL..  *
e8d0: 2f 0a 20 20 6d 78 53 61 66 65 46 72 61 6d 65 20  /.  mxSafeFrame 
e8e0: 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  = pWal->hdr.mxFr
e8f0: 61 6d 65 3b 0a 20 20 70 49 6e 66 6f 20 3d 20 77  ame;.  pInfo = w
e900: 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29  alCkptInfo(pWal)
e910: 3b 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 57  ;.  for(i=1; i<W
e920: 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29  AL_NREADER; i++)
e930: 7b 0a 20 20 20 20 75 33 32 20 79 20 3d 20 70 49  {.    u32 y = pI
e940: 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69  nfo->aReadMark[i
e950: 5d 3b 0a 20 20 20 20 69 66 28 20 6d 78 53 61 66  ];.    if( mxSaf
e960: 65 46 72 61 6d 65 3e 3d 79 20 29 7b 0a 20 20 20  eFrame>=y ){.   
e970: 20 20 20 61 73 73 65 72 74 28 20 79 3c 3d 70 57     assert( y<=pW
e980: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
e990: 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61  );.      rc = wa
e9a0: 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  lLockExclusive(p
e9b0: 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
e9c0: 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20 20 20  CK(i), 1);.     
e9d0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
e9e0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49  OK ){.        pI
e9f0: 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69  nfo->aReadMark[i
ea00: 5d 20 3d 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54  ] = READMARK_NOT
ea10: 5f 55 53 45 44 3b 0a 20 20 20 20 20 20 20 20 77  _USED;.        w
ea20: 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
ea30: 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
ea40: 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20  _LOCK(i), 1);.  
ea50: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63      }else if( rc
ea60: 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b  ==SQLITE_BUSY ){
ea70: 0a 20 20 20 20 20 20 20 20 6d 78 53 61 66 65 46  .        mxSafeF
ea80: 72 61 6d 65 20 3d 20 79 3b 0a 20 20 20 20 20 20  rame = y;.      
ea90: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 67  }else{.        g
eaa0: 6f 74 6f 20 77 61 6c 63 68 65 63 6b 70 6f 69 6e  oto walcheckpoin
eab0: 74 5f 6f 75 74 3b 0a 20 20 20 20 20 20 7d 0a 20  t_out;.      }. 
eac0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
ead0: 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
eae0: 3c 6d 78 53 61 66 65 46 72 61 6d 65 0a 20 20 20  <mxSafeFrame.   
eaf0: 26 26 20 28 72 63 20 3d 20 77 61 6c 4c 6f 63 6b  && (rc = walLock
eb00: 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
eb10: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29  WAL_READ_LOCK(0)
eb20: 2c 20 31 29 29 3d 3d 53 51 4c 49 54 45 5f 4f 4b  , 1))==SQLITE_OK
eb30: 0a 20 20 29 7b 0a 20 20 20 20 75 33 32 20 6e 42  .  ){.    u32 nB
eb40: 61 63 6b 66 69 6c 6c 20 3d 20 70 49 6e 66 6f 2d  ackfill = pInfo-
eb50: 3e 6e 42 61 63 6b 66 69 6c 6c 3b 0a 0a 20 20 20  >nBackfill;..   
eb60: 20 2f 2a 20 53 79 6e 63 20 74 68 65 20 57 41 4c   /* Sync the WAL
eb70: 20 74 6f 20 64 69 73 6b 20 2a 2f 0a 20 20 20 20   to disk */.    
eb80: 69 66 28 20 73 79 6e 63 5f 66 6c 61 67 73 20 29  if( sync_flags )
eb90: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  {.      rc = sql
eba0: 69 74 65 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d  ite3OsSync(pWal-
ebb0: 3e 70 57 61 6c 46 64 2c 20 73 79 6e 63 5f 66 6c  >pWalFd, sync_fl
ebc0: 61 67 73 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  ags);.    }..   
ebd0: 20 2f 2a 20 49 74 65 72 61 74 65 20 74 68 72 6f   /* Iterate thro
ebe0: 75 67 68 20 74 68 65 20 63 6f 6e 74 65 6e 74 73  ugh the contents
ebf0: 20 6f 66 20 74 68 65 20 57 41 4c 2c 20 63 6f 70   of the WAL, cop
ec00: 79 69 6e 67 20 64 61 74 61 20 74 6f 20 74 68 65  ying data to the
ec10: 20 64 62 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 20   db file. */.   
ec20: 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49   while( rc==SQLI
ec30: 54 45 5f 4f 4b 20 26 26 20 30 3d 3d 77 61 6c 49  TE_OK && 0==walI
ec40: 74 65 72 61 74 6f 72 4e 65 78 74 28 70 49 74 65  teratorNext(pIte
ec50: 72 2c 20 26 69 44 62 70 61 67 65 2c 20 26 69 46  r, &iDbpage, &iF
ec60: 72 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20 69  rame) ){.      i
ec70: 36 34 20 69 4f 66 66 73 65 74 3b 0a 20 20 20 20  64 iOffset;.    
ec80: 20 20 61 73 73 65 72 74 28 20 77 61 6c 46 72 61    assert( walFra
ec90: 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 46 72  mePgno(pWal, iFr
eca0: 61 6d 65 29 3d 3d 69 44 62 70 61 67 65 20 29 3b  ame)==iDbpage );
ecb0: 0a 20 20 20 20 20 20 69 66 28 20 69 46 72 61 6d  .      if( iFram
ecc0: 65 3c 3d 6e 42 61 63 6b 66 69 6c 6c 20 7c 7c 20  e<=nBackfill || 
ecd0: 69 46 72 61 6d 65 3e 6d 78 53 61 66 65 46 72 61  iFrame>mxSafeFra
ece0: 6d 65 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20  me ) continue;. 
ecf0: 20 20 20 20 20 69 4f 66 66 73 65 74 20 3d 20 77       iOffset = w
ed00: 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 69 46  alFrameOffset(iF
ed10: 72 61 6d 65 2c 20 73 7a 50 61 67 65 29 20 2b 20  rame, szPage) + 
ed20: 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a  WAL_FRAME_HDRSIZ
ed30: 45 3b 0a 20 20 20 20 20 20 2f 2a 20 74 65 73 74  E;.      /* test
ed40: 63 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54  case( IS_BIG_INT
ed50: 28 69 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f 20  (iOffset) ); // 
ed60: 72 65 71 75 69 72 65 73 20 61 20 34 47 69 42 20  requires a 4GiB 
ed70: 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20  WAL file */.    
ed80: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
ed90: 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46  Read(pWal->pWalF
eda0: 64 2c 20 7a 42 75 66 2c 20 73 7a 50 61 67 65 2c  d, zBuf, szPage,
edb0: 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20   iOffset);.     
edc0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
edd0: 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  OK ) break;.    
ede0: 20 20 69 4f 66 66 73 65 74 20 3d 20 28 69 44 62    iOffset = (iDb
edf0: 70 61 67 65 2d 31 29 2a 28 69 36 34 29 73 7a 50  page-1)*(i64)szP
ee00: 61 67 65 3b 0a 20 20 20 20 20 20 74 65 73 74 63  age;.      testc
ee10: 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28  ase( IS_BIG_INT(
ee20: 69 4f 66 66 73 65 74 29 20 29 3b 0a 20 20 20 20  iOffset) );.    
ee30: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
ee40: 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 44 62 46  Write(pWal->pDbF
ee50: 64 2c 20 7a 42 75 66 2c 20 73 7a 50 61 67 65 2c  d, zBuf, szPage,
ee60: 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20   iOffset);.     
ee70: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
ee80: 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  OK ) break;.    
ee90: 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 77 6f 72  }..    /* If wor
eea0: 6b 20 77 61 73 20 61 63 74 75 61 6c 6c 79 20 61  k was actually a
eeb0: 63 63 6f 6d 70 6c 69 73 68 65 64 2e 2e 2e 20 2a  ccomplished... *
eec0: 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  /.    if( rc==SQ
eed0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
eee0: 20 69 66 28 20 6d 78 53 61 66 65 46 72 61 6d 65   if( mxSafeFrame
eef0: 3d 3d 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57  ==walIndexHdr(pW
ef00: 61 6c 29 2d 3e 6d 78 46 72 61 6d 65 20 29 7b 0a  al)->mxFrame ){.
ef10: 20 20 20 20 20 20 20 20 69 36 34 20 73 7a 44 62          i64 szDb
ef20: 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61   = pWal->hdr.nPa
ef30: 67 65 2a 28 69 36 34 29 73 7a 50 61 67 65 3b 0a  ge*(i64)szPage;.
ef40: 20 20 20 20 20 20 20 20 74 65 73 74 63 61 73 65          testcase
ef50: 28 20 49 53 5f 42 49 47 5f 49 4e 54 28 73 7a 44  ( IS_BIG_INT(szD
ef60: 62 29 20 29 3b 0a 20 20 20 20 20 20 20 20 72 63  b) );.        rc
ef70: 20 3d 20 73 71 6c 69 74 65 33 4f 73 54 72 75 6e   = sqlite3OsTrun
ef80: 63 61 74 65 28 70 57 61 6c 2d 3e 70 44 62 46 64  cate(pWal->pDbFd
ef90: 2c 20 73 7a 44 62 29 3b 0a 20 20 20 20 20 20 20  , szDb);.       
efa0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
efb0: 4f 4b 20 26 26 20 73 79 6e 63 5f 66 6c 61 67 73  OK && sync_flags
efc0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63   ){.          rc
efd0: 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63   = sqlite3OsSync
efe0: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 73 79  (pWal->pDbFd, sy
eff0: 6e 63 5f 66 6c 61 67 73 29 3b 0a 20 20 20 20 20  nc_flags);.     
f000: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
f010: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
f020: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
f030: 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
f040: 20 3d 20 6d 78 53 61 66 65 46 72 61 6d 65 3b 0a   = mxSafeFrame;.
f050: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
f060: 20 20 20 2f 2a 20 52 65 6c 65 61 73 65 20 74 68     /* Release th
f070: 65 20 72 65 61 64 65 72 20 6c 6f 63 6b 20 68 65  e reader lock he
f080: 6c 64 20 77 68 69 6c 65 20 62 61 63 6b 66 69 6c  ld while backfil
f090: 6c 69 6e 67 20 2a 2f 0a 20 20 20 20 77 61 6c 55  ling */.    walU
f0a0: 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  nlockExclusive(p
f0b0: 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
f0c0: 43 4b 28 30 29 2c 20 31 29 3b 0a 20 20 7d 65 6c  CK(0), 1);.  }el
f0d0: 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  se if( rc==SQLIT
f0e0: 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 2f 2a  E_BUSY ){.    /*
f0f0: 20 52 65 73 65 74 20 74 68 65 20 72 65 74 75 72   Reset the retur
f100: 6e 20 63 6f 64 65 20 73 6f 20 61 73 20 6e 6f 74  n code so as not
f110: 20 74 6f 20 72 65 70 6f 72 74 20 61 20 63 68 65   to report a che
f120: 63 6b 70 6f 69 6e 74 20 66 61 69 6c 75 72 65 0a  ckpoint failure.
f130: 20 20 20 20 2a 2a 20 6a 75 73 74 20 62 65 63 61      ** just beca
f140: 75 73 65 20 61 63 74 69 76 65 20 72 65 61 64 65  use active reade
f150: 72 73 20 70 72 65 76 65 6e 74 20 61 6e 79 20 62  rs prevent any b
f160: 61 63 6b 66 69 6c 6c 2e 0a 20 20 20 20 2a 2f 0a  ackfill..    */.
f170: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
f180: 4f 4b 3b 0a 20 20 7d 0a 0a 20 77 61 6c 63 68 65  OK;.  }.. walche
f190: 63 6b 70 6f 69 6e 74 5f 6f 75 74 3a 0a 20 20 77  ckpoint_out:.  w
f1a0: 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28 70  alIteratorFree(p
f1b0: 49 74 65 72 29 3b 0a 20 20 72 65 74 75 72 6e 20  Iter);.  return 
f1c0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f  rc;.}../*.** Clo
f1d0: 73 65 20 61 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  se a connection 
f1e0: 74 6f 20 61 20 6c 6f 67 20 66 69 6c 65 2e 0a 2a  to a log file..*
f1f0: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c  /.int sqlite3Wal
f200: 43 6c 6f 73 65 28 0a 20 20 57 61 6c 20 2a 70 57  Close(.  Wal *pW
f210: 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
f220: 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20           /* Wal 
f230: 74 6f 20 63 6c 6f 73 65 20 2a 2f 0a 20 20 69 6e  to close */.  in
f240: 74 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20  t sync_flags,   
f250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
f260: 20 46 6c 61 67 73 20 74 6f 20 70 61 73 73 20 74   Flags to pass t
f270: 6f 20 4f 73 53 79 6e 63 28 29 20 28 6f 72 20 30  o OsSync() (or 0
f280: 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 2c  ) */.  int nBuf,
f290: 0a 20 20 75 38 20 2a 7a 42 75 66 20 20 20 20 20  .  u8 *zBuf     
f2a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f2b0: 20 20 20 2f 2a 20 42 75 66 66 65 72 20 6f 66 20     /* Buffer of 
f2c0: 61 74 20 6c 65 61 73 74 20 6e 42 75 66 20 62 79  at least nBuf by
f2d0: 74 65 73 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  tes */.){.  int 
f2e0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
f2f0: 20 20 69 66 28 20 70 57 61 6c 20 29 7b 0a 20 20    if( pWal ){.  
f300: 20 20 69 6e 74 20 69 73 44 65 6c 65 74 65 20 3d    int isDelete =
f310: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
f320: 2f 2a 20 54 72 75 65 20 74 6f 20 75 6e 6c 69 6e  /* True to unlin
f330: 6b 20 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e  k wal and wal-in
f340: 64 65 78 20 66 69 6c 65 73 20 2a 2f 0a 0a 20 20  dex files */..  
f350: 20 20 2f 2a 20 49 66 20 61 6e 20 45 58 43 4c 55    /* If an EXCLU
f360: 53 49 56 45 20 6c 6f 63 6b 20 63 61 6e 20 62 65  SIVE lock can be
f370: 20 6f 62 74 61 69 6e 65 64 20 6f 6e 20 74 68 65   obtained on the
f380: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 28   database file (
f390: 75 73 69 6e 67 20 74 68 65 0a 20 20 20 20 2a 2a  using the.    **
f3a0: 20 6f 72 64 69 6e 61 72 79 2c 20 72 6f 6c 6c 62   ordinary, rollb
f3b0: 61 63 6b 2d 6d 6f 64 65 20 6c 6f 63 6b 69 6e 67  ack-mode locking
f3c0: 20 6d 65 74 68 6f 64 73 2c 20 74 68 69 73 20 67   methods, this g
f3d0: 75 61 72 61 6e 74 65 65 73 20 74 68 61 74 20 74  uarantees that t
f3e0: 68 65 0a 20 20 20 20 2a 2a 20 63 6f 6e 6e 65 63  he.    ** connec
f3f0: 74 69 6f 6e 20 61 73 73 6f 63 69 61 74 65 64 20  tion associated 
f400: 77 69 74 68 20 74 68 69 73 20 6c 6f 67 20 66 69  with this log fi
f410: 6c 65 20 69 73 20 74 68 65 20 6f 6e 6c 79 20 63  le is the only c
f420: 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 0a 20 20 20  onnection to.   
f430: 20 2a 2a 20 74 68 65 20 64 61 74 61 62 61 73 65   ** the database
f440: 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 20 63  . In this case c
f450: 68 65 63 6b 70 6f 69 6e 74 20 74 68 65 20 64 61  heckpoint the da
f460: 74 61 62 61 73 65 20 61 6e 64 20 75 6e 6c 69 6e  tabase and unlin
f470: 6b 20 62 6f 74 68 0a 20 20 20 20 2a 2a 20 74 68  k both.    ** th
f480: 65 20 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e  e wal and wal-in
f490: 64 65 78 20 66 69 6c 65 73 2e 0a 20 20 20 20 2a  dex files..    *
f4a0: 2a 0a 20 20 20 20 2a 2a 20 54 68 65 20 45 58 43  *.    ** The EXC
f4b0: 4c 55 53 49 56 45 20 6c 6f 63 6b 20 69 73 20 6e  LUSIVE lock is n
f4c0: 6f 74 20 72 65 6c 65 61 73 65 64 20 62 65 66 6f  ot released befo
f4d0: 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 20 20  re returning..  
f4e0: 20 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 71    */.    rc = sq
f4f0: 6c 69 74 65 33 4f 73 4c 6f 63 6b 28 70 57 61 6c  lite3OsLock(pWal
f500: 2d 3e 70 44 62 46 64 2c 20 53 51 4c 49 54 45 5f  ->pDbFd, SQLITE_
f510: 4c 4f 43 4b 5f 45 58 43 4c 55 53 49 56 45 29 3b  LOCK_EXCLUSIVE);
f520: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
f530: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
f540: 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
f550: 6f 64 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 72  ode = 1;.      r
f560: 63 20 3d 20 73 71 6c 69 74 65 33 57 61 6c 43 68  c = sqlite3WalCh
f570: 65 63 6b 70 6f 69 6e 74 28 70 57 61 6c 2c 20 73  eckpoint(pWal, s
f580: 79 6e 63 5f 66 6c 61 67 73 2c 20 6e 42 75 66 2c  ync_flags, nBuf,
f590: 20 7a 42 75 66 29 3b 0a 20 20 20 20 20 20 69 66   zBuf);.      if
f5a0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
f5b0: 29 7b 0a 20 20 20 20 20 20 20 20 69 73 44 65 6c  ){.        isDel
f5c0: 65 74 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d  ete = 1;.      }
f5d0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 77 61 6c 49  .    }..    walI
f5e0: 6e 64 65 78 43 6c 6f 73 65 28 70 57 61 6c 2c 20  ndexClose(pWal, 
f5f0: 69 73 44 65 6c 65 74 65 29 3b 0a 20 20 20 20 73  isDelete);.    s
f600: 71 6c 69 74 65 33 4f 73 43 6c 6f 73 65 28 70 57  qlite3OsClose(pW
f610: 61 6c 2d 3e 70 57 61 6c 46 64 29 3b 0a 20 20 20  al->pWalFd);.   
f620: 20 69 66 28 20 69 73 44 65 6c 65 74 65 20 29 7b   if( isDelete ){
f630: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73  .      sqlite3Os
f640: 44 65 6c 65 74 65 28 70 57 61 6c 2d 3e 70 56 66  Delete(pWal->pVf
f650: 73 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d  s, pWal->zWalNam
f660: 65 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 20 20 20  e, 0);.    }.   
f670: 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25   WALTRACE(("WAL%
f680: 70 3a 20 63 6c 6f 73 65 64 5c 6e 22 2c 20 70 57  p: closed\n", pW
f690: 61 6c 29 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  al));.    sqlite
f6a0: 33 5f 66 72 65 65 28 28 76 6f 69 64 20 2a 29 70  3_free((void *)p
f6b0: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 29 3b 0a  Wal->apWiData);.
f6c0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
f6d0: 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20 20 72 65  (pWal);.  }.  re
f6e0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
f6f0: 2a 20 54 72 79 20 74 6f 20 72 65 61 64 20 74 68  * Try to read th
f700: 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
f710: 65 72 2e 20 20 52 65 74 75 72 6e 20 30 20 6f 6e  er.  Return 0 on
f720: 20 73 75 63 63 65 73 73 20 61 6e 64 20 31 20 69   success and 1 i
f730: 66 0a 2a 2a 20 74 68 65 72 65 20 69 73 20 61 20  f.** there is a 
f740: 70 72 6f 62 6c 65 6d 2e 0a 2a 2a 0a 2a 2a 20 54  problem..**.** T
f750: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
f760: 69 6e 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79  in shared memory
f770: 2e 20 20 41 6e 6f 74 68 65 72 20 74 68 72 65 61  .  Another threa
f780: 64 20 6f 72 20 70 72 6f 63 65 73 73 20 6d 69 67  d or process mig
f790: 68 74 0a 2a 2a 20 62 65 20 77 72 69 74 69 6e 67  ht.** be writing
f7a0: 20 74 68 65 20 68 65 61 64 65 72 20 61 74 20 74   the header at t
f7b0: 68 65 20 73 61 6d 65 20 74 69 6d 65 20 74 68 69  he same time thi
f7c0: 73 20 70 72 6f 63 65 64 75 72 65 20 69 73 20 74  s procedure is t
f7d0: 72 79 69 6e 67 20 74 6f 0a 2a 2a 20 72 65 61 64  rying to.** read
f7e0: 20 69 74 2c 20 77 68 69 63 68 20 6d 69 67 68 74   it, which might
f7f0: 20 72 65 73 75 6c 74 20 69 6e 20 69 6e 63 6f 6e   result in incon
f800: 73 69 73 74 65 6e 63 79 2e 20 20 41 20 64 69 72  sistency.  A dir
f810: 74 79 20 72 65 61 64 20 69 73 20 64 65 74 65 63  ty read is detec
f820: 74 65 64 0a 2a 2a 20 62 79 20 76 65 72 69 66 79  ted.** by verify
f830: 69 6e 67 20 74 68 61 74 20 62 6f 74 68 20 63 6f  ing that both co
f840: 70 69 65 73 20 6f 66 20 74 68 65 20 68 65 61 64  pies of the head
f850: 65 72 20 61 72 65 20 74 68 65 20 73 61 6d 65 20  er are the same 
f860: 61 6e 64 20 61 6c 73 6f 20 62 79 0a 2a 2a 20 61  and also by.** a
f870: 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20 74 68 65   checksum on the
f880: 20 68 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 49   header..**.** I
f890: 66 20 61 6e 64 20 6f 6e 6c 79 20 69 66 20 74 68  f and only if th
f8a0: 65 20 72 65 61 64 20 69 73 20 63 6f 6e 73 69 73  e read is consis
f8b0: 74 65 6e 74 20 61 6e 64 20 74 68 65 20 68 65 61  tent and the hea
f8c0: 64 65 72 20 69 73 20 64 69 66 66 65 72 65 6e 74  der is different
f8d0: 20 66 72 6f 6d 0a 2a 2a 20 70 57 61 6c 2d 3e 68   from.** pWal->h
f8e0: 64 72 2c 20 74 68 65 6e 20 70 57 61 6c 2d 3e 68  dr, then pWal->h
f8f0: 64 72 20 69 73 20 75 70 64 61 74 65 64 20 74 6f  dr is updated to
f900: 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20   the content of 
f910: 74 68 65 20 6e 65 77 20 68 65 61 64 65 72 0a 2a  the new header.*
f920: 2a 20 61 6e 64 20 2a 70 43 68 61 6e 67 65 64 20  * and *pChanged 
f930: 69 73 20 73 65 74 20 74 6f 20 31 2e 0a 2a 2a 0a  is set to 1..**.
f940: 2a 2a 20 49 66 20 74 68 65 20 63 68 65 63 6b 73  ** If the checks
f950: 75 6d 20 63 61 6e 6e 6f 74 20 62 65 20 76 65 72  um cannot be ver
f960: 69 66 69 65 64 20 72 65 74 75 72 6e 20 6e 6f 6e  ified return non
f970: 2d 7a 65 72 6f 2e 20 49 66 20 74 68 65 20 68 65  -zero. If the he
f980: 61 64 65 72 0a 2a 2a 20 69 73 20 72 65 61 64 20  ader.** is read 
f990: 73 75 63 63 65 73 73 66 75 6c 6c 79 20 61 6e 64  successfully and
f9a0: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 76 65   the checksum ve
f9b0: 72 69 66 69 65 64 2c 20 72 65 74 75 72 6e 20 7a  rified, return z
f9c0: 65 72 6f 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ero..*/.static i
f9d0: 6e 74 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64  nt walIndexTryHd
f9e0: 72 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  r(Wal *pWal, int
f9f0: 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a 20 20 75   *pChanged){.  u
fa00: 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20  32 aCksum[2];   
fa10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
fa20: 2a 20 43 68 65 63 6b 73 75 6d 20 6f 6e 20 74 68  * Checksum on th
fa30: 65 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74  e header content
fa40: 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65 78 48 64   */.  WalIndexHd
fa50: 72 20 68 31 2c 20 68 32 3b 20 20 20 20 20 20 20  r h1, h2;       
fa60: 20 20 20 20 20 20 2f 2a 20 54 77 6f 20 63 6f 70        /* Two cop
fa70: 69 65 73 20 6f 66 20 74 68 65 20 68 65 61 64 65  ies of the heade
fa80: 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 57  r content */.  W
fa90: 61 6c 49 6e 64 65 78 48 64 72 20 76 6f 6c 61 74  alIndexHdr volat
faa0: 69 6c 65 20 2a 61 48 64 72 3b 20 20 20 20 20 2f  ile *aHdr;     /
fab0: 2a 20 48 65 61 64 65 72 20 69 6e 20 73 68 61 72  * Header in shar
fac0: 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a 0a 20 20  ed memory */..  
fad0: 2f 2a 20 54 68 65 20 66 69 72 73 74 20 70 61 67  /* The first pag
fae0: 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  e of the wal-ind
faf0: 65 78 20 6d 75 73 74 20 62 65 20 6d 61 70 70 65  ex must be mappe
fb00: 64 20 61 74 20 74 68 69 73 20 70 6f 69 6e 74 2e  d at this point.
fb10: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57   */.  assert( pW
fb20: 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20 26 26  al->nWiData>0 &&
fb30: 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
fb40: 30 5d 20 29 3b 0a 0a 20 20 2f 2a 20 52 65 61 64  0] );..  /* Read
fb50: 20 74 68 65 20 68 65 61 64 65 72 2e 20 54 68 69   the header. Thi
fb60: 73 20 6d 69 67 68 74 20 68 61 70 70 65 6e 20 63  s might happen c
fb70: 75 72 72 65 6e 74 6c 79 20 77 69 74 68 20 61 20  urrently with a 
fb80: 77 72 69 74 65 20 74 6f 20 74 68 65 0a 20 20 2a  write to the.  *
fb90: 2a 20 73 61 6d 65 20 61 72 65 61 20 6f 66 20 73  * same area of s
fba0: 68 61 72 65 64 20 6d 65 6d 6f 72 79 20 6f 6e 20  hared memory on 
fbb0: 61 20 64 69 66 66 65 72 65 6e 74 20 43 50 55 20  a different CPU 
fbc0: 69 6e 20 61 20 53 4d 50 2c 0a 20 20 2a 2a 20 6d  in a SMP,.  ** m
fbd0: 65 61 6e 69 6e 67 20 69 74 20 69 73 20 70 6f 73  eaning it is pos
fbe0: 73 69 62 6c 65 20 74 68 61 74 20 61 6e 20 69 6e  sible that an in
fbf0: 63 6f 6e 73 69 73 74 65 6e 74 20 73 6e 61 70 73  consistent snaps
fc00: 68 6f 74 20 69 73 20 72 65 61 64 0a 20 20 2a 2a  hot is read.  **
fc10: 20 66 72 6f 6d 20 74 68 65 20 66 69 6c 65 2e 20   from the file. 
fc20: 49 66 20 74 68 69 73 20 68 61 70 70 65 6e 73 2c  If this happens,
fc30: 20 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f   return non-zero
fc40: 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 72  ..  **.  ** Ther
fc50: 65 20 61 72 65 20 74 77 6f 20 63 6f 70 69 65 73  e are two copies
fc60: 20 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 61   of the header a
fc70: 74 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20  t the beginning 
fc80: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
fc90: 2e 0a 20 20 2a 2a 20 57 68 65 6e 20 72 65 61 64  ..  ** When read
fca0: 69 6e 67 2c 20 72 65 61 64 20 5b 30 5d 20 66 69  ing, read [0] fi
fcb0: 72 73 74 20 74 68 65 6e 20 5b 31 5d 2e 20 20 57  rst then [1].  W
fcc0: 72 69 74 65 73 20 61 72 65 20 69 6e 20 74 68 65  rites are in the
fcd0: 20 72 65 76 65 72 73 65 20 6f 72 64 65 72 2e 0a   reverse order..
fce0: 20 20 2a 2a 20 4d 65 6d 6f 72 79 20 62 61 72 72    ** Memory barr
fcf0: 69 65 72 73 20 61 72 65 20 75 73 65 64 20 74 6f  iers are used to
fd00: 20 70 72 65 76 65 6e 74 20 74 68 65 20 63 6f 6d   prevent the com
fd10: 70 69 6c 65 72 20 6f 72 20 74 68 65 20 68 61 72  piler or the har
fd20: 64 77 61 72 65 20 66 72 6f 6d 0a 20 20 2a 2a 20  dware from.  ** 
fd30: 72 65 6f 72 64 65 72 69 6e 67 20 74 68 65 20 72  reordering the r
fd40: 65 61 64 73 20 61 6e 64 20 77 72 69 74 65 73 2e  eads and writes.
fd50: 0a 20 20 2a 2f 0a 20 20 61 48 64 72 20 3d 20 77  .  */.  aHdr = w
fd60: 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29  alIndexHdr(pWal)
fd70: 3b 0a 20 20 6d 65 6d 63 70 79 28 26 68 31 2c 20  ;.  memcpy(&h1, 
fd80: 28 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 30 5d  (void *)&aHdr[0]
fd90: 2c 20 73 69 7a 65 6f 66 28 68 31 29 29 3b 0a 20  , sizeof(h1));. 
fda0: 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 42 61 72   sqlite3OsShmBar
fdb0: 72 69 65 72 28 70 57 61 6c 2d 3e 70 44 62 46 64  rier(pWal->pDbFd
fdc0: 29 3b 0a 20 20 6d 65 6d 63 70 79 28 26 68 32 2c  );.  memcpy(&h2,
fdd0: 20 28 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 31   (void *)&aHdr[1
fde0: 5d 2c 20 73 69 7a 65 6f 66 28 68 32 29 29 3b 0a  ], sizeof(h2));.
fdf0: 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 68  .  if( memcmp(&h
fe00: 31 2c 20 26 68 32 2c 20 73 69 7a 65 6f 66 28 68  1, &h2, sizeof(h
fe10: 31 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65  1))!=0 ){.    re
fe20: 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20 44 69 72  turn 1;   /* Dir
fe30: 74 79 20 72 65 61 64 20 2a 2f 0a 20 20 7d 20 20  ty read */.  }  
fe40: 0a 20 20 69 66 28 20 68 31 2e 69 73 49 6e 69 74  .  if( h1.isInit
fe50: 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  ==0 ){.    retur
fe60: 6e 20 31 3b 20 20 20 2f 2a 20 4d 61 6c 66 6f 72  n 1;   /* Malfor
fe70: 6d 65 64 20 68 65 61 64 65 72 20 2d 20 70 72 6f  med header - pro
fe80: 62 61 62 6c 79 20 61 6c 6c 20 7a 65 72 6f 73 20  bably all zeros 
fe90: 2a 2f 0a 20 20 7d 0a 20 20 77 61 6c 43 68 65 63  */.  }.  walChec
fea0: 6b 73 75 6d 42 79 74 65 73 28 31 2c 20 28 75 38  ksumBytes(1, (u8
feb0: 2a 29 26 68 31 2c 20 73 69 7a 65 6f 66 28 68 31  *)&h1, sizeof(h1
fec0: 29 2d 73 69 7a 65 6f 66 28 68 31 2e 61 43 6b 73  )-sizeof(h1.aCks
fed0: 75 6d 29 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b  um), 0, aCksum);
fee0: 0a 20 20 69 66 28 20 61 43 6b 73 75 6d 5b 30 5d  .  if( aCksum[0]
fef0: 21 3d 68 31 2e 61 43 6b 73 75 6d 5b 30 5d 20 7c  !=h1.aCksum[0] |
ff00: 7c 20 61 43 6b 73 75 6d 5b 31 5d 21 3d 68 31 2e  | aCksum[1]!=h1.
ff10: 61 43 6b 73 75 6d 5b 31 5d 20 29 7b 0a 20 20 20  aCksum[1] ){.   
ff20: 20 72 65 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20   return 1;   /* 
ff30: 43 68 65 63 6b 73 75 6d 20 64 6f 65 73 20 6e 6f  Checksum does no
ff40: 74 20 6d 61 74 63 68 20 2a 2f 0a 20 20 7d 0a 0a  t match */.  }..
ff50: 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57    if( memcmp(&pW
ff60: 61 6c 2d 3e 68 64 72 2c 20 26 68 31 2c 20 73 69  al->hdr, &h1, si
ff70: 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
ff80: 29 29 20 29 7b 0a 20 20 20 20 2a 70 43 68 61 6e  )) ){.    *pChan
ff90: 67 65 64 20 3d 20 31 3b 0a 20 20 20 20 6d 65 6d  ged = 1;.    mem
ffa0: 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20  cpy(&pWal->hdr, 
ffb0: 26 68 31 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49  &h1, sizeof(WalI
ffc0: 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 20 20 70  ndexHdr));.    p
ffd0: 57 61 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 70 57  Wal->szPage = pW
ffe0: 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 3b 0a  al->hdr.szPage;.
fff0: 20 20 7d 0a 0a 20 20 2f 2a 20 54 68 65 20 68 65    }..  /* The he
10000 61 64 65 72 20 77 61 73 20 73 75 63 63 65 73 73  ader was success
10010 66 75 6c 6c 79 20 72 65 61 64 2e 20 52 65 74 75  fully read. Retu
10020 72 6e 20 7a 65 72 6f 2e 20 2a 2f 0a 20 20 72 65  rn zero. */.  re
10030 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn 0;.}../*.**
10040 20 52 65 61 64 20 74 68 65 20 77 61 6c 2d 69 6e   Read the wal-in
10050 64 65 78 20 68 65 61 64 65 72 20 66 72 6f 6d 20  dex header from 
10060 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 61 6e  the wal-index an
10070 64 20 69 6e 74 6f 20 70 57 61 6c 2d 3e 68 64 72  d into pWal->hdr
10080 2e 0a 2a 2a 20 49 66 20 74 68 65 20 77 61 6c 2d  ..** If the wal-
10090 68 65 61 64 65 72 20 61 70 70 65 61 72 73 20 74  header appears t
100a0 6f 20 62 65 20 63 6f 72 72 75 70 74 2c 20 74 72  o be corrupt, tr
100b0 79 20 74 6f 20 72 65 63 6f 6e 73 74 72 75 63 74  y to reconstruct
100c0 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65   the.** wal-inde
100d0 78 20 66 72 6f 6d 20 74 68 65 20 57 41 4c 20 62  x from the WAL b
100e0 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
100f0 0a 2a 2a 0a 2a 2a 20 53 65 74 20 2a 70 43 68 61  .**.** Set *pCha
10100 6e 67 65 64 20 74 6f 20 31 20 69 66 20 74 68 65  nged to 1 if the
10110 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
10120 72 20 76 61 6c 75 65 20 69 6e 20 70 57 61 6c 2d  r value in pWal-
10130 3e 68 64 72 20 69 73 0a 2a 2a 20 63 68 61 6e 67  >hdr is.** chang
10140 65 64 20 62 79 20 74 68 69 73 20 6f 70 65 72 74  ed by this opert
10150 69 6f 6e 2e 20 20 49 66 20 70 57 61 6c 2d 3e 68  ion.  If pWal->h
10160 64 72 20 69 73 20 75 6e 63 68 61 6e 67 65 64 2c  dr is unchanged,
10170 20 73 65 74 20 2a 70 43 68 61 6e 67 65 64 0a 2a   set *pChanged.*
10180 2a 20 74 6f 20 30 2e 0a 2a 2a 0a 2a 2a 20 49 66  * to 0..**.** If
10190 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
101a0 65 61 64 65 72 20 69 73 20 73 75 63 63 65 73 73  eader is success
101b0 66 75 6c 6c 79 20 72 65 61 64 2c 20 72 65 74 75  fully read, retu
101c0 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 0a 2a  rn SQLITE_OK. .*
101d0 2a 20 4f 74 68 65 72 77 69 73 65 20 61 6e 20 53  * Otherwise an S
101e0 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
101f0 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
10200 77 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28  walIndexReadHdr(
10210 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a  Wal *pWal, int *
10220 70 43 68 61 6e 67 65 64 29 7b 0a 20 20 69 6e 74  pChanged){.  int
10230 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
10240 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
10250 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
10260 20 69 6e 74 20 62 61 64 48 64 72 3b 20 20 20 20   int badHdr;    
10270 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10280 20 2f 2a 20 54 72 75 65 20 69 66 20 61 20 68 65   /* True if a he
10290 61 64 65 72 20 72 65 61 64 20 66 61 69 6c 65 64  ader read failed
102a0 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75   */.  volatile u
102b0 33 32 20 2a 70 61 67 65 30 3b 20 20 20 20 20 20  32 *page0;      
102c0 20 20 20 20 20 20 2f 2a 20 43 68 75 6e 6b 20 6f        /* Chunk o
102d0 66 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 74  f wal-index cont
102e0 61 69 6e 69 6e 67 20 68 65 61 64 65 72 20 2a 2f  aining header */
102f0 0a 0a 20 20 2f 2a 20 45 6e 73 75 72 65 20 74 68  ..  /* Ensure th
10300 61 74 20 70 61 67 65 20 30 20 6f 66 20 74 68 65  at page 0 of the
10310 20 77 61 6c 2d 69 6e 64 65 78 20 28 74 68 65 20   wal-index (the 
10320 70 61 67 65 20 74 68 61 74 20 63 6f 6e 74 61 69  page that contai
10330 6e 73 20 74 68 65 20 0a 20 20 2a 2a 20 77 61 6c  ns the .  ** wal
10340 2d 69 6e 64 65 78 20 68 65 61 64 65 72 29 20 69  -index header) i
10350 73 20 6d 61 70 70 65 64 2e 20 52 65 74 75 72 6e  s mapped. Return
10360 20 65 61 72 6c 79 20 69 66 20 61 6e 20 65 72 72   early if an err
10370 6f 72 20 6f 63 63 75 72 73 20 68 65 72 65 2e 0a  or occurs here..
10380 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70    */.  assert( p
10390 43 68 61 6e 67 65 64 20 29 3b 0a 20 20 72 63 20  Changed );.  rc 
103a0 3d 20 77 61 6c 49 6e 64 65 78 50 61 67 65 28 70  = walIndexPage(p
103b0 57 61 6c 2c 20 30 2c 20 26 70 61 67 65 30 29 3b  Wal, 0, &page0);
103c0 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
103d0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74 75  E_OK ){.    retu
103e0 72 6e 20 72 63 3b 0a 20 20 7d 3b 0a 20 20 61 73  rn rc;.  };.  as
103f0 73 65 72 74 28 20 70 61 67 65 30 20 7c 7c 20 70  sert( page0 || p
10400 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d  Wal->writeLock==
10410 30 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68  0 );..  /* If th
10420 65 20 66 69 72 73 74 20 70 61 67 65 20 6f 66 20  e first page of 
10430 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 61  the wal-index ha
10440 73 20 62 65 65 6e 20 6d 61 70 70 65 64 2c 20 74  s been mapped, t
10450 72 79 20 74 6f 20 72 65 61 64 20 74 68 65 0a 20  ry to read the. 
10460 20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65   ** wal-index he
10470 61 64 65 72 20 69 6d 6d 65 64 69 61 74 65 6c 79  ader immediately
10480 2c 20 77 69 74 68 6f 75 74 20 68 6f 6c 64 69 6e  , without holdin
10490 67 20 61 6e 79 20 6c 6f 63 6b 2e 20 54 68 69 73  g any lock. This
104a0 20 75 73 75 61 6c 6c 79 0a 20 20 2a 2a 20 77 6f   usually.  ** wo
104b0 72 6b 73 2c 20 62 75 74 20 6d 61 79 20 66 61 69  rks, but may fai
104c0 6c 20 69 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  l if the wal-ind
104d0 65 78 20 68 65 61 64 65 72 20 69 73 20 63 6f 72  ex header is cor
104e0 72 75 70 74 20 6f 72 20 63 75 72 72 65 6e 74 6c  rupt or currentl
104f0 79 20 0a 20 20 2a 2a 20 62 65 69 6e 67 20 6d 6f  y .  ** being mo
10500 64 69 66 69 65 64 20 62 79 20 61 6e 6f 74 68 65  dified by anothe
10510 72 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63  r thread or proc
10520 65 73 73 2e 0a 20 20 2a 2f 0a 20 20 62 61 64 48  ess..  */.  badH
10530 64 72 20 3d 20 28 70 61 67 65 30 20 3f 20 77 61  dr = (page0 ? wa
10540 6c 49 6e 64 65 78 54 72 79 48 64 72 28 70 57 61  lIndexTryHdr(pWa
10550 6c 2c 20 70 43 68 61 6e 67 65 64 29 20 3a 20 31  l, pChanged) : 1
10560 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20  );..  /* If the 
10570 66 69 72 73 74 20 61 74 74 65 6d 70 74 20 66 61  first attempt fa
10580 69 6c 65 64 2c 20 69 74 20 6d 69 67 68 74 20 68  iled, it might h
10590 61 76 65 20 62 65 65 6e 20 64 75 65 20 74 6f 20  ave been due to 
105a0 61 20 72 61 63 65 0a 20 20 2a 2a 20 77 69 74 68  a race.  ** with
105b0 20 61 20 77 72 69 74 65 72 2e 20 20 53 6f 20 67   a writer.  So g
105c0 65 74 20 61 20 57 52 49 54 45 20 6c 6f 63 6b 20  et a WRITE lock 
105d0 61 6e 64 20 74 72 79 20 61 67 61 69 6e 2e 0a 20  and try again.. 
105e0 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 62 61   */.  assert( ba
105f0 64 48 64 72 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d  dHdr==0 || pWal-
10600 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b  >writeLock==0 );
10610 0a 20 20 69 66 28 20 62 61 64 48 64 72 20 26 26  .  if( badHdr &&
10620 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20   SQLITE_OK==(rc 
10630 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69  = walLockExclusi
10640 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49  ve(pWal, WAL_WRI
10650 54 45 5f 4c 4f 43 4b 2c 20 31 29 29 20 29 7b 0a  TE_LOCK, 1)) ){.
10660 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c      pWal->writeL
10670 6f 63 6b 20 3d 20 31 3b 0a 20 20 20 20 69 66 28  ock = 1;.    if(
10680 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20   SQLITE_OK==(rc 
10690 3d 20 77 61 6c 49 6e 64 65 78 50 61 67 65 28 70  = walIndexPage(p
106a0 57 61 6c 2c 20 30 2c 20 26 70 61 67 65 30 29 29  Wal, 0, &page0))
106b0 20 29 7b 0a 20 20 20 20 20 20 62 61 64 48 64 72   ){.      badHdr
106c0 20 3d 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64   = walIndexTryHd
106d0 72 28 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64  r(pWal, pChanged
106e0 29 3b 0a 20 20 20 20 20 20 69 66 28 20 62 61 64  );.      if( bad
106f0 48 64 72 20 29 7b 0a 20 20 20 20 20 20 20 20 2f  Hdr ){.        /
10700 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  * If the wal-ind
10710 65 78 20 68 65 61 64 65 72 20 69 73 20 73 74 69  ex header is sti
10720 6c 6c 20 6d 61 6c 66 6f 72 6d 65 64 20 65 76 65  ll malformed eve
10730 6e 20 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67 0a  n while holding.
10740 20 20 20 20 20 20 20 20 2a 2a 20 61 20 57 52 49          ** a WRI
10750 54 45 20 6c 6f 63 6b 2c 20 69 74 20 63 61 6e 20  TE lock, it can 
10760 6f 6e 6c 79 20 6d 65 61 6e 20 74 68 61 74 20 74  only mean that t
10770 68 65 20 68 65 61 64 65 72 20 69 73 20 63 6f 72  he header is cor
10780 72 75 70 74 65 64 20 61 6e 64 0a 20 20 20 20 20  rupted and.     
10790 20 20 20 2a 2a 20 6e 65 65 64 73 20 74 6f 20 62     ** needs to b
107a0 65 20 72 65 63 6f 6e 73 74 72 75 63 74 65 64 2e  e reconstructed.
107b0 20 20 53 6f 20 72 75 6e 20 72 65 63 6f 76 65 72    So run recover
107c0 79 20 74 6f 20 64 6f 20 65 78 61 63 74 6c 79 20  y to do exactly 
107d0 74 68 61 74 2e 0a 20 20 20 20 20 20 20 20 2a 2f  that..        */
107e0 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 77 61  .        rc = wa
107f0 6c 49 6e 64 65 78 52 65 63 6f 76 65 72 28 70 57  lIndexRecover(pW
10800 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 2a 70 43  al);.        *pC
10810 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20 20 20 20  hanged = 1;.    
10820 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 70 57    }.    }.    pW
10830 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20  al->writeLock = 
10840 30 3b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b  0;.    walUnlock
10850 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
10860 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20  WAL_WRITE_LOCK, 
10870 31 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66  1);.  }..  /* If
10880 20 74 68 65 20 68 65 61 64 65 72 20 69 73 20 72   the header is r
10890 65 61 64 20 73 75 63 63 65 73 73 66 75 6c 6c 79  ead successfully
108a0 2c 20 63 68 65 63 6b 20 74 68 65 20 76 65 72 73  , check the vers
108b0 69 6f 6e 20 6e 75 6d 62 65 72 20 74 6f 20 6d 61  ion number to ma
108c0 6b 65 0a 20 20 2a 2a 20 73 75 72 65 20 74 68 65  ke.  ** sure the
108d0 20 77 61 6c 2d 69 6e 64 65 78 20 77 61 73 20 6e   wal-index was n
108e0 6f 74 20 63 6f 6e 73 74 72 75 63 74 65 64 20 77  ot constructed w
108f0 69 74 68 20 73 6f 6d 65 20 66 75 74 75 72 65 20  ith some future 
10900 66 6f 72 6d 61 74 20 74 68 61 74 0a 20 20 2a 2a  format that.  **
10910 20 74 68 69 73 20 76 65 72 73 69 6f 6e 20 6f 66   this version of
10920 20 53 51 4c 69 74 65 20 63 61 6e 6e 6f 74 20 75   SQLite cannot u
10930 6e 64 65 72 73 74 61 6e 64 2e 0a 20 20 2a 2f 0a  nderstand..  */.
10940 20 20 69 66 28 20 62 61 64 48 64 72 3d 3d 30 20    if( badHdr==0 
10950 26 26 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56 65  && pWal->hdr.iVe
10960 72 73 69 6f 6e 21 3d 57 41 4c 49 4e 44 45 58 5f  rsion!=WALINDEX_
10970 4d 41 58 5f 56 45 52 53 49 4f 4e 20 29 7b 0a 20  MAX_VERSION ){. 
10980 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43     rc = SQLITE_C
10990 41 4e 54 4f 50 45 4e 5f 42 4b 50 54 3b 0a 20 20  ANTOPEN_BKPT;.  
109a0 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
109b0 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73  }../*.** This is
109c0 20 74 68 65 20 76 61 6c 75 65 20 74 68 61 74 20   the value that 
109d0 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64 20  walTryBeginRead 
109e0 72 65 74 75 72 6e 73 20 77 68 65 6e 20 69 74 20  returns when it 
109f0 6e 65 65 64 73 20 74 6f 0a 2a 2a 20 62 65 20 72  needs to.** be r
10a00 65 74 72 69 65 64 2e 0a 2a 2f 0a 23 64 65 66 69  etried..*/.#defi
10a10 6e 65 20 57 41 4c 5f 52 45 54 52 59 20 20 28 2d  ne WAL_RETRY  (-
10a20 31 29 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70  1)../*.** Attemp
10a30 74 20 74 6f 20 73 74 61 72 74 20 61 20 72 65 61  t to start a rea
10a40 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 20  d transaction.  
10a50 54 68 69 73 20 6d 69 67 68 74 20 66 61 69 6c 20  This might fail 
10a60 64 75 65 20 74 6f 20 61 20 72 61 63 65 20 6f 72  due to a race or
10a70 0a 2a 2a 20 6f 74 68 65 72 20 74 72 61 6e 73 69  .** other transi
10a80 65 6e 74 20 63 6f 6e 64 69 74 69 6f 6e 2e 20 20  ent condition.  
10a90 57 68 65 6e 20 74 68 61 74 20 68 61 70 70 65 6e  When that happen
10aa0 73 2c 20 69 74 20 72 65 74 75 72 6e 73 20 57 41  s, it returns WA
10ab0 4c 5f 52 45 54 52 59 20 74 6f 0a 2a 2a 20 69 6e  L_RETRY to.** in
10ac0 64 69 63 61 74 65 20 74 6f 20 74 68 65 20 63 61  dicate to the ca
10ad0 6c 6c 65 72 20 74 68 61 74 20 69 74 20 69 73 20  ller that it is 
10ae0 73 61 66 65 20 74 6f 20 72 65 74 72 79 20 69 6d  safe to retry im
10af0 6d 65 64 69 61 74 65 6c 79 2e 0a 2a 2a 0a 2a 2a  mediately..**.**
10b00 20 4f 6e 20 73 75 63 63 65 73 73 20 72 65 74 75   On success retu
10b10 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 20 4f  rn SQLITE_OK.  O
10b20 6e 20 61 20 70 65 72 6d 61 6e 65 6e 74 20 66 61  n a permanent fa
10b30 69 6c 75 72 65 20 28 73 75 63 68 20 61 6e 0a 2a  ilure (such an.*
10b40 2a 20 49 2f 4f 20 65 72 72 6f 72 20 6f 72 20 61  * I/O error or a
10b50 6e 20 53 51 4c 49 54 45 5f 42 55 53 59 20 62 65  n SQLITE_BUSY be
10b60 63 61 75 73 65 20 61 6e 6f 74 68 65 72 20 70 72  cause another pr
10b70 6f 63 65 73 73 20 69 73 20 72 75 6e 6e 69 6e 67  ocess is running
10b80 0a 2a 2a 20 72 65 63 6f 76 65 72 79 29 20 72 65  .** recovery) re
10b90 74 75 72 6e 20 61 20 70 6f 73 69 74 69 76 65 20  turn a positive 
10ba0 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a  error code..**.*
10bb0 2a 20 54 68 65 20 75 73 65 57 61 6c 20 70 61 72  * The useWal par
10bc0 61 6d 65 74 65 72 20 69 73 20 74 72 75 65 20 74  ameter is true t
10bd0 6f 20 66 6f 72 63 65 20 74 68 65 20 75 73 65 20  o force the use 
10be0 6f 66 20 74 68 65 20 57 41 4c 20 61 6e 64 20 64  of the WAL and d
10bf0 69 73 61 62 6c 65 0a 2a 2a 20 74 68 65 20 63 61  isable.** the ca
10c00 73 65 20 77 68 65 72 65 20 74 68 65 20 57 41 4c  se where the WAL
10c10 20 69 73 20 62 79 70 61 73 73 65 64 20 62 65 63   is bypassed bec
10c20 61 75 73 65 20 69 74 20 68 61 73 20 62 65 65 6e  ause it has been
10c30 20 63 6f 6d 70 6c 65 74 65 6c 79 0a 2a 2a 20 63   completely.** c
10c40 68 65 63 6b 70 6f 69 6e 74 65 64 2e 20 20 49 66  heckpointed.  If
10c50 20 75 73 65 57 61 6c 3d 3d 30 20 74 68 65 6e 20   useWal==0 then 
10c60 74 68 69 73 20 72 6f 75 74 69 6e 65 20 63 61 6c  this routine cal
10c70 6c 73 20 77 61 6c 49 6e 64 65 78 52 65 61 64 48  ls walIndexReadH
10c80 64 72 28 29 20 0a 2a 2a 20 74 6f 20 6d 61 6b 65  dr() .** to make
10c90 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 77   a copy of the w
10ca0 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
10cb0 69 6e 74 6f 20 70 57 61 6c 2d 3e 68 64 72 2e 20  into pWal->hdr. 
10cc0 20 49 66 20 74 68 65 20 0a 2a 2a 20 77 61 6c 2d   If the .** wal-
10cd0 69 6e 64 65 78 20 68 65 61 64 65 72 20 68 61 73  index header has
10ce0 20 63 68 61 6e 67 65 64 2c 20 2a 70 43 68 61 6e   changed, *pChan
10cf0 67 65 64 20 69 73 20 73 65 74 20 74 6f 20 31 20  ged is set to 1 
10d00 28 61 73 20 61 6e 20 69 6e 64 69 63 61 74 69 6f  (as an indicatio
10d10 6e 20 0a 2a 2a 20 74 6f 20 74 68 65 20 63 61 6c  n .** to the cal
10d20 6c 65 72 20 74 68 61 74 20 74 68 65 20 6c 6f 63  ler that the loc
10d30 61 6c 20 70 61 67 65 74 20 63 61 63 68 65 20 69  al paget cache i
10d40 73 20 6f 62 73 6f 6c 65 74 65 20 61 6e 64 20 6e  s obsolete and n
10d50 65 65 64 73 20 74 6f 20 62 65 20 0a 2a 2a 20 66  eeds to be .** f
10d60 6c 75 73 68 65 64 2e 29 20 20 57 68 65 6e 20 75  lushed.)  When u
10d70 73 65 57 61 6c 3d 3d 31 2c 20 74 68 65 20 77 61  seWal==1, the wa
10d80 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69  l-index header i
10d90 73 20 61 73 73 75 6d 65 64 20 74 6f 20 61 6c 72  s assumed to alr
10da0 65 61 64 79 0a 2a 2a 20 62 65 20 6c 6f 61 64 65  eady.** be loade
10db0 64 20 61 6e 64 20 74 68 65 20 70 43 68 61 6e 67  d and the pChang
10dc0 65 64 20 70 61 72 61 6d 65 74 65 72 20 69 73 20  ed parameter is 
10dd0 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68  unused..**.** Th
10de0 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 73 65  e caller must se
10df0 74 20 74 68 65 20 63 6e 74 20 70 61 72 61 6d 65  t the cnt parame
10e00 74 65 72 20 74 6f 20 74 68 65 20 6e 75 6d 62 65  ter to the numbe
10e10 72 20 6f 66 20 70 72 69 6f 72 20 63 61 6c 6c 73  r of prior calls
10e20 20 74 6f 0a 2a 2a 20 74 68 69 73 20 72 6f 75 74   to.** this rout
10e30 69 6e 65 20 64 75 72 69 6e 67 20 74 68 65 20 63  ine during the c
10e40 75 72 72 65 6e 74 20 72 65 61 64 20 61 74 74 65  urrent read atte
10e50 6d 70 74 20 74 68 61 74 20 72 65 74 75 72 6e 65  mpt that returne
10e60 64 20 57 41 4c 5f 52 45 54 52 59 2e 0a 2a 2a 20  d WAL_RETRY..** 
10e70 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c  This routine wil
10e80 6c 20 73 74 61 72 74 20 74 61 6b 69 6e 67 20 6d  l start taking m
10e90 6f 72 65 20 61 67 67 72 65 73 73 69 76 65 20 6d  ore aggressive m
10ea0 65 61 73 75 72 65 73 20 74 6f 20 63 6c 65 61 72  easures to clear
10eb0 20 74 68 65 0a 2a 2a 20 72 61 63 65 20 63 6f 6e   the.** race con
10ec0 64 69 74 69 6f 6e 73 20 61 66 74 65 72 20 6d 75  ditions after mu
10ed0 6c 74 69 70 6c 65 20 57 41 4c 5f 52 45 54 52 59  ltiple WAL_RETRY
10ee0 20 72 65 74 75 72 6e 73 2c 20 61 6e 64 20 61 66   returns, and af
10ef0 74 65 72 20 61 6e 20 65 78 63 65 73 73 69 76 65  ter an excessive
10f00 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 65 72  .** number of er
10f10 72 6f 72 73 20 77 69 6c 6c 20 75 6c 74 69 6d 61  rors will ultima
10f20 74 65 6c 79 20 72 65 74 75 72 6e 20 53 51 4c 49  tely return SQLI
10f30 54 45 5f 50 52 4f 54 4f 43 4f 4c 2e 20 20 54 68  TE_PROTOCOL.  Th
10f40 65 0a 2a 2a 20 53 51 4c 49 54 45 5f 50 52 4f 54  e.** SQLITE_PROT
10f50 4f 43 4f 4c 20 72 65 74 75 72 6e 20 69 6e 64 69  OCOL return indi
10f60 63 61 74 65 73 20 74 68 61 74 20 73 6f 6d 65 20  cates that some 
10f70 6f 74 68 65 72 20 70 72 6f 63 65 73 73 20 68 61  other process ha
10f80 73 20 67 6f 6e 65 20 72 6f 67 75 65 0a 2a 2a 20  s gone rogue.** 
10f90 61 6e 64 20 69 73 20 6e 6f 74 20 68 6f 6e 6f 72  and is not honor
10fa0 69 6e 67 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20  ing the locking 
10fb0 70 72 6f 74 6f 63 6f 6c 2e 20 20 54 68 65 72 65  protocol.  There
10fc0 20 69 73 20 61 20 76 61 6e 69 73 68 69 6e 67 6c   is a vanishingl
10fd0 79 20 73 6d 61 6c 6c 0a 2a 2a 20 63 68 61 6e 63  y small.** chanc
10fe0 65 20 74 68 61 74 20 53 51 4c 49 54 45 5f 50 52  e that SQLITE_PR
10ff0 4f 54 4f 43 4f 4c 20 63 6f 75 6c 64 20 62 65 20  OTOCOL could be 
11000 72 65 74 75 72 6e 65 64 20 62 65 63 61 75 73 65  returned because
11010 20 6f 66 20 61 20 72 75 6e 20 6f 66 20 72 65 61   of a run of rea
11020 6c 6c 79 0a 2a 2a 20 62 61 64 20 6c 75 63 6b 20  lly.** bad luck 
11030 77 68 65 6e 20 74 68 65 72 65 20 69 73 20 6c 6f  when there is lo
11040 74 73 20 6f 66 20 63 6f 6e 74 65 6e 74 69 6f 6e  ts of contention
11050 20 66 6f 72 20 74 68 65 20 77 61 6c 2d 69 6e 64   for the wal-ind
11060 65 78 2c 20 62 75 74 20 74 68 61 74 0a 2a 2a 20  ex, but that.** 
11070 70 6f 73 73 69 62 69 6c 69 74 79 20 69 73 20 73  possibility is s
11080 6f 20 73 6d 61 6c 6c 20 74 68 61 74 20 69 74 20  o small that it 
11090 63 61 6e 20 62 65 20 73 61 66 65 6c 79 20 6e 65  can be safely ne
110a0 67 6c 65 63 74 65 64 2c 20 77 65 20 62 65 6c 69  glected, we beli
110b0 65 76 65 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75  eve..**.** On su
110c0 63 63 65 73 73 2c 20 74 68 69 73 20 72 6f 75 74  ccess, this rout
110d0 69 6e 65 20 6f 62 74 61 69 6e 73 20 61 20 72 65  ine obtains a re
110e0 61 64 20 6c 6f 63 6b 20 6f 6e 20 0a 2a 2a 20 57  ad lock on .** W
110f0 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61  AL_READ_LOCK(pWa
11100 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 2e 20 20 54  l->readLock).  T
11110 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  he pWal->readLoc
11120 6b 20 69 6e 74 65 67 65 72 20 69 73 0a 2a 2a 20  k integer is.** 
11130 69 6e 20 74 68 65 20 72 61 6e 67 65 20 30 20 3c  in the range 0 <
11140 3d 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  = pWal->readLock
11150 20 3c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2e 20   < WAL_NREADER. 
11160 20 49 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f   If pWal->readLo
11170 63 6b 3d 3d 28 2d 31 29 0a 2a 2a 20 74 68 61 74  ck==(-1).** that
11180 20 6d 65 61 6e 73 20 74 68 65 20 57 61 6c 20 64   means the Wal d
11190 6f 65 73 20 6e 6f 74 20 68 6f 6c 64 20 61 6e 79  oes not hold any
111a0 20 72 65 61 64 20 6c 6f 63 6b 2e 20 20 54 68 65   read lock.  The
111b0 20 72 65 61 64 65 72 20 6d 75 73 74 20 6e 6f 74   reader must not
111c0 0a 2a 2a 20 61 63 63 65 73 73 20 61 6e 79 20 64  .** access any d
111d0 61 74 61 62 61 73 65 20 70 61 67 65 20 74 68 61  atabase page tha
111e0 74 20 69 73 20 6d 6f 64 69 66 69 65 64 20 62 79  t is modified by
111f0 20 61 20 57 41 4c 20 66 72 61 6d 65 20 75 70 20   a WAL frame up 
11200 74 6f 20 61 6e 64 0a 2a 2a 20 69 6e 63 6c 75 64  to and.** includ
11210 69 6e 67 20 66 72 61 6d 65 20 6e 75 6d 62 65 72  ing frame number
11220 20 61 52 65 61 64 4d 61 72 6b 5b 70 57 61 6c 2d   aReadMark[pWal-
11230 3e 72 65 61 64 4c 6f 63 6b 5d 2e 20 20 54 68 65  >readLock].  The
11240 20 72 65 61 64 65 72 20 77 69 6c 6c 0a 2a 2a 20   reader will.** 
11250 75 73 65 20 57 41 4c 20 66 72 61 6d 65 73 20 75  use WAL frames u
11260 70 20 74 6f 20 61 6e 64 20 69 6e 63 6c 75 64 69  p to and includi
11270 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ng pWal->hdr.mxF
11280 72 61 6d 65 20 69 66 20 70 57 61 6c 2d 3e 72 65  rame if pWal->re
11290 61 64 4c 6f 63 6b 3e 30 0a 2a 2a 20 4f 72 20 69  adLock>0.** Or i
112a0 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  f pWal->readLock
112b0 3d 3d 30 2c 20 74 68 65 6e 20 74 68 65 20 72 65  ==0, then the re
112c0 61 64 65 72 20 77 69 6c 6c 20 69 67 6e 6f 72 65  ader will ignore
112d0 20 74 68 65 20 57 41 4c 0a 2a 2a 20 63 6f 6d 70   the WAL.** comp
112e0 6c 65 74 65 6c 79 20 61 6e 64 20 67 65 74 20 61  letely and get a
112f0 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72 65 63  ll content direc
11300 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61 74  tly from the dat
11310 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 20 49  abase file..** I
11320 66 20 74 68 65 20 75 73 65 57 61 6c 20 70 61 72  f the useWal par
11330 61 6d 65 74 65 72 20 69 73 20 31 20 74 68 65 6e  ameter is 1 then
11340 20 74 68 65 20 57 41 4c 20 77 69 6c 6c 20 6e 65   the WAL will ne
11350 76 65 72 20 62 65 20 69 67 6e 6f 72 65 64 20 61  ver be ignored a
11360 6e 64 0a 2a 2a 20 74 68 69 73 20 72 6f 75 74 69  nd.** this routi
11370 6e 65 20 77 69 6c 6c 20 61 6c 77 61 79 73 20 73  ne will always s
11380 65 74 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  et pWal->readLoc
11390 6b 3e 30 20 6f 6e 20 73 75 63 63 65 73 73 2e 0a  k>0 on success..
113a0 2a 2a 20 57 68 65 6e 20 74 68 65 20 72 65 61 64  ** When the read
113b0 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20   transaction is 
113c0 63 6f 6d 70 6c 65 74 65 64 2c 20 74 68 65 20 63  completed, the c
113d0 61 6c 6c 65 72 20 6d 75 73 74 20 72 65 6c 65 61  aller must relea
113e0 73 65 20 74 68 65 0a 2a 2a 20 6c 6f 63 6b 20 6f  se the.** lock o
113f0 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  n WAL_READ_LOCK(
11400 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 20  pWal->readLock) 
11410 61 6e 64 20 73 65 74 20 70 57 61 6c 2d 3e 72 65  and set pWal->re
11420 61 64 4c 6f 63 6b 20 74 6f 20 2d 31 2e 0a 2a 2a  adLock to -1..**
11430 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
11440 20 75 73 65 73 20 74 68 65 20 6e 42 61 63 6b 66   uses the nBackf
11450 69 6c 6c 20 61 6e 64 20 61 52 65 61 64 4d 61 72  ill and aReadMar
11460 6b 5b 5d 20 66 69 65 6c 64 73 20 6f 66 20 74 68  k[] fields of th
11470 65 20 68 65 61 64 65 72 0a 2a 2a 20 74 6f 20 73  e header.** to s
11480 65 6c 65 63 74 20 61 20 70 61 72 74 69 63 75 6c  elect a particul
11490 61 72 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  ar WAL_READ_LOCK
114a0 28 29 20 74 68 61 74 20 73 74 72 69 76 65 73 20  () that strives 
114b0 74 6f 20 6c 65 74 20 74 68 65 0a 2a 2a 20 63 68  to let the.** ch
114c0 65 63 6b 70 6f 69 6e 74 20 70 72 6f 63 65 73 73  eckpoint process
114d0 20 64 6f 20 61 73 20 6d 75 63 68 20 77 6f 72 6b   do as much work
114e0 20 61 73 20 70 6f 73 73 69 62 6c 65 2e 20 20 54   as possible.  T
114f0 68 69 73 20 72 6f 75 74 69 6e 65 20 6d 69 67 68  his routine migh
11500 74 0a 2a 2a 20 75 70 64 61 74 65 20 76 61 6c 75  t.** update valu
11510 65 73 20 6f 66 20 74 68 65 20 61 52 65 61 64 4d  es of the aReadM
11520 61 72 6b 5b 5d 20 61 72 72 61 79 20 69 6e 20 74  ark[] array in t
11530 68 65 20 68 65 61 64 65 72 2c 20 62 75 74 20 69  he header, but i
11540 66 20 69 74 20 64 6f 65 73 0a 2a 2a 20 73 6f 20  f it does.** so 
11550 69 74 20 74 61 6b 65 73 20 63 61 72 65 20 74 6f  it takes care to
11560 20 68 6f 6c 64 20 61 6e 20 65 78 63 6c 75 73 69   hold an exclusi
11570 76 65 20 6c 6f 63 6b 20 6f 6e 20 74 68 65 20 63  ve lock on the c
11580 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20  orresponding.** 
11590 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 29 20  WAL_READ_LOCK() 
115a0 77 68 69 6c 65 20 63 68 61 6e 67 69 6e 67 20 76  while changing v
115b0 61 6c 75 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  alues..*/.static
115c0 20 69 6e 74 20 77 61 6c 54 72 79 42 65 67 69 6e   int walTryBegin
115d0 52 65 61 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Read(Wal *pWal, 
115e0 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 2c 20 69  int *pChanged, i
115f0 6e 74 20 75 73 65 57 61 6c 2c 20 69 6e 74 20 63  nt useWal, int c
11600 6e 74 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20  nt){.  volatile 
11610 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e  WalCkptInfo *pIn
11620 66 6f 3b 20 20 20 20 2f 2a 20 43 68 65 63 6b 70  fo;    /* Checkp
11630 6f 69 6e 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  oint information
11640 20 69 6e 20 77 61 6c 2d 69 6e 64 65 78 20 2a 2f   in wal-index */
11650 0a 20 20 75 33 32 20 6d 78 52 65 61 64 4d 61 72  .  u32 mxReadMar
11660 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k;              
11670 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 61 52     /* Largest aR
11680 65 61 64 4d 61 72 6b 5b 5d 20 76 61 6c 75 65 20  eadMark[] value 
11690 2a 2f 0a 20 20 69 6e 74 20 6d 78 49 3b 20 20 20  */.  int mxI;   
116a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
116b0 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66       /* Index of
116c0 20 6c 61 72 67 65 73 74 20 61 52 65 61 64 4d 61   largest aReadMa
116d0 72 6b 5b 5d 20 76 61 6c 75 65 20 2a 2f 0a 20 20  rk[] value */.  
116e0 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
116f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11700 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20  /* Loop counter 
11710 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  */.  int rc = SQ
11720 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20  LITE_OK;        
11730 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
11740 6f 64 65 20 20 2a 2f 0a 0a 20 20 61 73 73 65 72  ode  */..  asser
11750 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  t( pWal->readLoc
11760 6b 3c 30 20 29 3b 20 20 20 20 20 2f 2a 20 4e 6f  k<0 );     /* No
11770 74 20 63 75 72 72 65 6e 74 6c 79 20 6c 6f 63 6b  t currently lock
11780 65 64 20 2a 2f 0a 0a 20 20 2f 2a 20 54 61 6b 65  ed */..  /* Take
11790 20 73 74 65 70 73 20 74 6f 20 61 76 6f 69 64 20   steps to avoid 
117a0 73 70 69 6e 6e 69 6e 67 20 66 6f 72 65 76 65 72  spinning forever
117b0 20 69 66 20 74 68 65 72 65 20 69 73 20 61 20 70   if there is a p
117c0 72 6f 74 6f 63 6f 6c 20 65 72 72 6f 72 2e 20 2a  rotocol error. *
117d0 2f 0a 20 20 69 66 28 20 63 6e 74 3e 35 20 29 7b  /.  if( cnt>5 ){
117e0 0a 20 20 20 20 69 66 28 20 63 6e 74 3e 31 30 30  .    if( cnt>100
117f0 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
11800 5f 50 52 4f 54 4f 43 4f 4c 3b 0a 20 20 20 20 73  _PROTOCOL;.    s
11810 71 6c 69 74 65 33 4f 73 53 6c 65 65 70 28 70 57  qlite3OsSleep(pW
11820 61 6c 2d 3e 70 56 66 73 2c 20 31 29 3b 0a 20 20  al->pVfs, 1);.  
11830 7d 0a 0a 20 20 69 66 28 20 21 75 73 65 57 61 6c  }..  if( !useWal
11840 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c   ){.    rc = wal
11850 49 6e 64 65 78 52 65 61 64 48 64 72 28 70 57 61  IndexReadHdr(pWa
11860 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b 0a 20 20  l, pChanged);.  
11870 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
11880 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20 2f  _BUSY ){.      /
11890 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f  * If there is no
118a0 74 20 61 20 72 65 63 6f 76 65 72 79 20 72 75 6e  t a recovery run
118b0 6e 69 6e 67 20 69 6e 20 61 6e 6f 74 68 65 72 20  ning in another 
118c0 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73  thread or proces
118d0 73 0a 20 20 20 20 20 20 2a 2a 20 74 68 65 6e 20  s.      ** then 
118e0 63 6f 6e 76 65 72 74 20 42 55 53 59 20 65 72 72  convert BUSY err
118f0 6f 72 73 20 74 6f 20 57 41 4c 5f 52 45 54 52 59  ors to WAL_RETRY
11900 2e 20 20 49 66 20 72 65 63 6f 76 65 72 79 20 69  .  If recovery i
11910 73 20 6b 6e 6f 77 6e 20 74 6f 0a 20 20 20 20 20  s known to.     
11920 20 2a 2a 20 62 65 20 72 75 6e 6e 69 6e 67 2c 20   ** be running, 
11930 63 6f 6e 76 65 72 74 20 42 55 53 59 20 74 6f 20  convert BUSY to 
11940 42 55 53 59 5f 52 45 43 4f 56 45 52 59 2e 20 20  BUSY_RECOVERY.  
11950 54 68 65 72 65 20 69 73 20 61 20 72 61 63 65 20  There is a race 
11960 68 65 72 65 0a 20 20 20 20 20 20 2a 2a 20 77 68  here.      ** wh
11970 69 63 68 20 6d 69 67 68 74 20 63 61 75 73 65 20  ich might cause 
11980 57 41 4c 5f 52 45 54 52 59 20 74 6f 20 62 65 20  WAL_RETRY to be 
11990 72 65 74 75 72 6e 65 64 20 65 76 65 6e 20 69 66  returned even if
119a0 20 42 55 53 59 5f 52 45 43 4f 56 45 52 59 0a 20   BUSY_RECOVERY. 
119b0 20 20 20 20 20 2a 2a 20 77 6f 75 6c 64 20 62 65       ** would be
119c0 20 74 65 63 68 6e 69 63 61 6c 6c 79 20 63 6f 72   technically cor
119d0 72 65 63 74 2e 20 20 42 75 74 20 74 68 65 20 72  rect.  But the r
119e0 61 63 65 20 69 73 20 62 65 6e 69 67 6e 20 73 69  ace is benign si
119f0 6e 63 65 20 77 69 74 68 0a 20 20 20 20 20 20 2a  nce with.      *
11a00 2a 20 57 41 4c 5f 52 45 54 52 59 20 74 68 69 73  * WAL_RETRY this
11a10 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20 62 65   routine will be
11a20 20 63 61 6c 6c 65 64 20 61 67 61 69 6e 20 61 6e   called again an
11a30 64 20 77 69 6c 6c 20 70 72 6f 62 61 62 6c 79 20  d will probably 
11a40 62 65 0a 20 20 20 20 20 20 2a 2a 20 72 69 67 68  be.      ** righ
11a50 74 20 6f 6e 20 74 68 65 20 73 65 63 6f 6e 64 20  t on the second 
11a60 69 74 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20 20  iteration..     
11a70 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 77   */.      rc = w
11a80 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61  alLockShared(pWa
11a90 6c 2c 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c  l, WAL_RECOVER_L
11aa0 4f 43 4b 29 3b 0a 20 20 20 20 20 20 69 66 28 20  OCK);.      if( 
11ab0 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
11ac0 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f  .        walUnlo
11ad0 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
11ae0 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 29  AL_RECOVER_LOCK)
11af0 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 57  ;.        rc = W
11b00 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20  AL_RETRY;.      
11b10 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51  }else if( rc==SQ
11b20 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
11b30 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
11b40 5f 42 55 53 59 5f 52 45 43 4f 56 45 52 59 3b 0a  _BUSY_RECOVERY;.
11b50 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
11b60 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
11b70 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74  _OK ){.      ret
11b80 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20  urn rc;.    }.  
11b90 7d 0a 0a 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c  }..  pInfo = wal
11ba0 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a  CkptInfo(pWal);.
11bb0 20 20 69 66 28 20 21 75 73 65 57 61 6c 20 26 26    if( !useWal &&
11bc0 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
11bd0 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  l==pWal->hdr.mxF
11be0 72 61 6d 65 20 29 7b 0a 20 20 20 20 2f 2a 20 54  rame ){.    /* T
11bf0 68 65 20 57 41 4c 20 68 61 73 20 62 65 65 6e 20  he WAL has been 
11c00 63 6f 6d 70 6c 65 74 65 6c 79 20 62 61 63 6b 66  completely backf
11c10 69 6c 6c 65 64 20 28 6f 72 20 69 74 20 69 73 20  illed (or it is 
11c20 65 6d 70 74 79 29 2e 0a 20 20 20 20 2a 2a 20 61  empty)..    ** a
11c30 6e 64 20 63 61 6e 20 62 65 20 73 61 66 65 6c 79  nd can be safely
11c40 20 69 67 6e 6f 72 65 64 2e 0a 20 20 20 20 2a 2f   ignored..    */
11c50 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63  .    rc = walLoc
11c60 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
11c70 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b  L_READ_LOCK(0));
11c80 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53 68  .    sqlite3OsSh
11c90 6d 42 61 72 72 69 65 72 28 70 57 61 6c 2d 3e 70  mBarrier(pWal->p
11ca0 44 62 46 64 29 3b 0a 20 20 20 20 69 66 28 20 72  DbFd);.    if( r
11cb0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
11cc0 20 20 20 20 20 20 69 66 28 20 6d 65 6d 63 6d 70        if( memcmp
11cd0 28 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65  ((void *)walInde
11ce0 78 48 64 72 28 70 57 61 6c 29 2c 20 26 70 57 61  xHdr(pWal), &pWa
11cf0 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57  l->hdr, sizeof(W
11d00 61 6c 49 6e 64 65 78 48 64 72 29 29 20 29 7b 0a  alIndexHdr)) ){.
11d10 20 20 20 20 20 20 20 20 2f 2a 20 49 74 20 69 73          /* It is
11d20 20 6e 6f 74 20 73 61 66 65 20 74 6f 20 61 6c 6c   not safe to all
11d30 6f 77 20 74 68 65 20 72 65 61 64 65 72 20 74 6f  ow the reader to
11d40 20 63 6f 6e 74 69 6e 75 65 20 68 65 72 65 20 69   continue here i
11d50 66 20 66 72 61 6d 65 73 0a 20 20 20 20 20 20 20  f frames.       
11d60 20 2a 2a 20 6d 61 79 20 68 61 76 65 20 62 65 65   ** may have bee
11d70 6e 20 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68  n appended to th
11d80 65 20 6c 6f 67 20 62 65 66 6f 72 65 20 52 45 41  e log before REA
11d90 44 5f 4c 4f 43 4b 28 30 29 20 77 61 73 20 6f 62  D_LOCK(0) was ob
11da0 74 61 69 6e 65 64 2e 0a 20 20 20 20 20 20 20 20  tained..        
11db0 2a 2a 20 57 68 65 6e 20 68 6f 6c 64 69 6e 67 20  ** When holding 
11dc0 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 74 68  READ_LOCK(0), th
11dd0 65 20 72 65 61 64 65 72 20 69 67 6e 6f 72 65 73  e reader ignores
11de0 20 74 68 65 20 65 6e 74 69 72 65 20 6c 6f 67 20   the entire log 
11df0 66 69 6c 65 2c 0a 20 20 20 20 20 20 20 20 2a 2a  file,.        **
11e00 20 77 68 69 63 68 20 69 6d 70 6c 69 65 73 20 74   which implies t
11e10 68 61 74 20 74 68 65 20 64 61 74 61 62 61 73 65  hat the database
11e20 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 61   file contains a
11e30 20 74 72 75 73 74 77 6f 72 74 68 79 0a 20 20 20   trustworthy.   
11e40 20 20 20 20 20 2a 2a 20 73 6e 61 70 73 68 6f 54       ** snapshoT
11e50 2e 20 53 69 6e 63 65 20 68 6f 6c 64 69 6e 67 20  . Since holding 
11e60 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20 70 72 65  READ_LOCK(0) pre
11e70 76 65 6e 74 73 20 61 20 63 68 65 63 6b 70 6f 69  vents a checkpoi
11e80 6e 74 20 66 72 6f 6d 0a 20 20 20 20 20 20 20 20  nt from.        
11e90 2a 2a 20 68 61 70 70 65 6e 69 6e 67 2c 20 74 68  ** happening, th
11ea0 69 73 20 69 73 20 75 73 75 61 6c 6c 79 20 63 6f  is is usually co
11eb0 72 72 65 63 74 2e 0a 20 20 20 20 20 20 20 20 2a  rrect..        *
11ec0 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 48 6f 77  *.        ** How
11ed0 65 76 65 72 2c 20 69 66 20 66 72 61 6d 65 73 20  ever, if frames 
11ee0 68 61 76 65 20 62 65 65 6e 20 61 70 70 65 6e 64  have been append
11ef0 65 64 20 74 6f 20 74 68 65 20 6c 6f 67 20 28 6f  ed to the log (o
11f00 72 20 69 66 20 74 68 65 20 6c 6f 67 20 0a 20 20  r if the log .  
11f10 20 20 20 20 20 20 2a 2a 20 69 73 20 77 72 61 70        ** is wrap
11f20 70 65 64 20 61 6e 64 20 77 72 69 74 74 65 6e 20  ped and written 
11f30 66 6f 72 20 74 68 61 74 20 6d 61 74 74 65 72 29  for that matter)
11f40 20 62 65 66 6f 72 65 20 74 68 65 20 52 45 41 44   before the READ
11f50 5f 4c 4f 43 4b 28 30 29 0a 20 20 20 20 20 20 20  _LOCK(0).       
11f60 20 2a 2a 20 69 73 20 6f 62 74 61 69 6e 65 64 2c   ** is obtained,
11f70 20 74 68 61 74 20 69 73 20 6e 6f 74 20 6e 65 63   that is not nec
11f80 65 73 73 61 72 69 6c 79 20 74 72 75 65 2e 20 41  essarily true. A
11f90 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 20 6d 61   checkpointer ma
11fa0 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 68 61 76  y.        ** hav
11fb0 65 20 73 74 61 72 74 65 64 20 74 6f 20 62 61 63  e started to bac
11fc0 6b 66 69 6c 6c 20 74 68 65 20 61 70 70 65 6e 64  kfill the append
11fd0 65 64 20 66 72 61 6d 65 73 20 62 75 74 20 63 72  ed frames but cr
11fe0 61 73 68 65 64 20 62 65 66 6f 72 65 0a 20 20 20  ashed before.   
11ff0 20 20 20 20 20 2a 2a 20 69 74 20 66 69 6e 69 73       ** it finis
12000 68 65 64 2e 20 4c 65 61 76 69 6e 67 20 61 20 63  hed. Leaving a c
12010 6f 72 72 75 70 74 20 69 6d 61 67 65 20 69 6e 20  orrupt image in 
12020 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
12030 65 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20  e..        */.  
12040 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53        walUnlockS
12050 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
12060 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20  READ_LOCK(0));. 
12070 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 57 41         return WA
12080 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d  L_RETRY;.      }
12090 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 72 65 61  .      pWal->rea
120a0 64 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 20  dLock = 0;.     
120b0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
120c0 4b 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  K;.    }else if(
120d0 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc!=SQLITE_BUSY
120e0 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
120f0 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a   rc;.    }.  }..
12100 20 20 2f 2a 20 49 66 20 77 65 20 67 65 74 20 74    /* If we get t
12110 68 69 73 20 66 61 72 2c 20 69 74 20 6d 65 61 6e  his far, it mean
12120 73 20 74 68 61 74 20 74 68 65 20 72 65 61 64 65  s that the reade
12130 72 20 77 69 6c 6c 20 77 61 6e 74 20 74 6f 20 75  r will want to u
12140 73 65 0a 20 20 2a 2a 20 74 68 65 20 57 41 4c 20  se.  ** the WAL 
12150 74 6f 20 67 65 74 20 61 74 20 63 6f 6e 74 65 6e  to get at conten
12160 74 20 66 72 6f 6d 20 72 65 63 65 6e 74 20 63 6f  t from recent co
12170 6d 6d 69 74 73 2e 20 20 54 68 65 20 6a 6f 62 20  mmits.  The job 
12180 6e 6f 77 20 69 73 0a 20 20 2a 2a 20 74 6f 20 73  now is.  ** to s
12190 65 6c 65 63 74 20 6f 6e 65 20 6f 66 20 74 68 65  elect one of the
121a0 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e 74   aReadMark[] ent
121b0 72 69 65 73 20 74 68 61 74 20 69 73 20 63 6c 6f  ries that is clo
121c0 73 65 73 74 20 74 6f 0a 20 20 2a 2a 20 62 75 74  sest to.  ** but
121d0 20 6e 6f 74 20 65 78 63 65 65 64 69 6e 67 20 70   not exceeding p
121e0 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
121f0 20 61 6e 64 20 6c 6f 63 6b 20 74 68 61 74 20 65   and lock that e
12200 6e 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 6d 78 52  ntry..  */.  mxR
12210 65 61 64 4d 61 72 6b 20 3d 20 30 3b 0a 20 20 6d  eadMark = 0;.  m
12220 78 49 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d  xI = 0;.  for(i=
12230 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52  1; i<WAL_NREADER
12240 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 75 33 32 20  ; i++){.    u32 
12250 74 68 69 73 4d 61 72 6b 20 3d 20 70 49 6e 66 6f  thisMark = pInfo
12260 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a  ->aReadMark[i];.
12270 20 20 20 20 69 66 28 20 6d 78 52 65 61 64 4d 61      if( mxReadMa
12280 72 6b 3c 3d 74 68 69 73 4d 61 72 6b 20 26 26 20  rk<=thisMark && 
12290 74 68 69 73 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e  thisMark<=pWal->
122a0 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20  hdr.mxFrame ){. 
122b0 20 20 20 20 20 61 73 73 65 72 74 28 20 74 68 69       assert( thi
122c0 73 4d 61 72 6b 21 3d 52 45 41 44 4d 41 52 4b 5f  sMark!=READMARK_
122d0 4e 4f 54 5f 55 53 45 44 20 29 3b 0a 20 20 20 20  NOT_USED );.    
122e0 20 20 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20 74    mxReadMark = t
122f0 68 69 73 4d 61 72 6b 3b 0a 20 20 20 20 20 20 6d  hisMark;.      m
12300 78 49 20 3d 20 69 3b 0a 20 20 20 20 7d 0a 20 20  xI = i;.    }.  
12310 7d 0a 20 20 69 66 28 20 6d 78 49 3d 3d 30 20 29  }.  if( mxI==0 )
12320 7b 0a 20 20 20 20 2f 2a 20 49 66 20 77 65 20 67  {.    /* If we g
12330 65 74 20 68 65 72 65 2c 20 69 74 20 6d 65 61 6e  et here, it mean
12340 73 20 74 68 61 74 20 61 6c 6c 20 6f 66 20 74 68  s that all of th
12350 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e  e aReadMark[] en
12360 74 72 69 65 73 20 62 65 74 77 65 65 6e 0a 20 20  tries between.  
12370 20 20 2a 2a 20 31 20 61 6e 64 20 57 41 4c 5f 4e    ** 1 and WAL_N
12380 52 45 41 44 45 52 2d 31 20 61 72 65 20 7a 65 72  READER-1 are zer
12390 6f 2e 20 20 54 72 79 20 74 6f 20 69 6e 69 74 69  o.  Try to initi
123a0 61 6c 69 7a 65 20 61 52 65 61 64 4d 61 72 6b 5b  alize aReadMark[
123b0 31 5d 20 74 6f 0a 20 20 20 20 2a 2a 20 62 65 20  1] to.    ** be 
123c0 6d 78 46 72 61 6d 65 2c 20 74 68 65 6e 20 72 65  mxFrame, then re
123d0 74 72 79 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  try..    */.    
123e0 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
123f0 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
12400 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 31 29  READ_LOCK(1), 1)
12410 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
12420 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
12430 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
12440 6b 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72  k[1] = pWal->hdr
12450 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 20 20  .mxFrame;.      
12460 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69  walUnlockExclusi
12470 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ve(pWal, WAL_REA
12480 44 5f 4c 4f 43 4b 28 31 29 2c 20 31 29 3b 0a 20  D_LOCK(1), 1);. 
12490 20 20 20 20 20 72 63 20 3d 20 57 41 4c 5f 52 45       rc = WAL_RE
124a0 54 52 59 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  TRY;.    }else i
124b0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  f( rc==SQLITE_BU
124c0 53 59 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  SY ){.      rc =
124d0 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20   WAL_RETRY;.    
124e0 7d 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  }.    return rc;
124f0 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66  .  }else{.    if
12500 28 20 6d 78 52 65 61 64 4d 61 72 6b 20 3c 20 70  ( mxReadMark < p
12510 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
12520 20 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d   ){.      for(i=
12530 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52  1; i<WAL_NREADER
12540 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
12550 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
12560 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
12570 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29  READ_LOCK(i), 1)
12580 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
12590 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
125a0 20 20 20 20 20 20 20 20 20 6d 78 52 65 61 64 4d           mxReadM
125b0 61 72 6b 20 3d 20 70 49 6e 66 6f 2d 3e 61 52 65  ark = pInfo->aRe
125c0 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 70 57 61 6c  adMark[i] = pWal
125d0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20  ->hdr.mxFrame;. 
125e0 20 20 20 20 20 20 20 20 20 6d 78 49 20 3d 20 69           mxI = i
125f0 3b 0a 20 20 20 20 20 20 20 20 20 20 77 61 6c 55  ;.          walU
12600 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  nlockExclusive(p
12610 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
12620 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20 20 20  CK(i), 1);.     
12630 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
12640 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63      }else if( rc
12650 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b  !=SQLITE_BUSY ){
12660 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72  .          retur
12670 6e 20 72 63 3b 0a 20 20 20 20 20 20 20 20 7d 0a  n rc;.        }.
12680 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
12690 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53     rc = walLockS
126a0 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
126b0 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b  READ_LOCK(mxI));
126c0 0a 20 20 20 20 69 66 28 20 72 63 20 29 7b 0a 20  .    if( rc ){. 
126d0 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d       return rc==
126e0 53 51 4c 49 54 45 5f 42 55 53 59 20 3f 20 57 41  SQLITE_BUSY ? WA
126f0 4c 5f 52 45 54 52 59 20 3a 20 72 63 3b 0a 20 20  L_RETRY : rc;.  
12700 20 20 7d 0a 20 20 20 20 2f 2a 20 4e 6f 77 20 74    }.    /* Now t
12710 68 61 74 20 74 68 65 20 72 65 61 64 2d 6c 6f 63  hat the read-loc
12720 6b 20 68 61 73 20 62 65 65 6e 20 6f 62 74 61 69  k has been obtai
12730 6e 65 64 2c 20 63 68 65 63 6b 20 74 68 61 74 20  ned, check that 
12740 6e 65 69 74 68 65 72 20 74 68 65 0a 20 20 20 20  neither the.    
12750 2a 2a 20 76 61 6c 75 65 20 69 6e 20 74 68 65 20  ** value in the 
12760 61 52 65 61 64 4d 61 72 6b 5b 5d 20 61 72 72 61  aReadMark[] arra
12770 79 20 6f 72 20 74 68 65 20 63 6f 6e 74 65 6e 74  y or the content
12780 73 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  s of the wal-ind
12790 65 78 0a 20 20 20 20 2a 2a 20 68 65 61 64 65 72  ex.    ** header
127a0 20 68 61 76 65 20 63 68 61 6e 67 65 64 2e 0a 20   have changed.. 
127b0 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 49 74 20     **.    ** It 
127c0 69 73 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20  is necessary to 
127d0 63 68 65 63 6b 20 74 68 61 74 20 74 68 65 20 77  check that the w
127e0 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
127f0 64 69 64 20 6e 6f 74 20 63 68 61 6e 67 65 0a 20  did not change. 
12800 20 20 20 2a 2a 20 62 65 74 77 65 65 6e 20 74 68     ** between th
12810 65 20 74 69 6d 65 20 69 74 20 77 61 73 20 72 65  e time it was re
12820 61 64 20 61 6e 64 20 77 68 65 6e 20 74 68 65 20  ad and when the 
12830 73 68 61 72 65 64 2d 6c 6f 63 6b 20 77 61 73 20  shared-lock was 
12840 6f 62 74 61 69 6e 65 64 0a 20 20 20 20 2a 2a 20  obtained.    ** 
12850 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  on WAL_READ_LOCK
12860 28 6d 78 49 29 20 77 61 73 20 6f 62 74 61 69 6e  (mxI) was obtain
12870 65 64 20 74 6f 20 61 63 63 6f 75 6e 74 20 66 6f  ed to account fo
12880 72 20 74 68 65 20 70 6f 73 73 69 62 69 6c 69 74  r the possibilit
12890 79 0a 20 20 20 20 2a 2a 20 74 68 61 74 20 74 68  y.    ** that th
128a0 65 20 6c 6f 67 20 66 69 6c 65 20 6d 61 79 20 68  e log file may h
128b0 61 76 65 20 62 65 65 6e 20 77 72 61 70 70 65 64  ave been wrapped
128c0 20 62 79 20 61 20 77 72 69 74 65 72 2c 20 6f 72   by a writer, or
128d0 20 74 68 61 74 20 66 72 61 6d 65 73 0a 20 20 20   that frames.   
128e0 20 2a 2a 20 74 68 61 74 20 6f 63 63 75 72 20 6c   ** that occur l
128f0 61 74 65 72 20 69 6e 20 74 68 65 20 6c 6f 67 20  ater in the log 
12900 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  than pWal->hdr.m
12910 78 46 72 61 6d 65 20 6d 61 79 20 68 61 76 65 20  xFrame may have 
12920 62 65 65 6e 0a 20 20 20 20 2a 2a 20 63 6f 70 69  been.    ** copi
12930 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ed into the data
12940 62 61 73 65 20 62 79 20 61 20 63 68 65 63 6b 70  base by a checkp
12950 6f 69 6e 74 65 72 2e 20 49 66 20 65 69 74 68 65  ointer. If eithe
12960 72 20 6f 66 20 74 68 65 73 65 20 74 68 69 6e 67  r of these thing
12970 73 0a 20 20 20 20 2a 2a 20 68 61 70 70 65 6e 65  s.    ** happene
12980 64 2c 20 74 68 65 6e 20 72 65 61 64 69 6e 67 20  d, then reading 
12990 74 68 65 20 64 61 74 61 62 61 73 65 20 77 69 74  the database wit
129a0 68 20 74 68 65 20 63 75 72 72 65 6e 74 20 76 61  h the current va
129b0 6c 75 65 20 6f 66 0a 20 20 20 20 2a 2a 20 70 57  lue of.    ** pW
129c0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
129d0 72 69 73 6b 73 20 72 65 61 64 69 6e 67 20 61 20  risks reading a 
129e0 63 6f 72 72 75 70 74 65 64 20 73 6e 61 70 73 68  corrupted snapsh
129f0 6f 74 2e 20 53 6f 2c 20 72 65 74 72 79 0a 20 20  ot. So, retry.  
12a00 20 20 2a 2a 20 69 6e 73 74 65 61 64 2e 0a 20 20    ** instead..  
12a10 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68 69 73    **.    ** This
12a20 20 64 6f 65 73 20 6e 6f 74 20 67 75 61 72 61 6e   does not guaran
12a30 74 65 65 20 74 68 61 74 20 74 68 65 20 63 6f 70  tee that the cop
12a40 79 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  y of the wal-ind
12a50 65 78 20 68 65 61 64 65 72 20 69 73 20 75 70 20  ex header is up 
12a60 74 6f 0a 20 20 20 20 2a 2a 20 64 61 74 65 20 62  to.    ** date b
12a70 65 66 6f 72 65 20 70 72 6f 63 65 65 64 69 6e 67  efore proceeding
12a80 2e 20 54 68 61 74 20 77 6f 75 6c 64 20 6e 6f 74  . That would not
12a90 20 62 65 20 70 6f 73 73 69 62 6c 65 20 77 69 74   be possible wit
12aa0 68 6f 75 74 20 73 6f 6d 65 68 6f 77 0a 20 20 20  hout somehow.   
12ab0 20 2a 2a 20 62 6c 6f 63 6b 69 6e 67 20 77 72 69   ** blocking wri
12ac0 74 65 72 73 2e 20 49 74 20 6f 6e 6c 79 20 67 75  ters. It only gu
12ad0 61 72 61 6e 74 65 65 73 20 74 68 61 74 20 61 20  arantees that a 
12ae0 64 61 6e 67 65 72 6f 75 73 20 63 68 65 63 6b 70  dangerous checkp
12af0 6f 69 6e 74 20 6f 72 20 0a 20 20 20 20 2a 2a 20  oint or .    ** 
12b00 6c 6f 67 2d 77 72 61 70 20 28 65 69 74 68 65 72  log-wrap (either
12b10 20 6f 66 20 77 68 69 63 68 20 77 6f 75 6c 64 20   of which would 
12b20 72 65 71 75 69 72 65 20 61 6e 20 65 78 63 6c 75  require an exclu
12b30 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 0a 20 20 20  sive lock on.   
12b40 20 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43   ** WAL_READ_LOC
12b50 4b 28 6d 78 49 29 29 20 68 61 73 20 6e 6f 74 20  K(mxI)) has not 
12b60 6f 63 63 75 72 72 65 64 20 73 69 6e 63 65 20 74  occurred since t
12b70 68 65 20 73 6e 61 70 73 68 6f 74 20 77 61 73 20  he snapshot was 
12b80 76 61 6c 69 64 2e 0a 20 20 20 20 2a 2f 0a 20 20  valid..    */.  
12b90 20 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 42 61    sqlite3OsShmBa
12ba0 72 72 69 65 72 28 70 57 61 6c 2d 3e 70 44 62 46  rrier(pWal->pDbF
12bb0 64 29 3b 0a 20 20 20 20 69 66 28 20 70 49 6e 66  d);.    if( pInf
12bc0 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 6d 78 49  o->aReadMark[mxI
12bd0 5d 21 3d 6d 78 52 65 61 64 4d 61 72 6b 0a 20 20  ]!=mxReadMark.  
12be0 20 20 20 7c 7c 20 6d 65 6d 63 6d 70 28 28 76 6f     || memcmp((vo
12bf0 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72  id *)walIndexHdr
12c00 28 70 57 61 6c 29 2c 20 26 70 57 61 6c 2d 3e 68  (pWal), &pWal->h
12c10 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  dr, sizeof(WalIn
12c20 64 65 78 48 64 72 29 29 0a 20 20 20 20 29 7b 0a  dexHdr)).    ){.
12c30 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53        walUnlockS
12c40 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
12c50 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b  READ_LOCK(mxI));
12c60 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 57 41  .      return WA
12c70 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 7d 65 6c  L_RETRY;.    }el
12c80 73 65 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74  se{.      assert
12c90 28 20 6d 78 52 65 61 64 4d 61 72 6b 3c 3d 70 57  ( mxReadMark<=pW
12ca0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
12cb0 29 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 72  );.      pWal->r
12cc0 65 61 64 4c 6f 63 6b 20 3d 20 28 69 31 36 29 6d  eadLock = (i16)m
12cd0 78 49 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  xI;.    }.  }.  
12ce0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
12cf0 0a 2a 2a 20 42 65 67 69 6e 20 61 20 72 65 61 64  .** Begin a read
12d00 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20   transaction on 
12d10 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2a  the database..**
12d20 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
12d30 20 75 73 65 64 20 74 6f 20 62 65 20 63 61 6c 6c   used to be call
12d40 65 64 20 73 71 6c 69 74 65 33 4f 70 65 6e 53 6e  ed sqlite3OpenSn
12d50 61 70 73 68 6f 74 28 29 20 61 6e 64 20 77 69 74  apshot() and wit
12d60 68 20 67 6f 6f 64 20 72 65 61 73 6f 6e 3a 0a 2a  h good reason:.*
12d70 2a 20 69 74 20 74 61 6b 65 73 20 61 20 73 6e 61  * it takes a sna
12d80 70 73 68 6f 74 20 6f 66 20 74 68 65 20 73 74 61  pshot of the sta
12d90 74 65 20 6f 66 20 74 68 65 20 57 41 4c 20 61 6e  te of the WAL an
12da0 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 6f 72 20  d wal-index for 
12db0 74 68 65 20 63 75 72 72 65 6e 74 0a 2a 2a 20 69  the current.** i
12dc0 6e 73 74 61 6e 74 20 69 6e 20 74 69 6d 65 2e 20  nstant in time. 
12dd0 20 54 68 65 20 63 75 72 72 65 6e 74 20 74 68 72   The current thr
12de0 65 61 64 20 77 69 6c 6c 20 63 6f 6e 74 69 6e 75  ead will continu
12df0 65 20 74 6f 20 75 73 65 20 74 68 69 73 20 73 6e  e to use this sn
12e00 61 70 73 68 6f 74 2e 0a 2a 2a 20 4f 74 68 65 72  apshot..** Other
12e10 20 74 68 72 65 61 64 73 20 6d 69 67 68 74 20 61   threads might a
12e20 70 70 65 6e 64 20 6e 65 77 20 63 6f 6e 74 65 6e  ppend new conten
12e30 74 20 74 6f 20 74 68 65 20 57 41 4c 20 61 6e 64  t to the WAL and
12e40 20 77 61 6c 2d 69 6e 64 65 78 20 62 75 74 0a 2a   wal-index but.*
12e50 2a 20 74 68 61 74 20 65 78 74 72 61 20 63 6f 6e  * that extra con
12e60 74 65 6e 74 20 69 73 20 69 67 6e 6f 72 65 64 20  tent is ignored 
12e70 62 79 20 74 68 65 20 63 75 72 72 65 6e 74 20 74  by the current t
12e80 68 72 65 61 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  hread..**.** If 
12e90 74 68 65 20 64 61 74 61 62 61 73 65 20 63 6f 6e  the database con
12ea0 74 65 6e 74 73 20 68 61 76 65 20 63 68 61 6e 67  tents have chang
12eb0 65 73 20 73 69 6e 63 65 20 74 68 65 20 70 72 65  es since the pre
12ec0 76 69 6f 75 73 20 72 65 61 64 0a 2a 2a 20 74 72  vious read.** tr
12ed0 61 6e 73 61 63 74 69 6f 6e 2c 20 74 68 65 6e 20  ansaction, then 
12ee0 2a 70 43 68 61 6e 67 65 64 20 69 73 20 73 65 74  *pChanged is set
12ef0 20 74 6f 20 31 20 62 65 66 6f 72 65 20 72 65 74   to 1 before ret
12f00 75 72 6e 69 6e 67 2e 20 20 54 68 65 0a 2a 2a 20  urning.  The.** 
12f10 50 61 67 65 72 20 6c 61 79 65 72 20 77 69 6c 6c  Pager layer will
12f20 20 75 73 65 20 74 68 69 73 20 74 6f 20 6b 6e 6f   use this to kno
12f30 77 20 74 68 61 74 20 69 73 20 63 61 63 68 65 20  w that is cache 
12f40 69 73 20 73 74 61 6c 65 20 61 6e 64 0a 2a 2a 20  is stale and.** 
12f50 6e 65 65 64 73 20 74 6f 20 62 65 20 66 6c 75 73  needs to be flus
12f60 68 65 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  hed..*/.int sqli
12f70 74 65 33 57 61 6c 42 65 67 69 6e 52 65 61 64 54  te3WalBeginReadT
12f80 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a  ransaction(Wal *
12f90 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e  pWal, int *pChan
12fa0 67 65 64 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  ged){.  int rc; 
12fb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12fc0 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
12fd0 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
12fe0 63 6e 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20  cnt = 0;        
12ff0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
13000 75 6d 62 65 72 20 6f 66 20 54 72 79 42 65 67 69  umber of TryBegi
13010 6e 52 65 61 64 20 61 74 74 65 6d 70 74 73 20 2a  nRead attempts *
13020 2f 0a 0a 20 20 64 6f 7b 0a 20 20 20 20 72 63 20  /..  do{.    rc 
13030 3d 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61  = walTryBeginRea
13040 64 28 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64  d(pWal, pChanged
13050 2c 20 30 2c 20 2b 2b 63 6e 74 29 3b 0a 20 20 7d  , 0, ++cnt);.  }
13060 77 68 69 6c 65 28 20 72 63 3d 3d 57 41 4c 5f 52  while( rc==WAL_R
13070 45 54 52 59 20 29 3b 0a 20 20 72 65 74 75 72 6e  ETRY );.  return
13080 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69   rc;.}../*.** Fi
13090 6e 69 73 68 20 77 69 74 68 20 61 20 72 65 61 64  nish with a read
130a0 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 20 41   transaction.  A
130b0 6c 6c 20 74 68 69 73 20 64 6f 65 73 20 69 73 20  ll this does is 
130c0 72 65 6c 65 61 73 65 20 74 68 65 0a 2a 2a 20 72  release the.** r
130d0 65 61 64 2d 6c 6f 63 6b 2e 0a 2a 2f 0a 76 6f 69  ead-lock..*/.voi
130e0 64 20 73 71 6c 69 74 65 33 57 61 6c 45 6e 64 52  d sqlite3WalEndR
130f0 65 61 64 54 72 61 6e 73 61 63 74 69 6f 6e 28 57  eadTransaction(W
13100 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28  al *pWal){.  if(
13110 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e   pWal->readLock>
13120 3d 30 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c  =0 ){.    walUnl
13130 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20  ockShared(pWal, 
13140 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57  WAL_READ_LOCK(pW
13150 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 3b 0a  al->readLock));.
13160 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f      pWal->readLo
13170 63 6b 20 3d 20 2d 31 3b 0a 20 20 7d 0a 7d 0a 0a  ck = -1;.  }.}..
13180 2f 2a 0a 2a 2a 20 52 65 61 64 20 61 20 70 61 67  /*.** Read a pag
13190 65 20 66 72 6f 6d 20 74 68 65 20 57 41 4c 2c 20  e from the WAL, 
131a0 69 66 20 69 74 20 69 73 20 70 72 65 73 65 6e 74  if it is present
131b0 20 69 6e 20 74 68 65 20 57 41 4c 20 61 6e 64 20   in the WAL and 
131c0 69 66 20 74 68 65 20 0a 2a 2a 20 63 75 72 72 65  if the .** curre
131d0 6e 74 20 72 65 61 64 20 74 72 61 6e 73 61 63 74  nt read transact
131e0 69 6f 6e 20 69 73 20 63 6f 6e 66 69 67 75 72 65  ion is configure
131f0 64 20 74 6f 20 75 73 65 20 74 68 65 20 57 41 4c  d to use the WAL
13200 2e 20 20 0a 2a 2a 0a 2a 2a 20 54 68 65 20 2a 70  .  .**.** The *p
13210 49 6e 57 61 6c 20 69 73 20 73 65 74 20 74 6f 20  InWal is set to 
13220 31 20 69 66 20 74 68 65 20 72 65 71 75 65 73 74  1 if the request
13230 65 64 20 70 61 67 65 20 69 73 20 69 6e 20 74 68  ed page is in th
13240 65 20 57 41 4c 20 61 6e 64 0a 2a 2a 20 68 61 73  e WAL and.** has
13250 20 62 65 65 6e 20 6c 6f 61 64 65 64 2e 20 20 4f   been loaded.  O
13260 72 20 2a 70 49 6e 57 61 6c 20 69 73 20 73 65 74  r *pInWal is set
13270 20 74 6f 20 30 20 69 66 20 74 68 65 20 70 61 67   to 0 if the pag
13280 65 20 77 61 73 20 6e 6f 74 20 69 6e 20 0a 2a 2a  e was not in .**
13290 20 74 68 65 20 57 41 4c 20 61 6e 64 20 6e 65 65   the WAL and nee
132a0 64 73 20 74 6f 20 62 65 20 72 65 61 64 20 6f 75  ds to be read ou
132b0 74 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  t of the databas
132c0 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
132d0 33 57 61 6c 52 65 61 64 28 0a 20 20 57 61 6c 20  3WalRead(.  Wal 
132e0 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20  *pWal,          
132f0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
13300 41 4c 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 50  AL handle */.  P
13310 67 6e 6f 20 70 67 6e 6f 2c 20 20 20 20 20 20 20  gno pgno,       
13320 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
13330 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20  * Database page 
13340 6e 75 6d 62 65 72 20 74 6f 20 72 65 61 64 20 64  number to read d
13350 61 74 61 20 66 6f 72 20 2a 2f 0a 20 20 69 6e 74  ata for */.  int
13360 20 2a 70 49 6e 57 61 6c 2c 20 20 20 20 20 20 20   *pInWal,       
13370 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
13380 4f 55 54 3a 20 54 72 75 65 20 69 66 20 64 61 74  OUT: True if dat
13390 61 20 69 73 20 72 65 61 64 20 66 72 6f 6d 20 57  a is read from W
133a0 41 4c 20 2a 2f 0a 20 20 69 6e 74 20 6e 4f 75 74  AL */.  int nOut
133b0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
133c0 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
133d0 6f 66 20 62 75 66 66 65 72 20 70 4f 75 74 20 69  of buffer pOut i
133e0 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 38 20  n bytes */.  u8 
133f0 2a 70 4f 75 74 20 20 20 20 20 20 20 20 20 20 20  *pOut           
13400 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
13410 42 75 66 66 65 72 20 74 6f 20 77 72 69 74 65 20  Buffer to write 
13420 70 61 67 65 20 64 61 74 61 20 74 6f 20 2a 2f 0a  page data to */.
13430 29 7b 0a 20 20 75 33 32 20 69 52 65 61 64 20 3d  ){.  u32 iRead =
13440 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
13450 20 20 20 20 20 2f 2a 20 49 66 20 21 3d 30 2c 20       /* If !=0, 
13460 57 41 4c 20 66 72 61 6d 65 20 74 6f 20 72 65 74  WAL frame to ret
13470 75 72 6e 20 64 61 74 61 20 66 72 6f 6d 20 2a 2f  urn data from */
13480 0a 20 20 75 33 32 20 69 4c 61 73 74 20 3d 20 70  .  u32 iLast = p
13490 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
134a0 3b 20 20 2f 2a 20 4c 61 73 74 20 70 61 67 65 20  ;  /* Last page 
134b0 69 6e 20 57 41 4c 20 66 6f 72 20 74 68 69 73 20  in WAL for this 
134c0 72 65 61 64 65 72 20 2a 2f 0a 20 20 69 6e 74 20  reader */.  int 
134d0 69 48 61 73 68 3b 20 20 20 20 20 20 20 20 20 20  iHash;          
134e0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55              /* U
134f0 73 65 64 20 74 6f 20 6c 6f 6f 70 20 74 68 72 6f  sed to loop thro
13500 75 67 68 20 4e 20 68 61 73 68 20 74 61 62 6c 65  ugh N hash table
13510 73 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 69 73 20  s */..  /* This 
13520 72 6f 75 74 69 6e 65 20 69 73 20 6f 6e 6c 79 20  routine is only 
13530 62 65 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77  be called from w
13540 69 74 68 69 6e 20 61 20 72 65 61 64 20 74 72 61  ithin a read tra
13550 6e 73 61 63 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61  nsaction. */.  a
13560 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65 61  ssert( pWal->rea
13570 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70 57 61 6c  dLock>=0 || pWal
13580 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 29 3b 0a 0a  ->lockError );..
13590 20 20 2f 2a 20 49 66 20 74 68 65 20 22 6c 61 73    /* If the "las
135a0 74 20 70 61 67 65 22 20 66 69 65 6c 64 20 6f 66  t page" field of
135b0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
135c0 65 61 64 65 72 20 73 6e 61 70 73 68 6f 74 20 69  eader snapshot i
135d0 73 20 30 2c 20 74 68 65 6e 0a 20 20 2a 2a 20 6e  s 0, then.  ** n
135e0 6f 20 64 61 74 61 20 77 69 6c 6c 20 62 65 20 72  o data will be r
135f0 65 61 64 20 66 72 6f 6d 20 74 68 65 20 77 61 6c  ead from the wal
13600 20 75 6e 64 65 72 20 61 6e 79 20 63 69 72 63 75   under any circu
13610 6d 73 74 61 6e 63 65 73 2e 20 52 65 74 75 72 6e  mstances. Return
13620 20 65 61 72 6c 79 0a 20 20 2a 2a 20 69 6e 20 74   early.  ** in t
13630 68 69 73 20 63 61 73 65 20 61 73 20 61 6e 20 6f  his case as an o
13640 70 74 69 6d 69 7a 61 74 69 6f 6e 2e 20 20 4c 69  ptimization.  Li
13650 6b 65 77 69 73 65 2c 20 69 66 20 70 57 61 6c 2d  kewise, if pWal-
13660 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 2c 20 0a 20  >readLock==0, . 
13670 20 2a 2a 20 74 68 65 6e 20 74 68 65 20 57 41 4c   ** then the WAL
13680 20 69 73 20 69 67 6e 6f 72 65 64 20 62 79 20 74   is ignored by t
13690 68 65 20 72 65 61 64 65 72 20 73 6f 20 72 65 74  he reader so ret
136a0 75 72 6e 20 65 61 72 6c 79 2c 20 61 73 20 69 66  urn early, as if
136b0 20 74 68 65 20 0a 20 20 2a 2a 20 57 41 4c 20 77   the .  ** WAL w
136c0 65 72 65 20 65 6d 70 74 79 2e 0a 20 20 2a 2f 0a  ere empty..  */.
136d0 20 20 69 66 28 20 69 4c 61 73 74 3d 3d 30 20 7c    if( iLast==0 |
136e0 7c 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  | pWal->readLock
136f0 3d 3d 30 20 29 7b 0a 20 20 20 20 2a 70 49 6e 57  ==0 ){.    *pInW
13700 61 6c 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75  al = 0;.    retu
13710 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20  rn SQLITE_OK;.  
13720 7d 0a 0a 20 20 2f 2a 20 53 65 61 72 63 68 20 74  }..  /* Search t
13730 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 6f 72  he hash table or
13740 20 74 61 62 6c 65 73 20 66 6f 72 20 61 6e 20 65   tables for an e
13750 6e 74 72 79 20 6d 61 74 63 68 69 6e 67 20 70 61  ntry matching pa
13760 67 65 20 6e 75 6d 62 65 72 0a 20 20 2a 2a 20 70  ge number.  ** p
13770 67 6e 6f 2e 20 45 61 63 68 20 69 74 65 72 61 74  gno. Each iterat
13780 69 6f 6e 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  ion of the follo
13790 77 69 6e 67 20 66 6f 72 28 29 20 6c 6f 6f 70 20  wing for() loop 
137a0 73 65 61 72 63 68 65 73 20 6f 6e 65 0a 20 20 2a  searches one.  *
137b0 2a 20 68 61 73 68 20 74 61 62 6c 65 20 28 65 61  * hash table (ea
137c0 63 68 20 68 61 73 68 20 74 61 62 6c 65 20 69 6e  ch hash table in
137d0 64 65 78 65 73 20 75 70 20 74 6f 20 48 41 53 48  dexes up to HASH
137e0 54 41 42 4c 45 5f 4e 50 41 47 45 20 66 72 61 6d  TABLE_NPAGE fram
137f0 65 73 29 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54  es)..  **.  ** T
13800 68 69 73 20 63 6f 64 65 20 6d 69 67 68 74 20 72  his code might r
13810 75 6e 20 63 6f 6e 63 75 72 72 65 6e 74 6c 79 20  un concurrently 
13820 74 6f 20 74 68 65 20 63 6f 64 65 20 69 6e 20 77  to the code in w
13830 61 6c 49 6e 64 65 78 41 70 70 65 6e 64 28 29 0a  alIndexAppend().
13840 20 20 2a 2a 20 74 68 61 74 20 61 64 64 73 20 65    ** that adds e
13850 6e 74 72 69 65 73 20 74 6f 20 74 68 65 20 77 61  ntries to the wa
13860 6c 2d 69 6e 64 65 78 20 28 61 6e 64 20 70 6f 73  l-index (and pos
13870 73 69 62 6c 79 20 74 6f 20 74 68 69 73 20 68 61  sibly to this ha
13880 73 68 20 0a 20 20 2a 2a 20 74 61 62 6c 65 29 2e  sh .  ** table).
13890 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68 65 20   This means the 
138a0 76 61 6c 75 65 20 6a 75 73 74 20 72 65 61 64 20  value just read 
138b0 66 72 6f 6d 20 74 68 65 20 68 61 73 68 20 0a 20  from the hash . 
138c0 20 2a 2a 20 73 6c 6f 74 20 28 61 48 61 73 68 5b   ** slot (aHash[
138d0 69 4b 65 79 5d 29 20 6d 61 79 20 68 61 76 65 20  iKey]) may have 
138e0 62 65 65 6e 20 61 64 64 65 64 20 62 65 66 6f 72  been added befor
138f0 65 20 6f 72 20 61 66 74 65 72 20 74 68 65 20 0a  e or after the .
13900 20 20 2a 2a 20 63 75 72 72 65 6e 74 20 72 65 61    ** current rea
13910 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61  d transaction wa
13920 73 20 6f 70 65 6e 65 64 2e 20 56 61 6c 75 65 73  s opened. Values
13930 20 61 64 64 65 64 20 61 66 74 65 72 20 74 68 65   added after the
13940 0a 20 20 2a 2a 20 72 65 61 64 20 74 72 61 6e 73  .  ** read trans
13950 61 63 74 69 6f 6e 20 77 61 73 20 6f 70 65 6e 65  action was opene
13960 64 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20  d may have been 
13970 77 72 69 74 74 65 6e 20 69 6e 63 6f 72 72 65 63  written incorrec
13980 74 6c 79 20 2d 0a 20 20 2a 2a 20 69 2e 65 2e 20  tly -.  ** i.e. 
13990 74 68 65 73 65 20 73 6c 6f 74 73 20 6d 61 79 20  these slots may 
139a0 63 6f 6e 74 61 69 6e 20 67 61 72 62 61 67 65 20  contain garbage 
139b0 64 61 74 61 2e 20 48 6f 77 65 76 65 72 2c 20 77  data. However, w
139c0 65 20 61 73 73 75 6d 65 0a 20 20 2a 2a 20 74 68  e assume.  ** th
139d0 61 74 20 61 6e 79 20 73 6c 6f 74 73 20 77 72 69  at any slots wri
139e0 74 74 65 6e 20 62 65 66 6f 72 65 20 74 68 65 20  tten before the 
139f0 63 75 72 72 65 6e 74 20 72 65 61 64 20 74 72 61  current read tra
13a00 6e 73 61 63 74 69 6f 6e 20 77 61 73 0a 20 20 2a  nsaction was.  *
13a10 2a 20 6f 70 65 6e 65 64 20 72 65 6d 61 69 6e 20  * opened remain 
13a20 75 6e 6d 6f 64 69 66 69 65 64 2e 0a 20 20 2a 2a  unmodified..  **
13a30 0a 20 20 2a 2a 20 46 6f 72 20 74 68 65 20 72 65  .  ** For the re
13a40 61 73 6f 6e 73 20 61 62 6f 76 65 2c 20 74 68 65  asons above, the
13a50 20 69 66 28 2e 2e 2e 29 20 63 6f 6e 64 69 74 69   if(...) conditi
13a60 6f 6e 20 66 65 61 74 75 72 65 64 20 69 6e 20 74  on featured in t
13a70 68 65 20 69 6e 6e 65 72 0a 20 20 2a 2a 20 6c 6f  he inner.  ** lo
13a80 6f 70 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77  op of the follow
13a90 69 6e 67 20 62 6c 6f 63 6b 20 69 73 20 6d 6f 72  ing block is mor
13aa0 65 20 73 74 72 69 6e 67 65 6e 74 20 74 68 61 74  e stringent that
13ab0 20 77 6f 75 6c 64 20 62 65 20 72 65 71 75 69 72   would be requir
13ac0 65 64 20 0a 20 20 2a 2a 20 69 66 20 77 65 20 68  ed .  ** if we h
13ad0 61 64 20 65 78 63 6c 75 73 69 76 65 20 61 63 63  ad exclusive acc
13ae0 65 73 73 20 74 6f 20 74 68 65 20 68 61 73 68 2d  ess to the hash-
13af0 74 61 62 6c 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a  table:.  **.  **
13b00 20 20 20 28 61 50 67 6e 6f 5b 69 46 72 61 6d 65     (aPgno[iFrame
13b10 5d 3d 3d 70 67 6e 6f 29 3a 20 0a 20 20 2a 2a 20  ]==pgno): .  ** 
13b20 20 20 20 20 54 68 69 73 20 63 6f 6e 64 69 74 69      This conditi
13b30 6f 6e 20 66 69 6c 74 65 72 73 20 6f 75 74 20 6e  on filters out n
13b40 6f 72 6d 61 6c 20 68 61 73 68 2d 74 61 62 6c 65  ormal hash-table
13b50 20 63 6f 6c 6c 69 73 69 6f 6e 73 2e 0a 20 20 2a   collisions..  *
13b60 2a 0a 20 20 2a 2a 20 20 20 28 69 46 72 61 6d 65  *.  **   (iFrame
13b70 3c 3d 69 4c 61 73 74 29 3a 20 0a 20 20 2a 2a 20  <=iLast): .  ** 
13b80 20 20 20 20 54 68 69 73 20 63 6f 6e 64 69 74 69      This conditi
13b90 6f 6e 20 66 69 6c 74 65 72 73 20 6f 75 74 20 65  on filters out e
13ba0 6e 74 72 69 65 73 20 74 68 61 74 20 77 65 72 65  ntries that were
13bb0 20 61 64 64 65 64 20 74 6f 20 74 68 65 20 68 61   added to the ha
13bc0 73 68 0a 20 20 2a 2a 20 20 20 20 20 74 61 62 6c  sh.  **     tabl
13bd0 65 20 61 66 74 65 72 20 74 68 65 20 63 75 72 72  e after the curr
13be0 65 6e 74 20 72 65 61 64 2d 74 72 61 6e 73 61 63  ent read-transac
13bf0 74 69 6f 6e 20 68 61 64 20 73 74 61 72 74 65 64  tion had started
13c00 2e 0a 20 20 2a 2f 0a 20 20 66 6f 72 28 69 48 61  ..  */.  for(iHa
13c10 73 68 3d 77 61 6c 46 72 61 6d 65 50 61 67 65 28  sh=walFramePage(
13c20 69 4c 61 73 74 29 3b 20 69 48 61 73 68 3e 3d 30  iLast); iHash>=0
13c30 20 26 26 20 69 52 65 61 64 3d 3d 30 3b 20 69 48   && iRead==0; iH
13c40 61 73 68 2d 2d 29 7b 0a 20 20 20 20 76 6f 6c 61  ash--){.    vola
13c50 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 61 48  tile ht_slot *aH
13c60 61 73 68 3b 20 20 20 20 20 20 2f 2a 20 50 6f 69  ash;      /* Poi
13c70 6e 74 65 72 20 74 6f 20 68 61 73 68 20 74 61 62  nter to hash tab
13c80 6c 65 20 2a 2f 0a 20 20 20 20 76 6f 6c 61 74 69  le */.    volati
13c90 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 3b 20 20  le u32 *aPgno;  
13ca0 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
13cb0 65 72 20 74 6f 20 61 72 72 61 79 20 6f 66 20 70  er to array of p
13cc0 61 67 65 20 6e 75 6d 62 65 72 73 20 2a 2f 0a 20  age numbers */. 
13cd0 20 20 20 75 33 32 20 69 5a 65 72 6f 3b 20 20 20     u32 iZero;   
13ce0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13cf0 20 2f 2a 20 46 72 61 6d 65 20 6e 75 6d 62 65 72   /* Frame number
13d00 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74   corresponding t
13d10 6f 20 61 50 67 6e 6f 5b 30 5d 20 2a 2f 0a 20 20  o aPgno[0] */.  
13d20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20 20    int iKey;     
13d30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13d40 2f 2a 20 48 61 73 68 20 73 6c 6f 74 20 69 6e 64  /* Hash slot ind
13d50 65 78 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 43  ex */.    int nC
13d60 6f 6c 6c 69 64 65 3b 20 20 20 20 20 20 20 20 20  ollide;         
13d70 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
13d80 72 20 6f 66 20 68 61 73 68 20 63 6f 6c 6c 69 73  r of hash collis
13d90 69 6f 6e 73 20 72 65 6d 61 69 6e 69 6e 67 20 2a  ions remaining *
13da0 2f 0a 20 20 20 20 69 6e 74 20 72 63 3b 20 20 20  /.    int rc;   
13db0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13dc0 20 20 20 20 2f 2a 20 45 72 72 6f 72 20 63 6f 64      /* Error cod
13dd0 65 20 2a 2f 0a 0a 20 20 20 20 72 63 20 3d 20 77  e */..    rc = w
13de0 61 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c 20  alHashGet(pWal, 
13df0 69 48 61 73 68 2c 20 26 61 48 61 73 68 2c 20 26  iHash, &aHash, &
13e00 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a  aPgno, &iZero);.
13e10 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
13e20 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  TE_OK ){.      r
13e30 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
13e40 20 20 20 20 6e 43 6f 6c 6c 69 64 65 20 3d 20 48      nCollide = H
13e50 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 0a  ASHTABLE_NSLOT;.
13e60 20 20 20 20 66 6f 72 28 69 4b 65 79 3d 77 61 6c      for(iKey=wal
13e70 48 61 73 68 28 70 67 6e 6f 29 3b 20 61 48 61 73  Hash(pgno); aHas
13e80 68 5b 69 4b 65 79 5d 3b 20 69 4b 65 79 3d 77 61  h[iKey]; iKey=wa
13e90 6c 4e 65 78 74 48 61 73 68 28 69 4b 65 79 29 29  lNextHash(iKey))
13ea0 7b 0a 20 20 20 20 20 20 75 33 32 20 69 46 72 61  {.      u32 iFra
13eb0 6d 65 20 3d 20 61 48 61 73 68 5b 69 4b 65 79 5d  me = aHash[iKey]
13ec0 20 2b 20 69 5a 65 72 6f 3b 0a 20 20 20 20 20 20   + iZero;.      
13ed0 69 66 28 20 69 46 72 61 6d 65 3c 3d 69 4c 61 73  if( iFrame<=iLas
13ee0 74 20 26 26 20 61 50 67 6e 6f 5b 61 48 61 73 68  t && aPgno[aHash
13ef0 5b 69 4b 65 79 5d 5d 3d 3d 70 67 6e 6f 20 29 7b  [iKey]]==pgno ){
13f00 0a 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28  .        assert(
13f10 20 69 46 72 61 6d 65 3e 69 52 65 61 64 20 29 3b   iFrame>iRead );
13f20 0a 20 20 20 20 20 20 20 20 69 52 65 61 64 20 3d  .        iRead =
13f30 20 69 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 7d   iFrame;.      }
13f40 0a 20 20 20 20 20 20 69 66 28 20 28 6e 43 6f 6c  .      if( (nCol
13f50 6c 69 64 65 2d 2d 29 3d 3d 30 20 29 7b 0a 20 20  lide--)==0 ){.  
13f60 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c        return SQL
13f70 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54  ITE_CORRUPT_BKPT
13f80 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
13f90 20 20 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49    }..#ifdef SQLI
13fa0 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53  TE_ENABLE_EXPENS
13fb0 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20  IVE_ASSERT.  /* 
13fc0 49 66 20 65 78 70 65 6e 73 69 76 65 20 61 73 73  If expensive ass
13fd0 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74 73  ert() statements
13fe0 20 61 72 65 20 61 76 61 69 6c 61 62 6c 65 2c 20   are available, 
13ff0 64 6f 20 61 20 6c 69 6e 65 61 72 20 73 65 61 72  do a linear sear
14000 63 68 0a 20 20 2a 2a 20 6f 66 20 74 68 65 20 77  ch.  ** of the w
14010 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20 63 6f  al-index file co
14020 6e 74 65 6e 74 2e 20 4d 61 6b 65 20 73 75 72 65  ntent. Make sure
14030 20 74 68 65 20 72 65 73 75 6c 74 73 20 61 67 72   the results agr
14040 65 65 20 77 69 74 68 20 74 68 65 0a 20 20 2a 2a  ee with the.  **
14050 20 72 65 73 75 6c 74 20 6f 62 74 61 69 6e 65 64   result obtained
14060 20 75 73 69 6e 67 20 74 68 65 20 68 61 73 68 20   using the hash 
14070 69 6e 64 65 78 65 73 20 61 62 6f 76 65 2e 20 20  indexes above.  
14080 2a 2f 0a 20 20 7b 0a 20 20 20 20 75 33 32 20 69  */.  {.    u32 i
14090 52 65 61 64 32 20 3d 20 30 3b 0a 20 20 20 20 75  Read2 = 0;.    u
140a0 33 32 20 69 54 65 73 74 3b 0a 20 20 20 20 66 6f  32 iTest;.    fo
140b0 72 28 69 54 65 73 74 3d 69 4c 61 73 74 3b 20 69  r(iTest=iLast; i
140c0 54 65 73 74 3e 30 3b 20 69 54 65 73 74 2d 2d 29  Test>0; iTest--)
140d0 7b 0a 20 20 20 20 20 20 69 66 28 20 77 61 6c 46  {.      if( walF
140e0 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69  ramePgno(pWal, i
140f0 54 65 73 74 29 3d 3d 70 67 6e 6f 20 29 7b 0a 20  Test)==pgno ){. 
14100 20 20 20 20 20 20 20 69 52 65 61 64 32 20 3d 20         iRead2 = 
14110 69 54 65 73 74 3b 0a 20 20 20 20 20 20 20 20 62  iTest;.        b
14120 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
14130 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20    }.    assert( 
14140 69 52 65 61 64 3d 3d 69 52 65 61 64 32 20 29 3b  iRead==iRead2 );
14150 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2f  .  }.#endif..  /
14160 2a 20 49 66 20 69 52 65 61 64 20 69 73 20 6e 6f  * If iRead is no
14170 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 69 74 20  n-zero, then it 
14180 69 73 20 74 68 65 20 6c 6f 67 20 66 72 61 6d 65  is the log frame
14190 20 6e 75 6d 62 65 72 20 74 68 61 74 20 63 6f 6e   number that con
141a0 74 61 69 6e 73 20 74 68 65 0a 20 20 2a 2a 20 72  tains the.  ** r
141b0 65 71 75 69 72 65 64 20 70 61 67 65 2e 20 52 65  equired page. Re
141c0 61 64 20 61 6e 64 20 72 65 74 75 72 6e 20 64 61  ad and return da
141d0 74 61 20 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20  ta from the log 
141e0 66 69 6c 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  file..  */.  if(
141f0 20 69 52 65 61 64 20 29 7b 0a 20 20 20 20 69 36   iRead ){.    i6
14200 34 20 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46  4 iOffset = walF
14210 72 61 6d 65 4f 66 66 73 65 74 28 69 52 65 61 64  rameOffset(iRead
14220 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61  , pWal->hdr.szPa
14230 67 65 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  ge) + WAL_FRAME_
14240 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 2a 70 49  HDRSIZE;.    *pI
14250 6e 57 61 6c 20 3d 20 31 3b 0a 20 20 20 20 2f 2a  nWal = 1;.    /*
14260 20 74 65 73 74 63 61 73 65 28 20 49 53 5f 42 49   testcase( IS_BI
14270 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20 29  G_INT(iOffset) )
14280 3b 20 2f 2f 20 72 65 71 75 69 72 65 73 20 61 20  ; // requires a 
14290 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20 20 20 20  4GiB WAL */.    
142a0 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73  return sqlite3Os
142b0 52 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46  Read(pWal->pWalF
142c0 64 2c 20 70 4f 75 74 2c 20 6e 4f 75 74 2c 20 69  d, pOut, nOut, i
142d0 4f 66 66 73 65 74 29 3b 0a 20 20 7d 0a 0a 20 20  Offset);.  }..  
142e0 2a 70 49 6e 57 61 6c 20 3d 20 30 3b 0a 20 20 72  *pInWal = 0;.  r
142f0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
14300 0a 7d 0a 0a 0a 2f 2a 20 0a 2a 2a 20 53 65 74 20  .}.../* .** Set 
14310 2a 70 50 67 6e 6f 20 74 6f 20 74 68 65 20 73 69  *pPgno to the si
14320 7a 65 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  ze of the databa
14330 73 65 20 66 69 6c 65 20 28 6f 72 20 7a 65 72 6f  se file (or zero
14340 2c 20 69 66 20 75 6e 6b 6e 6f 77 6e 29 2e 0a 2a  , if unknown)..*
14350 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61  /.void sqlite3Wa
14360 6c 44 62 73 69 7a 65 28 57 61 6c 20 2a 70 57 61  lDbsize(Wal *pWa
14370 6c 2c 20 50 67 6e 6f 20 2a 70 50 67 6e 6f 29 7b  l, Pgno *pPgno){
14380 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
14390 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20  >readLock>=0 || 
143a0 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20  pWal->lockError 
143b0 29 3b 0a 20 20 2a 70 50 67 6e 6f 20 3d 20 70 57  );.  *pPgno = pW
143c0 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 3b 0a 7d  al->hdr.nPage;.}
143d0 0a 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 66  .../* .** This f
143e0 75 6e 63 74 69 6f 6e 20 73 74 61 72 74 73 20 61  unction starts a
143f0 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69   write transacti
14400 6f 6e 20 6f 6e 20 74 68 65 20 57 41 4c 2e 0a 2a  on on the WAL..*
14410 2a 0a 2a 2a 20 41 20 72 65 61 64 20 74 72 61 6e  *.** A read tran
14420 73 61 63 74 69 6f 6e 20 6d 75 73 74 20 68 61 76  saction must hav
14430 65 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 73  e already been s
14440 74 61 72 74 65 64 20 62 79 20 61 20 70 72 69 6f  tarted by a prio
14450 72 20 63 61 6c 6c 0a 2a 2a 20 74 6f 20 73 71 6c  r call.** to sql
14460 69 74 65 33 57 61 6c 42 65 67 69 6e 52 65 61 64  ite3WalBeginRead
14470 54 72 61 6e 73 61 63 74 69 6f 6e 28 29 2e 0a 2a  Transaction()..*
14480 2a 0a 2a 2a 20 49 66 20 61 6e 6f 74 68 65 72 20  *.** If another 
14490 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73  thread or proces
144a0 73 20 68 61 73 20 77 72 69 74 74 65 6e 20 69 6e  s has written in
144b0 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20  to the database 
144c0 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 72 65 61  since.** the rea
144d0 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61  d transaction wa
144e0 73 20 73 74 61 72 74 65 64 2c 20 74 68 65 6e 20  s started, then 
144f0 69 74 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62  it is not possib
14500 6c 65 20 66 6f 72 20 74 68 69 73 0a 2a 2a 20 74  le for this.** t
14510 68 72 65 61 64 20 74 6f 20 77 72 69 74 65 20 61  hread to write a
14520 73 20 64 6f 69 6e 67 20 73 6f 20 77 6f 75 6c 64  s doing so would
14530 20 63 61 75 73 65 20 61 20 66 6f 72 6b 2e 20 20   cause a fork.  
14540 53 6f 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a  So this routine.
14550 2a 2a 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  ** returns SQLIT
14560 45 5f 42 55 53 59 20 69 6e 20 74 68 61 74 20 63  E_BUSY in that c
14570 61 73 65 20 61 6e 64 20 6e 6f 20 77 72 69 74 65  ase and no write
14580 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20   transaction is 
14590 73 74 61 72 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 54  started..**.** T
145a0 68 65 72 65 20 63 61 6e 20 6f 6e 6c 79 20 62 65  here can only be
145b0 20 61 20 73 69 6e 67 6c 65 20 77 72 69 74 65 72   a single writer
145c0 20 61 63 74 69 76 65 20 61 74 20 61 20 74 69 6d   active at a tim
145d0 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
145e0 33 57 61 6c 42 65 67 69 6e 57 72 69 74 65 54 72  3WalBeginWriteTr
145f0 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70  ansaction(Wal *p
14600 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  Wal){.  int rc;.
14610 0a 20 20 2f 2a 20 43 61 6e 6e 6f 74 20 73 74 61  .  /* Cannot sta
14620 72 74 20 61 20 77 72 69 74 65 20 74 72 61 6e 73  rt a write trans
14630 61 63 74 69 6f 6e 20 77 69 74 68 6f 75 74 20 66  action without f
14640 69 72 73 74 20 68 6f 6c 64 69 6e 67 20 61 20 72  irst holding a r
14650 65 61 64 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63  ead.  ** transac
14660 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72  tion. */.  asser
14670 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  t( pWal->readLoc
14680 6b 3e 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 4f 6e  k>=0 );..  /* On
14690 6c 79 20 6f 6e 65 20 77 72 69 74 65 72 20 61 6c  ly one writer al
146a0 6c 6f 77 65 64 20 61 74 20 61 20 74 69 6d 65 2e  lowed at a time.
146b0 20 20 47 65 74 20 74 68 65 20 77 72 69 74 65 20    Get the write 
146c0 6c 6f 63 6b 2e 20 20 52 65 74 75 72 6e 0a 20 20  lock.  Return.  
146d0 2a 2a 20 53 51 4c 49 54 45 5f 42 55 53 59 20 69  ** SQLITE_BUSY i
146e0 66 20 75 6e 61 62 6c 65 2e 0a 20 20 2a 2f 0a 20  f unable..  */. 
146f0 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63   rc = walLockExc
14700 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
14710 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b  _WRITE_LOCK, 1);
14720 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20  .  if( rc ){.   
14730 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
14740 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63    pWal->writeLoc
14750 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 49 66 20  k = 1;..  /* If 
14760 61 6e 6f 74 68 65 72 20 63 6f 6e 6e 65 63 74 69  another connecti
14770 6f 6e 20 68 61 73 20 77 72 69 74 74 65 6e 20 74  on has written t
14780 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  o the database f
14790 69 6c 65 20 73 69 6e 63 65 20 74 68 65 0a 20 20  ile since the.  
147a0 2a 2a 20 74 69 6d 65 20 74 68 65 20 72 65 61 64  ** time the read
147b0 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20   transaction on 
147c0 74 68 69 73 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  this connection 
147d0 77 61 73 20 73 74 61 72 74 65 64 2c 20 74 68 65  was started, the
147e0 6e 0a 20 20 2a 2a 20 74 68 65 20 77 72 69 74 65  n.  ** the write
147f0 20 69 73 20 64 69 73 61 6c 6c 6f 77 65 64 2e 0a   is disallowed..
14800 20 20 2a 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d    */.  if( memcm
14810 70 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76  p(&pWal->hdr, (v
14820 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64  oid *)walIndexHd
14830 72 28 70 57 61 6c 29 2c 20 73 69 7a 65 6f 66 28  r(pWal), sizeof(
14840 57 61 6c 49 6e 64 65 78 48 64 72 29 29 21 3d 30  WalIndexHdr))!=0
14850 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63   ){.    walUnloc
14860 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
14870 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c   WAL_WRITE_LOCK,
14880 20 31 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77   1);.    pWal->w
14890 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20  riteLock = 0;.  
148a0 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55    rc = SQLITE_BU
148b0 53 59 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  SY;.  }..  retur
148c0 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45  n rc;.}../*.** E
148d0 6e 64 20 61 20 77 72 69 74 65 20 74 72 61 6e 73  nd a write trans
148e0 61 63 74 69 6f 6e 2e 20 20 54 68 65 20 63 6f 6d  action.  The com
148f0 6d 69 74 20 68 61 73 20 61 6c 72 65 61 64 79 20  mit has already 
14900 62 65 65 6e 20 64 6f 6e 65 2e 20 20 54 68 69 73  been done.  This
14910 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 6d 65 72 65  .** routine mere
14920 6c 79 20 72 65 6c 65 61 73 65 73 20 74 68 65 20  ly releases the 
14930 6c 6f 63 6b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  lock..*/.int sql
14940 69 74 65 33 57 61 6c 45 6e 64 57 72 69 74 65 54  ite3WalEndWriteT
14950 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a  ransaction(Wal *
14960 70 57 61 6c 29 7b 0a 20 20 69 66 28 20 70 57 61  pWal){.  if( pWa
14970 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 7b 0a  l->writeLock ){.
14980 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63      walUnlockExc
14990 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
149a0 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b  _WRITE_LOCK, 1);
149b0 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65  .    pWal->write
149c0 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 7d 0a 20 20  Lock = 0;.  }.  
149d0 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
149e0 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 61 6e  ;.}../*.** If an
149f0 79 20 64 61 74 61 20 68 61 73 20 62 65 65 6e 20  y data has been 
14a00 77 72 69 74 74 65 6e 20 28 62 75 74 20 6e 6f 74  written (but not
14a10 20 63 6f 6d 6d 69 74 74 65 64 29 20 74 6f 20 74   committed) to t
14a20 68 65 20 6c 6f 67 20 66 69 6c 65 2c 20 74 68 69  he log file, thi
14a30 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 6d 6f  s.** function mo
14a40 76 65 73 20 74 68 65 20 77 72 69 74 65 2d 70 6f  ves the write-po
14a50 69 6e 74 65 72 20 62 61 63 6b 20 74 6f 20 74 68  inter back to th
14a60 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 74  e start of the t
14a70 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a  ransaction..**.*
14a80 2a 20 41 64 64 69 74 69 6f 6e 61 6c 6c 79 2c 20  * Additionally, 
14a90 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 66 75 6e  the callback fun
14aa0 63 74 69 6f 6e 20 69 73 20 69 6e 76 6f 6b 65 64  ction is invoked
14ab0 20 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65 20   for each frame 
14ac0 77 72 69 74 74 65 6e 0a 2a 2a 20 74 6f 20 74 68  written.** to th
14ad0 65 20 57 41 4c 20 73 69 6e 63 65 20 74 68 65 20  e WAL since the 
14ae0 73 74 61 72 74 20 6f 66 20 74 68 65 20 74 72 61  start of the tra
14af0 6e 73 61 63 74 69 6f 6e 2e 20 49 66 20 74 68 65  nsaction. If the
14b00 20 63 61 6c 6c 62 61 63 6b 20 72 65 74 75 72 6e   callback return
14b10 73 0a 2a 2a 20 6f 74 68 65 72 20 74 68 61 6e 20  s.** other than 
14b20 53 51 4c 49 54 45 5f 4f 4b 2c 20 69 74 20 69 73  SQLITE_OK, it is
14b30 20 6e 6f 74 20 69 6e 76 6f 6b 65 64 20 61 67 61   not invoked aga
14b40 69 6e 20 61 6e 64 20 74 68 65 20 65 72 72 6f 72  in and the error
14b50 20 63 6f 64 65 20 69 73 0a 2a 2a 20 72 65 74 75   code is.** retu
14b60 72 6e 65 64 20 74 6f 20 74 68 65 20 63 61 6c 6c  rned to the call
14b70 65 72 2e 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77  er..**.** Otherw
14b80 69 73 65 2c 20 69 66 20 74 68 65 20 63 61 6c 6c  ise, if the call
14b90 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20 64 6f  back function do
14ba0 65 73 20 6e 6f 74 20 72 65 74 75 72 6e 20 61 6e  es not return an
14bb0 20 65 72 72 6f 72 2c 20 74 68 69 73 0a 2a 2a 20   error, this.** 
14bc0 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73  function returns
14bd0 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69   SQLITE_OK..*/.i
14be0 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 55 6e 64  nt sqlite3WalUnd
14bf0 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  o(Wal *pWal, int
14c00 20 28 2a 78 55 6e 64 6f 29 28 76 6f 69 64 20 2a   (*xUndo)(void *
14c10 2c 20 50 67 6e 6f 29 2c 20 76 6f 69 64 20 2a 70  , Pgno), void *p
14c20 55 6e 64 6f 43 74 78 29 7b 0a 20 20 69 6e 74 20  UndoCtx){.  int 
14c30 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
14c40 20 20 69 66 28 20 70 57 61 6c 2d 3e 77 72 69 74    if( pWal->writ
14c50 65 4c 6f 63 6b 20 29 7b 0a 20 20 20 20 50 67 6e  eLock ){.    Pgn
14c60 6f 20 69 4d 61 78 20 3d 20 70 57 61 6c 2d 3e 68  o iMax = pWal->h
14c70 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20  dr.mxFrame;.    
14c80 50 67 6e 6f 20 69 46 72 61 6d 65 3b 0a 20 20 0a  Pgno iFrame;.  .
14c90 20 20 20 20 2f 2a 20 52 65 73 74 6f 72 65 20 74      /* Restore t
14ca0 68 65 20 63 6c 69 65 6e 74 73 20 63 61 63 68 65  he clients cache
14cb0 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
14cc0 78 20 68 65 61 64 65 72 20 74 6f 20 74 68 65 20  x header to the 
14cd0 73 74 61 74 65 20 69 74 0a 20 20 20 20 2a 2a 20  state it.    ** 
14ce0 77 61 73 20 69 6e 20 62 65 66 6f 72 65 20 74 68  was in before th
14cf0 65 20 63 6c 69 65 6e 74 20 62 65 67 61 6e 20 77  e client began w
14d00 72 69 74 69 6e 67 20 74 6f 20 74 68 65 20 64 61  riting to the da
14d10 74 61 62 61 73 65 2e 20 0a 20 20 20 20 2a 2f 0a  tabase. .    */.
14d20 20 20 20 20 6d 65 6d 63 70 79 28 26 70 57 61 6c      memcpy(&pWal
14d30 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20 2a 29 77  ->hdr, (void *)w
14d40 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29  alIndexHdr(pWal)
14d50 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65  , sizeof(WalInde
14d60 78 48 64 72 29 29 3b 0a 0a 20 20 20 20 66 6f 72  xHdr));..    for
14d70 28 69 46 72 61 6d 65 3d 70 57 61 6c 2d 3e 68 64  (iFrame=pWal->hd
14d80 72 2e 6d 78 46 72 61 6d 65 2b 31 3b 20 0a 20 20  r.mxFrame+1; .  
14d90 20 20 20 20 20 20 41 4c 57 41 59 53 28 72 63 3d        ALWAYS(rc=
14da0 3d 53 51 4c 49 54 45 5f 4f 4b 29 20 26 26 20 69  =SQLITE_OK) && i
14db0 46 72 61 6d 65 3c 3d 69 4d 61 78 3b 20 0a 20 20  Frame<=iMax; .  
14dc0 20 20 20 20 20 20 69 46 72 61 6d 65 2b 2b 0a 20        iFrame++. 
14dd0 20 20 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54     ){.      /* T
14de0 68 69 73 20 63 61 6c 6c 20 63 61 6e 6e 6f 74 20  his call cannot 
14df0 66 61 69 6c 2e 20 55 6e 6c 65 73 73 20 74 68 65  fail. Unless the
14e00 20 70 61 67 65 20 66 6f 72 20 77 68 69 63 68 20   page for which 
14e10 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 0a  the page number.
14e20 20 20 20 20 20 20 2a 2a 20 69 73 20 70 61 73 73        ** is pass
14e30 65 64 20 61 73 20 74 68 65 20 73 65 63 6f 6e 64  ed as the second
14e40 20 61 72 67 75 6d 65 6e 74 20 69 73 20 28 61 29   argument is (a)
14e50 20 69 6e 20 74 68 65 20 63 61 63 68 65 20 61 6e   in the cache an
14e60 64 20 0a 20 20 20 20 20 20 2a 2a 20 28 62 29 20  d .      ** (b) 
14e70 68 61 73 20 61 6e 20 6f 75 74 73 74 61 6e 64 69  has an outstandi
14e80 6e 67 20 72 65 66 65 72 65 6e 63 65 2c 20 74 68  ng reference, th
14e90 65 6e 20 78 55 6e 64 6f 20 69 73 20 65 69 74 68  en xUndo is eith
14ea0 65 72 20 61 20 6e 6f 2d 6f 70 0a 20 20 20 20 20  er a no-op.     
14eb0 20 2a 2a 20 28 69 66 20 28 61 29 20 69 73 20 66   ** (if (a) is f
14ec0 61 6c 73 65 29 20 6f 72 20 73 69 6d 70 6c 79 20  alse) or simply 
14ed0 65 78 70 65 6c 73 20 74 68 65 20 70 61 67 65 20  expels the page 
14ee0 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65 20 28  from the cache (
14ef0 69 66 20 28 62 29 0a 20 20 20 20 20 20 2a 2a 20  if (b).      ** 
14f00 69 73 20 66 61 6c 73 65 29 2e 0a 20 20 20 20 20  is false)..     
14f10 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 49 66 20   **.      ** If 
14f20 74 68 65 20 75 70 70 65 72 20 6c 61 79 65 72 20  the upper layer 
14f30 69 73 20 64 6f 69 6e 67 20 61 20 72 6f 6c 6c 62  is doing a rollb
14f40 61 63 6b 2c 20 69 74 20 69 73 20 67 75 61 72 61  ack, it is guara
14f50 6e 74 65 65 64 20 74 68 61 74 20 74 68 65 72 65  nteed that there
14f60 0a 20 20 20 20 20 20 2a 2a 20 61 72 65 20 6e 6f  .      ** are no
14f70 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 72 65 66   outstanding ref
14f80 65 72 65 6e 63 65 73 20 74 6f 20 61 6e 79 20 70  erences to any p
14f90 61 67 65 20 6f 74 68 65 72 20 74 68 61 6e 20 70  age other than p
14fa0 61 67 65 20 31 2e 20 41 6e 64 0a 20 20 20 20 20  age 1. And.     
14fb0 20 2a 2a 20 70 61 67 65 20 31 20 69 73 20 6e 65   ** page 1 is ne
14fc0 76 65 72 20 77 72 69 74 74 65 6e 20 74 6f 20 74  ver written to t
14fd0 68 65 20 6c 6f 67 20 75 6e 74 69 6c 20 74 68 65  he log until the
14fe0 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 0a   transaction is.
14ff0 20 20 20 20 20 20 2a 2a 20 63 6f 6d 6d 69 74 74        ** committ
15000 65 64 2e 20 41 73 20 61 20 72 65 73 75 6c 74 2c  ed. As a result,
15010 20 74 68 65 20 63 61 6c 6c 20 74 6f 20 78 55 6e   the call to xUn
15020 64 6f 20 6d 61 79 20 6e 6f 74 20 66 61 69 6c 2e  do may not fail.
15030 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20  .      */.      
15040 61 73 73 65 72 74 28 20 77 61 6c 46 72 61 6d 65  assert( walFrame
15050 50 67 6e 6f 28 70 57 61 6c 2c 20 69 46 72 61 6d  Pgno(pWal, iFram
15060 65 29 21 3d 31 20 29 3b 0a 20 20 20 20 20 20 72  e)!=1 );.      r
15070 63 20 3d 20 78 55 6e 64 6f 28 70 55 6e 64 6f 43  c = xUndo(pUndoC
15080 74 78 2c 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f  tx, walFramePgno
15090 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 29 3b  (pWal, iFrame));
150a0 0a 20 20 20 20 7d 0a 20 20 20 20 77 61 6c 43 6c  .    }.    walCl
150b0 65 61 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b  eanupHash(pWal);
150c0 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20 72  .  }.  assert( r
150d0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c==SQLITE_OK );.
150e0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
150f0 2f 2a 20 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20  /* .** Argument 
15100 61 57 61 6c 44 61 74 61 20 6d 75 73 74 20 70 6f  aWalData must po
15110 69 6e 74 20 74 6f 20 61 6e 20 61 72 72 61 79 20  int to an array 
15120 6f 66 20 57 41 4c 5f 53 41 56 45 50 4f 49 4e 54  of WAL_SAVEPOINT
15130 5f 4e 44 41 54 41 20 75 33 32 20 0a 2a 2a 20 76  _NDATA u32 .** v
15140 61 6c 75 65 73 2e 20 54 68 69 73 20 66 75 6e 63  alues. This func
15150 74 69 6f 6e 20 70 6f 70 75 6c 61 74 65 73 20 74  tion populates t
15160 68 65 20 61 72 72 61 79 20 77 69 74 68 20 76 61  he array with va
15170 6c 75 65 73 20 72 65 71 75 69 72 65 64 20 74 6f  lues required to
15180 20 0a 2a 2a 20 22 72 6f 6c 6c 62 61 63 6b 22 20   .** "rollback" 
15190 74 68 65 20 77 72 69 74 65 20 70 6f 73 69 74 69  the write positi
151a0 6f 6e 20 6f 66 20 74 68 65 20 57 41 4c 20 68 61  on of the WAL ha
151b0 6e 64 6c 65 20 62 61 63 6b 20 74 6f 20 74 68 65  ndle back to the
151c0 20 63 75 72 72 65 6e 74 20 0a 2a 2a 20 70 6f 69   current .** poi
151d0 6e 74 20 69 6e 20 74 68 65 20 65 76 65 6e 74 20  nt in the event 
151e0 6f 66 20 61 20 73 61 76 65 70 6f 69 6e 74 20 72  of a savepoint r
151f0 6f 6c 6c 62 61 63 6b 20 28 76 69 61 20 57 61 6c  ollback (via Wal
15200 53 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28 29 29  SavepointUndo())
15210 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65  ..*/.void sqlite
15220 33 57 61 6c 53 61 76 65 70 6f 69 6e 74 28 57 61  3WalSavepoint(Wa
15230 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a 61 57  l *pWal, u32 *aW
15240 61 6c 44 61 74 61 29 7b 0a 20 20 61 73 73 65 72  alData){.  asser
15250 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  t( pWal->writeLo
15260 63 6b 20 29 3b 0a 20 20 61 57 61 6c 44 61 74 61  ck );.  aWalData
15270 5b 30 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  [0] = pWal->hdr.
15280 6d 78 46 72 61 6d 65 3b 0a 20 20 61 57 61 6c 44  mxFrame;.  aWalD
15290 61 74 61 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68  ata[1] = pWal->h
152a0 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30  dr.aFrameCksum[0
152b0 5d 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 32 5d  ];.  aWalData[2]
152c0 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72   = pWal->hdr.aFr
152d0 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 61  ameCksum[1];.  a
152e0 57 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70 57 61  WalData[3] = pWa
152f0 6c 2d 3e 6e 43 6b 70 74 3b 0a 7d 0a 0a 2f 2a 20  l->nCkpt;.}../* 
15300 0a 2a 2a 20 4d 6f 76 65 20 74 68 65 20 77 72 69  .** Move the wri
15310 74 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66 20 74  te position of t
15320 68 65 20 57 41 4c 20 62 61 63 6b 20 74 6f 20 74  he WAL back to t
15330 68 65 20 70 6f 69 6e 74 20 69 64 65 6e 74 69 66  he point identif
15340 69 65 64 20 62 79 0a 2a 2a 20 74 68 65 20 76 61  ied by.** the va
15350 6c 75 65 73 20 69 6e 20 74 68 65 20 61 57 61 6c  lues in the aWal
15360 44 61 74 61 5b 5d 20 61 72 72 61 79 2e 20 61 57  Data[] array. aW
15370 61 6c 44 61 74 61 20 6d 75 73 74 20 70 6f 69 6e  alData must poin
15380 74 20 74 6f 20 61 6e 20 61 72 72 61 79 0a 2a 2a  t to an array.**
15390 20 6f 66 20 57 41 4c 5f 53 41 56 45 50 4f 49 4e   of WAL_SAVEPOIN
153a0 54 5f 4e 44 41 54 41 20 75 33 32 20 76 61 6c 75  T_NDATA u32 valu
153b0 65 73 20 74 68 61 74 20 68 61 73 20 62 65 65 6e  es that has been
153c0 20 70 72 65 76 69 6f 75 73 6c 79 20 70 6f 70 75   previously popu
153d0 6c 61 74 65 64 0a 2a 2a 20 62 79 20 61 20 63 61  lated.** by a ca
153e0 6c 6c 20 74 6f 20 57 61 6c 53 61 76 65 70 6f 69  ll to WalSavepoi
153f0 6e 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  nt()..*/.int sql
15400 69 74 65 33 57 61 6c 53 61 76 65 70 6f 69 6e 74  ite3WalSavepoint
15410 55 6e 64 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Undo(Wal *pWal, 
15420 75 33 32 20 2a 61 57 61 6c 44 61 74 61 29 7b 0a  u32 *aWalData){.
15430 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
15440 45 5f 4f 4b 3b 0a 0a 20 20 61 73 73 65 72 74 28  E_OK;..  assert(
15450 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
15460 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 61 57   );.  assert( aW
15470 61 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d  alData[3]!=pWal-
15480 3e 6e 43 6b 70 74 20 7c 7c 20 61 57 61 6c 44 61  >nCkpt || aWalDa
15490 74 61 5b 30 5d 3c 3d 70 57 61 6c 2d 3e 68 64 72  ta[0]<=pWal->hdr
154a0 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 0a 20 20 69  .mxFrame );..  i
154b0 66 28 20 61 57 61 6c 44 61 74 61 5b 33 5d 21 3d  f( aWalData[3]!=
154c0 70 57 61 6c 2d 3e 6e 43 6b 70 74 20 29 7b 0a 20  pWal->nCkpt ){. 
154d0 20 20 20 2f 2a 20 54 68 69 73 20 73 61 76 65 70     /* This savep
154e0 6f 69 6e 74 20 77 61 73 20 6f 70 65 6e 65 64 20  oint was opened 
154f0 69 6d 6d 65 64 69 61 74 65 6c 79 20 61 66 74 65  immediately afte
15500 72 20 74 68 65 20 77 72 69 74 65 2d 74 72 61 6e  r the write-tran
15510 73 61 63 74 69 6f 6e 0a 20 20 20 20 2a 2a 20 77  saction.    ** w
15520 61 73 20 73 74 61 72 74 65 64 2e 20 52 69 67 68  as started. Righ
15530 74 20 61 66 74 65 72 20 74 68 61 74 2c 20 74 68  t after that, th
15540 65 20 77 72 69 74 65 72 20 64 65 63 69 64 65 64  e writer decided
15550 20 74 6f 20 77 72 61 70 20 61 72 6f 75 6e 64 0a   to wrap around.
15560 20 20 20 20 2a 2a 20 74 6f 20 74 68 65 20 73 74      ** to the st
15570 61 72 74 20 6f 66 20 74 68 65 20 6c 6f 67 2e 20  art of the log. 
15580 55 70 64 61 74 65 20 74 68 65 20 73 61 76 65 70  Update the savep
15590 6f 69 6e 74 20 76 61 6c 75 65 73 20 74 6f 20 6d  oint values to m
155a0 61 74 63 68 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  atch..    */.   
155b0 20 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d 20 30   aWalData[0] = 0
155c0 3b 0a 20 20 20 20 61 57 61 6c 44 61 74 61 5b 33  ;.    aWalData[3
155d0 5d 20 3d 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 3b  ] = pWal->nCkpt;
155e0 0a 20 20 7d 0a 0a 20 20 69 66 28 20 61 57 61 6c  .  }..  if( aWal
155f0 44 61 74 61 5b 30 5d 3c 70 57 61 6c 2d 3e 68 64  Data[0]<pWal->hd
15600 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20  r.mxFrame ){.   
15610 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
15620 6d 65 20 3d 20 61 57 61 6c 44 61 74 61 5b 30 5d  me = aWalData[0]
15630 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  ;.    pWal->hdr.
15640 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d  aFrameCksum[0] =
15650 20 61 57 61 6c 44 61 74 61 5b 31 5d 3b 0a 20 20   aWalData[1];.  
15660 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61    pWal->hdr.aFra
15670 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 61 57 61  meCksum[1] = aWa
15680 6c 44 61 74 61 5b 32 5d 3b 0a 20 20 20 20 77 61  lData[2];.    wa
15690 6c 43 6c 65 61 6e 75 70 48 61 73 68 28 70 57 61  lCleanupHash(pWa
156a0 6c 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  l);.  }..  retur
156b0 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  n rc;.}../*.** T
156c0 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
156d0 63 61 6c 6c 65 64 20 6a 75 73 74 20 62 65 66 6f  called just befo
156e0 72 65 20 77 72 69 74 69 6e 67 20 61 20 73 65 74  re writing a set
156f0 20 6f 66 20 66 72 61 6d 65 73 20 74 6f 20 74 68   of frames to th
15700 65 20 6c 6f 67 0a 2a 2a 20 66 69 6c 65 20 28 73  e log.** file (s
15710 65 65 20 73 71 6c 69 74 65 33 57 61 6c 46 72 61  ee sqlite3WalFra
15720 6d 65 73 28 29 29 2e 20 49 74 20 63 68 65 63 6b  mes()). It check
15730 73 20 74 6f 20 73 65 65 20 69 66 2c 20 69 6e 73  s to see if, ins
15740 74 65 61 64 20 6f 66 20 61 70 70 65 6e 64 69 6e  tead of appendin
15750 67 0a 2a 2a 20 74 6f 20 74 68 65 20 63 75 72 72  g.** to the curr
15760 65 6e 74 20 6c 6f 67 20 66 69 6c 65 2c 20 69 74  ent log file, it
15770 20 69 73 20 70 6f 73 73 69 62 6c 65 20 74 6f 20   is possible to 
15780 6f 76 65 72 77 72 69 74 65 20 74 68 65 20 73 74  overwrite the st
15790 61 72 74 20 6f 66 20 74 68 65 0a 2a 2a 20 65 78  art of the.** ex
157a0 69 73 74 69 6e 67 20 6c 6f 67 20 66 69 6c 65 20  isting log file 
157b0 77 69 74 68 20 74 68 65 20 6e 65 77 20 66 72 61  with the new fra
157c0 6d 65 73 20 28 69 2e 65 2e 20 22 72 65 73 65 74  mes (i.e. "reset
157d0 22 20 74 68 65 20 6c 6f 67 29 2e 20 49 66 20 73  " the log). If s
157e0 6f 2c 0a 2a 2a 20 69 74 20 73 65 74 73 20 70 57  o,.** it sets pW
157f0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
15800 74 6f 20 30 2e 20 4f 74 68 65 72 77 69 73 65 2c  to 0. Otherwise,
15810 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
15820 6d 65 20 69 73 20 6c 65 66 74 0a 2a 2a 20 75 6e  me is left.** un
15830 63 68 61 6e 67 65 64 2e 0a 2a 2a 0a 2a 2a 20 53  changed..**.** S
15840 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
15850 72 6e 65 64 20 69 66 20 6e 6f 20 65 72 72 6f 72  rned if no error
15860 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65 64 20   is encountered 
15870 28 72 65 67 61 72 64 6c 65 73 73 20 6f 66 20 77  (regardless of w
15880 68 65 74 68 65 72 0a 2a 2a 20 6f 72 20 6e 6f 74  hether.** or not
15890 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
158a0 6d 65 20 69 73 20 6d 6f 64 69 66 69 65 64 29 2e  me is modified).
158b0 20 41 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   An SQLite error
158c0 20 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65   code is returne
158d0 64 0a 2a 2a 20 69 66 20 73 6f 6d 65 20 65 72 72  d.** if some err
158e0 6f 72 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  or .*/.static in
158f0 74 20 77 61 6c 52 65 73 74 61 72 74 4c 6f 67 28  t walRestartLog(
15900 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e  Wal *pWal){.  in
15910 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
15920 3b 0a 20 20 69 6e 74 20 63 6e 74 3b 0a 0a 20 20  ;.  int cnt;..  
15930 69 66 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  if( pWal->readLo
15940 63 6b 3d 3d 30 20 29 7b 0a 20 20 20 20 76 6f 6c  ck==0 ){.    vol
15950 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66  atile WalCkptInf
15960 6f 20 2a 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b  o *pInfo = walCk
15970 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20  ptInfo(pWal);.  
15980 20 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d    assert( pInfo-
15990 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70 57 61 6c  >nBackfill==pWal
159a0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b  ->hdr.mxFrame );
159b0 0a 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e  .    if( pInfo->
159c0 6e 42 61 63 6b 66 69 6c 6c 3e 30 20 29 7b 0a 20  nBackfill>0 ){. 
159d0 20 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63       rc = walLoc
159e0 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
159f0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31   WAL_READ_LOCK(1
15a00 29 2c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31  ), WAL_NREADER-1
15a10 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d  );.      if( rc=
15a20 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
15a30 20 20 20 20 20 20 2f 2a 20 49 66 20 61 6c 6c 20        /* If all 
15a40 72 65 61 64 65 72 73 20 61 72 65 20 75 73 69 6e  readers are usin
15a50 67 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  g WAL_READ_LOCK(
15a60 30 29 20 28 69 6e 20 6f 74 68 65 72 20 77 6f 72  0) (in other wor
15a70 64 73 20 69 66 20 6e 6f 0a 20 20 20 20 20 20 20  ds if no.       
15a80 20 2a 2a 20 72 65 61 64 65 72 73 20 61 72 65 20   ** readers are 
15a90 63 75 72 72 65 6e 74 6c 79 20 75 73 69 6e 67 20  currently using 
15aa0 74 68 65 20 57 41 4c 29 2c 20 74 68 65 6e 20 74  the WAL), then t
15ab0 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 0a  he transactions.
15ac0 20 20 20 20 20 20 20 20 2a 2a 20 66 72 61 6d 65          ** frame
15ad0 73 20 77 69 6c 6c 20 6f 76 65 72 77 72 69 74 65  s will overwrite
15ae0 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
15af0 65 20 65 78 69 73 74 69 6e 67 20 6c 6f 67 2e 20  e existing log. 
15b00 55 70 64 61 74 65 20 74 68 65 0a 20 20 20 20 20  Update the.     
15b10 20 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20     ** wal-index 
15b20 68 65 61 64 65 72 20 74 6f 20 72 65 66 6c 65 63  header to reflec
15b30 74 20 74 68 69 73 2e 0a 20 20 20 20 20 20 20 20  t this..        
15b40 2a 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 49 6e  **.        ** In
15b50 20 74 68 65 6f 72 79 20 69 74 20 77 6f 75 6c 64   theory it would
15b60 20 62 65 20 4f 6b 20 74 6f 20 75 70 64 61 74 65   be Ok to update
15b70 20 74 68 65 20 63 61 63 68 65 20 6f 66 20 74 68   the cache of th
15b80 65 20 68 65 61 64 65 72 20 6f 6e 6c 79 0a 20 20  e header only.  
15b90 20 20 20 20 20 20 2a 2a 20 61 74 20 74 68 69 73        ** at this
15ba0 20 70 6f 69 6e 74 2e 20 42 75 74 20 75 70 64 61   point. But upda
15bb0 74 69 6e 67 20 74 68 65 20 61 63 74 75 61 6c 20  ting the actual 
15bc0 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
15bd0 20 69 73 20 61 6c 73 6f 0a 20 20 20 20 20 20 20   is also.       
15be0 20 2a 2a 20 73 61 66 65 20 61 6e 64 20 6d 65 61   ** safe and mea
15bf0 6e 73 20 74 68 65 72 65 20 69 73 20 6e 6f 20 73  ns there is no s
15c00 70 65 63 69 61 6c 20 63 61 73 65 20 66 6f 72 20  pecial case for 
15c10 73 71 6c 69 74 65 33 57 61 6c 55 6e 64 6f 28 29  sqlite3WalUndo()
15c20 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 6f 20 68  .        ** to h
15c30 61 6e 64 6c 65 20 69 66 20 74 68 69 73 20 74 72  andle if this tr
15c40 61 6e 73 61 63 74 69 6f 6e 20 69 73 20 72 6f 6c  ansaction is rol
15c50 6c 65 64 20 62 61 63 6b 2e 0a 20 20 20 20 20 20  led back..      
15c60 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 6e 74    */.        int
15c70 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
15c80 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63         /* Loop c
15c90 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20 20 20 20  ounter */.      
15ca0 20 20 75 33 32 20 2a 61 53 61 6c 74 20 3d 20 70    u32 *aSalt = p
15cb0 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 3b 20  Wal->hdr.aSalt; 
15cc0 20 20 20 20 20 20 2f 2a 20 42 69 67 2d 65 6e 64        /* Big-end
15cd0 69 61 6e 20 73 61 6c 74 20 76 61 6c 75 65 73 20  ian salt values 
15ce0 2a 2f 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d  */.        pWal-
15cf0 3e 6e 43 6b 70 74 2b 2b 3b 0a 20 20 20 20 20 20  >nCkpt++;.      
15d00 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72    pWal->hdr.mxFr
15d10 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ame = 0;.       
15d20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65   sqlite3Put4byte
15d30 28 28 75 38 2a 29 26 61 53 61 6c 74 5b 30 5d 2c  ((u8*)&aSalt[0],
15d40 20 31 20 2b 20 73 71 6c 69 74 65 33 47 65 74 34   1 + sqlite3Get4
15d50 62 79 74 65 28 28 75 38 2a 29 26 61 53 61 6c 74  byte((u8*)&aSalt
15d60 5b 30 5d 29 29 3b 0a 20 20 20 20 20 20 20 20 73  [0]));.        s
15d70 71 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73  qlite3_randomnes
15d80 73 28 34 2c 20 26 61 53 61 6c 74 5b 31 5d 29 3b  s(4, &aSalt[1]);
15d90 0a 20 20 20 20 20 20 20 20 77 61 6c 49 6e 64 65  .        walInde
15da0 78 57 72 69 74 65 48 64 72 28 70 57 61 6c 29 3b  xWriteHdr(pWal);
15db0 0a 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e  .        pInfo->
15dc0 6e 42 61 63 6b 66 69 6c 6c 20 3d 20 30 3b 0a 20  nBackfill = 0;. 
15dd0 20 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20         for(i=1; 
15de0 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69  i<WAL_NREADER; i
15df0 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64  ++) pInfo->aRead
15e00 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41  Mark[i] = READMA
15e10 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 20  RK_NOT_USED;.   
15e20 20 20 20 20 20 61 73 73 65 72 74 28 20 70 49 6e       assert( pIn
15e30 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d  fo->aReadMark[0]
15e40 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 20 20 77  ==0 );.        w
15e50 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
15e60 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
15e70 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52  _LOCK(1), WAL_NR
15e80 45 41 44 45 52 2d 31 29 3b 0a 20 20 20 20 20 20  EADER-1);.      
15e90 7d 0a 20 20 20 20 7d 0a 20 20 20 20 77 61 6c 55  }.    }.    walU
15ea0 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
15eb0 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
15ec0 30 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 72  0));.    pWal->r
15ed0 65 61 64 4c 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20  eadLock = -1;.  
15ee0 20 20 63 6e 74 20 3d 20 30 3b 0a 20 20 20 20 64    cnt = 0;.    d
15ef0 6f 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 6f 74  o{.      int not
15f00 55 73 65 64 3b 0a 20 20 20 20 20 20 72 63 20 3d  Used;.      rc =
15f10 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64   walTryBeginRead
15f20 28 70 57 61 6c 2c 20 26 6e 6f 74 55 73 65 64 2c  (pWal, &notUsed,
15f30 20 31 2c 20 2b 2b 63 6e 74 29 3b 0a 20 20 20 20   1, ++cnt);.    
15f40 7d 77 68 69 6c 65 28 20 72 63 3d 3d 57 41 4c 5f  }while( rc==WAL_
15f50 52 45 54 52 59 20 29 3b 0a 20 20 7d 0a 20 20 72  RETRY );.  }.  r
15f60 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
15f70 0a 2a 2a 20 57 72 69 74 65 20 61 20 73 65 74 20  .** Write a set 
15f80 6f 66 20 66 72 61 6d 65 73 20 74 6f 20 74 68 65  of frames to the
15f90 20 6c 6f 67 2e 20 54 68 65 20 63 61 6c 6c 65 72   log. The caller
15fa0 20 6d 75 73 74 20 68 6f 6c 64 20 74 68 65 20 77   must hold the w
15fb0 72 69 74 65 2d 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20  rite-lock.** on 
15fc0 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 28 6f 62  the log file (ob
15fd0 74 61 69 6e 65 64 20 75 73 69 6e 67 20 73 71 6c  tained using sql
15fe0 69 74 65 33 57 61 6c 42 65 67 69 6e 57 72 69 74  ite3WalBeginWrit
15ff0 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 29 29 2e  eTransaction()).
16000 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
16010 61 6c 46 72 61 6d 65 73 28 0a 20 20 57 61 6c 20  alFrames(.  Wal 
16020 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20  *pWal,          
16030 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
16040 61 6c 20 68 61 6e 64 6c 65 20 74 6f 20 77 72 69  al handle to wri
16050 74 65 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73  te to */.  int s
16060 7a 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20  zPage,          
16070 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
16080 74 61 62 61 73 65 20 70 61 67 65 2d 73 69 7a 65  tabase page-size
16090 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 50   in bytes */.  P
160a0 67 48 64 72 20 2a 70 4c 69 73 74 2c 20 20 20 20  gHdr *pList,    
160b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
160c0 2a 20 4c 69 73 74 20 6f 66 20 64 69 72 74 79 20  * List of dirty 
160d0 70 61 67 65 73 20 74 6f 20 77 72 69 74 65 20 2a  pages to write *
160e0 2f 0a 20 20 50 67 6e 6f 20 6e 54 72 75 6e 63 61  /.  Pgno nTrunca
160f0 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  te,             
16100 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
16110 73 69 7a 65 20 61 66 74 65 72 20 74 68 69 73 20  size after this 
16120 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20  commit */.  int 
16130 69 73 43 6f 6d 6d 69 74 2c 20 20 20 20 20 20 20  isCommit,       
16140 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
16150 72 75 65 20 69 66 20 74 68 69 73 20 69 73 20 61  rue if this is a
16160 20 63 6f 6d 6d 69 74 20 2a 2f 0a 20 20 69 6e 74   commit */.  int
16170 20 73 79 6e 63 5f 66 6c 61 67 73 20 20 20 20 20   sync_flags     
16180 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
16190 46 6c 61 67 73 20 74 6f 20 70 61 73 73 20 74 6f  Flags to pass to
161a0 20 4f 73 53 79 6e 63 28 29 20 28 6f 72 20 30 29   OsSync() (or 0)
161b0 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b   */.){.  int rc;
161c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
161d0 20 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64           /* Used
161e0 20 74 6f 20 63 61 74 63 68 20 72 65 74 75 72 6e   to catch return
161f0 20 63 6f 64 65 73 20 2a 2f 0a 20 20 75 33 32 20   codes */.  u32 
16200 69 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20  iFrame;         
16210 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
16220 65 78 74 20 66 72 61 6d 65 20 61 64 64 72 65 73  ext frame addres
16230 73 20 2a 2f 0a 20 20 75 38 20 61 46 72 61 6d 65  s */.  u8 aFrame
16240 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49  [WAL_FRAME_HDRSI
16250 5a 45 5d 3b 20 20 20 2f 2a 20 42 75 66 66 65 72  ZE];   /* Buffer
16260 20 74 6f 20 61 73 73 65 6d 62 6c 65 20 66 72 61   to assemble fra
16270 6d 65 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f 0a  me-header in */.
16280 20 20 50 67 48 64 72 20 2a 70 3b 20 20 20 20 20    PgHdr *p;     
16290 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
162a0 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f    /* Iterator to
162b0 20 72 75 6e 20 74 68 72 6f 75 67 68 20 70 4c 69   run through pLi
162c0 73 74 20 77 69 74 68 2e 20 2a 2f 0a 20 20 50 67  st with. */.  Pg
162d0 48 64 72 20 2a 70 4c 61 73 74 20 3d 20 30 3b 20  Hdr *pLast = 0; 
162e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
162f0 20 4c 61 73 74 20 66 72 61 6d 65 20 69 6e 20 6c   Last frame in l
16300 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 61  ist */.  int nLa
16310 73 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  st = 0;         
16320 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
16330 65 72 20 6f 66 20 65 78 74 72 61 20 63 6f 70 69  er of extra copi
16340 65 73 20 6f 66 20 6c 61 73 74 20 70 61 67 65 20  es of last page 
16350 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 4c  */..  assert( pL
16360 69 73 74 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ist );.  assert(
16370 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
16380 20 29 3b 0a 0a 23 69 66 20 64 65 66 69 6e 65 64   );..#if defined
16390 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26 26  (SQLITE_TEST) &&
163a0 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
163b0 44 45 42 55 47 29 0a 20 20 7b 20 69 6e 74 20 63  DEBUG).  { int c
163c0 6e 74 3b 20 66 6f 72 28 63 6e 74 3d 30 2c 20 70  nt; for(cnt=0, p
163d0 3d 70 4c 69 73 74 3b 20 70 3b 20 70 3d 70 2d 3e  =pList; p; p=p->
163e0 70 44 69 72 74 79 2c 20 63 6e 74 2b 2b 29 7b 7d  pDirty, cnt++){}
163f0 0a 20 20 20 20 57 41 4c 54 52 41 43 45 28 28 22  .    WALTRACE(("
16400 57 41 4c 25 70 3a 20 66 72 61 6d 65 20 77 72 69  WAL%p: frame wri
16410 74 65 20 62 65 67 69 6e 2e 20 25 64 20 66 72 61  te begin. %d fra
16420 6d 65 73 2e 20 6d 78 46 72 61 6d 65 3d 25 64 2e  mes. mxFrame=%d.
16430 20 25 73 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20   %s\n",.        
16440 20 20 20 20 20 20 70 57 61 6c 2c 20 63 6e 74 2c        pWal, cnt,
16450 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
16460 6d 65 2c 20 69 73 43 6f 6d 6d 69 74 20 3f 20 22  me, isCommit ? "
16470 43 6f 6d 6d 69 74 22 20 3a 20 22 53 70 69 6c 6c  Commit" : "Spill
16480 22 29 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a  "));.  }.#endif.
16490 0a 20 20 2f 2a 20 53 65 65 20 69 66 20 69 74 20  .  /* See if it 
164a0 69 73 20 70 6f 73 73 69 62 6c 65 20 74 6f 20 77  is possible to w
164b0 72 69 74 65 20 74 68 65 73 65 20 66 72 61 6d 65  rite these frame
164c0 73 20 69 6e 74 6f 20 74 68 65 20 73 74 61 72 74  s into the start
164d0 20 6f 66 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 67   of the.  ** log
164e0 20 66 69 6c 65 2c 20 69 6e 73 74 65 61 64 20 6f   file, instead o
164f0 66 20 61 70 70 65 6e 64 69 6e 67 20 74 6f 20 69  f appending to i
16500 74 20 61 74 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  t at pWal->hdr.m
16510 78 46 72 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69  xFrame..  */.  i
16520 66 28 20 53 51 4c 49 54 45 5f 4f 4b 21 3d 28 72  f( SQLITE_OK!=(r
16530 63 20 3d 20 77 61 6c 52 65 73 74 61 72 74 4c 6f  c = walRestartLo
16540 67 28 70 57 61 6c 29 29 20 29 7b 0a 20 20 20 20  g(pWal)) ){.    
16550 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a  return rc;.  }..
16560 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20    /* If this is 
16570 74 68 65 20 66 69 72 73 74 20 66 72 61 6d 65 20  the first frame 
16580 77 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65  written into the
16590 20 6c 6f 67 2c 20 77 72 69 74 65 20 74 68 65 20   log, write the 
165a0 57 41 4c 0a 20 20 2a 2a 20 68 65 61 64 65 72 20  WAL.  ** header 
165b0 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  to the start of 
165c0 74 68 65 20 57 41 4c 20 66 69 6c 65 2e 20 53 65  the WAL file. Se
165d0 65 20 63 6f 6d 6d 65 6e 74 73 20 61 74 20 74 68  e comments at th
165e0 65 20 74 6f 70 20 6f 66 0a 20 20 2a 2a 20 74 68  e top of.  ** th
165f0 69 73 20 73 6f 75 72 63 65 20 66 69 6c 65 20 66  is source file f
16600 6f 72 20 61 20 64 65 73 63 72 69 70 74 69 6f 6e  or a description
16610 20 6f 66 20 74 68 65 20 57 41 4c 20 68 65 61 64   of the WAL head
16620 65 72 20 66 6f 72 6d 61 74 2e 0a 20 20 2a 2f 0a  er format..  */.
16630 20 20 69 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d    iFrame = pWal-
16640 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20  >hdr.mxFrame;.  
16650 69 66 28 20 69 46 72 61 6d 65 3d 3d 30 20 29 7b  if( iFrame==0 ){
16660 0a 20 20 20 20 75 38 20 61 57 61 6c 48 64 72 5b  .    u8 aWalHdr[
16670 57 41 4c 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20  WAL_HDRSIZE];   
16680 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20     /* Buffer to 
16690 61 73 73 65 6d 62 6c 65 20 77 61 6c 2d 68 65 61  assemble wal-hea
166a0 64 65 72 20 69 6e 20 2a 2f 0a 20 20 20 20 75 33  der in */.    u3
166b0 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20 20  2 aCksum[2];    
166c0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
166d0 68 65 63 6b 73 75 6d 20 66 6f 72 20 77 61 6c 2d  hecksum for wal-
166e0 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20 20 20 73  header */..    s
166f0 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
16700 61 57 61 6c 48 64 72 5b 30 5d 2c 20 28 57 41 4c  aWalHdr[0], (WAL
16710 5f 4d 41 47 49 43 20 7c 20 53 51 4c 49 54 45 5f  _MAGIC | SQLITE_
16720 42 49 47 45 4e 44 49 41 4e 29 29 3b 0a 20 20 20  BIGENDIAN));.   
16730 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65   sqlite3Put4byte
16740 28 26 61 57 61 6c 48 64 72 5b 34 5d 2c 20 57 41  (&aWalHdr[4], WA
16750 4c 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 29 3b 0a  L_MAX_VERSION);.
16760 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62      sqlite3Put4b
16770 79 74 65 28 26 61 57 61 6c 48 64 72 5b 38 5d 2c  yte(&aWalHdr[8],
16780 20 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 73 71   szPage);.    sq
16790 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61  lite3Put4byte(&a
167a0 57 61 6c 48 64 72 5b 31 32 5d 2c 20 70 57 61 6c  WalHdr[12], pWal
167b0 2d 3e 6e 43 6b 70 74 29 3b 0a 20 20 20 20 73 71  ->nCkpt);.    sq
167c0 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73  lite3_randomness
167d0 28 38 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53  (8, pWal->hdr.aS
167e0 61 6c 74 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79  alt);.    memcpy
167f0 28 26 61 57 61 6c 48 64 72 5b 31 36 5d 2c 20 70  (&aWalHdr[16], p
16800 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20  Wal->hdr.aSalt, 
16810 38 29 3b 0a 20 20 20 20 77 61 6c 43 68 65 63 6b  8);.    walCheck
16820 73 75 6d 42 79 74 65 73 28 31 2c 20 61 57 61 6c  sumBytes(1, aWal
16830 48 64 72 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45  Hdr, WAL_HDRSIZE
16840 2d 32 2a 34 2c 20 30 2c 20 61 43 6b 73 75 6d 29  -2*4, 0, aCksum)
16850 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74  ;.    sqlite3Put
16860 34 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32  4byte(&aWalHdr[2
16870 34 5d 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b 0a  4], aCksum[0]);.
16880 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62      sqlite3Put4b
16890 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32 38 5d  yte(&aWalHdr[28]
168a0 2c 20 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 20 20  , aCksum[1]);.  
168b0 20 20 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50    .    pWal->szP
168c0 61 67 65 20 3d 20 28 75 31 36 29 73 7a 50 61 67  age = (u16)szPag
168d0 65 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  e;.    pWal->hdr
168e0 2e 62 69 67 45 6e 64 43 6b 73 75 6d 20 3d 20 53  .bigEndCksum = S
168f0 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e 3b  QLITE_BIGENDIAN;
16900 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61  .    pWal->hdr.a
16910 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d 20  FrameCksum[0] = 
16920 61 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 20 20 70  aCksum[0];.    p
16930 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
16940 6b 73 75 6d 5b 31 5d 20 3d 20 61 43 6b 73 75 6d  ksum[1] = aCksum
16950 5b 31 5d 3b 0a 0a 20 20 20 20 72 63 20 3d 20 73  [1];..    rc = s
16960 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 57  qlite3OsWrite(pW
16970 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 57 61 6c  al->pWalFd, aWal
16980 48 64 72 2c 20 73 69 7a 65 6f 66 28 61 57 61 6c  Hdr, sizeof(aWal
16990 48 64 72 29 2c 20 30 29 3b 0a 20 20 20 20 57 41  Hdr), 0);.    WA
169a0 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20  LTRACE(("WAL%p: 
169b0 77 61 6c 2d 68 65 61 64 65 72 20 77 72 69 74 65  wal-header write
169c0 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72 63   %s\n", pWal, rc
169d0 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f   ? "failed" : "o
169e0 6b 22 29 29 3b 0a 20 20 20 20 69 66 28 20 72 63  k"));.    if( rc
169f0 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
16a00 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a       return rc;.
16a10 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73 65      }.  }.  asse
16a20 72 74 28 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65  rt( pWal->szPage
16a30 3d 3d 73 7a 50 61 67 65 20 29 3b 0a 0a 20 20 2f  ==szPage );..  /
16a40 2a 20 57 72 69 74 65 20 74 68 65 20 6c 6f 67 20  * Write the log 
16a50 66 69 6c 65 2e 20 2a 2f 0a 20 20 66 6f 72 28 70  file. */.  for(p
16a60 3d 70 4c 69 73 74 3b 20 70 3b 20 70 3d 70 2d 3e  =pList; p; p=p->
16a70 70 44 69 72 74 79 29 7b 0a 20 20 20 20 75 33 32  pDirty){.    u32
16a80 20 6e 44 62 73 69 7a 65 3b 20 20 20 20 20 20 20   nDbsize;       
16a90 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 62             /* Db
16aa0 2d 73 69 7a 65 20 66 69 65 6c 64 20 66 6f 72 20  -size field for 
16ab0 66 72 61 6d 65 20 68 65 61 64 65 72 20 2a 2f 0a  frame header */.
16ac0 20 20 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b      i64 iOffset;
16ad0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16ae0 20 20 2f 2a 20 57 72 69 74 65 20 6f 66 66 73 65    /* Write offse
16af0 74 20 69 6e 20 6c 6f 67 20 66 69 6c 65 20 2a 2f  t in log file */
16b00 0a 20 20 20 20 76 6f 69 64 20 2a 70 44 61 74 61  .    void *pData
16b10 3b 0a 20 20 20 0a 20 20 20 20 69 4f 66 66 73 65  ;.   .    iOffse
16b20 74 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73  t = walFrameOffs
16b30 65 74 28 2b 2b 69 46 72 61 6d 65 2c 20 73 7a 50  et(++iFrame, szP
16b40 61 67 65 29 3b 0a 20 20 20 20 2f 2a 20 74 65 73  age);.    /* tes
16b50 74 63 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e  tcase( IS_BIG_IN
16b60 54 28 69 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f  T(iOffset) ); //
16b70 20 72 65 71 75 69 72 65 73 20 61 20 34 47 69 42   requires a 4GiB
16b80 20 57 41 4c 20 2a 2f 0a 20 20 20 20 0a 20 20 20   WAL */.    .   
16b90 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20 61 6e 64   /* Populate and
16ba0 20 77 72 69 74 65 20 74 68 65 20 66 72 61 6d 65   write the frame
16bb0 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 6e   header */.    n
16bc0 44 62 73 69 7a 65 20 3d 20 28 69 73 43 6f 6d 6d  Dbsize = (isComm
16bd0 69 74 20 26 26 20 70 2d 3e 70 44 69 72 74 79 3d  it && p->pDirty=
16be0 3d 30 29 20 3f 20 6e 54 72 75 6e 63 61 74 65 20  =0) ? nTruncate 
16bf0 3a 20 30 3b 0a 23 69 66 20 64 65 66 69 6e 65 64  : 0;.#if defined
16c00 28 53 51 4c 49 54 45 5f 48 41 53 5f 43 4f 44 45  (SQLITE_HAS_CODE
16c10 43 29 0a 20 20 20 20 69 66 28 20 28 70 44 61 74  C).    if( (pDat
16c20 61 20 3d 20 73 71 6c 69 74 65 33 50 61 67 65 72  a = sqlite3Pager
16c30 43 6f 64 65 63 28 70 29 29 3d 3d 30 20 29 20 72  Codec(p))==0 ) r
16c40 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
16c50 45 4d 3b 0a 23 65 6c 73 65 0a 20 20 20 20 70 44  EM;.#else.    pD
16c60 61 74 61 20 3d 20 70 2d 3e 70 44 61 74 61 3b 0a  ata = p->pData;.
16c70 23 65 6e 64 69 66 0a 20 20 20 20 77 61 6c 45 6e  #endif.    walEn
16c80 63 6f 64 65 46 72 61 6d 65 28 70 57 61 6c 2c 20  codeFrame(pWal, 
16c90 70 2d 3e 70 67 6e 6f 2c 20 6e 44 62 73 69 7a 65  p->pgno, nDbsize
16ca0 2c 20 70 44 61 74 61 2c 20 61 46 72 61 6d 65 29  , pData, aFrame)
16cb0 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
16cc0 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e  e3OsWrite(pWal->
16cd0 70 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20  pWalFd, aFrame, 
16ce0 73 69 7a 65 6f 66 28 61 46 72 61 6d 65 29 2c 20  sizeof(aFrame), 
16cf0 69 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 69 66  iOffset);.    if
16d00 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
16d10 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
16d20 72 63 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  rc;.    }..    /
16d30 2a 20 57 72 69 74 65 20 74 68 65 20 70 61 67 65  * Write the page
16d40 20 64 61 74 61 20 2a 2f 0a 20 20 20 20 72 63 20   data */.    rc 
16d50 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65  = sqlite3OsWrite
16d60 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 70  (pWal->pWalFd, p
16d70 44 61 74 61 2c 20 73 7a 50 61 67 65 2c 20 69 4f  Data, szPage, iO
16d80 66 66 73 65 74 2b 73 69 7a 65 6f 66 28 61 46 72  ffset+sizeof(aFr
16d90 61 6d 65 29 29 3b 0a 20 20 20 20 69 66 28 20 72  ame));.    if( r
16da0 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
16db0 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
16dc0 0a 20 20 20 20 7d 0a 20 20 20 20 70 4c 61 73 74  .    }.    pLast
16dd0 20 3d 20 70 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20   = p;.  }..  /* 
16de0 53 79 6e 63 20 74 68 65 20 6c 6f 67 20 66 69 6c  Sync the log fil
16df0 65 20 69 66 20 74 68 65 20 27 69 73 53 79 6e 63  e if the 'isSync
16e00 27 20 66 6c 61 67 20 77 61 73 20 73 70 65 63 69  ' flag was speci
16e10 66 69 65 64 2e 20 2a 2f 0a 20 20 69 66 28 20 73  fied. */.  if( s
16e20 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a 20 20 20  ync_flags ){.   
16e30 20 69 36 34 20 69 53 65 67 6d 65 6e 74 20 3d 20   i64 iSegment = 
16e40 73 71 6c 69 74 65 33 4f 73 53 65 63 74 6f 72 53  sqlite3OsSectorS
16e50 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ize(pWal->pWalFd
16e60 29 3b 0a 20 20 20 20 69 36 34 20 69 4f 66 66 73  );.    i64 iOffs
16e70 65 74 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66  et = walFrameOff
16e80 73 65 74 28 69 46 72 61 6d 65 2b 31 2c 20 73 7a  set(iFrame+1, sz
16e90 50 61 67 65 29 3b 0a 0a 20 20 20 20 61 73 73 65  Page);..    asse
16ea0 72 74 28 20 69 73 43 6f 6d 6d 69 74 20 29 3b 0a  rt( isCommit );.
16eb0 20 20 20 20 61 73 73 65 72 74 28 20 69 53 65 67      assert( iSeg
16ec0 6d 65 6e 74 3e 30 20 29 3b 0a 0a 20 20 20 20 69  ment>0 );..    i
16ed0 53 65 67 6d 65 6e 74 20 3d 20 28 28 28 69 4f 66  Segment = (((iOf
16ee0 66 73 65 74 2b 69 53 65 67 6d 65 6e 74 2d 31 29  fset+iSegment-1)
16ef0 2f 69 53 65 67 6d 65 6e 74 29 20 2a 20 69 53 65  /iSegment) * iSe
16f00 67 6d 65 6e 74 29 3b 0a 20 20 20 20 77 68 69 6c  gment);.    whil
16f10 65 28 20 69 4f 66 66 73 65 74 3c 69 53 65 67 6d  e( iOffset<iSegm
16f20 65 6e 74 20 29 7b 0a 20 20 20 20 20 20 76 6f 69  ent ){.      voi
16f30 64 20 2a 70 44 61 74 61 3b 0a 23 69 66 20 64 65  d *pData;.#if de
16f40 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 48 41 53  fined(SQLITE_HAS
16f50 5f 43 4f 44 45 43 29 0a 20 20 20 20 20 20 69 66  _CODEC).      if
16f60 28 20 28 70 44 61 74 61 20 3d 20 73 71 6c 69 74  ( (pData = sqlit
16f70 65 33 50 61 67 65 72 43 6f 64 65 63 28 70 4c 61  e3PagerCodec(pLa
16f80 73 74 29 29 3d 3d 30 20 29 20 72 65 74 75 72 6e  st))==0 ) return
16f90 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 23   SQLITE_NOMEM;.#
16fa0 65 6c 73 65 0a 20 20 20 20 20 20 70 44 61 74 61  else.      pData
16fb0 20 3d 20 70 4c 61 73 74 2d 3e 70 44 61 74 61 3b   = pLast->pData;
16fc0 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 77 61  .#endif.      wa
16fd0 6c 45 6e 63 6f 64 65 46 72 61 6d 65 28 70 57 61  lEncodeFrame(pWa
16fe0 6c 2c 20 70 4c 61 73 74 2d 3e 70 67 6e 6f 2c 20  l, pLast->pgno, 
16ff0 6e 54 72 75 6e 63 61 74 65 2c 20 70 44 61 74 61  nTruncate, pData
17000 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20 20 20 20  , aFrame);.     
17010 20 2f 2a 20 74 65 73 74 63 61 73 65 28 20 49 53   /* testcase( IS
17020 5f 42 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74  _BIG_INT(iOffset
17030 29 20 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73  ) ); // requires
17040 20 61 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20   a 4GiB WAL */. 
17050 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
17060 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70  3OsWrite(pWal->p
17070 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20 73  WalFd, aFrame, s
17080 69 7a 65 6f 66 28 61 46 72 61 6d 65 29 2c 20 69  izeof(aFrame), i
17090 4f 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 69  Offset);.      i
170a0 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
170b0 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75   ){.        retu
170c0 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20  rn rc;.      }. 
170d0 20 20 20 20 20 69 4f 66 66 73 65 74 20 2b 3d 20       iOffset += 
170e0 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a  WAL_FRAME_HDRSIZ
170f0 45 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  E;.      rc = sq
17100 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 57 61  lite3OsWrite(pWa
17110 6c 2d 3e 70 57 61 6c 46 64 2c 20 70 44 61 74 61  l->pWalFd, pData
17120 2c 20 73 7a 50 61 67 65 2c 20 69 4f 66 66 73 65  , szPage, iOffse
17130 74 29 3b 20 0a 20 20 20 20 20 20 69 66 28 20 72  t); .      if( r
17140 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
17150 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72          return r
17160 63 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  c;.      }.     
17170 20 6e 4c 61 73 74 2b 2b 3b 0a 20 20 20 20 20 20   nLast++;.      
17180 69 4f 66 66 73 65 74 20 2b 3d 20 73 7a 50 61 67  iOffset += szPag
17190 65 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 63  e;.    }..    rc
171a0 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63   = sqlite3OsSync
171b0 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 73  (pWal->pWalFd, s
171c0 79 6e 63 5f 66 6c 61 67 73 29 3b 0a 20 20 7d 0a  ync_flags);.  }.
171d0 0a 20 20 2f 2a 20 41 70 70 65 6e 64 20 64 61 74  .  /* Append dat
171e0 61 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64  a to the wal-ind
171f0 65 78 2e 20 49 74 20 69 73 20 6e 6f 74 20 6e 65  ex. It is not ne
17200 63 65 73 73 61 72 79 20 74 6f 20 6c 6f 63 6b 20  cessary to lock 
17210 74 68 65 20 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e  the .  ** wal-in
17220 64 65 78 20 74 6f 20 64 6f 20 74 68 69 73 20 61  dex to do this a
17230 73 20 74 68 65 20 53 51 4c 49 54 45 5f 53 48 4d  s the SQLITE_SHM
17240 5f 57 52 49 54 45 20 6c 6f 63 6b 20 68 65 6c 64  _WRITE lock held
17250 20 6f 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   on the wal-inde
17260 78 0a 20 20 2a 2a 20 67 75 61 72 61 6e 74 65 65  x.  ** guarantee
17270 73 20 74 68 61 74 20 74 68 65 72 65 20 61 72 65  s that there are
17280 20 6e 6f 20 6f 74 68 65 72 20 77 72 69 74 65 72   no other writer
17290 73 2c 20 61 6e 64 20 6e 6f 20 64 61 74 61 20 74  s, and no data t
172a0 68 61 74 20 6d 61 79 0a 20 20 2a 2a 20 62 65 20  hat may.  ** be 
172b0 69 6e 20 75 73 65 20 62 79 20 65 78 69 73 74 69  in use by existi
172c0 6e 67 20 72 65 61 64 65 72 73 20 69 73 20 62 65  ng readers is be
172d0 69 6e 67 20 6f 76 65 72 77 72 69 74 74 65 6e 2e  ing overwritten.
172e0 0a 20 20 2a 2f 0a 20 20 69 46 72 61 6d 65 20 3d  .  */.  iFrame =
172f0 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
17300 6d 65 3b 0a 20 20 66 6f 72 28 70 3d 70 4c 69 73  me;.  for(p=pLis
17310 74 3b 20 70 20 26 26 20 72 63 3d 3d 53 51 4c 49  t; p && rc==SQLI
17320 54 45 5f 4f 4b 3b 20 70 3d 70 2d 3e 70 44 69 72  TE_OK; p=p->pDir
17330 74 79 29 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b  ty){.    iFrame+
17340 2b 3b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49  +;.    rc = walI
17350 6e 64 65 78 41 70 70 65 6e 64 28 70 57 61 6c 2c  ndexAppend(pWal,
17360 20 69 46 72 61 6d 65 2c 20 70 2d 3e 70 67 6e 6f   iFrame, p->pgno
17370 29 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20  );.  }.  while( 
17380 6e 4c 61 73 74 3e 30 20 26 26 20 72 63 3d 3d 53  nLast>0 && rc==S
17390 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
173a0 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 6e 4c  iFrame++;.    nL
173b0 61 73 74 2d 2d 3b 0a 20 20 20 20 72 63 20 3d 20  ast--;.    rc = 
173c0 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64 28 70  walIndexAppend(p
173d0 57 61 6c 2c 20 69 46 72 61 6d 65 2c 20 70 4c 61  Wal, iFrame, pLa
173e0 73 74 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 0a  st->pgno);.  }..
173f0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
17400 5f 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 55 70  _OK ){.    /* Up
17410 64 61 74 65 20 74 68 65 20 70 72 69 76 61 74 65  date the private
17420 20 63 6f 70 79 20 6f 66 20 74 68 65 20 68 65 61   copy of the hea
17430 64 65 72 2e 20 2a 2f 0a 20 20 20 20 70 57 61 6c  der. */.    pWal
17440 2d 3e 68 64 72 2e 73 7a 50 61 67 65 20 3d 20 28  ->hdr.szPage = (
17450 75 31 36 29 73 7a 50 61 67 65 3b 0a 20 20 20 20  u16)szPage;.    
17460 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
17470 65 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20 20  e = iFrame;.    
17480 69 66 28 20 69 73 43 6f 6d 6d 69 74 20 29 7b 0a  if( isCommit ){.
17490 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e        pWal->hdr.
174a0 69 43 68 61 6e 67 65 2b 2b 3b 0a 20 20 20 20 20  iChange++;.     
174b0 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65   pWal->hdr.nPage
174c0 20 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a 20 20   = nTruncate;.  
174d0 20 20 7d 0a 20 20 20 20 2f 2a 20 49 66 20 74 68    }.    /* If th
174e0 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 2c 20  is is a commit, 
174f0 75 70 64 61 74 65 20 74 68 65 20 77 61 6c 2d 69  update the wal-i
17500 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f 6f 2e  ndex header too.
17510 20 2a 2f 0a 20 20 20 20 69 66 28 20 69 73 43 6f   */.    if( isCo
17520 6d 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 77 61  mmit ){.      wa
17530 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72 28 70  lIndexWriteHdr(p
17540 57 61 6c 29 3b 0a 20 20 20 20 20 20 70 57 61 6c  Wal);.      pWal
17550 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20 69 46  ->iCallback = iF
17560 72 61 6d 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  rame;.    }.  }.
17570 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41  .  WALTRACE(("WA
17580 4c 25 70 3a 20 66 72 61 6d 65 20 77 72 69 74 65  L%p: frame write
17590 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72 63   %s\n", pWal, rc
175a0 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f   ? "failed" : "o
175b0 6b 22 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  k"));.  return r
175c0 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69  c;.}../* .** Thi
175d0 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c  s routine is cal
175e0 6c 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  led to implement
175f0 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68 65   sqlite3_wal_che
17600 63 6b 70 6f 69 6e 74 28 29 20 61 6e 64 0a 2a 2a  ckpoint() and.**
17610 20 72 65 6c 61 74 65 64 20 69 6e 74 65 72 66 61   related interfa
17620 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74 61 69  ces..**.** Obtai
17630 6e 20 61 20 43 48 45 43 4b 50 4f 49 4e 54 20 6c  n a CHECKPOINT l
17640 6f 63 6b 20 61 6e 64 20 74 68 65 6e 20 62 61 63  ock and then bac
17650 6b 66 69 6c 6c 20 61 73 20 6d 75 63 68 20 69 6e  kfill as much in
17660 66 6f 72 6d 61 74 69 6f 6e 20 61 73 0a 2a 2a 20  formation as.** 
17670 77 65 20 63 61 6e 20 66 72 6f 6d 20 57 41 4c 20  we can from WAL 
17680 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
17690 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  e..*/.int sqlite
176a0 33 57 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a  3WalCheckpoint(.
176b0 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
176c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
176d0 20 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65 63 74    /* Wal connect
176e0 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e  ion */.  int syn
176f0 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20  c_flags,        
17700 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67           /* Flag
17710 73 20 74 6f 20 73 79 6e 63 20 64 62 20 66 69 6c  s to sync db fil
17720 65 20 77 69 74 68 20 28 6f 72 20 30 29 20 2a 2f  e with (or 0) */
17730 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20 20  .  int nBuf,    
17740 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17750 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74 65     /* Size of te
17760 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72 20 2a  mporary buffer *
17770 2f 0a 20 20 75 38 20 2a 7a 42 75 66 20 20 20 20  /.  u8 *zBuf    
17780 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17790 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79      /* Temporary
177a0 20 62 75 66 66 65 72 20 74 6f 20 75 73 65 20 2a   buffer to use *
177b0 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20  /.){.  int rc;  
177c0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
177d0 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
177e0 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69   code */.  int i
177f0 73 43 68 61 6e 67 65 64 20 3d 20 30 3b 20 20 20  sChanged = 0;   
17800 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
17810 75 65 20 69 66 20 61 20 6e 65 77 20 77 61 6c 2d  ue if a new wal-
17820 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20  index header is 
17830 6c 6f 61 64 65 64 20 2a 2f 0a 0a 20 20 61 73 73  loaded */..  ass
17840 65 72 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c  ert( pWal->ckptL
17850 6f 63 6b 3d 3d 30 20 29 3b 0a 0a 20 20 57 41 4c  ock==0 );..  WAL
17860 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63  TRACE(("WAL%p: c
17870 68 65 63 6b 70 6f 69 6e 74 20 62 65 67 69 6e 73  heckpoint begins
17880 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 20 20 72  \n", pWal));.  r
17890 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75  c = walLockExclu
178a0 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 43  sive(pWal, WAL_C
178b0 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20  KPT_LOCK, 1);.  
178c0 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 2f 2a  if( rc ){.    /*
178d0 20 55 73 75 61 6c 6c 79 20 74 68 69 73 20 69 73   Usually this is
178e0 20 53 51 4c 49 54 45 5f 42 55 53 59 20 6d 65 61   SQLITE_BUSY mea
178f0 6e 69 6e 67 20 74 68 61 74 20 61 6e 6f 74 68 65  ning that anothe
17900 72 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63  r thread or proc
17910 65 73 73 0a 20 20 20 20 2a 2a 20 69 73 20 61 6c  ess.    ** is al
17920 72 65 61 64 79 20 72 75 6e 6e 69 6e 67 20 61 20  ready running a 
17930 63 68 65 63 6b 70 6f 69 6e 74 2c 20 6f 72 20 6d  checkpoint, or m
17940 61 79 62 65 20 61 20 72 65 63 6f 76 65 72 79 2e  aybe a recovery.
17950 20 20 42 75 74 20 69 74 20 6d 69 67 68 74 0a 20    But it might. 
17960 20 20 20 2a 2a 20 61 6c 73 6f 20 62 65 20 53 51     ** also be SQ
17970 4c 49 54 45 5f 49 4f 45 52 52 2e 20 2a 2f 0a 20  LITE_IOERR. */. 
17980 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
17990 7d 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f  }.  pWal->ckptLo
179a0 63 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 43 6f  ck = 1;..  /* Co
179b0 70 79 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65  py data from the
179c0 20 6c 6f 67 20 74 6f 20 74 68 65 20 64 61 74 61   log to the data
179d0 62 61 73 65 20 66 69 6c 65 2e 20 2a 2f 0a 20 20  base file. */.  
179e0 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52 65 61  rc = walIndexRea
179f0 64 48 64 72 28 70 57 61 6c 2c 20 26 69 73 43 68  dHdr(pWal, &isCh
17a00 61 6e 67 65 64 29 3b 0a 20 20 69 66 28 20 72 63  anged);.  if( rc
17a10 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
17a20 20 20 20 72 63 20 3d 20 77 61 6c 43 68 65 63 6b     rc = walCheck
17a30 70 6f 69 6e 74 28 70 57 61 6c 2c 20 73 79 6e 63  point(pWal, sync
17a40 5f 66 6c 61 67 73 2c 20 6e 42 75 66 2c 20 7a 42  _flags, nBuf, zB
17a50 75 66 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69  uf);.  }.  if( i
17a60 73 43 68 61 6e 67 65 64 20 29 7b 0a 20 20 20 20  sChanged ){.    
17a70 2f 2a 20 49 66 20 61 20 6e 65 77 20 77 61 6c 2d  /* If a new wal-
17a80 69 6e 64 65 78 20 68 65 61 64 65 72 20 77 61 73  index header was
17a90 20 6c 6f 61 64 65 64 20 62 65 66 6f 72 65 20 74   loaded before t
17aa0 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 77 61  he checkpoint wa
17ab0 73 20 0a 20 20 20 20 2a 2a 20 70 65 72 66 6f 72  s .    ** perfor
17ac0 6d 65 64 2c 20 74 68 65 6e 20 74 68 65 20 70 61  med, then the pa
17ad0 67 65 72 2d 63 61 63 68 65 20 61 73 73 6f 63 69  ger-cache associ
17ae0 61 74 65 64 20 77 69 74 68 20 70 57 61 6c 20 69  ated with pWal i
17af0 73 20 6e 6f 77 0a 20 20 20 20 2a 2a 20 6f 75 74  s now.    ** out
17b00 20 6f 66 20 64 61 74 65 2e 20 53 6f 20 7a 65 72   of date. So zer
17b10 6f 20 74 68 65 20 63 61 63 68 65 64 20 77 61 6c  o the cached wal
17b20 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f  -index header to
17b30 20 65 6e 73 75 72 65 20 74 68 61 74 0a 20 20 20   ensure that.   
17b40 20 2a 2a 20 6e 65 78 74 20 74 69 6d 65 20 74 68   ** next time th
17b50 65 20 70 61 67 65 72 20 6f 70 65 6e 73 20 61 20  e pager opens a 
17b60 73 6e 61 70 73 68 6f 74 20 6f 6e 20 74 68 69 73  snapshot on this
17b70 20 64 61 74 61 62 61 73 65 20 69 74 20 6b 6e 6f   database it kno
17b80 77 73 20 74 68 61 74 0a 20 20 20 20 2a 2a 20 74  ws that.    ** t
17b90 68 65 20 63 61 63 68 65 20 6e 65 65 64 73 20 74  he cache needs t
17ba0 6f 20 62 65 20 72 65 73 65 74 2e 0a 20 20 20 20  o be reset..    
17bb0 2a 2f 0a 20 20 20 20 6d 65 6d 73 65 74 28 26 70  */.    memset(&p
17bc0 57 61 6c 2d 3e 68 64 72 2c 20 30 2c 20 73 69 7a  Wal->hdr, 0, siz
17bd0 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29  eof(WalIndexHdr)
17be0 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 6c  );.  }..  /* Rel
17bf0 65 61 73 65 20 74 68 65 20 6c 6f 63 6b 73 2e 20  ease the locks. 
17c00 2a 2f 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78  */.  walUnlockEx
17c10 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
17c20 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b  L_CKPT_LOCK, 1);
17c30 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63  .  pWal->ckptLoc
17c40 6b 20 3d 20 30 3b 0a 20 20 57 41 4c 54 52 41 43  k = 0;.  WALTRAC
17c50 45 28 28 22 57 41 4c 25 70 3a 20 63 68 65 63 6b  E(("WAL%p: check
17c60 70 6f 69 6e 74 20 25 73 5c 6e 22 2c 20 70 57 61  point %s\n", pWa
17c70 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22  l, rc ? "failed"
17c80 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 72 65 74   : "ok"));.  ret
17c90 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 52 65  urn rc;.}../* Re
17ca0 74 75 72 6e 20 74 68 65 20 76 61 6c 75 65 20 74  turn the value t
17cb0 6f 20 70 61 73 73 20 74 6f 20 61 20 73 71 6c 69  o pass to a sqli
17cc0 74 65 33 5f 77 61 6c 5f 68 6f 6f 6b 20 63 61 6c  te3_wal_hook cal
17cd0 6c 62 61 63 6b 2c 20 74 68 65 0a 2a 2a 20 6e 75  lback, the.** nu
17ce0 6d 62 65 72 20 6f 66 20 66 72 61 6d 65 73 20 69  mber of frames i
17cf0 6e 20 74 68 65 20 57 41 4c 20 61 74 20 74 68 65  n the WAL at the
17d00 20 70 6f 69 6e 74 20 6f 66 20 74 68 65 20 6c 61   point of the la
17d10 73 74 20 63 6f 6d 6d 69 74 20 73 69 6e 63 65 0a  st commit since.
17d20 2a 2a 20 73 71 6c 69 74 65 33 57 61 6c 43 61 6c  ** sqlite3WalCal
17d30 6c 62 61 63 6b 28 29 20 77 61 73 20 63 61 6c 6c  lback() was call
17d40 65 64 2e 20 20 49 66 20 6e 6f 20 63 6f 6d 6d 69  ed.  If no commi
17d50 74 73 20 68 61 76 65 20 6f 63 63 75 72 72 65 64  ts have occurred
17d60 20 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 6c 61   since.** the la
17d70 73 74 20 63 61 6c 6c 2c 20 74 68 65 6e 20 72 65  st call, then re
17d80 74 75 72 6e 20 30 2e 0a 2a 2f 0a 69 6e 74 20 73  turn 0..*/.int s
17d90 71 6c 69 74 65 33 57 61 6c 43 61 6c 6c 62 61 63  qlite3WalCallbac
17da0 6b 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20  k(Wal *pWal){.  
17db0 75 33 32 20 72 65 74 20 3d 20 30 3b 0a 20 20 69  u32 ret = 0;.  i
17dc0 66 28 20 70 57 61 6c 20 29 7b 0a 20 20 20 20 72  f( pWal ){.    r
17dd0 65 74 20 3d 20 70 57 61 6c 2d 3e 69 43 61 6c 6c  et = pWal->iCall
17de0 62 61 63 6b 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  back;.    pWal->
17df0 69 43 61 6c 6c 62 61 63 6b 20 3d 20 30 3b 0a 20  iCallback = 0;. 
17e00 20 7d 0a 20 20 72 65 74 75 72 6e 20 28 69 6e 74   }.  return (int
17e10 29 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  )ret;.}../*.** T
17e20 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
17e30 63 61 6c 6c 65 64 20 74 6f 20 63 68 61 6e 67 65  called to change
17e40 20 74 68 65 20 57 41 4c 20 73 75 62 73 79 73 74   the WAL subsyst
17e50 65 6d 20 69 6e 74 6f 20 6f 72 20 6f 75 74 0a 2a  em into or out.*
17e60 2a 20 6f 66 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64  * of locking_mod
17e70 65 3d 45 58 43 4c 55 53 49 56 45 2e 0a 2a 2a 0a  e=EXCLUSIVE..**.
17e80 2a 2a 20 49 66 20 6f 70 20 69 73 20 7a 65 72 6f  ** If op is zero
17e90 2c 20 74 68 65 6e 20 61 74 74 65 6d 70 74 20 74  , then attempt t
17ea0 6f 20 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f  o change from lo
17eb0 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55  cking_mode=EXCLU
17ec0 53 49 56 45 0a 2a 2a 20 69 6e 74 6f 20 6c 6f 63  SIVE.** into loc
17ed0 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c  king_mode=NORMAL
17ee0 2e 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68  .  This means th
17ef0 61 74 20 77 65 20 6d 75 73 74 20 61 63 71 75 69  at we must acqui
17f00 72 65 20 61 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20  re a lock.** on 
17f10 74 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  the pWal->readLo
17f20 63 6b 20 62 79 74 65 2e 20 20 49 66 20 74 68 65  ck byte.  If the
17f30 20 57 41 4c 20 69 73 20 61 6c 72 65 61 64 79 20   WAL is already 
17f40 69 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d  in locking_mode=
17f50 4e 4f 52 4d 41 4c 0a 2a 2a 20 6f 72 20 69 66 20  NORMAL.** or if 
17f60 74 68 65 20 61 63 71 75 69 73 69 74 69 6f 6e 20  the acquisition 
17f70 6f 66 20 74 68 65 20 6c 6f 63 6b 20 66 61 69 6c  of the lock fail
17f80 73 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20 30  s, then return 0
17f90 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 74 72 61  .  If the.** tra
17fa0 6e 73 69 74 69 6f 6e 20 6f 75 74 20 6f 66 20 65  nsition out of e
17fb0 78 63 6c 75 73 69 76 65 2d 6d 6f 64 65 20 69 73  xclusive-mode is
17fc0 20 73 75 63 63 65 73 73 66 75 6c 2c 20 72 65 74   successful, ret
17fd0 75 72 6e 20 31 2e 20 20 54 68 69 73 0a 2a 2a 20  urn 1.  This.** 
17fe0 6f 70 65 72 61 74 69 6f 6e 20 6d 75 73 74 20 6f  operation must o
17ff0 63 63 75 72 20 77 68 69 6c 65 20 74 68 65 20 70  ccur while the p
18000 61 67 65 72 20 69 73 20 73 74 69 6c 6c 20 68 6f  ager is still ho
18010 6c 64 69 6e 67 20 74 68 65 20 65 78 63 6c 75 73  lding the exclus
18020 69 76 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20 74  ive.** lock on t
18030 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65  he main database
18040 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20   file..**.** If 
18050 6f 70 20 69 73 20 6f 6e 65 2c 20 74 68 65 6e 20  op is one, then 
18060 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63 6b  change from lock
18070 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20  ing_mode=NORMAL 
18080 69 6e 74 6f 20 0a 2a 2a 20 6c 6f 63 6b 69 6e 67  into .** locking
18090 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2e  _mode=EXCLUSIVE.
180a0 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68 61    This means tha
180b0 74 20 74 68 65 20 70 57 61 6c 2d 3e 72 65 61 64  t the pWal->read
180c0 4c 6f 63 6b 20 6d 75 73 74 0a 2a 2a 20 62 65 20  Lock must.** be 
180d0 72 65 6c 65 61 73 65 64 2e 20 20 52 65 74 75 72  released.  Retur
180e0 6e 20 31 20 69 66 20 74 68 65 20 74 72 61 6e 73  n 1 if the trans
180f0 69 74 69 6f 6e 20 69 73 20 6d 61 64 65 20 61 6e  ition is made an
18100 64 20 30 20 69 66 20 74 68 65 0a 2a 2a 20 57 41  d 0 if the.** WA
18110 4c 20 69 73 20 61 6c 72 65 61 64 79 20 69 6e 20  L is already in 
18120 65 78 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69 6e  exclusive-lockin
18130 67 20 6d 6f 64 65 20 2d 20 6d 65 61 6e 69 6e 67  g mode - meaning
18140 20 74 68 61 74 20 74 68 69 73 0a 2a 2a 20 72 6f   that this.** ro
18150 75 74 69 6e 65 20 69 73 20 61 20 6e 6f 2d 6f 70  utine is a no-op
18160 2e 20 20 54 68 65 20 70 61 67 65 72 20 6d 75 73  .  The pager mus
18170 74 20 61 6c 72 65 61 64 79 20 68 6f 6c 64 20 74  t already hold t
18180 68 65 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63  he exclusive loc
18190 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20 6d 61 69 6e  k.** on the main
181a0 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 62   database file b
181b0 65 66 6f 72 65 20 69 6e 76 6f 6b 69 6e 67 20 74  efore invoking t
181c0 68 69 73 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 2a  his operation..*
181d0 2a 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20 6e 65  *.** If op is ne
181e0 67 61 74 69 76 65 2c 20 74 68 65 6e 20 64 6f 20  gative, then do 
181f0 61 20 64 72 79 2d 72 75 6e 20 6f 66 20 74 68 65  a dry-run of the
18200 20 6f 70 3d 3d 31 20 63 61 73 65 20 62 75 74 20   op==1 case but 
18210 64 6f 0a 2a 2a 20 6e 6f 74 20 61 63 74 75 61 6c  do.** not actual
18220 6c 79 20 63 68 61 6e 67 65 20 61 6e 79 74 68 69  ly change anythi
18230 6e 67 2e 20 20 54 68 65 20 70 61 67 65 72 20 75  ng.  The pager u
18240 73 65 73 20 74 68 69 73 20 74 6f 20 73 65 65 20  ses this to see 
18250 69 66 20 69 74 0a 2a 2a 20 73 68 6f 75 6c 64 20  if it.** should 
18260 61 63 71 75 69 72 65 20 74 68 65 20 64 61 74 61  acquire the data
18270 62 61 73 65 20 65 78 63 6c 75 73 69 76 65 20 6c  base exclusive l
18280 6f 63 6b 20 70 72 69 6f 72 20 74 6f 20 69 6e 76  ock prior to inv
18290 6f 6b 69 6e 67 0a 2a 2a 20 74 68 65 20 6f 70 3d  oking.** the op=
182a0 3d 31 20 63 61 73 65 2e 0a 2a 2f 0a 69 6e 74 20  =1 case..*/.int 
182b0 73 71 6c 69 74 65 33 57 61 6c 45 78 63 6c 75 73  sqlite3WalExclus
182c0 69 76 65 4d 6f 64 65 28 57 61 6c 20 2a 70 57 61  iveMode(Wal *pWa
182d0 6c 2c 20 69 6e 74 20 6f 70 29 7b 0a 20 20 69 6e  l, int op){.  in
182e0 74 20 72 63 3b 0a 20 20 61 73 73 65 72 74 28 20  t rc;.  assert( 
182f0 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d  pWal->writeLock=
18300 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 70 57 61 6c  =0 );..  /* pWal
18310 2d 3e 72 65 61 64 4c 6f 63 6b 20 69 73 20 75 73  ->readLock is us
18320 75 61 6c 6c 79 20 73 65 74 2c 20 62 75 74 20 6d  ually set, but m
18330 69 67 68 74 20 62 65 20 2d 31 20 69 66 20 74 68  ight be -1 if th
18340 65 72 65 20 77 61 73 20 61 20 0a 20 20 2a 2a 20  ere was a .  ** 
18350 70 72 69 6f 72 20 65 72 72 6f 72 20 77 68 69 6c  prior error whil
18360 65 20 61 74 74 65 6d 70 74 69 6e 67 20 74 6f 20  e attempting to 
18370 61 63 71 75 69 72 65 20 61 72 65 20 72 65 61 64  acquire are read
18380 2d 6c 6f 63 6b 2e 20 54 68 69 73 20 63 61 6e 6e  -lock. This cann
18390 6f 74 20 0a 20 20 2a 2a 20 68 61 70 70 65 6e 20  ot .  ** happen 
183a0 69 66 20 74 68 65 20 63 6f 6e 6e 65 63 74 69 6f  if the connectio
183b0 6e 20 69 73 20 61 63 74 75 61 6c 6c 79 20 69 6e  n is actually in
183c0 20 65 78 63 6c 75 73 69 76 65 20 6d 6f 64 65 20   exclusive mode 
183d0 28 61 73 20 6e 6f 20 78 53 68 6d 4c 6f 63 6b 0a  (as no xShmLock.
183e0 20 20 2a 2a 20 6c 6f 63 6b 73 20 61 72 65 20 74    ** locks are t
183f0 61 6b 65 6e 20 69 6e 20 74 68 69 73 20 63 61 73  aken in this cas
18400 65 29 2e 20 4e 6f 72 20 73 68 6f 75 6c 64 20 74  e). Nor should t
18410 68 65 20 70 61 67 65 72 20 61 74 74 65 6d 70 74  he pager attempt
18420 20 74 6f 0a 20 20 2a 2a 20 75 70 67 72 61 64 65   to.  ** upgrade
18430 20 74 6f 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f   to exclusive-mo
18440 64 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 75 63  de following suc
18450 68 20 61 6e 20 65 72 72 6f 72 2e 0a 20 20 2a 2f  h an error..  */
18460 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
18470 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20  >readLock>=0 || 
18480 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20  pWal->lockError 
18490 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61  );.  assert( pWa
184a0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c  l->readLock>=0 |
184b0 7c 20 28 6f 70 3c 3d 30 20 26 26 20 70 57 61 6c  | (op<=0 && pWal
184c0 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d  ->exclusiveMode=
184d0 3d 30 29 20 29 3b 0a 0a 20 20 69 66 28 20 6f 70  =0) );..  if( op
184e0 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70  ==0 ){.    if( p
184f0 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
18500 64 65 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c  de ){.      pWal
18510 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20  ->exclusiveMode 
18520 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20 77  = 0;.      if( w
18530 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61  alLockShared(pWa
18540 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  l, WAL_READ_LOCK
18550 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29  (pWal->readLock)
18560 29 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  )!=SQLITE_OK ){.
18570 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 65 78          pWal->ex
18580 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 31 3b  clusiveMode = 1;
18590 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72  .      }.      r
185a0 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  c = pWal->exclus
185b0 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 20 20  iveMode==0;.    
185c0 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20  }else{.      /* 
185d0 41 6c 72 65 61 64 79 20 69 6e 20 6c 6f 63 6b 69  Already in locki
185e0 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 2a  ng_mode=NORMAL *
185f0 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 30 3b 0a  /.      rc = 0;.
18600 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66      }.  }else if
18610 28 20 6f 70 3e 30 20 29 7b 0a 20 20 20 20 61 73  ( op>0 ){.    as
18620 73 65 72 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c  sert( pWal->excl
18630 75 73 69 76 65 4d 6f 64 65 3d 3d 30 20 29 3b 0a  usiveMode==0 );.
18640 20 20 20 20 61 73 73 65 72 74 28 20 70 57 61 6c      assert( pWal
18650 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b  ->readLock>=0 );
18660 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68  .    walUnlockSh
18670 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
18680 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72  EAD_LOCK(pWal->r
18690 65 61 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70  eadLock));.    p
186a0 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
186b0 64 65 20 3d 20 31 3b 0a 20 20 20 20 72 63 20 3d  de = 1;.    rc =
186c0 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20   1;.  }else{.   
186d0 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c   rc = pWal->excl
186e0 75 73 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20  usiveMode==0;.  
186f0 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
18700 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 23 69 66 6e  ..#endif /* #ifn
18710 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f  def SQLITE_OMIT_
18720 57 41 4c 20 2a 2f 0a                             WAL */.