/ Hex Artifact Content
Login

Artifact 5fe1ba55b8fab9d3936bc9093af61ab9f1c580a1:


0000: 2f 2a 0a 2a 2a 20 32 30 31 30 20 46 65 62 72 75  /*.** 2010 Febru
0010: 61 72 79 20 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ary 1.**.** The 
0020: 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73  author disclaims
0030: 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68   copyright to th
0040: 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20  is source code. 
0050: 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20   In place of.** 
0060: 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20  a legal notice, 
0070: 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69  here is a blessi
0080: 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79  ng:.**.**    May
0090: 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64   you do good and
00a0: 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20   not evil..**   
00b0: 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f   May you find fo
00c0: 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f  rgiveness for yo
00d0: 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69  urself and forgi
00e0: 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20  ve others..**   
00f0: 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66   May you share f
0100: 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b  reely, never tak
0110: 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f  ing more than yo
0120: 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a  u give..**.*****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 74 68  file contains th
0190: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
01a0: 20 6f 66 20 61 20 77 72 69 74 65 2d 61 68 65 61   of a write-ahea
01b0: 64 20 6c 6f 67 20 28 57 41 4c 29 20 75 73 65 64  d log (WAL) used
01c0: 20 69 6e 20 0a 2a 2a 20 22 6a 6f 75 72 6e 61 6c   in .** "journal
01d0: 5f 6d 6f 64 65 3d 57 41 4c 22 20 6d 6f 64 65 2e  _mode=WAL" mode.
01e0: 0a 2a 2a 0a 2a 2a 20 57 52 49 54 45 2d 41 48 45  .**.** WRITE-AHE
01f0: 41 44 20 4c 4f 47 20 28 57 41 4c 29 20 46 49 4c  AD LOG (WAL) FIL
0200: 45 20 46 4f 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 41  E FORMAT.**.** A
0210: 20 57 41 4c 20 66 69 6c 65 20 63 6f 6e 73 69 73   WAL file consis
0220: 74 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 66  ts of a header f
0230: 6f 6c 6c 6f 77 65 64 20 62 79 20 7a 65 72 6f 20  ollowed by zero 
0240: 6f 72 20 6d 6f 72 65 20 22 66 72 61 6d 65 73 22  or more "frames"
0250: 2e 0a 2a 2a 20 45 61 63 68 20 66 72 61 6d 65 20  ..** Each frame 
0260: 72 65 63 6f 72 64 73 20 74 68 65 20 72 65 76 69  records the revi
0270: 73 65 64 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  sed content of a
0280: 20 73 69 6e 67 6c 65 20 70 61 67 65 20 66 72 6f   single page fro
0290: 6d 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73  m the.** databas
02a0: 65 20 66 69 6c 65 2e 20 20 41 6c 6c 20 63 68 61  e file.  All cha
02b0: 6e 67 65 73 20 74 6f 20 74 68 65 20 64 61 74 61  nges to the data
02c0: 62 61 73 65 20 61 72 65 20 72 65 63 6f 72 64 65  base are recorde
02d0: 64 20 62 79 20 77 72 69 74 69 6e 67 0a 2a 2a 20  d by writing.** 
02e0: 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20  frames into the 
02f0: 57 41 4c 2e 20 20 54 72 61 6e 73 61 63 74 69 6f  WAL.  Transactio
0300: 6e 73 20 63 6f 6d 6d 69 74 20 77 68 65 6e 20 61  ns commit when a
0310: 20 66 72 61 6d 65 20 69 73 20 77 72 69 74 74 65   frame is writte
0320: 6e 20 74 68 61 74 0a 2a 2a 20 63 6f 6e 74 61 69  n that.** contai
0330: 6e 73 20 61 20 63 6f 6d 6d 69 74 20 6d 61 72 6b  ns a commit mark
0340: 65 72 2e 20 20 41 20 73 69 6e 67 6c 65 20 57 41  er.  A single WA
0350: 4c 20 63 61 6e 20 61 6e 64 20 75 73 75 61 6c 6c  L can and usuall
0360: 79 20 64 6f 65 73 20 72 65 63 6f 72 64 20 0a 2a  y does record .*
0370: 2a 20 6d 75 6c 74 69 70 6c 65 20 74 72 61 6e 73  * multiple trans
0380: 61 63 74 69 6f 6e 73 2e 20 20 50 65 72 69 6f 64  actions.  Period
0390: 69 63 61 6c 6c 79 2c 20 74 68 65 20 63 6f 6e 74  ically, the cont
03a0: 65 6e 74 20 6f 66 20 74 68 65 20 57 41 4c 20 69  ent of the WAL i
03b0: 73 0a 2a 2a 20 74 72 61 6e 73 66 65 72 72 65 64  s.** transferred
03c0: 20 62 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64   back into the d
03d0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 69 6e 20  atabase file in 
03e0: 61 6e 20 6f 70 65 72 61 74 69 6f 6e 20 63 61 6c  an operation cal
03f0: 6c 65 64 20 61 0a 2a 2a 20 22 63 68 65 63 6b 70  led a.** "checkp
0400: 6f 69 6e 74 22 2e 0a 2a 2a 0a 2a 2a 20 41 20 73  oint"..**.** A s
0410: 69 6e 67 6c 65 20 57 41 4c 20 66 69 6c 65 20 63  ingle WAL file c
0420: 61 6e 20 62 65 20 75 73 65 64 20 6d 75 6c 74 69  an be used multi
0430: 70 6c 65 20 74 69 6d 65 73 2e 20 20 49 6e 20 6f  ple times.  In o
0440: 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68 65 0a  ther words, the.
0450: 2a 2a 20 57 41 4c 20 63 61 6e 20 66 69 6c 6c 20  ** WAL can fill 
0460: 75 70 20 77 69 74 68 20 66 72 61 6d 65 73 20 61  up with frames a
0470: 6e 64 20 74 68 65 6e 20 62 65 20 63 68 65 63 6b  nd then be check
0480: 70 6f 69 6e 74 65 64 20 61 6e 64 20 74 68 65 6e  pointed and then
0490: 20 6e 65 77 0a 2a 2a 20 66 72 61 6d 65 73 20 63   new.** frames c
04a0: 61 6e 20 6f 76 65 72 77 72 69 74 65 20 74 68 65  an overwrite the
04b0: 20 6f 6c 64 20 6f 6e 65 73 2e 20 20 41 20 57 41   old ones.  A WA
04c0: 4c 20 61 6c 77 61 79 73 20 67 72 6f 77 73 20 66  L always grows f
04d0: 72 6f 6d 20 62 65 67 69 6e 6e 69 6e 67 0a 2a 2a  rom beginning.**
04e0: 20 74 6f 77 61 72 64 20 74 68 65 20 65 6e 64 2e   toward the end.
04f0: 20 20 43 68 65 63 6b 73 75 6d 73 20 61 6e 64 20    Checksums and 
0500: 63 6f 75 6e 74 65 72 73 20 61 74 74 61 63 68 65  counters attache
0510: 64 20 74 6f 20 65 61 63 68 20 66 72 61 6d 65 20  d to each frame 
0520: 61 72 65 0a 2a 2a 20 75 73 65 64 20 74 6f 20 64  are.** used to d
0530: 65 74 65 72 6d 69 6e 65 20 77 68 69 63 68 20 66  etermine which f
0540: 72 61 6d 65 73 20 77 69 74 68 69 6e 20 74 68 65  rames within the
0550: 20 57 41 4c 20 61 72 65 20 76 61 6c 69 64 20 61   WAL are valid a
0560: 6e 64 20 77 68 69 63 68 0a 2a 2a 20 61 72 65 20  nd which.** are 
0570: 6c 65 66 74 6f 76 65 72 73 20 66 72 6f 6d 20 70  leftovers from p
0580: 72 69 6f 72 20 63 68 65 63 6b 70 6f 69 6e 74 73  rior checkpoints
0590: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 57 41 4c 20  ..**.** The WAL 
05a0: 68 65 61 64 65 72 20 69 73 20 33 32 20 62 79 74  header is 32 byt
05b0: 65 73 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 63  es in size and c
05c0: 6f 6e 73 69 73 74 73 20 6f 66 20 74 68 65 20 66  onsists of the f
05d0: 6f 6c 6c 6f 77 69 6e 67 20 65 69 67 68 74 0a 2a  ollowing eight.*
05e0: 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 33 32 2d  * big-endian 32-
05f0: 62 69 74 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  bit unsigned int
0600: 65 67 65 72 20 76 61 6c 75 65 73 3a 0a 2a 2a 0a  eger values:.**.
0610: 2a 2a 20 20 20 20 20 30 3a 20 4d 61 67 69 63 20  **     0: Magic 
0620: 6e 75 6d 62 65 72 2e 20 20 30 78 33 37 37 66 30  number.  0x377f0
0630: 36 38 32 20 6f 72 20 30 78 33 37 37 66 30 36 38  682 or 0x377f068
0640: 33 0a 2a 2a 20 20 20 20 20 34 3a 20 46 69 6c 65  3.**     4: File
0650: 20 66 6f 72 6d 61 74 20 76 65 72 73 69 6f 6e 2e   format version.
0660: 20 20 43 75 72 72 65 6e 74 6c 79 20 33 30 30 37    Currently 3007
0670: 30 30 30 0a 2a 2a 20 20 20 20 20 38 3a 20 44 61  000.**     8: Da
0680: 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65  tabase page size
0690: 2e 20 20 45 78 61 6d 70 6c 65 3a 20 31 30 32 34  .  Example: 1024
06a0: 0a 2a 2a 20 20 20 20 31 32 3a 20 43 68 65 63 6b  .**    12: Check
06b0: 70 6f 69 6e 74 20 73 65 71 75 65 6e 63 65 20 6e  point sequence n
06c0: 75 6d 62 65 72 0a 2a 2a 20 20 20 20 31 36 3a 20  umber.**    16: 
06d0: 53 61 6c 74 2d 31 2c 20 72 61 6e 64 6f 6d 20 69  Salt-1, random i
06e0: 6e 74 65 67 65 72 20 69 6e 63 72 65 6d 65 6e 74  nteger increment
06f0: 65 64 20 77 69 74 68 20 65 61 63 68 20 63 68 65  ed with each che
0700: 63 6b 70 6f 69 6e 74 0a 2a 2a 20 20 20 20 32 30  ckpoint.**    20
0710: 3a 20 53 61 6c 74 2d 32 2c 20 61 20 64 69 66 66  : Salt-2, a diff
0720: 65 72 65 6e 74 20 72 61 6e 64 6f 6d 20 69 6e 74  erent random int
0730: 65 67 65 72 20 63 68 61 6e 67 69 6e 67 20 77 69  eger changing wi
0740: 74 68 20 65 61 63 68 20 63 6b 70 74 0a 2a 2a 20  th each ckpt.** 
0750: 20 20 20 32 34 3a 20 43 68 65 63 6b 73 75 6d 2d     24: Checksum-
0760: 31 20 28 66 69 72 73 74 20 70 61 72 74 20 6f 66  1 (first part of
0770: 20 63 68 65 63 6b 73 75 6d 20 66 6f 72 20 66 69   checksum for fi
0780: 72 73 74 20 32 34 20 62 79 74 65 73 20 6f 66 20  rst 24 bytes of 
0790: 68 65 61 64 65 72 29 2e 0a 2a 2a 20 20 20 20 32  header)..**    2
07a0: 38 3a 20 43 68 65 63 6b 73 75 6d 2d 32 20 28 73  8: Checksum-2 (s
07b0: 65 63 6f 6e 64 20 70 61 72 74 20 6f 66 20 63 68  econd part of ch
07c0: 65 63 6b 73 75 6d 20 66 6f 72 20 66 69 72 73 74  ecksum for first
07d0: 20 32 34 20 62 79 74 65 73 20 6f 66 20 68 65 61   24 bytes of hea
07e0: 64 65 72 29 2e 0a 2a 2a 0a 2a 2a 20 49 6d 6d 65  der)..**.** Imme
07f0: 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e  diately followin
0800: 67 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  g the wal-header
0810: 20 61 72 65 20 7a 65 72 6f 20 6f 72 20 6d 6f 72   are zero or mor
0820: 65 20 66 72 61 6d 65 73 2e 20 45 61 63 68 0a 2a  e frames. Each.*
0830: 2a 20 66 72 61 6d 65 20 63 6f 6e 73 69 73 74 73  * frame consists
0840: 20 6f 66 20 61 20 32 34 2d 62 79 74 65 20 66 72   of a 24-byte fr
0850: 61 6d 65 2d 68 65 61 64 65 72 20 66 6f 6c 6c 6f  ame-header follo
0860: 77 65 64 20 62 79 20 61 20 3c 70 61 67 65 2d 73  wed by a <page-s
0870: 69 7a 65 3e 20 62 79 74 65 73 0a 2a 2a 20 6f 66  ize> bytes.** of
0880: 20 70 61 67 65 20 64 61 74 61 2e 20 54 68 65 20   page data. The 
0890: 66 72 61 6d 65 2d 68 65 61 64 65 72 20 69 73 20  frame-header is 
08a0: 73 69 78 20 62 69 67 2d 65 6e 64 69 61 6e 20 33  six big-endian 3
08b0: 32 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20 0a  2-bit unsigned .
08c0: 2a 2a 20 69 6e 74 65 67 65 72 20 76 61 6c 75 65  ** integer value
08d0: 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  s, as follows:.*
08e0: 2a 0a 2a 2a 20 20 20 20 20 30 3a 20 50 61 67 65  *.**     0: Page
08f0: 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20 20 20 20   number..**     
0900: 34 3a 20 46 6f 72 20 63 6f 6d 6d 69 74 20 72 65  4: For commit re
0910: 63 6f 72 64 73 2c 20 74 68 65 20 73 69 7a 65 20  cords, the size 
0920: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  of the database 
0930: 69 6d 61 67 65 20 69 6e 20 70 61 67 65 73 20 0a  image in pages .
0940: 2a 2a 20 20 20 20 20 20 20 20 61 66 74 65 72 20  **        after 
0950: 74 68 65 20 63 6f 6d 6d 69 74 2e 20 46 6f 72 20  the commit. For 
0960: 61 6c 6c 20 6f 74 68 65 72 20 72 65 63 6f 72 64  all other record
0970: 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20 20  s, zero..**     
0980: 38 3a 20 53 61 6c 74 2d 31 20 28 63 6f 70 69 65  8: Salt-1 (copie
0990: 64 20 66 72 6f 6d 20 74 68 65 20 68 65 61 64 65  d from the heade
09a0: 72 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61 6c  r).**    12: Sal
09b0: 74 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f 6d  t-2 (copied from
09c0: 20 74 68 65 20 68 65 61 64 65 72 29 0a 2a 2a 20   the header).** 
09d0: 20 20 20 31 36 3a 20 43 68 65 63 6b 73 75 6d 2d     16: Checksum-
09e0: 31 2e 0a 2a 2a 20 20 20 20 32 30 3a 20 43 68 65  1..**    20: Che
09f0: 63 6b 73 75 6d 2d 32 2e 0a 2a 2a 0a 2a 2a 20 41  cksum-2..**.** A
0a00: 20 66 72 61 6d 65 20 69 73 20 63 6f 6e 73 69 64   frame is consid
0a10: 65 72 65 64 20 76 61 6c 69 64 20 69 66 20 61 6e  ered valid if an
0a20: 64 20 6f 6e 6c 79 20 69 66 20 74 68 65 20 66 6f  d only if the fo
0a30: 6c 6c 6f 77 69 6e 67 20 63 6f 6e 64 69 74 69 6f  llowing conditio
0a40: 6e 73 20 61 72 65 0a 2a 2a 20 74 72 75 65 3a 0a  ns are.** true:.
0a50: 2a 2a 0a 2a 2a 20 20 20 20 28 31 29 20 54 68 65  **.**    (1) The
0a60: 20 73 61 6c 74 2d 31 20 61 6e 64 20 73 61 6c 74   salt-1 and salt
0a70: 2d 32 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  -2 values in the
0a80: 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20 6d 61   frame-header ma
0a90: 74 63 68 0a 2a 2a 20 20 20 20 20 20 20 20 73 61  tch.**        sa
0aa0: 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  lt values in the
0ab0: 20 77 61 6c 2d 68 65 61 64 65 72 0a 2a 2a 0a 2a   wal-header.**.*
0ac0: 2a 20 20 20 20 28 32 29 20 54 68 65 20 63 68 65  *    (2) The che
0ad0: 63 6b 73 75 6d 20 76 61 6c 75 65 73 20 69 6e 20  cksum values in 
0ae0: 74 68 65 20 66 69 6e 61 6c 20 38 20 62 79 74 65  the final 8 byte
0af0: 73 20 6f 66 20 74 68 65 20 66 72 61 6d 65 2d 68  s of the frame-h
0b00: 65 61 64 65 72 0a 2a 2a 20 20 20 20 20 20 20 20  eader.**        
0b10: 65 78 61 63 74 6c 79 20 6d 61 74 63 68 20 74 68  exactly match th
0b20: 65 20 63 68 65 63 6b 73 75 6d 20 63 6f 6d 70 75  e checksum compu
0b30: 74 65 64 20 63 6f 6e 73 65 63 75 74 69 76 65 6c  ted consecutivel
0b40: 79 20 6f 6e 20 74 68 65 0a 2a 2a 20 20 20 20 20  y on the.**     
0b50: 20 20 20 57 41 4c 20 68 65 61 64 65 72 20 61 6e     WAL header an
0b60: 64 20 74 68 65 20 66 69 72 73 74 20 38 20 62 79  d the first 8 by
0b70: 74 65 73 20 61 6e 64 20 74 68 65 20 63 6f 6e 74  tes and the cont
0b80: 65 6e 74 20 6f 66 20 61 6c 6c 20 66 72 61 6d 65  ent of all frame
0b90: 73 0a 2a 2a 20 20 20 20 20 20 20 20 75 70 20 74  s.**        up t
0ba0: 6f 20 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20  o and including 
0bb0: 74 68 65 20 63 75 72 72 65 6e 74 20 66 72 61 6d  the current fram
0bc0: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65  e..**.** The che
0bd0: 63 6b 73 75 6d 20 69 73 20 63 6f 6d 70 75 74 65  cksum is compute
0be0: 64 20 75 73 69 6e 67 20 33 32 2d 62 69 74 20 62  d using 32-bit b
0bf0: 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65  ig-endian intege
0c00: 72 73 20 69 66 20 74 68 65 0a 2a 2a 20 6d 61 67  rs if the.** mag
0c10: 69 63 20 6e 75 6d 62 65 72 20 69 6e 20 74 68 65  ic number in the
0c20: 20 66 69 72 73 74 20 34 20 62 79 74 65 73 20 6f   first 4 bytes o
0c30: 66 20 74 68 65 20 57 41 4c 20 69 73 20 30 78 33  f the WAL is 0x3
0c40: 37 37 66 30 36 38 33 20 61 6e 64 20 69 74 0a 2a  77f0683 and it.*
0c50: 2a 20 69 73 20 63 6f 6d 70 75 74 65 64 20 75 73  * is computed us
0c60: 69 6e 67 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61  ing little-endia
0c70: 6e 20 69 66 20 74 68 65 20 6d 61 67 69 63 20 6e  n if the magic n
0c80: 75 6d 62 65 72 20 69 73 20 30 78 33 37 37 66 30  umber is 0x377f0
0c90: 36 38 32 2e 0a 2a 2a 20 54 68 65 20 63 68 65 63  682..** The chec
0ca0: 6b 73 75 6d 20 76 61 6c 75 65 73 20 61 72 65 20  ksum values are 
0cb0: 61 6c 77 61 79 73 20 73 74 6f 72 65 64 20 69 6e  always stored in
0cc0: 20 74 68 65 20 66 72 61 6d 65 20 68 65 61 64 65   the frame heade
0cd0: 72 20 69 6e 20 61 0a 2a 2a 20 62 69 67 2d 65 6e  r in a.** big-en
0ce0: 64 69 61 6e 20 66 6f 72 6d 61 74 20 72 65 67 61  dian format rega
0cf0: 72 64 6c 65 73 73 20 6f 66 20 77 68 69 63 68 20  rdless of which 
0d00: 62 79 74 65 20 6f 72 64 65 72 20 69 73 20 75 73  byte order is us
0d10: 65 64 20 74 6f 20 63 6f 6d 70 75 74 65 0a 2a 2a  ed to compute.**
0d20: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 2e 20 20   the checksum.  
0d30: 54 68 65 20 63 68 65 63 6b 73 75 6d 20 69 73 20  The checksum is 
0d40: 63 6f 6d 70 75 74 65 64 20 62 79 20 69 6e 74 65  computed by inte
0d50: 72 70 72 65 74 69 6e 67 20 74 68 65 20 69 6e 70  rpreting the inp
0d60: 75 74 20 61 73 0a 2a 2a 20 61 6e 20 65 76 65 6e  ut as.** an even
0d70: 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 73 69 67   number of unsig
0d80: 6e 65 64 20 33 32 2d 62 69 74 20 69 6e 74 65 67  ned 32-bit integ
0d90: 65 72 73 3a 20 78 5b 30 5d 20 74 68 72 6f 75 67  ers: x[0] throug
0da0: 68 20 78 5b 4e 5d 2e 20 20 54 68 65 0a 2a 2a 20  h x[N].  The.** 
0db0: 61 6c 67 6f 72 69 74 68 6d 20 75 73 65 64 20 66  algorithm used f
0dc0: 6f 72 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20  or the checksum 
0dd0: 69 73 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  is as follows:.*
0de0: 2a 20 0a 2a 2a 20 20 20 66 6f 72 20 69 20 66 72  * .**   for i fr
0df0: 6f 6d 20 30 20 74 6f 20 6e 2d 31 20 73 74 65 70  om 0 to n-1 step
0e00: 20 32 3a 0a 2a 2a 20 20 20 20 20 73 30 20 2b 3d   2:.**     s0 +=
0e10: 20 78 5b 69 5d 20 2b 20 73 31 3b 0a 2a 2a 20 20   x[i] + s1;.**  
0e20: 20 20 20 73 31 20 2b 3d 20 78 5b 69 2b 31 5d 20     s1 += x[i+1] 
0e30: 2b 20 73 30 3b 0a 2a 2a 20 20 20 65 6e 64 66 6f  + s0;.**   endfo
0e40: 72 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61  r.**.** Note tha
0e50: 74 20 73 30 20 61 6e 64 20 73 31 20 61 72 65 20  t s0 and s1 are 
0e60: 62 6f 74 68 20 77 65 69 67 68 74 65 64 20 63 68  both weighted ch
0e70: 65 63 6b 73 75 6d 73 20 75 73 69 6e 67 20 66 69  ecksums using fi
0e80: 62 6f 6e 61 63 63 69 20 77 65 69 67 68 74 73 0a  bonacci weights.
0e90: 2a 2a 20 69 6e 20 72 65 76 65 72 73 65 20 6f 72  ** in reverse or
0ea0: 64 65 72 20 28 74 68 65 20 6c 61 72 67 65 73 74  der (the largest
0eb0: 20 66 69 62 6f 6e 61 63 63 69 20 77 65 69 67 68   fibonacci weigh
0ec0: 74 20 6f 63 63 75 72 73 20 6f 6e 20 74 68 65 20  t occurs on the 
0ed0: 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 0a 2a 2a  first element.**
0ee0: 20 6f 66 20 74 68 65 20 73 65 71 75 65 6e 63 65   of the sequence
0ef0: 20 62 65 69 6e 67 20 73 75 6d 6d 65 64 2e 29 20   being summed.) 
0f00: 20 54 68 65 20 73 31 20 76 61 6c 75 65 20 73 70   The s1 value sp
0f10: 61 6e 73 20 61 6c 6c 20 33 32 2d 62 69 74 20 0a  ans all 32-bit .
0f20: 2a 2a 20 74 65 72 6d 73 20 6f 66 20 74 68 65 20  ** terms of the 
0f30: 73 65 71 75 65 6e 63 65 20 77 68 65 72 65 61 73  sequence whereas
0f40: 20 73 30 20 6f 6d 69 74 73 20 74 68 65 20 66 69   s0 omits the fi
0f50: 6e 61 6c 20 74 65 72 6d 2e 0a 2a 2a 0a 2a 2a 20  nal term..**.** 
0f60: 4f 6e 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c  On a checkpoint,
0f70: 20 74 68 65 20 57 41 4c 20 69 73 20 66 69 72 73   the WAL is firs
0f80: 74 20 56 46 53 2e 78 53 79 6e 63 2d 65 64 2c 20  t VFS.xSync-ed, 
0f90: 74 68 65 6e 20 76 61 6c 69 64 20 63 6f 6e 74 65  then valid conte
0fa0: 6e 74 20 6f 66 20 74 68 65 0a 2a 2a 20 57 41 4c  nt of the.** WAL
0fb0: 20 69 73 20 74 72 61 6e 73 66 65 72 72 65 64 20   is transferred 
0fc0: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
0fd0: 65 2c 20 74 68 65 6e 20 74 68 65 20 64 61 74 61  e, then the data
0fe0: 62 61 73 65 20 69 73 20 56 46 53 2e 78 53 79 6e  base is VFS.xSyn
0ff0: 63 2d 65 64 2e 0a 2a 2a 20 54 68 65 20 56 46 53  c-ed..** The VFS
1000: 2e 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e  .xSync operation
1010: 73 20 73 65 72 76 65 20 61 73 20 77 72 69 74 65  s serve as write
1020: 20 62 61 72 72 69 65 72 73 20 2d 20 61 6c 6c 20   barriers - all 
1030: 77 72 69 74 65 73 20 6c 61 75 6e 63 68 65 64 0a  writes launched.
1040: 2a 2a 20 62 65 66 6f 72 65 20 74 68 65 20 78 53  ** before the xS
1050: 79 6e 63 20 6d 75 73 74 20 63 6f 6d 70 6c 65 74  ync must complet
1060: 65 20 62 65 66 6f 72 65 20 61 6e 79 20 77 72 69  e before any wri
1070: 74 65 20 74 68 61 74 20 6c 61 75 6e 63 68 65 73  te that launches
1080: 20 61 66 74 65 72 20 74 68 65 0a 2a 2a 20 78 53   after the.** xS
1090: 79 6e 63 20 62 65 67 69 6e 73 2e 0a 2a 2a 0a 2a  ync begins..**.*
10a0: 2a 20 41 66 74 65 72 20 65 61 63 68 20 63 68 65  * After each che
10b0: 63 6b 70 6f 69 6e 74 2c 20 74 68 65 20 73 61 6c  ckpoint, the sal
10c0: 74 2d 31 20 76 61 6c 75 65 20 69 73 20 69 6e 63  t-1 value is inc
10d0: 72 65 6d 65 6e 74 65 64 20 61 6e 64 20 74 68 65  remented and the
10e0: 20 73 61 6c 74 2d 32 0a 2a 2a 20 76 61 6c 75 65   salt-2.** value
10f0: 20 69 73 20 72 61 6e 64 6f 6d 69 7a 65 64 2e 20   is randomized. 
1100: 20 54 68 69 73 20 70 72 65 76 65 6e 74 73 20 6f   This prevents o
1110: 6c 64 20 61 6e 64 20 6e 65 77 20 66 72 61 6d 65  ld and new frame
1120: 73 20 69 6e 20 74 68 65 20 57 41 4c 20 66 72 6f  s in the WAL fro
1130: 6d 0a 2a 2a 20 62 65 69 6e 67 20 63 6f 6e 73 69  m.** being consi
1140: 64 65 72 65 64 20 76 61 6c 69 64 20 61 74 20 74  dered valid at t
1150: 68 65 20 73 61 6d 65 20 74 69 6d 65 20 61 6e 64  he same time and
1160: 20 62 65 69 6e 67 20 63 68 65 63 6b 70 6f 69 6e   being checkpoin
1170: 74 69 6e 67 20 74 6f 67 65 74 68 65 72 0a 2a 2a  ting together.**
1180: 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 63 72 61   following a cra
1190: 73 68 2e 0a 2a 2a 0a 2a 2a 20 52 45 41 44 45 52  sh..**.** READER
11a0: 20 41 4c 47 4f 52 49 54 48 4d 0a 2a 2a 0a 2a 2a   ALGORITHM.**.**
11b0: 20 54 6f 20 72 65 61 64 20 61 20 70 61 67 65 20   To read a page 
11c0: 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
11d0: 65 20 28 63 61 6c 6c 20 69 74 20 70 61 67 65 20  e (call it page 
11e0: 6e 75 6d 62 65 72 20 50 29 2c 20 61 20 72 65 61  number P), a rea
11f0: 64 65 72 0a 2a 2a 20 66 69 72 73 74 20 63 68 65  der.** first che
1200: 63 6b 73 20 74 68 65 20 57 41 4c 20 74 6f 20 73  cks the WAL to s
1210: 65 65 20 69 66 20 69 74 20 63 6f 6e 74 61 69 6e  ee if it contain
1220: 73 20 70 61 67 65 20 50 2e 20 20 49 66 20 73 6f  s page P.  If so
1230: 2c 20 74 68 65 6e 20 74 68 65 0a 2a 2a 20 6c 61  , then the.** la
1240: 73 74 20 76 61 6c 69 64 20 69 6e 73 74 61 6e 63  st valid instanc
1250: 65 20 6f 66 20 70 61 67 65 20 50 20 74 68 61 74  e of page P that
1260: 20 69 73 20 61 20 66 6f 6c 6c 6f 77 65 64 20 62   is a followed b
1270: 79 20 61 20 63 6f 6d 6d 69 74 20 66 72 61 6d 65  y a commit frame
1280: 0a 2a 2a 20 6f 72 20 69 73 20 61 20 63 6f 6d 6d  .** or is a comm
1290: 69 74 20 66 72 61 6d 65 20 69 74 73 65 6c 66 20  it frame itself 
12a0: 62 65 63 6f 6d 65 73 20 74 68 65 20 76 61 6c 75  becomes the valu
12b0: 65 20 72 65 61 64 2e 20 20 49 66 20 74 68 65 20  e read.  If the 
12c0: 57 41 4c 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20  WAL.** contains 
12d0: 6e 6f 20 63 6f 70 69 65 73 20 6f 66 20 70 61 67  no copies of pag
12e0: 65 20 50 20 74 68 61 74 20 61 72 65 20 76 61 6c  e P that are val
12f0: 69 64 20 61 6e 64 20 77 68 69 63 68 20 61 72 65  id and which are
1300: 20 61 20 63 6f 6d 6d 69 74 0a 2a 2a 20 66 72 61   a commit.** fra
1310: 6d 65 20 6f 72 20 61 72 65 20 66 6f 6c 6c 6f 77  me or are follow
1320: 65 64 20 62 79 20 61 20 63 6f 6d 6d 69 74 20 66  ed by a commit f
1330: 72 61 6d 65 2c 20 74 68 65 6e 20 70 61 67 65 20  rame, then page 
1340: 50 20 69 73 20 72 65 61 64 20 66 72 6f 6d 0a 2a  P is read from.*
1350: 2a 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  * the database f
1360: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 73 74  ile..**.** To st
1370: 61 72 74 20 61 20 72 65 61 64 20 74 72 61 6e 73  art a read trans
1380: 61 63 74 69 6f 6e 2c 20 74 68 65 20 72 65 61 64  action, the read
1390: 65 72 20 72 65 63 6f 72 64 73 20 74 68 65 20 69  er records the i
13a0: 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 73 74  ndex of the last
13b0: 0a 2a 2a 20 76 61 6c 69 64 20 66 72 61 6d 65 20  .** valid frame 
13c0: 69 6e 20 74 68 65 20 57 41 4c 2e 20 20 54 68 65  in the WAL.  The
13d0: 20 72 65 61 64 65 72 20 75 73 65 73 20 74 68 69   reader uses thi
13e0: 73 20 72 65 63 6f 72 64 65 64 20 22 6d 78 46 72  s recorded "mxFr
13f0: 61 6d 65 22 20 76 61 6c 75 65 0a 2a 2a 20 66 6f  ame" value.** fo
1400: 72 20 61 6c 6c 20 73 75 62 73 65 71 75 65 6e 74  r all subsequent
1410: 20 72 65 61 64 20 6f 70 65 72 61 74 69 6f 6e 73   read operations
1420: 2e 20 20 4e 65 77 20 74 72 61 6e 73 61 63 74 69  .  New transacti
1430: 6f 6e 73 20 63 61 6e 20 62 65 20 61 70 70 65 6e  ons can be appen
1440: 64 65 64 0a 2a 2a 20 74 6f 20 74 68 65 20 57 41  ded.** to the WA
1450: 4c 2c 20 62 75 74 20 61 73 20 6c 6f 6e 67 20 61  L, but as long a
1460: 73 20 74 68 65 20 72 65 61 64 65 72 20 75 73 65  s the reader use
1470: 73 20 69 74 73 20 6f 72 69 67 69 6e 61 6c 20 6d  s its original m
1480: 78 46 72 61 6d 65 20 76 61 6c 75 65 0a 2a 2a 20  xFrame value.** 
1490: 61 6e 64 20 69 67 6e 6f 72 65 73 20 74 68 65 20  and ignores the 
14a0: 6e 65 77 6c 79 20 61 70 70 65 6e 64 65 64 20 63  newly appended c
14b0: 6f 6e 74 65 6e 74 2c 20 69 74 20 77 69 6c 6c 20  ontent, it will 
14c0: 73 65 65 20 61 20 63 6f 6e 73 69 73 74 65 6e 74  see a consistent
14d0: 20 73 6e 61 70 73 68 6f 74 0a 2a 2a 20 6f 66 20   snapshot.** of 
14e0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 72 6f  the database fro
14f0: 6d 20 61 20 73 69 6e 67 6c 65 20 70 6f 69 6e 74  m a single point
1500: 20 69 6e 20 74 69 6d 65 2e 20 20 54 68 69 73 20   in time.  This 
1510: 74 65 63 68 6e 69 71 75 65 20 61 6c 6c 6f 77 73  technique allows
1520: 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 63 6f 6e  .** multiple con
1530: 63 75 72 72 65 6e 74 20 72 65 61 64 65 72 73 20  current readers 
1540: 74 6f 20 76 69 65 77 20 64 69 66 66 65 72 65 6e  to view differen
1550: 74 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68  t versions of th
1560: 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 63 6f  e database.** co
1570: 6e 74 65 6e 74 20 73 69 6d 75 6c 74 61 6e 65 6f  ntent simultaneo
1580: 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  usly..**.** The 
1590: 72 65 61 64 65 72 20 61 6c 67 6f 72 69 74 68 6d  reader algorithm
15a0: 20 69 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73   in the previous
15b0: 20 70 61 72 61 67 72 61 70 68 73 20 77 6f 72 6b   paragraphs work
15c0: 73 20 63 6f 72 72 65 63 74 6c 79 2c 20 62 75 74  s correctly, but
15d0: 20 0a 2a 2a 20 62 65 63 61 75 73 65 20 66 72 61   .** because fra
15e0: 6d 65 73 20 66 6f 72 20 70 61 67 65 20 50 20 63  mes for page P c
15f0: 61 6e 20 61 70 70 65 61 72 20 61 6e 79 77 68 65  an appear anywhe
1600: 72 65 20 77 69 74 68 69 6e 20 74 68 65 20 57 41  re within the WA
1610: 4c 2c 20 74 68 65 0a 2a 2a 20 72 65 61 64 65 72  L, the.** reader
1620: 20 68 61 73 20 74 6f 20 73 63 61 6e 20 74 68 65   has to scan the
1630: 20 65 6e 74 69 72 65 20 57 41 4c 20 6c 6f 6f 6b   entire WAL look
1640: 69 6e 67 20 66 6f 72 20 70 61 67 65 20 50 20 66  ing for page P f
1650: 72 61 6d 65 73 2e 20 20 49 66 20 74 68 65 0a 2a  rames.  If the.*
1660: 2a 20 57 41 4c 20 69 73 20 6c 61 72 67 65 20 28  * WAL is large (
1670: 6d 75 6c 74 69 70 6c 65 20 6d 65 67 61 62 79 74  multiple megabyt
1680: 65 73 20 69 73 20 74 79 70 69 63 61 6c 29 20 74  es is typical) t
1690: 68 61 74 20 73 63 61 6e 20 63 61 6e 20 62 65 20  hat scan can be 
16a0: 73 6c 6f 77 2c 0a 2a 2a 20 61 6e 64 20 72 65 61  slow,.** and rea
16b0: 64 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 73 75  d performance su
16c0: 66 66 65 72 73 2e 20 20 54 6f 20 6f 76 65 72 63  ffers.  To overc
16d0: 6f 6d 65 20 74 68 69 73 20 70 72 6f 62 6c 65 6d  ome this problem
16e0: 2c 20 61 20 73 65 70 61 72 61 74 65 0a 2a 2a 20  , a separate.** 
16f0: 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20 63  data structure c
1700: 61 6c 6c 65 64 20 74 68 65 20 77 61 6c 2d 69 6e  alled the wal-in
1710: 64 65 78 20 69 73 20 6d 61 69 6e 74 61 69 6e 65  dex is maintaine
1720: 64 20 74 6f 20 65 78 70 65 64 69 74 65 20 74 68  d to expedite th
1730: 65 0a 2a 2a 20 73 65 61 72 63 68 20 66 6f 72 20  e.** search for 
1740: 66 72 61 6d 65 73 20 6f 66 20 61 20 70 61 72 74  frames of a part
1750: 69 63 75 6c 61 72 20 70 61 67 65 2e 0a 2a 2a 20  icular page..** 
1760: 0a 2a 2a 20 57 41 4c 2d 49 4e 44 45 58 20 46 4f  .** WAL-INDEX FO
1770: 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 43 6f 6e 63 65  RMAT.**.** Conce
1780: 70 74 75 61 6c 6c 79 2c 20 74 68 65 20 77 61 6c  ptually, the wal
1790: 2d 69 6e 64 65 78 20 69 73 20 73 68 61 72 65 64  -index is shared
17a0: 20 6d 65 6d 6f 72 79 2c 20 74 68 6f 75 67 68 20   memory, though 
17b0: 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  VFS implementati
17c0: 6f 6e 73 0a 2a 2a 20 6d 69 67 68 74 20 63 68 6f  ons.** might cho
17d0: 6f 73 65 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  ose to implement
17e0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 75   the wal-index u
17f0: 73 69 6e 67 20 61 20 6d 6d 61 70 70 65 64 20 66  sing a mmapped f
1800: 69 6c 65 2e 20 20 42 65 63 61 75 73 65 0a 2a 2a  ile.  Because.**
1810: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69   the wal-index i
1820: 73 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 2c  s shared memory,
1830: 20 53 51 4c 69 74 65 20 64 6f 65 73 20 6e 6f 74   SQLite does not
1840: 20 73 75 70 70 6f 72 74 20 6a 6f 75 72 6e 61 6c   support journal
1850: 5f 6d 6f 64 65 3d 57 41 4c 20 0a 2a 2a 20 6f 6e  _mode=WAL .** on
1860: 20 61 20 6e 65 74 77 6f 72 6b 20 66 69 6c 65 73   a network files
1870: 79 73 74 65 6d 2e 20 20 41 6c 6c 20 75 73 65 72  ystem.  All user
1880: 73 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  s of the databas
1890: 65 20 6d 75 73 74 20 62 65 20 61 62 6c 65 20 74  e must be able t
18a0: 6f 0a 2a 2a 20 73 68 61 72 65 20 6d 65 6d 6f 72  o.** share memor
18b0: 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61 6c  y..**.** The wal
18c0: 2d 69 6e 64 65 78 20 69 73 20 74 72 61 6e 73 69  -index is transi
18d0: 65 6e 74 2e 20 20 41 66 74 65 72 20 61 20 63 72  ent.  After a cr
18e0: 61 73 68 2c 20 74 68 65 20 77 61 6c 2d 69 6e 64  ash, the wal-ind
18f0: 65 78 20 63 61 6e 20 28 61 6e 64 20 73 68 6f 75  ex can (and shou
1900: 6c 64 0a 2a 2a 20 62 65 29 20 72 65 63 6f 6e 73  ld.** be) recons
1910: 74 72 75 63 74 65 64 20 66 72 6f 6d 20 74 68 65  tructed from the
1920: 20 6f 72 69 67 69 6e 61 6c 20 57 41 4c 20 66 69   original WAL fi
1930: 6c 65 2e 20 20 49 6e 20 66 61 63 74 2c 20 74 68  le.  In fact, th
1940: 65 20 56 46 53 20 69 73 20 72 65 71 75 69 72 65  e VFS is require
1950: 64 0a 2a 2a 20 74 6f 20 65 69 74 68 65 72 20 74  d.** to either t
1960: 72 75 6e 63 61 74 65 20 6f 72 20 7a 65 72 6f 20  runcate or zero 
1970: 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 74 68  the header of th
1980: 65 20 77 61 6c 2d 69 6e 64 65 78 20 77 68 65 6e  e wal-index when
1990: 20 74 68 65 20 6c 61 73 74 0a 2a 2a 20 63 6f 6e   the last.** con
19a0: 6e 65 63 74 69 6f 6e 20 74 6f 20 69 74 20 63 6c  nection to it cl
19b0: 6f 73 65 73 2e 20 20 42 65 63 61 75 73 65 20 74  oses.  Because t
19c0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
19d0: 74 72 61 6e 73 69 65 6e 74 2c 20 69 74 20 63 61  transient, it ca
19e0: 6e 0a 2a 2a 20 75 73 65 20 61 6e 20 61 72 63 68  n.** use an arch
19f0: 69 74 65 63 74 75 72 65 2d 73 70 65 63 69 66 69  itecture-specifi
1a00: 63 20 66 6f 72 6d 61 74 3b 20 69 74 20 64 6f 65  c format; it doe
1a10: 73 20 6e 6f 74 20 68 61 76 65 20 74 6f 20 62 65  s not have to be
1a20: 20 63 72 6f 73 73 2d 70 6c 61 74 66 6f 72 6d 2e   cross-platform.
1a30: 0a 2a 2a 20 48 65 6e 63 65 2c 20 75 6e 6c 69 6b  .** Hence, unlik
1a40: 65 20 74 68 65 20 64 61 74 61 62 61 73 65 20 61  e the database a
1a50: 6e 64 20 57 41 4c 20 66 69 6c 65 20 66 6f 72 6d  nd WAL file form
1a60: 61 74 73 20 77 68 69 63 68 20 73 74 6f 72 65 20  ats which store 
1a70: 61 6c 6c 20 76 61 6c 75 65 73 0a 2a 2a 20 61 73  all values.** as
1a80: 20 62 69 67 20 65 6e 64 69 61 6e 2c 20 74 68 65   big endian, the
1a90: 20 77 61 6c 2d 69 6e 64 65 78 20 63 61 6e 20 73   wal-index can s
1aa0: 74 6f 72 65 20 6d 75 6c 74 69 2d 62 79 74 65 20  tore multi-byte 
1ab0: 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 6e 61  values in the na
1ac0: 74 69 76 65 0a 2a 2a 20 62 79 74 65 20 6f 72 64  tive.** byte ord
1ad0: 65 72 20 6f 66 20 74 68 65 20 68 6f 73 74 20 63  er of the host c
1ae0: 6f 6d 70 75 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54  omputer..**.** T
1af0: 68 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74 68  he purpose of th
1b00: 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 74  e wal-index is t
1b10: 6f 20 61 6e 73 77 65 72 20 74 68 69 73 20 71 75  o answer this qu
1b20: 65 73 74 69 6f 6e 20 71 75 69 63 6b 6c 79 3a 20  estion quickly: 
1b30: 20 47 69 76 65 6e 0a 2a 2a 20 61 20 70 61 67 65   Given.** a page
1b40: 20 6e 75 6d 62 65 72 20 50 2c 20 72 65 74 75 72   number P, retur
1b50: 6e 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74  n the index of t
1b60: 68 65 20 6c 61 73 74 20 66 72 61 6d 65 20 66 6f  he last frame fo
1b70: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
1b80: 57 41 4c 2c 0a 2a 2a 20 6f 72 20 72 65 74 75 72  WAL,.** or retur
1b90: 6e 20 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20  n NULL if there 
1ba0: 61 72 65 20 6e 6f 20 66 72 61 6d 65 73 20 66 6f  are no frames fo
1bb0: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
1bc0: 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77  WAL..**.** The w
1bd0: 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69 73 74  al-index consist
1be0: 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 72 65  s of a header re
1bf0: 67 69 6f 6e 2c 20 66 6f 6c 6c 6f 77 65 64 20 62  gion, followed b
1c00: 79 20 61 6e 20 6f 6e 65 20 6f 72 0a 2a 2a 20 6d  y an one or.** m
1c10: 6f 72 65 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73  ore index blocks
1c20: 2e 20 20 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61  .  .**.** The wa
1c30: 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 63  l-index header c
1c40: 6f 6e 74 61 69 6e 73 20 74 68 65 20 74 6f 74 61  ontains the tota
1c50: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d  l number of fram
1c60: 65 73 20 77 69 74 68 69 6e 20 74 68 65 20 57 41  es within the WA
1c70: 4c 0a 2a 2a 20 69 6e 20 74 68 65 20 74 68 65 20  L.** in the the 
1c80: 6d 78 46 72 61 6d 65 20 66 69 65 6c 64 2e 20 20  mxFrame field.  
1c90: 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 69 6e 64 65  .**.** Each inde
1ca0: 78 20 62 6c 6f 63 6b 20 65 78 63 65 70 74 20 66  x block except f
1cb0: 6f 72 20 74 68 65 20 66 69 72 73 74 20 63 6f 6e  or the first con
1cc0: 74 61 69 6e 73 20 69 6e 66 6f 72 6d 61 74 69 6f  tains informatio
1cd0: 6e 20 6f 6e 20 0a 2a 2a 20 48 41 53 48 54 41 42  n on .** HASHTAB
1ce0: 4c 45 5f 4e 50 41 47 45 20 66 72 61 6d 65 73 2e  LE_NPAGE frames.
1cf0: 20 54 68 65 20 66 69 72 73 74 20 69 6e 64 65 78   The first index
1d00: 20 62 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20   block contains 
1d10: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f 6e 0a 2a  information on.*
1d20: 2a 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  * HASHTABLE_NPAG
1d30: 45 5f 4f 4e 45 20 66 72 61 6d 65 73 2e 20 54 68  E_ONE frames. Th
1d40: 65 20 76 61 6c 75 65 73 20 6f 66 20 48 41 53 48  e values of HASH
1d50: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20  TABLE_NPAGE_ONE 
1d60: 61 6e 64 20 0a 2a 2a 20 48 41 53 48 54 41 42 4c  and .** HASHTABL
1d70: 45 5f 4e 50 41 47 45 20 61 72 65 20 73 65 6c 65  E_NPAGE are sele
1d80: 63 74 65 64 20 73 6f 20 74 68 61 74 20 74 6f 67  cted so that tog
1d90: 65 74 68 65 72 20 74 68 65 20 77 61 6c 2d 69 6e  ether the wal-in
1da0: 64 65 78 20 68 65 61 64 65 72 20 61 6e 64 0a 2a  dex header and.*
1db0: 2a 20 66 69 72 73 74 20 69 6e 64 65 78 20 62 6c  * first index bl
1dc0: 6f 63 6b 20 61 72 65 20 74 68 65 20 73 61 6d 65  ock are the same
1dd0: 20 73 69 7a 65 20 61 73 20 61 6c 6c 20 6f 74 68   size as all oth
1de0: 65 72 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73 20  er index blocks 
1df0: 69 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e  in the.** wal-in
1e00: 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20  dex..**.** Each 
1e10: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 63 6f 6e 74  index block cont
1e20: 61 69 6e 73 20 74 77 6f 20 73 65 63 74 69 6f 6e  ains two section
1e30: 73 2c 20 61 20 70 61 67 65 2d 6d 61 70 70 69 6e  s, a page-mappin
1e40: 67 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  g that contains 
1e50: 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20  the.** database 
1e60: 70 61 67 65 20 6e 75 6d 62 65 72 20 61 73 73 6f  page number asso
1e70: 63 69 61 74 65 64 20 77 69 74 68 20 65 61 63 68  ciated with each
1e80: 20 77 61 6c 20 66 72 61 6d 65 2c 20 61 6e 64 20   wal frame, and 
1e90: 61 20 68 61 73 68 2d 74 61 62 6c 65 20 0a 2a 2a  a hash-table .**
1ea0: 20 74 68 61 74 20 61 6c 6c 6f 77 73 20 72 65 61   that allows rea
1eb0: 64 65 72 73 20 74 6f 20 71 75 65 72 79 20 61 6e  ders to query an
1ec0: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 66 6f 72   index block for
1ed0: 20 61 20 73 70 65 63 69 66 69 63 20 70 61 67 65   a specific page
1ee0: 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 54 68 65 20   number..** The 
1ef0: 70 61 67 65 2d 6d 61 70 70 69 6e 67 20 69 73 20  page-mapping is 
1f00: 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53 48  an array of HASH
1f10: 54 41 42 4c 45 5f 4e 50 41 47 45 20 28 6f 72 20  TABLE_NPAGE (or 
1f20: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
1f30: 4f 4e 45 0a 2a 2a 20 66 6f 72 20 74 68 65 20 66  ONE.** for the f
1f40: 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b  irst index block
1f50: 29 20 33 32 2d 62 69 74 20 70 61 67 65 20 6e 75  ) 32-bit page nu
1f60: 6d 62 65 72 73 2e 20 54 68 65 20 66 69 72 73 74  mbers. The first
1f70: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 0a 2a   entry in the .*
1f80: 2a 20 66 69 72 73 74 20 69 6e 64 65 78 2d 62 6c  * first index-bl
1f90: 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  ock contains the
1fa0: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6e   database page n
1fb0: 75 6d 62 65 72 20 63 6f 72 72 65 73 70 6f 6e 64  umber correspond
1fc0: 69 6e 67 20 74 6f 20 74 68 65 0a 2a 2a 20 66 69  ing to the.** fi
1fd0: 72 73 74 20 66 72 61 6d 65 20 69 6e 20 74 68 65  rst frame in the
1fe0: 20 57 41 4c 20 66 69 6c 65 2e 20 54 68 65 20 66   WAL file. The f
1ff0: 69 72 73 74 20 65 6e 74 72 79 20 69 6e 20 74 68  irst entry in th
2000: 65 20 73 65 63 6f 6e 64 20 69 6e 64 65 78 20 62  e second index b
2010: 6c 6f 63 6b 0a 2a 2a 20 69 6e 20 74 68 65 20 57  lock.** in the W
2020: 41 4c 20 66 69 6c 65 20 63 6f 72 72 65 73 70 6f  AL file correspo
2030: 6e 64 73 20 74 6f 20 74 68 65 20 28 48 41 53 48  nds to the (HASH
2040: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b  TABLE_NPAGE_ONE+
2050: 31 29 74 68 20 66 72 61 6d 65 20 69 6e 0a 2a 2a  1)th frame in.**
2060: 20 74 68 65 20 6c 6f 67 2c 20 61 6e 64 20 73 6f   the log, and so
2070: 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c   on..**.** The l
2080: 61 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20  ast index block 
2090: 69 6e 20 61 20 77 61 6c 2d 69 6e 64 65 78 20 75  in a wal-index u
20a0: 73 75 61 6c 6c 79 20 63 6f 6e 74 61 69 6e 73 20  sually contains 
20b0: 6c 65 73 73 20 74 68 61 6e 20 74 68 65 20 66 75  less than the fu
20c0: 6c 6c 0a 2a 2a 20 63 6f 6d 70 6c 65 6d 65 6e 74  ll.** complement
20d0: 20 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e 50   of HASHTABLE_NP
20e0: 41 47 45 20 28 6f 72 20 48 41 53 48 54 41 42 4c  AGE (or HASHTABL
20f0: 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 20 70 61 67  E_NPAGE_ONE) pag
2100: 65 2d 6e 75 6d 62 65 72 73 2c 0a 2a 2a 20 64 65  e-numbers,.** de
2110: 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20 63  pending on the c
2120: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 57  ontents of the W
2130: 41 4c 20 66 69 6c 65 2e 20 54 68 69 73 20 64 6f  AL file. This do
2140: 65 73 20 6e 6f 74 20 63 68 61 6e 67 65 20 74 68  es not change th
2150: 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74 65 64 20 73  e.** allocated s
2160: 69 7a 65 20 6f 66 20 74 68 65 20 70 61 67 65 2d  ize of the page-
2170: 6d 61 70 70 69 6e 67 20 61 72 72 61 79 20 2d 20  mapping array - 
2180: 74 68 65 20 70 61 67 65 2d 6d 61 70 70 69 6e 67  the page-mapping
2190: 20 61 72 72 61 79 20 6d 65 72 65 6c 79 0a 2a 2a   array merely.**
21a0: 20 63 6f 6e 74 61 69 6e 73 20 75 6e 75 73 65 64   contains unused
21b0: 20 65 6e 74 72 69 65 73 2e 0a 2a 2a 0a 2a 2a 20   entries..**.** 
21c0: 45 76 65 6e 20 77 69 74 68 6f 75 74 20 75 73 69  Even without usi
21d0: 6e 67 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ng the hash tabl
21e0: 65 2c 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d  e, the last fram
21f0: 65 20 66 6f 72 20 70 61 67 65 20 50 0a 2a 2a 20  e for page P.** 
2200: 63 61 6e 20 62 65 20 66 6f 75 6e 64 20 62 79 20  can be found by 
2210: 73 63 61 6e 6e 69 6e 67 20 74 68 65 20 70 61 67  scanning the pag
2220: 65 2d 6d 61 70 70 69 6e 67 20 73 65 63 74 69 6f  e-mapping sectio
2230: 6e 73 20 6f 66 20 65 61 63 68 20 69 6e 64 65 78  ns of each index
2240: 20 62 6c 6f 63 6b 0a 2a 2a 20 73 74 61 72 74 69   block.** starti
2250: 6e 67 20 77 69 74 68 20 74 68 65 20 6c 61 73 74  ng with the last
2260: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 61 6e 64   index block and
2270: 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20 74   moving toward t
2280: 68 65 20 66 69 72 73 74 2c 20 61 6e 64 0a 2a 2a  he first, and.**
2290: 20 77 69 74 68 69 6e 20 65 61 63 68 20 69 6e 64   within each ind
22a0: 65 78 20 62 6c 6f 63 6b 2c 20 73 74 61 72 74 69  ex block, starti
22b0: 6e 67 20 61 74 20 74 68 65 20 65 6e 64 20 61 6e  ng at the end an
22c0: 64 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20  d moving toward 
22d0: 74 68 65 0a 2a 2a 20 62 65 67 69 6e 6e 69 6e 67  the.** beginning
22e0: 2e 20 20 54 68 65 20 66 69 72 73 74 20 65 6e 74  .  The first ent
22f0: 72 79 20 74 68 61 74 20 65 71 75 61 6c 73 20 50  ry that equals P
2300: 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20   corresponds to 
2310: 74 68 65 20 66 72 61 6d 65 0a 2a 2a 20 68 6f 6c  the frame.** hol
2320: 64 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74  ding the content
2330: 20 66 6f 72 20 74 68 61 74 20 70 61 67 65 2e 0a   for that page..
2340: 2a 2a 0a 2a 2a 20 54 68 65 20 68 61 73 68 20 74  **.** The hash t
2350: 61 62 6c 65 20 63 6f 6e 73 69 73 74 73 20 6f 66  able consists of
2360: 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54   HASHTABLE_NSLOT
2370: 20 31 36 2d 62 69 74 20 75 6e 73 69 67 6e 65 64   16-bit unsigned
2380: 20 69 6e 74 65 67 65 72 73 2e 0a 2a 2a 20 48 41   integers..** HA
2390: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 3d 20  SHTABLE_NSLOT = 
23a0: 32 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  2*HASHTABLE_NPAG
23b0: 45 2c 20 61 6e 64 20 74 68 65 72 65 20 69 73 20  E, and there is 
23c0: 6f 6e 65 20 65 6e 74 72 79 20 69 6e 20 74 68 65  one entry in the
23d0: 0a 2a 2a 20 68 61 73 68 20 74 61 62 6c 65 20 66  .** hash table f
23e0: 6f 72 20 65 61 63 68 20 70 61 67 65 20 6e 75 6d  or each page num
23f0: 62 65 72 20 69 6e 20 74 68 65 20 6d 61 70 70 69  ber in the mappi
2400: 6e 67 20 73 65 63 74 69 6f 6e 2c 20 73 6f 20 74  ng section, so t
2410: 68 65 20 68 61 73 68 20 0a 2a 2a 20 74 61 62 6c  he hash .** tabl
2420: 65 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20  e is never more 
2430: 74 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2e 20  than half full. 
2440: 20 54 68 65 20 65 78 70 65 63 74 65 64 20 6e 75   The expected nu
2450: 6d 62 65 72 20 6f 66 20 63 6f 6c 6c 69 73 69 6f  mber of collisio
2460: 6e 73 20 0a 2a 2a 20 70 72 69 6f 72 20 74 6f 20  ns .** prior to 
2470: 66 69 6e 64 69 6e 67 20 61 20 6d 61 74 63 68 20  finding a match 
2480: 69 73 20 31 2e 20 20 45 61 63 68 20 65 6e 74 72  is 1.  Each entr
2490: 79 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61  y of the hash ta
24a0: 62 6c 65 20 69 73 20 61 6e 0a 2a 2a 20 31 2d 62  ble is an.** 1-b
24b0: 61 73 65 64 20 69 6e 64 65 78 20 6f 66 20 61 6e  ased index of an
24c0: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61   entry in the ma
24d0: 70 70 69 6e 67 20 73 65 63 74 69 6f 6e 20 6f 66  pping section of
24e0: 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20 69 6e 64   the same.** ind
24f0: 65 78 20 62 6c 6f 63 6b 2e 20 20 20 4c 65 74 20  ex block.   Let 
2500: 4b 20 62 65 20 74 68 65 20 31 2d 62 61 73 65 64  K be the 1-based
2510: 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61   index of the la
2520: 72 67 65 73 74 20 65 6e 74 72 79 20 69 6e 0a 2a  rgest entry in.*
2530: 2a 20 74 68 65 20 6d 61 70 70 69 6e 67 20 73 65  * the mapping se
2540: 63 74 69 6f 6e 2e 20 20 28 46 6f 72 20 69 6e 64  ction.  (For ind
2550: 65 78 20 62 6c 6f 63 6b 73 20 6f 74 68 65 72 20  ex blocks other 
2560: 74 68 61 6e 20 74 68 65 20 6c 61 73 74 2c 20 4b  than the last, K
2570: 20 77 69 6c 6c 0a 2a 2a 20 61 6c 77 61 79 73 20   will.** always 
2580: 62 65 20 65 78 61 63 74 6c 79 20 48 41 53 48 54  be exactly HASHT
2590: 41 42 4c 45 5f 4e 50 41 47 45 20 28 34 30 39 36  ABLE_NPAGE (4096
25a0: 29 20 61 6e 64 20 66 6f 72 20 74 68 65 20 6c 61  ) and for the la
25b0: 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 0a 2a  st index block.*
25c0: 2a 20 4b 20 77 69 6c 6c 20 62 65 20 28 6d 78 46  * K will be (mxF
25d0: 72 61 6d 65 25 48 41 53 48 54 41 42 4c 45 5f 4e  rame%HASHTABLE_N
25e0: 50 41 47 45 29 2e 29 20 20 55 6e 75 73 65 64 20  PAGE).)  Unused 
25f0: 73 6c 6f 74 73 20 6f 66 20 74 68 65 20 68 61 73  slots of the has
2600: 68 20 74 61 62 6c 65 0a 2a 2a 20 63 6f 6e 74 61  h table.** conta
2610: 69 6e 20 61 20 76 61 6c 75 65 20 6f 66 20 30 2e  in a value of 0.
2620: 0a 2a 2a 0a 2a 2a 20 54 6f 20 6c 6f 6f 6b 20 66  .**.** To look f
2630: 6f 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65  or page P in the
2640: 20 68 61 73 68 20 74 61 62 6c 65 2c 20 66 69 72   hash table, fir
2650: 73 74 20 63 6f 6d 70 75 74 65 20 61 20 68 61 73  st compute a has
2660: 68 20 69 4b 65 79 20 6f 6e 0a 2a 2a 20 50 20 61  h iKey on.** P a
2670: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a  s follows:.**.**
2680: 20 20 20 20 20 20 69 4b 65 79 20 3d 20 28 50 20        iKey = (P 
2690: 2a 20 33 38 33 29 20 25 20 48 41 53 48 54 41 42  * 383) % HASHTAB
26a0: 4c 45 5f 4e 53 4c 4f 54 0a 2a 2a 0a 2a 2a 20 54  LE_NSLOT.**.** T
26b0: 68 65 6e 20 73 74 61 72 74 20 73 63 61 6e 6e 69  hen start scanni
26c0: 6e 67 20 65 6e 74 72 69 65 73 20 6f 66 20 74 68  ng entries of th
26d0: 65 20 68 61 73 68 20 74 61 62 6c 65 2c 20 73 74  e hash table, st
26e0: 61 72 74 69 6e 67 20 77 69 74 68 20 69 4b 65 79  arting with iKey
26f0: 0a 2a 2a 20 28 77 72 61 70 70 69 6e 67 20 61 72  .** (wrapping ar
2700: 6f 75 6e 64 20 74 6f 20 74 68 65 20 62 65 67 69  ound to the begi
2710: 6e 6e 69 6e 67 20 77 68 65 6e 20 74 68 65 20 65  nning when the e
2720: 6e 64 20 6f 66 20 74 68 65 20 68 61 73 68 20 74  nd of the hash t
2730: 61 62 6c 65 20 69 73 0a 2a 2a 20 72 65 61 63 68  able is.** reach
2740: 65 64 29 20 75 6e 74 69 6c 20 61 6e 20 75 6e 75  ed) until an unu
2750: 73 65 64 20 68 61 73 68 20 73 6c 6f 74 20 69 73  sed hash slot is
2760: 20 66 6f 75 6e 64 2e 20 4c 65 74 20 74 68 65 20   found. Let the 
2770: 66 69 72 73 74 20 75 6e 75 73 65 64 20 73 6c 6f  first unused slo
2780: 74 0a 2a 2a 20 62 65 20 61 74 20 69 6e 64 65 78  t.** be at index
2790: 20 69 55 6e 75 73 65 64 2e 20 20 28 69 55 6e 75   iUnused.  (iUnu
27a0: 73 65 64 20 6d 69 67 68 74 20 62 65 20 6c 65 73  sed might be les
27b0: 73 20 74 68 61 6e 20 69 4b 65 79 20 69 66 20 74  s than iKey if t
27c0: 68 65 72 65 20 77 61 73 0a 2a 2a 20 77 72 61 70  here was.** wrap
27d0: 2d 61 72 6f 75 6e 64 2e 29 20 42 65 63 61 75 73  -around.) Becaus
27e0: 65 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  e the hash table
27f0: 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20 74   is never more t
2800: 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2c 0a 2a  han half full,.*
2810: 2a 20 74 68 65 20 73 65 61 72 63 68 20 69 73 20  * the search is 
2820: 67 75 61 72 61 6e 74 65 65 64 20 74 6f 20 65 76  guaranteed to ev
2830: 65 6e 74 75 61 6c 6c 79 20 68 69 74 20 61 6e 20  entually hit an 
2840: 75 6e 75 73 65 64 20 65 6e 74 72 79 2e 20 20 4c  unused entry.  L
2850: 65 74 20 0a 2a 2a 20 69 4d 61 78 20 62 65 20 74  et .** iMax be t
2860: 68 65 20 76 61 6c 75 65 20 62 65 74 77 65 65 6e  he value between
2870: 20 69 4b 65 79 20 61 6e 64 20 69 55 6e 75 73 65   iKey and iUnuse
2880: 64 2c 20 63 6c 6f 73 65 73 74 20 74 6f 20 69 55  d, closest to iU
2890: 6e 75 73 65 64 2c 0a 2a 2a 20 77 68 65 72 65 20  nused,.** where 
28a0: 61 48 61 73 68 5b 69 4d 61 78 5d 3d 3d 50 2e 20  aHash[iMax]==P. 
28b0: 20 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20   If there is no 
28c0: 69 4d 61 78 20 65 6e 74 72 79 20 28 69 66 20 74  iMax entry (if t
28d0: 68 65 72 65 20 65 78 69 73 74 73 0a 2a 2a 20 6e  here exists.** n
28e0: 6f 20 68 61 73 68 20 73 6c 6f 74 20 73 75 63 68  o hash slot such
28f0: 20 74 68 61 74 20 61 48 61 73 68 5b 69 5d 3d 3d   that aHash[i]==
2900: 70 29 20 74 68 65 6e 20 70 61 67 65 20 50 20 69  p) then page P i
2910: 73 20 6e 6f 74 20 69 6e 20 74 68 65 0a 2a 2a 20  s not in the.** 
2920: 63 75 72 72 65 6e 74 20 69 6e 64 65 78 20 62 6c  current index bl
2930: 6f 63 6b 2e 20 20 4f 74 68 65 72 77 69 73 65 20  ock.  Otherwise 
2940: 74 68 65 20 69 4d 61 78 2d 74 68 20 6d 61 70 70  the iMax-th mapp
2950: 69 6e 67 20 65 6e 74 72 79 20 6f 66 20 74 68 65  ing entry of the
2960: 0a 2a 2a 20 63 75 72 72 65 6e 74 20 69 6e 64 65  .** current inde
2970: 78 20 62 6c 6f 63 6b 20 63 6f 72 72 65 73 70 6f  x block correspo
2980: 6e 64 73 20 74 6f 20 74 68 65 20 6c 61 73 74 20  nds to the last 
2990: 65 6e 74 72 79 20 74 68 61 74 20 72 65 66 65 72  entry that refer
29a0: 65 6e 63 65 73 20 0a 2a 2a 20 70 61 67 65 20 50  ences .** page P
29b0: 2e 0a 2a 2a 0a 2a 2a 20 41 20 68 61 73 68 20 73  ..**.** A hash s
29c0: 65 61 72 63 68 20 62 65 67 69 6e 73 20 77 69 74  earch begins wit
29d0: 68 20 74 68 65 20 6c 61 73 74 20 69 6e 64 65 78  h the last index
29e0: 20 62 6c 6f 63 6b 20 61 6e 64 20 6d 6f 76 65 73   block and moves
29f0: 20 74 6f 77 61 72 64 20 74 68 65 0a 2a 2a 20 66   toward the.** f
2a00: 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b  irst index block
2a10: 2c 20 6c 6f 6f 6b 69 6e 67 20 66 6f 72 20 65 6e  , looking for en
2a20: 74 72 69 65 73 20 63 6f 72 72 65 73 70 6f 6e 64  tries correspond
2a30: 69 6e 67 20 74 6f 20 70 61 67 65 20 50 2e 20 20  ing to page P.  
2a40: 4f 6e 0a 2a 2a 20 61 76 65 72 61 67 65 2c 20 6f  On.** average, o
2a50: 6e 6c 79 20 74 77 6f 20 6f 72 20 74 68 72 65 65  nly two or three
2a60: 20 73 6c 6f 74 73 20 69 6e 20 65 61 63 68 20 69   slots in each i
2a70: 6e 64 65 78 20 62 6c 6f 63 6b 20 6e 65 65 64 20  ndex block need 
2a80: 74 6f 20 62 65 0a 2a 2a 20 65 78 61 6d 69 6e 65  to be.** examine
2a90: 64 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 65 69  d in order to ei
2aa0: 74 68 65 72 20 66 69 6e 64 20 74 68 65 20 6c 61  ther find the la
2ab0: 73 74 20 65 6e 74 72 79 20 66 6f 72 20 70 61 67  st entry for pag
2ac0: 65 20 50 2c 20 6f 72 20 74 6f 0a 2a 2a 20 65 73  e P, or to.** es
2ad0: 74 61 62 6c 69 73 68 20 74 68 61 74 20 6e 6f 20  tablish that no 
2ae0: 73 75 63 68 20 65 6e 74 72 79 20 65 78 69 73 74  such entry exist
2af0: 73 20 69 6e 20 74 68 65 20 62 6c 6f 63 6b 2e 20  s in the block. 
2b00: 20 45 61 63 68 20 69 6e 64 65 78 20 62 6c 6f 63   Each index bloc
2b10: 6b 0a 2a 2a 20 68 6f 6c 64 73 20 6f 76 65 72 20  k.** holds over 
2b20: 34 30 30 30 20 65 6e 74 72 69 65 73 2e 20 20 53  4000 entries.  S
2b30: 6f 20 74 77 6f 20 6f 72 20 74 68 72 65 65 20 69  o two or three i
2b40: 6e 64 65 78 20 62 6c 6f 63 6b 73 20 61 72 65 20  ndex blocks are 
2b50: 73 75 66 66 69 63 69 65 6e 74 0a 2a 2a 20 74 6f  sufficient.** to
2b60: 20 63 6f 76 65 72 20 61 20 74 79 70 69 63 61 6c   cover a typical
2b70: 20 31 30 20 6d 65 67 61 62 79 74 65 20 57 41 4c   10 megabyte WAL
2b80: 20 66 69 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20   file, assuming 
2b90: 31 4b 20 70 61 67 65 73 2e 20 20 38 20 6f 72 20  1K pages.  8 or 
2ba0: 31 30 0a 2a 2a 20 63 6f 6d 70 61 72 69 73 6f 6e  10.** comparison
2bb0: 73 20 28 6f 6e 20 61 76 65 72 61 67 65 29 20 73  s (on average) s
2bc0: 75 66 66 69 63 65 20 74 6f 20 65 69 74 68 65 72  uffice to either
2bd0: 20 6c 6f 63 61 74 65 20 61 20 66 72 61 6d 65 20   locate a frame 
2be0: 69 6e 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6f 72  in the.** WAL or
2bf0: 20 74 6f 20 65 73 74 61 62 6c 69 73 68 20 74 68   to establish th
2c00: 61 74 20 74 68 65 20 66 72 61 6d 65 20 64 6f 65  at the frame doe
2c10: 73 20 6e 6f 74 20 65 78 69 73 74 20 69 6e 20 74  s not exist in t
2c20: 68 65 20 57 41 4c 2e 20 20 54 68 69 73 0a 2a 2a  he WAL.  This.**
2c30: 20 69 73 20 6d 75 63 68 20 66 61 73 74 65 72 20   is much faster 
2c40: 74 68 61 6e 20 73 63 61 6e 6e 69 6e 67 20 74 68  than scanning th
2c50: 65 20 65 6e 74 69 72 65 20 31 30 4d 42 20 57 41  e entire 10MB WA
2c60: 4c 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68  L..**.** Note th
2c70: 61 74 20 65 6e 74 72 69 65 73 20 61 72 65 20 61  at entries are a
2c80: 64 64 65 64 20 69 6e 20 6f 72 64 65 72 20 6f 66  dded in order of
2c90: 20 69 6e 63 72 65 61 73 69 6e 67 20 4b 2e 20 20   increasing K.  
2ca0: 48 65 6e 63 65 2c 20 6f 6e 65 0a 2a 2a 20 72 65  Hence, one.** re
2cb0: 61 64 65 72 20 6d 69 67 68 74 20 62 65 20 75 73  ader might be us
2cc0: 69 6e 67 20 73 6f 6d 65 20 76 61 6c 75 65 20 4b  ing some value K
2cd0: 30 20 61 6e 64 20 61 20 73 65 63 6f 6e 64 20 72  0 and a second r
2ce0: 65 61 64 65 72 20 74 68 61 74 20 73 74 61 72 74  eader that start
2cf0: 65 64 0a 2a 2a 20 61 74 20 61 20 6c 61 74 65 72  ed.** at a later
2d00: 20 74 69 6d 65 20 28 61 66 74 65 72 20 61 64 64   time (after add
2d10: 69 74 69 6f 6e 61 6c 20 74 72 61 6e 73 61 63 74  itional transact
2d20: 69 6f 6e 73 20 77 65 72 65 20 61 64 64 65 64 20  ions were added 
2d30: 74 6f 20 74 68 65 20 57 41 4c 0a 2a 2a 20 61 6e  to the WAL.** an
2d40: 64 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64  d to the wal-ind
2d50: 65 78 29 20 6d 69 67 68 74 20 62 65 20 75 73 69  ex) might be usi
2d60: 6e 67 20 61 20 64 69 66 66 65 72 65 6e 74 20 76  ng a different v
2d70: 61 6c 75 65 20 4b 31 2c 20 77 68 65 72 65 20 4b  alue K1, where K
2d80: 31 3e 4b 30 2e 0a 2a 2a 20 42 6f 74 68 20 72 65  1>K0..** Both re
2d90: 61 64 65 72 73 20 63 61 6e 20 75 73 65 20 74 68  aders can use th
2da0: 65 20 73 61 6d 65 20 68 61 73 68 20 74 61 62 6c  e same hash tabl
2db0: 65 20 61 6e 64 20 6d 61 70 70 69 6e 67 20 73 65  e and mapping se
2dc0: 63 74 69 6f 6e 20 74 6f 20 67 65 74 0a 2a 2a 20  ction to get.** 
2dd0: 74 68 65 20 63 6f 72 72 65 63 74 20 72 65 73 75  the correct resu
2de0: 6c 74 2e 20 20 54 68 65 72 65 20 6d 61 79 20 62  lt.  There may b
2df0: 65 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65  e entries in the
2e00: 20 68 61 73 68 20 74 61 62 6c 65 20 77 69 74 68   hash table with
2e10: 0a 2a 2a 20 4b 3e 4b 30 20 62 75 74 20 74 6f 20  .** K>K0 but to 
2e20: 74 68 65 20 66 69 72 73 74 20 72 65 61 64 65 72  the first reader
2e30: 2c 20 74 68 6f 73 65 20 65 6e 74 72 69 65 73 20  , those entries 
2e40: 77 69 6c 6c 20 61 70 70 65 61 72 20 74 6f 20 62  will appear to b
2e50: 65 20 75 6e 75 73 65 64 0a 2a 2a 20 73 6c 6f 74  e unused.** slot
2e60: 73 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61  s in the hash ta
2e70: 62 6c 65 20 61 6e 64 20 73 6f 20 74 68 65 20 66  ble and so the f
2e80: 69 72 73 74 20 72 65 61 64 65 72 20 77 69 6c 6c  irst reader will
2e90: 20 67 65 74 20 61 6e 20 61 6e 73 77 65 72 20 61   get an answer a
2ea0: 73 0a 2a 2a 20 69 66 20 6e 6f 20 76 61 6c 75 65  s.** if no value
2eb0: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 4b  s greater than K
2ec0: 30 20 68 61 64 20 65 76 65 72 20 62 65 65 6e 20  0 had ever been 
2ed0: 69 6e 73 65 72 74 65 64 20 69 6e 74 6f 20 74 68  inserted into th
2ee0: 65 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20  e hash table.** 
2ef0: 69 6e 20 74 68 65 20 66 69 72 73 74 20 70 6c 61  in the first pla
2f00: 63 65 20 2d 20 77 68 69 63 68 20 69 73 20 77 68  ce - which is wh
2f10: 61 74 20 72 65 61 64 65 72 20 6f 6e 65 20 77 61  at reader one wa
2f20: 6e 74 73 2e 20 20 4d 65 61 6e 77 68 69 6c 65 2c  nts.  Meanwhile,
2f30: 20 74 68 65 0a 2a 2a 20 73 65 63 6f 6e 64 20 72   the.** second r
2f40: 65 61 64 65 72 20 75 73 69 6e 67 20 4b 31 20 77  eader using K1 w
2f50: 69 6c 6c 20 73 65 65 20 61 64 64 69 74 69 6f 6e  ill see addition
2f60: 61 6c 20 76 61 6c 75 65 73 20 74 68 61 74 20 77  al values that w
2f70: 65 72 65 20 69 6e 73 65 72 74 65 64 0a 2a 2a 20  ere inserted.** 
2f80: 6c 61 74 65 72 2c 20 77 68 69 63 68 20 69 73 20  later, which is 
2f90: 65 78 61 63 74 6c 79 20 77 68 61 74 20 72 65 61  exactly what rea
2fa0: 64 65 72 20 74 77 6f 20 77 61 6e 74 73 2e 20 20  der two wants.  
2fb0: 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 61 20 72 6f  .**.** When a ro
2fc0: 6c 6c 62 61 63 6b 20 6f 63 63 75 72 73 2c 20 74  llback occurs, t
2fd0: 68 65 20 76 61 6c 75 65 20 6f 66 20 4b 20 69 73  he value of K is
2fe0: 20 64 65 63 72 65 61 73 65 64 2e 20 48 61 73 68   decreased. Hash
2ff0: 20 74 61 62 6c 65 20 65 6e 74 72 69 65 73 0a 2a   table entries.*
3000: 2a 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  * that correspon
3010: 64 20 74 6f 20 66 72 61 6d 65 73 20 67 72 65 61  d to frames grea
3020: 74 65 72 20 74 68 61 6e 20 74 68 65 20 6e 65 77  ter than the new
3030: 20 4b 20 76 61 6c 75 65 20 61 72 65 20 72 65 6d   K value are rem
3040: 6f 76 65 64 0a 2a 2a 20 66 72 6f 6d 20 74 68 65  oved.** from the
3050: 20 68 61 73 68 20 74 61 62 6c 65 20 61 74 20 74   hash table at t
3060: 68 69 73 20 70 6f 69 6e 74 2e 0a 2a 2f 0a 23 69  his point..*/.#i
3070: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
3080: 54 5f 57 41 4c 0a 0a 23 69 6e 63 6c 75 64 65 20  T_WAL..#include 
3090: 22 77 61 6c 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 54  "wal.h"../*.** T
30a0: 72 61 63 65 20 6f 75 74 70 75 74 20 6d 61 63 72  race output macr
30b0: 6f 73 0a 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65  os.*/.#if define
30c0: 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26  d(SQLITE_TEST) &
30d0: 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  & defined(SQLITE
30e0: 5f 44 45 42 55 47 29 0a 69 6e 74 20 73 71 6c 69  _DEBUG).int sqli
30f0: 74 65 33 57 61 6c 54 72 61 63 65 20 3d 20 30 3b  te3WalTrace = 0;
3100: 0a 23 20 64 65 66 69 6e 65 20 57 41 4c 54 52 41  .# define WALTRA
3110: 43 45 28 58 29 20 20 69 66 28 73 71 6c 69 74 65  CE(X)  if(sqlite
3120: 33 57 61 6c 54 72 61 63 65 29 20 73 71 6c 69 74  3WalTrace) sqlit
3130: 65 33 44 65 62 75 67 50 72 69 6e 74 66 20 58 0a  e3DebugPrintf X.
3140: 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 57  #else.# define W
3150: 41 4c 54 52 41 43 45 28 58 29 0a 23 65 6e 64 69  ALTRACE(X).#endi
3160: 66 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 78  f../*.** The max
3170: 69 6d 75 6d 20 28 61 6e 64 20 6f 6e 6c 79 29 20  imum (and only) 
3180: 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68 65 20  versions of the 
3190: 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65  wal and wal-inde
31a0: 78 20 66 6f 72 6d 61 74 73 0a 2a 2a 20 74 68 61  x formats.** tha
31b0: 74 20 6d 61 79 20 62 65 20 69 6e 74 65 72 70 72  t may be interpr
31c0: 65 74 65 64 20 62 79 20 74 68 69 73 20 76 65 72  eted by this ver
31d0: 73 69 6f 6e 20 6f 66 20 53 51 4c 69 74 65 2e 0a  sion of SQLite..
31e0: 2a 2a 0a 2a 2a 20 49 66 20 61 20 63 6c 69 65 6e  **.** If a clien
31f0: 74 20 62 65 67 69 6e 73 20 72 65 63 6f 76 65 72  t begins recover
3200: 69 6e 67 20 61 20 57 41 4c 20 66 69 6c 65 20 61  ing a WAL file a
3210: 6e 64 20 66 69 6e 64 73 20 74 68 61 74 20 28 61  nd finds that (a
3220: 29 20 74 68 65 20 63 68 65 63 6b 73 75 6d 0a 2a  ) the checksum.*
3230: 2a 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20  * values in the 
3240: 77 61 6c 2d 68 65 61 64 65 72 20 61 72 65 20 63  wal-header are c
3250: 6f 72 72 65 63 74 20 61 6e 64 20 28 62 29 20 74  orrect and (b) t
3260: 68 65 20 76 65 72 73 69 6f 6e 20 66 69 65 6c 64  he version field
3270: 20 69 73 20 6e 6f 74 0a 2a 2a 20 57 41 4c 5f 4d   is not.** WAL_M
3280: 41 58 5f 56 45 52 53 49 4f 4e 2c 20 72 65 63 6f  AX_VERSION, reco
3290: 76 65 72 79 20 66 61 69 6c 73 20 61 6e 64 20 53  very fails and S
32a0: 51 4c 69 74 65 20 72 65 74 75 72 6e 73 20 53 51  QLite returns SQ
32b0: 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2e 0a 2a  LITE_CANTOPEN..*
32c0: 2a 0a 2a 2a 20 53 69 6d 69 6c 61 72 6c 79 2c 20  *.** Similarly, 
32d0: 69 66 20 61 20 63 6c 69 65 6e 74 20 73 75 63 63  if a client succ
32e0: 65 73 73 66 75 6c 6c 79 20 72 65 61 64 73 20 61  essfully reads a
32f0: 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
3300: 72 20 28 69 2e 65 2e 20 74 68 65 20 0a 2a 2a 20  r (i.e. the .** 
3310: 63 68 65 63 6b 73 75 6d 20 74 65 73 74 20 69 73  checksum test is
3320: 20 73 75 63 63 65 73 73 66 75 6c 29 20 61 6e 64   successful) and
3330: 20 66 69 6e 64 73 20 74 68 61 74 20 74 68 65 20   finds that the 
3340: 76 65 72 73 69 6f 6e 20 66 69 65 6c 64 20 69 73  version field is
3350: 20 6e 6f 74 0a 2a 2a 20 57 41 4c 49 4e 44 45 58   not.** WALINDEX
3360: 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 2c 20 74 68  _MAX_VERSION, th
3370: 65 6e 20 6e 6f 20 72 65 61 64 2d 74 72 61 6e 73  en no read-trans
3380: 61 63 74 69 6f 6e 20 69 73 20 6f 70 65 6e 65 64  action is opened
3390: 20 61 6e 64 20 53 51 4c 69 74 65 0a 2a 2a 20 72   and SQLite.** r
33a0: 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 43 41  eturns SQLITE_CA
33b0: 4e 54 4f 50 45 4e 2e 0a 2a 2f 0a 23 64 65 66 69  NTOPEN..*/.#defi
33c0: 6e 65 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49  ne WAL_MAX_VERSI
33d0: 4f 4e 20 20 20 20 20 20 33 30 30 37 30 30 30 0a  ON      3007000.
33e0: 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58  #define WALINDEX
33f0: 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 20 33 30 30  _MAX_VERSION 300
3400: 37 30 30 30 0a 0a 2f 2a 0a 2a 2a 20 49 6e 64 69  7000../*.** Indi
3410: 63 65 73 20 6f 66 20 76 61 72 69 6f 75 73 20 6c  ces of various l
3420: 6f 63 6b 69 6e 67 20 62 79 74 65 73 2e 20 20 20  ocking bytes.   
3430: 57 41 4c 5f 4e 52 45 41 44 45 52 20 69 73 20 74  WAL_NREADER is t
3440: 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20  he number.** of 
3450: 61 76 61 69 6c 61 62 6c 65 20 72 65 61 64 65 72  available reader
3460: 20 6c 6f 63 6b 73 20 61 6e 64 20 73 68 6f 75 6c   locks and shoul
3470: 64 20 62 65 20 61 74 20 6c 65 61 73 74 20 33 2e  d be at least 3.
3480: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f  .*/.#define WAL_
3490: 57 52 49 54 45 5f 4c 4f 43 4b 20 20 20 20 20 20  WRITE_LOCK      
34a0: 20 20 20 30 0a 23 64 65 66 69 6e 65 20 57 41 4c     0.#define WAL
34b0: 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 20  _ALL_BUT_WRITE  
34c0: 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41      1.#define WA
34d0: 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 20 20 20 20  L_CKPT_LOCK     
34e0: 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57       1.#define W
34f0: 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20  AL_RECOVER_LOCK 
3500: 20 20 20 20 20 20 32 0a 23 64 65 66 69 6e 65 20        2.#define 
3510: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 49 29  WAL_READ_LOCK(I)
3520: 20 20 20 20 20 20 20 28 33 2b 28 49 29 29 0a 23         (3+(I)).#
3530: 64 65 66 69 6e 65 20 57 41 4c 5f 4e 52 45 41 44  define WAL_NREAD
3540: 45 52 20 20 20 20 20 20 20 20 20 20 20 20 28 53  ER            (S
3550: 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 2d  QLITE_SHM_NLOCK-
3560: 33 29 0a 0a 0a 2f 2a 20 4f 62 6a 65 63 74 20 64  3).../* Object d
3570: 65 63 6c 61 72 61 74 69 6f 6e 73 20 2a 2f 0a 74  eclarations */.t
3580: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61  ypedef struct Wa
3590: 6c 49 6e 64 65 78 48 64 72 20 57 61 6c 49 6e 64  lIndexHdr WalInd
35a0: 65 78 48 64 72 3b 0a 74 79 70 65 64 65 66 20 73  exHdr;.typedef s
35b0: 74 72 75 63 74 20 57 61 6c 49 74 65 72 61 74 6f  truct WalIterato
35c0: 72 20 57 61 6c 49 74 65 72 61 74 6f 72 3b 0a 74  r WalIterator;.t
35d0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61  ypedef struct Wa
35e0: 6c 43 6b 70 74 49 6e 66 6f 20 57 61 6c 43 6b 70  lCkptInfo WalCkp
35f0: 74 49 6e 66 6f 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54  tInfo;.../*.** T
3600: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a  he following obj
3610: 65 63 74 20 68 6f 6c 64 73 20 61 20 63 6f 70 79  ect holds a copy
3620: 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
3630: 78 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74  x header content
3640: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63 74 75  ..**.** The actu
3650: 61 6c 20 68 65 61 64 65 72 20 69 6e 20 74 68 65  al header in the
3660: 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69   wal-index consi
3670: 73 74 73 20 6f 66 20 74 77 6f 20 63 6f 70 69 65  sts of two copie
3680: 73 20 6f 66 20 74 68 69 73 0a 2a 2a 20 6f 62 6a  s of this.** obj
3690: 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 73  ect..**.** The s
36a0: 7a 50 61 67 65 20 76 61 6c 75 65 20 63 61 6e 20  zPage value can 
36b0: 62 65 20 61 6e 79 20 70 6f 77 65 72 20 6f 66 20  be any power of 
36c0: 32 20 62 65 74 77 65 65 6e 20 35 31 32 20 61 6e  2 between 512 an
36d0: 64 20 33 32 37 36 38 2c 20 69 6e 63 6c 75 73 69  d 32768, inclusi
36e0: 76 65 2e 0a 2a 2a 20 4f 72 20 69 74 20 63 61 6e  ve..** Or it can
36f0: 20 62 65 20 31 20 74 6f 20 72 65 70 72 65 73 65   be 1 to represe
3700: 6e 74 20 61 20 36 35 35 33 36 2d 62 79 74 65 20  nt a 65536-byte 
3710: 70 61 67 65 2e 20 20 54 68 65 20 6c 61 74 74 65  page.  The latte
3720: 72 20 63 61 73 65 20 77 61 73 0a 2a 2a 20 61 64  r case was.** ad
3730: 64 65 64 20 69 6e 20 33 2e 37 2e 31 20 77 68 65  ded in 3.7.1 whe
3740: 6e 20 73 75 70 70 6f 72 74 20 66 6f 72 20 36 34  n support for 64
3750: 4b 20 70 61 67 65 73 20 77 61 73 20 61 64 64 65  K pages was adde
3760: 64 2e 20 20 0a 2a 2f 0a 73 74 72 75 63 74 20 57  d.  .*/.struct W
3770: 61 6c 49 6e 64 65 78 48 64 72 20 7b 0a 20 20 75  alIndexHdr {.  u
3780: 33 32 20 69 56 65 72 73 69 6f 6e 3b 20 20 20 20  32 iVersion;    
3790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
37a0: 2a 20 57 61 6c 2d 69 6e 64 65 78 20 76 65 72 73  * Wal-index vers
37b0: 69 6f 6e 20 2a 2f 0a 20 20 75 33 32 20 75 6e 75  ion */.  u32 unu
37c0: 73 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  sed;            
37d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 75 73           /* Unus
37e0: 65 64 20 28 70 61 64 64 69 6e 67 29 20 66 69 65  ed (padding) fie
37f0: 6c 64 20 2a 2f 0a 20 20 75 33 32 20 69 43 68 61  ld */.  u32 iCha
3800: 6e 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  nge;            
3810: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74          /* Count
3820: 65 72 20 69 6e 63 72 65 6d 65 6e 74 65 64 20 65  er incremented e
3830: 61 63 68 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ach transaction 
3840: 2a 2f 0a 20 20 75 38 20 69 73 49 6e 69 74 3b 20  */.  u8 isInit; 
3850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3860: 20 20 20 20 20 2f 2a 20 31 20 77 68 65 6e 20 69       /* 1 when i
3870: 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20  nitialized */.  
3880: 75 38 20 62 69 67 45 6e 64 43 6b 73 75 6d 3b 20  u8 bigEndCksum; 
3890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38a0: 2f 2a 20 54 72 75 65 20 69 66 20 63 68 65 63 6b  /* True if check
38b0: 73 75 6d 73 20 69 6e 20 57 41 4c 20 61 72 65 20  sums in WAL are 
38c0: 62 69 67 2d 65 6e 64 69 61 6e 20 2a 2f 0a 20 20  big-endian */.  
38d0: 75 31 36 20 73 7a 50 61 67 65 3b 20 20 20 20 20  u16 szPage;     
38e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38f0: 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  /* Database page
3900: 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 2e 20   size in bytes. 
3910: 31 3d 3d 36 34 4b 20 2a 2f 0a 20 20 75 33 32 20  1==64K */.  u32 
3920: 6d 78 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20  mxFrame;        
3930: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
3940: 6e 64 65 78 20 6f 66 20 6c 61 73 74 20 76 61 6c  ndex of last val
3950: 69 64 20 66 72 61 6d 65 20 69 6e 20 74 68 65 20  id frame in the 
3960: 57 41 4c 20 2a 2f 0a 20 20 75 33 32 20 6e 50 61  WAL */.  u32 nPa
3970: 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ge;             
3980: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65           /* Size
3990: 20 6f 66 20 64 61 74 61 62 61 73 65 20 69 6e 20   of database in 
39a0: 70 61 67 65 73 20 2a 2f 0a 20 20 75 33 32 20 61  pages */.  u32 a
39b0: 46 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 3b 20 20  FrameCksum[2];  
39c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68             /* Ch
39d0: 65 63 6b 73 75 6d 20 6f 66 20 6c 61 73 74 20 66  ecksum of last f
39e0: 72 61 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20  rame in log */. 
39f0: 20 75 33 32 20 61 53 61 6c 74 5b 32 5d 3b 20 20   u32 aSalt[2];  
3a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a10: 20 2f 2a 20 54 77 6f 20 73 61 6c 74 20 76 61 6c   /* Two salt val
3a20: 75 65 73 20 63 6f 70 69 65 64 20 66 72 6f 6d 20  ues copied from 
3a30: 57 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a 20 20  WAL header */.  
3a40: 75 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20 20  u32 aCksum[2];  
3a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3a60: 2f 2a 20 43 68 65 63 6b 73 75 6d 20 6f 76 65 72  /* Checksum over
3a70: 20 61 6c 6c 20 70 72 69 6f 72 20 66 69 65 6c 64   all prior field
3a80: 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41  s */.};../*.** A
3a90: 20 63 6f 70 79 20 6f 66 20 74 68 65 20 66 6f 6c   copy of the fol
3aa0: 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 6f 63  lowing object oc
3ab0: 63 75 72 73 20 69 6e 20 74 68 65 20 77 61 6c 2d  curs in the wal-
3ac0: 69 6e 64 65 78 20 69 6d 6d 65 64 69 61 74 65 6c  index immediatel
3ad0: 79 0a 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20 74  y.** following t
3ae0: 68 65 20 73 65 63 6f 6e 64 20 63 6f 70 79 20 6f  he second copy o
3af0: 66 20 74 68 65 20 57 61 6c 49 6e 64 65 78 48 64  f the WalIndexHd
3b00: 72 2e 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20  r.  This object 
3b10: 73 74 6f 72 65 73 0a 2a 2a 20 69 6e 66 6f 72 6d  stores.** inform
3b20: 61 74 69 6f 6e 20 75 73 65 64 20 62 79 20 63 68  ation used by ch
3b30: 65 63 6b 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20  eckpoint..**.** 
3b40: 6e 42 61 63 6b 66 69 6c 6c 20 69 73 20 74 68 65  nBackfill is the
3b50: 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d 65   number of frame
3b60: 73 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68 61  s in the WAL tha
3b70: 74 20 68 61 76 65 20 62 65 65 6e 20 77 72 69 74  t have been writ
3b80: 74 65 6e 0a 2a 2a 20 62 61 63 6b 20 69 6e 74 6f  ten.** back into
3b90: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 28   the database. (
3ba0: 57 65 20 63 61 6c 6c 20 74 68 65 20 61 63 74 20  We call the act 
3bb0: 6f 66 20 6d 6f 76 69 6e 67 20 63 6f 6e 74 65 6e  of moving conten
3bc0: 74 20 66 72 6f 6d 20 57 41 4c 20 74 6f 0a 2a 2a  t from WAL to.**
3bd0: 20 64 61 74 61 62 61 73 65 20 22 62 61 63 6b 66   database "backf
3be0: 69 6c 6c 69 6e 67 22 2e 29 20 20 54 68 65 20 6e  illing".)  The n
3bf0: 42 61 63 6b 66 69 6c 6c 20 6e 75 6d 62 65 72 20  Backfill number 
3c00: 69 73 20 6e 65 76 65 72 20 67 72 65 61 74 65 72  is never greater
3c10: 20 74 68 61 6e 0a 2a 2a 20 57 61 6c 49 6e 64 65   than.** WalInde
3c20: 78 48 64 72 2e 6d 78 46 72 61 6d 65 2e 20 20 6e  xHdr.mxFrame.  n
3c30: 42 61 63 6b 66 69 6c 6c 20 63 61 6e 20 6f 6e 6c  Backfill can onl
3c40: 79 20 62 65 20 69 6e 63 72 65 61 73 65 64 20 62  y be increased b
3c50: 79 20 74 68 72 65 61 64 73 0a 2a 2a 20 68 6f 6c  y threads.** hol
3c60: 64 69 6e 67 20 74 68 65 20 57 41 4c 5f 43 4b 50  ding the WAL_CKP
3c70: 54 5f 4c 4f 43 4b 20 6c 6f 63 6b 20 28 77 68 69  T_LOCK lock (whi
3c80: 63 68 20 69 6e 63 6c 75 64 65 73 20 61 20 72 65  ch includes a re
3c90: 63 6f 76 65 72 79 20 74 68 72 65 61 64 29 2e 0a  covery thread)..
3ca0: 2a 2a 20 48 6f 77 65 76 65 72 2c 20 61 20 57 41  ** However, a WA
3cb0: 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 74 68 72  L_WRITE_LOCK thr
3cc0: 65 61 64 20 63 61 6e 20 6d 6f 76 65 20 74 68 65  ead can move the
3cd0: 20 76 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b 66   value of nBackf
3ce0: 69 6c 6c 20 66 72 6f 6d 0a 2a 2a 20 6d 78 46 72  ill from.** mxFr
3cf0: 61 6d 65 20 62 61 63 6b 20 74 6f 20 7a 65 72 6f  ame back to zero
3d00: 20 77 68 65 6e 20 74 68 65 20 57 41 4c 20 69 73   when the WAL is
3d10: 20 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 54 68   reset..**.** Th
3d20: 65 72 65 20 69 73 20 6f 6e 65 20 65 6e 74 72 79  ere is one entry
3d30: 20 69 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20   in aReadMark[] 
3d40: 66 6f 72 20 65 61 63 68 20 72 65 61 64 65 72 20  for each reader 
3d50: 6c 6f 63 6b 2e 20 20 49 66 20 61 20 72 65 61 64  lock.  If a read
3d60: 65 72 0a 2a 2a 20 68 6f 6c 64 73 20 72 65 61 64  er.** holds read
3d70: 2d 6c 6f 63 6b 20 4b 2c 20 74 68 65 6e 20 74 68  -lock K, then th
3d80: 65 20 76 61 6c 75 65 20 69 6e 20 61 52 65 61 64  e value in aRead
3d90: 4d 61 72 6b 5b 4b 5d 20 69 73 20 6e 6f 20 67 72  Mark[K] is no gr
3da0: 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 74 68  eater than.** th
3db0: 65 20 6d 78 46 72 61 6d 65 20 66 6f 72 20 74 68  e mxFrame for th
3dc0: 61 74 20 72 65 61 64 65 72 2e 20 20 54 68 65 20  at reader.  The 
3dd0: 76 61 6c 75 65 20 52 45 41 44 4d 41 52 4b 5f 4e  value READMARK_N
3de0: 4f 54 5f 55 53 45 44 20 28 30 78 66 66 66 66 66  OT_USED (0xfffff
3df0: 66 66 66 29 0a 2a 2a 20 66 6f 72 20 61 6e 79 20  fff).** for any 
3e00: 61 52 65 61 64 4d 61 72 6b 5b 5d 20 6d 65 61 6e  aReadMark[] mean
3e10: 73 20 74 68 61 74 20 65 6e 74 72 79 20 69 73 20  s that entry is 
3e20: 75 6e 75 73 65 64 2e 20 20 61 52 65 61 64 4d 61  unused.  aReadMa
3e30: 72 6b 5b 30 5d 20 69 73 20 0a 2a 2a 20 61 20 73  rk[0] is .** a s
3e40: 70 65 63 69 61 6c 20 63 61 73 65 3b 20 69 74 73  pecial case; its
3e50: 20 76 61 6c 75 65 20 69 73 20 6e 65 76 65 72 20   value is never 
3e60: 75 73 65 64 20 61 6e 64 20 69 74 20 65 78 69 73  used and it exis
3e70: 74 73 20 61 73 20 61 20 70 6c 61 63 65 2d 68 6f  ts as a place-ho
3e80: 6c 64 65 72 0a 2a 2a 20 74 6f 20 61 76 6f 69 64  lder.** to avoid
3e90: 20 68 61 76 69 6e 67 20 74 6f 20 6f 66 66 73 65   having to offse
3ea0: 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 69 6e  t aReadMark[] in
3eb0: 64 65 78 73 20 62 79 20 6f 6e 65 2e 20 20 52 65  dexs by one.  Re
3ec0: 61 64 65 72 73 20 68 6f 6c 64 69 6e 67 0a 2a 2a  aders holding.**
3ed0: 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
3ee0: 29 20 61 6c 77 61 79 73 20 69 67 6e 6f 72 65 20  ) always ignore 
3ef0: 74 68 65 20 65 6e 74 69 72 65 20 57 41 4c 20 61  the entire WAL a
3f00: 6e 64 20 72 65 61 64 20 61 6c 6c 20 63 6f 6e 74  nd read all cont
3f10: 65 6e 74 0a 2a 2a 20 64 69 72 65 63 74 6c 79 20  ent.** directly 
3f20: 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
3f30: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 6c  e..**.** The val
3f40: 75 65 20 6f 66 20 61 52 65 61 64 4d 61 72 6b 5b  ue of aReadMark[
3f50: 4b 5d 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20 63  K] may only be c
3f60: 68 61 6e 67 65 64 20 62 79 20 61 20 74 68 72 65  hanged by a thre
3f70: 61 64 20 74 68 61 74 0a 2a 2a 20 69 73 20 68 6f  ad that.** is ho
3f80: 6c 64 69 6e 67 20 61 6e 20 65 78 63 6c 75 73 69  lding an exclusi
3f90: 76 65 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52  ve lock on WAL_R
3fa0: 45 41 44 5f 4c 4f 43 4b 28 4b 29 2e 20 20 54 68  EAD_LOCK(K).  Th
3fb0: 75 73 2c 20 74 68 65 20 76 61 6c 75 65 20 6f 66  us, the value of
3fc0: 0a 2a 2a 20 61 52 65 61 64 4d 61 72 6b 5b 4b 5d  .** aReadMark[K]
3fd0: 20 63 61 6e 6e 6f 74 20 63 68 61 6e 67 65 64 20   cannot changed 
3fe0: 77 68 69 6c 65 20 74 68 65 72 65 20 69 73 20 61  while there is a
3ff0: 20 72 65 61 64 65 72 20 69 73 20 75 73 69 6e 67   reader is using
4000: 20 74 68 61 74 20 6d 61 72 6b 0a 2a 2a 20 73 69   that mark.** si
4010: 6e 63 65 20 74 68 65 20 72 65 61 64 65 72 20 77  nce the reader w
4020: 69 6c 6c 20 62 65 20 68 6f 6c 64 69 6e 67 20 61  ill be holding a
4030: 20 73 68 61 72 65 64 20 6c 6f 63 6b 20 6f 6e 20   shared lock on 
4040: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 4b 29  WAL_READ_LOCK(K)
4050: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63  ..**.** The chec
4060: 6b 70 6f 69 6e 74 65 72 20 6d 61 79 20 6f 6e 6c  kpointer may onl
4070: 79 20 74 72 61 6e 73 66 65 72 20 66 72 61 6d 65  y transfer frame
4080: 73 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64 61  s from WAL to da
4090: 74 61 62 61 73 65 20 77 68 65 72 65 0a 2a 2a 20  tabase where.** 
40a0: 74 68 65 20 66 72 61 6d 65 20 6e 75 6d 62 65 72  the frame number
40b0: 73 20 61 72 65 20 6c 65 73 73 20 74 68 61 6e 20  s are less than 
40c0: 6f 72 20 65 71 75 61 6c 20 74 6f 20 65 76 65 72  or equal to ever
40d0: 79 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 74 68  y aReadMark[] th
40e0: 61 74 20 69 73 0a 2a 2a 20 69 6e 20 75 73 65 20  at is.** in use 
40f0: 28 74 68 61 74 20 69 73 2c 20 65 76 65 72 79 20  (that is, every 
4100: 61 52 65 61 64 4d 61 72 6b 5b 6a 5d 20 66 6f 72  aReadMark[j] for
4110: 20 77 68 69 63 68 20 74 68 65 72 65 20 69 73 20   which there is 
4120: 61 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a  a corresponding.
4130: 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  ** WAL_READ_LOCK
4140: 28 6a 29 29 2e 20 20 4e 65 77 20 72 65 61 64 65  (j)).  New reade
4150: 72 73 20 28 75 73 75 61 6c 6c 79 29 20 70 69 63  rs (usually) pic
4160: 6b 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b  k the aReadMark[
4170: 5d 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 6c 61  ] with the.** la
4180: 72 67 65 73 74 20 76 61 6c 75 65 20 61 6e 64 20  rgest value and 
4190: 77 69 6c 6c 20 69 6e 63 72 65 61 73 65 20 61 6e  will increase an
41a0: 20 75 6e 75 73 65 64 20 61 52 65 61 64 4d 61 72   unused aReadMar
41b0: 6b 5b 5d 20 74 6f 20 6d 78 46 72 61 6d 65 20 69  k[] to mxFrame i
41c0: 66 20 74 68 65 72 65 0a 2a 2a 20 69 73 20 6e 6f  f there.** is no
41d0: 74 20 61 6c 72 65 61 64 79 20 61 6e 20 61 52 65  t already an aRe
41e0: 61 64 4d 61 72 6b 5b 5d 20 65 71 75 61 6c 20 74  adMark[] equal t
41f0: 6f 20 6d 78 46 72 61 6d 65 2e 20 20 54 68 65 20  o mxFrame.  The 
4200: 65 78 63 65 70 74 69 6f 6e 20 74 6f 20 74 68 65  exception to the
4210: 0a 2a 2a 20 70 72 65 76 69 6f 75 73 20 73 65 6e  .** previous sen
4220: 74 65 6e 63 65 20 69 73 20 77 68 65 6e 20 6e 42  tence is when nB
4230: 61 63 6b 66 69 6c 6c 20 65 71 75 61 6c 73 20 6d  ackfill equals m
4240: 78 46 72 61 6d 65 20 28 6d 65 61 6e 69 6e 67 20  xFrame (meaning 
4250: 74 68 61 74 20 65 76 65 72 79 74 68 69 6e 67 0a  that everything.
4260: 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 68 61  ** in the WAL ha
4270: 73 20 62 65 65 6e 20 62 61 63 6b 66 69 6c 6c 65  s been backfille
4280: 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  d into the datab
4290: 61 73 65 29 20 74 68 65 6e 20 6e 65 77 20 72 65  ase) then new re
42a0: 61 64 65 72 73 0a 2a 2a 20 77 69 6c 6c 20 63 68  aders.** will ch
42b0: 6f 6f 73 65 20 61 52 65 61 64 4d 61 72 6b 5b 30  oose aReadMark[0
42c0: 5d 20 77 68 69 63 68 20 68 61 73 20 76 61 6c 75  ] which has valu
42d0: 65 20 30 20 61 6e 64 20 68 65 6e 63 65 20 73 75  e 0 and hence su
42e0: 63 68 20 72 65 61 64 65 72 20 77 69 6c 6c 0a 2a  ch reader will.*
42f0: 2a 20 67 65 74 20 61 6c 6c 20 74 68 65 69 72 20  * get all their 
4300: 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72 65  all content dire
4310: 63 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61  ctly from the da
4320: 74 61 62 61 73 65 20 66 69 6c 65 20 61 6e 64 20  tabase file and 
4330: 69 67 6e 6f 72 65 20 0a 2a 2a 20 74 68 65 20 57  ignore .** the W
4340: 41 4c 2e 0a 2a 2a 0a 2a 2a 20 57 72 69 74 65 72  AL..**.** Writer
4350: 73 20 6e 6f 72 6d 61 6c 6c 79 20 61 70 70 65 6e  s normally appen
4360: 64 20 6e 65 77 20 66 72 61 6d 65 73 20 74 6f 20  d new frames to 
4370: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 57  the end of the W
4380: 41 4c 2e 20 20 48 6f 77 65 76 65 72 2c 0a 2a 2a  AL.  However,.**
4390: 20 69 66 20 6e 42 61 63 6b 66 69 6c 6c 20 65 71   if nBackfill eq
43a0: 75 61 6c 73 20 6d 78 46 72 61 6d 65 20 28 6d 65  uals mxFrame (me
43b0: 61 6e 69 6e 67 20 74 68 61 74 20 61 6c 6c 20 57  aning that all W
43c0: 41 4c 20 63 6f 6e 74 65 6e 74 20 68 61 73 20 62  AL content has b
43d0: 65 65 6e 0a 2a 2a 20 77 72 69 74 74 65 6e 20 62  een.** written b
43e0: 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74  ack into the dat
43f0: 61 62 61 73 65 29 20 61 6e 64 20 69 66 20 6e 6f  abase) and if no
4400: 20 72 65 61 64 65 72 73 20 61 72 65 20 75 73 69   readers are usi
4410: 6e 67 20 74 68 65 20 57 41 4c 0a 2a 2a 20 28 69  ng the WAL.** (i
4420: 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c 20 69  n other words, i
4430: 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 57  f there are no W
4440: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 20  AL_READ_LOCK(i) 
4450: 77 68 65 72 65 20 69 3e 30 29 20 74 68 65 6e 0a  where i>0) then.
4460: 2a 2a 20 74 68 65 20 77 72 69 74 65 72 20 77 69  ** the writer wi
4470: 6c 6c 20 66 69 72 73 74 20 22 72 65 73 65 74 22  ll first "reset"
4480: 20 74 68 65 20 57 41 4c 20 62 61 63 6b 20 74 6f   the WAL back to
4490: 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 61   the beginning a
44a0: 6e 64 20 73 74 61 72 74 0a 2a 2a 20 77 72 69 74  nd start.** writ
44b0: 69 6e 67 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20  ing new content 
44c0: 62 65 67 69 6e 6e 69 6e 67 20 61 74 20 66 72 61  beginning at fra
44d0: 6d 65 20 31 2e 0a 2a 2a 0a 2a 2a 20 57 65 20 61  me 1..**.** We a
44e0: 73 73 75 6d 65 20 74 68 61 74 20 33 32 2d 62 69  ssume that 32-bi
44f0: 74 20 6c 6f 61 64 73 20 61 72 65 20 61 74 6f 6d  t loads are atom
4500: 69 63 20 61 6e 64 20 73 6f 20 6e 6f 20 6c 6f 63  ic and so no loc
4510: 6b 73 20 61 72 65 20 6e 65 65 64 65 64 20 69 6e  ks are needed in
4520: 0a 2a 2a 20 6f 72 64 65 72 20 74 6f 20 72 65 61  .** order to rea
4530: 64 20 66 72 6f 6d 20 61 6e 79 20 61 52 65 61 64  d from any aRead
4540: 4d 61 72 6b 5b 5d 20 65 6e 74 72 69 65 73 2e 0a  Mark[] entries..
4550: 2a 2f 0a 73 74 72 75 63 74 20 57 61 6c 43 6b 70  */.struct WalCkp
4560: 74 49 6e 66 6f 20 7b 0a 20 20 75 33 32 20 6e 42  tInfo {.  u32 nB
4570: 61 63 6b 66 69 6c 6c 3b 20 20 20 20 20 20 20 20  ackfill;        
4580: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
4590: 62 65 72 20 6f 66 20 57 41 4c 20 66 72 61 6d 65  ber of WAL frame
45a0: 73 20 62 61 63 6b 66 69 6c 6c 65 64 20 69 6e 74  s backfilled int
45b0: 6f 20 44 42 20 2a 2f 0a 20 20 75 33 32 20 61 52  o DB */.  u32 aR
45c0: 65 61 64 4d 61 72 6b 5b 57 41 4c 5f 4e 52 45 41  eadMark[WAL_NREA
45d0: 44 45 52 5d 3b 20 20 20 20 20 2f 2a 20 52 65 61  DER];     /* Rea
45e0: 64 65 72 20 6d 61 72 6b 73 20 2a 2f 0a 7d 3b 0a  der marks */.};.
45f0: 23 64 65 66 69 6e 65 20 52 45 41 44 4d 41 52 4b  #define READMARK
4600: 5f 4e 4f 54 5f 55 53 45 44 20 20 30 78 66 66 66  _NOT_USED  0xfff
4610: 66 66 66 66 66 0a 0a 0a 2f 2a 20 41 20 62 6c 6f  fffff.../* A blo
4620: 63 6b 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f 4c  ck of WALINDEX_L
4630: 4f 43 4b 5f 52 45 53 45 52 56 45 44 20 62 79 74  OCK_RESERVED byt
4640: 65 73 20 62 65 67 69 6e 6e 69 6e 67 20 61 74 0a  es beginning at.
4650: 2a 2a 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b  ** WALINDEX_LOCK
4660: 5f 4f 46 46 53 45 54 20 69 73 20 72 65 73 65 72  _OFFSET is reser
4670: 76 65 64 20 66 6f 72 20 6c 6f 63 6b 73 2e 20 53  ved for locks. S
4680: 69 6e 63 65 20 73 6f 6d 65 20 73 79 73 74 65 6d  ince some system
4690: 73 0a 2a 2a 20 6f 6e 6c 79 20 73 75 70 70 6f 72  s.** only suppor
46a0: 74 20 6d 61 6e 64 61 74 6f 72 79 20 66 69 6c 65  t mandatory file
46b0: 2d 6c 6f 63 6b 73 2c 20 77 65 20 64 6f 20 6e 6f  -locks, we do no
46c0: 74 20 72 65 61 64 20 6f 72 20 77 72 69 74 65 20  t read or write 
46d0: 64 61 74 61 0a 2a 2a 20 66 72 6f 6d 20 74 68 65  data.** from the
46e0: 20 72 65 67 69 6f 6e 20 6f 66 20 74 68 65 20 66   region of the f
46f0: 69 6c 65 20 6f 6e 20 77 68 69 63 68 20 6c 6f 63  ile on which loc
4700: 6b 73 20 61 72 65 20 61 70 70 6c 69 65 64 2e 0a  ks are applied..
4710: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e  */.#define WALIN
4720: 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20  DEX_LOCK_OFFSET 
4730: 20 20 28 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64    (sizeof(WalInd
4740: 65 78 48 64 72 29 2a 32 20 2b 20 73 69 7a 65 6f  exHdr)*2 + sizeo
4750: 66 28 57 61 6c 43 6b 70 74 49 6e 66 6f 29 29 0a  f(WalCkptInfo)).
4760: 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58  #define WALINDEX
4770: 5f 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 20 31  _LOCK_RESERVED 1
4780: 36 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44  6.#define WALIND
4790: 45 58 5f 48 44 52 5f 53 49 5a 45 20 20 20 20 20  EX_HDR_SIZE     
47a0: 20 28 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f   (WALINDEX_LOCK_
47b0: 4f 46 46 53 45 54 2b 57 41 4c 49 4e 44 45 58 5f  OFFSET+WALINDEX_
47c0: 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 29 0a 0a  LOCK_RESERVED)..
47d0: 2f 2a 20 53 69 7a 65 20 6f 66 20 68 65 61 64 65  /* Size of heade
47e0: 72 20 62 65 66 6f 72 65 20 65 61 63 68 20 66 72  r before each fr
47f0: 61 6d 65 20 69 6e 20 77 61 6c 20 2a 2f 0a 23 64  ame in wal */.#d
4800: 65 66 69 6e 65 20 57 41 4c 5f 46 52 41 4d 45 5f  efine WAL_FRAME_
4810: 48 44 52 53 49 5a 45 20 32 34 0a 0a 2f 2a 20 53  HDRSIZE 24../* S
4820: 69 7a 65 20 6f 66 20 77 72 69 74 65 20 61 68 65  ize of write ahe
4830: 61 64 20 6c 6f 67 20 68 65 61 64 65 72 2c 20 69  ad log header, i
4840: 6e 63 6c 75 64 69 6e 67 20 63 68 65 63 6b 73 75  ncluding checksu
4850: 6d 2e 20 2a 2f 0a 2f 2a 20 23 64 65 66 69 6e 65  m. */./* #define
4860: 20 57 41 4c 5f 48 44 52 53 49 5a 45 20 32 34 20   WAL_HDRSIZE 24 
4870: 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48  */.#define WAL_H
4880: 44 52 53 49 5a 45 20 33 32 0a 0a 2f 2a 20 57 41  DRSIZE 32../* WA
4890: 4c 20 6d 61 67 69 63 20 76 61 6c 75 65 2e 20 45  L magic value. E
48a0: 69 74 68 65 72 20 74 68 69 73 20 76 61 6c 75 65  ither this value
48b0: 2c 20 6f 72 20 74 68 65 20 73 61 6d 65 20 76 61  , or the same va
48c0: 6c 75 65 20 77 69 74 68 20 74 68 65 20 6c 65 61  lue with the lea
48d0: 73 74 0a 2a 2a 20 73 69 67 6e 69 66 69 63 61 6e  st.** significan
48e0: 74 20 62 69 74 20 61 6c 73 6f 20 73 65 74 20 28  t bit also set (
48f0: 57 41 4c 5f 4d 41 47 49 43 20 7c 20 30 78 30 30  WAL_MAGIC | 0x00
4900: 30 30 30 30 30 31 29 20 69 73 20 73 74 6f 72 65  000001) is store
4910: 64 20 69 6e 20 33 32 2d 62 69 74 0a 2a 2a 20 62  d in 32-bit.** b
4920: 69 67 2d 65 6e 64 69 61 6e 20 66 6f 72 6d 61 74  ig-endian format
4930: 20 69 6e 20 74 68 65 20 66 69 72 73 74 20 34 20   in the first 4 
4940: 62 79 74 65 73 20 6f 66 20 61 20 57 41 4c 20 66  bytes of a WAL f
4950: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ile..**.** If th
4960: 65 20 4c 53 42 20 69 73 20 73 65 74 2c 20 74 68  e LSB is set, th
4970: 65 6e 20 74 68 65 20 63 68 65 63 6b 73 75 6d 73  en the checksums
4980: 20 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65 20   for each frame 
4990: 77 69 74 68 69 6e 20 74 68 65 20 57 41 4c 0a 2a  within the WAL.*
49a0: 2a 20 66 69 6c 65 20 61 72 65 20 63 61 6c 63 75  * file are calcu
49b0: 6c 61 74 65 64 20 62 79 20 74 72 65 61 74 69 6e  lated by treatin
49c0: 67 20 61 6c 6c 20 64 61 74 61 20 61 73 20 61 6e  g all data as an
49d0: 20 61 72 72 61 79 20 6f 66 20 33 32 2d 62 69 74   array of 32-bit
49e0: 20 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20   .** big-endian 
49f0: 77 6f 72 64 73 2e 20 4f 74 68 65 72 77 69 73 65  words. Otherwise
4a00: 2c 20 74 68 65 79 20 61 72 65 20 63 61 6c 63 75  , they are calcu
4a10: 6c 61 74 65 64 20 62 79 20 69 6e 74 65 72 70 72  lated by interpr
4a20: 65 74 69 6e 67 20 0a 2a 2a 20 61 6c 6c 20 64 61  eting .** all da
4a30: 74 61 20 61 73 20 33 32 2d 62 69 74 20 6c 69 74  ta as 32-bit lit
4a40: 74 6c 65 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73  tle-endian words
4a50: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c  ..*/.#define WAL
4a60: 5f 4d 41 47 49 43 20 30 78 33 37 37 66 30 36 38  _MAGIC 0x377f068
4a70: 32 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  2../*.** Return 
4a80: 74 68 65 20 6f 66 66 73 65 74 20 6f 66 20 66 72  the offset of fr
4a90: 61 6d 65 20 69 46 72 61 6d 65 20 69 6e 20 74 68  ame iFrame in th
4aa0: 65 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f  e write-ahead lo
4ab0: 67 20 66 69 6c 65 2c 20 0a 2a 2a 20 61 73 73 75  g file, .** assu
4ac0: 6d 69 6e 67 20 61 20 64 61 74 61 62 61 73 65 20  ming a database 
4ad0: 70 61 67 65 20 73 69 7a 65 20 6f 66 20 73 7a 50  page size of szP
4ae0: 61 67 65 20 62 79 74 65 73 2e 20 54 68 65 20 6f  age bytes. The o
4af0: 66 66 73 65 74 20 72 65 74 75 72 6e 65 64 0a 2a  ffset returned.*
4b00: 2a 20 69 73 20 74 6f 20 74 68 65 20 73 74 61 72  * is to the star
4b10: 74 20 6f 66 20 74 68 65 20 77 72 69 74 65 2d 61  t of the write-a
4b20: 68 65 61 64 20 6c 6f 67 20 66 72 61 6d 65 2d 68  head log frame-h
4b30: 65 61 64 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e  eader..*/.#defin
4b40: 65 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74  e walFrameOffset
4b50: 28 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29  (iFrame, szPage)
4b60: 20 28 20 20 20 20 20 20 20 20 20 20 20 20 20 20   (              
4b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4b80: 20 5c 0a 20 20 57 41 4c 5f 48 44 52 53 49 5a 45   \.  WAL_HDRSIZE
4b90: 20 2b 20 28 28 69 46 72 61 6d 65 29 2d 31 29 2a   + ((iFrame)-1)*
4ba0: 28 69 36 34 29 28 28 73 7a 50 61 67 65 29 2b 57  (i64)((szPage)+W
4bb0: 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
4bc0: 29 20 20 20 20 20 20 20 20 20 5c 0a 29 0a 0a 2f  )         \.)../
4bd0: 2a 0a 2a 2a 20 41 6e 20 6f 70 65 6e 20 77 72 69  *.** An open wri
4be0: 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c  te-ahead log fil
4bf0: 65 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64  e is represented
4c00: 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63 65 20   by an instance 
4c10: 6f 66 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c 6f 77  of the.** follow
4c20: 69 6e 67 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73  ing object..*/.s
4c30: 74 72 75 63 74 20 57 61 6c 20 7b 0a 20 20 73 71  truct Wal {.  sq
4c40: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 3b  lite3_vfs *pVfs;
4c50: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
4c60: 56 46 53 20 75 73 65 64 20 74 6f 20 63 72 65 61  VFS used to crea
4c70: 74 65 20 70 44 62 46 64 20 2a 2f 0a 20 20 73 71  te pDbFd */.  sq
4c80: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 44 62 46  lite3_file *pDbF
4c90: 64 3b 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65  d;       /* File
4ca0: 20 68 61 6e 64 6c 65 20 66 6f 72 20 74 68 65 20   handle for the 
4cb0: 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f  database file */
4cc0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
4cd0: 2a 70 57 61 6c 46 64 3b 20 20 20 20 20 20 2f 2a  *pWalFd;      /*
4ce0: 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 66 6f 72   File handle for
4cf0: 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 75   WAL file */.  u
4d00: 33 32 20 69 43 61 6c 6c 62 61 63 6b 3b 20 20 20  32 iCallback;   
4d10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
4d20: 75 65 20 74 6f 20 70 61 73 73 20 74 6f 20 6c 6f  ue to pass to lo
4d30: 67 20 63 61 6c 6c 62 61 63 6b 20 28 6f 72 20 30  g callback (or 0
4d40: 29 20 2a 2f 0a 20 20 69 36 34 20 6d 78 57 61 6c  ) */.  i64 mxWal
4d50: 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20  Size;           
4d60: 20 20 2f 2a 20 54 72 75 6e 63 61 74 65 20 57 41    /* Truncate WA
4d70: 4c 20 74 6f 20 74 68 69 73 20 73 69 7a 65 20 75  L to this size u
4d80: 70 6f 6e 20 72 65 73 65 74 20 2a 2f 0a 20 20 69  pon reset */.  i
4d90: 6e 74 20 6e 57 69 44 61 74 61 3b 20 20 20 20 20  nt nWiData;     
4da0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
4db0: 65 20 6f 66 20 61 72 72 61 79 20 61 70 57 69 44  e of array apWiD
4dc0: 61 74 61 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c  ata */.  volatil
4dd0: 65 20 75 33 32 20 2a 2a 61 70 57 69 44 61 74 61  e u32 **apWiData
4de0: 3b 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74  ;   /* Pointer t
4df0: 6f 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 74  o wal-index cont
4e00: 65 6e 74 20 69 6e 20 6d 65 6d 6f 72 79 20 2a 2f  ent in memory */
4e10: 0a 20 20 75 33 32 20 73 7a 50 61 67 65 3b 20 20  .  u32 szPage;  
4e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4e30: 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20 73   Database page s
4e40: 69 7a 65 20 2a 2f 0a 20 20 69 31 36 20 72 65 61  ize */.  i16 rea
4e50: 64 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20  dLock;          
4e60: 20 20 20 20 2f 2a 20 57 68 69 63 68 20 72 65 61      /* Which rea
4e70: 64 20 6c 6f 63 6b 20 69 73 20 62 65 69 6e 67 20  d lock is being 
4e80: 68 65 6c 64 2e 20 20 2d 31 20 66 6f 72 20 6e 6f  held.  -1 for no
4e90: 6e 65 20 2a 2f 0a 20 20 75 38 20 65 78 63 6c 75  ne */.  u8 exclu
4ea0: 73 69 76 65 4d 6f 64 65 3b 20 20 20 20 20 20 20  siveMode;       
4eb0: 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20 69     /* Non-zero i
4ec0: 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73 20  f connection is 
4ed0: 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f 64  in exclusive mod
4ee0: 65 20 2a 2f 0a 20 20 75 38 20 77 72 69 74 65 4c  e */.  u8 writeL
4ef0: 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ock;            
4f00: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 20    /* True if in 
4f10: 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74  a write transact
4f20: 69 6f 6e 20 2a 2f 0a 20 20 75 38 20 63 6b 70 74  ion */.  u8 ckpt
4f30: 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Lock;           
4f40: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 68      /* True if h
4f50: 6f 6c 64 69 6e 67 20 61 20 63 68 65 63 6b 70 6f  olding a checkpo
4f60: 69 6e 74 20 6c 6f 63 6b 20 2a 2f 0a 20 20 75 38  int lock */.  u8
4f70: 20 72 65 61 64 4f 6e 6c 79 3b 20 20 20 20 20 20   readOnly;      
4f80: 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 5f           /* WAL_
4f90: 52 44 57 52 2c 20 57 41 4c 5f 52 44 4f 4e 4c 59  RDWR, WAL_RDONLY
4fa0: 2c 20 6f 72 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  , or WAL_SHM_RDO
4fb0: 4e 4c 59 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65  NLY */.  WalInde
4fc0: 78 48 64 72 20 68 64 72 3b 20 20 20 20 20 20 20  xHdr hdr;       
4fd0: 20 20 20 20 2f 2a 20 57 61 6c 2d 69 6e 64 65 78      /* Wal-index
4fe0: 20 68 65 61 64 65 72 20 66 6f 72 20 63 75 72 72   header for curr
4ff0: 65 6e 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ent transaction 
5000: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
5010: 2a 7a 57 61 6c 4e 61 6d 65 3b 20 20 20 20 20 20  *zWalName;      
5020: 2f 2a 20 4e 61 6d 65 20 6f 66 20 57 41 4c 20 66  /* Name of WAL f
5030: 69 6c 65 20 2a 2f 0a 20 20 75 33 32 20 6e 43 6b  ile */.  u32 nCk
5040: 70 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  pt;             
5050: 20 20 20 20 2f 2a 20 43 68 65 63 6b 70 6f 69 6e      /* Checkpoin
5060: 74 20 73 65 71 75 65 6e 63 65 20 63 6f 75 6e 74  t sequence count
5070: 65 72 20 69 6e 20 74 68 65 20 77 61 6c 2d 68 65  er in the wal-he
5080: 61 64 65 72 20 2a 2f 0a 23 69 66 64 65 66 20 53  ader */.#ifdef S
5090: 51 4c 49 54 45 5f 44 45 42 55 47 0a 20 20 75 38  QLITE_DEBUG.  u8
50a0: 20 6c 6f 63 6b 45 72 72 6f 72 3b 20 20 20 20 20   lockError;     
50b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
50c0: 20 69 66 20 61 20 6c 6f 63 6b 69 6e 67 20 65 72   if a locking er
50d0: 72 6f 72 20 68 61 73 20 6f 63 63 75 72 72 65 64  ror has occurred
50e0: 20 2a 2f 0a 23 65 6e 64 69 66 0a 7d 3b 0a 0a 2f   */.#endif.};../
50f0: 2a 0a 2a 2a 20 43 61 6e 64 69 64 61 74 65 20 76  *.** Candidate v
5100: 61 6c 75 65 73 20 66 6f 72 20 57 61 6c 2e 65 78  alues for Wal.ex
5110: 63 6c 75 73 69 76 65 4d 6f 64 65 2e 0a 2a 2f 0a  clusiveMode..*/.
5120: 23 64 65 66 69 6e 65 20 57 41 4c 5f 4e 4f 52 4d  #define WAL_NORM
5130: 41 4c 5f 4d 4f 44 45 20 20 20 20 20 30 0a 23 64  AL_MODE     0.#d
5140: 65 66 69 6e 65 20 57 41 4c 5f 45 58 43 4c 55 53  efine WAL_EXCLUS
5150: 49 56 45 5f 4d 4f 44 45 20 20 31 20 20 20 20 20  IVE_MODE  1     
5160: 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48 45 41  .#define WAL_HEA
5170: 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 32 0a 0a  PMEMORY_MODE 2..
5180: 2f 2a 0a 2a 2a 20 50 6f 73 73 69 62 6c 65 20 76  /*.** Possible v
5190: 61 6c 75 65 73 20 66 6f 72 20 57 41 4c 2e 72 65  alues for WAL.re
51a0: 61 64 4f 6e 6c 79 0a 2a 2f 0a 23 64 65 66 69 6e  adOnly.*/.#defin
51b0: 65 20 57 41 4c 5f 52 44 57 52 20 20 20 20 20 20  e WAL_RDWR      
51c0: 20 20 30 20 20 20 20 2f 2a 20 4e 6f 72 6d 61 6c    0    /* Normal
51d0: 20 72 65 61 64 2f 77 72 69 74 65 20 63 6f 6e 6e   read/write conn
51e0: 65 63 74 69 6f 6e 20 2a 2f 0a 23 64 65 66 69 6e  ection */.#defin
51f0: 65 20 57 41 4c 5f 52 44 4f 4e 4c 59 20 20 20 20  e WAL_RDONLY    
5200: 20 20 31 20 20 20 20 2f 2a 20 54 68 65 20 57 41    1    /* The WA
5210: 4c 20 66 69 6c 65 20 69 73 20 72 65 61 64 6f 6e  L file is readon
5220: 6c 79 20 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41  ly */.#define WA
5230: 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 20 20 32 20  L_SHM_RDONLY  2 
5240: 20 20 20 2f 2a 20 54 68 65 20 53 48 4d 20 66 69     /* The SHM fi
5250: 6c 65 20 69 73 20 72 65 61 64 6f 6e 6c 79 20 2a  le is readonly *
5260: 2f 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 70 61  /../*.** Each pa
5270: 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ge of the wal-in
5280: 64 65 78 20 6d 61 70 70 69 6e 67 20 63 6f 6e 74  dex mapping cont
5290: 61 69 6e 73 20 61 20 68 61 73 68 2d 74 61 62 6c  ains a hash-tabl
52a0: 65 20 6d 61 64 65 20 75 70 20 6f 66 0a 2a 2a 20  e made up of.** 
52b0: 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53 48  an array of HASH
52c0: 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 65 6c 65 6d  TABLE_NSLOT elem
52d0: 65 6e 74 73 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ents of the foll
52e0: 6f 77 69 6e 67 20 74 79 70 65 2e 0a 2a 2f 0a 74  owing type..*/.t
52f0: 79 70 65 64 65 66 20 75 31 36 20 68 74 5f 73 6c  ypedef u16 ht_sl
5300: 6f 74 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ot;../*.** This 
5310: 73 74 72 75 63 74 75 72 65 20 69 73 20 75 73 65  structure is use
5320: 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 61  d to implement a
5330: 6e 20 69 74 65 72 61 74 6f 72 20 74 68 61 74 20  n iterator that 
5340: 6c 6f 6f 70 73 20 74 68 72 6f 75 67 68 0a 2a 2a  loops through.**
5350: 20 61 6c 6c 20 66 72 61 6d 65 73 20 69 6e 20 74   all frames in t
5360: 68 65 20 57 41 4c 20 69 6e 20 64 61 74 61 62 61  he WAL in databa
5370: 73 65 20 70 61 67 65 20 6f 72 64 65 72 2e 20 57  se page order. W
5380: 68 65 72 65 20 74 77 6f 20 6f 72 20 6d 6f 72 65  here two or more
5390: 20 66 72 61 6d 65 73 0a 2a 2a 20 63 6f 72 72 65   frames.** corre
53a0: 73 70 6f 6e 64 20 74 6f 20 74 68 65 20 73 61 6d  spond to the sam
53b0: 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65 2c  e database page,
53c0: 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 76 69   the iterator vi
53d0: 73 69 74 73 20 6f 6e 6c 79 20 74 68 65 20 0a 2a  sits only the .*
53e0: 2a 20 66 72 61 6d 65 20 6d 6f 73 74 20 72 65 63  * frame most rec
53f0: 65 6e 74 6c 79 20 77 72 69 74 74 65 6e 20 74 6f  ently written to
5400: 20 74 68 65 20 57 41 4c 20 28 69 6e 20 6f 74 68   the WAL (in oth
5410: 65 72 20 77 6f 72 64 73 2c 20 74 68 65 20 66 72  er words, the fr
5420: 61 6d 65 20 77 69 74 68 0a 2a 2a 20 74 68 65 20  ame with.** the 
5430: 6c 61 72 67 65 73 74 20 69 6e 64 65 78 29 2e 0a  largest index)..
5440: 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e 74 65 72 6e  **.** The intern
5450: 61 6c 73 20 6f 66 20 74 68 69 73 20 73 74 72 75  als of this stru
5460: 63 74 75 72 65 20 61 72 65 20 6f 6e 6c 79 20 61  cture are only a
5470: 63 63 65 73 73 65 64 20 62 79 3a 0a 2a 2a 0a 2a  ccessed by:.**.*
5480: 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f 72 49  *   walIteratorI
5490: 6e 69 74 28 29 20 2d 20 43 72 65 61 74 65 20 61  nit() - Create a
54a0: 20 6e 65 77 20 69 74 65 72 61 74 6f 72 2c 0a 2a   new iterator,.*
54b0: 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f 72 4e  *   walIteratorN
54c0: 65 78 74 28 29 20 2d 20 53 74 65 70 20 61 6e 20  ext() - Step an 
54d0: 69 74 65 72 61 74 6f 72 2c 0a 2a 2a 20 20 20 77  iterator,.**   w
54e0: 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28 29  alIteratorFree()
54f0: 20 2d 20 46 72 65 65 20 61 6e 20 69 74 65 72 61   - Free an itera
5500: 74 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  tor..**.** This 
5510: 66 75 6e 63 74 69 6f 6e 61 6c 69 74 79 20 69 73  functionality is
5520: 20 75 73 65 64 20 62 79 20 74 68 65 20 63 68 65   used by the che
5530: 63 6b 70 6f 69 6e 74 20 63 6f 64 65 20 28 73 65  ckpoint code (se
5540: 65 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28  e walCheckpoint(
5550: 29 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61  ))..*/.struct Wa
5560: 6c 49 74 65 72 61 74 6f 72 20 7b 0a 20 20 69 6e  lIterator {.  in
5570: 74 20 69 50 72 69 6f 72 3b 20 20 20 20 20 20 20  t iPrior;       
5580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5590: 20 4c 61 73 74 20 72 65 73 75 6c 74 20 72 65 74   Last result ret
55a0: 75 72 6e 65 64 20 66 72 6f 6d 20 74 68 65 20 69  urned from the i
55b0: 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74  terator */.  int
55c0: 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20 20 20 20   nSegment;      
55d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
55e0: 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  Number of entrie
55f0: 73 20 69 6e 20 61 53 65 67 6d 65 6e 74 5b 5d 20  s in aSegment[] 
5600: 2a 2f 0a 20 20 73 74 72 75 63 74 20 57 61 6c 53  */.  struct WalS
5610: 65 67 6d 65 6e 74 20 7b 0a 20 20 20 20 69 6e 74  egment {.    int
5620: 20 69 4e 65 78 74 3b 20 20 20 20 20 20 20 20 20   iNext;         
5630: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65             /* Ne
5640: 78 74 20 73 6c 6f 74 20 69 6e 20 61 49 6e 64 65  xt slot in aInde
5650: 78 5b 5d 20 6e 6f 74 20 79 65 74 20 72 65 74 75  x[] not yet retu
5660: 72 6e 65 64 20 2a 2f 0a 20 20 20 20 68 74 5f 73  rned */.    ht_s
5670: 6c 6f 74 20 2a 61 49 6e 64 65 78 3b 20 20 20 20  lot *aIndex;    
5680: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 30 2c            /* i0,
5690: 20 69 31 2c 20 69 32 2e 2e 2e 20 73 75 63 68 20   i1, i2... such 
56a0: 74 68 61 74 20 61 50 67 6e 6f 5b 69 4e 5d 20 61  that aPgno[iN] a
56b0: 73 63 65 6e 64 20 2a 2f 0a 20 20 20 20 75 33 32  scend */.    u32
56c0: 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20 20 20   *aPgno;        
56d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72             /* Ar
56e0: 72 61 79 20 6f 66 20 70 61 67 65 20 6e 75 6d 62  ray of page numb
56f0: 65 72 73 2e 20 2a 2f 0a 20 20 20 20 69 6e 74 20  ers. */.    int 
5700: 6e 45 6e 74 72 79 3b 20 20 20 20 20 20 20 20 20  nEntry;         
5710: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 72 2e            /* Nr.
5720: 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 61   of entries in a
5730: 50 67 6e 6f 5b 5d 20 61 6e 64 20 61 49 6e 64 65  Pgno[] and aInde
5740: 78 5b 5d 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69  x[] */.    int i
5750: 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20 20 20  Zero;           
5760: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72 61 6d           /* Fram
5770: 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63 69 61  e number associa
5780: 74 65 64 20 77 69 74 68 20 61 50 67 6e 6f 5b 30  ted with aPgno[0
5790: 5d 20 2a 2f 0a 20 20 7d 20 61 53 65 67 6d 65 6e  ] */.  } aSegmen
57a0: 74 5b 31 5d 3b 20 20 20 20 20 20 20 20 20 20 20  t[1];           
57b0: 20 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20 66 6f         /* One fo
57c0: 72 20 65 76 65 72 79 20 33 32 4b 42 20 70 61 67  r every 32KB pag
57d0: 65 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64  e in the wal-ind
57e0: 65 78 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ex */.};../*.** 
57f0: 44 65 66 69 6e 65 20 74 68 65 20 70 61 72 61 6d  Define the param
5800: 65 74 65 72 73 20 6f 66 20 74 68 65 20 68 61 73  eters of the has
5810: 68 20 74 61 62 6c 65 73 20 69 6e 20 74 68 65 20  h tables in the 
5820: 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 2e 20  wal-index file. 
5830: 54 68 65 72 65 0a 2a 2a 20 69 73 20 61 20 68 61  There.** is a ha
5840: 73 68 2d 74 61 62 6c 65 20 66 6f 6c 6c 6f 77 69  sh-table followi
5850: 6e 67 20 65 76 65 72 79 20 48 41 53 48 54 41 42  ng every HASHTAB
5860: 4c 45 5f 4e 50 41 47 45 20 70 61 67 65 20 6e 75  LE_NPAGE page nu
5870: 6d 62 65 72 73 20 69 6e 20 74 68 65 0a 2a 2a 20  mbers in the.** 
5880: 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a  wal-index..**.**
5890: 20 43 68 61 6e 67 69 6e 67 20 61 6e 79 20 6f 66   Changing any of
58a0: 20 74 68 65 73 65 20 63 6f 6e 73 74 61 6e 74 73   these constants
58b0: 20 77 69 6c 6c 20 61 6c 74 65 72 20 74 68 65 20   will alter the 
58c0: 77 61 6c 2d 69 6e 64 65 78 20 66 6f 72 6d 61 74  wal-index format
58d0: 20 61 6e 64 0a 2a 2a 20 63 72 65 61 74 65 20 69   and.** create i
58e0: 6e 63 6f 6d 70 61 74 69 62 69 6c 69 74 69 65 73  ncompatibilities
58f0: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 48 41 53  ..*/.#define HAS
5900: 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 20 20 20  HTABLE_NPAGE    
5910: 20 20 34 30 39 36 20 20 20 20 20 20 20 20 20 20    4096          
5920: 20 20 20 20 20 20 20 2f 2a 20 4d 75 73 74 20 62         /* Must b
5930: 65 20 70 6f 77 65 72 20 6f 66 20 32 20 2a 2f 0a  e power of 2 */.
5940: 23 64 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c  #define HASHTABL
5950: 45 5f 48 41 53 48 5f 31 20 20 20 20 20 33 38 33  E_HASH_1     383
5960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5970: 20 20 2f 2a 20 53 68 6f 75 6c 64 20 62 65 20 70    /* Should be p
5980: 72 69 6d 65 20 2a 2f 0a 23 64 65 66 69 6e 65 20  rime */.#define 
5990: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20  HASHTABLE_NSLOT 
59a0: 20 20 20 20 20 28 48 41 53 48 54 41 42 4c 45 5f       (HASHTABLE_
59b0: 4e 50 41 47 45 2a 32 29 20 20 2f 2a 20 4d 75 73  NPAGE*2)  /* Mus
59c0: 74 20 62 65 20 61 20 70 6f 77 65 72 20 6f 66 20  t be a power of 
59d0: 32 20 2a 2f 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 65  2 */../* .** The
59e0: 20 62 6c 6f 63 6b 20 6f 66 20 70 61 67 65 20 6e   block of page n
59f0: 75 6d 62 65 72 73 20 61 73 73 6f 63 69 61 74 65  umbers associate
5a00: 64 20 77 69 74 68 20 74 68 65 20 66 69 72 73 74  d with the first
5a10: 20 68 61 73 68 2d 74 61 62 6c 65 20 69 6e 20 61   hash-table in a
5a20: 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 69 73  .** wal-index is
5a30: 20 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 75 73   smaller than us
5a40: 75 61 6c 2e 20 54 68 69 73 20 69 73 20 73 6f 20  ual. This is so 
5a50: 74 68 61 74 20 74 68 65 72 65 20 69 73 20 61 20  that there is a 
5a60: 63 6f 6d 70 6c 65 74 65 0a 2a 2a 20 68 61 73 68  complete.** hash
5a70: 2d 74 61 62 6c 65 20 6f 6e 20 65 61 63 68 20 61  -table on each a
5a80: 6c 69 67 6e 65 64 20 33 32 4b 42 20 70 61 67 65  ligned 32KB page
5a90: 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
5aa0: 78 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 48 41  x..*/.#define HA
5ab0: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e  SHTABLE_NPAGE_ON
5ac0: 45 20 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 50  E  (HASHTABLE_NP
5ad0: 41 47 45 20 2d 20 28 57 41 4c 49 4e 44 45 58 5f  AGE - (WALINDEX_
5ae0: 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f 66 28  HDR_SIZE/sizeof(
5af0: 75 33 32 29 29 29 0a 0a 2f 2a 20 54 68 65 20 77  u32)))../* The w
5b00: 61 6c 2d 69 6e 64 65 78 20 69 73 20 64 69 76 69  al-index is divi
5b10: 64 65 64 20 69 6e 74 6f 20 70 61 67 65 73 20 6f  ded into pages o
5b20: 66 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a 20  f WALINDEX_PGSZ 
5b30: 62 79 74 65 73 20 65 61 63 68 2e 20 2a 2f 0a 23  bytes each. */.#
5b40: 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58 5f  define WALINDEX_
5b50: 50 47 53 5a 20 20 20 28 20 20 20 20 20 20 20 20  PGSZ   (        
5b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5b80: 20 5c 0a 20 20 20 20 73 69 7a 65 6f 66 28 68 74   \.    sizeof(ht
5b90: 5f 73 6c 6f 74 29 2a 48 41 53 48 54 41 42 4c 45  _slot)*HASHTABLE
5ba0: 5f 4e 53 4c 4f 54 20 2b 20 48 41 53 48 54 41 42  _NSLOT + HASHTAB
5bb0: 4c 45 5f 4e 50 41 47 45 2a 73 69 7a 65 6f 66 28  LE_NPAGE*sizeof(
5bc0: 75 33 32 29 20 5c 0a 29 0a 0a 2f 2a 0a 2a 2a 20  u32) \.)../*.** 
5bd0: 4f 62 74 61 69 6e 20 61 20 70 6f 69 6e 74 65 72  Obtain a pointer
5be0: 20 74 6f 20 74 68 65 20 69 50 61 67 65 27 74 68   to the iPage'th
5bf0: 20 70 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c   page of the wal
5c00: 2d 69 6e 64 65 78 2e 20 54 68 65 20 77 61 6c 2d  -index. The wal-
5c10: 69 6e 64 65 78 0a 2a 2a 20 69 73 20 62 72 6f 6b  index.** is brok
5c20: 65 6e 20 69 6e 74 6f 20 70 61 67 65 73 20 6f 66  en into pages of
5c30: 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a 20 62   WALINDEX_PGSZ b
5c40: 79 74 65 73 2e 20 57 61 6c 2d 69 6e 64 65 78 20  ytes. Wal-index 
5c50: 70 61 67 65 73 20 61 72 65 0a 2a 2a 20 6e 75 6d  pages are.** num
5c60: 62 65 72 65 64 20 66 72 6f 6d 20 7a 65 72 6f 2e  bered from zero.
5c70: 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 69 73 20 63  .**.** If this c
5c80: 61 6c 6c 20 69 73 20 73 75 63 63 65 73 73 66 75  all is successfu
5c90: 6c 2c 20 2a 70 70 50 61 67 65 20 69 73 20 73 65  l, *ppPage is se
5ca0: 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68  t to point to th
5cb0: 65 20 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a 20 70  e wal-index.** p
5cc0: 61 67 65 20 61 6e 64 20 53 51 4c 49 54 45 5f 4f  age and SQLITE_O
5cd0: 4b 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 49  K is returned. I
5ce0: 66 20 61 6e 20 65 72 72 6f 72 20 28 61 6e 20 4f  f an error (an O
5cf0: 4f 4d 20 6f 72 20 56 46 53 20 65 72 72 6f 72 29  OM or VFS error)
5d00: 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 74 68 65 6e   occurs,.** then
5d10: 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
5d20: 20 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65   code is returne
5d30: 64 20 61 6e 64 20 2a 70 70 50 61 67 65 20 69 73  d and *ppPage is
5d40: 20 73 65 74 20 74 6f 20 30 2e 0a 2a 2f 0a 73 74   set to 0..*/.st
5d50: 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e 64 65  atic int walInde
5d60: 78 50 61 67 65 28 57 61 6c 20 2a 70 57 61 6c 2c  xPage(Wal *pWal,
5d70: 20 69 6e 74 20 69 50 61 67 65 2c 20 76 6f 6c 61   int iPage, vola
5d80: 74 69 6c 65 20 75 33 32 20 2a 2a 70 70 50 61 67  tile u32 **ppPag
5d90: 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  e){.  int rc = S
5da0: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f 2a 20  QLITE_OK;..  /* 
5db0: 45 6e 6c 61 72 67 65 20 74 68 65 20 70 57 61 6c  Enlarge the pWal
5dc0: 2d 3e 61 70 57 69 44 61 74 61 5b 5d 20 61 72 72  ->apWiData[] arr
5dd0: 61 79 20 69 66 20 72 65 71 75 69 72 65 64 20 2a  ay if required *
5de0: 2f 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 6e 57  /.  if( pWal->nW
5df0: 69 44 61 74 61 3c 3d 69 50 61 67 65 20 29 7b 0a  iData<=iPage ){.
5e00: 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20 3d 20      int nByte = 
5e10: 73 69 7a 65 6f 66 28 75 33 32 2a 29 2a 28 69 50  sizeof(u32*)*(iP
5e20: 61 67 65 2b 31 29 3b 0a 20 20 20 20 76 6f 6c 61  age+1);.    vola
5e30: 74 69 6c 65 20 75 33 32 20 2a 2a 61 70 4e 65 77  tile u32 **apNew
5e40: 3b 0a 20 20 20 20 61 70 4e 65 77 20 3d 20 28 76  ;.    apNew = (v
5e50: 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 29 73  olatile u32 **)s
5e60: 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63 28 28  qlite3_realloc((
5e70: 76 6f 69 64 20 2a 29 70 57 61 6c 2d 3e 61 70 57  void *)pWal->apW
5e80: 69 44 61 74 61 2c 20 6e 42 79 74 65 29 3b 0a 20  iData, nByte);. 
5e90: 20 20 20 69 66 28 20 21 61 70 4e 65 77 20 29 7b     if( !apNew ){
5ea0: 0a 20 20 20 20 20 20 2a 70 70 50 61 67 65 20 3d  .      *ppPage =
5eb0: 20 30 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   0;.      return
5ec0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
5ed0: 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74 28     }.    memset(
5ee0: 28 76 6f 69 64 2a 29 26 61 70 4e 65 77 5b 70 57  (void*)&apNew[pW
5ef0: 61 6c 2d 3e 6e 57 69 44 61 74 61 5d 2c 20 30 2c  al->nWiData], 0,
5f00: 0a 20 20 20 20 20 20 20 20 20 20 20 73 69 7a 65  .           size
5f10: 6f 66 28 75 33 32 2a 29 2a 28 69 50 61 67 65 2b  of(u32*)*(iPage+
5f20: 31 2d 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 29  1-pWal->nWiData)
5f30: 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 61 70 57  );.    pWal->apW
5f40: 69 44 61 74 61 20 3d 20 61 70 4e 65 77 3b 0a 20  iData = apNew;. 
5f50: 20 20 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61     pWal->nWiData
5f60: 20 3d 20 69 50 61 67 65 2b 31 3b 0a 20 20 7d 0a   = iPage+1;.  }.
5f70: 0a 20 20 2f 2a 20 52 65 71 75 65 73 74 20 61 20  .  /* Request a 
5f80: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 72  pointer to the r
5f90: 65 71 75 69 72 65 64 20 70 61 67 65 20 66 72 6f  equired page fro
5fa0: 6d 20 74 68 65 20 56 46 53 20 2a 2f 0a 20 20 69  m the VFS */.  i
5fb0: 66 28 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  f( pWal->apWiDat
5fc0: 61 5b 69 50 61 67 65 5d 3d 3d 30 20 29 7b 0a 20  a[iPage]==0 ){. 
5fd0: 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63     if( pWal->exc
5fe0: 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f  lusiveMode==WAL_
5ff0: 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20  HEAPMEMORY_MODE 
6000: 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 61  ){.      pWal->a
6010: 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d 20 3d  pWiData[iPage] =
6020: 20 28 75 33 32 20 76 6f 6c 61 74 69 6c 65 20 2a   (u32 volatile *
6030: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65  )sqlite3MallocZe
6040: 72 6f 28 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a  ro(WALINDEX_PGSZ
6050: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 21 70 57  );.      if( !pW
6060: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50 61  al->apWiData[iPa
6070: 67 65 5d 20 29 20 72 63 20 3d 20 53 51 4c 49 54  ge] ) rc = SQLIT
6080: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c  E_NOMEM;.    }el
6090: 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  se{.      rc = s
60a0: 71 6c 69 74 65 33 4f 73 53 68 6d 4d 61 70 28 70  qlite3OsShmMap(p
60b0: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 50 61 67  Wal->pDbFd, iPag
60c0: 65 2c 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a  e, WALINDEX_PGSZ
60d0: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 70 57 61  , .          pWa
60e0: 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 2c 20 28 76  l->writeLock, (v
60f0: 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a 2a 29  oid volatile **)
6100: 26 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b  &pWal->apWiData[
6110: 69 50 61 67 65 5d 0a 20 20 20 20 20 20 29 3b 0a  iPage].      );.
6120: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
6130: 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 20 29 7b  LITE_READONLY ){
6140: 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 72  .        pWal->r
6150: 65 61 64 4f 6e 6c 79 20 7c 3d 20 57 41 4c 5f 53  eadOnly |= WAL_S
6160: 48 4d 5f 52 44 4f 4e 4c 59 3b 0a 20 20 20 20 20  HM_RDONLY;.     
6170: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f     rc = SQLITE_O
6180: 4b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  K;.      }.    }
6190: 0a 20 20 7d 0a 0a 20 20 2a 70 70 50 61 67 65 20  .  }..  *ppPage 
61a0: 3d 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61  = pWal->apWiData
61b0: 5b 69 50 61 67 65 5d 3b 0a 20 20 61 73 73 65 72  [iPage];.  asser
61c0: 74 28 20 69 50 61 67 65 3d 3d 30 20 7c 7c 20 2a  t( iPage==0 || *
61d0: 70 70 50 61 67 65 20 7c 7c 20 72 63 21 3d 53 51  ppPage || rc!=SQ
61e0: 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74  LITE_OK );.  ret
61f0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
6200: 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65   Return a pointe
6210: 72 20 74 6f 20 74 68 65 20 57 61 6c 43 6b 70 74  r to the WalCkpt
6220: 49 6e 66 6f 20 73 74 72 75 63 74 75 72 65 20 69  Info structure i
6230: 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e  n the wal-index.
6240: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c 61 74  .*/.static volat
6250: 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20  ile WalCkptInfo 
6260: 2a 77 61 6c 43 6b 70 74 49 6e 66 6f 28 57 61 6c  *walCkptInfo(Wal
6270: 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73 65 72   *pWal){.  asser
6280: 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61  t( pWal->nWiData
6290: 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70 57 69  >0 && pWal->apWi
62a0: 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72 65 74  Data[0] );.  ret
62b0: 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20 57 61  urn (volatile Wa
62c0: 6c 43 6b 70 74 49 6e 66 6f 2a 29 26 28 70 57 61  lCkptInfo*)&(pWa
62d0: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 5b 73  l->apWiData[0][s
62e0: 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64  izeof(WalIndexHd
62f0: 72 29 2f 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  r)/2]);.}../*.**
6300: 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65   Return a pointe
6310: 72 20 74 6f 20 74 68 65 20 57 61 6c 49 6e 64 65  r to the WalInde
6320: 78 48 64 72 20 73 74 72 75 63 74 75 72 65 20 69  xHdr structure i
6330: 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e  n the wal-index.
6340: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 6c 61 74  .*/.static volat
6350: 69 6c 65 20 57 61 6c 49 6e 64 65 78 48 64 72 20  ile WalIndexHdr 
6360: 2a 77 61 6c 49 6e 64 65 78 48 64 72 28 57 61 6c  *walIndexHdr(Wal
6370: 20 2a 70 57 61 6c 29 7b 0a 20 20 61 73 73 65 72   *pWal){.  asser
6380: 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61  t( pWal->nWiData
6390: 3e 30 20 26 26 20 70 57 61 6c 2d 3e 61 70 57 69  >0 && pWal->apWi
63a0: 44 61 74 61 5b 30 5d 20 29 3b 0a 20 20 72 65 74  Data[0] );.  ret
63b0: 75 72 6e 20 28 76 6f 6c 61 74 69 6c 65 20 57 61  urn (volatile Wa
63c0: 6c 49 6e 64 65 78 48 64 72 2a 29 70 57 61 6c 2d  lIndexHdr*)pWal-
63d0: 3e 61 70 57 69 44 61 74 61 5b 30 5d 3b 0a 7d 0a  >apWiData[0];.}.
63e0: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61 72 67 75 6d  ./*.** The argum
63f0: 65 6e 74 20 74 6f 20 74 68 69 73 20 6d 61 63 72  ent to this macr
6400: 6f 20 6d 75 73 74 20 62 65 20 6f 66 20 74 79 70  o must be of typ
6410: 65 20 75 33 32 2e 20 4f 6e 20 61 20 6c 69 74 74  e u32. On a litt
6420: 6c 65 2d 65 6e 64 69 61 6e 0a 2a 2a 20 61 72 63  le-endian.** arc
6430: 68 69 74 65 63 74 75 72 65 2c 20 69 74 20 72 65  hitecture, it re
6440: 74 75 72 6e 73 20 74 68 65 20 75 33 32 20 76 61  turns the u32 va
6450: 6c 75 65 20 74 68 61 74 20 72 65 73 75 6c 74 73  lue that results
6460: 20 66 72 6f 6d 20 69 6e 74 65 72 70 72 65 74 69   from interpreti
6470: 6e 67 0a 2a 2a 20 74 68 65 20 34 20 62 79 74 65  ng.** the 4 byte
6480: 73 20 61 73 20 61 20 62 69 67 2d 65 6e 64 69 61  s as a big-endia
6490: 6e 20 76 61 6c 75 65 2e 20 4f 6e 20 61 20 62 69  n value. On a bi
64a0: 67 2d 65 6e 64 69 61 6e 20 61 72 63 68 69 74 65  g-endian archite
64b0: 63 74 75 72 65 2c 20 69 74 0a 2a 2a 20 72 65 74  cture, it.** ret
64c0: 75 72 6e 73 20 74 68 65 20 76 61 6c 75 65 20 74  urns the value t
64d0: 68 61 74 20 77 6f 75 6c 64 20 62 65 20 70 72 6f  hat would be pro
64e0: 64 75 63 65 64 20 62 79 20 69 6e 74 65 70 72 65  duced by intepre
64f0: 74 69 6e 67 20 74 68 65 20 34 20 62 79 74 65 73  ting the 4 bytes
6500: 0a 2a 2a 20 6f 66 20 74 68 65 20 69 6e 70 75 74  .** of the input
6510: 20 76 61 6c 75 65 20 61 73 20 61 20 6c 69 74 74   value as a litt
6520: 6c 65 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65  le-endian intege
6530: 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 42 59  r..*/.#define BY
6540: 54 45 53 57 41 50 33 32 28 78 29 20 28 20 5c 0a  TESWAP32(x) ( \.
6550: 20 20 20 20 28 28 28 78 29 26 30 78 30 30 30 30      (((x)&0x0000
6560: 30 30 46 46 29 3c 3c 32 34 29 20 2b 20 28 28 28  00FF)<<24) + (((
6570: 78 29 26 30 78 30 30 30 30 46 46 30 30 29 3c 3c  x)&0x0000FF00)<<
6580: 38 29 20 20 5c 0a 20 20 2b 20 28 28 28 78 29 26  8)  \.  + (((x)&
6590: 30 78 30 30 46 46 30 30 30 30 29 3e 3e 38 29 20  0x00FF0000)>>8) 
65a0: 20 2b 20 28 28 28 78 29 26 30 78 46 46 30 30 30   + (((x)&0xFF000
65b0: 30 30 30 29 3e 3e 32 34 29 20 5c 0a 29 0a 0a 2f  000)>>24) \.)../
65c0: 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20 6f 72  *.** Generate or
65d0: 20 65 78 74 65 6e 64 20 61 6e 20 38 20 62 79 74   extend an 8 byt
65e0: 65 20 63 68 65 63 6b 73 75 6d 20 62 61 73 65 64  e checksum based
65f0: 20 6f 6e 20 74 68 65 20 64 61 74 61 20 69 6e 20   on the data in 
6600: 0a 2a 2a 20 61 72 72 61 79 20 61 42 79 74 65 5b  .** array aByte[
6610: 5d 20 61 6e 64 20 74 68 65 20 69 6e 69 74 69 61  ] and the initia
6620: 6c 20 76 61 6c 75 65 73 20 6f 66 20 61 49 6e 5b  l values of aIn[
6630: 30 5d 20 61 6e 64 20 61 49 6e 5b 31 5d 20 28 6f  0] and aIn[1] (o
6640: 72 0a 2a 2a 20 69 6e 69 74 69 61 6c 20 76 61 6c  r.** initial val
6650: 75 65 73 20 6f 66 20 30 20 61 6e 64 20 30 20 69  ues of 0 and 0 i
6660: 66 20 61 49 6e 3d 3d 4e 55 4c 4c 29 2e 0a 2a 2a  f aIn==NULL)..**
6670: 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b 73 75 6d  .** The checksum
6680: 20 69 73 20 77 72 69 74 74 65 6e 20 62 61 63 6b   is written back
6690: 20 69 6e 74 6f 20 61 4f 75 74 5b 5d 20 62 65 66   into aOut[] bef
66a0: 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a  ore returning..*
66b0: 2a 0a 2a 2a 20 6e 42 79 74 65 20 6d 75 73 74 20  *.** nByte must 
66c0: 62 65 20 61 20 70 6f 73 69 74 69 76 65 20 6d 75  be a positive mu
66d0: 6c 74 69 70 6c 65 20 6f 66 20 38 2e 0a 2a 2f 0a  ltiple of 8..*/.
66e0: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 43  static void walC
66f0: 68 65 63 6b 73 75 6d 42 79 74 65 73 28 0a 20 20  hecksumBytes(.  
6700: 69 6e 74 20 6e 61 74 69 76 65 43 6b 73 75 6d 2c  int nativeCksum,
6710: 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e 61 74   /* True for nat
6720: 69 76 65 20 62 79 74 65 2d 6f 72 64 65 72 2c 20  ive byte-order, 
6730: 66 61 6c 73 65 20 66 6f 72 20 6e 6f 6e 2d 6e 61  false for non-na
6740: 74 69 76 65 20 2a 2f 0a 20 20 75 38 20 2a 61 2c  tive */.  u8 *a,
6750: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f             /* Co
6760: 6e 74 65 6e 74 20 74 6f 20 62 65 20 63 68 65 63  ntent to be chec
6770: 6b 73 75 6d 6d 65 64 20 2a 2f 0a 20 20 69 6e 74  ksummed */.  int
6780: 20 6e 42 79 74 65 2c 20 20 20 20 20 20 20 2f 2a   nByte,       /*
6790: 20 42 79 74 65 73 20 6f 66 20 63 6f 6e 74 65 6e   Bytes of conten
67a0: 74 20 69 6e 20 61 5b 5d 2e 20 20 4d 75 73 74 20  t in a[].  Must 
67b0: 62 65 20 61 20 6d 75 6c 74 69 70 6c 65 20 6f 66  be a multiple of
67c0: 20 38 2e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 75   8. */.  const u
67d0: 33 32 20 2a 61 49 6e 2c 20 20 2f 2a 20 49 6e 69  32 *aIn,  /* Ini
67e0: 74 69 61 6c 20 63 68 65 63 6b 73 75 6d 20 76 61  tial checksum va
67f0: 6c 75 65 20 69 6e 70 75 74 20 2a 2f 0a 20 20 75  lue input */.  u
6800: 33 32 20 2a 61 4f 75 74 20 20 20 20 20 20 20 20  32 *aOut        
6810: 2f 2a 20 4f 55 54 3a 20 46 69 6e 61 6c 20 63 68  /* OUT: Final ch
6820: 65 63 6b 73 75 6d 20 76 61 6c 75 65 20 6f 75 74  ecksum value out
6830: 70 75 74 20 2a 2f 0a 29 7b 0a 20 20 75 33 32 20  put */.){.  u32 
6840: 73 31 2c 20 73 32 3b 0a 20 20 75 33 32 20 2a 61  s1, s2;.  u32 *a
6850: 44 61 74 61 20 3d 20 28 75 33 32 20 2a 29 61 3b  Data = (u32 *)a;
6860: 0a 20 20 75 33 32 20 2a 61 45 6e 64 20 3d 20 28  .  u32 *aEnd = (
6870: 75 33 32 20 2a 29 26 61 5b 6e 42 79 74 65 5d 3b  u32 *)&a[nByte];
6880: 0a 0a 20 20 69 66 28 20 61 49 6e 20 29 7b 0a 20  ..  if( aIn ){. 
6890: 20 20 20 73 31 20 3d 20 61 49 6e 5b 30 5d 3b 0a     s1 = aIn[0];.
68a0: 20 20 20 20 73 32 20 3d 20 61 49 6e 5b 31 5d 3b      s2 = aIn[1];
68b0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 31  .  }else{.    s1
68c0: 20 3d 20 73 32 20 3d 20 30 3b 0a 20 20 7d 0a 0a   = s2 = 0;.  }..
68d0: 20 20 61 73 73 65 72 74 28 20 6e 42 79 74 65 3e    assert( nByte>
68e0: 3d 38 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =8 );.  assert( 
68f0: 28 6e 42 79 74 65 26 30 78 30 30 30 30 30 30 30  (nByte&0x0000000
6900: 37 29 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20  7)==0 );..  if( 
6910: 6e 61 74 69 76 65 43 6b 73 75 6d 20 29 7b 0a 20  nativeCksum ){. 
6920: 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 20 73 31     do {.      s1
6930: 20 2b 3d 20 2a 61 44 61 74 61 2b 2b 20 2b 20 73   += *aData++ + s
6940: 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d 20 2a  2;.      s2 += *
6950: 61 44 61 74 61 2b 2b 20 2b 20 73 31 3b 0a 20 20  aData++ + s1;.  
6960: 20 20 7d 77 68 69 6c 65 28 20 61 44 61 74 61 3c    }while( aData<
6970: 61 45 6e 64 20 29 3b 0a 20 20 7d 65 6c 73 65 7b  aEnd );.  }else{
6980: 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 20  .    do {.      
6990: 73 31 20 2b 3d 20 42 59 54 45 53 57 41 50 33 32  s1 += BYTESWAP32
69a0: 28 61 44 61 74 61 5b 30 5d 29 20 2b 20 73 32 3b  (aData[0]) + s2;
69b0: 0a 20 20 20 20 20 20 73 32 20 2b 3d 20 42 59 54  .      s2 += BYT
69c0: 45 53 57 41 50 33 32 28 61 44 61 74 61 5b 31 5d  ESWAP32(aData[1]
69d0: 29 20 2b 20 73 31 3b 0a 20 20 20 20 20 20 61 44  ) + s1;.      aD
69e0: 61 74 61 20 2b 3d 20 32 3b 0a 20 20 20 20 7d 77  ata += 2;.    }w
69f0: 68 69 6c 65 28 20 61 44 61 74 61 3c 61 45 6e 64  hile( aData<aEnd
6a00: 20 29 3b 0a 20 20 7d 0a 0a 20 20 61 4f 75 74 5b   );.  }..  aOut[
6a10: 30 5d 20 3d 20 73 31 3b 0a 20 20 61 4f 75 74 5b  0] = s1;.  aOut[
6a20: 31 5d 20 3d 20 73 32 3b 0a 7d 0a 0a 73 74 61 74  1] = s2;.}..stat
6a30: 69 63 20 76 6f 69 64 20 77 61 6c 53 68 6d 42 61  ic void walShmBa
6a40: 72 72 69 65 72 28 57 61 6c 20 2a 70 57 61 6c 29  rrier(Wal *pWal)
6a50: 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78  {.  if( pWal->ex
6a60: 63 6c 75 73 69 76 65 4d 6f 64 65 21 3d 57 41 4c  clusiveMode!=WAL
6a70: 5f 48 45 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45  _HEAPMEMORY_MODE
6a80: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f   ){.    sqlite3O
6a90: 73 53 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c  sShmBarrier(pWal
6aa0: 2d 3e 70 44 62 46 64 29 3b 0a 20 20 7d 0a 7d 0a  ->pDbFd);.  }.}.
6ab0: 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68 65  ./*.** Write the
6ac0: 20 68 65 61 64 65 72 20 69 6e 66 6f 72 6d 61 74   header informat
6ad0: 69 6f 6e 20 69 6e 20 70 57 61 6c 2d 3e 68 64 72  ion in pWal->hdr
6ae0: 20 69 6e 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e   into the wal-in
6af0: 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63  dex..**.** The c
6b00: 68 65 63 6b 73 75 6d 20 6f 6e 20 70 57 61 6c 2d  hecksum on pWal-
6b10: 3e 68 64 72 20 69 73 20 75 70 64 61 74 65 64 20  >hdr is updated 
6b20: 62 65 66 6f 72 65 20 69 74 20 69 73 20 77 72 69  before it is wri
6b30: 74 74 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  tten..*/.static 
6b40: 76 6f 69 64 20 77 61 6c 49 6e 64 65 78 57 72 69  void walIndexWri
6b50: 74 65 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 29  teHdr(Wal *pWal)
6b60: 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c  {.  volatile Wal
6b70: 49 6e 64 65 78 48 64 72 20 2a 61 48 64 72 20 3d  IndexHdr *aHdr =
6b80: 20 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61   walIndexHdr(pWa
6b90: 6c 29 3b 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20  l);.  const int 
6ba0: 6e 43 6b 73 75 6d 20 3d 20 6f 66 66 73 65 74 6f  nCksum = offseto
6bb0: 66 28 57 61 6c 49 6e 64 65 78 48 64 72 2c 20 61  f(WalIndexHdr, a
6bc0: 43 6b 73 75 6d 29 3b 0a 0a 20 20 61 73 73 65 72  Cksum);..  asser
6bd0: 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  t( pWal->writeLo
6be0: 63 6b 20 29 3b 0a 20 20 70 57 61 6c 2d 3e 68 64  ck );.  pWal->hd
6bf0: 72 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a 20 20  r.isInit = 1;.  
6c00: 70 57 61 6c 2d 3e 68 64 72 2e 69 56 65 72 73 69  pWal->hdr.iVersi
6c10: 6f 6e 20 3d 20 57 41 4c 49 4e 44 45 58 5f 4d 41  on = WALINDEX_MA
6c20: 58 5f 56 45 52 53 49 4f 4e 3b 0a 20 20 77 61 6c  X_VERSION;.  wal
6c30: 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28 31 2c  ChecksumBytes(1,
6c40: 20 28 75 38 2a 29 26 70 57 61 6c 2d 3e 68 64 72   (u8*)&pWal->hdr
6c50: 2c 20 6e 43 6b 73 75 6d 2c 20 30 2c 20 70 57 61  , nCksum, 0, pWa
6c60: 6c 2d 3e 68 64 72 2e 61 43 6b 73 75 6d 29 3b 0a  l->hdr.aCksum);.
6c70: 20 20 6d 65 6d 63 70 79 28 28 76 6f 69 64 20 2a    memcpy((void *
6c80: 29 26 61 48 64 72 5b 31 5d 2c 20 28 76 6f 69 64  )&aHdr[1], (void
6c90: 20 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73   *)&pWal->hdr, s
6ca0: 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64  izeof(WalIndexHd
6cb0: 72 29 29 3b 0a 20 20 77 61 6c 53 68 6d 42 61 72  r));.  walShmBar
6cc0: 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20 6d 65  rier(pWal);.  me
6cd0: 6d 63 70 79 28 28 76 6f 69 64 20 2a 29 26 61 48  mcpy((void *)&aH
6ce0: 64 72 5b 30 5d 2c 20 28 76 6f 69 64 20 2a 29 26  dr[0], (void *)&
6cf0: 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f  pWal->hdr, sizeo
6d00: 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b  f(WalIndexHdr));
6d10: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
6d20: 75 6e 63 74 69 6f 6e 20 65 6e 63 6f 64 65 73 20  unction encodes 
6d30: 61 20 73 69 6e 67 6c 65 20 66 72 61 6d 65 20 68  a single frame h
6d40: 65 61 64 65 72 20 61 6e 64 20 77 72 69 74 65 73  eader and writes
6d50: 20 69 74 20 74 6f 20 61 20 62 75 66 66 65 72 0a   it to a buffer.
6d60: 2a 2a 20 73 75 70 70 6c 69 65 64 20 62 79 20 74  ** supplied by t
6d70: 68 65 20 63 61 6c 6c 65 72 2e 20 41 20 66 72 61  he caller. A fra
6d80: 6d 65 2d 68 65 61 64 65 72 20 69 73 20 6d 61 64  me-header is mad
6d90: 65 20 75 70 20 6f 66 20 61 20 73 65 72 69 65 73  e up of a series
6da0: 20 6f 66 20 0a 2a 2a 20 34 2d 62 79 74 65 20 62   of .** 4-byte b
6db0: 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65  ig-endian intege
6dc0: 72 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a  rs, as follows:.
6dd0: 2a 2a 0a 2a 2a 20 20 20 20 20 30 3a 20 50 61 67  **.**     0: Pag
6de0: 65 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20 20 20  e number..**    
6df0: 20 34 3a 20 46 6f 72 20 63 6f 6d 6d 69 74 20 72   4: For commit r
6e00: 65 63 6f 72 64 73 2c 20 74 68 65 20 73 69 7a 65  ecords, the size
6e10: 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65   of the database
6e20: 20 69 6d 61 67 65 20 69 6e 20 70 61 67 65 73 20   image in pages 
6e30: 0a 2a 2a 20 20 20 20 20 20 20 20 61 66 74 65 72  .**        after
6e40: 20 74 68 65 20 63 6f 6d 6d 69 74 2e 20 46 6f 72   the commit. For
6e50: 20 61 6c 6c 20 6f 74 68 65 72 20 72 65 63 6f 72   all other recor
6e60: 64 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20  ds, zero..**    
6e70: 20 38 3a 20 53 61 6c 74 2d 31 20 28 63 6f 70 69   8: Salt-1 (copi
6e80: 65 64 20 66 72 6f 6d 20 74 68 65 20 77 61 6c 2d  ed from the wal-
6e90: 68 65 61 64 65 72 29 0a 2a 2a 20 20 20 20 31 32  header).**    12
6ea0: 3a 20 53 61 6c 74 2d 32 20 28 63 6f 70 69 65 64  : Salt-2 (copied
6eb0: 20 66 72 6f 6d 20 74 68 65 20 77 61 6c 2d 68 65   from the wal-he
6ec0: 61 64 65 72 29 0a 2a 2a 20 20 20 20 31 36 3a 20  ader).**    16: 
6ed0: 43 68 65 63 6b 73 75 6d 2d 31 2e 0a 2a 2a 20 20  Checksum-1..**  
6ee0: 20 20 32 30 3a 20 43 68 65 63 6b 73 75 6d 2d 32    20: Checksum-2
6ef0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
6f00: 20 77 61 6c 45 6e 63 6f 64 65 46 72 61 6d 65 28   walEncodeFrame(
6f10: 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20  .  Wal *pWal,   
6f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6f30: 20 20 20 2f 2a 20 54 68 65 20 77 72 69 74 65 2d     /* The write-
6f40: 61 68 65 61 64 20 6c 6f 67 20 2a 2f 0a 20 20 75  ahead log */.  u
6f50: 33 32 20 69 50 61 67 65 2c 20 20 20 20 20 20 20  32 iPage,       
6f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6f70: 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20  * Database page 
6f80: 6e 75 6d 62 65 72 20 66 6f 72 20 66 72 61 6d 65  number for frame
6f90: 20 2a 2f 0a 20 20 75 33 32 20 6e 54 72 75 6e 63   */.  u32 nTrunc
6fa0: 61 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ate,            
6fb0: 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 64 62 20        /* New db 
6fc0: 73 69 7a 65 20 28 6f 72 20 30 20 66 6f 72 20 6e  size (or 0 for n
6fd0: 6f 6e 2d 63 6f 6d 6d 69 74 20 66 72 61 6d 65 73  on-commit frames
6fe0: 29 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61 74 61  ) */.  u8 *aData
6ff0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
7000: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
7010: 72 20 74 6f 20 70 61 67 65 20 64 61 74 61 20 2a  r to page data *
7020: 2f 0a 20 20 75 38 20 2a 61 46 72 61 6d 65 20 20  /.  u8 *aFrame  
7030: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7040: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 57 72 69 74      /* OUT: Writ
7050: 65 20 65 6e 63 6f 64 65 64 20 66 72 61 6d 65 20  e encoded frame 
7060: 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  here */.){.  int
7070: 20 6e 61 74 69 76 65 43 6b 73 75 6d 3b 20 20 20   nativeCksum;   
7080: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7090: 54 72 75 65 20 66 6f 72 20 6e 61 74 69 76 65 20  True for native 
70a0: 62 79 74 65 2d 6f 72 64 65 72 20 63 68 65 63 6b  byte-order check
70b0: 73 75 6d 73 20 2a 2f 0a 20 20 75 33 32 20 2a 61  sums */.  u32 *a
70c0: 43 6b 73 75 6d 20 3d 20 70 57 61 6c 2d 3e 68 64  Cksum = pWal->hd
70d0: 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 3b 0a 20  r.aFrameCksum;. 
70e0: 20 61 73 73 65 72 74 28 20 57 41 4c 5f 46 52 41   assert( WAL_FRA
70f0: 4d 45 5f 48 44 52 53 49 5a 45 3d 3d 32 34 20 29  ME_HDRSIZE==24 )
7100: 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74 34 62  ;.  sqlite3Put4b
7110: 79 74 65 28 26 61 46 72 61 6d 65 5b 30 5d 2c 20  yte(&aFrame[0], 
7120: 69 50 61 67 65 29 3b 0a 20 20 73 71 6c 69 74 65  iPage);.  sqlite
7130: 33 50 75 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Put4byte(&aFram
7140: 65 5b 34 5d 2c 20 6e 54 72 75 6e 63 61 74 65 29  e[4], nTruncate)
7150: 3b 0a 20 20 6d 65 6d 63 70 79 28 26 61 46 72 61  ;.  memcpy(&aFra
7160: 6d 65 5b 38 5d 2c 20 70 57 61 6c 2d 3e 68 64 72  me[8], pWal->hdr
7170: 2e 61 53 61 6c 74 2c 20 38 29 3b 0a 0a 20 20 6e  .aSalt, 8);..  n
7180: 61 74 69 76 65 43 6b 73 75 6d 20 3d 20 28 70 57  ativeCksum = (pW
7190: 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b  al->hdr.bigEndCk
71a0: 73 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45  sum==SQLITE_BIGE
71b0: 4e 44 49 41 4e 29 3b 0a 20 20 77 61 6c 43 68 65  NDIAN);.  walChe
71c0: 63 6b 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76  cksumBytes(nativ
71d0: 65 43 6b 73 75 6d 2c 20 61 46 72 61 6d 65 2c 20  eCksum, aFrame, 
71e0: 38 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75  8, aCksum, aCksu
71f0: 6d 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75  m);.  walChecksu
7200: 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73  mBytes(nativeCks
7210: 75 6d 2c 20 61 44 61 74 61 2c 20 70 57 61 6c 2d  um, aData, pWal-
7220: 3e 73 7a 50 61 67 65 2c 20 61 43 6b 73 75 6d 2c  >szPage, aCksum,
7230: 20 61 43 6b 73 75 6d 29 3b 0a 0a 20 20 73 71 6c   aCksum);..  sql
7240: 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 46  ite3Put4byte(&aF
7250: 72 61 6d 65 5b 31 36 5d 2c 20 61 43 6b 73 75 6d  rame[16], aCksum
7260: 5b 30 5d 29 3b 0a 20 20 73 71 6c 69 74 65 33 50  [0]);.  sqlite3P
7270: 75 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b  ut4byte(&aFrame[
7280: 32 30 5d 2c 20 61 43 6b 73 75 6d 5b 31 5d 29 3b  20], aCksum[1]);
7290: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20  .}../*.** Check 
72a0: 74 6f 20 73 65 65 20 69 66 20 74 68 65 20 66 72  to see if the fr
72b0: 61 6d 65 20 77 69 74 68 20 68 65 61 64 65 72 20  ame with header 
72c0: 69 6e 20 61 46 72 61 6d 65 5b 5d 20 61 6e 64 20  in aFrame[] and 
72d0: 63 6f 6e 74 65 6e 74 0a 2a 2a 20 69 6e 20 61 44  content.** in aD
72e0: 61 74 61 5b 5d 20 69 73 20 76 61 6c 69 64 2e 20  ata[] is valid. 
72f0: 20 49 66 20 69 74 20 69 73 20 61 20 76 61 6c 69   If it is a vali
7300: 64 20 66 72 61 6d 65 2c 20 66 69 6c 6c 20 2a 70  d frame, fill *p
7310: 69 50 61 67 65 20 61 6e 64 0a 2a 2a 20 2a 70 6e  iPage and.** *pn
7320: 54 72 75 6e 63 61 74 65 20 61 6e 64 20 72 65 74  Truncate and ret
7330: 75 72 6e 20 74 72 75 65 2e 20 20 52 65 74 75 72  urn true.  Retur
7340: 6e 20 69 66 20 74 68 65 20 66 72 61 6d 65 20 69  n if the frame i
7350: 73 20 6e 6f 74 20 76 61 6c 69 64 2e 0a 2a 2f 0a  s not valid..*/.
7360: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 44 65  static int walDe
7370: 63 6f 64 65 46 72 61 6d 65 28 0a 20 20 57 61 6c  codeFrame(.  Wal
7380: 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20   *pWal,         
7390: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
73a0: 54 68 65 20 77 72 69 74 65 2d 61 68 65 61 64 20  The write-ahead 
73b0: 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69  log */.  u32 *pi
73c0: 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20  Page,           
73d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
73e0: 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20 6e   Database page n
73f0: 75 6d 62 65 72 20 66 6f 72 20 66 72 61 6d 65 20  umber for frame 
7400: 2a 2f 0a 20 20 75 33 32 20 2a 70 6e 54 72 75 6e  */.  u32 *pnTrun
7410: 63 61 74 65 2c 20 20 20 20 20 20 20 20 20 20 20  cate,           
7420: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77       /* OUT: New
7430: 20 64 62 20 73 69 7a 65 20 28 6f 72 20 30 20 69   db size (or 0 i
7440: 66 20 6e 6f 74 20 63 6f 6d 6d 69 74 29 20 2a 2f  f not commit) */
7450: 0a 20 20 75 38 20 2a 61 44 61 74 61 2c 20 20 20  .  u8 *aData,   
7460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7470: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
7480: 20 70 61 67 65 20 64 61 74 61 20 28 66 6f 72 20   page data (for 
7490: 63 68 65 63 6b 73 75 6d 29 20 2a 2f 0a 20 20 75  checksum) */.  u
74a0: 38 20 2a 61 46 72 61 6d 65 20 20 20 20 20 20 20  8 *aFrame       
74b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
74c0: 2a 20 46 72 61 6d 65 20 64 61 74 61 20 2a 2f 0a  * Frame data */.
74d0: 29 7b 0a 20 20 69 6e 74 20 6e 61 74 69 76 65 43  ){.  int nativeC
74e0: 6b 73 75 6d 3b 20 20 20 20 20 20 20 20 20 20 20  ksum;           
74f0: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72       /* True for
7500: 20 6e 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64   native byte-ord
7510: 65 72 20 63 68 65 63 6b 73 75 6d 73 20 2a 2f 0a  er checksums */.
7520: 20 20 75 33 32 20 2a 61 43 6b 73 75 6d 20 3d 20    u32 *aCksum = 
7530: 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
7540: 43 6b 73 75 6d 3b 0a 20 20 75 33 32 20 70 67 6e  Cksum;.  u32 pgn
7550: 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o;              
7560: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65           /* Page
7570: 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 66   number of the f
7580: 72 61 6d 65 20 2a 2f 0a 20 20 61 73 73 65 72 74  rame */.  assert
7590: 28 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  ( WAL_FRAME_HDRS
75a0: 49 5a 45 3d 3d 32 34 20 29 3b 0a 0a 20 20 2f 2a  IZE==24 );..  /*
75b0: 20 41 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79   A frame is only
75c0: 20 76 61 6c 69 64 20 69 66 20 74 68 65 20 73 61   valid if the sa
75d0: 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  lt values in the
75e0: 20 66 72 61 6d 65 2d 68 65 61 64 65 72 0a 20 20   frame-header.  
75f0: 2a 2a 20 6d 61 74 63 68 20 74 68 65 20 73 61 6c  ** match the sal
7600: 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20  t values in the 
7610: 77 61 6c 2d 68 65 61 64 65 72 2e 20 0a 20 20 2a  wal-header. .  *
7620: 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26  /.  if( memcmp(&
7630: 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c  pWal->hdr.aSalt,
7640: 20 26 61 46 72 61 6d 65 5b 38 5d 2c 20 38 29 21   &aFrame[8], 8)!
7650: 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  =0 ){.    return
7660: 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 20   0;.  }..  /* A 
7670: 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20 76 61  frame is only va
7680: 6c 69 64 20 69 66 20 74 68 65 20 70 61 67 65 20  lid if the page 
7690: 6e 75 6d 62 65 72 20 69 73 20 63 72 65 61 74 65  number is create
76a0: 72 20 74 68 61 6e 20 7a 65 72 6f 2e 0a 20 20 2a  r than zero..  *
76b0: 2f 0a 20 20 70 67 6e 6f 20 3d 20 73 71 6c 69 74  /.  pgno = sqlit
76c0: 65 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61  e3Get4byte(&aFra
76d0: 6d 65 5b 30 5d 29 3b 0a 20 20 69 66 28 20 70 67  me[0]);.  if( pg
76e0: 6e 6f 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  no==0 ){.    ret
76f0: 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  urn 0;.  }..  /*
7700: 20 41 20 66 72 61 6d 65 20 69 73 20 6f 6e 6c 79   A frame is only
7710: 20 76 61 6c 69 64 20 69 66 20 61 20 63 68 65 63   valid if a chec
7720: 6b 73 75 6d 20 6f 66 20 74 68 65 20 57 41 4c 20  ksum of the WAL 
7730: 68 65 61 64 65 72 2c 0a 20 20 2a 2a 20 61 6c 6c  header,.  ** all
7740: 20 70 72 69 6f 72 20 66 72 61 6d 73 2c 20 74 68   prior frams, th
7750: 65 20 66 69 72 73 74 20 31 36 20 62 79 74 65 73  e first 16 bytes
7760: 20 6f 66 20 74 68 69 73 20 66 72 61 6d 65 2d 68   of this frame-h
7770: 65 61 64 65 72 2c 20 0a 20 20 2a 2a 20 61 6e 64  eader, .  ** and
7780: 20 74 68 65 20 66 72 61 6d 65 2d 64 61 74 61 20   the frame-data 
7790: 6d 61 74 63 68 65 73 20 74 68 65 20 63 68 65 63  matches the chec
77a0: 6b 73 75 6d 20 69 6e 20 74 68 65 20 6c 61 73 74  ksum in the last
77b0: 20 38 20 0a 20 20 2a 2a 20 62 79 74 65 73 20 6f   8 .  ** bytes o
77c0: 66 20 74 68 69 73 20 66 72 61 6d 65 2d 68 65 61  f this frame-hea
77d0: 64 65 72 2e 0a 20 20 2a 2f 0a 20 20 6e 61 74 69  der..  */.  nati
77e0: 76 65 43 6b 73 75 6d 20 3d 20 28 70 57 61 6c 2d  veCksum = (pWal-
77f0: 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d  >hdr.bigEndCksum
7800: 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49  ==SQLITE_BIGENDI
7810: 41 4e 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73  AN);.  walChecks
7820: 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b  umBytes(nativeCk
7830: 73 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38 2c 20  sum, aFrame, 8, 
7840: 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b  aCksum, aCksum);
7850: 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79  .  walChecksumBy
7860: 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c  tes(nativeCksum,
7870: 20 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e 73 7a   aData, pWal->sz
7880: 50 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20 61 43  Page, aCksum, aC
7890: 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20 61 43 6b  ksum);.  if( aCk
78a0: 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65 33 47  sum[0]!=sqlite3G
78b0: 65 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b  et4byte(&aFrame[
78c0: 31 36 5d 29 20 0a 20 20 20 7c 7c 20 61 43 6b 73  16]) .   || aCks
78d0: 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33 47 65  um[1]!=sqlite3Ge
78e0: 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 32  t4byte(&aFrame[2
78f0: 30 5d 29 20 0a 20 20 29 7b 0a 20 20 20 20 2f 2a  0]) .  ){.    /*
7900: 20 43 68 65 63 6b 73 75 6d 20 66 61 69 6c 65 64   Checksum failed
7910: 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20  . */.    return 
7920: 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20  0;.  }..  /* If 
7930: 77 65 20 72 65 61 63 68 20 74 68 69 73 20 70 6f  we reach this po
7940: 69 6e 74 2c 20 74 68 65 20 66 72 61 6d 65 20 69  int, the frame i
7950: 73 20 76 61 6c 69 64 2e 20 20 52 65 74 75 72 6e  s valid.  Return
7960: 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72   the page number
7970: 0a 20 20 2a 2a 20 61 6e 64 20 74 68 65 20 6e 65  .  ** and the ne
7980: 77 20 64 61 74 61 62 61 73 65 20 73 69 7a 65 2e  w database size.
7990: 0a 20 20 2a 2f 0a 20 20 2a 70 69 50 61 67 65 20  .  */.  *piPage 
79a0: 3d 20 70 67 6e 6f 3b 0a 20 20 2a 70 6e 54 72 75  = pgno;.  *pnTru
79b0: 6e 63 61 74 65 20 3d 20 73 71 6c 69 74 65 33 47  ncate = sqlite3G
79c0: 65 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b  et4byte(&aFrame[
79d0: 34 5d 29 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b  4]);.  return 1;
79e0: 0a 7d 0a 0a 0a 23 69 66 20 64 65 66 69 6e 65 64  .}...#if defined
79f0: 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26 26  (SQLITE_TEST) &&
7a00: 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
7a10: 44 45 42 55 47 29 0a 2f 2a 0a 2a 2a 20 4e 61 6d  DEBUG)./*.** Nam
7a20: 65 73 20 6f 66 20 6c 6f 63 6b 73 2e 20 20 54 68  es of locks.  Th
7a30: 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 75 73  is routine is us
7a40: 65 64 20 74 6f 20 70 72 6f 76 69 64 65 20 64 65  ed to provide de
7a50: 62 75 67 67 69 6e 67 20 6f 75 74 70 75 74 20 61  bugging output a
7a60: 6e 64 20 69 73 20 6e 6f 74 0a 2a 2a 20 61 20 70  nd is not.** a p
7a70: 61 72 74 20 6f 66 20 61 6e 20 6f 72 64 69 6e 61  art of an ordina
7a80: 72 79 20 62 75 69 6c 64 2e 0a 2a 2f 0a 73 74 61  ry build..*/.sta
7a90: 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  tic const char *
7aa0: 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 69 6e 74 20  walLockName(int 
7ab0: 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66 28 20  lockIdx){.  if( 
7ac0: 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 57 52 49  lockIdx==WAL_WRI
7ad0: 54 45 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 72  TE_LOCK ){.    r
7ae0: 65 74 75 72 6e 20 22 57 52 49 54 45 2d 4c 4f 43  eturn "WRITE-LOC
7af0: 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20  K";.  }else if( 
7b00: 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 43 4b 50  lockIdx==WAL_CKP
7b10: 54 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 72 65  T_LOCK ){.    re
7b20: 74 75 72 6e 20 22 43 4b 50 54 2d 4c 4f 43 4b 22  turn "CKPT-LOCK"
7b30: 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 6c 6f  ;.  }else if( lo
7b40: 63 6b 49 64 78 3d 3d 57 41 4c 5f 52 45 43 4f 56  ckIdx==WAL_RECOV
7b50: 45 52 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20 72  ER_LOCK ){.    r
7b60: 65 74 75 72 6e 20 22 52 45 43 4f 56 45 52 2d 4c  eturn "RECOVER-L
7b70: 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  OCK";.  }else{. 
7b80: 20 20 20 73 74 61 74 69 63 20 63 68 61 72 20 7a     static char z
7b90: 4e 61 6d 65 5b 31 35 5d 3b 0a 20 20 20 20 73 71  Name[15];.    sq
7ba0: 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 73  lite3_snprintf(s
7bb0: 69 7a 65 6f 66 28 7a 4e 61 6d 65 29 2c 20 7a 4e  izeof(zName), zN
7bc0: 61 6d 65 2c 20 22 52 45 41 44 2d 4c 4f 43 4b 5b  ame, "READ-LOCK[
7bd0: 25 64 5d 22 2c 0a 20 20 20 20 20 20 20 20 20 20  %d]",.          
7be0: 20 20 20 20 20 20 20 20 20 20 20 6c 6f 63 6b 49             lockI
7bf0: 64 78 2d 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  dx-WAL_READ_LOCK
7c00: 28 30 29 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  (0));.    return
7c10: 20 7a 4e 61 6d 65 3b 0a 20 20 7d 0a 7d 0a 23 65   zName;.  }.}.#e
7c20: 6e 64 69 66 20 2f 2a 64 65 66 69 6e 65 64 28 53  ndif /*defined(S
7c30: 51 4c 49 54 45 5f 54 45 53 54 29 20 7c 7c 20 64  QLITE_TEST) || d
7c40: 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45  efined(SQLITE_DE
7c50: 42 55 47 29 20 2a 2f 0a 20 20 20 20 0a 0a 2f 2a  BUG) */.    ../*
7c60: 0a 2a 2a 20 53 65 74 20 6f 72 20 72 65 6c 65 61  .** Set or relea
7c70: 73 65 20 6c 6f 63 6b 73 20 6f 6e 20 74 68 65 20  se locks on the 
7c80: 57 41 4c 2e 20 20 4c 6f 63 6b 73 20 61 72 65 20  WAL.  Locks are 
7c90: 65 69 74 68 65 72 20 73 68 61 72 65 64 20 6f 72  either shared or
7ca0: 20 65 78 63 6c 75 73 69 76 65 2e 0a 2a 2a 20 41   exclusive..** A
7cb0: 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62 65 20   lock cannot be 
7cc0: 6d 6f 76 65 64 20 64 69 72 65 63 74 6c 79 20 62  moved directly b
7cd0: 65 74 77 65 65 6e 20 73 68 61 72 65 64 20 61 6e  etween shared an
7ce0: 64 20 65 78 63 6c 75 73 69 76 65 20 2d 20 69 74  d exclusive - it
7cf0: 20 6d 75 73 74 20 67 6f 0a 2a 2a 20 74 68 72 6f   must go.** thro
7d00: 75 67 68 20 74 68 65 20 75 6e 6c 6f 63 6b 65 64  ugh the unlocked
7d10: 20 73 74 61 74 65 20 66 69 72 73 74 2e 0a 2a 2a   state first..**
7d20: 0a 2a 2a 20 49 6e 20 6c 6f 63 6b 69 6e 67 5f 6d  .** In locking_m
7d30: 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2c 20 61  ode=EXCLUSIVE, a
7d40: 6c 6c 20 6f 66 20 74 68 65 73 65 20 72 6f 75 74  ll of these rout
7d50: 69 6e 65 73 20 62 65 63 6f 6d 65 20 6e 6f 2d 6f  ines become no-o
7d60: 70 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ps..*/.static in
7d70: 74 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28  t walLockShared(
7d80: 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c  Wal *pWal, int l
7d90: 6f 63 6b 49 64 78 29 7b 0a 20 20 69 6e 74 20 72  ockIdx){.  int r
7da0: 63 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65  c;.  if( pWal->e
7db0: 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72  xclusiveMode ) r
7dc0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
7dd0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f  .  rc = sqlite3O
7de0: 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70  sShmLock(pWal->p
7df0: 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 31  DbFd, lockIdx, 1
7e00: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
7e10: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
7e20: 5f 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49  _SHM_LOCK | SQLI
7e30: 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29 3b 0a  TE_SHM_SHARED);.
7e40: 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c    WALTRACE(("WAL
7e50: 25 70 3a 20 61 63 71 75 69 72 65 20 53 48 41 52  %p: acquire SHAR
7e60: 45 44 2d 25 73 20 25 73 5c 6e 22 2c 20 70 57 61  ED-%s %s\n", pWa
7e70: 6c 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 77  l,.            w
7e80: 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49  alLockName(lockI
7e90: 64 78 29 2c 20 72 63 20 3f 20 22 66 61 69 6c 65  dx), rc ? "faile
7ea0: 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 56  d" : "ok"));.  V
7eb0: 56 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c  VA_ONLY( pWal->l
7ec0: 6f 63 6b 45 72 72 6f 72 20 3d 20 28 75 38 29 28  ockError = (u8)(
7ed0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc!=SQLITE_OK &&
7ee0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc!=SQLITE_BUSY
7ef0: 29 3b 20 29 0a 20 20 72 65 74 75 72 6e 20 72 63  ); ).  return rc
7f00: 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20  ;.}.static void 
7f10: 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28  walUnlockShared(
7f20: 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c  Wal *pWal, int l
7f30: 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66 28 20 70  ockIdx){.  if( p
7f40: 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f  Wal->exclusiveMo
7f50: 64 65 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 28  de ) return;.  (
7f60: 76 6f 69 64 29 73 71 6c 69 74 65 33 4f 73 53 68  void)sqlite3OsSh
7f70: 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46  mLock(pWal->pDbF
7f80: 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 31 2c 0a 20  d, lockIdx, 1,. 
7f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7fa0: 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53          SQLITE_S
7fb0: 48 4d 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51 4c 49  HM_UNLOCK | SQLI
7fc0: 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29 3b 0a  TE_SHM_SHARED);.
7fd0: 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c    WALTRACE(("WAL
7fe0: 25 70 3a 20 72 65 6c 65 61 73 65 20 53 48 41 52  %p: release SHAR
7ff0: 45 44 2d 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20  ED-%s\n", pWal, 
8000: 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63 6b  walLockName(lock
8010: 49 64 78 29 29 29 3b 0a 7d 0a 73 74 61 74 69 63  Idx)));.}.static
8020: 20 69 6e 74 20 77 61 6c 4c 6f 63 6b 45 78 63 6c   int walLockExcl
8030: 75 73 69 76 65 28 57 61 6c 20 2a 70 57 61 6c 2c  usive(Wal *pWal,
8040: 20 69 6e 74 20 6c 6f 63 6b 49 64 78 2c 20 69 6e   int lockIdx, in
8050: 74 20 6e 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  t n){.  int rc;.
8060: 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c    if( pWal->excl
8070: 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65 74 75  usiveMode ) retu
8080: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20  rn SQLITE_OK;.  
8090: 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 68  rc = sqlite3OsSh
80a0: 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46  mLock(pWal->pDbF
80b0: 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c 0a 20  d, lockIdx, n,. 
80c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
80d0: 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53 48         SQLITE_SH
80e0: 4d 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45 5f  M_LOCK | SQLITE_
80f0: 53 48 4d 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a  SHM_EXCLUSIVE);.
8100: 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c    WALTRACE(("WAL
8110: 25 70 3a 20 61 63 71 75 69 72 65 20 45 58 43 4c  %p: acquire EXCL
8120: 55 53 49 56 45 2d 25 73 20 63 6e 74 3d 25 64 20  USIVE-%s cnt=%d 
8130: 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20 20 20  %s\n", pWal,.   
8140: 20 20 20 20 20 20 20 20 20 77 61 6c 4c 6f 63 6b           walLock
8150: 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c 20 6e  Name(lockIdx), n
8160: 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20  , rc ? "failed" 
8170: 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 56 56 41 5f  : "ok"));.  VVA_
8180: 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f 63 6b  ONLY( pWal->lock
8190: 45 72 72 6f 72 20 3d 20 28 75 38 29 28 72 63 21  Error = (u8)(rc!
81a0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 72 63  =SQLITE_OK && rc
81b0: 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 29 3b 20  !=SQLITE_BUSY); 
81c0: 29 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ).  return rc;.}
81d0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
81e0: 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  UnlockExclusive(
81f0: 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c  Wal *pWal, int l
8200: 6f 63 6b 49 64 78 2c 20 69 6e 74 20 6e 29 7b 0a  ockIdx, int n){.
8210: 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c    if( pWal->excl
8220: 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65 74 75  usiveMode ) retu
8230: 72 6e 3b 0a 20 20 28 76 6f 69 64 29 73 71 6c 69  rn;.  (void)sqli
8240: 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61  te3OsShmLock(pWa
8250: 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64  l->pDbFd, lockId
8260: 78 2c 20 6e 2c 0a 20 20 20 20 20 20 20 20 20 20  x, n,.          
8270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53                 S
8280: 51 4c 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f 43 4b  QLITE_SHM_UNLOCK
8290: 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f 45 58   | SQLITE_SHM_EX
82a0: 43 4c 55 53 49 56 45 29 3b 0a 20 20 57 41 4c 54  CLUSIVE);.  WALT
82b0: 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 72 65  RACE(("WAL%p: re
82c0: 6c 65 61 73 65 20 45 58 43 4c 55 53 49 56 45 2d  lease EXCLUSIVE-
82d0: 25 73 20 63 6e 74 3d 25 64 5c 6e 22 2c 20 70 57  %s cnt=%d\n", pW
82e0: 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  al,.            
82f0: 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63   walLockName(loc
8300: 6b 49 64 78 29 2c 20 6e 29 29 3b 0a 7d 0a 0a 2f  kIdx), n));.}../
8310: 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20 68  *.** Compute a h
8320: 61 73 68 20 6f 6e 20 61 20 70 61 67 65 20 6e 75  ash on a page nu
8330: 6d 62 65 72 2e 20 20 54 68 65 20 72 65 73 75 6c  mber.  The resul
8340: 74 69 6e 67 20 68 61 73 68 20 76 61 6c 75 65 20  ting hash value 
8350: 6d 75 73 74 20 6c 61 6e 64 0a 2a 2a 20 62 65 74  must land.** bet
8360: 77 65 65 6e 20 30 20 61 6e 64 20 28 48 41 53 48  ween 0 and (HASH
8370: 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 2e 20  TABLE_NSLOT-1). 
8380: 20 54 68 65 20 77 61 6c 48 61 73 68 4e 65 78 74   The walHashNext
8390: 28 29 20 66 75 6e 63 74 69 6f 6e 20 61 64 76 61  () function adva
83a0: 6e 63 65 73 0a 2a 2a 20 74 68 65 20 68 61 73 68  nces.** the hash
83b0: 20 74 6f 20 74 68 65 20 6e 65 78 74 20 76 61 6c   to the next val
83c0: 75 65 20 69 6e 20 74 68 65 20 65 76 65 6e 74 20  ue in the event 
83d0: 6f 66 20 61 20 63 6f 6c 6c 69 73 69 6f 6e 2e 0a  of a collision..
83e0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  */.static int wa
83f0: 6c 48 61 73 68 28 75 33 32 20 69 50 61 67 65 29  lHash(u32 iPage)
8400: 7b 0a 20 20 61 73 73 65 72 74 28 20 69 50 61 67  {.  assert( iPag
8410: 65 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  e>0 );.  assert(
8420: 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f   (HASHTABLE_NSLO
8430: 54 20 26 20 28 48 41 53 48 54 41 42 4c 45 5f 4e  T & (HASHTABLE_N
8440: 53 4c 4f 54 2d 31 29 29 3d 3d 30 20 29 3b 0a 20  SLOT-1))==0 );. 
8450: 20 72 65 74 75 72 6e 20 28 69 50 61 67 65 2a 48   return (iPage*H
8460: 41 53 48 54 41 42 4c 45 5f 48 41 53 48 5f 31 29  ASHTABLE_HASH_1)
8470: 20 26 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 53   & (HASHTABLE_NS
8480: 4c 4f 54 2d 31 29 3b 0a 7d 0a 73 74 61 74 69 63  LOT-1);.}.static
8490: 20 69 6e 74 20 77 61 6c 4e 65 78 74 48 61 73 68   int walNextHash
84a0: 28 69 6e 74 20 69 50 72 69 6f 72 48 61 73 68 29  (int iPriorHash)
84b0: 7b 0a 20 20 72 65 74 75 72 6e 20 28 69 50 72 69  {.  return (iPri
84c0: 6f 72 48 61 73 68 2b 31 29 26 28 48 41 53 48 54  orHash+1)&(HASHT
84d0: 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 3b 0a 7d  ABLE_NSLOT-1);.}
84e0: 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72 6e 20  ../* .** Return 
84f0: 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68 65 20  pointers to the 
8500: 68 61 73 68 20 74 61 62 6c 65 20 61 6e 64 20 70  hash table and p
8510: 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79  age number array
8520: 20 73 74 6f 72 65 64 20 6f 6e 0a 2a 2a 20 70 61   stored on.** pa
8530: 67 65 20 69 48 61 73 68 20 6f 66 20 74 68 65 20  ge iHash of the 
8540: 77 61 6c 2d 69 6e 64 65 78 2e 20 54 68 65 20 77  wal-index. The w
8550: 61 6c 2d 69 6e 64 65 78 20 69 73 20 62 72 6f 6b  al-index is brok
8560: 65 6e 20 69 6e 74 6f 20 33 32 4b 42 20 70 61 67  en into 32KB pag
8570: 65 73 0a 2a 2a 20 6e 75 6d 62 65 72 65 64 20 73  es.** numbered s
8580: 74 61 72 74 69 6e 67 20 66 72 6f 6d 20 30 2e 0a  tarting from 0..
8590: 2a 2a 0a 2a 2a 20 53 65 74 20 6f 75 74 70 75 74  **.** Set output
85a0: 20 76 61 72 69 61 62 6c 65 20 2a 70 61 48 61 73   variable *paHas
85b0: 68 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68  h to point to th
85c0: 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 68  e start of the h
85d0: 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20 69 6e 20  ash table.** in 
85e0: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69  the wal-index fi
85f0: 6c 65 2e 20 53 65 74 20 2a 70 69 5a 65 72 6f 20  le. Set *piZero 
8600: 74 6f 20 6f 6e 65 20 6c 65 73 73 20 74 68 61 6e  to one less than
8610: 20 74 68 65 20 66 72 61 6d 65 20 0a 2a 2a 20 6e   the frame .** n
8620: 75 6d 62 65 72 20 6f 66 20 74 68 65 20 66 69 72  umber of the fir
8630: 73 74 20 66 72 61 6d 65 20 69 6e 64 65 78 65 64  st frame indexed
8640: 20 62 79 20 74 68 69 73 20 68 61 73 68 20 74 61   by this hash ta
8650: 62 6c 65 2e 20 49 66 20 61 0a 2a 2a 20 73 6c 6f  ble. If a.** slo
8660: 74 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61  t in the hash ta
8670: 62 6c 65 20 69 73 20 73 65 74 20 74 6f 20 4e 2c  ble is set to N,
8680: 20 69 74 20 72 65 66 65 72 73 20 74 6f 20 66 72   it refers to fr
8690: 61 6d 65 20 6e 75 6d 62 65 72 20 0a 2a 2a 20 28  ame number .** (
86a0: 2a 70 69 5a 65 72 6f 2b 4e 29 20 69 6e 20 74 68  *piZero+N) in th
86b0: 65 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a 20 46 69 6e  e log..**.** Fin
86c0: 61 6c 6c 79 2c 20 73 65 74 20 2a 70 61 50 67 6e  ally, set *paPgn
86d0: 6f 20 73 6f 20 74 68 61 74 20 2a 70 61 50 67 6e  o so that *paPgn
86e0: 6f 5b 31 5d 20 69 73 20 74 68 65 20 70 61 67 65  o[1] is the page
86f0: 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 0a 2a   number of the.*
8700: 2a 20 66 69 72 73 74 20 66 72 61 6d 65 20 69 6e  * first frame in
8710: 64 65 78 65 64 20 62 79 20 74 68 65 20 68 61 73  dexed by the has
8720: 68 20 74 61 62 6c 65 2c 20 66 72 61 6d 65 20 28  h table, frame (
8730: 2a 70 69 5a 65 72 6f 2b 31 29 2e 0a 2a 2f 0a 73  *piZero+1)..*/.s
8740: 74 61 74 69 63 20 69 6e 74 20 77 61 6c 48 61 73  tatic int walHas
8750: 68 47 65 74 28 0a 20 20 57 61 6c 20 2a 70 57 61  hGet(.  Wal *pWa
8760: 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
8770: 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 68          /* WAL h
8780: 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 69  andle */.  int i
8790: 48 61 73 68 2c 20 20 20 20 20 20 20 20 20 20 20  Hash,           
87a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
87b0: 6e 64 20 74 68 65 20 69 48 61 73 68 27 74 68 20  nd the iHash'th 
87c0: 74 61 62 6c 65 20 2a 2f 0a 20 20 76 6f 6c 61 74  table */.  volat
87d0: 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 2a 70 61  ile ht_slot **pa
87e0: 48 61 73 68 2c 20 20 20 20 20 20 2f 2a 20 4f 55  Hash,      /* OU
87f0: 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20 68 61  T: Pointer to ha
8800: 73 68 20 69 6e 64 65 78 20 2a 2f 0a 20 20 76 6f  sh index */.  vo
8810: 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 70 61 50  latile u32 **paP
8820: 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  gno,          /*
8830: 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f   OUT: Pointer to
8840: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72   page number arr
8850: 61 79 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 5a  ay */.  u32 *piZ
8860: 65 72 6f 20 20 20 20 20 20 20 20 20 20 20 20 20  ero             
8870: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
8880: 46 72 61 6d 65 20 61 73 73 6f 63 69 61 74 65 64  Frame associated
8890: 20 77 69 74 68 20 2a 70 61 50 67 6e 6f 5b 30 5d   with *paPgno[0]
88a0: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b   */.){.  int rc;
88b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
88c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
88d0: 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 76 6f 6c  rn code */.  vol
88e0: 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f  atile u32 *aPgno
88f0: 3b 0a 0a 20 20 72 63 20 3d 20 77 61 6c 49 6e 64  ;..  rc = walInd
8900: 65 78 50 61 67 65 28 70 57 61 6c 2c 20 69 48 61  exPage(pWal, iHa
8910: 73 68 2c 20 26 61 50 67 6e 6f 29 3b 0a 20 20 61  sh, &aPgno);.  a
8920: 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49 54  ssert( rc==SQLIT
8930: 45 5f 4f 4b 20 7c 7c 20 69 48 61 73 68 3e 30 20  E_OK || iHash>0 
8940: 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  );..  if( rc==SQ
8950: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 75  LITE_OK ){.    u
8960: 33 32 20 69 5a 65 72 6f 3b 0a 20 20 20 20 76 6f  32 iZero;.    vo
8970: 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a  latile ht_slot *
8980: 61 48 61 73 68 3b 0a 0a 20 20 20 20 61 48 61 73  aHash;..    aHas
8990: 68 20 3d 20 28 76 6f 6c 61 74 69 6c 65 20 68 74  h = (volatile ht
89a0: 5f 73 6c 6f 74 20 2a 29 26 61 50 67 6e 6f 5b 48  _slot *)&aPgno[H
89b0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5d 3b  ASHTABLE_NPAGE];
89c0: 0a 20 20 20 20 69 66 28 20 69 48 61 73 68 3d 3d  .    if( iHash==
89d0: 30 20 29 7b 0a 20 20 20 20 20 20 61 50 67 6e 6f  0 ){.      aPgno
89e0: 20 3d 20 26 61 50 67 6e 6f 5b 57 41 4c 49 4e 44   = &aPgno[WALIND
89f0: 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65  EX_HDR_SIZE/size
8a00: 6f 66 28 75 33 32 29 5d 3b 0a 20 20 20 20 20 20  of(u32)];.      
8a10: 69 5a 65 72 6f 20 3d 20 30 3b 0a 20 20 20 20 7d  iZero = 0;.    }
8a20: 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 5a 65 72  else{.      iZer
8a30: 6f 20 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e 50  o = HASHTABLE_NP
8a40: 41 47 45 5f 4f 4e 45 20 2b 20 28 69 48 61 73 68  AGE_ONE + (iHash
8a50: 2d 31 29 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50  -1)*HASHTABLE_NP
8a60: 41 47 45 3b 0a 20 20 20 20 7d 0a 20 20 0a 20 20  AGE;.    }.  .  
8a70: 20 20 2a 70 61 50 67 6e 6f 20 3d 20 26 61 50 67    *paPgno = &aPg
8a80: 6e 6f 5b 2d 31 5d 3b 0a 20 20 20 20 2a 70 61 48  no[-1];.    *paH
8a90: 61 73 68 20 3d 20 61 48 61 73 68 3b 0a 20 20 20  ash = aHash;.   
8aa0: 20 2a 70 69 5a 65 72 6f 20 3d 20 69 5a 65 72 6f   *piZero = iZero
8ab0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
8ac0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  c;.}../*.** Retu
8ad0: 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  rn the number of
8ae0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 70   the wal-index p
8af0: 61 67 65 20 74 68 61 74 20 63 6f 6e 74 61 69 6e  age that contain
8b00: 73 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65  s the hash-table
8b10: 0a 2a 2a 20 61 6e 64 20 70 61 67 65 2d 6e 75 6d  .** and page-num
8b20: 62 65 72 20 61 72 72 61 79 20 74 68 61 74 20 63  ber array that c
8b30: 6f 6e 74 61 69 6e 20 65 6e 74 72 69 65 73 20 63  ontain entries c
8b40: 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20  orresponding to 
8b50: 57 41 4c 20 66 72 61 6d 65 0a 2a 2a 20 69 46 72  WAL frame.** iFr
8b60: 61 6d 65 2e 20 54 68 65 20 77 61 6c 2d 69 6e 64  ame. The wal-ind
8b70: 65 78 20 69 73 20 62 72 6f 6b 65 6e 20 75 70 20  ex is broken up 
8b80: 69 6e 74 6f 20 33 32 4b 42 20 70 61 67 65 73 2e  into 32KB pages.
8b90: 20 57 61 6c 2d 69 6e 64 65 78 20 70 61 67 65 73   Wal-index pages
8ba0: 20 0a 2a 2a 20 61 72 65 20 6e 75 6d 62 65 72 65   .** are numbere
8bb0: 64 20 73 74 61 72 74 69 6e 67 20 66 72 6f 6d 20  d starting from 
8bc0: 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  0..*/.static int
8bd0: 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 75 33   walFramePage(u3
8be0: 32 20 69 46 72 61 6d 65 29 7b 0a 20 20 69 6e 74  2 iFrame){.  int
8bf0: 20 69 48 61 73 68 20 3d 20 28 69 46 72 61 6d 65   iHash = (iFrame
8c00: 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  +HASHTABLE_NPAGE
8c10: 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  -HASHTABLE_NPAGE
8c20: 5f 4f 4e 45 2d 31 29 20 2f 20 48 41 53 48 54 41  _ONE-1) / HASHTA
8c30: 42 4c 45 5f 4e 50 41 47 45 3b 0a 20 20 61 73 73  BLE_NPAGE;.  ass
8c40: 65 72 74 28 20 28 69 48 61 73 68 3d 3d 30 20 7c  ert( (iHash==0 |
8c50: 7c 20 69 46 72 61 6d 65 3e 48 41 53 48 54 41 42  | iFrame>HASHTAB
8c60: 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 0a 20 20  LE_NPAGE_ONE).  
8c70: 20 20 20 20 20 26 26 20 28 69 48 61 73 68 3e 3d       && (iHash>=
8c80: 31 20 7c 7c 20 69 46 72 61 6d 65 3c 3d 48 41 53  1 || iFrame<=HAS
8c90: 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45  HTABLE_NPAGE_ONE
8ca0: 29 0a 20 20 20 20 20 20 20 26 26 20 28 69 48 61  ).       && (iHa
8cb0: 73 68 3c 3d 31 20 7c 7c 20 69 46 72 61 6d 65 3e  sh<=1 || iFrame>
8cc0: 28 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  (HASHTABLE_NPAGE
8cd0: 5f 4f 4e 45 2b 48 41 53 48 54 41 42 4c 45 5f 4e  _ONE+HASHTABLE_N
8ce0: 50 41 47 45 29 29 0a 20 20 20 20 20 20 20 26 26  PAGE)).       &&
8cf0: 20 28 69 48 61 73 68 3e 3d 32 20 7c 7c 20 69 46   (iHash>=2 || iF
8d00: 72 61 6d 65 3c 3d 48 41 53 48 54 41 42 4c 45 5f  rame<=HASHTABLE_
8d10: 4e 50 41 47 45 5f 4f 4e 45 2b 48 41 53 48 54 41  NPAGE_ONE+HASHTA
8d20: 42 4c 45 5f 4e 50 41 47 45 29 0a 20 20 20 20 20  BLE_NPAGE).     
8d30: 20 20 26 26 20 28 69 48 61 73 68 3c 3d 32 20 7c    && (iHash<=2 |
8d40: 7c 20 69 46 72 61 6d 65 3e 28 48 41 53 48 54 41  | iFrame>(HASHTA
8d50: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 32 2a  BLE_NPAGE_ONE+2*
8d60: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 29  HASHTABLE_NPAGE)
8d70: 29 0a 20 20 29 3b 0a 20 20 72 65 74 75 72 6e 20  ).  );.  return 
8d80: 69 48 61 73 68 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  iHash;.}../*.** 
8d90: 52 65 74 75 72 6e 20 74 68 65 20 70 61 67 65 20  Return the page 
8da0: 6e 75 6d 62 65 72 20 61 73 73 6f 63 69 61 74 65  number associate
8db0: 64 20 77 69 74 68 20 66 72 61 6d 65 20 69 46 72  d with frame iFr
8dc0: 61 6d 65 20 69 6e 20 74 68 69 73 20 57 41 4c 2e  ame in this WAL.
8dd0: 0a 2a 2f 0a 73 74 61 74 69 63 20 75 33 32 20 77  .*/.static u32 w
8de0: 61 6c 46 72 61 6d 65 50 67 6e 6f 28 57 61 6c 20  alFramePgno(Wal 
8df0: 2a 70 57 61 6c 2c 20 75 33 32 20 69 46 72 61 6d  *pWal, u32 iFram
8e00: 65 29 7b 0a 20 20 69 6e 74 20 69 48 61 73 68 20  e){.  int iHash 
8e10: 3d 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69  = walFramePage(i
8e20: 46 72 61 6d 65 29 3b 0a 20 20 69 66 28 20 69 48  Frame);.  if( iH
8e30: 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65  ash==0 ){.    re
8e40: 74 75 72 6e 20 70 57 61 6c 2d 3e 61 70 57 69 44  turn pWal->apWiD
8e50: 61 74 61 5b 30 5d 5b 57 41 4c 49 4e 44 45 58 5f  ata[0][WALINDEX_
8e60: 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f 66 28  HDR_SIZE/sizeof(
8e70: 75 33 32 29 20 2b 20 69 46 72 61 6d 65 20 2d 20  u32) + iFrame - 
8e80: 31 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  1];.  }.  return
8e90: 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
8ea0: 69 48 61 73 68 5d 5b 28 69 46 72 61 6d 65 2d 31  iHash][(iFrame-1
8eb0: 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  -HASHTABLE_NPAGE
8ec0: 5f 4f 4e 45 29 25 48 41 53 48 54 41 42 4c 45 5f  _ONE)%HASHTABLE_
8ed0: 4e 50 41 47 45 5d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  NPAGE];.}../*.**
8ee0: 20 52 65 6d 6f 76 65 20 65 6e 74 72 69 65 73 20   Remove entries 
8ef0: 66 72 6f 6d 20 74 68 65 20 68 61 73 68 20 74 61  from the hash ta
8f00: 62 6c 65 20 74 68 61 74 20 70 6f 69 6e 74 20 74  ble that point t
8f10: 6f 20 57 41 4c 20 73 6c 6f 74 73 20 67 72 65 61  o WAL slots grea
8f20: 74 65 72 0a 2a 2a 20 74 68 61 6e 20 70 57 61 6c  ter.** than pWal
8f30: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a 2a  ->hdr.mxFrame..*
8f40: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
8f50: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 77 68 65  on is called whe
8f60: 6e 65 76 65 72 20 70 57 61 6c 2d 3e 68 64 72 2e  never pWal->hdr.
8f70: 6d 78 46 72 61 6d 65 20 69 73 20 64 65 63 72 65  mxFrame is decre
8f80: 61 73 65 64 20 64 75 65 0a 2a 2a 20 74 6f 20 61  ased due.** to a
8f90: 20 72 6f 6c 6c 62 61 63 6b 20 6f 72 20 73 61 76   rollback or sav
8fa0: 65 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20 41 74  epoint..**.** At
8fb0: 20 6d 6f 73 74 20 6f 6e 6c 79 20 74 68 65 20 68   most only the h
8fc0: 61 73 68 20 74 61 62 6c 65 20 63 6f 6e 74 61 69  ash table contai
8fd0: 6e 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  ning pWal->hdr.m
8fe0: 78 46 72 61 6d 65 20 6e 65 65 64 73 20 74 6f 20  xFrame needs to 
8ff0: 62 65 0a 2a 2a 20 75 70 64 61 74 65 64 2e 20 20  be.** updated.  
9000: 41 6e 79 20 6c 61 74 65 72 20 68 61 73 68 20 74  Any later hash t
9010: 61 62 6c 65 73 20 77 69 6c 6c 20 62 65 20 61 75  ables will be au
9020: 74 6f 6d 61 74 69 63 61 6c 6c 79 20 63 6c 65 61  tomatically clea
9030: 72 65 64 20 77 68 65 6e 0a 2a 2a 20 70 57 61 6c  red when.** pWal
9040: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 61 64  ->hdr.mxFrame ad
9050: 76 61 6e 63 65 73 20 74 6f 20 74 68 65 20 70 6f  vances to the po
9060: 69 6e 74 20 77 68 65 72 65 20 74 68 6f 73 65 20  int where those 
9070: 68 61 73 68 20 74 61 62 6c 65 73 20 61 72 65 0a  hash tables are.
9080: 2a 2a 20 61 63 74 75 61 6c 6c 79 20 6e 65 65 64  ** actually need
9090: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
90a0: 69 64 20 77 61 6c 43 6c 65 61 6e 75 70 48 61 73  id walCleanupHas
90b0: 68 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20  h(Wal *pWal){.  
90c0: 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74  volatile ht_slot
90d0: 20 2a 61 48 61 73 68 20 3d 20 30 3b 20 20 20 20   *aHash = 0;    
90e0: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 68 61  /* Pointer to ha
90f0: 73 68 20 74 61 62 6c 65 20 74 6f 20 63 6c 65 61  sh table to clea
9100: 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20  r */.  volatile 
9110: 75 33 32 20 2a 61 50 67 6e 6f 20 3d 20 30 3b 20  u32 *aPgno = 0; 
9120: 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e         /* Page n
9130: 75 6d 62 65 72 20 61 72 72 61 79 20 66 6f 72 20  umber array for 
9140: 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20  hash table */.  
9150: 75 33 32 20 69 5a 65 72 6f 20 3d 20 30 3b 20 20  u32 iZero = 0;  
9160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9170: 2f 2a 20 66 72 61 6d 65 20 3d 3d 20 28 61 48 61  /* frame == (aHa
9180: 73 68 5b 78 5d 2b 69 5a 65 72 6f 29 20 2a 2f 0a  sh[x]+iZero) */.
9190: 20 20 69 6e 74 20 69 4c 69 6d 69 74 20 3d 20 30    int iLimit = 0
91a0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
91b0: 20 20 2f 2a 20 5a 65 72 6f 20 76 61 6c 75 65 73    /* Zero values
91c0: 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 74 68   greater than th
91d0: 69 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74  is */.  int nByt
91e0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
91f0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
9200: 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20 7a 65  r of bytes to ze
9210: 72 6f 20 69 6e 20 61 50 67 6e 6f 5b 5d 20 2a 2f  ro in aPgno[] */
9220: 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
9230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9240: 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20 69 74     /* Used to it
9250: 65 72 61 74 65 20 74 68 72 6f 75 67 68 20 61 48  erate through aH
9260: 61 73 68 5b 5d 20 2a 2f 0a 0a 20 20 61 73 73 65  ash[] */..  asse
9270: 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c  rt( pWal->writeL
9280: 6f 63 6b 20 29 3b 0a 20 20 74 65 73 74 63 61 73  ock );.  testcas
9290: 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  e( pWal->hdr.mxF
92a0: 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45 5f  rame==HASHTABLE_
92b0: 4e 50 41 47 45 5f 4f 4e 45 2d 31 20 29 3b 0a 20  NPAGE_ONE-1 );. 
92c0: 20 74 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d   testcase( pWal-
92d0: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 48 41  >hdr.mxFrame==HA
92e0: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e  SHTABLE_NPAGE_ON
92f0: 45 20 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28  E );.  testcase(
9300: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
9310: 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50  me==HASHTABLE_NP
9320: 41 47 45 5f 4f 4e 45 2b 31 20 29 3b 0a 0a 20 20  AGE_ONE+1 );..  
9330: 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  if( pWal->hdr.mx
9340: 46 72 61 6d 65 3d 3d 30 20 29 20 72 65 74 75 72  Frame==0 ) retur
9350: 6e 3b 0a 0a 20 20 2f 2a 20 4f 62 74 61 69 6e 20  n;..  /* Obtain 
9360: 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68 65 20  pointers to the 
9370: 68 61 73 68 2d 74 61 62 6c 65 20 61 6e 64 20 70  hash-table and p
9380: 61 67 65 2d 6e 75 6d 62 65 72 20 61 72 72 61 79  age-number array
9390: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 0a 20 20 2a   containing .  *
93a0: 2a 20 74 68 65 20 65 6e 74 72 79 20 74 68 61 74  * the entry that
93b0: 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20   corresponds to 
93c0: 66 72 61 6d 65 20 70 57 61 6c 2d 3e 68 64 72 2e  frame pWal->hdr.
93d0: 6d 78 46 72 61 6d 65 2e 20 49 74 20 69 73 20 67  mxFrame. It is g
93e0: 75 61 72 61 6e 74 65 65 64 0a 20 20 2a 2a 20 74  uaranteed.  ** t
93f0: 68 61 74 20 74 68 65 20 70 61 67 65 20 73 61 69  hat the page sai
9400: 64 20 68 61 73 68 2d 74 61 62 6c 65 20 61 6e 64  d hash-table and
9410: 20 61 72 72 61 79 20 72 65 73 69 64 65 20 6f 6e   array reside on
9420: 20 69 73 20 61 6c 72 65 61 64 79 20 6d 61 70 70   is already mapp
9430: 65 64 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72  ed..  */.  asser
9440: 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61  t( pWal->nWiData
9450: 3e 77 61 6c 46 72 61 6d 65 50 61 67 65 28 70 57  >walFramePage(pW
9460: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 29  al->hdr.mxFrame)
9470: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57   );.  assert( pW
9480: 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 77 61 6c  al->apWiData[wal
9490: 46 72 61 6d 65 50 61 67 65 28 70 57 61 6c 2d 3e  FramePage(pWal->
94a0: 68 64 72 2e 6d 78 46 72 61 6d 65 29 5d 20 29 3b  hdr.mxFrame)] );
94b0: 0a 20 20 77 61 6c 48 61 73 68 47 65 74 28 70 57  .  walHashGet(pW
94c0: 61 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61 67 65  al, walFramePage
94d0: 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  (pWal->hdr.mxFra
94e0: 6d 65 29 2c 20 26 61 48 61 73 68 2c 20 26 61 50  me), &aHash, &aP
94f0: 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 0a 20  gno, &iZero);.. 
9500: 20 2f 2a 20 5a 65 72 6f 20 61 6c 6c 20 68 61 73   /* Zero all has
9510: 68 2d 74 61 62 6c 65 20 65 6e 74 72 69 65 73 20  h-table entries 
9520: 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 20  that correspond 
9530: 74 6f 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 73  to frame numbers
9540: 20 67 72 65 61 74 65 72 0a 20 20 2a 2a 20 74 68   greater.  ** th
9550: 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  an pWal->hdr.mxF
9560: 72 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 4c 69  rame..  */.  iLi
9570: 6d 69 74 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  mit = pWal->hdr.
9580: 6d 78 46 72 61 6d 65 20 2d 20 69 5a 65 72 6f 3b  mxFrame - iZero;
9590: 0a 20 20 61 73 73 65 72 74 28 20 69 4c 69 6d 69  .  assert( iLimi
95a0: 74 3e 30 20 29 3b 0a 20 20 66 6f 72 28 69 3d 30  t>0 );.  for(i=0
95b0: 3b 20 69 3c 48 41 53 48 54 41 42 4c 45 5f 4e 53  ; i<HASHTABLE_NS
95c0: 4c 4f 54 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69  LOT; i++){.    i
95d0: 66 28 20 61 48 61 73 68 5b 69 5d 3e 69 4c 69 6d  f( aHash[i]>iLim
95e0: 69 74 20 29 7b 0a 20 20 20 20 20 20 61 48 61 73  it ){.      aHas
95f0: 68 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  h[i] = 0;.    }.
9600: 20 20 7d 0a 20 20 0a 20 20 2f 2a 20 5a 65 72 6f    }.  .  /* Zero
9610: 20 74 68 65 20 65 6e 74 72 69 65 73 20 69 6e 20   the entries in 
9620: 74 68 65 20 61 50 67 6e 6f 20 61 72 72 61 79 20  the aPgno array 
9630: 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 20  that correspond 
9640: 74 6f 20 66 72 61 6d 65 73 20 77 69 74 68 0a 20  to frames with. 
9650: 20 2a 2a 20 66 72 61 6d 65 20 6e 75 6d 62 65 72   ** frame number
9660: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 70  s greater than p
9670: 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
9680: 2e 20 0a 20 20 2a 2f 0a 20 20 6e 42 79 74 65 20  . .  */.  nByte 
9690: 3d 20 28 69 6e 74 29 28 28 63 68 61 72 20 2a 29  = (int)((char *)
96a0: 61 48 61 73 68 20 2d 20 28 63 68 61 72 20 2a 29  aHash - (char *)
96b0: 26 61 50 67 6e 6f 5b 69 4c 69 6d 69 74 2b 31 5d  &aPgno[iLimit+1]
96c0: 29 3b 0a 20 20 6d 65 6d 73 65 74 28 28 76 6f 69  );.  memset((voi
96d0: 64 20 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d 69  d *)&aPgno[iLimi
96e0: 74 2b 31 5d 2c 20 30 2c 20 6e 42 79 74 65 29 3b  t+1], 0, nByte);
96f0: 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f  ..#ifdef SQLITE_
9700: 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45  ENABLE_EXPENSIVE
9710: 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20 56 65 72  _ASSERT.  /* Ver
9720: 69 66 79 20 74 68 61 74 20 74 68 65 20 65 76 65  ify that the eve
9730: 72 79 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20  ry entry in the 
9740: 6d 61 70 70 69 6e 67 20 72 65 67 69 6f 6e 20 69  mapping region i
9750: 73 20 73 74 69 6c 6c 20 72 65 61 63 68 61 62 6c  s still reachabl
9760: 65 0a 20 20 2a 2a 20 76 69 61 20 74 68 65 20 68  e.  ** via the h
9770: 61 73 68 20 74 61 62 6c 65 20 65 76 65 6e 20 61  ash table even a
9780: 66 74 65 72 20 74 68 65 20 63 6c 65 61 6e 75 70  fter the cleanup
9790: 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69 4c 69  ..  */.  if( iLi
97a0: 6d 69 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  mit ){.    int i
97b0: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c  ;           /* L
97c0: 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20  oop counter */. 
97d0: 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20     int iKey;    
97e0: 20 20 20 20 2f 2a 20 48 61 73 68 20 6b 65 79 20      /* Hash key 
97f0: 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20  */.    for(i=1; 
9800: 69 3c 3d 69 4c 69 6d 69 74 3b 20 69 2b 2b 29 7b  i<=iLimit; i++){
9810: 0a 20 20 20 20 20 20 66 6f 72 28 69 4b 65 79 3d  .      for(iKey=
9820: 77 61 6c 48 61 73 68 28 61 50 67 6e 6f 5b 69 5d  walHash(aPgno[i]
9830: 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20  ); aHash[iKey]; 
9840: 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68  iKey=walNextHash
9850: 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 20  (iKey)){.       
9860: 20 69 66 28 20 61 48 61 73 68 5b 69 4b 65 79 5d   if( aHash[iKey]
9870: 3d 3d 69 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ==i ) break;.   
9880: 20 20 20 7d 0a 20 20 20 20 20 20 61 73 73 65 72     }.      asser
9890: 74 28 20 61 48 61 73 68 5b 69 4b 65 79 5d 3d 3d  t( aHash[iKey]==
98a0: 69 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 23  i );.    }.  }.#
98b0: 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f  endif /* SQLITE_
98c0: 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45  ENABLE_EXPENSIVE
98d0: 5f 41 53 53 45 52 54 20 2a 2f 0a 7d 0a 0a 0a 2f  _ASSERT */.}.../
98e0: 2a 0a 2a 2a 20 53 65 74 20 61 6e 20 65 6e 74 72  *.** Set an entr
98f0: 79 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64  y in the wal-ind
9900: 65 78 20 74 68 61 74 20 77 69 6c 6c 20 6d 61 70  ex that will map
9910: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6e   database page n
9920: 75 6d 62 65 72 0a 2a 2a 20 70 50 61 67 65 20 69  umber.** pPage i
9930: 6e 74 6f 20 57 41 4c 20 66 72 61 6d 65 20 69 46  nto WAL frame iF
9940: 72 61 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  rame..*/.static 
9950: 69 6e 74 20 77 61 6c 49 6e 64 65 78 41 70 70 65  int walIndexAppe
9960: 6e 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33  nd(Wal *pWal, u3
9970: 32 20 69 46 72 61 6d 65 2c 20 75 33 32 20 69 50  2 iFrame, u32 iP
9980: 61 67 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  age){.  int rc; 
9990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
99a0: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
99b0: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 75 33 32 20  n code */.  u32 
99c0: 69 5a 65 72 6f 20 3d 20 30 3b 20 20 20 20 20 20  iZero = 0;      
99d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
99e0: 6e 65 20 6c 65 73 73 20 74 68 61 6e 20 66 72 61  ne less than fra
99f0: 6d 65 20 6e 75 6d 62 65 72 20 6f 66 20 61 50 67  me number of aPg
9a00: 6e 6f 5b 31 5d 20 2a 2f 0a 20 20 76 6f 6c 61 74  no[1] */.  volat
9a10: 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 20 3d  ile u32 *aPgno =
9a20: 20 30 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 61   0;        /* Pa
9a30: 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20  ge number array 
9a40: 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 68 74  */.  volatile ht
9a50: 5f 73 6c 6f 74 20 2a 61 48 61 73 68 20 3d 20 30  _slot *aHash = 0
9a60: 3b 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62  ;    /* Hash tab
9a70: 6c 65 20 2a 2f 0a 0a 20 20 72 63 20 3d 20 77 61  le */..  rc = wa
9a80: 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c 20 77  lHashGet(pWal, w
9a90: 61 6c 46 72 61 6d 65 50 61 67 65 28 69 46 72 61  alFramePage(iFra
9aa0: 6d 65 29 2c 20 26 61 48 61 73 68 2c 20 26 61 50  me), &aHash, &aP
9ab0: 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 0a 20  gno, &iZero);.. 
9ac0: 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20 74 68 65   /* Assuming the
9ad0: 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20   wal-index file 
9ae0: 77 61 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79  was successfully
9af0: 20 6d 61 70 70 65 64 2c 20 70 6f 70 75 6c 61 74   mapped, populat
9b00: 65 20 74 68 65 0a 20 20 2a 2a 20 70 61 67 65 20  e the.  ** page 
9b10: 6e 75 6d 62 65 72 20 61 72 72 61 79 20 61 6e 64  number array and
9b20: 20 68 61 73 68 20 74 61 62 6c 65 20 65 6e 74 72   hash table entr
9b30: 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63  y..  */.  if( rc
9b40: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
9b50: 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20 20 20     int iKey;    
9b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9b70: 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 6b   /* Hash table k
9b80: 65 79 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 64  ey */.    int id
9b90: 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  x;              
9ba0: 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65          /* Value
9bb0: 20 74 6f 20 77 72 69 74 65 20 74 6f 20 68 61 73   to write to has
9bc0: 68 2d 74 61 62 6c 65 20 73 6c 6f 74 20 2a 2f 0a  h-table slot */.
9bd0: 20 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69 64 65      int nCollide
9be0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
9bf0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 68    /* Number of h
9c00: 61 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73 20 2a  ash collisions *
9c10: 2f 0a 0a 20 20 20 20 69 64 78 20 3d 20 69 46 72  /..    idx = iFr
9c20: 61 6d 65 20 2d 20 69 5a 65 72 6f 3b 0a 20 20 20  ame - iZero;.   
9c30: 20 61 73 73 65 72 74 28 20 69 64 78 20 3c 3d 20   assert( idx <= 
9c40: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2f  HASHTABLE_NSLOT/
9c50: 32 20 2b 20 31 20 29 3b 0a 20 20 20 20 0a 20 20  2 + 1 );.    .  
9c60: 20 20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20    /* If this is 
9c70: 74 68 65 20 66 69 72 73 74 20 65 6e 74 72 79 20  the first entry 
9c80: 74 6f 20 62 65 20 61 64 64 65 64 20 74 6f 20 74  to be added to t
9c90: 68 69 73 20 68 61 73 68 2d 74 61 62 6c 65 2c 20  his hash-table, 
9ca0: 7a 65 72 6f 20 74 68 65 0a 20 20 20 20 2a 2a 20  zero the.    ** 
9cb0: 65 6e 74 69 72 65 20 68 61 73 68 20 74 61 62 6c  entire hash tabl
9cc0: 65 20 61 6e 64 20 61 50 67 6e 6f 5b 5d 20 61 72  e and aPgno[] ar
9cd0: 72 61 79 20 62 65 66 6f 72 65 20 70 72 6f 63 65  ray before proce
9ce0: 64 69 6e 67 2e 20 0a 20 20 20 20 2a 2f 0a 20 20  ding. .    */.  
9cf0: 20 20 69 66 28 20 69 64 78 3d 3d 31 20 29 7b 0a    if( idx==1 ){.
9d00: 20 20 20 20 20 20 69 6e 74 20 6e 42 79 74 65 20        int nByte 
9d10: 3d 20 28 69 6e 74 29 28 28 75 38 20 2a 29 26 61  = (int)((u8 *)&a
9d20: 48 61 73 68 5b 48 41 53 48 54 41 42 4c 45 5f 4e  Hash[HASHTABLE_N
9d30: 53 4c 4f 54 5d 20 2d 20 28 75 38 20 2a 29 26 61  SLOT] - (u8 *)&a
9d40: 50 67 6e 6f 5b 31 5d 29 3b 0a 20 20 20 20 20 20  Pgno[1]);.      
9d50: 6d 65 6d 73 65 74 28 28 76 6f 69 64 2a 29 26 61  memset((void*)&a
9d60: 50 67 6e 6f 5b 31 5d 2c 20 30 2c 20 6e 42 79 74  Pgno[1], 0, nByt
9d70: 65 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  e);.    }..    /
9d80: 2a 20 49 66 20 74 68 65 20 65 6e 74 72 79 20 69  * If the entry i
9d90: 6e 20 61 50 67 6e 6f 5b 5d 20 69 73 20 61 6c 72  n aPgno[] is alr
9da0: 65 61 64 79 20 73 65 74 2c 20 74 68 65 6e 20 74  eady set, then t
9db0: 68 65 20 70 72 65 76 69 6f 75 73 20 77 72 69 74  he previous writ
9dc0: 65 72 0a 20 20 20 20 2a 2a 20 6d 75 73 74 20 68  er.    ** must h
9dd0: 61 76 65 20 65 78 69 74 65 64 20 75 6e 65 78 70  ave exited unexp
9de0: 65 63 74 65 64 6c 79 20 69 6e 20 74 68 65 20 6d  ectedly in the m
9df0: 69 64 64 6c 65 20 6f 66 20 61 20 74 72 61 6e 73  iddle of a trans
9e00: 61 63 74 69 6f 6e 20 28 61 66 74 65 72 0a 20 20  action (after.  
9e10: 20 20 2a 2a 20 77 72 69 74 69 6e 67 20 6f 6e 65    ** writing one
9e20: 20 6f 72 20 6d 6f 72 65 20 64 69 72 74 79 20 70   or more dirty p
9e30: 61 67 65 73 20 74 6f 20 74 68 65 20 57 41 4c 20  ages to the WAL 
9e40: 74 6f 20 66 72 65 65 20 75 70 20 6d 65 6d 6f 72  to free up memor
9e50: 79 29 2e 20 0a 20 20 20 20 2a 2a 20 52 65 6d 6f  y). .    ** Remo
9e60: 76 65 20 74 68 65 20 72 65 6d 6e 61 6e 74 73 20  ve the remnants 
9e70: 6f 66 20 74 68 61 74 20 77 72 69 74 65 72 73 20  of that writers 
9e80: 75 6e 63 6f 6d 6d 69 74 74 65 64 20 74 72 61 6e  uncommitted tran
9e90: 73 61 63 74 69 6f 6e 20 66 72 6f 6d 20 0a 20 20  saction from .  
9ea0: 20 20 2a 2a 20 74 68 65 20 68 61 73 68 2d 74 61    ** the hash-ta
9eb0: 62 6c 65 20 62 65 66 6f 72 65 20 77 72 69 74 69  ble before writi
9ec0: 6e 67 20 61 6e 79 20 6e 65 77 20 65 6e 74 72 69  ng any new entri
9ed0: 65 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  es..    */.    i
9ee0: 66 28 20 61 50 67 6e 6f 5b 69 64 78 5d 20 29 7b  f( aPgno[idx] ){
9ef0: 0a 20 20 20 20 20 20 77 61 6c 43 6c 65 61 6e 75  .      walCleanu
9f00: 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 20  pHash(pWal);.   
9f10: 20 20 20 61 73 73 65 72 74 28 20 21 61 50 67 6e     assert( !aPgn
9f20: 6f 5b 69 64 78 5d 20 29 3b 0a 20 20 20 20 7d 0a  o[idx] );.    }.
9f30: 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68  .    /* Write th
9f40: 65 20 61 50 67 6e 6f 5b 5d 20 61 72 72 61 79 20  e aPgno[] array 
9f50: 65 6e 74 72 79 20 61 6e 64 20 74 68 65 20 68 61  entry and the ha
9f60: 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 2e 20 2a  sh-table slot. *
9f70: 2f 0a 20 20 20 20 6e 43 6f 6c 6c 69 64 65 20 3d  /.    nCollide =
9f80: 20 69 64 78 3b 0a 20 20 20 20 66 6f 72 28 69 4b   idx;.    for(iK
9f90: 65 79 3d 77 61 6c 48 61 73 68 28 69 50 61 67 65  ey=walHash(iPage
9fa0: 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20  ); aHash[iKey]; 
9fb0: 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68  iKey=walNextHash
9fc0: 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 69  (iKey)){.      i
9fd0: 66 28 20 28 6e 43 6f 6c 6c 69 64 65 2d 2d 29 3d  f( (nCollide--)=
9fe0: 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
9ff0: 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54 3b  TE_CORRUPT_BKPT;
a000: 0a 20 20 20 20 7d 0a 20 20 20 20 61 50 67 6e 6f  .    }.    aPgno
a010: 5b 69 64 78 5d 20 3d 20 69 50 61 67 65 3b 0a 20  [idx] = iPage;. 
a020: 20 20 20 61 48 61 73 68 5b 69 4b 65 79 5d 20 3d     aHash[iKey] =
a030: 20 28 68 74 5f 73 6c 6f 74 29 69 64 78 3b 0a 0a   (ht_slot)idx;..
a040: 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e  #ifdef SQLITE_EN
a050: 41 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41  ABLE_EXPENSIVE_A
a060: 53 53 45 52 54 0a 20 20 20 20 2f 2a 20 56 65 72  SSERT.    /* Ver
a070: 69 66 79 20 74 68 61 74 20 74 68 65 20 6e 75 6d  ify that the num
a080: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69  ber of entries i
a090: 6e 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  n the hash table
a0a0: 20 65 78 61 63 74 6c 79 20 65 71 75 61 6c 73 0a   exactly equals.
a0b0: 20 20 20 20 2a 2a 20 74 68 65 20 6e 75 6d 62 65      ** the numbe
a0c0: 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20  r of entries in 
a0d0: 74 68 65 20 6d 61 70 70 69 6e 67 20 72 65 67 69  the mapping regi
a0e0: 6f 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7b  on..    */.    {
a0f0: 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 20 20 20  .      int i;   
a100: 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20          /* Loop 
a110: 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 20 20 20  counter */.     
a120: 20 69 6e 74 20 6e 45 6e 74 72 79 20 3d 20 30 3b   int nEntry = 0;
a130: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65    /* Number of e
a140: 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20 68 61  ntries in the ha
a150: 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 20 20  sh table */.    
a160: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48 41 53    for(i=0; i<HAS
a170: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 20 69 2b  HTABLE_NSLOT; i+
a180: 2b 29 7b 20 69 66 28 20 61 48 61 73 68 5b 69 5d  +){ if( aHash[i]
a190: 20 29 20 6e 45 6e 74 72 79 2b 2b 3b 20 7d 0a 20   ) nEntry++; }. 
a1a0: 20 20 20 20 20 61 73 73 65 72 74 28 20 6e 45 6e       assert( nEn
a1b0: 74 72 79 3d 3d 69 64 78 20 29 3b 0a 20 20 20 20  try==idx );.    
a1c0: 7d 0a 0a 20 20 20 20 2f 2a 20 56 65 72 69 66 79  }..    /* Verify
a1d0: 20 74 68 61 74 20 74 68 65 20 65 76 65 72 79 20   that the every 
a1e0: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61 70  entry in the map
a1f0: 70 69 6e 67 20 72 65 67 69 6f 6e 20 69 73 20 72  ping region is r
a200: 65 61 63 68 61 62 6c 65 0a 20 20 20 20 2a 2a 20  eachable.    ** 
a210: 76 69 61 20 74 68 65 20 68 61 73 68 20 74 61 62  via the hash tab
a220: 6c 65 2e 20 20 54 68 69 73 20 74 75 72 6e 73 20  le.  This turns 
a230: 6f 75 74 20 74 6f 20 62 65 20 61 20 72 65 61 6c  out to be a real
a240: 6c 79 2c 20 72 65 61 6c 6c 79 20 65 78 70 65 6e  ly, really expen
a250: 73 69 76 65 0a 20 20 20 20 2a 2a 20 74 68 69 6e  sive.    ** thin
a260: 67 20 74 6f 20 63 68 65 63 6b 2c 20 73 6f 20 6f  g to check, so o
a270: 6e 6c 79 20 64 6f 20 74 68 69 73 20 6f 63 63 61  nly do this occa
a280: 73 69 6f 6e 61 6c 6c 79 20 2d 20 6e 6f 74 20 6f  sionally - not o
a290: 6e 20 65 76 65 72 79 0a 20 20 20 20 2a 2a 20 69  n every.    ** i
a2a0: 74 65 72 61 74 69 6f 6e 2e 0a 20 20 20 20 2a 2f  teration..    */
a2b0: 0a 20 20 20 20 69 66 28 20 28 69 64 78 26 30 78  .    if( (idx&0x
a2c0: 33 66 66 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  3ff)==0 ){.     
a2d0: 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
a2e0: 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65    /* Loop counte
a2f0: 72 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28 69  r */.      for(i
a300: 3d 31 3b 20 69 3c 3d 69 64 78 3b 20 69 2b 2b 29  =1; i<=idx; i++)
a310: 7b 0a 20 20 20 20 20 20 20 20 66 6f 72 28 69 4b  {.        for(iK
a320: 65 79 3d 77 61 6c 48 61 73 68 28 61 50 67 6e 6f  ey=walHash(aPgno
a330: 5b 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b 65 79  [i]); aHash[iKey
a340: 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48  ]; iKey=walNextH
a350: 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20  ash(iKey)){.    
a360: 20 20 20 20 20 20 69 66 28 20 61 48 61 73 68 5b        if( aHash[
a370: 69 4b 65 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b  iKey]==i ) break
a380: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
a390: 20 20 20 20 61 73 73 65 72 74 28 20 61 48 61 73      assert( aHas
a3a0: 68 5b 69 4b 65 79 5d 3d 3d 69 20 29 3b 0a 20 20  h[iKey]==i );.  
a3b0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 23 65 6e 64      }.    }.#end
a3c0: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 45 4e 41  if /* SQLITE_ENA
a3d0: 42 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53  BLE_EXPENSIVE_AS
a3e0: 53 45 52 54 20 2a 2f 0a 20 20 7d 0a 0a 0a 20 20  SERT */.  }...  
a3f0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f  return rc;.}.../
a400: 2a 0a 2a 2a 20 52 65 63 6f 76 65 72 20 74 68 65  *.** Recover the
a410: 20 77 61 6c 2d 69 6e 64 65 78 20 62 79 20 72 65   wal-index by re
a420: 61 64 69 6e 67 20 74 68 65 20 77 72 69 74 65 2d  ading the write-
a430: 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65 2e 20  ahead log file. 
a440: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74  .**.** This rout
a450: 69 6e 65 20 66 69 72 73 74 20 74 72 69 65 73 20  ine first tries 
a460: 74 6f 20 65 73 74 61 62 6c 69 73 68 20 61 6e 20  to establish an 
a470: 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f  exclusive lock o
a480: 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64  n the.** wal-ind
a490: 65 78 20 74 6f 20 70 72 65 76 65 6e 74 20 6f 74  ex to prevent ot
a4a0: 68 65 72 20 74 68 72 65 61 64 73 2f 70 72 6f 63  her threads/proc
a4b0: 65 73 73 65 73 20 66 72 6f 6d 20 64 6f 69 6e 67  esses from doing
a4c0: 20 61 6e 79 74 68 69 6e 67 0a 2a 2a 20 77 69 74   anything.** wit
a4d0: 68 20 74 68 65 20 57 41 4c 20 6f 72 20 77 61 6c  h the WAL or wal
a4e0: 2d 69 6e 64 65 78 20 77 68 69 6c 65 20 72 65 63  -index while rec
a4f0: 6f 76 65 72 79 20 69 73 20 72 75 6e 6e 69 6e 67  overy is running
a500: 2e 20 20 54 68 65 0a 2a 2a 20 57 41 4c 5f 52 45  .  The.** WAL_RE
a510: 43 4f 56 45 52 5f 4c 4f 43 4b 20 69 73 20 61 6c  COVER_LOCK is al
a520: 73 6f 20 68 65 6c 64 20 73 6f 20 74 68 61 74 20  so held so that 
a530: 6f 74 68 65 72 20 74 68 72 65 61 64 73 20 77 69  other threads wi
a540: 6c 6c 20 6b 6e 6f 77 0a 2a 2a 20 74 68 61 74 20  ll know.** that 
a550: 74 68 69 73 20 74 68 72 65 61 64 20 69 73 20 72  this thread is r
a560: 75 6e 6e 69 6e 67 20 72 65 63 6f 76 65 72 79 2e  unning recovery.
a570: 20 20 49 66 20 75 6e 61 62 6c 65 20 74 6f 20 65    If unable to e
a580: 73 74 61 62 6c 69 73 68 0a 2a 2a 20 74 68 65 20  stablish.** the 
a590: 6e 65 63 65 73 73 61 72 79 20 6c 6f 63 6b 73 2c  necessary locks,
a5a0: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65   this routine re
a5b0: 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 42 55 53  turns SQLITE_BUS
a5c0: 59 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  Y..*/.static int
a5d0: 20 77 61 6c 49 6e 64 65 78 52 65 63 6f 76 65 72   walIndexRecover
a5e0: 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69  (Wal *pWal){.  i
a5f0: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
a600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
a610: 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f  * Return Code */
a620: 0a 20 20 69 36 34 20 6e 53 69 7a 65 3b 20 20 20  .  i64 nSize;   
a630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a640: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 6c 6f     /* Size of lo
a650: 67 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32 20  g file */.  u32 
a660: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 20 3d  aFrameCksum[2] =
a670: 20 7b 30 2c 20 30 7d 3b 0a 20 20 69 6e 74 20 69   {0, 0};.  int i
a680: 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20  Lock;           
a690: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f             /* Lo
a6a0: 63 6b 20 6f 66 66 73 65 74 20 74 6f 20 6c 6f 63  ck offset to loc
a6b0: 6b 20 66 6f 72 20 63 68 65 63 6b 70 6f 69 6e 74  k for checkpoint
a6c0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 6f 63 6b 3b   */.  int nLock;
a6d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a6e0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
a6f0: 6f 66 20 6c 6f 63 6b 73 20 74 6f 20 68 6f 6c 64  of locks to hold
a700: 20 2a 2f 0a 0a 20 20 2f 2a 20 4f 62 74 61 69 6e   */..  /* Obtain
a710: 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c 6f   an exclusive lo
a720: 63 6b 20 6f 6e 20 61 6c 6c 20 62 79 74 65 20 69  ck on all byte i
a730: 6e 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 72 61  n the locking ra
a740: 6e 67 65 20 6e 6f 74 20 61 6c 72 65 61 64 79 0a  nge not already.
a750: 20 20 2a 2a 20 6c 6f 63 6b 65 64 20 62 79 20 74    ** locked by t
a760: 68 65 20 63 61 6c 6c 65 72 2e 20 54 68 65 20 63  he caller. The c
a770: 61 6c 6c 65 72 20 69 73 20 67 75 61 72 61 6e 74  aller is guarant
a780: 65 65 64 20 74 6f 20 68 61 76 65 20 6c 6f 63 6b  eed to have lock
a790: 65 64 20 74 68 65 0a 20 20 2a 2a 20 57 41 4c 5f  ed the.  ** WAL_
a7a0: 57 52 49 54 45 5f 4c 4f 43 4b 20 62 79 74 65 2c  WRITE_LOCK byte,
a7b0: 20 61 6e 64 20 6d 61 79 20 68 61 76 65 20 61 6c   and may have al
a7c0: 73 6f 20 6c 6f 63 6b 65 64 20 74 68 65 20 57 41  so locked the WA
a7d0: 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 62 79 74 65  L_CKPT_LOCK byte
a7e0: 2e 0a 20 20 2a 2a 20 49 66 20 73 75 63 63 65 73  ..  ** If succes
a7f0: 73 66 75 6c 2c 20 74 68 65 20 73 61 6d 65 20 62  sful, the same b
a800: 79 74 65 73 20 74 68 61 74 20 61 72 65 20 6c 6f  ytes that are lo
a810: 63 6b 65 64 20 68 65 72 65 20 61 72 65 20 75 6e  cked here are un
a820: 6c 6f 63 6b 65 64 20 62 65 66 6f 72 65 0a 20 20  locked before.  
a830: 2a 2a 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** this function
a840: 20 72 65 74 75 72 6e 73 2e 0a 20 20 2a 2f 0a 20   returns..  */. 
a850: 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 63   assert( pWal->c
a860: 6b 70 74 4c 6f 63 6b 3d 3d 31 20 7c 7c 20 70 57  kptLock==1 || pW
a870: 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 30 20  al->ckptLock==0 
a880: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 57 41 4c  );.  assert( WAL
a890: 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 3d 3d  _ALL_BUT_WRITE==
a8a0: 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2b 31  WAL_WRITE_LOCK+1
a8b0: 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 57 41   );.  assert( WA
a8c0: 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 3d 3d 57 41 4c  L_CKPT_LOCK==WAL
a8d0: 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 29  _ALL_BUT_WRITE )
a8e0: 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ;.  assert( pWal
a8f0: 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20  ->writeLock );. 
a900: 20 69 4c 6f 63 6b 20 3d 20 57 41 4c 5f 41 4c 4c   iLock = WAL_ALL
a910: 5f 42 55 54 5f 57 52 49 54 45 20 2b 20 70 57 61  _BUT_WRITE + pWa
a920: 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 3b 0a 20 20 6e  l->ckptLock;.  n
a930: 4c 6f 63 6b 20 3d 20 53 51 4c 49 54 45 5f 53 48  Lock = SQLITE_SH
a940: 4d 5f 4e 4c 4f 43 4b 20 2d 20 69 4c 6f 63 6b 3b  M_NLOCK - iLock;
a950: 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45  .  rc = walLockE
a960: 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 69  xclusive(pWal, i
a970: 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b 0a 20 20  Lock, nLock);.  
a980: 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 72 65  if( rc ){.    re
a990: 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 57  turn rc;.  }.  W
a9a0: 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
a9b0: 20 72 65 63 6f 76 65 72 79 20 62 65 67 69 6e 2e   recovery begin.
a9c0: 2e 2e 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 0a  ..\n", pWal));..
a9d0: 20 20 6d 65 6d 73 65 74 28 26 70 57 61 6c 2d 3e    memset(&pWal->
a9e0: 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 57  hdr, 0, sizeof(W
a9f0: 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 0a 20  alIndexHdr));.. 
aa00: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 46   rc = sqlite3OsF
aa10: 69 6c 65 53 69 7a 65 28 70 57 61 6c 2d 3e 70 57  ileSize(pWal->pW
aa20: 61 6c 46 64 2c 20 26 6e 53 69 7a 65 29 3b 0a 20  alFd, &nSize);. 
aa30: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
aa40: 4f 4b 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20 72  OK ){.    goto r
aa50: 65 63 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20  ecovery_error;. 
aa60: 20 7d 0a 0a 20 20 69 66 28 20 6e 53 69 7a 65 3e   }..  if( nSize>
aa70: 57 41 4c 5f 48 44 52 53 49 5a 45 20 29 7b 0a 20  WAL_HDRSIZE ){. 
aa80: 20 20 20 75 38 20 61 42 75 66 5b 57 41 4c 5f 48     u8 aBuf[WAL_H
aa90: 44 52 53 49 5a 45 5d 3b 20 20 20 20 20 20 20 20  DRSIZE];        
aaa0: 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 6c 6f   /* Buffer to lo
aab0: 61 64 20 57 41 4c 20 68 65 61 64 65 72 20 69 6e  ad WAL header in
aac0: 74 6f 20 2a 2f 0a 20 20 20 20 75 38 20 2a 61 46  to */.    u8 *aF
aad0: 72 61 6d 65 20 3d 20 30 3b 20 20 20 20 20 20 20  rame = 0;       
aae0: 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f          /* Mallo
aaf0: 63 27 64 20 62 75 66 66 65 72 20 74 6f 20 6c 6f  c'd buffer to lo
ab00: 61 64 20 65 6e 74 69 72 65 20 66 72 61 6d 65 20  ad entire frame 
ab10: 2a 2f 0a 20 20 20 20 69 6e 74 20 73 7a 46 72 61  */.    int szFra
ab20: 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  me;             
ab30: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
ab40: 66 20 62 79 74 65 73 20 69 6e 20 62 75 66 66 65  f bytes in buffe
ab50: 72 20 61 46 72 61 6d 65 5b 5d 20 2a 2f 0a 20 20  r aFrame[] */.  
ab60: 20 20 75 38 20 2a 61 44 61 74 61 3b 20 20 20 20    u8 *aData;    
ab70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ab80: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 64 61  /* Pointer to da
ab90: 74 61 20 70 61 72 74 20 6f 66 20 61 46 72 61 6d  ta part of aFram
aba0: 65 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 20 20  e buffer */.    
abb0: 69 6e 74 20 69 46 72 61 6d 65 3b 20 20 20 20 20  int iFrame;     
abc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
abd0: 20 49 6e 64 65 78 20 6f 66 20 6c 61 73 74 20 66   Index of last f
abe0: 72 61 6d 65 20 72 65 61 64 20 2a 2f 0a 20 20 20  rame read */.   
abf0: 20 69 36 34 20 69 4f 66 66 73 65 74 3b 20 20 20   i64 iOffset;   
ac00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
ac10: 2a 20 4e 65 78 74 20 6f 66 66 73 65 74 20 74 6f  * Next offset to
ac20: 20 72 65 61 64 20 66 72 6f 6d 20 6c 6f 67 20 66   read from log f
ac30: 69 6c 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20 73  ile */.    int s
ac40: 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20 20  zPage;          
ac50: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65           /* Page
ac60: 20 73 69 7a 65 20 61 63 63 6f 72 64 69 6e 67 20   size according 
ac70: 74 6f 20 74 68 65 20 6c 6f 67 20 2a 2f 0a 20 20  to the log */.  
ac80: 20 20 75 33 32 20 6d 61 67 69 63 3b 20 20 20 20    u32 magic;    
ac90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aca0: 2f 2a 20 4d 61 67 69 63 20 76 61 6c 75 65 20 72  /* Magic value r
acb0: 65 61 64 20 66 72 6f 6d 20 57 41 4c 20 68 65 61  ead from WAL hea
acc0: 64 65 72 20 2a 2f 0a 20 20 20 20 75 33 32 20 76  der */.    u32 v
acd0: 65 72 73 69 6f 6e 3b 20 20 20 20 20 20 20 20 20  ersion;         
ace0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 67 69           /* Magi
acf0: 63 20 76 61 6c 75 65 20 72 65 61 64 20 66 72 6f  c value read fro
ad00: 6d 20 57 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a  m WAL header */.
ad10: 0a 20 20 20 20 2f 2a 20 52 65 61 64 20 69 6e 20  .    /* Read in 
ad20: 74 68 65 20 57 41 4c 20 68 65 61 64 65 72 2e 20  the WAL header. 
ad30: 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  */.    rc = sqli
ad40: 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e  te3OsRead(pWal->
ad50: 70 57 61 6c 46 64 2c 20 61 42 75 66 2c 20 57 41  pWalFd, aBuf, WA
ad60: 4c 5f 48 44 52 53 49 5a 45 2c 20 30 29 3b 0a 20  L_HDRSIZE, 0);. 
ad70: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
ad80: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 67 6f  E_OK ){.      go
ad90: 74 6f 20 72 65 63 6f 76 65 72 79 5f 65 72 72 6f  to recovery_erro
ada0: 72 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  r;.    }..    /*
adb0: 20 49 66 20 74 68 65 20 64 61 74 61 62 61 73 65   If the database
adc0: 20 70 61 67 65 20 73 69 7a 65 20 69 73 20 6e 6f   page size is no
add0: 74 20 61 20 70 6f 77 65 72 20 6f 66 20 74 77 6f  t a power of two
ade0: 2c 20 6f 72 20 69 73 20 67 72 65 61 74 65 72 20  , or is greater 
adf0: 74 68 61 6e 0a 20 20 20 20 2a 2a 20 53 51 4c 49  than.    ** SQLI
ae00: 54 45 5f 4d 41 58 5f 50 41 47 45 5f 53 49 5a 45  TE_MAX_PAGE_SIZE
ae10: 2c 20 63 6f 6e 63 6c 75 64 65 20 74 68 61 74 20  , conclude that 
ae20: 74 68 65 20 57 41 4c 20 66 69 6c 65 20 63 6f 6e  the WAL file con
ae30: 74 61 69 6e 73 20 6e 6f 20 76 61 6c 69 64 20 0a  tains no valid .
ae40: 20 20 20 20 2a 2a 20 64 61 74 61 2e 20 53 69 6d      ** data. Sim
ae50: 69 6c 61 72 6c 79 2c 20 69 66 20 74 68 65 20 27  ilarly, if the '
ae60: 6d 61 67 69 63 27 20 76 61 6c 75 65 20 69 73 20  magic' value is 
ae70: 69 6e 76 61 6c 69 64 2c 20 69 67 6e 6f 72 65 20  invalid, ignore 
ae80: 74 68 65 20 77 68 6f 6c 65 0a 20 20 20 20 2a 2a  the whole.    **
ae90: 20 57 41 4c 20 66 69 6c 65 2e 0a 20 20 20 20 2a   WAL file..    *
aea0: 2f 0a 20 20 20 20 6d 61 67 69 63 20 3d 20 73 71  /.    magic = sq
aeb0: 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61  lite3Get4byte(&a
aec0: 42 75 66 5b 30 5d 29 3b 0a 20 20 20 20 73 7a 50  Buf[0]);.    szP
aed0: 61 67 65 20 3d 20 73 71 6c 69 74 65 33 47 65 74  age = sqlite3Get
aee0: 34 62 79 74 65 28 26 61 42 75 66 5b 38 5d 29 3b  4byte(&aBuf[8]);
aef0: 0a 20 20 20 20 69 66 28 20 28 6d 61 67 69 63 26  .    if( (magic&
af00: 30 78 46 46 46 46 46 46 46 45 29 21 3d 57 41 4c  0xFFFFFFFE)!=WAL
af10: 5f 4d 41 47 49 43 20 0a 20 20 20 20 20 7c 7c 20  _MAGIC .     || 
af20: 73 7a 50 61 67 65 26 28 73 7a 50 61 67 65 2d 31  szPage&(szPage-1
af30: 29 20 0a 20 20 20 20 20 7c 7c 20 73 7a 50 61 67  ) .     || szPag
af40: 65 3e 53 51 4c 49 54 45 5f 4d 41 58 5f 50 41 47  e>SQLITE_MAX_PAG
af50: 45 5f 53 49 5a 45 20 0a 20 20 20 20 20 7c 7c 20  E_SIZE .     || 
af60: 73 7a 50 61 67 65 3c 35 31 32 20 0a 20 20 20 20  szPage<512 .    
af70: 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 66 69  ){.      goto fi
af80: 6e 69 73 68 65 64 3b 0a 20 20 20 20 7d 0a 20 20  nished;.    }.  
af90: 20 20 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45    pWal->hdr.bigE
afa0: 6e 64 43 6b 73 75 6d 20 3d 20 28 75 38 29 28 6d  ndCksum = (u8)(m
afb0: 61 67 69 63 26 30 78 30 30 30 30 30 30 30 31 29  agic&0x00000001)
afc0: 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50 61  ;.    pWal->szPa
afd0: 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20  ge = szPage;.   
afe0: 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 20 3d 20 73   pWal->nCkpt = s
aff0: 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26  qlite3Get4byte(&
b000: 61 42 75 66 5b 31 32 5d 29 3b 0a 20 20 20 20 6d  aBuf[12]);.    m
b010: 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72  emcpy(&pWal->hdr
b020: 2e 61 53 61 6c 74 2c 20 26 61 42 75 66 5b 31 36  .aSalt, &aBuf[16
b030: 5d 2c 20 38 29 3b 0a 0a 20 20 20 20 2f 2a 20 56  ], 8);..    /* V
b040: 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20 57  erify that the W
b050: 41 4c 20 68 65 61 64 65 72 20 63 68 65 63 6b 73  AL header checks
b060: 75 6d 20 69 73 20 63 6f 72 72 65 63 74 20 2a 2f  um is correct */
b070: 0a 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75 6d  .    walChecksum
b080: 42 79 74 65 73 28 70 57 61 6c 2d 3e 68 64 72 2e  Bytes(pWal->hdr.
b090: 62 69 67 45 6e 64 43 6b 73 75 6d 3d 3d 53 51 4c  bigEndCksum==SQL
b0a0: 49 54 45 5f 42 49 47 45 4e 44 49 41 4e 2c 20 0a  ITE_BIGENDIAN, .
b0b0: 20 20 20 20 20 20 20 20 61 42 75 66 2c 20 57 41          aBuf, WA
b0c0: 4c 5f 48 44 52 53 49 5a 45 2d 32 2a 34 2c 20 30  L_HDRSIZE-2*4, 0
b0d0: 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61  , pWal->hdr.aFra
b0e0: 6d 65 43 6b 73 75 6d 0a 20 20 20 20 29 3b 0a 20  meCksum.    );. 
b0f0: 20 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72     if( pWal->hdr
b100: 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 21  .aFrameCksum[0]!
b110: 3d 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65  =sqlite3Get4byte
b120: 28 26 61 42 75 66 5b 32 34 5d 29 0a 20 20 20 20  (&aBuf[24]).    
b130: 20 7c 7c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46   || pWal->hdr.aF
b140: 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 21 3d 73 71  rameCksum[1]!=sq
b150: 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61  lite3Get4byte(&a
b160: 42 75 66 5b 32 38 5d 29 0a 20 20 20 20 29 7b 0a  Buf[28]).    ){.
b170: 20 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73        goto finis
b180: 68 65 64 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  hed;.    }..    
b190: 2f 2a 20 56 65 72 69 66 79 20 74 68 61 74 20 74  /* Verify that t
b1a0: 68 65 20 76 65 72 73 69 6f 6e 20 6e 75 6d 62 65  he version numbe
b1b0: 72 20 6f 6e 20 74 68 65 20 57 41 4c 20 66 6f 72  r on the WAL for
b1c0: 6d 61 74 20 69 73 20 6f 6e 65 20 74 68 61 74 0a  mat is one that.
b1d0: 20 20 20 20 2a 2a 20 61 72 65 20 61 62 6c 65 20      ** are able 
b1e0: 74 6f 20 75 6e 64 65 72 73 74 61 6e 64 20 2a 2f  to understand */
b1f0: 0a 20 20 20 20 76 65 72 73 69 6f 6e 20 3d 20 73  .    version = s
b200: 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26  qlite3Get4byte(&
b210: 61 42 75 66 5b 34 5d 29 3b 0a 20 20 20 20 69 66  aBuf[4]);.    if
b220: 28 20 76 65 72 73 69 6f 6e 21 3d 57 41 4c 5f 4d  ( version!=WAL_M
b230: 41 58 5f 56 45 52 53 49 4f 4e 20 29 7b 0a 20 20  AX_VERSION ){.  
b240: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
b250: 43 41 4e 54 4f 50 45 4e 5f 42 4b 50 54 3b 0a 20  CANTOPEN_BKPT;. 
b260: 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73 68       goto finish
b270: 65 64 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  ed;.    }..    /
b280: 2a 20 4d 61 6c 6c 6f 63 20 61 20 62 75 66 66 65  * Malloc a buffe
b290: 72 20 74 6f 20 72 65 61 64 20 66 72 61 6d 65 73  r to read frames
b2a0: 20 69 6e 74 6f 2e 20 2a 2f 0a 20 20 20 20 73 7a   into. */.    sz
b2b0: 46 72 61 6d 65 20 3d 20 73 7a 50 61 67 65 20 2b  Frame = szPage +
b2c0: 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49   WAL_FRAME_HDRSI
b2d0: 5a 45 3b 0a 20 20 20 20 61 46 72 61 6d 65 20 3d  ZE;.    aFrame =
b2e0: 20 28 75 38 20 2a 29 73 71 6c 69 74 65 33 5f 6d   (u8 *)sqlite3_m
b2f0: 61 6c 6c 6f 63 28 73 7a 46 72 61 6d 65 29 3b 0a  alloc(szFrame);.
b300: 20 20 20 20 69 66 28 20 21 61 46 72 61 6d 65 20      if( !aFrame 
b310: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  ){.      rc = SQ
b320: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
b330: 20 20 67 6f 74 6f 20 72 65 63 6f 76 65 72 79 5f    goto recovery_
b340: 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a 20 20 20  error;.    }.   
b350: 20 61 44 61 74 61 20 3d 20 26 61 46 72 61 6d 65   aData = &aFrame
b360: 5b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49  [WAL_FRAME_HDRSI
b370: 5a 45 5d 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 61  ZE];..    /* Rea
b380: 64 20 61 6c 6c 20 66 72 61 6d 65 73 20 66 72 6f  d all frames fro
b390: 6d 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 20  m the log file. 
b3a0: 2a 2f 0a 20 20 20 20 69 46 72 61 6d 65 20 3d 20  */.    iFrame = 
b3b0: 30 3b 0a 20 20 20 20 66 6f 72 28 69 4f 66 66 73  0;.    for(iOffs
b3c0: 65 74 3d 57 41 4c 5f 48 44 52 53 49 5a 45 3b 20  et=WAL_HDRSIZE; 
b3d0: 28 69 4f 66 66 73 65 74 2b 73 7a 46 72 61 6d 65  (iOffset+szFrame
b3e0: 29 3c 3d 6e 53 69 7a 65 3b 20 69 4f 66 66 73 65  )<=nSize; iOffse
b3f0: 74 2b 3d 73 7a 46 72 61 6d 65 29 7b 0a 20 20 20  t+=szFrame){.   
b400: 20 20 20 75 33 32 20 70 67 6e 6f 3b 20 20 20 20     u32 pgno;    
b410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
b420: 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20  * Database page 
b430: 6e 75 6d 62 65 72 20 66 6f 72 20 66 72 61 6d 65  number for frame
b440: 20 2a 2f 0a 20 20 20 20 20 20 75 33 32 20 6e 54   */.      u32 nT
b450: 72 75 6e 63 61 74 65 3b 20 20 20 20 20 20 20 20  runcate;        
b460: 20 20 20 20 20 20 2f 2a 20 64 62 73 69 7a 65 20        /* dbsize 
b470: 66 69 65 6c 64 20 66 72 6f 6d 20 66 72 61 6d 65  field from frame
b480: 20 68 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 20   header */.     
b490: 20 69 6e 74 20 69 73 56 61 6c 69 64 3b 20 20 20   int isValid;   
b4a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
b4b0: 54 72 75 65 20 69 66 20 74 68 69 73 20 66 72 61  True if this fra
b4c0: 6d 65 20 69 73 20 76 61 6c 69 64 20 2a 2f 0a 0a  me is valid */..
b4d0: 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20 61 6e        /* Read an
b4e0: 64 20 64 65 63 6f 64 65 20 74 68 65 20 6e 65 78  d decode the nex
b4f0: 74 20 6c 6f 67 20 66 72 61 6d 65 2e 20 2a 2f 0a  t log frame. */.
b500: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
b510: 65 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70  e3OsRead(pWal->p
b520: 57 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20 73  WalFd, aFrame, s
b530: 7a 46 72 61 6d 65 2c 20 69 4f 66 66 73 65 74 29  zFrame, iOffset)
b540: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
b550: 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61  SQLITE_OK ) brea
b560: 6b 3b 0a 20 20 20 20 20 20 69 73 56 61 6c 69 64  k;.      isValid
b570: 20 3d 20 77 61 6c 44 65 63 6f 64 65 46 72 61 6d   = walDecodeFram
b580: 65 28 70 57 61 6c 2c 20 26 70 67 6e 6f 2c 20 26  e(pWal, &pgno, &
b590: 6e 54 72 75 6e 63 61 74 65 2c 20 61 44 61 74 61  nTruncate, aData
b5a0: 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20 20 20 20  , aFrame);.     
b5b0: 20 69 66 28 20 21 69 73 56 61 6c 69 64 20 29 20   if( !isValid ) 
b5c0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 72 63 20  break;.      rc 
b5d0: 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64  = walIndexAppend
b5e0: 28 70 57 61 6c 2c 20 2b 2b 69 46 72 61 6d 65 2c  (pWal, ++iFrame,
b5f0: 20 70 67 6e 6f 29 3b 0a 20 20 20 20 20 20 69 66   pgno);.      if
b600: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
b610: 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20  ) break;..      
b620: 2f 2a 20 49 66 20 6e 54 72 75 6e 63 61 74 65 20  /* If nTruncate 
b630: 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 69  is non-zero, thi
b640: 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 20 72 65  s is a commit re
b650: 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 20 20 69  cord. */.      i
b660: 66 28 20 6e 54 72 75 6e 63 61 74 65 20 29 7b 0a  f( nTruncate ){.
b670: 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64          pWal->hd
b680: 72 2e 6d 78 46 72 61 6d 65 20 3d 20 69 46 72 61  r.mxFrame = iFra
b690: 6d 65 3b 0a 20 20 20 20 20 20 20 20 70 57 61 6c  me;.        pWal
b6a0: 2d 3e 68 64 72 2e 6e 50 61 67 65 20 3d 20 6e 54  ->hdr.nPage = nT
b6b0: 72 75 6e 63 61 74 65 3b 0a 20 20 20 20 20 20 20  runcate;.       
b6c0: 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67   pWal->hdr.szPag
b6d0: 65 20 3d 20 28 75 31 36 29 28 28 73 7a 50 61 67  e = (u16)((szPag
b6e0: 65 26 30 78 66 66 30 30 29 20 7c 20 28 73 7a 50  e&0xff00) | (szP
b6f0: 61 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20 20 20  age>>16));.     
b700: 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 50     testcase( szP
b710: 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20  age<=32768 );.  
b720: 20 20 20 20 20 20 74 65 73 74 63 61 73 65 28 20        testcase( 
b730: 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20 29 3b  szPage>=65536 );
b740: 0a 20 20 20 20 20 20 20 20 61 46 72 61 6d 65 43  .        aFrameC
b750: 6b 73 75 6d 5b 30 5d 20 3d 20 70 57 61 6c 2d 3e  ksum[0] = pWal->
b760: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
b770: 30 5d 3b 0a 20 20 20 20 20 20 20 20 61 46 72 61  0];.        aFra
b780: 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 70 57 61  meCksum[1] = pWa
b790: 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
b7a0: 75 6d 5b 31 5d 3b 0a 20 20 20 20 20 20 7d 0a 20  um[1];.      }. 
b7b0: 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65     }..    sqlite
b7c0: 33 5f 66 72 65 65 28 61 46 72 61 6d 65 29 3b 0a  3_free(aFrame);.
b7d0: 20 20 7d 0a 0a 66 69 6e 69 73 68 65 64 3a 0a 20    }..finished:. 
b7e0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
b7f0: 4f 4b 20 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69  OK ){.    volati
b800: 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a  le WalCkptInfo *
b810: 70 49 6e 66 6f 3b 0a 20 20 20 20 69 6e 74 20 69  pInfo;.    int i
b820: 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  ;.    pWal->hdr.
b830: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d  aFrameCksum[0] =
b840: 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b   aFrameCksum[0];
b850: 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61  .    pWal->hdr.a
b860: 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20  FrameCksum[1] = 
b870: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a  aFrameCksum[1];.
b880: 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72 69 74      walIndexWrit
b890: 65 48 64 72 28 70 57 61 6c 29 3b 0a 0a 20 20 20  eHdr(pWal);..   
b8a0: 20 2f 2a 20 52 65 73 65 74 20 74 68 65 20 63 68   /* Reset the ch
b8b0: 65 63 6b 70 6f 69 6e 74 2d 68 65 61 64 65 72 2e  eckpoint-header.
b8c0: 20 54 68 69 73 20 69 73 20 73 61 66 65 20 62 65   This is safe be
b8d0: 63 61 75 73 65 20 74 68 69 73 20 74 68 72 65 61  cause this threa
b8e0: 64 20 69 73 20 0a 20 20 20 20 2a 2a 20 63 75 72  d is .    ** cur
b8f0: 72 65 6e 74 6c 79 20 68 6f 6c 64 69 6e 67 20 6c  rently holding l
b900: 6f 63 6b 73 20 74 68 61 74 20 65 78 63 6c 75 64  ocks that exclud
b910: 65 20 61 6c 6c 20 6f 74 68 65 72 20 72 65 61 64  e all other read
b920: 65 72 73 2c 20 77 72 69 74 65 72 73 20 61 6e 64  ers, writers and
b930: 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69  .    ** checkpoi
b940: 6e 74 65 72 73 2e 0a 20 20 20 20 2a 2f 0a 20 20  nters..    */.  
b950: 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70    pInfo = walCkp
b960: 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20  tInfo(pWal);.   
b970: 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
b980: 6c 20 3d 20 30 3b 0a 20 20 20 20 70 49 6e 66 6f  l = 0;.    pInfo
b990: 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20 3d  ->aReadMark[0] =
b9a0: 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b   0;.    for(i=1;
b9b0: 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
b9c0: 69 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61  i++) pInfo->aRea
b9d0: 64 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d  dMark[i] = READM
b9e0: 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 0a 20  ARK_NOT_USED;.. 
b9f0: 20 20 20 2f 2a 20 49 66 20 6d 6f 72 65 20 74 68     /* If more th
ba00: 61 6e 20 6f 6e 65 20 66 72 61 6d 65 20 77 61 73  an one frame was
ba10: 20 72 65 63 6f 76 65 72 65 64 20 66 72 6f 6d 20   recovered from 
ba20: 74 68 65 20 6c 6f 67 20 66 69 6c 65 2c 20 72 65  the log file, re
ba30: 70 6f 72 74 20 61 6e 0a 20 20 20 20 2a 2a 20 65  port an.    ** e
ba40: 76 65 6e 74 20 76 69 61 20 73 71 6c 69 74 65 33  vent via sqlite3
ba50: 5f 6c 6f 67 28 29 2e 20 54 68 69 73 20 69 73 20  _log(). This is 
ba60: 74 6f 20 68 65 6c 70 20 77 69 74 68 20 69 64 65  to help with ide
ba70: 6e 74 69 66 79 69 6e 67 20 70 65 72 66 6f 72 6d  ntifying perform
ba80: 61 6e 63 65 0a 20 20 20 20 2a 2a 20 70 72 6f 62  ance.    ** prob
ba90: 6c 65 6d 73 20 63 61 75 73 65 64 20 62 79 20 61  lems caused by a
baa0: 70 70 6c 69 63 61 74 69 6f 6e 73 20 72 6f 75 74  pplications rout
bab0: 69 6e 65 6c 79 20 73 68 75 74 74 69 6e 67 20 64  inely shutting d
bac0: 6f 77 6e 20 77 69 74 68 6f 75 74 0a 20 20 20 20  own without.    
bad0: 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 69 6e 67  ** checkpointing
bae0: 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 0a 20   the log file.. 
baf0: 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 70 57     */.    if( pW
bb00: 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20 29 7b  al->hdr.nPage ){
bb10: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6c  .      sqlite3_l
bb20: 6f 67 28 53 51 4c 49 54 45 5f 4f 4b 2c 20 22 52  og(SQLITE_OK, "R
bb30: 65 63 6f 76 65 72 65 64 20 25 64 20 66 72 61 6d  ecovered %d fram
bb40: 65 73 20 66 72 6f 6d 20 57 41 4c 20 66 69 6c 65  es from WAL file
bb50: 20 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20 20   %s",.          
bb60: 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 2c  pWal->hdr.nPage,
bb70: 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65 0a   pWal->zWalName.
bb80: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20        );.    }. 
bb90: 20 7d 0a 0a 72 65 63 6f 76 65 72 79 5f 65 72 72   }..recovery_err
bba0: 6f 72 3a 0a 20 20 57 41 4c 54 52 41 43 45 28 28  or:.  WALTRACE((
bbb0: 22 57 41 4c 25 70 3a 20 72 65 63 6f 76 65 72 79  "WAL%p: recovery
bbc0: 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72 63   %s\n", pWal, rc
bbd0: 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f   ? "failed" : "o
bbe0: 6b 22 29 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f 63  k"));.  walUnloc
bbf0: 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
bc00: 20 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b 0a   iLock, nLock);.
bc10: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
bc20: 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20 6f  /*.** Close an o
bc30: 70 65 6e 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a  pen wal-index..*
bc40: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61  /.static void wa
bc50: 6c 49 6e 64 65 78 43 6c 6f 73 65 28 57 61 6c 20  lIndexClose(Wal 
bc60: 2a 70 57 61 6c 2c 20 69 6e 74 20 69 73 44 65 6c  *pWal, int isDel
bc70: 65 74 65 29 7b 0a 20 20 69 66 28 20 70 57 61 6c  ete){.  if( pWal
bc80: 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d  ->exclusiveMode=
bc90: 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f  =WAL_HEAPMEMORY_
bca0: 4d 4f 44 45 20 29 7b 0a 20 20 20 20 69 6e 74 20  MODE ){.    int 
bcb0: 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  i;.    for(i=0; 
bcc0: 69 3c 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3b  i<pWal->nWiData;
bcd0: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 71 6c   i++){.      sql
bce0: 69 74 65 33 5f 66 72 65 65 28 28 76 6f 69 64 20  ite3_free((void 
bcf0: 2a 29 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61  *)pWal->apWiData
bd00: 5b 69 5d 29 3b 0a 20 20 20 20 20 20 70 57 61 6c  [i]);.      pWal
bd10: 2d 3e 61 70 57 69 44 61 74 61 5b 69 5d 20 3d 20  ->apWiData[i] = 
bd20: 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65  0;.    }.  }else
bd30: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53  {.    sqlite3OsS
bd40: 68 6d 55 6e 6d 61 70 28 70 57 61 6c 2d 3e 70 44  hmUnmap(pWal->pD
bd50: 62 46 64 2c 20 69 73 44 65 6c 65 74 65 29 3b 0a  bFd, isDelete);.
bd60: 20 20 7d 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4f 70    }.}../* .** Op
bd70: 65 6e 20 61 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  en a connection 
bd80: 74 6f 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20  to the WAL file 
bd90: 7a 57 61 6c 4e 61 6d 65 2e 20 54 68 65 20 64 61  zWalName. The da
bda0: 74 61 62 61 73 65 20 66 69 6c 65 20 6d 75 73 74  tabase file must
bdb0: 20 0a 2a 2a 20 61 6c 72 65 61 64 79 20 62 65 20   .** already be 
bdc0: 6f 70 65 6e 65 64 20 6f 6e 20 63 6f 6e 6e 65 63  opened on connec
bdd0: 74 69 6f 6e 20 70 44 62 46 64 2e 20 54 68 65 20  tion pDbFd. The 
bde0: 62 75 66 66 65 72 20 74 68 61 74 20 7a 57 61 6c  buffer that zWal
bdf0: 4e 61 6d 65 20 70 6f 69 6e 74 73 0a 2a 2a 20 74  Name points.** t
be00: 6f 20 6d 75 73 74 20 72 65 6d 61 69 6e 20 76 61  o must remain va
be10: 6c 69 64 20 66 6f 72 20 74 68 65 20 6c 69 66 65  lid for the life
be20: 74 69 6d 65 20 6f 66 20 74 68 65 20 72 65 74 75  time of the retu
be30: 72 6e 65 64 20 57 61 6c 2a 20 68 61 6e 64 6c 65  rned Wal* handle
be40: 2e 0a 2a 2a 0a 2a 2a 20 41 20 53 48 41 52 45 44  ..**.** A SHARED
be50: 20 6c 6f 63 6b 20 73 68 6f 75 6c 64 20 62 65 20   lock should be 
be60: 68 65 6c 64 20 6f 6e 20 74 68 65 20 64 61 74 61  held on the data
be70: 62 61 73 65 20 66 69 6c 65 20 77 68 65 6e 20 74  base file when t
be80: 68 69 73 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20  his function.** 
be90: 69 73 20 63 61 6c 6c 65 64 2e 20 54 68 65 20 70  is called. The p
bea0: 75 72 70 6f 73 65 20 6f 66 20 74 68 69 73 20 53  urpose of this S
beb0: 48 41 52 45 44 20 6c 6f 63 6b 20 69 73 20 74 6f  HARED lock is to
bec0: 20 70 72 65 76 65 6e 74 20 61 6e 79 20 6f 74 68   prevent any oth
bed0: 65 72 0a 2a 2a 20 63 6c 69 65 6e 74 20 66 72 6f  er.** client fro
bee0: 6d 20 75 6e 6c 69 6e 6b 69 6e 67 20 74 68 65 20  m unlinking the 
bef0: 57 41 4c 20 6f 72 20 77 61 6c 2d 69 6e 64 65 78  WAL or wal-index
bf00: 20 66 69 6c 65 2e 20 49 66 20 61 6e 6f 74 68 65   file. If anothe
bf10: 72 20 70 72 6f 63 65 73 73 0a 2a 2a 20 77 65 72  r process.** wer
bf20: 65 20 74 6f 20 64 6f 20 74 68 69 73 20 6a 75 73  e to do this jus
bf30: 74 20 61 66 74 65 72 20 74 68 69 73 20 63 6c 69  t after this cli
bf40: 65 6e 74 20 6f 70 65 6e 65 64 20 6f 6e 65 20 6f  ent opened one o
bf50: 66 20 74 68 65 73 65 20 66 69 6c 65 73 2c 20 74  f these files, t
bf60: 68 65 0a 2a 2a 20 73 79 73 74 65 6d 20 77 6f 75  he.** system wou
bf70: 6c 64 20 62 65 20 62 61 64 6c 79 20 62 72 6f 6b  ld be badly brok
bf80: 65 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  en..**.** If the
bf90: 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 73 75 63   log file is suc
bfa0: 63 65 73 73 66 75 6c 6c 79 20 6f 70 65 6e 65 64  cessfully opened
bfb0: 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  , SQLITE_OK is r
bfc0: 65 74 75 72 6e 65 64 20 61 6e 64 20 0a 2a 2a 20  eturned and .** 
bfd0: 2a 70 70 57 61 6c 20 69 73 20 73 65 74 20 74 6f  *ppWal is set to
bfe0: 20 70 6f 69 6e 74 20 74 6f 20 61 20 6e 65 77 20   point to a new 
bff0: 57 41 4c 20 68 61 6e 64 6c 65 2e 20 49 66 20 61  WAL handle. If a
c000: 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 0a  n error occurs,.
c010: 2a 2a 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72  ** an SQLite err
c020: 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  or code is retur
c030: 6e 65 64 20 61 6e 64 20 2a 70 70 57 61 6c 20 69  ned and *ppWal i
c040: 73 20 6c 65 66 74 20 75 6e 6d 6f 64 69 66 69 65  s left unmodifie
c050: 64 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  d..*/.int sqlite
c060: 33 57 61 6c 4f 70 65 6e 28 0a 20 20 73 71 6c 69  3WalOpen(.  sqli
c070: 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 20  te3_vfs *pVfs,  
c080: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 76              /* v
c090: 66 73 20 6d 6f 64 75 6c 65 20 74 6f 20 6f 70 65  fs module to ope
c0a0: 6e 20 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e  n wal and wal-in
c0b0: 64 65 78 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  dex */.  sqlite3
c0c0: 5f 66 69 6c 65 20 2a 70 44 62 46 64 2c 20 20 20  _file *pDbFd,   
c0d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
c0e0: 6f 70 65 6e 20 64 61 74 61 62 61 73 65 20 66 69  open database fi
c0f0: 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  le */.  const ch
c100: 61 72 20 2a 7a 57 61 6c 4e 61 6d 65 2c 20 20 20  ar *zWalName,   
c110: 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20          /* Name 
c120: 6f 66 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20  of the WAL file 
c130: 2a 2f 0a 20 20 69 6e 74 20 62 4e 6f 53 68 6d 2c  */.  int bNoShm,
c140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c150: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20       /* True to 
c160: 72 75 6e 20 69 6e 20 68 65 61 70 2d 6d 65 6d 6f  run in heap-memo
c170: 72 79 20 6d 6f 64 65 20 2a 2f 0a 20 20 69 36 34  ry mode */.  i64
c180: 20 6d 78 57 61 6c 53 69 7a 65 2c 20 20 20 20 20   mxWalSize,     
c190: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c1a0: 54 72 75 6e 63 61 74 65 20 57 41 4c 20 74 6f 20  Truncate WAL to 
c1b0: 74 68 69 73 20 73 69 7a 65 20 6f 6e 20 72 65 73  this size on res
c1c0: 65 74 20 2a 2f 0a 20 20 57 61 6c 20 2a 2a 70 70  et */.  Wal **pp
c1d0: 57 61 6c 20 20 20 20 20 20 20 20 20 20 20 20 20  Wal             
c1e0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
c1f0: 41 6c 6c 6f 63 61 74 65 64 20 57 61 6c 20 68 61  Allocated Wal ha
c200: 6e 64 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ndle */.){.  int
c210: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
c220: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c230: 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20  Return Code */. 
c240: 20 57 61 6c 20 2a 70 52 65 74 3b 20 20 20 20 20   Wal *pRet;     
c250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c260: 20 2f 2a 20 4f 62 6a 65 63 74 20 74 6f 20 61 6c   /* Object to al
c270: 6c 6f 63 61 74 65 20 61 6e 64 20 72 65 74 75 72  locate and retur
c280: 6e 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73  n */.  int flags
c290: 3b 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 6c 61 67 73 20         /* Flags 
c2b0: 70 61 73 73 65 64 20 74 6f 20 4f 73 4f 70 65 6e  passed to OsOpen
c2c0: 28 29 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28  () */..  assert(
c2d0: 20 7a 57 61 6c 4e 61 6d 65 20 26 26 20 7a 57 61   zWalName && zWa
c2e0: 6c 4e 61 6d 65 5b 30 5d 20 29 3b 0a 20 20 61 73  lName[0] );.  as
c2f0: 73 65 72 74 28 20 70 44 62 46 64 20 29 3b 0a 0a  sert( pDbFd );..
c300: 20 20 2f 2a 20 49 6e 20 74 68 65 20 61 6d 61 6c    /* In the amal
c310: 67 61 6d 61 74 69 6f 6e 2c 20 74 68 65 20 6f 73  gamation, the os
c320: 5f 75 6e 69 78 2e 63 20 61 6e 64 20 6f 73 5f 77  _unix.c and os_w
c330: 69 6e 2e 63 20 73 6f 75 72 63 65 20 66 69 6c 65  in.c source file
c340: 73 20 63 6f 6d 65 20 62 65 66 6f 72 65 0a 20 20  s come before.  
c350: 2a 2a 20 74 68 69 73 20 73 6f 75 72 63 65 20 66  ** this source f
c360: 69 6c 65 2e 20 20 56 65 72 69 66 79 20 74 68 61  ile.  Verify tha
c370: 74 20 74 68 65 20 23 64 65 66 69 6e 65 73 20 6f  t the #defines o
c380: 66 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 62 79  f the locking by
c390: 74 65 20 6f 66 66 73 65 74 73 0a 20 20 2a 2a 20  te offsets.  ** 
c3a0: 69 6e 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e 64  in os_unix.c and
c3b0: 20 6f 73 5f 77 69 6e 2e 63 20 61 67 72 65 65 20   os_win.c agree 
c3c0: 77 69 74 68 20 74 68 65 20 57 41 4c 49 4e 44 45  with the WALINDE
c3d0: 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 76 61  X_LOCK_OFFSET va
c3e0: 6c 75 65 2e 0a 20 20 2a 2f 0a 23 69 66 64 65 66  lue..  */.#ifdef
c3f0: 20 57 49 4e 5f 53 48 4d 5f 42 41 53 45 0a 20 20   WIN_SHM_BASE.  
c400: 61 73 73 65 72 74 28 20 57 49 4e 5f 53 48 4d 5f  assert( WIN_SHM_
c410: 42 41 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c  BASE==WALINDEX_L
c420: 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65  OCK_OFFSET );.#e
c430: 6e 64 69 66 0a 23 69 66 64 65 66 20 55 4e 49 58  ndif.#ifdef UNIX
c440: 5f 53 48 4d 5f 42 41 53 45 0a 20 20 61 73 73 65  _SHM_BASE.  asse
c450: 72 74 28 20 55 4e 49 58 5f 53 48 4d 5f 42 41 53  rt( UNIX_SHM_BAS
c460: 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b  E==WALINDEX_LOCK
c470: 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65 6e 64 69  _OFFSET );.#endi
c480: 66 0a 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  f...  /* Allocat
c490: 65 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66  e an instance of
c4a0: 20 73 74 72 75 63 74 20 57 61 6c 20 74 6f 20 72   struct Wal to r
c4b0: 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 2a 70 70 57  eturn. */.  *ppW
c4c0: 61 6c 20 3d 20 30 3b 0a 20 20 70 52 65 74 20 3d  al = 0;.  pRet =
c4d0: 20 28 57 61 6c 2a 29 73 71 6c 69 74 65 33 4d 61   (Wal*)sqlite3Ma
c4e0: 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28  llocZero(sizeof(
c4f0: 57 61 6c 29 20 2b 20 70 56 66 73 2d 3e 73 7a 4f  Wal) + pVfs->szO
c500: 73 46 69 6c 65 29 3b 0a 20 20 69 66 28 20 21 70  sFile);.  if( !p
c510: 52 65 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72  Ret ){.    retur
c520: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
c530: 20 20 7d 0a 0a 20 20 70 52 65 74 2d 3e 70 56 66    }..  pRet->pVf
c540: 73 20 3d 20 70 56 66 73 3b 0a 20 20 70 52 65 74  s = pVfs;.  pRet
c550: 2d 3e 70 57 61 6c 46 64 20 3d 20 28 73 71 6c 69  ->pWalFd = (sqli
c560: 74 65 33 5f 66 69 6c 65 20 2a 29 26 70 52 65 74  te3_file *)&pRet
c570: 5b 31 5d 3b 0a 20 20 70 52 65 74 2d 3e 70 44 62  [1];.  pRet->pDb
c580: 46 64 20 3d 20 70 44 62 46 64 3b 0a 20 20 70 52  Fd = pDbFd;.  pR
c590: 65 74 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d  et->readLock = -
c5a0: 31 3b 0a 20 20 70 52 65 74 2d 3e 6d 78 57 61 6c  1;.  pRet->mxWal
c5b0: 53 69 7a 65 20 3d 20 6d 78 57 61 6c 53 69 7a 65  Size = mxWalSize
c5c0: 3b 0a 20 20 70 52 65 74 2d 3e 7a 57 61 6c 4e 61  ;.  pRet->zWalNa
c5d0: 6d 65 20 3d 20 7a 57 61 6c 4e 61 6d 65 3b 0a 20  me = zWalName;. 
c5e0: 20 70 52 65 74 2d 3e 65 78 63 6c 75 73 69 76 65   pRet->exclusive
c5f0: 4d 6f 64 65 20 3d 20 28 62 4e 6f 53 68 6d 20 3f  Mode = (bNoShm ?
c600: 20 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f   WAL_HEAPMEMORY_
c610: 4d 4f 44 45 3a 20 57 41 4c 5f 4e 4f 52 4d 41 4c  MODE: WAL_NORMAL
c620: 5f 4d 4f 44 45 29 3b 0a 0a 20 20 2f 2a 20 4f 70  _MODE);..  /* Op
c630: 65 6e 20 66 69 6c 65 20 68 61 6e 64 6c 65 20 6f  en file handle o
c640: 6e 20 74 68 65 20 77 72 69 74 65 2d 61 68 65 61  n the write-ahea
c650: 64 20 6c 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a 20  d log file. */. 
c660: 20 66 6c 61 67 73 20 3d 20 28 53 51 4c 49 54 45   flags = (SQLITE
c670: 5f 4f 50 45 4e 5f 52 45 41 44 57 52 49 54 45 7c  _OPEN_READWRITE|
c680: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41  SQLITE_OPEN_CREA
c690: 54 45 7c 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 57  TE|SQLITE_OPEN_W
c6a0: 41 4c 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69  AL);.  rc = sqli
c6b0: 74 65 33 4f 73 4f 70 65 6e 28 70 56 66 73 2c 20  te3OsOpen(pVfs, 
c6c0: 7a 57 61 6c 4e 61 6d 65 2c 20 70 52 65 74 2d 3e  zWalName, pRet->
c6d0: 70 57 61 6c 46 64 2c 20 66 6c 61 67 73 2c 20 26  pWalFd, flags, &
c6e0: 66 6c 61 67 73 29 3b 0a 20 20 69 66 28 20 72 63  flags);.  if( rc
c6f0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 66  ==SQLITE_OK && f
c700: 6c 61 67 73 26 53 51 4c 49 54 45 5f 4f 50 45 4e  lags&SQLITE_OPEN
c710: 5f 52 45 41 44 4f 4e 4c 59 20 29 7b 0a 20 20 20  _READONLY ){.   
c720: 20 70 52 65 74 2d 3e 72 65 61 64 4f 6e 6c 79 20   pRet->readOnly 
c730: 3d 20 57 41 4c 5f 52 44 4f 4e 4c 59 3b 0a 20 20  = WAL_RDONLY;.  
c740: 7d 0a 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  }..  if( rc!=SQL
c750: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 61  ITE_OK ){.    wa
c760: 6c 49 6e 64 65 78 43 6c 6f 73 65 28 70 52 65 74  lIndexClose(pRet
c770: 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  , 0);.    sqlite
c780: 33 4f 73 43 6c 6f 73 65 28 70 52 65 74 2d 3e 70  3OsClose(pRet->p
c790: 57 61 6c 46 64 29 3b 0a 20 20 20 20 73 71 6c 69  WalFd);.    sqli
c7a0: 74 65 33 5f 66 72 65 65 28 70 52 65 74 29 3b 0a  te3_free(pRet);.
c7b0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 70    }else{.    *pp
c7c0: 57 61 6c 20 3d 20 70 52 65 74 3b 0a 20 20 20 20  Wal = pRet;.    
c7d0: 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 64  WALTRACE(("WAL%d
c7e0: 3a 20 6f 70 65 6e 65 64 5c 6e 22 2c 20 70 52 65  : opened\n", pRe
c7f0: 74 29 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  t));.  }.  retur
c800: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  n rc;.}../*.** C
c810: 68 61 6e 67 65 20 74 68 65 20 73 69 7a 65 20 74  hange the size t
c820: 6f 20 77 68 69 63 68 20 74 68 65 20 57 41 4c 20  o which the WAL 
c830: 66 69 6c 65 20 69 73 20 74 72 75 63 61 74 65 64  file is trucated
c840: 20 6f 6e 20 65 61 63 68 20 72 65 73 65 74 2e 0a   on each reset..
c850: 2a 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 57  */.void sqlite3W
c860: 61 6c 4c 69 6d 69 74 28 57 61 6c 20 2a 70 57 61  alLimit(Wal *pWa
c870: 6c 2c 20 69 36 34 20 69 4c 69 6d 69 74 29 7b 0a  l, i64 iLimit){.
c880: 20 20 69 66 28 20 70 57 61 6c 20 29 20 70 57 61    if( pWal ) pWa
c890: 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 20 3d 20 69  l->mxWalSize = i
c8a0: 4c 69 6d 69 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Limit;.}../*.** 
c8b0: 46 69 6e 64 20 74 68 65 20 73 6d 61 6c 6c 65 73  Find the smalles
c8c0: 74 20 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 75  t page number ou
c8d0: 74 20 6f 66 20 61 6c 6c 20 70 61 67 65 73 20 68  t of all pages h
c8e0: 65 6c 64 20 69 6e 20 74 68 65 20 57 41 4c 20 74  eld in the WAL t
c8f0: 68 61 74 0a 2a 2a 20 68 61 73 20 6e 6f 74 20 62  hat.** has not b
c900: 65 65 6e 20 72 65 74 75 72 6e 65 64 20 62 79 20  een returned by 
c910: 61 6e 79 20 70 72 69 6f 72 20 69 6e 76 6f 63 61  any prior invoca
c920: 74 69 6f 6e 20 6f 66 20 74 68 69 73 20 6d 65 74  tion of this met
c930: 68 6f 64 20 6f 6e 20 74 68 65 0a 2a 2a 20 73 61  hod on the.** sa
c940: 6d 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f  me WalIterator o
c950: 62 6a 65 63 74 2e 20 20 20 57 72 69 74 65 20 69  bject.   Write i
c960: 6e 74 6f 20 2a 70 69 46 72 61 6d 65 20 74 68 65  nto *piFrame the
c970: 20 66 72 61 6d 65 20 69 6e 64 65 78 20 77 68 65   frame index whe
c980: 72 65 0a 2a 2a 20 74 68 61 74 20 70 61 67 65 20  re.** that page 
c990: 77 61 73 20 6c 61 73 74 20 77 72 69 74 74 65 6e  was last written
c9a0: 20 69 6e 74 6f 20 74 68 65 20 57 41 4c 2e 20 20   into the WAL.  
c9b0: 57 72 69 74 65 20 69 6e 74 6f 20 2a 70 69 50 61  Write into *piPa
c9c0: 67 65 20 74 68 65 20 70 61 67 65 0a 2a 2a 20 6e  ge the page.** n
c9d0: 75 6d 62 65 72 2e 0a 2a 2a 0a 2a 2a 20 52 65 74  umber..**.** Ret
c9e0: 75 72 6e 20 30 20 6f 6e 20 73 75 63 63 65 73 73  urn 0 on success
c9f0: 2e 20 20 49 66 20 74 68 65 72 65 20 61 72 65 20  .  If there are 
ca00: 6e 6f 20 70 61 67 65 73 20 69 6e 20 74 68 65 20  no pages in the 
ca10: 57 41 4c 20 77 69 74 68 20 61 20 70 61 67 65 0a  WAL with a page.
ca20: 2a 2a 20 6e 75 6d 62 65 72 20 6c 61 72 67 65 72  ** number larger
ca30: 20 74 68 61 6e 20 2a 70 69 50 61 67 65 2c 20 74   than *piPage, t
ca40: 68 65 6e 20 72 65 74 75 72 6e 20 31 2e 0a 2a 2f  hen return 1..*/
ca50: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49  .static int walI
ca60: 74 65 72 61 74 6f 72 4e 65 78 74 28 0a 20 20 57  teratorNext(.  W
ca70: 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 2c 20 20  alIterator *p,  
ca80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
ca90: 49 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 75 33  Iterator */.  u3
caa0: 32 20 2a 70 69 50 61 67 65 2c 20 20 20 20 20 20  2 *piPage,      
cab0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
cac0: 55 54 3a 20 54 68 65 20 70 61 67 65 20 6e 75 6d  UT: The page num
cad0: 62 65 72 20 6f 66 20 74 68 65 20 6e 65 78 74 20  ber of the next 
cae0: 70 61 67 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70  page */.  u32 *p
caf0: 69 46 72 61 6d 65 20 20 20 20 20 20 20 20 20 20  iFrame          
cb00: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
cb10: 57 61 6c 20 66 72 61 6d 65 20 69 6e 64 65 78 20  Wal frame index 
cb20: 6f 66 20 6e 65 78 74 20 70 61 67 65 20 2a 2f 0a  of next page */.
cb30: 29 7b 0a 20 20 75 33 32 20 69 4d 69 6e 3b 20 20  ){.  u32 iMin;  
cb40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cb50: 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 70 67 6e     /* Result pgn
cb60: 6f 20 6d 75 73 74 20 62 65 20 67 72 65 61 74 65  o must be greate
cb70: 72 20 74 68 61 6e 20 69 4d 69 6e 20 2a 2f 0a 20  r than iMin */. 
cb80: 20 75 33 32 20 69 52 65 74 20 3d 20 30 78 46 46   u32 iRet = 0xFF
cb90: 46 46 46 46 46 46 3b 20 20 20 20 20 20 20 20 2f  FFFFFF;        /
cba0: 2a 20 30 78 66 66 66 66 66 66 66 66 20 69 73 20  * 0xffffffff is 
cbb0: 6e 65 76 65 72 20 61 20 76 61 6c 69 64 20 70 61  never a valid pa
cbc0: 67 65 20 6e 75 6d 62 65 72 20 2a 2f 0a 20 20 69  ge number */.  i
cbd0: 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20  nt i;           
cbe0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
cbf0: 46 6f 72 20 6c 6f 6f 70 69 6e 67 20 74 68 72 6f  For looping thro
cc00: 75 67 68 20 73 65 67 6d 65 6e 74 73 20 2a 2f 0a  ugh segments */.
cc10: 0a 20 20 69 4d 69 6e 20 3d 20 70 2d 3e 69 50 72  .  iMin = p->iPr
cc20: 69 6f 72 3b 0a 20 20 61 73 73 65 72 74 28 20 69  ior;.  assert( i
cc30: 4d 69 6e 3c 30 78 66 66 66 66 66 66 66 66 20 29  Min<0xffffffff )
cc40: 3b 0a 20 20 66 6f 72 28 69 3d 70 2d 3e 6e 53 65  ;.  for(i=p->nSe
cc50: 67 6d 65 6e 74 2d 31 3b 20 69 3e 3d 30 3b 20 69  gment-1; i>=0; i
cc60: 2d 2d 29 7b 0a 20 20 20 20 73 74 72 75 63 74 20  --){.    struct 
cc70: 57 61 6c 53 65 67 6d 65 6e 74 20 2a 70 53 65 67  WalSegment *pSeg
cc80: 6d 65 6e 74 20 3d 20 26 70 2d 3e 61 53 65 67 6d  ment = &p->aSegm
cc90: 65 6e 74 5b 69 5d 3b 0a 20 20 20 20 77 68 69 6c  ent[i];.    whil
cca0: 65 28 20 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65  e( pSegment->iNe
ccb0: 78 74 3c 70 53 65 67 6d 65 6e 74 2d 3e 6e 45 6e  xt<pSegment->nEn
ccc0: 74 72 79 20 29 7b 0a 20 20 20 20 20 20 75 33 32  try ){.      u32
ccd0: 20 69 50 67 20 3d 20 70 53 65 67 6d 65 6e 74 2d   iPg = pSegment-
cce0: 3e 61 50 67 6e 6f 5b 70 53 65 67 6d 65 6e 74 2d  >aPgno[pSegment-
ccf0: 3e 61 49 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74  >aIndex[pSegment
cd00: 2d 3e 69 4e 65 78 74 5d 5d 3b 0a 20 20 20 20 20  ->iNext]];.     
cd10: 20 69 66 28 20 69 50 67 3e 69 4d 69 6e 20 29 7b   if( iPg>iMin ){
cd20: 0a 20 20 20 20 20 20 20 20 69 66 28 20 69 50 67  .        if( iPg
cd30: 3c 69 52 65 74 20 29 7b 0a 20 20 20 20 20 20 20  <iRet ){.       
cd40: 20 20 20 69 52 65 74 20 3d 20 69 50 67 3b 0a 20     iRet = iPg;. 
cd50: 20 20 20 20 20 20 20 20 20 2a 70 69 46 72 61 6d           *piFram
cd60: 65 20 3d 20 70 53 65 67 6d 65 6e 74 2d 3e 69 5a  e = pSegment->iZ
cd70: 65 72 6f 20 2b 20 70 53 65 67 6d 65 6e 74 2d 3e  ero + pSegment->
cd80: 61 49 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d  aIndex[pSegment-
cd90: 3e 69 4e 65 78 74 5d 3b 0a 20 20 20 20 20 20 20  >iNext];.       
cda0: 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b   }.        break
cdb0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
cdc0: 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 2b  pSegment->iNext+
cdd0: 2b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  +;.    }.  }..  
cde0: 2a 70 69 50 61 67 65 20 3d 20 70 2d 3e 69 50 72  *piPage = p->iPr
cdf0: 69 6f 72 20 3d 20 69 52 65 74 3b 0a 20 20 72 65  ior = iRet;.  re
ce00: 74 75 72 6e 20 28 69 52 65 74 3d 3d 30 78 46 46  turn (iRet==0xFF
ce10: 46 46 46 46 46 46 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  FFFFFF);.}../*.*
ce20: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
ce30: 6d 65 72 67 65 73 20 74 77 6f 20 73 6f 72 74 65  merges two sorte
ce40: 64 20 6c 69 73 74 73 20 69 6e 74 6f 20 61 20 73  d lists into a s
ce50: 69 6e 67 6c 65 20 73 6f 72 74 65 64 20 6c 69 73  ingle sorted lis
ce60: 74 2e 0a 2a 2a 0a 2a 2a 20 61 4c 65 66 74 5b 5d  t..**.** aLeft[]
ce70: 20 61 6e 64 20 61 52 69 67 68 74 5b 5d 20 61 72   and aRight[] ar
ce80: 65 20 61 72 72 61 79 73 20 6f 66 20 69 6e 64 69  e arrays of indi
ce90: 63 65 73 2e 20 20 54 68 65 20 73 6f 72 74 20 6b  ces.  The sort k
cea0: 65 79 20 69 73 0a 2a 2a 20 61 43 6f 6e 74 65 6e  ey is.** aConten
ceb0: 74 5b 61 4c 65 66 74 5b 5d 5d 20 61 6e 64 20 61  t[aLeft[]] and a
cec0: 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74 5b 5d  Content[aRight[]
ced0: 5d 2e 20 20 55 70 6f 6e 20 65 6e 74 72 79 2c 20  ].  Upon entry, 
cee0: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a  the following.**
cef0: 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 66   is guaranteed f
cf00: 6f 72 20 61 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a 2a  or all J<K:.**.*
cf10: 2a 20 20 20 20 20 20 20 20 61 43 6f 6e 74 65 6e  *        aConten
cf20: 74 5b 61 4c 65 66 74 5b 4a 5d 5d 20 3c 20 61 43  t[aLeft[J]] < aC
cf30: 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 4b 5d 5d  ontent[aLeft[K]]
cf40: 0a 2a 2a 20 20 20 20 20 20 20 20 61 43 6f 6e 74  .**        aCont
cf50: 65 6e 74 5b 61 52 69 67 68 74 5b 4a 5d 5d 20 3c  ent[aRight[J]] <
cf60: 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74   aContent[aRight
cf70: 5b 4b 5d 5d 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  [K]].**.** This 
cf80: 72 6f 75 74 69 6e 65 20 6f 76 65 72 77 72 69 74  routine overwrit
cf90: 65 73 20 61 52 69 67 68 74 5b 5d 20 77 69 74 68  es aRight[] with
cfa0: 20 61 20 6e 65 77 20 28 70 72 6f 62 61 62 6c 79   a new (probably
cfb0: 20 6c 6f 6e 67 65 72 29 20 73 65 71 75 65 6e 63   longer) sequenc
cfc0: 65 0a 2a 2a 20 6f 66 20 69 6e 64 69 63 65 73 20  e.** of indices 
cfd0: 73 75 63 68 20 74 68 61 74 20 74 68 65 20 61 52  such that the aR
cfe0: 69 67 68 74 5b 5d 20 63 6f 6e 74 61 69 6e 73 20  ight[] contains 
cff0: 65 76 65 72 79 20 69 6e 64 65 78 20 74 68 61 74  every index that
d000: 20 61 70 70 65 61 72 73 20 69 6e 0a 2a 2a 20 65   appears in.** e
d010: 69 74 68 65 72 20 61 4c 65 66 74 5b 5d 20 6f 72  ither aLeft[] or
d020: 20 74 68 65 20 6f 6c 64 20 61 52 69 67 68 74 5b   the old aRight[
d030: 5d 20 61 6e 64 20 73 75 63 68 20 74 68 61 74 20  ] and such that 
d040: 74 68 65 20 73 65 63 6f 6e 64 20 63 6f 6e 64 69  the second condi
d050: 74 69 6f 6e 0a 2a 2a 20 61 62 6f 76 65 20 69 73  tion.** above is
d060: 20 73 74 69 6c 6c 20 6d 65 74 2e 0a 2a 2a 0a 2a   still met..**.*
d070: 2a 20 54 68 65 20 61 43 6f 6e 74 65 6e 74 5b 61  * The aContent[a
d080: 4c 65 66 74 5b 58 5d 5d 20 76 61 6c 75 65 73 20  Left[X]] values 
d090: 77 69 6c 6c 20 62 65 20 75 6e 69 71 75 65 20 66  will be unique f
d0a0: 6f 72 20 61 6c 6c 20 58 2e 20 20 41 6e 64 20 74  or all X.  And t
d0b0: 68 65 0a 2a 2a 20 61 43 6f 6e 74 65 6e 74 5b 61  he.** aContent[a
d0c0: 52 69 67 68 74 5b 58 5d 5d 20 76 61 6c 75 65 73  Right[X]] values
d0d0: 20 77 69 6c 6c 20 62 65 20 75 6e 69 71 75 65 20   will be unique 
d0e0: 74 6f 6f 2e 20 20 42 75 74 20 74 68 65 72 65 20  too.  But there 
d0f0: 6d 69 67 68 74 20 62 65 0a 2a 2a 20 6f 6e 65 20  might be.** one 
d100: 6f 72 20 6d 6f 72 65 20 63 6f 6d 62 69 6e 61 74  or more combinat
d110: 69 6f 6e 73 20 6f 66 20 58 20 61 6e 64 20 59 20  ions of X and Y 
d120: 73 75 63 68 20 74 68 61 74 0a 2a 2a 0a 2a 2a 20  such that.**.** 
d130: 20 20 20 20 20 61 4c 65 66 74 5b 58 5d 21 3d 61       aLeft[X]!=a
d140: 52 69 67 68 74 5b 59 5d 20 20 26 26 20 20 61 43  Right[Y]  &&  aC
d150: 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 58 5d 5d  ontent[aLeft[X]]
d160: 20 3d 3d 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69   == aContent[aRi
d170: 67 68 74 5b 59 5d 5d 0a 2a 2a 0a 2a 2a 20 57 68  ght[Y]].**.** Wh
d180: 65 6e 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c  en that happens,
d190: 20 6f 6d 69 74 20 74 68 65 20 61 4c 65 66 74 5b   omit the aLeft[
d1a0: 58 5d 20 61 6e 64 20 75 73 65 20 74 68 65 20 61  X] and use the a
d1b0: 52 69 67 68 74 5b 59 5d 20 69 6e 64 65 78 2e 0a  Right[Y] index..
d1c0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
d1d0: 61 6c 4d 65 72 67 65 28 0a 20 20 63 6f 6e 73 74  alMerge(.  const
d1e0: 20 75 33 32 20 2a 61 43 6f 6e 74 65 6e 74 2c 20   u32 *aContent, 
d1f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
d200: 67 65 73 20 69 6e 20 77 61 6c 20 2d 20 6b 65 79  ges in wal - key
d210: 73 20 66 6f 72 20 74 68 65 20 73 6f 72 74 20 2a  s for the sort *
d220: 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 65  /.  ht_slot *aLe
d230: 66 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ft,             
d240: 20 20 20 20 2f 2a 20 49 4e 3a 20 4c 65 66 74 20      /* IN: Left 
d250: 68 61 6e 64 20 69 6e 70 75 74 20 6c 69 73 74 20  hand input list 
d260: 2a 2f 0a 20 20 69 6e 74 20 6e 4c 65 66 74 2c 20  */.  int nLeft, 
d270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d280: 20 20 20 20 20 2f 2a 20 49 4e 3a 20 45 6c 65 6d       /* IN: Elem
d290: 65 6e 74 73 20 69 6e 20 61 72 72 61 79 20 2a 70  ents in array *p
d2a0: 61 4c 65 66 74 20 2a 2f 0a 20 20 68 74 5f 73 6c  aLeft */.  ht_sl
d2b0: 6f 74 20 2a 2a 70 61 52 69 67 68 74 2c 20 20 20  ot **paRight,   
d2c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e             /* IN
d2d0: 2f 4f 55 54 3a 20 52 69 67 68 74 20 68 61 6e 64  /OUT: Right hand
d2e0: 20 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20   input list */. 
d2f0: 20 69 6e 74 20 2a 70 6e 52 69 67 68 74 2c 20 20   int *pnRight,  
d300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d310: 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45 6c 65 6d   /* IN/OUT: Elem
d320: 65 6e 74 73 20 69 6e 20 2a 70 61 52 69 67 68 74  ents in *paRight
d330: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61   */.  ht_slot *a
d340: 54 6d 70 20 20 20 20 20 20 20 20 20 20 20 20 20  Tmp             
d350: 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61        /* Tempora
d360: 72 79 20 62 75 66 66 65 72 20 2a 2f 0a 29 7b 0a  ry buffer */.){.
d370: 20 20 69 6e 74 20 69 4c 65 66 74 20 3d 20 30 3b    int iLeft = 0;
d380: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d390: 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64    /* Current ind
d3a0: 65 78 20 69 6e 20 61 4c 65 66 74 20 2a 2f 0a 20  ex in aLeft */. 
d3b0: 20 69 6e 74 20 69 52 69 67 68 74 20 3d 20 30 3b   int iRight = 0;
d3c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d3d0: 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65   /* Current inde
d3e0: 78 20 69 6e 20 61 52 69 67 68 74 20 2a 2f 0a 20  x in aRight */. 
d3f0: 20 69 6e 74 20 69 4f 75 74 20 3d 20 30 3b 20 20   int iOut = 0;  
d400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d410: 20 2f 2a 20 43 75 72 72 65 6e 74 20 69 6e 64 65   /* Current inde
d420: 78 20 69 6e 20 6f 75 74 70 75 74 20 62 75 66 66  x in output buff
d430: 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 69 67  er */.  int nRig
d440: 68 74 20 3d 20 2a 70 6e 52 69 67 68 74 3b 0a 20  ht = *pnRight;. 
d450: 20 68 74 5f 73 6c 6f 74 20 2a 61 52 69 67 68 74   ht_slot *aRight
d460: 20 3d 20 2a 70 61 52 69 67 68 74 3b 0a 0a 20 20   = *paRight;..  
d470: 61 73 73 65 72 74 28 20 6e 4c 65 66 74 3e 30 20  assert( nLeft>0 
d480: 26 26 20 6e 52 69 67 68 74 3e 30 20 29 3b 0a 20  && nRight>0 );. 
d490: 20 77 68 69 6c 65 28 20 69 52 69 67 68 74 3c 6e   while( iRight<n
d4a0: 52 69 67 68 74 20 7c 7c 20 69 4c 65 66 74 3c 6e  Right || iLeft<n
d4b0: 4c 65 66 74 20 29 7b 0a 20 20 20 20 68 74 5f 73  Left ){.    ht_s
d4c0: 6c 6f 74 20 6c 6f 67 70 61 67 65 3b 0a 20 20 20  lot logpage;.   
d4d0: 20 50 67 6e 6f 20 64 62 70 61 67 65 3b 0a 0a 20   Pgno dbpage;.. 
d4e0: 20 20 20 69 66 28 20 28 69 4c 65 66 74 3c 6e 4c     if( (iLeft<nL
d4f0: 65 66 74 29 20 0a 20 20 20 20 20 26 26 20 28 69  eft) .     && (i
d500: 52 69 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c  Right>=nRight ||
d510: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b   aContent[aLeft[
d520: 69 4c 65 66 74 5d 5d 3c 61 43 6f 6e 74 65 6e 74  iLeft]]<aContent
d530: 5b 61 52 69 67 68 74 5b 69 52 69 67 68 74 5d 5d  [aRight[iRight]]
d540: 29 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 6c  ).    ){.      l
d550: 6f 67 70 61 67 65 20 3d 20 61 4c 65 66 74 5b 69  ogpage = aLeft[i
d560: 4c 65 66 74 2b 2b 5d 3b 0a 20 20 20 20 7d 65 6c  Left++];.    }el
d570: 73 65 7b 0a 20 20 20 20 20 20 6c 6f 67 70 61 67  se{.      logpag
d580: 65 20 3d 20 61 52 69 67 68 74 5b 69 52 69 67 68  e = aRight[iRigh
d590: 74 2b 2b 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20  t++];.    }.    
d5a0: 64 62 70 61 67 65 20 3d 20 61 43 6f 6e 74 65 6e  dbpage = aConten
d5b0: 74 5b 6c 6f 67 70 61 67 65 5d 3b 0a 0a 20 20 20  t[logpage];..   
d5c0: 20 61 54 6d 70 5b 69 4f 75 74 2b 2b 5d 20 3d 20   aTmp[iOut++] = 
d5d0: 6c 6f 67 70 61 67 65 3b 0a 20 20 20 20 69 66 28  logpage;.    if(
d5e0: 20 69 4c 65 66 74 3c 6e 4c 65 66 74 20 26 26 20   iLeft<nLeft && 
d5f0: 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69  aContent[aLeft[i
d600: 4c 65 66 74 5d 5d 3d 3d 64 62 70 61 67 65 20 29  Left]]==dbpage )
d610: 20 69 4c 65 66 74 2b 2b 3b 0a 0a 20 20 20 20 61   iLeft++;..    a
d620: 73 73 65 72 74 28 20 69 4c 65 66 74 3e 3d 6e 4c  ssert( iLeft>=nL
d630: 65 66 74 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b  eft || aContent[
d640: 61 4c 65 66 74 5b 69 4c 65 66 74 5d 5d 3e 64 62  aLeft[iLeft]]>db
d650: 70 61 67 65 20 29 3b 0a 20 20 20 20 61 73 73 65  page );.    asse
d660: 72 74 28 20 69 52 69 67 68 74 3e 3d 6e 52 69 67  rt( iRight>=nRig
d670: 68 74 20 7c 7c 20 61 43 6f 6e 74 65 6e 74 5b 61  ht || aContent[a
d680: 52 69 67 68 74 5b 69 52 69 67 68 74 5d 5d 3e 64  Right[iRight]]>d
d690: 62 70 61 67 65 20 29 3b 0a 20 20 7d 0a 0a 20 20  bpage );.  }..  
d6a0: 2a 70 61 52 69 67 68 74 20 3d 20 61 4c 65 66 74  *paRight = aLeft
d6b0: 3b 0a 20 20 2a 70 6e 52 69 67 68 74 20 3d 20 69  ;.  *pnRight = i
d6c0: 4f 75 74 3b 0a 20 20 6d 65 6d 63 70 79 28 61 4c  Out;.  memcpy(aL
d6d0: 65 66 74 2c 20 61 54 6d 70 2c 20 73 69 7a 65 6f  eft, aTmp, sizeo
d6e0: 66 28 61 54 6d 70 5b 30 5d 29 2a 69 4f 75 74 29  f(aTmp[0])*iOut)
d6f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 6f 72 74 20  ;.}../*.** Sort 
d700: 74 68 65 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20  the elements in 
d710: 6c 69 73 74 20 61 4c 69 73 74 20 75 73 69 6e 67  list aList using
d720: 20 61 43 6f 6e 74 65 6e 74 5b 5d 20 61 73 20 74   aContent[] as t
d730: 68 65 20 73 6f 72 74 20 6b 65 79 2e 0a 2a 2a 20  he sort key..** 
d740: 52 65 6d 6f 76 65 20 65 6c 65 6d 65 6e 74 73 20  Remove elements 
d750: 77 69 74 68 20 64 75 70 6c 69 63 61 74 65 20 6b  with duplicate k
d760: 65 79 73 2c 20 70 72 65 66 65 72 72 69 6e 67 20  eys, preferring 
d770: 74 6f 20 6b 65 65 70 20 74 68 65 0a 2a 2a 20 6c  to keep the.** l
d780: 61 72 67 65 72 20 61 4c 69 73 74 5b 5d 20 76 61  arger aList[] va
d790: 6c 75 65 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  lues..**.** The 
d7a0: 61 4c 69 73 74 5b 5d 20 65 6e 74 72 69 65 73 20  aList[] entries 
d7b0: 61 72 65 20 69 6e 64 69 63 65 73 20 69 6e 74 6f  are indices into
d7c0: 20 61 43 6f 6e 74 65 6e 74 5b 5d 2e 20 20 54 68   aContent[].  Th
d7d0: 65 20 76 61 6c 75 65 73 20 69 6e 0a 2a 2a 20 61  e values in.** a
d7e0: 4c 69 73 74 5b 5d 20 61 72 65 20 74 6f 20 62 65  List[] are to be
d7f0: 20 73 6f 72 74 65 64 20 73 6f 20 74 68 61 74 20   sorted so that 
d800: 66 6f 72 20 61 6c 6c 20 4a 3c 4b 3a 0a 2a 2a 0a  for all J<K:.**.
d810: 2a 2a 20 20 20 20 20 20 61 43 6f 6e 74 65 6e 74  **      aContent
d820: 5b 61 4c 69 73 74 5b 4a 5d 5d 20 3c 20 61 43 6f  [aList[J]] < aCo
d830: 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 4b 5d 5d 0a  ntent[aList[K]].
d840: 2a 2a 0a 2a 2a 20 46 6f 72 20 61 6e 79 20 58 20  **.** For any X 
d850: 61 6e 64 20 59 20 73 75 63 68 20 74 68 61 74 0a  and Y such that.
d860: 2a 2a 0a 2a 2a 20 20 20 20 20 20 61 43 6f 6e 74  **.**      aCont
d870: 65 6e 74 5b 61 4c 69 73 74 5b 58 5d 5d 20 3d 3d  ent[aList[X]] ==
d880: 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b   aContent[aList[
d890: 59 5d 5d 0a 2a 2a 0a 2a 2a 20 4b 65 65 70 20 74  Y]].**.** Keep t
d8a0: 68 65 20 6c 61 72 67 65 72 20 6f 66 20 74 68 65  he larger of the
d8b0: 20 74 77 6f 20 76 61 6c 75 65 73 20 61 4c 69 73   two values aLis
d8c0: 74 5b 58 5d 20 61 6e 64 20 61 4c 69 73 74 5b 59  t[X] and aList[Y
d8d0: 5d 20 61 6e 64 20 64 69 73 63 61 72 64 0a 2a 2a  ] and discard.**
d8e0: 20 74 68 65 20 73 6d 61 6c 6c 65 72 2e 0a 2a 2f   the smaller..*/
d8f0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
d900: 4d 65 72 67 65 73 6f 72 74 28 0a 20 20 63 6f 6e  Mergesort(.  con
d910: 73 74 20 75 33 32 20 2a 61 43 6f 6e 74 65 6e 74  st u32 *aContent
d920: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
d930: 50 61 67 65 73 20 69 6e 20 77 61 6c 20 2a 2f 0a  Pages in wal */.
d940: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 42 75 66 66    ht_slot *aBuff
d950: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
d960: 20 20 2f 2a 20 42 75 66 66 65 72 20 6f 66 20 61    /* Buffer of a
d970: 74 20 6c 65 61 73 74 20 2a 70 6e 4c 69 73 74 20  t least *pnList 
d980: 69 74 65 6d 73 20 74 6f 20 75 73 65 20 2a 2f 0a  items to use */.
d990: 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 69 73 74    ht_slot *aList
d9a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
d9b0: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4c 69 73    /* IN/OUT: Lis
d9c0: 74 20 74 6f 20 73 6f 72 74 20 2a 2f 0a 20 20 69  t to sort */.  i
d9d0: 6e 74 20 2a 70 6e 4c 69 73 74 20 20 20 20 20 20  nt *pnList      
d9e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
d9f0: 2a 20 49 4e 2f 4f 55 54 3a 20 4e 75 6d 62 65 72  * IN/OUT: Number
da00: 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20   of elements in 
da10: 61 4c 69 73 74 5b 5d 20 2a 2f 0a 29 7b 0a 20 20  aList[] */.){.  
da20: 73 74 72 75 63 74 20 53 75 62 6c 69 73 74 20 7b  struct Sublist {
da30: 0a 20 20 20 20 69 6e 74 20 6e 4c 69 73 74 3b 20  .    int nList; 
da40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
da50: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
da60: 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 4c 69 73  elements in aLis
da70: 74 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74  t */.    ht_slot
da80: 20 2a 61 4c 69 73 74 3b 20 20 20 20 20 20 20 20   *aList;        
da90: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
daa0: 72 20 74 6f 20 73 75 62 2d 6c 69 73 74 20 63 6f  r to sub-list co
dab0: 6e 74 65 6e 74 20 2a 2f 0a 20 20 7d 3b 0a 0a 20  ntent */.  };.. 
dac0: 20 63 6f 6e 73 74 20 69 6e 74 20 6e 4c 69 73 74   const int nList
dad0: 20 3d 20 2a 70 6e 4c 69 73 74 3b 20 20 20 20 20   = *pnList;     
dae0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 69 6e 70 75   /* Size of inpu
daf0: 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20  t list */.  int 
db00: 6e 4d 65 72 67 65 20 3d 20 30 3b 20 20 20 20 20  nMerge = 0;     
db10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
db20: 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74  umber of element
db30: 73 20 69 6e 20 6c 69 73 74 20 61 4d 65 72 67 65  s in list aMerge
db40: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61   */.  ht_slot *a
db50: 4d 65 72 67 65 20 3d 20 30 3b 20 20 20 20 20 20  Merge = 0;      
db60: 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 74 6f        /* List to
db70: 20 62 65 20 6d 65 72 67 65 64 20 2a 2f 0a 20 20   be merged */.  
db80: 69 6e 74 20 69 4c 69 73 74 3b 20 20 20 20 20 20  int iList;      
db90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
dba0: 2f 2a 20 49 6e 64 65 78 20 69 6e 74 6f 20 69 6e  /* Index into in
dbb0: 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e  put list */.  in
dbc0: 74 20 69 53 75 62 20 3d 20 30 3b 20 20 20 20 20  t iSub = 0;     
dbd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
dbe0: 20 49 6e 64 65 78 20 69 6e 74 6f 20 61 53 75 62   Index into aSub
dbf0: 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 74 72 75   array */.  stru
dc00: 63 74 20 53 75 62 6c 69 73 74 20 61 53 75 62 5b  ct Sublist aSub[
dc10: 31 33 5d 3b 20 20 20 20 20 20 20 20 2f 2a 20 41  13];        /* A
dc20: 72 72 61 79 20 6f 66 20 73 75 62 2d 6c 69 73 74  rray of sub-list
dc30: 73 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65 74 28 61  s */..  memset(a
dc40: 53 75 62 2c 20 30 2c 20 73 69 7a 65 6f 66 28 61  Sub, 0, sizeof(a
dc50: 53 75 62 29 29 3b 0a 20 20 61 73 73 65 72 74 28  Sub));.  assert(
dc60: 20 6e 4c 69 73 74 3c 3d 48 41 53 48 54 41 42 4c   nList<=HASHTABL
dc70: 45 5f 4e 50 41 47 45 20 26 26 20 6e 4c 69 73 74  E_NPAGE && nList
dc80: 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  >0 );.  assert( 
dc90: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3d  HASHTABLE_NPAGE=
dca0: 3d 28 31 3c 3c 28 41 72 72 61 79 53 69 7a 65 28  =(1<<(ArraySize(
dcb0: 61 53 75 62 29 2d 31 29 29 20 29 3b 0a 0a 20 20  aSub)-1)) );..  
dcc0: 66 6f 72 28 69 4c 69 73 74 3d 30 3b 20 69 4c 69  for(iList=0; iLi
dcd0: 73 74 3c 6e 4c 69 73 74 3b 20 69 4c 69 73 74 2b  st<nList; iList+
dce0: 2b 29 7b 0a 20 20 20 20 6e 4d 65 72 67 65 20 3d  +){.    nMerge =
dcf0: 20 31 3b 0a 20 20 20 20 61 4d 65 72 67 65 20 3d   1;.    aMerge =
dd00: 20 26 61 4c 69 73 74 5b 69 4c 69 73 74 5d 3b 0a   &aList[iList];.
dd10: 20 20 20 20 66 6f 72 28 69 53 75 62 3d 30 3b 20      for(iSub=0; 
dd20: 69 4c 69 73 74 20 26 20 28 31 3c 3c 69 53 75 62  iList & (1<<iSub
dd30: 29 3b 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20  ); iSub++){.    
dd40: 20 20 73 74 72 75 63 74 20 53 75 62 6c 69 73 74    struct Sublist
dd50: 20 2a 70 20 3d 20 26 61 53 75 62 5b 69 53 75 62   *p = &aSub[iSub
dd60: 5d 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  ];.      assert(
dd70: 20 70 2d 3e 61 4c 69 73 74 20 26 26 20 70 2d 3e   p->aList && p->
dd80: 6e 4c 69 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29  nList<=(1<<iSub)
dd90: 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74   );.      assert
dda0: 28 20 70 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69  ( p->aList==&aLi
ddb0: 73 74 5b 69 4c 69 73 74 26 7e 28 28 32 3c 3c 69  st[iList&~((2<<i
ddc0: 53 75 62 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20  Sub)-1)] );.    
ddd0: 20 20 77 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74    walMerge(aCont
dde0: 65 6e 74 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70  ent, p->aList, p
ddf0: 2d 3e 6e 4c 69 73 74 2c 20 26 61 4d 65 72 67 65  ->nList, &aMerge
de00: 2c 20 26 6e 4d 65 72 67 65 2c 20 61 42 75 66 66  , &nMerge, aBuff
de10: 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  er);.    }.    a
de20: 53 75 62 5b 69 53 75 62 5d 2e 61 4c 69 73 74 20  Sub[iSub].aList 
de30: 3d 20 61 4d 65 72 67 65 3b 0a 20 20 20 20 61 53  = aMerge;.    aS
de40: 75 62 5b 69 53 75 62 5d 2e 6e 4c 69 73 74 20 3d  ub[iSub].nList =
de50: 20 6e 4d 65 72 67 65 3b 0a 20 20 7d 0a 0a 20 20   nMerge;.  }..  
de60: 66 6f 72 28 69 53 75 62 2b 2b 3b 20 69 53 75 62  for(iSub++; iSub
de70: 3c 41 72 72 61 79 53 69 7a 65 28 61 53 75 62 29  <ArraySize(aSub)
de80: 3b 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20 20 69  ; iSub++){.    i
de90: 66 28 20 6e 4c 69 73 74 20 26 20 28 31 3c 3c 69  f( nList & (1<<i
dea0: 53 75 62 29 20 29 7b 0a 20 20 20 20 20 20 73 74  Sub) ){.      st
deb0: 72 75 63 74 20 53 75 62 6c 69 73 74 20 2a 70 20  ruct Sublist *p 
dec0: 3d 20 26 61 53 75 62 5b 69 53 75 62 5d 3b 0a 20  = &aSub[iSub];. 
ded0: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 2d 3e       assert( p->
dee0: 6e 4c 69 73 74 3c 3d 28 31 3c 3c 69 53 75 62 29  nList<=(1<<iSub)
def0: 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72 74   );.      assert
df00: 28 20 70 2d 3e 61 4c 69 73 74 3d 3d 26 61 4c 69  ( p->aList==&aLi
df10: 73 74 5b 6e 4c 69 73 74 26 7e 28 28 32 3c 3c 69  st[nList&~((2<<i
df20: 53 75 62 29 2d 31 29 5d 20 29 3b 0a 20 20 20 20  Sub)-1)] );.    
df30: 20 20 77 61 6c 4d 65 72 67 65 28 61 43 6f 6e 74    walMerge(aCont
df40: 65 6e 74 2c 20 70 2d 3e 61 4c 69 73 74 2c 20 70  ent, p->aList, p
df50: 2d 3e 6e 4c 69 73 74 2c 20 26 61 4d 65 72 67 65  ->nList, &aMerge
df60: 2c 20 26 6e 4d 65 72 67 65 2c 20 61 42 75 66 66  , &nMerge, aBuff
df70: 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  er);.    }.  }. 
df80: 20 61 73 73 65 72 74 28 20 61 4d 65 72 67 65 3d   assert( aMerge=
df90: 3d 61 4c 69 73 74 20 29 3b 0a 20 20 2a 70 6e 4c  =aList );.  *pnL
dfa0: 69 73 74 20 3d 20 6e 4d 65 72 67 65 3b 0a 0a 23  ist = nMerge;..#
dfb0: 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44 45 42  ifdef SQLITE_DEB
dfc0: 55 47 0a 20 20 7b 0a 20 20 20 20 69 6e 74 20 69  UG.  {.    int i
dfd0: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69  ;.    for(i=1; i
dfe0: 3c 2a 70 6e 4c 69 73 74 3b 20 69 2b 2b 29 7b 0a  <*pnList; i++){.
dff0: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 61 43        assert( aC
e000: 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 69 5d 5d  ontent[aList[i]]
e010: 20 3e 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73   > aContent[aLis
e020: 74 5b 69 2d 31 5d 5d 20 29 3b 0a 20 20 20 20 7d  t[i-1]] );.    }
e030: 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f  .  }.#endif.}../
e040: 2a 20 0a 2a 2a 20 46 72 65 65 20 61 6e 20 69 74  * .** Free an it
e050: 65 72 61 74 6f 72 20 61 6c 6c 6f 63 61 74 65 64  erator allocated
e060: 20 62 79 20 77 61 6c 49 74 65 72 61 74 6f 72 49   by walIteratorI
e070: 6e 69 74 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  nit()..*/.static
e080: 20 76 6f 69 64 20 77 61 6c 49 74 65 72 61 74 6f   void walIterato
e090: 72 46 72 65 65 28 57 61 6c 49 74 65 72 61 74 6f  rFree(WalIterato
e0a0: 72 20 2a 70 29 7b 0a 20 20 73 71 6c 69 74 65 33  r *p){.  sqlite3
e0b0: 53 63 72 61 74 63 68 46 72 65 65 28 70 29 3b 0a  ScratchFree(p);.
e0c0: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 72 75  }../*.** Constru
e0d0: 63 74 20 61 20 57 61 6c 49 6e 74 65 72 61 74 6f  ct a WalInterato
e0e0: 72 20 6f 62 6a 65 63 74 20 74 68 61 74 20 63 61  r object that ca
e0f0: 6e 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f  n be used to loo
e100: 70 20 6f 76 65 72 20 61 6c 6c 20 0a 2a 2a 20 70  p over all .** p
e110: 61 67 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20  ages in the WAL 
e120: 69 6e 20 61 73 63 65 6e 64 69 6e 67 20 6f 72 64  in ascending ord
e130: 65 72 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 6d  er. The caller m
e140: 75 73 74 20 68 6f 6c 64 20 74 68 65 20 63 68 65  ust hold the che
e150: 63 6b 70 6f 69 6e 74 0a 2a 2a 20 6c 6f 63 6b 2e  ckpoint.** lock.
e160: 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63 65 73  .**.** On succes
e170: 73 2c 20 6d 61 6b 65 20 2a 70 70 20 70 6f 69 6e  s, make *pp poin
e180: 74 20 74 6f 20 74 68 65 20 6e 65 77 6c 79 20 61  t to the newly a
e190: 6c 6c 6f 63 61 74 65 64 20 57 61 6c 49 6e 74 65  llocated WalInte
e1a0: 72 61 74 6f 72 20 6f 62 6a 65 63 74 0a 2a 2a 20  rator object.** 
e1b0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
e1c0: 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 72 65 74  . Otherwise, ret
e1d0: 75 72 6e 20 61 6e 20 65 72 72 6f 72 20 63 6f 64  urn an error cod
e1e0: 65 2e 20 49 66 20 74 68 69 73 20 72 6f 75 74 69  e. If this routi
e1f0: 6e 65 0a 2a 2a 20 72 65 74 75 72 6e 73 20 61 6e  ne.** returns an
e200: 20 65 72 72 6f 72 2c 20 74 68 65 20 76 61 6c 75   error, the valu
e210: 65 20 6f 66 20 2a 70 70 20 69 73 20 75 6e 64 65  e of *pp is unde
e220: 66 69 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  fined..**.** The
e230: 20 63 61 6c 6c 69 6e 67 20 72 6f 75 74 69 6e 65   calling routine
e240: 20 73 68 6f 75 6c 64 20 69 6e 76 6f 6b 65 20 77   should invoke w
e250: 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28 29  alIteratorFree()
e260: 20 74 6f 20 64 65 73 74 72 6f 79 20 74 68 65 0a   to destroy the.
e270: 2a 2a 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f  ** WalIterator o
e280: 62 6a 65 63 74 20 77 68 65 6e 20 69 74 20 68 61  bject when it ha
e290: 73 20 66 69 6e 69 73 68 65 64 20 77 69 74 68 20  s finished with 
e2a0: 69 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  it..*/.static in
e2b0: 74 20 77 61 6c 49 74 65 72 61 74 6f 72 49 6e 69  t walIteratorIni
e2c0: 74 28 57 61 6c 20 2a 70 57 61 6c 2c 20 57 61 6c  t(Wal *pWal, Wal
e2d0: 49 74 65 72 61 74 6f 72 20 2a 2a 70 70 29 7b 0a  Iterator **pp){.
e2e0: 20 20 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 70    WalIterator *p
e2f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
e300: 20 20 2f 2a 20 52 65 74 75 72 6e 20 76 61 6c 75    /* Return valu
e310: 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 65 67 6d  e */.  int nSegm
e320: 65 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ent;            
e330: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
e340: 20 6f 66 20 73 65 67 6d 65 6e 74 73 20 74 6f 20   of segments to 
e350: 6d 65 72 67 65 20 2a 2f 0a 20 20 75 33 32 20 69  merge */.  u32 i
e360: 4c 61 73 74 3b 20 20 20 20 20 20 20 20 20 20 20  Last;           
e370: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
e380: 73 74 20 66 72 61 6d 65 20 69 6e 20 6c 6f 67 20  st frame in log 
e390: 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 20  */.  int nByte; 
e3a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e3b0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
e3c0: 66 20 62 79 74 65 73 20 74 6f 20 61 6c 6c 6f 63  f bytes to alloc
e3d0: 61 74 65 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20  ate */.  int i; 
e3e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e3f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72           /* Iter
e400: 61 74 6f 72 20 76 61 72 69 61 62 6c 65 20 2a 2f  ator variable */
e410: 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 54 6d 70  .  ht_slot *aTmp
e420: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
e430: 20 20 20 2f 2a 20 54 65 6d 70 20 73 70 61 63 65     /* Temp space
e440: 20 75 73 65 64 20 62 79 20 6d 65 72 67 65 2d 73   used by merge-s
e450: 6f 72 74 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20  ort */.  int rc 
e460: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20  = SQLITE_OK;    
e470: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
e480: 72 6e 20 43 6f 64 65 20 2a 2f 0a 0a 20 20 2f 2a  rn Code */..  /*
e490: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 6f 6e   This routine on
e4a0: 6c 79 20 72 75 6e 73 20 77 68 69 6c 65 20 68 6f  ly runs while ho
e4b0: 6c 64 69 6e 67 20 74 68 65 20 63 68 65 63 6b 70  lding the checkp
e4c0: 6f 69 6e 74 20 6c 6f 63 6b 2e 20 41 6e 64 0a 20  oint lock. And. 
e4d0: 20 2a 2a 20 69 74 20 6f 6e 6c 79 20 72 75 6e 73   ** it only runs
e4e0: 20 69 66 20 74 68 65 72 65 20 69 73 20 61 63 74   if there is act
e4f0: 75 61 6c 6c 79 20 63 6f 6e 74 65 6e 74 20 69 6e  ually content in
e500: 20 74 68 65 20 6c 6f 67 20 28 6d 78 46 72 61 6d   the log (mxFram
e510: 65 3e 30 29 2e 0a 20 20 2a 2f 0a 20 20 61 73 73  e>0)..  */.  ass
e520: 65 72 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c  ert( pWal->ckptL
e530: 6f 63 6b 20 26 26 20 70 57 61 6c 2d 3e 68 64 72  ock && pWal->hdr
e540: 2e 6d 78 46 72 61 6d 65 3e 30 20 29 3b 0a 20 20  .mxFrame>0 );.  
e550: 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d 3e 68 64  iLast = pWal->hd
e560: 72 2e 6d 78 46 72 61 6d 65 3b 0a 0a 20 20 2f 2a  r.mxFrame;..  /*
e570: 20 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20   Allocate space 
e580: 66 6f 72 20 74 68 65 20 57 61 6c 49 74 65 72 61  for the WalItera
e590: 74 6f 72 20 6f 62 6a 65 63 74 2e 20 2a 2f 0a 20  tor object. */. 
e5a0: 20 6e 53 65 67 6d 65 6e 74 20 3d 20 77 61 6c 46   nSegment = walF
e5b0: 72 61 6d 65 50 61 67 65 28 69 4c 61 73 74 29 20  ramePage(iLast) 
e5c0: 2b 20 31 3b 0a 20 20 6e 42 79 74 65 20 3d 20 73  + 1;.  nByte = s
e5d0: 69 7a 65 6f 66 28 57 61 6c 49 74 65 72 61 74 6f  izeof(WalIterato
e5e0: 72 29 20 0a 20 20 20 20 20 20 20 20 2b 20 28 6e  r) .        + (n
e5f0: 53 65 67 6d 65 6e 74 2d 31 29 2a 73 69 7a 65 6f  Segment-1)*sizeo
e600: 66 28 73 74 72 75 63 74 20 57 61 6c 53 65 67 6d  f(struct WalSegm
e610: 65 6e 74 29 0a 20 20 20 20 20 20 20 20 2b 20 69  ent).        + i
e620: 4c 61 73 74 2a 73 69 7a 65 6f 66 28 68 74 5f 73  Last*sizeof(ht_s
e630: 6c 6f 74 29 3b 0a 20 20 70 20 3d 20 28 57 61 6c  lot);.  p = (Wal
e640: 49 74 65 72 61 74 6f 72 20 2a 29 73 71 6c 69 74  Iterator *)sqlit
e650: 65 33 53 63 72 61 74 63 68 4d 61 6c 6c 6f 63 28  e3ScratchMalloc(
e660: 6e 42 79 74 65 29 3b 0a 20 20 69 66 28 20 21 70  nByte);.  if( !p
e670: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
e680: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
e690: 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20  .  memset(p, 0, 
e6a0: 6e 42 79 74 65 29 3b 0a 20 20 70 2d 3e 6e 53 65  nByte);.  p->nSe
e6b0: 67 6d 65 6e 74 20 3d 20 6e 53 65 67 6d 65 6e 74  gment = nSegment
e6c0: 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65  ;..  /* Allocate
e6d0: 20 74 65 6d 70 6f 72 61 72 79 20 73 70 61 63 65   temporary space
e6e0: 20 75 73 65 64 20 62 79 20 74 68 65 20 6d 65 72   used by the mer
e6f0: 67 65 2d 73 6f 72 74 20 72 6f 75 74 69 6e 65 2e  ge-sort routine.
e700: 20 54 68 69 73 20 62 6c 6f 63 6b 0a 20 20 2a 2a   This block.  **
e710: 20 6f 66 20 6d 65 6d 6f 72 79 20 77 69 6c 6c 20   of memory will 
e720: 62 65 20 66 72 65 65 64 20 62 65 66 6f 72 65 20  be freed before 
e730: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65  this function re
e740: 74 75 72 6e 73 2e 0a 20 20 2a 2f 0a 20 20 61 54  turns..  */.  aT
e750: 6d 70 20 3d 20 28 68 74 5f 73 6c 6f 74 20 2a 29  mp = (ht_slot *)
e760: 73 71 6c 69 74 65 33 53 63 72 61 74 63 68 4d 61  sqlite3ScratchMa
e770: 6c 6c 6f 63 28 0a 20 20 20 20 20 20 73 69 7a 65  lloc(.      size
e780: 6f 66 28 68 74 5f 73 6c 6f 74 29 20 2a 20 28 69  of(ht_slot) * (i
e790: 4c 61 73 74 3e 48 41 53 48 54 41 42 4c 45 5f 4e  Last>HASHTABLE_N
e7a0: 50 41 47 45 3f 48 41 53 48 54 41 42 4c 45 5f 4e  PAGE?HASHTABLE_N
e7b0: 50 41 47 45 3a 69 4c 61 73 74 29 0a 20 20 29 3b  PAGE:iLast).  );
e7c0: 0a 20 20 69 66 28 20 21 61 54 6d 70 20 29 7b 0a  .  if( !aTmp ){.
e7d0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
e7e0: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 66 6f  NOMEM;.  }..  fo
e7f0: 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54  r(i=0; rc==SQLIT
e800: 45 5f 4f 4b 20 26 26 20 69 3c 6e 53 65 67 6d 65  E_OK && i<nSegme
e810: 6e 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76 6f  nt; i++){.    vo
e820: 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a  latile ht_slot *
e830: 61 48 61 73 68 3b 0a 20 20 20 20 75 33 32 20 69  aHash;.    u32 i
e840: 5a 65 72 6f 3b 0a 20 20 20 20 76 6f 6c 61 74 69  Zero;.    volati
e850: 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 3b 0a 0a  le u32 *aPgno;..
e860: 20 20 20 20 72 63 20 3d 20 77 61 6c 48 61 73 68      rc = walHash
e870: 47 65 74 28 70 57 61 6c 2c 20 69 2c 20 26 61 48  Get(pWal, i, &aH
e880: 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20 26 69 5a  ash, &aPgno, &iZ
e890: 65 72 6f 29 3b 0a 20 20 20 20 69 66 28 20 72 63  ero);.    if( rc
e8a0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
e8b0: 20 20 20 20 20 69 6e 74 20 6a 3b 20 20 20 20 20       int j;     
e8c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e8d0: 20 2f 2a 20 43 6f 75 6e 74 65 72 20 76 61 72 69   /* Counter vari
e8e0: 61 62 6c 65 20 2a 2f 0a 20 20 20 20 20 20 69 6e  able */.      in
e8f0: 74 20 6e 45 6e 74 72 79 3b 20 20 20 20 20 20 20  t nEntry;       
e900: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
e910: 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69  ber of entries i
e920: 6e 20 74 68 69 73 20 73 65 67 6d 65 6e 74 20 2a  n this segment *
e930: 2f 0a 20 20 20 20 20 20 68 74 5f 73 6c 6f 74 20  /.      ht_slot 
e940: 2a 61 49 6e 64 65 78 3b 20 20 20 20 20 20 20 20  *aIndex;        
e950: 20 20 20 20 2f 2a 20 53 6f 72 74 65 64 20 69 6e      /* Sorted in
e960: 64 65 78 20 66 6f 72 20 74 68 69 73 20 73 65 67  dex for this seg
e970: 6d 65 6e 74 20 2a 2f 0a 0a 20 20 20 20 20 20 61  ment */..      a
e980: 50 67 6e 6f 2b 2b 3b 0a 20 20 20 20 20 20 69 66  Pgno++;.      if
e990: 28 20 28 69 2b 31 29 3d 3d 6e 53 65 67 6d 65 6e  ( (i+1)==nSegmen
e9a0: 74 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 45 6e  t ){.        nEn
e9b0: 74 72 79 20 3d 20 28 69 6e 74 29 28 69 4c 61 73  try = (int)(iLas
e9c0: 74 20 2d 20 69 5a 65 72 6f 29 3b 0a 20 20 20 20  t - iZero);.    
e9d0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
e9e0: 20 6e 45 6e 74 72 79 20 3d 20 28 69 6e 74 29 28   nEntry = (int)(
e9f0: 28 75 33 32 2a 29 61 48 61 73 68 20 2d 20 28 75  (u32*)aHash - (u
ea00: 33 32 2a 29 61 50 67 6e 6f 29 3b 0a 20 20 20 20  32*)aPgno);.    
ea10: 20 20 7d 0a 20 20 20 20 20 20 61 49 6e 64 65 78    }.      aIndex
ea20: 20 3d 20 26 28 28 68 74 5f 73 6c 6f 74 20 2a 29   = &((ht_slot *)
ea30: 26 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 70 2d 3e  &p->aSegment[p->
ea40: 6e 53 65 67 6d 65 6e 74 5d 29 5b 69 5a 65 72 6f  nSegment])[iZero
ea50: 5d 3b 0a 20 20 20 20 20 20 69 5a 65 72 6f 2b 2b  ];.      iZero++
ea60: 3b 0a 20 20 0a 20 20 20 20 20 20 66 6f 72 28 6a  ;.  .      for(j
ea70: 3d 30 3b 20 6a 3c 6e 45 6e 74 72 79 3b 20 6a 2b  =0; j<nEntry; j+
ea80: 2b 29 7b 0a 20 20 20 20 20 20 20 20 61 49 6e 64  +){.        aInd
ea90: 65 78 5b 6a 5d 20 3d 20 28 68 74 5f 73 6c 6f 74  ex[j] = (ht_slot
eaa0: 29 6a 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  )j;.      }.    
eab0: 20 20 77 61 6c 4d 65 72 67 65 73 6f 72 74 28 28    walMergesort((
eac0: 75 33 32 20 2a 29 61 50 67 6e 6f 2c 20 61 54 6d  u32 *)aPgno, aTm
ead0: 70 2c 20 61 49 6e 64 65 78 2c 20 26 6e 45 6e 74  p, aIndex, &nEnt
eae0: 72 79 29 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53  ry);.      p->aS
eaf0: 65 67 6d 65 6e 74 5b 69 5d 2e 69 5a 65 72 6f 20  egment[i].iZero 
eb00: 3d 20 69 5a 65 72 6f 3b 0a 20 20 20 20 20 20 70  = iZero;.      p
eb10: 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 6e 45  ->aSegment[i].nE
eb20: 6e 74 72 79 20 3d 20 6e 45 6e 74 72 79 3b 0a 20  ntry = nEntry;. 
eb30: 20 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74       p->aSegment
eb40: 5b 69 5d 2e 61 49 6e 64 65 78 20 3d 20 61 49 6e  [i].aIndex = aIn
eb50: 64 65 78 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53  dex;.      p->aS
eb60: 65 67 6d 65 6e 74 5b 69 5d 2e 61 50 67 6e 6f 20  egment[i].aPgno 
eb70: 3d 20 28 75 33 32 20 2a 29 61 50 67 6e 6f 3b 0a  = (u32 *)aPgno;.
eb80: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69      }.  }.  sqli
eb90: 74 65 33 53 63 72 61 74 63 68 46 72 65 65 28 61  te3ScratchFree(a
eba0: 54 6d 70 29 3b 0a 0a 20 20 69 66 28 20 72 63 21  Tmp);..  if( rc!
ebb0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
ebc0: 20 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72 65    walIteratorFre
ebd0: 65 28 70 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 20  e(p);.  }.  *pp 
ebe0: 3d 20 70 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  = p;.  return rc
ebf0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d  ;.}../*.** Attem
ec00: 70 74 20 74 6f 20 6f 62 74 61 69 6e 20 74 68 65  pt to obtain the
ec10: 20 65 78 63 6c 75 73 69 76 65 20 57 41 4c 20 6c   exclusive WAL l
ec20: 6f 63 6b 20 64 65 66 69 6e 65 64 20 62 79 20 70  ock defined by p
ec30: 61 72 61 6d 65 74 65 72 73 20 6c 6f 63 6b 49 64  arameters lockId
ec40: 78 20 61 6e 64 0a 2a 2a 20 6e 2e 20 49 66 20 74  x and.** n. If t
ec50: 68 65 20 61 74 74 65 6d 70 74 20 66 61 69 6c 73  he attempt fails
ec60: 20 61 6e 64 20 70 61 72 61 6d 65 74 65 72 20 78   and parameter x
ec70: 42 75 73 79 20 69 73 20 6e 6f 74 20 4e 55 4c 4c  Busy is not NULL
ec80: 2c 20 74 68 65 6e 20 69 74 20 69 73 20 61 0a 2a  , then it is a.*
ec90: 2a 20 62 75 73 79 2d 68 61 6e 64 6c 65 72 20 66  * busy-handler f
eca0: 75 6e 63 74 69 6f 6e 2e 20 49 6e 76 6f 6b 65 20  unction. Invoke 
ecb0: 69 74 20 61 6e 64 20 72 65 74 72 79 20 74 68 65  it and retry the
ecc0: 20 6c 6f 63 6b 20 75 6e 74 69 6c 20 65 69 74 68   lock until eith
ecd0: 65 72 20 74 68 65 0a 2a 2a 20 6c 6f 63 6b 20 69  er the.** lock i
ece0: 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20 6f  s successfully o
ecf0: 62 74 61 69 6e 65 64 20 6f 72 20 74 68 65 20 62  btained or the b
ed00: 75 73 79 2d 68 61 6e 64 6c 65 72 20 72 65 74 75  usy-handler retu
ed10: 72 6e 73 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63  rns 0..*/.static
ed20: 20 69 6e 74 20 77 61 6c 42 75 73 79 4c 6f 63 6b   int walBusyLock
ed30: 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20  (.  Wal *pWal,  
ed40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ed50: 20 20 20 20 2f 2a 20 57 41 4c 20 63 6f 6e 6e 65      /* WAL conne
ed60: 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 28  ction */.  int (
ed70: 2a 78 42 75 73 79 29 28 76 6f 69 64 2a 29 2c 20  *xBusy)(void*), 
ed80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 75             /* Fu
ed90: 6e 63 74 69 6f 6e 20 74 6f 20 63 61 6c 6c 20 77  nction to call w
eda0: 68 65 6e 20 62 75 73 79 20 2a 2f 0a 20 20 76 6f  hen busy */.  vo
edb0: 69 64 20 2a 70 42 75 73 79 41 72 67 2c 20 20 20  id *pBusyArg,   
edc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
edd0: 20 43 6f 6e 74 65 78 74 20 61 72 67 75 6d 65 6e   Context argumen
ede0: 74 20 66 6f 72 20 78 42 75 73 79 48 61 6e 64 6c  t for xBusyHandl
edf0: 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6c 6f 63 6b  er */.  int lock
ee00: 49 64 78 2c 20 20 20 20 20 20 20 20 20 20 20 20  Idx,            
ee10: 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65          /* Offse
ee20: 74 20 6f 66 20 66 69 72 73 74 20 62 79 74 65 20  t of first byte 
ee30: 74 6f 20 6c 6f 63 6b 20 2a 2f 0a 20 20 69 6e 74  to lock */.  int
ee40: 20 6e 20 20 20 20 20 20 20 20 20 20 20 20 20 20   n              
ee50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
ee60: 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  Number of bytes 
ee70: 74 6f 20 6c 6f 63 6b 20 2a 2f 0a 29 7b 0a 20 20  to lock */.){.  
ee80: 69 6e 74 20 72 63 3b 0a 20 20 64 6f 20 7b 0a 20  int rc;.  do {. 
ee90: 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45     rc = walLockE
eea0: 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 6c  xclusive(pWal, l
eeb0: 6f 63 6b 49 64 78 2c 20 6e 29 3b 0a 20 20 7d 77  ockIdx, n);.  }w
eec0: 68 69 6c 65 28 20 78 42 75 73 79 20 26 26 20 72  hile( xBusy && r
eed0: 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 26  c==SQLITE_BUSY &
eee0: 26 20 78 42 75 73 79 28 70 42 75 73 79 41 72 67  & xBusy(pBusyArg
eef0: 29 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  ) );.  return rc
ef00: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 63  ;.}../*.** The c
ef10: 61 63 68 65 20 6f 66 20 74 68 65 20 77 61 6c 2d  ache of the wal-
ef20: 69 6e 64 65 78 20 68 65 61 64 65 72 20 6d 75 73  index header mus
ef30: 74 20 62 65 20 76 61 6c 69 64 20 74 6f 20 63 61  t be valid to ca
ef40: 6c 6c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  ll this function
ef50: 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  ..** Return the 
ef60: 70 61 67 65 2d 73 69 7a 65 20 69 6e 20 62 79 74  page-size in byt
ef70: 65 73 20 75 73 65 64 20 62 79 20 74 68 65 20 64  es used by the d
ef80: 61 74 61 62 61 73 65 2e 0a 2a 2f 0a 73 74 61 74  atabase..*/.stat
ef90: 69 63 20 69 6e 74 20 77 61 6c 50 61 67 65 73 69  ic int walPagesi
efa0: 7a 65 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20  ze(Wal *pWal){. 
efb0: 20 72 65 74 75 72 6e 20 28 70 57 61 6c 2d 3e 68   return (pWal->h
efc0: 64 72 2e 73 7a 50 61 67 65 26 30 78 66 65 30 30  dr.szPage&0xfe00
efd0: 29 20 2b 20 28 28 70 57 61 6c 2d 3e 68 64 72 2e  ) + ((pWal->hdr.
efe0: 73 7a 50 61 67 65 26 30 78 30 30 30 31 29 3c 3c  szPage&0x0001)<<
eff0: 31 36 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f  16);.}../*.** Co
f000: 70 79 20 61 73 20 6d 75 63 68 20 63 6f 6e 74 65  py as much conte
f010: 6e 74 20 61 73 20 77 65 20 63 61 6e 20 66 72 6f  nt as we can fro
f020: 6d 20 74 68 65 20 57 41 4c 20 62 61 63 6b 20 69  m the WAL back i
f030: 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65  nto the database
f040: 20 66 69 6c 65 0a 2a 2a 20 69 6e 20 72 65 73 70   file.** in resp
f050: 6f 6e 73 65 20 74 6f 20 61 6e 20 73 71 6c 69 74  onse to an sqlit
f060: 65 33 5f 77 61 6c 5f 63 68 65 63 6b 70 6f 69 6e  e3_wal_checkpoin
f070: 74 28 29 20 72 65 71 75 65 73 74 20 6f 72 20 74  t() request or t
f080: 68 65 20 65 71 75 69 76 61 6c 65 6e 74 2e 0a 2a  he equivalent..*
f090: 2a 0a 2a 2a 20 54 68 65 20 61 6d 6f 75 6e 74 20  *.** The amount 
f0a0: 6f 66 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 63  of information c
f0b0: 6f 70 69 65 73 20 66 72 6f 6d 20 57 41 4c 20 74  opies from WAL t
f0c0: 6f 20 64 61 74 61 62 61 73 65 20 6d 69 67 68 74  o database might
f0d0: 20 62 65 20 6c 69 6d 69 74 65 64 0a 2a 2a 20 62   be limited.** b
f0e0: 79 20 61 63 74 69 76 65 20 72 65 61 64 65 72 73  y active readers
f0f0: 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  .  This routine 
f100: 77 69 6c 6c 20 6e 65 76 65 72 20 6f 76 65 72 77  will never overw
f110: 72 69 74 65 20 61 20 64 61 74 61 62 61 73 65 20  rite a database 
f120: 70 61 67 65 0a 2a 2a 20 74 68 61 74 20 61 20 63  page.** that a c
f130: 6f 6e 63 75 72 72 65 6e 74 20 72 65 61 64 65 72  oncurrent reader
f140: 20 6d 69 67 68 74 20 62 65 20 75 73 69 6e 67 2e   might be using.
f150: 0a 2a 2a 0a 2a 2a 20 41 6c 6c 20 49 2f 4f 20 62  .**.** All I/O b
f160: 61 72 72 69 65 72 20 6f 70 65 72 61 74 69 6f 6e  arrier operation
f170: 73 20 28 61 2e 6b 2e 61 20 66 73 79 6e 63 73 29  s (a.k.a fsyncs)
f180: 20 6f 63 63 75 72 20 69 6e 20 74 68 69 73 20 72   occur in this r
f190: 6f 75 74 69 6e 65 20 77 68 65 6e 0a 2a 2a 20 53  outine when.** S
f1a0: 51 4c 69 74 65 20 69 73 20 69 6e 20 57 41 4c 2d  QLite is in WAL-
f1b0: 6d 6f 64 65 20 69 6e 20 73 79 6e 63 68 72 6f 6e  mode in synchron
f1c0: 6f 75 73 3d 4e 4f 52 4d 41 4c 2e 20 20 54 68 61  ous=NORMAL.  Tha
f1d0: 74 20 6d 65 61 6e 73 20 74 68 61 74 20 69 66 20  t means that if 
f1e0: 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 73 20  .** checkpoints 
f1f0: 61 72 65 20 61 6c 77 61 79 73 20 72 75 6e 20 62  are always run b
f200: 79 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  y a background t
f210: 68 72 65 61 64 20 6f 72 20 62 61 63 6b 67 72 6f  hread or backgro
f220: 75 6e 64 20 0a 2a 2a 20 70 72 6f 63 65 73 73 2c  und .** process,
f230: 20 66 6f 72 65 67 72 6f 75 6e 64 20 74 68 72 65   foreground thre
f240: 61 64 73 20 77 69 6c 6c 20 6e 65 76 65 72 20 62  ads will never b
f250: 6c 6f 63 6b 20 6f 6e 20 61 20 6c 65 6e 67 74 68  lock on a length
f260: 79 20 66 73 79 6e 63 20 63 61 6c 6c 2e 0a 2a 2a  y fsync call..**
f270: 0a 2a 2a 20 46 73 79 6e 63 20 69 73 20 63 61 6c  .** Fsync is cal
f280: 6c 65 64 20 6f 6e 20 74 68 65 20 57 41 4c 20 62  led on the WAL b
f290: 65 66 6f 72 65 20 77 72 69 74 69 6e 67 20 63 6f  efore writing co
f2a0: 6e 74 65 6e 74 20 6f 75 74 20 6f 66 20 74 68 65  ntent out of the
f2b0: 20 57 41 4c 20 61 6e 64 0a 2a 2a 20 69 6e 74 6f   WAL and.** into
f2c0: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 20   the database.  
f2d0: 54 68 69 73 20 65 6e 73 75 72 65 73 20 74 68 61  This ensures tha
f2e0: 74 20 69 66 20 74 68 65 20 6e 65 77 20 63 6f 6e  t if the new con
f2f0: 74 65 6e 74 20 69 73 20 70 65 72 73 69 73 74 65  tent is persiste
f300: 6e 74 0a 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c  nt.** in the WAL
f310: 20 61 6e 64 20 63 61 6e 20 62 65 20 72 65 63 6f   and can be reco
f320: 76 65 72 65 64 20 66 6f 6c 6c 6f 77 69 6e 67 20  vered following 
f330: 61 20 70 6f 77 65 72 2d 6c 6f 73 73 20 6f 72 20  a power-loss or 
f340: 68 61 72 64 20 72 65 73 65 74 2e 0a 2a 2a 0a 2a  hard reset..**.*
f350: 2a 20 46 73 79 6e 63 20 69 73 20 61 6c 73 6f 20  * Fsync is also 
f360: 63 61 6c 6c 65 64 20 6f 6e 20 74 68 65 20 64 61  called on the da
f370: 74 61 62 61 73 65 20 66 69 6c 65 20 69 66 20 28  tabase file if (
f380: 61 6e 64 20 6f 6e 6c 79 20 69 66 29 20 74 68 65  and only if) the
f390: 20 65 6e 74 69 72 65 0a 2a 2a 20 57 41 4c 20 63   entire.** WAL c
f3a0: 6f 6e 74 65 6e 74 20 69 73 20 63 6f 70 69 65 64  ontent is copied
f3b0: 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
f3c0: 73 65 20 66 69 6c 65 2e 20 20 54 68 69 73 20 73  se file.  This s
f3d0: 65 63 6f 6e 64 20 66 73 79 6e 63 20 6d 61 6b 65  econd fsync make
f3e0: 73 0a 2a 2a 20 69 74 20 73 61 66 65 20 74 6f 20  s.** it safe to 
f3f0: 64 65 6c 65 74 65 20 74 68 65 20 57 41 4c 20 73  delete the WAL s
f400: 69 6e 63 65 20 74 68 65 20 6e 65 77 20 63 6f 6e  ince the new con
f410: 74 65 6e 74 20 77 69 6c 6c 20 70 65 72 73 69 73  tent will persis
f420: 74 20 69 6e 20 74 68 65 0a 2a 2a 20 64 61 74 61  t in the.** data
f430: 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a  base file..**.**
f440: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 75 73   This routine us
f450: 65 73 20 61 6e 64 20 75 70 64 61 74 65 73 20 74  es and updates t
f460: 68 65 20 6e 42 61 63 6b 66 69 6c 6c 20 66 69 65  he nBackfill fie
f470: 6c 64 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ld of the wal-in
f480: 64 65 78 20 68 65 61 64 65 72 2e 0a 2a 2a 20 54  dex header..** T
f490: 68 69 73 20 69 73 20 74 68 65 20 6f 6e 6c 79 20  his is the only 
f4a0: 72 6f 75 74 69 6e 65 20 74 68 61 20 77 69 6c 6c  routine tha will
f4b0: 20 69 6e 63 72 65 61 73 65 20 74 68 65 20 76 61   increase the va
f4c0: 6c 75 65 20 6f 66 20 6e 42 61 63 6b 66 69 6c 6c  lue of nBackfill
f4d0: 2e 20 20 0a 2a 2a 20 28 41 20 57 41 4c 20 72 65  .  .** (A WAL re
f4e0: 73 65 74 20 6f 72 20 72 65 63 6f 76 65 72 79 20  set or recovery 
f4f0: 77 69 6c 6c 20 72 65 76 65 72 74 20 6e 42 61 63  will revert nBac
f500: 6b 66 69 6c 6c 20 74 6f 20 7a 65 72 6f 2c 20 62  kfill to zero, b
f510: 75 74 20 6e 6f 74 20 69 6e 63 72 65 61 73 65 0a  ut not increase.
f520: 2a 2a 20 69 74 73 20 76 61 6c 75 65 2e 29 0a 2a  ** its value.).*
f530: 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 65 72 20  *.** The caller 
f540: 6d 75 73 74 20 62 65 20 68 6f 6c 64 69 6e 67 20  must be holding 
f550: 73 75 66 66 69 63 69 65 6e 74 20 6c 6f 63 6b 73  sufficient locks
f560: 20 74 6f 20 65 6e 73 75 72 65 20 74 68 61 74 20   to ensure that 
f570: 6e 6f 20 6f 74 68 65 72 0a 2a 2a 20 63 68 65 63  no other.** chec
f580: 6b 70 6f 69 6e 74 20 69 73 20 72 75 6e 6e 69 6e  kpoint is runnin
f590: 67 20 28 69 6e 20 61 6e 79 20 6f 74 68 65 72 20  g (in any other 
f5a0: 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73  thread or proces
f5b0: 73 29 20 61 74 20 74 68 65 20 73 61 6d 65 0a 2a  s) at the same.*
f5c0: 2a 20 74 69 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69  * time..*/.stati
f5d0: 63 20 69 6e 74 20 77 61 6c 43 68 65 63 6b 70 6f  c int walCheckpo
f5e0: 69 6e 74 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c  int(.  Wal *pWal
f5f0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
f600: 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 63 6f         /* Wal co
f610: 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e  nnection */.  in
f620: 74 20 65 4d 6f 64 65 2c 20 20 20 20 20 20 20 20  t eMode,        
f630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
f640: 20 4f 6e 65 20 6f 66 20 50 41 53 53 49 56 45 2c   One of PASSIVE,
f650: 20 46 55 4c 4c 20 6f 72 20 52 45 53 54 41 52 54   FULL or RESTART
f660: 20 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 42 75 73   */.  int (*xBus
f670: 79 43 61 6c 6c 29 28 76 6f 69 64 2a 29 2c 20 20  yCall)(void*),  
f680: 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f        /* Functio
f690: 6e 20 74 6f 20 63 61 6c 6c 20 77 68 65 6e 20 62  n to call when b
f6a0: 75 73 79 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70  usy */.  void *p
f6b0: 42 75 73 79 41 72 67 2c 20 20 20 20 20 20 20 20  BusyArg,        
f6c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74           /* Cont
f6d0: 65 78 74 20 61 72 67 75 6d 65 6e 74 20 66 6f 72  ext argument for
f6e0: 20 78 42 75 73 79 48 61 6e 64 6c 65 72 20 2a 2f   xBusyHandler */
f6f0: 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67  .  int sync_flag
f700: 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s,              
f710: 20 20 20 2f 2a 20 46 6c 61 67 73 20 66 6f 72 20     /* Flags for 
f720: 4f 73 53 79 6e 63 28 29 20 28 6f 72 20 30 29 20  OsSync() (or 0) 
f730: 2a 2f 0a 20 20 75 38 20 2a 7a 42 75 66 20 20 20  */.  u8 *zBuf   
f740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f750: 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72       /* Temporar
f760: 79 20 62 75 66 66 65 72 20 74 6f 20 75 73 65 20  y buffer to use 
f770: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  */.){.  int rc; 
f780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f790: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
f7a0: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
f7b0: 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20 20  szPage;         
f7c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
f7d0: 61 74 61 62 61 73 65 20 70 61 67 65 2d 73 69 7a  atabase page-siz
f7e0: 65 20 2a 2f 0a 20 20 57 61 6c 49 74 65 72 61 74  e */.  WalIterat
f7f0: 6f 72 20 2a 70 49 74 65 72 20 3d 20 30 3b 20 20  or *pIter = 0;  
f800: 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 69 74         /* Wal it
f810: 65 72 61 74 6f 72 20 63 6f 6e 74 65 78 74 20 2a  erator context *
f820: 2f 0a 20 20 75 33 32 20 69 44 62 70 61 67 65 20  /.  u32 iDbpage 
f830: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
f840: 20 20 20 20 2f 2a 20 4e 65 78 74 20 64 61 74 61      /* Next data
f850: 62 61 73 65 20 70 61 67 65 20 74 6f 20 77 72 69  base page to wri
f860: 74 65 20 2a 2f 0a 20 20 75 33 32 20 69 46 72 61  te */.  u32 iFra
f870: 6d 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  me = 0;         
f880: 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 66          /* Wal f
f890: 72 61 6d 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20  rame containing 
f8a0: 64 61 74 61 20 66 6f 72 20 69 44 62 70 61 67 65  data for iDbpage
f8b0: 20 2a 2f 0a 20 20 75 33 32 20 6d 78 53 61 66 65   */.  u32 mxSafe
f8c0: 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  Frame;          
f8d0: 20 20 20 20 20 20 2f 2a 20 4d 61 78 20 66 72 61        /* Max fra
f8e0: 6d 65 20 74 68 61 74 20 63 61 6e 20 62 65 20 62  me that can be b
f8f0: 61 63 6b 66 69 6c 6c 65 64 20 2a 2f 0a 20 20 75  ackfilled */.  u
f900: 33 32 20 6d 78 50 61 67 65 3b 20 20 20 20 20 20  32 mxPage;      
f910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
f920: 2a 20 4d 61 78 20 64 61 74 61 62 61 73 65 20 70  * Max database p
f930: 61 67 65 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a  age to write */.
f940: 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
f950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f960: 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65    /* Loop counte
f970: 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20  r */.  volatile 
f980: 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e  WalCkptInfo *pIn
f990: 66 6f 3b 20 20 20 20 2f 2a 20 54 68 65 20 63 68  fo;    /* The ch
f9a0: 65 63 6b 70 6f 69 6e 74 20 73 74 61 74 75 73 20  eckpoint status 
f9b0: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 2a 2f 0a 20  information */. 
f9c0: 20 69 6e 74 20 28 2a 78 42 75 73 79 29 28 76 6f   int (*xBusy)(vo
f9d0: 69 64 2a 29 20 3d 20 30 3b 20 20 20 20 20 20 20  id*) = 0;       
f9e0: 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20   /* Function to 
f9f0: 63 61 6c 6c 20 77 68 65 6e 20 77 61 69 74 69 6e  call when waitin
fa00: 67 20 66 6f 72 20 6c 6f 63 6b 73 20 2a 2f 0a 0a  g for locks */..
fa10: 20 20 73 7a 50 61 67 65 20 3d 20 77 61 6c 50 61    szPage = walPa
fa20: 67 65 73 69 7a 65 28 70 57 61 6c 29 3b 0a 20 20  gesize(pWal);.  
fa30: 74 65 73 74 63 61 73 65 28 20 73 7a 50 61 67 65  testcase( szPage
fa40: 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20 74 65 73  <=32768 );.  tes
fa50: 74 63 61 73 65 28 20 73 7a 50 61 67 65 3e 3d 36  tcase( szPage>=6
fa60: 35 35 33 36 20 29 3b 0a 20 20 70 49 6e 66 6f 20  5536 );.  pInfo 
fa70: 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57  = walCkptInfo(pW
fa80: 61 6c 29 3b 0a 20 20 69 66 28 20 70 49 6e 66 6f  al);.  if( pInfo
fa90: 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3e 3d 70 57 61  ->nBackfill>=pWa
faa0: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29  l->hdr.mxFrame )
fab0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
fac0: 4b 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  K;..  /* Allocat
fad0: 65 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 2a  e the iterator *
fae0: 2f 0a 20 20 72 63 20 3d 20 77 61 6c 49 74 65 72  /.  rc = walIter
faf0: 61 74 6f 72 49 6e 69 74 28 70 57 61 6c 2c 20 26  atorInit(pWal, &
fb00: 70 49 74 65 72 29 3b 0a 20 20 69 66 28 20 72 63  pIter);.  if( rc
fb10: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
fb20: 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
fb30: 7d 0a 20 20 61 73 73 65 72 74 28 20 70 49 74 65  }.  assert( pIte
fb40: 72 20 29 3b 0a 0a 20 20 69 66 28 20 65 4d 6f 64  r );..  if( eMod
fb50: 65 21 3d 53 51 4c 49 54 45 5f 43 48 45 43 4b 50  e!=SQLITE_CHECKP
fb60: 4f 49 4e 54 5f 50 41 53 53 49 56 45 20 29 20 78  OINT_PASSIVE ) x
fb70: 42 75 73 79 20 3d 20 78 42 75 73 79 43 61 6c 6c  Busy = xBusyCall
fb80: 3b 0a 0a 20 20 2f 2a 20 43 6f 6d 70 75 74 65 20  ;..  /* Compute 
fb90: 69 6e 20 6d 78 53 61 66 65 46 72 61 6d 65 20 74  in mxSafeFrame t
fba0: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
fbb0: 6c 61 73 74 20 66 72 61 6d 65 20 6f 66 20 74 68  last frame of th
fbc0: 65 20 57 41 4c 20 74 68 61 74 20 69 73 0a 20 20  e WAL that is.  
fbd0: 2a 2a 20 73 61 66 65 20 74 6f 20 77 72 69 74 65  ** safe to write
fbe0: 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
fbf0: 73 65 2e 20 20 46 72 61 6d 65 73 20 62 65 79 6f  se.  Frames beyo
fc00: 6e 64 20 6d 78 53 61 66 65 46 72 61 6d 65 20 6d  nd mxSafeFrame m
fc10: 69 67 68 74 0a 20 20 2a 2a 20 6f 76 65 72 77 72  ight.  ** overwr
fc20: 69 74 65 20 64 61 74 61 62 61 73 65 20 70 61 67  ite database pag
fc30: 65 73 20 74 68 61 74 20 61 72 65 20 69 6e 20 75  es that are in u
fc40: 73 65 20 62 79 20 61 63 74 69 76 65 20 72 65 61  se by active rea
fc50: 64 65 72 73 20 61 6e 64 20 74 68 75 73 0a 20 20  ders and thus.  
fc60: 2a 2a 20 63 61 6e 6e 6f 74 20 62 65 20 62 61 63  ** cannot be bac
fc70: 6b 66 69 6c 6c 65 64 20 66 72 6f 6d 20 74 68 65  kfilled from the
fc80: 20 57 41 4c 2e 0a 20 20 2a 2f 0a 20 20 6d 78 53   WAL..  */.  mxS
fc90: 61 66 65 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d  afeFrame = pWal-
fca0: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20  >hdr.mxFrame;.  
fcb0: 6d 78 50 61 67 65 20 3d 20 70 57 61 6c 2d 3e 68  mxPage = pWal->h
fcc0: 64 72 2e 6e 50 61 67 65 3b 0a 20 20 66 6f 72 28  dr.nPage;.  for(
fcd0: 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44  i=1; i<WAL_NREAD
fce0: 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 75 33  ER; i++){.    u3
fcf0: 32 20 79 20 3d 20 70 49 6e 66 6f 2d 3e 61 52 65  2 y = pInfo->aRe
fd00: 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20 20 20 20 69  adMark[i];.    i
fd10: 66 28 20 6d 78 53 61 66 65 46 72 61 6d 65 3e 79  f( mxSafeFrame>y
fd20: 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74   ){.      assert
fd30: 28 20 79 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d  ( y<=pWal->hdr.m
fd40: 78 46 72 61 6d 65 20 29 3b 0a 20 20 20 20 20 20  xFrame );.      
fd50: 72 63 20 3d 20 77 61 6c 42 75 73 79 4c 6f 63 6b  rc = walBusyLock
fd60: 28 70 57 61 6c 2c 20 78 42 75 73 79 2c 20 70 42  (pWal, xBusy, pB
fd70: 75 73 79 41 72 67 2c 20 57 41 4c 5f 52 45 41 44  usyArg, WAL_READ
fd80: 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20  _LOCK(i), 1);.  
fd90: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
fda0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
fdb0: 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
fdc0: 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41 52 4b 5f  k[i] = READMARK_
fdd0: 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 20 20 20 20  NOT_USED;.      
fde0: 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75    walUnlockExclu
fdf0: 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52  sive(pWal, WAL_R
fe00: 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b  EAD_LOCK(i), 1);
fe10: 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
fe20: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc==SQLITE_BUSY
fe30: 20 29 7b 0a 20 20 20 20 20 20 20 20 6d 78 53 61   ){.        mxSa
fe40: 66 65 46 72 61 6d 65 20 3d 20 79 3b 0a 20 20 20  feFrame = y;.   
fe50: 20 20 20 20 20 78 42 75 73 79 20 3d 20 30 3b 0a       xBusy = 0;.
fe60: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
fe70: 20 20 20 20 20 67 6f 74 6f 20 77 61 6c 63 68 65       goto walche
fe80: 63 6b 70 6f 69 6e 74 5f 6f 75 74 3b 0a 20 20 20  ckpoint_out;.   
fe90: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
fea0: 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61    if( pInfo->nBa
feb0: 63 6b 66 69 6c 6c 3c 6d 78 53 61 66 65 46 72 61  ckfill<mxSafeFra
fec0: 6d 65 0a 20 20 20 26 26 20 28 72 63 20 3d 20 77  me.   && (rc = w
fed0: 61 6c 42 75 73 79 4c 6f 63 6b 28 70 57 61 6c 2c  alBusyLock(pWal,
fee0: 20 78 42 75 73 79 2c 20 70 42 75 73 79 41 72 67   xBusy, pBusyArg
fef0: 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
ff00: 30 29 2c 20 31 29 29 3d 3d 53 51 4c 49 54 45 5f  0), 1))==SQLITE_
ff10: 4f 4b 0a 20 20 29 7b 0a 20 20 20 20 69 36 34 20  OK.  ){.    i64 
ff20: 6e 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20  nSize;          
ff30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72            /* Cur
ff40: 72 65 6e 74 20 73 69 7a 65 20 6f 66 20 64 61 74  rent size of dat
ff50: 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20  abase file */.  
ff60: 20 20 75 33 32 20 6e 42 61 63 6b 66 69 6c 6c 20    u32 nBackfill 
ff70: 3d 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69  = pInfo->nBackfi
ff80: 6c 6c 3b 0a 0a 20 20 20 20 2f 2a 20 53 79 6e 63  ll;..    /* Sync
ff90: 20 74 68 65 20 57 41 4c 20 74 6f 20 64 69 73 6b   the WAL to disk
ffa0: 20 2a 2f 0a 20 20 20 20 69 66 28 20 73 79 6e 63   */.    if( sync
ffb0: 5f 66 6c 61 67 73 20 29 7b 0a 20 20 20 20 20 20  _flags ){.      
ffc0: 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 79  rc = sqlite3OsSy
ffd0: 6e 63 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  nc(pWal->pWalFd,
ffe0: 20 73 79 6e 63 5f 66 6c 61 67 73 29 3b 0a 20 20   sync_flags);.  
fff0: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74    }..    /* If t
10000 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
10010 20 6d 61 79 20 67 72 6f 77 20 61 73 20 61 20 72   may grow as a r
10020 65 73 75 6c 74 20 6f 66 20 74 68 69 73 20 63 68  esult of this ch
10030 65 63 6b 70 6f 69 6e 74 2c 20 68 69 6e 74 0a 20  eckpoint, hint. 
10040 20 20 20 2a 2a 20 61 62 6f 75 74 20 74 68 65 20     ** about the 
10050 65 76 65 6e 74 75 61 6c 20 73 69 7a 65 20 6f 66  eventual size of
10060 20 74 68 65 20 64 62 20 66 69 6c 65 20 74 6f 20   the db file to 
10070 74 68 65 20 56 46 53 20 6c 61 79 65 72 2e 20 0a  the VFS layer. .
10080 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20 72      */.    if( r
10090 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
100a0 20 20 20 20 20 20 69 36 34 20 6e 52 65 71 20 3d        i64 nReq =
100b0 20 28 28 69 36 34 29 6d 78 50 61 67 65 20 2a 20   ((i64)mxPage * 
100c0 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 20 20 72  szPage);.      r
100d0 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 69 6c  c = sqlite3OsFil
100e0 65 53 69 7a 65 28 70 57 61 6c 2d 3e 70 44 62 46  eSize(pWal->pDbF
100f0 64 2c 20 26 6e 53 69 7a 65 29 3b 0a 20 20 20 20  d, &nSize);.    
10100 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
10110 5f 4f 4b 20 26 26 20 6e 53 69 7a 65 3c 6e 52 65  _OK && nSize<nRe
10120 71 20 29 7b 0a 20 20 20 20 20 20 20 20 73 71 6c  q ){.        sql
10130 69 74 65 33 4f 73 46 69 6c 65 43 6f 6e 74 72 6f  ite3OsFileContro
10140 6c 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 53  l(pWal->pDbFd, S
10150 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 53 49 5a 45  QLITE_FCNTL_SIZE
10160 5f 48 49 4e 54 2c 20 26 6e 52 65 71 29 3b 0a 20  _HINT, &nReq);. 
10170 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
10180 20 20 2f 2a 20 49 74 65 72 61 74 65 20 74 68 72    /* Iterate thr
10190 6f 75 67 68 20 74 68 65 20 63 6f 6e 74 65 6e 74  ough the content
101a0 73 20 6f 66 20 74 68 65 20 57 41 4c 2c 20 63 6f  s of the WAL, co
101b0 70 79 69 6e 67 20 64 61 74 61 20 74 6f 20 74 68  pying data to th
101c0 65 20 64 62 20 66 69 6c 65 2e 20 2a 2f 0a 20 20  e db file. */.  
101d0 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c    while( rc==SQL
101e0 49 54 45 5f 4f 4b 20 26 26 20 30 3d 3d 77 61 6c  ITE_OK && 0==wal
101f0 49 74 65 72 61 74 6f 72 4e 65 78 74 28 70 49 74  IteratorNext(pIt
10200 65 72 2c 20 26 69 44 62 70 61 67 65 2c 20 26 69  er, &iDbpage, &i
10210 46 72 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20  Frame) ){.      
10220 69 36 34 20 69 4f 66 66 73 65 74 3b 0a 20 20 20  i64 iOffset;.   
10230 20 20 20 61 73 73 65 72 74 28 20 77 61 6c 46 72     assert( walFr
10240 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 46  amePgno(pWal, iF
10250 72 61 6d 65 29 3d 3d 69 44 62 70 61 67 65 20 29  rame)==iDbpage )
10260 3b 0a 20 20 20 20 20 20 69 66 28 20 69 46 72 61  ;.      if( iFra
10270 6d 65 3c 3d 6e 42 61 63 6b 66 69 6c 6c 20 7c 7c  me<=nBackfill ||
10280 20 69 46 72 61 6d 65 3e 6d 78 53 61 66 65 46 72   iFrame>mxSafeFr
10290 61 6d 65 20 7c 7c 20 69 44 62 70 61 67 65 3e 6d  ame || iDbpage>m
102a0 78 50 61 67 65 20 29 20 63 6f 6e 74 69 6e 75 65  xPage ) continue
102b0 3b 0a 20 20 20 20 20 20 69 4f 66 66 73 65 74 20  ;.      iOffset 
102c0 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74  = walFrameOffset
102d0 28 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29  (iFrame, szPage)
102e0 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52   + WAL_FRAME_HDR
102f0 53 49 5a 45 3b 0a 20 20 20 20 20 20 2f 2a 20 74  SIZE;.      /* t
10300 65 73 74 63 61 73 65 28 20 49 53 5f 42 49 47 5f  estcase( IS_BIG_
10310 49 4e 54 28 69 4f 66 66 73 65 74 29 20 29 3b 20  INT(iOffset) ); 
10320 2f 2f 20 72 65 71 75 69 72 65 73 20 61 20 34 47  // requires a 4G
10330 69 42 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20  iB WAL file */. 
10340 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
10350 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57  3OsRead(pWal->pW
10360 61 6c 46 64 2c 20 7a 42 75 66 2c 20 73 7a 50 61  alFd, zBuf, szPa
10370 67 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  ge, iOffset);.  
10380 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
10390 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20  TE_OK ) break;. 
103a0 20 20 20 20 20 69 4f 66 66 73 65 74 20 3d 20 28       iOffset = (
103b0 69 44 62 70 61 67 65 2d 31 29 2a 28 69 36 34 29  iDbpage-1)*(i64)
103c0 73 7a 50 61 67 65 3b 0a 20 20 20 20 20 20 74 65  szPage;.      te
103d0 73 74 63 61 73 65 28 20 49 53 5f 42 49 47 5f 49  stcase( IS_BIG_I
103e0 4e 54 28 69 4f 66 66 73 65 74 29 20 29 3b 0a 20  NT(iOffset) );. 
103f0 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
10400 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70  3OsWrite(pWal->p
10410 44 62 46 64 2c 20 7a 42 75 66 2c 20 73 7a 50 61  DbFd, zBuf, szPa
10420 67 65 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  ge, iOffset);.  
10430 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
10440 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20  TE_OK ) break;. 
10450 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20     }..    /* If 
10460 77 6f 72 6b 20 77 61 73 20 61 63 74 75 61 6c 6c  work was actuall
10470 79 20 61 63 63 6f 6d 70 6c 69 73 68 65 64 2e 2e  y accomplished..
10480 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d  . */.    if( rc=
10490 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
104a0 20 20 20 20 69 66 28 20 6d 78 53 61 66 65 46 72      if( mxSafeFr
104b0 61 6d 65 3d 3d 77 61 6c 49 6e 64 65 78 48 64 72  ame==walIndexHdr
104c0 28 70 57 61 6c 29 2d 3e 6d 78 46 72 61 6d 65 20  (pWal)->mxFrame 
104d0 29 7b 0a 20 20 20 20 20 20 20 20 69 36 34 20 73  ){.        i64 s
104e0 7a 44 62 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  zDb = pWal->hdr.
104f0 6e 50 61 67 65 2a 28 69 36 34 29 73 7a 50 61 67  nPage*(i64)szPag
10500 65 3b 0a 20 20 20 20 20 20 20 20 74 65 73 74 63  e;.        testc
10510 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28  ase( IS_BIG_INT(
10520 73 7a 44 62 29 20 29 3b 0a 20 20 20 20 20 20 20  szDb) );.       
10530 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 54   rc = sqlite3OsT
10540 72 75 6e 63 61 74 65 28 70 57 61 6c 2d 3e 70 44  runcate(pWal->pD
10550 62 46 64 2c 20 73 7a 44 62 29 3b 0a 20 20 20 20  bFd, szDb);.    
10560 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
10570 54 45 5f 4f 4b 20 26 26 20 73 79 6e 63 5f 66 6c  TE_OK && sync_fl
10580 61 67 73 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ags ){.         
10590 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53   rc = sqlite3OsS
105a0 79 6e 63 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c  ync(pWal->pDbFd,
105b0 20 73 79 6e 63 5f 66 6c 61 67 73 29 3b 0a 20 20   sync_flags);.  
105c0 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
105d0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
105e0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
105f0 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66     pInfo->nBackf
10600 69 6c 6c 20 3d 20 6d 78 53 61 66 65 46 72 61 6d  ill = mxSafeFram
10610 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  e;.      }.    }
10620 0a 0a 20 20 20 20 2f 2a 20 52 65 6c 65 61 73 65  ..    /* Release
10630 20 74 68 65 20 72 65 61 64 65 72 20 6c 6f 63 6b   the reader lock
10640 20 68 65 6c 64 20 77 68 69 6c 65 20 62 61 63 6b   held while back
10650 66 69 6c 6c 69 6e 67 20 2a 2f 0a 20 20 20 20 77  filling */.    w
10660 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
10670 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
10680 5f 4c 4f 43 4b 28 30 29 2c 20 31 29 3b 0a 20 20  _LOCK(0), 1);.  
10690 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
106a0 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20  ITE_BUSY ){.    
106b0 2f 2a 20 52 65 73 65 74 20 74 68 65 20 72 65 74  /* Reset the ret
106c0 75 72 6e 20 63 6f 64 65 20 73 6f 20 61 73 20 6e  urn code so as n
106d0 6f 74 20 74 6f 20 72 65 70 6f 72 74 20 61 20 63  ot to report a c
106e0 68 65 63 6b 70 6f 69 6e 74 20 66 61 69 6c 75 72  heckpoint failur
106f0 65 0a 20 20 20 20 2a 2a 20 6a 75 73 74 20 62 65  e.    ** just be
10700 63 61 75 73 65 20 74 68 65 72 65 20 61 72 65 20  cause there are 
10710 61 63 74 69 76 65 20 72 65 61 64 65 72 73 2e 20  active readers. 
10720 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   */.    rc = SQL
10730 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 2f  ITE_OK;.  }..  /
10740 2a 20 49 66 20 74 68 69 73 20 69 73 20 61 6e 20  * If this is an 
10750 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e  SQLITE_CHECKPOIN
10760 54 5f 52 45 53 54 41 52 54 20 6f 70 65 72 61 74  T_RESTART operat
10770 69 6f 6e 2c 20 61 6e 64 20 74 68 65 20 65 6e 74  ion, and the ent
10780 69 72 65 20 77 61 6c 0a 20 20 2a 2a 20 66 69 6c  ire wal.  ** fil
10790 65 20 68 61 73 20 62 65 65 6e 20 63 6f 70 69 65  e has been copie
107a0 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62  d into the datab
107b0 61 73 65 20 66 69 6c 65 2c 20 74 68 65 6e 20 62  ase file, then b
107c0 6c 6f 63 6b 20 75 6e 74 69 6c 20 61 6c 6c 0a 20  lock until all. 
107d0 20 2a 2a 20 72 65 61 64 65 72 73 20 68 61 76 65   ** readers have
107e0 20 66 69 6e 69 73 68 65 64 20 75 73 69 6e 67 20   finished using 
107f0 74 68 65 20 77 61 6c 20 66 69 6c 65 2e 20 54 68  the wal file. Th
10800 69 73 20 65 6e 73 75 72 65 73 20 74 68 61 74 20  is ensures that 
10810 74 68 65 20 6e 65 78 74 0a 20 20 2a 2a 20 70 72  the next.  ** pr
10820 6f 63 65 73 73 20 74 6f 20 77 72 69 74 65 20 74  ocess to write t
10830 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20 72  o the database r
10840 65 73 74 61 72 74 73 20 74 68 65 20 77 61 6c 20  estarts the wal 
10850 66 69 6c 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  file..  */.  if(
10860 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
10870 26 20 65 4d 6f 64 65 21 3d 53 51 4c 49 54 45 5f  & eMode!=SQLITE_
10880 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49  CHECKPOINT_PASSI
10890 56 45 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  VE ){.    assert
108a0 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
108b0 6b 20 29 3b 0a 20 20 20 20 69 66 28 20 70 49 6e  k );.    if( pIn
108c0 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3c 70 57  fo->nBackfill<pW
108d0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
108e0 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  ){.      rc = SQ
108f0 4c 49 54 45 5f 42 55 53 59 3b 0a 20 20 20 20 7d  LITE_BUSY;.    }
10900 65 6c 73 65 20 69 66 28 20 65 4d 6f 64 65 3d 3d  else if( eMode==
10910 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e  SQLITE_CHECKPOIN
10920 54 5f 52 45 53 54 41 52 54 20 29 7b 0a 20 20 20  T_RESTART ){.   
10930 20 20 20 61 73 73 65 72 74 28 20 6d 78 53 61 66     assert( mxSaf
10940 65 46 72 61 6d 65 3d 3d 70 57 61 6c 2d 3e 68 64  eFrame==pWal->hd
10950 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20  r.mxFrame );.   
10960 20 20 20 72 63 20 3d 20 77 61 6c 42 75 73 79 4c     rc = walBusyL
10970 6f 63 6b 28 70 57 61 6c 2c 20 78 42 75 73 79 2c  ock(pWal, xBusy,
10980 20 70 42 75 73 79 41 72 67 2c 20 57 41 4c 5f 52   pBusyArg, WAL_R
10990 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c  EAD_LOCK(1), WAL
109a0 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20  _NREADER-1);.   
109b0 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
109c0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
109d0 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69  walUnlockExclusi
109e0 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ve(pWal, WAL_REA
109f0 44 5f 4c 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e  D_LOCK(1), WAL_N
10a00 52 45 41 44 45 52 2d 31 29 3b 0a 20 20 20 20 20  READER-1);.     
10a10 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 77   }.    }.  }.. w
10a20 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74  alcheckpoint_out
10a30 3a 0a 20 20 77 61 6c 49 74 65 72 61 74 6f 72 46  :.  walIteratorF
10a40 72 65 65 28 70 49 74 65 72 29 3b 0a 20 20 72 65  ree(pIter);.  re
10a50 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
10a60 2a 20 43 6c 6f 73 65 20 61 20 63 6f 6e 6e 65 63  * Close a connec
10a70 74 69 6f 6e 20 74 6f 20 61 20 6c 6f 67 20 66 69  tion to a log fi
10a80 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  le..*/.int sqlit
10a90 65 33 57 61 6c 43 6c 6f 73 65 28 0a 20 20 57 61  e3WalClose(.  Wa
10aa0 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20  l *pWal,        
10ab0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
10ac0 20 57 61 6c 20 74 6f 20 63 6c 6f 73 65 20 2a 2f   Wal to close */
10ad0 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67  .  int sync_flag
10ae0 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s,              
10af0 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20 70     /* Flags to p
10b00 61 73 73 20 74 6f 20 4f 73 53 79 6e 63 28 29 20  ass to OsSync() 
10b10 28 6f 72 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20  (or 0) */.  int 
10b20 6e 42 75 66 2c 0a 20 20 75 38 20 2a 7a 42 75 66  nBuf,.  u8 *zBuf
10b30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10b40 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65          /* Buffe
10b50 72 20 6f 66 20 61 74 20 6c 65 61 73 74 20 6e 42  r of at least nB
10b60 75 66 20 62 79 74 65 73 20 2a 2f 0a 29 7b 0a 20  uf bytes */.){. 
10b70 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
10b80 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 57 61 6c 20  _OK;.  if( pWal 
10b90 29 7b 0a 20 20 20 20 69 6e 74 20 69 73 44 65 6c  ){.    int isDel
10ba0 65 74 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ete = 0;        
10bb0 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20       /* True to 
10bc0 75 6e 6c 69 6e 6b 20 77 61 6c 20 61 6e 64 20 77  unlink wal and w
10bd0 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 73 20 2a  al-index files *
10be0 2f 0a 0a 20 20 20 20 2f 2a 20 49 66 20 61 6e 20  /..    /* If an 
10bf0 45 58 43 4c 55 53 49 56 45 20 6c 6f 63 6b 20 63  EXCLUSIVE lock c
10c00 61 6e 20 62 65 20 6f 62 74 61 69 6e 65 64 20 6f  an be obtained o
10c10 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  n the database f
10c20 69 6c 65 20 28 75 73 69 6e 67 20 74 68 65 0a 20  ile (using the. 
10c30 20 20 20 2a 2a 20 6f 72 64 69 6e 61 72 79 2c 20     ** ordinary, 
10c40 72 6f 6c 6c 62 61 63 6b 2d 6d 6f 64 65 20 6c 6f  rollback-mode lo
10c50 63 6b 69 6e 67 20 6d 65 74 68 6f 64 73 2c 20 74  cking methods, t
10c60 68 69 73 20 67 75 61 72 61 6e 74 65 65 73 20 74  his guarantees t
10c70 68 61 74 20 74 68 65 0a 20 20 20 20 2a 2a 20 63  hat the.    ** c
10c80 6f 6e 6e 65 63 74 69 6f 6e 20 61 73 73 6f 63 69  onnection associ
10c90 61 74 65 64 20 77 69 74 68 20 74 68 69 73 20 6c  ated with this l
10ca0 6f 67 20 66 69 6c 65 20 69 73 20 74 68 65 20 6f  og file is the o
10cb0 6e 6c 79 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74  nly connection t
10cc0 6f 0a 20 20 20 20 2a 2a 20 74 68 65 20 64 61 74  o.    ** the dat
10cd0 61 62 61 73 65 2e 20 49 6e 20 74 68 69 73 20 63  abase. In this c
10ce0 61 73 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 74  ase checkpoint t
10cf0 68 65 20 64 61 74 61 62 61 73 65 20 61 6e 64 20  he database and 
10d00 75 6e 6c 69 6e 6b 20 62 6f 74 68 0a 20 20 20 20  unlink both.    
10d10 2a 2a 20 74 68 65 20 77 61 6c 20 61 6e 64 20 77  ** the wal and w
10d20 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 73 2e 0a  al-index files..
10d30 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68      **.    ** Th
10d40 65 20 45 58 43 4c 55 53 49 56 45 20 6c 6f 63 6b  e EXCLUSIVE lock
10d50 20 69 73 20 6e 6f 74 20 72 65 6c 65 61 73 65 64   is not released
10d60 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
10d70 67 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 72 63  g..    */.    rc
10d80 20 3d 20 73 71 6c 69 74 65 33 4f 73 4c 6f 63 6b   = sqlite3OsLock
10d90 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 53 51  (pWal->pDbFd, SQ
10da0 4c 49 54 45 5f 4c 4f 43 4b 5f 45 58 43 4c 55 53  LITE_LOCK_EXCLUS
10db0 49 56 45 29 3b 0a 20 20 20 20 69 66 28 20 72 63  IVE);.    if( rc
10dc0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
10dd0 20 20 20 20 20 69 6e 74 20 62 50 65 72 73 69 73       int bPersis
10de0 74 57 61 6c 20 3d 20 2d 31 3b 0a 20 20 20 20 20  tWal = -1;.     
10df0 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75   if( pWal->exclu
10e00 73 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 4e 4f  siveMode==WAL_NO
10e10 52 4d 41 4c 5f 4d 4f 44 45 20 29 7b 0a 20 20 20  RMAL_MODE ){.   
10e20 20 20 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c 75       pWal->exclu
10e30 73 69 76 65 4d 6f 64 65 20 3d 20 57 41 4c 5f 45  siveMode = WAL_E
10e40 58 43 4c 55 53 49 56 45 5f 4d 4f 44 45 3b 0a 20  XCLUSIVE_MODE;. 
10e50 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 63 20       }.      rc 
10e60 3d 20 73 71 6c 69 74 65 33 57 61 6c 43 68 65 63  = sqlite3WalChec
10e70 6b 70 6f 69 6e 74 28 0a 20 20 20 20 20 20 20 20  kpoint(.        
10e80 20 20 70 57 61 6c 2c 20 53 51 4c 49 54 45 5f 43    pWal, SQLITE_C
10e90 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49 56  HECKPOINT_PASSIV
10ea0 45 2c 20 30 2c 20 30 2c 20 73 79 6e 63 5f 66 6c  E, 0, 0, sync_fl
10eb0 61 67 73 2c 20 6e 42 75 66 2c 20 7a 42 75 66 2c  ags, nBuf, zBuf,
10ec0 20 30 2c 20 30 0a 20 20 20 20 20 20 29 3b 0a 20   0, 0.      );. 
10ed0 20 20 20 20 20 73 71 6c 69 74 65 33 4f 73 46 69       sqlite3OsFi
10ee0 6c 65 43 6f 6e 74 72 6f 6c 28 70 57 61 6c 2d 3e  leControl(pWal->
10ef0 70 44 62 46 64 2c 20 53 51 4c 49 54 45 5f 46 43  pDbFd, SQLITE_FC
10f00 4e 54 4c 5f 50 45 52 53 49 53 54 5f 57 41 4c 2c  NTL_PERSIST_WAL,
10f10 20 26 62 50 65 72 73 69 73 74 57 61 6c 29 3b 0a   &bPersistWal);.
10f20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
10f30 4c 49 54 45 5f 4f 4b 20 26 26 20 62 50 65 72 73  LITE_OK && bPers
10f40 69 73 74 57 61 6c 21 3d 31 20 29 7b 0a 20 20 20  istWal!=1 ){.   
10f50 20 20 20 20 20 69 73 44 65 6c 65 74 65 20 3d 20       isDelete = 
10f60 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  1;.      }.    }
10f70 0a 0a 20 20 20 20 77 61 6c 49 6e 64 65 78 43 6c  ..    walIndexCl
10f80 6f 73 65 28 70 57 61 6c 2c 20 69 73 44 65 6c 65  ose(pWal, isDele
10f90 74 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  te);.    sqlite3
10fa0 4f 73 43 6c 6f 73 65 28 70 57 61 6c 2d 3e 70 57  OsClose(pWal->pW
10fb0 61 6c 46 64 29 3b 0a 20 20 20 20 69 66 28 20 69  alFd);.    if( i
10fc0 73 44 65 6c 65 74 65 20 29 7b 0a 20 20 20 20 20  sDelete ){.     
10fd0 20 73 71 6c 69 74 65 33 4f 73 44 65 6c 65 74 65   sqlite3OsDelete
10fe0 28 70 57 61 6c 2d 3e 70 56 66 73 2c 20 70 57 61  (pWal->pVfs, pWa
10ff0 6c 2d 3e 7a 57 61 6c 4e 61 6d 65 2c 20 30 29 3b  l->zWalName, 0);
11000 0a 20 20 20 20 7d 0a 20 20 20 20 57 41 4c 54 52  .    }.    WALTR
11010 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63 6c 6f  ACE(("WAL%p: clo
11020 73 65 64 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a  sed\n", pWal));.
11030 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
11040 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d 3e 61  ((void *)pWal->a
11050 70 57 69 44 61 74 61 29 3b 0a 20 20 20 20 73 71  pWiData);.    sq
11060 6c 69 74 65 33 5f 66 72 65 65 28 70 57 61 6c 29  lite3_free(pWal)
11070 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
11080 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79 20  c;.}../*.** Try 
11090 74 6f 20 72 65 61 64 20 74 68 65 20 77 61 6c 2d  to read the wal-
110a0 69 6e 64 65 78 20 68 65 61 64 65 72 2e 20 20 52  index header.  R
110b0 65 74 75 72 6e 20 30 20 6f 6e 20 73 75 63 63 65  eturn 0 on succe
110c0 73 73 20 61 6e 64 20 31 20 69 66 0a 2a 2a 20 74  ss and 1 if.** t
110d0 68 65 72 65 20 69 73 20 61 20 70 72 6f 62 6c 65  here is a proble
110e0 6d 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61 6c  m..**.** The wal
110f0 2d 69 6e 64 65 78 20 69 73 20 69 6e 20 73 68 61  -index is in sha
11100 72 65 64 20 6d 65 6d 6f 72 79 2e 20 20 41 6e 6f  red memory.  Ano
11110 74 68 65 72 20 74 68 72 65 61 64 20 6f 72 20 70  ther thread or p
11120 72 6f 63 65 73 73 20 6d 69 67 68 74 0a 2a 2a 20  rocess might.** 
11130 62 65 20 77 72 69 74 69 6e 67 20 74 68 65 20 68  be writing the h
11140 65 61 64 65 72 20 61 74 20 74 68 65 20 73 61 6d  eader at the sam
11150 65 20 74 69 6d 65 20 74 68 69 73 20 70 72 6f 63  e time this proc
11160 65 64 75 72 65 20 69 73 20 74 72 79 69 6e 67 20  edure is trying 
11170 74 6f 0a 2a 2a 20 72 65 61 64 20 69 74 2c 20 77  to.** read it, w
11180 68 69 63 68 20 6d 69 67 68 74 20 72 65 73 75 6c  hich might resul
11190 74 20 69 6e 20 69 6e 63 6f 6e 73 69 73 74 65 6e  t in inconsisten
111a0 63 79 2e 20 20 41 20 64 69 72 74 79 20 72 65 61  cy.  A dirty rea
111b0 64 20 69 73 20 64 65 74 65 63 74 65 64 0a 2a 2a  d is detected.**
111c0 20 62 79 20 76 65 72 69 66 79 69 6e 67 20 74 68   by verifying th
111d0 61 74 20 62 6f 74 68 20 63 6f 70 69 65 73 20 6f  at both copies o
111e0 66 20 74 68 65 20 68 65 61 64 65 72 20 61 72 65  f the header are
111f0 20 74 68 65 20 73 61 6d 65 20 61 6e 64 20 61 6c   the same and al
11200 73 6f 20 62 79 0a 2a 2a 20 61 20 63 68 65 63 6b  so by.** a check
11210 73 75 6d 20 6f 6e 20 74 68 65 20 68 65 61 64 65  sum on the heade
11220 72 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 64 20  r..**.** If and 
11230 6f 6e 6c 79 20 69 66 20 74 68 65 20 72 65 61 64  only if the read
11240 20 69 73 20 63 6f 6e 73 69 73 74 65 6e 74 20 61   is consistent a
11250 6e 64 20 74 68 65 20 68 65 61 64 65 72 20 69 73  nd the header is
11260 20 64 69 66 66 65 72 65 6e 74 20 66 72 6f 6d 0a   different from.
11270 2a 2a 20 70 57 61 6c 2d 3e 68 64 72 2c 20 74 68  ** pWal->hdr, th
11280 65 6e 20 70 57 61 6c 2d 3e 68 64 72 20 69 73 20  en pWal->hdr is 
11290 75 70 64 61 74 65 64 20 74 6f 20 74 68 65 20 63  updated to the c
112a0 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65 20 6e 65  ontent of the ne
112b0 77 20 68 65 61 64 65 72 0a 2a 2a 20 61 6e 64 20  w header.** and 
112c0 2a 70 43 68 61 6e 67 65 64 20 69 73 20 73 65 74  *pChanged is set
112d0 20 74 6f 20 31 2e 0a 2a 2a 0a 2a 2a 20 49 66 20   to 1..**.** If 
112e0 74 68 65 20 63 68 65 63 6b 73 75 6d 20 63 61 6e  the checksum can
112f0 6e 6f 74 20 62 65 20 76 65 72 69 66 69 65 64 20  not be verified 
11300 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e  return non-zero.
11310 20 49 66 20 74 68 65 20 68 65 61 64 65 72 0a 2a   If the header.*
11320 2a 20 69 73 20 72 65 61 64 20 73 75 63 63 65 73  * is read succes
11330 73 66 75 6c 6c 79 20 61 6e 64 20 74 68 65 20 63  sfully and the c
11340 68 65 63 6b 73 75 6d 20 76 65 72 69 66 69 65 64  hecksum verified
11350 2c 20 72 65 74 75 72 6e 20 7a 65 72 6f 2e 0a 2a  , return zero..*
11360 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  /.static int wal
11370 49 6e 64 65 78 54 72 79 48 64 72 28 57 61 6c 20  IndexTryHdr(Wal 
11380 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61  *pWal, int *pCha
11390 6e 67 65 64 29 7b 0a 20 20 75 33 32 20 61 43 6b  nged){.  u32 aCk
113a0 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20  sum[2];         
113b0 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63           /* Chec
113c0 6b 73 75 6d 20 6f 6e 20 74 68 65 20 68 65 61 64  ksum on the head
113d0 65 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20  er content */.  
113e0 57 61 6c 49 6e 64 65 78 48 64 72 20 68 31 2c 20  WalIndexHdr h1, 
113f0 68 32 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  h2;             
11400 2f 2a 20 54 77 6f 20 63 6f 70 69 65 73 20 6f 66  /* Two copies of
11410 20 74 68 65 20 68 65 61 64 65 72 20 63 6f 6e 74   the header cont
11420 65 6e 74 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65  ent */.  WalInde
11430 78 48 64 72 20 76 6f 6c 61 74 69 6c 65 20 2a 61  xHdr volatile *a
11440 48 64 72 3b 20 20 20 20 20 2f 2a 20 48 65 61 64  Hdr;     /* Head
11450 65 72 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d  er in shared mem
11460 6f 72 79 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 65  ory */..  /* The
11470 20 66 69 72 73 74 20 70 61 67 65 20 6f 66 20 74   first page of t
11480 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 6d 75 73  he wal-index mus
11490 74 20 62 65 20 6d 61 70 70 65 64 20 61 74 20 74  t be mapped at t
114a0 68 69 73 20 70 6f 69 6e 74 2e 20 2a 2f 0a 20 20  his point. */.  
114b0 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57  assert( pWal->nW
114c0 69 44 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d  iData>0 && pWal-
114d0 3e 61 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a  >apWiData[0] );.
114e0 0a 20 20 2f 2a 20 52 65 61 64 20 74 68 65 20 68  .  /* Read the h
114f0 65 61 64 65 72 2e 20 54 68 69 73 20 6d 69 67 68  eader. This migh
11500 74 20 68 61 70 70 65 6e 20 63 6f 6e 63 75 72 72  t happen concurr
11510 65 6e 74 6c 79 20 77 69 74 68 20 61 20 77 72 69  ently with a wri
11520 74 65 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20 73  te to the.  ** s
11530 61 6d 65 20 61 72 65 61 20 6f 66 20 73 68 61 72  ame area of shar
11540 65 64 20 6d 65 6d 6f 72 79 20 6f 6e 20 61 20 64  ed memory on a d
11550 69 66 66 65 72 65 6e 74 20 43 50 55 20 69 6e 20  ifferent CPU in 
11560 61 20 53 4d 50 2c 0a 20 20 2a 2a 20 6d 65 61 6e  a SMP,.  ** mean
11570 69 6e 67 20 69 74 20 69 73 20 70 6f 73 73 69 62  ing it is possib
11580 6c 65 20 74 68 61 74 20 61 6e 20 69 6e 63 6f 6e  le that an incon
11590 73 69 73 74 65 6e 74 20 73 6e 61 70 73 68 6f 74  sistent snapshot
115a0 20 69 73 20 72 65 61 64 0a 20 20 2a 2a 20 66 72   is read.  ** fr
115b0 6f 6d 20 74 68 65 20 66 69 6c 65 2e 20 49 66 20  om the file. If 
115c0 74 68 69 73 20 68 61 70 70 65 6e 73 2c 20 72 65  this happens, re
115d0 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 20  turn non-zero.. 
115e0 20 2a 2a 0a 20 20 2a 2a 20 54 68 65 72 65 20 61   **.  ** There a
115f0 72 65 20 74 77 6f 20 63 6f 70 69 65 73 20 6f 66  re two copies of
11600 20 74 68 65 20 68 65 61 64 65 72 20 61 74 20 74   the header at t
11610 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20  he beginning of 
11620 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 20  the wal-index.. 
11630 20 2a 2a 20 57 68 65 6e 20 72 65 61 64 69 6e 67   ** When reading
11640 2c 20 72 65 61 64 20 5b 30 5d 20 66 69 72 73 74  , read [0] first
11650 20 74 68 65 6e 20 5b 31 5d 2e 20 20 57 72 69 74   then [1].  Writ
11660 65 73 20 61 72 65 20 69 6e 20 74 68 65 20 72 65  es are in the re
11670 76 65 72 73 65 20 6f 72 64 65 72 2e 0a 20 20 2a  verse order..  *
11680 2a 20 4d 65 6d 6f 72 79 20 62 61 72 72 69 65 72  * Memory barrier
11690 73 20 61 72 65 20 75 73 65 64 20 74 6f 20 70 72  s are used to pr
116a0 65 76 65 6e 74 20 74 68 65 20 63 6f 6d 70 69 6c  event the compil
116b0 65 72 20 6f 72 20 74 68 65 20 68 61 72 64 77 61  er or the hardwa
116c0 72 65 20 66 72 6f 6d 0a 20 20 2a 2a 20 72 65 6f  re from.  ** reo
116d0 72 64 65 72 69 6e 67 20 74 68 65 20 72 65 61 64  rdering the read
116e0 73 20 61 6e 64 20 77 72 69 74 65 73 2e 0a 20 20  s and writes..  
116f0 2a 2f 0a 20 20 61 48 64 72 20 3d 20 77 61 6c 49  */.  aHdr = walI
11700 6e 64 65 78 48 64 72 28 70 57 61 6c 29 3b 0a 20  ndexHdr(pWal);. 
11710 20 6d 65 6d 63 70 79 28 26 68 31 2c 20 28 76 6f   memcpy(&h1, (vo
11720 69 64 20 2a 29 26 61 48 64 72 5b 30 5d 2c 20 73  id *)&aHdr[0], s
11730 69 7a 65 6f 66 28 68 31 29 29 3b 0a 20 20 77 61  izeof(h1));.  wa
11740 6c 53 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c  lShmBarrier(pWal
11750 29 3b 0a 20 20 6d 65 6d 63 70 79 28 26 68 32 2c  );.  memcpy(&h2,
11760 20 28 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 31   (void *)&aHdr[1
11770 5d 2c 20 73 69 7a 65 6f 66 28 68 32 29 29 3b 0a  ], sizeof(h2));.
11780 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 68  .  if( memcmp(&h
11790 31 2c 20 26 68 32 2c 20 73 69 7a 65 6f 66 28 68  1, &h2, sizeof(h
117a0 31 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65  1))!=0 ){.    re
117b0 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20 44 69 72  turn 1;   /* Dir
117c0 74 79 20 72 65 61 64 20 2a 2f 0a 20 20 7d 20 20  ty read */.  }  
117d0 0a 20 20 69 66 28 20 68 31 2e 69 73 49 6e 69 74  .  if( h1.isInit
117e0 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  ==0 ){.    retur
117f0 6e 20 31 3b 20 20 20 2f 2a 20 4d 61 6c 66 6f 72  n 1;   /* Malfor
11800 6d 65 64 20 68 65 61 64 65 72 20 2d 20 70 72 6f  med header - pro
11810 62 61 62 6c 79 20 61 6c 6c 20 7a 65 72 6f 73 20  bably all zeros 
11820 2a 2f 0a 20 20 7d 0a 20 20 77 61 6c 43 68 65 63  */.  }.  walChec
11830 6b 73 75 6d 42 79 74 65 73 28 31 2c 20 28 75 38  ksumBytes(1, (u8
11840 2a 29 26 68 31 2c 20 73 69 7a 65 6f 66 28 68 31  *)&h1, sizeof(h1
11850 29 2d 73 69 7a 65 6f 66 28 68 31 2e 61 43 6b 73  )-sizeof(h1.aCks
11860 75 6d 29 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b  um), 0, aCksum);
11870 0a 20 20 69 66 28 20 61 43 6b 73 75 6d 5b 30 5d  .  if( aCksum[0]
11880 21 3d 68 31 2e 61 43 6b 73 75 6d 5b 30 5d 20 7c  !=h1.aCksum[0] |
11890 7c 20 61 43 6b 73 75 6d 5b 31 5d 21 3d 68 31 2e  | aCksum[1]!=h1.
118a0 61 43 6b 73 75 6d 5b 31 5d 20 29 7b 0a 20 20 20  aCksum[1] ){.   
118b0 20 72 65 74 75 72 6e 20 31 3b 20 20 20 2f 2a 20   return 1;   /* 
118c0 43 68 65 63 6b 73 75 6d 20 64 6f 65 73 20 6e 6f  Checksum does no
118d0 74 20 6d 61 74 63 68 20 2a 2f 0a 20 20 7d 0a 0a  t match */.  }..
118e0 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57    if( memcmp(&pW
118f0 61 6c 2d 3e 68 64 72 2c 20 26 68 31 2c 20 73 69  al->hdr, &h1, si
11900 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
11910 29 29 20 29 7b 0a 20 20 20 20 2a 70 43 68 61 6e  )) ){.    *pChan
11920 67 65 64 20 3d 20 31 3b 0a 20 20 20 20 6d 65 6d  ged = 1;.    mem
11930 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20  cpy(&pWal->hdr, 
11940 26 68 31 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49  &h1, sizeof(WalI
11950 6e 64 65 78 48 64 72 29 29 3b 0a 20 20 20 20 70  ndexHdr));.    p
11960 57 61 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 28 70  Wal->szPage = (p
11970 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26  Wal->hdr.szPage&
11980 30 78 66 65 30 30 29 20 2b 20 28 28 70 57 61 6c  0xfe00) + ((pWal
11990 2d 3e 68 64 72 2e 73 7a 50 61 67 65 26 30 78 30  ->hdr.szPage&0x0
119a0 30 30 31 29 3c 3c 31 36 29 3b 0a 20 20 20 20 74  001)<<16);.    t
119b0 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d 3e 73  estcase( pWal->s
119c0 7a 50 61 67 65 3c 3d 33 32 37 36 38 20 29 3b 0a  zPage<=32768 );.
119d0 20 20 20 20 74 65 73 74 63 61 73 65 28 20 70 57      testcase( pW
119e0 61 6c 2d 3e 73 7a 50 61 67 65 3e 3d 36 35 35 33  al->szPage>=6553
119f0 36 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54  6 );.  }..  /* T
11a00 68 65 20 68 65 61 64 65 72 20 77 61 73 20 73 75  he header was su
11a10 63 63 65 73 73 66 75 6c 6c 79 20 72 65 61 64 2e  ccessfully read.
11a20 20 52 65 74 75 72 6e 20 7a 65 72 6f 2e 20 2a 2f   Return zero. */
11a30 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
11a40 2f 2a 0a 2a 2a 20 52 65 61 64 20 74 68 65 20 77  /*.** Read the w
11a50 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
11a60 66 72 6f 6d 20 74 68 65 20 77 61 6c 2d 69 6e 64  from the wal-ind
11a70 65 78 20 61 6e 64 20 69 6e 74 6f 20 70 57 61 6c  ex and into pWal
11a80 2d 3e 68 64 72 2e 0a 2a 2a 20 49 66 20 74 68 65  ->hdr..** If the
11a90 20 77 61 6c 2d 68 65 61 64 65 72 20 61 70 70 65   wal-header appe
11aa0 61 72 73 20 74 6f 20 62 65 20 63 6f 72 72 75 70  ars to be corrup
11ab0 74 2c 20 74 72 79 20 74 6f 20 72 65 63 6f 6e 73  t, try to recons
11ac0 74 72 75 63 74 20 74 68 65 0a 2a 2a 20 77 61 6c  truct the.** wal
11ad0 2d 69 6e 64 65 78 20 66 72 6f 6d 20 74 68 65 20  -index from the 
11ae0 57 41 4c 20 62 65 66 6f 72 65 20 72 65 74 75 72  WAL before retur
11af0 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20  ning..**.** Set 
11b00 2a 70 43 68 61 6e 67 65 64 20 74 6f 20 31 20 69  *pChanged to 1 i
11b10 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
11b20 68 65 61 64 65 72 20 76 61 6c 75 65 20 69 6e 20  header value in 
11b30 70 57 61 6c 2d 3e 68 64 72 20 69 73 0a 2a 2a 20  pWal->hdr is.** 
11b40 63 68 61 6e 67 65 64 20 62 79 20 74 68 69 73 20  changed by this 
11b50 6f 70 65 72 74 69 6f 6e 2e 20 20 49 66 20 70 57  opertion.  If pW
11b60 61 6c 2d 3e 68 64 72 20 69 73 20 75 6e 63 68 61  al->hdr is uncha
11b70 6e 67 65 64 2c 20 73 65 74 20 2a 70 43 68 61 6e  nged, set *pChan
11b80 67 65 64 0a 2a 2a 20 74 6f 20 30 2e 0a 2a 2a 0a  ged.** to 0..**.
11b90 2a 2a 20 49 66 20 74 68 65 20 77 61 6c 2d 69 6e  ** If the wal-in
11ba0 64 65 78 20 68 65 61 64 65 72 20 69 73 20 73 75  dex header is su
11bb0 63 63 65 73 73 66 75 6c 6c 79 20 72 65 61 64 2c  ccessfully read,
11bc0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
11bd0 4b 2e 20 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  K. .** Otherwise
11be0 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72   an SQLite error
11bf0 20 63 6f 64 65 2e 0a 2a 2f 0a 73 74 61 74 69 63   code..*/.static
11c00 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 52 65 61   int walIndexRea
11c10 64 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 2c 20  dHdr(Wal *pWal, 
11c20 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 29 7b 0a  int *pChanged){.
11c30 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
11c40 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11c50 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
11c60 20 2a 2f 0a 20 20 69 6e 74 20 62 61 64 48 64 72   */.  int badHdr
11c70 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
11c80 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
11c90 20 61 20 68 65 61 64 65 72 20 72 65 61 64 20 66   a header read f
11ca0 61 69 6c 65 64 20 2a 2f 0a 20 20 76 6f 6c 61 74  ailed */.  volat
11cb0 69 6c 65 20 75 33 32 20 2a 70 61 67 65 30 3b 20  ile u32 *page0; 
11cc0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68             /* Ch
11cd0 75 6e 6b 20 6f 66 20 77 61 6c 2d 69 6e 64 65 78  unk of wal-index
11ce0 20 63 6f 6e 74 61 69 6e 69 6e 67 20 68 65 61 64   containing head
11cf0 65 72 20 2a 2f 0a 0a 20 20 2f 2a 20 45 6e 73 75  er */..  /* Ensu
11d00 72 65 20 74 68 61 74 20 70 61 67 65 20 30 20 6f  re that page 0 o
11d10 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  f the wal-index 
11d20 28 74 68 65 20 70 61 67 65 20 74 68 61 74 20 63  (the page that c
11d30 6f 6e 74 61 69 6e 73 20 74 68 65 20 0a 20 20 2a  ontains the .  *
11d40 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  * wal-index head
11d50 65 72 29 20 69 73 20 6d 61 70 70 65 64 2e 20 52  er) is mapped. R
11d60 65 74 75 72 6e 20 65 61 72 6c 79 20 69 66 20 61  eturn early if a
11d70 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73 20 68  n error occurs h
11d80 65 72 65 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65  ere..  */.  asse
11d90 72 74 28 20 70 43 68 61 6e 67 65 64 20 29 3b 0a  rt( pChanged );.
11da0 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 50    rc = walIndexP
11db0 61 67 65 28 70 57 61 6c 2c 20 30 2c 20 26 70 61  age(pWal, 0, &pa
11dc0 67 65 30 29 3b 0a 20 20 69 66 28 20 72 63 21 3d  ge0);.  if( rc!=
11dd0 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
11de0 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 3b   return rc;.  };
11df0 0a 20 20 61 73 73 65 72 74 28 20 70 61 67 65 30  .  assert( page0
11e00 20 7c 7c 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c   || pWal->writeL
11e10 6f 63 6b 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20  ock==0 );..  /* 
11e20 49 66 20 74 68 65 20 66 69 72 73 74 20 70 61 67  If the first pag
11e30 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  e of the wal-ind
11e40 65 78 20 68 61 73 20 62 65 65 6e 20 6d 61 70 70  ex has been mapp
11e50 65 64 2c 20 74 72 79 20 74 6f 20 72 65 61 64 20  ed, try to read 
11e60 74 68 65 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64  the.  ** wal-ind
11e70 65 78 20 68 65 61 64 65 72 20 69 6d 6d 65 64 69  ex header immedi
11e80 61 74 65 6c 79 2c 20 77 69 74 68 6f 75 74 20 68  ately, without h
11e90 6f 6c 64 69 6e 67 20 61 6e 79 20 6c 6f 63 6b 2e  olding any lock.
11ea0 20 54 68 69 73 20 75 73 75 61 6c 6c 79 0a 20 20   This usually.  
11eb0 2a 2a 20 77 6f 72 6b 73 2c 20 62 75 74 20 6d 61  ** works, but ma
11ec0 79 20 66 61 69 6c 20 69 66 20 74 68 65 20 77 61  y fail if the wa
11ed0 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69  l-index header i
11ee0 73 20 63 6f 72 72 75 70 74 20 6f 72 20 63 75 72  s corrupt or cur
11ef0 72 65 6e 74 6c 79 20 0a 20 20 2a 2a 20 62 65 69  rently .  ** bei
11f00 6e 67 20 6d 6f 64 69 66 69 65 64 20 62 79 20 61  ng modified by a
11f10 6e 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f 72  nother thread or
11f20 20 70 72 6f 63 65 73 73 2e 0a 20 20 2a 2f 0a 20   process..  */. 
11f30 20 62 61 64 48 64 72 20 3d 20 28 70 61 67 65 30   badHdr = (page0
11f40 20 3f 20 77 61 6c 49 6e 64 65 78 54 72 79 48 64   ? walIndexTryHd
11f50 72 28 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64  r(pWal, pChanged
11f60 29 20 3a 20 31 29 3b 0a 0a 20 20 2f 2a 20 49 66  ) : 1);..  /* If
11f70 20 74 68 65 20 66 69 72 73 74 20 61 74 74 65 6d   the first attem
11f80 70 74 20 66 61 69 6c 65 64 2c 20 69 74 20 6d 69  pt failed, it mi
11f90 67 68 74 20 68 61 76 65 20 62 65 65 6e 20 64 75  ght have been du
11fa0 65 20 74 6f 20 61 20 72 61 63 65 0a 20 20 2a 2a  e to a race.  **
11fb0 20 77 69 74 68 20 61 20 77 72 69 74 65 72 2e 20   with a writer. 
11fc0 20 53 6f 20 67 65 74 20 61 20 57 52 49 54 45 20   So get a WRITE 
11fd0 6c 6f 63 6b 20 61 6e 64 20 74 72 79 20 61 67 61  lock and try aga
11fe0 69 6e 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72  in..  */.  asser
11ff0 74 28 20 62 61 64 48 64 72 3d 3d 30 20 7c 7c 20  t( badHdr==0 || 
12000 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d  pWal->writeLock=
12010 3d 30 20 29 3b 0a 20 20 69 66 28 20 62 61 64 48  =0 );.  if( badH
12020 64 72 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57  dr ){.    if( pW
12030 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57  al->readOnly & W
12040 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 20 29 7b  AL_SHM_RDONLY ){
12050 0a 20 20 20 20 20 20 69 66 28 20 53 51 4c 49 54  .      if( SQLIT
12060 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c 4c  E_OK==(rc = walL
12070 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20  ockShared(pWal, 
12080 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 29 29  WAL_WRITE_LOCK))
12090 20 29 7b 0a 20 20 20 20 20 20 20 20 77 61 6c 55   ){.        walU
120a0 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
120b0 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b  , WAL_WRITE_LOCK
120c0 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  );.        rc = 
120d0 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 5f  SQLITE_READONLY_
120e0 52 45 43 4f 56 45 52 59 3b 0a 20 20 20 20 20 20  RECOVERY;.      
120f0 7d 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  }.    }else if( 
12100 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d  SQLITE_OK==(rc =
12110 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76   walLockExclusiv
12120 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54  e(pWal, WAL_WRIT
12130 45 5f 4c 4f 43 4b 2c 20 31 29 29 20 29 7b 0a 20  E_LOCK, 1)) ){. 
12140 20 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65       pWal->write
12150 4c 6f 63 6b 20 3d 20 31 3b 0a 20 20 20 20 20 20  Lock = 1;.      
12160 69 66 28 20 53 51 4c 49 54 45 5f 4f 4b 3d 3d 28  if( SQLITE_OK==(
12170 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 50 61 67  rc = walIndexPag
12180 65 28 70 57 61 6c 2c 20 30 2c 20 26 70 61 67 65  e(pWal, 0, &page
12190 30 29 29 20 29 7b 0a 20 20 20 20 20 20 20 20 62  0)) ){.        b
121a0 61 64 48 64 72 20 3d 20 77 61 6c 49 6e 64 65 78  adHdr = walIndex
121b0 54 72 79 48 64 72 28 70 57 61 6c 2c 20 70 43 68  TryHdr(pWal, pCh
121c0 61 6e 67 65 64 29 3b 0a 20 20 20 20 20 20 20 20  anged);.        
121d0 69 66 28 20 62 61 64 48 64 72 20 29 7b 0a 20 20  if( badHdr ){.  
121e0 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68          /* If th
121f0 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
12200 65 72 20 69 73 20 73 74 69 6c 6c 20 6d 61 6c 66  er is still malf
12210 6f 72 6d 65 64 20 65 76 65 6e 20 77 68 69 6c 65  ormed even while
12220 20 68 6f 6c 64 69 6e 67 0a 20 20 20 20 20 20 20   holding.       
12230 20 20 20 2a 2a 20 61 20 57 52 49 54 45 20 6c 6f     ** a WRITE lo
12240 63 6b 2c 20 69 74 20 63 61 6e 20 6f 6e 6c 79 20  ck, it can only 
12250 6d 65 61 6e 20 74 68 61 74 20 74 68 65 20 68 65  mean that the he
12260 61 64 65 72 20 69 73 20 63 6f 72 72 75 70 74 65  ader is corrupte
12270 64 20 61 6e 64 0a 20 20 20 20 20 20 20 20 20 20  d and.          
12280 2a 2a 20 6e 65 65 64 73 20 74 6f 20 62 65 20 72  ** needs to be r
12290 65 63 6f 6e 73 74 72 75 63 74 65 64 2e 20 20 53  econstructed.  S
122a0 6f 20 72 75 6e 20 72 65 63 6f 76 65 72 79 20 74  o run recovery t
122b0 6f 20 64 6f 20 65 78 61 63 74 6c 79 20 74 68 61  o do exactly tha
122c0 74 2e 0a 20 20 20 20 20 20 20 20 20 20 2a 2f 0a  t..          */.
122d0 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 77            rc = w
122e0 61 6c 49 6e 64 65 78 52 65 63 6f 76 65 72 28 70  alIndexRecover(p
122f0 57 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Wal);.          
12300 2a 70 43 68 61 6e 67 65 64 20 3d 20 31 3b 0a 20  *pChanged = 1;. 
12310 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
12320 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 77 72 69  .      pWal->wri
12330 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20  teLock = 0;.    
12340 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75    walUnlockExclu
12350 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57  sive(pWal, WAL_W
12360 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  RITE_LOCK, 1);. 
12370 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49     }.  }..  /* I
12380 66 20 74 68 65 20 68 65 61 64 65 72 20 69 73 20  f the header is 
12390 72 65 61 64 20 73 75 63 63 65 73 73 66 75 6c 6c  read successfull
123a0 79 2c 20 63 68 65 63 6b 20 74 68 65 20 76 65 72  y, check the ver
123b0 73 69 6f 6e 20 6e 75 6d 62 65 72 20 74 6f 20 6d  sion number to m
123c0 61 6b 65 0a 20 20 2a 2a 20 73 75 72 65 20 74 68  ake.  ** sure th
123d0 65 20 77 61 6c 2d 69 6e 64 65 78 20 77 61 73 20  e wal-index was 
123e0 6e 6f 74 20 63 6f 6e 73 74 72 75 63 74 65 64 20  not constructed 
123f0 77 69 74 68 20 73 6f 6d 65 20 66 75 74 75 72 65  with some future
12400 20 66 6f 72 6d 61 74 20 74 68 61 74 0a 20 20 2a   format that.  *
12410 2a 20 74 68 69 73 20 76 65 72 73 69 6f 6e 20 6f  * this version o
12420 66 20 53 51 4c 69 74 65 20 63 61 6e 6e 6f 74 20  f SQLite cannot 
12430 75 6e 64 65 72 73 74 61 6e 64 2e 0a 20 20 2a 2f  understand..  */
12440 0a 20 20 69 66 28 20 62 61 64 48 64 72 3d 3d 30  .  if( badHdr==0
12450 20 26 26 20 70 57 61 6c 2d 3e 68 64 72 2e 69 56   && pWal->hdr.iV
12460 65 72 73 69 6f 6e 21 3d 57 41 4c 49 4e 44 45 58  ersion!=WALINDEX
12470 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 20 29 7b 0a  _MAX_VERSION ){.
12480 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
12490 43 41 4e 54 4f 50 45 4e 5f 42 4b 50 54 3b 0a 20  CANTOPEN_BKPT;. 
124a0 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
124b0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69  .}../*.** This i
124c0 73 20 74 68 65 20 76 61 6c 75 65 20 74 68 61 74  s the value that
124d0 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64   walTryBeginRead
124e0 20 72 65 74 75 72 6e 73 20 77 68 65 6e 20 69 74   returns when it
124f0 20 6e 65 65 64 73 20 74 6f 0a 2a 2a 20 62 65 20   needs to.** be 
12500 72 65 74 72 69 65 64 2e 0a 2a 2f 0a 23 64 65 66  retried..*/.#def
12510 69 6e 65 20 57 41 4c 5f 52 45 54 52 59 20 20 28  ine WAL_RETRY  (
12520 2d 31 29 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d  -1)../*.** Attem
12530 70 74 20 74 6f 20 73 74 61 72 74 20 61 20 72 65  pt to start a re
12540 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20  ad transaction. 
12550 20 54 68 69 73 20 6d 69 67 68 74 20 66 61 69 6c   This might fail
12560 20 64 75 65 20 74 6f 20 61 20 72 61 63 65 20 6f   due to a race o
12570 72 0a 2a 2a 20 6f 74 68 65 72 20 74 72 61 6e 73  r.** other trans
12580 69 65 6e 74 20 63 6f 6e 64 69 74 69 6f 6e 2e 20  ient condition. 
12590 20 57 68 65 6e 20 74 68 61 74 20 68 61 70 70 65   When that happe
125a0 6e 73 2c 20 69 74 20 72 65 74 75 72 6e 73 20 57  ns, it returns W
125b0 41 4c 5f 52 45 54 52 59 20 74 6f 0a 2a 2a 20 69  AL_RETRY to.** i
125c0 6e 64 69 63 61 74 65 20 74 6f 20 74 68 65 20 63  ndicate to the c
125d0 61 6c 6c 65 72 20 74 68 61 74 20 69 74 20 69 73  aller that it is
125e0 20 73 61 66 65 20 74 6f 20 72 65 74 72 79 20 69   safe to retry i
125f0 6d 6d 65 64 69 61 74 65 6c 79 2e 0a 2a 2a 0a 2a  mmediately..**.*
12600 2a 20 4f 6e 20 73 75 63 63 65 73 73 20 72 65 74  * On success ret
12610 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 20  urn SQLITE_OK.  
12620 4f 6e 20 61 20 70 65 72 6d 61 6e 65 6e 74 20 66  On a permanent f
12630 61 69 6c 75 72 65 20 28 73 75 63 68 20 61 6e 0a  ailure (such an.
12640 2a 2a 20 49 2f 4f 20 65 72 72 6f 72 20 6f 72 20  ** I/O error or 
12650 61 6e 20 53 51 4c 49 54 45 5f 42 55 53 59 20 62  an SQLITE_BUSY b
12660 65 63 61 75 73 65 20 61 6e 6f 74 68 65 72 20 70  ecause another p
12670 72 6f 63 65 73 73 20 69 73 20 72 75 6e 6e 69 6e  rocess is runnin
12680 67 0a 2a 2a 20 72 65 63 6f 76 65 72 79 29 20 72  g.** recovery) r
12690 65 74 75 72 6e 20 61 20 70 6f 73 69 74 69 76 65  eturn a positive
126a0 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2a 0a   error code..**.
126b0 2a 2a 20 54 68 65 20 75 73 65 57 61 6c 20 70 61  ** The useWal pa
126c0 72 61 6d 65 74 65 72 20 69 73 20 74 72 75 65 20  rameter is true 
126d0 74 6f 20 66 6f 72 63 65 20 74 68 65 20 75 73 65  to force the use
126e0 20 6f 66 20 74 68 65 20 57 41 4c 20 61 6e 64 20   of the WAL and 
126f0 64 69 73 61 62 6c 65 0a 2a 2a 20 74 68 65 20 63  disable.** the c
12700 61 73 65 20 77 68 65 72 65 20 74 68 65 20 57 41  ase where the WA
12710 4c 20 69 73 20 62 79 70 61 73 73 65 64 20 62 65  L is bypassed be
12720 63 61 75 73 65 20 69 74 20 68 61 73 20 62 65 65  cause it has bee
12730 6e 20 63 6f 6d 70 6c 65 74 65 6c 79 0a 2a 2a 20  n completely.** 
12740 63 68 65 63 6b 70 6f 69 6e 74 65 64 2e 20 20 49  checkpointed.  I
12750 66 20 75 73 65 57 61 6c 3d 3d 30 20 74 68 65 6e  f useWal==0 then
12760 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 63 61   this routine ca
12770 6c 6c 73 20 77 61 6c 49 6e 64 65 78 52 65 61 64  lls walIndexRead
12780 48 64 72 28 29 20 0a 2a 2a 20 74 6f 20 6d 61 6b  Hdr() .** to mak
12790 65 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20  e a copy of the 
127a0 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
127b0 20 69 6e 74 6f 20 70 57 61 6c 2d 3e 68 64 72 2e   into pWal->hdr.
127c0 20 20 49 66 20 74 68 65 20 0a 2a 2a 20 77 61 6c    If the .** wal
127d0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 68 61  -index header ha
127e0 73 20 63 68 61 6e 67 65 64 2c 20 2a 70 43 68 61  s changed, *pCha
127f0 6e 67 65 64 20 69 73 20 73 65 74 20 74 6f 20 31  nged is set to 1
12800 20 28 61 73 20 61 6e 20 69 6e 64 69 63 61 74 69   (as an indicati
12810 6f 6e 20 0a 2a 2a 20 74 6f 20 74 68 65 20 63 61  on .** to the ca
12820 6c 6c 65 72 20 74 68 61 74 20 74 68 65 20 6c 6f  ller that the lo
12830 63 61 6c 20 70 61 67 65 74 20 63 61 63 68 65 20  cal paget cache 
12840 69 73 20 6f 62 73 6f 6c 65 74 65 20 61 6e 64 20  is obsolete and 
12850 6e 65 65 64 73 20 74 6f 20 62 65 20 0a 2a 2a 20  needs to be .** 
12860 66 6c 75 73 68 65 64 2e 29 20 20 57 68 65 6e 20  flushed.)  When 
12870 75 73 65 57 61 6c 3d 3d 31 2c 20 74 68 65 20 77  useWal==1, the w
12880 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
12890 69 73 20 61 73 73 75 6d 65 64 20 74 6f 20 61 6c  is assumed to al
128a0 72 65 61 64 79 0a 2a 2a 20 62 65 20 6c 6f 61 64  ready.** be load
128b0 65 64 20 61 6e 64 20 74 68 65 20 70 43 68 61 6e  ed and the pChan
128c0 67 65 64 20 70 61 72 61 6d 65 74 65 72 20 69 73  ged parameter is
128d0 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 54   unused..**.** T
128e0 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 73  he caller must s
128f0 65 74 20 74 68 65 20 63 6e 74 20 70 61 72 61 6d  et the cnt param
12900 65 74 65 72 20 74 6f 20 74 68 65 20 6e 75 6d 62  eter to the numb
12910 65 72 20 6f 66 20 70 72 69 6f 72 20 63 61 6c 6c  er of prior call
12920 73 20 74 6f 0a 2a 2a 20 74 68 69 73 20 72 6f 75  s to.** this rou
12930 74 69 6e 65 20 64 75 72 69 6e 67 20 74 68 65 20  tine during the 
12940 63 75 72 72 65 6e 74 20 72 65 61 64 20 61 74 74  current read att
12950 65 6d 70 74 20 74 68 61 74 20 72 65 74 75 72 6e  empt that return
12960 65 64 20 57 41 4c 5f 52 45 54 52 59 2e 0a 2a 2a  ed WAL_RETRY..**
12970 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69   This routine wi
12980 6c 6c 20 73 74 61 72 74 20 74 61 6b 69 6e 67 20  ll start taking 
12990 6d 6f 72 65 20 61 67 67 72 65 73 73 69 76 65 20  more aggressive 
129a0 6d 65 61 73 75 72 65 73 20 74 6f 20 63 6c 65 61  measures to clea
129b0 72 20 74 68 65 0a 2a 2a 20 72 61 63 65 20 63 6f  r the.** race co
129c0 6e 64 69 74 69 6f 6e 73 20 61 66 74 65 72 20 6d  nditions after m
129d0 75 6c 74 69 70 6c 65 20 57 41 4c 5f 52 45 54 52  ultiple WAL_RETR
129e0 59 20 72 65 74 75 72 6e 73 2c 20 61 6e 64 20 61  Y returns, and a
129f0 66 74 65 72 20 61 6e 20 65 78 63 65 73 73 69 76  fter an excessiv
12a00 65 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 65  e.** number of e
12a10 72 72 6f 72 73 20 77 69 6c 6c 20 75 6c 74 69 6d  rrors will ultim
12a20 61 74 65 6c 79 20 72 65 74 75 72 6e 20 53 51 4c  ately return SQL
12a30 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 2e 20 20 54  ITE_PROTOCOL.  T
12a40 68 65 0a 2a 2a 20 53 51 4c 49 54 45 5f 50 52 4f  he.** SQLITE_PRO
12a50 54 4f 43 4f 4c 20 72 65 74 75 72 6e 20 69 6e 64  TOCOL return ind
12a60 69 63 61 74 65 73 20 74 68 61 74 20 73 6f 6d 65  icates that some
12a70 20 6f 74 68 65 72 20 70 72 6f 63 65 73 73 20 68   other process h
12a80 61 73 20 67 6f 6e 65 20 72 6f 67 75 65 0a 2a 2a  as gone rogue.**
12a90 20 61 6e 64 20 69 73 20 6e 6f 74 20 68 6f 6e 6f   and is not hono
12aa0 72 69 6e 67 20 74 68 65 20 6c 6f 63 6b 69 6e 67  ring the locking
12ab0 20 70 72 6f 74 6f 63 6f 6c 2e 20 20 54 68 65 72   protocol.  Ther
12ac0 65 20 69 73 20 61 20 76 61 6e 69 73 68 69 6e 67  e is a vanishing
12ad0 6c 79 20 73 6d 61 6c 6c 0a 2a 2a 20 63 68 61 6e  ly small.** chan
12ae0 63 65 20 74 68 61 74 20 53 51 4c 49 54 45 5f 50  ce that SQLITE_P
12af0 52 4f 54 4f 43 4f 4c 20 63 6f 75 6c 64 20 62 65  ROTOCOL could be
12b00 20 72 65 74 75 72 6e 65 64 20 62 65 63 61 75 73   returned becaus
12b10 65 20 6f 66 20 61 20 72 75 6e 20 6f 66 20 72 65  e of a run of re
12b20 61 6c 6c 79 0a 2a 2a 20 62 61 64 20 6c 75 63 6b  ally.** bad luck
12b30 20 77 68 65 6e 20 74 68 65 72 65 20 69 73 20 6c   when there is l
12b40 6f 74 73 20 6f 66 20 63 6f 6e 74 65 6e 74 69 6f  ots of contentio
12b50 6e 20 66 6f 72 20 74 68 65 20 77 61 6c 2d 69 6e  n for the wal-in
12b60 64 65 78 2c 20 62 75 74 20 74 68 61 74 0a 2a 2a  dex, but that.**
12b70 20 70 6f 73 73 69 62 69 6c 69 74 79 20 69 73 20   possibility is 
12b80 73 6f 20 73 6d 61 6c 6c 20 74 68 61 74 20 69 74  so small that it
12b90 20 63 61 6e 20 62 65 20 73 61 66 65 6c 79 20 6e   can be safely n
12ba0 65 67 6c 65 63 74 65 64 2c 20 77 65 20 62 65 6c  eglected, we bel
12bb0 69 65 76 65 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73  ieve..**.** On s
12bc0 75 63 63 65 73 73 2c 20 74 68 69 73 20 72 6f 75  uccess, this rou
12bd0 74 69 6e 65 20 6f 62 74 61 69 6e 73 20 61 20 72  tine obtains a r
12be0 65 61 64 20 6c 6f 63 6b 20 6f 6e 20 0a 2a 2a 20  ead lock on .** 
12bf0 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57  WAL_READ_LOCK(pW
12c00 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 2e 20 20  al->readLock).  
12c10 54 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  The pWal->readLo
12c20 63 6b 20 69 6e 74 65 67 65 72 20 69 73 0a 2a 2a  ck integer is.**
12c30 20 69 6e 20 74 68 65 20 72 61 6e 67 65 20 30 20   in the range 0 
12c40 3c 3d 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  <= pWal->readLoc
12c50 6b 20 3c 20 57 41 4c 5f 4e 52 45 41 44 45 52 2e  k < WAL_NREADER.
12c60 20 20 49 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c    If pWal->readL
12c70 6f 63 6b 3d 3d 28 2d 31 29 0a 2a 2a 20 74 68 61  ock==(-1).** tha
12c80 74 20 6d 65 61 6e 73 20 74 68 65 20 57 61 6c 20  t means the Wal 
12c90 64 6f 65 73 20 6e 6f 74 20 68 6f 6c 64 20 61 6e  does not hold an
12ca0 79 20 72 65 61 64 20 6c 6f 63 6b 2e 20 20 54 68  y read lock.  Th
12cb0 65 20 72 65 61 64 65 72 20 6d 75 73 74 20 6e 6f  e reader must no
12cc0 74 0a 2a 2a 20 61 63 63 65 73 73 20 61 6e 79 20  t.** access any 
12cd0 64 61 74 61 62 61 73 65 20 70 61 67 65 20 74 68  database page th
12ce0 61 74 20 69 73 20 6d 6f 64 69 66 69 65 64 20 62  at is modified b
12cf0 79 20 61 20 57 41 4c 20 66 72 61 6d 65 20 75 70  y a WAL frame up
12d00 20 74 6f 20 61 6e 64 0a 2a 2a 20 69 6e 63 6c 75   to and.** inclu
12d10 64 69 6e 67 20 66 72 61 6d 65 20 6e 75 6d 62 65  ding frame numbe
12d20 72 20 61 52 65 61 64 4d 61 72 6b 5b 70 57 61 6c  r aReadMark[pWal
12d30 2d 3e 72 65 61 64 4c 6f 63 6b 5d 2e 20 20 54 68  ->readLock].  Th
12d40 65 20 72 65 61 64 65 72 20 77 69 6c 6c 0a 2a 2a  e reader will.**
12d50 20 75 73 65 20 57 41 4c 20 66 72 61 6d 65 73 20   use WAL frames 
12d60 75 70 20 74 6f 20 61 6e 64 20 69 6e 63 6c 75 64  up to and includ
12d70 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  ing pWal->hdr.mx
12d80 46 72 61 6d 65 20 69 66 20 70 57 61 6c 2d 3e 72  Frame if pWal->r
12d90 65 61 64 4c 6f 63 6b 3e 30 0a 2a 2a 20 4f 72 20  eadLock>0.** Or 
12da0 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  if pWal->readLoc
12db0 6b 3d 3d 30 2c 20 74 68 65 6e 20 74 68 65 20 72  k==0, then the r
12dc0 65 61 64 65 72 20 77 69 6c 6c 20 69 67 6e 6f 72  eader will ignor
12dd0 65 20 74 68 65 20 57 41 4c 0a 2a 2a 20 63 6f 6d  e the WAL.** com
12de0 70 6c 65 74 65 6c 79 20 61 6e 64 20 67 65 74 20  pletely and get 
12df0 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72 65  all content dire
12e00 63 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64 61  ctly from the da
12e10 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 20  tabase file..** 
12e20 49 66 20 74 68 65 20 75 73 65 57 61 6c 20 70 61  If the useWal pa
12e30 72 61 6d 65 74 65 72 20 69 73 20 31 20 74 68 65  rameter is 1 the
12e40 6e 20 74 68 65 20 57 41 4c 20 77 69 6c 6c 20 6e  n the WAL will n
12e50 65 76 65 72 20 62 65 20 69 67 6e 6f 72 65 64 20  ever be ignored 
12e60 61 6e 64 0a 2a 2a 20 74 68 69 73 20 72 6f 75 74  and.** this rout
12e70 69 6e 65 20 77 69 6c 6c 20 61 6c 77 61 79 73 20  ine will always 
12e80 73 65 74 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  set pWal->readLo
12e90 63 6b 3e 30 20 6f 6e 20 73 75 63 63 65 73 73 2e  ck>0 on success.
12ea0 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 72 65 61  .** When the rea
12eb0 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73  d transaction is
12ec0 20 63 6f 6d 70 6c 65 74 65 64 2c 20 74 68 65 20   completed, the 
12ed0 63 61 6c 6c 65 72 20 6d 75 73 74 20 72 65 6c 65  caller must rele
12ee0 61 73 65 20 74 68 65 0a 2a 2a 20 6c 6f 63 6b 20  ase the.** lock 
12ef0 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  on WAL_READ_LOCK
12f00 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29  (pWal->readLock)
12f10 20 61 6e 64 20 73 65 74 20 70 57 61 6c 2d 3e 72   and set pWal->r
12f20 65 61 64 4c 6f 63 6b 20 74 6f 20 2d 31 2e 0a 2a  eadLock to -1..*
12f30 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  *.** This routin
12f40 65 20 75 73 65 73 20 74 68 65 20 6e 42 61 63 6b  e uses the nBack
12f50 66 69 6c 6c 20 61 6e 64 20 61 52 65 61 64 4d 61  fill and aReadMa
12f60 72 6b 5b 5d 20 66 69 65 6c 64 73 20 6f 66 20 74  rk[] fields of t
12f70 68 65 20 68 65 61 64 65 72 0a 2a 2a 20 74 6f 20  he header.** to 
12f80 73 65 6c 65 63 74 20 61 20 70 61 72 74 69 63 75  select a particu
12f90 6c 61 72 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  lar WAL_READ_LOC
12fa0 4b 28 29 20 74 68 61 74 20 73 74 72 69 76 65 73  K() that strives
12fb0 20 74 6f 20 6c 65 74 20 74 68 65 0a 2a 2a 20 63   to let the.** c
12fc0 68 65 63 6b 70 6f 69 6e 74 20 70 72 6f 63 65 73  heckpoint proces
12fd0 73 20 64 6f 20 61 73 20 6d 75 63 68 20 77 6f 72  s do as much wor
12fe0 6b 20 61 73 20 70 6f 73 73 69 62 6c 65 2e 20 20  k as possible.  
12ff0 54 68 69 73 20 72 6f 75 74 69 6e 65 20 6d 69 67  This routine mig
13000 68 74 0a 2a 2a 20 75 70 64 61 74 65 20 76 61 6c  ht.** update val
13010 75 65 73 20 6f 66 20 74 68 65 20 61 52 65 61 64  ues of the aRead
13020 4d 61 72 6b 5b 5d 20 61 72 72 61 79 20 69 6e 20  Mark[] array in 
13030 74 68 65 20 68 65 61 64 65 72 2c 20 62 75 74 20  the header, but 
13040 69 66 20 69 74 20 64 6f 65 73 0a 2a 2a 20 73 6f  if it does.** so
13050 20 69 74 20 74 61 6b 65 73 20 63 61 72 65 20 74   it takes care t
13060 6f 20 68 6f 6c 64 20 61 6e 20 65 78 63 6c 75 73  o hold an exclus
13070 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 74 68 65 20  ive lock on the 
13080 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 0a 2a 2a  corresponding.**
13090 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 29   WAL_READ_LOCK()
130a0 20 77 68 69 6c 65 20 63 68 61 6e 67 69 6e 67 20   while changing 
130b0 76 61 6c 75 65 73 2e 0a 2a 2f 0a 73 74 61 74 69  values..*/.stati
130c0 63 20 69 6e 74 20 77 61 6c 54 72 79 42 65 67 69  c int walTryBegi
130d0 6e 52 65 61 64 28 57 61 6c 20 2a 70 57 61 6c 2c  nRead(Wal *pWal,
130e0 20 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 2c 20   int *pChanged, 
130f0 69 6e 74 20 75 73 65 57 61 6c 2c 20 69 6e 74 20  int useWal, int 
13100 63 6e 74 29 7b 0a 20 20 76 6f 6c 61 74 69 6c 65  cnt){.  volatile
13110 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49   WalCkptInfo *pI
13120 6e 66 6f 3b 20 20 20 20 2f 2a 20 43 68 65 63 6b  nfo;    /* Check
13130 70 6f 69 6e 74 20 69 6e 66 6f 72 6d 61 74 69 6f  point informatio
13140 6e 20 69 6e 20 77 61 6c 2d 69 6e 64 65 78 20 2a  n in wal-index *
13150 2f 0a 20 20 75 33 32 20 6d 78 52 65 61 64 4d 61  /.  u32 mxReadMa
13160 72 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rk;             
13170 20 20 20 20 2f 2a 20 4c 61 72 67 65 73 74 20 61      /* Largest a
13180 52 65 61 64 4d 61 72 6b 5b 5d 20 76 61 6c 75 65  ReadMark[] value
13190 20 2a 2f 0a 20 20 69 6e 74 20 6d 78 49 3b 20 20   */.  int mxI;  
131a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
131b0 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f        /* Index o
131c0 66 20 6c 61 72 67 65 73 74 20 61 52 65 61 64 4d  f largest aReadM
131d0 61 72 6b 5b 5d 20 76 61 6c 75 65 20 2a 2f 0a 20  ark[] value */. 
131e0 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
131f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13200 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72   /* Loop counter
13210 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   */.  int rc = S
13220 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
13230 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
13240 63 6f 64 65 20 20 2a 2f 0a 0a 20 20 61 73 73 65  code  */..  asse
13250 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  rt( pWal->readLo
13260 63 6b 3c 30 20 29 3b 20 20 20 20 20 2f 2a 20 4e  ck<0 );     /* N
13270 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 6c 6f 63  ot currently loc
13280 6b 65 64 20 2a 2f 0a 0a 20 20 2f 2a 20 54 61 6b  ked */..  /* Tak
13290 65 20 73 74 65 70 73 20 74 6f 20 61 76 6f 69 64  e steps to avoid
132a0 20 73 70 69 6e 6e 69 6e 67 20 66 6f 72 65 76 65   spinning foreve
132b0 72 20 69 66 20 74 68 65 72 65 20 69 73 20 61 20  r if there is a 
132c0 70 72 6f 74 6f 63 6f 6c 20 65 72 72 6f 72 2e 0a  protocol error..
132d0 20 20 2a 2a 0a 20 20 2a 2a 20 43 69 72 63 75 6d    **.  ** Circum
132e0 73 74 61 6e 63 65 73 20 74 68 61 74 20 63 61 75  stances that cau
132f0 73 65 20 61 20 52 45 54 52 59 20 73 68 6f 75 6c  se a RETRY shoul
13300 64 20 6f 6e 6c 79 20 6c 61 73 74 20 66 6f 72 20  d only last for 
13310 74 68 65 20 62 72 69 65 66 65 73 74 0a 20 20 2a  the briefest.  *
13320 2a 20 69 6e 73 74 61 6e 63 65 73 20 6f 66 20 74  * instances of t
13330 69 6d 65 2e 20 20 4e 6f 20 49 2f 4f 20 6f 72 20  ime.  No I/O or 
13340 6f 74 68 65 72 20 73 79 73 74 65 6d 20 63 61 6c  other system cal
13350 6c 73 20 61 72 65 20 64 6f 6e 65 20 77 68 69 6c  ls are done whil
13360 65 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 63 6b 73  e the.  ** locks
13370 20 61 72 65 20 68 65 6c 64 2c 20 73 6f 20 74 68   are held, so th
13380 65 20 6c 6f 63 6b 73 20 73 68 6f 75 6c 64 20 6e  e locks should n
13390 6f 74 20 62 65 20 68 65 6c 64 20 66 6f 72 20 76  ot be held for v
133a0 65 72 79 20 6c 6f 6e 67 2e 20 42 75 74 20 0a 20  ery long. But . 
133b0 20 2a 2a 20 69 66 20 77 65 20 61 72 65 20 75 6e   ** if we are un
133c0 6c 75 63 6b 79 2c 20 61 6e 6f 74 68 65 72 20 70  lucky, another p
133d0 72 6f 63 65 73 73 20 74 68 61 74 20 69 73 20 68  rocess that is h
133e0 6f 6c 64 69 6e 67 20 61 20 6c 6f 63 6b 20 6d 69  olding a lock mi
133f0 67 68 74 20 67 65 74 0a 20 20 2a 2a 20 70 61 67  ght get.  ** pag
13400 65 64 20 6f 75 74 20 6f 72 20 74 61 6b 65 20 61  ed out or take a
13410 20 70 61 67 65 2d 66 61 75 6c 74 20 74 68 61 74   page-fault that
13420 20 69 73 20 74 69 6d 65 2d 63 6f 6e 73 75 6d 69   is time-consumi
13430 6e 67 20 74 6f 20 72 65 73 6f 6c 76 65 2c 20 0a  ng to resolve, .
13440 20 20 2a 2a 20 64 75 72 69 6e 67 20 74 68 65 20    ** during the 
13450 66 65 77 20 6e 61 6e 6f 73 65 63 6f 6e 64 73 20  few nanoseconds 
13460 74 68 61 74 20 69 74 20 69 73 20 68 6f 6c 64 69  that it is holdi
13470 6e 67 20 74 68 65 20 6c 6f 63 6b 2e 20 20 49 6e  ng the lock.  In
13480 20 74 68 61 74 20 63 61 73 65 2c 0a 20 20 2a 2a   that case,.  **
13490 20 69 74 20 6d 69 67 68 74 20 74 61 6b 65 20 6c   it might take l
134a0 6f 6e 67 65 72 20 74 68 61 6e 20 6e 6f 72 6d 61  onger than norma
134b0 6c 20 66 6f 72 20 74 68 65 20 6c 6f 63 6b 20 74  l for the lock t
134c0 6f 20 66 72 65 65 2e 0a 20 20 2a 2a 0a 20 20 2a  o free..  **.  *
134d0 2a 20 41 66 74 65 72 20 35 20 52 45 54 52 59 73  * After 5 RETRYs
134e0 2c 20 77 65 20 62 65 67 69 6e 20 63 61 6c 6c 69  , we begin calli
134f0 6e 67 20 73 71 6c 69 74 65 33 4f 73 53 6c 65 65  ng sqlite3OsSlee
13500 70 28 29 2e 20 20 54 68 65 20 66 69 72 73 74 20  p().  The first 
13510 66 65 77 0a 20 20 2a 2a 20 63 61 6c 6c 73 20 74  few.  ** calls t
13520 6f 20 73 71 6c 69 74 65 33 4f 73 53 6c 65 65 70  o sqlite3OsSleep
13530 28 29 20 68 61 76 65 20 61 20 64 65 6c 61 79 20  () have a delay 
13540 6f 66 20 31 20 6d 69 63 72 6f 73 65 63 6f 6e 64  of 1 microsecond
13550 2e 20 20 52 65 61 6c 6c 79 20 74 68 69 73 0a 20  .  Really this. 
13560 20 2a 2a 20 69 73 20 6d 6f 72 65 20 6f 66 20 61   ** is more of a
13570 20 73 63 68 65 64 75 6c 65 72 20 79 69 65 6c 64   scheduler yield
13580 20 74 68 61 6e 20 61 6e 20 61 63 74 75 61 6c 20   than an actual 
13590 64 65 6c 61 79 2e 20 20 42 75 74 20 6f 6e 20 74  delay.  But on t
135a0 68 65 20 31 30 74 68 0a 20 20 2a 2a 20 61 6e 20  he 10th.  ** an 
135b0 73 75 62 73 65 71 75 65 6e 74 20 72 65 74 72 69  subsequent retri
135c0 65 73 2c 20 74 68 65 20 64 65 6c 61 79 73 20 73  es, the delays s
135d0 74 61 72 74 20 62 65 63 6f 6d 69 6e 67 20 6c 6f  tart becoming lo
135e0 6e 67 65 72 20 61 6e 64 20 6c 6f 6e 67 65 72 2c  nger and longer,
135f0 20 0a 20 20 2a 2a 20 73 6f 20 74 68 61 74 20 6f   .  ** so that o
13600 6e 20 74 68 65 20 31 30 30 74 68 20 28 61 6e 64  n the 100th (and
13610 20 6c 61 73 74 29 20 52 45 54 52 59 20 77 65 20   last) RETRY we 
13620 64 65 6c 61 79 20 66 6f 72 20 32 31 20 6d 69 6c  delay for 21 mil
13630 6c 69 73 65 63 6f 6e 64 73 2e 0a 20 20 2a 2a 20  liseconds..  ** 
13640 54 68 65 20 74 6f 74 61 6c 20 64 65 6c 61 79 20  The total delay 
13650 74 69 6d 65 20 62 65 66 6f 72 65 20 67 69 76 69  time before givi
13660 6e 67 20 75 70 20 69 73 20 6c 65 73 73 20 74 68  ng up is less th
13670 61 6e 20 31 20 73 65 63 6f 6e 64 2e 0a 20 20 2a  an 1 second..  *
13680 2f 0a 20 20 69 66 28 20 63 6e 74 3e 35 20 29 7b  /.  if( cnt>5 ){
13690 0a 20 20 20 20 69 6e 74 20 6e 44 65 6c 61 79 20  .    int nDelay 
136a0 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 1;            
136b0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 75            /* Pau
136c0 73 65 20 74 69 6d 65 20 69 6e 20 6d 69 63 72 6f  se time in micro
136d0 73 65 63 6f 6e 64 73 20 2a 2f 0a 20 20 20 20 69  seconds */.    i
136e0 66 28 20 63 6e 74 3e 31 30 30 20 29 7b 0a 20 20  f( cnt>100 ){.  
136f0 20 20 20 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57      VVA_ONLY( pW
13700 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20  al->lockError = 
13710 31 3b 20 29 0a 20 20 20 20 20 20 72 65 74 75 72  1; ).      retur
13720 6e 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f  n SQLITE_PROTOCO
13730 4c 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  L;.    }.    if(
13740 20 63 6e 74 3e 3d 31 30 20 29 20 6e 44 65 6c 61   cnt>=10 ) nDela
13750 79 20 3d 20 28 63 6e 74 2d 39 29 2a 32 33 38 3b  y = (cnt-9)*238;
13760 20 20 2f 2a 20 4d 61 78 20 64 65 6c 61 79 20 32    /* Max delay 2
13770 31 6d 73 2e 20 54 6f 74 61 6c 20 64 65 6c 61 79  1ms. Total delay
13780 20 39 39 36 6d 73 20 2a 2f 0a 20 20 20 20 73 71   996ms */.    sq
13790 6c 69 74 65 33 4f 73 53 6c 65 65 70 28 70 57 61  lite3OsSleep(pWa
137a0 6c 2d 3e 70 56 66 73 2c 20 6e 44 65 6c 61 79 29  l->pVfs, nDelay)
137b0 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21 75 73  ;.  }..  if( !us
137c0 65 57 61 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d  eWal ){.    rc =
137d0 20 77 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72   walIndexReadHdr
137e0 28 70 57 61 6c 2c 20 70 43 68 61 6e 67 65 64 29  (pWal, pChanged)
137f0 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
13800 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
13810 20 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69     /* If there i
13820 73 20 6e 6f 74 20 61 20 72 65 63 6f 76 65 72 79  s not a recovery
13830 20 72 75 6e 6e 69 6e 67 20 69 6e 20 61 6e 6f 74   running in anot
13840 68 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72  her thread or pr
13850 6f 63 65 73 73 0a 20 20 20 20 20 20 2a 2a 20 74  ocess.      ** t
13860 68 65 6e 20 63 6f 6e 76 65 72 74 20 42 55 53 59  hen convert BUSY
13870 20 65 72 72 6f 72 73 20 74 6f 20 57 41 4c 5f 52   errors to WAL_R
13880 45 54 52 59 2e 20 20 49 66 20 72 65 63 6f 76 65  ETRY.  If recove
13890 72 79 20 69 73 20 6b 6e 6f 77 6e 20 74 6f 0a 20  ry is known to. 
138a0 20 20 20 20 20 2a 2a 20 62 65 20 72 75 6e 6e 69       ** be runni
138b0 6e 67 2c 20 63 6f 6e 76 65 72 74 20 42 55 53 59  ng, convert BUSY
138c0 20 74 6f 20 42 55 53 59 5f 52 45 43 4f 56 45 52   to BUSY_RECOVER
138d0 59 2e 20 20 54 68 65 72 65 20 69 73 20 61 20 72  Y.  There is a r
138e0 61 63 65 20 68 65 72 65 0a 20 20 20 20 20 20 2a  ace here.      *
138f0 2a 20 77 68 69 63 68 20 6d 69 67 68 74 20 63 61  * which might ca
13900 75 73 65 20 57 41 4c 5f 52 45 54 52 59 20 74 6f  use WAL_RETRY to
13910 20 62 65 20 72 65 74 75 72 6e 65 64 20 65 76 65   be returned eve
13920 6e 20 69 66 20 42 55 53 59 5f 52 45 43 4f 56 45  n if BUSY_RECOVE
13930 52 59 0a 20 20 20 20 20 20 2a 2a 20 77 6f 75 6c  RY.      ** woul
13940 64 20 62 65 20 74 65 63 68 6e 69 63 61 6c 6c 79  d be technically
13950 20 63 6f 72 72 65 63 74 2e 20 20 42 75 74 20 74   correct.  But t
13960 68 65 20 72 61 63 65 20 69 73 20 62 65 6e 69 67  he race is benig
13970 6e 20 73 69 6e 63 65 20 77 69 74 68 0a 20 20 20  n since with.   
13980 20 20 20 2a 2a 20 57 41 4c 5f 52 45 54 52 59 20     ** WAL_RETRY 
13990 74 68 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c  this routine wil
139a0 6c 20 62 65 20 63 61 6c 6c 65 64 20 61 67 61 69  l be called agai
139b0 6e 20 61 6e 64 20 77 69 6c 6c 20 70 72 6f 62 61  n and will proba
139c0 62 6c 79 20 62 65 0a 20 20 20 20 20 20 2a 2a 20  bly be.      ** 
139d0 72 69 67 68 74 20 6f 6e 20 74 68 65 20 73 65 63  right on the sec
139e0 6f 6e 64 20 69 74 65 72 61 74 69 6f 6e 2e 0a 20  ond iteration.. 
139f0 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 69 66       */.      if
13a00 28 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61  ( pWal->apWiData
13a10 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  [0]==0 ){.      
13a20 20 20 2f 2a 20 54 68 69 73 20 62 72 61 6e 63 68    /* This branch
13a30 20 69 73 20 74 61 6b 65 6e 20 77 68 65 6e 20 74   is taken when t
13a40 68 65 20 78 53 68 6d 4d 61 70 28 29 20 6d 65 74  he xShmMap() met
13a50 68 6f 64 20 72 65 74 75 72 6e 73 20 53 51 4c 49  hod returns SQLI
13a60 54 45 5f 42 55 53 59 2e 0a 20 20 20 20 20 20 20  TE_BUSY..       
13a70 20 2a 2a 20 57 65 20 61 73 73 75 6d 65 20 74 68   ** We assume th
13a80 69 73 20 69 73 20 61 20 74 72 61 6e 73 69 65 6e  is is a transien
13a90 74 20 63 6f 6e 64 69 74 69 6f 6e 2c 20 73 6f 20  t condition, so 
13aa0 72 65 74 75 72 6e 20 57 41 4c 5f 52 45 54 52 59  return WAL_RETRY
13ab0 2e 20 54 68 65 0a 20 20 20 20 20 20 20 20 2a 2a  . The.        **
13ac0 20 78 53 68 6d 4d 61 70 28 29 20 69 6d 70 6c 65   xShmMap() imple
13ad0 6d 65 6e 74 61 74 69 6f 6e 20 75 73 65 64 20 62  mentation used b
13ae0 79 20 74 68 65 20 64 65 66 61 75 6c 74 20 75 6e  y the default un
13af0 69 78 20 61 6e 64 20 77 69 6e 33 32 20 56 46 53  ix and win32 VFS
13b00 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 6d 6f 64   .        ** mod
13b10 75 6c 65 73 20 6d 61 79 20 72 65 74 75 72 6e 20  ules may return 
13b20 53 51 4c 49 54 45 5f 42 55 53 59 20 64 75 65 20  SQLITE_BUSY due 
13b30 74 6f 20 61 20 72 61 63 65 20 63 6f 6e 64 69 74  to a race condit
13b40 69 6f 6e 20 69 6e 20 74 68 65 20 0a 20 20 20 20  ion in the .    
13b50 20 20 20 20 2a 2a 20 63 6f 64 65 20 74 68 61 74      ** code that
13b60 20 64 65 74 65 72 6d 69 6e 65 73 20 77 68 65 74   determines whet
13b70 68 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 73  her or not the s
13b80 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20 72 65 67  hared-memory reg
13b90 69 6f 6e 20 0a 20 20 20 20 20 20 20 20 2a 2a 20  ion .        ** 
13ba0 6d 75 73 74 20 62 65 20 7a 65 72 6f 65 64 20 62  must be zeroed b
13bb0 65 66 6f 72 65 20 74 68 65 20 72 65 71 75 65 73  efore the reques
13bc0 74 65 64 20 70 61 67 65 20 69 73 20 72 65 74 75  ted page is retu
13bd0 72 6e 65 64 2e 0a 20 20 20 20 20 20 20 20 2a 2f  rned..        */
13be0 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 57 41  .        rc = WA
13bf0 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d  L_RETRY;.      }
13c00 65 6c 73 65 20 69 66 28 20 53 51 4c 49 54 45 5f  else if( SQLITE_
13c10 4f 4b 3d 3d 28 72 63 20 3d 20 77 61 6c 4c 6f 63  OK==(rc = walLoc
13c20 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
13c30 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 29 29  L_RECOVER_LOCK))
13c40 20 29 7b 0a 20 20 20 20 20 20 20 20 77 61 6c 55   ){.        walU
13c50 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
13c60 2c 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f  , WAL_RECOVER_LO
13c70 43 4b 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20  CK);.        rc 
13c80 3d 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20  = WAL_RETRY;.   
13c90 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 3d     }else if( rc=
13ca0 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a  =SQLITE_BUSY ){.
13cb0 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
13cc0 49 54 45 5f 42 55 53 59 5f 52 45 43 4f 56 45 52  ITE_BUSY_RECOVER
13cd0 59 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  Y;.      }.    }
13ce0 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
13cf0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
13d00 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
13d10 0a 20 20 7d 0a 0a 20 20 70 49 6e 66 6f 20 3d 20  .  }..  pInfo = 
13d20 77 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c  walCkptInfo(pWal
13d30 29 3b 0a 20 20 69 66 28 20 21 75 73 65 57 61 6c  );.  if( !useWal
13d40 20 26 26 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b   && pInfo->nBack
13d50 66 69 6c 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e  fill==pWal->hdr.
13d60 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 2f  mxFrame ){.    /
13d70 2a 20 54 68 65 20 57 41 4c 20 68 61 73 20 62 65  * The WAL has be
13d80 65 6e 20 63 6f 6d 70 6c 65 74 65 6c 79 20 62 61  en completely ba
13d90 63 6b 66 69 6c 6c 65 64 20 28 6f 72 20 69 74 20  ckfilled (or it 
13da0 69 73 20 65 6d 70 74 79 29 2e 0a 20 20 20 20 2a  is empty)..    *
13db0 2a 20 61 6e 64 20 63 61 6e 20 62 65 20 73 61 66  * and can be saf
13dc0 65 6c 79 20 69 67 6e 6f 72 65 64 2e 0a 20 20 20  ely ignored..   
13dd0 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 77 61 6c   */.    rc = wal
13de0 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  LockShared(pWal,
13df0 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
13e00 29 29 3b 0a 20 20 20 20 77 61 6c 53 68 6d 42 61  ));.    walShmBa
13e10 72 72 69 65 72 28 70 57 61 6c 29 3b 0a 20 20 20  rrier(pWal);.   
13e20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
13e30 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  OK ){.      if( 
13e40 6d 65 6d 63 6d 70 28 28 76 6f 69 64 20 2a 29 77  memcmp((void *)w
13e50 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c 29  alIndexHdr(pWal)
13e60 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69  , &pWal->hdr, si
13e70 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
13e80 29 29 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a  )) ){.        /*
13e90 20 49 74 20 69 73 20 6e 6f 74 20 73 61 66 65 20   It is not safe 
13ea0 74 6f 20 61 6c 6c 6f 77 20 74 68 65 20 72 65 61  to allow the rea
13eb0 64 65 72 20 74 6f 20 63 6f 6e 74 69 6e 75 65 20  der to continue 
13ec0 68 65 72 65 20 69 66 20 66 72 61 6d 65 73 0a 20  here if frames. 
13ed0 20 20 20 20 20 20 20 2a 2a 20 6d 61 79 20 68 61         ** may ha
13ee0 76 65 20 62 65 65 6e 20 61 70 70 65 6e 64 65 64  ve been appended
13ef0 20 74 6f 20 74 68 65 20 6c 6f 67 20 62 65 66 6f   to the log befo
13f00 72 65 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20  re READ_LOCK(0) 
13f10 77 61 73 20 6f 62 74 61 69 6e 65 64 2e 0a 20 20  was obtained..  
13f20 20 20 20 20 20 20 2a 2a 20 57 68 65 6e 20 68 6f        ** When ho
13f30 6c 64 69 6e 67 20 52 45 41 44 5f 4c 4f 43 4b 28  lding READ_LOCK(
13f40 30 29 2c 20 74 68 65 20 72 65 61 64 65 72 20 69  0), the reader i
13f50 67 6e 6f 72 65 73 20 74 68 65 20 65 6e 74 69 72  gnores the entir
13f60 65 20 6c 6f 67 20 66 69 6c 65 2c 0a 20 20 20 20  e log file,.    
13f70 20 20 20 20 2a 2a 20 77 68 69 63 68 20 69 6d 70      ** which imp
13f80 6c 69 65 73 20 74 68 61 74 20 74 68 65 20 64 61  lies that the da
13f90 74 61 62 61 73 65 20 66 69 6c 65 20 63 6f 6e 74  tabase file cont
13fa0 61 69 6e 73 20 61 20 74 72 75 73 74 77 6f 72 74  ains a trustwort
13fb0 68 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 6e  hy.        ** sn
13fc0 61 70 73 68 6f 54 2e 20 53 69 6e 63 65 20 68 6f  apshoT. Since ho
13fd0 6c 64 69 6e 67 20 52 45 41 44 5f 4c 4f 43 4b 28  lding READ_LOCK(
13fe0 30 29 20 70 72 65 76 65 6e 74 73 20 61 20 63 68  0) prevents a ch
13ff0 65 63 6b 70 6f 69 6e 74 20 66 72 6f 6d 0a 20 20  eckpoint from.  
14000 20 20 20 20 20 20 2a 2a 20 68 61 70 70 65 6e 69        ** happeni
14010 6e 67 2c 20 74 68 69 73 20 69 73 20 75 73 75 61  ng, this is usua
14020 6c 6c 79 20 63 6f 72 72 65 63 74 2e 0a 20 20 20  lly correct..   
14030 20 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20       **.        
14040 2a 2a 20 48 6f 77 65 76 65 72 2c 20 69 66 20 66  ** However, if f
14050 72 61 6d 65 73 20 68 61 76 65 20 62 65 65 6e 20  rames have been 
14060 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20  appended to the 
14070 6c 6f 67 20 28 6f 72 20 69 66 20 74 68 65 20 6c  log (or if the l
14080 6f 67 20 0a 20 20 20 20 20 20 20 20 2a 2a 20 69  og .        ** i
14090 73 20 77 72 61 70 70 65 64 20 61 6e 64 20 77 72  s wrapped and wr
140a0 69 74 74 65 6e 20 66 6f 72 20 74 68 61 74 20 6d  itten for that m
140b0 61 74 74 65 72 29 20 62 65 66 6f 72 65 20 74 68  atter) before th
140c0 65 20 52 45 41 44 5f 4c 4f 43 4b 28 30 29 0a 20  e READ_LOCK(0). 
140d0 20 20 20 20 20 20 20 2a 2a 20 69 73 20 6f 62 74         ** is obt
140e0 61 69 6e 65 64 2c 20 74 68 61 74 20 69 73 20 6e  ained, that is n
140f0 6f 74 20 6e 65 63 65 73 73 61 72 69 6c 79 20 74  ot necessarily t
14100 72 75 65 2e 20 41 20 63 68 65 63 6b 70 6f 69 6e  rue. A checkpoin
14110 74 65 72 20 6d 61 79 0a 20 20 20 20 20 20 20 20  ter may.        
14120 2a 2a 20 68 61 76 65 20 73 74 61 72 74 65 64 20  ** have started 
14130 74 6f 20 62 61 63 6b 66 69 6c 6c 20 74 68 65 20  to backfill the 
14140 61 70 70 65 6e 64 65 64 20 66 72 61 6d 65 73 20  appended frames 
14150 62 75 74 20 63 72 61 73 68 65 64 20 62 65 66 6f  but crashed befo
14160 72 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 69 74  re.        ** it
14170 20 66 69 6e 69 73 68 65 64 2e 20 4c 65 61 76 69   finished. Leavi
14180 6e 67 20 61 20 63 6f 72 72 75 70 74 20 69 6d 61  ng a corrupt ima
14190 67 65 20 69 6e 20 74 68 65 20 64 61 74 61 62 61  ge in the databa
141a0 73 65 20 66 69 6c 65 2e 0a 20 20 20 20 20 20 20  se file..       
141b0 20 2a 2f 0a 20 20 20 20 20 20 20 20 77 61 6c 55   */.        walU
141c0 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  nlockShared(pWal
141d0 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
141e0 30 29 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74  0));.        ret
141f0 75 72 6e 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20  urn WAL_RETRY;. 
14200 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 57 61       }.      pWa
14210 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 30 3b  l->readLock = 0;
14220 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
14230 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 65 6c  LITE_OK;.    }el
14240 73 65 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  se if( rc!=SQLIT
14250 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20  E_BUSY ){.      
14260 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
14270 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 77 65  .  }..  /* If we
14280 20 67 65 74 20 74 68 69 73 20 66 61 72 2c 20 69   get this far, i
14290 74 20 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65  t means that the
142a0 20 72 65 61 64 65 72 20 77 69 6c 6c 20 77 61 6e   reader will wan
142b0 74 20 74 6f 20 75 73 65 0a 20 20 2a 2a 20 74 68  t to use.  ** th
142c0 65 20 57 41 4c 20 74 6f 20 67 65 74 20 61 74 20  e WAL to get at 
142d0 63 6f 6e 74 65 6e 74 20 66 72 6f 6d 20 72 65 63  content from rec
142e0 65 6e 74 20 63 6f 6d 6d 69 74 73 2e 20 20 54 68  ent commits.  Th
142f0 65 20 6a 6f 62 20 6e 6f 77 20 69 73 0a 20 20 2a  e job now is.  *
14300 2a 20 74 6f 20 73 65 6c 65 63 74 20 6f 6e 65 20  * to select one 
14310 6f 66 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b  of the aReadMark
14320 5b 5d 20 65 6e 74 72 69 65 73 20 74 68 61 74 20  [] entries that 
14330 69 73 20 63 6c 6f 73 65 73 74 20 74 6f 0a 20 20  is closest to.  
14340 2a 2a 20 62 75 74 20 6e 6f 74 20 65 78 63 65 65  ** but not excee
14350 64 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  ding pWal->hdr.m
14360 78 46 72 61 6d 65 20 61 6e 64 20 6c 6f 63 6b 20  xFrame and lock 
14370 74 68 61 74 20 65 6e 74 72 79 2e 0a 20 20 2a 2f  that entry..  */
14380 0a 20 20 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20  .  mxReadMark = 
14390 30 3b 0a 20 20 6d 78 49 20 3d 20 30 3b 0a 20 20  0;.  mxI = 0;.  
143a0 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e  for(i=1; i<WAL_N
143b0 52 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20  READER; i++){.  
143c0 20 20 75 33 32 20 74 68 69 73 4d 61 72 6b 20 3d    u32 thisMark =
143d0 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
143e0 6b 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 6d 78  k[i];.    if( mx
143f0 52 65 61 64 4d 61 72 6b 3c 3d 74 68 69 73 4d 61  ReadMark<=thisMa
14400 72 6b 20 26 26 20 74 68 69 73 4d 61 72 6b 3c 3d  rk && thisMark<=
14410 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
14420 65 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72  e ){.      asser
14430 74 28 20 74 68 69 73 4d 61 72 6b 21 3d 52 45 41  t( thisMark!=REA
14440 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 20 29  DMARK_NOT_USED )
14450 3b 0a 20 20 20 20 20 20 6d 78 52 65 61 64 4d 61  ;.      mxReadMa
14460 72 6b 20 3d 20 74 68 69 73 4d 61 72 6b 3b 0a 20  rk = thisMark;. 
14470 20 20 20 20 20 6d 78 49 20 3d 20 69 3b 0a 20 20       mxI = i;.  
14480 20 20 7d 0a 20 20 7d 0a 20 20 2f 2a 20 54 68 65    }.  }.  /* The
14490 72 65 20 77 61 73 20 6f 6e 63 65 20 61 6e 20 22  re was once an "
144a0 69 66 22 20 68 65 72 65 2e 20 54 68 65 20 65 78  if" here. The ex
144b0 74 72 61 20 22 7b 22 20 69 73 20 74 6f 20 70 72  tra "{" is to pr
144c0 65 73 65 72 76 65 20 69 6e 64 65 6e 74 61 74 69  eserve indentati
144d0 6f 6e 2e 20 2a 2f 0a 20 20 7b 0a 20 20 20 20 69  on. */.  {.    i
144e0 66 28 20 28 70 57 61 6c 2d 3e 72 65 61 64 4f 6e  f( (pWal->readOn
144f0 6c 79 20 26 20 57 41 4c 5f 53 48 4d 5f 52 44 4f  ly & WAL_SHM_RDO
14500 4e 4c 59 29 3d 3d 30 0a 20 20 20 20 20 26 26 20  NLY)==0.     && 
14510 28 6d 78 52 65 61 64 4d 61 72 6b 3c 70 57 61 6c  (mxReadMark<pWal
14520 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 7c 7c  ->hdr.mxFrame ||
14530 20 6d 78 49 3d 3d 30 29 0a 20 20 20 20 29 7b 0a   mxI==0).    ){.
14540 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69        for(i=1; i
14550 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b  <WAL_NREADER; i+
14560 2b 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  +){.        rc =
14570 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76   walLockExclusiv
14580 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
14590 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20  _LOCK(i), 1);.  
145a0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
145b0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
145c0 20 20 20 20 20 6d 78 52 65 61 64 4d 61 72 6b 20       mxReadMark 
145d0 3d 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61  = pInfo->aReadMa
145e0 72 6b 5b 69 5d 20 3d 20 70 57 61 6c 2d 3e 68 64  rk[i] = pWal->hd
145f0 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 20  r.mxFrame;.     
14600 20 20 20 20 20 6d 78 49 20 3d 20 69 3b 0a 20 20       mxI = i;.  
14610 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63          walUnloc
14620 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
14630 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69   WAL_READ_LOCK(i
14640 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20 20  ), 1);.         
14650 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
14660 7d 65 6c 73 65 20 69 66 28 20 72 63 21 3d 53 51  }else if( rc!=SQ
14670 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
14680 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63         return rc
14690 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
146a0 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
146b0 28 20 6d 78 49 3d 3d 30 20 29 7b 0a 20 20 20 20  ( mxI==0 ){.    
146c0 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51    assert( rc==SQ
146d0 4c 49 54 45 5f 42 55 53 59 20 7c 7c 20 28 70 57  LITE_BUSY || (pW
146e0 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 26 20 57  al->readOnly & W
146f0 41 4c 5f 53 48 4d 5f 52 44 4f 4e 4c 59 29 21 3d  AL_SHM_RDONLY)!=
14700 30 20 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72  0 );.      retur
14710 6e 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  n rc==SQLITE_BUS
14720 59 20 3f 20 57 41 4c 5f 52 45 54 52 59 20 3a 20  Y ? WAL_RETRY : 
14730 53 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 5f  SQLITE_READONLY_
14740 43 41 4e 54 4c 4f 43 4b 3b 0a 20 20 20 20 7d 0a  CANTLOCK;.    }.
14750 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63  .    rc = walLoc
14760 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
14770 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29  L_READ_LOCK(mxI)
14780 29 3b 0a 20 20 20 20 69 66 28 20 72 63 20 29 7b  );.    if( rc ){
14790 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63  .      return rc
147a0 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 3f 20  ==SQLITE_BUSY ? 
147b0 57 41 4c 5f 52 45 54 52 59 20 3a 20 72 63 3b 0a  WAL_RETRY : rc;.
147c0 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20 4e 6f 77      }.    /* Now
147d0 20 74 68 61 74 20 74 68 65 20 72 65 61 64 2d 6c   that the read-l
147e0 6f 63 6b 20 68 61 73 20 62 65 65 6e 20 6f 62 74  ock has been obt
147f0 61 69 6e 65 64 2c 20 63 68 65 63 6b 20 74 68 61  ained, check tha
14800 74 20 6e 65 69 74 68 65 72 20 74 68 65 0a 20 20  t neither the.  
14810 20 20 2a 2a 20 76 61 6c 75 65 20 69 6e 20 74 68    ** value in th
14820 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 61 72  e aReadMark[] ar
14830 72 61 79 20 6f 72 20 74 68 65 20 63 6f 6e 74 65  ray or the conte
14840 6e 74 73 20 6f 66 20 74 68 65 20 77 61 6c 2d 69  nts of the wal-i
14850 6e 64 65 78 0a 20 20 20 20 2a 2a 20 68 65 61 64  ndex.    ** head
14860 65 72 20 68 61 76 65 20 63 68 61 6e 67 65 64 2e  er have changed.
14870 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 49  .    **.    ** I
14880 74 20 69 73 20 6e 65 63 65 73 73 61 72 79 20 74  t is necessary t
14890 6f 20 63 68 65 63 6b 20 74 68 61 74 20 74 68 65  o check that the
148a0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
148b0 72 20 64 69 64 20 6e 6f 74 20 63 68 61 6e 67 65  r did not change
148c0 0a 20 20 20 20 2a 2a 20 62 65 74 77 65 65 6e 20  .    ** between 
148d0 74 68 65 20 74 69 6d 65 20 69 74 20 77 61 73 20  the time it was 
148e0 72 65 61 64 20 61 6e 64 20 77 68 65 6e 20 74 68  read and when th
148f0 65 20 73 68 61 72 65 64 2d 6c 6f 63 6b 20 77 61  e shared-lock wa
14900 73 20 6f 62 74 61 69 6e 65 64 0a 20 20 20 20 2a  s obtained.    *
14910 2a 20 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  * on WAL_READ_LO
14920 43 4b 28 6d 78 49 29 20 77 61 73 20 6f 62 74 61  CK(mxI) was obta
14930 69 6e 65 64 20 74 6f 20 61 63 63 6f 75 6e 74 20  ined to account 
14940 66 6f 72 20 74 68 65 20 70 6f 73 73 69 62 69 6c  for the possibil
14950 69 74 79 0a 20 20 20 20 2a 2a 20 74 68 61 74 20  ity.    ** that 
14960 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 6d 61 79  the log file may
14970 20 68 61 76 65 20 62 65 65 6e 20 77 72 61 70 70   have been wrapp
14980 65 64 20 62 79 20 61 20 77 72 69 74 65 72 2c 20  ed by a writer, 
14990 6f 72 20 74 68 61 74 20 66 72 61 6d 65 73 0a 20  or that frames. 
149a0 20 20 20 2a 2a 20 74 68 61 74 20 6f 63 63 75 72     ** that occur
149b0 20 6c 61 74 65 72 20 69 6e 20 74 68 65 20 6c 6f   later in the lo
149c0 67 20 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72  g than pWal->hdr
149d0 2e 6d 78 46 72 61 6d 65 20 6d 61 79 20 68 61 76  .mxFrame may hav
149e0 65 20 62 65 65 6e 0a 20 20 20 20 2a 2a 20 63 6f  e been.    ** co
149f0 70 69 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61  pied into the da
14a00 74 61 62 61 73 65 20 62 79 20 61 20 63 68 65 63  tabase by a chec
14a10 6b 70 6f 69 6e 74 65 72 2e 20 49 66 20 65 69 74  kpointer. If eit
14a20 68 65 72 20 6f 66 20 74 68 65 73 65 20 74 68 69  her of these thi
14a30 6e 67 73 0a 20 20 20 20 2a 2a 20 68 61 70 70 65  ngs.    ** happe
14a40 6e 65 64 2c 20 74 68 65 6e 20 72 65 61 64 69 6e  ned, then readin
14a50 67 20 74 68 65 20 64 61 74 61 62 61 73 65 20 77  g the database w
14a60 69 74 68 20 74 68 65 20 63 75 72 72 65 6e 74 20  ith the current 
14a70 76 61 6c 75 65 20 6f 66 0a 20 20 20 20 2a 2a 20  value of.    ** 
14a80 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
14a90 65 20 72 69 73 6b 73 20 72 65 61 64 69 6e 67 20  e risks reading 
14aa0 61 20 63 6f 72 72 75 70 74 65 64 20 73 6e 61 70  a corrupted snap
14ab0 73 68 6f 74 2e 20 53 6f 2c 20 72 65 74 72 79 0a  shot. So, retry.
14ac0 20 20 20 20 2a 2a 20 69 6e 73 74 65 61 64 2e 0a      ** instead..
14ad0 20 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68      **.    ** Th
14ae0 69 73 20 64 6f 65 73 20 6e 6f 74 20 67 75 61 72  is does not guar
14af0 61 6e 74 65 65 20 74 68 61 74 20 74 68 65 20 63  antee that the c
14b00 6f 70 79 20 6f 66 20 74 68 65 20 77 61 6c 2d 69  opy of the wal-i
14b10 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20 75  ndex header is u
14b20 70 20 74 6f 0a 20 20 20 20 2a 2a 20 64 61 74 65  p to.    ** date
14b30 20 62 65 66 6f 72 65 20 70 72 6f 63 65 65 64 69   before proceedi
14b40 6e 67 2e 20 54 68 61 74 20 77 6f 75 6c 64 20 6e  ng. That would n
14b50 6f 74 20 62 65 20 70 6f 73 73 69 62 6c 65 20 77  ot be possible w
14b60 69 74 68 6f 75 74 20 73 6f 6d 65 68 6f 77 0a 20  ithout somehow. 
14b70 20 20 20 2a 2a 20 62 6c 6f 63 6b 69 6e 67 20 77     ** blocking w
14b80 72 69 74 65 72 73 2e 20 49 74 20 6f 6e 6c 79 20  riters. It only 
14b90 67 75 61 72 61 6e 74 65 65 73 20 74 68 61 74 20  guarantees that 
14ba0 61 20 64 61 6e 67 65 72 6f 75 73 20 63 68 65 63  a dangerous chec
14bb0 6b 70 6f 69 6e 74 20 6f 72 20 0a 20 20 20 20 2a  kpoint or .    *
14bc0 2a 20 6c 6f 67 2d 77 72 61 70 20 28 65 69 74 68  * log-wrap (eith
14bd0 65 72 20 6f 66 20 77 68 69 63 68 20 77 6f 75 6c  er of which woul
14be0 64 20 72 65 71 75 69 72 65 20 61 6e 20 65 78 63  d require an exc
14bf0 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 0a 20  lusive lock on. 
14c00 20 20 20 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c     ** WAL_READ_L
14c10 4f 43 4b 28 6d 78 49 29 29 20 68 61 73 20 6e 6f  OCK(mxI)) has no
14c20 74 20 6f 63 63 75 72 72 65 64 20 73 69 6e 63 65  t occurred since
14c30 20 74 68 65 20 73 6e 61 70 73 68 6f 74 20 77 61   the snapshot wa
14c40 73 20 76 61 6c 69 64 2e 0a 20 20 20 20 2a 2f 0a  s valid..    */.
14c50 20 20 20 20 77 61 6c 53 68 6d 42 61 72 72 69 65      walShmBarrie
14c60 72 28 70 57 61 6c 29 3b 0a 20 20 20 20 69 66 28  r(pWal);.    if(
14c70 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
14c80 6b 5b 6d 78 49 5d 21 3d 6d 78 52 65 61 64 4d 61  k[mxI]!=mxReadMa
14c90 72 6b 0a 20 20 20 20 20 7c 7c 20 6d 65 6d 63 6d  rk.     || memcm
14ca0 70 28 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64  p((void *)walInd
14cb0 65 78 48 64 72 28 70 57 61 6c 29 2c 20 26 70 57  exHdr(pWal), &pW
14cc0 61 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28  al->hdr, sizeof(
14cd0 57 61 6c 49 6e 64 65 78 48 64 72 29 29 0a 20 20  WalIndexHdr)).  
14ce0 20 20 29 7b 0a 20 20 20 20 20 20 77 61 6c 55 6e    ){.      walUn
14cf0 6c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c  lockShared(pWal,
14d00 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d   WAL_READ_LOCK(m
14d10 78 49 29 29 3b 0a 20 20 20 20 20 20 72 65 74 75  xI));.      retu
14d20 72 6e 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20  rn WAL_RETRY;.  
14d30 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 61    }else{.      a
14d40 73 73 65 72 74 28 20 6d 78 52 65 61 64 4d 61 72  ssert( mxReadMar
14d50 6b 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  k<=pWal->hdr.mxF
14d60 72 61 6d 65 20 29 3b 0a 20 20 20 20 20 20 70 57  rame );.      pW
14d70 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 28  al->readLock = (
14d80 69 31 36 29 6d 78 49 3b 0a 20 20 20 20 7d 0a 20  i16)mxI;.    }. 
14d90 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
14da0 7d 0a 0a 2f 2a 0a 2a 2a 20 42 65 67 69 6e 20 61  }../*.** Begin a
14db0 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
14dc0 6e 20 6f 6e 20 74 68 65 20 64 61 74 61 62 61 73  n on the databas
14dd0 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  e..**.** This ro
14de0 75 74 69 6e 65 20 75 73 65 64 20 74 6f 20 62 65  utine used to be
14df0 20 63 61 6c 6c 65 64 20 73 71 6c 69 74 65 33 4f   called sqlite3O
14e00 70 65 6e 53 6e 61 70 73 68 6f 74 28 29 20 61 6e  penSnapshot() an
14e10 64 20 77 69 74 68 20 67 6f 6f 64 20 72 65 61 73  d with good reas
14e20 6f 6e 3a 0a 2a 2a 20 69 74 20 74 61 6b 65 73 20  on:.** it takes 
14e30 61 20 73 6e 61 70 73 68 6f 74 20 6f 66 20 74 68  a snapshot of th
14e40 65 20 73 74 61 74 65 20 6f 66 20 74 68 65 20 57  e state of the W
14e50 41 4c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78  AL and wal-index
14e60 20 66 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74   for the current
14e70 0a 2a 2a 20 69 6e 73 74 61 6e 74 20 69 6e 20 74  .** instant in t
14e80 69 6d 65 2e 20 20 54 68 65 20 63 75 72 72 65 6e  ime.  The curren
14e90 74 20 74 68 72 65 61 64 20 77 69 6c 6c 20 63 6f  t thread will co
14ea0 6e 74 69 6e 75 65 20 74 6f 20 75 73 65 20 74 68  ntinue to use th
14eb0 69 73 20 73 6e 61 70 73 68 6f 74 2e 0a 2a 2a 20  is snapshot..** 
14ec0 4f 74 68 65 72 20 74 68 72 65 61 64 73 20 6d 69  Other threads mi
14ed0 67 68 74 20 61 70 70 65 6e 64 20 6e 65 77 20 63  ght append new c
14ee0 6f 6e 74 65 6e 74 20 74 6f 20 74 68 65 20 57 41  ontent to the WA
14ef0 4c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20  L and wal-index 
14f00 62 75 74 0a 2a 2a 20 74 68 61 74 20 65 78 74 72  but.** that extr
14f10 61 20 63 6f 6e 74 65 6e 74 20 69 73 20 69 67 6e  a content is ign
14f20 6f 72 65 64 20 62 79 20 74 68 65 20 63 75 72 72  ored by the curr
14f30 65 6e 74 20 74 68 72 65 61 64 2e 0a 2a 2a 0a 2a  ent thread..**.*
14f40 2a 20 49 66 20 74 68 65 20 64 61 74 61 62 61 73  * If the databas
14f50 65 20 63 6f 6e 74 65 6e 74 73 20 68 61 76 65 20  e contents have 
14f60 63 68 61 6e 67 65 73 20 73 69 6e 63 65 20 74 68  changes since th
14f70 65 20 70 72 65 76 69 6f 75 73 20 72 65 61 64 0a  e previous read.
14f80 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20  ** transaction, 
14f90 74 68 65 6e 20 2a 70 43 68 61 6e 67 65 64 20 69  then *pChanged i
14fa0 73 20 73 65 74 20 74 6f 20 31 20 62 65 66 6f 72  s set to 1 befor
14fb0 65 20 72 65 74 75 72 6e 69 6e 67 2e 20 20 54 68  e returning.  Th
14fc0 65 0a 2a 2a 20 50 61 67 65 72 20 6c 61 79 65 72  e.** Pager layer
14fd0 20 77 69 6c 6c 20 75 73 65 20 74 68 69 73 20 74   will use this t
14fe0 6f 20 6b 6e 6f 77 20 74 68 61 74 20 69 73 20 63  o know that is c
14ff0 61 63 68 65 20 69 73 20 73 74 61 6c 65 20 61 6e  ache is stale an
15000 64 0a 2a 2a 20 6e 65 65 64 73 20 74 6f 20 62 65  d.** needs to be
15010 20 66 6c 75 73 68 65 64 2e 0a 2a 2f 0a 69 6e 74   flushed..*/.int
15020 20 73 71 6c 69 74 65 33 57 61 6c 42 65 67 69 6e   sqlite3WalBegin
15030 52 65 61 64 54 72 61 6e 73 61 63 74 69 6f 6e 28  ReadTransaction(
15040 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a  Wal *pWal, int *
15050 70 43 68 61 6e 67 65 64 29 7b 0a 20 20 69 6e 74  pChanged){.  int
15060 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
15070 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
15080 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
15090 20 69 6e 74 20 63 6e 74 20 3d 20 30 3b 20 20 20   int cnt = 0;   
150a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
150b0 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 54 72   /* Number of Tr
150c0 79 42 65 67 69 6e 52 65 61 64 20 61 74 74 65 6d  yBeginRead attem
150d0 70 74 73 20 2a 2f 0a 0a 20 20 64 6f 7b 0a 20 20  pts */..  do{.  
150e0 20 20 72 63 20 3d 20 77 61 6c 54 72 79 42 65 67    rc = walTryBeg
150f0 69 6e 52 65 61 64 28 70 57 61 6c 2c 20 70 43 68  inRead(pWal, pCh
15100 61 6e 67 65 64 2c 20 30 2c 20 2b 2b 63 6e 74 29  anged, 0, ++cnt)
15110 3b 0a 20 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d  ;.  }while( rc==
15120 57 41 4c 5f 52 45 54 52 59 20 29 3b 0a 20 20 74  WAL_RETRY );.  t
15130 65 73 74 63 61 73 65 28 20 28 72 63 26 30 78 66  estcase( (rc&0xf
15140 66 29 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  f)==SQLITE_BUSY 
15150 29 3b 0a 20 20 74 65 73 74 63 61 73 65 28 20 28  );.  testcase( (
15160 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49 54 45  rc&0xff)==SQLITE
15170 5f 49 4f 45 52 52 20 29 3b 0a 20 20 74 65 73 74  _IOERR );.  test
15180 63 61 73 65 28 20 72 63 3d 3d 53 51 4c 49 54 45  case( rc==SQLITE
15190 5f 50 52 4f 54 4f 43 4f 4c 20 29 3b 0a 20 20 74  _PROTOCOL );.  t
151a0 65 73 74 63 61 73 65 28 20 72 63 3d 3d 53 51 4c  estcase( rc==SQL
151b0 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74 75  ITE_OK );.  retu
151c0 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
151d0 46 69 6e 69 73 68 20 77 69 74 68 20 61 20 72 65  Finish with a re
151e0 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20  ad transaction. 
151f0 20 41 6c 6c 20 74 68 69 73 20 64 6f 65 73 20 69   All this does i
15200 73 20 72 65 6c 65 61 73 65 20 74 68 65 0a 2a 2a  s release the.**
15210 20 72 65 61 64 2d 6c 6f 63 6b 2e 0a 2a 2f 0a 76   read-lock..*/.v
15220 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 45 6e  oid sqlite3WalEn
15230 64 52 65 61 64 54 72 61 6e 73 61 63 74 69 6f 6e  dReadTransaction
15240 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 73  (Wal *pWal){.  s
15250 71 6c 69 74 65 33 57 61 6c 45 6e 64 57 72 69 74  qlite3WalEndWrit
15260 65 54 72 61 6e 73 61 63 74 69 6f 6e 28 70 57 61  eTransaction(pWa
15270 6c 29 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  l);.  if( pWal->
15280 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 7b 0a 20  readLock>=0 ){. 
15290 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72     walUnlockShar
152a0 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ed(pWal, WAL_REA
152b0 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61  D_LOCK(pWal->rea
152c0 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70 57 61  dLock));.    pWa
152d0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31  l->readLock = -1
152e0 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  ;.  }.}../*.** R
152f0 65 61 64 20 61 20 70 61 67 65 20 66 72 6f 6d 20  ead a page from 
15300 74 68 65 20 57 41 4c 2c 20 69 66 20 69 74 20 69  the WAL, if it i
15310 73 20 70 72 65 73 65 6e 74 20 69 6e 20 74 68 65  s present in the
15320 20 57 41 4c 20 61 6e 64 20 69 66 20 74 68 65 20   WAL and if the 
15330 0a 2a 2a 20 63 75 72 72 65 6e 74 20 72 65 61 64  .** current read
15340 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20   transaction is 
15350 63 6f 6e 66 69 67 75 72 65 64 20 74 6f 20 75 73  configured to us
15360 65 20 74 68 65 20 57 41 4c 2e 20 20 0a 2a 2a 0a  e the WAL.  .**.
15370 2a 2a 20 54 68 65 20 2a 70 49 6e 57 61 6c 20 69  ** The *pInWal i
15380 73 20 73 65 74 20 74 6f 20 31 20 69 66 20 74 68  s set to 1 if th
15390 65 20 72 65 71 75 65 73 74 65 64 20 70 61 67 65  e requested page
153a0 20 69 73 20 69 6e 20 74 68 65 20 57 41 4c 20 61   is in the WAL a
153b0 6e 64 0a 2a 2a 20 68 61 73 20 62 65 65 6e 20 6c  nd.** has been l
153c0 6f 61 64 65 64 2e 20 20 4f 72 20 2a 70 49 6e 57  oaded.  Or *pInW
153d0 61 6c 20 69 73 20 73 65 74 20 74 6f 20 30 20 69  al is set to 0 i
153e0 66 20 74 68 65 20 70 61 67 65 20 77 61 73 20 6e  f the page was n
153f0 6f 74 20 69 6e 20 0a 2a 2a 20 74 68 65 20 57 41  ot in .** the WA
15400 4c 20 61 6e 64 20 6e 65 65 64 73 20 74 6f 20 62  L and needs to b
15410 65 20 72 65 61 64 20 6f 75 74 20 6f 66 20 74 68  e read out of th
15420 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2f 0a 69  e database..*/.i
15430 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 52 65 61  nt sqlite3WalRea
15440 64 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20  d(.  Wal *pWal, 
15450 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15460 20 20 20 20 20 2f 2a 20 57 41 4c 20 68 61 6e 64       /* WAL hand
15470 6c 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70 67 6e  le */.  Pgno pgn
15480 6f 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  o,              
15490 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
154a0 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  ase page number 
154b0 74 6f 20 72 65 61 64 20 64 61 74 61 20 66 6f 72  to read data for
154c0 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 49 6e 57 61   */.  int *pInWa
154d0 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
154e0 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 72        /* OUT: Tr
154f0 75 65 20 69 66 20 64 61 74 61 20 69 73 20 72 65  ue if data is re
15500 61 64 20 66 72 6f 6d 20 57 41 4c 20 2a 2f 0a 20  ad from WAL */. 
15510 20 69 6e 74 20 6e 4f 75 74 2c 20 20 20 20 20 20   int nOut,      
15520 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15530 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62 75 66 66   /* Size of buff
15540 65 72 20 70 4f 75 74 20 69 6e 20 62 79 74 65 73  er pOut in bytes
15550 20 2a 2f 0a 20 20 75 38 20 2a 70 4f 75 74 20 20   */.  u8 *pOut  
15560 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15570 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20        /* Buffer 
15580 74 6f 20 77 72 69 74 65 20 70 61 67 65 20 64 61  to write page da
15590 74 61 20 74 6f 20 2a 2f 0a 29 7b 0a 20 20 75 33  ta to */.){.  u3
155a0 32 20 69 52 65 61 64 20 3d 20 30 3b 20 20 20 20  2 iRead = 0;    
155b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
155c0 20 49 66 20 21 3d 30 2c 20 57 41 4c 20 66 72 61   If !=0, WAL fra
155d0 6d 65 20 74 6f 20 72 65 74 75 72 6e 20 64 61 74  me to return dat
155e0 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 75 33 32 20  a from */.  u32 
155f0 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d 3e 68 64  iLast = pWal->hd
15600 72 2e 6d 78 46 72 61 6d 65 3b 20 20 2f 2a 20 4c  r.mxFrame;  /* L
15610 61 73 74 20 70 61 67 65 20 69 6e 20 57 41 4c 20  ast page in WAL 
15620 66 6f 72 20 74 68 69 73 20 72 65 61 64 65 72 20  for this reader 
15630 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73 68 3b 20  */.  int iHash; 
15640 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15650 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
15660 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20 4e 20 68  loop through N h
15670 61 73 68 20 74 61 62 6c 65 73 20 2a 2f 0a 0a 20  ash tables */.. 
15680 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65   /* This routine
15690 20 69 73 20 6f 6e 6c 79 20 62 65 20 63 61 6c 6c   is only be call
156a0 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 61  ed from within a
156b0 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
156c0 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  n. */.  assert( 
156d0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
156e0 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45  0 || pWal->lockE
156f0 72 72 6f 72 20 29 3b 0a 0a 20 20 2f 2a 20 49 66  rror );..  /* If
15700 20 74 68 65 20 22 6c 61 73 74 20 70 61 67 65 22   the "last page"
15710 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20 77 61   field of the wa
15720 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 73  l-index header s
15730 6e 61 70 73 68 6f 74 20 69 73 20 30 2c 20 74 68  napshot is 0, th
15740 65 6e 0a 20 20 2a 2a 20 6e 6f 20 64 61 74 61 20  en.  ** no data 
15750 77 69 6c 6c 20 62 65 20 72 65 61 64 20 66 72 6f  will be read fro
15760 6d 20 74 68 65 20 77 61 6c 20 75 6e 64 65 72 20  m the wal under 
15770 61 6e 79 20 63 69 72 63 75 6d 73 74 61 6e 63 65  any circumstance
15780 73 2e 20 52 65 74 75 72 6e 20 65 61 72 6c 79 0a  s. Return early.
15790 20 20 2a 2a 20 69 6e 20 74 68 69 73 20 63 61 73    ** in this cas
157a0 65 20 61 73 20 61 6e 20 6f 70 74 69 6d 69 7a 61  e as an optimiza
157b0 74 69 6f 6e 2e 20 20 4c 69 6b 65 77 69 73 65 2c  tion.  Likewise,
157c0 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f   if pWal->readLo
157d0 63 6b 3d 3d 30 2c 20 0a 20 20 2a 2a 20 74 68 65  ck==0, .  ** the
157e0 6e 20 74 68 65 20 57 41 4c 20 69 73 20 69 67 6e  n the WAL is ign
157f0 6f 72 65 64 20 62 79 20 74 68 65 20 72 65 61 64  ored by the read
15800 65 72 20 73 6f 20 72 65 74 75 72 6e 20 65 61 72  er so return ear
15810 6c 79 2c 20 61 73 20 69 66 20 74 68 65 20 0a 20  ly, as if the . 
15820 20 2a 2a 20 57 41 4c 20 77 65 72 65 20 65 6d 70   ** WAL were emp
15830 74 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69  ty..  */.  if( i
15840 4c 61 73 74 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d  Last==0 || pWal-
15850 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20 29 7b 0a  >readLock==0 ){.
15860 20 20 20 20 2a 70 49 6e 57 61 6c 20 3d 20 30 3b      *pInWal = 0;
15870 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
15880 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  TE_OK;.  }..  /*
15890 20 53 65 61 72 63 68 20 74 68 65 20 68 61 73 68   Search the hash
158a0 20 74 61 62 6c 65 20 6f 72 20 74 61 62 6c 65 73   table or tables
158b0 20 66 6f 72 20 61 6e 20 65 6e 74 72 79 20 6d 61   for an entry ma
158c0 74 63 68 69 6e 67 20 70 61 67 65 20 6e 75 6d 62  tching page numb
158d0 65 72 0a 20 20 2a 2a 20 70 67 6e 6f 2e 20 45 61  er.  ** pgno. Ea
158e0 63 68 20 69 74 65 72 61 74 69 6f 6e 20 6f 66 20  ch iteration of 
158f0 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 66 6f  the following fo
15900 72 28 29 20 6c 6f 6f 70 20 73 65 61 72 63 68 65  r() loop searche
15910 73 20 6f 6e 65 0a 20 20 2a 2a 20 68 61 73 68 20  s one.  ** hash 
15920 74 61 62 6c 65 20 28 65 61 63 68 20 68 61 73 68  table (each hash
15930 20 74 61 62 6c 65 20 69 6e 64 65 78 65 73 20 75   table indexes u
15940 70 20 74 6f 20 48 41 53 48 54 41 42 4c 45 5f 4e  p to HASHTABLE_N
15950 50 41 47 45 20 66 72 61 6d 65 73 29 2e 0a 20 20  PAGE frames)..  
15960 2a 2a 0a 20 20 2a 2a 20 54 68 69 73 20 63 6f 64  **.  ** This cod
15970 65 20 6d 69 67 68 74 20 72 75 6e 20 63 6f 6e 63  e might run conc
15980 75 72 72 65 6e 74 6c 79 20 74 6f 20 74 68 65 20  urrently to the 
15990 63 6f 64 65 20 69 6e 20 77 61 6c 49 6e 64 65 78  code in walIndex
159a0 41 70 70 65 6e 64 28 29 0a 20 20 2a 2a 20 74 68  Append().  ** th
159b0 61 74 20 61 64 64 73 20 65 6e 74 72 69 65 73 20  at adds entries 
159c0 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  to the wal-index
159d0 20 28 61 6e 64 20 70 6f 73 73 69 62 6c 79 20 74   (and possibly t
159e0 6f 20 74 68 69 73 20 68 61 73 68 20 0a 20 20 2a  o this hash .  *
159f0 2a 20 74 61 62 6c 65 29 2e 20 54 68 69 73 20 6d  * table). This m
15a00 65 61 6e 73 20 74 68 65 20 76 61 6c 75 65 20 6a  eans the value j
15a10 75 73 74 20 72 65 61 64 20 66 72 6f 6d 20 74 68  ust read from th
15a20 65 20 68 61 73 68 20 0a 20 20 2a 2a 20 73 6c 6f  e hash .  ** slo
15a30 74 20 28 61 48 61 73 68 5b 69 4b 65 79 5d 29 20  t (aHash[iKey]) 
15a40 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 61 64  may have been ad
15a50 64 65 64 20 62 65 66 6f 72 65 20 6f 72 20 61 66  ded before or af
15a60 74 65 72 20 74 68 65 20 0a 20 20 2a 2a 20 63 75  ter the .  ** cu
15a70 72 72 65 6e 74 20 72 65 61 64 20 74 72 61 6e 73  rrent read trans
15a80 61 63 74 69 6f 6e 20 77 61 73 20 6f 70 65 6e 65  action was opene
15a90 64 2e 20 56 61 6c 75 65 73 20 61 64 64 65 64 20  d. Values added 
15aa0 61 66 74 65 72 20 74 68 65 0a 20 20 2a 2a 20 72  after the.  ** r
15ab0 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
15ac0 77 61 73 20 6f 70 65 6e 65 64 20 6d 61 79 20 68  was opened may h
15ad0 61 76 65 20 62 65 65 6e 20 77 72 69 74 74 65 6e  ave been written
15ae0 20 69 6e 63 6f 72 72 65 63 74 6c 79 20 2d 0a 20   incorrectly -. 
15af0 20 2a 2a 20 69 2e 65 2e 20 74 68 65 73 65 20 73   ** i.e. these s
15b00 6c 6f 74 73 20 6d 61 79 20 63 6f 6e 74 61 69 6e  lots may contain
15b10 20 67 61 72 62 61 67 65 20 64 61 74 61 2e 20 48   garbage data. H
15b20 6f 77 65 76 65 72 2c 20 77 65 20 61 73 73 75 6d  owever, we assum
15b30 65 0a 20 20 2a 2a 20 74 68 61 74 20 61 6e 79 20  e.  ** that any 
15b40 73 6c 6f 74 73 20 77 72 69 74 74 65 6e 20 62 65  slots written be
15b50 66 6f 72 65 20 74 68 65 20 63 75 72 72 65 6e 74  fore the current
15b60 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f   read transactio
15b70 6e 20 77 61 73 0a 20 20 2a 2a 20 6f 70 65 6e 65  n was.  ** opene
15b80 64 20 72 65 6d 61 69 6e 20 75 6e 6d 6f 64 69 66  d remain unmodif
15b90 69 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 46  ied..  **.  ** F
15ba0 6f 72 20 74 68 65 20 72 65 61 73 6f 6e 73 20 61  or the reasons a
15bb0 62 6f 76 65 2c 20 74 68 65 20 69 66 28 2e 2e 2e  bove, the if(...
15bc0 29 20 63 6f 6e 64 69 74 69 6f 6e 20 66 65 61 74  ) condition feat
15bd0 75 72 65 64 20 69 6e 20 74 68 65 20 69 6e 6e 65  ured in the inne
15be0 72 0a 20 20 2a 2a 20 6c 6f 6f 70 20 6f 66 20 74  r.  ** loop of t
15bf0 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 62 6c 6f  he following blo
15c00 63 6b 20 69 73 20 6d 6f 72 65 20 73 74 72 69 6e  ck is more strin
15c10 67 65 6e 74 20 74 68 61 74 20 77 6f 75 6c 64 20  gent that would 
15c20 62 65 20 72 65 71 75 69 72 65 64 20 0a 20 20 2a  be required .  *
15c30 2a 20 69 66 20 77 65 20 68 61 64 20 65 78 63 6c  * if we had excl
15c40 75 73 69 76 65 20 61 63 63 65 73 73 20 74 6f 20  usive access to 
15c50 74 68 65 20 68 61 73 68 2d 74 61 62 6c 65 3a 0a  the hash-table:.
15c60 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 28 61 50 67    **.  **   (aPg
15c70 6e 6f 5b 69 46 72 61 6d 65 5d 3d 3d 70 67 6e 6f  no[iFrame]==pgno
15c80 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69  ): .  **     Thi
15c90 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74  s condition filt
15ca0 65 72 73 20 6f 75 74 20 6e 6f 72 6d 61 6c 20 68  ers out normal h
15cb0 61 73 68 2d 74 61 62 6c 65 20 63 6f 6c 6c 69 73  ash-table collis
15cc0 69 6f 6e 73 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20  ions..  **.  ** 
15cd0 20 20 28 69 46 72 61 6d 65 3c 3d 69 4c 61 73 74    (iFrame<=iLast
15ce0 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20 54 68 69  ): .  **     Thi
15cf0 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66 69 6c 74  s condition filt
15d00 65 72 73 20 6f 75 74 20 65 6e 74 72 69 65 73 20  ers out entries 
15d10 74 68 61 74 20 77 65 72 65 20 61 64 64 65 64 20  that were added 
15d20 74 6f 20 74 68 65 20 68 61 73 68 0a 20 20 2a 2a  to the hash.  **
15d30 20 20 20 20 20 74 61 62 6c 65 20 61 66 74 65 72       table after
15d40 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 65 61   the current rea
15d50 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e 20 68 61  d-transaction ha
15d60 64 20 73 74 61 72 74 65 64 2e 0a 20 20 2a 2f 0a  d started..  */.
15d70 20 20 66 6f 72 28 69 48 61 73 68 3d 77 61 6c 46    for(iHash=walF
15d80 72 61 6d 65 50 61 67 65 28 69 4c 61 73 74 29 3b  ramePage(iLast);
15d90 20 69 48 61 73 68 3e 3d 30 20 26 26 20 69 52 65   iHash>=0 && iRe
15da0 61 64 3d 3d 30 3b 20 69 48 61 73 68 2d 2d 29 7b  ad==0; iHash--){
15db0 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 68 74  .    volatile ht
15dc0 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b 20 20 20  _slot *aHash;   
15dd0 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
15de0 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20   hash table */. 
15df0 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20     volatile u32 
15e00 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20 20 20 20  *aPgno;         
15e10 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 61   /* Pointer to a
15e20 72 72 61 79 20 6f 66 20 70 61 67 65 20 6e 75 6d  rray of page num
15e30 62 65 72 73 20 2a 2f 0a 20 20 20 20 75 33 32 20  bers */.    u32 
15e40 69 5a 65 72 6f 3b 20 20 20 20 20 20 20 20 20 20  iZero;          
15e50 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72 61            /* Fra
15e60 6d 65 20 6e 75 6d 62 65 72 20 63 6f 72 72 65 73  me number corres
15e70 70 6f 6e 64 69 6e 67 20 74 6f 20 61 50 67 6e 6f  ponding to aPgno
15e80 5b 30 5d 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69  [0] */.    int i
15e90 4b 65 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  Key;            
15ea0 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68           /* Hash
15eb0 20 73 6c 6f 74 20 69 6e 64 65 78 20 2a 2f 0a 20   slot index */. 
15ec0 20 20 20 69 6e 74 20 6e 43 6f 6c 6c 69 64 65 3b     int nCollide;
15ed0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15ee0 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 68 61   /* Number of ha
15ef0 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73 20 72 65  sh collisions re
15f00 6d 61 69 6e 69 6e 67 20 2a 2f 0a 20 20 20 20 69  maining */.    i
15f10 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
15f20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
15f30 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 0a 20  Error code */.. 
15f40 20 20 20 72 63 20 3d 20 77 61 6c 48 61 73 68 47     rc = walHashG
15f50 65 74 28 70 57 61 6c 2c 20 69 48 61 73 68 2c 20  et(pWal, iHash, 
15f60 26 61 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20  &aHash, &aPgno, 
15f70 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20 69 66 28  &iZero);.    if(
15f80 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
15f90 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72  {.      return r
15fa0 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e 43 6f  c;.    }.    nCo
15fb0 6c 6c 69 64 65 20 3d 20 48 41 53 48 54 41 42 4c  llide = HASHTABL
15fc0 45 5f 4e 53 4c 4f 54 3b 0a 20 20 20 20 66 6f 72  E_NSLOT;.    for
15fd0 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 70 67  (iKey=walHash(pg
15fe0 6e 6f 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  no); aHash[iKey]
15ff0 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
16000 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
16010 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20 61 48   u32 iFrame = aH
16020 61 73 68 5b 69 4b 65 79 5d 20 2b 20 69 5a 65 72  ash[iKey] + iZer
16030 6f 3b 0a 20 20 20 20 20 20 69 66 28 20 69 46 72  o;.      if( iFr
16040 61 6d 65 3c 3d 69 4c 61 73 74 20 26 26 20 61 50  ame<=iLast && aP
16050 67 6e 6f 5b 61 48 61 73 68 5b 69 4b 65 79 5d 5d  gno[aHash[iKey]]
16060 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20  ==pgno ){.      
16070 20 20 2f 2a 20 61 73 73 65 72 74 28 20 69 46 72    /* assert( iFr
16080 61 6d 65 3e 69 52 65 61 64 20 29 3b 20 2d 2d 20  ame>iRead ); -- 
16090 6e 6f 74 20 74 72 75 65 20 69 66 20 74 68 65 72  not true if ther
160a0 65 20 69 73 20 63 6f 72 72 75 70 74 69 6f 6e 20  e is corruption 
160b0 2a 2f 0a 20 20 20 20 20 20 20 20 69 52 65 61 64  */.        iRead
160c0 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20 20 20   = iFrame;.     
160d0 20 7d 0a 20 20 20 20 20 20 69 66 28 20 28 6e 43   }.      if( (nC
160e0 6f 6c 6c 69 64 65 2d 2d 29 3d 3d 30 20 29 7b 0a  ollide--)==0 ){.
160f0 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 53          return S
16100 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b  QLITE_CORRUPT_BK
16110 50 54 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  PT;.      }.    
16120 7d 0a 20 20 7d 0a 0a 23 69 66 64 65 66 20 53 51  }.  }..#ifdef SQ
16130 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45  LITE_ENABLE_EXPE
16140 4e 53 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f  NSIVE_ASSERT.  /
16150 2a 20 49 66 20 65 78 70 65 6e 73 69 76 65 20 61  * If expensive a
16160 73 73 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e  ssert() statemen
16170 74 73 20 61 72 65 20 61 76 61 69 6c 61 62 6c 65  ts are available
16180 2c 20 64 6f 20 61 20 6c 69 6e 65 61 72 20 73 65  , do a linear se
16190 61 72 63 68 0a 20 20 2a 2a 20 6f 66 20 74 68 65  arch.  ** of the
161a0 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20   wal-index file 
161b0 63 6f 6e 74 65 6e 74 2e 20 4d 61 6b 65 20 73 75  content. Make su
161c0 72 65 20 74 68 65 20 72 65 73 75 6c 74 73 20 61  re the results a
161d0 67 72 65 65 20 77 69 74 68 20 74 68 65 0a 20 20  gree with the.  
161e0 2a 2a 20 72 65 73 75 6c 74 20 6f 62 74 61 69 6e  ** result obtain
161f0 65 64 20 75 73 69 6e 67 20 74 68 65 20 68 61 73  ed using the has
16200 68 20 69 6e 64 65 78 65 73 20 61 62 6f 76 65 2e  h indexes above.
16210 20 20 2a 2f 0a 20 20 7b 0a 20 20 20 20 75 33 32    */.  {.    u32
16220 20 69 52 65 61 64 32 20 3d 20 30 3b 0a 20 20 20   iRead2 = 0;.   
16230 20 75 33 32 20 69 54 65 73 74 3b 0a 20 20 20 20   u32 iTest;.    
16240 66 6f 72 28 69 54 65 73 74 3d 69 4c 61 73 74 3b  for(iTest=iLast;
16250 20 69 54 65 73 74 3e 30 3b 20 69 54 65 73 74 2d   iTest>0; iTest-
16260 2d 29 7b 0a 20 20 20 20 20 20 69 66 28 20 77 61  -){.      if( wa
16270 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c  lFramePgno(pWal,
16280 20 69 54 65 73 74 29 3d 3d 70 67 6e 6f 20 29 7b   iTest)==pgno ){
16290 0a 20 20 20 20 20 20 20 20 69 52 65 61 64 32 20  .        iRead2 
162a0 3d 20 69 54 65 73 74 3b 0a 20 20 20 20 20 20 20  = iTest;.       
162b0 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
162c0 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74      }.    assert
162d0 28 20 69 52 65 61 64 3d 3d 69 52 65 61 64 32 20  ( iRead==iRead2 
162e0 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20  );.  }.#endif.. 
162f0 20 2f 2a 20 49 66 20 69 52 65 61 64 20 69 73 20   /* If iRead is 
16300 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 69  non-zero, then i
16310 74 20 69 73 20 74 68 65 20 6c 6f 67 20 66 72 61  t is the log fra
16320 6d 65 20 6e 75 6d 62 65 72 20 74 68 61 74 20 63  me number that c
16330 6f 6e 74 61 69 6e 73 20 74 68 65 0a 20 20 2a 2a  ontains the.  **
16340 20 72 65 71 75 69 72 65 64 20 70 61 67 65 2e 20   required page. 
16350 52 65 61 64 20 61 6e 64 20 72 65 74 75 72 6e 20  Read and return 
16360 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 6c 6f  data from the lo
16370 67 20 66 69 6c 65 2e 0a 20 20 2a 2f 0a 20 20 69  g file..  */.  i
16380 66 28 20 69 52 65 61 64 20 29 7b 0a 20 20 20 20  f( iRead ){.    
16390 69 6e 74 20 73 7a 3b 0a 20 20 20 20 69 36 34 20  int sz;.    i64 
163a0 69 4f 66 66 73 65 74 3b 0a 20 20 20 20 73 7a 20  iOffset;.    sz 
163b0 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61  = pWal->hdr.szPa
163c0 67 65 3b 0a 20 20 20 20 73 7a 20 3d 20 28 73 7a  ge;.    sz = (sz
163d0 26 30 78 66 65 30 30 29 20 2b 20 28 28 73 7a 26  &0xfe00) + ((sz&
163e0 30 78 30 30 30 31 29 3c 3c 31 36 29 3b 0a 20 20  0x0001)<<16);.  
163f0 20 20 74 65 73 74 63 61 73 65 28 20 73 7a 3c 3d    testcase( sz<=
16400 33 32 37 36 38 20 29 3b 0a 20 20 20 20 74 65 73  32768 );.    tes
16410 74 63 61 73 65 28 20 73 7a 3e 3d 36 35 35 33 36  tcase( sz>=65536
16420 20 29 3b 0a 20 20 20 20 69 4f 66 66 73 65 74 20   );.    iOffset 
16430 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74  = walFrameOffset
16440 28 69 52 65 61 64 2c 20 73 7a 29 20 2b 20 57 41  (iRead, sz) + WA
16450 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b  L_FRAME_HDRSIZE;
16460 0a 20 20 20 20 2a 70 49 6e 57 61 6c 20 3d 20 31  .    *pInWal = 1
16470 3b 0a 20 20 20 20 2f 2a 20 74 65 73 74 63 61 73  ;.    /* testcas
16480 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28 69 4f  e( IS_BIG_INT(iO
16490 66 66 73 65 74 29 20 29 3b 20 2f 2f 20 72 65 71  ffset) ); // req
164a0 75 69 72 65 73 20 61 20 34 47 69 42 20 57 41 4c  uires a 4GiB WAL
164b0 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 73   */.    return s
164c0 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57 61  qlite3OsRead(pWa
164d0 6c 2d 3e 70 57 61 6c 46 64 2c 20 70 4f 75 74 2c  l->pWalFd, pOut,
164e0 20 6e 4f 75 74 2c 20 69 4f 66 66 73 65 74 29 3b   nOut, iOffset);
164f0 0a 20 20 7d 0a 0a 20 20 2a 70 49 6e 57 61 6c 20  .  }..  *pInWal 
16500 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  = 0;.  return SQ
16510 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 20  LITE_OK;.}.../* 
16520 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73  .** Return the s
16530 69 7a 65 20 6f 66 20 74 68 65 20 64 61 74 61 62  ize of the datab
16540 61 73 65 20 69 6e 20 70 61 67 65 73 20 28 6f 72  ase in pages (or
16550 20 7a 65 72 6f 2c 20 69 66 20 75 6e 6b 6e 6f 77   zero, if unknow
16560 6e 29 2e 0a 2a 2f 0a 50 67 6e 6f 20 73 71 6c 69  n)..*/.Pgno sqli
16570 74 65 33 57 61 6c 44 62 73 69 7a 65 28 57 61 6c  te3WalDbsize(Wal
16580 20 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28 20 70   *pWal){.  if( p
16590 57 61 6c 20 26 26 20 41 4c 57 41 59 53 28 70 57  Wal && ALWAYS(pW
165a0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 29  al->readLock>=0)
165b0 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
165c0 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 3b 0a  Wal->hdr.nPage;.
165d0 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a    }.  return 0;.
165e0 7d 0a 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20  }.../* .** This 
165f0 66 75 6e 63 74 69 6f 6e 20 73 74 61 72 74 73 20  function starts 
16600 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74  a write transact
16610 69 6f 6e 20 6f 6e 20 74 68 65 20 57 41 4c 2e 0a  ion on the WAL..
16620 2a 2a 0a 2a 2a 20 41 20 72 65 61 64 20 74 72 61  **.** A read tra
16630 6e 73 61 63 74 69 6f 6e 20 6d 75 73 74 20 68 61  nsaction must ha
16640 76 65 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20  ve already been 
16650 73 74 61 72 74 65 64 20 62 79 20 61 20 70 72 69  started by a pri
16660 6f 72 20 63 61 6c 6c 0a 2a 2a 20 74 6f 20 73 71  or call.** to sq
16670 6c 69 74 65 33 57 61 6c 42 65 67 69 6e 52 65 61  lite3WalBeginRea
16680 64 54 72 61 6e 73 61 63 74 69 6f 6e 28 29 2e 0a  dTransaction()..
16690 2a 2a 0a 2a 2a 20 49 66 20 61 6e 6f 74 68 65 72  **.** If another
166a0 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65   thread or proce
166b0 73 73 20 68 61 73 20 77 72 69 74 74 65 6e 20 69  ss has written i
166c0 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65  nto the database
166d0 20 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 72 65   since.** the re
166e0 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77  ad transaction w
166f0 61 73 20 73 74 61 72 74 65 64 2c 20 74 68 65 6e  as started, then
16700 20 69 74 20 69 73 20 6e 6f 74 20 70 6f 73 73 69   it is not possi
16710 62 6c 65 20 66 6f 72 20 74 68 69 73 0a 2a 2a 20  ble for this.** 
16720 74 68 72 65 61 64 20 74 6f 20 77 72 69 74 65 20  thread to write 
16730 61 73 20 64 6f 69 6e 67 20 73 6f 20 77 6f 75 6c  as doing so woul
16740 64 20 63 61 75 73 65 20 61 20 66 6f 72 6b 2e 20  d cause a fork. 
16750 20 53 6f 20 74 68 69 73 20 72 6f 75 74 69 6e 65   So this routine
16760 0a 2a 2a 20 72 65 74 75 72 6e 73 20 53 51 4c 49  .** returns SQLI
16770 54 45 5f 42 55 53 59 20 69 6e 20 74 68 61 74 20  TE_BUSY in that 
16780 63 61 73 65 20 61 6e 64 20 6e 6f 20 77 72 69 74  case and no writ
16790 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73  e transaction is
167a0 20 73 74 61 72 74 65 64 2e 0a 2a 2a 0a 2a 2a 20   started..**.** 
167b0 54 68 65 72 65 20 63 61 6e 20 6f 6e 6c 79 20 62  There can only b
167c0 65 20 61 20 73 69 6e 67 6c 65 20 77 72 69 74 65  e a single write
167d0 72 20 61 63 74 69 76 65 20 61 74 20 61 20 74 69  r active at a ti
167e0 6d 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  me..*/.int sqlit
167f0 65 33 57 61 6c 42 65 67 69 6e 57 72 69 74 65 54  e3WalBeginWriteT
16800 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a  ransaction(Wal *
16810 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 3b  pWal){.  int rc;
16820 0a 0a 20 20 2f 2a 20 43 61 6e 6e 6f 74 20 73 74  ..  /* Cannot st
16830 61 72 74 20 61 20 77 72 69 74 65 20 74 72 61 6e  art a write tran
16840 73 61 63 74 69 6f 6e 20 77 69 74 68 6f 75 74 20  saction without 
16850 66 69 72 73 74 20 68 6f 6c 64 69 6e 67 20 61 20  first holding a 
16860 72 65 61 64 0a 20 20 2a 2a 20 74 72 61 6e 73 61  read.  ** transa
16870 63 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65  ction. */.  asse
16880 72 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  rt( pWal->readLo
16890 63 6b 3e 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20  ck>=0 );..  if( 
168a0 70 57 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 29  pWal->readOnly )
168b0 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
168c0 49 54 45 5f 52 45 41 44 4f 4e 4c 59 3b 0a 20 20  ITE_READONLY;.  
168d0 7d 0a 0a 20 20 2f 2a 20 4f 6e 6c 79 20 6f 6e 65  }..  /* Only one
168e0 20 77 72 69 74 65 72 20 61 6c 6c 6f 77 65 64 20   writer allowed 
168f0 61 74 20 61 20 74 69 6d 65 2e 20 20 47 65 74 20  at a time.  Get 
16900 74 68 65 20 77 72 69 74 65 20 6c 6f 63 6b 2e 20  the write lock. 
16910 20 52 65 74 75 72 6e 0a 20 20 2a 2a 20 53 51 4c   Return.  ** SQL
16920 49 54 45 5f 42 55 53 59 20 69 66 20 75 6e 61 62  ITE_BUSY if unab
16930 6c 65 2e 0a 20 20 2a 2f 0a 20 20 72 63 20 3d 20  le..  */.  rc = 
16940 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65  walLockExclusive
16950 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45  (pWal, WAL_WRITE
16960 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 69 66 28  _LOCK, 1);.  if(
16970 20 72 63 20 29 7b 0a 20 20 20 20 72 65 74 75 72   rc ){.    retur
16980 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70 57 61 6c  n rc;.  }.  pWal
16990 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 31 3b  ->writeLock = 1;
169a0 0a 0a 20 20 2f 2a 20 49 66 20 61 6e 6f 74 68 65  ..  /* If anothe
169b0 72 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 68 61 73  r connection has
169c0 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20   written to the 
169d0 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 73 69  database file si
169e0 6e 63 65 20 74 68 65 0a 20 20 2a 2a 20 74 69 6d  nce the.  ** tim
169f0 65 20 74 68 65 20 72 65 61 64 20 74 72 61 6e 73  e the read trans
16a00 61 63 74 69 6f 6e 20 6f 6e 20 74 68 69 73 20 63  action on this c
16a10 6f 6e 6e 65 63 74 69 6f 6e 20 77 61 73 20 73 74  onnection was st
16a20 61 72 74 65 64 2c 20 74 68 65 6e 0a 20 20 2a 2a  arted, then.  **
16a30 20 74 68 65 20 77 72 69 74 65 20 69 73 20 64 69   the write is di
16a40 73 61 6c 6c 6f 77 65 64 2e 0a 20 20 2a 2f 0a 20  sallowed..  */. 
16a50 20 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57 61   if( memcmp(&pWa
16a60 6c 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20 2a 29  l->hdr, (void *)
16a70 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c  walIndexHdr(pWal
16a80 29 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64  ), sizeof(WalInd
16a90 65 78 48 64 72 29 29 21 3d 30 20 29 7b 0a 20 20  exHdr))!=0 ){.  
16aa0 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75    walUnlockExclu
16ab0 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57  sive(pWal, WAL_W
16ac0 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  RITE_LOCK, 1);. 
16ad0 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f     pWal->writeLo
16ae0 63 6b 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d  ck = 0;.    rc =
16af0 20 53 51 4c 49 54 45 5f 42 55 53 59 3b 0a 20 20   SQLITE_BUSY;.  
16b00 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
16b10 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 64 20 61 20 77  }../*.** End a w
16b20 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  rite transaction
16b30 2e 20 20 54 68 65 20 63 6f 6d 6d 69 74 20 68 61  .  The commit ha
16b40 73 20 61 6c 72 65 61 64 79 20 62 65 65 6e 20 64  s already been d
16b50 6f 6e 65 2e 20 20 54 68 69 73 0a 2a 2a 20 72 6f  one.  This.** ro
16b60 75 74 69 6e 65 20 6d 65 72 65 6c 79 20 72 65 6c  utine merely rel
16b70 65 61 73 65 73 20 74 68 65 20 6c 6f 63 6b 2e 0a  eases the lock..
16b80 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
16b90 6c 45 6e 64 57 72 69 74 65 54 72 61 6e 73 61 63  lEndWriteTransac
16ba0 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 29 7b  tion(Wal *pWal){
16bb0 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 77 72 69  .  if( pWal->wri
16bc0 74 65 4c 6f 63 6b 20 29 7b 0a 20 20 20 20 77 61  teLock ){.    wa
16bd0 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65  lUnlockExclusive
16be0 28 70 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45  (pWal, WAL_WRITE
16bf0 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 20 20 70  _LOCK, 1);.    p
16c00 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 3d  Wal->writeLock =
16c10 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   0;.  }.  return
16c20 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
16c30 2a 0a 2a 2a 20 49 66 20 61 6e 79 20 64 61 74 61  *.** If any data
16c40 20 68 61 73 20 62 65 65 6e 20 77 72 69 74 74 65   has been writte
16c50 6e 20 28 62 75 74 20 6e 6f 74 20 63 6f 6d 6d 69  n (but not commi
16c60 74 74 65 64 29 20 74 6f 20 74 68 65 20 6c 6f 67  tted) to the log
16c70 20 66 69 6c 65 2c 20 74 68 69 73 0a 2a 2a 20 66   file, this.** f
16c80 75 6e 63 74 69 6f 6e 20 6d 6f 76 65 73 20 74 68  unction moves th
16c90 65 20 77 72 69 74 65 2d 70 6f 69 6e 74 65 72 20  e write-pointer 
16ca0 62 61 63 6b 20 74 6f 20 74 68 65 20 73 74 61 72  back to the star
16cb0 74 20 6f 66 20 74 68 65 20 74 72 61 6e 73 61 63  t of the transac
16cc0 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41 64 64 69  tion..**.** Addi
16cd0 74 69 6f 6e 61 6c 6c 79 2c 20 74 68 65 20 63 61  tionally, the ca
16ce0 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20  llback function 
16cf0 69 73 20 69 6e 76 6f 6b 65 64 20 66 6f 72 20 65  is invoked for e
16d00 61 63 68 20 66 72 61 6d 65 20 77 72 69 74 74 65  ach frame writte
16d10 6e 0a 2a 2a 20 74 6f 20 74 68 65 20 57 41 4c 20  n.** to the WAL 
16d20 73 69 6e 63 65 20 74 68 65 20 73 74 61 72 74 20  since the start 
16d30 6f 66 20 74 68 65 20 74 72 61 6e 73 61 63 74 69  of the transacti
16d40 6f 6e 2e 20 49 66 20 74 68 65 20 63 61 6c 6c 62  on. If the callb
16d50 61 63 6b 20 72 65 74 75 72 6e 73 0a 2a 2a 20 6f  ack returns.** o
16d60 74 68 65 72 20 74 68 61 6e 20 53 51 4c 49 54 45  ther than SQLITE
16d70 5f 4f 4b 2c 20 69 74 20 69 73 20 6e 6f 74 20 69  _OK, it is not i
16d80 6e 76 6f 6b 65 64 20 61 67 61 69 6e 20 61 6e 64  nvoked again and
16d90 20 74 68 65 20 65 72 72 6f 72 20 63 6f 64 65 20   the error code 
16da0 69 73 0a 2a 2a 20 72 65 74 75 72 6e 65 64 20 74  is.** returned t
16db0 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e 0a 2a 2a  o the caller..**
16dc0 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65 2c 20 69  .** Otherwise, i
16dd0 66 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 66  f the callback f
16de0 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20 6e 6f 74  unction does not
16df0 20 72 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72   return an error
16e00 2c 20 74 68 69 73 0a 2a 2a 20 66 75 6e 63 74 69  , this.** functi
16e10 6f 6e 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54  on returns SQLIT
16e20 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  E_OK..*/.int sql
16e30 69 74 65 33 57 61 6c 55 6e 64 6f 28 57 61 6c 20  ite3WalUndo(Wal 
16e40 2a 70 57 61 6c 2c 20 69 6e 74 20 28 2a 78 55 6e  *pWal, int (*xUn
16e50 64 6f 29 28 76 6f 69 64 20 2a 2c 20 50 67 6e 6f  do)(void *, Pgno
16e60 29 2c 20 76 6f 69 64 20 2a 70 55 6e 64 6f 43 74  ), void *pUndoCt
16e70 78 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  x){.  int rc = S
16e80 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20  QLITE_OK;.  if( 
16e90 41 4c 57 41 59 53 28 70 57 61 6c 2d 3e 77 72 69  ALWAYS(pWal->wri
16ea0 74 65 4c 6f 63 6b 29 20 29 7b 0a 20 20 20 20 50  teLock) ){.    P
16eb0 67 6e 6f 20 69 4d 61 78 20 3d 20 70 57 61 6c 2d  gno iMax = pWal-
16ec0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20  >hdr.mxFrame;.  
16ed0 20 20 50 67 6e 6f 20 69 46 72 61 6d 65 3b 0a 20    Pgno iFrame;. 
16ee0 20 0a 20 20 20 20 2f 2a 20 52 65 73 74 6f 72 65   .    /* Restore
16ef0 20 74 68 65 20 63 6c 69 65 6e 74 73 20 63 61 63   the clients cac
16f00 68 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  he of the wal-in
16f10 64 65 78 20 68 65 61 64 65 72 20 74 6f 20 74 68  dex header to th
16f20 65 20 73 74 61 74 65 20 69 74 0a 20 20 20 20 2a  e state it.    *
16f30 2a 20 77 61 73 20 69 6e 20 62 65 66 6f 72 65 20  * was in before 
16f40 74 68 65 20 63 6c 69 65 6e 74 20 62 65 67 61 6e  the client began
16f50 20 77 72 69 74 69 6e 67 20 74 6f 20 74 68 65 20   writing to the 
16f60 64 61 74 61 62 61 73 65 2e 20 0a 20 20 20 20 2a  database. .    *
16f70 2f 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70 57  /.    memcpy(&pW
16f80 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69 64 20 2a  al->hdr, (void *
16f90 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61  )walIndexHdr(pWa
16fa0 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  l), sizeof(WalIn
16fb0 64 65 78 48 64 72 29 29 3b 0a 0a 20 20 20 20 66  dexHdr));..    f
16fc0 6f 72 28 69 46 72 61 6d 65 3d 70 57 61 6c 2d 3e  or(iFrame=pWal->
16fd0 68 64 72 2e 6d 78 46 72 61 6d 65 2b 31 3b 20 0a  hdr.mxFrame+1; .
16fe0 20 20 20 20 20 20 20 20 41 4c 57 41 59 53 28 72          ALWAYS(r
16ff0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 29 20 26 26  c==SQLITE_OK) &&
17000 20 69 46 72 61 6d 65 3c 3d 69 4d 61 78 3b 20 0a   iFrame<=iMax; .
17010 20 20 20 20 20 20 20 20 69 46 72 61 6d 65 2b 2b          iFrame++
17020 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 2f 2a  .    ){.      /*
17030 20 54 68 69 73 20 63 61 6c 6c 20 63 61 6e 6e 6f   This call canno
17040 74 20 66 61 69 6c 2e 20 55 6e 6c 65 73 73 20 74  t fail. Unless t
17050 68 65 20 70 61 67 65 20 66 6f 72 20 77 68 69 63  he page for whic
17060 68 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62 65  h the page numbe
17070 72 0a 20 20 20 20 20 20 2a 2a 20 69 73 20 70 61  r.      ** is pa
17080 73 73 65 64 20 61 73 20 74 68 65 20 73 65 63 6f  ssed as the seco
17090 6e 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20 28  nd argument is (
170a0 61 29 20 69 6e 20 74 68 65 20 63 61 63 68 65 20  a) in the cache 
170b0 61 6e 64 20 0a 20 20 20 20 20 20 2a 2a 20 28 62  and .      ** (b
170c0 29 20 68 61 73 20 61 6e 20 6f 75 74 73 74 61 6e  ) has an outstan
170d0 64 69 6e 67 20 72 65 66 65 72 65 6e 63 65 2c 20  ding reference, 
170e0 74 68 65 6e 20 78 55 6e 64 6f 20 69 73 20 65 69  then xUndo is ei
170f0 74 68 65 72 20 61 20 6e 6f 2d 6f 70 0a 20 20 20  ther a no-op.   
17100 20 20 20 2a 2a 20 28 69 66 20 28 61 29 20 69 73     ** (if (a) is
17110 20 66 61 6c 73 65 29 20 6f 72 20 73 69 6d 70 6c   false) or simpl
17120 79 20 65 78 70 65 6c 73 20 74 68 65 20 70 61 67  y expels the pag
17130 65 20 66 72 6f 6d 20 74 68 65 20 63 61 63 68 65  e from the cache
17140 20 28 69 66 20 28 62 29 0a 20 20 20 20 20 20 2a   (if (b).      *
17150 2a 20 69 73 20 66 61 6c 73 65 29 2e 0a 20 20 20  * is false)..   
17160 20 20 20 2a 2a 0a 20 20 20 20 20 20 2a 2a 20 49     **.      ** I
17170 66 20 74 68 65 20 75 70 70 65 72 20 6c 61 79 65  f the upper laye
17180 72 20 69 73 20 64 6f 69 6e 67 20 61 20 72 6f 6c  r is doing a rol
17190 6c 62 61 63 6b 2c 20 69 74 20 69 73 20 67 75 61  lback, it is gua
171a0 72 61 6e 74 65 65 64 20 74 68 61 74 20 74 68 65  ranteed that the
171b0 72 65 0a 20 20 20 20 20 20 2a 2a 20 61 72 65 20  re.      ** are 
171c0 6e 6f 20 6f 75 74 73 74 61 6e 64 69 6e 67 20 72  no outstanding r
171d0 65 66 65 72 65 6e 63 65 73 20 74 6f 20 61 6e 79  eferences to any
171e0 20 70 61 67 65 20 6f 74 68 65 72 20 74 68 61 6e   page other than
171f0 20 70 61 67 65 20 31 2e 20 41 6e 64 0a 20 20 20   page 1. And.   
17200 20 20 20 2a 2a 20 70 61 67 65 20 31 20 69 73 20     ** page 1 is 
17210 6e 65 76 65 72 20 77 72 69 74 74 65 6e 20 74 6f  never written to
17220 20 74 68 65 20 6c 6f 67 20 75 6e 74 69 6c 20 74   the log until t
17230 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69  he transaction i
17240 73 0a 20 20 20 20 20 20 2a 2a 20 63 6f 6d 6d 69  s.      ** commi
17250 74 74 65 64 2e 20 41 73 20 61 20 72 65 73 75 6c  tted. As a resul
17260 74 2c 20 74 68 65 20 63 61 6c 6c 20 74 6f 20 78  t, the call to x
17270 55 6e 64 6f 20 6d 61 79 20 6e 6f 74 20 66 61 69  Undo may not fai
17280 6c 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  l..      */.    
17290 20 20 61 73 73 65 72 74 28 20 77 61 6c 46 72 61    assert( walFra
172a0 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69 46 72  mePgno(pWal, iFr
172b0 61 6d 65 29 21 3d 31 20 29 3b 0a 20 20 20 20 20  ame)!=1 );.     
172c0 20 72 63 20 3d 20 78 55 6e 64 6f 28 70 55 6e 64   rc = xUndo(pUnd
172d0 6f 43 74 78 2c 20 77 61 6c 46 72 61 6d 65 50 67  oCtx, walFramePg
172e0 6e 6f 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29  no(pWal, iFrame)
172f0 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 77 61 6c  );.    }.    wal
17300 43 6c 65 61 6e 75 70 48 61 73 68 28 70 57 61 6c  CleanupHash(pWal
17310 29 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28  );.  }.  assert(
17320 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
17330 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
17340 0a 0a 2f 2a 20 0a 2a 2a 20 41 72 67 75 6d 65 6e  ../* .** Argumen
17350 74 20 61 57 61 6c 44 61 74 61 20 6d 75 73 74 20  t aWalData must 
17360 70 6f 69 6e 74 20 74 6f 20 61 6e 20 61 72 72 61  point to an arra
17370 79 20 6f 66 20 57 41 4c 5f 53 41 56 45 50 4f 49  y of WAL_SAVEPOI
17380 4e 54 5f 4e 44 41 54 41 20 75 33 32 20 0a 2a 2a  NT_NDATA u32 .**
17390 20 76 61 6c 75 65 73 2e 20 54 68 69 73 20 66 75   values. This fu
173a0 6e 63 74 69 6f 6e 20 70 6f 70 75 6c 61 74 65 73  nction populates
173b0 20 74 68 65 20 61 72 72 61 79 20 77 69 74 68 20   the array with 
173c0 76 61 6c 75 65 73 20 72 65 71 75 69 72 65 64 20  values required 
173d0 74 6f 20 0a 2a 2a 20 22 72 6f 6c 6c 62 61 63 6b  to .** "rollback
173e0 22 20 74 68 65 20 77 72 69 74 65 20 70 6f 73 69  " the write posi
173f0 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41 4c 20  tion of the WAL 
17400 68 61 6e 64 6c 65 20 62 61 63 6b 20 74 6f 20 74  handle back to t
17410 68 65 20 63 75 72 72 65 6e 74 20 0a 2a 2a 20 70  he current .** p
17420 6f 69 6e 74 20 69 6e 20 74 68 65 20 65 76 65 6e  oint in the even
17430 74 20 6f 66 20 61 20 73 61 76 65 70 6f 69 6e 74  t of a savepoint
17440 20 72 6f 6c 6c 62 61 63 6b 20 28 76 69 61 20 57   rollback (via W
17450 61 6c 53 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28  alSavepointUndo(
17460 29 29 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c 69  ))..*/.void sqli
17470 74 65 33 57 61 6c 53 61 76 65 70 6f 69 6e 74 28  te3WalSavepoint(
17480 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a  Wal *pWal, u32 *
17490 61 57 61 6c 44 61 74 61 29 7b 0a 20 20 61 73 73  aWalData){.  ass
174a0 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65  ert( pWal->write
174b0 4c 6f 63 6b 20 29 3b 0a 20 20 61 57 61 6c 44 61  Lock );.  aWalDa
174c0 74 61 5b 30 5d 20 3d 20 70 57 61 6c 2d 3e 68 64  ta[0] = pWal->hd
174d0 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 61 57 61  r.mxFrame;.  aWa
174e0 6c 44 61 74 61 5b 31 5d 20 3d 20 70 57 61 6c 2d  lData[1] = pWal-
174f0 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
17500 5b 30 5d 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b  [0];.  aWalData[
17510 32 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61  2] = pWal->hdr.a
17520 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a 20  FrameCksum[1];. 
17530 20 61 57 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70   aWalData[3] = p
17540 57 61 6c 2d 3e 6e 43 6b 70 74 3b 0a 7d 0a 0a 2f  Wal->nCkpt;.}../
17550 2a 20 0a 2a 2a 20 4d 6f 76 65 20 74 68 65 20 77  * .** Move the w
17560 72 69 74 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66  rite position of
17570 20 74 68 65 20 57 41 4c 20 62 61 63 6b 20 74 6f   the WAL back to
17580 20 74 68 65 20 70 6f 69 6e 74 20 69 64 65 6e 74   the point ident
17590 69 66 69 65 64 20 62 79 0a 2a 2a 20 74 68 65 20  ified by.** the 
175a0 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 61 57  values in the aW
175b0 61 6c 44 61 74 61 5b 5d 20 61 72 72 61 79 2e 20  alData[] array. 
175c0 61 57 61 6c 44 61 74 61 20 6d 75 73 74 20 70 6f  aWalData must po
175d0 69 6e 74 20 74 6f 20 61 6e 20 61 72 72 61 79 0a  int to an array.
175e0 2a 2a 20 6f 66 20 57 41 4c 5f 53 41 56 45 50 4f  ** of WAL_SAVEPO
175f0 49 4e 54 5f 4e 44 41 54 41 20 75 33 32 20 76 61  INT_NDATA u32 va
17600 6c 75 65 73 20 74 68 61 74 20 68 61 73 20 62 65  lues that has be
17610 65 6e 20 70 72 65 76 69 6f 75 73 6c 79 20 70 6f  en previously po
17620 70 75 6c 61 74 65 64 0a 2a 2a 20 62 79 20 61 20  pulated.** by a 
17630 63 61 6c 6c 20 74 6f 20 57 61 6c 53 61 76 65 70  call to WalSavep
17640 6f 69 6e 74 28 29 2e 0a 2a 2f 0a 69 6e 74 20 73  oint()..*/.int s
17650 71 6c 69 74 65 33 57 61 6c 53 61 76 65 70 6f 69  qlite3WalSavepoi
17660 6e 74 55 6e 64 6f 28 57 61 6c 20 2a 70 57 61 6c  ntUndo(Wal *pWal
17670 2c 20 75 33 32 20 2a 61 57 61 6c 44 61 74 61 29  , u32 *aWalData)
17680 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
17690 49 54 45 5f 4f 4b 3b 0a 0a 20 20 61 73 73 65 72  ITE_OK;..  asser
176a0 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  t( pWal->writeLo
176b0 63 6b 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  ck );.  assert( 
176c0 61 57 61 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61  aWalData[3]!=pWa
176d0 6c 2d 3e 6e 43 6b 70 74 20 7c 7c 20 61 57 61 6c  l->nCkpt || aWal
176e0 44 61 74 61 5b 30 5d 3c 3d 70 57 61 6c 2d 3e 68  Data[0]<=pWal->h
176f0 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 0a 20  dr.mxFrame );.. 
17700 20 69 66 28 20 61 57 61 6c 44 61 74 61 5b 33 5d   if( aWalData[3]
17710 21 3d 70 57 61 6c 2d 3e 6e 43 6b 70 74 20 29 7b  !=pWal->nCkpt ){
17720 0a 20 20 20 20 2f 2a 20 54 68 69 73 20 73 61 76  .    /* This sav
17730 65 70 6f 69 6e 74 20 77 61 73 20 6f 70 65 6e 65  epoint was opene
17740 64 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 61 66  d immediately af
17750 74 65 72 20 74 68 65 20 77 72 69 74 65 2d 74 72  ter the write-tr
17760 61 6e 73 61 63 74 69 6f 6e 0a 20 20 20 20 2a 2a  ansaction.    **
17770 20 77 61 73 20 73 74 61 72 74 65 64 2e 20 52 69   was started. Ri
17780 67 68 74 20 61 66 74 65 72 20 74 68 61 74 2c 20  ght after that, 
17790 74 68 65 20 77 72 69 74 65 72 20 64 65 63 69 64  the writer decid
177a0 65 64 20 74 6f 20 77 72 61 70 20 61 72 6f 75 6e  ed to wrap aroun
177b0 64 0a 20 20 20 20 2a 2a 20 74 6f 20 74 68 65 20  d.    ** to the 
177c0 73 74 61 72 74 20 6f 66 20 74 68 65 20 6c 6f 67  start of the log
177d0 2e 20 55 70 64 61 74 65 20 74 68 65 20 73 61 76  . Update the sav
177e0 65 70 6f 69 6e 74 20 76 61 6c 75 65 73 20 74 6f  epoint values to
177f0 20 6d 61 74 63 68 2e 0a 20 20 20 20 2a 2f 0a 20   match..    */. 
17800 20 20 20 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d     aWalData[0] =
17810 20 30 3b 0a 20 20 20 20 61 57 61 6c 44 61 74 61   0;.    aWalData
17820 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e 6e 43 6b 70  [3] = pWal->nCkp
17830 74 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 61 57  t;.  }..  if( aW
17840 61 6c 44 61 74 61 5b 30 5d 3c 70 57 61 6c 2d 3e  alData[0]<pWal->
17850 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20  hdr.mxFrame ){. 
17860 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46     pWal->hdr.mxF
17870 72 61 6d 65 20 3d 20 61 57 61 6c 44 61 74 61 5b  rame = aWalData[
17880 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64  0];.    pWal->hd
17890 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d  r.aFrameCksum[0]
178a0 20 3d 20 61 57 61 6c 44 61 74 61 5b 31 5d 3b 0a   = aWalData[1];.
178b0 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46      pWal->hdr.aF
178c0 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 61  rameCksum[1] = a
178d0 57 61 6c 44 61 74 61 5b 32 5d 3b 0a 20 20 20 20  WalData[2];.    
178e0 77 61 6c 43 6c 65 61 6e 75 70 48 61 73 68 28 70  walCleanupHash(p
178f0 57 61 6c 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  Wal);.  }..  ret
17900 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
17910 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
17920 73 20 63 61 6c 6c 65 64 20 6a 75 73 74 20 62 65  s called just be
17930 66 6f 72 65 20 77 72 69 74 69 6e 67 20 61 20 73  fore writing a s
17940 65 74 20 6f 66 20 66 72 61 6d 65 73 20 74 6f 20  et of frames to 
17950 74 68 65 20 6c 6f 67 0a 2a 2a 20 66 69 6c 65 20  the log.** file 
17960 28 73 65 65 20 73 71 6c 69 74 65 33 57 61 6c 46  (see sqlite3WalF
17970 72 61 6d 65 73 28 29 29 2e 20 49 74 20 63 68 65  rames()). It che
17980 63 6b 73 20 74 6f 20 73 65 65 20 69 66 2c 20 69  cks to see if, i
17990 6e 73 74 65 61 64 20 6f 66 20 61 70 70 65 6e 64  nstead of append
179a0 69 6e 67 0a 2a 2a 20 74 6f 20 74 68 65 20 63 75  ing.** to the cu
179b0 72 72 65 6e 74 20 6c 6f 67 20 66 69 6c 65 2c 20  rrent log file, 
179c0 69 74 20 69 73 20 70 6f 73 73 69 62 6c 65 20 74  it is possible t
179d0 6f 20 6f 76 65 72 77 72 69 74 65 20 74 68 65 20  o overwrite the 
179e0 73 74 61 72 74 20 6f 66 20 74 68 65 0a 2a 2a 20  start of the.** 
179f0 65 78 69 73 74 69 6e 67 20 6c 6f 67 20 66 69 6c  existing log fil
17a00 65 20 77 69 74 68 20 74 68 65 20 6e 65 77 20 66  e with the new f
17a10 72 61 6d 65 73 20 28 69 2e 65 2e 20 22 72 65 73  rames (i.e. "res
17a20 65 74 22 20 74 68 65 20 6c 6f 67 29 2e 20 49 66  et" the log). If
17a30 20 73 6f 2c 0a 2a 2a 20 69 74 20 73 65 74 73 20   so,.** it sets 
17a40 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
17a50 65 20 74 6f 20 30 2e 20 4f 74 68 65 72 77 69 73  e to 0. Otherwis
17a60 65 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  e, pWal->hdr.mxF
17a70 72 61 6d 65 20 69 73 20 6c 65 66 74 0a 2a 2a 20  rame is left.** 
17a80 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2a 0a 2a 2a  unchanged..**.**
17a90 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65   SQLITE_OK is re
17aa0 74 75 72 6e 65 64 20 69 66 20 6e 6f 20 65 72 72  turned if no err
17ab0 6f 72 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65  or is encountere
17ac0 64 20 28 72 65 67 61 72 64 6c 65 73 73 20 6f 66  d (regardless of
17ad0 20 77 68 65 74 68 65 72 0a 2a 2a 20 6f 72 20 6e   whether.** or n
17ae0 6f 74 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ot pWal->hdr.mxF
17af0 72 61 6d 65 20 69 73 20 6d 6f 64 69 66 69 65 64  rame is modified
17b00 29 2e 20 41 6e 20 53 51 4c 69 74 65 20 65 72 72  ). An SQLite err
17b10 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72  or code is retur
17b20 6e 65 64 0a 2a 2a 20 69 66 20 61 6e 20 65 72 72  ned.** if an err
17b30 6f 72 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74  or occurs..*/.st
17b40 61 74 69 63 20 69 6e 74 20 77 61 6c 52 65 73 74  atic int walRest
17b50 61 72 74 4c 6f 67 28 57 61 6c 20 2a 70 57 61 6c  artLog(Wal *pWal
17b60 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
17b70 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 63  LITE_OK;.  int c
17b80 6e 74 3b 0a 0a 20 20 69 66 28 20 70 57 61 6c 2d  nt;..  if( pWal-
17b90 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20 29 7b 0a  >readLock==0 ){.
17ba0 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c      volatile Wal
17bb0 43 6b 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 20  CkptInfo *pInfo 
17bc0 3d 20 77 61 6c 43 6b 70 74 49 6e 66 6f 28 70 57  = walCkptInfo(pW
17bd0 61 6c 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  al);.    assert(
17be0 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
17bf0 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  l==pWal->hdr.mxF
17c00 72 61 6d 65 20 29 3b 0a 20 20 20 20 69 66 28 20  rame );.    if( 
17c10 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
17c20 3e 30 20 29 7b 0a 20 20 20 20 20 20 75 33 32 20  >0 ){.      u32 
17c30 73 61 6c 74 31 3b 0a 20 20 20 20 20 20 73 71 6c  salt1;.      sql
17c40 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28  ite3_randomness(
17c50 34 2c 20 26 73 61 6c 74 31 29 3b 0a 20 20 20 20  4, &salt1);.    
17c60 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78    rc = walLockEx
17c70 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
17c80 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20  L_READ_LOCK(1), 
17c90 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a  WAL_NREADER-1);.
17ca0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
17cb0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
17cc0 20 20 20 2f 2a 20 49 66 20 61 6c 6c 20 72 65 61     /* If all rea
17cd0 64 65 72 73 20 61 72 65 20 75 73 69 6e 67 20 57  ders are using W
17ce0 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20  AL_READ_LOCK(0) 
17cf0 28 69 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 20  (in other words 
17d00 69 66 20 6e 6f 0a 20 20 20 20 20 20 20 20 2a 2a  if no.        **
17d10 20 72 65 61 64 65 72 73 20 61 72 65 20 63 75 72   readers are cur
17d20 72 65 6e 74 6c 79 20 75 73 69 6e 67 20 74 68 65  rently using the
17d30 20 57 41 4c 29 2c 20 74 68 65 6e 20 74 68 65 20   WAL), then the 
17d40 74 72 61 6e 73 61 63 74 69 6f 6e 73 0a 20 20 20  transactions.   
17d50 20 20 20 20 20 2a 2a 20 66 72 61 6d 65 73 20 77       ** frames w
17d60 69 6c 6c 20 6f 76 65 72 77 72 69 74 65 20 74 68  ill overwrite th
17d70 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 65  e start of the e
17d80 78 69 73 74 69 6e 67 20 6c 6f 67 2e 20 55 70 64  xisting log. Upd
17d90 61 74 65 20 74 68 65 0a 20 20 20 20 20 20 20 20  ate the.        
17da0 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  ** wal-index hea
17db0 64 65 72 20 74 6f 20 72 65 66 6c 65 63 74 20 74  der to reflect t
17dc0 68 69 73 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a  his..        **.
17dd0 20 20 20 20 20 20 20 20 2a 2a 20 49 6e 20 74 68          ** In th
17de0 65 6f 72 79 20 69 74 20 77 6f 75 6c 64 20 62 65  eory it would be
17df0 20 4f 6b 20 74 6f 20 75 70 64 61 74 65 20 74 68   Ok to update th
17e00 65 20 63 61 63 68 65 20 6f 66 20 74 68 65 20 68  e cache of the h
17e10 65 61 64 65 72 20 6f 6e 6c 79 0a 20 20 20 20 20  eader only.     
17e20 20 20 20 2a 2a 20 61 74 20 74 68 69 73 20 70 6f     ** at this po
17e30 69 6e 74 2e 20 42 75 74 20 75 70 64 61 74 69 6e  int. But updatin
17e40 67 20 74 68 65 20 61 63 74 75 61 6c 20 77 61 6c  g the actual wal
17e50 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73  -index header is
17e60 20 61 6c 73 6f 0a 20 20 20 20 20 20 20 20 2a 2a   also.        **
17e70 20 73 61 66 65 20 61 6e 64 20 6d 65 61 6e 73 20   safe and means 
17e80 74 68 65 72 65 20 69 73 20 6e 6f 20 73 70 65 63  there is no spec
17e90 69 61 6c 20 63 61 73 65 20 66 6f 72 20 73 71 6c  ial case for sql
17ea0 69 74 65 33 57 61 6c 55 6e 64 6f 28 29 0a 20 20  ite3WalUndo().  
17eb0 20 20 20 20 20 20 2a 2a 20 74 6f 20 68 61 6e 64        ** to hand
17ec0 6c 65 20 69 66 20 74 68 69 73 20 74 72 61 6e 73  le if this trans
17ed0 61 63 74 69 6f 6e 20 69 73 20 72 6f 6c 6c 65 64  action is rolled
17ee0 20 62 61 63 6b 2e 0a 20 20 20 20 20 20 20 20 2a   back..        *
17ef0 2f 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 3b  /.        int i;
17f00 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17f10 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e      /* Loop coun
17f20 74 65 72 20 2a 2f 0a 20 20 20 20 20 20 20 20 75  ter */.        u
17f30 33 32 20 2a 61 53 61 6c 74 20 3d 20 70 57 61 6c  32 *aSalt = pWal
17f40 2d 3e 68 64 72 2e 61 53 61 6c 74 3b 20 20 20 20  ->hdr.aSalt;    
17f50 20 20 20 2f 2a 20 42 69 67 2d 65 6e 64 69 61 6e     /* Big-endian
17f60 20 73 61 6c 74 20 76 61 6c 75 65 73 20 2a 2f 0a   salt values */.
17f70 0a 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 6d 69  .        /* Limi
17f80 74 20 74 68 65 20 73 69 7a 65 20 6f 66 20 57 41  t the size of WA
17f90 4c 20 66 69 6c 65 20 69 66 20 74 68 65 20 6a 6f  L file if the jo
17fa0 75 72 6e 61 6c 5f 73 69 7a 65 5f 6c 69 6d 69 74  urnal_size_limit
17fb0 20 50 52 41 47 4d 41 20 69 73 0a 20 20 20 20 20   PRAGMA is.     
17fc0 20 20 20 2a 2a 20 73 65 74 20 74 6f 20 61 20 6e     ** set to a n
17fd0 6f 6e 2d 6e 65 67 61 74 69 76 65 20 76 61 6c 75  on-negative valu
17fe0 65 2e 20 20 4c 6f 67 20 65 72 72 6f 72 73 20 65  e.  Log errors e
17ff0 6e 63 6f 75 6e 74 65 72 65 64 0a 20 20 20 20 20  ncountered.     
18000 20 20 20 2a 2a 20 64 75 72 69 6e 67 20 74 68 65     ** during the
18010 20 74 72 75 6e 63 61 74 69 6f 6e 20 61 74 74 65   truncation atte
18020 6d 70 74 2e 20 2a 2f 0a 20 20 20 20 20 20 20 20  mpt. */.        
18030 69 66 28 20 70 57 61 6c 2d 3e 6d 78 57 61 6c 53  if( pWal->mxWalS
18040 69 7a 65 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20  ize>=0 ){.      
18050 20 20 20 20 69 36 34 20 73 7a 3b 0a 20 20 20 20      i64 sz;.    
18060 20 20 20 20 20 20 69 6e 74 20 72 78 3b 0a 20 20        int rx;.  
18070 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 42          sqlite3B
18080 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63  eginBenignMalloc
18090 28 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 78  ();.          rx
180a0 20 3d 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65   = sqlite3OsFile
180b0 53 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46  Size(pWal->pWalF
180c0 64 2c 20 26 73 7a 29 3b 0a 20 20 20 20 20 20 20  d, &sz);.       
180d0 20 20 20 69 66 28 20 72 78 3d 3d 53 51 4c 49 54     if( rx==SQLIT
180e0 45 5f 4f 4b 20 26 26 20 28 73 7a 20 3e 20 70 57  E_OK && (sz > pW
180f0 61 6c 2d 3e 6d 78 57 61 6c 53 69 7a 65 29 20 29  al->mxWalSize) )
18100 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 78  {.            rx
18110 20 3d 20 73 71 6c 69 74 65 33 4f 73 54 72 75 6e   = sqlite3OsTrun
18120 63 61 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46  cate(pWal->pWalF
18130 64 2c 20 70 57 61 6c 2d 3e 6d 78 57 61 6c 53 69  d, pWal->mxWalSi
18140 7a 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  ze);.          }
18150 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74  .          sqlit
18160 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f  e3EndBenignMallo
18170 63 28 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69  c();.          i
18180 66 28 20 72 78 20 29 7b 0a 20 20 20 20 20 20 20  f( rx ){.       
18190 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6c 6f 67       sqlite3_log
181a0 28 72 78 2c 20 22 63 61 6e 6e 6f 74 20 6c 69 6d  (rx, "cannot lim
181b0 69 74 20 57 41 4c 20 73 69 7a 65 3a 20 25 73 22  it WAL size: %s"
181c0 2c 20 70 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65  , pWal->zWalName
181d0 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  );.          }. 
181e0 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20         }..      
181f0 20 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 2b 2b 3b    pWal->nCkpt++;
18200 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 68  .        pWal->h
18210 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20 30 3b 0a  dr.mxFrame = 0;.
18220 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 50          sqlite3P
18230 75 74 34 62 79 74 65 28 28 75 38 2a 29 26 61 53  ut4byte((u8*)&aS
18240 61 6c 74 5b 30 5d 2c 20 31 20 2b 20 73 71 6c 69  alt[0], 1 + sqli
18250 74 65 33 47 65 74 34 62 79 74 65 28 28 75 38 2a  te3Get4byte((u8*
18260 29 26 61 53 61 6c 74 5b 30 5d 29 29 3b 0a 20 20  )&aSalt[0]));.  
18270 20 20 20 20 20 20 61 53 61 6c 74 5b 31 5d 20 3d        aSalt[1] =
18280 20 73 61 6c 74 31 3b 0a 20 20 20 20 20 20 20 20   salt1;.        
18290 77 61 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72  walIndexWriteHdr
182a0 28 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 20 20  (pWal);.        
182b0 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
182c0 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 66 6f   = 0;.        fo
182d0 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52 45  r(i=1; i<WAL_NRE
182e0 41 44 45 52 3b 20 69 2b 2b 29 20 70 49 6e 66 6f  ADER; i++) pInfo
182f0 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d  ->aReadMark[i] =
18300 20 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53   READMARK_NOT_US
18310 45 44 3b 0a 20 20 20 20 20 20 20 20 61 73 73 65  ED;.        asse
18320 72 74 28 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64  rt( pInfo->aRead
18330 4d 61 72 6b 5b 30 5d 3d 3d 30 20 29 3b 0a 20 20  Mark[0]==0 );.  
18340 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45        walUnlockE
18350 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
18360 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c  AL_READ_LOCK(1),
18370 20 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b   WAL_NREADER-1);
18380 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
18390 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc!=SQLITE_BUSY
183a0 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75   ){.        retu
183b0 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20  rn rc;.      }. 
183c0 20 20 20 7d 0a 20 20 20 20 77 61 6c 55 6e 6c 6f     }.    walUnlo
183d0 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
183e0 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29  AL_READ_LOCK(0))
183f0 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64  ;.    pWal->read
18400 4c 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20 20 20 63  Lock = -1;.    c
18410 6e 74 20 3d 20 30 3b 0a 20 20 20 20 64 6f 7b 0a  nt = 0;.    do{.
18420 20 20 20 20 20 20 69 6e 74 20 6e 6f 74 55 73 65        int notUse
18430 64 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61  d;.      rc = wa
18440 6c 54 72 79 42 65 67 69 6e 52 65 61 64 28 70 57  lTryBeginRead(pW
18450 61 6c 2c 20 26 6e 6f 74 55 73 65 64 2c 20 31 2c  al, &notUsed, 1,
18460 20 2b 2b 63 6e 74 29 3b 0a 20 20 20 20 7d 77 68   ++cnt);.    }wh
18470 69 6c 65 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54  ile( rc==WAL_RET
18480 52 59 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74  RY );.    assert
18490 28 20 28 72 63 26 30 78 66 66 29 21 3d 53 51 4c  ( (rc&0xff)!=SQL
184a0 49 54 45 5f 42 55 53 59 20 29 3b 20 2f 2a 20 42  ITE_BUSY ); /* B
184b0 55 53 59 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65  USY not possible
184c0 20 77 68 65 6e 20 75 73 65 57 61 6c 3d 3d 31 20   when useWal==1 
184d0 2a 2f 0a 20 20 20 20 74 65 73 74 63 61 73 65 28  */.    testcase(
184e0 20 28 72 63 26 30 78 66 66 29 3d 3d 53 51 4c 49   (rc&0xff)==SQLI
184f0 54 45 5f 49 4f 45 52 52 20 29 3b 0a 20 20 20 20  TE_IOERR );.    
18500 74 65 73 74 63 61 73 65 28 20 72 63 3d 3d 53 51  testcase( rc==SQ
18510 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 20 29 3b  LITE_PROTOCOL );
18520 0a 20 20 20 20 74 65 73 74 63 61 73 65 28 20 72  .    testcase( r
18530 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c==SQLITE_OK );.
18540 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
18550 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 57 72 69 74 65  .}../* .** Write
18560 20 61 20 73 65 74 20 6f 66 20 66 72 61 6d 65 73   a set of frames
18570 20 74 6f 20 74 68 65 20 6c 6f 67 2e 20 54 68 65   to the log. The
18580 20 63 61 6c 6c 65 72 20 6d 75 73 74 20 68 6f 6c   caller must hol
18590 64 20 74 68 65 20 77 72 69 74 65 2d 6c 6f 63 6b  d the write-lock
185a0 0a 2a 2a 20 6f 6e 20 74 68 65 20 6c 6f 67 20 66  .** on the log f
185b0 69 6c 65 20 28 6f 62 74 61 69 6e 65 64 20 75 73  ile (obtained us
185c0 69 6e 67 20 73 71 6c 69 74 65 33 57 61 6c 42 65  ing sqlite3WalBe
185d0 67 69 6e 57 72 69 74 65 54 72 61 6e 73 61 63 74  ginWriteTransact
185e0 69 6f 6e 28 29 29 2e 0a 2a 2f 0a 69 6e 74 20 73  ion())..*/.int s
185f0 71 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73 28  qlite3WalFrames(
18600 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20  .  Wal *pWal,   
18610 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18620 20 20 20 2f 2a 20 57 61 6c 20 68 61 6e 64 6c 65     /* Wal handle
18630 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a   to write to */.
18640 20 20 69 6e 74 20 73 7a 50 61 67 65 2c 20 20 20    int szPage,   
18650 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18660 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61    /* Database pa
18670 67 65 2d 73 69 7a 65 20 69 6e 20 62 79 74 65 73  ge-size in bytes
18680 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 4c 69   */.  PgHdr *pLi
18690 73 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  st,             
186a0 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f 66        /* List of
186b0 20 64 69 72 74 79 20 70 61 67 65 73 20 74 6f 20   dirty pages to 
186c0 77 72 69 74 65 20 2a 2f 0a 20 20 50 67 6e 6f 20  write */.  Pgno 
186d0 6e 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20  nTruncate,      
186e0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
186f0 74 61 62 61 73 65 20 73 69 7a 65 20 61 66 74 65  tabase size afte
18700 72 20 74 68 69 73 20 63 6f 6d 6d 69 74 20 2a 2f  r this commit */
18710 0a 20 20 69 6e 74 20 69 73 43 6f 6d 6d 69 74 2c  .  int isCommit,
18720 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18730 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 74 68     /* True if th
18740 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 20 2a  is is a commit *
18750 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61  /.  int sync_fla
18760 67 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20  gs              
18770 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20      /* Flags to 
18780 70 61 73 73 20 74 6f 20 4f 73 53 79 6e 63 28 29  pass to OsSync()
18790 20 28 6f 72 20 30 29 20 2a 2f 0a 29 7b 0a 20 20   (or 0) */.){.  
187a0 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
187b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
187c0 2f 2a 20 55 73 65 64 20 74 6f 20 63 61 74 63 68  /* Used to catch
187d0 20 72 65 74 75 72 6e 20 63 6f 64 65 73 20 2a 2f   return codes */
187e0 0a 20 20 75 33 32 20 69 46 72 61 6d 65 3b 20 20  .  u32 iFrame;  
187f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18800 20 20 20 2f 2a 20 4e 65 78 74 20 66 72 61 6d 65     /* Next frame
18810 20 61 64 64 72 65 73 73 20 2a 2f 0a 20 20 75 38   address */.  u8
18820 20 61 46 72 61 6d 65 5b 57 41 4c 5f 46 52 41 4d   aFrame[WAL_FRAM
18830 45 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20 2f 2a  E_HDRSIZE];   /*
18840 20 42 75 66 66 65 72 20 74 6f 20 61 73 73 65 6d   Buffer to assem
18850 62 6c 65 20 66 72 61 6d 65 2d 68 65 61 64 65 72  ble frame-header
18860 20 69 6e 20 2a 2f 0a 20 20 50 67 48 64 72 20 2a   in */.  PgHdr *
18870 70 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p;              
18880 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72           /* Iter
18890 61 74 6f 72 20 74 6f 20 72 75 6e 20 74 68 72 6f  ator to run thro
188a0 75 67 68 20 70 4c 69 73 74 20 77 69 74 68 2e 20  ugh pList with. 
188b0 2a 2f 0a 20 20 50 67 48 64 72 20 2a 70 4c 61 73  */.  PgHdr *pLas
188c0 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  t = 0;          
188d0 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 66 72 61       /* Last fra
188e0 6d 65 20 69 6e 20 6c 69 73 74 20 2a 2f 0a 20 20  me in list */.  
188f0 69 6e 74 20 6e 4c 61 73 74 20 3d 20 30 3b 20 20  int nLast = 0;  
18900 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18910 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 78 74  /* Number of ext
18920 72 61 20 63 6f 70 69 65 73 20 6f 66 20 6c 61 73  ra copies of las
18930 74 20 70 61 67 65 20 2a 2f 0a 0a 20 20 61 73 73  t page */..  ass
18940 65 72 74 28 20 70 4c 69 73 74 20 29 3b 0a 20 20  ert( pList );.  
18950 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72  assert( pWal->wr
18960 69 74 65 4c 6f 63 6b 20 29 3b 0a 0a 23 69 66 20  iteLock );..#if 
18970 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54  defined(SQLITE_T
18980 45 53 54 29 20 26 26 20 64 65 66 69 6e 65 64 28  EST) && defined(
18990 53 51 4c 49 54 45 5f 44 45 42 55 47 29 0a 20 20  SQLITE_DEBUG).  
189a0 7b 20 69 6e 74 20 63 6e 74 3b 20 66 6f 72 28 63  { int cnt; for(c
189b0 6e 74 3d 30 2c 20 70 3d 70 4c 69 73 74 3b 20 70  nt=0, p=pList; p
189c0 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 2c 20 63  ; p=p->pDirty, c
189d0 6e 74 2b 2b 29 7b 7d 0a 20 20 20 20 57 41 4c 54  nt++){}.    WALT
189e0 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 66 72  RACE(("WAL%p: fr
189f0 61 6d 65 20 77 72 69 74 65 20 62 65 67 69 6e 2e  ame write begin.
18a00 20 25 64 20 66 72 61 6d 65 73 2e 20 6d 78 46 72   %d frames. mxFr
18a10 61 6d 65 3d 25 64 2e 20 25 73 5c 6e 22 2c 0a 20  ame=%d. %s\n",. 
18a20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 57 61               pWa
18a30 6c 2c 20 63 6e 74 2c 20 70 57 61 6c 2d 3e 68 64  l, cnt, pWal->hd
18a40 72 2e 6d 78 46 72 61 6d 65 2c 20 69 73 43 6f 6d  r.mxFrame, isCom
18a50 6d 69 74 20 3f 20 22 43 6f 6d 6d 69 74 22 20 3a  mit ? "Commit" :
18a60 20 22 53 70 69 6c 6c 22 29 29 3b 0a 20 20 7d 0a   "Spill"));.  }.
18a70 23 65 6e 64 69 66 0a 0a 20 20 2f 2a 20 53 65 65  #endif..  /* See
18a80 20 69 66 20 69 74 20 69 73 20 70 6f 73 73 69 62   if it is possib
18a90 6c 65 20 74 6f 20 77 72 69 74 65 20 74 68 65 73  le to write thes
18aa0 65 20 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68  e frames into th
18ab0 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 0a 20  e start of the. 
18ac0 20 2a 2a 20 6c 6f 67 20 66 69 6c 65 2c 20 69 6e   ** log file, in
18ad0 73 74 65 61 64 20 6f 66 20 61 70 70 65 6e 64 69  stead of appendi
18ae0 6e 67 20 74 6f 20 69 74 20 61 74 20 70 57 61 6c  ng to it at pWal
18af0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a 20  ->hdr.mxFrame.. 
18b00 20 2a 2f 0a 20 20 69 66 28 20 53 51 4c 49 54 45   */.  if( SQLITE
18b10 5f 4f 4b 21 3d 28 72 63 20 3d 20 77 61 6c 52 65  _OK!=(rc = walRe
18b20 73 74 61 72 74 4c 6f 67 28 70 57 61 6c 29 29 20  startLog(pWal)) 
18b30 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  ){.    return rc
18b40 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74  ;.  }..  /* If t
18b50 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74  his is the first
18b60 20 66 72 61 6d 65 20 77 72 69 74 74 65 6e 20 69   frame written i
18b70 6e 74 6f 20 74 68 65 20 6c 6f 67 2c 20 77 72 69  nto the log, wri
18b80 74 65 20 74 68 65 20 57 41 4c 0a 20 20 2a 2a 20  te the WAL.  ** 
18b90 68 65 61 64 65 72 20 74 6f 20 74 68 65 20 73 74  header to the st
18ba0 61 72 74 20 6f 66 20 74 68 65 20 57 41 4c 20 66  art of the WAL f
18bb0 69 6c 65 2e 20 53 65 65 20 63 6f 6d 6d 65 6e 74  ile. See comment
18bc0 73 20 61 74 20 74 68 65 20 74 6f 70 20 6f 66 0a  s at the top of.
18bd0 20 20 2a 2a 20 74 68 69 73 20 73 6f 75 72 63 65    ** this source
18be0 20 66 69 6c 65 20 66 6f 72 20 61 20 64 65 73 63   file for a desc
18bf0 72 69 70 74 69 6f 6e 20 6f 66 20 74 68 65 20 57  ription of the W
18c00 41 4c 20 68 65 61 64 65 72 20 66 6f 72 6d 61 74  AL header format
18c10 2e 0a 20 20 2a 2f 0a 20 20 69 46 72 61 6d 65 20  ..  */.  iFrame 
18c20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  = pWal->hdr.mxFr
18c30 61 6d 65 3b 0a 20 20 69 66 28 20 69 46 72 61 6d  ame;.  if( iFram
18c40 65 3d 3d 30 20 29 7b 0a 20 20 20 20 75 38 20 61  e==0 ){.    u8 a
18c50 57 61 6c 48 64 72 5b 57 41 4c 5f 48 44 52 53 49  WalHdr[WAL_HDRSI
18c60 5a 45 5d 3b 20 20 20 20 20 20 2f 2a 20 42 75 66  ZE];      /* Buf
18c70 66 65 72 20 74 6f 20 61 73 73 65 6d 62 6c 65 20  fer to assemble 
18c80 77 61 6c 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f  wal-header in */
18c90 0a 20 20 20 20 75 33 32 20 61 43 6b 73 75 6d 5b  .    u32 aCksum[
18ca0 32 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  2];             
18cb0 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66     /* Checksum f
18cc0 6f 72 20 77 61 6c 2d 68 65 61 64 65 72 20 2a 2f  or wal-header */
18cd0 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74  ..    sqlite3Put
18ce0 34 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 30  4byte(&aWalHdr[0
18cf0 5d 2c 20 28 57 41 4c 5f 4d 41 47 49 43 20 7c 20  ], (WAL_MAGIC | 
18d00 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e  SQLITE_BIGENDIAN
18d10 29 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50  ));.    sqlite3P
18d20 75 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72  ut4byte(&aWalHdr
18d30 5b 34 5d 2c 20 57 41 4c 5f 4d 41 58 5f 56 45 52  [4], WAL_MAX_VER
18d40 53 49 4f 4e 29 3b 0a 20 20 20 20 73 71 6c 69 74  SION);.    sqlit
18d50 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c  e3Put4byte(&aWal
18d60 48 64 72 5b 38 5d 2c 20 73 7a 50 61 67 65 29 3b  Hdr[8], szPage);
18d70 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34  .    sqlite3Put4
18d80 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 31 32  byte(&aWalHdr[12
18d90 5d 2c 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 29 3b  ], pWal->nCkpt);
18da0 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 61 6e  .    sqlite3_ran
18db0 64 6f 6d 6e 65 73 73 28 38 2c 20 70 57 61 6c 2d  domness(8, pWal-
18dc0 3e 68 64 72 2e 61 53 61 6c 74 29 3b 0a 20 20 20  >hdr.aSalt);.   
18dd0 20 6d 65 6d 63 70 79 28 26 61 57 61 6c 48 64 72   memcpy(&aWalHdr
18de0 5b 31 36 5d 2c 20 70 57 61 6c 2d 3e 68 64 72 2e  [16], pWal->hdr.
18df0 61 53 61 6c 74 2c 20 38 29 3b 0a 20 20 20 20 77  aSalt, 8);.    w
18e00 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
18e10 31 2c 20 61 57 61 6c 48 64 72 2c 20 57 41 4c 5f  1, aWalHdr, WAL_
18e20 48 44 52 53 49 5a 45 2d 32 2a 34 2c 20 30 2c 20  HDRSIZE-2*4, 0, 
18e30 61 43 6b 73 75 6d 29 3b 0a 20 20 20 20 73 71 6c  aCksum);.    sql
18e40 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57  ite3Put4byte(&aW
18e50 61 6c 48 64 72 5b 32 34 5d 2c 20 61 43 6b 73 75  alHdr[24], aCksu
18e60 6d 5b 30 5d 29 3b 0a 20 20 20 20 73 71 6c 69 74  m[0]);.    sqlit
18e70 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c  e3Put4byte(&aWal
18e80 48 64 72 5b 32 38 5d 2c 20 61 43 6b 73 75 6d 5b  Hdr[28], aCksum[
18e90 31 5d 29 3b 0a 20 20 20 20 0a 20 20 20 20 70 57  1]);.    .    pW
18ea0 61 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 73 7a 50  al->szPage = szP
18eb0 61 67 65 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68  age;.    pWal->h
18ec0 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 20 3d  dr.bigEndCksum =
18ed0 20 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41   SQLITE_BIGENDIA
18ee0 4e 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  N;.    pWal->hdr
18ef0 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20  .aFrameCksum[0] 
18f00 3d 20 61 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 20  = aCksum[0];.   
18f10 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
18f20 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 61 43 6b 73  eCksum[1] = aCks
18f30 75 6d 5b 31 5d 3b 0a 0a 20 20 20 20 72 63 20 3d  um[1];..    rc =
18f40 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28   sqlite3OsWrite(
18f50 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 57  pWal->pWalFd, aW
18f60 61 6c 48 64 72 2c 20 73 69 7a 65 6f 66 28 61 57  alHdr, sizeof(aW
18f70 61 6c 48 64 72 29 2c 20 30 29 3b 0a 20 20 20 20  alHdr), 0);.    
18f80 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70  WALTRACE(("WAL%p
18f90 3a 20 77 61 6c 2d 68 65 61 64 65 72 20 77 72 69  : wal-header wri
18fa0 74 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20  te %s\n", pWal, 
18fb0 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20  rc ? "failed" : 
18fc0 22 6f 6b 22 29 29 3b 0a 20 20 20 20 69 66 28 20  "ok"));.    if( 
18fd0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
18fe0 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63  .      return rc
18ff0 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73  ;.    }.  }.  as
19000 73 65 72 74 28 20 28 69 6e 74 29 70 57 61 6c 2d  sert( (int)pWal-
19010 3e 73 7a 50 61 67 65 3d 3d 73 7a 50 61 67 65 20  >szPage==szPage 
19020 29 3b 0a 0a 20 20 2f 2a 20 57 72 69 74 65 20 74  );..  /* Write t
19030 68 65 20 6c 6f 67 20 66 69 6c 65 2e 20 2a 2f 0a  he log file. */.
19040 20 20 66 6f 72 28 70 3d 70 4c 69 73 74 3b 20 70    for(p=pList; p
19050 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79 29 7b 0a  ; p=p->pDirty){.
19060 20 20 20 20 75 33 32 20 6e 44 62 73 69 7a 65 3b      u32 nDbsize;
19070 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19080 20 20 2f 2a 20 44 62 2d 73 69 7a 65 20 66 69 65    /* Db-size fie
19090 6c 64 20 66 6f 72 20 66 72 61 6d 65 20 68 65 61  ld for frame hea
190a0 64 65 72 20 2a 2f 0a 20 20 20 20 69 36 34 20 69  der */.    i64 i
190b0 4f 66 66 73 65 74 3b 20 20 20 20 20 20 20 20 20  Offset;         
190c0 20 20 20 20 20 20 20 20 20 2f 2a 20 57 72 69 74           /* Writ
190d0 65 20 6f 66 66 73 65 74 20 69 6e 20 6c 6f 67 20  e offset in log 
190e0 66 69 6c 65 20 2a 2f 0a 20 20 20 20 76 6f 69 64  file */.    void
190f0 20 2a 70 44 61 74 61 3b 0a 20 20 20 0a 20 20 20   *pData;.   .   
19100 20 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72   iOffset = walFr
19110 61 6d 65 4f 66 66 73 65 74 28 2b 2b 69 46 72 61  ameOffset(++iFra
19120 6d 65 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20 20  me, szPage);.   
19130 20 2f 2a 20 74 65 73 74 63 61 73 65 28 20 49 53   /* testcase( IS
19140 5f 42 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74  _BIG_INT(iOffset
19150 29 20 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73  ) ); // requires
19160 20 61 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20   a 4GiB WAL */. 
19170 20 20 20 0a 20 20 20 20 2f 2a 20 50 6f 70 75 6c     .    /* Popul
19180 61 74 65 20 61 6e 64 20 77 72 69 74 65 20 74 68  ate and write th
19190 65 20 66 72 61 6d 65 20 68 65 61 64 65 72 20 2a  e frame header *
191a0 2f 0a 20 20 20 20 6e 44 62 73 69 7a 65 20 3d 20  /.    nDbsize = 
191b0 28 69 73 43 6f 6d 6d 69 74 20 26 26 20 70 2d 3e  (isCommit && p->
191c0 70 44 69 72 74 79 3d 3d 30 29 20 3f 20 6e 54 72  pDirty==0) ? nTr
191d0 75 6e 63 61 74 65 20 3a 20 30 3b 0a 23 69 66 20  uncate : 0;.#if 
191e0 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 48  defined(SQLITE_H
191f0 41 53 5f 43 4f 44 45 43 29 0a 20 20 20 20 69 66  AS_CODEC).    if
19200 28 20 28 70 44 61 74 61 20 3d 20 73 71 6c 69 74  ( (pData = sqlit
19210 65 33 50 61 67 65 72 43 6f 64 65 63 28 70 29 29  e3PagerCodec(p))
19220 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
19230 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 23 65 6c 73 65  ITE_NOMEM;.#else
19240 0a 20 20 20 20 70 44 61 74 61 20 3d 20 70 2d 3e  .    pData = p->
19250 70 44 61 74 61 3b 0a 23 65 6e 64 69 66 0a 20 20  pData;.#endif.  
19260 20 20 77 61 6c 45 6e 63 6f 64 65 46 72 61 6d 65    walEncodeFrame
19270 28 70 57 61 6c 2c 20 70 2d 3e 70 67 6e 6f 2c 20  (pWal, p->pgno, 
19280 6e 44 62 73 69 7a 65 2c 20 70 44 61 74 61 2c 20  nDbsize, pData, 
19290 61 46 72 61 6d 65 29 3b 0a 20 20 20 20 72 63 20  aFrame);.    rc 
192a0 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65  = sqlite3OsWrite
192b0 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61  (pWal->pWalFd, a
192c0 46 72 61 6d 65 2c 20 73 69 7a 65 6f 66 28 61 46  Frame, sizeof(aF
192d0 72 61 6d 65 29 2c 20 69 4f 66 66 73 65 74 29 3b  rame), iOffset);
192e0 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
192f0 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
19300 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
19310 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74  ..    /* Write t
19320 68 65 20 70 61 67 65 20 64 61 74 61 20 2a 2f 0a  he page data */.
19330 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
19340 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 57  OsWrite(pWal->pW
19350 61 6c 46 64 2c 20 70 44 61 74 61 2c 20 73 7a 50  alFd, pData, szP
19360 61 67 65 2c 20 69 4f 66 66 73 65 74 2b 73 69 7a  age, iOffset+siz
19370 65 6f 66 28 61 46 72 61 6d 65 29 29 3b 0a 20 20  eof(aFrame));.  
19380 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
19390 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74  _OK ){.      ret
193a0 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20  urn rc;.    }.  
193b0 20 20 70 4c 61 73 74 20 3d 20 70 3b 0a 20 20 7d    pLast = p;.  }
193c0 0a 0a 20 20 2f 2a 20 53 79 6e 63 20 74 68 65 20  ..  /* Sync the 
193d0 6c 6f 67 20 66 69 6c 65 20 69 66 20 74 68 65 20  log file if the 
193e0 27 69 73 53 79 6e 63 27 20 66 6c 61 67 20 77 61  'isSync' flag wa
193f0 73 20 73 70 65 63 69 66 69 65 64 2e 20 2a 2f 0a  s specified. */.
19400 20 20 69 66 28 20 73 79 6e 63 5f 66 6c 61 67 73    if( sync_flags
19410 20 29 7b 0a 20 20 20 20 69 36 34 20 69 53 65 67   ){.    i64 iSeg
19420 6d 65 6e 74 20 3d 20 73 71 6c 69 74 65 33 4f 73  ment = sqlite3Os
19430 53 65 63 74 6f 72 53 69 7a 65 28 70 57 61 6c 2d  SectorSize(pWal-
19440 3e 70 57 61 6c 46 64 29 3b 0a 20 20 20 20 69 36  >pWalFd);.    i6
19450 34 20 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46  4 iOffset = walF
19460 72 61 6d 65 4f 66 66 73 65 74 28 69 46 72 61 6d  rameOffset(iFram
19470 65 2b 31 2c 20 73 7a 50 61 67 65 29 3b 0a 0a 20  e+1, szPage);.. 
19480 20 20 20 61 73 73 65 72 74 28 20 69 73 43 6f 6d     assert( isCom
19490 6d 69 74 20 29 3b 0a 20 20 20 20 61 73 73 65 72  mit );.    asser
194a0 74 28 20 69 53 65 67 6d 65 6e 74 3e 30 20 29 3b  t( iSegment>0 );
194b0 0a 0a 20 20 20 20 69 53 65 67 6d 65 6e 74 20 3d  ..    iSegment =
194c0 20 28 28 28 69 4f 66 66 73 65 74 2b 69 53 65 67   (((iOffset+iSeg
194d0 6d 65 6e 74 2d 31 29 2f 69 53 65 67 6d 65 6e 74  ment-1)/iSegment
194e0 29 20 2a 20 69 53 65 67 6d 65 6e 74 29 3b 0a 20  ) * iSegment);. 
194f0 20 20 20 77 68 69 6c 65 28 20 69 4f 66 66 73 65     while( iOffse
19500 74 3c 69 53 65 67 6d 65 6e 74 20 29 7b 0a 20 20  t<iSegment ){.  
19510 20 20 20 20 76 6f 69 64 20 2a 70 44 61 74 61 3b      void *pData;
19520 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c  .#if defined(SQL
19530 49 54 45 5f 48 41 53 5f 43 4f 44 45 43 29 0a 20  ITE_HAS_CODEC). 
19540 20 20 20 20 20 69 66 28 20 28 70 44 61 74 61 20       if( (pData 
19550 3d 20 73 71 6c 69 74 65 33 50 61 67 65 72 43 6f  = sqlite3PagerCo
19560 64 65 63 28 70 4c 61 73 74 29 29 3d 3d 30 20 29  dec(pLast))==0 )
19570 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
19580 4f 4d 45 4d 3b 0a 23 65 6c 73 65 0a 20 20 20 20  OMEM;.#else.    
19590 20 20 70 44 61 74 61 20 3d 20 70 4c 61 73 74 2d    pData = pLast-
195a0 3e 70 44 61 74 61 3b 0a 23 65 6e 64 69 66 0a 20  >pData;.#endif. 
195b0 20 20 20 20 20 77 61 6c 45 6e 63 6f 64 65 46 72       walEncodeFr
195c0 61 6d 65 28 70 57 61 6c 2c 20 70 4c 61 73 74 2d  ame(pWal, pLast-
195d0 3e 70 67 6e 6f 2c 20 6e 54 72 75 6e 63 61 74 65  >pgno, nTruncate
195e0 2c 20 70 44 61 74 61 2c 20 61 46 72 61 6d 65 29  , pData, aFrame)
195f0 3b 0a 20 20 20 20 20 20 2f 2a 20 74 65 73 74 63  ;.      /* testc
19600 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28  ase( IS_BIG_INT(
19610 69 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f 20 72  iOffset) ); // r
19620 65 71 75 69 72 65 73 20 61 20 34 47 69 42 20 57  equires a 4GiB W
19630 41 4c 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d  AL */.      rc =
19640 20 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28   sqlite3OsWrite(
19650 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 46  pWal->pWalFd, aF
19660 72 61 6d 65 2c 20 73 69 7a 65 6f 66 28 61 46 72  rame, sizeof(aFr
19670 61 6d 65 29 2c 20 69 4f 66 66 73 65 74 29 3b 0a  ame), iOffset);.
19680 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
19690 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
196a0 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
196b0 20 20 20 20 7d 0a 20 20 20 20 20 20 69 4f 66 66      }.      iOff
196c0 73 65 74 20 2b 3d 20 57 41 4c 5f 46 52 41 4d 45  set += WAL_FRAME
196d0 5f 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 20 20  _HDRSIZE;.      
196e0 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72  rc = sqlite3OsWr
196f0 69 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ite(pWal->pWalFd
19700 2c 20 70 44 61 74 61 2c 20 73 7a 50 61 67 65 2c  , pData, szPage,
19710 20 69 4f 66 66 73 65 74 29 3b 20 0a 20 20 20 20   iOffset); .    
19720 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
19730 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
19740 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20  eturn rc;.      
19750 7d 0a 20 20 20 20 20 20 6e 4c 61 73 74 2b 2b 3b  }.      nLast++;
19760 0a 20 20 20 20 20 20 69 4f 66 66 73 65 74 20 2b  .      iOffset +
19770 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 7d 0a  = szPage;.    }.
19780 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
19790 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57  3OsSync(pWal->pW
197a0 61 6c 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73  alFd, sync_flags
197b0 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 70 70  );.  }..  /* App
197c0 65 6e 64 20 64 61 74 61 20 74 6f 20 74 68 65 20  end data to the 
197d0 77 61 6c 2d 69 6e 64 65 78 2e 20 49 74 20 69 73  wal-index. It is
197e0 20 6e 6f 74 20 6e 65 63 65 73 73 61 72 79 20 74   not necessary t
197f0 6f 20 6c 6f 63 6b 20 74 68 65 20 0a 20 20 2a 2a  o lock the .  **
19800 20 77 61 6c 2d 69 6e 64 65 78 20 74 6f 20 64 6f   wal-index to do
19810 20 74 68 69 73 20 61 73 20 74 68 65 20 53 51 4c   this as the SQL
19820 49 54 45 5f 53 48 4d 5f 57 52 49 54 45 20 6c 6f  ITE_SHM_WRITE lo
19830 63 6b 20 68 65 6c 64 20 6f 6e 20 74 68 65 20 77  ck held on the w
19840 61 6c 2d 69 6e 64 65 78 0a 20 20 2a 2a 20 67 75  al-index.  ** gu
19850 61 72 61 6e 74 65 65 73 20 74 68 61 74 20 74 68  arantees that th
19860 65 72 65 20 61 72 65 20 6e 6f 20 6f 74 68 65 72  ere are no other
19870 20 77 72 69 74 65 72 73 2c 20 61 6e 64 20 6e 6f   writers, and no
19880 20 64 61 74 61 20 74 68 61 74 20 6d 61 79 0a 20   data that may. 
19890 20 2a 2a 20 62 65 20 69 6e 20 75 73 65 20 62 79   ** be in use by
198a0 20 65 78 69 73 74 69 6e 67 20 72 65 61 64 65 72   existing reader
198b0 73 20 69 73 20 62 65 69 6e 67 20 6f 76 65 72 77  s is being overw
198c0 72 69 74 74 65 6e 2e 0a 20 20 2a 2f 0a 20 20 69  ritten..  */.  i
198d0 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64  Frame = pWal->hd
198e0 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 66 6f 72  r.mxFrame;.  for
198f0 28 70 3d 70 4c 69 73 74 3b 20 70 20 26 26 20 72  (p=pList; p && r
19900 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 70 3d  c==SQLITE_OK; p=
19910 70 2d 3e 70 44 69 72 74 79 29 7b 0a 20 20 20 20  p->pDirty){.    
19920 69 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 72 63  iFrame++;.    rc
19930 20 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e   = walIndexAppen
19940 64 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c 20  d(pWal, iFrame, 
19950 70 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 20 20  p->pgno);.  }.  
19960 77 68 69 6c 65 28 20 6e 4c 61 73 74 3e 30 20 26  while( nLast>0 &
19970 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  & rc==SQLITE_OK 
19980 29 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b 2b 3b  ){.    iFrame++;
19990 0a 20 20 20 20 6e 4c 61 73 74 2d 2d 3b 0a 20 20  .    nLast--;.  
199a0 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 41    rc = walIndexA
199b0 70 70 65 6e 64 28 70 57 61 6c 2c 20 69 46 72 61  ppend(pWal, iFra
199c0 6d 65 2c 20 70 4c 61 73 74 2d 3e 70 67 6e 6f 29  me, pLast->pgno)
199d0 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
199e0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
199f0 20 20 2f 2a 20 55 70 64 61 74 65 20 74 68 65 20    /* Update the 
19a00 70 72 69 76 61 74 65 20 63 6f 70 79 20 6f 66 20  private copy of 
19a10 74 68 65 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20  the header. */. 
19a20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50     pWal->hdr.szP
19a30 61 67 65 20 3d 20 28 75 31 36 29 28 28 73 7a 50  age = (u16)((szP
19a40 61 67 65 26 30 78 66 66 30 30 29 20 7c 20 28 73  age&0xff00) | (s
19a50 7a 50 61 67 65 3e 3e 31 36 29 29 3b 0a 20 20 20  zPage>>16));.   
19a60 20 74 65 73 74 63 61 73 65 28 20 73 7a 50 61 67   testcase( szPag
19a70 65 3c 3d 33 32 37 36 38 20 29 3b 0a 20 20 20 20  e<=32768 );.    
19a80 74 65 73 74 63 61 73 65 28 20 73 7a 50 61 67 65  testcase( szPage
19a90 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 20 20 70  >=65536 );.    p
19aa0 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
19ab0 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20 20 69   = iFrame;.    i
19ac0 66 28 20 69 73 43 6f 6d 6d 69 74 20 29 7b 0a 20  f( isCommit ){. 
19ad0 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69       pWal->hdr.i
19ae0 43 68 61 6e 67 65 2b 2b 3b 0a 20 20 20 20 20 20  Change++;.      
19af0 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20  pWal->hdr.nPage 
19b00 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a 20 20 20  = nTruncate;.   
19b10 20 7d 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 69   }.    /* If thi
19b20 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 2c 20 75  s is a commit, u
19b30 70 64 61 74 65 20 74 68 65 20 77 61 6c 2d 69 6e  pdate the wal-in
19b40 64 65 78 20 68 65 61 64 65 72 20 74 6f 6f 2e 20  dex header too. 
19b50 2a 2f 0a 20 20 20 20 69 66 28 20 69 73 43 6f 6d  */.    if( isCom
19b60 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 77 61 6c  mit ){.      wal
19b70 49 6e 64 65 78 57 72 69 74 65 48 64 72 28 70 57  IndexWriteHdr(pW
19b80 61 6c 29 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d  al);.      pWal-
19b90 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20 69 46 72  >iCallback = iFr
19ba0 61 6d 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ame;.    }.  }..
19bb0 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c    WALTRACE(("WAL
19bc0 25 70 3a 20 66 72 61 6d 65 20 77 72 69 74 65 20  %p: frame write 
19bd0 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72 63 20  %s\n", pWal, rc 
19be0 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b  ? "failed" : "ok
19bf0 22 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  "));.  return rc
19c00 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73  ;.}../* .** This
19c10 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c   routine is call
19c20 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20  ed to implement 
19c30 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68 65 63  sqlite3_wal_chec
19c40 6b 70 6f 69 6e 74 28 29 20 61 6e 64 0a 2a 2a 20  kpoint() and.** 
19c50 72 65 6c 61 74 65 64 20 69 6e 74 65 72 66 61 63  related interfac
19c60 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74 61 69 6e  es..**.** Obtain
19c70 20 61 20 43 48 45 43 4b 50 4f 49 4e 54 20 6c 6f   a CHECKPOINT lo
19c80 63 6b 20 61 6e 64 20 74 68 65 6e 20 62 61 63 6b  ck and then back
19c90 66 69 6c 6c 20 61 73 20 6d 75 63 68 20 69 6e 66  fill as much inf
19ca0 6f 72 6d 61 74 69 6f 6e 20 61 73 0a 2a 2a 20 77  ormation as.** w
19cb0 65 20 63 61 6e 20 66 72 6f 6d 20 57 41 4c 20 69  e can from WAL i
19cc0 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65  nto the database
19cd0 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70 61 72 61 6d  ..**.** If param
19ce0 65 74 65 72 20 78 42 75 73 79 20 69 73 20 6e 6f  eter xBusy is no
19cf0 74 20 4e 55 4c 4c 2c 20 69 74 20 69 73 20 61 20  t NULL, it is a 
19d00 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 62 75 73  pointer to a bus
19d10 79 2d 68 61 6e 64 6c 65 72 0a 2a 2a 20 63 61 6c  y-handler.** cal
19d20 6c 62 61 63 6b 2e 20 49 6e 20 74 68 69 73 20 63  lback. In this c
19d30 61 73 65 20 74 68 69 73 20 66 75 6e 63 74 69 6f  ase this functio
19d40 6e 20 72 75 6e 73 20 61 20 62 6c 6f 63 6b 69 6e  n runs a blockin
19d50 67 20 63 68 65 63 6b 70 6f 69 6e 74 2e 0a 2a 2f  g checkpoint..*/
19d60 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 43  .int sqlite3WalC
19d70 68 65 63 6b 70 6f 69 6e 74 28 0a 20 20 57 61 6c  heckpoint(.  Wal
19d80 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20   *pWal,         
19d90 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
19da0 57 61 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a  Wal connection *
19db0 2f 0a 20 20 69 6e 74 20 65 4d 6f 64 65 2c 20 20  /.  int eMode,  
19dc0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19dd0 20 20 20 20 2f 2a 20 50 41 53 53 49 56 45 2c 20      /* PASSIVE, 
19de0 46 55 4c 4c 20 6f 72 20 52 45 53 54 41 52 54 20  FULL or RESTART 
19df0 2a 2f 0a 20 20 69 6e 74 20 28 2a 78 42 75 73 79  */.  int (*xBusy
19e00 29 28 76 6f 69 64 2a 29 2c 20 20 20 20 20 20 20  )(void*),       
19e10 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e       /* Function
19e20 20 74 6f 20 63 61 6c 6c 20 77 68 65 6e 20 62 75   to call when bu
19e30 73 79 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 42  sy */.  void *pB
19e40 75 73 79 41 72 67 2c 20 20 20 20 20 20 20 20 20  usyArg,         
19e50 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65          /* Conte
19e60 78 74 20 61 72 67 75 6d 65 6e 74 20 66 6f 72 20  xt argument for 
19e70 78 42 75 73 79 48 61 6e 64 6c 65 72 20 2a 2f 0a  xBusyHandler */.
19e80 20 20 69 6e 74 20 73 79 6e 63 5f 66 6c 61 67 73    int sync_flags
19e90 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
19ea0 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20 73 79    /* Flags to sy
19eb0 6e 63 20 64 62 20 66 69 6c 65 20 77 69 74 68 20  nc db file with 
19ec0 28 6f 72 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20  (or 0) */.  int 
19ed0 6e 42 75 66 2c 20 20 20 20 20 20 20 20 20 20 20  nBuf,           
19ee0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
19ef0 69 7a 65 20 6f 66 20 74 65 6d 70 6f 72 61 72 79  ize of temporary
19f00 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 75 38 20   buffer */.  u8 
19f10 2a 7a 42 75 66 2c 20 20 20 20 20 20 20 20 20 20  *zBuf,          
19f20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
19f30 54 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72  Temporary buffer
19f40 20 74 6f 20 75 73 65 20 2a 2f 0a 20 20 69 6e 74   to use */.  int
19f50 20 2a 70 6e 4c 6f 67 2c 20 20 20 20 20 20 20 20   *pnLog,        
19f60 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
19f70 4f 55 54 3a 20 4e 75 6d 62 65 72 20 6f 66 20 66  OUT: Number of f
19f80 72 61 6d 65 73 20 69 6e 20 57 41 4c 20 2a 2f 0a  rames in WAL */.
19f90 20 20 69 6e 74 20 2a 70 6e 43 6b 70 74 20 20 20    int *pnCkpt   
19fa0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19fb0 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62 65 72    /* OUT: Number
19fc0 20 6f 66 20 62 61 63 6b 66 69 6c 6c 65 64 20 66   of backfilled f
19fd0 72 61 6d 65 73 20 69 6e 20 57 41 4c 20 2a 2f 0a  rames in WAL */.
19fe0 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20  ){.  int rc;    
19ff0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a000 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63       /* Return c
1a010 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43  ode */.  int isC
1a020 68 61 6e 67 65 64 20 3d 20 30 3b 20 20 20 20 20  hanged = 0;     
1a030 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
1a040 20 69 66 20 61 20 6e 65 77 20 77 61 6c 2d 69 6e   if a new wal-in
1a050 64 65 78 20 68 65 61 64 65 72 20 69 73 20 6c 6f  dex header is lo
1a060 61 64 65 64 20 2a 2f 0a 20 20 69 6e 74 20 65 4d  aded */.  int eM
1a070 6f 64 65 32 20 3d 20 65 4d 6f 64 65 3b 20 20 20  ode2 = eMode;   
1a080 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 6f 64            /* Mod
1a090 65 20 74 6f 20 70 61 73 73 20 74 6f 20 77 61 6c  e to pass to wal
1a0a0 43 68 65 63 6b 70 6f 69 6e 74 28 29 20 2a 2f 0a  Checkpoint() */.
1a0b0 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
1a0c0 3e 63 6b 70 74 4c 6f 63 6b 3d 3d 30 20 29 3b 0a  >ckptLock==0 );.
1a0d0 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
1a0e0 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a  writeLock==0 );.
1a0f0 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 72 65 61  .  if( pWal->rea
1a100 64 4f 6e 6c 79 20 29 20 72 65 74 75 72 6e 20 53  dOnly ) return S
1a110 51 4c 49 54 45 5f 52 45 41 44 4f 4e 4c 59 3b 0a  QLITE_READONLY;.
1a120 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c    WALTRACE(("WAL
1a130 25 70 3a 20 63 68 65 63 6b 70 6f 69 6e 74 20 62  %p: checkpoint b
1a140 65 67 69 6e 73 5c 6e 22 2c 20 70 57 61 6c 29 29  egins\n", pWal))
1a150 3b 0a 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b  ;.  rc = walLock
1a160 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
1a170 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31  WAL_CKPT_LOCK, 1
1a180 29 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20  );.  if( rc ){. 
1a190 20 20 20 2f 2a 20 55 73 75 61 6c 6c 79 20 74 68     /* Usually th
1a1a0 69 73 20 69 73 20 53 51 4c 49 54 45 5f 42 55 53  is is SQLITE_BUS
1a1b0 59 20 6d 65 61 6e 69 6e 67 20 74 68 61 74 20 61  Y meaning that a
1a1c0 6e 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f 72  nother thread or
1a1d0 20 70 72 6f 63 65 73 73 0a 20 20 20 20 2a 2a 20   process.    ** 
1a1e0 69 73 20 61 6c 72 65 61 64 79 20 72 75 6e 6e 69  is already runni
1a1f0 6e 67 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c  ng a checkpoint,
1a200 20 6f 72 20 6d 61 79 62 65 20 61 20 72 65 63 6f   or maybe a reco
1a210 76 65 72 79 2e 20 20 42 75 74 20 69 74 20 6d 69  very.  But it mi
1a220 67 68 74 0a 20 20 20 20 2a 2a 20 61 6c 73 6f 20  ght.    ** also 
1a230 62 65 20 53 51 4c 49 54 45 5f 49 4f 45 52 52 2e  be SQLITE_IOERR.
1a240 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 72   */.    return r
1a250 63 3b 0a 20 20 7d 0a 20 20 70 57 61 6c 2d 3e 63  c;.  }.  pWal->c
1a260 6b 70 74 4c 6f 63 6b 20 3d 20 31 3b 0a 0a 20 20  kptLock = 1;..  
1a270 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20 61 20  /* If this is a 
1a280 62 6c 6f 63 6b 69 6e 67 2d 63 68 65 63 6b 70 6f  blocking-checkpo
1a290 69 6e 74 2c 20 74 68 65 6e 20 6f 62 74 61 69 6e  int, then obtain
1a2a0 20 74 68 65 20 77 72 69 74 65 2d 6c 6f 63 6b 20   the write-lock 
1a2b0 61 73 20 77 65 6c 6c 0a 20 20 2a 2a 20 74 6f 20  as well.  ** to 
1a2c0 70 72 65 76 65 6e 74 20 61 6e 79 20 77 72 69 74  prevent any writ
1a2d0 65 72 73 20 66 72 6f 6d 20 72 75 6e 6e 69 6e 67  ers from running
1a2e0 20 77 68 69 6c 65 20 74 68 65 20 63 68 65 63 6b   while the check
1a2f0 70 6f 69 6e 74 20 69 73 20 75 6e 64 65 72 77 61  point is underwa
1a300 79 2e 0a 20 20 2a 2a 20 54 68 69 73 20 68 61 73  y..  ** This has
1a310 20 74 6f 20 62 65 20 64 6f 6e 65 20 62 65 66 6f   to be done befo
1a320 72 65 20 74 68 65 20 63 61 6c 6c 20 74 6f 20 77  re the call to w
1a330 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28 29  alIndexReadHdr()
1a340 20 62 65 6c 6f 77 2e 0a 20 20 2a 2a 0a 20 20 2a   below..  **.  *
1a350 2a 20 49 66 20 74 68 65 20 77 72 69 74 65 72 20  * If the writer 
1a360 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62 65 20 6f  lock cannot be o
1a370 62 74 61 69 6e 65 64 2c 20 74 68 65 6e 20 61 20  btained, then a 
1a380 70 61 73 73 69 76 65 20 63 68 65 63 6b 70 6f 69  passive checkpoi
1a390 6e 74 20 69 73 0a 20 20 2a 2a 20 72 75 6e 20 69  nt is.  ** run i
1a3a0 6e 73 74 65 61 64 2e 20 53 69 6e 63 65 20 74 68  nstead. Since th
1a3b0 65 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 20 69  e checkpointer i
1a3c0 73 20 6e 6f 74 20 68 6f 6c 64 69 6e 67 20 74 68  s not holding th
1a3d0 65 20 77 72 69 74 65 72 20 6c 6f 63 6b 2c 0a 20  e writer lock,. 
1a3e0 20 2a 2a 20 74 68 65 72 65 20 69 73 20 6e 6f 20   ** there is no 
1a3f0 70 6f 69 6e 74 20 69 6e 20 62 6c 6f 63 6b 69 6e  point in blockin
1a400 67 20 77 61 69 74 69 6e 67 20 66 6f 72 20 61 6e  g waiting for an
1a410 79 20 72 65 61 64 65 72 73 2e 20 41 73 73 75 6d  y readers. Assum
1a420 69 6e 67 20 6e 6f 20 0a 20 20 2a 2a 20 6f 74 68  ing no .  ** oth
1a430 65 72 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c  er error occurs,
1a440 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 77   this function w
1a450 69 6c 6c 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ill return SQLIT
1a460 45 5f 42 55 53 59 20 74 6f 20 74 68 65 20 63 61  E_BUSY to the ca
1a470 6c 6c 65 72 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  ller..  */.  if(
1a480 20 65 4d 6f 64 65 21 3d 53 51 4c 49 54 45 5f 43   eMode!=SQLITE_C
1a490 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49 56  HECKPOINT_PASSIV
1a4a0 45 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 77 61  E ){.    rc = wa
1a4b0 6c 42 75 73 79 4c 6f 63 6b 28 70 57 61 6c 2c 20  lBusyLock(pWal, 
1a4c0 78 42 75 73 79 2c 20 70 42 75 73 79 41 72 67 2c  xBusy, pBusyArg,
1a4d0 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c   WAL_WRITE_LOCK,
1a4e0 20 31 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d   1);.    if( rc=
1a4f0 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
1a500 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c      pWal->writeL
1a510 6f 63 6b 20 3d 20 31 3b 0a 20 20 20 20 7d 65 6c  ock = 1;.    }el
1a520 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  se if( rc==SQLIT
1a530 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20  E_BUSY ){.      
1a540 65 4d 6f 64 65 32 20 3d 20 53 51 4c 49 54 45 5f  eMode2 = SQLITE_
1a550 43 48 45 43 4b 50 4f 49 4e 54 5f 50 41 53 53 49  CHECKPOINT_PASSI
1a560 56 45 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 53  VE;.      rc = S
1a570 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a  QLITE_OK;.    }.
1a580 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 61 64 20 74    }..  /* Read t
1a590 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
1a5a0 64 65 72 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63  der. */.  if( rc
1a5b0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
1a5c0 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78     rc = walIndex
1a5d0 52 65 61 64 48 64 72 28 70 57 61 6c 2c 20 26 69  ReadHdr(pWal, &i
1a5e0 73 43 68 61 6e 67 65 64 29 3b 0a 20 20 7d 0a 0a  sChanged);.  }..
1a5f0 20 20 2f 2a 20 43 6f 70 79 20 64 61 74 61 20 66    /* Copy data f
1a600 72 6f 6d 20 74 68 65 20 6c 6f 67 20 74 6f 20 74  rom the log to t
1a610 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
1a620 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  . */.  if( rc==S
1a630 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1a640 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  if( pWal->hdr.mx
1a650 46 72 61 6d 65 20 26 26 20 77 61 6c 50 61 67 65  Frame && walPage
1a660 73 69 7a 65 28 70 57 61 6c 29 21 3d 6e 42 75 66  size(pWal)!=nBuf
1a670 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
1a680 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b  QLITE_CORRUPT_BK
1a690 50 54 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  PT;.    }else{. 
1a6a0 20 20 20 20 20 72 63 20 3d 20 77 61 6c 43 68 65       rc = walChe
1a6b0 63 6b 70 6f 69 6e 74 28 70 57 61 6c 2c 20 65 4d  ckpoint(pWal, eM
1a6c0 6f 64 65 32 2c 20 78 42 75 73 79 2c 20 70 42 75  ode2, xBusy, pBu
1a6d0 73 79 41 72 67 2c 20 73 79 6e 63 5f 66 6c 61 67  syArg, sync_flag
1a6e0 73 2c 20 7a 42 75 66 29 3b 0a 20 20 20 20 7d 0a  s, zBuf);.    }.
1a6f0 0a 20 20 20 20 2f 2a 20 49 66 20 6e 6f 20 65 72  .    /* If no er
1a700 72 6f 72 20 6f 63 63 75 72 72 65 64 2c 20 73 65  ror occurred, se
1a710 74 20 74 68 65 20 6f 75 74 70 75 74 20 76 61 72  t the output var
1a720 69 61 62 6c 65 73 2e 20 2a 2f 0a 20 20 20 20 69  iables. */.    i
1a730 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
1a740 20 7c 7c 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42   || rc==SQLITE_B
1a750 55 53 59 20 29 7b 0a 20 20 20 20 20 20 69 66 28  USY ){.      if(
1a760 20 70 6e 4c 6f 67 20 29 20 2a 70 6e 4c 6f 67 20   pnLog ) *pnLog 
1a770 3d 20 28 69 6e 74 29 70 57 61 6c 2d 3e 68 64 72  = (int)pWal->hdr
1a780 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 20 20  .mxFrame;.      
1a790 69 66 28 20 70 6e 43 6b 70 74 20 29 20 2a 70 6e  if( pnCkpt ) *pn
1a7a0 43 6b 70 74 20 3d 20 28 69 6e 74 29 28 77 61 6c  Ckpt = (int)(wal
1a7b0 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 2d 3e  CkptInfo(pWal)->
1a7c0 6e 42 61 63 6b 66 69 6c 6c 29 3b 0a 20 20 20 20  nBackfill);.    
1a7d0 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 73 43  }.  }..  if( isC
1a7e0 68 61 6e 67 65 64 20 29 7b 0a 20 20 20 20 2f 2a  hanged ){.    /*
1a7f0 20 49 66 20 61 20 6e 65 77 20 77 61 6c 2d 69 6e   If a new wal-in
1a800 64 65 78 20 68 65 61 64 65 72 20 77 61 73 20 6c  dex header was l
1a810 6f 61 64 65 64 20 62 65 66 6f 72 65 20 74 68 65  oaded before the
1a820 20 63 68 65 63 6b 70 6f 69 6e 74 20 77 61 73 20   checkpoint was 
1a830 0a 20 20 20 20 2a 2a 20 70 65 72 66 6f 72 6d 65  .    ** performe
1a840 64 2c 20 74 68 65 6e 20 74 68 65 20 70 61 67 65  d, then the page
1a850 72 2d 63 61 63 68 65 20 61 73 73 6f 63 69 61 74  r-cache associat
1a860 65 64 20 77 69 74 68 20 70 57 61 6c 20 69 73 20  ed with pWal is 
1a870 6e 6f 77 0a 20 20 20 20 2a 2a 20 6f 75 74 20 6f  now.    ** out o
1a880 66 20 64 61 74 65 2e 20 53 6f 20 7a 65 72 6f 20  f date. So zero 
1a890 74 68 65 20 63 61 63 68 65 64 20 77 61 6c 2d 69  the cached wal-i
1a8a0 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f 20 65  ndex header to e
1a8b0 6e 73 75 72 65 20 74 68 61 74 0a 20 20 20 20 2a  nsure that.    *
1a8c0 2a 20 6e 65 78 74 20 74 69 6d 65 20 74 68 65 20  * next time the 
1a8d0 70 61 67 65 72 20 6f 70 65 6e 73 20 61 20 73 6e  pager opens a sn
1a8e0 61 70 73 68 6f 74 20 6f 6e 20 74 68 69 73 20 64  apshot on this d
1a8f0 61 74 61 62 61 73 65 20 69 74 20 6b 6e 6f 77 73  atabase it knows
1a900 20 74 68 61 74 0a 20 20 20 20 2a 2a 20 74 68 65   that.    ** the
1a910 20 63 61 63 68 65 20 6e 65 65 64 73 20 74 6f 20   cache needs to 
1a920 62 65 20 72 65 73 65 74 2e 0a 20 20 20 20 2a 2f  be reset..    */
1a930 0a 20 20 20 20 6d 65 6d 73 65 74 28 26 70 57 61  .    memset(&pWa
1a940 6c 2d 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65 6f  l->hdr, 0, sizeo
1a950 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b  f(WalIndexHdr));
1a960 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 6c 65 61  .  }..  /* Relea
1a970 73 65 20 74 68 65 20 6c 6f 63 6b 73 2e 20 2a 2f  se the locks. */
1a980 0a 20 20 73 71 6c 69 74 65 33 57 61 6c 45 6e 64  .  sqlite3WalEnd
1a990 57 72 69 74 65 54 72 61 6e 73 61 63 74 69 6f 6e  WriteTransaction
1a9a0 28 70 57 61 6c 29 3b 0a 20 20 77 61 6c 55 6e 6c  (pWal);.  walUnl
1a9b0 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61  ockExclusive(pWa
1a9c0 6c 2c 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b  l, WAL_CKPT_LOCK
1a9d0 2c 20 31 29 3b 0a 20 20 70 57 61 6c 2d 3e 63 6b  , 1);.  pWal->ck
1a9e0 70 74 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 57 41  ptLock = 0;.  WA
1a9f0 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20  LTRACE(("WAL%p: 
1aa00 63 68 65 63 6b 70 6f 69 6e 74 20 25 73 5c 6e 22  checkpoint %s\n"
1aa10 2c 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61  , pWal, rc ? "fa
1aa20 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a  iled" : "ok"));.
1aa30 20 20 72 65 74 75 72 6e 20 28 72 63 3d 3d 53 51    return (rc==SQ
1aa40 4c 49 54 45 5f 4f 4b 20 26 26 20 65 4d 6f 64 65  LITE_OK && eMode
1aa50 21 3d 65 4d 6f 64 65 32 20 3f 20 53 51 4c 49 54  !=eMode2 ? SQLIT
1aa60 45 5f 42 55 53 59 20 3a 20 72 63 29 3b 0a 7d 0a  E_BUSY : rc);.}.
1aa70 0a 2f 2a 20 52 65 74 75 72 6e 20 74 68 65 20 76  ./* Return the v
1aa80 61 6c 75 65 20 74 6f 20 70 61 73 73 20 74 6f 20  alue to pass to 
1aa90 61 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 68 6f  a sqlite3_wal_ho
1aaa0 6f 6b 20 63 61 6c 6c 62 61 63 6b 2c 20 74 68 65  ok callback, the
1aab0 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 66 72  .** number of fr
1aac0 61 6d 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20  ames in the WAL 
1aad0 61 74 20 74 68 65 20 70 6f 69 6e 74 20 6f 66 20  at the point of 
1aae0 74 68 65 20 6c 61 73 74 20 63 6f 6d 6d 69 74 20  the last commit 
1aaf0 73 69 6e 63 65 0a 2a 2a 20 73 71 6c 69 74 65 33  since.** sqlite3
1ab00 57 61 6c 43 61 6c 6c 62 61 63 6b 28 29 20 77 61  WalCallback() wa
1ab10 73 20 63 61 6c 6c 65 64 2e 20 20 49 66 20 6e 6f  s called.  If no
1ab20 20 63 6f 6d 6d 69 74 73 20 68 61 76 65 20 6f 63   commits have oc
1ab30 63 75 72 72 65 64 20 73 69 6e 63 65 0a 2a 2a 20  curred since.** 
1ab40 74 68 65 20 6c 61 73 74 20 63 61 6c 6c 2c 20 74  the last call, t
1ab50 68 65 6e 20 72 65 74 75 72 6e 20 30 2e 0a 2a 2f  hen return 0..*/
1ab60 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 43  .int sqlite3WalC
1ab70 61 6c 6c 62 61 63 6b 28 57 61 6c 20 2a 70 57 61  allback(Wal *pWa
1ab80 6c 29 7b 0a 20 20 75 33 32 20 72 65 74 20 3d 20  l){.  u32 ret = 
1ab90 30 3b 0a 20 20 69 66 28 20 70 57 61 6c 20 29 7b  0;.  if( pWal ){
1aba0 0a 20 20 20 20 72 65 74 20 3d 20 70 57 61 6c 2d  .    ret = pWal-
1abb0 3e 69 43 61 6c 6c 62 61 63 6b 3b 0a 20 20 20 20  >iCallback;.    
1abc0 70 57 61 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20  pWal->iCallback 
1abd0 3d 20 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  = 0;.  }.  retur
1abe0 6e 20 28 69 6e 74 29 72 65 74 3b 0a 7d 0a 0a 2f  n (int)ret;.}../
1abf0 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
1ac00 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20  on is called to 
1ac10 63 68 61 6e 67 65 20 74 68 65 20 57 41 4c 20 73  change the WAL s
1ac20 75 62 73 79 73 74 65 6d 20 69 6e 74 6f 20 6f 72  ubsystem into or
1ac30 20 6f 75 74 0a 2a 2a 20 6f 66 20 6c 6f 63 6b 69   out.** of locki
1ac40 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56  ng_mode=EXCLUSIV
1ac50 45 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20 69  E..**.** If op i
1ac60 73 20 7a 65 72 6f 2c 20 74 68 65 6e 20 61 74 74  s zero, then att
1ac70 65 6d 70 74 20 74 6f 20 63 68 61 6e 67 65 20 66  empt to change f
1ac80 72 6f 6d 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65  rom locking_mode
1ac90 3d 45 58 43 4c 55 53 49 56 45 0a 2a 2a 20 69 6e  =EXCLUSIVE.** in
1aca0 74 6f 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d  to locking_mode=
1acb0 4e 4f 52 4d 41 4c 2e 20 20 54 68 69 73 20 6d 65  NORMAL.  This me
1acc0 61 6e 73 20 74 68 61 74 20 77 65 20 6d 75 73 74  ans that we must
1acd0 20 61 63 71 75 69 72 65 20 61 20 6c 6f 63 6b 0a   acquire a lock.
1ace0 2a 2a 20 6f 6e 20 74 68 65 20 70 57 61 6c 2d 3e  ** on the pWal->
1acf0 72 65 61 64 4c 6f 63 6b 20 62 79 74 65 2e 20 20  readLock byte.  
1ad00 49 66 20 74 68 65 20 57 41 4c 20 69 73 20 61 6c  If the WAL is al
1ad10 72 65 61 64 79 20 69 6e 20 6c 6f 63 6b 69 6e 67  ready in locking
1ad20 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 0a 2a 2a 20  _mode=NORMAL.** 
1ad30 6f 72 20 69 66 20 74 68 65 20 61 63 71 75 69 73  or if the acquis
1ad40 69 74 69 6f 6e 20 6f 66 20 74 68 65 20 6c 6f 63  ition of the loc
1ad50 6b 20 66 61 69 6c 73 2c 20 74 68 65 6e 20 72 65  k fails, then re
1ad60 74 75 72 6e 20 30 2e 20 20 49 66 20 74 68 65 0a  turn 0.  If the.
1ad70 2a 2a 20 74 72 61 6e 73 69 74 69 6f 6e 20 6f 75  ** transition ou
1ad80 74 20 6f 66 20 65 78 63 6c 75 73 69 76 65 2d 6d  t of exclusive-m
1ad90 6f 64 65 20 69 73 20 73 75 63 63 65 73 73 66 75  ode is successfu
1ada0 6c 2c 20 72 65 74 75 72 6e 20 31 2e 20 20 54 68  l, return 1.  Th
1adb0 69 73 0a 2a 2a 20 6f 70 65 72 61 74 69 6f 6e 20  is.** operation 
1adc0 6d 75 73 74 20 6f 63 63 75 72 20 77 68 69 6c 65  must occur while
1add0 20 74 68 65 20 70 61 67 65 72 20 69 73 20 73 74   the pager is st
1ade0 69 6c 6c 20 68 6f 6c 64 69 6e 67 20 74 68 65 20  ill holding the 
1adf0 65 78 63 6c 75 73 69 76 65 0a 2a 2a 20 6c 6f 63  exclusive.** loc
1ae00 6b 20 6f 6e 20 74 68 65 20 6d 61 69 6e 20 64 61  k on the main da
1ae10 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a  tabase file..**.
1ae20 2a 2a 20 49 66 20 6f 70 20 69 73 20 6f 6e 65 2c  ** If op is one,
1ae30 20 74 68 65 6e 20 63 68 61 6e 67 65 20 66 72 6f   then change fro
1ae40 6d 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e  m locking_mode=N
1ae50 4f 52 4d 41 4c 20 69 6e 74 6f 20 0a 2a 2a 20 6c  ORMAL into .** l
1ae60 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c  ocking_mode=EXCL
1ae70 55 53 49 56 45 2e 20 20 54 68 69 73 20 6d 65 61  USIVE.  This mea
1ae80 6e 73 20 74 68 61 74 20 74 68 65 20 70 57 61 6c  ns that the pWal
1ae90 2d 3e 72 65 61 64 4c 6f 63 6b 20 6d 75 73 74 0a  ->readLock must.
1aea0 2a 2a 20 62 65 20 72 65 6c 65 61 73 65 64 2e 20  ** be released. 
1aeb0 20 52 65 74 75 72 6e 20 31 20 69 66 20 74 68 65   Return 1 if the
1aec0 20 74 72 61 6e 73 69 74 69 6f 6e 20 69 73 20 6d   transition is m
1aed0 61 64 65 20 61 6e 64 20 30 20 69 66 20 74 68 65  ade and 0 if the
1aee0 0a 2a 2a 20 57 41 4c 20 69 73 20 61 6c 72 65 61  .** WAL is alrea
1aef0 64 79 20 69 6e 20 65 78 63 6c 75 73 69 76 65 2d  dy in exclusive-
1af00 6c 6f 63 6b 69 6e 67 20 6d 6f 64 65 20 2d 20 6d  locking mode - m
1af10 65 61 6e 69 6e 67 20 74 68 61 74 20 74 68 69 73  eaning that this
1af20 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 69 73 20 61  .** routine is a
1af30 20 6e 6f 2d 6f 70 2e 20 20 54 68 65 20 70 61 67   no-op.  The pag
1af40 65 72 20 6d 75 73 74 20 61 6c 72 65 61 64 79 20  er must already 
1af50 68 6f 6c 64 20 74 68 65 20 65 78 63 6c 75 73 69  hold the exclusi
1af60 76 65 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68  ve lock.** on th
1af70 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20  e main database 
1af80 66 69 6c 65 20 62 65 66 6f 72 65 20 69 6e 76 6f  file before invo
1af90 6b 69 6e 67 20 74 68 69 73 20 6f 70 65 72 61 74  king this operat
1afa0 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70  ion..**.** If op
1afb0 20 69 73 20 6e 65 67 61 74 69 76 65 2c 20 74 68   is negative, th
1afc0 65 6e 20 64 6f 20 61 20 64 72 79 2d 72 75 6e 20  en do a dry-run 
1afd0 6f 66 20 74 68 65 20 6f 70 3d 3d 31 20 63 61 73  of the op==1 cas
1afe0 65 20 62 75 74 20 64 6f 0a 2a 2a 20 6e 6f 74 20  e but do.** not 
1aff0 61 63 74 75 61 6c 6c 79 20 63 68 61 6e 67 65 20  actually change 
1b000 61 6e 79 74 68 69 6e 67 2e 20 54 68 65 20 70 61  anything. The pa
1b010 67 65 72 20 75 73 65 73 20 74 68 69 73 20 74 6f  ger uses this to
1b020 20 73 65 65 20 69 66 20 69 74 0a 2a 2a 20 73 68   see if it.** sh
1b030 6f 75 6c 64 20 61 63 71 75 69 72 65 20 74 68 65  ould acquire the
1b040 20 64 61 74 61 62 61 73 65 20 65 78 63 6c 75 73   database exclus
1b050 69 76 65 20 6c 6f 63 6b 20 70 72 69 6f 72 20 74  ive lock prior t
1b060 6f 20 69 6e 76 6f 6b 69 6e 67 0a 2a 2a 20 74 68  o invoking.** th
1b070 65 20 6f 70 3d 3d 31 20 63 61 73 65 2e 0a 2a 2f  e op==1 case..*/
1b080 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 45  .int sqlite3WalE
1b090 78 63 6c 75 73 69 76 65 4d 6f 64 65 28 57 61 6c  xclusiveMode(Wal
1b0a0 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6f 70 29 7b   *pWal, int op){
1b0b0 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 61 73 73  .  int rc;.  ass
1b0c0 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74 65  ert( pWal->write
1b0d0 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 61 73 73  Lock==0 );.  ass
1b0e0 65 72 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75  ert( pWal->exclu
1b0f0 73 69 76 65 4d 6f 64 65 21 3d 57 41 4c 5f 48 45  siveMode!=WAL_HE
1b100 41 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 7c 7c  APMEMORY_MODE ||
1b110 20 6f 70 3d 3d 2d 31 20 29 3b 0a 0a 20 20 2f 2a   op==-1 );..  /*
1b120 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20   pWal->readLock 
1b130 69 73 20 75 73 75 61 6c 6c 79 20 73 65 74 2c 20  is usually set, 
1b140 62 75 74 20 6d 69 67 68 74 20 62 65 20 2d 31 20  but might be -1 
1b150 69 66 20 74 68 65 72 65 20 77 61 73 20 61 20 0a  if there was a .
1b160 20 20 2a 2a 20 70 72 69 6f 72 20 65 72 72 6f 72    ** prior error
1b170 20 77 68 69 6c 65 20 61 74 74 65 6d 70 74 69 6e   while attemptin
1b180 67 20 74 6f 20 61 63 71 75 69 72 65 20 61 72 65  g to acquire are
1b190 20 72 65 61 64 2d 6c 6f 63 6b 2e 20 54 68 69 73   read-lock. This
1b1a0 20 63 61 6e 6e 6f 74 20 0a 20 20 2a 2a 20 68 61   cannot .  ** ha
1b1b0 70 70 65 6e 20 69 66 20 74 68 65 20 63 6f 6e 6e  ppen if the conn
1b1c0 65 63 74 69 6f 6e 20 69 73 20 61 63 74 75 61 6c  ection is actual
1b1d0 6c 79 20 69 6e 20 65 78 63 6c 75 73 69 76 65 20  ly in exclusive 
1b1e0 6d 6f 64 65 20 28 61 73 20 6e 6f 20 78 53 68 6d  mode (as no xShm
1b1f0 4c 6f 63 6b 0a 20 20 2a 2a 20 6c 6f 63 6b 73 20  Lock.  ** locks 
1b200 61 72 65 20 74 61 6b 65 6e 20 69 6e 20 74 68 69  are taken in thi
1b210 73 20 63 61 73 65 29 2e 20 4e 6f 72 20 73 68 6f  s case). Nor sho
1b220 75 6c 64 20 74 68 65 20 70 61 67 65 72 20 61 74  uld the pager at
1b230 74 65 6d 70 74 20 74 6f 0a 20 20 2a 2a 20 75 70  tempt to.  ** up
1b240 67 72 61 64 65 20 74 6f 20 65 78 63 6c 75 73 69  grade to exclusi
1b250 76 65 2d 6d 6f 64 65 20 66 6f 6c 6c 6f 77 69 6e  ve-mode followin
1b260 67 20 73 75 63 68 20 61 6e 20 65 72 72 6f 72 2e  g such an error.
1b270 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  .  */.  assert( 
1b280 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d  pWal->readLock>=
1b290 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45  0 || pWal->lockE
1b2a0 72 72 6f 72 20 29 3b 0a 20 20 61 73 73 65 72 74  rror );.  assert
1b2b0 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  ( pWal->readLock
1b2c0 3e 3d 30 20 7c 7c 20 28 6f 70 3c 3d 30 20 26 26  >=0 || (op<=0 &&
1b2d0 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
1b2e0 4d 6f 64 65 3d 3d 30 29 20 29 3b 0a 0a 20 20 69  Mode==0) );..  i
1b2f0 66 28 20 6f 70 3d 3d 30 20 29 7b 0a 20 20 20 20  f( op==0 ){.    
1b300 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73  if( pWal->exclus
1b310 69 76 65 4d 6f 64 65 20 29 7b 0a 20 20 20 20 20  iveMode ){.     
1b320 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
1b330 4d 6f 64 65 20 3d 20 30 3b 0a 20 20 20 20 20 20  Mode = 0;.      
1b340 69 66 28 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65  if( walLockShare
1b350 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  d(pWal, WAL_READ
1b360 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64  _LOCK(pWal->read
1b370 4c 6f 63 6b 29 29 21 3d 53 51 4c 49 54 45 5f 4f  Lock))!=SQLITE_O
1b380 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61  K ){.        pWa
1b390 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
1b3a0 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = 1;.      }.  
1b3b0 20 20 20 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65      rc = pWal->e
1b3c0 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 3b  xclusiveMode==0;
1b3d0 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
1b3e0 20 20 2f 2a 20 41 6c 72 65 61 64 79 20 69 6e 20    /* Already in 
1b3f0 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52  locking_mode=NOR
1b400 4d 41 4c 20 2a 2f 0a 20 20 20 20 20 20 72 63 20  MAL */.      rc 
1b410 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c  = 0;.    }.  }el
1b420 73 65 20 69 66 28 20 6f 70 3e 30 20 29 7b 0a 20  se if( op>0 ){. 
1b430 20 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d     assert( pWal-
1b440 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d  >exclusiveMode==
1b450 30 20 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28  0 );.    assert(
1b460 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e   pWal->readLock>
1b470 3d 30 20 29 3b 0a 20 20 20 20 77 61 6c 55 6e 6c  =0 );.    walUnl
1b480 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20  ockShared(pWal, 
1b490 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57  WAL_READ_LOCK(pW
1b4a0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 3b 0a  al->readLock));.
1b4b0 20 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73      pWal->exclus
1b4c0 69 76 65 4d 6f 64 65 20 3d 20 31 3b 0a 20 20 20  iveMode = 1;.   
1b4d0 20 72 63 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65   rc = 1;.  }else
1b4e0 7b 0a 20 20 20 20 72 63 20 3d 20 70 57 61 6c 2d  {.    rc = pWal-
1b4f0 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d  >exclusiveMode==
1b500 30 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  0;.  }.  return 
1b510 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65  rc;.}../* .** Re
1b520 74 75 72 6e 20 74 72 75 65 20 69 66 20 74 68 65  turn true if the
1b530 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6e 6f 6e   argument is non
1b540 2d 4e 55 4c 4c 20 61 6e 64 20 74 68 65 20 57 41  -NULL and the WA
1b550 4c 20 6d 6f 64 75 6c 65 20 69 73 20 75 73 69 6e  L module is usin
1b560 67 0a 2a 2a 20 68 65 61 70 2d 6d 65 6d 6f 72 79  g.** heap-memory
1b570 20 66 6f 72 20 74 68 65 20 77 61 6c 2d 69 6e 64   for the wal-ind
1b580 65 78 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 69  ex. Otherwise, i
1b590 66 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20 69  f the argument i
1b5a0 73 20 4e 55 4c 4c 20 6f 72 20 74 68 65 0a 2a 2a  s NULL or the.**
1b5b0 20 57 41 4c 20 6d 6f 64 75 6c 65 20 69 73 20 75   WAL module is u
1b5c0 73 69 6e 67 20 73 68 61 72 65 64 2d 6d 65 6d 6f  sing shared-memo
1b5d0 72 79 2c 20 72 65 74 75 72 6e 20 66 61 6c 73 65  ry, return false
1b5e0 2e 20 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  . .*/.int sqlite
1b5f0 33 57 61 6c 48 65 61 70 4d 65 6d 6f 72 79 28 57  3WalHeapMemory(W
1b600 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 72 65 74  al *pWal){.  ret
1b610 75 72 6e 20 28 70 57 61 6c 20 26 26 20 70 57 61  urn (pWal && pWa
1b620 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
1b630 3d 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59  ==WAL_HEAPMEMORY
1b640 5f 4d 4f 44 45 20 29 3b 0a 7d 0a 0a 23 65 6e 64  _MODE );.}..#end
1b650 69 66 20 2f 2a 20 23 69 66 6e 64 65 66 20 53 51  if /* #ifndef SQ
1b660 4c 49 54 45 5f 4f 4d 49 54 5f 57 41 4c 20 2a 2f  LITE_OMIT_WAL */
1b670 0a                                               .