/ Hex Artifact Content
Login

Artifact 9658df8d404b82e6b2d40fd05944463214e2d935:


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 61 73 73 65 72 74 28 20 69 46 72 61 6d 65    assert( iFrame
16080 3e 69 52 65 61 64 20 29 3b 0a 20 20 20 20 20 20  >iRead );.      
16090 20 20 69 52 65 61 64 20 3d 20 69 46 72 61 6d 65    iRead = iFrame
160a0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
160b0 69 66 28 20 28 6e 43 6f 6c 6c 69 64 65 2d 2d 29  if( (nCollide--)
160c0 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72  ==0 ){.        r
160d0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 43 4f 52  eturn SQLITE_COR
160e0 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20 20 20  RUPT_BKPT;.     
160f0 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 23 69   }.    }.  }..#i
16100 66 64 65 66 20 53 51 4c 49 54 45 5f 45 4e 41 42  fdef SQLITE_ENAB
16110 4c 45 5f 45 58 50 45 4e 53 49 56 45 5f 41 53 53  LE_EXPENSIVE_ASS
16120 45 52 54 0a 20 20 2f 2a 20 49 66 20 65 78 70 65  ERT.  /* If expe
16130 6e 73 69 76 65 20 61 73 73 65 72 74 28 29 20 73  nsive assert() s
16140 74 61 74 65 6d 65 6e 74 73 20 61 72 65 20 61 76  tatements are av
16150 61 69 6c 61 62 6c 65 2c 20 64 6f 20 61 20 6c 69  ailable, do a li
16160 6e 65 61 72 20 73 65 61 72 63 68 0a 20 20 2a 2a  near search.  **
16170 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
16180 78 20 66 69 6c 65 20 63 6f 6e 74 65 6e 74 2e 20  x file content. 
16190 4d 61 6b 65 20 73 75 72 65 20 74 68 65 20 72 65  Make sure the re
161a0 73 75 6c 74 73 20 61 67 72 65 65 20 77 69 74 68  sults agree with
161b0 20 74 68 65 0a 20 20 2a 2a 20 72 65 73 75 6c 74   the.  ** result
161c0 20 6f 62 74 61 69 6e 65 64 20 75 73 69 6e 67 20   obtained using 
161d0 74 68 65 20 68 61 73 68 20 69 6e 64 65 78 65 73  the hash indexes
161e0 20 61 62 6f 76 65 2e 20 20 2a 2f 0a 20 20 7b 0a   above.  */.  {.
161f0 20 20 20 20 75 33 32 20 69 52 65 61 64 32 20 3d      u32 iRead2 =
16200 20 30 3b 0a 20 20 20 20 75 33 32 20 69 54 65 73   0;.    u32 iTes
16210 74 3b 0a 20 20 20 20 66 6f 72 28 69 54 65 73 74  t;.    for(iTest
16220 3d 69 4c 61 73 74 3b 20 69 54 65 73 74 3e 30 3b  =iLast; iTest>0;
16230 20 69 54 65 73 74 2d 2d 29 7b 0a 20 20 20 20 20   iTest--){.     
16240 20 69 66 28 20 77 61 6c 46 72 61 6d 65 50 67 6e   if( walFramePgn
16250 6f 28 70 57 61 6c 2c 20 69 54 65 73 74 29 3d 3d  o(pWal, iTest)==
16260 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20 20 20  pgno ){.        
16270 69 52 65 61 64 32 20 3d 20 69 54 65 73 74 3b 0a  iRead2 = iTest;.
16280 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
16290 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
162a0 20 61 73 73 65 72 74 28 20 69 52 65 61 64 3d 3d   assert( iRead==
162b0 69 52 65 61 64 32 20 29 3b 0a 20 20 7d 0a 23 65  iRead2 );.  }.#e
162c0 6e 64 69 66 0a 0a 20 20 2f 2a 20 49 66 20 69 52  ndif..  /* If iR
162d0 65 61 64 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c  ead is non-zero,
162e0 20 74 68 65 6e 20 69 74 20 69 73 20 74 68 65 20   then it is the 
162f0 6c 6f 67 20 66 72 61 6d 65 20 6e 75 6d 62 65 72  log frame number
16300 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74   that contains t
16310 68 65 0a 20 20 2a 2a 20 72 65 71 75 69 72 65 64  he.  ** required
16320 20 70 61 67 65 2e 20 52 65 61 64 20 61 6e 64 20   page. Read and 
16330 72 65 74 75 72 6e 20 64 61 74 61 20 66 72 6f 6d  return data from
16340 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 0a 20   the log file.. 
16350 20 2a 2f 0a 20 20 69 66 28 20 69 52 65 61 64 20   */.  if( iRead 
16360 29 7b 0a 20 20 20 20 69 6e 74 20 73 7a 3b 0a 20  ){.    int sz;. 
16370 20 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 0a     i64 iOffset;.
16380 20 20 20 20 73 7a 20 3d 20 70 57 61 6c 2d 3e 68      sz = pWal->h
16390 64 72 2e 73 7a 50 61 67 65 3b 0a 20 20 20 20 73  dr.szPage;.    s
163a0 7a 20 3d 20 28 73 7a 26 30 78 66 65 30 30 29 20  z = (sz&0xfe00) 
163b0 2b 20 28 28 73 7a 26 30 78 30 30 30 31 29 3c 3c  + ((sz&0x0001)<<
163c0 31 36 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73  16);.    testcas
163d0 65 28 20 73 7a 3c 3d 33 32 37 36 38 20 29 3b 0a  e( sz<=32768 );.
163e0 20 20 20 20 74 65 73 74 63 61 73 65 28 20 73 7a      testcase( sz
163f0 3e 3d 36 35 35 33 36 20 29 3b 0a 20 20 20 20 69  >=65536 );.    i
16400 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61 6d  Offset = walFram
16410 65 4f 66 66 73 65 74 28 69 52 65 61 64 2c 20 73  eOffset(iRead, s
16420 7a 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f 48  z) + WAL_FRAME_H
16430 44 52 53 49 5a 45 3b 0a 20 20 20 20 2a 70 49 6e  DRSIZE;.    *pIn
16440 57 61 6c 20 3d 20 31 3b 0a 20 20 20 20 2f 2a 20  Wal = 1;.    /* 
16450 74 65 73 74 63 61 73 65 28 20 49 53 5f 42 49 47  testcase( IS_BIG
16460 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20 29 3b  _INT(iOffset) );
16470 20 2f 2f 20 72 65 71 75 69 72 65 73 20 61 20 34   // requires a 4
16480 47 69 42 20 57 41 4c 20 2a 2f 0a 20 20 20 20 72  GiB WAL */.    r
16490 65 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52  eturn sqlite3OsR
164a0 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ead(pWal->pWalFd
164b0 2c 20 70 4f 75 74 2c 20 6e 4f 75 74 2c 20 69 4f  , pOut, nOut, iO
164c0 66 66 73 65 74 29 3b 0a 20 20 7d 0a 0a 20 20 2a  ffset);.  }..  *
164d0 70 49 6e 57 61 6c 20 3d 20 30 3b 0a 20 20 72 65  pInWal = 0;.  re
164e0 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
164f0 7d 0a 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72  }.../* .** Retur
16500 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68  n the size of th
16510 65 20 64 61 74 61 62 61 73 65 20 69 6e 20 70 61  e database in pa
16520 67 65 73 20 28 6f 72 20 7a 65 72 6f 2c 20 69 66  ges (or zero, if
16530 20 75 6e 6b 6e 6f 77 6e 29 2e 0a 2a 2f 0a 50 67   unknown)..*/.Pg
16540 6e 6f 20 73 71 6c 69 74 65 33 57 61 6c 44 62 73  no sqlite3WalDbs
16550 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ize(Wal *pWal){.
16560 20 20 69 66 28 20 70 57 61 6c 20 26 26 20 41 4c    if( pWal && AL
16570 57 41 59 53 28 70 57 61 6c 2d 3e 72 65 61 64 4c  WAYS(pWal->readL
16580 6f 63 6b 3e 3d 30 29 20 29 7b 0a 20 20 20 20 72  ock>=0) ){.    r
16590 65 74 75 72 6e 20 70 57 61 6c 2d 3e 68 64 72 2e  eturn pWal->hdr.
165a0 6e 50 61 67 65 3b 0a 20 20 7d 0a 20 20 72 65 74  nPage;.  }.  ret
165b0 75 72 6e 20 30 3b 0a 7d 0a 0a 0a 2f 2a 20 0a 2a  urn 0;.}.../* .*
165c0 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
165d0 73 74 61 72 74 73 20 61 20 77 72 69 74 65 20 74  starts a write t
165e0 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68  ransaction on th
165f0 65 20 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20 41 20 72  e WAL..**.** A r
16600 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
16610 6d 75 73 74 20 68 61 76 65 20 61 6c 72 65 61 64  must have alread
16620 79 20 62 65 65 6e 20 73 74 61 72 74 65 64 20 62  y been started b
16630 79 20 61 20 70 72 69 6f 72 20 63 61 6c 6c 0a 2a  y a prior call.*
16640 2a 20 74 6f 20 73 71 6c 69 74 65 33 57 61 6c 42  * to sqlite3WalB
16650 65 67 69 6e 52 65 61 64 54 72 61 6e 73 61 63 74  eginReadTransact
16660 69 6f 6e 28 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  ion()..**.** If 
16670 61 6e 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f  another thread o
16680 72 20 70 72 6f 63 65 73 73 20 68 61 73 20 77 72  r process has wr
16690 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65 20 64  itten into the d
166a0 61 74 61 62 61 73 65 20 73 69 6e 63 65 0a 2a 2a  atabase since.**
166b0 20 74 68 65 20 72 65 61 64 20 74 72 61 6e 73 61   the read transa
166c0 63 74 69 6f 6e 20 77 61 73 20 73 74 61 72 74 65  ction was starte
166d0 64 2c 20 74 68 65 6e 20 69 74 20 69 73 20 6e 6f  d, then it is no
166e0 74 20 70 6f 73 73 69 62 6c 65 20 66 6f 72 20 74  t possible for t
166f0 68 69 73 0a 2a 2a 20 74 68 72 65 61 64 20 74 6f  his.** thread to
16700 20 77 72 69 74 65 20 61 73 20 64 6f 69 6e 67 20   write as doing 
16710 73 6f 20 77 6f 75 6c 64 20 63 61 75 73 65 20 61  so would cause a
16720 20 66 6f 72 6b 2e 20 20 53 6f 20 74 68 69 73 20   fork.  So this 
16730 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65 74 75 72  routine.** retur
16740 6e 73 20 53 51 4c 49 54 45 5f 42 55 53 59 20 69  ns SQLITE_BUSY i
16750 6e 20 74 68 61 74 20 63 61 73 65 20 61 6e 64 20  n that case and 
16760 6e 6f 20 77 72 69 74 65 20 74 72 61 6e 73 61 63  no write transac
16770 74 69 6f 6e 20 69 73 20 73 74 61 72 74 65 64 2e  tion is started.
16780 0a 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 63 61 6e  .**.** There can
16790 20 6f 6e 6c 79 20 62 65 20 61 20 73 69 6e 67 6c   only be a singl
167a0 65 20 77 72 69 74 65 72 20 61 63 74 69 76 65 20  e writer active 
167b0 61 74 20 61 20 74 69 6d 65 2e 0a 2a 2f 0a 69 6e  at a time..*/.in
167c0 74 20 73 71 6c 69 74 65 33 57 61 6c 42 65 67 69  t sqlite3WalBegi
167d0 6e 57 72 69 74 65 54 72 61 6e 73 61 63 74 69 6f  nWriteTransactio
167e0 6e 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20  n(Wal *pWal){.  
167f0 69 6e 74 20 72 63 3b 0a 0a 20 20 2f 2a 20 43 61  int rc;..  /* Ca
16800 6e 6e 6f 74 20 73 74 61 72 74 20 61 20 77 72 69  nnot start a wri
16810 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 77  te transaction w
16820 69 74 68 6f 75 74 20 66 69 72 73 74 20 68 6f 6c  ithout first hol
16830 64 69 6e 67 20 61 20 72 65 61 64 0a 20 20 2a 2a  ding a read.  **
16840 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e 20 2a 2f   transaction. */
16850 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
16860 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b 0a  >readLock>=0 );.
16870 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 72 65 61  .  if( pWal->rea
16880 64 4f 6e 6c 79 20 29 7b 0a 20 20 20 20 72 65 74  dOnly ){.    ret
16890 75 72 6e 20 53 51 4c 49 54 45 5f 52 45 41 44 4f  urn SQLITE_READO
168a0 4e 4c 59 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4f  NLY;.  }..  /* O
168b0 6e 6c 79 20 6f 6e 65 20 77 72 69 74 65 72 20 61  nly one writer a
168c0 6c 6c 6f 77 65 64 20 61 74 20 61 20 74 69 6d 65  llowed at a time
168d0 2e 20 20 47 65 74 20 74 68 65 20 77 72 69 74 65  .  Get the write
168e0 20 6c 6f 63 6b 2e 20 20 52 65 74 75 72 6e 0a 20   lock.  Return. 
168f0 20 2a 2a 20 53 51 4c 49 54 45 5f 42 55 53 59 20   ** SQLITE_BUSY 
16900 69 66 20 75 6e 61 62 6c 65 2e 0a 20 20 2a 2f 0a  if unable..  */.
16910 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78    rc = walLockEx
16920 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
16930 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29  L_WRITE_LOCK, 1)
16940 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20  ;.  if( rc ){.  
16950 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d    return rc;.  }
16960 0a 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  .  pWal->writeLo
16970 63 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 49 66  ck = 1;..  /* If
16980 20 61 6e 6f 74 68 65 72 20 63 6f 6e 6e 65 63 74   another connect
16990 69 6f 6e 20 68 61 73 20 77 72 69 74 74 65 6e 20  ion has written 
169a0 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20  to the database 
169b0 66 69 6c 65 20 73 69 6e 63 65 20 74 68 65 0a 20  file since the. 
169c0 20 2a 2a 20 74 69 6d 65 20 74 68 65 20 72 65 61   ** time the rea
169d0 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e  d transaction on
169e0 20 74 68 69 73 20 63 6f 6e 6e 65 63 74 69 6f 6e   this connection
169f0 20 77 61 73 20 73 74 61 72 74 65 64 2c 20 74 68   was started, th
16a00 65 6e 0a 20 20 2a 2a 20 74 68 65 20 77 72 69 74  en.  ** the writ
16a10 65 20 69 73 20 64 69 73 61 6c 6c 6f 77 65 64 2e  e is disallowed.
16a20 0a 20 20 2a 2f 0a 20 20 69 66 28 20 6d 65 6d 63  .  */.  if( memc
16a30 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28  mp(&pWal->hdr, (
16a40 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48  void *)walIndexH
16a50 64 72 28 70 57 61 6c 29 2c 20 73 69 7a 65 6f 66  dr(pWal), sizeof
16a60 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 21 3d  (WalIndexHdr))!=
16a70 30 20 29 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f  0 ){.    walUnlo
16a80 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c  ckExclusive(pWal
16a90 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b  , WAL_WRITE_LOCK
16aa0 2c 20 31 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  , 1);.    pWal->
16ab0 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20  writeLock = 0;. 
16ac0 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42     rc = SQLITE_B
16ad0 55 53 59 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  USY;.  }..  retu
16ae0 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
16af0 45 6e 64 20 61 20 77 72 69 74 65 20 74 72 61 6e  End a write tran
16b00 73 61 63 74 69 6f 6e 2e 20 20 54 68 65 20 63 6f  saction.  The co
16b10 6d 6d 69 74 20 68 61 73 20 61 6c 72 65 61 64 79  mmit has already
16b20 20 62 65 65 6e 20 64 6f 6e 65 2e 20 20 54 68 69   been done.  Thi
16b30 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 6d 65 72  s.** routine mer
16b40 65 6c 79 20 72 65 6c 65 61 73 65 73 20 74 68 65  ely releases the
16b50 20 6c 6f 63 6b 2e 0a 2a 2f 0a 69 6e 74 20 73 71   lock..*/.int sq
16b60 6c 69 74 65 33 57 61 6c 45 6e 64 57 72 69 74 65  lite3WalEndWrite
16b70 54 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20  Transaction(Wal 
16b80 2a 70 57 61 6c 29 7b 0a 20 20 69 66 28 20 70 57  *pWal){.  if( pW
16b90 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 7b  al->writeLock ){
16ba0 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78  .    walUnlockEx
16bb0 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
16bc0 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29  L_WRITE_LOCK, 1)
16bd0 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74  ;.    pWal->writ
16be0 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 7d 0a 20  eLock = 0;.  }. 
16bf0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
16c00 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 61  K;.}../*.** If a
16c10 6e 79 20 64 61 74 61 20 68 61 73 20 62 65 65 6e  ny data has been
16c20 20 77 72 69 74 74 65 6e 20 28 62 75 74 20 6e 6f   written (but no
16c30 74 20 63 6f 6d 6d 69 74 74 65 64 29 20 74 6f 20  t committed) to 
16c40 74 68 65 20 6c 6f 67 20 66 69 6c 65 2c 20 74 68  the log file, th
16c50 69 73 0a 2a 2a 20 66 75 6e 63 74 69 6f 6e 20 6d  is.** function m
16c60 6f 76 65 73 20 74 68 65 20 77 72 69 74 65 2d 70  oves the write-p
16c70 6f 69 6e 74 65 72 20 62 61 63 6b 20 74 6f 20 74  ointer back to t
16c80 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  he start of the 
16c90 74 72 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a 2a 0a  transaction..**.
16ca0 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c 6c 79 2c  ** Additionally,
16cb0 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 66 75   the callback fu
16cc0 6e 63 74 69 6f 6e 20 69 73 20 69 6e 76 6f 6b 65  nction is invoke
16cd0 64 20 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65  d for each frame
16ce0 20 77 72 69 74 74 65 6e 0a 2a 2a 20 74 6f 20 74   written.** to t
16cf0 68 65 20 57 41 4c 20 73 69 6e 63 65 20 74 68 65  he WAL since the
16d00 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 74 72   start of the tr
16d10 61 6e 73 61 63 74 69 6f 6e 2e 20 49 66 20 74 68  ansaction. If th
16d20 65 20 63 61 6c 6c 62 61 63 6b 20 72 65 74 75 72  e callback retur
16d30 6e 73 0a 2a 2a 20 6f 74 68 65 72 20 74 68 61 6e  ns.** other than
16d40 20 53 51 4c 49 54 45 5f 4f 4b 2c 20 69 74 20 69   SQLITE_OK, it i
16d50 73 20 6e 6f 74 20 69 6e 76 6f 6b 65 64 20 61 67  s not invoked ag
16d60 61 69 6e 20 61 6e 64 20 74 68 65 20 65 72 72 6f  ain and the erro
16d70 72 20 63 6f 64 65 20 69 73 0a 2a 2a 20 72 65 74  r code is.** ret
16d80 75 72 6e 65 64 20 74 6f 20 74 68 65 20 63 61 6c  urned to the cal
16d90 6c 65 72 2e 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72  ler..**.** Other
16da0 77 69 73 65 2c 20 69 66 20 74 68 65 20 63 61 6c  wise, if the cal
16db0 6c 62 61 63 6b 20 66 75 6e 63 74 69 6f 6e 20 64  lback function d
16dc0 6f 65 73 20 6e 6f 74 20 72 65 74 75 72 6e 20 61  oes not return a
16dd0 6e 20 65 72 72 6f 72 2c 20 74 68 69 73 0a 2a 2a  n error, this.**
16de0 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e   function return
16df0 73 20 53 51 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a  s SQLITE_OK..*/.
16e00 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 55 6e  int sqlite3WalUn
16e10 64 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e  do(Wal *pWal, in
16e20 74 20 28 2a 78 55 6e 64 6f 29 28 76 6f 69 64 20  t (*xUndo)(void 
16e30 2a 2c 20 50 67 6e 6f 29 2c 20 76 6f 69 64 20 2a  *, Pgno), void *
16e40 70 55 6e 64 6f 43 74 78 29 7b 0a 20 20 69 6e 74  pUndoCtx){.  int
16e50 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
16e60 0a 20 20 69 66 28 20 41 4c 57 41 59 53 28 70 57  .  if( ALWAYS(pW
16e70 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 29 20 29  al->writeLock) )
16e80 7b 0a 20 20 20 20 50 67 6e 6f 20 69 4d 61 78 20  {.    Pgno iMax 
16e90 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  = pWal->hdr.mxFr
16ea0 61 6d 65 3b 0a 20 20 20 20 50 67 6e 6f 20 69 46  ame;.    Pgno iF
16eb0 72 61 6d 65 3b 0a 20 20 0a 20 20 20 20 2f 2a 20  rame;.  .    /* 
16ec0 52 65 73 74 6f 72 65 20 74 68 65 20 63 6c 69 65  Restore the clie
16ed0 6e 74 73 20 63 61 63 68 65 20 6f 66 20 74 68 65  nts cache of the
16ee0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
16ef0 72 20 74 6f 20 74 68 65 20 73 74 61 74 65 20 69  r to the state i
16f00 74 0a 20 20 20 20 2a 2a 20 77 61 73 20 69 6e 20  t.    ** was in 
16f10 62 65 66 6f 72 65 20 74 68 65 20 63 6c 69 65 6e  before the clien
16f20 74 20 62 65 67 61 6e 20 77 72 69 74 69 6e 67 20  t began writing 
16f30 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 2e  to the database.
16f40 20 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d 65 6d   .    */.    mem
16f50 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20  cpy(&pWal->hdr, 
16f60 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65 78  (void *)walIndex
16f70 48 64 72 28 70 57 61 6c 29 2c 20 73 69 7a 65 6f  Hdr(pWal), sizeo
16f80 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 3b  f(WalIndexHdr));
16f90 0a 0a 20 20 20 20 66 6f 72 28 69 46 72 61 6d 65  ..    for(iFrame
16fa0 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  =pWal->hdr.mxFra
16fb0 6d 65 2b 31 3b 20 0a 20 20 20 20 20 20 20 20 41  me+1; .        A
16fc0 4c 57 41 59 53 28 72 63 3d 3d 53 51 4c 49 54 45  LWAYS(rc==SQLITE
16fd0 5f 4f 4b 29 20 26 26 20 69 46 72 61 6d 65 3c 3d  _OK) && iFrame<=
16fe0 69 4d 61 78 3b 20 0a 20 20 20 20 20 20 20 20 69  iMax; .        i
16ff0 46 72 61 6d 65 2b 2b 0a 20 20 20 20 29 7b 0a 20  Frame++.    ){. 
17000 20 20 20 20 20 2f 2a 20 54 68 69 73 20 63 61 6c       /* This cal
17010 6c 20 63 61 6e 6e 6f 74 20 66 61 69 6c 2e 20 55  l cannot fail. U
17020 6e 6c 65 73 73 20 74 68 65 20 70 61 67 65 20 66  nless the page f
17030 6f 72 20 77 68 69 63 68 20 74 68 65 20 70 61 67  or which the pag
17040 65 20 6e 75 6d 62 65 72 0a 20 20 20 20 20 20 2a  e number.      *
17050 2a 20 69 73 20 70 61 73 73 65 64 20 61 73 20 74  * is passed as t
17060 68 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65  he second argume
17070 6e 74 20 69 73 20 28 61 29 20 69 6e 20 74 68 65  nt is (a) in the
17080 20 63 61 63 68 65 20 61 6e 64 20 0a 20 20 20 20   cache and .    
17090 20 20 2a 2a 20 28 62 29 20 68 61 73 20 61 6e 20    ** (b) has an 
170a0 6f 75 74 73 74 61 6e 64 69 6e 67 20 72 65 66 65  outstanding refe
170b0 72 65 6e 63 65 2c 20 74 68 65 6e 20 78 55 6e 64  rence, then xUnd
170c0 6f 20 69 73 20 65 69 74 68 65 72 20 61 20 6e 6f  o is either a no
170d0 2d 6f 70 0a 20 20 20 20 20 20 2a 2a 20 28 69 66  -op.      ** (if
170e0 20 28 61 29 20 69 73 20 66 61 6c 73 65 29 20 6f   (a) is false) o
170f0 72 20 73 69 6d 70 6c 79 20 65 78 70 65 6c 73 20  r simply expels 
17100 74 68 65 20 70 61 67 65 20 66 72 6f 6d 20 74 68  the page from th
17110 65 20 63 61 63 68 65 20 28 69 66 20 28 62 29 0a  e cache (if (b).
17120 20 20 20 20 20 20 2a 2a 20 69 73 20 66 61 6c 73        ** is fals
17130 65 29 2e 0a 20 20 20 20 20 20 2a 2a 0a 20 20 20  e)..      **.   
17140 20 20 20 2a 2a 20 49 66 20 74 68 65 20 75 70 70     ** If the upp
17150 65 72 20 6c 61 79 65 72 20 69 73 20 64 6f 69 6e  er layer is doin
17160 67 20 61 20 72 6f 6c 6c 62 61 63 6b 2c 20 69 74  g a rollback, it
17170 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74   is guaranteed t
17180 68 61 74 20 74 68 65 72 65 0a 20 20 20 20 20 20  hat there.      
17190 2a 2a 20 61 72 65 20 6e 6f 20 6f 75 74 73 74 61  ** are no outsta
171a0 6e 64 69 6e 67 20 72 65 66 65 72 65 6e 63 65 73  nding references
171b0 20 74 6f 20 61 6e 79 20 70 61 67 65 20 6f 74 68   to any page oth
171c0 65 72 20 74 68 61 6e 20 70 61 67 65 20 31 2e 20  er than page 1. 
171d0 41 6e 64 0a 20 20 20 20 20 20 2a 2a 20 70 61 67  And.      ** pag
171e0 65 20 31 20 69 73 20 6e 65 76 65 72 20 77 72 69  e 1 is never wri
171f0 74 74 65 6e 20 74 6f 20 74 68 65 20 6c 6f 67 20  tten to the log 
17200 75 6e 74 69 6c 20 74 68 65 20 74 72 61 6e 73 61  until the transa
17210 63 74 69 6f 6e 20 69 73 0a 20 20 20 20 20 20 2a  ction is.      *
17220 2a 20 63 6f 6d 6d 69 74 74 65 64 2e 20 41 73 20  * committed. As 
17230 61 20 72 65 73 75 6c 74 2c 20 74 68 65 20 63 61  a result, the ca
17240 6c 6c 20 74 6f 20 78 55 6e 64 6f 20 6d 61 79 20  ll to xUndo may 
17250 6e 6f 74 20 66 61 69 6c 2e 0a 20 20 20 20 20 20  not fail..      
17260 2a 2f 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  */.      assert(
17270 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57   walFramePgno(pW
17280 61 6c 2c 20 69 46 72 61 6d 65 29 21 3d 31 20 29  al, iFrame)!=1 )
17290 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 78 55 6e  ;.      rc = xUn
172a0 64 6f 28 70 55 6e 64 6f 43 74 78 2c 20 77 61 6c  do(pUndoCtx, wal
172b0 46 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20  FramePgno(pWal, 
172c0 69 46 72 61 6d 65 29 29 3b 0a 20 20 20 20 7d 0a  iFrame));.    }.
172d0 20 20 20 20 77 61 6c 43 6c 65 61 6e 75 70 48 61      walCleanupHa
172e0 73 68 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20 20  sh(pWal);.  }.  
172f0 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c 49  assert( rc==SQLI
17300 54 45 5f 4f 4b 20 29 3b 0a 20 20 72 65 74 75 72  TE_OK );.  retur
17310 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  n rc;.}../* .** 
17320 41 72 67 75 6d 65 6e 74 20 61 57 61 6c 44 61 74  Argument aWalDat
17330 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f 20  a must point to 
17340 61 6e 20 61 72 72 61 79 20 6f 66 20 57 41 4c 5f  an array of WAL_
17350 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54 41 20  SAVEPOINT_NDATA 
17360 75 33 32 20 0a 2a 2a 20 76 61 6c 75 65 73 2e 20  u32 .** values. 
17370 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 70 6f  This function po
17380 70 75 6c 61 74 65 73 20 74 68 65 20 61 72 72 61  pulates the arra
17390 79 20 77 69 74 68 20 76 61 6c 75 65 73 20 72 65  y with values re
173a0 71 75 69 72 65 64 20 74 6f 20 0a 2a 2a 20 22 72  quired to .** "r
173b0 6f 6c 6c 62 61 63 6b 22 20 74 68 65 20 77 72 69  ollback" the wri
173c0 74 65 20 70 6f 73 69 74 69 6f 6e 20 6f 66 20 74  te position of t
173d0 68 65 20 57 41 4c 20 68 61 6e 64 6c 65 20 62 61  he WAL handle ba
173e0 63 6b 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e  ck to the curren
173f0 74 20 0a 2a 2a 20 70 6f 69 6e 74 20 69 6e 20 74  t .** point in t
17400 68 65 20 65 76 65 6e 74 20 6f 66 20 61 20 73 61  he event of a sa
17410 76 65 70 6f 69 6e 74 20 72 6f 6c 6c 62 61 63 6b  vepoint rollback
17420 20 28 76 69 61 20 57 61 6c 53 61 76 65 70 6f 69   (via WalSavepoi
17430 6e 74 55 6e 64 6f 28 29 29 2e 0a 2a 2f 0a 76 6f  ntUndo())..*/.vo
17440 69 64 20 73 71 6c 69 74 65 33 57 61 6c 53 61 76  id sqlite3WalSav
17450 65 70 6f 69 6e 74 28 57 61 6c 20 2a 70 57 61 6c  epoint(Wal *pWal
17460 2c 20 75 33 32 20 2a 61 57 61 6c 44 61 74 61 29  , u32 *aWalData)
17470 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  {.  assert( pWal
17480 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20  ->writeLock );. 
17490 20 61 57 61 6c 44 61 74 61 5b 30 5d 20 3d 20 70   aWalData[0] = p
174a0 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
174b0 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 31 5d 20  ;.  aWalData[1] 
174c0 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61  = pWal->hdr.aFra
174d0 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 61 57  meCksum[0];.  aW
174e0 61 6c 44 61 74 61 5b 32 5d 20 3d 20 70 57 61 6c  alData[2] = pWal
174f0 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
17500 6d 5b 31 5d 3b 0a 20 20 61 57 61 6c 44 61 74 61  m[1];.  aWalData
17510 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e 6e 43 6b 70  [3] = pWal->nCkp
17520 74 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 4d 6f 76  t;.}../* .** Mov
17530 65 20 74 68 65 20 77 72 69 74 65 20 70 6f 73 69  e the write posi
17540 74 69 6f 6e 20 6f 66 20 74 68 65 20 57 41 4c 20  tion of the WAL 
17550 62 61 63 6b 20 74 6f 20 74 68 65 20 70 6f 69 6e  back to the poin
17560 74 20 69 64 65 6e 74 69 66 69 65 64 20 62 79 0a  t identified by.
17570 2a 2a 20 74 68 65 20 76 61 6c 75 65 73 20 69 6e  ** the values in
17580 20 74 68 65 20 61 57 61 6c 44 61 74 61 5b 5d 20   the aWalData[] 
17590 61 72 72 61 79 2e 20 61 57 61 6c 44 61 74 61 20  array. aWalData 
175a0 6d 75 73 74 20 70 6f 69 6e 74 20 74 6f 20 61 6e  must point to an
175b0 20 61 72 72 61 79 0a 2a 2a 20 6f 66 20 57 41 4c   array.** of WAL
175c0 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44 41 54 41  _SAVEPOINT_NDATA
175d0 20 75 33 32 20 76 61 6c 75 65 73 20 74 68 61 74   u32 values that
175e0 20 68 61 73 20 62 65 65 6e 20 70 72 65 76 69 6f   has been previo
175f0 75 73 6c 79 20 70 6f 70 75 6c 61 74 65 64 0a 2a  usly populated.*
17600 2a 20 62 79 20 61 20 63 61 6c 6c 20 74 6f 20 57  * by a call to W
17610 61 6c 53 61 76 65 70 6f 69 6e 74 28 29 2e 0a 2a  alSavepoint()..*
17620 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c  /.int sqlite3Wal
17630 53 61 76 65 70 6f 69 6e 74 55 6e 64 6f 28 57 61  SavepointUndo(Wa
17640 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 2a 61 57  l *pWal, u32 *aW
17650 61 6c 44 61 74 61 29 7b 0a 20 20 69 6e 74 20 72  alData){.  int r
17660 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
17670 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
17680 77 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 61  writeLock );.  a
17690 73 73 65 72 74 28 20 61 57 61 6c 44 61 74 61 5b  ssert( aWalData[
176a0 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43 6b 70 74 20  3]!=pWal->nCkpt 
176b0 7c 7c 20 61 57 61 6c 44 61 74 61 5b 30 5d 3c 3d  || aWalData[0]<=
176c0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
176d0 65 20 29 3b 0a 0a 20 20 69 66 28 20 61 57 61 6c  e );..  if( aWal
176e0 44 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e  Data[3]!=pWal->n
176f0 43 6b 70 74 20 29 7b 0a 20 20 20 20 2f 2a 20 54  Ckpt ){.    /* T
17700 68 69 73 20 73 61 76 65 70 6f 69 6e 74 20 77 61  his savepoint wa
17710 73 20 6f 70 65 6e 65 64 20 69 6d 6d 65 64 69 61  s opened immedia
17720 74 65 6c 79 20 61 66 74 65 72 20 74 68 65 20 77  tely after the w
17730 72 69 74 65 2d 74 72 61 6e 73 61 63 74 69 6f 6e  rite-transaction
17740 0a 20 20 20 20 2a 2a 20 77 61 73 20 73 74 61 72  .    ** was star
17750 74 65 64 2e 20 52 69 67 68 74 20 61 66 74 65 72  ted. Right after
17760 20 74 68 61 74 2c 20 74 68 65 20 77 72 69 74 65   that, the write
17770 72 20 64 65 63 69 64 65 64 20 74 6f 20 77 72 61  r decided to wra
17780 70 20 61 72 6f 75 6e 64 0a 20 20 20 20 2a 2a 20  p around.    ** 
17790 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  to the start of 
177a0 74 68 65 20 6c 6f 67 2e 20 55 70 64 61 74 65 20  the log. Update 
177b0 74 68 65 20 73 61 76 65 70 6f 69 6e 74 20 76 61  the savepoint va
177c0 6c 75 65 73 20 74 6f 20 6d 61 74 63 68 2e 0a 20  lues to match.. 
177d0 20 20 20 2a 2f 0a 20 20 20 20 61 57 61 6c 44 61     */.    aWalDa
177e0 74 61 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20 61  ta[0] = 0;.    a
177f0 57 61 6c 44 61 74 61 5b 33 5d 20 3d 20 70 57 61  WalData[3] = pWa
17800 6c 2d 3e 6e 43 6b 70 74 3b 0a 20 20 7d 0a 0a 20  l->nCkpt;.  }.. 
17810 20 69 66 28 20 61 57 61 6c 44 61 74 61 5b 30 5d   if( aWalData[0]
17820 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61  <pWal->hdr.mxFra
17830 6d 65 20 29 7b 0a 20 20 20 20 70 57 61 6c 2d 3e  me ){.    pWal->
17840 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d 20 61 57  hdr.mxFrame = aW
17850 61 6c 44 61 74 61 5b 30 5d 3b 0a 20 20 20 20 70  alData[0];.    p
17860 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
17870 6b 73 75 6d 5b 30 5d 20 3d 20 61 57 61 6c 44 61  ksum[0] = aWalDa
17880 74 61 5b 31 5d 3b 0a 20 20 20 20 70 57 61 6c 2d  ta[1];.    pWal-
17890 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d  >hdr.aFrameCksum
178a0 5b 31 5d 20 3d 20 61 57 61 6c 44 61 74 61 5b 32  [1] = aWalData[2
178b0 5d 3b 0a 20 20 20 20 77 61 6c 43 6c 65 61 6e 75  ];.    walCleanu
178c0 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 7d  pHash(pWal);.  }
178d0 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
178e0 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
178f0 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
17900 6a 75 73 74 20 62 65 66 6f 72 65 20 77 72 69 74  just before writ
17910 69 6e 67 20 61 20 73 65 74 20 6f 66 20 66 72 61  ing a set of fra
17920 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f 67 0a 2a  mes to the log.*
17930 2a 20 66 69 6c 65 20 28 73 65 65 20 73 71 6c 69  * file (see sqli
17940 74 65 33 57 61 6c 46 72 61 6d 65 73 28 29 29 2e  te3WalFrames()).
17950 20 49 74 20 63 68 65 63 6b 73 20 74 6f 20 73 65   It checks to se
17960 65 20 69 66 2c 20 69 6e 73 74 65 61 64 20 6f 66  e if, instead of
17970 20 61 70 70 65 6e 64 69 6e 67 0a 2a 2a 20 74 6f   appending.** to
17980 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c 6f 67   the current log
17990 20 66 69 6c 65 2c 20 69 74 20 69 73 20 70 6f 73   file, it is pos
179a0 73 69 62 6c 65 20 74 6f 20 6f 76 65 72 77 72 69  sible to overwri
179b0 74 65 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  te the start of 
179c0 74 68 65 0a 2a 2a 20 65 78 69 73 74 69 6e 67 20  the.** existing 
179d0 6c 6f 67 20 66 69 6c 65 20 77 69 74 68 20 74 68  log file with th
179e0 65 20 6e 65 77 20 66 72 61 6d 65 73 20 28 69 2e  e new frames (i.
179f0 65 2e 20 22 72 65 73 65 74 22 20 74 68 65 20 6c  e. "reset" the l
17a00 6f 67 29 2e 20 49 66 20 73 6f 2c 0a 2a 2a 20 69  og). If so,.** i
17a10 74 20 73 65 74 73 20 70 57 61 6c 2d 3e 68 64 72  t sets pWal->hdr
17a20 2e 6d 78 46 72 61 6d 65 20 74 6f 20 30 2e 20 4f  .mxFrame to 0. O
17a30 74 68 65 72 77 69 73 65 2c 20 70 57 61 6c 2d 3e  therwise, pWal->
17a40 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20 6c  hdr.mxFrame is l
17a50 65 66 74 0a 2a 2a 20 75 6e 63 68 61 6e 67 65 64  eft.** unchanged
17a60 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f  ..**.** SQLITE_O
17a70 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 69 66  K is returned if
17a80 20 6e 6f 20 65 72 72 6f 72 20 69 73 20 65 6e 63   no error is enc
17a90 6f 75 6e 74 65 72 65 64 20 28 72 65 67 61 72 64  ountered (regard
17aa0 6c 65 73 73 20 6f 66 20 77 68 65 74 68 65 72 0a  less of whether.
17ab0 2a 2a 20 6f 72 20 6e 6f 74 20 70 57 61 6c 2d 3e  ** or not pWal->
17ac0 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20 6d  hdr.mxFrame is m
17ad0 6f 64 69 66 69 65 64 29 2e 20 41 6e 20 53 51 4c  odified). An SQL
17ae0 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
17af0 73 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69 66  s returned.** if
17b00 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
17b10 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
17b20 77 61 6c 52 65 73 74 61 72 74 4c 6f 67 28 57 61  walRestartLog(Wa
17b30 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20  l *pWal){.  int 
17b40 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
17b50 20 20 69 6e 74 20 63 6e 74 3b 0a 0a 20 20 69 66    int cnt;..  if
17b60 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  ( pWal->readLock
17b70 3d 3d 30 20 29 7b 0a 20 20 20 20 76 6f 6c 61 74  ==0 ){.    volat
17b80 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20  ile WalCkptInfo 
17b90 2a 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74  *pInfo = walCkpt
17ba0 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20 20  Info(pWal);.    
17bb0 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e 6e  assert( pInfo->n
17bc0 42 61 63 6b 66 69 6c 6c 3d 3d 70 57 61 6c 2d 3e  Backfill==pWal->
17bd0 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20  hdr.mxFrame );. 
17be0 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 42     if( pInfo->nB
17bf0 61 63 6b 66 69 6c 6c 3e 30 20 29 7b 0a 20 20 20  ackfill>0 ){.   
17c00 20 20 20 75 33 32 20 73 61 6c 74 31 3b 0a 20 20     u32 salt1;.  
17c10 20 20 20 20 73 71 6c 69 74 65 33 5f 72 61 6e 64      sqlite3_rand
17c20 6f 6d 6e 65 73 73 28 34 2c 20 26 73 61 6c 74 31  omness(4, &salt1
17c30 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61  );.      rc = wa
17c40 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  lLockExclusive(p
17c50 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
17c60 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44  CK(1), WAL_NREAD
17c70 45 52 2d 31 29 3b 0a 20 20 20 20 20 20 69 66 28  ER-1);.      if(
17c80 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
17c90 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20  {.        /* If 
17ca0 61 6c 6c 20 72 65 61 64 65 72 73 20 61 72 65 20  all readers are 
17cb0 75 73 69 6e 67 20 57 41 4c 5f 52 45 41 44 5f 4c  using WAL_READ_L
17cc0 4f 43 4b 28 30 29 20 28 69 6e 20 6f 74 68 65 72  OCK(0) (in other
17cd0 20 77 6f 72 64 73 20 69 66 20 6e 6f 0a 20 20 20   words if no.   
17ce0 20 20 20 20 20 2a 2a 20 72 65 61 64 65 72 73 20       ** readers 
17cf0 61 72 65 20 63 75 72 72 65 6e 74 6c 79 20 75 73  are currently us
17d00 69 6e 67 20 74 68 65 20 57 41 4c 29 2c 20 74 68  ing the WAL), th
17d10 65 6e 20 74 68 65 20 74 72 61 6e 73 61 63 74 69  en the transacti
17d20 6f 6e 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 66  ons.        ** f
17d30 72 61 6d 65 73 20 77 69 6c 6c 20 6f 76 65 72 77  rames will overw
17d40 72 69 74 65 20 74 68 65 20 73 74 61 72 74 20 6f  rite the start o
17d50 66 20 74 68 65 20 65 78 69 73 74 69 6e 67 20 6c  f the existing l
17d60 6f 67 2e 20 55 70 64 61 74 65 20 74 68 65 0a 20  og. Update the. 
17d70 20 20 20 20 20 20 20 2a 2a 20 77 61 6c 2d 69 6e         ** wal-in
17d80 64 65 78 20 68 65 61 64 65 72 20 74 6f 20 72 65  dex header to re
17d90 66 6c 65 63 74 20 74 68 69 73 2e 0a 20 20 20 20  flect this..    
17da0 20 20 20 20 2a 2a 0a 20 20 20 20 20 20 20 20 2a      **.        *
17db0 2a 20 49 6e 20 74 68 65 6f 72 79 20 69 74 20 77  * In theory it w
17dc0 6f 75 6c 64 20 62 65 20 4f 6b 20 74 6f 20 75 70  ould be Ok to up
17dd0 64 61 74 65 20 74 68 65 20 63 61 63 68 65 20 6f  date the cache o
17de0 66 20 74 68 65 20 68 65 61 64 65 72 20 6f 6e 6c  f the header onl
17df0 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 74 20  y.        ** at 
17e00 74 68 69 73 20 70 6f 69 6e 74 2e 20 42 75 74 20  this point. But 
17e10 75 70 64 61 74 69 6e 67 20 74 68 65 20 61 63 74  updating the act
17e20 75 61 6c 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  ual wal-index he
17e30 61 64 65 72 20 69 73 20 61 6c 73 6f 0a 20 20 20  ader is also.   
17e40 20 20 20 20 20 2a 2a 20 73 61 66 65 20 61 6e 64       ** safe and
17e50 20 6d 65 61 6e 73 20 74 68 65 72 65 20 69 73 20   means there is 
17e60 6e 6f 20 73 70 65 63 69 61 6c 20 63 61 73 65 20  no special case 
17e70 66 6f 72 20 73 71 6c 69 74 65 33 57 61 6c 55 6e  for sqlite3WalUn
17e80 64 6f 28 29 0a 20 20 20 20 20 20 20 20 2a 2a 20  do().        ** 
17e90 74 6f 20 68 61 6e 64 6c 65 20 69 66 20 74 68 69  to handle if thi
17ea0 73 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 73  s transaction is
17eb0 20 72 6f 6c 6c 65 64 20 62 61 63 6b 2e 0a 20 20   rolled back..  
17ec0 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20        */.       
17ed0 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
17ee0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f             /* Lo
17ef0 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20  op counter */.  
17f00 20 20 20 20 20 20 75 33 32 20 2a 61 53 61 6c 74        u32 *aSalt
17f10 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61   = pWal->hdr.aSa
17f20 6c 74 3b 20 20 20 20 20 20 20 2f 2a 20 42 69 67  lt;       /* Big
17f30 2d 65 6e 64 69 61 6e 20 73 61 6c 74 20 76 61 6c  -endian salt val
17f40 75 65 73 20 2a 2f 0a 0a 20 20 20 20 20 20 20 20  ues */..        
17f50 2f 2a 20 4c 69 6d 69 74 20 74 68 65 20 73 69 7a  /* Limit the siz
17f60 65 20 6f 66 20 57 41 4c 20 66 69 6c 65 20 69 66  e of WAL file if
17f70 20 74 68 65 20 6a 6f 75 72 6e 61 6c 5f 73 69 7a   the journal_siz
17f80 65 5f 6c 69 6d 69 74 20 50 52 41 47 4d 41 20 69  e_limit PRAGMA i
17f90 73 0a 20 20 20 20 20 20 20 20 2a 2a 20 73 65 74  s.        ** set
17fa0 20 74 6f 20 61 20 6e 6f 6e 2d 6e 65 67 61 74 69   to a non-negati
17fb0 76 65 20 76 61 6c 75 65 2e 20 20 4c 6f 67 20 65  ve value.  Log e
17fc0 72 72 6f 72 73 20 65 6e 63 6f 75 6e 74 65 72 65  rrors encountere
17fd0 64 0a 20 20 20 20 20 20 20 20 2a 2a 20 64 75 72  d.        ** dur
17fe0 69 6e 67 20 74 68 65 20 74 72 75 6e 63 61 74 69  ing the truncati
17ff0 6f 6e 20 61 74 74 65 6d 70 74 2e 20 2a 2f 0a 20  on attempt. */. 
18000 20 20 20 20 20 20 20 69 66 28 20 70 57 61 6c 2d         if( pWal-
18010 3e 6d 78 57 61 6c 53 69 7a 65 3e 3d 30 20 29 7b  >mxWalSize>=0 ){
18020 0a 20 20 20 20 20 20 20 20 20 20 69 36 34 20 73  .          i64 s
18030 7a 3b 0a 20 20 20 20 20 20 20 20 20 20 69 6e 74  z;.          int
18040 20 72 78 3b 0a 20 20 20 20 20 20 20 20 20 20 73   rx;.          s
18050 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e 69 67  qlite3BeginBenig
18060 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 20 20 20  nMalloc();.     
18070 20 20 20 20 20 72 78 20 3d 20 73 71 6c 69 74 65       rx = sqlite
18080 33 4f 73 46 69 6c 65 53 69 7a 65 28 70 57 61 6c  3OsFileSize(pWal
18090 2d 3e 70 57 61 6c 46 64 2c 20 26 73 7a 29 3b 0a  ->pWalFd, &sz);.
180a0 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72 78            if( rx
180b0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 28  ==SQLITE_OK && (
180c0 73 7a 20 3e 20 70 57 61 6c 2d 3e 6d 78 57 61 6c  sz > pWal->mxWal
180d0 53 69 7a 65 29 20 29 7b 0a 20 20 20 20 20 20 20  Size) ){.       
180e0 20 20 20 20 20 72 78 20 3d 20 73 71 6c 69 74 65       rx = sqlite
180f0 33 4f 73 54 72 75 6e 63 61 74 65 28 70 57 61 6c  3OsTruncate(pWal
18100 2d 3e 70 57 61 6c 46 64 2c 20 70 57 61 6c 2d 3e  ->pWalFd, pWal->
18110 6d 78 57 61 6c 53 69 7a 65 29 3b 0a 20 20 20 20  mxWalSize);.    
18120 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
18130 20 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e 69    sqlite3EndBeni
18140 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 20 20  gnMalloc();.    
18150 20 20 20 20 20 20 69 66 28 20 72 78 20 29 7b 0a        if( rx ){.
18160 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
18170 74 65 33 5f 6c 6f 67 28 72 78 2c 20 22 63 61 6e  te3_log(rx, "can
18180 6e 6f 74 20 6c 69 6d 69 74 20 57 41 4c 20 73 69  not limit WAL si
18190 7a 65 3a 20 25 73 22 2c 20 70 57 61 6c 2d 3e 7a  ze: %s", pWal->z
181a0 57 61 6c 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20  WalName);.      
181b0 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
181c0 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 6e  .        pWal->n
181d0 43 6b 70 74 2b 2b 3b 0a 20 20 20 20 20 20 20 20  Ckpt++;.        
181e0 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
181f0 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 73  e = 0;.        s
18200 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 28  qlite3Put4byte((
18210 75 38 2a 29 26 61 53 61 6c 74 5b 30 5d 2c 20 31  u8*)&aSalt[0], 1
18220 20 2b 20 73 71 6c 69 74 65 33 47 65 74 34 62 79   + sqlite3Get4by
18230 74 65 28 28 75 38 2a 29 26 61 53 61 6c 74 5b 30  te((u8*)&aSalt[0
18240 5d 29 29 3b 0a 20 20 20 20 20 20 20 20 61 53 61  ]));.        aSa
18250 6c 74 5b 31 5d 20 3d 20 73 61 6c 74 31 3b 0a 20  lt[1] = salt1;. 
18260 20 20 20 20 20 20 20 77 61 6c 49 6e 64 65 78 57         walIndexW
18270 72 69 74 65 48 64 72 28 70 57 61 6c 29 3b 0a 20  riteHdr(pWal);. 
18280 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42         pInfo->nB
18290 61 63 6b 66 69 6c 6c 20 3d 20 30 3b 0a 20 20 20  ackfill = 0;.   
182a0 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c       for(i=1; i<
182b0 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b 2b  WAL_NREADER; i++
182c0 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61  ) pInfo->aReadMa
182d0 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41 52 4b  rk[i] = READMARK
182e0 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 20 20 20  _NOT_USED;.     
182f0 20 20 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f     assert( pInfo
18300 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 3d 3d  ->aReadMark[0]==
18310 30 20 29 3b 0a 20 20 20 20 20 20 20 20 77 61 6c  0 );.        wal
18320 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28  UnlockExclusive(
18330 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  pWal, WAL_READ_L
18340 4f 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41  OCK(1), WAL_NREA
18350 44 45 52 2d 31 29 3b 0a 20 20 20 20 20 20 7d 65  DER-1);.      }e
18360 6c 73 65 20 69 66 28 20 72 63 21 3d 53 51 4c 49  lse if( rc!=SQLI
18370 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20  TE_BUSY ){.     
18380 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
18390 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
183a0 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28  walUnlockShared(
183b0 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c  pWal, WAL_READ_L
183c0 4f 43 4b 28 30 29 29 3b 0a 20 20 20 20 70 57 61  OCK(0));.    pWa
183d0 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31  l->readLock = -1
183e0 3b 0a 20 20 20 20 63 6e 74 20 3d 20 30 3b 0a 20  ;.    cnt = 0;. 
183f0 20 20 20 64 6f 7b 0a 20 20 20 20 20 20 69 6e 74     do{.      int
18400 20 6e 6f 74 55 73 65 64 3b 0a 20 20 20 20 20 20   notUsed;.      
18410 72 63 20 3d 20 77 61 6c 54 72 79 42 65 67 69 6e  rc = walTryBegin
18420 52 65 61 64 28 70 57 61 6c 2c 20 26 6e 6f 74 55  Read(pWal, &notU
18430 73 65 64 2c 20 31 2c 20 2b 2b 63 6e 74 29 3b 0a  sed, 1, ++cnt);.
18440 20 20 20 20 7d 77 68 69 6c 65 28 20 72 63 3d 3d      }while( rc==
18450 57 41 4c 5f 52 45 54 52 59 20 29 3b 0a 20 20 20  WAL_RETRY );.   
18460 20 61 73 73 65 72 74 28 20 28 72 63 26 30 78 66   assert( (rc&0xf
18470 66 29 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  f)!=SQLITE_BUSY 
18480 29 3b 20 2f 2a 20 42 55 53 59 20 6e 6f 74 20 70  ); /* BUSY not p
18490 6f 73 73 69 62 6c 65 20 77 68 65 6e 20 75 73 65  ossible when use
184a0 57 61 6c 3d 3d 31 20 2a 2f 0a 20 20 20 20 74 65  Wal==1 */.    te
184b0 73 74 63 61 73 65 28 20 28 72 63 26 30 78 66 66  stcase( (rc&0xff
184c0 29 3d 3d 53 51 4c 49 54 45 5f 49 4f 45 52 52 20  )==SQLITE_IOERR 
184d0 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73 65 28  );.    testcase(
184e0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 50 52 4f 54   rc==SQLITE_PROT
184f0 4f 43 4f 4c 20 29 3b 0a 20 20 20 20 74 65 73 74  OCOL );.    test
18500 63 61 73 65 28 20 72 63 3d 3d 53 51 4c 49 54 45  case( rc==SQLITE
18510 5f 4f 4b 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74  _OK );.  }.  ret
18520 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  urn rc;.}../* .*
18530 2a 20 57 72 69 74 65 20 61 20 73 65 74 20 6f 66  * Write a set of
18540 20 66 72 61 6d 65 73 20 74 6f 20 74 68 65 20 6c   frames to the l
18550 6f 67 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 6d  og. The caller m
18560 75 73 74 20 68 6f 6c 64 20 74 68 65 20 77 72 69  ust hold the wri
18570 74 65 2d 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68  te-lock.** on th
18580 65 20 6c 6f 67 20 66 69 6c 65 20 28 6f 62 74 61  e log file (obta
18590 69 6e 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74  ined using sqlit
185a0 65 33 57 61 6c 42 65 67 69 6e 57 72 69 74 65 54  e3WalBeginWriteT
185b0 72 61 6e 73 61 63 74 69 6f 6e 28 29 29 2e 0a 2a  ransaction())..*
185c0 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c  /.int sqlite3Wal
185d0 46 72 61 6d 65 73 28 0a 20 20 57 61 6c 20 2a 70  Frames(.  Wal *p
185e0 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Wal,            
185f0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c            /* Wal
18600 20 68 61 6e 64 6c 65 20 74 6f 20 77 72 69 74 65   handle to write
18610 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50   to */.  int szP
18620 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  age,            
18630 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
18640 62 61 73 65 20 70 61 67 65 2d 73 69 7a 65 20 69  base page-size i
18650 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 50 67 48  n bytes */.  PgH
18660 64 72 20 2a 70 4c 69 73 74 2c 20 20 20 20 20 20  dr *pList,      
18670 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
18680 4c 69 73 74 20 6f 66 20 64 69 72 74 79 20 70 61  List of dirty pa
18690 67 65 73 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a  ges to write */.
186a0 20 20 50 67 6e 6f 20 6e 54 72 75 6e 63 61 74 65    Pgno nTruncate
186b0 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
186c0 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 73 69    /* Database si
186d0 7a 65 20 61 66 74 65 72 20 74 68 69 73 20 63 6f  ze after this co
186e0 6d 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20 69 73  mmit */.  int is
186f0 43 6f 6d 6d 69 74 2c 20 20 20 20 20 20 20 20 20  Commit,         
18700 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
18710 65 20 69 66 20 74 68 69 73 20 69 73 20 61 20 63  e if this is a c
18720 6f 6d 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20 73  ommit */.  int s
18730 79 6e 63 5f 66 6c 61 67 73 20 20 20 20 20 20 20  ync_flags       
18740 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c             /* Fl
18750 61 67 73 20 74 6f 20 70 61 73 73 20 74 6f 20 4f  ags to pass to O
18760 73 53 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a  sSync() (or 0) *
18770 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20  /.){.  int rc;  
18780 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18790 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
187a0 6f 20 63 61 74 63 68 20 72 65 74 75 72 6e 20 63  o catch return c
187b0 6f 64 65 73 20 2a 2f 0a 20 20 75 33 32 20 69 46  odes */.  u32 iF
187c0 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20  rame;           
187d0 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78            /* Nex
187e0 74 20 66 72 61 6d 65 20 61 64 64 72 65 73 73 20  t frame address 
187f0 2a 2f 0a 20 20 75 38 20 61 46 72 61 6d 65 5b 57  */.  u8 aFrame[W
18800 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
18810 5d 3b 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74  ];   /* Buffer t
18820 6f 20 61 73 73 65 6d 62 6c 65 20 66 72 61 6d 65  o assemble frame
18830 2d 68 65 61 64 65 72 20 69 6e 20 2a 2f 0a 20 20  -header in */.  
18840 50 67 48 64 72 20 2a 70 3b 20 20 20 20 20 20 20  PgHdr *p;       
18850 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
18860 2f 2a 20 49 74 65 72 61 74 6f 72 20 74 6f 20 72  /* Iterator to r
18870 75 6e 20 74 68 72 6f 75 67 68 20 70 4c 69 73 74  un through pList
18880 20 77 69 74 68 2e 20 2a 2f 0a 20 20 50 67 48 64   with. */.  PgHd
18890 72 20 2a 70 4c 61 73 74 20 3d 20 30 3b 20 20 20  r *pLast = 0;   
188a0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
188b0 61 73 74 20 66 72 61 6d 65 20 69 6e 20 6c 69 73  ast frame in lis
188c0 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 61 73 74  t */.  int nLast
188d0 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
188e0 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
188f0 20 6f 66 20 65 78 74 72 61 20 63 6f 70 69 65 73   of extra copies
18900 20 6f 66 20 6c 61 73 74 20 70 61 67 65 20 2a 2f   of last page */
18910 0a 0a 20 20 61 73 73 65 72 74 28 20 70 4c 69 73  ..  assert( pLis
18920 74 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70  t );.  assert( p
18930 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29  Wal->writeLock )
18940 3b 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53  ;..#if defined(S
18950 51 4c 49 54 45 5f 54 45 53 54 29 20 26 26 20 64  QLITE_TEST) && d
18960 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45  efined(SQLITE_DE
18970 42 55 47 29 0a 20 20 7b 20 69 6e 74 20 63 6e 74  BUG).  { int cnt
18980 3b 20 66 6f 72 28 63 6e 74 3d 30 2c 20 70 3d 70  ; for(cnt=0, p=p
18990 4c 69 73 74 3b 20 70 3b 20 70 3d 70 2d 3e 70 44  List; p; p=p->pD
189a0 69 72 74 79 2c 20 63 6e 74 2b 2b 29 7b 7d 0a 20  irty, cnt++){}. 
189b0 20 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41     WALTRACE(("WA
189c0 4c 25 70 3a 20 66 72 61 6d 65 20 77 72 69 74 65  L%p: frame write
189d0 20 62 65 67 69 6e 2e 20 25 64 20 66 72 61 6d 65   begin. %d frame
189e0 73 2e 20 6d 78 46 72 61 6d 65 3d 25 64 2e 20 25  s. mxFrame=%d. %
189f0 73 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 20 20  s\n",.          
18a00 20 20 20 20 70 57 61 6c 2c 20 63 6e 74 2c 20 70      pWal, cnt, p
18a10 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
18a20 2c 20 69 73 43 6f 6d 6d 69 74 20 3f 20 22 43 6f  , isCommit ? "Co
18a30 6d 6d 69 74 22 20 3a 20 22 53 70 69 6c 6c 22 29  mmit" : "Spill")
18a40 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20  );.  }.#endif.. 
18a50 20 2f 2a 20 53 65 65 20 69 66 20 69 74 20 69 73   /* See if it is
18a60 20 70 6f 73 73 69 62 6c 65 20 74 6f 20 77 72 69   possible to wri
18a70 74 65 20 74 68 65 73 65 20 66 72 61 6d 65 73 20  te these frames 
18a80 69 6e 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f  into the start o
18a90 66 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 67 20 66  f the.  ** log f
18aa0 69 6c 65 2c 20 69 6e 73 74 65 61 64 20 6f 66 20  ile, instead of 
18ab0 61 70 70 65 6e 64 69 6e 67 20 74 6f 20 69 74 20  appending to it 
18ac0 61 74 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  at pWal->hdr.mxF
18ad0 72 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  rame..  */.  if(
18ae0 20 53 51 4c 49 54 45 5f 4f 4b 21 3d 28 72 63 20   SQLITE_OK!=(rc 
18af0 3d 20 77 61 6c 52 65 73 74 61 72 74 4c 6f 67 28  = walRestartLog(
18b00 70 57 61 6c 29 29 20 29 7b 0a 20 20 20 20 72 65  pWal)) ){.    re
18b10 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20  turn rc;.  }..  
18b20 2f 2a 20 49 66 20 74 68 69 73 20 69 73 20 74 68  /* If this is th
18b30 65 20 66 69 72 73 74 20 66 72 61 6d 65 20 77 72  e first frame wr
18b40 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65 20 6c  itten into the l
18b50 6f 67 2c 20 77 72 69 74 65 20 74 68 65 20 57 41  og, write the WA
18b60 4c 0a 20 20 2a 2a 20 68 65 61 64 65 72 20 74 6f  L.  ** header to
18b70 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
18b80 65 20 57 41 4c 20 66 69 6c 65 2e 20 53 65 65 20  e WAL file. See 
18b90 63 6f 6d 6d 65 6e 74 73 20 61 74 20 74 68 65 20  comments at the 
18ba0 74 6f 70 20 6f 66 0a 20 20 2a 2a 20 74 68 69 73  top of.  ** this
18bb0 20 73 6f 75 72 63 65 20 66 69 6c 65 20 66 6f 72   source file for
18bc0 20 61 20 64 65 73 63 72 69 70 74 69 6f 6e 20 6f   a description o
18bd0 66 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72  f the WAL header
18be0 20 66 6f 72 6d 61 74 2e 0a 20 20 2a 2f 0a 20 20   format..  */.  
18bf0 69 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68  iFrame = pWal->h
18c00 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 69 66  dr.mxFrame;.  if
18c10 28 20 69 46 72 61 6d 65 3d 3d 30 20 29 7b 0a 20  ( iFrame==0 ){. 
18c20 20 20 20 75 38 20 61 57 61 6c 48 64 72 5b 57 41     u8 aWalHdr[WA
18c30 4c 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20 20 20  L_HDRSIZE];     
18c40 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 61 73   /* Buffer to as
18c50 73 65 6d 62 6c 65 20 77 61 6c 2d 68 65 61 64 65  semble wal-heade
18c60 72 20 69 6e 20 2a 2f 0a 20 20 20 20 75 33 32 20  r in */.    u32 
18c70 61 43 6b 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20  aCksum[2];      
18c80 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65            /* Che
18c90 63 6b 73 75 6d 20 66 6f 72 20 77 61 6c 2d 68 65  cksum for wal-he
18ca0 61 64 65 72 20 2a 2f 0a 0a 20 20 20 20 73 71 6c  ader */..    sql
18cb0 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57  ite3Put4byte(&aW
18cc0 61 6c 48 64 72 5b 30 5d 2c 20 28 57 41 4c 5f 4d  alHdr[0], (WAL_M
18cd0 41 47 49 43 20 7c 20 53 51 4c 49 54 45 5f 42 49  AGIC | SQLITE_BI
18ce0 47 45 4e 44 49 41 4e 29 29 3b 0a 20 20 20 20 73  GENDIAN));.    s
18cf0 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
18d00 61 57 61 6c 48 64 72 5b 34 5d 2c 20 57 41 4c 5f  aWalHdr[4], WAL_
18d10 4d 41 58 5f 56 45 52 53 49 4f 4e 29 3b 0a 20 20  MAX_VERSION);.  
18d20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74    sqlite3Put4byt
18d30 65 28 26 61 57 61 6c 48 64 72 5b 38 5d 2c 20 73  e(&aWalHdr[8], s
18d40 7a 50 61 67 65 29 3b 0a 20 20 20 20 73 71 6c 69  zPage);.    sqli
18d50 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61  te3Put4byte(&aWa
18d60 6c 48 64 72 5b 31 32 5d 2c 20 70 57 61 6c 2d 3e  lHdr[12], pWal->
18d70 6e 43 6b 70 74 29 3b 0a 20 20 20 20 73 71 6c 69  nCkpt);.    sqli
18d80 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 38  te3_randomness(8
18d90 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c  , pWal->hdr.aSal
18da0 74 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26  t);.    memcpy(&
18db0 61 57 61 6c 48 64 72 5b 31 36 5d 2c 20 70 57 61  aWalHdr[16], pWa
18dc0 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 38 29  l->hdr.aSalt, 8)
18dd0 3b 0a 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75  ;.    walChecksu
18de0 6d 42 79 74 65 73 28 31 2c 20 61 57 61 6c 48 64  mBytes(1, aWalHd
18df0 72 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2d 32  r, WAL_HDRSIZE-2
18e00 2a 34 2c 20 30 2c 20 61 43 6b 73 75 6d 29 3b 0a  *4, 0, aCksum);.
18e10 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34 62      sqlite3Put4b
18e20 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32 34 5d  yte(&aWalHdr[24]
18e30 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b 0a 20 20  , aCksum[0]);.  
18e40 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74    sqlite3Put4byt
18e50 65 28 26 61 57 61 6c 48 64 72 5b 32 38 5d 2c 20  e(&aWalHdr[28], 
18e60 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 20 20 20 20  aCksum[1]);.    
18e70 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50 61 67  .    pWal->szPag
18e80 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20  e = szPage;.    
18e90 70 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64  pWal->hdr.bigEnd
18ea0 43 6b 73 75 6d 20 3d 20 53 51 4c 49 54 45 5f 42  Cksum = SQLITE_B
18eb0 49 47 45 4e 44 49 41 4e 3b 0a 20 20 20 20 70 57  IGENDIAN;.    pW
18ec0 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
18ed0 73 75 6d 5b 30 5d 20 3d 20 61 43 6b 73 75 6d 5b  sum[0] = aCksum[
18ee0 30 5d 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64  0];.    pWal->hd
18ef0 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d  r.aFrameCksum[1]
18f00 20 3d 20 61 43 6b 73 75 6d 5b 31 5d 3b 0a 0a 20   = aCksum[1];.. 
18f10 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
18f20 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 57 61  sWrite(pWal->pWa
18f30 6c 46 64 2c 20 61 57 61 6c 48 64 72 2c 20 73 69  lFd, aWalHdr, si
18f40 7a 65 6f 66 28 61 57 61 6c 48 64 72 29 2c 20 30  zeof(aWalHdr), 0
18f50 29 3b 0a 20 20 20 20 57 41 4c 54 52 41 43 45 28  );.    WALTRACE(
18f60 28 22 57 41 4c 25 70 3a 20 77 61 6c 2d 68 65 61  ("WAL%p: wal-hea
18f70 64 65 72 20 77 72 69 74 65 20 25 73 5c 6e 22 2c  der write %s\n",
18f80 20 70 57 61 6c 2c 20 72 63 20 3f 20 22 66 61 69   pWal, rc ? "fai
18f90 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
18fa0 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
18fb0 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65  E_OK ){.      re
18fc0 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20  turn rc;.    }. 
18fd0 20 7d 0a 20 20 61 73 73 65 72 74 28 20 28 69 6e   }.  assert( (in
18fe0 74 29 70 57 61 6c 2d 3e 73 7a 50 61 67 65 3d 3d  t)pWal->szPage==
18ff0 73 7a 50 61 67 65 20 29 3b 0a 0a 20 20 2f 2a 20  szPage );..  /* 
19000 57 72 69 74 65 20 74 68 65 20 6c 6f 67 20 66 69  Write the log fi
19010 6c 65 2e 20 2a 2f 0a 20 20 66 6f 72 28 70 3d 70  le. */.  for(p=p
19020 4c 69 73 74 3b 20 70 3b 20 70 3d 70 2d 3e 70 44  List; p; p=p->pD
19030 69 72 74 79 29 7b 0a 20 20 20 20 75 33 32 20 6e  irty){.    u32 n
19040 44 62 73 69 7a 65 3b 20 20 20 20 20 20 20 20 20  Dbsize;         
19050 20 20 20 20 20 20 20 20 20 2f 2a 20 44 62 2d 73           /* Db-s
19060 69 7a 65 20 66 69 65 6c 64 20 66 6f 72 20 66 72  ize field for fr
19070 61 6d 65 20 68 65 61 64 65 72 20 2a 2f 0a 20 20  ame header */.  
19080 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 20 20    i64 iOffset;  
19090 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
190a0 2f 2a 20 57 72 69 74 65 20 6f 66 66 73 65 74 20  /* Write offset 
190b0 69 6e 20 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a 20  in log file */. 
190c0 20 20 20 76 6f 69 64 20 2a 70 44 61 74 61 3b 0a     void *pData;.
190d0 20 20 20 0a 20 20 20 20 69 4f 66 66 73 65 74 20     .    iOffset 
190e0 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74  = walFrameOffset
190f0 28 2b 2b 69 46 72 61 6d 65 2c 20 73 7a 50 61 67  (++iFrame, szPag
19100 65 29 3b 0a 20 20 20 20 2f 2a 20 74 65 73 74 63  e);.    /* testc
19110 61 73 65 28 20 49 53 5f 42 49 47 5f 49 4e 54 28  ase( IS_BIG_INT(
19120 69 4f 66 66 73 65 74 29 20 29 3b 20 2f 2f 20 72  iOffset) ); // r
19130 65 71 75 69 72 65 73 20 61 20 34 47 69 42 20 57  equires a 4GiB W
19140 41 4c 20 2a 2f 0a 20 20 20 20 0a 20 20 20 20 2f  AL */.    .    /
19150 2a 20 50 6f 70 75 6c 61 74 65 20 61 6e 64 20 77  * Populate and w
19160 72 69 74 65 20 74 68 65 20 66 72 61 6d 65 20 68  rite the frame h
19170 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 6e 44 62  eader */.    nDb
19180 73 69 7a 65 20 3d 20 28 69 73 43 6f 6d 6d 69 74  size = (isCommit
19190 20 26 26 20 70 2d 3e 70 44 69 72 74 79 3d 3d 30   && p->pDirty==0
191a0 29 20 3f 20 6e 54 72 75 6e 63 61 74 65 20 3a 20  ) ? nTruncate : 
191b0 30 3b 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53  0;.#if defined(S
191c0 51 4c 49 54 45 5f 48 41 53 5f 43 4f 44 45 43 29  QLITE_HAS_CODEC)
191d0 0a 20 20 20 20 69 66 28 20 28 70 44 61 74 61 20  .    if( (pData 
191e0 3d 20 73 71 6c 69 74 65 33 50 61 67 65 72 43 6f  = sqlite3PagerCo
191f0 64 65 63 28 70 29 29 3d 3d 30 20 29 20 72 65 74  dec(p))==0 ) ret
19200 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
19210 3b 0a 23 65 6c 73 65 0a 20 20 20 20 70 44 61 74  ;.#else.    pDat
19220 61 20 3d 20 70 2d 3e 70 44 61 74 61 3b 0a 23 65  a = p->pData;.#e
19230 6e 64 69 66 0a 20 20 20 20 77 61 6c 45 6e 63 6f  ndif.    walEnco
19240 64 65 46 72 61 6d 65 28 70 57 61 6c 2c 20 70 2d  deFrame(pWal, p-
19250 3e 70 67 6e 6f 2c 20 6e 44 62 73 69 7a 65 2c 20  >pgno, nDbsize, 
19260 70 44 61 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a  pData, aFrame);.
19270 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
19280 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 57  OsWrite(pWal->pW
19290 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20 73 69  alFd, aFrame, si
192a0 7a 65 6f 66 28 61 46 72 61 6d 65 29 2c 20 69 4f  zeof(aFrame), iO
192b0 66 66 73 65 74 29 3b 0a 20 20 20 20 69 66 28 20  ffset);.    if( 
192c0 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
192d0 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63  .      return rc
192e0 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
192f0 57 72 69 74 65 20 74 68 65 20 70 61 67 65 20 64  Write the page d
19300 61 74 61 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20  ata */.    rc = 
19310 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70  sqlite3OsWrite(p
19320 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 70 44 61  Wal->pWalFd, pDa
19330 74 61 2c 20 73 7a 50 61 67 65 2c 20 69 4f 66 66  ta, szPage, iOff
19340 73 65 74 2b 73 69 7a 65 6f 66 28 61 46 72 61 6d  set+sizeof(aFram
19350 65 29 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21  e));.    if( rc!
19360 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
19370 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
19380 20 20 20 7d 0a 20 20 20 20 70 4c 61 73 74 20 3d     }.    pLast =
19390 20 70 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 79   p;.  }..  /* Sy
193a0 6e 63 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 20  nc the log file 
193b0 69 66 20 74 68 65 20 27 69 73 53 79 6e 63 27 20  if the 'isSync' 
193c0 66 6c 61 67 20 77 61 73 20 73 70 65 63 69 66 69  flag was specifi
193d0 65 64 2e 20 2a 2f 0a 20 20 69 66 28 20 73 79 6e  ed. */.  if( syn
193e0 63 5f 66 6c 61 67 73 20 29 7b 0a 20 20 20 20 69  c_flags ){.    i
193f0 36 34 20 69 53 65 67 6d 65 6e 74 20 3d 20 73 71  64 iSegment = sq
19400 6c 69 74 65 33 4f 73 53 65 63 74 6f 72 53 69 7a  lite3OsSectorSiz
19410 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 29 3b  e(pWal->pWalFd);
19420 0a 20 20 20 20 69 36 34 20 69 4f 66 66 73 65 74  .    i64 iOffset
19430 20 3d 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65   = walFrameOffse
19440 74 28 69 46 72 61 6d 65 2b 31 2c 20 73 7a 50 61  t(iFrame+1, szPa
19450 67 65 29 3b 0a 0a 20 20 20 20 61 73 73 65 72 74  ge);..    assert
19460 28 20 69 73 43 6f 6d 6d 69 74 20 29 3b 0a 20 20  ( isCommit );.  
19470 20 20 61 73 73 65 72 74 28 20 69 53 65 67 6d 65    assert( iSegme
19480 6e 74 3e 30 20 29 3b 0a 0a 20 20 20 20 69 53 65  nt>0 );..    iSe
19490 67 6d 65 6e 74 20 3d 20 28 28 28 69 4f 66 66 73  gment = (((iOffs
194a0 65 74 2b 69 53 65 67 6d 65 6e 74 2d 31 29 2f 69  et+iSegment-1)/i
194b0 53 65 67 6d 65 6e 74 29 20 2a 20 69 53 65 67 6d  Segment) * iSegm
194c0 65 6e 74 29 3b 0a 20 20 20 20 77 68 69 6c 65 28  ent);.    while(
194d0 20 69 4f 66 66 73 65 74 3c 69 53 65 67 6d 65 6e   iOffset<iSegmen
194e0 74 20 29 7b 0a 20 20 20 20 20 20 76 6f 69 64 20  t ){.      void 
194f0 2a 70 44 61 74 61 3b 0a 23 69 66 20 64 65 66 69  *pData;.#if defi
19500 6e 65 64 28 53 51 4c 49 54 45 5f 48 41 53 5f 43  ned(SQLITE_HAS_C
19510 4f 44 45 43 29 0a 20 20 20 20 20 20 69 66 28 20  ODEC).      if( 
19520 28 70 44 61 74 61 20 3d 20 73 71 6c 69 74 65 33  (pData = sqlite3
19530 50 61 67 65 72 43 6f 64 65 63 28 70 4c 61 73 74  PagerCodec(pLast
19540 29 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  ))==0 ) return S
19550 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 23 65 6c  QLITE_NOMEM;.#el
19560 73 65 0a 20 20 20 20 20 20 70 44 61 74 61 20 3d  se.      pData =
19570 20 70 4c 61 73 74 2d 3e 70 44 61 74 61 3b 0a 23   pLast->pData;.#
19580 65 6e 64 69 66 0a 20 20 20 20 20 20 77 61 6c 45  endif.      walE
19590 6e 63 6f 64 65 46 72 61 6d 65 28 70 57 61 6c 2c  ncodeFrame(pWal,
195a0 20 70 4c 61 73 74 2d 3e 70 67 6e 6f 2c 20 6e 54   pLast->pgno, nT
195b0 72 75 6e 63 61 74 65 2c 20 70 44 61 74 61 2c 20  runcate, pData, 
195c0 61 46 72 61 6d 65 29 3b 0a 20 20 20 20 20 20 2f  aFrame);.      /
195d0 2a 20 74 65 73 74 63 61 73 65 28 20 49 53 5f 42  * testcase( IS_B
195e0 49 47 5f 49 4e 54 28 69 4f 66 66 73 65 74 29 20  IG_INT(iOffset) 
195f0 29 3b 20 2f 2f 20 72 65 71 75 69 72 65 73 20 61  ); // requires a
19600 20 34 47 69 42 20 57 41 4c 20 2a 2f 0a 20 20 20   4GiB WAL */.   
19610 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
19620 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 57 61  sWrite(pWal->pWa
19630 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20 73 69 7a  lFd, aFrame, siz
19640 65 6f 66 28 61 46 72 61 6d 65 29 2c 20 69 4f 66  eof(aFrame), iOf
19650 66 73 65 74 29 3b 0a 20 20 20 20 20 20 69 66 28  fset);.      if(
19660 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
19670 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  {.        return
19680 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20   rc;.      }.   
19690 20 20 20 69 4f 66 66 73 65 74 20 2b 3d 20 57 41     iOffset += WA
196a0 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3b  L_FRAME_HDRSIZE;
196b0 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
196c0 74 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d  te3OsWrite(pWal-
196d0 3e 70 57 61 6c 46 64 2c 20 70 44 61 74 61 2c 20  >pWalFd, pData, 
196e0 73 7a 50 61 67 65 2c 20 69 4f 66 66 73 65 74 29  szPage, iOffset)
196f0 3b 20 0a 20 20 20 20 20 20 69 66 28 20 72 63 21  ; .      if( rc!
19700 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
19710 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
19720 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 6e  .      }.      n
19730 4c 61 73 74 2b 2b 3b 0a 20 20 20 20 20 20 69 4f  Last++;.      iO
19740 66 66 73 65 74 20 2b 3d 20 73 7a 50 61 67 65 3b  ffset += szPage;
19750 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 63 20 3d  .    }..    rc =
19760 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 70   sqlite3OsSync(p
19770 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 73 79 6e  Wal->pWalFd, syn
19780 63 5f 66 6c 61 67 73 29 3b 0a 20 20 7d 0a 0a 20  c_flags);.  }.. 
19790 20 2f 2a 20 41 70 70 65 6e 64 20 64 61 74 61 20   /* Append data 
197a0 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  to the wal-index
197b0 2e 20 49 74 20 69 73 20 6e 6f 74 20 6e 65 63 65  . It is not nece
197c0 73 73 61 72 79 20 74 6f 20 6c 6f 63 6b 20 74 68  ssary to lock th
197d0 65 20 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65  e .  ** wal-inde
197e0 78 20 74 6f 20 64 6f 20 74 68 69 73 20 61 73 20  x to do this as 
197f0 74 68 65 20 53 51 4c 49 54 45 5f 53 48 4d 5f 57  the SQLITE_SHM_W
19800 52 49 54 45 20 6c 6f 63 6b 20 68 65 6c 64 20 6f  RITE lock held o
19810 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a  n the wal-index.
19820 20 20 2a 2a 20 67 75 61 72 61 6e 74 65 65 73 20    ** guarantees 
19830 74 68 61 74 20 74 68 65 72 65 20 61 72 65 20 6e  that there are n
19840 6f 20 6f 74 68 65 72 20 77 72 69 74 65 72 73 2c  o other writers,
19850 20 61 6e 64 20 6e 6f 20 64 61 74 61 20 74 68 61   and no data tha
19860 74 20 6d 61 79 0a 20 20 2a 2a 20 62 65 20 69 6e  t may.  ** be in
19870 20 75 73 65 20 62 79 20 65 78 69 73 74 69 6e 67   use by existing
19880 20 72 65 61 64 65 72 73 20 69 73 20 62 65 69 6e   readers is bein
19890 67 20 6f 76 65 72 77 72 69 74 74 65 6e 2e 0a 20  g overwritten.. 
198a0 20 2a 2f 0a 20 20 69 46 72 61 6d 65 20 3d 20 70   */.  iFrame = p
198b0 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
198c0 3b 0a 20 20 66 6f 72 28 70 3d 70 4c 69 73 74 3b  ;.  for(p=pList;
198d0 20 70 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45   p && rc==SQLITE
198e0 5f 4f 4b 3b 20 70 3d 70 2d 3e 70 44 69 72 74 79  _OK; p=p->pDirty
198f0 29 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b 2b 3b  ){.    iFrame++;
19900 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64  .    rc = walInd
19910 65 78 41 70 70 65 6e 64 28 70 57 61 6c 2c 20 69  exAppend(pWal, i
19920 46 72 61 6d 65 2c 20 70 2d 3e 70 67 6e 6f 29 3b  Frame, p->pgno);
19930 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 6e 4c  .  }.  while( nL
19940 61 73 74 3e 30 20 26 26 20 72 63 3d 3d 53 51 4c  ast>0 && rc==SQL
19950 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 46  ITE_OK ){.    iF
19960 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 6e 4c 61 73  rame++;.    nLas
19970 74 2d 2d 3b 0a 20 20 20 20 72 63 20 3d 20 77 61  t--;.    rc = wa
19980 6c 49 6e 64 65 78 41 70 70 65 6e 64 28 70 57 61  lIndexAppend(pWa
19990 6c 2c 20 69 46 72 61 6d 65 2c 20 70 4c 61 73 74  l, iFrame, pLast
199a0 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 0a 20 20  ->pgno);.  }..  
199b0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
199c0 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 55 70 64 61  K ){.    /* Upda
199d0 74 65 20 74 68 65 20 70 72 69 76 61 74 65 20 63  te the private c
199e0 6f 70 79 20 6f 66 20 74 68 65 20 68 65 61 64 65  opy of the heade
199f0 72 2e 20 2a 2f 0a 20 20 20 20 70 57 61 6c 2d 3e  r. */.    pWal->
19a00 68 64 72 2e 73 7a 50 61 67 65 20 3d 20 28 75 31  hdr.szPage = (u1
19a10 36 29 28 28 73 7a 50 61 67 65 26 30 78 66 66 30  6)((szPage&0xff0
19a20 30 29 20 7c 20 28 73 7a 50 61 67 65 3e 3e 31 36  0) | (szPage>>16
19a30 29 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73 65  ));.    testcase
19a40 28 20 73 7a 50 61 67 65 3c 3d 33 32 37 36 38 20  ( szPage<=32768 
19a50 29 3b 0a 20 20 20 20 74 65 73 74 63 61 73 65 28  );.    testcase(
19a60 20 73 7a 50 61 67 65 3e 3d 36 35 35 33 36 20 29   szPage>=65536 )
19a70 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  ;.    pWal->hdr.
19a80 6d 78 46 72 61 6d 65 20 3d 20 69 46 72 61 6d 65  mxFrame = iFrame
19a90 3b 0a 20 20 20 20 69 66 28 20 69 73 43 6f 6d 6d  ;.    if( isComm
19aa0 69 74 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c  it ){.      pWal
19ab0 2d 3e 68 64 72 2e 69 43 68 61 6e 67 65 2b 2b 3b  ->hdr.iChange++;
19ac0 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  .      pWal->hdr
19ad0 2e 6e 50 61 67 65 20 3d 20 6e 54 72 75 6e 63 61  .nPage = nTrunca
19ae0 74 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2f 2a  te;.    }.    /*
19af0 20 49 66 20 74 68 69 73 20 69 73 20 61 20 63 6f   If this is a co
19b00 6d 6d 69 74 2c 20 75 70 64 61 74 65 20 74 68 65  mmit, update the
19b10 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
19b20 72 20 74 6f 6f 2e 20 2a 2f 0a 20 20 20 20 69 66  r too. */.    if
19b30 28 20 69 73 43 6f 6d 6d 69 74 20 29 7b 0a 20 20  ( isCommit ){.  
19b40 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72 69 74      walIndexWrit
19b50 65 48 64 72 28 70 57 61 6c 29 3b 0a 20 20 20 20  eHdr(pWal);.    
19b60 20 20 70 57 61 6c 2d 3e 69 43 61 6c 6c 62 61 63    pWal->iCallbac
19b70 6b 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20 20  k = iFrame;.    
19b80 7d 0a 20 20 7d 0a 0a 20 20 57 41 4c 54 52 41 43  }.  }..  WALTRAC
19b90 45 28 28 22 57 41 4c 25 70 3a 20 66 72 61 6d 65  E(("WAL%p: frame
19ba0 20 77 72 69 74 65 20 25 73 5c 6e 22 2c 20 70 57   write %s\n", pW
19bb0 61 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64  al, rc ? "failed
19bc0 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 72 65  " : "ok"));.  re
19bd0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a  turn rc;.}../* .
19be0 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
19bf0 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 69 6d 70  is called to imp
19c00 6c 65 6d 65 6e 74 20 73 71 6c 69 74 65 33 5f 77  lement sqlite3_w
19c10 61 6c 5f 63 68 65 63 6b 70 6f 69 6e 74 28 29 20  al_checkpoint() 
19c20 61 6e 64 0a 2a 2a 20 72 65 6c 61 74 65 64 20 69  and.** related i
19c30 6e 74 65 72 66 61 63 65 73 2e 0a 2a 2a 0a 2a 2a  nterfaces..**.**
19c40 20 4f 62 74 61 69 6e 20 61 20 43 48 45 43 4b 50   Obtain a CHECKP
19c50 4f 49 4e 54 20 6c 6f 63 6b 20 61 6e 64 20 74 68  OINT lock and th
19c60 65 6e 20 62 61 63 6b 66 69 6c 6c 20 61 73 20 6d  en backfill as m
19c70 75 63 68 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  uch information 
19c80 61 73 0a 2a 2a 20 77 65 20 63 61 6e 20 66 72 6f  as.** we can fro
19c90 6d 20 57 41 4c 20 69 6e 74 6f 20 74 68 65 20 64  m WAL into the d
19ca0 61 74 61 62 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 49  atabase..**.** I
19cb0 66 20 70 61 72 61 6d 65 74 65 72 20 78 42 75 73  f parameter xBus
19cc0 79 20 69 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 69  y is not NULL, i
19cd0 74 20 69 73 20 61 20 70 6f 69 6e 74 65 72 20 74  t is a pointer t
19ce0 6f 20 61 20 62 75 73 79 2d 68 61 6e 64 6c 65 72  o a busy-handler
19cf0 0a 2a 2a 20 63 61 6c 6c 62 61 63 6b 2e 20 49 6e  .** callback. In
19d00 20 74 68 69 73 20 63 61 73 65 20 74 68 69 73 20   this case this 
19d10 66 75 6e 63 74 69 6f 6e 20 72 75 6e 73 20 61 20  function runs a 
19d20 62 6c 6f 63 6b 69 6e 67 20 63 68 65 63 6b 70 6f  blocking checkpo
19d30 69 6e 74 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  int..*/.int sqli
19d40 74 65 33 57 61 6c 43 68 65 63 6b 70 6f 69 6e 74  te3WalCheckpoint
19d50 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20  (.  Wal *pWal,  
19d60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19d70 20 20 20 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65      /* Wal conne
19d80 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 65  ction */.  int e
19d90 4d 6f 64 65 2c 20 20 20 20 20 20 20 20 20 20 20  Mode,           
19da0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 41             /* PA
19db0 53 53 49 56 45 2c 20 46 55 4c 4c 20 6f 72 20 52  SSIVE, FULL or R
19dc0 45 53 54 41 52 54 20 2a 2f 0a 20 20 69 6e 74 20  ESTART */.  int 
19dd0 28 2a 78 42 75 73 79 29 28 76 6f 69 64 2a 29 2c  (*xBusy)(void*),
19de0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
19df0 75 6e 63 74 69 6f 6e 20 74 6f 20 63 61 6c 6c 20  unction to call 
19e00 77 68 65 6e 20 62 75 73 79 20 2a 2f 0a 20 20 76  when busy */.  v
19e10 6f 69 64 20 2a 70 42 75 73 79 41 72 67 2c 20 20  oid *pBusyArg,  
19e20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
19e30 2a 20 43 6f 6e 74 65 78 74 20 61 72 67 75 6d 65  * Context argume
19e40 6e 74 20 66 6f 72 20 78 42 75 73 79 48 61 6e 64  nt for xBusyHand
19e50 6c 65 72 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e  ler */.  int syn
19e60 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20  c_flags,        
19e70 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67           /* Flag
19e80 73 20 74 6f 20 73 79 6e 63 20 64 62 20 66 69 6c  s to sync db fil
19e90 65 20 77 69 74 68 20 28 6f 72 20 30 29 20 2a 2f  e with (or 0) */
19ea0 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20 20  .  int nBuf,    
19eb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19ec0 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74 65     /* Size of te
19ed0 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72 20 2a  mporary buffer *
19ee0 2f 0a 20 20 75 38 20 2a 7a 42 75 66 2c 20 20 20  /.  u8 *zBuf,   
19ef0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19f00 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79      /* Temporary
19f10 20 62 75 66 66 65 72 20 74 6f 20 75 73 65 20 2a   buffer to use *
19f20 2f 0a 20 20 69 6e 74 20 2a 70 6e 4c 6f 67 2c 20  /.  int *pnLog, 
19f30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
19f40 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 75 6d 62      /* OUT: Numb
19f50 65 72 20 6f 66 20 66 72 61 6d 65 73 20 69 6e 20  er of frames in 
19f60 57 41 4c 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e  WAL */.  int *pn
19f70 43 6b 70 74 20 20 20 20 20 20 20 20 20 20 20 20  Ckpt            
19f80 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
19f90 20 4e 75 6d 62 65 72 20 6f 66 20 62 61 63 6b 66   Number of backf
19fa0 69 6c 6c 65 64 20 66 72 61 6d 65 73 20 69 6e 20  illed frames in 
19fb0 57 41 4c 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  WAL */.){.  int 
19fc0 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
19fd0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
19fe0 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
19ff0 69 6e 74 20 69 73 43 68 61 6e 67 65 64 20 3d 20  int isChanged = 
1a000 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
1a010 2f 2a 20 54 72 75 65 20 69 66 20 61 20 6e 65 77  /* True if a new
1a020 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
1a030 72 20 69 73 20 6c 6f 61 64 65 64 20 2a 2f 0a 20  r is loaded */. 
1a040 20 69 6e 74 20 65 4d 6f 64 65 32 20 3d 20 65 4d   int eMode2 = eM
1a050 6f 64 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ode;            
1a060 20 2f 2a 20 4d 6f 64 65 20 74 6f 20 70 61 73 73   /* Mode to pass
1a070 20 74 6f 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e   to walCheckpoin
1a080 74 28 29 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  t() */..  assert
1a090 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b  ( pWal->ckptLock
1a0a0 3d 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28  ==0 );.  assert(
1a0b0 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
1a0c0 3d 3d 30 20 29 3b 0a 0a 20 20 69 66 28 20 70 57  ==0 );..  if( pW
1a0d0 61 6c 2d 3e 72 65 61 64 4f 6e 6c 79 20 29 20 72  al->readOnly ) r
1a0e0 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 52 45 41  eturn SQLITE_REA
1a0f0 44 4f 4e 4c 59 3b 0a 20 20 57 41 4c 54 52 41 43  DONLY;.  WALTRAC
1a100 45 28 28 22 57 41 4c 25 70 3a 20 63 68 65 63 6b  E(("WAL%p: check
1a110 70 6f 69 6e 74 20 62 65 67 69 6e 73 5c 6e 22 2c  point begins\n",
1a120 20 70 57 61 6c 29 29 3b 0a 20 20 72 63 20 3d 20   pWal));.  rc = 
1a130 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65  walLockExclusive
1a140 28 70 57 61 6c 2c 20 57 41 4c 5f 43 4b 50 54 5f  (pWal, WAL_CKPT_
1a150 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 69 66 28 20  LOCK, 1);.  if( 
1a160 72 63 20 29 7b 0a 20 20 20 20 2f 2a 20 55 73 75  rc ){.    /* Usu
1a170 61 6c 6c 79 20 74 68 69 73 20 69 73 20 53 51 4c  ally this is SQL
1a180 49 54 45 5f 42 55 53 59 20 6d 65 61 6e 69 6e 67  ITE_BUSY meaning
1a190 20 74 68 61 74 20 61 6e 6f 74 68 65 72 20 74 68   that another th
1a1a0 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 0a  read or process.
1a1b0 20 20 20 20 2a 2a 20 69 73 20 61 6c 72 65 61 64      ** is alread
1a1c0 79 20 72 75 6e 6e 69 6e 67 20 61 20 63 68 65 63  y running a chec
1a1d0 6b 70 6f 69 6e 74 2c 20 6f 72 20 6d 61 79 62 65  kpoint, or maybe
1a1e0 20 61 20 72 65 63 6f 76 65 72 79 2e 20 20 42 75   a recovery.  Bu
1a1f0 74 20 69 74 20 6d 69 67 68 74 0a 20 20 20 20 2a  t it might.    *
1a200 2a 20 61 6c 73 6f 20 62 65 20 53 51 4c 49 54 45  * also be SQLITE
1a210 5f 49 4f 45 52 52 2e 20 2a 2f 0a 20 20 20 20 72  _IOERR. */.    r
1a220 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20  eturn rc;.  }.  
1a230 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20 3d  pWal->ckptLock =
1a240 20 31 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 69   1;..  /* If thi
1a250 73 20 69 73 20 61 20 62 6c 6f 63 6b 69 6e 67 2d  s is a blocking-
1a260 63 68 65 63 6b 70 6f 69 6e 74 2c 20 74 68 65 6e  checkpoint, then
1a270 20 6f 62 74 61 69 6e 20 74 68 65 20 77 72 69 74   obtain the writ
1a280 65 2d 6c 6f 63 6b 20 61 73 20 77 65 6c 6c 0a 20  e-lock as well. 
1a290 20 2a 2a 20 74 6f 20 70 72 65 76 65 6e 74 20 61   ** to prevent a
1a2a0 6e 79 20 77 72 69 74 65 72 73 20 66 72 6f 6d 20  ny writers from 
1a2b0 72 75 6e 6e 69 6e 67 20 77 68 69 6c 65 20 74 68  running while th
1a2c0 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 69 73 20  e checkpoint is 
1a2d0 75 6e 64 65 72 77 61 79 2e 0a 20 20 2a 2a 20 54  underway..  ** T
1a2e0 68 69 73 20 68 61 73 20 74 6f 20 62 65 20 64 6f  his has to be do
1a2f0 6e 65 20 62 65 66 6f 72 65 20 74 68 65 20 63 61  ne before the ca
1a300 6c 6c 20 74 6f 20 77 61 6c 49 6e 64 65 78 52 65  ll to walIndexRe
1a310 61 64 48 64 72 28 29 20 62 65 6c 6f 77 2e 0a 20  adHdr() below.. 
1a320 20 2a 2a 0a 20 20 2a 2a 20 49 66 20 74 68 65 20   **.  ** If the 
1a330 77 72 69 74 65 72 20 6c 6f 63 6b 20 63 61 6e 6e  writer lock cann
1a340 6f 74 20 62 65 20 6f 62 74 61 69 6e 65 64 2c 20  ot be obtained, 
1a350 74 68 65 6e 20 61 20 70 61 73 73 69 76 65 20 63  then a passive c
1a360 68 65 63 6b 70 6f 69 6e 74 20 69 73 0a 20 20 2a  heckpoint is.  *
1a370 2a 20 72 75 6e 20 69 6e 73 74 65 61 64 2e 20 53  * run instead. S
1a380 69 6e 63 65 20 74 68 65 20 63 68 65 63 6b 70 6f  ince the checkpo
1a390 69 6e 74 65 72 20 69 73 20 6e 6f 74 20 68 6f 6c  inter is not hol
1a3a0 64 69 6e 67 20 74 68 65 20 77 72 69 74 65 72 20  ding the writer 
1a3b0 6c 6f 63 6b 2c 0a 20 20 2a 2a 20 74 68 65 72 65  lock,.  ** there
1a3c0 20 69 73 20 6e 6f 20 70 6f 69 6e 74 20 69 6e 20   is no point in 
1a3d0 62 6c 6f 63 6b 69 6e 67 20 77 61 69 74 69 6e 67  blocking waiting
1a3e0 20 66 6f 72 20 61 6e 79 20 72 65 61 64 65 72 73   for any readers
1a3f0 2e 20 41 73 73 75 6d 69 6e 67 20 6e 6f 20 0a 20  . Assuming no . 
1a400 20 2a 2a 20 6f 74 68 65 72 20 65 72 72 6f 72 20   ** other error 
1a410 6f 63 63 75 72 73 2c 20 74 68 69 73 20 66 75 6e  occurs, this fun
1a420 63 74 69 6f 6e 20 77 69 6c 6c 20 72 65 74 75 72  ction will retur
1a430 6e 20 53 51 4c 49 54 45 5f 42 55 53 59 20 74 6f  n SQLITE_BUSY to
1a440 20 74 68 65 20 63 61 6c 6c 65 72 2e 0a 20 20 2a   the caller..  *
1a450 2f 0a 20 20 69 66 28 20 65 4d 6f 64 65 21 3d 53  /.  if( eMode!=S
1a460 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e 54  QLITE_CHECKPOINT
1a470 5f 50 41 53 53 49 56 45 20 29 7b 0a 20 20 20 20  _PASSIVE ){.    
1a480 72 63 20 3d 20 77 61 6c 42 75 73 79 4c 6f 63 6b  rc = walBusyLock
1a490 28 70 57 61 6c 2c 20 78 42 75 73 79 2c 20 70 42  (pWal, xBusy, pB
1a4a0 75 73 79 41 72 67 2c 20 57 41 4c 5f 57 52 49 54  usyArg, WAL_WRIT
1a4b0 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 20 20  E_LOCK, 1);.    
1a4c0 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
1a4d0 4b 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d  K ){.      pWal-
1a4e0 3e 77 72 69 74 65 4c 6f 63 6b 20 3d 20 31 3b 0a  >writeLock = 1;.
1a4f0 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63      }else if( rc
1a500 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b  ==SQLITE_BUSY ){
1a510 0a 20 20 20 20 20 20 65 4d 6f 64 65 32 20 3d 20  .      eMode2 = 
1a520 53 51 4c 49 54 45 5f 43 48 45 43 4b 50 4f 49 4e  SQLITE_CHECKPOIN
1a530 54 5f 50 41 53 53 49 56 45 3b 0a 20 20 20 20 20  T_PASSIVE;.     
1a540 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
1a550 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
1a560 20 52 65 61 64 20 74 68 65 20 77 61 6c 2d 69 6e   Read the wal-in
1a570 64 65 78 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20  dex header. */. 
1a580 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
1a590 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 77  OK ){.    rc = w
1a5a0 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28 70  alIndexReadHdr(p
1a5b0 57 61 6c 2c 20 26 69 73 43 68 61 6e 67 65 64 29  Wal, &isChanged)
1a5c0 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 70 79  ;.  }..  /* Copy
1a5d0 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20 6c   data from the l
1a5e0 6f 67 20 74 6f 20 74 68 65 20 64 61 74 61 62 61  og to the databa
1a5f0 73 65 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 69 66  se file. */.  if
1a600 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1a610 29 7b 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d  ){.    if( pWal-
1a620 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 26 26 20  >hdr.mxFrame && 
1a630 77 61 6c 50 61 67 65 73 69 7a 65 28 70 57 61 6c  walPagesize(pWal
1a640 29 21 3d 6e 42 75 66 20 29 7b 0a 20 20 20 20 20  )!=nBuf ){.     
1a650 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43 4f 52   rc = SQLITE_COR
1a660 52 55 50 54 5f 42 4b 50 54 3b 0a 20 20 20 20 7d  RUPT_BKPT;.    }
1a670 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20 3d  else{.      rc =
1a680 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 70   walCheckpoint(p
1a690 57 61 6c 2c 20 65 4d 6f 64 65 32 2c 20 78 42 75  Wal, eMode2, xBu
1a6a0 73 79 2c 20 70 42 75 73 79 41 72 67 2c 20 73 79  sy, pBusyArg, sy
1a6b0 6e 63 5f 66 6c 61 67 73 2c 20 7a 42 75 66 29 3b  nc_flags, zBuf);
1a6c0 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49  .    }..    /* I
1a6d0 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63 75 72  f no error occur
1a6e0 72 65 64 2c 20 73 65 74 20 74 68 65 20 6f 75 74  red, set the out
1a6f0 70 75 74 20 76 61 72 69 61 62 6c 65 73 2e 20 2a  put variables. *
1a700 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  /.    if( rc==SQ
1a710 4c 49 54 45 5f 4f 4b 20 7c 7c 20 72 63 3d 3d 53  LITE_OK || rc==S
1a720 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20  QLITE_BUSY ){.  
1a730 20 20 20 20 69 66 28 20 70 6e 4c 6f 67 20 29 20      if( pnLog ) 
1a740 2a 70 6e 4c 6f 67 20 3d 20 28 69 6e 74 29 70 57  *pnLog = (int)pW
1a750 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b  al->hdr.mxFrame;
1a760 0a 20 20 20 20 20 20 69 66 28 20 70 6e 43 6b 70  .      if( pnCkp
1a770 74 20 29 20 2a 70 6e 43 6b 70 74 20 3d 20 28 69  t ) *pnCkpt = (i
1a780 6e 74 29 28 77 61 6c 43 6b 70 74 49 6e 66 6f 28  nt)(walCkptInfo(
1a790 70 57 61 6c 29 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pWal)->nBackfill
1a7a0 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
1a7b0 69 66 28 20 69 73 43 68 61 6e 67 65 64 20 29 7b  if( isChanged ){
1a7c0 0a 20 20 20 20 2f 2a 20 49 66 20 61 20 6e 65 77  .    /* If a new
1a7d0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
1a7e0 72 20 77 61 73 20 6c 6f 61 64 65 64 20 62 65 66  r was loaded bef
1a7f0 6f 72 65 20 74 68 65 20 63 68 65 63 6b 70 6f 69  ore the checkpoi
1a800 6e 74 20 77 61 73 20 0a 20 20 20 20 2a 2a 20 70  nt was .    ** p
1a810 65 72 66 6f 72 6d 65 64 2c 20 74 68 65 6e 20 74  erformed, then t
1a820 68 65 20 70 61 67 65 72 2d 63 61 63 68 65 20 61  he pager-cache a
1a830 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 70  ssociated with p
1a840 57 61 6c 20 69 73 20 6e 6f 77 0a 20 20 20 20 2a  Wal is now.    *
1a850 2a 20 6f 75 74 20 6f 66 20 64 61 74 65 2e 20 53  * out of date. S
1a860 6f 20 7a 65 72 6f 20 74 68 65 20 63 61 63 68 65  o zero the cache
1a870 64 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  d wal-index head
1a880 65 72 20 74 6f 20 65 6e 73 75 72 65 20 74 68 61  er to ensure tha
1a890 74 0a 20 20 20 20 2a 2a 20 6e 65 78 74 20 74 69  t.    ** next ti
1a8a0 6d 65 20 74 68 65 20 70 61 67 65 72 20 6f 70 65  me the pager ope
1a8b0 6e 73 20 61 20 73 6e 61 70 73 68 6f 74 20 6f 6e  ns a snapshot on
1a8c0 20 74 68 69 73 20 64 61 74 61 62 61 73 65 20 69   this database i
1a8d0 74 20 6b 6e 6f 77 73 20 74 68 61 74 0a 20 20 20  t knows that.   
1a8e0 20 2a 2a 20 74 68 65 20 63 61 63 68 65 20 6e 65   ** the cache ne
1a8f0 65 64 73 20 74 6f 20 62 65 20 72 65 73 65 74 2e  eds to be reset.
1a900 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6d 65 6d 73  .    */.    mems
1a910 65 74 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 30  et(&pWal->hdr, 0
1a920 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65  , sizeof(WalInde
1a930 78 48 64 72 29 29 3b 0a 20 20 7d 0a 0a 20 20 2f  xHdr));.  }..  /
1a940 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20 6c 6f  * Release the lo
1a950 63 6b 73 2e 20 2a 2f 0a 20 20 73 71 6c 69 74 65  cks. */.  sqlite
1a960 33 57 61 6c 45 6e 64 57 72 69 74 65 54 72 61 6e  3WalEndWriteTran
1a970 73 61 63 74 69 6f 6e 28 70 57 61 6c 29 3b 0a 20  saction(pWal);. 
1a980 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
1a990 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 43 4b  ive(pWal, WAL_CK
1a9a0 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 70  PT_LOCK, 1);.  p
1a9b0 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20 3d 20  Wal->ckptLock = 
1a9c0 30 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  0;.  WALTRACE(("
1a9d0 57 41 4c 25 70 3a 20 63 68 65 63 6b 70 6f 69 6e  WAL%p: checkpoin
1a9e0 74 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  t %s\n", pWal, r
1a9f0 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
1aa00 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75 72 6e 20  ok"));.  return 
1aa10 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26  (rc==SQLITE_OK &
1aa20 26 20 65 4d 6f 64 65 21 3d 65 4d 6f 64 65 32 20  & eMode!=eMode2 
1aa30 3f 20 53 51 4c 49 54 45 5f 42 55 53 59 20 3a 20  ? SQLITE_BUSY : 
1aa40 72 63 29 3b 0a 7d 0a 0a 2f 2a 20 52 65 74 75 72  rc);.}../* Retur
1aa50 6e 20 74 68 65 20 76 61 6c 75 65 20 74 6f 20 70  n the value to p
1aa60 61 73 73 20 74 6f 20 61 20 73 71 6c 69 74 65 33  ass to a sqlite3
1aa70 5f 77 61 6c 5f 68 6f 6f 6b 20 63 61 6c 6c 62 61  _wal_hook callba
1aa80 63 6b 2c 20 74 68 65 0a 2a 2a 20 6e 75 6d 62 65  ck, the.** numbe
1aa90 72 20 6f 66 20 66 72 61 6d 65 73 20 69 6e 20 74  r of frames in t
1aaa0 68 65 20 57 41 4c 20 61 74 20 74 68 65 20 70 6f  he WAL at the po
1aab0 69 6e 74 20 6f 66 20 74 68 65 20 6c 61 73 74 20  int of the last 
1aac0 63 6f 6d 6d 69 74 20 73 69 6e 63 65 0a 2a 2a 20  commit since.** 
1aad0 73 71 6c 69 74 65 33 57 61 6c 43 61 6c 6c 62 61  sqlite3WalCallba
1aae0 63 6b 28 29 20 77 61 73 20 63 61 6c 6c 65 64 2e  ck() was called.
1aaf0 20 20 49 66 20 6e 6f 20 63 6f 6d 6d 69 74 73 20    If no commits 
1ab00 68 61 76 65 20 6f 63 63 75 72 72 65 64 20 73 69  have occurred si
1ab10 6e 63 65 0a 2a 2a 20 74 68 65 20 6c 61 73 74 20  nce.** the last 
1ab20 63 61 6c 6c 2c 20 74 68 65 6e 20 72 65 74 75 72  call, then retur
1ab30 6e 20 30 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  n 0..*/.int sqli
1ab40 74 65 33 57 61 6c 43 61 6c 6c 62 61 63 6b 28 57  te3WalCallback(W
1ab50 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 75 33 32  al *pWal){.  u32
1ab60 20 72 65 74 20 3d 20 30 3b 0a 20 20 69 66 28 20   ret = 0;.  if( 
1ab70 70 57 61 6c 20 29 7b 0a 20 20 20 20 72 65 74 20  pWal ){.    ret 
1ab80 3d 20 70 57 61 6c 2d 3e 69 43 61 6c 6c 62 61 63  = pWal->iCallbac
1ab90 6b 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 69 43 61  k;.    pWal->iCa
1aba0 6c 6c 62 61 63 6b 20 3d 20 30 3b 0a 20 20 7d 0a  llback = 0;.  }.
1abb0 20 20 72 65 74 75 72 6e 20 28 69 6e 74 29 72 65    return (int)re
1abc0 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  t;.}../*.** This
1abd0 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
1abe0 6c 65 64 20 74 6f 20 63 68 61 6e 67 65 20 74 68  led to change th
1abf0 65 20 57 41 4c 20 73 75 62 73 79 73 74 65 6d 20  e WAL subsystem 
1ac00 69 6e 74 6f 20 6f 72 20 6f 75 74 0a 2a 2a 20 6f  into or out.** o
1ac10 66 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45  f locking_mode=E
1ac20 58 43 4c 55 53 49 56 45 2e 0a 2a 2a 0a 2a 2a 20  XCLUSIVE..**.** 
1ac30 49 66 20 6f 70 20 69 73 20 7a 65 72 6f 2c 20 74  If op is zero, t
1ac40 68 65 6e 20 61 74 74 65 6d 70 74 20 74 6f 20 63  hen attempt to c
1ac50 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63 6b 69  hange from locki
1ac60 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56  ng_mode=EXCLUSIV
1ac70 45 0a 2a 2a 20 69 6e 74 6f 20 6c 6f 63 6b 69 6e  E.** into lockin
1ac80 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 2e 20 20  g_mode=NORMAL.  
1ac90 54 68 69 73 20 6d 65 61 6e 73 20 74 68 61 74 20  This means that 
1aca0 77 65 20 6d 75 73 74 20 61 63 71 75 69 72 65 20  we must acquire 
1acb0 61 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65  a lock.** on the
1acc0 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20   pWal->readLock 
1acd0 62 79 74 65 2e 20 20 49 66 20 74 68 65 20 57 41  byte.  If the WA
1ace0 4c 20 69 73 20 61 6c 72 65 61 64 79 20 69 6e 20  L is already in 
1acf0 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52  locking_mode=NOR
1ad00 4d 41 4c 0a 2a 2a 20 6f 72 20 69 66 20 74 68 65  MAL.** or if the
1ad10 20 61 63 71 75 69 73 69 74 69 6f 6e 20 6f 66 20   acquisition of 
1ad20 74 68 65 20 6c 6f 63 6b 20 66 61 69 6c 73 2c 20  the lock fails, 
1ad30 74 68 65 6e 20 72 65 74 75 72 6e 20 30 2e 20 20  then return 0.  
1ad40 49 66 20 74 68 65 0a 2a 2a 20 74 72 61 6e 73 69  If the.** transi
1ad50 74 69 6f 6e 20 6f 75 74 20 6f 66 20 65 78 63 6c  tion out of excl
1ad60 75 73 69 76 65 2d 6d 6f 64 65 20 69 73 20 73 75  usive-mode is su
1ad70 63 63 65 73 73 66 75 6c 2c 20 72 65 74 75 72 6e  ccessful, return
1ad80 20 31 2e 20 20 54 68 69 73 0a 2a 2a 20 6f 70 65   1.  This.** ope
1ad90 72 61 74 69 6f 6e 20 6d 75 73 74 20 6f 63 63 75  ration must occu
1ada0 72 20 77 68 69 6c 65 20 74 68 65 20 70 61 67 65  r while the page
1adb0 72 20 69 73 20 73 74 69 6c 6c 20 68 6f 6c 64 69  r is still holdi
1adc0 6e 67 20 74 68 65 20 65 78 63 6c 75 73 69 76 65  ng the exclusive
1add0 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20 74 68 65 20  .** lock on the 
1ade0 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20 66 69  main database fi
1adf0 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20  le..**.** If op 
1ae00 69 73 20 6f 6e 65 2c 20 74 68 65 6e 20 63 68 61  is one, then cha
1ae10 6e 67 65 20 66 72 6f 6d 20 6c 6f 63 6b 69 6e 67  nge from locking
1ae20 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 69 6e 74  _mode=NORMAL int
1ae30 6f 20 0a 2a 2a 20 6c 6f 63 6b 69 6e 67 5f 6d 6f  o .** locking_mo
1ae40 64 65 3d 45 58 43 4c 55 53 49 56 45 2e 20 20 54  de=EXCLUSIVE.  T
1ae50 68 69 73 20 6d 65 61 6e 73 20 74 68 61 74 20 74  his means that t
1ae60 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  he pWal->readLoc
1ae70 6b 20 6d 75 73 74 0a 2a 2a 20 62 65 20 72 65 6c  k must.** be rel
1ae80 65 61 73 65 64 2e 20 20 52 65 74 75 72 6e 20 31  eased.  Return 1
1ae90 20 69 66 20 74 68 65 20 74 72 61 6e 73 69 74 69   if the transiti
1aea0 6f 6e 20 69 73 20 6d 61 64 65 20 61 6e 64 20 30  on is made and 0
1aeb0 20 69 66 20 74 68 65 0a 2a 2a 20 57 41 4c 20 69   if the.** WAL i
1aec0 73 20 61 6c 72 65 61 64 79 20 69 6e 20 65 78 63  s already in exc
1aed0 6c 75 73 69 76 65 2d 6c 6f 63 6b 69 6e 67 20 6d  lusive-locking m
1aee0 6f 64 65 20 2d 20 6d 65 61 6e 69 6e 67 20 74 68  ode - meaning th
1aef0 61 74 20 74 68 69 73 0a 2a 2a 20 72 6f 75 74 69  at this.** routi
1af00 6e 65 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 20 20  ne is a no-op.  
1af10 54 68 65 20 70 61 67 65 72 20 6d 75 73 74 20 61  The pager must a
1af20 6c 72 65 61 64 79 20 68 6f 6c 64 20 74 68 65 20  lready hold the 
1af30 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 0a 2a  exclusive lock.*
1af40 2a 20 6f 6e 20 74 68 65 20 6d 61 69 6e 20 64 61  * on the main da
1af50 74 61 62 61 73 65 20 66 69 6c 65 20 62 65 66 6f  tabase file befo
1af60 72 65 20 69 6e 76 6f 6b 69 6e 67 20 74 68 69 73  re invoking this
1af70 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a   operation..**.*
1af80 2a 20 49 66 20 6f 70 20 69 73 20 6e 65 67 61 74  * If op is negat
1af90 69 76 65 2c 20 74 68 65 6e 20 64 6f 20 61 20 64  ive, then do a d
1afa0 72 79 2d 72 75 6e 20 6f 66 20 74 68 65 20 6f 70  ry-run of the op
1afb0 3d 3d 31 20 63 61 73 65 20 62 75 74 20 64 6f 0a  ==1 case but do.
1afc0 2a 2a 20 6e 6f 74 20 61 63 74 75 61 6c 6c 79 20  ** not actually 
1afd0 63 68 61 6e 67 65 20 61 6e 79 74 68 69 6e 67 2e  change anything.
1afe0 20 54 68 65 20 70 61 67 65 72 20 75 73 65 73 20   The pager uses 
1aff0 74 68 69 73 20 74 6f 20 73 65 65 20 69 66 20 69  this to see if i
1b000 74 0a 2a 2a 20 73 68 6f 75 6c 64 20 61 63 71 75  t.** should acqu
1b010 69 72 65 20 74 68 65 20 64 61 74 61 62 61 73 65  ire the database
1b020 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20   exclusive lock 
1b030 70 72 69 6f 72 20 74 6f 20 69 6e 76 6f 6b 69 6e  prior to invokin
1b040 67 0a 2a 2a 20 74 68 65 20 6f 70 3d 3d 31 20 63  g.** the op==1 c
1b050 61 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ase..*/.int sqli
1b060 74 65 33 57 61 6c 45 78 63 6c 75 73 69 76 65 4d  te3WalExclusiveM
1b070 6f 64 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69  ode(Wal *pWal, i
1b080 6e 74 20 6f 70 29 7b 0a 20 20 69 6e 74 20 72 63  nt op){.  int rc
1b090 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ;.  assert( pWal
1b0a0 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29  ->writeLock==0 )
1b0b0 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ;.  assert( pWal
1b0c0 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 21  ->exclusiveMode!
1b0d0 3d 57 41 4c 5f 48 45 41 50 4d 45 4d 4f 52 59 5f  =WAL_HEAPMEMORY_
1b0e0 4d 4f 44 45 20 7c 7c 20 6f 70 3d 3d 2d 31 20 29  MODE || op==-1 )
1b0f0 3b 0a 0a 20 20 2f 2a 20 70 57 61 6c 2d 3e 72 65  ;..  /* pWal->re
1b100 61 64 4c 6f 63 6b 20 69 73 20 75 73 75 61 6c 6c  adLock is usuall
1b110 79 20 73 65 74 2c 20 62 75 74 20 6d 69 67 68 74  y set, but might
1b120 20 62 65 20 2d 31 20 69 66 20 74 68 65 72 65 20   be -1 if there 
1b130 77 61 73 20 61 20 0a 20 20 2a 2a 20 70 72 69 6f  was a .  ** prio
1b140 72 20 65 72 72 6f 72 20 77 68 69 6c 65 20 61 74  r error while at
1b150 74 65 6d 70 74 69 6e 67 20 74 6f 20 61 63 71 75  tempting to acqu
1b160 69 72 65 20 61 72 65 20 72 65 61 64 2d 6c 6f 63  ire are read-loc
1b170 6b 2e 20 54 68 69 73 20 63 61 6e 6e 6f 74 20 0a  k. This cannot .
1b180 20 20 2a 2a 20 68 61 70 70 65 6e 20 69 66 20 74    ** happen if t
1b190 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73  he connection is
1b1a0 20 61 63 74 75 61 6c 6c 79 20 69 6e 20 65 78 63   actually in exc
1b1b0 6c 75 73 69 76 65 20 6d 6f 64 65 20 28 61 73 20  lusive mode (as 
1b1c0 6e 6f 20 78 53 68 6d 4c 6f 63 6b 0a 20 20 2a 2a  no xShmLock.  **
1b1d0 20 6c 6f 63 6b 73 20 61 72 65 20 74 61 6b 65 6e   locks are taken
1b1e0 20 69 6e 20 74 68 69 73 20 63 61 73 65 29 2e 20   in this case). 
1b1f0 4e 6f 72 20 73 68 6f 75 6c 64 20 74 68 65 20 70  Nor should the p
1b200 61 67 65 72 20 61 74 74 65 6d 70 74 20 74 6f 0a  ager attempt to.
1b210 20 20 2a 2a 20 75 70 67 72 61 64 65 20 74 6f 20    ** upgrade to 
1b220 65 78 63 6c 75 73 69 76 65 2d 6d 6f 64 65 20 66  exclusive-mode f
1b230 6f 6c 6c 6f 77 69 6e 67 20 73 75 63 68 20 61 6e  ollowing such an
1b240 20 65 72 72 6f 72 2e 0a 20 20 2a 2f 0a 20 20 61   error..  */.  a
1b250 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65 61  ssert( pWal->rea
1b260 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70 57 61 6c  dLock>=0 || pWal
1b270 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 29 3b 0a 20  ->lockError );. 
1b280 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72   assert( pWal->r
1b290 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 28 6f  eadLock>=0 || (o
1b2a0 70 3c 3d 30 20 26 26 20 70 57 61 6c 2d 3e 65 78  p<=0 && pWal->ex
1b2b0 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 29 20  clusiveMode==0) 
1b2c0 29 3b 0a 0a 20 20 69 66 28 20 6f 70 3d 3d 30 20  );..  if( op==0 
1b2d0 29 7b 0a 20 20 20 20 69 66 28 20 70 57 61 6c 2d  ){.    if( pWal-
1b2e0 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29  >exclusiveMode )
1b2f0 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 65 78  {.      pWal->ex
1b300 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 30 3b  clusiveMode = 0;
1b310 0a 20 20 20 20 20 20 69 66 28 20 77 61 6c 4c 6f  .      if( walLo
1b320 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
1b330 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61  AL_READ_LOCK(pWa
1b340 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29 21 3d 53  l->readLock))!=S
1b350 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1b360 20 20 20 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73      pWal->exclus
1b370 69 76 65 4d 6f 64 65 20 3d 20 31 3b 0a 20 20 20  iveMode = 1;.   
1b380 20 20 20 7d 0a 20 20 20 20 20 20 72 63 20 3d 20     }.      rc = 
1b390 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
1b3a0 6f 64 65 3d 3d 30 3b 0a 20 20 20 20 7d 65 6c 73  ode==0;.    }els
1b3b0 65 7b 0a 20 20 20 20 20 20 2f 2a 20 41 6c 72 65  e{.      /* Alre
1b3c0 61 64 79 20 69 6e 20 6c 6f 63 6b 69 6e 67 5f 6d  ady in locking_m
1b3d0 6f 64 65 3d 4e 4f 52 4d 41 4c 20 2a 2f 0a 20 20  ode=NORMAL */.  
1b3e0 20 20 20 20 72 63 20 3d 20 30 3b 0a 20 20 20 20      rc = 0;.    
1b3f0 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 6f 70  }.  }else if( op
1b400 3e 30 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  >0 ){.    assert
1b410 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76  ( pWal->exclusiv
1b420 65 4d 6f 64 65 3d 3d 30 20 29 3b 0a 20 20 20 20  eMode==0 );.    
1b430 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72 65  assert( pWal->re
1b440 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b 0a 20 20 20  adLock>=0 );.   
1b450 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64   walUnlockShared
1b460 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f  (pWal, WAL_READ_
1b470 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c  LOCK(pWal->readL
1b480 6f 63 6b 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d  ock));.    pWal-
1b490 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d  >exclusiveMode =
1b4a0 20 31 3b 0a 20 20 20 20 72 63 20 3d 20 31 3b 0a   1;.    rc = 1;.
1b4b0 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20    }else{.    rc 
1b4c0 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76  = pWal->exclusiv
1b4d0 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 7d 0a 20 20  eMode==0;.  }.  
1b4e0 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
1b4f0 20 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65   .** Return true
1b500 20 69 66 20 74 68 65 20 61 72 67 75 6d 65 6e 74   if the argument
1b510 20 69 73 20 6e 6f 6e 2d 4e 55 4c 4c 20 61 6e 64   is non-NULL and
1b520 20 74 68 65 20 57 41 4c 20 6d 6f 64 75 6c 65 20   the WAL module 
1b530 69 73 20 75 73 69 6e 67 0a 2a 2a 20 68 65 61 70  is using.** heap
1b540 2d 6d 65 6d 6f 72 79 20 66 6f 72 20 74 68 65 20  -memory for the 
1b550 77 61 6c 2d 69 6e 64 65 78 2e 20 4f 74 68 65 72  wal-index. Other
1b560 77 69 73 65 2c 20 69 66 20 74 68 65 20 61 72 67  wise, if the arg
1b570 75 6d 65 6e 74 20 69 73 20 4e 55 4c 4c 20 6f 72  ument is NULL or
1b580 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6d 6f 64 75   the.** WAL modu
1b590 6c 65 20 69 73 20 75 73 69 6e 67 20 73 68 61 72  le is using shar
1b5a0 65 64 2d 6d 65 6d 6f 72 79 2c 20 72 65 74 75 72  ed-memory, retur
1b5b0 6e 20 66 61 6c 73 65 2e 20 0a 2a 2f 0a 69 6e 74  n false. .*/.int
1b5c0 20 73 71 6c 69 74 65 33 57 61 6c 48 65 61 70 4d   sqlite3WalHeapM
1b5d0 65 6d 6f 72 79 28 57 61 6c 20 2a 70 57 61 6c 29  emory(Wal *pWal)
1b5e0 7b 0a 20 20 72 65 74 75 72 6e 20 28 70 57 61 6c  {.  return (pWal
1b5f0 20 26 26 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73   && pWal->exclus
1b600 69 76 65 4d 6f 64 65 3d 3d 57 41 4c 5f 48 45 41  iveMode==WAL_HEA
1b610 50 4d 45 4d 4f 52 59 5f 4d 4f 44 45 20 29 3b 0a  PMEMORY_MODE );.
1b620 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 23 69 66  }..#endif /* #if
1b630 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
1b640 5f 57 41 4c 20 2a 2f 0a                          _WAL */.