/ Hex Artifact Content
Login

Artifact 737408e8e6f2386e6318cd01dfaa534c45ffe3ed:


0000: 2f 2a 0a 2a 2a 20 32 30 31 30 20 46 65 62 72 75  /*.** 2010 Febru
0010: 61 72 79 20 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ary 1.**.** The 
0020: 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73  author disclaims
0030: 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68   copyright to th
0040: 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20  is source code. 
0050: 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20   In place of.** 
0060: 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20  a legal notice, 
0070: 68 65 72 65 20 69 73 20 61 20 62 6c 65 73 73 69  here is a blessi
0080: 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79  ng:.**.**    May
0090: 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64   you do good and
00a0: 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20   not evil..**   
00b0: 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f   May you find fo
00c0: 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f  rgiveness for yo
00d0: 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69  urself and forgi
00e0: 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20  ve others..**   
00f0: 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65 20 66   May you share f
0100: 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b  reely, never tak
0110: 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f  ing more than yo
0120: 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a  u give..**.*****
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 74 68  file contains th
0190: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
01a0: 20 6f 66 20 61 20 77 72 69 74 65 2d 61 68 65 61   of a write-ahea
01b0: 64 20 6c 6f 67 20 28 57 41 4c 29 20 75 73 65 64  d log (WAL) used
01c0: 20 69 6e 20 0a 2a 2a 20 22 6a 6f 75 72 6e 61 6c   in .** "journal
01d0: 5f 6d 6f 64 65 3d 57 41 4c 22 20 6d 6f 64 65 2e  _mode=WAL" mode.
01e0: 0a 2a 2a 0a 2a 2a 20 57 52 49 54 45 2d 41 48 45  .**.** WRITE-AHE
01f0: 41 44 20 4c 4f 47 20 28 57 41 4c 29 20 46 49 4c  AD LOG (WAL) FIL
0200: 45 20 46 4f 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 41  E FORMAT.**.** A
0210: 20 57 41 4c 20 66 69 6c 65 20 63 6f 6e 73 69 73   WAL file consis
0220: 74 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 66  ts of a header f
0230: 6f 6c 6c 6f 77 65 64 20 62 79 20 7a 65 72 6f 20  ollowed by zero 
0240: 6f 72 20 6d 6f 72 65 20 22 66 72 61 6d 65 73 22  or more "frames"
0250: 2e 0a 2a 2a 20 45 61 63 68 20 66 72 61 6d 65 20  ..** Each frame 
0260: 72 65 63 6f 72 64 73 20 74 68 65 20 72 65 76 69  records the revi
0270: 73 65 64 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  sed content of a
0280: 20 73 69 6e 67 6c 65 20 70 61 67 65 20 66 72 6f   single page fro
0290: 6d 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73  m the.** databas
02a0: 65 20 66 69 6c 65 2e 20 20 41 6c 6c 20 63 68 61  e file.  All cha
02b0: 6e 67 65 73 20 74 6f 20 74 68 65 20 64 61 74 61  nges to the data
02c0: 62 61 73 65 20 61 72 65 20 72 65 63 6f 72 64 65  base are recorde
02d0: 64 20 62 79 20 77 72 69 74 69 6e 67 0a 2a 2a 20  d by writing.** 
02e0: 66 72 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20  frames into the 
02f0: 57 41 4c 2e 20 20 54 72 61 6e 73 61 63 74 69 6f  WAL.  Transactio
0300: 6e 73 20 63 6f 6d 6d 69 74 20 77 68 65 6e 20 61  ns commit when a
0310: 20 66 72 61 6d 65 20 69 73 20 77 72 69 74 74 65   frame is writte
0320: 6e 20 74 68 61 74 0a 2a 2a 20 63 6f 6e 74 61 69  n that.** contai
0330: 6e 73 20 61 20 63 6f 6d 6d 69 74 20 6d 61 72 6b  ns a commit mark
0340: 65 72 2e 20 20 41 20 73 69 6e 67 6c 65 20 57 41  er.  A single WA
0350: 4c 20 63 61 6e 20 61 6e 64 20 75 73 75 61 6c 6c  L can and usuall
0360: 79 20 64 6f 65 73 20 72 65 63 6f 72 64 20 0a 2a  y does record .*
0370: 2a 20 6d 75 6c 74 69 70 6c 65 20 74 72 61 6e 73  * multiple trans
0380: 61 63 74 69 6f 6e 73 2e 20 20 50 65 72 69 6f 64  actions.  Period
0390: 69 63 61 6c 6c 79 2c 20 74 68 65 20 63 6f 6e 74  ically, the cont
03a0: 65 6e 74 20 6f 66 20 74 68 65 20 57 41 4c 20 69  ent of the WAL i
03b0: 73 0a 2a 2a 20 74 72 61 6e 73 66 65 72 72 65 64  s.** transferred
03c0: 20 62 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64   back into the d
03d0: 61 74 61 62 61 73 65 20 66 69 6c 65 20 69 6e 20  atabase file in 
03e0: 61 6e 20 6f 70 65 72 61 74 69 6f 6e 20 63 61 6c  an operation cal
03f0: 6c 65 64 20 61 0a 2a 2a 20 22 63 68 65 63 6b 70  led a.** "checkp
0400: 6f 69 6e 74 22 2e 0a 2a 2a 0a 2a 2a 20 41 20 73  oint"..**.** A s
0410: 69 6e 67 6c 65 20 57 41 4c 20 66 69 6c 65 20 63  ingle WAL file c
0420: 61 6e 20 62 65 20 75 73 65 64 20 6d 75 6c 74 69  an be used multi
0430: 70 6c 65 20 74 69 6d 65 73 2e 20 20 49 6e 20 6f  ple times.  In o
0440: 74 68 65 72 20 77 6f 72 64 73 2c 20 74 68 65 0a  ther words, the.
0450: 2a 2a 20 57 41 4c 20 63 61 6e 20 66 69 6c 6c 20  ** WAL can fill 
0460: 75 70 20 77 69 74 68 20 66 72 61 6d 65 73 20 61  up with frames a
0470: 6e 64 20 74 68 65 6e 20 62 65 20 63 68 65 63 6b  nd then be check
0480: 70 6f 69 6e 74 65 64 20 61 6e 64 20 74 68 65 6e  pointed and then
0490: 20 6e 65 77 0a 2a 2a 20 66 72 61 6d 65 73 20 63   new.** frames c
04a0: 61 6e 20 6f 76 65 72 77 72 69 74 65 20 74 68 65  an overwrite the
04b0: 20 6f 6c 64 20 6f 6e 65 73 2e 20 20 41 20 57 41   old ones.  A WA
04c0: 4c 20 61 6c 77 61 79 73 20 67 72 6f 77 73 20 66  L always grows f
04d0: 72 6f 6d 20 62 65 67 69 6e 6e 69 6e 67 0a 2a 2a  rom beginning.**
04e0: 20 74 6f 77 61 72 64 20 74 68 65 20 65 6e 64 2e   toward the end.
04f0: 20 20 43 68 65 63 6b 73 75 6d 73 20 61 6e 64 20    Checksums and 
0500: 63 6f 75 6e 74 65 72 73 20 61 74 74 61 63 68 65  counters attache
0510: 64 20 74 6f 20 65 61 63 68 20 66 72 61 6d 65 20  d to each frame 
0520: 61 72 65 0a 2a 2a 20 75 73 65 64 20 74 6f 20 64  are.** used to d
0530: 65 74 65 72 6d 69 6e 65 20 77 68 69 63 68 20 66  etermine which f
0540: 72 61 6d 65 73 20 77 69 74 68 69 6e 20 74 68 65  rames within the
0550: 20 57 41 4c 20 61 72 65 20 76 61 6c 69 64 20 61   WAL are valid a
0560: 6e 64 20 77 68 69 63 68 0a 2a 2a 20 61 72 65 20  nd which.** are 
0570: 6c 65 66 74 6f 76 65 72 73 20 66 72 6f 6d 20 70  leftovers from p
0580: 72 69 6f 72 20 63 68 65 63 6b 70 6f 69 6e 74 73  rior checkpoints
0590: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 57 41 4c 20  ..**.** The WAL 
05a0: 68 65 61 64 65 72 20 69 73 20 33 32 20 62 79 74  header is 32 byt
05b0: 65 73 20 69 6e 20 73 69 7a 65 20 61 6e 64 20 63  es in size and c
05c0: 6f 6e 73 69 73 74 73 20 6f 66 20 74 68 65 20 66  onsists of the f
05d0: 6f 6c 6c 6f 77 69 6e 67 20 65 69 67 68 74 0a 2a  ollowing eight.*
05e0: 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 33 32 2d  * big-endian 32-
05f0: 62 69 74 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  bit unsigned int
0600: 65 67 65 72 20 76 61 6c 75 65 73 3a 0a 2a 2a 0a  eger values:.**.
0610: 2a 2a 20 20 20 20 20 30 3a 20 4d 61 67 69 63 20  **     0: Magic 
0620: 6e 75 6d 62 65 72 2e 20 20 30 78 33 37 37 66 30  number.  0x377f0
0630: 36 38 32 20 6f 72 20 30 78 33 37 37 66 30 36 38  682 or 0x377f068
0640: 33 0a 2a 2a 20 20 20 20 20 34 3a 20 46 69 6c 65  3.**     4: File
0650: 20 66 6f 72 6d 61 74 20 76 65 72 73 69 6f 6e 2e   format version.
0660: 20 20 43 75 72 72 65 6e 74 6c 79 20 33 30 30 37    Currently 3007
0670: 30 30 30 0a 2a 2a 20 20 20 20 20 38 3a 20 44 61  000.**     8: Da
0680: 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a 65  tabase page size
0690: 2e 20 20 45 78 61 6d 70 6c 65 3a 20 31 30 32 34  .  Example: 1024
06a0: 0a 2a 2a 20 20 20 20 31 32 3a 20 43 68 65 63 6b  .**    12: Check
06b0: 70 6f 69 6e 74 20 73 65 71 75 65 6e 63 65 20 6e  point sequence n
06c0: 75 6d 62 65 72 0a 2a 2a 20 20 20 20 31 36 3a 20  umber.**    16: 
06d0: 53 61 6c 74 2d 31 2c 20 72 61 6e 64 6f 6d 20 69  Salt-1, random i
06e0: 6e 74 65 67 65 72 20 69 6e 63 72 65 6d 65 6e 74  nteger increment
06f0: 65 64 20 77 69 74 68 20 65 61 63 68 20 63 68 65  ed with each che
0700: 63 6b 70 6f 69 6e 74 0a 2a 2a 20 20 20 20 32 30  ckpoint.**    20
0710: 3a 20 53 61 6c 74 2d 32 2c 20 61 20 64 69 66 66  : Salt-2, a diff
0720: 65 72 65 6e 74 20 72 61 6e 64 6f 6d 20 69 6e 74  erent random int
0730: 65 67 65 72 20 63 68 61 6e 67 69 6e 67 20 77 69  eger changing wi
0740: 74 68 20 65 61 63 68 20 63 6b 70 74 0a 2a 2a 20  th each ckpt.** 
0750: 20 20 20 32 34 3a 20 43 68 65 63 6b 73 75 6d 2d     24: Checksum-
0760: 31 20 28 66 69 72 73 74 20 70 61 72 74 20 6f 66  1 (first part of
0770: 20 63 68 65 63 6b 73 75 6d 20 66 6f 72 20 66 69   checksum for fi
0780: 72 73 74 20 32 34 20 62 79 74 65 73 20 6f 66 20  rst 24 bytes of 
0790: 68 65 61 64 65 72 29 2e 0a 2a 2a 20 20 20 20 32  header)..**    2
07a0: 38 3a 20 43 68 65 63 6b 73 75 6d 2d 32 20 28 73  8: Checksum-2 (s
07b0: 65 63 6f 6e 64 20 70 61 72 74 20 6f 66 20 63 68  econd part of ch
07c0: 65 63 6b 73 75 6d 20 66 6f 72 20 66 69 72 73 74  ecksum for first
07d0: 20 32 34 20 62 79 74 65 73 20 6f 66 20 68 65 61   24 bytes of hea
07e0: 64 65 72 29 2e 0a 2a 2a 0a 2a 2a 20 49 6d 6d 65  der)..**.** Imme
07f0: 64 69 61 74 65 6c 79 20 66 6f 6c 6c 6f 77 69 6e  diately followin
0800: 67 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  g the wal-header
0810: 20 61 72 65 20 7a 65 72 6f 20 6f 72 20 6d 6f 72   are zero or mor
0820: 65 20 66 72 61 6d 65 73 2e 20 45 61 63 68 0a 2a  e frames. Each.*
0830: 2a 20 66 72 61 6d 65 20 63 6f 6e 73 69 73 74 73  * frame consists
0840: 20 6f 66 20 61 20 32 34 2d 62 79 74 65 20 66 72   of a 24-byte fr
0850: 61 6d 65 2d 68 65 61 64 65 72 20 66 6f 6c 6c 6f  ame-header follo
0860: 77 65 64 20 62 79 20 61 20 3c 70 61 67 65 2d 73  wed by a <page-s
0870: 69 7a 65 3e 20 62 79 74 65 73 0a 2a 2a 20 6f 66  ize> bytes.** of
0880: 20 70 61 67 65 20 64 61 74 61 2e 20 54 68 65 20   page data. The 
0890: 66 72 61 6d 65 2d 68 65 61 64 65 72 20 69 73 20  frame-header is 
08a0: 73 69 78 20 62 69 67 2d 65 6e 64 69 61 6e 20 33  six big-endian 3
08b0: 32 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20 0a  2-bit unsigned .
08c0: 2a 2a 20 69 6e 74 65 67 65 72 20 76 61 6c 75 65  ** integer value
08d0: 73 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  s, as follows:.*
08e0: 2a 0a 2a 2a 20 20 20 20 20 30 3a 20 50 61 67 65  *.**     0: Page
08f0: 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20 20 20 20   number..**     
0900: 34 3a 20 46 6f 72 20 63 6f 6d 6d 69 74 20 72 65  4: For commit re
0910: 63 6f 72 64 73 2c 20 74 68 65 20 73 69 7a 65 20  cords, the size 
0920: 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20  of the database 
0930: 69 6d 61 67 65 20 69 6e 20 70 61 67 65 73 20 0a  image in pages .
0940: 2a 2a 20 20 20 20 20 20 20 20 61 66 74 65 72 20  **        after 
0950: 74 68 65 20 63 6f 6d 6d 69 74 2e 20 46 6f 72 20  the commit. For 
0960: 61 6c 6c 20 6f 74 68 65 72 20 72 65 63 6f 72 64  all other record
0970: 73 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20 20  s, zero..**     
0980: 38 3a 20 53 61 6c 74 2d 31 20 28 63 6f 70 69 65  8: Salt-1 (copie
0990: 64 20 66 72 6f 6d 20 74 68 65 20 68 65 61 64 65  d from the heade
09a0: 72 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61 6c  r).**    12: Sal
09b0: 74 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f 6d  t-2 (copied from
09c0: 20 74 68 65 20 68 65 61 64 65 72 29 0a 2a 2a 20   the header).** 
09d0: 20 20 20 31 36 3a 20 43 68 65 63 6b 73 75 6d 2d     16: Checksum-
09e0: 31 2e 0a 2a 2a 20 20 20 20 32 30 3a 20 43 68 65  1..**    20: Che
09f0: 63 6b 73 75 6d 2d 32 2e 0a 2a 2a 0a 2a 2a 20 41  cksum-2..**.** A
0a00: 20 66 72 61 6d 65 20 69 73 20 63 6f 6e 73 69 64   frame is consid
0a10: 65 72 65 64 20 76 61 6c 69 64 20 69 66 20 61 6e  ered valid if an
0a20: 64 20 6f 6e 6c 79 20 69 66 20 74 68 65 20 66 6f  d only if the fo
0a30: 6c 6c 6f 77 69 6e 67 20 63 6f 6e 64 69 74 69 6f  llowing conditio
0a40: 6e 73 20 61 72 65 0a 2a 2a 20 74 72 75 65 3a 0a  ns are.** true:.
0a50: 2a 2a 0a 2a 2a 20 20 20 20 28 31 29 20 54 68 65  **.**    (1) The
0a60: 20 73 61 6c 74 2d 31 20 61 6e 64 20 73 61 6c 74   salt-1 and salt
0a70: 2d 32 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  -2 values in the
0a80: 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20 6d 61   frame-header ma
0a90: 74 63 68 0a 2a 2a 20 20 20 20 20 20 20 20 73 61  tch.**        sa
0aa0: 6c 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65  lt values in the
0ab0: 20 77 61 6c 2d 68 65 61 64 65 72 0a 2a 2a 0a 2a   wal-header.**.*
0ac0: 2a 20 20 20 20 28 32 29 20 54 68 65 20 63 68 65  *    (2) The che
0ad0: 63 6b 73 75 6d 20 76 61 6c 75 65 73 20 69 6e 20  cksum values in 
0ae0: 74 68 65 20 66 69 6e 61 6c 20 38 20 62 79 74 65  the final 8 byte
0af0: 73 20 6f 66 20 74 68 65 20 66 72 61 6d 65 2d 68  s of the frame-h
0b00: 65 61 64 65 72 0a 2a 2a 20 20 20 20 20 20 20 20  eader.**        
0b10: 65 78 61 63 74 6c 79 20 6d 61 74 63 68 20 74 68  exactly match th
0b20: 65 20 63 68 65 63 6b 73 75 6d 20 63 6f 6d 70 75  e checksum compu
0b30: 74 65 64 20 63 6f 6e 73 65 63 75 74 69 76 65 6c  ted consecutivel
0b40: 79 20 6f 6e 20 74 68 65 0a 2a 2a 20 20 20 20 20  y on the.**     
0b50: 20 20 20 57 41 4c 20 68 65 61 64 65 72 20 61 6e     WAL header an
0b60: 64 20 74 68 65 20 66 69 72 73 74 20 38 20 62 79  d the first 8 by
0b70: 74 65 73 20 61 6e 64 20 74 68 65 20 63 6f 6e 74  tes and the cont
0b80: 65 6e 74 20 6f 66 20 61 6c 6c 20 66 72 61 6d 65  ent of all frame
0b90: 73 0a 2a 2a 20 20 20 20 20 20 20 20 75 70 20 74  s.**        up t
0ba0: 6f 20 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20  o and including 
0bb0: 74 68 65 20 63 75 72 72 65 6e 74 20 66 72 61 6d  the current fram
0bc0: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65  e..**.** The che
0bd0: 63 6b 73 75 6d 20 69 73 20 63 6f 6d 70 75 74 65  cksum is compute
0be0: 64 20 75 73 69 6e 67 20 33 32 2d 62 69 74 20 62  d using 32-bit b
0bf0: 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65  ig-endian intege
0c00: 72 73 20 69 66 20 74 68 65 0a 2a 2a 20 6d 61 67  rs if the.** mag
0c10: 69 63 20 6e 75 6d 62 65 72 20 69 6e 20 74 68 65  ic number in the
0c20: 20 66 69 72 73 74 20 34 20 62 79 74 65 73 20 6f   first 4 bytes o
0c30: 66 20 74 68 65 20 57 41 4c 20 69 73 20 30 78 33  f the WAL is 0x3
0c40: 37 37 66 30 36 38 33 20 61 6e 64 20 69 74 0a 2a  77f0683 and it.*
0c50: 2a 20 69 73 20 63 6f 6d 70 75 74 65 64 20 75 73  * is computed us
0c60: 69 6e 67 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61  ing little-endia
0c70: 6e 20 69 66 20 74 68 65 20 6d 61 67 69 63 20 6e  n if the magic n
0c80: 75 6d 62 65 72 20 69 73 20 30 78 33 37 37 66 30  umber is 0x377f0
0c90: 36 38 32 2e 0a 2a 2a 20 54 68 65 20 63 68 65 63  682..** The chec
0ca0: 6b 73 75 6d 20 76 61 6c 75 65 73 20 61 72 65 20  ksum values are 
0cb0: 61 6c 77 61 79 73 20 73 74 6f 72 65 64 20 69 6e  always stored in
0cc0: 20 74 68 65 20 66 72 61 6d 65 20 68 65 61 64 65   the frame heade
0cd0: 72 20 69 6e 20 61 0a 2a 2a 20 62 69 67 2d 65 6e  r in a.** big-en
0ce0: 64 69 61 6e 20 66 6f 72 6d 61 74 20 72 65 67 61  dian format rega
0cf0: 72 64 6c 65 73 73 20 6f 66 20 77 68 69 63 68 20  rdless of which 
0d00: 62 79 74 65 20 6f 72 64 65 72 20 69 73 20 75 73  byte order is us
0d10: 65 64 20 74 6f 20 63 6f 6d 70 75 74 65 0a 2a 2a  ed to compute.**
0d20: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 2e 20 20   the checksum.  
0d30: 54 68 65 20 63 68 65 63 6b 73 75 6d 20 69 73 20  The checksum is 
0d40: 63 6f 6d 70 75 74 65 64 20 62 79 20 69 6e 74 65  computed by inte
0d50: 72 70 72 65 74 69 6e 67 20 74 68 65 20 69 6e 70  rpreting the inp
0d60: 75 74 20 61 73 0a 2a 2a 20 61 6e 20 65 76 65 6e  ut as.** an even
0d70: 20 6e 75 6d 62 65 72 20 6f 66 20 75 6e 73 69 67   number of unsig
0d80: 6e 65 64 20 33 32 2d 62 69 74 20 69 6e 74 65 67  ned 32-bit integ
0d90: 65 72 73 3a 20 78 5b 30 5d 20 74 68 72 6f 75 67  ers: x[0] throug
0da0: 68 20 78 5b 4e 5d 2e 20 20 54 68 65 0a 2a 2a 20  h x[N].  The.** 
0db0: 61 6c 67 6f 72 69 74 68 6d 20 75 73 65 64 20 66  algorithm used f
0dc0: 6f 72 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20  or the checksum 
0dd0: 69 73 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  is as follows:.*
0de0: 2a 20 0a 2a 2a 20 20 20 66 6f 72 20 69 20 66 72  * .**   for i fr
0df0: 6f 6d 20 30 20 74 6f 20 6e 2d 31 20 73 74 65 70  om 0 to n-1 step
0e00: 20 32 3a 0a 2a 2a 20 20 20 20 20 73 30 20 2b 3d   2:.**     s0 +=
0e10: 20 78 5b 69 5d 20 2b 20 73 31 3b 0a 2a 2a 20 20   x[i] + s1;.**  
0e20: 20 20 20 73 31 20 2b 3d 20 78 5b 69 2b 31 5d 20     s1 += x[i+1] 
0e30: 2b 20 73 30 3b 0a 2a 2a 20 20 20 65 6e 64 66 6f  + s0;.**   endfo
0e40: 72 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61  r.**.** Note tha
0e50: 74 20 73 30 20 61 6e 64 20 73 31 20 61 72 65 20  t s0 and s1 are 
0e60: 62 6f 74 68 20 77 65 69 67 68 74 65 64 20 63 68  both weighted ch
0e70: 65 63 6b 73 75 6d 73 20 75 73 69 6e 67 20 66 69  ecksums using fi
0e80: 62 6f 6e 61 63 63 69 20 77 65 69 67 68 74 73 0a  bonacci weights.
0e90: 2a 2a 20 69 6e 20 72 65 76 65 72 73 65 20 6f 72  ** in reverse or
0ea0: 64 65 72 20 28 74 68 65 20 6c 61 72 67 65 73 74  der (the largest
0eb0: 20 66 69 62 6f 6e 61 63 63 69 20 77 65 69 67 68   fibonacci weigh
0ec0: 74 20 6f 63 63 75 72 73 20 6f 6e 20 74 68 65 20  t occurs on the 
0ed0: 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 0a 2a 2a  first element.**
0ee0: 20 6f 66 20 74 68 65 20 73 65 71 75 65 6e 63 65   of the sequence
0ef0: 20 62 65 69 6e 67 20 73 75 6d 6d 65 64 2e 29 20   being summed.) 
0f00: 20 54 68 65 20 73 31 20 76 61 6c 75 65 20 73 70   The s1 value sp
0f10: 61 6e 73 20 61 6c 6c 20 33 32 2d 62 69 74 20 0a  ans all 32-bit .
0f20: 2a 2a 20 74 65 72 6d 73 20 6f 66 20 74 68 65 20  ** terms of the 
0f30: 73 65 71 75 65 6e 63 65 20 77 68 65 72 65 61 73  sequence whereas
0f40: 20 73 30 20 6f 6d 69 74 73 20 74 68 65 20 66 69   s0 omits the fi
0f50: 6e 61 6c 20 74 65 72 6d 2e 0a 2a 2a 0a 2a 2a 20  nal term..**.** 
0f60: 4f 6e 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 2c  On a checkpoint,
0f70: 20 74 68 65 20 57 41 4c 20 69 73 20 66 69 72 73   the WAL is firs
0f80: 74 20 56 46 53 2e 78 53 79 6e 63 2d 65 64 2c 20  t VFS.xSync-ed, 
0f90: 74 68 65 6e 20 76 61 6c 69 64 20 63 6f 6e 74 65  then valid conte
0fa0: 6e 74 20 6f 66 20 74 68 65 0a 2a 2a 20 57 41 4c  nt of the.** WAL
0fb0: 20 69 73 20 74 72 61 6e 73 66 65 72 72 65 64 20   is transferred 
0fc0: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
0fd0: 65 2c 20 74 68 65 6e 20 74 68 65 20 64 61 74 61  e, then the data
0fe0: 62 61 73 65 20 69 73 20 56 46 53 2e 78 53 79 6e  base is VFS.xSyn
0ff0: 63 2d 65 64 2e 0a 2a 2a 20 54 68 65 20 56 46 53  c-ed..** The VFS
1000: 2e 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e  .xSync operation
1010: 73 20 73 65 72 76 65 20 61 73 20 77 72 69 74 65  s serve as write
1020: 20 62 61 72 72 69 65 72 73 20 2d 20 61 6c 6c 20   barriers - all 
1030: 77 72 69 74 65 73 20 6c 61 75 6e 63 68 65 64 0a  writes launched.
1040: 2a 2a 20 62 65 66 6f 72 65 20 74 68 65 20 78 53  ** before the xS
1050: 79 6e 63 20 6d 75 73 74 20 63 6f 6d 70 6c 65 74  ync must complet
1060: 65 20 62 65 66 6f 72 65 20 61 6e 79 20 77 72 69  e before any wri
1070: 74 65 20 74 68 61 74 20 6c 61 75 6e 63 68 65 73  te that launches
1080: 20 61 66 74 65 72 20 74 68 65 0a 2a 2a 20 78 53   after the.** xS
1090: 79 6e 63 20 62 65 67 69 6e 73 2e 0a 2a 2a 0a 2a  ync begins..**.*
10a0: 2a 20 41 66 74 65 72 20 65 61 63 68 20 63 68 65  * After each che
10b0: 63 6b 70 6f 69 6e 74 2c 20 74 68 65 20 73 61 6c  ckpoint, the sal
10c0: 74 2d 31 20 76 61 6c 75 65 20 69 73 20 69 6e 63  t-1 value is inc
10d0: 72 65 6d 65 6e 74 65 64 20 61 6e 64 20 74 68 65  remented and the
10e0: 20 73 61 6c 74 2d 32 0a 2a 2a 20 76 61 6c 75 65   salt-2.** value
10f0: 20 69 73 20 72 61 6e 64 6f 6d 69 7a 65 64 2e 20   is randomized. 
1100: 20 54 68 69 73 20 70 72 65 76 65 6e 74 73 20 6f   This prevents o
1110: 6c 64 20 61 6e 64 20 6e 65 77 20 66 72 61 6d 65  ld and new frame
1120: 73 20 69 6e 20 74 68 65 20 57 41 4c 20 66 72 6f  s in the WAL fro
1130: 6d 0a 2a 2a 20 62 65 69 6e 67 20 63 6f 6e 73 69  m.** being consi
1140: 64 65 72 65 64 20 76 61 6c 69 64 20 61 74 20 74  dered valid at t
1150: 68 65 20 73 61 6d 65 20 74 69 6d 65 20 61 6e 64  he same time and
1160: 20 62 65 69 6e 67 20 63 68 65 63 6b 70 6f 69 6e   being checkpoin
1170: 74 69 6e 67 20 74 6f 67 65 74 68 65 72 0a 2a 2a  ting together.**
1180: 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 63 72 61   following a cra
1190: 73 68 2e 0a 2a 2a 0a 2a 2a 20 52 45 41 44 45 52  sh..**.** READER
11a0: 20 41 4c 47 4f 52 49 54 48 4d 0a 2a 2a 0a 2a 2a   ALGORITHM.**.**
11b0: 20 54 6f 20 72 65 61 64 20 61 20 70 61 67 65 20   To read a page 
11c0: 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
11d0: 65 20 28 63 61 6c 6c 20 69 74 20 70 61 67 65 20  e (call it page 
11e0: 6e 75 6d 62 65 72 20 50 29 2c 20 61 20 72 65 61  number P), a rea
11f0: 64 65 72 0a 2a 2a 20 66 69 72 73 74 20 63 68 65  der.** first che
1200: 63 6b 73 20 74 68 65 20 57 41 4c 20 74 6f 20 73  cks the WAL to s
1210: 65 65 20 69 66 20 69 74 20 63 6f 6e 74 61 69 6e  ee if it contain
1220: 73 20 70 61 67 65 20 50 2e 20 20 49 66 20 73 6f  s page P.  If so
1230: 2c 20 74 68 65 6e 20 74 68 65 0a 2a 2a 20 6c 61  , then the.** la
1240: 73 74 20 76 61 6c 69 64 20 69 6e 73 74 61 6e 63  st valid instanc
1250: 65 20 6f 66 20 70 61 67 65 20 50 20 74 68 61 74  e of page P that
1260: 20 69 73 20 61 20 66 6f 6c 6c 6f 77 65 64 20 62   is a followed b
1270: 79 20 61 20 63 6f 6d 6d 69 74 20 66 72 61 6d 65  y a commit frame
1280: 0a 2a 2a 20 6f 72 20 69 73 20 61 20 63 6f 6d 6d  .** or is a comm
1290: 69 74 20 66 72 61 6d 65 20 69 74 73 65 6c 66 20  it frame itself 
12a0: 62 65 63 6f 6d 65 73 20 74 68 65 20 76 61 6c 75  becomes the valu
12b0: 65 20 72 65 61 64 2e 20 20 49 66 20 74 68 65 20  e read.  If the 
12c0: 57 41 4c 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20  WAL.** contains 
12d0: 6e 6f 20 63 6f 70 69 65 73 20 6f 66 20 70 61 67  no copies of pag
12e0: 65 20 50 20 74 68 61 74 20 61 72 65 20 76 61 6c  e P that are val
12f0: 69 64 20 61 6e 64 20 77 68 69 63 68 20 61 72 65  id and which are
1300: 20 61 20 63 6f 6d 6d 69 74 0a 2a 2a 20 66 72 61   a commit.** fra
1310: 6d 65 20 6f 72 20 61 72 65 20 66 6f 6c 6c 6f 77  me or are follow
1320: 65 64 20 62 79 20 61 20 63 6f 6d 6d 69 74 20 66  ed by a commit f
1330: 72 61 6d 65 2c 20 74 68 65 6e 20 70 61 67 65 20  rame, then page 
1340: 50 20 69 73 20 72 65 61 64 20 66 72 6f 6d 0a 2a  P is read from.*
1350: 2a 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  * the database f
1360: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 73 74  ile..**.** To st
1370: 61 72 74 20 61 20 72 65 61 64 20 74 72 61 6e 73  art a read trans
1380: 61 63 74 69 6f 6e 2c 20 74 68 65 20 72 65 61 64  action, the read
1390: 65 72 20 72 65 63 6f 72 64 73 20 74 68 65 20 69  er records the i
13a0: 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61 73 74  ndex of the last
13b0: 0a 2a 2a 20 76 61 6c 69 64 20 66 72 61 6d 65 20  .** valid frame 
13c0: 69 6e 20 74 68 65 20 57 41 4c 2e 20 20 54 68 65  in the WAL.  The
13d0: 20 72 65 61 64 65 72 20 75 73 65 73 20 74 68 69   reader uses thi
13e0: 73 20 72 65 63 6f 72 64 65 64 20 22 6d 78 46 72  s recorded "mxFr
13f0: 61 6d 65 22 20 76 61 6c 75 65 0a 2a 2a 20 66 6f  ame" value.** fo
1400: 72 20 61 6c 6c 20 73 75 62 73 65 71 75 65 6e 74  r all subsequent
1410: 20 72 65 61 64 20 6f 70 65 72 61 74 69 6f 6e 73   read operations
1420: 2e 20 20 4e 65 77 20 74 72 61 6e 73 61 63 74 69  .  New transacti
1430: 6f 6e 73 20 63 61 6e 20 62 65 20 61 70 70 65 6e  ons can be appen
1440: 64 65 64 0a 2a 2a 20 74 6f 20 74 68 65 20 57 41  ded.** to the WA
1450: 4c 2c 20 62 75 74 20 61 73 20 6c 6f 6e 67 20 61  L, but as long a
1460: 73 20 74 68 65 20 72 65 61 64 65 72 20 75 73 65  s the reader use
1470: 73 20 69 74 73 20 6f 72 69 67 69 6e 61 6c 20 6d  s its original m
1480: 78 46 72 61 6d 65 20 76 61 6c 75 65 0a 2a 2a 20  xFrame value.** 
1490: 61 6e 64 20 69 67 6e 6f 72 65 73 20 74 68 65 20  and ignores the 
14a0: 6e 65 77 6c 79 20 61 70 70 65 6e 64 65 64 20 63  newly appended c
14b0: 6f 6e 74 65 6e 74 2c 20 69 74 20 77 69 6c 6c 20  ontent, it will 
14c0: 73 65 65 20 61 20 63 6f 6e 73 69 73 74 65 6e 74  see a consistent
14d0: 20 73 6e 61 70 73 68 6f 74 0a 2a 2a 20 6f 66 20   snapshot.** of 
14e0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 72 6f  the database fro
14f0: 6d 20 61 20 73 69 6e 67 6c 65 20 70 6f 69 6e 74  m a single point
1500: 20 69 6e 20 74 69 6d 65 2e 20 20 54 68 69 73 20   in time.  This 
1510: 74 65 63 68 6e 69 71 75 65 20 61 6c 6c 6f 77 73  technique allows
1520: 0a 2a 2a 20 6d 75 6c 74 69 70 6c 65 20 63 6f 6e  .** multiple con
1530: 63 75 72 72 65 6e 74 20 72 65 61 64 65 72 73 20  current readers 
1540: 74 6f 20 76 69 65 77 20 64 69 66 66 65 72 65 6e  to view differen
1550: 74 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68  t versions of th
1560: 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 63 6f  e database.** co
1570: 6e 74 65 6e 74 20 73 69 6d 75 6c 74 61 6e 65 6f  ntent simultaneo
1580: 75 73 6c 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  usly..**.** The 
1590: 72 65 61 64 65 72 20 61 6c 67 6f 72 69 74 68 6d  reader algorithm
15a0: 20 69 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73   in the previous
15b0: 20 70 61 72 61 67 72 61 70 68 73 20 77 6f 72 6b   paragraphs work
15c0: 73 20 63 6f 72 72 65 63 74 6c 79 2c 20 62 75 74  s correctly, but
15d0: 20 0a 2a 2a 20 62 65 63 61 75 73 65 20 66 72 61   .** because fra
15e0: 6d 65 73 20 66 6f 72 20 70 61 67 65 20 50 20 63  mes for page P c
15f0: 61 6e 20 61 70 70 65 61 72 20 61 6e 79 77 68 65  an appear anywhe
1600: 72 65 20 77 69 74 68 69 6e 20 74 68 65 20 57 41  re within the WA
1610: 4c 2c 20 74 68 65 0a 2a 2a 20 72 65 61 64 65 72  L, the.** reader
1620: 20 68 61 73 20 74 6f 20 73 63 61 6e 20 74 68 65   has to scan the
1630: 20 65 6e 74 69 72 65 20 57 41 4c 20 6c 6f 6f 6b   entire WAL look
1640: 69 6e 67 20 66 6f 72 20 70 61 67 65 20 50 20 66  ing for page P f
1650: 72 61 6d 65 73 2e 20 20 49 66 20 74 68 65 0a 2a  rames.  If the.*
1660: 2a 20 57 41 4c 20 69 73 20 6c 61 72 67 65 20 28  * WAL is large (
1670: 6d 75 6c 74 69 70 6c 65 20 6d 65 67 61 62 79 74  multiple megabyt
1680: 65 73 20 69 73 20 74 79 70 69 63 61 6c 29 20 74  es is typical) t
1690: 68 61 74 20 73 63 61 6e 20 63 61 6e 20 62 65 20  hat scan can be 
16a0: 73 6c 6f 77 2c 0a 2a 2a 20 61 6e 64 20 72 65 61  slow,.** and rea
16b0: 64 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 73 75  d performance su
16c0: 66 66 65 72 73 2e 20 20 54 6f 20 6f 76 65 72 63  ffers.  To overc
16d0: 6f 6d 65 20 74 68 69 73 20 70 72 6f 62 6c 65 6d  ome this problem
16e0: 2c 20 61 20 73 65 70 61 72 61 74 65 0a 2a 2a 20  , a separate.** 
16f0: 64 61 74 61 20 73 74 72 75 63 74 75 72 65 20 63  data structure c
1700: 61 6c 6c 65 64 20 74 68 65 20 77 61 6c 2d 69 6e  alled the wal-in
1710: 64 65 78 20 69 73 20 6d 61 69 6e 74 61 69 6e 65  dex is maintaine
1720: 64 20 74 6f 20 65 78 70 65 64 69 74 65 20 74 68  d to expedite th
1730: 65 0a 2a 2a 20 73 65 61 72 63 68 20 66 6f 72 20  e.** search for 
1740: 66 72 61 6d 65 73 20 6f 66 20 61 20 70 61 72 74  frames of a part
1750: 69 63 75 6c 61 72 20 70 61 67 65 2e 0a 2a 2a 20  icular page..** 
1760: 0a 2a 2a 20 57 41 4c 2d 49 4e 44 45 58 20 46 4f  .** WAL-INDEX FO
1770: 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 43 6f 6e 63 65  RMAT.**.** Conce
1780: 70 74 75 61 6c 6c 79 2c 20 74 68 65 20 77 61 6c  ptually, the wal
1790: 2d 69 6e 64 65 78 20 69 73 20 73 68 61 72 65 64  -index is shared
17a0: 20 6d 65 6d 6f 72 79 2c 20 74 68 6f 75 67 68 20   memory, though 
17b0: 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  VFS implementati
17c0: 6f 6e 73 0a 2a 2a 20 6d 69 67 68 74 20 63 68 6f  ons.** might cho
17d0: 6f 73 65 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74  ose to implement
17e0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 75   the wal-index u
17f0: 73 69 6e 67 20 61 20 6d 6d 61 70 70 65 64 20 66  sing a mmapped f
1800: 69 6c 65 2e 20 20 42 65 63 61 75 73 65 0a 2a 2a  ile.  Because.**
1810: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69   the wal-index i
1820: 73 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 2c  s shared memory,
1830: 20 53 51 4c 69 74 65 20 64 6f 65 73 20 6e 6f 74   SQLite does not
1840: 20 73 75 70 70 6f 72 74 20 6a 6f 75 72 6e 61 6c   support journal
1850: 5f 6d 6f 64 65 3d 57 41 4c 20 0a 2a 2a 20 6f 6e  _mode=WAL .** on
1860: 20 61 20 6e 65 74 77 6f 72 6b 20 66 69 6c 65 73   a network files
1870: 79 73 74 65 6d 2e 20 20 41 6c 6c 20 75 73 65 72  ystem.  All user
1880: 73 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  s of the databas
1890: 65 20 6d 75 73 74 20 62 65 20 61 62 6c 65 20 74  e must be able t
18a0: 6f 0a 2a 2a 20 73 68 61 72 65 20 6d 65 6d 6f 72  o.** share memor
18b0: 79 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61 6c  y..**.** The wal
18c0: 2d 69 6e 64 65 78 20 69 73 20 74 72 61 6e 73 69  -index is transi
18d0: 65 6e 74 2e 20 20 41 66 74 65 72 20 61 20 63 72  ent.  After a cr
18e0: 61 73 68 2c 20 74 68 65 20 77 61 6c 2d 69 6e 64  ash, the wal-ind
18f0: 65 78 20 63 61 6e 20 28 61 6e 64 20 73 68 6f 75  ex can (and shou
1900: 6c 64 0a 2a 2a 20 62 65 29 20 72 65 63 6f 6e 73  ld.** be) recons
1910: 74 72 75 63 74 65 64 20 66 72 6f 6d 20 74 68 65  tructed from the
1920: 20 6f 72 69 67 69 6e 61 6c 20 57 41 4c 20 66 69   original WAL fi
1930: 6c 65 2e 20 20 49 6e 20 66 61 63 74 2c 20 74 68  le.  In fact, th
1940: 65 20 56 46 53 20 69 73 20 72 65 71 75 69 72 65  e VFS is require
1950: 64 0a 2a 2a 20 74 6f 20 65 69 74 68 65 72 20 74  d.** to either t
1960: 72 75 6e 63 61 74 65 20 6f 72 20 7a 65 72 6f 20  runcate or zero 
1970: 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 74 68  the header of th
1980: 65 20 77 61 6c 2d 69 6e 64 65 78 20 77 68 65 6e  e wal-index when
1990: 20 74 68 65 20 6c 61 73 74 0a 2a 2a 20 63 6f 6e   the last.** con
19a0: 6e 65 63 74 69 6f 6e 20 74 6f 20 69 74 20 63 6c  nection to it cl
19b0: 6f 73 65 73 2e 20 20 42 65 63 61 75 73 65 20 74  oses.  Because t
19c0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
19d0: 74 72 61 6e 73 69 65 6e 74 2c 20 69 74 20 63 61  transient, it ca
19e0: 6e 0a 2a 2a 20 75 73 65 20 61 6e 20 61 72 63 68  n.** use an arch
19f0: 69 74 65 63 74 75 72 65 2d 73 70 65 63 69 66 69  itecture-specifi
1a00: 63 20 66 6f 72 6d 61 74 3b 20 69 74 20 64 6f 65  c format; it doe
1a10: 73 20 6e 6f 74 20 68 61 76 65 20 74 6f 20 62 65  s not have to be
1a20: 20 63 72 6f 73 73 2d 70 6c 61 74 66 6f 72 6d 2e   cross-platform.
1a30: 0a 2a 2a 20 48 65 6e 63 65 2c 20 75 6e 6c 69 6b  .** Hence, unlik
1a40: 65 20 74 68 65 20 64 61 74 61 62 61 73 65 20 61  e the database a
1a50: 6e 64 20 57 41 4c 20 66 69 6c 65 20 66 6f 72 6d  nd WAL file form
1a60: 61 74 73 20 77 68 69 63 68 20 73 74 6f 72 65 20  ats which store 
1a70: 61 6c 6c 20 76 61 6c 75 65 73 0a 2a 2a 20 61 73  all values.** as
1a80: 20 62 69 67 20 65 6e 64 69 61 6e 2c 20 74 68 65   big endian, the
1a90: 20 77 61 6c 2d 69 6e 64 65 78 20 63 61 6e 20 73   wal-index can s
1aa0: 74 6f 72 65 20 6d 75 6c 74 69 2d 62 79 74 65 20  tore multi-byte 
1ab0: 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20 6e 61  values in the na
1ac0: 74 69 76 65 0a 2a 2a 20 62 79 74 65 20 6f 72 64  tive.** byte ord
1ad0: 65 72 20 6f 66 20 74 68 65 20 68 6f 73 74 20 63  er of the host c
1ae0: 6f 6d 70 75 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 54  omputer..**.** T
1af0: 68 65 20 70 75 72 70 6f 73 65 20 6f 66 20 74 68  he purpose of th
1b00: 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 74  e wal-index is t
1b10: 6f 20 61 6e 73 77 65 72 20 74 68 69 73 20 71 75  o answer this qu
1b20: 65 73 74 69 6f 6e 20 71 75 69 63 6b 6c 79 3a 20  estion quickly: 
1b30: 20 47 69 76 65 6e 0a 2a 2a 20 61 20 70 61 67 65   Given.** a page
1b40: 20 6e 75 6d 62 65 72 20 50 2c 20 72 65 74 75 72   number P, retur
1b50: 6e 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74  n the index of t
1b60: 68 65 20 6c 61 73 74 20 66 72 61 6d 65 20 66 6f  he last frame fo
1b70: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
1b80: 57 41 4c 2c 0a 2a 2a 20 6f 72 20 72 65 74 75 72  WAL,.** or retur
1b90: 6e 20 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20  n NULL if there 
1ba0: 61 72 65 20 6e 6f 20 66 72 61 6d 65 73 20 66 6f  are no frames fo
1bb0: 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65 20  r page P in the 
1bc0: 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77  WAL..**.** The w
1bd0: 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69 73 74  al-index consist
1be0: 73 20 6f 66 20 61 20 68 65 61 64 65 72 20 72 65  s of a header re
1bf0: 67 69 6f 6e 2c 20 66 6f 6c 6c 6f 77 65 64 20 62  gion, followed b
1c00: 79 20 61 6e 20 6f 6e 65 20 6f 72 0a 2a 2a 20 6d  y an one or.** m
1c10: 6f 72 65 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73  ore index blocks
1c20: 2e 20 20 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77 61  .  .**.** The wa
1c30: 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 63  l-index header c
1c40: 6f 6e 74 61 69 6e 73 20 74 68 65 20 74 6f 74 61  ontains the tota
1c50: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d  l number of fram
1c60: 65 73 20 77 69 74 68 69 6e 20 74 68 65 20 57 41  es within the WA
1c70: 4c 0a 2a 2a 20 69 6e 20 74 68 65 20 74 68 65 20  L.** in the the 
1c80: 6d 78 46 72 61 6d 65 20 66 69 65 6c 64 2e 20 20  mxFrame field.  
1c90: 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 69 6e 64 65  .**.** Each inde
1ca0: 78 20 62 6c 6f 63 6b 20 65 78 63 65 70 74 20 66  x block except f
1cb0: 6f 72 20 74 68 65 20 66 69 72 73 74 20 63 6f 6e  or the first con
1cc0: 74 61 69 6e 73 20 69 6e 66 6f 72 6d 61 74 69 6f  tains informatio
1cd0: 6e 20 6f 6e 20 0a 2a 2a 20 48 41 53 48 54 41 42  n on .** HASHTAB
1ce0: 4c 45 5f 4e 50 41 47 45 20 66 72 61 6d 65 73 2e  LE_NPAGE frames.
1cf0: 20 54 68 65 20 66 69 72 73 74 20 69 6e 64 65 78   The first index
1d00: 20 62 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20   block contains 
1d10: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 6f 6e 0a 2a  information on.*
1d20: 2a 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  * HASHTABLE_NPAG
1d30: 45 5f 4f 4e 45 20 66 72 61 6d 65 73 2e 20 54 68  E_ONE frames. Th
1d40: 65 20 76 61 6c 75 65 73 20 6f 66 20 48 41 53 48  e values of HASH
1d50: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 20  TABLE_NPAGE_ONE 
1d60: 61 6e 64 20 0a 2a 2a 20 48 41 53 48 54 41 42 4c  and .** HASHTABL
1d70: 45 5f 4e 50 41 47 45 20 61 72 65 20 73 65 6c 65  E_NPAGE are sele
1d80: 63 74 65 64 20 73 6f 20 74 68 61 74 20 74 6f 67  cted so that tog
1d90: 65 74 68 65 72 20 74 68 65 20 77 61 6c 2d 69 6e  ether the wal-in
1da0: 64 65 78 20 68 65 61 64 65 72 20 61 6e 64 0a 2a  dex header and.*
1db0: 2a 20 66 69 72 73 74 20 69 6e 64 65 78 20 62 6c  * first index bl
1dc0: 6f 63 6b 20 61 72 65 20 74 68 65 20 73 61 6d 65  ock are the same
1dd0: 20 73 69 7a 65 20 61 73 20 61 6c 6c 20 6f 74 68   size as all oth
1de0: 65 72 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73 20  er index blocks 
1df0: 69 6e 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e  in the.** wal-in
1e00: 64 65 78 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20  dex..**.** Each 
1e10: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 63 6f 6e 74  index block cont
1e20: 61 69 6e 73 20 74 77 6f 20 73 65 63 74 69 6f 6e  ains two section
1e30: 73 2c 20 61 20 70 61 67 65 2d 6d 61 70 70 69 6e  s, a page-mappin
1e40: 67 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20  g that contains 
1e50: 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20  the.** database 
1e60: 70 61 67 65 20 6e 75 6d 62 65 72 20 61 73 73 6f  page number asso
1e70: 63 69 61 74 65 64 20 77 69 74 68 20 65 61 63 68  ciated with each
1e80: 20 77 61 6c 20 66 72 61 6d 65 2c 20 61 6e 64 20   wal frame, and 
1e90: 61 20 68 61 73 68 2d 74 61 62 6c 65 20 0a 2a 2a  a hash-table .**
1ea0: 20 74 68 61 74 20 61 6c 6c 6f 77 73 20 72 65 61   that allows rea
1eb0: 64 65 72 73 20 74 6f 20 71 75 65 72 79 20 61 6e  ders to query an
1ec0: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 66 6f 72   index block for
1ed0: 20 61 20 73 70 65 63 69 66 69 63 20 70 61 67 65   a specific page
1ee0: 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20 54 68 65 20   number..** The 
1ef0: 70 61 67 65 2d 6d 61 70 70 69 6e 67 20 69 73 20  page-mapping is 
1f00: 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53 48  an array of HASH
1f10: 54 41 42 4c 45 5f 4e 50 41 47 45 20 28 6f 72 20  TABLE_NPAGE (or 
1f20: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
1f30: 4f 4e 45 0a 2a 2a 20 66 6f 72 20 74 68 65 20 66  ONE.** for the f
1f40: 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b  irst index block
1f50: 29 20 33 32 2d 62 69 74 20 70 61 67 65 20 6e 75  ) 32-bit page nu
1f60: 6d 62 65 72 73 2e 20 54 68 65 20 66 69 72 73 74  mbers. The first
1f70: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 0a 2a   entry in the .*
1f80: 2a 20 66 69 72 73 74 20 69 6e 64 65 78 2d 62 6c  * first index-bl
1f90: 6f 63 6b 20 63 6f 6e 74 61 69 6e 73 20 74 68 65  ock contains the
1fa0: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6e   database page n
1fb0: 75 6d 62 65 72 20 63 6f 72 72 65 73 70 6f 6e 64  umber correspond
1fc0: 69 6e 67 20 74 6f 20 74 68 65 0a 2a 2a 20 66 69  ing to the.** fi
1fd0: 72 73 74 20 66 72 61 6d 65 20 69 6e 20 74 68 65  rst frame in the
1fe0: 20 57 41 4c 20 66 69 6c 65 2e 20 54 68 65 20 66   WAL file. The f
1ff0: 69 72 73 74 20 65 6e 74 72 79 20 69 6e 20 74 68  irst entry in th
2000: 65 20 73 65 63 6f 6e 64 20 69 6e 64 65 78 20 62  e second index b
2010: 6c 6f 63 6b 0a 2a 2a 20 69 6e 20 74 68 65 20 57  lock.** in the W
2020: 41 4c 20 66 69 6c 65 20 63 6f 72 72 65 73 70 6f  AL file correspo
2030: 6e 64 73 20 74 6f 20 74 68 65 20 28 48 41 53 48  nds to the (HASH
2040: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b  TABLE_NPAGE_ONE+
2050: 31 29 74 68 20 66 72 61 6d 65 20 69 6e 0a 2a 2a  1)th frame in.**
2060: 20 74 68 65 20 6c 6f 67 2c 20 61 6e 64 20 73 6f   the log, and so
2070: 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c   on..**.** The l
2080: 61 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20  ast index block 
2090: 69 6e 20 61 20 77 61 6c 2d 69 6e 64 65 78 20 75  in a wal-index u
20a0: 73 75 61 6c 6c 79 20 63 6f 6e 74 61 69 6e 73 20  sually contains 
20b0: 6c 65 73 73 20 74 68 61 6e 20 74 68 65 20 66 75  less than the fu
20c0: 6c 6c 0a 2a 2a 20 63 6f 6d 70 6c 65 6d 65 6e 74  ll.** complement
20d0: 20 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e 50   of HASHTABLE_NP
20e0: 41 47 45 20 28 6f 72 20 48 41 53 48 54 41 42 4c  AGE (or HASHTABL
20f0: 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 20 70 61 67  E_NPAGE_ONE) pag
2100: 65 2d 6e 75 6d 62 65 72 73 2c 0a 2a 2a 20 64 65  e-numbers,.** de
2110: 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20 63  pending on the c
2120: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 57  ontents of the W
2130: 41 4c 20 66 69 6c 65 2e 20 54 68 69 73 20 64 6f  AL file. This do
2140: 65 73 20 6e 6f 74 20 63 68 61 6e 67 65 20 74 68  es not change th
2150: 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74 65 64 20 73  e.** allocated s
2160: 69 7a 65 20 6f 66 20 74 68 65 20 70 61 67 65 2d  ize of the page-
2170: 6d 61 70 70 69 6e 67 20 61 72 72 61 79 20 2d 20  mapping array - 
2180: 74 68 65 20 70 61 67 65 2d 6d 61 70 70 69 6e 67  the page-mapping
2190: 20 61 72 72 61 79 20 6d 65 72 65 6c 79 0a 2a 2a   array merely.**
21a0: 20 63 6f 6e 74 61 69 6e 73 20 75 6e 75 73 65 64   contains unused
21b0: 20 65 6e 74 72 69 65 73 2e 0a 2a 2a 0a 2a 2a 20   entries..**.** 
21c0: 45 76 65 6e 20 77 69 74 68 6f 75 74 20 75 73 69  Even without usi
21d0: 6e 67 20 74 68 65 20 68 61 73 68 20 74 61 62 6c  ng the hash tabl
21e0: 65 2c 20 74 68 65 20 6c 61 73 74 20 66 72 61 6d  e, the last fram
21f0: 65 20 66 6f 72 20 70 61 67 65 20 50 0a 2a 2a 20  e for page P.** 
2200: 63 61 6e 20 62 65 20 66 6f 75 6e 64 20 62 79 20  can be found by 
2210: 73 63 61 6e 6e 69 6e 67 20 74 68 65 20 70 61 67  scanning the pag
2220: 65 2d 6d 61 70 70 69 6e 67 20 73 65 63 74 69 6f  e-mapping sectio
2230: 6e 73 20 6f 66 20 65 61 63 68 20 69 6e 64 65 78  ns of each index
2240: 20 62 6c 6f 63 6b 0a 2a 2a 20 73 74 61 72 74 69   block.** starti
2250: 6e 67 20 77 69 74 68 20 74 68 65 20 6c 61 73 74  ng with the last
2260: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 61 6e 64   index block and
2270: 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20 74   moving toward t
2280: 68 65 20 66 69 72 73 74 2c 20 61 6e 64 0a 2a 2a  he first, and.**
2290: 20 77 69 74 68 69 6e 20 65 61 63 68 20 69 6e 64   within each ind
22a0: 65 78 20 62 6c 6f 63 6b 2c 20 73 74 61 72 74 69  ex block, starti
22b0: 6e 67 20 61 74 20 74 68 65 20 65 6e 64 20 61 6e  ng at the end an
22c0: 64 20 6d 6f 76 69 6e 67 20 74 6f 77 61 72 64 20  d moving toward 
22d0: 74 68 65 0a 2a 2a 20 62 65 67 69 6e 6e 69 6e 67  the.** beginning
22e0: 2e 20 20 54 68 65 20 66 69 72 73 74 20 65 6e 74  .  The first ent
22f0: 72 79 20 74 68 61 74 20 65 71 75 61 6c 73 20 50  ry that equals P
2300: 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20   corresponds to 
2310: 74 68 65 20 66 72 61 6d 65 0a 2a 2a 20 68 6f 6c  the frame.** hol
2320: 64 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e 74  ding the content
2330: 20 66 6f 72 20 74 68 61 74 20 70 61 67 65 2e 0a   for that page..
2340: 2a 2a 0a 2a 2a 20 54 68 65 20 68 61 73 68 20 74  **.** The hash t
2350: 61 62 6c 65 20 63 6f 6e 73 69 73 74 73 20 6f 66  able consists of
2360: 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54   HASHTABLE_NSLOT
2370: 20 31 36 2d 62 69 74 20 75 6e 73 69 67 6e 65 64   16-bit unsigned
2380: 20 69 6e 74 65 67 65 72 73 2e 0a 2a 2a 20 48 41   integers..** HA
2390: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 3d 20  SHTABLE_NSLOT = 
23a0: 32 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  2*HASHTABLE_NPAG
23b0: 45 2c 20 61 6e 64 20 74 68 65 72 65 20 69 73 20  E, and there is 
23c0: 6f 6e 65 20 65 6e 74 72 79 20 69 6e 20 74 68 65  one entry in the
23d0: 0a 2a 2a 20 68 61 73 68 20 74 61 62 6c 65 20 66  .** hash table f
23e0: 6f 72 20 65 61 63 68 20 70 61 67 65 20 6e 75 6d  or each page num
23f0: 62 65 72 20 69 6e 20 74 68 65 20 6d 61 70 70 69  ber in the mappi
2400: 6e 67 20 73 65 63 74 69 6f 6e 2c 20 73 6f 20 74  ng section, so t
2410: 68 65 20 68 61 73 68 20 0a 2a 2a 20 74 61 62 6c  he hash .** tabl
2420: 65 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20  e is never more 
2430: 74 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2e 20  than half full. 
2440: 20 54 68 65 20 65 78 70 65 63 74 65 64 20 6e 75   The expected nu
2450: 6d 62 65 72 20 6f 66 20 63 6f 6c 6c 69 73 69 6f  mber of collisio
2460: 6e 73 20 0a 2a 2a 20 70 72 69 6f 72 20 74 6f 20  ns .** prior to 
2470: 66 69 6e 64 69 6e 67 20 61 20 6d 61 74 63 68 20  finding a match 
2480: 69 73 20 31 2e 20 20 45 61 63 68 20 65 6e 74 72  is 1.  Each entr
2490: 79 20 6f 66 20 74 68 65 20 68 61 73 68 20 74 61  y of the hash ta
24a0: 62 6c 65 20 69 73 20 61 6e 0a 2a 2a 20 31 2d 62  ble is an.** 1-b
24b0: 61 73 65 64 20 69 6e 64 65 78 20 6f 66 20 61 6e  ased index of an
24c0: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 6d 61   entry in the ma
24d0: 70 70 69 6e 67 20 73 65 63 74 69 6f 6e 20 6f 66  pping section of
24e0: 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20 69 6e 64   the same.** ind
24f0: 65 78 20 62 6c 6f 63 6b 2e 20 20 20 4c 65 74 20  ex block.   Let 
2500: 4b 20 62 65 20 74 68 65 20 31 2d 62 61 73 65 64  K be the 1-based
2510: 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20 6c 61   index of the la
2520: 72 67 65 73 74 20 65 6e 74 72 79 20 69 6e 0a 2a  rgest entry in.*
2530: 2a 20 74 68 65 20 6d 61 70 70 69 6e 67 20 73 65  * the mapping se
2540: 63 74 69 6f 6e 2e 20 20 28 46 6f 72 20 69 6e 64  ction.  (For ind
2550: 65 78 20 62 6c 6f 63 6b 73 20 6f 74 68 65 72 20  ex blocks other 
2560: 74 68 61 6e 20 74 68 65 20 6c 61 73 74 2c 20 4b  than the last, K
2570: 20 77 69 6c 6c 0a 2a 2a 20 61 6c 77 61 79 73 20   will.** always 
2580: 62 65 20 65 78 61 63 74 6c 79 20 48 41 53 48 54  be exactly HASHT
2590: 41 42 4c 45 5f 4e 50 41 47 45 20 28 34 30 39 36  ABLE_NPAGE (4096
25a0: 29 20 61 6e 64 20 66 6f 72 20 74 68 65 20 6c 61  ) and for the la
25b0: 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b 0a 2a  st index block.*
25c0: 2a 20 4b 20 77 69 6c 6c 20 62 65 20 28 6d 78 46  * K will be (mxF
25d0: 72 61 6d 65 25 48 41 53 48 54 41 42 4c 45 5f 4e  rame%HASHTABLE_N
25e0: 50 41 47 45 29 2e 29 20 20 55 6e 75 73 65 64 20  PAGE).)  Unused 
25f0: 73 6c 6f 74 73 20 6f 66 20 74 68 65 20 68 61 73  slots of the has
2600: 68 20 74 61 62 6c 65 0a 2a 2a 20 63 6f 6e 74 61  h table.** conta
2610: 69 6e 20 61 20 76 61 6c 75 65 20 6f 66 20 30 2e  in a value of 0.
2620: 0a 2a 2a 0a 2a 2a 20 54 6f 20 6c 6f 6f 6b 20 66  .**.** To look f
2630: 6f 72 20 70 61 67 65 20 50 20 69 6e 20 74 68 65  or page P in the
2640: 20 68 61 73 68 20 74 61 62 6c 65 2c 20 66 69 72   hash table, fir
2650: 73 74 20 63 6f 6d 70 75 74 65 20 61 20 68 61 73  st compute a has
2660: 68 20 69 4b 65 79 20 6f 6e 0a 2a 2a 20 50 20 61  h iKey on.** P a
2670: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a  s follows:.**.**
2680: 20 20 20 20 20 20 69 4b 65 79 20 3d 20 28 50 20        iKey = (P 
2690: 2a 20 33 38 33 29 20 25 20 48 41 53 48 54 41 42  * 383) % HASHTAB
26a0: 4c 45 5f 4e 53 4c 4f 54 0a 2a 2a 0a 2a 2a 20 54  LE_NSLOT.**.** T
26b0: 68 65 6e 20 73 74 61 72 74 20 73 63 61 6e 6e 69  hen start scanni
26c0: 6e 67 20 65 6e 74 72 69 65 73 20 6f 66 20 74 68  ng entries of th
26d0: 65 20 68 61 73 68 20 74 61 62 6c 65 2c 20 73 74  e hash table, st
26e0: 61 72 74 69 6e 67 20 77 69 74 68 20 69 4b 65 79  arting with iKey
26f0: 0a 2a 2a 20 28 77 72 61 70 70 69 6e 67 20 61 72  .** (wrapping ar
2700: 6f 75 6e 64 20 74 6f 20 74 68 65 20 62 65 67 69  ound to the begi
2710: 6e 6e 69 6e 67 20 77 68 65 6e 20 74 68 65 20 65  nning when the e
2720: 6e 64 20 6f 66 20 74 68 65 20 68 61 73 68 20 74  nd of the hash t
2730: 61 62 6c 65 20 69 73 0a 2a 2a 20 72 65 61 63 68  able is.** reach
2740: 65 64 29 20 75 6e 74 69 6c 20 61 6e 20 75 6e 75  ed) until an unu
2750: 73 65 64 20 68 61 73 68 20 73 6c 6f 74 20 69 73  sed hash slot is
2760: 20 66 6f 75 6e 64 2e 20 4c 65 74 20 74 68 65 20   found. Let the 
2770: 66 69 72 73 74 20 75 6e 75 73 65 64 20 73 6c 6f  first unused slo
2780: 74 0a 2a 2a 20 62 65 20 61 74 20 69 6e 64 65 78  t.** be at index
2790: 20 69 55 6e 75 73 65 64 2e 20 20 28 69 55 6e 75   iUnused.  (iUnu
27a0: 73 65 64 20 6d 69 67 68 74 20 62 65 20 6c 65 73  sed might be les
27b0: 73 20 74 68 61 6e 20 69 4b 65 79 20 69 66 20 74  s than iKey if t
27c0: 68 65 72 65 20 77 61 73 0a 2a 2a 20 77 72 61 70  here was.** wrap
27d0: 2d 61 72 6f 75 6e 64 2e 29 20 42 65 63 61 75 73  -around.) Becaus
27e0: 65 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  e the hash table
27f0: 20 69 73 20 6e 65 76 65 72 20 6d 6f 72 65 20 74   is never more t
2800: 68 61 6e 20 68 61 6c 66 20 66 75 6c 6c 2c 0a 2a  han half full,.*
2810: 2a 20 74 68 65 20 73 65 61 72 63 68 20 69 73 20  * the search is 
2820: 67 75 61 72 61 6e 74 65 65 64 20 74 6f 20 65 76  guaranteed to ev
2830: 65 6e 74 75 61 6c 6c 79 20 68 69 74 20 61 6e 20  entually hit an 
2840: 75 6e 75 73 65 64 20 65 6e 74 72 79 2e 20 20 4c  unused entry.  L
2850: 65 74 20 0a 2a 2a 20 69 4d 61 78 20 62 65 20 74  et .** iMax be t
2860: 68 65 20 76 61 6c 75 65 20 62 65 74 77 65 65 6e  he value between
2870: 20 69 4b 65 79 20 61 6e 64 20 69 55 6e 75 73 65   iKey and iUnuse
2880: 64 2c 20 63 6c 6f 73 65 73 74 20 74 6f 20 69 55  d, closest to iU
2890: 6e 75 73 65 64 2c 0a 2a 2a 20 77 68 65 72 65 20  nused,.** where 
28a0: 61 48 61 73 68 5b 69 4d 61 78 5d 3d 3d 50 2e 20  aHash[iMax]==P. 
28b0: 20 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20   If there is no 
28c0: 69 4d 61 78 20 65 6e 74 72 79 20 28 69 66 20 74  iMax entry (if t
28d0: 68 65 72 65 20 65 78 69 73 74 73 0a 2a 2a 20 6e  here exists.** n
28e0: 6f 20 68 61 73 68 20 73 6c 6f 74 20 73 75 63 68  o hash slot such
28f0: 20 74 68 61 74 20 61 48 61 73 68 5b 69 5d 3d 3d   that aHash[i]==
2900: 70 29 20 74 68 65 6e 20 70 61 67 65 20 50 20 69  p) then page P i
2910: 73 20 6e 6f 74 20 69 6e 20 74 68 65 0a 2a 2a 20  s not in the.** 
2920: 63 75 72 72 65 6e 74 20 69 6e 64 65 78 20 62 6c  current index bl
2930: 6f 63 6b 2e 20 20 4f 74 68 65 72 77 69 73 65 20  ock.  Otherwise 
2940: 74 68 65 20 69 4d 61 78 2d 74 68 20 6d 61 70 70  the iMax-th mapp
2950: 69 6e 67 20 65 6e 74 72 79 20 6f 66 20 74 68 65  ing entry of the
2960: 0a 2a 2a 20 63 75 72 72 65 6e 74 20 69 6e 64 65  .** current inde
2970: 78 20 62 6c 6f 63 6b 20 63 6f 72 72 65 73 70 6f  x block correspo
2980: 6e 64 73 20 74 6f 20 74 68 65 20 6c 61 73 74 20  nds to the last 
2990: 65 6e 74 72 79 20 74 68 61 74 20 72 65 66 65 72  entry that refer
29a0: 65 6e 63 65 73 20 0a 2a 2a 20 70 61 67 65 20 50  ences .** page P
29b0: 2e 0a 2a 2a 0a 2a 2a 20 41 20 68 61 73 68 20 73  ..**.** A hash s
29c0: 65 61 72 63 68 20 62 65 67 69 6e 73 20 77 69 74  earch begins wit
29d0: 68 20 74 68 65 20 6c 61 73 74 20 69 6e 64 65 78  h the last index
29e0: 20 62 6c 6f 63 6b 20 61 6e 64 20 6d 6f 76 65 73   block and moves
29f0: 20 74 6f 77 61 72 64 20 74 68 65 0a 2a 2a 20 66   toward the.** f
2a00: 69 72 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b  irst index block
2a10: 2c 20 6c 6f 6f 6b 69 6e 67 20 66 6f 72 20 65 6e  , looking for en
2a20: 74 72 69 65 73 20 63 6f 72 72 65 73 70 6f 6e 64  tries correspond
2a30: 69 6e 67 20 74 6f 20 70 61 67 65 20 50 2e 20 20  ing to page P.  
2a40: 4f 6e 0a 2a 2a 20 61 76 65 72 61 67 65 2c 20 6f  On.** average, o
2a50: 6e 6c 79 20 74 77 6f 20 6f 72 20 74 68 72 65 65  nly two or three
2a60: 20 73 6c 6f 74 73 20 69 6e 20 65 61 63 68 20 69   slots in each i
2a70: 6e 64 65 78 20 62 6c 6f 63 6b 20 6e 65 65 64 20  ndex block need 
2a80: 74 6f 20 62 65 0a 2a 2a 20 65 78 61 6d 69 6e 65  to be.** examine
2a90: 64 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 65 69  d in order to ei
2aa0: 74 68 65 72 20 66 69 6e 64 20 74 68 65 20 6c 61  ther find the la
2ab0: 73 74 20 65 6e 74 72 79 20 66 6f 72 20 70 61 67  st entry for pag
2ac0: 65 20 50 2c 20 6f 72 20 74 6f 0a 2a 2a 20 65 73  e P, or to.** es
2ad0: 74 61 62 6c 69 73 68 20 74 68 61 74 20 6e 6f 20  tablish that no 
2ae0: 73 75 63 68 20 65 6e 74 72 79 20 65 78 69 73 74  such entry exist
2af0: 73 20 69 6e 20 74 68 65 20 62 6c 6f 63 6b 2e 20  s in the block. 
2b00: 20 45 61 63 68 20 69 6e 64 65 78 20 62 6c 6f 63   Each index bloc
2b10: 6b 0a 2a 2a 20 68 6f 6c 64 73 20 6f 76 65 72 20  k.** holds over 
2b20: 34 30 30 30 20 65 6e 74 72 69 65 73 2e 20 20 53  4000 entries.  S
2b30: 6f 20 74 77 6f 20 6f 72 20 74 68 72 65 65 20 69  o two or three i
2b40: 6e 64 65 78 20 62 6c 6f 63 6b 73 20 61 72 65 20  ndex blocks are 
2b50: 73 75 66 66 69 63 69 65 6e 74 0a 2a 2a 20 74 6f  sufficient.** to
2b60: 20 63 6f 76 65 72 20 61 20 74 79 70 69 63 61 6c   cover a typical
2b70: 20 31 30 20 6d 65 67 61 62 79 74 65 20 57 41 4c   10 megabyte WAL
2b80: 20 66 69 6c 65 2c 20 61 73 73 75 6d 69 6e 67 20   file, assuming 
2b90: 31 4b 20 70 61 67 65 73 2e 20 20 38 20 6f 72 20  1K pages.  8 or 
2ba0: 31 30 0a 2a 2a 20 63 6f 6d 70 61 72 69 73 6f 6e  10.** comparison
2bb0: 73 20 28 6f 6e 20 61 76 65 72 61 67 65 29 20 73  s (on average) s
2bc0: 75 66 66 69 63 65 20 74 6f 20 65 69 74 68 65 72  uffice to either
2bd0: 20 6c 6f 63 61 74 65 20 61 20 66 72 61 6d 65 20   locate a frame 
2be0: 69 6e 20 74 68 65 0a 2a 2a 20 57 41 4c 20 6f 72  in the.** WAL or
2bf0: 20 74 6f 20 65 73 74 61 62 6c 69 73 68 20 74 68   to establish th
2c00: 61 74 20 74 68 65 20 66 72 61 6d 65 20 64 6f 65  at the frame doe
2c10: 73 20 6e 6f 74 20 65 78 69 73 74 20 69 6e 20 74  s not exist in t
2c20: 68 65 20 57 41 4c 2e 20 20 54 68 69 73 0a 2a 2a  he WAL.  This.**
2c30: 20 69 73 20 6d 75 63 68 20 66 61 73 74 65 72 20   is much faster 
2c40: 74 68 61 6e 20 73 63 61 6e 6e 69 6e 67 20 74 68  than scanning th
2c50: 65 20 65 6e 74 69 72 65 20 31 30 4d 42 20 57 41  e entire 10MB WA
2c60: 4c 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68  L..**.** Note th
2c70: 61 74 20 65 6e 74 72 69 65 73 20 61 72 65 20 61  at entries are a
2c80: 64 64 65 64 20 69 6e 20 6f 72 64 65 72 20 6f 66  dded in order of
2c90: 20 69 6e 63 72 65 61 73 69 6e 67 20 4b 2e 20 20   increasing K.  
2ca0: 48 65 6e 63 65 2c 20 6f 6e 65 0a 2a 2a 20 72 65  Hence, one.** re
2cb0: 61 64 65 72 20 6d 69 67 68 74 20 62 65 20 75 73  ader might be us
2cc0: 69 6e 67 20 73 6f 6d 65 20 76 61 6c 75 65 20 4b  ing some value K
2cd0: 30 20 61 6e 64 20 61 20 73 65 63 6f 6e 64 20 72  0 and a second r
2ce0: 65 61 64 65 72 20 74 68 61 74 20 73 74 61 72 74  eader that start
2cf0: 65 64 0a 2a 2a 20 61 74 20 61 20 6c 61 74 65 72  ed.** at a later
2d00: 20 74 69 6d 65 20 28 61 66 74 65 72 20 61 64 64   time (after add
2d10: 69 74 69 6f 6e 61 6c 20 74 72 61 6e 73 61 63 74  itional transact
2d20: 69 6f 6e 73 20 77 65 72 65 20 61 64 64 65 64 20  ions were added 
2d30: 74 6f 20 74 68 65 20 57 41 4c 0a 2a 2a 20 61 6e  to the WAL.** an
2d40: 64 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64  d to the wal-ind
2d50: 65 78 29 20 6d 69 67 68 74 20 62 65 20 75 73 69  ex) might be usi
2d60: 6e 67 20 61 20 64 69 66 66 65 72 65 6e 74 20 76  ng a different v
2d70: 61 6c 75 65 20 4b 31 2c 20 77 68 65 72 65 20 4b  alue K1, where K
2d80: 31 3e 4b 30 2e 0a 2a 2a 20 42 6f 74 68 20 72 65  1>K0..** Both re
2d90: 61 64 65 72 73 20 63 61 6e 20 75 73 65 20 74 68  aders can use th
2da0: 65 20 73 61 6d 65 20 68 61 73 68 20 74 61 62 6c  e same hash tabl
2db0: 65 20 61 6e 64 20 6d 61 70 70 69 6e 67 20 73 65  e and mapping se
2dc0: 63 74 69 6f 6e 20 74 6f 20 67 65 74 0a 2a 2a 20  ction to get.** 
2dd0: 74 68 65 20 63 6f 72 72 65 63 74 20 72 65 73 75  the correct resu
2de0: 6c 74 2e 20 20 54 68 65 72 65 20 6d 61 79 20 62  lt.  There may b
2df0: 65 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65  e entries in the
2e00: 20 68 61 73 68 20 74 61 62 6c 65 20 77 69 74 68   hash table with
2e10: 0a 2a 2a 20 4b 3e 4b 30 20 62 75 74 20 74 6f 20  .** K>K0 but to 
2e20: 74 68 65 20 66 69 72 73 74 20 72 65 61 64 65 72  the first reader
2e30: 2c 20 74 68 6f 73 65 20 65 6e 74 72 69 65 73 20  , those entries 
2e40: 77 69 6c 6c 20 61 70 70 65 61 72 20 74 6f 20 62  will appear to b
2e50: 65 20 75 6e 75 73 65 64 0a 2a 2a 20 73 6c 6f 74  e unused.** slot
2e60: 73 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61  s in the hash ta
2e70: 62 6c 65 20 61 6e 64 20 73 6f 20 74 68 65 20 66  ble and so the f
2e80: 69 72 73 74 20 72 65 61 64 65 72 20 77 69 6c 6c  irst reader will
2e90: 20 67 65 74 20 61 6e 20 61 6e 73 77 65 72 20 61   get an answer a
2ea0: 73 0a 2a 2a 20 69 66 20 6e 6f 20 76 61 6c 75 65  s.** if no value
2eb0: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20 4b  s greater than K
2ec0: 30 20 68 61 64 20 65 76 65 72 20 62 65 65 6e 20  0 had ever been 
2ed0: 69 6e 73 65 72 74 65 64 20 69 6e 74 6f 20 74 68  inserted into th
2ee0: 65 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20  e hash table.** 
2ef0: 69 6e 20 74 68 65 20 66 69 72 73 74 20 70 6c 61  in the first pla
2f00: 63 65 20 2d 20 77 68 69 63 68 20 69 73 20 77 68  ce - which is wh
2f10: 61 74 20 72 65 61 64 65 72 20 6f 6e 65 20 77 61  at reader one wa
2f20: 6e 74 73 2e 20 20 4d 65 61 6e 77 68 69 6c 65 2c  nts.  Meanwhile,
2f30: 20 74 68 65 0a 2a 2a 20 73 65 63 6f 6e 64 20 72   the.** second r
2f40: 65 61 64 65 72 20 75 73 69 6e 67 20 4b 31 20 77  eader using K1 w
2f50: 69 6c 6c 20 73 65 65 20 61 64 64 69 74 69 6f 6e  ill see addition
2f60: 61 6c 20 76 61 6c 75 65 73 20 74 68 61 74 20 77  al values that w
2f70: 65 72 65 20 69 6e 73 65 72 74 65 64 0a 2a 2a 20  ere inserted.** 
2f80: 6c 61 74 65 72 2c 20 77 68 69 63 68 20 69 73 20  later, which is 
2f90: 65 78 61 63 74 6c 79 20 77 68 61 74 20 72 65 61  exactly what rea
2fa0: 64 65 72 20 74 77 6f 20 77 61 6e 74 73 2e 20 20  der two wants.  
2fb0: 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20 61 20 72 6f  .**.** When a ro
2fc0: 6c 6c 62 61 63 6b 20 6f 63 63 75 72 73 2c 20 74  llback occurs, t
2fd0: 68 65 20 76 61 6c 75 65 20 6f 66 20 4b 20 69 73  he value of K is
2fe0: 20 64 65 63 72 65 61 73 65 64 2e 20 48 61 73 68   decreased. Hash
2ff0: 20 74 61 62 6c 65 20 65 6e 74 72 69 65 73 0a 2a   table entries.*
3000: 2a 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  * that correspon
3010: 64 20 74 6f 20 66 72 61 6d 65 73 20 67 72 65 61  d to frames grea
3020: 74 65 72 20 74 68 61 6e 20 74 68 65 20 6e 65 77  ter than the new
3030: 20 4b 20 76 61 6c 75 65 20 61 72 65 20 72 65 6d   K value are rem
3040: 6f 76 65 64 0a 2a 2a 20 66 72 6f 6d 20 74 68 65  oved.** from the
3050: 20 68 61 73 68 20 74 61 62 6c 65 20 61 74 20 74   hash table at t
3060: 68 69 73 20 70 6f 69 6e 74 2e 0a 2a 2f 0a 23 69  his point..*/.#i
3070: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
3080: 54 5f 57 41 4c 0a 0a 23 69 6e 63 6c 75 64 65 20  T_WAL..#include 
3090: 22 77 61 6c 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 54  "wal.h"../*.** T
30a0: 72 61 63 65 20 6f 75 74 70 75 74 20 6d 61 63 72  race output macr
30b0: 6f 73 0a 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65  os.*/.#if define
30c0: 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 26  d(SQLITE_TEST) &
30d0: 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  & defined(SQLITE
30e0: 5f 44 45 42 55 47 29 0a 69 6e 74 20 73 71 6c 69  _DEBUG).int sqli
30f0: 74 65 33 57 61 6c 54 72 61 63 65 20 3d 20 30 3b  te3WalTrace = 0;
3100: 0a 23 20 64 65 66 69 6e 65 20 57 41 4c 54 52 41  .# define WALTRA
3110: 43 45 28 58 29 20 20 69 66 28 73 71 6c 69 74 65  CE(X)  if(sqlite
3120: 33 57 61 6c 54 72 61 63 65 29 20 73 71 6c 69 74  3WalTrace) sqlit
3130: 65 33 44 65 62 75 67 50 72 69 6e 74 66 20 58 0a  e3DebugPrintf X.
3140: 23 65 6c 73 65 0a 23 20 64 65 66 69 6e 65 20 57  #else.# define W
3150: 41 4c 54 52 41 43 45 28 58 29 0a 23 65 6e 64 69  ALTRACE(X).#endi
3160: 66 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 6d 61 78  f../*.** The max
3170: 69 6d 75 6d 20 28 61 6e 64 20 6f 6e 6c 79 29 20  imum (and only) 
3180: 76 65 72 73 69 6f 6e 73 20 6f 66 20 74 68 65 20  versions of the 
3190: 77 61 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65  wal and wal-inde
31a0: 78 20 66 6f 72 6d 61 74 73 0a 2a 2a 20 74 68 61  x formats.** tha
31b0: 74 20 6d 61 79 20 62 65 20 69 6e 74 65 72 70 72  t may be interpr
31c0: 65 74 65 64 20 62 79 20 74 68 69 73 20 76 65 72  eted by this ver
31d0: 73 69 6f 6e 20 6f 66 20 53 51 4c 69 74 65 2e 0a  sion of SQLite..
31e0: 2a 2a 0a 2a 2a 20 49 66 20 61 20 63 6c 69 65 6e  **.** If a clien
31f0: 74 20 62 65 67 69 6e 73 20 72 65 63 6f 76 65 72  t begins recover
3200: 69 6e 67 20 61 20 57 41 4c 20 66 69 6c 65 20 61  ing a WAL file a
3210: 6e 64 20 66 69 6e 64 73 20 74 68 61 74 20 28 61  nd finds that (a
3220: 29 20 74 68 65 20 63 68 65 63 6b 73 75 6d 0a 2a  ) the checksum.*
3230: 2a 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20  * values in the 
3240: 77 61 6c 2d 68 65 61 64 65 72 20 61 72 65 20 63  wal-header are c
3250: 6f 72 72 65 63 74 20 61 6e 64 20 28 62 29 20 74  orrect and (b) t
3260: 68 65 20 76 65 72 73 69 6f 6e 20 66 69 65 6c 64  he version field
3270: 20 69 73 20 6e 6f 74 0a 2a 2a 20 57 41 4c 5f 4d   is not.** WAL_M
3280: 41 58 5f 56 45 52 53 49 4f 4e 2c 20 72 65 63 6f  AX_VERSION, reco
3290: 76 65 72 79 20 66 61 69 6c 73 20 61 6e 64 20 53  very fails and S
32a0: 51 4c 69 74 65 20 72 65 74 75 72 6e 73 20 53 51  QLite returns SQ
32b0: 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 2e 0a 2a  LITE_CANTOPEN..*
32c0: 2a 0a 2a 2a 20 53 69 6d 69 6c 61 72 6c 79 2c 20  *.** Similarly, 
32d0: 69 66 20 61 20 63 6c 69 65 6e 74 20 73 75 63 63  if a client succ
32e0: 65 73 73 66 75 6c 6c 79 20 72 65 61 64 73 20 61  essfully reads a
32f0: 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
3300: 72 20 28 69 2e 65 2e 20 74 68 65 20 0a 2a 2a 20  r (i.e. the .** 
3310: 63 68 65 63 6b 73 75 6d 20 74 65 73 74 20 69 73  checksum test is
3320: 20 73 75 63 63 65 73 73 66 75 6c 29 20 61 6e 64   successful) and
3330: 20 66 69 6e 64 73 20 74 68 61 74 20 74 68 65 20   finds that the 
3340: 76 65 72 73 69 6f 6e 20 66 69 65 6c 64 20 69 73  version field is
3350: 20 6e 6f 74 0a 2a 2a 20 57 41 4c 49 4e 44 45 58   not.** WALINDEX
3360: 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 2c 20 74 68  _MAX_VERSION, th
3370: 65 6e 20 6e 6f 20 72 65 61 64 2d 74 72 61 6e 73  en no read-trans
3380: 61 63 74 69 6f 6e 20 69 73 20 6f 70 65 6e 65 64  action is opened
3390: 20 61 6e 64 20 53 51 4c 69 74 65 0a 2a 2a 20 72   and SQLite.** r
33a0: 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f 43 41  eturns SQLITE_CA
33b0: 4e 54 4f 50 45 4e 2e 0a 2a 2f 0a 23 64 65 66 69  NTOPEN..*/.#defi
33c0: 6e 65 20 57 41 4c 5f 4d 41 58 5f 56 45 52 53 49  ne WAL_MAX_VERSI
33d0: 4f 4e 20 20 20 20 20 20 33 30 30 37 30 30 30 0a  ON      3007000.
33e0: 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58  #define WALINDEX
33f0: 5f 4d 41 58 5f 56 45 52 53 49 4f 4e 20 33 30 30  _MAX_VERSION 300
3400: 37 30 30 30 0a 0a 2f 2a 0a 2a 2a 20 49 6e 64 69  7000../*.** Indi
3410: 63 65 73 20 6f 66 20 76 61 72 69 6f 75 73 20 6c  ces of various l
3420: 6f 63 6b 69 6e 67 20 62 79 74 65 73 2e 20 20 20  ocking bytes.   
3430: 57 41 4c 5f 4e 52 45 41 44 45 52 20 69 73 20 74  WAL_NREADER is t
3440: 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20  he number.** of 
3450: 61 76 61 69 6c 61 62 6c 65 20 72 65 61 64 65 72  available reader
3460: 20 6c 6f 63 6b 73 20 61 6e 64 20 73 68 6f 75 6c   locks and shoul
3470: 64 20 62 65 20 61 74 20 6c 65 61 73 74 20 33 2e  d be at least 3.
3480: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f  .*/.#define WAL_
3490: 57 52 49 54 45 5f 4c 4f 43 4b 20 20 20 20 20 20  WRITE_LOCK      
34a0: 20 20 20 30 0a 23 64 65 66 69 6e 65 20 57 41 4c     0.#define WAL
34b0: 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45 20 20  _ALL_BUT_WRITE  
34c0: 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57 41      1.#define WA
34d0: 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 20 20 20 20  L_CKPT_LOCK     
34e0: 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20 57       1.#define W
34f0: 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 20  AL_RECOVER_LOCK 
3500: 20 20 20 20 20 20 32 0a 23 64 65 66 69 6e 65 20        2.#define 
3510: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 49 29  WAL_READ_LOCK(I)
3520: 20 20 20 20 20 20 20 28 33 2b 28 49 29 29 0a 23         (3+(I)).#
3530: 64 65 66 69 6e 65 20 57 41 4c 5f 4e 52 45 41 44  define WAL_NREAD
3540: 45 52 20 20 20 20 20 20 20 20 20 20 20 20 28 53  ER            (S
3550: 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43 4b 2d  QLITE_SHM_NLOCK-
3560: 33 29 0a 0a 0a 2f 2a 20 4f 62 6a 65 63 74 20 64  3).../* Object d
3570: 65 63 6c 61 72 61 74 69 6f 6e 73 20 2a 2f 0a 74  eclarations */.t
3580: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61  ypedef struct Wa
3590: 6c 49 6e 64 65 78 48 64 72 20 57 61 6c 49 6e 64  lIndexHdr WalInd
35a0: 65 78 48 64 72 3b 0a 74 79 70 65 64 65 66 20 73  exHdr;.typedef s
35b0: 74 72 75 63 74 20 57 61 6c 49 74 65 72 61 74 6f  truct WalIterato
35c0: 72 20 57 61 6c 49 74 65 72 61 74 6f 72 3b 0a 74  r WalIterator;.t
35d0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 57 61  ypedef struct Wa
35e0: 6c 43 6b 70 74 49 6e 66 6f 20 57 61 6c 43 6b 70  lCkptInfo WalCkp
35f0: 74 49 6e 66 6f 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54  tInfo;.../*.** T
3600: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a  he following obj
3610: 65 63 74 20 68 6f 6c 64 73 20 61 20 63 6f 70 79  ect holds a copy
3620: 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
3630: 78 20 68 65 61 64 65 72 20 63 6f 6e 74 65 6e 74  x header content
3640: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63 74 75  ..**.** The actu
3650: 61 6c 20 68 65 61 64 65 72 20 69 6e 20 74 68 65  al header in the
3660: 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e 73 69   wal-index consi
3670: 73 74 73 20 6f 66 20 74 77 6f 20 63 6f 70 69 65  sts of two copie
3680: 73 20 6f 66 20 74 68 69 73 0a 2a 2a 20 6f 62 6a  s of this.** obj
3690: 65 63 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57  ect..*/.struct W
36a0: 61 6c 49 6e 64 65 78 48 64 72 20 7b 0a 20 20 75  alIndexHdr {.  u
36b0: 33 32 20 69 56 65 72 73 69 6f 6e 3b 20 20 20 20  32 iVersion;    
36c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
36d0: 2a 20 57 61 6c 2d 69 6e 64 65 78 20 76 65 72 73  * Wal-index vers
36e0: 69 6f 6e 20 2a 2f 0a 20 20 75 33 32 20 75 6e 75  ion */.  u32 unu
36f0: 73 65 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  sed;            
3700: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 75 73           /* Unus
3710: 65 64 20 28 70 61 64 64 69 6e 67 29 20 66 69 65  ed (padding) fie
3720: 6c 64 20 2a 2f 0a 20 20 75 33 32 20 69 43 68 61  ld */.  u32 iCha
3730: 6e 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  nge;            
3740: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74          /* Count
3750: 65 72 20 69 6e 63 72 65 6d 65 6e 74 65 64 20 65  er incremented e
3760: 61 63 68 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ach transaction 
3770: 2a 2f 0a 20 20 75 38 20 69 73 49 6e 69 74 3b 20  */.  u8 isInit; 
3780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3790: 20 20 20 20 20 2f 2a 20 31 20 77 68 65 6e 20 69       /* 1 when i
37a0: 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20  nitialized */.  
37b0: 75 38 20 62 69 67 45 6e 64 43 6b 73 75 6d 3b 20  u8 bigEndCksum; 
37c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
37d0: 2f 2a 20 54 72 75 65 20 69 66 20 63 68 65 63 6b  /* True if check
37e0: 73 75 6d 73 20 69 6e 20 57 41 4c 20 61 72 65 20  sums in WAL are 
37f0: 62 69 67 2d 65 6e 64 69 61 6e 20 2a 2f 0a 20 20  big-endian */.  
3800: 75 31 36 20 73 7a 50 61 67 65 3b 20 20 20 20 20  u16 szPage;     
3810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3820: 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  /* Database page
3830: 20 73 69 7a 65 20 69 6e 20 62 79 74 65 73 20 2a   size in bytes *
3840: 2f 0a 20 20 75 33 32 20 6d 78 46 72 61 6d 65 3b  /.  u32 mxFrame;
3850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3860: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20      /* Index of 
3870: 6c 61 73 74 20 76 61 6c 69 64 20 66 72 61 6d 65  last valid frame
3880: 20 69 6e 20 74 68 65 20 57 41 4c 20 2a 2f 0a 20   in the WAL */. 
3890: 20 75 33 32 20 6e 50 61 67 65 3b 20 20 20 20 20   u32 nPage;     
38a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38b0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 64 61 74 61   /* Size of data
38c0: 62 61 73 65 20 69 6e 20 70 61 67 65 73 20 2a 2f  base in pages */
38d0: 0a 20 20 75 33 32 20 61 46 72 61 6d 65 43 6b 73  .  u32 aFrameCks
38e0: 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  um[2];          
38f0: 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 6f     /* Checksum o
3900: 66 20 6c 61 73 74 20 66 72 61 6d 65 20 69 6e 20  f last frame in 
3910: 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 61 53 61  log */.  u32 aSa
3920: 6c 74 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  lt[2];          
3930: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 77 6f 20           /* Two 
3940: 73 61 6c 74 20 76 61 6c 75 65 73 20 63 6f 70 69  salt values copi
3950: 65 64 20 66 72 6f 6d 20 57 41 4c 20 68 65 61 64  ed from WAL head
3960: 65 72 20 2a 2f 0a 20 20 75 33 32 20 61 43 6b 73  er */.  u32 aCks
3970: 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20 20  um[2];          
3980: 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b          /* Check
3990: 73 75 6d 20 6f 76 65 72 20 61 6c 6c 20 70 72 69  sum over all pri
39a0: 6f 72 20 66 69 65 6c 64 73 20 2a 2f 0a 7d 3b 0a  or fields */.};.
39b0: 0a 2f 2a 0a 2a 2a 20 41 20 63 6f 70 79 20 6f 66  ./*.** A copy of
39c0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f   the following o
39d0: 62 6a 65 63 74 20 6f 63 63 75 72 73 20 69 6e 20  bject occurs in 
39e0: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 6d  the wal-index im
39f0: 6d 65 64 69 61 74 65 6c 79 0a 2a 2a 20 66 6f 6c  mediately.** fol
3a00: 6c 6f 77 69 6e 67 20 74 68 65 20 73 65 63 6f 6e  lowing the secon
3a10: 64 20 63 6f 70 79 20 6f 66 20 74 68 65 20 57 61  d copy of the Wa
3a20: 6c 49 6e 64 65 78 48 64 72 2e 20 20 54 68 69 73  lIndexHdr.  This
3a30: 20 6f 62 6a 65 63 74 20 73 74 6f 72 65 73 0a 2a   object stores.*
3a40: 2a 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73  * information us
3a50: 65 64 20 62 79 20 63 68 65 63 6b 70 6f 69 6e 74  ed by checkpoint
3a60: 2e 0a 2a 2a 0a 2a 2a 20 6e 42 61 63 6b 66 69 6c  ..**.** nBackfil
3a70: 6c 20 69 73 20 74 68 65 20 6e 75 6d 62 65 72 20  l is the number 
3a80: 6f 66 20 66 72 61 6d 65 73 20 69 6e 20 74 68 65  of frames in the
3a90: 20 57 41 4c 20 74 68 61 74 20 68 61 76 65 20 62   WAL that have b
3aa0: 65 65 6e 20 77 72 69 74 74 65 6e 0a 2a 2a 20 62  een written.** b
3ab0: 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61 74  ack into the dat
3ac0: 61 62 61 73 65 2e 20 28 57 65 20 63 61 6c 6c 20  abase. (We call 
3ad0: 74 68 65 20 61 63 74 20 6f 66 20 6d 6f 76 69 6e  the act of movin
3ae0: 67 20 63 6f 6e 74 65 6e 74 20 66 72 6f 6d 20 57  g content from W
3af0: 41 4c 20 74 6f 0a 2a 2a 20 64 61 74 61 62 61 73  AL to.** databas
3b00: 65 20 22 62 61 63 6b 66 69 6c 6c 69 6e 67 22 2e  e "backfilling".
3b10: 29 20 20 54 68 65 20 6e 42 61 63 6b 66 69 6c 6c  )  The nBackfill
3b20: 20 6e 75 6d 62 65 72 20 69 73 20 6e 65 76 65 72   number is never
3b30: 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a   greater than.**
3b40: 20 57 61 6c 49 6e 64 65 78 48 64 72 2e 6d 78 46   WalIndexHdr.mxF
3b50: 72 61 6d 65 2e 20 20 6e 42 61 63 6b 66 69 6c 6c  rame.  nBackfill
3b60: 20 63 61 6e 20 6f 6e 6c 79 20 62 65 20 69 6e 63   can only be inc
3b70: 72 65 61 73 65 64 20 62 79 20 74 68 72 65 61 64  reased by thread
3b80: 73 0a 2a 2a 20 68 6f 6c 64 69 6e 67 20 74 68 65  s.** holding the
3b90: 20 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 6c   WAL_CKPT_LOCK l
3ba0: 6f 63 6b 20 28 77 68 69 63 68 20 69 6e 63 6c 75  ock (which inclu
3bb0: 64 65 73 20 61 20 72 65 63 6f 76 65 72 79 20 74  des a recovery t
3bc0: 68 72 65 61 64 29 2e 0a 2a 2a 20 48 6f 77 65 76  hread)..** Howev
3bd0: 65 72 2c 20 61 20 57 41 4c 5f 57 52 49 54 45 5f  er, a WAL_WRITE_
3be0: 4c 4f 43 4b 20 74 68 72 65 61 64 20 63 61 6e 20  LOCK thread can 
3bf0: 6d 6f 76 65 20 74 68 65 20 76 61 6c 75 65 20 6f  move the value o
3c00: 66 20 6e 42 61 63 6b 66 69 6c 6c 20 66 72 6f 6d  f nBackfill from
3c10: 0a 2a 2a 20 6d 78 46 72 61 6d 65 20 62 61 63 6b  .** mxFrame back
3c20: 20 74 6f 20 7a 65 72 6f 20 77 68 65 6e 20 74 68   to zero when th
3c30: 65 20 57 41 4c 20 69 73 20 72 65 73 65 74 2e 0a  e WAL is reset..
3c40: 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 69 73 20 6f  **.** There is o
3c50: 6e 65 20 65 6e 74 72 79 20 69 6e 20 61 52 65 61  ne entry in aRea
3c60: 64 4d 61 72 6b 5b 5d 20 66 6f 72 20 65 61 63 68  dMark[] for each
3c70: 20 72 65 61 64 65 72 20 6c 6f 63 6b 2e 20 20 49   reader lock.  I
3c80: 66 20 61 20 72 65 61 64 65 72 0a 2a 2a 20 68 6f  f a reader.** ho
3c90: 6c 64 73 20 72 65 61 64 2d 6c 6f 63 6b 20 4b 2c  lds read-lock K,
3ca0: 20 74 68 65 6e 20 74 68 65 20 76 61 6c 75 65 20   then the value 
3cb0: 69 6e 20 61 52 65 61 64 4d 61 72 6b 5b 4b 5d 20  in aReadMark[K] 
3cc0: 69 73 20 6e 6f 20 67 72 65 61 74 65 72 20 74 68  is no greater th
3cd0: 61 6e 0a 2a 2a 20 74 68 65 20 6d 78 46 72 61 6d  an.** the mxFram
3ce0: 65 20 66 6f 72 20 74 68 61 74 20 72 65 61 64 65  e for that reade
3cf0: 72 2e 20 20 54 68 65 20 76 61 6c 75 65 20 52 45  r.  The value RE
3d00: 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 20  ADMARK_NOT_USED 
3d10: 28 30 78 66 66 66 66 66 66 66 66 29 0a 2a 2a 20  (0xffffffff).** 
3d20: 66 6f 72 20 61 6e 79 20 61 52 65 61 64 4d 61 72  for any aReadMar
3d30: 6b 5b 5d 20 6d 65 61 6e 73 20 74 68 61 74 20 65  k[] means that e
3d40: 6e 74 72 79 20 69 73 20 75 6e 75 73 65 64 2e 20  ntry is unused. 
3d50: 20 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20 69 73   aReadMark[0] is
3d60: 20 0a 2a 2a 20 61 20 73 70 65 63 69 61 6c 20 63   .** a special c
3d70: 61 73 65 3b 20 69 74 73 20 76 61 6c 75 65 20 69  ase; its value i
3d80: 73 20 6e 65 76 65 72 20 75 73 65 64 20 61 6e 64  s never used and
3d90: 20 69 74 20 65 78 69 73 74 73 20 61 73 20 61 20   it exists as a 
3da0: 70 6c 61 63 65 2d 68 6f 6c 64 65 72 0a 2a 2a 20  place-holder.** 
3db0: 74 6f 20 61 76 6f 69 64 20 68 61 76 69 6e 67 20  to avoid having 
3dc0: 74 6f 20 6f 66 66 73 65 74 20 61 52 65 61 64 4d  to offset aReadM
3dd0: 61 72 6b 5b 5d 20 69 6e 64 65 78 73 20 62 79 20  ark[] indexs by 
3de0: 6f 6e 65 2e 20 20 52 65 61 64 65 72 73 20 68 6f  one.  Readers ho
3df0: 6c 64 69 6e 67 0a 2a 2a 20 57 41 4c 5f 52 45 41  lding.** WAL_REA
3e00: 44 5f 4c 4f 43 4b 28 30 29 20 61 6c 77 61 79 73  D_LOCK(0) always
3e10: 20 69 67 6e 6f 72 65 20 74 68 65 20 65 6e 74 69   ignore the enti
3e20: 72 65 20 57 41 4c 20 61 6e 64 20 72 65 61 64 20  re WAL and read 
3e30: 61 6c 6c 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 64  all content.** d
3e40: 69 72 65 63 74 6c 79 20 66 72 6f 6d 20 74 68 65  irectly from the
3e50: 20 64 61 74 61 62 61 73 65 2e 0a 2a 2a 0a 2a 2a   database..**.**
3e60: 20 54 68 65 20 76 61 6c 75 65 20 6f 66 20 61 52   The value of aR
3e70: 65 61 64 4d 61 72 6b 5b 4b 5d 20 6d 61 79 20 6f  eadMark[K] may o
3e80: 6e 6c 79 20 62 65 20 63 68 61 6e 67 65 64 20 62  nly be changed b
3e90: 79 20 61 20 74 68 72 65 61 64 20 74 68 61 74 0a  y a thread that.
3ea0: 2a 2a 20 69 73 20 68 6f 6c 64 69 6e 67 20 61 6e  ** is holding an
3eb0: 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20   exclusive lock 
3ec0: 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  on WAL_READ_LOCK
3ed0: 28 4b 29 2e 20 20 54 68 75 73 2c 20 74 68 65 20  (K).  Thus, the 
3ee0: 76 61 6c 75 65 20 6f 66 0a 2a 2a 20 61 52 65 61  value of.** aRea
3ef0: 64 4d 61 72 6b 5b 4b 5d 20 63 61 6e 6e 6f 74 20  dMark[K] cannot 
3f00: 63 68 61 6e 67 65 64 20 77 68 69 6c 65 20 74 68  changed while th
3f10: 65 72 65 20 69 73 20 61 20 72 65 61 64 65 72 20  ere is a reader 
3f20: 69 73 20 75 73 69 6e 67 20 74 68 61 74 20 6d 61  is using that ma
3f30: 72 6b 0a 2a 2a 20 73 69 6e 63 65 20 74 68 65 20  rk.** since the 
3f40: 72 65 61 64 65 72 20 77 69 6c 6c 20 62 65 20 68  reader will be h
3f50: 6f 6c 64 69 6e 67 20 61 20 73 68 61 72 65 64 20  olding a shared 
3f60: 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52 45 41 44  lock on WAL_READ
3f70: 5f 4c 4f 43 4b 28 4b 29 2e 0a 2a 2a 0a 2a 2a 20  _LOCK(K)..**.** 
3f80: 54 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 65 72  The checkpointer
3f90: 20 6d 61 79 20 6f 6e 6c 79 20 74 72 61 6e 73 66   may only transf
3fa0: 65 72 20 66 72 61 6d 65 73 20 66 72 6f 6d 20 57  er frames from W
3fb0: 41 4c 20 74 6f 20 64 61 74 61 62 61 73 65 20 77  AL to database w
3fc0: 68 65 72 65 0a 2a 2a 20 74 68 65 20 66 72 61 6d  here.** the fram
3fd0: 65 20 6e 75 6d 62 65 72 73 20 61 72 65 20 6c 65  e numbers are le
3fe0: 73 73 20 74 68 61 6e 20 6f 72 20 65 71 75 61 6c  ss than or equal
3ff0: 20 74 6f 20 65 76 65 72 79 20 61 52 65 61 64 4d   to every aReadM
4000: 61 72 6b 5b 5d 20 74 68 61 74 20 69 73 0a 2a 2a  ark[] that is.**
4010: 20 69 6e 20 75 73 65 20 28 74 68 61 74 20 69 73   in use (that is
4020: 2c 20 65 76 65 72 79 20 61 52 65 61 64 4d 61 72  , every aReadMar
4030: 6b 5b 6a 5d 20 66 6f 72 20 77 68 69 63 68 20 74  k[j] for which t
4040: 68 65 72 65 20 69 73 20 61 20 63 6f 72 72 65 73  here is a corres
4050: 70 6f 6e 64 69 6e 67 0a 2a 2a 20 57 41 4c 5f 52  ponding.** WAL_R
4060: 45 41 44 5f 4c 4f 43 4b 28 6a 29 29 2e 20 20 4e  EAD_LOCK(j)).  N
4070: 65 77 20 72 65 61 64 65 72 73 20 28 75 73 75 61  ew readers (usua
4080: 6c 6c 79 29 20 70 69 63 6b 20 74 68 65 20 61 52  lly) pick the aR
4090: 65 61 64 4d 61 72 6b 5b 5d 20 77 69 74 68 20 74  eadMark[] with t
40a0: 68 65 0a 2a 2a 20 6c 61 72 67 65 73 74 20 76 61  he.** largest va
40b0: 6c 75 65 20 61 6e 64 20 77 69 6c 6c 20 69 6e 63  lue and will inc
40c0: 72 65 61 73 65 20 61 6e 20 75 6e 75 73 65 64 20  rease an unused 
40d0: 61 52 65 61 64 4d 61 72 6b 5b 5d 20 74 6f 20 6d  aReadMark[] to m
40e0: 78 46 72 61 6d 65 20 69 66 20 74 68 65 72 65 0a  xFrame if there.
40f0: 2a 2a 20 69 73 20 6e 6f 74 20 61 6c 72 65 61 64  ** is not alread
4100: 79 20 61 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d  y an aReadMark[]
4110: 20 65 71 75 61 6c 20 74 6f 20 6d 78 46 72 61 6d   equal to mxFram
4120: 65 2e 20 20 54 68 65 20 65 78 63 65 70 74 69 6f  e.  The exceptio
4130: 6e 20 74 6f 20 74 68 65 0a 2a 2a 20 70 72 65 76  n to the.** prev
4140: 69 6f 75 73 20 73 65 6e 74 65 6e 63 65 20 69 73  ious sentence is
4150: 20 77 68 65 6e 20 6e 42 61 63 6b 66 69 6c 6c 20   when nBackfill 
4160: 65 71 75 61 6c 73 20 6d 78 46 72 61 6d 65 20 28  equals mxFrame (
4170: 6d 65 61 6e 69 6e 67 20 74 68 61 74 20 65 76 65  meaning that eve
4180: 72 79 74 68 69 6e 67 0a 2a 2a 20 69 6e 20 74 68  rything.** in th
4190: 65 20 57 41 4c 20 68 61 73 20 62 65 65 6e 20 62  e WAL has been b
41a0: 61 63 6b 66 69 6c 6c 65 64 20 69 6e 74 6f 20 74  ackfilled into t
41b0: 68 65 20 64 61 74 61 62 61 73 65 29 20 74 68 65  he database) the
41c0: 6e 20 6e 65 77 20 72 65 61 64 65 72 73 0a 2a 2a  n new readers.**
41d0: 20 77 69 6c 6c 20 63 68 6f 6f 73 65 20 61 52 65   will choose aRe
41e0: 61 64 4d 61 72 6b 5b 30 5d 20 77 68 69 63 68 20  adMark[0] which 
41f0: 68 61 73 20 76 61 6c 75 65 20 30 20 61 6e 64 20  has value 0 and 
4200: 68 65 6e 63 65 20 73 75 63 68 20 72 65 61 64 65  hence such reade
4210: 72 20 77 69 6c 6c 0a 2a 2a 20 67 65 74 20 61 6c  r will.** get al
4220: 6c 20 74 68 65 69 72 20 61 6c 6c 20 63 6f 6e 74  l their all cont
4230: 65 6e 74 20 64 69 72 65 63 74 6c 79 20 66 72 6f  ent directly fro
4240: 6d 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66  m the database f
4250: 69 6c 65 20 61 6e 64 20 69 67 6e 6f 72 65 20 0a  ile and ignore .
4260: 2a 2a 20 74 68 65 20 57 41 4c 2e 0a 2a 2a 0a 2a  ** the WAL..**.*
4270: 2a 20 57 72 69 74 65 72 73 20 6e 6f 72 6d 61 6c  * Writers normal
4280: 6c 79 20 61 70 70 65 6e 64 20 6e 65 77 20 66 72  ly append new fr
4290: 61 6d 65 73 20 74 6f 20 74 68 65 20 65 6e 64 20  ames to the end 
42a0: 6f 66 20 74 68 65 20 57 41 4c 2e 20 20 48 6f 77  of the WAL.  How
42b0: 65 76 65 72 2c 0a 2a 2a 20 69 66 20 6e 42 61 63  ever,.** if nBac
42c0: 6b 66 69 6c 6c 20 65 71 75 61 6c 73 20 6d 78 46  kfill equals mxF
42d0: 72 61 6d 65 20 28 6d 65 61 6e 69 6e 67 20 74 68  rame (meaning th
42e0: 61 74 20 61 6c 6c 20 57 41 4c 20 63 6f 6e 74 65  at all WAL conte
42f0: 6e 74 20 68 61 73 20 62 65 65 6e 0a 2a 2a 20 77  nt has been.** w
4300: 72 69 74 74 65 6e 20 62 61 63 6b 20 69 6e 74 6f  ritten back into
4310: 20 74 68 65 20 64 61 74 61 62 61 73 65 29 20 61   the database) a
4320: 6e 64 20 69 66 20 6e 6f 20 72 65 61 64 65 72 73  nd if no readers
4330: 20 61 72 65 20 75 73 69 6e 67 20 74 68 65 20 57   are using the W
4340: 41 4c 0a 2a 2a 20 28 69 6e 20 6f 74 68 65 72 20  AL.** (in other 
4350: 77 6f 72 64 73 2c 20 69 66 20 74 68 65 72 65 20  words, if there 
4360: 61 72 65 20 6e 6f 20 57 41 4c 5f 52 45 41 44 5f  are no WAL_READ_
4370: 4c 4f 43 4b 28 69 29 20 77 68 65 72 65 20 69 3e  LOCK(i) where i>
4380: 30 29 20 74 68 65 6e 0a 2a 2a 20 74 68 65 20 77  0) then.** the w
4390: 72 69 74 65 72 20 77 69 6c 6c 20 66 69 72 73 74  riter will first
43a0: 20 22 72 65 73 65 74 22 20 74 68 65 20 57 41 4c   "reset" the WAL
43b0: 20 62 61 63 6b 20 74 6f 20 74 68 65 20 62 65 67   back to the beg
43c0: 69 6e 6e 69 6e 67 20 61 6e 64 20 73 74 61 72 74  inning and start
43d0: 0a 2a 2a 20 77 72 69 74 69 6e 67 20 6e 65 77 20  .** writing new 
43e0: 63 6f 6e 74 65 6e 74 20 62 65 67 69 6e 6e 69 6e  content beginnin
43f0: 67 20 61 74 20 66 72 61 6d 65 20 31 2e 0a 2a 2a  g at frame 1..**
4400: 0a 2a 2a 20 57 65 20 61 73 73 75 6d 65 20 74 68  .** We assume th
4410: 61 74 20 33 32 2d 62 69 74 20 6c 6f 61 64 73 20  at 32-bit loads 
4420: 61 72 65 20 61 74 6f 6d 69 63 20 61 6e 64 20 73  are atomic and s
4430: 6f 20 6e 6f 20 6c 6f 63 6b 73 20 61 72 65 20 6e  o no locks are n
4440: 65 65 64 65 64 20 69 6e 0a 2a 2a 20 6f 72 64 65  eeded in.** orde
4450: 72 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 61  r to read from a
4460: 6e 79 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65  ny aReadMark[] e
4470: 6e 74 72 69 65 73 2e 0a 2a 2f 0a 73 74 72 75 63  ntries..*/.struc
4480: 74 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 7b 0a  t WalCkptInfo {.
4490: 20 20 75 33 32 20 6e 42 61 63 6b 66 69 6c 6c 3b    u32 nBackfill;
44a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
44b0: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 57    /* Number of W
44c0: 41 4c 20 66 72 61 6d 65 73 20 62 61 63 6b 66 69  AL frames backfi
44d0: 6c 6c 65 64 20 69 6e 74 6f 20 44 42 20 2a 2f 0a  lled into DB */.
44e0: 20 20 75 33 32 20 61 52 65 61 64 4d 61 72 6b 5b    u32 aReadMark[
44f0: 57 41 4c 5f 4e 52 45 41 44 45 52 5d 3b 20 20 20  WAL_NREADER];   
4500: 20 20 2f 2a 20 52 65 61 64 65 72 20 6d 61 72 6b    /* Reader mark
4510: 73 20 2a 2f 0a 7d 3b 0a 23 64 65 66 69 6e 65 20  s */.};.#define 
4520: 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45  READMARK_NOT_USE
4530: 44 20 20 30 78 66 66 66 66 66 66 66 66 0a 0a 0a  D  0xffffffff...
4540: 2f 2a 20 41 20 62 6c 6f 63 6b 20 6f 66 20 57 41  /* A block of WA
4550: 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 52 45 53 45  LINDEX_LOCK_RESE
4560: 52 56 45 44 20 62 79 74 65 73 20 62 65 67 69 6e  RVED bytes begin
4570: 6e 69 6e 67 20 61 74 0a 2a 2a 20 57 41 4c 49 4e  ning at.** WALIN
4580: 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20  DEX_LOCK_OFFSET 
4590: 69 73 20 72 65 73 65 72 76 65 64 20 66 6f 72 20  is reserved for 
45a0: 6c 6f 63 6b 73 2e 20 53 69 6e 63 65 20 73 6f 6d  locks. Since som
45b0: 65 20 73 79 73 74 65 6d 73 0a 2a 2a 20 6f 6e 6c  e systems.** onl
45c0: 79 20 73 75 70 70 6f 72 74 20 6d 61 6e 64 61 74  y support mandat
45d0: 6f 72 79 20 66 69 6c 65 2d 6c 6f 63 6b 73 2c 20  ory file-locks, 
45e0: 77 65 20 64 6f 20 6e 6f 74 20 72 65 61 64 20 6f  we do not read o
45f0: 72 20 77 72 69 74 65 20 64 61 74 61 0a 2a 2a 20  r write data.** 
4600: 66 72 6f 6d 20 74 68 65 20 72 65 67 69 6f 6e 20  from the region 
4610: 6f 66 20 74 68 65 20 66 69 6c 65 20 6f 6e 20 77  of the file on w
4620: 68 69 63 68 20 6c 6f 63 6b 73 20 61 72 65 20 61  hich locks are a
4630: 70 70 6c 69 65 64 2e 0a 2a 2f 0a 23 64 65 66 69  pplied..*/.#defi
4640: 6e 65 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b  ne WALINDEX_LOCK
4650: 5f 4f 46 46 53 45 54 20 20 20 28 73 69 7a 65 6f  _OFFSET   (sizeo
4660: 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 2a 32  f(WalIndexHdr)*2
4670: 20 2b 20 73 69 7a 65 6f 66 28 57 61 6c 43 6b 70   + sizeof(WalCkp
4680: 74 49 6e 66 6f 29 29 0a 23 64 65 66 69 6e 65 20  tInfo)).#define 
4690: 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 52 45  WALINDEX_LOCK_RE
46a0: 53 45 52 56 45 44 20 31 36 0a 23 64 65 66 69 6e  SERVED 16.#defin
46b0: 65 20 57 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53  e WALINDEX_HDR_S
46c0: 49 5a 45 20 20 20 20 20 20 28 57 41 4c 49 4e 44  IZE      (WALIND
46d0: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 2b 57  EX_LOCK_OFFSET+W
46e0: 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b 5f 52 45 53  ALINDEX_LOCK_RES
46f0: 45 52 56 45 44 29 0a 0a 2f 2a 20 53 69 7a 65 20  ERVED)../* Size 
4700: 6f 66 20 68 65 61 64 65 72 20 62 65 66 6f 72 65  of header before
4710: 20 65 61 63 68 20 66 72 61 6d 65 20 69 6e 20 77   each frame in w
4720: 61 6c 20 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41  al */.#define WA
4730: 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 20  L_FRAME_HDRSIZE 
4740: 32 34 0a 0a 2f 2a 20 53 69 7a 65 20 6f 66 20 77  24../* Size of w
4750: 72 69 74 65 20 61 68 65 61 64 20 6c 6f 67 20 68  rite ahead log h
4760: 65 61 64 65 72 2c 20 69 6e 63 6c 75 64 69 6e 67  eader, including
4770: 20 63 68 65 63 6b 73 75 6d 2e 20 2a 2f 0a 2f 2a   checksum. */./*
4780: 20 23 64 65 66 69 6e 65 20 57 41 4c 5f 48 44 52   #define WAL_HDR
4790: 53 49 5a 45 20 32 34 20 2a 2f 0a 23 64 65 66 69  SIZE 24 */.#defi
47a0: 6e 65 20 57 41 4c 5f 48 44 52 53 49 5a 45 20 33  ne WAL_HDRSIZE 3
47b0: 32 0a 0a 2f 2a 20 57 41 4c 20 6d 61 67 69 63 20  2../* WAL magic 
47c0: 76 61 6c 75 65 2e 20 45 69 74 68 65 72 20 74 68  value. Either th
47d0: 69 73 20 76 61 6c 75 65 2c 20 6f 72 20 74 68 65  is value, or the
47e0: 20 73 61 6d 65 20 76 61 6c 75 65 20 77 69 74 68   same value with
47f0: 20 74 68 65 20 6c 65 61 73 74 0a 2a 2a 20 73 69   the least.** si
4800: 67 6e 69 66 69 63 61 6e 74 20 62 69 74 20 61 6c  gnificant bit al
4810: 73 6f 20 73 65 74 20 28 57 41 4c 5f 4d 41 47 49  so set (WAL_MAGI
4820: 43 20 7c 20 30 78 30 30 30 30 30 30 30 31 29 20  C | 0x00000001) 
4830: 69 73 20 73 74 6f 72 65 64 20 69 6e 20 33 32 2d  is stored in 32-
4840: 62 69 74 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61  bit.** big-endia
4850: 6e 20 66 6f 72 6d 61 74 20 69 6e 20 74 68 65 20  n format in the 
4860: 66 69 72 73 74 20 34 20 62 79 74 65 73 20 6f 66  first 4 bytes of
4870: 20 61 20 57 41 4c 20 66 69 6c 65 2e 0a 2a 2a 0a   a WAL file..**.
4880: 2a 2a 20 49 66 20 74 68 65 20 4c 53 42 20 69 73  ** If the LSB is
4890: 20 73 65 74 2c 20 74 68 65 6e 20 74 68 65 20 63   set, then the c
48a0: 68 65 63 6b 73 75 6d 73 20 66 6f 72 20 65 61 63  hecksums for eac
48b0: 68 20 66 72 61 6d 65 20 77 69 74 68 69 6e 20 74  h frame within t
48c0: 68 65 20 57 41 4c 0a 2a 2a 20 66 69 6c 65 20 61  he WAL.** file a
48d0: 72 65 20 63 61 6c 63 75 6c 61 74 65 64 20 62 79  re calculated by
48e0: 20 74 72 65 61 74 69 6e 67 20 61 6c 6c 20 64 61   treating all da
48f0: 74 61 20 61 73 20 61 6e 20 61 72 72 61 79 20 6f  ta as an array o
4900: 66 20 33 32 2d 62 69 74 20 0a 2a 2a 20 62 69 67  f 32-bit .** big
4910: 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73 2e 20 4f  -endian words. O
4920: 74 68 65 72 77 69 73 65 2c 20 74 68 65 79 20 61  therwise, they a
4930: 72 65 20 63 61 6c 63 75 6c 61 74 65 64 20 62 79  re calculated by
4940: 20 69 6e 74 65 72 70 72 65 74 69 6e 67 20 0a 2a   interpreting .*
4950: 2a 20 61 6c 6c 20 64 61 74 61 20 61 73 20 33 32  * all data as 32
4960: 2d 62 69 74 20 6c 69 74 74 6c 65 2d 65 6e 64 69  -bit little-endi
4970: 61 6e 20 77 6f 72 64 73 2e 0a 2a 2f 0a 23 64 65  an words..*/.#de
4980: 66 69 6e 65 20 57 41 4c 5f 4d 41 47 49 43 20 30  fine WAL_MAGIC 0
4990: 78 33 37 37 66 30 36 38 32 0a 0a 2f 2a 0a 2a 2a  x377f0682../*.**
49a0: 20 52 65 74 75 72 6e 20 74 68 65 20 6f 66 66 73   Return the offs
49b0: 65 74 20 6f 66 20 66 72 61 6d 65 20 69 46 72 61  et of frame iFra
49c0: 6d 65 20 69 6e 20 74 68 65 20 77 72 69 74 65 2d  me in the write-
49d0: 61 68 65 61 64 20 6c 6f 67 20 66 69 6c 65 2c 20  ahead log file, 
49e0: 0a 2a 2a 20 61 73 73 75 6d 69 6e 67 20 61 20 64  .** assuming a d
49f0: 61 74 61 62 61 73 65 20 70 61 67 65 20 73 69 7a  atabase page siz
4a00: 65 20 6f 66 20 73 7a 50 61 67 65 20 62 79 74 65  e of szPage byte
4a10: 73 2e 20 54 68 65 20 6f 66 66 73 65 74 20 72 65  s. The offset re
4a20: 74 75 72 6e 65 64 0a 2a 2a 20 69 73 20 74 6f 20  turned.** is to 
4a30: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
4a40: 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67   write-ahead log
4a50: 20 66 72 61 6d 65 2d 68 65 61 64 65 72 2e 0a 2a   frame-header..*
4a60: 2f 0a 23 64 65 66 69 6e 65 20 77 61 6c 46 72 61  /.#define walFra
4a70: 6d 65 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2c  meOffset(iFrame,
4a80: 20 73 7a 50 61 67 65 29 20 28 20 20 20 20 20 20   szPage) (      
4a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4aa0: 20 20 20 20 20 20 20 20 20 5c 0a 20 20 57 41 4c           \.  WAL
4ab0: 5f 48 44 52 53 49 5a 45 20 2b 20 28 28 69 46 72  _HDRSIZE + ((iFr
4ac0: 61 6d 65 29 2d 31 29 2a 28 28 73 7a 50 61 67 65  ame)-1)*((szPage
4ad0: 29 2b 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53  )+WAL_FRAME_HDRS
4ae0: 49 5a 45 29 20 20 20 20 20 20 20 20 5c 0a 29 0a  IZE)        \.).
4af0: 0a 2f 2a 0a 2a 2a 20 41 6e 20 6f 70 65 6e 20 77  ./*.** An open w
4b00: 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66  rite-ahead log f
4b10: 69 6c 65 20 69 73 20 72 65 70 72 65 73 65 6e 74  ile is represent
4b20: 65 64 20 62 79 20 61 6e 20 69 6e 73 74 61 6e 63  ed by an instanc
4b30: 65 20 6f 66 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c  e of the.** foll
4b40: 6f 77 69 6e 67 20 6f 62 6a 65 63 74 2e 0a 2a 2f  owing object..*/
4b50: 0a 73 74 72 75 63 74 20 57 61 6c 20 7b 0a 20 20  .struct Wal {.  
4b60: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
4b70: 73 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68  s;         /* Th
4b80: 65 20 56 46 53 20 75 73 65 64 20 74 6f 20 63 72  e VFS used to cr
4b90: 65 61 74 65 20 70 44 62 46 64 20 2a 2f 0a 20 20  eate pDbFd */.  
4ba0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 44  sqlite3_file *pD
4bb0: 62 46 64 3b 20 20 20 20 20 20 20 2f 2a 20 46 69  bFd;       /* Fi
4bc0: 6c 65 20 68 61 6e 64 6c 65 20 66 6f 72 20 74 68  le handle for th
4bd0: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  e database file 
4be0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  */.  sqlite3_fil
4bf0: 65 20 2a 70 57 61 6c 46 64 3b 20 20 20 20 20 20  e *pWalFd;      
4c00: 2f 2a 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 66  /* File handle f
4c10: 6f 72 20 57 41 4c 20 66 69 6c 65 20 2a 2f 0a 20  or WAL file */. 
4c20: 20 75 33 32 20 69 43 61 6c 6c 62 61 63 6b 3b 20   u32 iCallback; 
4c30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56              /* V
4c40: 61 6c 75 65 20 74 6f 20 70 61 73 73 20 74 6f 20  alue to pass to 
4c50: 6c 6f 67 20 63 61 6c 6c 62 61 63 6b 20 28 6f 72  log callback (or
4c60: 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20 6e 57 69   0) */.  int nWi
4c70: 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20 20  Data;           
4c80: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61      /* Size of a
4c90: 72 72 61 79 20 61 70 57 69 44 61 74 61 20 2a 2f  rray apWiData */
4ca0: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20  .  volatile u32 
4cb0: 2a 2a 61 70 57 69 44 61 74 61 3b 20 20 20 2f 2a  **apWiData;   /*
4cc0: 20 50 6f 69 6e 74 65 72 20 74 6f 20 77 61 6c 2d   Pointer to wal-
4cd0: 69 6e 64 65 78 20 63 6f 6e 74 65 6e 74 20 69 6e  index content in
4ce0: 20 6d 65 6d 6f 72 79 20 2a 2f 0a 20 20 75 31 36   memory */.  u16
4cf0: 20 73 7a 50 61 67 65 3b 20 20 20 20 20 20 20 20   szPage;        
4d00: 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
4d10: 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 2a 2f  ase page size */
4d20: 0a 20 20 69 31 36 20 72 65 61 64 4c 6f 63 6b 3b  .  i16 readLock;
4d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4d40: 20 57 68 69 63 68 20 72 65 61 64 20 6c 6f 63 6b   Which read lock
4d50: 20 69 73 20 62 65 69 6e 67 20 68 65 6c 64 2e 20   is being held. 
4d60: 20 2d 31 20 66 6f 72 20 6e 6f 6e 65 20 2a 2f 0a   -1 for none */.
4d70: 20 20 75 38 20 65 78 63 6c 75 73 69 76 65 4d 6f    u8 exclusiveMo
4d80: 64 65 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20  de;          /* 
4d90: 4e 6f 6e 2d 7a 65 72 6f 20 69 66 20 63 6f 6e 6e  Non-zero if conn
4da0: 65 63 74 69 6f 6e 20 69 73 20 69 6e 20 65 78 63  ection is in exc
4db0: 6c 75 73 69 76 65 20 6d 6f 64 65 20 2a 2f 0a 20  lusive mode */. 
4dc0: 20 75 38 20 69 73 57 49 6e 64 65 78 4f 70 65 6e   u8 isWIndexOpen
4dd0: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54  ;           /* T
4de0: 72 75 65 20 69 66 20 53 68 6d 4f 70 65 6e 28 29  rue if ShmOpen()
4df0: 20 63 61 6c 6c 65 64 20 6f 6e 20 70 44 62 46 64   called on pDbFd
4e00: 20 2a 2f 0a 20 20 75 38 20 77 72 69 74 65 4c 6f   */.  u8 writeLo
4e10: 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ck;             
4e20: 20 2f 2a 20 54 72 75 65 20 69 66 20 69 6e 20 61   /* True if in a
4e30: 20 77 72 69 74 65 20 74 72 61 6e 73 61 63 74 69   write transacti
4e40: 6f 6e 20 2a 2f 0a 20 20 75 38 20 63 6b 70 74 4c  on */.  u8 ckptL
4e50: 6f 63 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  ock;            
4e60: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 68 6f     /* True if ho
4e70: 6c 64 69 6e 67 20 61 20 63 68 65 63 6b 70 6f 69  lding a checkpoi
4e80: 6e 74 20 6c 6f 63 6b 20 2a 2f 0a 20 20 57 61 6c  nt lock */.  Wal
4e90: 49 6e 64 65 78 48 64 72 20 68 64 72 3b 20 20 20  IndexHdr hdr;   
4ea0: 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 2d 69          /* Wal-i
4eb0: 6e 64 65 78 20 68 65 61 64 65 72 20 66 6f 72 20  ndex header for 
4ec0: 63 75 72 72 65 6e 74 20 74 72 61 6e 73 61 63 74  current transact
4ed0: 69 6f 6e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a  ion */.  char *z
4ee0: 57 61 6c 4e 61 6d 65 3b 20 20 20 20 20 20 20 20  WalName;        
4ef0: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 57      /* Name of W
4f00: 41 4c 20 66 69 6c 65 20 2a 2f 0a 20 20 75 33 32  AL file */.  u32
4f10: 20 6e 43 6b 70 74 3b 20 20 20 20 20 20 20 20 20   nCkpt;         
4f20: 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b          /* Check
4f30: 70 6f 69 6e 74 20 73 65 71 75 65 6e 63 65 20 63  point sequence c
4f40: 6f 75 6e 74 65 72 20 69 6e 20 74 68 65 20 77 61  ounter in the wa
4f50: 6c 2d 68 65 61 64 65 72 20 2a 2f 0a 23 69 66 64  l-header */.#ifd
4f60: 65 66 20 53 51 4c 49 54 45 5f 44 45 42 55 47 0a  ef SQLITE_DEBUG.
4f70: 20 20 75 38 20 6c 6f 63 6b 45 72 72 6f 72 3b 20    u8 lockError; 
4f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4f90: 54 72 75 65 20 69 66 20 61 20 6c 6f 63 6b 69 6e  True if a lockin
4fa0: 67 20 65 72 72 6f 72 20 68 61 73 20 6f 63 63 75  g error has occu
4fb0: 72 72 65 64 20 2a 2f 0a 23 65 6e 64 69 66 0a 7d  rred */.#endif.}
4fc0: 3b 0a 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20 70 61  ;../*.** Each pa
4fd0: 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ge of the wal-in
4fe0: 64 65 78 20 6d 61 70 70 69 6e 67 20 63 6f 6e 74  dex mapping cont
4ff0: 61 69 6e 73 20 61 20 68 61 73 68 2d 74 61 62 6c  ains a hash-tabl
5000: 65 20 6d 61 64 65 20 75 70 20 6f 66 0a 2a 2a 20  e made up of.** 
5010: 61 6e 20 61 72 72 61 79 20 6f 66 20 48 41 53 48  an array of HASH
5020: 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 65 6c 65 6d  TABLE_NSLOT elem
5030: 65 6e 74 73 20 6f 66 20 74 68 65 20 66 6f 6c 6c  ents of the foll
5040: 6f 77 69 6e 67 20 74 79 70 65 2e 0a 2a 2f 0a 74  owing type..*/.t
5050: 79 70 65 64 65 66 20 75 31 36 20 68 74 5f 73 6c  ypedef u16 ht_sl
5060: 6f 74 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ot;../*.** This 
5070: 73 74 72 75 63 74 75 72 65 20 69 73 20 75 73 65  structure is use
5080: 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20 61  d to implement a
5090: 6e 20 69 74 65 72 61 74 6f 72 20 74 68 61 74 20  n iterator that 
50a0: 6c 6f 6f 70 73 20 74 68 72 6f 75 67 68 0a 2a 2a  loops through.**
50b0: 20 61 6c 6c 20 66 72 61 6d 65 73 20 69 6e 20 74   all frames in t
50c0: 68 65 20 57 41 4c 20 69 6e 20 64 61 74 61 62 61  he WAL in databa
50d0: 73 65 20 70 61 67 65 20 6f 72 64 65 72 2e 20 57  se page order. W
50e0: 68 65 72 65 20 74 77 6f 20 6f 72 20 6d 6f 72 65  here two or more
50f0: 20 66 72 61 6d 65 73 0a 2a 2a 20 63 6f 72 72 65   frames.** corre
5100: 73 70 6f 6e 64 20 74 6f 20 74 68 65 20 73 61 6d  spond to the sam
5110: 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65 2c  e database page,
5120: 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 76 69   the iterator vi
5130: 73 69 74 73 20 6f 6e 6c 79 20 74 68 65 20 0a 2a  sits only the .*
5140: 2a 20 66 72 61 6d 65 20 6d 6f 73 74 20 72 65 63  * frame most rec
5150: 65 6e 74 6c 79 20 77 72 69 74 74 65 6e 20 74 6f  ently written to
5160: 20 74 68 65 20 57 41 4c 20 28 69 6e 20 6f 74 68   the WAL (in oth
5170: 65 72 20 77 6f 72 64 73 2c 20 74 68 65 20 66 72  er words, the fr
5180: 61 6d 65 20 77 69 74 68 0a 2a 2a 20 74 68 65 20  ame with.** the 
5190: 6c 61 72 67 65 73 74 20 69 6e 64 65 78 29 2e 0a  largest index)..
51a0: 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e 74 65 72 6e  **.** The intern
51b0: 61 6c 73 20 6f 66 20 74 68 69 73 20 73 74 72 75  als of this stru
51c0: 63 74 75 72 65 20 61 72 65 20 6f 6e 6c 79 20 61  cture are only a
51d0: 63 63 65 73 73 65 64 20 62 79 3a 0a 2a 2a 0a 2a  ccessed by:.**.*
51e0: 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f 72 49  *   walIteratorI
51f0: 6e 69 74 28 29 20 2d 20 43 72 65 61 74 65 20 61  nit() - Create a
5200: 20 6e 65 77 20 69 74 65 72 61 74 6f 72 2c 0a 2a   new iterator,.*
5210: 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f 72 4e  *   walIteratorN
5220: 65 78 74 28 29 20 2d 20 53 74 65 70 20 61 6e 20  ext() - Step an 
5230: 69 74 65 72 61 74 6f 72 2c 0a 2a 2a 20 20 20 77  iterator,.**   w
5240: 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65 28 29  alIteratorFree()
5250: 20 2d 20 46 72 65 65 20 61 6e 20 69 74 65 72 61   - Free an itera
5260: 74 6f 72 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  tor..**.** This 
5270: 66 75 6e 63 74 69 6f 6e 61 6c 69 74 79 20 69 73  functionality is
5280: 20 75 73 65 64 20 62 79 20 74 68 65 20 63 68 65   used by the che
5290: 63 6b 70 6f 69 6e 74 20 63 6f 64 65 20 28 73 65  ckpoint code (se
52a0: 65 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28  e walCheckpoint(
52b0: 29 29 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61  ))..*/.struct Wa
52c0: 6c 49 74 65 72 61 74 6f 72 20 7b 0a 20 20 69 6e  lIterator {.  in
52d0: 74 20 69 50 72 69 6f 72 3b 20 20 20 20 20 20 20  t iPrior;       
52e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
52f0: 20 4c 61 73 74 20 72 65 73 75 6c 74 20 72 65 74   Last result ret
5300: 75 72 6e 65 64 20 66 72 6f 6d 20 74 68 65 20 69  urned from the i
5310: 74 65 72 61 74 6f 72 20 2a 2f 0a 20 20 69 6e 74  terator */.  int
5320: 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20 20 20 20   nSegment;      
5330: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5340: 53 69 7a 65 20 6f 66 20 74 68 65 20 61 53 65 67  Size of the aSeg
5350: 6d 65 6e 74 5b 5d 20 61 72 72 61 79 20 2a 2f 0a  ment[] array */.
5360: 20 20 73 74 72 75 63 74 20 57 61 6c 53 65 67 6d    struct WalSegm
5370: 65 6e 74 20 7b 0a 20 20 20 20 69 6e 74 20 69 4e  ent {.    int iN
5380: 65 78 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ext;            
5390: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
53a0: 73 6c 6f 74 20 69 6e 20 61 49 6e 64 65 78 5b 5d  slot in aIndex[]
53b0: 20 6e 6f 74 20 79 65 74 20 72 65 74 75 72 6e 65   not yet returne
53c0: 64 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74  d */.    ht_slot
53d0: 20 2a 61 49 6e 64 65 78 3b 20 20 20 20 20 20 20   *aIndex;       
53e0: 20 20 20 20 20 20 20 2f 2a 20 69 30 2c 20 69 31         /* i0, i1
53f0: 2c 20 69 32 2e 2e 2e 20 73 75 63 68 20 74 68 61  , i2... such tha
5400: 74 20 61 50 67 6e 6f 5b 69 4e 5d 20 61 73 63 65  t aPgno[iN] asce
5410: 6e 64 20 2a 2f 0a 20 20 20 20 75 33 32 20 2a 61  nd */.    u32 *a
5420: 50 67 6e 6f 3b 20 20 20 20 20 20 20 20 20 20 20  Pgno;           
5430: 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79          /* Array
5440: 20 6f 66 20 70 61 67 65 20 6e 75 6d 62 65 72 73   of page numbers
5450: 2e 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e 45 6e  . */.    int nEn
5460: 74 72 79 3b 20 20 20 20 20 20 20 20 20 20 20 20  try;            
5470: 20 20 20 20 20 20 20 2f 2a 20 4d 61 78 20 73 69         /* Max si
5480: 7a 65 20 6f 66 20 61 50 67 6e 6f 5b 5d 20 61 6e  ze of aPgno[] an
5490: 64 20 61 49 6e 64 65 78 5b 5d 20 61 72 72 61 79  d aIndex[] array
54a0: 73 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 5a 65  s */.    int iZe
54b0: 72 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ro;             
54c0: 20 20 20 20 20 20 20 2f 2a 20 46 72 61 6d 65 20         /* Frame 
54d0: 6e 75 6d 62 65 72 20 61 73 73 6f 63 69 61 74 65  number associate
54e0: 64 20 77 69 74 68 20 61 50 67 6e 6f 5b 30 5d 20  d with aPgno[0] 
54f0: 2a 2f 0a 20 20 7d 20 61 53 65 67 6d 65 6e 74 5b  */.  } aSegment[
5500: 31 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  1];             
5510: 20 20 20 20 20 2f 2a 20 4f 6e 65 20 66 6f 72 20       /* One for 
5520: 65 76 65 72 79 20 33 32 4b 42 20 70 61 67 65 20  every 32KB page 
5530: 69 6e 20 74 68 65 20 57 41 4c 20 2a 2f 0a 7d 3b  in the WAL */.};
5540: 0a 0a 2f 2a 0a 2a 2a 20 44 65 66 69 6e 65 20 74  ../*.** Define t
5550: 68 65 20 70 61 72 61 6d 65 74 65 72 73 20 6f 66  he parameters of
5560: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 73   the hash tables
5570: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
5580: 78 20 66 69 6c 65 2e 20 54 68 65 72 65 0a 2a 2a  x file. There.**
5590: 20 69 73 20 61 20 68 61 73 68 2d 74 61 62 6c 65   is a hash-table
55a0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 65 76 65 72 79   following every
55b0: 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45   HASHTABLE_NPAGE
55c0: 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20 69 6e   page numbers in
55d0: 20 74 68 65 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65   the.** wal-inde
55e0: 78 2e 0a 2a 2a 0a 2a 2a 20 43 68 61 6e 67 69 6e  x..**.** Changin
55f0: 67 20 61 6e 79 20 6f 66 20 74 68 65 73 65 20 63  g any of these c
5600: 6f 6e 73 74 61 6e 74 73 20 77 69 6c 6c 20 61 6c  onstants will al
5610: 74 65 72 20 74 68 65 20 77 61 6c 2d 69 6e 64 65  ter the wal-inde
5620: 78 20 66 6f 72 6d 61 74 20 61 6e 64 0a 2a 2a 20  x format and.** 
5630: 63 72 65 61 74 65 20 69 6e 63 6f 6d 70 61 74 69  create incompati
5640: 62 69 6c 69 74 69 65 73 2e 0a 2a 2f 0a 23 64 65  bilities..*/.#de
5650: 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f 4e  fine HASHTABLE_N
5660: 50 41 47 45 20 20 20 20 20 20 34 30 39 36 20 20  PAGE      4096  
5670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5680: 2a 20 4d 75 73 74 20 62 65 20 70 6f 77 65 72 20  * Must be power 
5690: 6f 66 20 32 20 2a 2f 0a 23 64 65 66 69 6e 65 20  of 2 */.#define 
56a0: 48 41 53 48 54 41 42 4c 45 5f 48 41 53 48 5f 31  HASHTABLE_HASH_1
56b0: 20 20 20 20 20 33 38 33 20 20 20 20 20 20 20 20       383        
56c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 68 6f            /* Sho
56d0: 75 6c 64 20 62 65 20 70 72 69 6d 65 20 2a 2f 0a  uld be prime */.
56e0: 23 64 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c  #define HASHTABL
56f0: 45 5f 4e 53 4c 4f 54 20 20 20 20 20 20 28 48 41  E_NSLOT      (HA
5700: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 2a 32 29  SHTABLE_NPAGE*2)
5710: 20 20 2f 2a 20 4d 75 73 74 20 62 65 20 61 20 70    /* Must be a p
5720: 6f 77 65 72 20 6f 66 20 32 20 2a 2f 0a 0a 2f 2a  ower of 2 */../*
5730: 20 0a 2a 2a 20 54 68 65 20 62 6c 6f 63 6b 20 6f   .** The block o
5740: 66 20 70 61 67 65 20 6e 75 6d 62 65 72 73 20 61  f page numbers a
5750: 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74  ssociated with t
5760: 68 65 20 66 69 72 73 74 20 68 61 73 68 2d 74 61  he first hash-ta
5770: 62 6c 65 20 69 6e 20 61 0a 2a 2a 20 77 61 6c 2d  ble in a.** wal-
5780: 69 6e 64 65 78 20 69 73 20 73 6d 61 6c 6c 65 72  index is smaller
5790: 20 74 68 61 6e 20 75 73 75 61 6c 2e 20 54 68 69   than usual. Thi
57a0: 73 20 69 73 20 73 6f 20 74 68 61 74 20 74 68 65  s is so that the
57b0: 72 65 20 69 73 20 61 20 63 6f 6d 70 6c 65 74 65  re is a complete
57c0: 0a 2a 2a 20 68 61 73 68 2d 74 61 62 6c 65 20 6f  .** hash-table o
57d0: 6e 20 65 61 63 68 20 61 6c 69 67 6e 65 64 20 33  n each aligned 3
57e0: 32 4b 42 20 70 61 67 65 20 6f 66 20 74 68 65 20  2KB page of the 
57f0: 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 23 64  wal-index..*/.#d
5800: 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45 5f  efine HASHTABLE_
5810: 4e 50 41 47 45 5f 4f 4e 45 20 20 28 48 41 53 48  NPAGE_ONE  (HASH
5820: 54 41 42 4c 45 5f 4e 50 41 47 45 20 2d 20 28 57  TABLE_NPAGE - (W
5830: 41 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45  ALINDEX_HDR_SIZE
5840: 2f 73 69 7a 65 6f 66 28 75 33 32 29 29 29 0a 0a  /sizeof(u32)))..
5850: 2f 2a 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78  /* The wal-index
5860: 20 69 73 20 64 69 76 69 64 65 64 20 69 6e 74 6f   is divided into
5870: 20 70 61 67 65 73 20 6f 66 20 57 41 4c 49 4e 44   pages of WALIND
5880: 45 58 5f 50 47 53 5a 20 62 79 74 65 73 20 65 61  EX_PGSZ bytes ea
5890: 63 68 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20 57  ch. */.#define W
58a0: 41 4c 49 4e 44 45 58 5f 50 47 53 5a 20 20 20 28  ALINDEX_PGSZ   (
58b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58d0: 20 20 20 20 20 20 20 20 20 5c 0a 20 20 20 20 73           \.    s
58e0: 69 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 2a 48  izeof(ht_slot)*H
58f0: 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 2b  ASHTABLE_NSLOT +
5900: 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45   HASHTABLE_NPAGE
5910: 2a 73 69 7a 65 6f 66 28 75 33 32 29 20 5c 0a 29  *sizeof(u32) \.)
5920: 0a 0a 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20 61  ../*.** Obtain a
5930: 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20   pointer to the 
5940: 69 50 61 67 65 27 74 68 20 70 61 67 65 20 6f 66  iPage'th page of
5950: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20   the wal-index. 
5960: 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a  The wal-index.**
5970: 20 69 73 20 62 72 6f 6b 65 6e 20 69 6e 74 6f 20   is broken into 
5980: 70 61 67 65 73 20 6f 66 20 57 41 4c 49 4e 44 45  pages of WALINDE
5990: 58 5f 50 47 53 5a 20 62 79 74 65 73 2e 20 57 61  X_PGSZ bytes. Wa
59a0: 6c 2d 69 6e 64 65 78 20 70 61 67 65 73 20 61 72  l-index pages ar
59b0: 65 0a 2a 2a 20 6e 75 6d 62 65 72 65 64 20 66 72  e.** numbered fr
59c0: 6f 6d 20 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20 49  om zero..**.** I
59d0: 66 20 74 68 69 73 20 63 61 6c 6c 20 69 73 20 73  f this call is s
59e0: 75 63 63 65 73 73 66 75 6c 2c 20 2a 70 70 50 61  uccessful, *ppPa
59f0: 67 65 20 69 73 20 73 65 74 20 74 6f 20 70 6f 69  ge is set to poi
5a00: 6e 74 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e  nt to the wal-in
5a10: 64 65 78 0a 2a 2a 20 70 61 67 65 20 61 6e 64 20  dex.** page and 
5a20: 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
5a30: 75 72 6e 65 64 2e 20 49 66 20 61 6e 20 65 72 72  urned. If an err
5a40: 6f 72 20 28 61 6e 20 4f 4f 4d 20 6f 72 20 56 46  or (an OOM or VF
5a50: 53 20 65 72 72 6f 72 29 20 6f 63 63 75 72 73 2c  S error) occurs,
5a60: 0a 2a 2a 20 74 68 65 6e 20 61 6e 20 53 51 4c 69  .** then an SQLi
5a70: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73  te error code is
5a80: 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 2a 70   returned and *p
5a90: 70 50 61 67 65 20 69 73 20 73 65 74 20 74 6f 20  pPage is set to 
5aa0: 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  0..*/.static int
5ab0: 20 77 61 6c 49 6e 64 65 78 50 61 67 65 28 57 61   walIndexPage(Wa
5ac0: 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 69 50 61  l *pWal, int iPa
5ad0: 67 65 2c 20 76 6f 6c 61 74 69 6c 65 20 75 33 32  ge, volatile u32
5ae0: 20 2a 2a 70 70 50 61 67 65 29 7b 0a 20 20 69 6e   **ppPage){.  in
5af0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
5b00: 3b 0a 0a 20 20 2f 2a 20 45 6e 6c 61 72 67 65 20  ;..  /* Enlarge 
5b10: 74 68 65 20 70 57 61 6c 2d 3e 61 70 57 69 44 61  the pWal->apWiDa
5b20: 74 61 5b 5d 20 61 72 72 61 79 20 69 66 20 72 65  ta[] array if re
5b30: 71 75 69 72 65 64 20 2a 2f 0a 20 20 69 66 28 20  quired */.  if( 
5b40: 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 3c 3d 69  pWal->nWiData<=i
5b50: 50 61 67 65 20 29 7b 0a 20 20 20 20 69 6e 74 20  Page ){.    int 
5b60: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 75  nByte = sizeof(u
5b70: 33 32 20 2a 29 2a 28 69 50 61 67 65 2b 31 29 3b  32 *)*(iPage+1);
5b80: 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33  .    volatile u3
5b90: 32 20 2a 2a 61 70 4e 65 77 3b 0a 20 20 20 20 61  2 **apNew;.    a
5ba0: 70 4e 65 77 20 3d 20 28 76 6f 6c 61 74 69 6c 65  pNew = (volatile
5bb0: 20 75 33 32 20 2a 2a 29 73 71 6c 69 74 65 33 5f   u32 **)sqlite3_
5bc0: 72 65 61 6c 6c 6f 63 28 28 76 6f 69 64 20 2a 29  realloc((void *)
5bd0: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 2c 20  pWal->apWiData, 
5be0: 6e 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20  nByte);.    if( 
5bf0: 21 61 70 4e 65 77 20 29 7b 0a 20 20 20 20 20 20  !apNew ){.      
5c00: 2a 70 70 50 61 67 65 20 3d 20 30 3b 0a 20 20 20  *ppPage = 0;.   
5c10: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
5c20: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20  _NOMEM;.    }.  
5c30: 20 20 6d 65 6d 73 65 74 28 28 76 6f 69 64 20 2a    memset((void *
5c40: 29 26 61 70 4e 65 77 5b 70 57 61 6c 2d 3e 6e 57  )&apNew[pWal->nW
5c50: 69 44 61 74 61 5d 2c 20 30 2c 20 73 69 7a 65 6f  iData], 0, sizeo
5c60: 66 28 75 33 32 20 2a 29 2a 28 69 50 61 67 65 2b  f(u32 *)*(iPage+
5c70: 31 2d 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61 29  1-pWal->nWiData)
5c80: 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 61 70 57  );.    pWal->apW
5c90: 69 44 61 74 61 20 3d 20 61 70 4e 65 77 3b 0a 20  iData = apNew;. 
5ca0: 20 20 20 70 57 61 6c 2d 3e 6e 57 69 44 61 74 61     pWal->nWiData
5cb0: 20 3d 20 69 50 61 67 65 2b 31 3b 0a 20 20 7d 0a   = iPage+1;.  }.
5cc0: 0a 20 20 2f 2a 20 52 65 71 75 65 73 74 20 61 20  .  /* Request a 
5cd0: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 72  pointer to the r
5ce0: 65 71 75 69 72 65 64 20 70 61 67 65 20 66 72 6f  equired page fro
5cf0: 6d 20 74 68 65 20 56 46 53 20 2a 2f 0a 20 20 69  m the VFS */.  i
5d00: 66 28 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  f( pWal->apWiDat
5d10: 61 5b 69 50 61 67 65 5d 3d 3d 30 20 29 7b 0a 20  a[iPage]==0 ){. 
5d20: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
5d30: 73 53 68 6d 4d 61 70 28 70 57 61 6c 2d 3e 70 44  sShmMap(pWal->pD
5d40: 62 46 64 2c 20 69 50 61 67 65 2c 20 57 41 4c 49  bFd, iPage, WALI
5d50: 4e 44 45 58 5f 50 47 53 5a 2c 20 0a 20 20 20 20  NDEX_PGSZ, .    
5d60: 20 20 20 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c      pWal->writeL
5d70: 6f 63 6b 2c 20 28 76 6f 69 64 20 76 6f 6c 61 74  ock, (void volat
5d80: 69 6c 65 20 2a 2a 29 26 70 57 61 6c 2d 3e 61 70  ile **)&pWal->ap
5d90: 57 69 44 61 74 61 5b 69 50 61 67 65 5d 0a 20 20  WiData[iPage].  
5da0: 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 70 50    );.  }..  *ppP
5db0: 61 67 65 20 3d 20 70 57 61 6c 2d 3e 61 70 57 69  age = pWal->apWi
5dc0: 44 61 74 61 5b 69 50 61 67 65 5d 3b 0a 20 20 61  Data[iPage];.  a
5dd0: 73 73 65 72 74 28 20 69 50 61 67 65 3d 3d 30 20  ssert( iPage==0 
5de0: 7c 7c 20 2a 70 70 50 61 67 65 20 7c 7c 20 72 63  || *ppPage || rc
5df0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20  !=SQLITE_OK );. 
5e00: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
5e10: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f  *.** Return a po
5e20: 69 6e 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c  inter to the Wal
5e30: 43 6b 70 74 49 6e 66 6f 20 73 74 72 75 63 74 75  CkptInfo structu
5e40: 72 65 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e  re in the wal-in
5e50: 64 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  dex..*/.static v
5e60: 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49  olatile WalCkptI
5e70: 6e 66 6f 20 2a 77 61 6c 43 6b 70 74 49 6e 66 6f  nfo *walCkptInfo
5e80: 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61  (Wal *pWal){.  a
5e90: 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69  ssert( pWal->nWi
5ea0: 44 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e  Data>0 && pWal->
5eb0: 61 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20  apWiData[0] );. 
5ec0: 20 72 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c   return (volatil
5ed0: 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 2a 29 26  e WalCkptInfo*)&
5ee0: 28 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b  (pWal->apWiData[
5ef0: 30 5d 5b 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64  0][sizeof(WalInd
5f00: 65 78 48 64 72 29 2f 32 5d 29 3b 0a 7d 0a 0a 2f  exHdr)/2]);.}../
5f10: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f  *.** Return a po
5f20: 69 6e 74 65 72 20 74 6f 20 74 68 65 20 57 61 6c  inter to the Wal
5f30: 49 6e 64 65 78 48 64 72 20 73 74 72 75 63 74 75  IndexHdr structu
5f40: 72 65 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e  re in the wal-in
5f50: 64 65 78 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  dex..*/.static v
5f60: 6f 6c 61 74 69 6c 65 20 57 61 6c 49 6e 64 65 78  olatile WalIndex
5f70: 48 64 72 20 2a 77 61 6c 49 6e 64 65 78 48 64 72  Hdr *walIndexHdr
5f80: 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 61  (Wal *pWal){.  a
5f90: 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69  ssert( pWal->nWi
5fa0: 44 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d 3e  Data>0 && pWal->
5fb0: 61 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a 20  apWiData[0] );. 
5fc0: 20 72 65 74 75 72 6e 20 28 76 6f 6c 61 74 69 6c   return (volatil
5fd0: 65 20 57 61 6c 49 6e 64 65 78 48 64 72 2a 29 70  e WalIndexHdr*)p
5fe0: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d  Wal->apWiData[0]
5ff0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 61  ;.}../*.** The a
6000: 72 67 75 6d 65 6e 74 20 74 6f 20 74 68 69 73 20  rgument to this 
6010: 6d 61 63 72 6f 20 6d 75 73 74 20 62 65 20 6f 66  macro must be of
6020: 20 74 79 70 65 20 75 33 32 2e 20 4f 6e 20 61 20   type u32. On a 
6030: 6c 69 74 74 6c 65 2d 65 6e 64 69 61 6e 0a 2a 2a  little-endian.**
6040: 20 61 72 63 68 69 74 65 63 74 75 72 65 2c 20 69   architecture, i
6050: 74 20 72 65 74 75 72 6e 73 20 74 68 65 20 75 33  t returns the u3
6060: 32 20 76 61 6c 75 65 20 74 68 61 74 20 72 65 73  2 value that res
6070: 75 6c 74 73 20 66 72 6f 6d 20 69 6e 74 65 72 70  ults from interp
6080: 72 65 74 69 6e 67 0a 2a 2a 20 74 68 65 20 34 20  reting.** the 4 
6090: 62 79 74 65 73 20 61 73 20 61 20 62 69 67 2d 65  bytes as a big-e
60a0: 6e 64 69 61 6e 20 76 61 6c 75 65 2e 20 4f 6e 20  ndian value. On 
60b0: 61 20 62 69 67 2d 65 6e 64 69 61 6e 20 61 72 63  a big-endian arc
60c0: 68 69 74 65 63 74 75 72 65 2c 20 69 74 0a 2a 2a  hitecture, it.**
60d0: 20 72 65 74 75 72 6e 73 20 74 68 65 20 76 61 6c   returns the val
60e0: 75 65 20 74 68 61 74 20 77 6f 75 6c 64 20 62 65  ue that would be
60f0: 20 70 72 6f 64 75 63 65 64 20 62 79 20 69 6e 74   produced by int
6100: 65 70 72 65 74 69 6e 67 20 74 68 65 20 34 20 62  epreting the 4 b
6110: 79 74 65 73 0a 2a 2a 20 6f 66 20 74 68 65 20 69  ytes.** of the i
6120: 6e 70 75 74 20 76 61 6c 75 65 20 61 73 20 61 20  nput value as a 
6130: 6c 69 74 74 6c 65 2d 65 6e 64 69 61 6e 20 69 6e  little-endian in
6140: 74 65 67 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e  teger..*/.#defin
6150: 65 20 42 59 54 45 53 57 41 50 33 32 28 78 29 20  e BYTESWAP32(x) 
6160: 28 20 5c 0a 20 20 20 20 28 28 28 78 29 26 30 78  ( \.    (((x)&0x
6170: 30 30 30 30 30 30 46 46 29 3c 3c 32 34 29 20 2b  000000FF)<<24) +
6180: 20 28 28 28 78 29 26 30 78 30 30 30 30 46 46 30   (((x)&0x0000FF0
6190: 30 29 3c 3c 38 29 20 20 5c 0a 20 20 2b 20 28 28  0)<<8)  \.  + ((
61a0: 28 78 29 26 30 78 30 30 46 46 30 30 30 30 29 3e  (x)&0x00FF0000)>
61b0: 3e 38 29 20 20 2b 20 28 28 28 78 29 26 30 78 46  >8)  + (((x)&0xF
61c0: 46 30 30 30 30 30 30 29 3e 3e 32 34 29 20 5c 0a  F000000)>>24) \.
61d0: 29 0a 0a 2f 2a 0a 2a 2a 20 47 65 6e 65 72 61 74  )../*.** Generat
61e0: 65 20 6f 72 20 65 78 74 65 6e 64 20 61 6e 20 38  e or extend an 8
61f0: 20 62 79 74 65 20 63 68 65 63 6b 73 75 6d 20 62   byte checksum b
6200: 61 73 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61  ased on the data
6210: 20 69 6e 20 0a 2a 2a 20 61 72 72 61 79 20 61 42   in .** array aB
6220: 79 74 65 5b 5d 20 61 6e 64 20 74 68 65 20 69 6e  yte[] and the in
6230: 69 74 69 61 6c 20 76 61 6c 75 65 73 20 6f 66 20  itial values of 
6240: 61 49 6e 5b 30 5d 20 61 6e 64 20 61 49 6e 5b 31  aIn[0] and aIn[1
6250: 5d 20 28 6f 72 0a 2a 2a 20 69 6e 69 74 69 61 6c  ] (or.** initial
6260: 20 76 61 6c 75 65 73 20 6f 66 20 30 20 61 6e 64   values of 0 and
6270: 20 30 20 69 66 20 61 49 6e 3d 3d 4e 55 4c 4c 29   0 if aIn==NULL)
6280: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63  ..**.** The chec
6290: 6b 73 75 6d 20 69 73 20 77 72 69 74 74 65 6e 20  ksum is written 
62a0: 62 61 63 6b 20 69 6e 74 6f 20 61 4f 75 74 5b 5d  back into aOut[]
62b0: 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
62c0: 67 2e 0a 2a 2a 0a 2a 2a 20 6e 42 79 74 65 20 6d  g..**.** nByte m
62d0: 75 73 74 20 62 65 20 61 20 70 6f 73 69 74 69 76  ust be a positiv
62e0: 65 20 6d 75 6c 74 69 70 6c 65 20 6f 66 20 38 2e  e multiple of 8.
62f0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
6300: 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73  walChecksumBytes
6310: 28 0a 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b  (.  int nativeCk
6320: 73 75 6d 2c 20 2f 2a 20 54 72 75 65 20 66 6f 72  sum, /* True for
6330: 20 6e 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64   native byte-ord
6340: 65 72 2c 20 66 61 6c 73 65 20 66 6f 72 20 6e 6f  er, false for no
6350: 6e 2d 6e 61 74 69 76 65 20 2a 2f 0a 20 20 75 38  n-native */.  u8
6360: 20 2a 61 2c 20 20 20 20 20 20 20 20 20 20 20 2f   *a,           /
6370: 2a 20 43 6f 6e 74 65 6e 74 20 74 6f 20 62 65 20  * Content to be 
6380: 63 68 65 63 6b 73 75 6d 6d 65 64 20 2a 2f 0a 20  checksummed */. 
6390: 20 69 6e 74 20 6e 42 79 74 65 2c 20 20 20 20 20   int nByte,     
63a0: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 63 6f    /* Bytes of co
63b0: 6e 74 65 6e 74 20 69 6e 20 61 5b 5d 2e 20 20 4d  ntent in a[].  M
63c0: 75 73 74 20 62 65 20 61 20 6d 75 6c 74 69 70 6c  ust be a multipl
63d0: 65 20 6f 66 20 38 2e 20 2a 2f 0a 20 20 63 6f 6e  e of 8. */.  con
63e0: 73 74 20 75 33 32 20 2a 61 49 6e 2c 20 20 2f 2a  st u32 *aIn,  /*
63f0: 20 49 6e 69 74 69 61 6c 20 63 68 65 63 6b 73 75   Initial checksu
6400: 6d 20 76 61 6c 75 65 20 69 6e 70 75 74 20 2a 2f  m value input */
6410: 0a 20 20 75 33 32 20 2a 61 4f 75 74 20 20 20 20  .  u32 *aOut    
6420: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 46 69 6e 61      /* OUT: Fina
6430: 6c 20 63 68 65 63 6b 73 75 6d 20 76 61 6c 75 65  l checksum value
6440: 20 6f 75 74 70 75 74 20 2a 2f 0a 29 7b 0a 20 20   output */.){.  
6450: 75 33 32 20 73 31 2c 20 73 32 3b 0a 20 20 75 33  u32 s1, s2;.  u3
6460: 32 20 2a 61 44 61 74 61 20 3d 20 28 75 33 32 20  2 *aData = (u32 
6470: 2a 29 61 3b 0a 20 20 75 33 32 20 2a 61 45 6e 64  *)a;.  u32 *aEnd
6480: 20 3d 20 28 75 33 32 20 2a 29 26 61 5b 6e 42 79   = (u32 *)&a[nBy
6490: 74 65 5d 3b 0a 0a 20 20 69 66 28 20 61 49 6e 20  te];..  if( aIn 
64a0: 29 7b 0a 20 20 20 20 73 31 20 3d 20 61 49 6e 5b  ){.    s1 = aIn[
64b0: 30 5d 3b 0a 20 20 20 20 73 32 20 3d 20 61 49 6e  0];.    s2 = aIn
64c0: 5b 31 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  [1];.  }else{.  
64d0: 20 20 73 31 20 3d 20 73 32 20 3d 20 30 3b 0a 20    s1 = s2 = 0;. 
64e0: 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 42   }..  assert( nB
64f0: 79 74 65 3e 3d 38 20 29 3b 0a 20 20 61 73 73 65  yte>=8 );.  asse
6500: 72 74 28 20 28 6e 42 79 74 65 26 30 78 30 30 30  rt( (nByte&0x000
6510: 30 30 30 30 37 29 3d 3d 30 20 29 3b 0a 0a 20 20  00007)==0 );..  
6520: 69 66 28 20 6e 61 74 69 76 65 43 6b 73 75 6d 20  if( nativeCksum 
6530: 29 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20  ){.    do {.    
6540: 20 20 73 31 20 2b 3d 20 2a 61 44 61 74 61 2b 2b    s1 += *aData++
6550: 20 2b 20 73 32 3b 0a 20 20 20 20 20 20 73 32 20   + s2;.      s2 
6560: 2b 3d 20 2a 61 44 61 74 61 2b 2b 20 2b 20 73 31  += *aData++ + s1
6570: 3b 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 61 44  ;.    }while( aD
6580: 61 74 61 3c 61 45 6e 64 20 29 3b 0a 20 20 7d 65  ata<aEnd );.  }e
6590: 6c 73 65 7b 0a 20 20 20 20 64 6f 20 7b 0a 20 20  lse{.    do {.  
65a0: 20 20 20 20 73 31 20 2b 3d 20 42 59 54 45 53 57      s1 += BYTESW
65b0: 41 50 33 32 28 61 44 61 74 61 5b 30 5d 29 20 2b  AP32(aData[0]) +
65c0: 20 73 32 3b 0a 20 20 20 20 20 20 73 32 20 2b 3d   s2;.      s2 +=
65d0: 20 42 59 54 45 53 57 41 50 33 32 28 61 44 61 74   BYTESWAP32(aDat
65e0: 61 5b 31 5d 29 20 2b 20 73 31 3b 0a 20 20 20 20  a[1]) + s1;.    
65f0: 20 20 61 44 61 74 61 20 2b 3d 20 32 3b 0a 20 20    aData += 2;.  
6600: 20 20 7d 77 68 69 6c 65 28 20 61 44 61 74 61 3c    }while( aData<
6610: 61 45 6e 64 20 29 3b 0a 20 20 7d 0a 0a 20 20 61  aEnd );.  }..  a
6620: 4f 75 74 5b 30 5d 20 3d 20 73 31 3b 0a 20 20 61  Out[0] = s1;.  a
6630: 4f 75 74 5b 31 5d 20 3d 20 73 32 3b 0a 7d 0a 0a  Out[1] = s2;.}..
6640: 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68 65 20  /*.** Write the 
6650: 68 65 61 64 65 72 20 69 6e 66 6f 72 6d 61 74 69  header informati
6660: 6f 6e 20 69 6e 20 70 57 61 6c 2d 3e 68 64 72 20  on in pWal->hdr 
6670: 69 6e 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64  into the wal-ind
6680: 65 78 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68  ex..**.** The ch
6690: 65 63 6b 73 75 6d 20 6f 6e 20 70 57 61 6c 2d 3e  ecksum on pWal->
66a0: 68 64 72 20 69 73 20 75 70 64 61 74 65 64 20 62  hdr is updated b
66b0: 65 66 6f 72 65 20 69 74 20 69 73 20 77 72 69 74  efore it is writ
66c0: 74 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ten..*/.static v
66d0: 6f 69 64 20 77 61 6c 49 6e 64 65 78 57 72 69 74  oid walIndexWrit
66e0: 65 48 64 72 28 57 61 6c 20 2a 70 57 61 6c 29 7b  eHdr(Wal *pWal){
66f0: 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 49  .  volatile WalI
6700: 6e 64 65 78 48 64 72 20 2a 61 48 64 72 20 3d 20  ndexHdr *aHdr = 
6710: 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61 6c  walIndexHdr(pWal
6720: 29 3b 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20 6e  );.  const int n
6730: 43 6b 73 75 6d 20 3d 20 6f 66 66 73 65 74 6f 66  Cksum = offsetof
6740: 28 57 61 6c 49 6e 64 65 78 48 64 72 2c 20 61 43  (WalIndexHdr, aC
6750: 6b 73 75 6d 29 3b 0a 0a 20 20 61 73 73 65 72 74  ksum);..  assert
6760: 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63  ( pWal->writeLoc
6770: 6b 20 29 3b 0a 20 20 70 57 61 6c 2d 3e 68 64 72  k );.  pWal->hdr
6780: 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a 20 20 70  .isInit = 1;.  p
6790: 57 61 6c 2d 3e 68 64 72 2e 69 56 65 72 73 69 6f  Wal->hdr.iVersio
67a0: 6e 20 3d 20 57 41 4c 49 4e 44 45 58 5f 4d 41 58  n = WALINDEX_MAX
67b0: 5f 56 45 52 53 49 4f 4e 3b 0a 20 20 77 61 6c 43  _VERSION;.  walC
67c0: 68 65 63 6b 73 75 6d 42 79 74 65 73 28 31 2c 20  hecksumBytes(1, 
67d0: 28 75 38 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c  (u8*)&pWal->hdr,
67e0: 20 6e 43 6b 73 75 6d 2c 20 30 2c 20 70 57 61 6c   nCksum, 0, pWal
67f0: 2d 3e 68 64 72 2e 61 43 6b 73 75 6d 29 3b 0a 20  ->hdr.aCksum);. 
6800: 20 6d 65 6d 63 70 79 28 28 76 6f 69 64 20 2a 29   memcpy((void *)
6810: 26 61 48 64 72 5b 31 5d 2c 20 28 76 6f 69 64 20  &aHdr[1], (void 
6820: 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c 20 73 69  *)&pWal->hdr, si
6830: 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
6840: 29 29 3b 0a 20 20 73 71 6c 69 74 65 33 4f 73 53  ));.  sqlite3OsS
6850: 68 6d 42 61 72 72 69 65 72 28 70 57 61 6c 2d 3e  hmBarrier(pWal->
6860: 70 44 62 46 64 29 3b 0a 20 20 6d 65 6d 63 70 79  pDbFd);.  memcpy
6870: 28 28 76 6f 69 64 20 2a 29 26 61 48 64 72 5b 30  ((void *)&aHdr[0
6880: 5d 2c 20 28 76 6f 69 64 20 2a 29 26 70 57 61 6c  ], (void *)&pWal
6890: 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57 61  ->hdr, sizeof(Wa
68a0: 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 7d 0a 0a  lIndexHdr));.}..
68b0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
68c0: 69 6f 6e 20 65 6e 63 6f 64 65 73 20 61 20 73 69  ion encodes a si
68d0: 6e 67 6c 65 20 66 72 61 6d 65 20 68 65 61 64 65  ngle frame heade
68e0: 72 20 61 6e 64 20 77 72 69 74 65 73 20 69 74 20  r and writes it 
68f0: 74 6f 20 61 20 62 75 66 66 65 72 0a 2a 2a 20 73  to a buffer.** s
6900: 75 70 70 6c 69 65 64 20 62 79 20 74 68 65 20 63  upplied by the c
6910: 61 6c 6c 65 72 2e 20 41 20 66 72 61 6d 65 2d 68  aller. A frame-h
6920: 65 61 64 65 72 20 69 73 20 6d 61 64 65 20 75 70  eader is made up
6930: 20 6f 66 20 61 20 73 65 72 69 65 73 20 6f 66 20   of a series of 
6940: 0a 2a 2a 20 34 2d 62 79 74 65 20 62 69 67 2d 65  .** 4-byte big-e
6950: 6e 64 69 61 6e 20 69 6e 74 65 67 65 72 73 2c 20  ndian integers, 
6960: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a  as follows:.**.*
6970: 2a 20 20 20 20 20 30 3a 20 50 61 67 65 20 6e 75  *     0: Page nu
6980: 6d 62 65 72 2e 0a 2a 2a 20 20 20 20 20 34 3a 20  mber..**     4: 
6990: 46 6f 72 20 63 6f 6d 6d 69 74 20 72 65 63 6f 72  For commit recor
69a0: 64 73 2c 20 74 68 65 20 73 69 7a 65 20 6f 66 20  ds, the size of 
69b0: 74 68 65 20 64 61 74 61 62 61 73 65 20 69 6d 61  the database ima
69c0: 67 65 20 69 6e 20 70 61 67 65 73 20 0a 2a 2a 20  ge in pages .** 
69d0: 20 20 20 20 20 20 20 61 66 74 65 72 20 74 68 65         after the
69e0: 20 63 6f 6d 6d 69 74 2e 20 46 6f 72 20 61 6c 6c   commit. For all
69f0: 20 6f 74 68 65 72 20 72 65 63 6f 72 64 73 2c 20   other records, 
6a00: 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20 20 38 3a 20  zero..**     8: 
6a10: 53 61 6c 74 2d 31 20 28 63 6f 70 69 65 64 20 66  Salt-1 (copied f
6a20: 72 6f 6d 20 74 68 65 20 77 61 6c 2d 68 65 61 64  rom the wal-head
6a30: 65 72 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61  er).**    12: Sa
6a40: 6c 74 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f  lt-2 (copied fro
6a50: 6d 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  m the wal-header
6a60: 29 0a 2a 2a 20 20 20 20 31 36 3a 20 43 68 65 63  ).**    16: Chec
6a70: 6b 73 75 6d 2d 31 2e 0a 2a 2a 20 20 20 20 32 30  ksum-1..**    20
6a80: 3a 20 43 68 65 63 6b 73 75 6d 2d 32 2e 0a 2a 2f  : Checksum-2..*/
6a90: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
6aa0: 45 6e 63 6f 64 65 46 72 61 6d 65 28 0a 20 20 57  EncodeFrame(.  W
6ab0: 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20 20 20  al *pWal,       
6ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6ad0: 2a 20 54 68 65 20 77 72 69 74 65 2d 61 68 65 61  * The write-ahea
6ae0: 64 20 6c 6f 67 20 2a 2f 0a 20 20 75 33 32 20 69  d log */.  u32 i
6af0: 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20 20  Page,           
6b00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
6b10: 74 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62  tabase page numb
6b20: 65 72 20 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a  er for frame */.
6b30: 20 20 75 33 32 20 6e 54 72 75 6e 63 61 74 65 2c    u32 nTruncate,
6b40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b50: 20 20 2f 2a 20 4e 65 77 20 64 62 20 73 69 7a 65    /* New db size
6b60: 20 28 6f 72 20 30 20 66 6f 72 20 6e 6f 6e 2d 63   (or 0 for non-c
6b70: 6f 6d 6d 69 74 20 66 72 61 6d 65 73 29 20 2a 2f  ommit frames) */
6b80: 0a 20 20 75 38 20 2a 61 44 61 74 61 2c 20 20 20  .  u8 *aData,   
6b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ba0: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
6bb0: 20 70 61 67 65 20 64 61 74 61 20 2a 2f 0a 20 20   page data */.  
6bc0: 75 38 20 2a 61 46 72 61 6d 65 20 20 20 20 20 20  u8 *aFrame      
6bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6be0: 2f 2a 20 4f 55 54 3a 20 57 72 69 74 65 20 65 6e  /* OUT: Write en
6bf0: 63 6f 64 65 64 20 66 72 61 6d 65 20 68 65 72 65  coded frame here
6c00: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 61 74   */.){.  int nat
6c10: 69 76 65 43 6b 73 75 6d 3b 20 20 20 20 20 20 20  iveCksum;       
6c20: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
6c30: 20 66 6f 72 20 6e 61 74 69 76 65 20 62 79 74 65   for native byte
6c40: 2d 6f 72 64 65 72 20 63 68 65 63 6b 73 75 6d 73  -order checksums
6c50: 20 2a 2f 0a 20 20 75 33 32 20 2a 61 43 6b 73 75   */.  u32 *aCksu
6c60: 6d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46  m = pWal->hdr.aF
6c70: 72 61 6d 65 43 6b 73 75 6d 3b 0a 20 20 61 73 73  rameCksum;.  ass
6c80: 65 72 74 28 20 57 41 4c 5f 46 52 41 4d 45 5f 48  ert( WAL_FRAME_H
6c90: 44 52 53 49 5a 45 3d 3d 32 34 20 29 3b 0a 20 20  DRSIZE==24 );.  
6ca0: 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28  sqlite3Put4byte(
6cb0: 26 61 46 72 61 6d 65 5b 30 5d 2c 20 69 50 61 67  &aFrame[0], iPag
6cc0: 65 29 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74  e);.  sqlite3Put
6cd0: 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 34 5d  4byte(&aFrame[4]
6ce0: 2c 20 6e 54 72 75 6e 63 61 74 65 29 3b 0a 20 20  , nTruncate);.  
6cf0: 6d 65 6d 63 70 79 28 26 61 46 72 61 6d 65 5b 38  memcpy(&aFrame[8
6d00: 5d 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61  ], pWal->hdr.aSa
6d10: 6c 74 2c 20 38 29 3b 0a 0a 20 20 6e 61 74 69 76  lt, 8);..  nativ
6d20: 65 43 6b 73 75 6d 20 3d 20 28 70 57 61 6c 2d 3e  eCksum = (pWal->
6d30: 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d  hdr.bigEndCksum=
6d40: 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41  =SQLITE_BIGENDIA
6d50: 4e 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75  N);.  walChecksu
6d60: 6d 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73  mBytes(nativeCks
6d70: 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38 2c 20 61  um, aFrame, 8, a
6d80: 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a  Cksum, aCksum);.
6d90: 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74    walChecksumByt
6da0: 65 73 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20  es(nativeCksum, 
6db0: 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e 73 7a 50  aData, pWal->szP
6dc0: 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b  age, aCksum, aCk
6dd0: 73 75 6d 29 3b 0a 0a 20 20 73 71 6c 69 74 65 33  sum);..  sqlite3
6de0: 50 75 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Put4byte(&aFrame
6df0: 5b 31 36 5d 2c 20 61 43 6b 73 75 6d 5b 30 5d 29  [16], aCksum[0])
6e00: 3b 0a 20 20 73 71 6c 69 74 65 33 50 75 74 34 62  ;.  sqlite3Put4b
6e10: 79 74 65 28 26 61 46 72 61 6d 65 5b 32 30 5d 2c  yte(&aFrame[20],
6e20: 20 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 7d 0a 0a   aCksum[1]);.}..
6e30: 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 6f 20 73  /*.** Check to s
6e40: 65 65 20 69 66 20 74 68 65 20 66 72 61 6d 65 20  ee if the frame 
6e50: 77 69 74 68 20 68 65 61 64 65 72 20 69 6e 20 61  with header in a
6e60: 46 72 61 6d 65 5b 5d 20 61 6e 64 20 63 6f 6e 74  Frame[] and cont
6e70: 65 6e 74 0a 2a 2a 20 69 6e 20 61 44 61 74 61 5b  ent.** in aData[
6e80: 5d 20 69 73 20 76 61 6c 69 64 2e 20 20 49 66 20  ] is valid.  If 
6e90: 69 74 20 69 73 20 61 20 76 61 6c 69 64 20 66 72  it is a valid fr
6ea0: 61 6d 65 2c 20 66 69 6c 6c 20 2a 70 69 50 61 67  ame, fill *piPag
6eb0: 65 20 61 6e 64 0a 2a 2a 20 2a 70 6e 54 72 75 6e  e and.** *pnTrun
6ec0: 63 61 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20  cate and return 
6ed0: 74 72 75 65 2e 20 20 52 65 74 75 72 6e 20 69 66  true.  Return if
6ee0: 20 74 68 65 20 66 72 61 6d 65 20 69 73 20 6e 6f   the frame is no
6ef0: 74 20 76 61 6c 69 64 2e 0a 2a 2f 0a 73 74 61 74  t valid..*/.stat
6f00: 69 63 20 69 6e 74 20 77 61 6c 44 65 63 6f 64 65  ic int walDecode
6f10: 46 72 61 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57  Frame(.  Wal *pW
6f20: 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
6f30: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
6f40: 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20  write-ahead log 
6f50: 2a 2f 0a 20 20 75 33 32 20 2a 70 69 50 61 67 65  */.  u32 *piPage
6f60: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
6f70: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 44 61 74       /* OUT: Dat
6f80: 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65  abase page numbe
6f90: 72 20 66 6f 72 20 66 72 61 6d 65 20 2a 2f 0a 20  r for frame */. 
6fa0: 20 75 33 32 20 2a 70 6e 54 72 75 6e 63 61 74 65   u32 *pnTruncate
6fb0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
6fc0: 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 64 62 20   /* OUT: New db 
6fd0: 73 69 7a 65 20 28 6f 72 20 30 20 69 66 20 6e 6f  size (or 0 if no
6fe0: 74 20 63 6f 6d 6d 69 74 29 20 2a 2f 0a 20 20 75  t commit) */.  u
6ff0: 38 20 2a 61 44 61 74 61 2c 20 20 20 20 20 20 20  8 *aData,       
7000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7010: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 70 61 67  * Pointer to pag
7020: 65 20 64 61 74 61 20 28 66 6f 72 20 63 68 65 63  e data (for chec
7030: 6b 73 75 6d 29 20 2a 2f 0a 20 20 75 38 20 2a 61  ksum) */.  u8 *a
7040: 46 72 61 6d 65 20 20 20 20 20 20 20 20 20 20 20  Frame           
7050: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
7060: 61 6d 65 20 64 61 74 61 20 2a 2f 0a 29 7b 0a 20  ame data */.){. 
7070: 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73 75 6d   int nativeCksum
7080: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
7090: 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e 61 74   /* True for nat
70a0: 69 76 65 20 62 79 74 65 2d 6f 72 64 65 72 20 63  ive byte-order c
70b0: 68 65 63 6b 73 75 6d 73 20 2a 2f 0a 20 20 75 33  hecksums */.  u3
70c0: 32 20 2a 61 43 6b 73 75 6d 20 3d 20 70 57 61 6c  2 *aCksum = pWal
70d0: 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
70e0: 6d 3b 0a 20 20 75 33 32 20 70 67 6e 6f 3b 20 20  m;.  u32 pgno;  
70f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7100: 20 20 20 20 20 2f 2a 20 50 61 67 65 20 6e 75 6d       /* Page num
7110: 62 65 72 20 6f 66 20 74 68 65 20 66 72 61 6d 65  ber of the frame
7120: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 57 41   */.  assert( WA
7130: 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 3d  L_FRAME_HDRSIZE=
7140: 3d 32 34 20 29 3b 0a 0a 20 20 2f 2a 20 41 20 66  =24 );..  /* A f
7150: 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c  rame is only val
7160: 69 64 20 69 66 20 74 68 65 20 73 61 6c 74 20 76  id if the salt v
7170: 61 6c 75 65 73 20 69 6e 20 74 68 65 20 66 72 61  alues in the fra
7180: 6d 65 2d 68 65 61 64 65 72 0a 20 20 2a 2a 20 6d  me-header.  ** m
7190: 61 74 63 68 20 74 68 65 20 73 61 6c 74 20 76 61  atch the salt va
71a0: 6c 75 65 73 20 69 6e 20 74 68 65 20 77 61 6c 2d  lues in the wal-
71b0: 68 65 61 64 65 72 2e 20 0a 20 20 2a 2f 0a 20 20  header. .  */.  
71c0: 69 66 28 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c  if( memcmp(&pWal
71d0: 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 26 61 46  ->hdr.aSalt, &aF
71e0: 72 61 6d 65 5b 38 5d 2c 20 38 29 21 3d 30 20 29  rame[8], 8)!=0 )
71f0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  {.    return 0;.
7200: 20 20 7d 0a 0a 20 20 2f 2a 20 41 20 66 72 61 6d    }..  /* A fram
7210: 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20  e is only valid 
7220: 69 66 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62  if the page numb
7230: 65 72 20 69 73 20 63 72 65 61 74 65 72 20 74 68  er is creater th
7240: 61 6e 20 7a 65 72 6f 2e 0a 20 20 2a 2f 0a 20 20  an zero..  */.  
7250: 70 67 6e 6f 20 3d 20 73 71 6c 69 74 65 33 47 65  pgno = sqlite3Ge
7260: 74 34 62 79 74 65 28 26 61 46 72 61 6d 65 5b 30  t4byte(&aFrame[0
7270: 5d 29 3b 0a 20 20 69 66 28 20 70 67 6e 6f 3d 3d  ]);.  if( pgno==
7280: 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  0 ){.    return 
7290: 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 20 66  0;.  }..  /* A f
72a0: 72 61 6d 65 20 69 73 20 6f 6e 6c 79 20 76 61 6c  rame is only val
72b0: 69 64 20 69 66 20 61 20 63 68 65 63 6b 73 75 6d  id if a checksum
72c0: 20 6f 66 20 74 68 65 20 66 69 72 73 74 20 31 36   of the first 16
72d0: 20 62 79 74 65 73 0a 20 20 2a 2a 20 6f 66 20 74   bytes.  ** of t
72e0: 68 65 20 66 72 61 6d 65 2d 68 65 61 64 65 72 2c  he frame-header,
72f0: 20 61 6e 64 20 74 68 65 20 66 72 61 6d 65 2d 64   and the frame-d
7300: 61 74 61 20 6d 61 74 63 68 65 73 0a 20 20 2a 2a  ata matches.  **
7310: 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 69 6e   the checksum in
7320: 20 74 68 65 20 6c 61 73 74 20 38 20 62 79 74 65   the last 8 byte
7330: 73 20 6f 66 20 74 68 65 20 66 72 61 6d 65 2d 68  s of the frame-h
7340: 65 61 64 65 72 2e 0a 20 20 2a 2f 0a 20 20 6e 61  eader..  */.  na
7350: 74 69 76 65 43 6b 73 75 6d 20 3d 20 28 70 57 61  tiveCksum = (pWa
7360: 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73  l->hdr.bigEndCks
7370: 75 6d 3d 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e  um==SQLITE_BIGEN
7380: 44 49 41 4e 29 3b 0a 20 20 77 61 6c 43 68 65 63  DIAN);.  walChec
7390: 6b 73 75 6d 42 79 74 65 73 28 6e 61 74 69 76 65  ksumBytes(native
73a0: 43 6b 73 75 6d 2c 20 61 46 72 61 6d 65 2c 20 38  Cksum, aFrame, 8
73b0: 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d  , aCksum, aCksum
73c0: 29 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d  );.  walChecksum
73d0: 42 79 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75  Bytes(nativeCksu
73e0: 6d 2c 20 61 44 61 74 61 2c 20 70 57 61 6c 2d 3e  m, aData, pWal->
73f0: 73 7a 50 61 67 65 2c 20 61 43 6b 73 75 6d 2c 20  szPage, aCksum, 
7400: 61 43 6b 73 75 6d 29 3b 0a 20 20 69 66 28 20 61  aCksum);.  if( a
7410: 43 6b 73 75 6d 5b 30 5d 21 3d 73 71 6c 69 74 65  Cksum[0]!=sqlite
7420: 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Get4byte(&aFram
7430: 65 5b 31 36 5d 29 20 0a 20 20 20 7c 7c 20 61 43  e[16]) .   || aC
7440: 6b 73 75 6d 5b 31 5d 21 3d 73 71 6c 69 74 65 33  ksum[1]!=sqlite3
7450: 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d 65  Get4byte(&aFrame
7460: 5b 32 30 5d 29 20 0a 20 20 29 7b 0a 20 20 20 20  [20]) .  ){.    
7470: 2f 2a 20 43 68 65 63 6b 73 75 6d 20 66 61 69 6c  /* Checksum fail
7480: 65 64 2e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72  ed. */.    retur
7490: 6e 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49  n 0;.  }..  /* I
74a0: 66 20 77 65 20 72 65 61 63 68 20 74 68 69 73 20  f we reach this 
74b0: 70 6f 69 6e 74 2c 20 74 68 65 20 66 72 61 6d 65  point, the frame
74c0: 20 69 73 20 76 61 6c 69 64 2e 20 20 52 65 74 75   is valid.  Retu
74d0: 72 6e 20 74 68 65 20 70 61 67 65 20 6e 75 6d 62  rn the page numb
74e0: 65 72 0a 20 20 2a 2a 20 61 6e 64 20 74 68 65 20  er.  ** and the 
74f0: 6e 65 77 20 64 61 74 61 62 61 73 65 20 73 69 7a  new database siz
7500: 65 2e 0a 20 20 2a 2f 0a 20 20 2a 70 69 50 61 67  e..  */.  *piPag
7510: 65 20 3d 20 70 67 6e 6f 3b 0a 20 20 2a 70 6e 54  e = pgno;.  *pnT
7520: 72 75 6e 63 61 74 65 20 3d 20 73 71 6c 69 74 65  runcate = sqlite
7530: 33 47 65 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Get4byte(&aFram
7540: 65 5b 34 5d 29 3b 0a 20 20 72 65 74 75 72 6e 20  e[4]);.  return 
7550: 31 3b 0a 7d 0a 0a 0a 23 69 66 20 64 65 66 69 6e  1;.}...#if defin
7560: 65 64 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20  ed(SQLITE_TEST) 
7570: 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54  && defined(SQLIT
7580: 45 5f 44 45 42 55 47 29 0a 2f 2a 0a 2a 2a 20 4e  E_DEBUG)./*.** N
7590: 61 6d 65 73 20 6f 66 20 6c 6f 63 6b 73 2e 20 20  ames of locks.  
75a0: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20  This routine is 
75b0: 75 73 65 64 20 74 6f 20 70 72 6f 76 69 64 65 20  used to provide 
75c0: 64 65 62 75 67 67 69 6e 67 20 6f 75 74 70 75 74  debugging output
75d0: 20 61 6e 64 20 69 73 20 6e 6f 74 0a 2a 2a 20 61   and is not.** a
75e0: 20 70 61 72 74 20 6f 66 20 61 6e 20 6f 72 64 69   part of an ordi
75f0: 6e 61 72 79 20 62 75 69 6c 64 2e 0a 2a 2f 0a 73  nary build..*/.s
7600: 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72  tatic const char
7610: 20 2a 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 69 6e   *walLockName(in
7620: 74 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66  t lockIdx){.  if
7630: 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 57  ( lockIdx==WAL_W
7640: 52 49 54 45 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20  RITE_LOCK ){.   
7650: 20 72 65 74 75 72 6e 20 22 57 52 49 54 45 2d 4c   return "WRITE-L
7660: 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66  OCK";.  }else if
7670: 28 20 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 43  ( lockIdx==WAL_C
7680: 4b 50 54 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20 20  KPT_LOCK ){.    
7690: 72 65 74 75 72 6e 20 22 43 4b 50 54 2d 4c 4f 43  return "CKPT-LOC
76a0: 4b 22 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20  K";.  }else if( 
76b0: 6c 6f 63 6b 49 64 78 3d 3d 57 41 4c 5f 52 45 43  lockIdx==WAL_REC
76c0: 4f 56 45 52 5f 4c 4f 43 4b 20 29 7b 0a 20 20 20  OVER_LOCK ){.   
76d0: 20 72 65 74 75 72 6e 20 22 52 45 43 4f 56 45 52   return "RECOVER
76e0: 2d 4c 4f 43 4b 22 3b 0a 20 20 7d 65 6c 73 65 7b  -LOCK";.  }else{
76f0: 0a 20 20 20 20 73 74 61 74 69 63 20 63 68 61 72  .    static char
7700: 20 7a 4e 61 6d 65 5b 31 35 5d 3b 0a 20 20 20 20   zName[15];.    
7710: 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66  sqlite3_snprintf
7720: 28 73 69 7a 65 6f 66 28 7a 4e 61 6d 65 29 2c 20  (sizeof(zName), 
7730: 7a 4e 61 6d 65 2c 20 22 52 45 41 44 2d 4c 4f 43  zName, "READ-LOC
7740: 4b 5b 25 64 5d 22 2c 0a 20 20 20 20 20 20 20 20  K[%d]",.        
7750: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 63               loc
7760: 6b 49 64 78 2d 57 41 4c 5f 52 45 41 44 5f 4c 4f  kIdx-WAL_READ_LO
7770: 43 4b 28 30 29 29 3b 0a 20 20 20 20 72 65 74 75  CK(0));.    retu
7780: 72 6e 20 7a 4e 61 6d 65 3b 0a 20 20 7d 0a 7d 0a  rn zName;.  }.}.
7790: 23 65 6e 64 69 66 20 2f 2a 64 65 66 69 6e 65 64  #endif /*defined
77a0: 28 53 51 4c 49 54 45 5f 54 45 53 54 29 20 7c 7c  (SQLITE_TEST) ||
77b0: 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
77c0: 44 45 42 55 47 29 20 2a 2f 0a 20 20 20 20 0a 0a  DEBUG) */.    ..
77d0: 2f 2a 0a 2a 2a 20 53 65 74 20 6f 72 20 72 65 6c  /*.** Set or rel
77e0: 65 61 73 65 20 6c 6f 63 6b 73 20 6f 6e 20 74 68  ease locks on th
77f0: 65 20 57 41 4c 2e 20 20 4c 6f 63 6b 73 20 61 72  e WAL.  Locks ar
7800: 65 20 65 69 74 68 65 72 20 73 68 61 72 65 64 20  e either shared 
7810: 6f 72 20 65 78 63 6c 75 73 69 76 65 2e 0a 2a 2a  or exclusive..**
7820: 20 41 20 6c 6f 63 6b 20 63 61 6e 6e 6f 74 20 62   A lock cannot b
7830: 65 20 6d 6f 76 65 64 20 64 69 72 65 63 74 6c 79  e moved directly
7840: 20 62 65 74 77 65 65 6e 20 73 68 61 72 65 64 20   between shared 
7850: 61 6e 64 20 65 78 63 6c 75 73 69 76 65 20 2d 20  and exclusive - 
7860: 69 74 20 6d 75 73 74 20 67 6f 0a 2a 2a 20 74 68  it must go.** th
7870: 72 6f 75 67 68 20 74 68 65 20 75 6e 6c 6f 63 6b  rough the unlock
7880: 65 64 20 73 74 61 74 65 20 66 69 72 73 74 2e 0a  ed state first..
7890: 2a 2a 0a 2a 2a 20 49 6e 20 6c 6f 63 6b 69 6e 67  **.** In locking
78a0: 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2c  _mode=EXCLUSIVE,
78b0: 20 61 6c 6c 20 6f 66 20 74 68 65 73 65 20 72 6f   all of these ro
78c0: 75 74 69 6e 65 73 20 62 65 63 6f 6d 65 20 6e 6f  utines become no
78d0: 2d 6f 70 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  -ops..*/.static 
78e0: 69 6e 74 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65  int walLockShare
78f0: 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  d(Wal *pWal, int
7900: 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 6e 74   lockIdx){.  int
7910: 20 72 63 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d   rc;.  if( pWal-
7920: 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29  >exclusiveMode )
7930: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
7940: 4b 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  K;.  rc = sqlite
7950: 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d  3OsShmLock(pWal-
7960: 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c  >pDbFd, lockIdx,
7970: 20 31 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20   1,.            
7980: 20 20 20 20 20 20 20 20 20 20 20 20 53 51 4c 49              SQLI
7990: 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51  TE_SHM_LOCK | SQ
79a0: 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29  LITE_SHM_SHARED)
79b0: 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
79c0: 41 4c 25 70 3a 20 61 63 71 75 69 72 65 20 53 48  AL%p: acquire SH
79d0: 41 52 45 44 2d 25 73 20 25 73 5c 6e 22 2c 20 70  ARED-%s %s\n", p
79e0: 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20 20  Wal,.           
79f0: 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63   walLockName(loc
7a00: 6b 49 64 78 29 2c 20 72 63 20 3f 20 22 66 61 69  kIdx), rc ? "fai
7a10: 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20  led" : "ok"));. 
7a20: 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d   VVA_ONLY( pWal-
7a30: 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20 28 75 38  >lockError = (u8
7a40: 29 28 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  )(rc!=SQLITE_OK 
7a50: 26 26 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55  && rc!=SQLITE_BU
7a60: 53 59 29 3b 20 29 0a 20 20 72 65 74 75 72 6e 20  SY); ).  return 
7a70: 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69  rc;.}.static voi
7a80: 64 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65  d walUnlockShare
7a90: 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  d(Wal *pWal, int
7aa0: 20 6c 6f 63 6b 49 64 78 29 7b 0a 20 20 69 66 28   lockIdx){.  if(
7ab0: 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65   pWal->exclusive
7ac0: 4d 6f 64 65 20 29 20 72 65 74 75 72 6e 3b 0a 20  Mode ) return;. 
7ad0: 20 28 76 6f 69 64 29 73 71 6c 69 74 65 33 4f 73   (void)sqlite3Os
7ae0: 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44  ShmLock(pWal->pD
7af0: 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 31 2c  bFd, lockIdx, 1,
7b00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
7b10: 20 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45            SQLITE
7b20: 5f 53 48 4d 5f 55 4e 4c 4f 43 4b 20 7c 20 53 51  _SHM_UNLOCK | SQ
7b30: 4c 49 54 45 5f 53 48 4d 5f 53 48 41 52 45 44 29  LITE_SHM_SHARED)
7b40: 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
7b50: 41 4c 25 70 3a 20 72 65 6c 65 61 73 65 20 53 48  AL%p: release SH
7b60: 41 52 45 44 2d 25 73 5c 6e 22 2c 20 70 57 61 6c  ARED-%s\n", pWal
7b70: 2c 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f  , walLockName(lo
7b80: 63 6b 49 64 78 29 29 29 3b 0a 7d 0a 73 74 61 74  ckIdx)));.}.stat
7b90: 69 63 20 69 6e 74 20 77 61 6c 4c 6f 63 6b 45 78  ic int walLockEx
7ba0: 63 6c 75 73 69 76 65 28 57 61 6c 20 2a 70 57 61  clusive(Wal *pWa
7bb0: 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 2c 20  l, int lockIdx, 
7bc0: 69 6e 74 20 6e 29 7b 0a 20 20 69 6e 74 20 72 63  int n){.  int rc
7bd0: 3b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78  ;.  if( pWal->ex
7be0: 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65  clusiveMode ) re
7bf0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
7c00: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
7c10: 53 68 6d 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44  ShmLock(pWal->pD
7c20: 62 46 64 2c 20 6c 6f 63 6b 49 64 78 2c 20 6e 2c  bFd, lockIdx, n,
7c30: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
7c40: 20 20 20 20 20 20 20 20 20 53 51 4c 49 54 45 5f           SQLITE_
7c50: 53 48 4d 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49 54  SHM_LOCK | SQLIT
7c60: 45 5f 53 48 4d 5f 45 58 43 4c 55 53 49 56 45 29  E_SHM_EXCLUSIVE)
7c70: 3b 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ;.  WALTRACE(("W
7c80: 41 4c 25 70 3a 20 61 63 71 75 69 72 65 20 45 58  AL%p: acquire EX
7c90: 43 4c 55 53 49 56 45 2d 25 73 20 63 6e 74 3d 25  CLUSIVE-%s cnt=%
7ca0: 64 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20  d %s\n", pWal,. 
7cb0: 20 20 20 20 20 20 20 20 20 20 20 77 61 6c 4c 6f             walLo
7cc0: 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c  ckName(lockIdx),
7cd0: 20 6e 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64   n, rc ? "failed
7ce0: 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 56 56  " : "ok"));.  VV
7cf0: 41 5f 4f 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f  A_ONLY( pWal->lo
7d00: 63 6b 45 72 72 6f 72 20 3d 20 28 75 38 29 28 72  ckError = (u8)(r
7d10: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c!=SQLITE_OK && 
7d20: 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 29  rc!=SQLITE_BUSY)
7d30: 3b 20 29 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ; ).  return rc;
7d40: 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  .}.static void w
7d50: 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76  alUnlockExclusiv
7d60: 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74  e(Wal *pWal, int
7d70: 20 6c 6f 63 6b 49 64 78 2c 20 69 6e 74 20 6e 29   lockIdx, int n)
7d80: 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78  {.  if( pWal->ex
7d90: 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65  clusiveMode ) re
7da0: 74 75 72 6e 3b 0a 20 20 28 76 6f 69 64 29 73 71  turn;.  (void)sq
7db0: 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70  lite3OsShmLock(p
7dc0: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b  Wal->pDbFd, lock
7dd0: 49 64 78 2c 20 6e 2c 0a 20 20 20 20 20 20 20 20  Idx, n,.        
7de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7df0: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f   SQLITE_SHM_UNLO
7e00: 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f  CK | SQLITE_SHM_
7e10: 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20 57 41  EXCLUSIVE);.  WA
7e20: 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20  LTRACE(("WAL%p: 
7e30: 72 65 6c 65 61 73 65 20 45 58 43 4c 55 53 49 56  release EXCLUSIV
7e40: 45 2d 25 73 20 63 6e 74 3d 25 64 5c 6e 22 2c 20  E-%s cnt=%d\n", 
7e50: 70 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20  pWal,.          
7e60: 20 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c     walLockName(l
7e70: 6f 63 6b 49 64 78 29 2c 20 6e 29 29 3b 0a 7d 0a  ockIdx), n));.}.
7e80: 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61  ./*.** Compute a
7e90: 20 68 61 73 68 20 6f 6e 20 61 20 70 61 67 65 20   hash on a page 
7ea0: 6e 75 6d 62 65 72 2e 20 20 54 68 65 20 72 65 73  number.  The res
7eb0: 75 6c 74 69 6e 67 20 68 61 73 68 20 76 61 6c 75  ulting hash valu
7ec0: 65 20 6d 75 73 74 20 6c 61 6e 64 0a 2a 2a 20 62  e must land.** b
7ed0: 65 74 77 65 65 6e 20 30 20 61 6e 64 20 28 48 41  etween 0 and (HA
7ee0: 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29  SHTABLE_NSLOT-1)
7ef0: 2e 20 20 54 68 65 20 77 61 6c 48 61 73 68 4e 65  .  The walHashNe
7f00: 78 74 28 29 20 66 75 6e 63 74 69 6f 6e 20 61 64  xt() function ad
7f10: 76 61 6e 63 65 73 0a 2a 2a 20 74 68 65 20 68 61  vances.** the ha
7f20: 73 68 20 74 6f 20 74 68 65 20 6e 65 78 74 20 76  sh to the next v
7f30: 61 6c 75 65 20 69 6e 20 74 68 65 20 65 76 65 6e  alue in the even
7f40: 74 20 6f 66 20 61 20 63 6f 6c 6c 69 73 69 6f 6e  t of a collision
7f50: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
7f60: 77 61 6c 48 61 73 68 28 75 33 32 20 69 50 61 67  walHash(u32 iPag
7f70: 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20 69 50  e){.  assert( iP
7f80: 61 67 65 3e 30 20 29 3b 0a 20 20 61 73 73 65 72  age>0 );.  asser
7f90: 74 28 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 53  t( (HASHTABLE_NS
7fa0: 4c 4f 54 20 26 20 28 48 41 53 48 54 41 42 4c 45  LOT & (HASHTABLE
7fb0: 5f 4e 53 4c 4f 54 2d 31 29 29 3d 3d 30 20 29 3b  _NSLOT-1))==0 );
7fc0: 0a 20 20 72 65 74 75 72 6e 20 28 69 50 61 67 65  .  return (iPage
7fd0: 2a 48 41 53 48 54 41 42 4c 45 5f 48 41 53 48 5f  *HASHTABLE_HASH_
7fe0: 31 29 20 26 20 28 48 41 53 48 54 41 42 4c 45 5f  1) & (HASHTABLE_
7ff0: 4e 53 4c 4f 54 2d 31 29 3b 0a 7d 0a 73 74 61 74  NSLOT-1);.}.stat
8000: 69 63 20 69 6e 74 20 77 61 6c 4e 65 78 74 48 61  ic int walNextHa
8010: 73 68 28 69 6e 74 20 69 50 72 69 6f 72 48 61 73  sh(int iPriorHas
8020: 68 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 69 50  h){.  return (iP
8030: 72 69 6f 72 48 61 73 68 2b 31 29 26 28 48 41 53  riorHash+1)&(HAS
8040: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31 29 3b  HTABLE_NSLOT-1);
8050: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72  .}../* .** Retur
8060: 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68  n pointers to th
8070: 65 20 68 61 73 68 20 74 61 62 6c 65 20 61 6e 64  e hash table and
8080: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72   page number arr
8090: 61 79 20 73 74 6f 72 65 64 20 6f 6e 0a 2a 2a 20  ay stored on.** 
80a0: 70 61 67 65 20 69 48 61 73 68 20 6f 66 20 74 68  page iHash of th
80b0: 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 54 68 65  e wal-index. The
80c0: 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 62 72   wal-index is br
80d0: 6f 6b 65 6e 20 69 6e 74 6f 20 33 32 4b 42 20 70  oken into 32KB p
80e0: 61 67 65 73 0a 2a 2a 20 6e 75 6d 62 65 72 65 64  ages.** numbered
80f0: 20 73 74 61 72 74 69 6e 67 20 66 72 6f 6d 20 30   starting from 0
8100: 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20 6f 75 74 70  ..**.** Set outp
8110: 75 74 20 76 61 72 69 61 62 6c 65 20 2a 70 61 48  ut variable *paH
8120: 61 73 68 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  ash to point to 
8130: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
8140: 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20 69   hash table.** i
8150: 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  n the wal-index 
8160: 66 69 6c 65 2e 20 53 65 74 20 2a 70 69 5a 65 72  file. Set *piZer
8170: 6f 20 74 6f 20 6f 6e 65 20 6c 65 73 73 20 74 68  o to one less th
8180: 61 6e 20 74 68 65 20 66 72 61 6d 65 20 0a 2a 2a  an the frame .**
8190: 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65 20 66   number of the f
81a0: 69 72 73 74 20 66 72 61 6d 65 20 69 6e 64 65 78  irst frame index
81b0: 65 64 20 62 79 20 74 68 69 73 20 68 61 73 68 20  ed by this hash 
81c0: 74 61 62 6c 65 2e 20 49 66 20 61 0a 2a 2a 20 73  table. If a.** s
81d0: 6c 6f 74 20 69 6e 20 74 68 65 20 68 61 73 68 20  lot in the hash 
81e0: 74 61 62 6c 65 20 69 73 20 73 65 74 20 74 6f 20  table is set to 
81f0: 4e 2c 20 69 74 20 72 65 66 65 72 73 20 74 6f 20  N, it refers to 
8200: 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 0a 2a 2a  frame number .**
8210: 20 28 2a 70 69 5a 65 72 6f 2b 4e 29 20 69 6e 20   (*piZero+N) in 
8220: 74 68 65 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a 20 46  the log..**.** F
8230: 69 6e 61 6c 6c 79 2c 20 73 65 74 20 2a 70 61 50  inally, set *paP
8240: 67 6e 6f 20 73 6f 20 74 68 61 74 20 2a 70 61 50  gno so that *paP
8250: 67 6e 6f 5b 31 5d 20 69 73 20 74 68 65 20 70 61  gno[1] is the pa
8260: 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65  ge number of the
8270: 0a 2a 2a 20 66 69 72 73 74 20 66 72 61 6d 65 20  .** first frame 
8280: 69 6e 64 65 78 65 64 20 62 79 20 74 68 65 20 68  indexed by the h
8290: 61 73 68 20 74 61 62 6c 65 2c 20 66 72 61 6d 65  ash table, frame
82a0: 20 28 2a 70 69 5a 65 72 6f 2b 31 29 2e 0a 2a 2f   (*piZero+1)..*/
82b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 48  .static int walH
82c0: 61 73 68 47 65 74 28 0a 20 20 57 61 6c 20 2a 70  ashGet(.  Wal *p
82d0: 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Wal,            
82e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c            /* WAL
82f0: 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74   handle */.  int
8300: 20 69 48 61 73 68 2c 20 20 20 20 20 20 20 20 20   iHash,         
8310: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8320: 46 69 6e 64 20 74 68 65 20 69 48 61 73 68 27 74  Find the iHash't
8330: 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 76 6f 6c  h table */.  vol
8340: 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a 2a  atile ht_slot **
8350: 70 61 48 61 73 68 2c 20 20 20 20 20 20 2f 2a 20  paHash,      /* 
8360: 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74 6f 20  OUT: Pointer to 
8370: 68 61 73 68 20 69 6e 64 65 78 20 2a 2f 0a 20 20  hash index */.  
8380: 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 70  volatile u32 **p
8390: 61 50 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20  aPgno,          
83a0: 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20  /* OUT: Pointer 
83b0: 74 6f 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61  to page number a
83c0: 72 72 61 79 20 2a 2f 0a 20 20 75 33 32 20 2a 70  rray */.  u32 *p
83d0: 69 5a 65 72 6f 20 20 20 20 20 20 20 20 20 20 20  iZero           
83e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
83f0: 3a 20 46 72 61 6d 65 20 61 73 73 6f 63 69 61 74  : Frame associat
8400: 65 64 20 77 69 74 68 20 2a 70 61 50 67 6e 6f 5b  ed with *paPgno[
8410: 30 5d 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  0] */.){.  int r
8420: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
8430: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
8440: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 76  turn code */.  v
8450: 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67  olatile u32 *aPg
8460: 6e 6f 3b 0a 0a 20 20 72 63 20 3d 20 77 61 6c 49  no;..  rc = walI
8470: 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20 69  ndexPage(pWal, i
8480: 48 61 73 68 2c 20 26 61 50 67 6e 6f 29 3b 0a 20  Hash, &aPgno);. 
8490: 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53 51 4c   assert( rc==SQL
84a0: 49 54 45 5f 4f 4b 20 7c 7c 20 69 48 61 73 68 3e  ITE_OK || iHash>
84b0: 30 20 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d  0 );..  if( rc==
84c0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
84d0: 20 75 33 32 20 69 5a 65 72 6f 3b 0a 20 20 20 20   u32 iZero;.    
84e0: 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74  volatile ht_slot
84f0: 20 2a 61 48 61 73 68 3b 0a 0a 20 20 20 20 61 48   *aHash;..    aH
8500: 61 73 68 20 3d 20 28 76 6f 6c 61 74 69 6c 65 20  ash = (volatile 
8510: 68 74 5f 73 6c 6f 74 20 2a 29 26 61 50 67 6e 6f  ht_slot *)&aPgno
8520: 5b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  [HASHTABLE_NPAGE
8530: 5d 3b 0a 20 20 20 20 69 66 28 20 69 48 61 73 68  ];.    if( iHash
8540: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 61 50 67  ==0 ){.      aPg
8550: 6e 6f 20 3d 20 26 61 50 67 6e 6f 5b 57 41 4c 49  no = &aPgno[WALI
8560: 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69  NDEX_HDR_SIZE/si
8570: 7a 65 6f 66 28 75 33 32 29 5d 3b 0a 20 20 20 20  zeof(u32)];.    
8580: 20 20 69 5a 65 72 6f 20 3d 20 30 3b 0a 20 20 20    iZero = 0;.   
8590: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 5a   }else{.      iZ
85a0: 65 72 6f 20 3d 20 48 41 53 48 54 41 42 4c 45 5f  ero = HASHTABLE_
85b0: 4e 50 41 47 45 5f 4f 4e 45 20 2b 20 28 69 48 61  NPAGE_ONE + (iHa
85c0: 73 68 2d 31 29 2a 48 41 53 48 54 41 42 4c 45 5f  sh-1)*HASHTABLE_
85d0: 4e 50 41 47 45 3b 0a 20 20 20 20 7d 0a 20 20 0a  NPAGE;.    }.  .
85e0: 20 20 20 20 2a 70 61 50 67 6e 6f 20 3d 20 26 61      *paPgno = &a
85f0: 50 67 6e 6f 5b 2d 31 5d 3b 0a 20 20 20 20 2a 70  Pgno[-1];.    *p
8600: 61 48 61 73 68 20 3d 20 61 48 61 73 68 3b 0a 20  aHash = aHash;. 
8610: 20 20 20 2a 70 69 5a 65 72 6f 20 3d 20 69 5a 65     *piZero = iZe
8620: 72 6f 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ro;.  }.  return
8630: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65   rc;.}../*.** Re
8640: 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20  turn the number 
8650: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
8660: 20 70 61 67 65 20 74 68 61 74 20 63 6f 6e 74 61   page that conta
8670: 69 6e 73 20 74 68 65 20 68 61 73 68 2d 74 61 62  ins the hash-tab
8680: 6c 65 0a 2a 2a 20 61 6e 64 20 70 61 67 65 2d 6e  le.** and page-n
8690: 75 6d 62 65 72 20 61 72 72 61 79 20 74 68 61 74  umber array that
86a0: 20 63 6f 6e 74 61 69 6e 20 65 6e 74 72 69 65 73   contain entries
86b0: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 74   corresponding t
86c0: 6f 20 57 41 4c 20 66 72 61 6d 65 0a 2a 2a 20 69  o WAL frame.** i
86d0: 46 72 61 6d 65 2e 20 54 68 65 20 77 61 6c 2d 69  Frame. The wal-i
86e0: 6e 64 65 78 20 69 73 20 62 72 6f 6b 65 6e 20 75  ndex is broken u
86f0: 70 20 69 6e 74 6f 20 33 32 4b 42 20 70 61 67 65  p into 32KB page
8700: 73 2e 20 57 61 6c 2d 69 6e 64 65 78 20 70 61 67  s. Wal-index pag
8710: 65 73 20 0a 2a 2a 20 61 72 65 20 6e 75 6d 62 65  es .** are numbe
8720: 72 65 64 20 73 74 61 72 74 69 6e 67 20 66 72 6f  red starting fro
8730: 6d 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  m 0..*/.static i
8740: 6e 74 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28  nt walFramePage(
8750: 75 33 32 20 69 46 72 61 6d 65 29 7b 0a 20 20 69  u32 iFrame){.  i
8760: 6e 74 20 69 48 61 73 68 20 3d 20 28 69 46 72 61  nt iHash = (iFra
8770: 6d 65 2b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  me+HASHTABLE_NPA
8780: 47 45 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  GE-HASHTABLE_NPA
8790: 47 45 5f 4f 4e 45 2d 31 29 20 2f 20 48 41 53 48  GE_ONE-1) / HASH
87a0: 54 41 42 4c 45 5f 4e 50 41 47 45 3b 0a 20 20 61  TABLE_NPAGE;.  a
87b0: 73 73 65 72 74 28 20 28 69 48 61 73 68 3d 3d 30  ssert( (iHash==0
87c0: 20 7c 7c 20 69 46 72 61 6d 65 3e 48 41 53 48 54   || iFrame>HASHT
87d0: 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29 0a  ABLE_NPAGE_ONE).
87e0: 20 20 20 20 20 20 20 26 26 20 28 69 48 61 73 68         && (iHash
87f0: 3e 3d 31 20 7c 7c 20 69 46 72 61 6d 65 3c 3d 48  >=1 || iFrame<=H
8800: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f  ASHTABLE_NPAGE_O
8810: 4e 45 29 0a 20 20 20 20 20 20 20 26 26 20 28 69  NE).       && (i
8820: 48 61 73 68 3c 3d 31 20 7c 7c 20 69 46 72 61 6d  Hash<=1 || iFram
8830: 65 3e 28 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  e>(HASHTABLE_NPA
8840: 47 45 5f 4f 4e 45 2b 48 41 53 48 54 41 42 4c 45  GE_ONE+HASHTABLE
8850: 5f 4e 50 41 47 45 29 29 0a 20 20 20 20 20 20 20  _NPAGE)).       
8860: 26 26 20 28 69 48 61 73 68 3e 3d 32 20 7c 7c 20  && (iHash>=2 || 
8870: 69 46 72 61 6d 65 3c 3d 48 41 53 48 54 41 42 4c  iFrame<=HASHTABL
8880: 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 48 41 53 48  E_NPAGE_ONE+HASH
8890: 54 41 42 4c 45 5f 4e 50 41 47 45 29 0a 20 20 20  TABLE_NPAGE).   
88a0: 20 20 20 20 26 26 20 28 69 48 61 73 68 3c 3d 32      && (iHash<=2
88b0: 20 7c 7c 20 69 46 72 61 6d 65 3e 28 48 41 53 48   || iFrame>(HASH
88c0: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b  TABLE_NPAGE_ONE+
88d0: 32 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  2*HASHTABLE_NPAG
88e0: 45 29 29 0a 20 20 29 3b 0a 20 20 72 65 74 75 72  E)).  );.  retur
88f0: 6e 20 69 48 61 73 68 3b 0a 7d 0a 0a 2f 2a 0a 2a  n iHash;.}../*.*
8900: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 70 61 67  * Return the pag
8910: 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63 69 61  e number associa
8920: 74 65 64 20 77 69 74 68 20 66 72 61 6d 65 20 69  ted with frame i
8930: 46 72 61 6d 65 20 69 6e 20 74 68 69 73 20 57 41  Frame in this WA
8940: 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75 33 32  L..*/.static u32
8950: 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 57 61   walFramePgno(Wa
8960: 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 69 46 72  l *pWal, u32 iFr
8970: 61 6d 65 29 7b 0a 20 20 69 6e 74 20 69 48 61 73  ame){.  int iHas
8980: 68 20 3d 20 77 61 6c 46 72 61 6d 65 50 61 67 65  h = walFramePage
8990: 28 69 46 72 61 6d 65 29 3b 0a 20 20 69 66 28 20  (iFrame);.  if( 
89a0: 69 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20  iHash==0 ){.    
89b0: 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e 61 70 57  return pWal->apW
89c0: 69 44 61 74 61 5b 30 5d 5b 57 41 4c 49 4e 44 45  iData[0][WALINDE
89d0: 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f  X_HDR_SIZE/sizeo
89e0: 66 28 75 33 32 29 20 2b 20 69 46 72 61 6d 65 20  f(u32) + iFrame 
89f0: 2d 20 31 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75  - 1];.  }.  retu
8a00: 72 6e 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74  rn pWal->apWiDat
8a10: 61 5b 69 48 61 73 68 5d 5b 28 69 46 72 61 6d 65  a[iHash][(iFrame
8a20: 2d 31 2d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  -1-HASHTABLE_NPA
8a30: 47 45 5f 4f 4e 45 29 25 48 41 53 48 54 41 42 4c  GE_ONE)%HASHTABL
8a40: 45 5f 4e 50 41 47 45 5d 3b 0a 7d 0a 0a 2f 2a 0a  E_NPAGE];.}../*.
8a50: 2a 2a 20 52 65 6d 6f 76 65 20 65 6e 74 72 69 65  ** Remove entrie
8a60: 73 20 66 72 6f 6d 20 74 68 65 20 68 61 73 68 20  s from the hash 
8a70: 74 61 62 6c 65 20 74 68 61 74 20 70 6f 69 6e 74  table that point
8a80: 20 74 6f 20 57 41 4c 20 73 6c 6f 74 73 20 67 72   to WAL slots gr
8a90: 65 61 74 65 72 0a 2a 2a 20 74 68 61 6e 20 70 57  eater.** than pW
8aa0: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e  al->hdr.mxFrame.
8ab0: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  .**.** This func
8ac0: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 77  tion is called w
8ad0: 68 65 6e 65 76 65 72 20 70 57 61 6c 2d 3e 68 64  henever pWal->hd
8ae0: 72 2e 6d 78 46 72 61 6d 65 20 69 73 20 64 65 63  r.mxFrame is dec
8af0: 72 65 61 73 65 64 20 64 75 65 0a 2a 2a 20 74 6f  reased due.** to
8b00: 20 61 20 72 6f 6c 6c 62 61 63 6b 20 6f 72 20 73   a rollback or s
8b10: 61 76 65 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20  avepoint..**.** 
8b20: 41 74 20 6d 6f 73 74 20 6f 6e 6c 79 20 74 68 65  At most only the
8b30: 20 68 61 73 68 20 74 61 62 6c 65 20 63 6f 6e 74   hash table cont
8b40: 61 69 6e 69 6e 67 20 70 57 61 6c 2d 3e 68 64 72  aining pWal->hdr
8b50: 2e 6d 78 46 72 61 6d 65 20 6e 65 65 64 73 20 74  .mxFrame needs t
8b60: 6f 20 62 65 0a 2a 2a 20 75 70 64 61 74 65 64 2e  o be.** updated.
8b70: 20 20 41 6e 79 20 6c 61 74 65 72 20 68 61 73 68    Any later hash
8b80: 20 74 61 62 6c 65 73 20 77 69 6c 6c 20 62 65 20   tables will be 
8b90: 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 63 6c  automatically cl
8ba0: 65 61 72 65 64 20 77 68 65 6e 0a 2a 2a 20 70 57  eared when.** pW
8bb0: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
8bc0: 61 64 76 61 6e 63 65 73 20 74 6f 20 74 68 65 20  advances to the 
8bd0: 70 6f 69 6e 74 20 77 68 65 72 65 20 74 68 6f 73  point where thos
8be0: 65 20 68 61 73 68 20 74 61 62 6c 65 73 20 61 72  e hash tables ar
8bf0: 65 0a 2a 2a 20 61 63 74 75 61 6c 6c 79 20 6e 65  e.** actually ne
8c00: 65 64 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  eded..*/.static 
8c10: 76 6f 69 64 20 77 61 6c 43 6c 65 61 6e 75 70 48  void walCleanupH
8c20: 61 73 68 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a  ash(Wal *pWal){.
8c30: 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c    volatile ht_sl
8c40: 6f 74 20 2a 61 48 61 73 68 20 3d 20 30 3b 20 20  ot *aHash = 0;  
8c50: 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20    /* Pointer to 
8c60: 68 61 73 68 20 74 61 62 6c 65 20 74 6f 20 63 6c  hash table to cl
8c70: 65 61 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c  ear */.  volatil
8c80: 65 20 75 33 32 20 2a 61 50 67 6e 6f 20 3d 20 30  e u32 *aPgno = 0
8c90: 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67 65  ;        /* Page
8ca0: 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 66 6f   number array fo
8cb0: 72 20 68 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a  r hash table */.
8cc0: 20 20 75 33 32 20 69 5a 65 72 6f 20 3d 20 30 3b    u32 iZero = 0;
8cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ce0: 20 20 2f 2a 20 66 72 61 6d 65 20 3d 3d 20 28 61    /* frame == (a
8cf0: 48 61 73 68 5b 78 5d 2b 69 5a 65 72 6f 29 20 2a  Hash[x]+iZero) *
8d00: 2f 0a 20 20 69 6e 74 20 69 4c 69 6d 69 74 20 3d  /.  int iLimit =
8d10: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
8d20: 20 20 20 20 2f 2a 20 5a 65 72 6f 20 76 61 6c 75      /* Zero valu
8d30: 65 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 20  es greater than 
8d40: 74 68 69 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  this */.  int nB
8d50: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
8d60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
8d70: 62 65 72 20 6f 66 20 62 79 74 65 73 20 74 6f 20  ber of bytes to 
8d80: 7a 65 72 6f 20 69 6e 20 61 50 67 6e 6f 5b 5d 20  zero in aPgno[] 
8d90: 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20  */.  int i;     
8da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8db0: 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f 20       /* Used to 
8dc0: 69 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20  iterate through 
8dd0: 61 48 61 73 68 5b 5d 20 2a 2f 0a 0a 20 20 61 73  aHash[] */..  as
8de0: 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74  sert( pWal->writ
8df0: 65 4c 6f 63 6b 20 29 3b 0a 20 20 74 65 73 74 63  eLock );.  testc
8e00: 61 73 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  ase( pWal->hdr.m
8e10: 78 46 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c  xFrame==HASHTABL
8e20: 45 5f 4e 50 41 47 45 5f 4f 4e 45 2d 31 20 29 3b  E_NPAGE_ONE-1 );
8e30: 0a 20 20 74 65 73 74 63 61 73 65 28 20 70 57 61  .  testcase( pWa
8e40: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d  l->hdr.mxFrame==
8e50: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
8e60: 4f 4e 45 20 29 3b 0a 20 20 74 65 73 74 63 61 73  ONE );.  testcas
8e70: 65 28 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  e( pWal->hdr.mxF
8e80: 72 61 6d 65 3d 3d 48 41 53 48 54 41 42 4c 45 5f  rame==HASHTABLE_
8e90: 4e 50 41 47 45 5f 4f 4e 45 2b 31 20 29 3b 0a 0a  NPAGE_ONE+1 );..
8ea0: 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e    if( pWal->hdr.
8eb0: 6d 78 46 72 61 6d 65 3d 3d 30 20 29 20 72 65 74  mxFrame==0 ) ret
8ec0: 75 72 6e 3b 0a 0a 20 20 2f 2a 20 4f 62 74 61 69  urn;..  /* Obtai
8ed0: 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f 20 74 68  n pointers to th
8ee0: 65 20 68 61 73 68 2d 74 61 62 6c 65 20 61 6e 64  e hash-table and
8ef0: 20 70 61 67 65 2d 6e 75 6d 62 65 72 20 61 72 72   page-number arr
8f00: 61 79 20 63 6f 6e 74 61 69 6e 69 6e 67 20 0a 20  ay containing . 
8f10: 20 2a 2a 20 74 68 65 20 65 6e 74 72 79 20 74 68   ** the entry th
8f20: 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 73 20 74  at corresponds t
8f30: 6f 20 66 72 61 6d 65 20 70 57 61 6c 2d 3e 68 64  o frame pWal->hd
8f40: 72 2e 6d 78 46 72 61 6d 65 2e 20 49 74 20 69 73  r.mxFrame. It is
8f50: 20 67 75 61 72 61 6e 74 65 65 64 0a 20 20 2a 2a   guaranteed.  **
8f60: 20 74 68 61 74 20 74 68 65 20 70 61 67 65 20 73   that the page s
8f70: 61 69 64 20 68 61 73 68 2d 74 61 62 6c 65 20 61  aid hash-table a
8f80: 6e 64 20 61 72 72 61 79 20 72 65 73 69 64 65 20  nd array reside 
8f90: 6f 6e 20 69 73 20 61 6c 72 65 61 64 79 20 6d 61  on is already ma
8fa0: 70 70 65 64 2e 0a 20 20 2a 2f 0a 20 20 61 73 73  pped..  */.  ass
8fb0: 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57 69 44 61  ert( pWal->nWiDa
8fc0: 74 61 3e 77 61 6c 46 72 61 6d 65 50 61 67 65 28  ta>walFramePage(
8fd0: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
8fe0: 65 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  e) );.  assert( 
8ff0: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 77  pWal->apWiData[w
9000: 61 6c 46 72 61 6d 65 50 61 67 65 28 70 57 61 6c  alFramePage(pWal
9010: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 29 5d 20  ->hdr.mxFrame)] 
9020: 29 3b 0a 20 20 77 61 6c 48 61 73 68 47 65 74 28  );.  walHashGet(
9030: 70 57 61 6c 2c 20 77 61 6c 46 72 61 6d 65 50 61  pWal, walFramePa
9040: 67 65 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  ge(pWal->hdr.mxF
9050: 72 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20 26  rame), &aHash, &
9060: 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a  aPgno, &iZero);.
9070: 0a 20 20 2f 2a 20 5a 65 72 6f 20 61 6c 6c 20 68  .  /* Zero all h
9080: 61 73 68 2d 74 61 62 6c 65 20 65 6e 74 72 69 65  ash-table entrie
9090: 73 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  s that correspon
90a0: 64 20 74 6f 20 66 72 61 6d 65 20 6e 75 6d 62 65  d to frame numbe
90b0: 72 73 20 67 72 65 61 74 65 72 0a 20 20 2a 2a 20  rs greater.  ** 
90c0: 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  than pWal->hdr.m
90d0: 78 46 72 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69  xFrame..  */.  i
90e0: 4c 69 6d 69 74 20 3d 20 70 57 61 6c 2d 3e 68 64  Limit = pWal->hd
90f0: 72 2e 6d 78 46 72 61 6d 65 20 2d 20 69 5a 65 72  r.mxFrame - iZer
9100: 6f 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4c 69  o;.  assert( iLi
9110: 6d 69 74 3e 30 20 29 3b 0a 20 20 66 6f 72 28 69  mit>0 );.  for(i
9120: 3d 30 3b 20 69 3c 48 41 53 48 54 41 42 4c 45 5f  =0; i<HASHTABLE_
9130: 4e 53 4c 4f 54 3b 20 69 2b 2b 29 7b 0a 20 20 20  NSLOT; i++){.   
9140: 20 69 66 28 20 61 48 61 73 68 5b 69 5d 3e 69 4c   if( aHash[i]>iL
9150: 69 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 61 48  imit ){.      aH
9160: 61 73 68 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20  ash[i] = 0;.    
9170: 7d 0a 20 20 7d 0a 20 20 0a 20 20 2f 2a 20 5a 65  }.  }.  .  /* Ze
9180: 72 6f 20 74 68 65 20 65 6e 74 72 69 65 73 20 69  ro the entries i
9190: 6e 20 74 68 65 20 61 50 67 6e 6f 20 61 72 72 61  n the aPgno arra
91a0: 79 20 74 68 61 74 20 63 6f 72 72 65 73 70 6f 6e  y that correspon
91b0: 64 20 74 6f 20 66 72 61 6d 65 73 20 77 69 74 68  d to frames with
91c0: 0a 20 20 2a 2a 20 66 72 61 6d 65 20 6e 75 6d 62  .  ** frame numb
91d0: 65 72 73 20 67 72 65 61 74 65 72 20 74 68 61 6e  ers greater than
91e0: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
91f0: 6d 65 2e 20 0a 20 20 2a 2f 0a 20 20 6e 42 79 74  me. .  */.  nByt
9200: 65 20 3d 20 28 69 6e 74 29 28 28 63 68 61 72 20  e = (int)((char 
9210: 2a 29 61 48 61 73 68 20 2d 20 28 63 68 61 72 20  *)aHash - (char 
9220: 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d 69 74 2b  *)&aPgno[iLimit+
9230: 31 5d 29 3b 0a 20 20 6d 65 6d 73 65 74 28 28 76  1]);.  memset((v
9240: 6f 69 64 20 2a 29 26 61 50 67 6e 6f 5b 69 4c 69  oid *)&aPgno[iLi
9250: 6d 69 74 2b 31 5d 2c 20 30 2c 20 6e 42 79 74 65  mit+1], 0, nByte
9260: 29 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49 54  );..#ifdef SQLIT
9270: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
9280: 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20 56  VE_ASSERT.  /* V
9290: 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20 65  erify that the e
92a0: 76 65 72 79 20 65 6e 74 72 79 20 69 6e 20 74 68  very entry in th
92b0: 65 20 6d 61 70 70 69 6e 67 20 72 65 67 69 6f 6e  e mapping region
92c0: 20 69 73 20 73 74 69 6c 6c 20 72 65 61 63 68 61   is still reacha
92d0: 62 6c 65 0a 20 20 2a 2a 20 76 69 61 20 74 68 65  ble.  ** via the
92e0: 20 68 61 73 68 20 74 61 62 6c 65 20 65 76 65 6e   hash table even
92f0: 20 61 66 74 65 72 20 74 68 65 20 63 6c 65 61 6e   after the clean
9300: 75 70 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69  up..  */.  if( i
9310: 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20 69 6e 74  Limit ){.    int
9320: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a   i;           /*
9330: 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f   Loop counter */
9340: 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20  .    int iKey;  
9350: 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 6b 65        /* Hash ke
9360: 79 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d 31  y */.    for(i=1
9370: 3b 20 69 3c 3d 69 4c 69 6d 69 74 3b 20 69 2b 2b  ; i<=iLimit; i++
9380: 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 4b 65  ){.      for(iKe
9390: 79 3d 77 61 6c 48 61 73 68 28 61 50 67 6e 6f 5b  y=walHash(aPgno[
93a0: 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  i]); aHash[iKey]
93b0: 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
93c0: 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
93d0: 20 20 20 69 66 28 20 61 48 61 73 68 5b 69 4b 65     if( aHash[iKe
93e0: 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b 3b 0a 20  y]==i ) break;. 
93f0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73 73       }.      ass
9400: 65 72 74 28 20 61 48 61 73 68 5b 69 4b 65 79 5d  ert( aHash[iKey]
9410: 3d 3d 69 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  ==i );.    }.  }
9420: 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54  .#endif /* SQLIT
9430: 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53 49  E_ENABLE_EXPENSI
9440: 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a 7d 0a 0a  VE_ASSERT */.}..
9450: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 6e 20 65 6e  ./*.** Set an en
9460: 74 72 79 20 69 6e 20 74 68 65 20 77 61 6c 2d 69  try in the wal-i
9470: 6e 64 65 78 20 74 68 61 74 20 77 69 6c 6c 20 6d  ndex that will m
9480: 61 70 20 64 61 74 61 62 61 73 65 20 70 61 67 65  ap database page
9490: 20 6e 75 6d 62 65 72 0a 2a 2a 20 70 50 61 67 65   number.** pPage
94a0: 20 69 6e 74 6f 20 57 41 4c 20 66 72 61 6d 65 20   into WAL frame 
94b0: 69 46 72 61 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69  iFrame..*/.stati
94c0: 63 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 41 70  c int walIndexAp
94d0: 70 65 6e 64 28 57 61 6c 20 2a 70 57 61 6c 2c 20  pend(Wal *pWal, 
94e0: 75 33 32 20 69 46 72 61 6d 65 2c 20 75 33 32 20  u32 iFrame, u32 
94f0: 69 50 61 67 65 29 7b 0a 20 20 69 6e 74 20 72 63  iPage){.  int rc
9500: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
9510: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
9520: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 75 33  urn code */.  u3
9530: 32 20 69 5a 65 72 6f 20 3d 20 30 3b 20 20 20 20  2 iZero = 0;    
9540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9550: 20 4f 6e 65 20 6c 65 73 73 20 74 68 61 6e 20 66   One less than f
9560: 72 61 6d 65 20 6e 75 6d 62 65 72 20 6f 66 20 61  rame number of a
9570: 50 67 6e 6f 5b 31 5d 20 2a 2f 0a 20 20 76 6f 6c  Pgno[1] */.  vol
9580: 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f  atile u32 *aPgno
9590: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 2f 2a 20   = 0;        /* 
95a0: 50 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61  Page number arra
95b0: 79 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20  y */.  volatile 
95c0: 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 20 3d  ht_slot *aHash =
95d0: 20 30 3b 20 20 20 20 2f 2a 20 48 61 73 68 20 74   0;    /* Hash t
95e0: 61 62 6c 65 20 2a 2f 0a 0a 20 20 72 63 20 3d 20  able */..  rc = 
95f0: 77 61 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c  walHashGet(pWal,
9600: 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69 46   walFramePage(iF
9610: 72 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20 26  rame), &aHash, &
9620: 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a  aPgno, &iZero);.
9630: 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20 74  .  /* Assuming t
9640: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  he wal-index fil
9650: 65 20 77 61 73 20 73 75 63 63 65 73 73 66 75 6c  e was successful
9660: 6c 79 20 6d 61 70 70 65 64 2c 20 70 6f 70 75 6c  ly mapped, popul
9670: 61 74 65 20 74 68 65 0a 20 20 2a 2a 20 70 61 67  ate the.  ** pag
9680: 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20 61  e number array a
9690: 6e 64 20 68 61 73 68 20 74 61 62 6c 65 20 65 6e  nd hash table en
96a0: 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  try..  */.  if( 
96b0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
96c0: 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20 20  .    int iKey;  
96d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
96e0: 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65     /* Hash table
96f0: 20 6b 65 79 20 2a 2f 0a 20 20 20 20 69 6e 74 20   key */.    int 
9700: 69 64 78 3b 20 20 20 20 20 20 20 20 20 20 20 20  idx;            
9710: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
9720: 75 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 68  ue to write to h
9730: 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 20 2a  ash-table slot *
9740: 2f 0a 20 20 20 20 54 45 53 54 4f 4e 4c 59 28 20  /.    TESTONLY( 
9750: 69 6e 74 20 6e 43 6f 6c 6c 69 64 65 20 3d 20 30  int nCollide = 0
9760: 3b 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66  ;   /* Number of
9770: 20 68 61 73 68 20 63 6f 6c 6c 69 73 69 6f 6e 73   hash collisions
9780: 20 2a 2f 20 29 0a 0a 20 20 20 20 69 64 78 20 3d   */ )..    idx =
9790: 20 69 46 72 61 6d 65 20 2d 20 69 5a 65 72 6f 3b   iFrame - iZero;
97a0: 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 64 78  .    assert( idx
97b0: 20 3c 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e 53   <= HASHTABLE_NS
97c0: 4c 4f 54 2f 32 20 2b 20 31 20 29 3b 0a 20 20 20  LOT/2 + 1 );.   
97d0: 20 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 69 73   .    /* If this
97e0: 20 69 73 20 74 68 65 20 66 69 72 73 74 20 65 6e   is the first en
97f0: 74 72 79 20 74 6f 20 62 65 20 61 64 64 65 64 20  try to be added 
9800: 74 6f 20 74 68 69 73 20 68 61 73 68 2d 74 61 62  to this hash-tab
9810: 6c 65 2c 20 7a 65 72 6f 20 74 68 65 0a 20 20 20  le, zero the.   
9820: 20 2a 2a 20 65 6e 74 69 72 65 20 68 61 73 68 20   ** entire hash 
9830: 74 61 62 6c 65 20 61 6e 64 20 61 50 67 6e 6f 5b  table and aPgno[
9840: 5d 20 61 72 72 61 79 20 62 65 66 6f 72 65 20 70  ] array before p
9850: 72 6f 63 65 64 69 6e 67 2e 20 0a 20 20 20 20 2a  roceding. .    *
9860: 2f 0a 20 20 20 20 69 66 28 20 69 64 78 3d 3d 31  /.    if( idx==1
9870: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 42   ){.      int nB
9880: 79 74 65 20 3d 20 28 69 6e 74 29 28 28 75 38 20  yte = (int)((u8 
9890: 2a 29 26 61 48 61 73 68 5b 48 41 53 48 54 41 42  *)&aHash[HASHTAB
98a0: 4c 45 5f 4e 53 4c 4f 54 5d 20 2d 20 28 75 38 20  LE_NSLOT] - (u8 
98b0: 2a 29 26 61 50 67 6e 6f 5b 31 5d 29 3b 0a 20 20  *)&aPgno[1]);.  
98c0: 20 20 20 20 6d 65 6d 73 65 74 28 28 76 6f 69 64      memset((void
98d0: 2a 29 26 61 50 67 6e 6f 5b 31 5d 2c 20 30 2c 20  *)&aPgno[1], 0, 
98e0: 6e 42 79 74 65 29 3b 0a 20 20 20 20 7d 0a 0a 20  nByte);.    }.. 
98f0: 20 20 20 2f 2a 20 49 66 20 74 68 65 20 65 6e 74     /* If the ent
9900: 72 79 20 69 6e 20 61 50 67 6e 6f 5b 5d 20 69 73  ry in aPgno[] is
9910: 20 61 6c 72 65 61 64 79 20 73 65 74 2c 20 74 68   already set, th
9920: 65 6e 20 74 68 65 20 70 72 65 76 69 6f 75 73 20  en the previous 
9930: 77 72 69 74 65 72 0a 20 20 20 20 2a 2a 20 6d 75  writer.    ** mu
9940: 73 74 20 68 61 76 65 20 65 78 69 74 65 64 20 75  st have exited u
9950: 6e 65 78 70 65 63 74 65 64 6c 79 20 69 6e 20 74  nexpectedly in t
9960: 68 65 20 6d 69 64 64 6c 65 20 6f 66 20 61 20 74  he middle of a t
9970: 72 61 6e 73 61 63 74 69 6f 6e 20 28 61 66 74 65  ransaction (afte
9980: 72 0a 20 20 20 20 2a 2a 20 77 72 69 74 69 6e 67  r.    ** writing
9990: 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 64 69 72   one or more dir
99a0: 74 79 20 70 61 67 65 73 20 74 6f 20 74 68 65 20  ty pages to the 
99b0: 57 41 4c 20 74 6f 20 66 72 65 65 20 75 70 20 6d  WAL to free up m
99c0: 65 6d 6f 72 79 29 2e 20 0a 20 20 20 20 2a 2a 20  emory). .    ** 
99d0: 52 65 6d 6f 76 65 20 74 68 65 20 72 65 6d 6e 61  Remove the remna
99e0: 6e 74 73 20 6f 66 20 74 68 61 74 20 77 72 69 74  nts of that writ
99f0: 65 72 73 20 75 6e 63 6f 6d 6d 69 74 74 65 64 20  ers uncommitted 
9a00: 74 72 61 6e 73 61 63 74 69 6f 6e 20 66 72 6f 6d  transaction from
9a10: 20 0a 20 20 20 20 2a 2a 20 74 68 65 20 68 61 73   .    ** the has
9a20: 68 2d 74 61 62 6c 65 20 62 65 66 6f 72 65 20 77  h-table before w
9a30: 72 69 74 69 6e 67 20 61 6e 79 20 6e 65 77 20 65  riting any new e
9a40: 6e 74 72 69 65 73 2e 0a 20 20 20 20 2a 2f 0a 20  ntries..    */. 
9a50: 20 20 20 69 66 28 20 61 50 67 6e 6f 5b 69 64 78     if( aPgno[idx
9a60: 5d 20 29 7b 0a 20 20 20 20 20 20 77 61 6c 43 6c  ] ){.      walCl
9a70: 65 61 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b  eanupHash(pWal);
9a80: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 21  .      assert( !
9a90: 61 50 67 6e 6f 5b 69 64 78 5d 20 29 3b 0a 20 20  aPgno[idx] );.  
9aa0: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74    }..    /* Writ
9ab0: 65 20 74 68 65 20 61 50 67 6e 6f 5b 5d 20 61 72  e the aPgno[] ar
9ac0: 72 61 79 20 65 6e 74 72 79 20 61 6e 64 20 74 68  ray entry and th
9ad0: 65 20 68 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f  e hash-table slo
9ae0: 74 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 4b  t. */.    for(iK
9af0: 65 79 3d 77 61 6c 48 61 73 68 28 69 50 61 67 65  ey=walHash(iPage
9b00: 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20  ); aHash[iKey]; 
9b10: 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68  iKey=walNextHash
9b20: 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 61  (iKey)){.      a
9b30: 73 73 65 72 74 28 20 6e 43 6f 6c 6c 69 64 65 2b  ssert( nCollide+
9b40: 2b 20 3c 20 69 64 78 20 29 3b 0a 20 20 20 20 7d  + < idx );.    }
9b50: 0a 20 20 20 20 61 50 67 6e 6f 5b 69 64 78 5d 20  .    aPgno[idx] 
9b60: 3d 20 69 50 61 67 65 3b 0a 20 20 20 20 61 48 61  = iPage;.    aHa
9b70: 73 68 5b 69 4b 65 79 5d 20 3d 20 28 68 74 5f 73  sh[iKey] = (ht_s
9b80: 6c 6f 74 29 69 64 78 3b 0a 0a 23 69 66 64 65 66  lot)idx;..#ifdef
9b90: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45   SQLITE_ENABLE_E
9ba0: 58 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54 0a  XPENSIVE_ASSERT.
9bb0: 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20 74 68      /* Verify th
9bc0: 61 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  at the number of
9bd0: 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20   entries in the 
9be0: 68 61 73 68 20 74 61 62 6c 65 20 65 78 61 63 74  hash table exact
9bf0: 6c 79 20 65 71 75 61 6c 73 0a 20 20 20 20 2a 2a  ly equals.    **
9c00: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 65   the number of e
9c10: 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20 6d 61  ntries in the ma
9c20: 70 70 69 6e 67 20 72 65 67 69 6f 6e 2e 0a 20 20  pping region..  
9c30: 20 20 2a 2f 0a 20 20 20 20 7b 0a 20 20 20 20 20    */.    {.     
9c40: 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
9c50: 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65    /* Loop counte
9c60: 72 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e  r */.      int n
9c70: 45 6e 74 72 79 20 3d 20 30 3b 20 20 2f 2a 20 4e  Entry = 0;  /* N
9c80: 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73  umber of entries
9c90: 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61 62   in the hash tab
9ca0: 6c 65 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72 28  le */.      for(
9cb0: 69 3d 30 3b 20 69 3c 48 41 53 48 54 41 42 4c 45  i=0; i<HASHTABLE
9cc0: 5f 4e 53 4c 4f 54 3b 20 69 2b 2b 29 7b 20 69 66  _NSLOT; i++){ if
9cd0: 28 20 61 48 61 73 68 5b 69 5d 20 29 20 6e 45 6e  ( aHash[i] ) nEn
9ce0: 74 72 79 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 61  try++; }.      a
9cf0: 73 73 65 72 74 28 20 6e 45 6e 74 72 79 3d 3d 69  ssert( nEntry==i
9d00: 64 78 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  dx );.    }..   
9d10: 20 2f 2a 20 56 65 72 69 66 79 20 74 68 61 74 20   /* Verify that 
9d20: 74 68 65 20 65 76 65 72 79 20 65 6e 74 72 79 20  the every entry 
9d30: 69 6e 20 74 68 65 20 6d 61 70 70 69 6e 67 20 72  in the mapping r
9d40: 65 67 69 6f 6e 20 69 73 20 72 65 61 63 68 61 62  egion is reachab
9d50: 6c 65 0a 20 20 20 20 2a 2a 20 76 69 61 20 74 68  le.    ** via th
9d60: 65 20 68 61 73 68 20 74 61 62 6c 65 2e 20 20 54  e hash table.  T
9d70: 68 69 73 20 74 75 72 6e 73 20 6f 75 74 20 74 6f  his turns out to
9d80: 20 62 65 20 61 20 72 65 61 6c 6c 79 2c 20 72 65   be a really, re
9d90: 61 6c 6c 79 20 65 78 70 65 6e 73 69 76 65 0a 20  ally expensive. 
9da0: 20 20 20 2a 2a 20 74 68 69 6e 67 20 74 6f 20 63     ** thing to c
9db0: 68 65 63 6b 2c 20 73 6f 20 6f 6e 6c 79 20 64 6f  heck, so only do
9dc0: 20 74 68 69 73 20 6f 63 63 61 73 69 6f 6e 61 6c   this occasional
9dd0: 6c 79 20 2d 20 6e 6f 74 20 6f 6e 20 65 76 65 72  ly - not on ever
9de0: 79 0a 20 20 20 20 2a 2a 20 69 74 65 72 61 74 69  y.    ** iterati
9df0: 6f 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  on..    */.    i
9e00: 66 28 20 28 69 64 78 26 30 78 33 66 66 29 3d 3d  f( (idx&0x3ff)==
9e10: 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 69  0 ){.      int i
9e20: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c  ;           /* L
9e30: 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20  oop counter */. 
9e40: 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c       for(i=1; i<
9e50: 3d 69 64 78 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  =idx; i++){.    
9e60: 20 20 20 20 66 6f 72 28 69 4b 65 79 3d 77 61 6c      for(iKey=wal
9e70: 48 61 73 68 28 61 50 67 6e 6f 5b 69 5d 29 3b 20  Hash(aPgno[i]); 
9e80: 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20 69 4b 65  aHash[iKey]; iKe
9e90: 79 3d 77 61 6c 4e 65 78 74 48 61 73 68 28 69 4b  y=walNextHash(iK
9ea0: 65 79 29 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ey)){.          
9eb0: 69 66 28 20 61 48 61 73 68 5b 69 4b 65 79 5d 3d  if( aHash[iKey]=
9ec0: 3d 69 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  =i ) break;.    
9ed0: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 61 73      }.        as
9ee0: 73 65 72 74 28 20 61 48 61 73 68 5b 69 4b 65 79  sert( aHash[iKey
9ef0: 5d 3d 3d 69 20 29 3b 0a 20 20 20 20 20 20 7d 0a  ]==i );.      }.
9f00: 20 20 20 20 7d 0a 23 65 6e 64 69 66 20 2f 2a 20      }.#endif /* 
9f10: 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45 58  SQLITE_ENABLE_EX
9f20: 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54 20 2a  PENSIVE_ASSERT *
9f30: 2f 0a 20 20 7d 0a 0a 0a 20 20 72 65 74 75 72 6e  /.  }...  return
9f40: 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52   rc;.}.../*.** R
9f50: 65 63 6f 76 65 72 20 74 68 65 20 77 61 6c 2d 69  ecover the wal-i
9f60: 6e 64 65 78 20 62 79 20 72 65 61 64 69 6e 67 20  ndex by reading 
9f70: 74 68 65 20 77 72 69 74 65 2d 61 68 65 61 64 20  the write-ahead 
9f80: 6c 6f 67 20 66 69 6c 65 2e 20 0a 2a 2a 0a 2a 2a  log file. .**.**
9f90: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 66 69   This routine fi
9fa0: 72 73 74 20 74 72 69 65 73 20 74 6f 20 65 73 74  rst tries to est
9fb0: 61 62 6c 69 73 68 20 61 6e 20 65 78 63 6c 75 73  ablish an exclus
9fc0: 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 74 68 65 0a  ive lock on the.
9fd0: 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 74 6f 20  ** wal-index to 
9fe0: 70 72 65 76 65 6e 74 20 6f 74 68 65 72 20 74 68  prevent other th
9ff0: 72 65 61 64 73 2f 70 72 6f 63 65 73 73 65 73 20  reads/processes 
a000: 66 72 6f 6d 20 64 6f 69 6e 67 20 61 6e 79 74 68  from doing anyth
a010: 69 6e 67 0a 2a 2a 20 77 69 74 68 20 74 68 65 20  ing.** with the 
a020: 57 41 4c 20 6f 72 20 77 61 6c 2d 69 6e 64 65 78  WAL or wal-index
a030: 20 77 68 69 6c 65 20 72 65 63 6f 76 65 72 79 20   while recovery 
a040: 69 73 20 72 75 6e 6e 69 6e 67 2e 20 20 54 68 65  is running.  The
a050: 0a 2a 2a 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f  .** WAL_RECOVER_
a060: 4c 4f 43 4b 20 69 73 20 61 6c 73 6f 20 68 65 6c  LOCK is also hel
a070: 64 20 73 6f 20 74 68 61 74 20 6f 74 68 65 72 20  d so that other 
a080: 74 68 72 65 61 64 73 20 77 69 6c 6c 20 6b 6e 6f  threads will kno
a090: 77 0a 2a 2a 20 74 68 61 74 20 74 68 69 73 20 74  w.** that this t
a0a0: 68 72 65 61 64 20 69 73 20 72 75 6e 6e 69 6e 67  hread is running
a0b0: 20 72 65 63 6f 76 65 72 79 2e 20 20 49 66 20 75   recovery.  If u
a0c0: 6e 61 62 6c 65 20 74 6f 20 65 73 74 61 62 6c 69  nable to establi
a0d0: 73 68 0a 2a 2a 20 74 68 65 20 6e 65 63 65 73 73  sh.** the necess
a0e0: 61 72 79 20 6c 6f 63 6b 73 2c 20 74 68 69 73 20  ary locks, this 
a0f0: 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73 20  routine returns 
a100: 53 51 4c 49 54 45 5f 42 55 53 59 2e 0a 2a 2f 0a  SQLITE_BUSY..*/.
a110: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 6e  static int walIn
a120: 64 65 78 52 65 63 6f 76 65 72 28 57 61 6c 20 2a  dexRecover(Wal *
a130: 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63 3b  pWal){.  int rc;
a140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a150: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
a160: 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 69 36 34  rn Code */.  i64
a170: 20 6e 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20   nSize;         
a180: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
a190: 53 69 7a 65 20 6f 66 20 6c 6f 67 20 66 69 6c 65  Size of log file
a1a0: 20 2a 2f 0a 20 20 75 33 32 20 61 46 72 61 6d 65   */.  u32 aFrame
a1b0: 43 6b 73 75 6d 5b 32 5d 20 3d 20 7b 30 2c 20 30  Cksum[2] = {0, 0
a1c0: 7d 3b 0a 20 20 69 6e 74 20 69 4c 6f 63 6b 3b 20  };.  int iLock; 
a1d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a1e0: 20 20 20 20 20 2f 2a 20 4c 6f 63 6b 20 6f 66 66       /* Lock off
a1f0: 73 65 74 20 74 6f 20 6c 6f 63 6b 20 66 6f 72 20  set to lock for 
a200: 63 68 65 63 6b 70 6f 69 6e 74 20 2a 2f 0a 20 20  checkpoint */.  
a210: 69 6e 74 20 6e 4c 6f 63 6b 3b 20 20 20 20 20 20  int nLock;      
a220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a230: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6c 6f 63  /* Number of loc
a240: 6b 73 20 74 6f 20 68 6f 6c 64 20 2a 2f 0a 0a 20  ks to hold */.. 
a250: 20 2f 2a 20 4f 62 74 61 69 6e 20 61 6e 20 65 78   /* Obtain an ex
a260: 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 20  clusive lock on 
a270: 61 6c 6c 20 62 79 74 65 20 69 6e 20 74 68 65 20  all byte in the 
a280: 6c 6f 63 6b 69 6e 67 20 72 61 6e 67 65 20 6e 6f  locking range no
a290: 74 20 61 6c 72 65 61 64 79 0a 20 20 2a 2a 20 6c  t already.  ** l
a2a0: 6f 63 6b 65 64 20 62 79 20 74 68 65 20 63 61 6c  ocked by the cal
a2b0: 6c 65 72 2e 20 54 68 65 20 63 61 6c 6c 65 72 20  ler. The caller 
a2c0: 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74 6f  is guaranteed to
a2d0: 20 68 61 76 65 20 6c 6f 63 6b 65 64 20 74 68 65   have locked the
a2e0: 0a 20 20 2a 2a 20 57 41 4c 5f 57 52 49 54 45 5f  .  ** WAL_WRITE_
a2f0: 4c 4f 43 4b 20 62 79 74 65 2c 20 61 6e 64 20 6d  LOCK byte, and m
a300: 61 79 20 68 61 76 65 20 61 6c 73 6f 20 6c 6f 63  ay have also loc
a310: 6b 65 64 20 74 68 65 20 57 41 4c 5f 43 4b 50 54  ked the WAL_CKPT
a320: 5f 4c 4f 43 4b 20 62 79 74 65 2e 0a 20 20 2a 2a  _LOCK byte..  **
a330: 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   If successful, 
a340: 74 68 65 20 73 61 6d 65 20 62 79 74 65 73 20 74  the same bytes t
a350: 68 61 74 20 61 72 65 20 6c 6f 63 6b 65 64 20 68  hat are locked h
a360: 65 72 65 20 61 72 65 20 75 6e 6c 6f 63 6b 65 64  ere are unlocked
a370: 20 62 65 66 6f 72 65 0a 20 20 2a 2a 20 74 68 69   before.  ** thi
a380: 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72  s function retur
a390: 6e 73 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72  ns..  */.  asser
a3a0: 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63  t( pWal->ckptLoc
a3b0: 6b 3d 3d 31 20 7c 7c 20 70 57 61 6c 2d 3e 63 6b  k==1 || pWal->ck
a3c0: 70 74 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 61  ptLock==0 );.  a
a3d0: 73 73 65 72 74 28 20 57 41 4c 5f 41 4c 4c 5f 42  ssert( WAL_ALL_B
a3e0: 55 54 5f 57 52 49 54 45 3d 3d 57 41 4c 5f 57 52  UT_WRITE==WAL_WR
a3f0: 49 54 45 5f 4c 4f 43 4b 2b 31 20 29 3b 0a 20 20  ITE_LOCK+1 );.  
a400: 61 73 73 65 72 74 28 20 57 41 4c 5f 43 4b 50 54  assert( WAL_CKPT
a410: 5f 4c 4f 43 4b 3d 3d 57 41 4c 5f 41 4c 4c 5f 42  _LOCK==WAL_ALL_B
a420: 55 54 5f 57 52 49 54 45 20 29 3b 0a 20 20 61 73  UT_WRITE );.  as
a430: 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69 74  sert( pWal->writ
a440: 65 4c 6f 63 6b 20 29 3b 0a 20 20 69 4c 6f 63 6b  eLock );.  iLock
a450: 20 3d 20 57 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57   = WAL_ALL_BUT_W
a460: 52 49 54 45 20 2b 20 70 57 61 6c 2d 3e 63 6b 70  RITE + pWal->ckp
a470: 74 4c 6f 63 6b 3b 0a 20 20 6e 4c 6f 63 6b 20 3d  tLock;.  nLock =
a480: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43   SQLITE_SHM_NLOC
a490: 4b 20 2d 20 69 4c 6f 63 6b 3b 0a 20 20 72 63 20  K - iLock;.  rc 
a4a0: 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69  = walLockExclusi
a4b0: 76 65 28 70 57 61 6c 2c 20 69 4c 6f 63 6b 2c 20  ve(pWal, iLock, 
a4c0: 6e 4c 6f 63 6b 29 3b 0a 20 20 69 66 28 20 72 63  nLock);.  if( rc
a4d0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72   ){.    return r
a4e0: 63 3b 0a 20 20 7d 0a 20 20 57 41 4c 54 52 41 43  c;.  }.  WALTRAC
a4f0: 45 28 28 22 57 41 4c 25 70 3a 20 72 65 63 6f 76  E(("WAL%p: recov
a500: 65 72 79 20 62 65 67 69 6e 2e 2e 2e 5c 6e 22 2c  ery begin...\n",
a510: 20 70 57 61 6c 29 29 3b 0a 0a 20 20 6d 65 6d 73   pWal));..  mems
a520: 65 74 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20 30  et(&pWal->hdr, 0
a530: 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65  , sizeof(WalInde
a540: 78 48 64 72 29 29 3b 0a 0a 20 20 72 63 20 3d 20  xHdr));..  rc = 
a550: 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69 7a  sqlite3OsFileSiz
a560: 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20  e(pWal->pWalFd, 
a570: 26 6e 53 69 7a 65 29 3b 0a 20 20 69 66 28 20 72  &nSize);.  if( r
a580: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
a590: 20 20 20 20 67 6f 74 6f 20 72 65 63 6f 76 65 72      goto recover
a5a0: 79 5f 65 72 72 6f 72 3b 0a 20 20 7d 0a 0a 20 20  y_error;.  }..  
a5b0: 69 66 28 20 6e 53 69 7a 65 3e 57 41 4c 5f 48 44  if( nSize>WAL_HD
a5c0: 52 53 49 5a 45 20 29 7b 0a 20 20 20 20 75 38 20  RSIZE ){.    u8 
a5d0: 61 42 75 66 5b 57 41 4c 5f 48 44 52 53 49 5a 45  aBuf[WAL_HDRSIZE
a5e0: 5d 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75  ];         /* Bu
a5f0: 66 66 65 72 20 74 6f 20 6c 6f 61 64 20 57 41 4c  ffer to load WAL
a600: 20 68 65 61 64 65 72 20 69 6e 74 6f 20 2a 2f 0a   header into */.
a610: 20 20 20 20 75 38 20 2a 61 46 72 61 6d 65 20 3d      u8 *aFrame =
a620: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
a630: 20 20 2f 2a 20 4d 61 6c 6c 6f 63 27 64 20 62 75    /* Malloc'd bu
a640: 66 66 65 72 20 74 6f 20 6c 6f 61 64 20 65 6e 74  ffer to load ent
a650: 69 72 65 20 66 72 61 6d 65 20 2a 2f 0a 20 20 20  ire frame */.   
a660: 20 69 6e 74 20 73 7a 46 72 61 6d 65 3b 20 20 20   int szFrame;   
a670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
a680: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
a690: 73 20 69 6e 20 62 75 66 66 65 72 20 61 46 72 61  s in buffer aFra
a6a0: 6d 65 5b 5d 20 2a 2f 0a 20 20 20 20 75 38 20 2a  me[] */.    u8 *
a6b0: 61 44 61 74 61 3b 20 20 20 20 20 20 20 20 20 20  aData;          
a6c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69            /* Poi
a6d0: 6e 74 65 72 20 74 6f 20 64 61 74 61 20 70 61 72  nter to data par
a6e0: 74 20 6f 66 20 61 46 72 61 6d 65 20 62 75 66 66  t of aFrame buff
a6f0: 65 72 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 46  er */.    int iF
a700: 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20  rame;           
a710: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78          /* Index
a720: 20 6f 66 20 6c 61 73 74 20 66 72 61 6d 65 20 72   of last frame r
a730: 65 61 64 20 2a 2f 0a 20 20 20 20 69 36 34 20 69  ead */.    i64 i
a740: 4f 66 66 73 65 74 3b 20 20 20 20 20 20 20 20 20  Offset;         
a750: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
a760: 20 6f 66 66 73 65 74 20 74 6f 20 72 65 61 64 20   offset to read 
a770: 66 72 6f 6d 20 6c 6f 67 20 66 69 6c 65 20 2a 2f  from log file */
a780: 0a 20 20 20 20 69 6e 74 20 73 7a 50 61 67 65 3b  .    int szPage;
a790: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a7a0: 20 20 20 2f 2a 20 50 61 67 65 20 73 69 7a 65 20     /* Page size 
a7b0: 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 74 68 65  according to the
a7c0: 20 6c 6f 67 20 2a 2f 0a 20 20 20 20 75 33 32 20   log */.    u32 
a7d0: 6d 61 67 69 63 3b 20 20 20 20 20 20 20 20 20 20  magic;          
a7e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 67            /* Mag
a7f0: 69 63 20 76 61 6c 75 65 20 72 65 61 64 20 66 72  ic value read fr
a800: 6f 6d 20 57 41 4c 20 68 65 61 64 65 72 20 2a 2f  om WAL header */
a810: 0a 20 20 20 20 75 33 32 20 76 65 72 73 69 6f 6e  .    u32 version
a820: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
a830: 20 20 20 2f 2a 20 4d 61 67 69 63 20 76 61 6c 75     /* Magic valu
a840: 65 20 72 65 61 64 20 66 72 6f 6d 20 57 41 4c 20  e read from WAL 
a850: 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20 20 20 2f  header */..    /
a860: 2a 20 52 65 61 64 20 69 6e 20 74 68 65 20 57 41  * Read in the WA
a870: 4c 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20 20 20  L header. */.   
a880: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 52   rc = sqlite3OsR
a890: 65 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ead(pWal->pWalFd
a8a0: 2c 20 61 42 75 66 2c 20 57 41 4c 5f 48 44 52 53  , aBuf, WAL_HDRS
a8b0: 49 5a 45 2c 20 30 29 3b 0a 20 20 20 20 69 66 28  IZE, 0);.    if(
a8c0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
a8d0: 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 72 65 63  {.      goto rec
a8e0: 6f 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20 20 20  overy_error;.   
a8f0: 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 74 68   }..    /* If th
a900: 65 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20  e database page 
a910: 73 69 7a 65 20 69 73 20 6e 6f 74 20 61 20 70 6f  size is not a po
a920: 77 65 72 20 6f 66 20 74 77 6f 2c 20 6f 72 20 69  wer of two, or i
a930: 73 20 67 72 65 61 74 65 72 20 74 68 61 6e 0a 20  s greater than. 
a940: 20 20 20 2a 2a 20 53 51 4c 49 54 45 5f 4d 41 58     ** SQLITE_MAX
a950: 5f 50 41 47 45 5f 53 49 5a 45 2c 20 63 6f 6e 63  _PAGE_SIZE, conc
a960: 6c 75 64 65 20 74 68 61 74 20 74 68 65 20 57 41  lude that the WA
a970: 4c 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20  L file contains 
a980: 6e 6f 20 76 61 6c 69 64 20 0a 20 20 20 20 2a 2a  no valid .    **
a990: 20 64 61 74 61 2e 20 53 69 6d 69 6c 61 72 6c 79   data. Similarly
a9a0: 2c 20 69 66 20 74 68 65 20 27 6d 61 67 69 63 27  , if the 'magic'
a9b0: 20 76 61 6c 75 65 20 69 73 20 69 6e 76 61 6c 69   value is invali
a9c0: 64 2c 20 69 67 6e 6f 72 65 20 74 68 65 20 77 68  d, ignore the wh
a9d0: 6f 6c 65 0a 20 20 20 20 2a 2a 20 57 41 4c 20 66  ole.    ** WAL f
a9e0: 69 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ile..    */.    
a9f0: 6d 61 67 69 63 20 3d 20 73 71 6c 69 74 65 33 47  magic = sqlite3G
aa00: 65 74 34 62 79 74 65 28 26 61 42 75 66 5b 30 5d  et4byte(&aBuf[0]
aa10: 29 3b 0a 20 20 20 20 73 7a 50 61 67 65 20 3d 20  );.    szPage = 
aa20: 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
aa30: 26 61 42 75 66 5b 38 5d 29 3b 0a 20 20 20 20 69  &aBuf[8]);.    i
aa40: 66 28 20 28 6d 61 67 69 63 26 30 78 46 46 46 46  f( (magic&0xFFFF
aa50: 46 46 46 45 29 21 3d 57 41 4c 5f 4d 41 47 49 43  FFFE)!=WAL_MAGIC
aa60: 20 0a 20 20 20 20 20 7c 7c 20 73 7a 50 61 67 65   .     || szPage
aa70: 26 28 73 7a 50 61 67 65 2d 31 29 20 0a 20 20 20  &(szPage-1) .   
aa80: 20 20 7c 7c 20 73 7a 50 61 67 65 3e 53 51 4c 49    || szPage>SQLI
aa90: 54 45 5f 4d 41 58 5f 50 41 47 45 5f 53 49 5a 45  TE_MAX_PAGE_SIZE
aaa0: 20 0a 20 20 20 20 20 7c 7c 20 73 7a 50 61 67 65   .     || szPage
aab0: 3c 35 31 32 20 0a 20 20 20 20 29 7b 0a 20 20 20  <512 .    ){.   
aac0: 20 20 20 67 6f 74 6f 20 66 69 6e 69 73 68 65 64     goto finished
aad0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 57 61 6c  ;.    }.    pWal
aae0: 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75  ->hdr.bigEndCksu
aaf0: 6d 20 3d 20 28 75 38 29 28 6d 61 67 69 63 26 30  m = (u8)(magic&0
ab00: 78 30 30 30 30 30 30 30 31 29 3b 0a 20 20 20 20  x00000001);.    
ab10: 70 57 61 6c 2d 3e 73 7a 50 61 67 65 20 3d 20 28  pWal->szPage = (
ab20: 75 31 36 29 73 7a 50 61 67 65 3b 0a 20 20 20 20  u16)szPage;.    
ab30: 70 57 61 6c 2d 3e 6e 43 6b 70 74 20 3d 20 73 71  pWal->nCkpt = sq
ab40: 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61  lite3Get4byte(&a
ab50: 42 75 66 5b 31 32 5d 29 3b 0a 20 20 20 20 6d 65  Buf[12]);.    me
ab60: 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2e  mcpy(&pWal->hdr.
ab70: 61 53 61 6c 74 2c 20 26 61 42 75 66 5b 31 36 5d  aSalt, &aBuf[16]
ab80: 2c 20 38 29 3b 0a 0a 20 20 20 20 2f 2a 20 56 65  , 8);..    /* Ve
ab90: 72 69 66 79 20 74 68 61 74 20 74 68 65 20 57 41  rify that the WA
aba0: 4c 20 68 65 61 64 65 72 20 63 68 65 63 6b 73 75  L header checksu
abb0: 6d 20 69 73 20 63 6f 72 72 65 63 74 20 2a 2f 0a  m is correct */.
abc0: 20 20 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42      walChecksumB
abd0: 79 74 65 73 28 70 57 61 6c 2d 3e 68 64 72 2e 62  ytes(pWal->hdr.b
abe0: 69 67 45 6e 64 43 6b 73 75 6d 3d 3d 53 51 4c 49  igEndCksum==SQLI
abf0: 54 45 5f 42 49 47 45 4e 44 49 41 4e 2c 20 0a 20  TE_BIGENDIAN, . 
ac00: 20 20 20 20 20 20 20 61 42 75 66 2c 20 57 41 4c         aBuf, WAL
ac10: 5f 48 44 52 53 49 5a 45 2d 32 2a 34 2c 20 30 2c  _HDRSIZE-2*4, 0,
ac20: 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d   pWal->hdr.aFram
ac30: 65 43 6b 73 75 6d 0a 20 20 20 20 29 3b 0a 20 20  eCksum.    );.  
ac40: 20 20 69 66 28 20 70 57 61 6c 2d 3e 68 64 72 2e    if( pWal->hdr.
ac50: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 21 3d  aFrameCksum[0]!=
ac60: 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
ac70: 26 61 42 75 66 5b 32 34 5d 29 0a 20 20 20 20 20  &aBuf[24]).     
ac80: 7c 7c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72  || pWal->hdr.aFr
ac90: 61 6d 65 43 6b 73 75 6d 5b 31 5d 21 3d 73 71 6c  ameCksum[1]!=sql
aca0: 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61 42  ite3Get4byte(&aB
acb0: 75 66 5b 32 38 5d 29 0a 20 20 20 20 29 7b 0a 20  uf[28]).    ){. 
acc0: 20 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73 68       goto finish
acd0: 65 64 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  ed;.    }..    /
ace0: 2a 20 56 65 72 69 66 79 20 74 68 61 74 20 74 68  * Verify that th
acf0: 65 20 76 65 72 73 69 6f 6e 20 6e 75 6d 62 65 72  e version number
ad00: 20 6f 6e 20 74 68 65 20 57 41 4c 20 66 6f 72 6d   on the WAL form
ad10: 61 74 20 69 73 20 6f 6e 65 20 74 68 61 74 0a 20  at is one that. 
ad20: 20 20 20 2a 2a 20 61 72 65 20 61 62 6c 65 20 74     ** are able t
ad30: 6f 20 75 6e 64 65 72 73 74 61 6e 64 20 2a 2f 0a  o understand */.
ad40: 20 20 20 20 76 65 72 73 69 6f 6e 20 3d 20 73 71      version = sq
ad50: 6c 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61  lite3Get4byte(&a
ad60: 42 75 66 5b 34 5d 29 3b 0a 20 20 20 20 69 66 28  Buf[4]);.    if(
ad70: 20 76 65 72 73 69 6f 6e 21 3d 57 41 4c 5f 4d 41   version!=WAL_MA
ad80: 58 5f 56 45 52 53 49 4f 4e 20 29 7b 0a 20 20 20  X_VERSION ){.   
ad90: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43     rc = SQLITE_C
ada0: 41 4e 54 4f 50 45 4e 5f 42 4b 50 54 3b 0a 20 20  ANTOPEN_BKPT;.  
adb0: 20 20 20 20 67 6f 74 6f 20 66 69 6e 69 73 68 65      goto finishe
adc0: 64 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  d;.    }..    /*
add0: 20 4d 61 6c 6c 6f 63 20 61 20 62 75 66 66 65 72   Malloc a buffer
ade0: 20 74 6f 20 72 65 61 64 20 66 72 61 6d 65 73 20   to read frames 
adf0: 69 6e 74 6f 2e 20 2a 2f 0a 20 20 20 20 73 7a 46  into. */.    szF
ae00: 72 61 6d 65 20 3d 20 73 7a 50 61 67 65 20 2b 20  rame = szPage + 
ae10: 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a  WAL_FRAME_HDRSIZ
ae20: 45 3b 0a 20 20 20 20 61 46 72 61 6d 65 20 3d 20  E;.    aFrame = 
ae30: 28 75 38 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61  (u8 *)sqlite3_ma
ae40: 6c 6c 6f 63 28 73 7a 46 72 61 6d 65 29 3b 0a 20  lloc(szFrame);. 
ae50: 20 20 20 69 66 28 20 21 61 46 72 61 6d 65 20 29     if( !aFrame )
ae60: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
ae70: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
ae80: 20 67 6f 74 6f 20 72 65 63 6f 76 65 72 79 5f 65   goto recovery_e
ae90: 72 72 6f 72 3b 0a 20 20 20 20 7d 0a 20 20 20 20  rror;.    }.    
aea0: 61 44 61 74 61 20 3d 20 26 61 46 72 61 6d 65 5b  aData = &aFrame[
aeb0: 57 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a  WAL_FRAME_HDRSIZ
aec0: 45 5d 3b 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64  E];..    /* Read
aed0: 20 61 6c 6c 20 66 72 61 6d 65 73 20 66 72 6f 6d   all frames from
aee0: 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e 20 2a   the log file. *
aef0: 2f 0a 20 20 20 20 69 46 72 61 6d 65 20 3d 20 30  /.    iFrame = 0
af00: 3b 0a 20 20 20 20 66 6f 72 28 69 4f 66 66 73 65  ;.    for(iOffse
af10: 74 3d 57 41 4c 5f 48 44 52 53 49 5a 45 3b 20 28  t=WAL_HDRSIZE; (
af20: 69 4f 66 66 73 65 74 2b 73 7a 46 72 61 6d 65 29  iOffset+szFrame)
af30: 3c 3d 6e 53 69 7a 65 3b 20 69 4f 66 66 73 65 74  <=nSize; iOffset
af40: 2b 3d 73 7a 46 72 61 6d 65 29 7b 0a 20 20 20 20  +=szFrame){.    
af50: 20 20 75 33 32 20 70 67 6e 6f 3b 20 20 20 20 20    u32 pgno;     
af60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
af70: 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20 6e   Database page n
af80: 75 6d 62 65 72 20 66 6f 72 20 66 72 61 6d 65 20  umber for frame 
af90: 2a 2f 0a 20 20 20 20 20 20 75 33 32 20 6e 54 72  */.      u32 nTr
afa0: 75 6e 63 61 74 65 3b 20 20 20 20 20 20 20 20 20  uncate;         
afb0: 20 20 20 20 20 2f 2a 20 64 62 73 69 7a 65 20 66       /* dbsize f
afc0: 69 65 6c 64 20 66 72 6f 6d 20 66 72 61 6d 65 20  ield from frame 
afd0: 68 65 61 64 65 72 20 2a 2f 0a 20 20 20 20 20 20  header */.      
afe0: 69 6e 74 20 69 73 56 61 6c 69 64 3b 20 20 20 20  int isValid;    
aff0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
b000: 72 75 65 20 69 66 20 74 68 69 73 20 66 72 61 6d  rue if this fram
b010: 65 20 69 73 20 76 61 6c 69 64 20 2a 2f 0a 0a 20  e is valid */.. 
b020: 20 20 20 20 20 2f 2a 20 52 65 61 64 20 61 6e 64       /* Read and
b030: 20 64 65 63 6f 64 65 20 74 68 65 20 6e 65 78 74   decode the next
b040: 20 6c 6f 67 20 66 72 61 6d 65 2e 20 2a 2f 0a 20   log frame. */. 
b050: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
b060: 33 4f 73 52 65 61 64 28 70 57 61 6c 2d 3e 70 57  3OsRead(pWal->pW
b070: 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20 73 7a  alFd, aFrame, sz
b080: 46 72 61 6d 65 2c 20 69 4f 66 66 73 65 74 29 3b  Frame, iOffset);
b090: 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
b0a0: 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
b0b0: 3b 0a 20 20 20 20 20 20 69 73 56 61 6c 69 64 20  ;.      isValid 
b0c0: 3d 20 77 61 6c 44 65 63 6f 64 65 46 72 61 6d 65  = walDecodeFrame
b0d0: 28 70 57 61 6c 2c 20 26 70 67 6e 6f 2c 20 26 6e  (pWal, &pgno, &n
b0e0: 54 72 75 6e 63 61 74 65 2c 20 61 44 61 74 61 2c  Truncate, aData,
b0f0: 20 61 46 72 61 6d 65 29 3b 0a 20 20 20 20 20 20   aFrame);.      
b100: 69 66 28 20 21 69 73 56 61 6c 69 64 20 29 20 62  if( !isValid ) b
b110: 72 65 61 6b 3b 0a 20 20 20 20 20 20 72 63 20 3d  reak;.      rc =
b120: 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64 28   walIndexAppend(
b130: 70 57 61 6c 2c 20 2b 2b 69 46 72 61 6d 65 2c 20  pWal, ++iFrame, 
b140: 70 67 6e 6f 29 3b 0a 20 20 20 20 20 20 69 66 28  pgno);.      if(
b150: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
b160: 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 2f   break;..      /
b170: 2a 20 49 66 20 6e 54 72 75 6e 63 61 74 65 20 69  * If nTruncate i
b180: 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 69 73  s non-zero, this
b190: 20 69 73 20 61 20 63 6f 6d 6d 69 74 20 72 65 63   is a commit rec
b1a0: 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 20 20 69 66  ord. */.      if
b1b0: 28 20 6e 54 72 75 6e 63 61 74 65 20 29 7b 0a 20  ( nTruncate ){. 
b1c0: 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72         pWal->hdr
b1d0: 2e 6d 78 46 72 61 6d 65 20 3d 20 69 46 72 61 6d  .mxFrame = iFram
b1e0: 65 3b 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d  e;.        pWal-
b1f0: 3e 68 64 72 2e 6e 50 61 67 65 20 3d 20 6e 54 72  >hdr.nPage = nTr
b200: 75 6e 63 61 74 65 3b 0a 20 20 20 20 20 20 20 20  uncate;.        
b210: 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65  pWal->hdr.szPage
b220: 20 3d 20 28 75 31 36 29 73 7a 50 61 67 65 3b 0a   = (u16)szPage;.
b230: 20 20 20 20 20 20 20 20 61 46 72 61 6d 65 43 6b          aFrameCk
b240: 73 75 6d 5b 30 5d 20 3d 20 70 57 61 6c 2d 3e 68  sum[0] = pWal->h
b250: 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30  dr.aFrameCksum[0
b260: 5d 3b 0a 20 20 20 20 20 20 20 20 61 46 72 61 6d  ];.        aFram
b270: 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 70 57 61 6c  eCksum[1] = pWal
b280: 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
b290: 6d 5b 31 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20  m[1];.      }.  
b2a0: 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65 33    }..    sqlite3
b2b0: 5f 66 72 65 65 28 61 46 72 61 6d 65 29 3b 0a 20  _free(aFrame);. 
b2c0: 20 7d 0a 0a 66 69 6e 69 73 68 65 64 3a 0a 20 20   }..finished:.  
b2d0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
b2e0: 4b 20 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c  K ){.    volatil
b2f0: 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70  e WalCkptInfo *p
b300: 49 6e 66 6f 3b 0a 20 20 20 20 69 6e 74 20 69 3b  Info;.    int i;
b310: 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61  .    pWal->hdr.a
b320: 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d 20  FrameCksum[0] = 
b330: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a  aFrameCksum[0];.
b340: 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46      pWal->hdr.aF
b350: 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 61  rameCksum[1] = a
b360: 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a 20  FrameCksum[1];. 
b370: 20 20 20 77 61 6c 49 6e 64 65 78 57 72 69 74 65     walIndexWrite
b380: 48 64 72 28 70 57 61 6c 29 3b 0a 0a 20 20 20 20  Hdr(pWal);..    
b390: 2f 2a 20 52 65 73 65 74 20 74 68 65 20 63 68 65  /* Reset the che
b3a0: 63 6b 70 6f 69 6e 74 2d 68 65 61 64 65 72 2e 20  ckpoint-header. 
b3b0: 54 68 69 73 20 69 73 20 73 61 66 65 20 62 65 63  This is safe bec
b3c0: 61 75 73 65 20 74 68 69 73 20 74 68 72 65 61 64  ause this thread
b3d0: 20 69 73 20 0a 20 20 20 20 2a 2a 20 63 75 72 72   is .    ** curr
b3e0: 65 6e 74 6c 79 20 68 6f 6c 64 69 6e 67 20 6c 6f  ently holding lo
b3f0: 63 6b 73 20 74 68 61 74 20 65 78 63 6c 75 64 65  cks that exclude
b400: 20 61 6c 6c 20 6f 74 68 65 72 20 72 65 61 64 65   all other reade
b410: 72 73 2c 20 77 72 69 74 65 72 73 20 61 6e 64 0a  rs, writers and.
b420: 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69 6e      ** checkpoin
b430: 74 65 72 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  ters..    */.   
b440: 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74   pInfo = walCkpt
b450: 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20 20  Info(pWal);.    
b460: 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c  pInfo->nBackfill
b470: 20 3d 20 30 3b 0a 20 20 20 20 70 49 6e 66 6f 2d   = 0;.    pInfo-
b480: 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20 3d 20  >aReadMark[0] = 
b490: 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20  0;.    for(i=1; 
b4a0: 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69  i<WAL_NREADER; i
b4b0: 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64  ++) pInfo->aRead
b4c0: 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41  Mark[i] = READMA
b4d0: 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 7d  RK_NOT_USED;.  }
b4e0: 0a 0a 72 65 63 6f 76 65 72 79 5f 65 72 72 6f 72  ..recovery_error
b4f0: 3a 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  :.  WALTRACE(("W
b500: 41 4c 25 70 3a 20 72 65 63 6f 76 65 72 79 20 25  AL%p: recovery %
b510: 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72 63 20 3f  s\n", pWal, rc ?
b520: 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22   "failed" : "ok"
b530: 29 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 45  ));.  walUnlockE
b540: 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 69  xclusive(pWal, i
b550: 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b 0a 20 20  Lock, nLock);.  
b560: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
b570: 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20 6f 70 65  .** Close an ope
b580: 6e 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f 0a  n wal-index..*/.
b590: 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 49  static void walI
b5a0: 6e 64 65 78 43 6c 6f 73 65 28 57 61 6c 20 2a 70  ndexClose(Wal *p
b5b0: 57 61 6c 2c 20 69 6e 74 20 69 73 44 65 6c 65 74  Wal, int isDelet
b5c0: 65 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  e){.  if( pWal->
b5d0: 69 73 57 49 6e 64 65 78 4f 70 65 6e 20 29 7b 0a  isWIndexOpen ){.
b5e0: 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53 68 6d      sqlite3OsShm
b5f0: 43 6c 6f 73 65 28 70 57 61 6c 2d 3e 70 44 62 46  Close(pWal->pDbF
b600: 64 2c 20 69 73 44 65 6c 65 74 65 29 3b 0a 20 20  d, isDelete);.  
b610: 20 20 70 57 61 6c 2d 3e 69 73 57 49 6e 64 65 78    pWal->isWIndex
b620: 4f 70 65 6e 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a  Open = 0;.  }.}.
b630: 0a 2f 2a 20 0a 2a 2a 20 4f 70 65 6e 20 61 20 63  ./* .** Open a c
b640: 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 74 68 65  onnection to the
b650: 20 57 41 4c 20 66 69 6c 65 20 61 73 73 6f 63 69   WAL file associ
b660: 61 74 65 64 20 77 69 74 68 20 64 61 74 61 62 61  ated with databa
b670: 73 65 20 7a 44 62 4e 61 6d 65 2e 0a 2a 2a 20 54  se zDbName..** T
b680: 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
b690: 20 6d 75 73 74 20 61 6c 72 65 61 64 79 20 62 65   must already be
b6a0: 20 6f 70 65 6e 65 64 20 6f 6e 20 63 6f 6e 6e 65   opened on conne
b6b0: 63 74 69 6f 6e 20 70 44 62 46 64 2e 0a 2a 2a 0a  ction pDbFd..**.
b6c0: 2a 2a 20 41 20 53 48 41 52 45 44 20 6c 6f 63 6b  ** A SHARED lock
b6d0: 20 73 68 6f 75 6c 64 20 62 65 20 68 65 6c 64 20   should be held 
b6e0: 6f 6e 20 74 68 65 20 64 61 74 61 62 61 73 65 20  on the database 
b6f0: 66 69 6c 65 20 77 68 65 6e 20 74 68 69 73 20 66  file when this f
b700: 75 6e 63 74 69 6f 6e 0a 2a 2a 20 69 73 20 63 61  unction.** is ca
b710: 6c 6c 65 64 2e 20 54 68 65 20 70 75 72 70 6f 73  lled. The purpos
b720: 65 20 6f 66 20 74 68 69 73 20 53 48 41 52 45 44  e of this SHARED
b730: 20 6c 6f 63 6b 20 69 73 20 74 6f 20 70 72 65 76   lock is to prev
b740: 65 6e 74 20 61 6e 79 20 6f 74 68 65 72 0a 2a 2a  ent any other.**
b750: 20 63 6c 69 65 6e 74 20 66 72 6f 6d 20 75 6e 6c   client from unl
b760: 69 6e 6b 69 6e 67 20 74 68 65 20 57 41 4c 20 6f  inking the WAL o
b770: 72 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65  r wal-index file
b780: 2e 20 49 66 20 61 6e 6f 74 68 65 72 20 70 72 6f  . If another pro
b790: 63 65 73 73 0a 2a 2a 20 77 65 72 65 20 74 6f 20  cess.** were to 
b7a0: 64 6f 20 74 68 69 73 20 6a 75 73 74 20 61 66 74  do this just aft
b7b0: 65 72 20 74 68 69 73 20 63 6c 69 65 6e 74 20 6f  er this client o
b7c0: 70 65 6e 65 64 20 6f 6e 65 20 6f 66 20 74 68 65  pened one of the
b7d0: 73 65 20 66 69 6c 65 73 2c 20 74 68 65 0a 2a 2a  se files, the.**
b7e0: 20 73 79 73 74 65 6d 20 77 6f 75 6c 64 20 62 65   system would be
b7f0: 20 62 61 64 6c 79 20 62 72 6f 6b 65 6e 2e 0a 2a   badly broken..*
b800: 2a 0a 2a 2a 20 49 66 20 74 68 65 20 6c 6f 67 20  *.** If the log 
b810: 66 69 6c 65 20 69 73 20 73 75 63 63 65 73 73 66  file is successf
b820: 75 6c 6c 79 20 6f 70 65 6e 65 64 2c 20 53 51 4c  ully opened, SQL
b830: 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
b840: 65 64 20 61 6e 64 20 0a 2a 2a 20 2a 70 70 57 61  ed and .** *ppWa
b850: 6c 20 69 73 20 73 65 74 20 74 6f 20 70 6f 69 6e  l is set to poin
b860: 74 20 74 6f 20 61 20 6e 65 77 20 57 41 4c 20 68  t to a new WAL h
b870: 61 6e 64 6c 65 2e 20 49 66 20 61 6e 20 65 72 72  andle. If an err
b880: 6f 72 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 61 6e  or occurs,.** an
b890: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
b8a0: 64 65 20 69 73 20 72 65 74 75 72 6e 65 64 20 61  de is returned a
b8b0: 6e 64 20 2a 70 70 57 61 6c 20 69 73 20 6c 65 66  nd *ppWal is lef
b8c0: 74 20 75 6e 6d 6f 64 69 66 69 65 64 2e 0a 2a 2f  t unmodified..*/
b8d0: 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 4f  .int sqlite3WalO
b8e0: 70 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76  pen(.  sqlite3_v
b8f0: 66 73 20 2a 70 56 66 73 2c 20 20 20 20 20 20 20  fs *pVfs,       
b900: 20 20 20 20 20 20 20 2f 2a 20 76 66 73 20 6d 6f         /* vfs mo
b910: 64 75 6c 65 20 74 6f 20 6f 70 65 6e 20 77 61 6c  dule to open wal
b920: 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 2a   and wal-index *
b930: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  /.  sqlite3_file
b940: 20 2a 70 44 62 46 64 2c 20 20 20 20 20 20 20 20   *pDbFd,        
b950: 20 20 20 20 2f 2a 20 54 68 65 20 6f 70 65 6e 20      /* The open 
b960: 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 2a 2f  database file */
b970: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
b980: 44 62 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20  DbName,         
b990: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68     /* Name of th
b9a0: 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  e database file 
b9b0: 2a 2f 0a 20 20 57 61 6c 20 2a 2a 70 70 57 61 6c  */.  Wal **ppWal
b9c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b9d0: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 41 6c 6c       /* OUT: All
b9e0: 6f 63 61 74 65 64 20 57 61 6c 20 68 61 6e 64 6c  ocated Wal handl
b9f0: 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  e */.){.  int rc
ba00: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
ba10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
ba20: 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 57 61  urn Code */.  Wa
ba30: 6c 20 2a 70 52 65 74 3b 20 20 20 20 20 20 20 20  l *pRet;        
ba40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
ba50: 20 4f 62 6a 65 63 74 20 74 6f 20 61 6c 6c 6f 63   Object to alloc
ba60: 61 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20 2a  ate and return *
ba70: 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73 3b 20 20  /.  int flags;  
ba80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ba90: 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 70 61 73      /* Flags pas
baa0: 73 65 64 20 74 6f 20 4f 73 4f 70 65 6e 28 29 20  sed to OsOpen() 
bab0: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 57 61 6c 3b  */.  char *zWal;
bac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bad0: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
bae0: 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20  write-ahead log 
baf0: 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 57  file */.  int nW
bb00: 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  al;             
bb10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e            /* Len
bb20: 67 74 68 20 6f 66 20 7a 57 61 6c 20 69 6e 20 62  gth of zWal in b
bb30: 79 74 65 73 20 2a 2f 0a 0a 20 20 61 73 73 65 72  ytes */..  asser
bb40: 74 28 20 7a 44 62 4e 61 6d 65 20 26 26 20 7a 44  t( zDbName && zD
bb50: 62 4e 61 6d 65 5b 30 5d 20 29 3b 0a 20 20 61 73  bName[0] );.  as
bb60: 73 65 72 74 28 20 70 44 62 46 64 20 29 3b 0a 0a  sert( pDbFd );..
bb70: 20 20 2f 2a 20 49 6e 20 74 68 65 20 61 6d 61 6c    /* In the amal
bb80: 67 61 6d 61 74 69 6f 6e 2c 20 74 68 65 20 6f 73  gamation, the os
bb90: 5f 75 6e 69 78 2e 63 20 61 6e 64 20 6f 73 5f 77  _unix.c and os_w
bba0: 69 6e 2e 63 20 73 6f 75 72 63 65 20 66 69 6c 65  in.c source file
bbb0: 73 20 63 6f 6d 65 20 62 65 66 6f 72 65 0a 20 20  s come before.  
bbc0: 2a 2a 20 74 68 69 73 20 73 6f 75 72 63 65 20 66  ** this source f
bbd0: 69 6c 65 2e 20 20 56 65 72 69 66 79 20 74 68 61  ile.  Verify tha
bbe0: 74 20 74 68 65 20 23 64 65 66 69 6e 65 73 20 6f  t the #defines o
bbf0: 66 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 62 79  f the locking by
bc00: 74 65 20 6f 66 66 73 65 74 73 0a 20 20 2a 2a 20  te offsets.  ** 
bc10: 69 6e 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e 64  in os_unix.c and
bc20: 20 6f 73 5f 77 69 6e 2e 63 20 61 67 72 65 65 20   os_win.c agree 
bc30: 77 69 74 68 20 74 68 65 20 57 41 4c 49 4e 44 45  with the WALINDE
bc40: 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 76 61  X_LOCK_OFFSET va
bc50: 6c 75 65 2e 0a 20 20 2a 2f 0a 23 69 66 64 65 66  lue..  */.#ifdef
bc60: 20 57 49 4e 5f 53 48 4d 5f 42 41 53 45 0a 20 20   WIN_SHM_BASE.  
bc70: 61 73 73 65 72 74 28 20 57 49 4e 5f 53 48 4d 5f  assert( WIN_SHM_
bc80: 42 41 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c  BASE==WALINDEX_L
bc90: 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65  OCK_OFFSET );.#e
bca0: 6e 64 69 66 0a 23 69 66 64 65 66 20 55 4e 49 58  ndif.#ifdef UNIX
bcb0: 5f 53 48 4d 5f 42 41 53 45 0a 20 20 61 73 73 65  _SHM_BASE.  asse
bcc0: 72 74 28 20 55 4e 49 58 5f 53 48 4d 5f 42 41 53  rt( UNIX_SHM_BAS
bcd0: 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b  E==WALINDEX_LOCK
bce0: 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65 6e 64 69  _OFFSET );.#endi
bcf0: 66 0a 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  f...  /* Allocat
bd00: 65 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66  e an instance of
bd10: 20 73 74 72 75 63 74 20 57 61 6c 20 74 6f 20 72   struct Wal to r
bd20: 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 2a 70 70 57  eturn. */.  *ppW
bd30: 61 6c 20 3d 20 30 3b 0a 20 20 6e 57 61 6c 20 3d  al = 0;.  nWal =
bd40: 20 73 71 6c 69 74 65 33 53 74 72 6c 65 6e 33 30   sqlite3Strlen30
bd50: 28 7a 44 62 4e 61 6d 65 29 20 2b 20 35 3b 0a 20  (zDbName) + 5;. 
bd60: 20 70 52 65 74 20 3d 20 28 57 61 6c 2a 29 73 71   pRet = (Wal*)sq
bd70: 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28  lite3MallocZero(
bd80: 73 69 7a 65 6f 66 28 57 61 6c 29 20 2b 20 70 56  sizeof(Wal) + pV
bd90: 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 20 2b 20 6e  fs->szOsFile + n
bda0: 57 61 6c 29 3b 0a 20 20 69 66 28 20 21 70 52 65  Wal);.  if( !pRe
bdb0: 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  t ){.    return 
bdc0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
bdd0: 7d 0a 0a 20 20 70 52 65 74 2d 3e 70 56 66 73 20  }..  pRet->pVfs 
bde0: 3d 20 70 56 66 73 3b 0a 20 20 70 52 65 74 2d 3e  = pVfs;.  pRet->
bdf0: 70 57 61 6c 46 64 20 3d 20 28 73 71 6c 69 74 65  pWalFd = (sqlite
be00: 33 5f 66 69 6c 65 20 2a 29 26 70 52 65 74 5b 31  3_file *)&pRet[1
be10: 5d 3b 0a 20 20 70 52 65 74 2d 3e 70 44 62 46 64  ];.  pRet->pDbFd
be20: 20 3d 20 70 44 62 46 64 3b 0a 20 20 70 52 65 74   = pDbFd;.  pRet
be30: 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31 3b  ->readLock = -1;
be40: 0a 20 20 73 71 6c 69 74 65 33 5f 72 61 6e 64 6f  .  sqlite3_rando
be50: 6d 6e 65 73 73 28 38 2c 20 26 70 52 65 74 2d 3e  mness(8, &pRet->
be60: 68 64 72 2e 61 53 61 6c 74 29 3b 0a 20 20 70 52  hdr.aSalt);.  pR
be70: 65 74 2d 3e 7a 57 61 6c 4e 61 6d 65 20 3d 20 7a  et->zWalName = z
be80: 57 61 6c 20 3d 20 70 56 66 73 2d 3e 73 7a 4f 73  Wal = pVfs->szOs
be90: 46 69 6c 65 20 2b 20 28 63 68 61 72 2a 29 70 52  File + (char*)pR
bea0: 65 74 2d 3e 70 57 61 6c 46 64 3b 0a 20 20 73 71  et->pWalFd;.  sq
beb0: 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 28 6e  lite3_snprintf(n
bec0: 57 61 6c 2c 20 7a 57 61 6c 2c 20 22 25 73 2d 77  Wal, zWal, "%s-w
bed0: 61 6c 22 2c 20 7a 44 62 4e 61 6d 65 29 3b 0a 20  al", zDbName);. 
bee0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53   rc = sqlite3OsS
bef0: 68 6d 4f 70 65 6e 28 70 44 62 46 64 29 3b 0a 0a  hmOpen(pDbFd);..
bf00: 20 20 2f 2a 20 4f 70 65 6e 20 66 69 6c 65 20 68    /* Open file h
bf10: 61 6e 64 6c 65 20 6f 6e 20 74 68 65 20 77 72 69  andle on the wri
bf20: 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69 6c  te-ahead log fil
bf30: 65 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  e. */.  if( rc==
bf40: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
bf50: 20 70 52 65 74 2d 3e 69 73 57 49 6e 64 65 78 4f   pRet->isWIndexO
bf60: 70 65 6e 20 3d 20 31 3b 0a 20 20 20 20 66 6c 61  pen = 1;.    fla
bf70: 67 73 20 3d 20 28 53 51 4c 49 54 45 5f 4f 50 45  gs = (SQLITE_OPE
bf80: 4e 5f 52 45 41 44 57 52 49 54 45 7c 53 51 4c 49  N_READWRITE|SQLI
bf90: 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54 45 7c 53  TE_OPEN_CREATE|S
bfa0: 51 4c 49 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f  QLITE_OPEN_MAIN_
bfb0: 4a 4f 55 52 4e 41 4c 29 3b 0a 20 20 20 20 72 63  JOURNAL);.    rc
bfc0: 20 3d 20 73 71 6c 69 74 65 33 4f 73 4f 70 65 6e   = sqlite3OsOpen
bfd0: 28 70 56 66 73 2c 20 7a 57 61 6c 2c 20 70 52 65  (pVfs, zWal, pRe
bfe0: 74 2d 3e 70 57 61 6c 46 64 2c 20 66 6c 61 67 73  t->pWalFd, flags
bff0: 2c 20 26 66 6c 61 67 73 29 3b 0a 20 20 7d 0a 0a  , &flags);.  }..
c000: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
c010: 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49 6e  _OK ){.    walIn
c020: 64 65 78 43 6c 6f 73 65 28 70 52 65 74 2c 20 30  dexClose(pRet, 0
c030: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73  );.    sqlite3Os
c040: 43 6c 6f 73 65 28 70 52 65 74 2d 3e 70 57 61 6c  Close(pRet->pWal
c050: 46 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  Fd);.    sqlite3
c060: 5f 66 72 65 65 28 70 52 65 74 29 3b 0a 20 20 7d  _free(pRet);.  }
c070: 65 6c 73 65 7b 0a 20 20 20 20 2a 70 70 57 61 6c  else{.    *ppWal
c080: 20 3d 20 70 52 65 74 3b 0a 20 20 20 20 57 41 4c   = pRet;.    WAL
c090: 54 52 41 43 45 28 28 22 57 41 4c 25 64 3a 20 6f  TRACE(("WAL%d: o
c0a0: 70 65 6e 65 64 5c 6e 22 2c 20 70 52 65 74 29 29  pened\n", pRet))
c0b0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
c0c0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 64  c;.}../*.** Find
c0d0: 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70 61   the smallest pa
c0e0: 67 65 20 6e 75 6d 62 65 72 20 6f 75 74 20 6f 66  ge number out of
c0f0: 20 61 6c 6c 20 70 61 67 65 73 20 68 65 6c 64 20   all pages held 
c100: 69 6e 20 74 68 65 20 57 41 4c 20 74 68 61 74 0a  in the WAL that.
c110: 2a 2a 20 68 61 73 20 6e 6f 74 20 62 65 65 6e 20  ** has not been 
c120: 72 65 74 75 72 6e 65 64 20 62 79 20 61 6e 79 20  returned by any 
c130: 70 72 69 6f 72 20 69 6e 76 6f 63 61 74 69 6f 6e  prior invocation
c140: 20 6f 66 20 74 68 69 73 20 6d 65 74 68 6f 64 20   of this method 
c150: 6f 6e 20 74 68 65 0a 2a 2a 20 73 61 6d 65 20 57  on the.** same W
c160: 61 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65 63  alIterator objec
c170: 74 2e 20 20 20 57 72 69 74 65 20 69 6e 74 6f 20  t.   Write into 
c180: 2a 70 69 46 72 61 6d 65 20 74 68 65 20 66 72 61  *piFrame the fra
c190: 6d 65 20 69 6e 64 65 78 20 77 68 65 72 65 0a 2a  me index where.*
c1a0: 2a 20 74 68 61 74 20 70 61 67 65 20 77 61 73 20  * that page was 
c1b0: 6c 61 73 74 20 77 72 69 74 74 65 6e 20 69 6e 74  last written int
c1c0: 6f 20 74 68 65 20 57 41 4c 2e 20 20 57 72 69 74  o the WAL.  Writ
c1d0: 65 20 69 6e 74 6f 20 2a 70 69 50 61 67 65 20 74  e into *piPage t
c1e0: 68 65 20 70 61 67 65 0a 2a 2a 20 6e 75 6d 62 65  he page.** numbe
c1f0: 72 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  r..**.** Return 
c200: 30 20 6f 6e 20 73 75 63 63 65 73 73 2e 20 20 49  0 on success.  I
c210: 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20 70  f there are no p
c220: 61 67 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20  ages in the WAL 
c230: 77 69 74 68 20 61 20 70 61 67 65 0a 2a 2a 20 6e  with a page.** n
c240: 75 6d 62 65 72 20 6c 61 72 67 65 72 20 74 68 61  umber larger tha
c250: 6e 20 2a 70 69 50 61 67 65 2c 20 74 68 65 6e 20  n *piPage, then 
c260: 72 65 74 75 72 6e 20 31 2e 0a 2a 2f 0a 73 74 61  return 1..*/.sta
c270: 74 69 63 20 69 6e 74 20 77 61 6c 49 74 65 72 61  tic int walItera
c280: 74 6f 72 4e 65 78 74 28 0a 20 20 57 61 6c 49 74  torNext(.  WalIt
c290: 65 72 61 74 6f 72 20 2a 70 2c 20 20 20 20 20 20  erator *p,      
c2a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65 72           /* Iter
c2b0: 61 74 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a 70  ator */.  u32 *p
c2c0: 69 50 61 67 65 2c 20 20 20 20 20 20 20 20 20 20  iPage,          
c2d0: 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
c2e0: 54 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72 20  The page number 
c2f0: 6f 66 20 74 68 65 20 6e 65 78 74 20 70 61 67 65  of the next page
c300: 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 46 72 61   */.  u32 *piFra
c310: 6d 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20  me              
c320: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 57 61 6c 20      /* OUT: Wal 
c330: 66 72 61 6d 65 20 69 6e 64 65 78 20 6f 66 20 6e  frame index of n
c340: 65 78 74 20 70 61 67 65 20 2a 2f 0a 29 7b 0a 20  ext page */.){. 
c350: 20 75 33 32 20 69 4d 69 6e 3b 20 20 20 20 20 20   u32 iMin;      
c360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c370: 2a 20 52 65 73 75 6c 74 20 70 67 6e 6f 20 6d 75  * Result pgno mu
c380: 73 74 20 62 65 20 67 72 65 61 74 65 72 20 74 68  st be greater th
c390: 61 6e 20 69 4d 69 6e 20 2a 2f 0a 20 20 75 33 32  an iMin */.  u32
c3a0: 20 69 52 65 74 20 3d 20 30 78 46 46 46 46 46 46   iRet = 0xFFFFFF
c3b0: 46 46 3b 20 20 20 20 20 20 20 20 2f 2a 20 30 78  FF;        /* 0x
c3c0: 66 66 66 66 66 66 66 66 20 69 73 20 6e 65 76 65  ffffffff is neve
c3d0: 72 20 61 20 76 61 6c 69 64 20 70 61 67 65 20 6e  r a valid page n
c3e0: 75 6d 62 65 72 20 2a 2f 0a 20 20 69 6e 74 20 69  umber */.  int i
c3f0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
c400: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20           /* For 
c410: 6c 6f 6f 70 69 6e 67 20 74 68 72 6f 75 67 68 20  looping through 
c420: 73 65 67 6d 65 6e 74 73 20 2a 2f 0a 0a 20 20 69  segments */..  i
c430: 4d 69 6e 20 3d 20 70 2d 3e 69 50 72 69 6f 72 3b  Min = p->iPrior;
c440: 0a 20 20 61 73 73 65 72 74 28 20 69 4d 69 6e 3c  .  assert( iMin<
c450: 30 78 66 66 66 66 66 66 66 66 20 29 3b 0a 20 20  0xffffffff );.  
c460: 66 6f 72 28 69 3d 70 2d 3e 6e 53 65 67 6d 65 6e  for(i=p->nSegmen
c470: 74 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29 7b  t-1; i>=0; i--){
c480: 0a 20 20 20 20 73 74 72 75 63 74 20 57 61 6c 53  .    struct WalS
c490: 65 67 6d 65 6e 74 20 2a 70 53 65 67 6d 65 6e 74  egment *pSegment
c4a0: 20 3d 20 26 70 2d 3e 61 53 65 67 6d 65 6e 74 5b   = &p->aSegment[
c4b0: 69 5d 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 70  i];.    while( p
c4c0: 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 3c 70  Segment->iNext<p
c4d0: 53 65 67 6d 65 6e 74 2d 3e 6e 45 6e 74 72 79 20  Segment->nEntry 
c4e0: 29 7b 0a 20 20 20 20 20 20 75 33 32 20 69 50 67  ){.      u32 iPg
c4f0: 20 3d 20 70 53 65 67 6d 65 6e 74 2d 3e 61 50 67   = pSegment->aPg
c500: 6e 6f 5b 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e  no[pSegment->aIn
c510: 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e  dex[pSegment->iN
c520: 65 78 74 5d 5d 3b 0a 20 20 20 20 20 20 69 66 28  ext]];.      if(
c530: 20 69 50 67 3e 69 4d 69 6e 20 29 7b 0a 20 20 20   iPg>iMin ){.   
c540: 20 20 20 20 20 69 66 28 20 69 50 67 3c 69 52 65       if( iPg<iRe
c550: 74 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  t ){.          i
c560: 52 65 74 20 3d 20 69 50 67 3b 0a 20 20 20 20 20  Ret = iPg;.     
c570: 20 20 20 20 20 2a 70 69 46 72 61 6d 65 20 3d 20       *piFrame = 
c580: 70 53 65 67 6d 65 6e 74 2d 3e 69 5a 65 72 6f 20  pSegment->iZero 
c590: 2b 20 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e 64  + pSegment->aInd
c5a0: 65 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65  ex[pSegment->iNe
c5b0: 78 74 5d 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  xt];.        }. 
c5c0: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
c5d0: 20 20 20 20 7d 0a 20 20 20 20 20 20 70 53 65 67      }.      pSeg
c5e0: 6d 65 6e 74 2d 3e 69 4e 65 78 74 2b 2b 3b 0a 20  ment->iNext++;. 
c5f0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 69 50     }.  }..  *piP
c600: 61 67 65 20 3d 20 70 2d 3e 69 50 72 69 6f 72 20  age = p->iPrior 
c610: 3d 20 69 52 65 74 3b 0a 20 20 72 65 74 75 72 6e  = iRet;.  return
c620: 20 28 69 52 65 74 3d 3d 30 78 46 46 46 46 46 46   (iRet==0xFFFFFF
c630: 46 46 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  FF);.}../*.** Th
c640: 69 73 20 66 75 6e 63 74 69 6f 6e 20 6d 65 72 67  is function merg
c650: 65 73 20 74 77 6f 20 73 6f 72 74 65 64 20 6c 69  es two sorted li
c660: 73 74 73 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c  sts into a singl
c670: 65 20 73 6f 72 74 65 64 20 6c 69 73 74 2e 0a 2a  e sorted list..*
c680: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61  /.static void wa
c690: 6c 4d 65 72 67 65 28 0a 20 20 75 33 32 20 2a 61  lMerge(.  u32 *a
c6a0: 43 6f 6e 74 65 6e 74 2c 20 20 20 20 20 20 20 20  Content,        
c6b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61 67            /* Pag
c6c0: 65 73 20 69 6e 20 77 61 6c 20 2a 2f 0a 20 20 68  es in wal */.  h
c6d0: 74 5f 73 6c 6f 74 20 2a 61 4c 65 66 74 2c 20 20  t_slot *aLeft,  
c6e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c6f0: 2a 20 49 4e 3a 20 4c 65 66 74 20 68 61 6e 64 20  * IN: Left hand 
c700: 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20  input list */.  
c710: 69 6e 74 20 6e 4c 65 66 74 2c 20 20 20 20 20 20  int nLeft,      
c720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c730: 2f 2a 20 49 4e 3a 20 45 6c 65 6d 65 6e 74 73 20  /* IN: Elements 
c740: 69 6e 20 61 72 72 61 79 20 2a 70 61 4c 65 66 74  in array *paLeft
c750: 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 2a   */.  ht_slot **
c760: 70 61 52 69 67 68 74 2c 20 20 20 20 20 20 20 20  paRight,        
c770: 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a        /* IN/OUT:
c780: 20 52 69 67 68 74 20 68 61 6e 64 20 69 6e 70 75   Right hand inpu
c790: 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e 74 20  t list */.  int 
c7a0: 2a 70 6e 52 69 67 68 74 2c 20 20 20 20 20 20 20  *pnRight,       
c7b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
c7c0: 4e 2f 4f 55 54 3a 20 45 6c 65 6d 65 6e 74 73 20  N/OUT: Elements 
c7d0: 69 6e 20 2a 70 61 52 69 67 68 74 20 2a 2f 0a 20  in *paRight */. 
c7e0: 20 68 74 5f 73 6c 6f 74 20 2a 61 54 6d 70 20 20   ht_slot *aTmp  
c7f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c800: 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62 75   /* Temporary bu
c810: 66 66 65 72 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ffer */.){.  int
c820: 20 69 4c 65 66 74 20 3d 20 30 3b 20 20 20 20 20   iLeft = 0;     
c830: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c840: 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e  Current index in
c850: 20 61 4c 65 66 74 20 2a 2f 0a 20 20 69 6e 74 20   aLeft */.  int 
c860: 69 52 69 67 68 74 20 3d 20 30 3b 20 20 20 20 20  iRight = 0;     
c870: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
c880: 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e 20  urrent index in 
c890: 61 52 69 67 68 74 20 2a 2f 0a 20 20 69 6e 74 20  aRight */.  int 
c8a0: 69 4f 75 74 20 3d 20 30 3b 20 20 20 20 20 20 20  iOut = 0;       
c8b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
c8c0: 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e 20  urrent index in 
c8d0: 6f 75 74 70 75 74 20 62 75 66 66 65 72 20 2a 2f  output buffer */
c8e0: 0a 20 20 69 6e 74 20 6e 52 69 67 68 74 20 3d 20  .  int nRight = 
c8f0: 2a 70 6e 52 69 67 68 74 3b 0a 20 20 68 74 5f 73  *pnRight;.  ht_s
c900: 6c 6f 74 20 2a 61 52 69 67 68 74 20 3d 20 2a 70  lot *aRight = *p
c910: 61 52 69 67 68 74 3b 0a 0a 20 20 61 73 73 65 72  aRight;..  asser
c920: 74 28 20 6e 4c 65 66 74 3e 30 20 26 26 20 6e 52  t( nLeft>0 && nR
c930: 69 67 68 74 3e 30 20 29 3b 0a 20 20 77 68 69 6c  ight>0 );.  whil
c940: 65 28 20 69 52 69 67 68 74 3c 6e 52 69 67 68 74  e( iRight<nRight
c950: 20 7c 7c 20 69 4c 65 66 74 3c 6e 4c 65 66 74 20   || iLeft<nLeft 
c960: 29 7b 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20 6c  ){.    ht_slot l
c970: 6f 67 70 61 67 65 3b 0a 20 20 20 20 50 67 6e 6f  ogpage;.    Pgno
c980: 20 64 62 70 61 67 65 3b 0a 0a 20 20 20 20 69 66   dbpage;..    if
c990: 28 20 28 69 4c 65 66 74 3c 6e 4c 65 66 74 29 20  ( (iLeft<nLeft) 
c9a0: 0a 20 20 20 20 20 26 26 20 28 69 52 69 67 68 74  .     && (iRight
c9b0: 3e 3d 6e 52 69 67 68 74 20 7c 7c 20 61 43 6f 6e  >=nRight || aCon
c9c0: 74 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74  tent[aLeft[iLeft
c9d0: 5d 5d 3c 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67  ]]<aContent[aRig
c9e0: 68 74 5b 69 52 69 67 68 74 5d 5d 29 0a 20 20 20  ht[iRight]]).   
c9f0: 20 29 7b 0a 20 20 20 20 20 20 6c 6f 67 70 61 67   ){.      logpag
ca00: 65 20 3d 20 61 4c 65 66 74 5b 69 4c 65 66 74 2b  e = aLeft[iLeft+
ca10: 2b 5d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  +];.    }else{. 
ca20: 20 20 20 20 20 6c 6f 67 70 61 67 65 20 3d 20 61       logpage = a
ca30: 52 69 67 68 74 5b 69 52 69 67 68 74 2b 2b 5d 3b  Right[iRight++];
ca40: 0a 20 20 20 20 7d 0a 20 20 20 20 64 62 70 61 67  .    }.    dbpag
ca50: 65 20 3d 20 61 43 6f 6e 74 65 6e 74 5b 6c 6f 67  e = aContent[log
ca60: 70 61 67 65 5d 3b 0a 0a 20 20 20 20 61 54 6d 70  page];..    aTmp
ca70: 5b 69 4f 75 74 2b 2b 5d 20 3d 20 6c 6f 67 70 61  [iOut++] = logpa
ca80: 67 65 3b 0a 20 20 20 20 69 66 28 20 69 4c 65 66  ge;.    if( iLef
ca90: 74 3c 6e 4c 65 66 74 20 26 26 20 61 43 6f 6e 74  t<nLeft && aCont
caa0: 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74 5d  ent[aLeft[iLeft]
cab0: 5d 3d 3d 64 62 70 61 67 65 20 29 20 69 4c 65 66  ]==dbpage ) iLef
cac0: 74 2b 2b 3b 0a 0a 20 20 20 20 61 73 73 65 72 74  t++;..    assert
cad0: 28 20 69 4c 65 66 74 3e 3d 6e 4c 65 66 74 20 7c  ( iLeft>=nLeft |
cae0: 7c 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74  | aContent[aLeft
caf0: 5b 69 4c 65 66 74 5d 5d 3e 64 62 70 61 67 65 20  [iLeft]]>dbpage 
cb00: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 69  );.    assert( i
cb10: 52 69 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c  Right>=nRight ||
cb20: 20 61 43 6f 6e 74 65 6e 74 5b 61 52 69 67 68 74   aContent[aRight
cb30: 5b 69 52 69 67 68 74 5d 5d 3e 64 62 70 61 67 65  [iRight]]>dbpage
cb40: 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 61 52 69   );.  }..  *paRi
cb50: 67 68 74 20 3d 20 61 4c 65 66 74 3b 0a 20 20 2a  ght = aLeft;.  *
cb60: 70 6e 52 69 67 68 74 20 3d 20 69 4f 75 74 3b 0a  pnRight = iOut;.
cb70: 20 20 6d 65 6d 63 70 79 28 61 4c 65 66 74 2c 20    memcpy(aLeft, 
cb80: 61 54 6d 70 2c 20 73 69 7a 65 6f 66 28 61 54 6d  aTmp, sizeof(aTm
cb90: 70 5b 30 5d 29 2a 69 4f 75 74 29 3b 0a 7d 0a 0a  p[0])*iOut);.}..
cba0: 2f 2a 0a 2a 2a 20 53 6f 72 74 20 74 68 65 20 65  /*.** Sort the e
cbb0: 6c 65 6d 65 6e 74 73 20 69 6e 20 6c 69 73 74 20  lements in list 
cbc0: 61 4c 69 73 74 2c 20 72 65 6d 6f 76 69 6e 67 20  aList, removing 
cbd0: 61 6e 79 20 64 75 70 6c 69 63 61 74 65 73 2e 0a  any duplicates..
cbe0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77  */.static void w
cbf0: 61 6c 4d 65 72 67 65 73 6f 72 74 28 0a 20 20 75  alMergesort(.  u
cc00: 33 32 20 2a 61 43 6f 6e 74 65 6e 74 2c 20 20 20  32 *aContent,   
cc10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
cc20: 2a 20 50 61 67 65 73 20 69 6e 20 77 61 6c 20 2a  * Pages in wal *
cc30: 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 42 75  /.  ht_slot *aBu
cc40: 66 66 65 72 2c 20 20 20 20 20 20 20 20 20 20 20  ffer,           
cc50: 20 20 20 20 2f 2a 20 42 75 66 66 65 72 20 6f 66      /* Buffer of
cc60: 20 61 74 20 6c 65 61 73 74 20 2a 70 6e 4c 69 73   at least *pnLis
cc70: 74 20 69 74 65 6d 73 20 74 6f 20 75 73 65 20 2a  t items to use *
cc80: 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 4c 69  /.  ht_slot *aLi
cc90: 73 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  st,             
cca0: 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4c      /* IN/OUT: L
ccb0: 69 73 74 20 74 6f 20 73 6f 72 74 20 2a 2f 0a 20  ist to sort */. 
ccc0: 20 69 6e 74 20 2a 70 6e 4c 69 73 74 20 20 20 20   int *pnList    
ccd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cce0: 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 4e 75 6d 62   /* IN/OUT: Numb
ccf0: 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69  er of elements i
cd00: 6e 20 61 4c 69 73 74 5b 5d 20 2a 2f 0a 29 7b 0a  n aList[] */.){.
cd10: 20 20 73 74 72 75 63 74 20 53 75 62 6c 69 73 74    struct Sublist
cd20: 20 7b 0a 20 20 20 20 69 6e 74 20 6e 4c 69 73 74   {.    int nList
cd30: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
cd40: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
cd50: 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61 4c  f elements in aL
cd60: 69 73 74 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c  ist */.    ht_sl
cd70: 6f 74 20 2a 61 4c 69 73 74 3b 20 20 20 20 20 20  ot *aList;      
cd80: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
cd90: 74 65 72 20 74 6f 20 73 75 62 2d 6c 69 73 74 20  ter to sub-list 
cda0: 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 7d 3b 0a  content */.  };.
cdb0: 0a 20 20 63 6f 6e 73 74 20 69 6e 74 20 6e 4c 69  .  const int nLi
cdc0: 73 74 20 3d 20 2a 70 6e 4c 69 73 74 3b 20 20 20  st = *pnList;   
cdd0: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 69 6e     /* Size of in
cde0: 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20 69 6e  put list */.  in
cdf0: 74 20 6e 4d 65 72 67 65 20 3d 20 30 3b 20 20 20  t nMerge = 0;   
ce00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
ce10: 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65   Number of eleme
ce20: 6e 74 73 20 69 6e 20 6c 69 73 74 20 61 4d 65 72  nts in list aMer
ce30: 67 65 20 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20  ge */.  ht_slot 
ce40: 2a 61 4d 65 72 67 65 20 3d 20 30 3b 20 20 20 20  *aMerge = 0;    
ce50: 20 20 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20          /* List 
ce60: 74 6f 20 62 65 20 6d 65 72 67 65 64 20 2a 2f 0a  to be merged */.
ce70: 20 20 69 6e 74 20 69 4c 69 73 74 3b 20 20 20 20    int iList;    
ce80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ce90: 20 20 2f 2a 20 49 6e 64 65 78 20 69 6e 74 6f 20    /* Index into 
cea0: 69 6e 70 75 74 20 6c 69 73 74 20 2a 2f 0a 20 20  input list */.  
ceb0: 69 6e 74 20 69 53 75 62 20 3d 20 30 3b 20 20 20  int iSub = 0;   
cec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ced0: 2f 2a 20 49 6e 64 65 78 20 69 6e 74 6f 20 61 53  /* Index into aS
cee0: 75 62 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 74  ub array */.  st
cef0: 72 75 63 74 20 53 75 62 6c 69 73 74 20 61 53 75  ruct Sublist aSu
cf00: 62 5b 31 33 5d 3b 20 20 20 20 20 20 20 20 2f 2a  b[13];        /*
cf10: 20 41 72 72 61 79 20 6f 66 20 73 75 62 2d 6c 69   Array of sub-li
cf20: 73 74 73 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65 74  sts */..  memset
cf30: 28 61 53 75 62 2c 20 30 2c 20 73 69 7a 65 6f 66  (aSub, 0, sizeof
cf40: 28 61 53 75 62 29 29 3b 0a 20 20 61 73 73 65 72  (aSub));.  asser
cf50: 74 28 20 6e 4c 69 73 74 3c 3d 48 41 53 48 54 41  t( nList<=HASHTA
cf60: 42 4c 45 5f 4e 50 41 47 45 20 26 26 20 6e 4c 69  BLE_NPAGE && nLi
cf70: 73 74 3e 30 20 29 3b 0a 20 20 61 73 73 65 72 74  st>0 );.  assert
cf80: 28 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  ( HASHTABLE_NPAG
cf90: 45 3d 3d 28 31 3c 3c 28 41 72 72 61 79 53 69 7a  E==(1<<(ArraySiz
cfa0: 65 28 61 53 75 62 29 2d 31 29 29 20 29 3b 0a 0a  e(aSub)-1)) );..
cfb0: 20 20 66 6f 72 28 69 4c 69 73 74 3d 30 3b 20 69    for(iList=0; i
cfc0: 4c 69 73 74 3c 6e 4c 69 73 74 3b 20 69 4c 69 73  List<nList; iLis
cfd0: 74 2b 2b 29 7b 0a 20 20 20 20 6e 4d 65 72 67 65  t++){.    nMerge
cfe0: 20 3d 20 31 3b 0a 20 20 20 20 61 4d 65 72 67 65   = 1;.    aMerge
cff0: 20 3d 20 26 61 4c 69 73 74 5b 69 4c 69 73 74 5d   = &aList[iList]
d000: 3b 0a 20 20 20 20 66 6f 72 28 69 53 75 62 3d 30  ;.    for(iSub=0
d010: 3b 20 69 4c 69 73 74 20 26 20 28 31 3c 3c 69 53  ; iList & (1<<iS
d020: 75 62 29 3b 20 69 53 75 62 2b 2b 29 7b 0a 20 20  ub); iSub++){.  
d030: 20 20 20 20 73 74 72 75 63 74 20 53 75 62 6c 69      struct Subli
d040: 73 74 20 2a 70 20 3d 20 26 61 53 75 62 5b 69 53  st *p = &aSub[iS
d050: 75 62 5d 3b 0a 20 20 20 20 20 20 61 73 73 65 72  ub];.      asser
d060: 74 28 20 70 2d 3e 61 4c 69 73 74 20 26 26 20 70  t( p->aList && p
d070: 2d 3e 6e 4c 69 73 74 3c 3d 28 31 3c 3c 69 53 75  ->nList<=(1<<iSu
d080: 62 29 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65  b) );.      asse
d090: 72 74 28 20 70 2d 3e 61 4c 69 73 74 3d 3d 26 61  rt( p->aList==&a
d0a0: 4c 69 73 74 5b 69 4c 69 73 74 26 7e 28 28 32 3c  List[iList&~((2<
d0b0: 3c 69 53 75 62 29 2d 31 29 5d 20 29 3b 0a 20 20  <iSub)-1)] );.  
d0c0: 20 20 20 20 77 61 6c 4d 65 72 67 65 28 61 43 6f      walMerge(aCo
d0d0: 6e 74 65 6e 74 2c 20 70 2d 3e 61 4c 69 73 74 2c  ntent, p->aList,
d0e0: 20 70 2d 3e 6e 4c 69 73 74 2c 20 26 61 4d 65 72   p->nList, &aMer
d0f0: 67 65 2c 20 26 6e 4d 65 72 67 65 2c 20 61 42 75  ge, &nMerge, aBu
d100: 66 66 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 20  ffer);.    }.   
d110: 20 61 53 75 62 5b 69 53 75 62 5d 2e 61 4c 69 73   aSub[iSub].aLis
d120: 74 20 3d 20 61 4d 65 72 67 65 3b 0a 20 20 20 20  t = aMerge;.    
d130: 61 53 75 62 5b 69 53 75 62 5d 2e 6e 4c 69 73 74  aSub[iSub].nList
d140: 20 3d 20 6e 4d 65 72 67 65 3b 0a 20 20 7d 0a 0a   = nMerge;.  }..
d150: 20 20 66 6f 72 28 69 53 75 62 2b 2b 3b 20 69 53    for(iSub++; iS
d160: 75 62 3c 41 72 72 61 79 53 69 7a 65 28 61 53 75  ub<ArraySize(aSu
d170: 62 29 3b 20 69 53 75 62 2b 2b 29 7b 0a 20 20 20  b); iSub++){.   
d180: 20 69 66 28 20 6e 4c 69 73 74 20 26 20 28 31 3c   if( nList & (1<
d190: 3c 69 53 75 62 29 20 29 7b 0a 20 20 20 20 20 20  <iSub) ){.      
d1a0: 73 74 72 75 63 74 20 53 75 62 6c 69 73 74 20 2a  struct Sublist *
d1b0: 70 20 3d 20 26 61 53 75 62 5b 69 53 75 62 5d 3b  p = &aSub[iSub];
d1c0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
d1d0: 2d 3e 6e 4c 69 73 74 3c 3d 28 31 3c 3c 69 53 75  ->nList<=(1<<iSu
d1e0: 62 29 20 29 3b 0a 20 20 20 20 20 20 61 73 73 65  b) );.      asse
d1f0: 72 74 28 20 70 2d 3e 61 4c 69 73 74 3d 3d 26 61  rt( p->aList==&a
d200: 4c 69 73 74 5b 6e 4c 69 73 74 26 7e 28 28 32 3c  List[nList&~((2<
d210: 3c 69 53 75 62 29 2d 31 29 5d 20 29 3b 0a 20 20  <iSub)-1)] );.  
d220: 20 20 20 20 77 61 6c 4d 65 72 67 65 28 61 43 6f      walMerge(aCo
d230: 6e 74 65 6e 74 2c 20 70 2d 3e 61 4c 69 73 74 2c  ntent, p->aList,
d240: 20 70 2d 3e 6e 4c 69 73 74 2c 20 26 61 4d 65 72   p->nList, &aMer
d250: 67 65 2c 20 26 6e 4d 65 72 67 65 2c 20 61 42 75  ge, &nMerge, aBu
d260: 66 66 65 72 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  ffer);.    }.  }
d270: 0a 20 20 61 73 73 65 72 74 28 20 61 4d 65 72 67  .  assert( aMerg
d280: 65 3d 3d 61 4c 69 73 74 20 29 3b 0a 20 20 2a 70  e==aList );.  *p
d290: 6e 4c 69 73 74 20 3d 20 6e 4d 65 72 67 65 3b 0a  nList = nMerge;.
d2a0: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44  .#ifdef SQLITE_D
d2b0: 45 42 55 47 0a 20 20 7b 0a 20 20 20 20 69 6e 74  EBUG.  {.    int
d2c0: 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b   i;.    for(i=1;
d2d0: 20 69 3c 2a 70 6e 4c 69 73 74 3b 20 69 2b 2b 29   i<*pnList; i++)
d2e0: 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  {.      assert( 
d2f0: 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 69  aContent[aList[i
d300: 5d 5d 20 3e 20 61 43 6f 6e 74 65 6e 74 5b 61 4c  ]] > aContent[aL
d310: 69 73 74 5b 69 2d 31 5d 5d 20 29 3b 0a 20 20 20  ist[i-1]] );.   
d320: 20 7d 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 7d 0a   }.  }.#endif.}.
d330: 0a 2f 2a 20 0a 2a 2a 20 46 72 65 65 20 61 6e 20  ./* .** Free an 
d340: 69 74 65 72 61 74 6f 72 20 61 6c 6c 6f 63 61 74  iterator allocat
d350: 65 64 20 62 79 20 77 61 6c 49 74 65 72 61 74 6f  ed by walIterato
d360: 72 49 6e 69 74 28 29 2e 0a 2a 2f 0a 73 74 61 74  rInit()..*/.stat
d370: 69 63 20 76 6f 69 64 20 77 61 6c 49 74 65 72 61  ic void walItera
d380: 74 6f 72 46 72 65 65 28 57 61 6c 49 74 65 72 61  torFree(WalItera
d390: 74 6f 72 20 2a 70 29 7b 0a 20 20 73 71 6c 69 74  tor *p){.  sqlit
d3a0: 65 33 53 63 72 61 74 63 68 46 72 65 65 28 70 29  e3ScratchFree(p)
d3b0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73 74  ;.}../*.** Const
d3c0: 72 75 63 74 20 61 20 57 61 6c 49 6e 74 65 72 61  ruct a WalIntera
d3d0: 74 6f 72 20 6f 62 6a 65 63 74 20 74 68 61 74 20  tor object that 
d3e0: 63 61 6e 20 62 65 20 75 73 65 64 20 74 6f 20 6c  can be used to l
d3f0: 6f 6f 70 20 6f 76 65 72 20 61 6c 6c 20 0a 2a 2a  oop over all .**
d400: 20 70 61 67 65 73 20 69 6e 20 74 68 65 20 57 41   pages in the WA
d410: 4c 20 69 6e 20 61 73 63 65 6e 64 69 6e 67 20 6f  L in ascending o
d420: 72 64 65 72 2e 20 54 68 65 20 63 61 6c 6c 65 72  rder. The caller
d430: 20 6d 75 73 74 20 68 6f 6c 64 20 74 68 65 20 63   must hold the c
d440: 68 65 63 6b 70 6f 69 6e 74 0a 2a 2a 0a 2a 2a 20  heckpoint.**.** 
d450: 4f 6e 20 73 75 63 63 65 73 73 2c 20 6d 61 6b 65  On success, make
d460: 20 2a 70 70 20 70 6f 69 6e 74 20 74 6f 20 74 68   *pp point to th
d470: 65 20 6e 65 77 6c 79 20 61 6c 6c 6f 63 61 74 65  e newly allocate
d480: 64 20 57 61 6c 49 6e 74 65 72 61 74 6f 72 20 6f  d WalInterator o
d490: 62 6a 65 63 74 0a 2a 2a 20 72 65 74 75 72 6e 20  bject.** return 
d4a0: 53 51 4c 49 54 45 5f 4f 4b 2e 20 4f 74 68 65 72  SQLITE_OK. Other
d4b0: 77 69 73 65 2c 20 72 65 74 75 72 6e 20 61 6e 20  wise, return an 
d4c0: 65 72 72 6f 72 20 63 6f 64 65 2e 20 49 66 20 74  error code. If t
d4d0: 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72  his routine.** r
d4e0: 65 74 75 72 6e 73 20 61 6e 20 65 72 72 6f 72 2c  eturns an error,
d4f0: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 2a 70   the value of *p
d500: 70 20 69 73 20 75 6e 64 65 66 69 6e 65 64 2e 0a  p is undefined..
d510: 2a 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 69 6e  **.** The callin
d520: 67 20 72 6f 75 74 69 6e 65 20 73 68 6f 75 6c 64  g routine should
d530: 20 69 6e 76 6f 6b 65 20 77 61 6c 49 74 65 72 61   invoke walItera
d540: 74 6f 72 46 72 65 65 28 29 20 74 6f 20 64 65 73  torFree() to des
d550: 74 72 6f 79 20 74 68 65 0a 2a 2a 20 57 61 6c 49  troy the.** WalI
d560: 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 20 77  terator object w
d570: 68 65 6e 20 69 74 20 68 61 73 20 66 69 6e 69 73  hen it has finis
d580: 68 65 64 20 77 69 74 68 20 69 74 2e 0a 2a 2f 0a  hed with it..*/.
d590: 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49 74  static int walIt
d5a0: 65 72 61 74 6f 72 49 6e 69 74 28 57 61 6c 20 2a  eratorInit(Wal *
d5b0: 70 57 61 6c 2c 20 57 61 6c 49 74 65 72 61 74 6f  pWal, WalIterato
d5c0: 72 20 2a 2a 70 70 29 7b 0a 20 20 57 61 6c 49 74  r **pp){.  WalIt
d5d0: 65 72 61 74 6f 72 20 2a 70 3b 20 20 20 20 20 20  erator *p;      
d5e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
d5f0: 74 75 72 6e 20 76 61 6c 75 65 20 2a 2f 0a 20 20  turn value */.  
d600: 69 6e 74 20 6e 53 65 67 6d 65 6e 74 3b 20 20 20  int nSegment;   
d610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d620: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 73 65 67  /* Number of seg
d630: 6d 65 6e 74 73 20 74 6f 20 6d 65 72 67 65 20 2a  ments to merge *
d640: 2f 0a 20 20 75 33 32 20 69 4c 61 73 74 3b 20 20  /.  u32 iLast;  
d650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d660: 20 20 20 20 2f 2a 20 4c 61 73 74 20 66 72 61 6d      /* Last fram
d670: 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20 20 69 6e  e in log */.  in
d680: 74 20 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20  t nByte;        
d690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
d6a0: 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   Number of bytes
d6b0: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a   to allocate */.
d6c0: 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
d6d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d6e0: 20 20 2f 2a 20 49 74 65 72 61 74 6f 72 20 76 61    /* Iterator va
d6f0: 72 69 61 62 6c 65 20 2a 2f 0a 20 20 68 74 5f 73  riable */.  ht_s
d700: 6c 6f 74 20 2a 61 54 6d 70 3b 20 20 20 20 20 20  lot *aTmp;      
d710: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
d720: 65 6d 70 20 73 70 61 63 65 20 75 73 65 64 20 62  emp space used b
d730: 79 20 6d 65 72 67 65 2d 73 6f 72 74 20 2a 2f 0a  y merge-sort */.
d740: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
d750: 45 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20  E_OK;           
d760: 20 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65    /* Return Code
d770: 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 69 73 20 72   */..  /* This r
d780: 6f 75 74 69 6e 65 20 6f 6e 6c 79 20 72 75 6e 73  outine only runs
d790: 20 77 68 69 6c 65 20 68 6f 6c 64 69 6e 67 20 74   while holding t
d7a0: 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 6c 6f  he checkpoint lo
d7b0: 63 6b 2e 20 41 6e 64 0a 20 20 2a 2a 20 69 74 20  ck. And.  ** it 
d7c0: 6f 6e 6c 79 20 72 75 6e 73 20 69 66 20 74 68 65  only runs if the
d7d0: 72 65 20 69 73 20 61 63 74 75 61 6c 6c 79 20 63  re is actually c
d7e0: 6f 6e 74 65 6e 74 20 69 6e 20 74 68 65 20 6c 6f  ontent in the lo
d7f0: 67 20 28 6d 78 46 72 61 6d 65 3e 30 29 2e 0a 20  g (mxFrame>0).. 
d800: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57   */.  assert( pW
d810: 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b 20 26 26 20  al->ckptLock && 
d820: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
d830: 65 3e 30 20 29 3b 0a 20 20 69 4c 61 73 74 20 3d  e>0 );.  iLast =
d840: 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
d850: 6d 65 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61  me;..  /* Alloca
d860: 74 65 20 73 70 61 63 65 20 66 6f 72 20 74 68 65  te space for the
d870: 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a   WalIterator obj
d880: 65 63 74 2e 20 2a 2f 0a 20 20 6e 53 65 67 6d 65  ect. */.  nSegme
d890: 6e 74 20 3d 20 77 61 6c 46 72 61 6d 65 50 61 67  nt = walFramePag
d8a0: 65 28 69 4c 61 73 74 29 20 2b 20 31 3b 0a 20 20  e(iLast) + 1;.  
d8b0: 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 57  nByte = sizeof(W
d8c0: 61 6c 49 74 65 72 61 74 6f 72 29 20 0a 20 20 20  alIterator) .   
d8d0: 20 20 20 20 20 2b 20 28 6e 53 65 67 6d 65 6e 74       + (nSegment
d8e0: 2d 31 29 2a 73 69 7a 65 6f 66 28 73 74 72 75 63  -1)*sizeof(struc
d8f0: 74 20 57 61 6c 53 65 67 6d 65 6e 74 29 0a 20 20  t WalSegment).  
d900: 20 20 20 20 20 20 2b 20 69 4c 61 73 74 2a 73 69        + iLast*si
d910: 7a 65 6f 66 28 68 74 5f 73 6c 6f 74 29 3b 0a 20  zeof(ht_slot);. 
d920: 20 70 20 3d 20 28 57 61 6c 49 74 65 72 61 74 6f   p = (WalIterato
d930: 72 20 2a 29 73 71 6c 69 74 65 33 53 63 72 61 74  r *)sqlite3Scrat
d940: 63 68 4d 61 6c 6c 6f 63 28 6e 42 79 74 65 29 3b  chMalloc(nByte);
d950: 0a 20 20 69 66 28 20 21 70 20 29 7b 0a 20 20 20  .  if( !p ){.   
d960: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
d970: 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 6d 65 6d 73  OMEM;.  }.  mems
d980: 65 74 28 70 2c 20 30 2c 20 6e 42 79 74 65 29 3b  et(p, 0, nByte);
d990: 0a 20 20 70 2d 3e 6e 53 65 67 6d 65 6e 74 20 3d  .  p->nSegment =
d9a0: 20 6e 53 65 67 6d 65 6e 74 3b 0a 0a 20 20 2f 2a   nSegment;..  /*
d9b0: 20 41 6c 6c 6f 63 61 74 65 20 74 65 6d 70 6f 72   Allocate tempor
d9c0: 61 72 79 20 73 70 61 63 65 20 75 73 65 64 20 62  ary space used b
d9d0: 79 20 74 68 65 20 6d 65 72 67 65 2d 73 6f 72 74  y the merge-sort
d9e0: 20 72 6f 75 74 69 6e 65 2e 20 54 68 69 73 20 62   routine. This b
d9f0: 6c 6f 63 6b 0a 20 20 2a 2a 20 6f 66 20 6d 65 6d  lock.  ** of mem
da00: 6f 72 79 20 77 69 6c 6c 20 62 65 20 66 72 65 65  ory will be free
da10: 64 20 62 65 66 6f 72 65 20 74 68 69 73 20 66 75  d before this fu
da20: 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 2e 0a  nction returns..
da30: 20 20 2a 2f 0a 20 20 61 54 6d 70 20 3d 20 28 68    */.  aTmp = (h
da40: 74 5f 73 6c 6f 74 20 2a 29 73 71 6c 69 74 65 33  t_slot *)sqlite3
da50: 53 63 72 61 74 63 68 4d 61 6c 6c 6f 63 28 0a 20  ScratchMalloc(. 
da60: 20 20 20 20 20 73 69 7a 65 6f 66 28 68 74 5f 73       sizeof(ht_s
da70: 6c 6f 74 29 20 2a 20 28 69 4c 61 73 74 3e 48 41  lot) * (iLast>HA
da80: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3f 48 41  SHTABLE_NPAGE?HA
da90: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3a 69 4c  SHTABLE_NPAGE:iL
daa0: 61 73 74 29 0a 20 20 29 3b 0a 20 20 69 66 28 20  ast).  );.  if( 
dab0: 21 61 54 6d 70 20 29 7b 0a 20 20 20 20 72 63 20  !aTmp ){.    rc 
dac0: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
dad0: 20 20 7d 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20    }..  for(i=0; 
dae0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
daf0: 20 69 3c 6e 53 65 67 6d 65 6e 74 3b 20 69 2b 2b   i<nSegment; i++
db00: 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20  ){.    volatile 
db10: 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b 0a  ht_slot *aHash;.
db20: 20 20 20 20 75 33 32 20 69 5a 65 72 6f 3b 0a 20      u32 iZero;. 
db30: 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20     volatile u32 
db40: 2a 61 50 67 6e 6f 3b 0a 0a 20 20 20 20 72 63 20  *aPgno;..    rc 
db50: 3d 20 77 61 6c 48 61 73 68 47 65 74 28 70 57 61  = walHashGet(pWa
db60: 6c 2c 20 69 2c 20 26 61 48 61 73 68 2c 20 26 61  l, i, &aHash, &a
db70: 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 20  Pgno, &iZero);. 
db80: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
db90: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 69 6e  E_OK ){.      in
dba0: 74 20 6a 3b 20 20 20 20 20 20 20 20 20 20 20 20  t j;            
dbb0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75            /* Cou
dbc0: 6e 74 65 72 20 76 61 72 69 61 62 6c 65 20 2a 2f  nter variable */
dbd0: 0a 20 20 20 20 20 20 69 6e 74 20 6e 45 6e 74 72  .      int nEntr
dbe0: 79 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y;              
dbf0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
dc00: 65 6e 74 72 69 65 73 20 69 6e 20 74 68 69 73 20  entries in this 
dc10: 73 65 67 6d 65 6e 74 20 2a 2f 0a 20 20 20 20 20  segment */.     
dc20: 20 68 74 5f 73 6c 6f 74 20 2a 61 49 6e 64 65 78   ht_slot *aIndex
dc30: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
dc40: 53 6f 72 74 65 64 20 69 6e 64 65 78 20 66 6f 72  Sorted index for
dc50: 20 74 68 69 73 20 73 65 67 6d 65 6e 74 20 2a 2f   this segment */
dc60: 0a 0a 20 20 20 20 20 20 61 50 67 6e 6f 2b 2b 3b  ..      aPgno++;
dc70: 0a 20 20 20 20 20 20 6e 45 6e 74 72 79 20 3d 20  .      nEntry = 
dc80: 28 69 6e 74 29 28 28 28 69 2b 31 29 3d 3d 6e 53  (int)(((i+1)==nS
dc90: 65 67 6d 65 6e 74 29 3f 28 69 6e 74 29 28 69 4c  egment)?(int)(iL
dca0: 61 73 74 2d 69 5a 65 72 6f 29 3a 28 75 33 32 20  ast-iZero):(u32 
dcb0: 2a 29 61 48 61 73 68 2d 28 75 33 32 20 2a 29 61  *)aHash-(u32 *)a
dcc0: 50 67 6e 6f 29 3b 0a 20 20 20 20 20 20 61 49 6e  Pgno);.      aIn
dcd0: 64 65 78 20 3d 20 26 28 28 68 74 5f 73 6c 6f 74  dex = &((ht_slot
dce0: 20 2a 29 26 70 2d 3e 61 53 65 67 6d 65 6e 74 5b   *)&p->aSegment[
dcf0: 70 2d 3e 6e 53 65 67 6d 65 6e 74 5d 29 5b 69 5a  p->nSegment])[iZ
dd00: 65 72 6f 5d 3b 0a 20 20 20 20 20 20 69 5a 65 72  ero];.      iZer
dd10: 6f 2b 2b 3b 0a 20 20 0a 20 20 20 20 20 20 66 6f  o++;.  .      fo
dd20: 72 28 6a 3d 30 3b 20 6a 3c 6e 45 6e 74 72 79 3b  r(j=0; j<nEntry;
dd30: 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 61   j++){.        a
dd40: 49 6e 64 65 78 5b 6a 5d 20 3d 20 28 68 74 5f 73  Index[j] = (ht_s
dd50: 6c 6f 74 29 6a 3b 0a 20 20 20 20 20 20 7d 0a 20  lot)j;.      }. 
dd60: 20 20 20 20 20 77 61 6c 4d 65 72 67 65 73 6f 72       walMergesor
dd70: 74 28 28 75 33 32 20 2a 29 61 50 67 6e 6f 2c 20  t((u32 *)aPgno, 
dd80: 61 54 6d 70 2c 20 61 49 6e 64 65 78 2c 20 26 6e  aTmp, aIndex, &n
dd90: 45 6e 74 72 79 29 3b 0a 20 20 20 20 20 20 70 2d  Entry);.      p-
dda0: 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 69 5a 65  >aSegment[i].iZe
ddb0: 72 6f 20 3d 20 69 5a 65 72 6f 3b 0a 20 20 20 20  ro = iZero;.    
ddc0: 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d    p->aSegment[i]
ddd0: 2e 6e 45 6e 74 72 79 20 3d 20 6e 45 6e 74 72 79  .nEntry = nEntry
dde0: 3b 0a 20 20 20 20 20 20 70 2d 3e 61 53 65 67 6d  ;.      p->aSegm
ddf0: 65 6e 74 5b 69 5d 2e 61 49 6e 64 65 78 20 3d 20  ent[i].aIndex = 
de00: 61 49 6e 64 65 78 3b 0a 20 20 20 20 20 20 70 2d  aIndex;.      p-
de10: 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 61 50 67  >aSegment[i].aPg
de20: 6e 6f 20 3d 20 28 75 33 32 20 2a 29 61 50 67 6e  no = (u32 *)aPgn
de30: 6f 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73  o;.    }.  }.  s
de40: 71 6c 69 74 65 33 53 63 72 61 74 63 68 46 72 65  qlite3ScratchFre
de50: 65 28 61 54 6d 70 29 3b 0a 0a 20 20 69 66 28 20  e(aTmp);..  if( 
de60: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
de70: 0a 20 20 20 20 77 61 6c 49 74 65 72 61 74 6f 72  .    walIterator
de80: 46 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20 2a  Free(p);.  }.  *
de90: 70 70 20 3d 20 70 3b 0a 20 20 72 65 74 75 72 6e  pp = p;.  return
dea0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f   rc;.}../*.** Co
deb0: 70 79 20 61 73 20 6d 75 63 68 20 63 6f 6e 74 65  py as much conte
dec0: 6e 74 20 61 73 20 77 65 20 63 61 6e 20 66 72 6f  nt as we can fro
ded0: 6d 20 74 68 65 20 57 41 4c 20 62 61 63 6b 20 69  m the WAL back i
dee0: 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65  nto the database
def0: 20 66 69 6c 65 0a 2a 2a 20 69 6e 20 72 65 73 70   file.** in resp
df00: 6f 6e 73 65 20 74 6f 20 61 6e 20 73 71 6c 69 74  onse to an sqlit
df10: 65 33 5f 77 61 6c 5f 63 68 65 63 6b 70 6f 69 6e  e3_wal_checkpoin
df20: 74 28 29 20 72 65 71 75 65 73 74 20 6f 72 20 74  t() request or t
df30: 68 65 20 65 71 75 69 76 61 6c 65 6e 74 2e 0a 2a  he equivalent..*
df40: 2a 0a 2a 2a 20 54 68 65 20 61 6d 6f 75 6e 74 20  *.** The amount 
df50: 6f 66 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 63  of information c
df60: 6f 70 69 65 73 20 66 72 6f 6d 20 57 41 4c 20 74  opies from WAL t
df70: 6f 20 64 61 74 61 62 61 73 65 20 6d 69 67 68 74  o database might
df80: 20 62 65 20 6c 69 6d 69 74 65 64 0a 2a 2a 20 62   be limited.** b
df90: 79 20 61 63 74 69 76 65 20 72 65 61 64 65 72 73  y active readers
dfa0: 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  .  This routine 
dfb0: 77 69 6c 6c 20 6e 65 76 65 72 20 6f 76 65 72 77  will never overw
dfc0: 72 69 74 65 20 61 20 64 61 74 61 62 61 73 65 20  rite a database 
dfd0: 70 61 67 65 0a 2a 2a 20 74 68 61 74 20 61 20 63  page.** that a c
dfe0: 6f 6e 63 75 72 72 65 6e 74 20 72 65 61 64 65 72  oncurrent reader
dff0: 20 6d 69 67 68 74 20 62 65 20 75 73 69 6e 67 2e   might be using.
e000: 0a 2a 2a 0a 2a 2a 20 41 6c 6c 20 49 2f 4f 20 62  .**.** All I/O b
e010: 61 72 72 69 65 72 20 6f 70 65 72 61 74 69 6f 6e  arrier operation
e020: 73 20 28 61 2e 6b 2e 61 20 66 73 79 6e 63 73 29  s (a.k.a fsyncs)
e030: 20 6f 63 63 75 72 20 69 6e 20 74 68 69 73 20 72   occur in this r
e040: 6f 75 74 69 6e 65 20 77 68 65 6e 0a 2a 2a 20 53  outine when.** S
e050: 51 4c 69 74 65 20 69 73 20 69 6e 20 57 41 4c 2d  QLite is in WAL-
e060: 6d 6f 64 65 20 69 6e 20 73 79 6e 63 68 72 6f 6e  mode in synchron
e070: 6f 75 73 3d 4e 4f 52 4d 41 4c 2e 20 20 54 68 61  ous=NORMAL.  Tha
e080: 74 20 6d 65 61 6e 73 20 74 68 61 74 20 69 66 20  t means that if 
e090: 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 73 20  .** checkpoints 
e0a0: 61 72 65 20 61 6c 77 61 79 73 20 72 75 6e 20 62  are always run b
e0b0: 79 20 61 20 62 61 63 6b 67 72 6f 75 6e 64 20 74  y a background t
e0c0: 68 72 65 61 64 20 6f 72 20 62 61 63 6b 67 72 6f  hread or backgro
e0d0: 75 6e 64 20 0a 2a 2a 20 70 72 6f 63 65 73 73 2c  und .** process,
e0e0: 20 66 6f 72 65 67 72 6f 75 6e 64 20 74 68 72 65   foreground thre
e0f0: 61 64 73 20 77 69 6c 6c 20 6e 65 76 65 72 20 62  ads will never b
e100: 6c 6f 63 6b 20 6f 6e 20 61 20 6c 65 6e 67 74 68  lock on a length
e110: 79 20 66 73 79 6e 63 20 63 61 6c 6c 2e 0a 2a 2a  y fsync call..**
e120: 0a 2a 2a 20 46 73 79 6e 63 20 69 73 20 63 61 6c  .** Fsync is cal
e130: 6c 65 64 20 6f 6e 20 74 68 65 20 57 41 4c 20 62  led on the WAL b
e140: 65 66 6f 72 65 20 77 72 69 74 69 6e 67 20 63 6f  efore writing co
e150: 6e 74 65 6e 74 20 6f 75 74 20 6f 66 20 74 68 65  ntent out of the
e160: 20 57 41 4c 20 61 6e 64 0a 2a 2a 20 69 6e 74 6f   WAL and.** into
e170: 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 20   the database.  
e180: 54 68 69 73 20 65 6e 73 75 72 65 73 20 74 68 61  This ensures tha
e190: 74 20 69 66 20 74 68 65 20 6e 65 77 20 63 6f 6e  t if the new con
e1a0: 74 65 6e 74 20 69 73 20 70 65 72 73 69 73 74 65  tent is persiste
e1b0: 6e 74 0a 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c  nt.** in the WAL
e1c0: 20 61 6e 64 20 63 61 6e 20 62 65 20 72 65 63 6f   and can be reco
e1d0: 76 65 72 65 64 20 66 6f 6c 6c 6f 77 69 6e 67 20  vered following 
e1e0: 61 20 70 6f 77 65 72 2d 6c 6f 73 73 20 6f 72 20  a power-loss or 
e1f0: 68 61 72 64 20 72 65 73 65 74 2e 0a 2a 2a 0a 2a  hard reset..**.*
e200: 2a 20 46 73 79 6e 63 20 69 73 20 61 6c 73 6f 20  * Fsync is also 
e210: 63 61 6c 6c 65 64 20 6f 6e 20 74 68 65 20 64 61  called on the da
e220: 74 61 62 61 73 65 20 66 69 6c 65 20 69 66 20 28  tabase file if (
e230: 61 6e 64 20 6f 6e 6c 79 20 69 66 29 20 74 68 65  and only if) the
e240: 20 65 6e 74 69 72 65 0a 2a 2a 20 57 41 4c 20 63   entire.** WAL c
e250: 6f 6e 74 65 6e 74 20 69 73 20 63 6f 70 69 65 64  ontent is copied
e260: 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
e270: 73 65 20 66 69 6c 65 2e 20 20 54 68 69 73 20 73  se file.  This s
e280: 65 63 6f 6e 64 20 66 73 79 6e 63 20 6d 61 6b 65  econd fsync make
e290: 73 0a 2a 2a 20 69 74 20 73 61 66 65 20 74 6f 20  s.** it safe to 
e2a0: 64 65 6c 65 74 65 20 74 68 65 20 57 41 4c 20 73  delete the WAL s
e2b0: 69 6e 63 65 20 74 68 65 20 6e 65 77 20 63 6f 6e  ince the new con
e2c0: 74 65 6e 74 20 77 69 6c 6c 20 70 65 72 73 69 73  tent will persis
e2d0: 74 20 69 6e 20 74 68 65 0a 2a 2a 20 64 61 74 61  t in the.** data
e2e0: 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a  base file..**.**
e2f0: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 75 73   This routine us
e300: 65 73 20 61 6e 64 20 75 70 64 61 74 65 73 20 74  es and updates t
e310: 68 65 20 6e 42 61 63 6b 66 69 6c 6c 20 66 69 65  he nBackfill fie
e320: 6c 64 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  ld of the wal-in
e330: 64 65 78 20 68 65 61 64 65 72 2e 0a 2a 2a 20 54  dex header..** T
e340: 68 69 73 20 69 73 20 74 68 65 20 6f 6e 6c 79 20  his is the only 
e350: 72 6f 75 74 69 6e 65 20 74 68 61 20 77 69 6c 6c  routine tha will
e360: 20 69 6e 63 72 65 61 73 65 20 74 68 65 20 76 61   increase the va
e370: 6c 75 65 20 6f 66 20 6e 42 61 63 6b 66 69 6c 6c  lue of nBackfill
e380: 2e 20 20 0a 2a 2a 20 28 41 20 57 41 4c 20 72 65  .  .** (A WAL re
e390: 73 65 74 20 6f 72 20 72 65 63 6f 76 65 72 79 20  set or recovery 
e3a0: 77 69 6c 6c 20 72 65 76 65 72 74 20 6e 42 61 63  will revert nBac
e3b0: 6b 66 69 6c 6c 20 74 6f 20 7a 65 72 6f 2c 20 62  kfill to zero, b
e3c0: 75 74 20 6e 6f 74 20 69 6e 63 72 65 61 73 65 0a  ut not increase.
e3d0: 2a 2a 20 69 74 73 20 76 61 6c 75 65 2e 29 0a 2a  ** its value.).*
e3e0: 2a 0a 2a 2a 20 54 68 65 20 63 61 6c 6c 65 72 20  *.** The caller 
e3f0: 6d 75 73 74 20 62 65 20 68 6f 6c 64 69 6e 67 20  must be holding 
e400: 73 75 66 66 69 63 69 65 6e 74 20 6c 6f 63 6b 73  sufficient locks
e410: 20 74 6f 20 65 6e 73 75 72 65 20 74 68 61 74 20   to ensure that 
e420: 6e 6f 20 6f 74 68 65 72 0a 2a 2a 20 63 68 65 63  no other.** chec
e430: 6b 70 6f 69 6e 74 20 69 73 20 72 75 6e 6e 69 6e  kpoint is runnin
e440: 67 20 28 69 6e 20 61 6e 79 20 6f 74 68 65 72 20  g (in any other 
e450: 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73  thread or proces
e460: 73 29 20 61 74 20 74 68 65 20 73 61 6d 65 0a 2a  s) at the same.*
e470: 2a 20 74 69 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69  * time..*/.stati
e480: 63 20 69 6e 74 20 77 61 6c 43 68 65 63 6b 70 6f  c int walCheckpo
e490: 69 6e 74 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c  int(.  Wal *pWal
e4a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
e4b0: 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20 63 6f         /* Wal co
e4c0: 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e  nnection */.  in
e4d0: 74 20 73 79 6e 63 5f 66 6c 61 67 73 2c 20 20 20  t sync_flags,   
e4e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
e4f0: 20 46 6c 61 67 73 20 66 6f 72 20 4f 73 53 79 6e   Flags for OsSyn
e500: 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20  c() (or 0) */.  
e510: 69 6e 74 20 6e 42 75 66 2c 20 20 20 20 20 20 20  int nBuf,       
e520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e530: 2f 2a 20 53 69 7a 65 20 6f 66 20 7a 42 75 66 20  /* Size of zBuf 
e540: 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 38  in bytes */.  u8
e550: 20 2a 7a 42 75 66 20 20 20 20 20 20 20 20 20 20   *zBuf          
e560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
e570: 20 54 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65   Temporary buffe
e580: 72 20 74 6f 20 75 73 65 20 2a 2f 0a 29 7b 0a 20  r to use */.){. 
e590: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
e5a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e5b0: 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
e5c0: 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61 67 65 20  */.  int szPage 
e5d0: 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61  = pWal->hdr.szPa
e5e0: 67 65 3b 20 20 2f 2a 20 44 61 74 61 62 61 73 65  ge;  /* Database
e5f0: 20 70 61 67 65 2d 73 69 7a 65 20 2a 2f 0a 20 20   page-size */.  
e600: 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 70 49 74  WalIterator *pIt
e610: 65 72 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  er = 0;         
e620: 2f 2a 20 57 61 6c 20 69 74 65 72 61 74 6f 72 20  /* Wal iterator 
e630: 63 6f 6e 74 65 78 74 20 2a 2f 0a 20 20 75 33 32  context */.  u32
e640: 20 69 44 62 70 61 67 65 20 3d 20 30 3b 20 20 20   iDbpage = 0;   
e650: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e660: 4e 65 78 74 20 64 61 74 61 62 61 73 65 20 70 61  Next database pa
e670: 67 65 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20  ge to write */. 
e680: 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20 30 3b   u32 iFrame = 0;
e690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e6a0: 20 2f 2a 20 57 61 6c 20 66 72 61 6d 65 20 63 6f   /* Wal frame co
e6b0: 6e 74 61 69 6e 69 6e 67 20 64 61 74 61 20 66 6f  ntaining data fo
e6c0: 72 20 69 44 62 70 61 67 65 20 2a 2f 0a 20 20 75  r iDbpage */.  u
e6d0: 33 32 20 6d 78 53 61 66 65 46 72 61 6d 65 3b 20  32 mxSafeFrame; 
e6e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
e6f0: 2a 20 4d 61 78 20 66 72 61 6d 65 20 74 68 61 74  * Max frame that
e700: 20 63 61 6e 20 62 65 20 62 61 63 6b 66 69 6c 6c   can be backfill
e710: 65 64 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20  ed */.  int i;  
e720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e730: 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20          /* Loop 
e740: 63 6f 75 6e 74 65 72 20 2a 2f 0a 20 20 76 6f 6c  counter */.  vol
e750: 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66  atile WalCkptInf
e760: 6f 20 2a 70 49 6e 66 6f 3b 20 20 20 20 2f 2a 20  o *pInfo;    /* 
e770: 54 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 73  The checkpoint s
e780: 74 61 74 75 73 20 69 6e 66 6f 72 6d 61 74 69 6f  tatus informatio
e790: 6e 20 2a 2f 0a 0a 20 20 69 66 28 20 70 57 61 6c  n */..  if( pWal
e7a0: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 30  ->hdr.mxFrame==0
e7b0: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
e7c0: 5f 4f 4b 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63  _OK;..  /* Alloc
e7d0: 61 74 65 20 74 68 65 20 69 74 65 72 61 74 6f 72  ate the iterator
e7e0: 20 2a 2f 0a 20 20 72 63 20 3d 20 77 61 6c 49 74   */.  rc = walIt
e7f0: 65 72 61 74 6f 72 49 6e 69 74 28 70 57 61 6c 2c  eratorInit(pWal,
e800: 20 26 70 49 74 65 72 29 3b 0a 20 20 69 66 28 20   &pIter);.  if( 
e810: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
e820: 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
e830: 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20 70 49    }.  assert( pI
e840: 74 65 72 20 29 3b 0a 0a 20 20 2f 2a 2a 2a 20 54  ter );..  /*** T
e850: 4f 44 4f 3a 20 20 4d 6f 76 65 20 74 68 69 73 20  ODO:  Move this 
e860: 74 65 73 74 20 6f 75 74 20 74 6f 20 74 68 65 20  test out to the 
e870: 63 61 6c 6c 65 72 2e 20 20 4d 61 6b 65 20 69 74  caller.  Make it
e880: 20 61 6e 20 61 73 73 65 72 74 28 29 20 68 65 72   an assert() her
e890: 65 20 2a 2a 2a 2f 0a 20 20 69 66 28 20 70 57 61  e ***/.  if( pWa
e8a0: 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 21 3d 6e  l->hdr.szPage!=n
e8b0: 42 75 66 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  Buf ){.    rc = 
e8c0: 53 51 4c 49 54 45 5f 43 4f 52 52 55 50 54 5f 42  SQLITE_CORRUPT_B
e8d0: 4b 50 54 3b 0a 20 20 20 20 67 6f 74 6f 20 77 61  KPT;.    goto wa
e8e0: 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74 3b  lcheckpoint_out;
e8f0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6d 70 75  .  }..  /* Compu
e900: 74 65 20 69 6e 20 6d 78 53 61 66 65 46 72 61 6d  te in mxSafeFram
e910: 65 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74  e the index of t
e920: 68 65 20 6c 61 73 74 20 66 72 61 6d 65 20 6f 66  he last frame of
e930: 20 74 68 65 20 57 41 4c 20 74 68 61 74 20 69 73   the WAL that is
e940: 0a 20 20 2a 2a 20 73 61 66 65 20 74 6f 20 77 72  .  ** safe to wr
e950: 69 74 65 20 69 6e 74 6f 20 74 68 65 20 64 61 74  ite into the dat
e960: 61 62 61 73 65 2e 20 20 46 72 61 6d 65 73 20 62  abase.  Frames b
e970: 65 79 6f 6e 64 20 6d 78 53 61 66 65 46 72 61 6d  eyond mxSafeFram
e980: 65 20 6d 69 67 68 74 0a 20 20 2a 2a 20 6f 76 65  e might.  ** ove
e990: 72 77 72 69 74 65 20 64 61 74 61 62 61 73 65 20  rwrite database 
e9a0: 70 61 67 65 73 20 74 68 61 74 20 61 72 65 20 69  pages that are i
e9b0: 6e 20 75 73 65 20 62 79 20 61 63 74 69 76 65 20  n use by active 
e9c0: 72 65 61 64 65 72 73 20 61 6e 64 20 74 68 75 73  readers and thus
e9d0: 0a 20 20 2a 2a 20 63 61 6e 6e 6f 74 20 62 65 20  .  ** cannot be 
e9e0: 62 61 63 6b 66 69 6c 6c 65 64 20 66 72 6f 6d 20  backfilled from 
e9f0: 74 68 65 20 57 41 4c 2e 0a 20 20 2a 2f 0a 20 20  the WAL..  */.  
ea00: 6d 78 53 61 66 65 46 72 61 6d 65 20 3d 20 70 57  mxSafeFrame = pW
ea10: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b  al->hdr.mxFrame;
ea20: 0a 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b  .  pInfo = walCk
ea30: 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20  ptInfo(pWal);.  
ea40: 66 6f 72 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e  for(i=1; i<WAL_N
ea50: 52 45 41 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20  READER; i++){.  
ea60: 20 20 75 33 32 20 79 20 3d 20 70 49 6e 66 6f 2d    u32 y = pInfo-
ea70: 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20  >aReadMark[i];. 
ea80: 20 20 20 69 66 28 20 6d 78 53 61 66 65 46 72 61     if( mxSafeFra
ea90: 6d 65 3e 3d 79 20 29 7b 0a 20 20 20 20 20 20 61  me>=y ){.      a
eaa0: 73 73 65 72 74 28 20 79 3c 3d 70 57 61 6c 2d 3e  ssert( y<=pWal->
eab0: 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20  hdr.mxFrame );. 
eac0: 20 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63       rc = walLoc
ead0: 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
eae0: 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69   WAL_READ_LOCK(i
eaf0: 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 69 66 28  ), 1);.      if(
eb00: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
eb10: 7b 0a 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d  {.        pInfo-
eb20: 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 20 3d 20  >aReadMark[i] = 
eb30: 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45  READMARK_NOT_USE
eb40: 44 3b 0a 20 20 20 20 20 20 20 20 77 61 6c 55 6e  D;.        walUn
eb50: 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70 57  lockExclusive(pW
eb60: 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  al, WAL_READ_LOC
eb70: 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20 20 20 20  K(i), 1);.      
eb80: 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51  }else if( rc==SQ
eb90: 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
eba0: 20 20 20 20 20 6d 78 53 61 66 65 46 72 61 6d 65       mxSafeFrame
ebb0: 20 3d 20 79 3b 0a 20 20 20 20 20 20 7d 65 6c 73   = y;.      }els
ebc0: 65 7b 0a 20 20 20 20 20 20 20 20 67 6f 74 6f 20  e{.        goto 
ebd0: 77 61 6c 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75  walcheckpoint_ou
ebe0: 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  t;.      }.    }
ebf0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 49 6e 66  .  }..  if( pInf
ec00: 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3c 6d 78 53  o->nBackfill<mxS
ec10: 61 66 65 46 72 61 6d 65 0a 20 20 20 26 26 20 28  afeFrame.   && (
ec20: 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
ec30: 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
ec40: 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 31 29  READ_LOCK(0), 1)
ec50: 29 3d 3d 53 51 4c 49 54 45 5f 4f 4b 0a 20 20 29  )==SQLITE_OK.  )
ec60: 7b 0a 20 20 20 20 75 33 32 20 6e 42 61 63 6b 66  {.    u32 nBackf
ec70: 69 6c 6c 20 3d 20 70 49 6e 66 6f 2d 3e 6e 42 61  ill = pInfo->nBa
ec80: 63 6b 66 69 6c 6c 3b 0a 0a 20 20 20 20 2f 2a 20  ckfill;..    /* 
ec90: 53 79 6e 63 20 74 68 65 20 57 41 4c 20 74 6f 20  Sync the WAL to 
eca0: 64 69 73 6b 20 2a 2f 0a 20 20 20 20 69 66 28 20  disk */.    if( 
ecb0: 73 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a 20 20  sync_flags ){.  
ecc0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
ecd0: 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57 61  OsSync(pWal->pWa
ece0: 6c 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73 29  lFd, sync_flags)
ecf0: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
ed00: 49 74 65 72 61 74 65 20 74 68 72 6f 75 67 68 20  Iterate through 
ed10: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
ed20: 74 68 65 20 57 41 4c 2c 20 63 6f 70 79 69 6e 67  the WAL, copying
ed30: 20 64 61 74 61 20 74 6f 20 74 68 65 20 64 62 20   data to the db 
ed40: 66 69 6c 65 2e 20 2a 2f 0a 20 20 20 20 77 68 69  file. */.    whi
ed50: 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  le( rc==SQLITE_O
ed60: 4b 20 26 26 20 30 3d 3d 77 61 6c 49 74 65 72 61  K && 0==walItera
ed70: 74 6f 72 4e 65 78 74 28 70 49 74 65 72 2c 20 26  torNext(pIter, &
ed80: 69 44 62 70 61 67 65 2c 20 26 69 46 72 61 6d 65  iDbpage, &iFrame
ed90: 29 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72  ) ){.      asser
eda0: 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28  t( walFramePgno(
edb0: 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 3d 3d 69  pWal, iFrame)==i
edc0: 44 62 70 61 67 65 20 29 3b 0a 20 20 20 20 20 20  Dbpage );.      
edd0: 69 66 28 20 69 46 72 61 6d 65 3c 3d 6e 42 61 63  if( iFrame<=nBac
ede0: 6b 66 69 6c 6c 20 7c 7c 20 69 46 72 61 6d 65 3e  kfill || iFrame>
edf0: 6d 78 53 61 66 65 46 72 61 6d 65 20 29 20 63 6f  mxSafeFrame ) co
ee00: 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 72 63  ntinue;.      rc
ee10: 20 3d 20 73 71 6c 69 74 65 33 4f 73 52 65 61 64   = sqlite3OsRead
ee20: 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 7a  (pWal->pWalFd, z
ee30: 42 75 66 2c 20 73 7a 50 61 67 65 2c 20 0a 20 20  Buf, szPage, .  
ee40: 20 20 20 20 20 20 20 20 77 61 6c 46 72 61 6d 65          walFrame
ee50: 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2c 20 73  Offset(iFrame, s
ee60: 7a 50 61 67 65 29 20 2b 20 57 41 4c 5f 46 52 41  zPage) + WAL_FRA
ee70: 4d 45 5f 48 44 52 53 49 5a 45 0a 20 20 20 20 20  ME_HDRSIZE.     
ee80: 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63   );.      if( rc
ee90: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72  !=SQLITE_OK ) br
eea0: 65 61 6b 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  eak;.      rc = 
eeb0: 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70  sqlite3OsWrite(p
eec0: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 7a 42 75 66  Wal->pDbFd, zBuf
eed0: 2c 20 73 7a 50 61 67 65 2c 20 28 69 44 62 70 61  , szPage, (iDbpa
eee0: 67 65 2d 31 29 2a 73 7a 50 61 67 65 29 3b 0a 20  ge-1)*szPage);. 
eef0: 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c       if( rc!=SQL
ef00: 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a  ITE_OK ) break;.
ef10: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66      }..    /* If
ef20: 20 77 6f 72 6b 20 77 61 73 20 61 63 74 75 61 6c   work was actual
ef30: 6c 79 20 61 63 63 6f 6d 70 6c 69 73 68 65 64 2e  ly accomplished.
ef40: 2e 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 72 63  .. */.    if( rc
ef50: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
ef60: 20 20 20 20 20 69 66 28 20 6d 78 53 61 66 65 46       if( mxSafeF
ef70: 72 61 6d 65 3d 3d 77 61 6c 49 6e 64 65 78 48 64  rame==walIndexHd
ef80: 72 28 70 57 61 6c 29 2d 3e 6d 78 46 72 61 6d 65  r(pWal)->mxFrame
ef90: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
efa0: 20 73 71 6c 69 74 65 33 4f 73 54 72 75 6e 63 61   sqlite3OsTrunca
efb0: 74 65 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20  te(pWal->pDbFd, 
efc0: 28 28 69 36 34 29 70 57 61 6c 2d 3e 68 64 72 2e  ((i64)pWal->hdr.
efd0: 6e 50 61 67 65 2a 28 69 36 34 29 73 7a 50 61 67  nPage*(i64)szPag
efe0: 65 29 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  e));.        if(
eff0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
f000: 26 20 73 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a  & sync_flags ){.
f010: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 73            rc = s
f020: 71 6c 69 74 65 33 4f 73 53 79 6e 63 28 70 57 61  qlite3OsSync(pWa
f030: 6c 2d 3e 70 44 62 46 64 2c 20 73 79 6e 63 5f 66  l->pDbFd, sync_f
f040: 6c 61 67 73 29 3b 0a 20 20 20 20 20 20 20 20 7d  lags);.        }
f050: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
f060: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
f070: 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49 6e 66   ){.        pInf
f080: 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 20 3d 20 6d  o->nBackfill = m
f090: 78 53 61 66 65 46 72 61 6d 65 3b 0a 20 20 20 20  xSafeFrame;.    
f0a0: 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f    }.    }..    /
f0b0: 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20 72 65  * Release the re
f0c0: 61 64 65 72 20 6c 6f 63 6b 20 68 65 6c 64 20 77  ader lock held w
f0d0: 68 69 6c 65 20 62 61 63 6b 66 69 6c 6c 69 6e 67  hile backfilling
f0e0: 20 2a 2f 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63   */.    walUnloc
f0f0: 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
f100: 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30   WAL_READ_LOCK(0
f110: 29 2c 20 31 29 3b 0a 20 20 7d 65 6c 73 65 20 69  ), 1);.  }else i
f120: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  f( rc==SQLITE_BU
f130: 53 59 20 29 7b 0a 20 20 20 20 2f 2a 20 52 65 73  SY ){.    /* Res
f140: 65 74 20 74 68 65 20 72 65 74 75 72 6e 20 63 6f  et the return co
f150: 64 65 20 73 6f 20 61 73 20 6e 6f 74 20 74 6f 20  de so as not to 
f160: 72 65 70 6f 72 74 20 61 20 63 68 65 63 6b 70 6f  report a checkpo
f170: 69 6e 74 20 66 61 69 6c 75 72 65 0a 20 20 20 20  int failure.    
f180: 2a 2a 20 6a 75 73 74 20 62 65 63 61 75 73 65 20  ** just because 
f190: 61 63 74 69 76 65 20 72 65 61 64 65 72 73 20 70  active readers p
f1a0: 72 65 76 65 6e 74 20 61 6e 79 20 62 61 63 6b 66  revent any backf
f1b0: 69 6c 6c 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ill..    */.    
f1c0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
f1d0: 20 20 7d 0a 0a 20 77 61 6c 63 68 65 63 6b 70 6f    }.. walcheckpo
f1e0: 69 6e 74 5f 6f 75 74 3a 0a 20 20 77 61 6c 49 74  int_out:.  walIt
f1f0: 65 72 61 74 6f 72 46 72 65 65 28 70 49 74 65 72  eratorFree(pIter
f200: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
f210: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61  }../*.** Close a
f220: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 61   connection to a
f230: 20 6c 6f 67 20 66 69 6c 65 2e 0a 2a 2f 0a 69 6e   log file..*/.in
f240: 74 20 73 71 6c 69 74 65 33 57 61 6c 43 6c 6f 73  t sqlite3WalClos
f250: 65 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20  e(.  Wal *pWal, 
f260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f270: 20 20 20 20 20 2f 2a 20 57 61 6c 20 74 6f 20 63       /* Wal to c
f280: 6c 6f 73 65 20 2a 2f 0a 20 20 69 6e 74 20 73 79  lose */.  int sy
f290: 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20 20  nc_flags,       
f2a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61            /* Fla
f2b0: 67 73 20 74 6f 20 70 61 73 73 20 74 6f 20 4f 73  gs to pass to Os
f2c0: 53 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f  Sync() (or 0) */
f2d0: 0a 20 20 69 6e 74 20 6e 42 75 66 2c 0a 20 20 75  .  int nBuf,.  u
f2e0: 38 20 2a 7a 42 75 66 20 20 20 20 20 20 20 20 20  8 *zBuf         
f2f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
f300: 2a 20 42 75 66 66 65 72 20 6f 66 20 61 74 20 6c  * Buffer of at l
f310: 65 61 73 74 20 6e 42 75 66 20 62 79 74 65 73 20  east nBuf bytes 
f320: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  */.){.  int rc =
f330: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66   SQLITE_OK;.  if
f340: 28 20 70 57 61 6c 20 29 7b 0a 20 20 20 20 69 6e  ( pWal ){.    in
f350: 74 20 69 73 44 65 6c 65 74 65 20 3d 20 30 3b 20  t isDelete = 0; 
f360: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
f370: 72 75 65 20 74 6f 20 75 6e 6c 69 6e 6b 20 77 61  rue to unlink wa
f380: 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20  l and wal-index 
f390: 66 69 6c 65 73 20 2a 2f 0a 0a 20 20 20 20 2f 2a  files */..    /*
f3a0: 20 49 66 20 61 6e 20 45 58 43 4c 55 53 49 56 45   If an EXCLUSIVE
f3b0: 20 6c 6f 63 6b 20 63 61 6e 20 62 65 20 6f 62 74   lock can be obt
f3c0: 61 69 6e 65 64 20 6f 6e 20 74 68 65 20 64 61 74  ained on the dat
f3d0: 61 62 61 73 65 20 66 69 6c 65 20 28 75 73 69 6e  abase file (usin
f3e0: 67 20 74 68 65 0a 20 20 20 20 2a 2a 20 6f 72 64  g the.    ** ord
f3f0: 69 6e 61 72 79 2c 20 72 6f 6c 6c 62 61 63 6b 2d  inary, rollback-
f400: 6d 6f 64 65 20 6c 6f 63 6b 69 6e 67 20 6d 65 74  mode locking met
f410: 68 6f 64 73 2c 20 74 68 69 73 20 67 75 61 72 61  hods, this guara
f420: 6e 74 65 65 73 20 74 68 61 74 20 74 68 65 0a 20  ntees that the. 
f430: 20 20 20 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e     ** connection
f440: 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
f450: 20 74 68 69 73 20 6c 6f 67 20 66 69 6c 65 20 69   this log file i
f460: 73 20 74 68 65 20 6f 6e 6c 79 20 63 6f 6e 6e 65  s the only conne
f470: 63 74 69 6f 6e 20 74 6f 0a 20 20 20 20 2a 2a 20  ction to.    ** 
f480: 74 68 65 20 64 61 74 61 62 61 73 65 2e 20 49 6e  the database. In
f490: 20 74 68 69 73 20 63 61 73 65 20 63 68 65 63 6b   this case check
f4a0: 70 6f 69 6e 74 20 74 68 65 20 64 61 74 61 62 61  point the databa
f4b0: 73 65 20 61 6e 64 20 75 6e 6c 69 6e 6b 20 62 6f  se and unlink bo
f4c0: 74 68 0a 20 20 20 20 2a 2a 20 74 68 65 20 77 61  th.    ** the wa
f4d0: 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20  l and wal-index 
f4e0: 66 69 6c 65 73 2e 0a 20 20 20 20 2a 2a 0a 20 20  files..    **.  
f4f0: 20 20 2a 2a 20 54 68 65 20 45 58 43 4c 55 53 49    ** The EXCLUSI
f500: 56 45 20 6c 6f 63 6b 20 69 73 20 6e 6f 74 20 72  VE lock is not r
f510: 65 6c 65 61 73 65 64 20 62 65 66 6f 72 65 20 72  eleased before r
f520: 65 74 75 72 6e 69 6e 67 2e 0a 20 20 20 20 2a 2f  eturning..    */
f530: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
f540: 33 4f 73 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44  3OsLock(pWal->pD
f550: 62 46 64 2c 20 53 51 4c 49 54 45 5f 4c 4f 43 4b  bFd, SQLITE_LOCK
f560: 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20 20  _EXCLUSIVE);.   
f570: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
f580: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c  OK ){.      pWal
f590: 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20  ->exclusiveMode 
f5a0: 3d 20 31 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  = 1;.      rc = 
f5b0: 73 71 6c 69 74 65 33 57 61 6c 43 68 65 63 6b 70  sqlite3WalCheckp
f5c0: 6f 69 6e 74 28 70 57 61 6c 2c 20 73 79 6e 63 5f  oint(pWal, sync_
f5d0: 66 6c 61 67 73 2c 20 6e 42 75 66 2c 20 7a 42 75  flags, nBuf, zBu
f5e0: 66 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  f);.      if( rc
f5f0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
f600: 20 20 20 20 20 20 20 69 73 44 65 6c 65 74 65 20         isDelete 
f610: 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 1;.      }.   
f620: 20 7d 0a 0a 20 20 20 20 77 61 6c 49 6e 64 65 78   }..    walIndex
f630: 43 6c 6f 73 65 28 70 57 61 6c 2c 20 69 73 44 65  Close(pWal, isDe
f640: 6c 65 74 65 29 3b 0a 20 20 20 20 73 71 6c 69 74  lete);.    sqlit
f650: 65 33 4f 73 43 6c 6f 73 65 28 70 57 61 6c 2d 3e  e3OsClose(pWal->
f660: 70 57 61 6c 46 64 29 3b 0a 20 20 20 20 69 66 28  pWalFd);.    if(
f670: 20 69 73 44 65 6c 65 74 65 20 29 7b 0a 20 20 20   isDelete ){.   
f680: 20 20 20 73 71 6c 69 74 65 33 4f 73 44 65 6c 65     sqlite3OsDele
f690: 74 65 28 70 57 61 6c 2d 3e 70 56 66 73 2c 20 70  te(pWal->pVfs, p
f6a0: 57 61 6c 2d 3e 7a 57 61 6c 4e 61 6d 65 2c 20 30  Wal->zWalName, 0
f6b0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 57 41 4c  );.    }.    WAL
f6c0: 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63  TRACE(("WAL%p: c
f6d0: 6c 6f 73 65 64 5c 6e 22 2c 20 70 57 61 6c 29 29  losed\n", pWal))
f6e0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
f6f0: 65 65 28 28 76 6f 69 64 20 2a 29 70 57 61 6c 2d  ee((void *)pWal-
f700: 3e 61 70 57 69 44 61 74 61 29 3b 0a 20 20 20 20  >apWiData);.    
f710: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 57 61  sqlite3_free(pWa
f720: 6c 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  l);.  }.  return
f730: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72   rc;.}../*.** Tr
f740: 79 20 74 6f 20 72 65 61 64 20 74 68 65 20 77 61  y to read the wa
f750: 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 2e 20  l-index header. 
f760: 20 52 65 74 75 72 6e 20 30 20 6f 6e 20 73 75 63   Return 0 on suc
f770: 63 65 73 73 20 61 6e 64 20 31 20 69 66 0a 2a 2a  cess and 1 if.**
f780: 20 74 68 65 72 65 20 69 73 20 61 20 70 72 6f 62   there is a prob
f790: 6c 65 6d 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 77  lem..**.** The w
f7a0: 61 6c 2d 69 6e 64 65 78 20 69 73 20 69 6e 20 73  al-index is in s
f7b0: 68 61 72 65 64 20 6d 65 6d 6f 72 79 2e 20 20 41  hared memory.  A
f7c0: 6e 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f 72  nother thread or
f7d0: 20 70 72 6f 63 65 73 73 20 6d 69 67 68 74 0a 2a   process might.*
f7e0: 2a 20 62 65 20 77 72 69 74 69 6e 67 20 74 68 65  * be writing the
f7f0: 20 68 65 61 64 65 72 20 61 74 20 74 68 65 20 73   header at the s
f800: 61 6d 65 20 74 69 6d 65 20 74 68 69 73 20 70 72  ame time this pr
f810: 6f 63 65 64 75 72 65 20 69 73 20 74 72 79 69 6e  ocedure is tryin
f820: 67 20 74 6f 0a 2a 2a 20 72 65 61 64 20 69 74 2c  g to.** read it,
f830: 20 77 68 69 63 68 20 6d 69 67 68 74 20 72 65 73   which might res
f840: 75 6c 74 20 69 6e 20 69 6e 63 6f 6e 73 69 73 74  ult in inconsist
f850: 65 6e 63 79 2e 20 20 41 20 64 69 72 74 79 20 72  ency.  A dirty r
f860: 65 61 64 20 69 73 20 64 65 74 65 63 74 65 64 0a  ead is detected.
f870: 2a 2a 20 62 79 20 76 65 72 69 66 79 69 6e 67 20  ** by verifying 
f880: 74 68 61 74 20 62 6f 74 68 20 63 6f 70 69 65 73  that both copies
f890: 20 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 61   of the header a
f8a0: 72 65 20 74 68 65 20 73 61 6d 65 20 61 6e 64 20  re the same and 
f8b0: 61 6c 73 6f 20 62 79 0a 2a 2a 20 61 20 63 68 65  also by.** a che
f8c0: 63 6b 73 75 6d 20 6f 6e 20 74 68 65 20 68 65 61  cksum on the hea
f8d0: 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e  der..**.** If an
f8e0: 64 20 6f 6e 6c 79 20 69 66 20 74 68 65 20 72 65  d only if the re
f8f0: 61 64 20 69 73 20 63 6f 6e 73 69 73 74 65 6e 74  ad is consistent
f900: 20 61 6e 64 20 74 68 65 20 68 65 61 64 65 72 20   and the header 
f910: 69 73 20 64 69 66 66 65 72 65 6e 74 20 66 72 6f  is different fro
f920: 6d 0a 2a 2a 20 70 57 61 6c 2d 3e 68 64 72 2c 20  m.** pWal->hdr, 
f930: 74 68 65 6e 20 70 57 61 6c 2d 3e 68 64 72 20 69  then pWal->hdr i
f940: 73 20 75 70 64 61 74 65 64 20 74 6f 20 74 68 65  s updated to the
f950: 20 63 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65 20   content of the 
f960: 6e 65 77 20 68 65 61 64 65 72 0a 2a 2a 20 61 6e  new header.** an
f970: 64 20 2a 70 43 68 61 6e 67 65 64 20 69 73 20 73  d *pChanged is s
f980: 65 74 20 74 6f 20 31 2e 0a 2a 2a 0a 2a 2a 20 49  et to 1..**.** I
f990: 66 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 63  f the checksum c
f9a0: 61 6e 6e 6f 74 20 62 65 20 76 65 72 69 66 69 65  annot be verifie
f9b0: 64 20 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72  d return non-zer
f9c0: 6f 2e 20 49 66 20 74 68 65 20 68 65 61 64 65 72  o. If the header
f9d0: 0a 2a 2a 20 69 73 20 72 65 61 64 20 73 75 63 63  .** is read succ
f9e0: 65 73 73 66 75 6c 6c 79 20 61 6e 64 20 74 68 65  essfully and the
f9f0: 20 63 68 65 63 6b 73 75 6d 20 76 65 72 69 66 69   checksum verifi
fa00: 65 64 2c 20 72 65 74 75 72 6e 20 7a 65 72 6f 2e  ed, return zero.
fa10: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
fa20: 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28 57 61  alIndexTryHdr(Wa
fa30: 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43  l *pWal, int *pC
fa40: 68 61 6e 67 65 64 29 7b 0a 20 20 75 33 32 20 61  hanged){.  u32 a
fa50: 43 6b 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20  Cksum[2];       
fa60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68             /* Ch
fa70: 65 63 6b 73 75 6d 20 6f 6e 20 74 68 65 20 68 65  ecksum on the he
fa80: 61 64 65 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a  ader content */.
fa90: 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20 68 31    WalIndexHdr h1
faa0: 2c 20 68 32 3b 20 20 20 20 20 20 20 20 20 20 20  , h2;           
fab0: 20 20 2f 2a 20 54 77 6f 20 63 6f 70 69 65 73 20    /* Two copies 
fac0: 6f 66 20 74 68 65 20 68 65 61 64 65 72 20 63 6f  of the header co
fad0: 6e 74 65 6e 74 20 2a 2f 0a 20 20 57 61 6c 49 6e  ntent */.  WalIn
fae0: 64 65 78 48 64 72 20 76 6f 6c 61 74 69 6c 65 20  dexHdr volatile 
faf0: 2a 61 48 64 72 3b 20 20 20 20 20 2f 2a 20 48 65  *aHdr;     /* He
fb00: 61 64 65 72 20 69 6e 20 73 68 61 72 65 64 20 6d  ader in shared m
fb10: 65 6d 6f 72 79 20 2a 2f 0a 0a 20 20 2f 2a 20 54  emory */..  /* T
fb20: 68 65 20 66 69 72 73 74 20 70 61 67 65 20 6f 66  he first page of
fb30: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 6d   the wal-index m
fb40: 75 73 74 20 62 65 20 6d 61 70 70 65 64 20 61 74  ust be mapped at
fb50: 20 74 68 69 73 20 70 6f 69 6e 74 2e 20 2a 2f 0a   this point. */.
fb60: 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
fb70: 6e 57 69 44 61 74 61 3e 30 20 26 26 20 70 57 61  nWiData>0 && pWa
fb80: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 30 5d 20 29  l->apWiData[0] )
fb90: 3b 0a 0a 20 20 2f 2a 20 52 65 61 64 20 74 68 65  ;..  /* Read the
fba0: 20 68 65 61 64 65 72 2e 20 54 68 69 73 20 6d 69   header. This mi
fbb0: 67 68 74 20 68 61 70 70 65 6e 20 63 75 72 72 65  ght happen curre
fbc0: 6e 74 6c 79 20 77 69 74 68 20 61 20 77 72 69 74  ntly with a writ
fbd0: 65 20 74 6f 20 74 68 65 0a 20 20 2a 2a 20 73 61  e to the.  ** sa
fbe0: 6d 65 20 61 72 65 61 20 6f 66 20 73 68 61 72 65  me area of share
fbf0: 64 20 6d 65 6d 6f 72 79 20 6f 6e 20 61 20 64 69  d memory on a di
fc00: 66 66 65 72 65 6e 74 20 43 50 55 20 69 6e 20 61  fferent CPU in a
fc10: 20 53 4d 50 2c 0a 20 20 2a 2a 20 6d 65 61 6e 69   SMP,.  ** meani
fc20: 6e 67 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c  ng it is possibl
fc30: 65 20 74 68 61 74 20 61 6e 20 69 6e 63 6f 6e 73  e that an incons
fc40: 69 73 74 65 6e 74 20 73 6e 61 70 73 68 6f 74 20  istent snapshot 
fc50: 69 73 20 72 65 61 64 0a 20 20 2a 2a 20 66 72 6f  is read.  ** fro
fc60: 6d 20 74 68 65 20 66 69 6c 65 2e 20 49 66 20 74  m the file. If t
fc70: 68 69 73 20 68 61 70 70 65 6e 73 2c 20 72 65 74  his happens, ret
fc80: 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 20 20  urn non-zero..  
fc90: 2a 2a 0a 20 20 2a 2a 20 54 68 65 72 65 20 61 72  **.  ** There ar
fca0: 65 20 74 77 6f 20 63 6f 70 69 65 73 20 6f 66 20  e two copies of 
fcb0: 74 68 65 20 68 65 61 64 65 72 20 61 74 20 74 68  the header at th
fcc0: 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74  e beginning of t
fcd0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 20 20  he wal-index..  
fce0: 2a 2a 20 57 68 65 6e 20 72 65 61 64 69 6e 67 2c  ** When reading,
fcf0: 20 72 65 61 64 20 5b 30 5d 20 66 69 72 73 74 20   read [0] first 
fd00: 74 68 65 6e 20 5b 31 5d 2e 20 20 57 72 69 74 65  then [1].  Write
fd10: 73 20 61 72 65 20 69 6e 20 74 68 65 20 72 65 76  s are in the rev
fd20: 65 72 73 65 20 6f 72 64 65 72 2e 0a 20 20 2a 2a  erse order..  **
fd30: 20 4d 65 6d 6f 72 79 20 62 61 72 72 69 65 72 73   Memory barriers
fd40: 20 61 72 65 20 75 73 65 64 20 74 6f 20 70 72 65   are used to pre
fd50: 76 65 6e 74 20 74 68 65 20 63 6f 6d 70 69 6c 65  vent the compile
fd60: 72 20 6f 72 20 74 68 65 20 68 61 72 64 77 61 72  r or the hardwar
fd70: 65 20 66 72 6f 6d 0a 20 20 2a 2a 20 72 65 6f 72  e from.  ** reor
fd80: 64 65 72 69 6e 67 20 74 68 65 20 72 65 61 64 73  dering the reads
fd90: 20 61 6e 64 20 77 72 69 74 65 73 2e 0a 20 20 2a   and writes..  *
fda0: 2f 0a 20 20 61 48 64 72 20 3d 20 77 61 6c 49 6e  /.  aHdr = walIn
fdb0: 64 65 78 48 64 72 28 70 57 61 6c 29 3b 0a 20 20  dexHdr(pWal);.  
fdc0: 6d 65 6d 63 70 79 28 26 68 31 2c 20 28 76 6f 69  memcpy(&h1, (voi
fdd0: 64 20 2a 29 26 61 48 64 72 5b 30 5d 2c 20 73 69  d *)&aHdr[0], si
fde0: 7a 65 6f 66 28 68 31 29 29 3b 0a 20 20 73 71 6c  zeof(h1));.  sql
fdf0: 69 74 65 33 4f 73 53 68 6d 42 61 72 72 69 65 72  ite3OsShmBarrier
fe00: 28 70 57 61 6c 2d 3e 70 44 62 46 64 29 3b 0a 20  (pWal->pDbFd);. 
fe10: 20 6d 65 6d 63 70 79 28 26 68 32 2c 20 28 76 6f   memcpy(&h2, (vo
fe20: 69 64 20 2a 29 26 61 48 64 72 5b 31 5d 2c 20 73  id *)&aHdr[1], s
fe30: 69 7a 65 6f 66 28 68 32 29 29 3b 0a 0a 20 20 69  izeof(h2));..  i
fe40: 66 28 20 6d 65 6d 63 6d 70 28 26 68 31 2c 20 26  f( memcmp(&h1, &
fe50: 68 32 2c 20 73 69 7a 65 6f 66 28 68 31 29 29 21  h2, sizeof(h1))!
fe60: 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  =0 ){.    return
fe70: 20 31 3b 20 20 20 2f 2a 20 44 69 72 74 79 20 72   1;   /* Dirty r
fe80: 65 61 64 20 2a 2f 0a 20 20 7d 20 20 0a 20 20 69  ead */.  }  .  i
fe90: 66 28 20 68 31 2e 69 73 49 6e 69 74 3d 3d 30 20  f( h1.isInit==0 
fea0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b  ){.    return 1;
feb0: 20 20 20 2f 2a 20 4d 61 6c 66 6f 72 6d 65 64 20     /* Malformed 
fec0: 68 65 61 64 65 72 20 2d 20 70 72 6f 62 61 62 6c  header - probabl
fed0: 79 20 61 6c 6c 20 7a 65 72 6f 73 20 2a 2f 0a 20  y all zeros */. 
fee0: 20 7d 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d   }.  walChecksum
fef0: 42 79 74 65 73 28 31 2c 20 28 75 38 2a 29 26 68  Bytes(1, (u8*)&h
ff00: 31 2c 20 73 69 7a 65 6f 66 28 68 31 29 2d 73 69  1, sizeof(h1)-si
ff10: 7a 65 6f 66 28 68 31 2e 61 43 6b 73 75 6d 29 2c  zeof(h1.aCksum),
ff20: 20 30 2c 20 61 43 6b 73 75 6d 29 3b 0a 20 20 69   0, aCksum);.  i
ff30: 66 28 20 61 43 6b 73 75 6d 5b 30 5d 21 3d 68 31  f( aCksum[0]!=h1
ff40: 2e 61 43 6b 73 75 6d 5b 30 5d 20 7c 7c 20 61 43  .aCksum[0] || aC
ff50: 6b 73 75 6d 5b 31 5d 21 3d 68 31 2e 61 43 6b 73  ksum[1]!=h1.aCks
ff60: 75 6d 5b 31 5d 20 29 7b 0a 20 20 20 20 72 65 74  um[1] ){.    ret
ff70: 75 72 6e 20 31 3b 20 20 20 2f 2a 20 43 68 65 63  urn 1;   /* Chec
ff80: 6b 73 75 6d 20 64 6f 65 73 20 6e 6f 74 20 6d 61  ksum does not ma
ff90: 74 63 68 20 2a 2f 0a 20 20 7d 0a 0a 20 20 69 66  tch */.  }..  if
ffa0: 28 20 6d 65 6d 63 6d 70 28 26 70 57 61 6c 2d 3e  ( memcmp(&pWal->
ffb0: 68 64 72 2c 20 26 68 31 2c 20 73 69 7a 65 6f 66  hdr, &h1, sizeof
ffc0: 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29 20 29  (WalIndexHdr)) )
ffd0: 7b 0a 20 20 20 20 2a 70 43 68 61 6e 67 65 64 20  {.    *pChanged 
ffe0: 3d 20 31 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28  = 1;.    memcpy(
fff0: 26 70 57 61 6c 2d 3e 68 64 72 2c 20 26 68 31 2c  &pWal->hdr, &h1,
10000 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
10010 48 64 72 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d  Hdr));.    pWal-
10020 3e 73 7a 50 61 67 65 20 3d 20 70 57 61 6c 2d 3e  >szPage = pWal->
10030 68 64 72 2e 73 7a 50 61 67 65 3b 0a 20 20 7d 0a  hdr.szPage;.  }.
10040 0a 20 20 2f 2a 20 54 68 65 20 68 65 61 64 65 72  .  /* The header
10050 20 77 61 73 20 73 75 63 63 65 73 73 66 75 6c 6c   was successfull
10060 79 20 72 65 61 64 2e 20 52 65 74 75 72 6e 20 7a  y read. Return z
10070 65 72 6f 2e 20 2a 2f 0a 20 20 72 65 74 75 72 6e  ero. */.  return
10080 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61   0;.}../*.** Rea
10090 64 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20  d the wal-index 
100a0 68 65 61 64 65 72 20 66 72 6f 6d 20 74 68 65 20  header from the 
100b0 77 61 6c 2d 69 6e 64 65 78 20 61 6e 64 20 69 6e  wal-index and in
100c0 74 6f 20 70 57 61 6c 2d 3e 68 64 72 2e 0a 2a 2a  to pWal->hdr..**
100d0 20 49 66 20 74 68 65 20 77 61 6c 2d 68 65 61 64   If the wal-head
100e0 65 72 20 61 70 70 65 61 72 73 20 74 6f 20 62 65  er appears to be
100f0 20 63 6f 72 72 75 70 74 2c 20 74 72 79 20 74 6f   corrupt, try to
10100 20 72 65 63 6f 6e 73 74 72 75 63 74 20 74 68 65   reconstruct the
10110 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 66 72  .** wal-index fr
10120 6f 6d 20 74 68 65 20 57 41 4c 20 62 65 66 6f 72  om the WAL befor
10130 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a 2a 2a 0a  e returning..**.
10140 2a 2a 20 53 65 74 20 2a 70 43 68 61 6e 67 65 64  ** Set *pChanged
10150 20 74 6f 20 31 20 69 66 20 74 68 65 20 77 61 6c   to 1 if the wal
10160 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 76 61  -index header va
10170 6c 75 65 20 69 6e 20 70 57 61 6c 2d 3e 68 64 72  lue in pWal->hdr
10180 20 69 73 0a 2a 2a 20 63 68 61 6e 67 65 64 20 62   is.** changed b
10190 79 20 74 68 69 73 20 6f 70 65 72 74 69 6f 6e 2e  y this opertion.
101a0 20 20 49 66 20 70 57 61 6c 2d 3e 68 64 72 20 69    If pWal->hdr i
101b0 73 20 75 6e 63 68 61 6e 67 65 64 2c 20 73 65 74  s unchanged, set
101c0 20 2a 70 43 68 61 6e 67 65 64 0a 2a 2a 20 74 6f   *pChanged.** to
101d0 20 30 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65   0..**.** If the
101e0 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
101f0 72 20 69 73 20 73 75 63 63 65 73 73 66 75 6c 6c  r is successfull
10200 79 20 72 65 61 64 2c 20 72 65 74 75 72 6e 20 53  y read, return S
10210 51 4c 49 54 45 5f 4f 4b 2e 20 0a 2a 2a 20 4f 74  QLITE_OK. .** Ot
10220 68 65 72 77 69 73 65 20 61 6e 20 53 51 4c 69 74  herwise an SQLit
10230 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a 2f  e error code..*/
10240 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49  .static int walI
10250 6e 64 65 78 52 65 61 64 48 64 72 28 57 61 6c 20  ndexReadHdr(Wal 
10260 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61  *pWal, int *pCha
10270 6e 67 65 64 29 7b 0a 20 20 69 6e 74 20 72 63 3b  nged){.  int rc;
10280 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10290 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75           /* Retu
102a0 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74  rn code */.  int
102b0 20 62 61 64 48 64 72 3b 20 20 20 20 20 20 20 20   badHdr;        
102c0 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
102d0 54 72 75 65 20 69 66 20 61 20 68 65 61 64 65 72  True if a header
102e0 20 72 65 61 64 20 66 61 69 6c 65 64 20 2a 2f 0a   read failed */.
102f0 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a    volatile u32 *
10300 70 61 67 65 30 3b 20 20 20 20 20 20 20 20 20 20  page0;          
10310 20 20 2f 2a 20 43 68 75 6e 6b 20 6f 66 20 77 61    /* Chunk of wa
10320 6c 2d 69 6e 64 65 78 20 63 6f 6e 74 61 69 6e 69  l-index containi
10330 6e 67 20 68 65 61 64 65 72 20 2a 2f 0a 0a 20 20  ng header */..  
10340 2f 2a 20 45 6e 73 75 72 65 20 74 68 61 74 20 70  /* Ensure that p
10350 61 67 65 20 30 20 6f 66 20 74 68 65 20 77 61 6c  age 0 of the wal
10360 2d 69 6e 64 65 78 20 28 74 68 65 20 70 61 67 65  -index (the page
10370 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73 20 74   that contains t
10380 68 65 20 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64  he .  ** wal-ind
10390 65 78 20 68 65 61 64 65 72 29 20 69 73 20 6d 61  ex header) is ma
103a0 70 70 65 64 2e 20 52 65 74 75 72 6e 20 65 61 72  pped. Return ear
103b0 6c 79 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f  ly if an error o
103c0 63 63 75 72 73 20 68 65 72 65 2e 0a 20 20 2a 2f  ccurs here..  */
103d0 0a 20 20 61 73 73 65 72 74 28 20 70 43 68 61 6e  .  assert( pChan
103e0 67 65 64 20 29 3b 0a 20 20 72 63 20 3d 20 77 61  ged );.  rc = wa
103f0 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c  lIndexPage(pWal,
10400 20 30 2c 20 26 70 61 67 65 30 29 3b 0a 20 20 69   0, &page0);.  i
10410 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
10420 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72   ){.    return r
10430 63 3b 0a 20 20 7d 3b 0a 20 20 61 73 73 65 72 74  c;.  };.  assert
10440 28 20 70 61 67 65 30 20 7c 7c 20 70 57 61 6c 2d  ( page0 || pWal-
10450 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b  >writeLock==0 );
10460 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69  ..  /* If the fi
10470 72 73 74 20 70 61 67 65 20 6f 66 20 74 68 65 20  rst page of the 
10480 77 61 6c 2d 69 6e 64 65 78 20 68 61 73 20 62 65  wal-index has be
10490 65 6e 20 6d 61 70 70 65 64 2c 20 74 72 79 20 74  en mapped, try t
104a0 6f 20 72 65 61 64 20 74 68 65 0a 20 20 2a 2a 20  o read the.  ** 
104b0 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
104c0 20 69 6d 6d 65 64 69 61 74 65 6c 79 2c 20 77 69   immediately, wi
104d0 74 68 6f 75 74 20 68 6f 6c 64 69 6e 67 20 61 6e  thout holding an
104e0 79 20 6c 6f 63 6b 2e 20 54 68 69 73 20 75 73 75  y lock. This usu
104f0 61 6c 6c 79 0a 20 20 2a 2a 20 77 6f 72 6b 73 2c  ally.  ** works,
10500 20 62 75 74 20 6d 61 79 20 66 61 69 6c 20 69 66   but may fail if
10510 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
10520 65 61 64 65 72 20 69 73 20 63 6f 72 72 75 70 74  eader is corrupt
10530 20 6f 72 20 63 75 72 72 65 6e 74 6c 79 20 0a 20   or currently . 
10540 20 2a 2a 20 62 65 69 6e 67 20 6d 6f 64 69 66 69   ** being modifi
10550 65 64 20 62 79 20 61 6e 6f 74 68 65 72 20 74 68  ed by another th
10560 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 2e  read or process.
10570 0a 20 20 2a 2f 0a 20 20 62 61 64 48 64 72 20 3d  .  */.  badHdr =
10580 20 28 70 61 67 65 30 20 3f 20 77 61 6c 49 6e 64   (page0 ? walInd
10590 65 78 54 72 79 48 64 72 28 70 57 61 6c 2c 20 70  exTryHdr(pWal, p
105a0 43 68 61 6e 67 65 64 29 20 3a 20 31 29 3b 0a 0a  Changed) : 1);..
105b0 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72 73    /* If the firs
105c0 74 20 61 74 74 65 6d 70 74 20 66 61 69 6c 65 64  t attempt failed
105d0 2c 20 69 74 20 6d 69 67 68 74 20 68 61 76 65 20  , it might have 
105e0 62 65 65 6e 20 64 75 65 20 74 6f 20 61 20 72 61  been due to a ra
105f0 63 65 0a 20 20 2a 2a 20 77 69 74 68 20 61 20 77  ce.  ** with a w
10600 72 69 74 65 72 2e 20 20 53 6f 20 67 65 74 20 61  riter.  So get a
10610 20 57 52 49 54 45 20 6c 6f 63 6b 20 61 6e 64 20   WRITE lock and 
10620 74 72 79 20 61 67 61 69 6e 2e 0a 20 20 2a 2f 0a  try again..  */.
10630 20 20 61 73 73 65 72 74 28 20 62 61 64 48 64 72    assert( badHdr
10640 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 77 72 69  ==0 || pWal->wri
10650 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 69  teLock==0 );.  i
10660 66 28 20 62 61 64 48 64 72 20 26 26 20 53 51 4c  f( badHdr && SQL
10670 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61  ITE_OK==(rc = wa
10680 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  lLockExclusive(p
10690 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c  Wal, WAL_WRITE_L
106a0 4f 43 4b 2c 20 31 29 29 20 29 7b 0a 20 20 20 20  OCK, 1)) ){.    
106b0 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
106c0 3d 20 31 3b 0a 20 20 20 20 69 66 28 20 53 51 4c  = 1;.    if( SQL
106d0 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61  ITE_OK==(rc = wa
106e0 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c  lIndexPage(pWal,
106f0 20 30 2c 20 26 70 61 67 65 30 29 29 20 29 7b 0a   0, &page0)) ){.
10700 20 20 20 20 20 20 62 61 64 48 64 72 20 3d 20 77        badHdr = w
10710 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28 70 57  alIndexTryHdr(pW
10720 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b 0a 20  al, pChanged);. 
10730 20 20 20 20 20 69 66 28 20 62 61 64 48 64 72 20       if( badHdr 
10740 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49 66  ){.        /* If
10750 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
10760 65 61 64 65 72 20 69 73 20 73 74 69 6c 6c 20 6d  eader is still m
10770 61 6c 66 6f 72 6d 65 64 20 65 76 65 6e 20 77 68  alformed even wh
10780 69 6c 65 20 68 6f 6c 64 69 6e 67 0a 20 20 20 20  ile holding.    
10790 20 20 20 20 2a 2a 20 61 20 57 52 49 54 45 20 6c      ** a WRITE l
107a0 6f 63 6b 2c 20 69 74 20 63 61 6e 20 6f 6e 6c 79  ock, it can only
107b0 20 6d 65 61 6e 20 74 68 61 74 20 74 68 65 20 68   mean that the h
107c0 65 61 64 65 72 20 69 73 20 63 6f 72 72 75 70 74  eader is corrupt
107d0 65 64 20 61 6e 64 0a 20 20 20 20 20 20 20 20 2a  ed and.        *
107e0 2a 20 6e 65 65 64 73 20 74 6f 20 62 65 20 72 65  * needs to be re
107f0 63 6f 6e 73 74 72 75 63 74 65 64 2e 20 20 53 6f  constructed.  So
10800 20 72 75 6e 20 72 65 63 6f 76 65 72 79 20 74 6f   run recovery to
10810 20 64 6f 20 65 78 61 63 74 6c 79 20 74 68 61 74   do exactly that
10820 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20  ..        */.   
10830 20 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64       rc = walInd
10840 65 78 52 65 63 6f 76 65 72 28 70 57 61 6c 29 3b  exRecover(pWal);
10850 0a 20 20 20 20 20 20 20 20 2a 70 43 68 61 6e 67  .        *pChang
10860 65 64 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a  ed = 1;.      }.
10870 20 20 20 20 7d 0a 20 20 20 20 70 57 61 6c 2d 3e      }.    pWal->
10880 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20  writeLock = 0;. 
10890 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c     walUnlockExcl
108a0 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
108b0 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  WRITE_LOCK, 1);.
108c0 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65    }..  /* If the
108d0 20 68 65 61 64 65 72 20 69 73 20 72 65 61 64 20   header is read 
108e0 73 75 63 63 65 73 73 66 75 6c 6c 79 2c 20 63 68  successfully, ch
108f0 65 63 6b 20 74 68 65 20 76 65 72 73 69 6f 6e 20  eck the version 
10900 6e 75 6d 62 65 72 20 74 6f 20 6d 61 6b 65 0a 20  number to make. 
10910 20 2a 2a 20 73 75 72 65 20 74 68 65 20 77 61 6c   ** sure the wal
10920 2d 69 6e 64 65 78 20 77 61 73 20 6e 6f 74 20 63  -index was not c
10930 6f 6e 73 74 72 75 63 74 65 64 20 77 69 74 68 20  onstructed with 
10940 73 6f 6d 65 20 66 75 74 75 72 65 20 66 6f 72 6d  some future form
10950 61 74 20 74 68 61 74 0a 20 20 2a 2a 20 74 68 69  at that.  ** thi
10960 73 20 76 65 72 73 69 6f 6e 20 6f 66 20 53 51 4c  s version of SQL
10970 69 74 65 20 63 61 6e 6e 6f 74 20 75 6e 64 65 72  ite cannot under
10980 73 74 61 6e 64 2e 0a 20 20 2a 2f 0a 20 20 69 66  stand..  */.  if
10990 28 20 62 61 64 48 64 72 3d 3d 30 20 26 26 20 70  ( badHdr==0 && p
109a0 57 61 6c 2d 3e 68 64 72 2e 69 56 65 72 73 69 6f  Wal->hdr.iVersio
109b0 6e 21 3d 57 41 4c 49 4e 44 45 58 5f 4d 41 58 5f  n!=WALINDEX_MAX_
109c0 56 45 52 53 49 4f 4e 20 29 7b 0a 20 20 20 20 72  VERSION ){.    r
109d0 63 20 3d 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f  c = SQLITE_CANTO
109e0 50 45 4e 5f 42 4b 50 54 3b 0a 20 20 7d 0a 0a 20  PEN_BKPT;.  }.. 
109f0 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
10a00 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65  *.** This is the
10a10 20 76 61 6c 75 65 20 74 68 61 74 20 77 61 6c 54   value that walT
10a20 72 79 42 65 67 69 6e 52 65 61 64 20 72 65 74 75  ryBeginRead retu
10a30 72 6e 73 20 77 68 65 6e 20 69 74 20 6e 65 65 64  rns when it need
10a40 73 20 74 6f 0a 2a 2a 20 62 65 20 72 65 74 72 69  s to.** be retri
10a50 65 64 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57  ed..*/.#define W
10a60 41 4c 5f 52 45 54 52 59 20 20 28 2d 31 29 0a 0a  AL_RETRY  (-1)..
10a70 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74 20 74 6f  /*.** Attempt to
10a80 20 73 74 61 72 74 20 61 20 72 65 61 64 20 74 72   start a read tr
10a90 61 6e 73 61 63 74 69 6f 6e 2e 20 20 54 68 69 73  ansaction.  This
10aa0 20 6d 69 67 68 74 20 66 61 69 6c 20 64 75 65 20   might fail due 
10ab0 74 6f 20 61 20 72 61 63 65 20 6f 72 0a 2a 2a 20  to a race or.** 
10ac0 6f 74 68 65 72 20 74 72 61 6e 73 69 65 6e 74 20  other transient 
10ad0 63 6f 6e 64 69 74 69 6f 6e 2e 20 20 57 68 65 6e  condition.  When
10ae0 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c 20 69   that happens, i
10af0 74 20 72 65 74 75 72 6e 73 20 57 41 4c 5f 52 45  t returns WAL_RE
10b00 54 52 59 20 74 6f 0a 2a 2a 20 69 6e 64 69 63 61  TRY to.** indica
10b10 74 65 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72  te to the caller
10b20 20 74 68 61 74 20 69 74 20 69 73 20 73 61 66 65   that it is safe
10b30 20 74 6f 20 72 65 74 72 79 20 69 6d 6d 65 64 69   to retry immedi
10b40 61 74 65 6c 79 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20  ately..**.** On 
10b50 73 75 63 63 65 73 73 20 72 65 74 75 72 6e 20 53  success return S
10b60 51 4c 49 54 45 5f 4f 4b 2e 20 20 4f 6e 20 61 20  QLITE_OK.  On a 
10b70 70 65 72 6d 61 6e 65 6e 74 20 66 61 69 6c 75 72  permanent failur
10b80 65 20 28 73 75 63 68 20 61 6e 0a 2a 2a 20 49 2f  e (such an.** I/
10b90 4f 20 65 72 72 6f 72 20 6f 72 20 61 6e 20 53 51  O error or an SQ
10ba0 4c 49 54 45 5f 42 55 53 59 20 62 65 63 61 75 73  LITE_BUSY becaus
10bb0 65 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65 73  e another proces
10bc0 73 20 69 73 20 72 75 6e 6e 69 6e 67 0a 2a 2a 20  s is running.** 
10bd0 72 65 63 6f 76 65 72 79 29 20 72 65 74 75 72 6e  recovery) return
10be0 20 61 20 70 6f 73 69 74 69 76 65 20 65 72 72 6f   a positive erro
10bf0 72 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 54 68  r code..**.** Th
10c00 65 20 75 73 65 57 61 6c 20 70 61 72 61 6d 65 74  e useWal paramet
10c10 65 72 20 69 73 20 74 72 75 65 20 74 6f 20 66 6f  er is true to fo
10c20 72 63 65 20 74 68 65 20 75 73 65 20 6f 66 20 74  rce the use of t
10c30 68 65 20 57 41 4c 20 61 6e 64 20 64 69 73 61 62  he WAL and disab
10c40 6c 65 0a 2a 2a 20 74 68 65 20 63 61 73 65 20 77  le.** the case w
10c50 68 65 72 65 20 74 68 65 20 57 41 4c 20 69 73 20  here the WAL is 
10c60 62 79 70 61 73 73 65 64 20 62 65 63 61 75 73 65  bypassed because
10c70 20 69 74 20 68 61 73 20 62 65 65 6e 20 63 6f 6d   it has been com
10c80 70 6c 65 74 65 6c 79 0a 2a 2a 20 63 68 65 63 6b  pletely.** check
10c90 70 6f 69 6e 74 65 64 2e 20 20 49 66 20 75 73 65  pointed.  If use
10ca0 57 61 6c 3d 3d 30 20 74 68 65 6e 20 74 68 69 73  Wal==0 then this
10cb0 20 72 6f 75 74 69 6e 65 20 63 61 6c 6c 73 20 77   routine calls w
10cc0 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28 29  alIndexReadHdr()
10cd0 20 0a 2a 2a 20 74 6f 20 6d 61 6b 65 20 61 20 63   .** to make a c
10ce0 6f 70 79 20 6f 66 20 74 68 65 20 77 61 6c 2d 69  opy of the wal-i
10cf0 6e 64 65 78 20 68 65 61 64 65 72 20 69 6e 74 6f  ndex header into
10d00 20 70 57 61 6c 2d 3e 68 64 72 2e 20 20 49 66 20   pWal->hdr.  If 
10d10 74 68 65 20 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65  the .** wal-inde
10d20 78 20 68 65 61 64 65 72 20 68 61 73 20 63 68 61  x header has cha
10d30 6e 67 65 64 2c 20 2a 70 43 68 61 6e 67 65 64 20  nged, *pChanged 
10d40 69 73 20 73 65 74 20 74 6f 20 31 20 28 61 73 20  is set to 1 (as 
10d50 61 6e 20 69 6e 64 69 63 61 74 69 6f 6e 20 0a 2a  an indication .*
10d60 2a 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 20  * to the caller 
10d70 74 68 61 74 20 74 68 65 20 6c 6f 63 61 6c 20 70  that the local p
10d80 61 67 65 74 20 63 61 63 68 65 20 69 73 20 6f 62  aget cache is ob
10d90 73 6f 6c 65 74 65 20 61 6e 64 20 6e 65 65 64 73  solete and needs
10da0 20 74 6f 20 62 65 20 0a 2a 2a 20 66 6c 75 73 68   to be .** flush
10db0 65 64 2e 29 20 20 57 68 65 6e 20 75 73 65 57 61  ed.)  When useWa
10dc0 6c 3d 3d 31 2c 20 74 68 65 20 77 61 6c 2d 69 6e  l==1, the wal-in
10dd0 64 65 78 20 68 65 61 64 65 72 20 69 73 20 61 73  dex header is as
10de0 73 75 6d 65 64 20 74 6f 20 61 6c 72 65 61 64 79  sumed to already
10df0 0a 2a 2a 20 62 65 20 6c 6f 61 64 65 64 20 61 6e  .** be loaded an
10e00 64 20 74 68 65 20 70 43 68 61 6e 67 65 64 20 70  d the pChanged p
10e10 61 72 61 6d 65 74 65 72 20 69 73 20 75 6e 75 73  arameter is unus
10e20 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 61  ed..**.** The ca
10e30 6c 6c 65 72 20 6d 75 73 74 20 73 65 74 20 74 68  ller must set th
10e40 65 20 63 6e 74 20 70 61 72 61 6d 65 74 65 72 20  e cnt parameter 
10e50 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  to the number of
10e60 20 70 72 69 6f 72 20 63 61 6c 6c 73 20 74 6f 0a   prior calls to.
10e70 2a 2a 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  ** this routine 
10e80 64 75 72 69 6e 67 20 74 68 65 20 63 75 72 72 65  during the curre
10e90 6e 74 20 72 65 61 64 20 61 74 74 65 6d 70 74 20  nt read attempt 
10ea0 74 68 61 74 20 72 65 74 75 72 6e 65 64 20 57 41  that returned WA
10eb0 4c 5f 52 45 54 52 59 2e 0a 2a 2a 20 54 68 69 73  L_RETRY..** This
10ec0 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20 73 74   routine will st
10ed0 61 72 74 20 74 61 6b 69 6e 67 20 6d 6f 72 65 20  art taking more 
10ee0 61 67 67 72 65 73 73 69 76 65 20 6d 65 61 73 75  aggressive measu
10ef0 72 65 73 20 74 6f 20 63 6c 65 61 72 20 74 68 65  res to clear the
10f00 0a 2a 2a 20 72 61 63 65 20 63 6f 6e 64 69 74 69  .** race conditi
10f10 6f 6e 73 20 61 66 74 65 72 20 6d 75 6c 74 69 70  ons after multip
10f20 6c 65 20 57 41 4c 5f 52 45 54 52 59 20 72 65 74  le WAL_RETRY ret
10f30 75 72 6e 73 2c 20 61 6e 64 20 61 66 74 65 72 20  urns, and after 
10f40 61 6e 20 65 78 63 65 73 73 69 76 65 0a 2a 2a 20  an excessive.** 
10f50 6e 75 6d 62 65 72 20 6f 66 20 65 72 72 6f 72 73  number of errors
10f60 20 77 69 6c 6c 20 75 6c 74 69 6d 61 74 65 6c 79   will ultimately
10f70 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 50   return SQLITE_P
10f80 52 4f 54 4f 43 4f 4c 2e 20 20 54 68 65 0a 2a 2a  ROTOCOL.  The.**
10f90 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c   SQLITE_PROTOCOL
10fa0 20 72 65 74 75 72 6e 20 69 6e 64 69 63 61 74 65   return indicate
10fb0 73 20 74 68 61 74 20 73 6f 6d 65 20 6f 74 68 65  s that some othe
10fc0 72 20 70 72 6f 63 65 73 73 20 68 61 73 20 67 6f  r process has go
10fd0 6e 65 20 72 6f 67 75 65 0a 2a 2a 20 61 6e 64 20  ne rogue.** and 
10fe0 69 73 20 6e 6f 74 20 68 6f 6e 6f 72 69 6e 67 20  is not honoring 
10ff0 74 68 65 20 6c 6f 63 6b 69 6e 67 20 70 72 6f 74  the locking prot
11000 6f 63 6f 6c 2e 20 20 54 68 65 72 65 20 69 73 20  ocol.  There is 
11010 61 20 76 61 6e 69 73 68 69 6e 67 6c 79 20 73 6d  a vanishingly sm
11020 61 6c 6c 0a 2a 2a 20 63 68 61 6e 63 65 20 74 68  all.** chance th
11030 61 74 20 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43  at SQLITE_PROTOC
11040 4f 4c 20 63 6f 75 6c 64 20 62 65 20 72 65 74 75  OL could be retu
11050 72 6e 65 64 20 62 65 63 61 75 73 65 20 6f 66 20  rned because of 
11060 61 20 72 75 6e 20 6f 66 20 72 65 61 6c 6c 79 0a  a run of really.
11070 2a 2a 20 62 61 64 20 6c 75 63 6b 20 77 68 65 6e  ** bad luck when
11080 20 74 68 65 72 65 20 69 73 20 6c 6f 74 73 20 6f   there is lots o
11090 66 20 63 6f 6e 74 65 6e 74 69 6f 6e 20 66 6f 72  f contention for
110a0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2c 20   the wal-index, 
110b0 62 75 74 20 74 68 61 74 0a 2a 2a 20 70 6f 73 73  but that.** poss
110c0 69 62 69 6c 69 74 79 20 69 73 20 73 6f 20 73 6d  ibility is so sm
110d0 61 6c 6c 20 74 68 61 74 20 69 74 20 63 61 6e 20  all that it can 
110e0 62 65 20 73 61 66 65 6c 79 20 6e 65 67 6c 65 63  be safely neglec
110f0 74 65 64 2c 20 77 65 20 62 65 6c 69 65 76 65 2e  ted, we believe.
11100 0a 2a 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63 65 73  .**.** On succes
11110 73 2c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  s, this routine 
11120 6f 62 74 61 69 6e 73 20 61 20 72 65 61 64 20 6c  obtains a read l
11130 6f 63 6b 20 6f 6e 20 0a 2a 2a 20 57 41 4c 5f 52  ock on .** WAL_R
11140 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72  EAD_LOCK(pWal->r
11150 65 61 64 4c 6f 63 6b 29 2e 20 20 54 68 65 20 70  eadLock).  The p
11160 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69 6e  Wal->readLock in
11170 74 65 67 65 72 20 69 73 0a 2a 2a 20 69 6e 20 74  teger is.** in t
11180 68 65 20 72 61 6e 67 65 20 30 20 3c 3d 20 70 57  he range 0 <= pW
11190 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3c 20 57  al->readLock < W
111a0 41 4c 5f 4e 52 45 41 44 45 52 2e 20 20 49 66 20  AL_NREADER.  If 
111b0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d  pWal->readLock==
111c0 28 2d 31 29 0a 2a 2a 20 74 68 61 74 20 6d 65 61  (-1).** that mea
111d0 6e 73 20 74 68 65 20 57 61 6c 20 64 6f 65 73 20  ns the Wal does 
111e0 6e 6f 74 20 68 6f 6c 64 20 61 6e 79 20 72 65 61  not hold any rea
111f0 64 20 6c 6f 63 6b 2e 20 20 54 68 65 20 72 65 61  d lock.  The rea
11200 64 65 72 20 6d 75 73 74 20 6e 6f 74 0a 2a 2a 20  der must not.** 
11210 61 63 63 65 73 73 20 61 6e 79 20 64 61 74 61 62  access any datab
11220 61 73 65 20 70 61 67 65 20 74 68 61 74 20 69 73  ase page that is
11230 20 6d 6f 64 69 66 69 65 64 20 62 79 20 61 20 57   modified by a W
11240 41 4c 20 66 72 61 6d 65 20 75 70 20 74 6f 20 61  AL frame up to a
11250 6e 64 0a 2a 2a 20 69 6e 63 6c 75 64 69 6e 67 20  nd.** including 
11260 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 61 52 65  frame number aRe
11270 61 64 4d 61 72 6b 5b 70 57 61 6c 2d 3e 72 65 61  adMark[pWal->rea
11280 64 4c 6f 63 6b 5d 2e 20 20 54 68 65 20 72 65 61  dLock].  The rea
11290 64 65 72 20 77 69 6c 6c 0a 2a 2a 20 75 73 65 20  der will.** use 
112a0 57 41 4c 20 66 72 61 6d 65 73 20 75 70 20 74 6f  WAL frames up to
112b0 20 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20 70   and including p
112c0 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
112d0 20 69 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f   if pWal->readLo
112e0 63 6b 3e 30 0a 2a 2a 20 4f 72 20 69 66 20 70 57  ck>0.** Or if pW
112f0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 2c  al->readLock==0,
11300 20 74 68 65 6e 20 74 68 65 20 72 65 61 64 65 72   then the reader
11310 20 77 69 6c 6c 20 69 67 6e 6f 72 65 20 74 68 65   will ignore the
11320 20 57 41 4c 0a 2a 2a 20 63 6f 6d 70 6c 65 74 65   WAL.** complete
11330 6c 79 20 61 6e 64 20 67 65 74 20 61 6c 6c 20 63  ly and get all c
11340 6f 6e 74 65 6e 74 20 64 69 72 65 63 74 6c 79 20  ontent directly 
11350 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73  from the databas
11360 65 20 66 69 6c 65 2e 0a 2a 2a 20 49 66 20 74 68  e file..** If th
11370 65 20 75 73 65 57 61 6c 20 70 61 72 61 6d 65 74  e useWal paramet
11380 65 72 20 69 73 20 31 20 74 68 65 6e 20 74 68 65  er is 1 then the
11390 20 57 41 4c 20 77 69 6c 6c 20 6e 65 76 65 72 20   WAL will never 
113a0 62 65 20 69 67 6e 6f 72 65 64 20 61 6e 64 0a 2a  be ignored and.*
113b0 2a 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 77  * this routine w
113c0 69 6c 6c 20 61 6c 77 61 79 73 20 73 65 74 20 70  ill always set p
113d0 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 30 20  Wal->readLock>0 
113e0 6f 6e 20 73 75 63 63 65 73 73 2e 0a 2a 2a 20 57  on success..** W
113f0 68 65 6e 20 74 68 65 20 72 65 61 64 20 74 72 61  hen the read tra
11400 6e 73 61 63 74 69 6f 6e 20 69 73 20 63 6f 6d 70  nsaction is comp
11410 6c 65 74 65 64 2c 20 74 68 65 20 63 61 6c 6c 65  leted, the calle
11420 72 20 6d 75 73 74 20 72 65 6c 65 61 73 65 20 74  r must release t
11430 68 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20 57 41  he.** lock on WA
11440 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c  L_READ_LOCK(pWal
11450 2d 3e 72 65 61 64 4c 6f 63 6b 29 20 61 6e 64 20  ->readLock) and 
11460 73 65 74 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f  set pWal->readLo
11470 63 6b 20 74 6f 20 2d 31 2e 0a 2a 2a 0a 2a 2a 20  ck to -1..**.** 
11480 54 68 69 73 20 72 6f 75 74 69 6e 65 20 75 73 65  This routine use
11490 73 20 74 68 65 20 6e 42 61 63 6b 66 69 6c 6c 20  s the nBackfill 
114a0 61 6e 64 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20  and aReadMark[] 
114b0 66 69 65 6c 64 73 20 6f 66 20 74 68 65 20 68 65  fields of the he
114c0 61 64 65 72 0a 2a 2a 20 74 6f 20 73 65 6c 65 63  ader.** to selec
114d0 74 20 61 20 70 61 72 74 69 63 75 6c 61 72 20 57  t a particular W
114e0 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 29 20 74  AL_READ_LOCK() t
114f0 68 61 74 20 73 74 72 69 76 65 73 20 74 6f 20 6c  hat strives to l
11500 65 74 20 74 68 65 0a 2a 2a 20 63 68 65 63 6b 70  et the.** checkp
11510 6f 69 6e 74 20 70 72 6f 63 65 73 73 20 64 6f 20  oint process do 
11520 61 73 20 6d 75 63 68 20 77 6f 72 6b 20 61 73 20  as much work as 
11530 70 6f 73 73 69 62 6c 65 2e 20 20 54 68 69 73 20  possible.  This 
11540 72 6f 75 74 69 6e 65 20 6d 69 67 68 74 0a 2a 2a  routine might.**
11550 20 75 70 64 61 74 65 20 76 61 6c 75 65 73 20 6f   update values o
11560 66 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b 5b  f the aReadMark[
11570 5d 20 61 72 72 61 79 20 69 6e 20 74 68 65 20 68  ] array in the h
11580 65 61 64 65 72 2c 20 62 75 74 20 69 66 20 69 74  eader, but if it
11590 20 64 6f 65 73 0a 2a 2a 20 73 6f 20 69 74 20 74   does.** so it t
115a0 61 6b 65 73 20 63 61 72 65 20 74 6f 20 68 6f 6c  akes care to hol
115b0 64 20 61 6e 20 65 78 63 6c 75 73 69 76 65 20 6c  d an exclusive l
115c0 6f 63 6b 20 6f 6e 20 74 68 65 20 63 6f 72 72 65  ock on the corre
115d0 73 70 6f 6e 64 69 6e 67 0a 2a 2a 20 57 41 4c 5f  sponding.** WAL_
115e0 52 45 41 44 5f 4c 4f 43 4b 28 29 20 77 68 69 6c  READ_LOCK() whil
115f0 65 20 63 68 61 6e 67 69 6e 67 20 76 61 6c 75 65  e changing value
11600 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
11610 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61 64   walTryBeginRead
11620 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20  (Wal *pWal, int 
11630 2a 70 43 68 61 6e 67 65 64 2c 20 69 6e 74 20 75  *pChanged, int u
11640 73 65 57 61 6c 2c 20 69 6e 74 20 63 6e 74 29 7b  seWal, int cnt){
11650 0a 20 20 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43  .  volatile WalC
11660 6b 70 74 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b 20  kptInfo *pInfo; 
11670 20 20 20 2f 2a 20 43 68 65 63 6b 70 6f 69 6e 74     /* Checkpoint
11680 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e 20   information in 
11690 77 61 6c 2d 69 6e 64 65 78 20 2a 2f 0a 20 20 75  wal-index */.  u
116a0 33 32 20 6d 78 52 65 61 64 4d 61 72 6b 3b 20 20  32 mxReadMark;  
116b0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
116c0 2a 20 4c 61 72 67 65 73 74 20 61 52 65 61 64 4d  * Largest aReadM
116d0 61 72 6b 5b 5d 20 76 61 6c 75 65 20 2a 2f 0a 20  ark[] value */. 
116e0 20 69 6e 74 20 6d 78 49 3b 20 20 20 20 20 20 20   int mxI;       
116f0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11700 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6c 61 72   /* Index of lar
11710 67 65 73 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d  gest aReadMark[]
11720 20 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20   value */.  int 
11730 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
11740 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
11750 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a 20  oop counter */. 
11760 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
11770 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
11780 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
11790 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70   */..  assert( p
117a0 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3c 30 20  Wal->readLock<0 
117b0 29 3b 20 20 20 20 20 2f 2a 20 4e 6f 74 20 63 75  );     /* Not cu
117c0 72 72 65 6e 74 6c 79 20 6c 6f 63 6b 65 64 20 2a  rrently locked *
117d0 2f 0a 0a 20 20 2f 2a 20 54 61 6b 65 20 73 74 65  /..  /* Take ste
117e0 70 73 20 74 6f 20 61 76 6f 69 64 20 73 70 69 6e  ps to avoid spin
117f0 6e 69 6e 67 20 66 6f 72 65 76 65 72 20 69 66 20  ning forever if 
11800 74 68 65 72 65 20 69 73 20 61 20 70 72 6f 74 6f  there is a proto
11810 63 6f 6c 20 65 72 72 6f 72 2e 20 2a 2f 0a 20 20  col error. */.  
11820 69 66 28 20 63 6e 74 3e 35 20 29 7b 0a 20 20 20  if( cnt>5 ){.   
11830 20 69 66 28 20 63 6e 74 3e 31 30 30 20 29 20 72   if( cnt>100 ) r
11840 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 50 52 4f  eturn SQLITE_PRO
11850 54 4f 43 4f 4c 3b 0a 20 20 20 20 73 71 6c 69 74  TOCOL;.    sqlit
11860 65 33 4f 73 53 6c 65 65 70 28 70 57 61 6c 2d 3e  e3OsSleep(pWal->
11870 70 56 66 73 2c 20 31 29 3b 0a 20 20 7d 0a 0a 20  pVfs, 1);.  }.. 
11880 20 69 66 28 20 21 75 73 65 57 61 6c 20 29 7b 0a   if( !useWal ){.
11890 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65      rc = walInde
118a0 78 52 65 61 64 48 64 72 28 70 57 61 6c 2c 20 70  xReadHdr(pWal, p
118b0 43 68 61 6e 67 65 64 29 3b 0a 20 20 20 20 69 66  Changed);.    if
118c0 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53  ( rc==SQLITE_BUS
118d0 59 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 49 66  Y ){.      /* If
118e0 20 74 68 65 72 65 20 69 73 20 6e 6f 74 20 61 20   there is not a 
118f0 72 65 63 6f 76 65 72 79 20 72 75 6e 6e 69 6e 67  recovery running
11900 20 69 6e 20 61 6e 6f 74 68 65 72 20 74 68 72 65   in another thre
11910 61 64 20 6f 72 20 70 72 6f 63 65 73 73 0a 20 20  ad or process.  
11920 20 20 20 20 2a 2a 20 74 68 65 6e 20 63 6f 6e 76      ** then conv
11930 65 72 74 20 42 55 53 59 20 65 72 72 6f 72 73 20  ert BUSY errors 
11940 74 6f 20 57 41 4c 5f 52 45 54 52 59 2e 20 20 49  to WAL_RETRY.  I
11950 66 20 72 65 63 6f 76 65 72 79 20 69 73 20 6b 6e  f recovery is kn
11960 6f 77 6e 20 74 6f 0a 20 20 20 20 20 20 2a 2a 20  own to.      ** 
11970 62 65 20 72 75 6e 6e 69 6e 67 2c 20 63 6f 6e 76  be running, conv
11980 65 72 74 20 42 55 53 59 20 74 6f 20 42 55 53 59  ert BUSY to BUSY
11990 5f 52 45 43 4f 56 45 52 59 2e 20 20 54 68 65 72  _RECOVERY.  Ther
119a0 65 20 69 73 20 61 20 72 61 63 65 20 68 65 72 65  e is a race here
119b0 0a 20 20 20 20 20 20 2a 2a 20 77 68 69 63 68 20  .      ** which 
119c0 6d 69 67 68 74 20 63 61 75 73 65 20 57 41 4c 5f  might cause WAL_
119d0 52 45 54 52 59 20 74 6f 20 62 65 20 72 65 74 75  RETRY to be retu
119e0 72 6e 65 64 20 65 76 65 6e 20 69 66 20 42 55 53  rned even if BUS
119f0 59 5f 52 45 43 4f 56 45 52 59 0a 20 20 20 20 20  Y_RECOVERY.     
11a00 20 2a 2a 20 77 6f 75 6c 64 20 62 65 20 74 65 63   ** would be tec
11a10 68 6e 69 63 61 6c 6c 79 20 63 6f 72 72 65 63 74  hnically correct
11a20 2e 20 20 42 75 74 20 74 68 65 20 72 61 63 65 20  .  But the race 
11a30 69 73 20 62 65 6e 69 67 6e 20 73 69 6e 63 65 20  is benign since 
11a40 77 69 74 68 0a 20 20 20 20 20 20 2a 2a 20 57 41  with.      ** WA
11a50 4c 5f 52 45 54 52 59 20 74 68 69 73 20 72 6f 75  L_RETRY this rou
11a60 74 69 6e 65 20 77 69 6c 6c 20 62 65 20 63 61 6c  tine will be cal
11a70 6c 65 64 20 61 67 61 69 6e 20 61 6e 64 20 77 69  led again and wi
11a80 6c 6c 20 70 72 6f 62 61 62 6c 79 20 62 65 0a 20  ll probably be. 
11a90 20 20 20 20 20 2a 2a 20 72 69 67 68 74 20 6f 6e       ** right on
11aa0 20 74 68 65 20 73 65 63 6f 6e 64 20 69 74 65 72   the second iter
11ab0 61 74 69 6f 6e 2e 0a 20 20 20 20 20 20 2a 2f 0a  ation..      */.
11ac0 20 20 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f        rc = walLo
11ad0 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
11ae0 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43 4b 29  AL_RECOVER_LOCK)
11af0 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
11b00 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
11b10 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68       walUnlockSh
11b20 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
11b30 45 43 4f 56 45 52 5f 4c 4f 43 4b 29 3b 0a 20 20  ECOVER_LOCK);.  
11b40 20 20 20 20 20 20 72 63 20 3d 20 57 41 4c 5f 52        rc = WAL_R
11b50 45 54 52 59 3b 0a 20 20 20 20 20 20 7d 65 6c 73  ETRY;.      }els
11b60 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45  e if( rc==SQLITE
11b70 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20 20  _BUSY ){.       
11b80 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55 53   rc = SQLITE_BUS
11b90 59 5f 52 45 43 4f 56 45 52 59 3b 0a 20 20 20 20  Y_RECOVERY;.    
11ba0 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
11bb0 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
11bc0 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
11bd0 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  rc;.    }.  }.. 
11be0 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74   pInfo = walCkpt
11bf0 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 69 66  Info(pWal);.  if
11c00 28 20 21 75 73 65 57 61 6c 20 26 26 20 70 49 6e  ( !useWal && pIn
11c10 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c 6c 3d 3d 70  fo->nBackfill==p
11c20 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
11c30 20 29 7b 0a 20 20 20 20 2f 2a 20 54 68 65 20 57   ){.    /* The W
11c40 41 4c 20 68 61 73 20 62 65 65 6e 20 63 6f 6d 70  AL has been comp
11c50 6c 65 74 65 6c 79 20 62 61 63 6b 66 69 6c 6c 65  letely backfille
11c60 64 20 28 6f 72 20 69 74 20 69 73 20 65 6d 70 74  d (or it is empt
11c70 79 29 2e 0a 20 20 20 20 2a 2a 20 61 6e 64 20 63  y)..    ** and c
11c80 61 6e 20 62 65 20 73 61 66 65 6c 79 20 69 67 6e  an be safely ign
11c90 6f 72 65 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  ored..    */.   
11ca0 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61   rc = walLockSha
11cb0 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
11cc0 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20  AD_LOCK(0));.   
11cd0 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 42 61 72   sqlite3OsShmBar
11ce0 72 69 65 72 28 70 57 61 6c 2d 3e 70 44 62 46 64  rier(pWal->pDbFd
11cf0 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  );.    if( rc==S
11d00 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
11d10 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 28 76 6f    if( memcmp((vo
11d20 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72  id *)walIndexHdr
11d30 28 70 57 61 6c 29 2c 20 26 70 57 61 6c 2d 3e 68  (pWal), &pWal->h
11d40 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  dr, sizeof(WalIn
11d50 64 65 78 48 64 72 29 29 20 29 7b 0a 20 20 20 20  dexHdr)) ){.    
11d60 20 20 20 20 2f 2a 20 49 74 20 69 73 20 6e 6f 74      /* It is not
11d70 20 73 61 66 65 20 74 6f 20 61 6c 6c 6f 77 20 74   safe to allow t
11d80 68 65 20 72 65 61 64 65 72 20 74 6f 20 63 6f 6e  he reader to con
11d90 74 69 6e 75 65 20 68 65 72 65 20 69 66 20 66 72  tinue here if fr
11da0 61 6d 65 73 0a 20 20 20 20 20 20 20 20 2a 2a 20  ames.        ** 
11db0 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 61 70  may have been ap
11dc0 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 6c 6f  pended to the lo
11dd0 67 20 62 65 66 6f 72 65 20 52 45 41 44 5f 4c 4f  g before READ_LO
11de0 43 4b 28 30 29 20 77 61 73 20 6f 62 74 61 69 6e  CK(0) was obtain
11df0 65 64 2e 0a 20 20 20 20 20 20 20 20 2a 2a 20 57  ed..        ** W
11e00 68 65 6e 20 68 6f 6c 64 69 6e 67 20 52 45 41 44  hen holding READ
11e10 5f 4c 4f 43 4b 28 30 29 2c 20 74 68 65 20 72 65  _LOCK(0), the re
11e20 61 64 65 72 20 69 67 6e 6f 72 65 73 20 74 68 65  ader ignores the
11e30 20 65 6e 74 69 72 65 20 6c 6f 67 20 66 69 6c 65   entire log file
11e40 2c 0a 20 20 20 20 20 20 20 20 2a 2a 20 77 68 69  ,.        ** whi
11e50 63 68 20 69 6d 70 6c 69 65 73 20 74 68 61 74 20  ch implies that 
11e60 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
11e70 65 20 63 6f 6e 74 61 69 6e 73 20 61 20 74 72 75  e contains a tru
11e80 73 74 77 6f 72 74 68 79 0a 20 20 20 20 20 20 20  stworthy.       
11e90 20 2a 2a 20 73 6e 61 70 73 68 6f 54 2e 20 53 69   ** snapshoT. Si
11ea0 6e 63 65 20 68 6f 6c 64 69 6e 67 20 52 45 41 44  nce holding READ
11eb0 5f 4c 4f 43 4b 28 30 29 20 70 72 65 76 65 6e 74  _LOCK(0) prevent
11ec0 73 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 20 66  s a checkpoint f
11ed0 72 6f 6d 0a 20 20 20 20 20 20 20 20 2a 2a 20 68  rom.        ** h
11ee0 61 70 70 65 6e 69 6e 67 2c 20 74 68 69 73 20 69  appening, this i
11ef0 73 20 75 73 75 61 6c 6c 79 20 63 6f 72 72 65 63  s usually correc
11f00 74 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a 20 20  t..        **.  
11f10 20 20 20 20 20 20 2a 2a 20 48 6f 77 65 76 65 72        ** However
11f20 2c 20 69 66 20 66 72 61 6d 65 73 20 68 61 76 65  , if frames have
11f30 20 62 65 65 6e 20 61 70 70 65 6e 64 65 64 20 74   been appended t
11f40 6f 20 74 68 65 20 6c 6f 67 20 28 6f 72 20 69 66  o the log (or if
11f50 20 74 68 65 20 6c 6f 67 20 0a 20 20 20 20 20 20   the log .      
11f60 20 20 2a 2a 20 69 73 20 77 72 61 70 70 65 64 20    ** is wrapped 
11f70 61 6e 64 20 77 72 69 74 74 65 6e 20 66 6f 72 20  and written for 
11f80 74 68 61 74 20 6d 61 74 74 65 72 29 20 62 65 66  that matter) bef
11f90 6f 72 65 20 74 68 65 20 52 45 41 44 5f 4c 4f 43  ore the READ_LOC
11fa0 4b 28 30 29 0a 20 20 20 20 20 20 20 20 2a 2a 20  K(0).        ** 
11fb0 69 73 20 6f 62 74 61 69 6e 65 64 2c 20 74 68 61  is obtained, tha
11fc0 74 20 69 73 20 6e 6f 74 20 6e 65 63 65 73 73 61  t is not necessa
11fd0 72 69 6c 79 20 74 72 75 65 2e 20 41 20 63 68 65  rily true. A che
11fe0 63 6b 70 6f 69 6e 74 65 72 20 6d 61 79 0a 20 20  ckpointer may.  
11ff0 20 20 20 20 20 20 2a 2a 20 68 61 76 65 20 73 74        ** have st
12000 61 72 74 65 64 20 74 6f 20 62 61 63 6b 66 69 6c  arted to backfil
12010 6c 20 74 68 65 20 61 70 70 65 6e 64 65 64 20 66  l the appended f
12020 72 61 6d 65 73 20 62 75 74 20 63 72 61 73 68 65  rames but crashe
12030 64 20 62 65 66 6f 72 65 0a 20 20 20 20 20 20 20  d before.       
12040 20 2a 2a 20 69 74 20 66 69 6e 69 73 68 65 64 2e   ** it finished.
12050 20 4c 65 61 76 69 6e 67 20 61 20 63 6f 72 72 75   Leaving a corru
12060 70 74 20 69 6d 61 67 65 20 69 6e 20 74 68 65 20  pt image in the 
12070 64 61 74 61 62 61 73 65 20 66 69 6c 65 2e 0a 20  database file.. 
12080 20 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20         */.      
12090 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65    walUnlockShare
120a0 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  d(pWal, WAL_READ
120b0 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20 20 20 20 20  _LOCK(0));.     
120c0 20 20 20 72 65 74 75 72 6e 20 57 41 4c 5f 52 45     return WAL_RE
120d0 54 52 59 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  TRY;.      }.   
120e0 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63     pWal->readLoc
120f0 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 65 74  k = 0;.      ret
12100 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  urn SQLITE_OK;. 
12110 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63 21     }else if( rc!
12120 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a  =SQLITE_BUSY ){.
12130 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
12140 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
12150 20 49 66 20 77 65 20 67 65 74 20 74 68 69 73 20   If we get this 
12160 66 61 72 2c 20 69 74 20 6d 65 61 6e 73 20 74 68  far, it means th
12170 61 74 20 74 68 65 20 72 65 61 64 65 72 20 77 69  at the reader wi
12180 6c 6c 20 77 61 6e 74 20 74 6f 20 75 73 65 0a 20  ll want to use. 
12190 20 2a 2a 20 74 68 65 20 57 41 4c 20 74 6f 20 67   ** the WAL to g
121a0 65 74 20 61 74 20 63 6f 6e 74 65 6e 74 20 66 72  et at content fr
121b0 6f 6d 20 72 65 63 65 6e 74 20 63 6f 6d 6d 69 74  om recent commit
121c0 73 2e 20 20 54 68 65 20 6a 6f 62 20 6e 6f 77 20  s.  The job now 
121d0 69 73 0a 20 20 2a 2a 20 74 6f 20 73 65 6c 65 63  is.  ** to selec
121e0 74 20 6f 6e 65 20 6f 66 20 74 68 65 20 61 52 65  t one of the aRe
121f0 61 64 4d 61 72 6b 5b 5d 20 65 6e 74 72 69 65 73  adMark[] entries
12200 20 74 68 61 74 20 69 73 20 63 6c 6f 73 65 73 74   that is closest
12210 20 74 6f 0a 20 20 2a 2a 20 62 75 74 20 6e 6f 74   to.  ** but not
12220 20 65 78 63 65 65 64 69 6e 67 20 70 57 61 6c 2d   exceeding pWal-
12230 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 61 6e 64  >hdr.mxFrame and
12240 20 6c 6f 63 6b 20 74 68 61 74 20 65 6e 74 72 79   lock that entry
12250 2e 0a 20 20 2a 2f 0a 20 20 6d 78 52 65 61 64 4d  ..  */.  mxReadM
12260 61 72 6b 20 3d 20 30 3b 0a 20 20 6d 78 49 20 3d  ark = 0;.  mxI =
12270 20 30 3b 0a 20 20 66 6f 72 28 69 3d 31 3b 20 69   0;.  for(i=1; i
12280 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b  <WAL_NREADER; i+
12290 2b 29 7b 0a 20 20 20 20 75 33 32 20 74 68 69 73  +){.    u32 this
122a0 4d 61 72 6b 20 3d 20 70 49 6e 66 6f 2d 3e 61 52  Mark = pInfo->aR
122b0 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20 20 20 20  eadMark[i];.    
122c0 69 66 28 20 6d 78 52 65 61 64 4d 61 72 6b 3c 3d  if( mxReadMark<=
122d0 74 68 69 73 4d 61 72 6b 20 26 26 20 74 68 69 73  thisMark && this
122e0 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e  Mark<=pWal->hdr.
122f0 6d 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 20  mxFrame ){.     
12300 20 61 73 73 65 72 74 28 20 74 68 69 73 4d 61 72   assert( thisMar
12310 6b 21 3d 52 45 41 44 4d 41 52 4b 5f 4e 4f 54 5f  k!=READMARK_NOT_
12320 55 53 45 44 20 29 3b 0a 20 20 20 20 20 20 6d 78  USED );.      mx
12330 52 65 61 64 4d 61 72 6b 20 3d 20 74 68 69 73 4d  ReadMark = thisM
12340 61 72 6b 3b 0a 20 20 20 20 20 20 6d 78 49 20 3d  ark;.      mxI =
12350 20 69 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20   i;.    }.  }.  
12360 69 66 28 20 6d 78 49 3d 3d 30 20 29 7b 0a 20 20  if( mxI==0 ){.  
12370 20 20 2f 2a 20 49 66 20 77 65 20 67 65 74 20 68    /* If we get h
12380 65 72 65 2c 20 69 74 20 6d 65 61 6e 73 20 74 68  ere, it means th
12390 61 74 20 61 6c 6c 20 6f 66 20 74 68 65 20 61 52  at all of the aR
123a0 65 61 64 4d 61 72 6b 5b 5d 20 65 6e 74 72 69 65  eadMark[] entrie
123b0 73 20 62 65 74 77 65 65 6e 0a 20 20 20 20 2a 2a  s between.    **
123c0 20 31 20 61 6e 64 20 57 41 4c 5f 4e 52 45 41 44   1 and WAL_NREAD
123d0 45 52 2d 31 20 61 72 65 20 7a 65 72 6f 2e 20 20  ER-1 are zero.  
123e0 54 72 79 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a  Try to initializ
123f0 65 20 61 52 65 61 64 4d 61 72 6b 5b 31 5d 20 74  e aReadMark[1] t
12400 6f 0a 20 20 20 20 2a 2a 20 62 65 20 6d 78 46 72  o.    ** be mxFr
12410 61 6d 65 2c 20 74 68 65 6e 20 72 65 74 72 79 2e  ame, then retry.
12420 0a 20 20 20 20 2a 2f 0a 20 20 20 20 72 63 20 3d  .    */.    rc =
12430 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76   walLockExclusiv
12440 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
12450 5f 4c 4f 43 4b 28 31 29 2c 20 31 29 3b 0a 20 20  _LOCK(1), 1);.  
12460 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
12470 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 70 49 6e  _OK ){.      pIn
12480 66 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 31 5d  fo->aReadMark[1]
12490 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46   = pWal->hdr.mxF
124a0 72 61 6d 65 3b 0a 20 20 20 20 20 20 77 61 6c 55  rame;.      walU
124b0 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  nlockExclusive(p
124c0 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
124d0 43 4b 28 31 29 2c 20 31 29 3b 0a 20 20 20 20 20  CK(1), 1);.     
124e0 20 72 63 20 3d 20 57 41 4c 5f 52 45 54 52 59 3b   rc = WAL_RETRY;
124f0 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72  .    }else if( r
12500 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29  c==SQLITE_BUSY )
12510 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 57 41 4c  {.      rc = WAL
12520 5f 52 45 54 52 59 3b 0a 20 20 20 20 7d 0a 20 20  _RETRY;.    }.  
12530 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d    return rc;.  }
12540 65 6c 73 65 7b 0a 20 20 20 20 69 66 28 20 6d 78  else{.    if( mx
12550 52 65 61 64 4d 61 72 6b 20 3c 20 70 57 61 6c 2d  ReadMark < pWal-
12560 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a  >hdr.mxFrame ){.
12570 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69        for(i=1; i
12580 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b  <WAL_NREADER; i+
12590 2b 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  +){.        rc =
125a0 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76   walLockExclusiv
125b0 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  e(pWal, WAL_READ
125c0 5f 4c 4f 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20  _LOCK(i), 1);.  
125d0 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
125e0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
125f0 20 20 20 20 20 6d 78 52 65 61 64 4d 61 72 6b 20       mxReadMark 
12600 3d 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61  = pInfo->aReadMa
12610 72 6b 5b 69 5d 20 3d 20 70 57 61 6c 2d 3e 68 64  rk[i] = pWal->hd
12620 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 20  r.mxFrame;.     
12630 20 20 20 20 20 6d 78 49 20 3d 20 69 3b 0a 20 20       mxI = i;.  
12640 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63          walUnloc
12650 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
12660 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69   WAL_READ_LOCK(i
12670 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 20 20 20  ), 1);.         
12680 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
12690 7d 65 6c 73 65 20 69 66 28 20 72 63 21 3d 53 51  }else if( rc!=SQ
126a0 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20 20 20  LITE_BUSY ){.   
126b0 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63         return rc
126c0 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
126d0 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72    }.    }..    r
126e0 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72 65  c = walLockShare
126f0 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  d(pWal, WAL_READ
12700 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b 0a 20 20 20  _LOCK(mxI));.   
12710 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 20   if( rc ){.     
12720 20 72 65 74 75 72 6e 20 72 63 3d 3d 53 51 4c 49   return rc==SQLI
12730 54 45 5f 42 55 53 59 20 3f 20 57 41 4c 5f 52 45  TE_BUSY ? WAL_RE
12740 54 52 59 20 3a 20 72 63 3b 0a 20 20 20 20 7d 0a  TRY : rc;.    }.
12750 20 20 20 20 2f 2a 20 4e 6f 77 20 74 68 61 74 20      /* Now that 
12760 74 68 65 20 72 65 61 64 2d 6c 6f 63 6b 20 68 61  the read-lock ha
12770 73 20 62 65 65 6e 20 6f 62 74 61 69 6e 65 64 2c  s been obtained,
12780 20 63 68 65 63 6b 20 74 68 61 74 20 6e 65 69 74   check that neit
12790 68 65 72 20 74 68 65 0a 20 20 20 20 2a 2a 20 76  her the.    ** v
127a0 61 6c 75 65 20 69 6e 20 74 68 65 20 61 52 65 61  alue in the aRea
127b0 64 4d 61 72 6b 5b 5d 20 61 72 72 61 79 20 6f 72  dMark[] array or
127c0 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
127d0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 0a 20   the wal-index. 
127e0 20 20 20 2a 2a 20 68 65 61 64 65 72 20 68 61 76     ** header hav
127f0 65 20 63 68 61 6e 67 65 64 2e 0a 20 20 20 20 2a  e changed..    *
12800 2a 0a 20 20 20 20 2a 2a 20 49 74 20 69 73 20 6e  *.    ** It is n
12810 65 63 65 73 73 61 72 79 20 74 6f 20 63 68 65 63  ecessary to chec
12820 6b 20 74 68 61 74 20 74 68 65 20 77 61 6c 2d 69  k that the wal-i
12830 6e 64 65 78 20 68 65 61 64 65 72 20 64 69 64 20  ndex header did 
12840 6e 6f 74 20 63 68 61 6e 67 65 0a 20 20 20 20 2a  not change.    *
12850 2a 20 62 65 74 77 65 65 6e 20 74 68 65 20 74 69  * between the ti
12860 6d 65 20 69 74 20 77 61 73 20 72 65 61 64 20 61  me it was read a
12870 6e 64 20 77 68 65 6e 20 74 68 65 20 73 68 61 72  nd when the shar
12880 65 64 2d 6c 6f 63 6b 20 77 61 73 20 6f 62 74 61  ed-lock was obta
12890 69 6e 65 64 0a 20 20 20 20 2a 2a 20 6f 6e 20 57  ined.    ** on W
128a0 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49  AL_READ_LOCK(mxI
128b0 29 20 77 61 73 20 6f 62 74 61 69 6e 65 64 20 74  ) was obtained t
128c0 6f 20 61 63 63 6f 75 6e 74 20 66 6f 72 20 74 68  o account for th
128d0 65 20 70 6f 73 73 69 62 69 6c 69 74 79 0a 20 20  e possibility.  
128e0 20 20 2a 2a 20 74 68 61 74 20 74 68 65 20 6c 6f    ** that the lo
128f0 67 20 66 69 6c 65 20 6d 61 79 20 68 61 76 65 20  g file may have 
12900 62 65 65 6e 20 77 72 61 70 70 65 64 20 62 79 20  been wrapped by 
12910 61 20 77 72 69 74 65 72 2c 20 6f 72 20 74 68 61  a writer, or tha
12920 74 20 66 72 61 6d 65 73 0a 20 20 20 20 2a 2a 20  t frames.    ** 
12930 74 68 61 74 20 6f 63 63 75 72 20 6c 61 74 65 72  that occur later
12940 20 69 6e 20 74 68 65 20 6c 6f 67 20 74 68 61 6e   in the log than
12950 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
12960 6d 65 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e  me may have been
12970 0a 20 20 20 20 2a 2a 20 63 6f 70 69 65 64 20 69  .    ** copied i
12980 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65  nto the database
12990 20 62 79 20 61 20 63 68 65 63 6b 70 6f 69 6e 74   by a checkpoint
129a0 65 72 2e 20 49 66 20 65 69 74 68 65 72 20 6f 66  er. If either of
129b0 20 74 68 65 73 65 20 74 68 69 6e 67 73 0a 20 20   these things.  
129c0 20 20 2a 2a 20 68 61 70 70 65 6e 65 64 2c 20 74    ** happened, t
129d0 68 65 6e 20 72 65 61 64 69 6e 67 20 74 68 65 20  hen reading the 
129e0 64 61 74 61 62 61 73 65 20 77 69 74 68 20 74 68  database with th
129f0 65 20 63 75 72 72 65 6e 74 20 76 61 6c 75 65 20  e current value 
12a00 6f 66 0a 20 20 20 20 2a 2a 20 70 57 61 6c 2d 3e  of.    ** pWal->
12a10 68 64 72 2e 6d 78 46 72 61 6d 65 20 72 69 73 6b  hdr.mxFrame risk
12a20 73 20 72 65 61 64 69 6e 67 20 61 20 63 6f 72 72  s reading a corr
12a30 75 70 74 65 64 20 73 6e 61 70 73 68 6f 74 2e 20  upted snapshot. 
12a40 53 6f 2c 20 72 65 74 72 79 0a 20 20 20 20 2a 2a  So, retry.    **
12a50 20 69 6e 73 74 65 61 64 2e 0a 20 20 20 20 2a 2a   instead..    **
12a60 0a 20 20 20 20 2a 2a 20 54 68 69 73 20 64 6f 65  .    ** This doe
12a70 73 20 6e 6f 74 20 67 75 61 72 61 6e 74 65 65 20  s not guarantee 
12a80 74 68 61 74 20 74 68 65 20 63 6f 70 79 20 6f 66  that the copy of
12a90 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
12aa0 65 61 64 65 72 20 69 73 20 75 70 20 74 6f 0a 20  eader is up to. 
12ab0 20 20 20 2a 2a 20 64 61 74 65 20 62 65 66 6f 72     ** date befor
12ac0 65 20 70 72 6f 63 65 65 64 69 6e 67 2e 20 54 68  e proceeding. Th
12ad0 61 74 20 77 6f 75 6c 64 20 6e 6f 74 20 62 65 20  at would not be 
12ae0 70 6f 73 73 69 62 6c 65 20 77 69 74 68 6f 75 74  possible without
12af0 20 73 6f 6d 65 68 6f 77 0a 20 20 20 20 2a 2a 20   somehow.    ** 
12b00 62 6c 6f 63 6b 69 6e 67 20 77 72 69 74 65 72 73  blocking writers
12b10 2e 20 49 74 20 6f 6e 6c 79 20 67 75 61 72 61 6e  . It only guaran
12b20 74 65 65 73 20 74 68 61 74 20 61 20 64 61 6e 67  tees that a dang
12b30 65 72 6f 75 73 20 63 68 65 63 6b 70 6f 69 6e 74  erous checkpoint
12b40 20 6f 72 20 0a 20 20 20 20 2a 2a 20 6c 6f 67 2d   or .    ** log-
12b50 77 72 61 70 20 28 65 69 74 68 65 72 20 6f 66 20  wrap (either of 
12b60 77 68 69 63 68 20 77 6f 75 6c 64 20 72 65 71 75  which would requ
12b70 69 72 65 20 61 6e 20 65 78 63 6c 75 73 69 76 65  ire an exclusive
12b80 20 6c 6f 63 6b 20 6f 6e 0a 20 20 20 20 2a 2a 20   lock on.    ** 
12b90 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 6d 78  WAL_READ_LOCK(mx
12ba0 49 29 29 20 68 61 73 20 6e 6f 74 20 6f 63 63 75  I)) has not occu
12bb0 72 72 65 64 20 73 69 6e 63 65 20 74 68 65 20 73  rred since the s
12bc0 6e 61 70 73 68 6f 74 20 77 61 73 20 76 61 6c 69  napshot was vali
12bd0 64 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 73 71  d..    */.    sq
12be0 6c 69 74 65 33 4f 73 53 68 6d 42 61 72 72 69 65  lite3OsShmBarrie
12bf0 72 28 70 57 61 6c 2d 3e 70 44 62 46 64 29 3b 0a  r(pWal->pDbFd);.
12c00 20 20 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 61      if( pInfo->a
12c10 52 65 61 64 4d 61 72 6b 5b 6d 78 49 5d 21 3d 6d  ReadMark[mxI]!=m
12c20 78 52 65 61 64 4d 61 72 6b 0a 20 20 20 20 20 7c  xReadMark.     |
12c30 7c 20 6d 65 6d 63 6d 70 28 28 76 6f 69 64 20 2a  | memcmp((void *
12c40 29 77 61 6c 49 6e 64 65 78 48 64 72 28 70 57 61  )walIndexHdr(pWa
12c50 6c 29 2c 20 26 70 57 61 6c 2d 3e 68 64 72 2c 20  l), &pWal->hdr, 
12c60 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48  sizeof(WalIndexH
12c70 64 72 29 29 0a 20 20 20 20 29 7b 0a 20 20 20 20  dr)).    ){.    
12c80 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65    walUnlockShare
12c90 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44  d(pWal, WAL_READ
12ca0 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b 0a 20 20 20  _LOCK(mxI));.   
12cb0 20 20 20 72 65 74 75 72 6e 20 57 41 4c 5f 52 45     return WAL_RE
12cc0 54 52 59 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  TRY;.    }else{.
12cd0 20 20 20 20 20 20 61 73 73 65 72 74 28 20 6d 78        assert( mx
12ce0 52 65 61 64 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e  ReadMark<=pWal->
12cf0 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20  hdr.mxFrame );. 
12d00 20 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64 4c       pWal->readL
12d10 6f 63 6b 20 3d 20 28 69 31 36 29 6d 78 49 3b 0a  ock = (i16)mxI;.
12d20 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
12d30 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
12d40 42 65 67 69 6e 20 61 20 72 65 61 64 20 74 72 61  Begin a read tra
12d50 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20  nsaction on the 
12d60 64 61 74 61 62 61 73 65 2e 0a 2a 2a 0a 2a 2a 20  database..**.** 
12d70 54 68 69 73 20 72 6f 75 74 69 6e 65 20 75 73 65  This routine use
12d80 64 20 74 6f 20 62 65 20 63 61 6c 6c 65 64 20 73  d to be called s
12d90 71 6c 69 74 65 33 4f 70 65 6e 53 6e 61 70 73 68  qlite3OpenSnapsh
12da0 6f 74 28 29 20 61 6e 64 20 77 69 74 68 20 67 6f  ot() and with go
12db0 6f 64 20 72 65 61 73 6f 6e 3a 0a 2a 2a 20 69 74  od reason:.** it
12dc0 20 74 61 6b 65 73 20 61 20 73 6e 61 70 73 68 6f   takes a snapsho
12dd0 74 20 6f 66 20 74 68 65 20 73 74 61 74 65 20 6f  t of the state o
12de0 66 20 74 68 65 20 57 41 4c 20 61 6e 64 20 77 61  f the WAL and wa
12df0 6c 2d 69 6e 64 65 78 20 66 6f 72 20 74 68 65 20  l-index for the 
12e00 63 75 72 72 65 6e 74 0a 2a 2a 20 69 6e 73 74 61  current.** insta
12e10 6e 74 20 69 6e 20 74 69 6d 65 2e 20 20 54 68 65  nt in time.  The
12e20 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 20   current thread 
12e30 77 69 6c 6c 20 63 6f 6e 74 69 6e 75 65 20 74 6f  will continue to
12e40 20 75 73 65 20 74 68 69 73 20 73 6e 61 70 73 68   use this snapsh
12e50 6f 74 2e 0a 2a 2a 20 4f 74 68 65 72 20 74 68 72  ot..** Other thr
12e60 65 61 64 73 20 6d 69 67 68 74 20 61 70 70 65 6e  eads might appen
12e70 64 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20 74 6f  d new content to
12e80 20 74 68 65 20 57 41 4c 20 61 6e 64 20 77 61 6c   the WAL and wal
12e90 2d 69 6e 64 65 78 20 62 75 74 0a 2a 2a 20 74 68  -index but.** th
12ea0 61 74 20 65 78 74 72 61 20 63 6f 6e 74 65 6e 74  at extra content
12eb0 20 69 73 20 69 67 6e 6f 72 65 64 20 62 79 20 74   is ignored by t
12ec0 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61  he current threa
12ed0 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  d..**.** If the 
12ee0 64 61 74 61 62 61 73 65 20 63 6f 6e 74 65 6e 74  database content
12ef0 73 20 68 61 76 65 20 63 68 61 6e 67 65 73 20 73  s have changes s
12f00 69 6e 63 65 20 74 68 65 20 70 72 65 76 69 6f 75  ince the previou
12f10 73 20 72 65 61 64 0a 2a 2a 20 74 72 61 6e 73 61  s read.** transa
12f20 63 74 69 6f 6e 2c 20 74 68 65 6e 20 2a 70 43 68  ction, then *pCh
12f30 61 6e 67 65 64 20 69 73 20 73 65 74 20 74 6f 20  anged is set to 
12f40 31 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69  1 before returni
12f50 6e 67 2e 20 20 54 68 65 0a 2a 2a 20 50 61 67 65  ng.  The.** Page
12f60 72 20 6c 61 79 65 72 20 77 69 6c 6c 20 75 73 65  r layer will use
12f70 20 74 68 69 73 20 74 6f 20 6b 6e 6f 77 20 74 68   this to know th
12f80 61 74 20 69 73 20 63 61 63 68 65 20 69 73 20 73  at is cache is s
12f90 74 61 6c 65 20 61 6e 64 0a 2a 2a 20 6e 65 65 64  tale and.** need
12fa0 73 20 74 6f 20 62 65 20 66 6c 75 73 68 65 64 2e  s to be flushed.
12fb0 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
12fc0 61 6c 42 65 67 69 6e 52 65 61 64 54 72 61 6e 73  alBeginReadTrans
12fd0 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c  action(Wal *pWal
12fe0 2c 20 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 29  , int *pChanged)
12ff0 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  {.  int rc;     
13000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13010 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
13020 64 65 20 2a 2f 0a 20 20 69 6e 74 20 63 6e 74 20  de */.  int cnt 
13030 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
13040 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
13050 72 20 6f 66 20 54 72 79 42 65 67 69 6e 52 65 61  r of TryBeginRea
13060 64 20 61 74 74 65 6d 70 74 73 20 2a 2f 0a 0a 20  d attempts */.. 
13070 20 64 6f 7b 0a 20 20 20 20 72 63 20 3d 20 77 61   do{.    rc = wa
13080 6c 54 72 79 42 65 67 69 6e 52 65 61 64 28 70 57  lTryBeginRead(pW
13090 61 6c 2c 20 70 43 68 61 6e 67 65 64 2c 20 30 2c  al, pChanged, 0,
130a0 20 2b 2b 63 6e 74 29 3b 0a 20 20 7d 77 68 69 6c   ++cnt);.  }whil
130b0 65 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54 52 59  e( rc==WAL_RETRY
130c0 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   );.  return rc;
130d0 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 69 73 68  .}../*.** Finish
130e0 20 77 69 74 68 20 61 20 72 65 61 64 20 74 72 61   with a read tra
130f0 6e 73 61 63 74 69 6f 6e 2e 20 20 41 6c 6c 20 74  nsaction.  All t
13100 68 69 73 20 64 6f 65 73 20 69 73 20 72 65 6c 65  his does is rele
13110 61 73 65 20 74 68 65 0a 2a 2a 20 72 65 61 64 2d  ase the.** read-
13120 6c 6f 63 6b 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71  lock..*/.void sq
13130 6c 69 74 65 33 57 61 6c 45 6e 64 52 65 61 64 54  lite3WalEndReadT
13140 72 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a  ransaction(Wal *
13150 70 57 61 6c 29 7b 0a 20 20 69 66 28 20 70 57 61  pWal){.  if( pWa
13160 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29  l->readLock>=0 )
13170 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53  {.    walUnlockS
13180 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
13190 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e  READ_LOCK(pWal->
131a0 72 65 61 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20  readLock));.    
131b0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d  pWal->readLock =
131c0 20 2d 31 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a   -1;.  }.}../*.*
131d0 2a 20 52 65 61 64 20 61 20 70 61 67 65 20 66 72  * Read a page fr
131e0 6f 6d 20 74 68 65 20 57 41 4c 2c 20 69 66 20 69  om the WAL, if i
131f0 74 20 69 73 20 70 72 65 73 65 6e 74 20 69 6e 20  t is present in 
13200 74 68 65 20 57 41 4c 20 61 6e 64 20 69 66 20 74  the WAL and if t
13210 68 65 20 0a 2a 2a 20 63 75 72 72 65 6e 74 20 72  he .** current r
13220 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ead transaction 
13230 69 73 20 63 6f 6e 66 69 67 75 72 65 64 20 74 6f  is configured to
13240 20 75 73 65 20 74 68 65 20 57 41 4c 2e 20 20 0a   use the WAL.  .
13250 2a 2a 0a 2a 2a 20 54 68 65 20 2a 70 49 6e 57 61  **.** The *pInWa
13260 6c 20 69 73 20 73 65 74 20 74 6f 20 31 20 69 66  l is set to 1 if
13270 20 74 68 65 20 72 65 71 75 65 73 74 65 64 20 70   the requested p
13280 61 67 65 20 69 73 20 69 6e 20 74 68 65 20 57 41  age is in the WA
13290 4c 20 61 6e 64 0a 2a 2a 20 68 61 73 20 62 65 65  L and.** has bee
132a0 6e 20 6c 6f 61 64 65 64 2e 20 20 4f 72 20 2a 70  n loaded.  Or *p
132b0 49 6e 57 61 6c 20 69 73 20 73 65 74 20 74 6f 20  InWal is set to 
132c0 30 20 69 66 20 74 68 65 20 70 61 67 65 20 77 61  0 if the page wa
132d0 73 20 6e 6f 74 20 69 6e 20 0a 2a 2a 20 74 68 65  s not in .** the
132e0 20 57 41 4c 20 61 6e 64 20 6e 65 65 64 73 20 74   WAL and needs t
132f0 6f 20 62 65 20 72 65 61 64 20 6f 75 74 20 6f 66  o be read out of
13300 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a   the database..*
13310 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c  /.int sqlite3Wal
13320 52 65 61 64 28 0a 20 20 57 61 6c 20 2a 70 57 61  Read(.  Wal *pWa
13330 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l,              
13340 20 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 68          /* WAL h
13350 61 6e 64 6c 65 20 2a 2f 0a 20 20 50 67 6e 6f 20  andle */.  Pgno 
13360 70 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20  pgno,           
13370 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
13380 74 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62  tabase page numb
13390 65 72 20 74 6f 20 72 65 61 64 20 64 61 74 61 20  er to read data 
133a0 66 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 49  for */.  int *pI
133b0 6e 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20  nWal,           
133c0 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
133d0 20 54 72 75 65 20 69 66 20 64 61 74 61 20 69 73   True if data is
133e0 20 72 65 61 64 20 66 72 6f 6d 20 57 41 4c 20 2a   read from WAL *
133f0 2f 0a 20 20 69 6e 74 20 6e 4f 75 74 2c 20 20 20  /.  int nOut,   
13400 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
13410 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62      /* Size of b
13420 75 66 66 65 72 20 70 4f 75 74 20 69 6e 20 62 79  uffer pOut in by
13430 74 65 73 20 2a 2f 0a 20 20 75 38 20 2a 70 4f 75  tes */.  u8 *pOu
13440 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
13450 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66           /* Buff
13460 65 72 20 74 6f 20 77 72 69 74 65 20 70 61 67 65  er to write page
13470 20 64 61 74 61 20 74 6f 20 2a 2f 0a 29 7b 0a 20   data to */.){. 
13480 20 75 33 32 20 69 52 65 61 64 20 3d 20 30 3b 20   u32 iRead = 0; 
13490 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
134a0 20 2f 2a 20 49 66 20 21 3d 30 2c 20 57 41 4c 20   /* If !=0, WAL 
134b0 66 72 61 6d 65 20 74 6f 20 72 65 74 75 72 6e 20  frame to return 
134c0 64 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 75  data from */.  u
134d0 33 32 20 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d  32 iLast = pWal-
134e0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 20 20 2f  >hdr.mxFrame;  /
134f0 2a 20 4c 61 73 74 20 70 61 67 65 20 69 6e 20 57  * Last page in W
13500 41 4c 20 66 6f 72 20 74 68 69 73 20 72 65 61 64  AL for this read
13510 65 72 20 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73  er */.  int iHas
13520 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  h;              
13530 20 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20          /* Used 
13540 74 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20  to loop through 
13550 4e 20 68 61 73 68 20 74 61 62 6c 65 73 20 2a 2f  N hash tables */
13560 0a 0a 20 20 2f 2a 20 54 68 69 73 20 72 6f 75 74  ..  /* This rout
13570 69 6e 65 20 69 73 20 6f 6e 6c 79 20 62 65 20 63  ine is only be c
13580 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74 68 69  alled from withi
13590 6e 20 61 20 72 65 61 64 20 74 72 61 6e 73 61 63  n a read transac
135a0 74 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72  tion. */.  asser
135b0 74 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  t( pWal->readLoc
135c0 6b 3e 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f  k>=0 || pWal->lo
135d0 63 6b 45 72 72 6f 72 20 29 3b 0a 0a 20 20 2f 2a  ckError );..  /*
135e0 20 49 66 20 74 68 65 20 22 6c 61 73 74 20 70 61   If the "last pa
135f0 67 65 22 20 66 69 65 6c 64 20 6f 66 20 74 68 65  ge" field of the
13600 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65   wal-index heade
13610 72 20 73 6e 61 70 73 68 6f 74 20 69 73 20 30 2c  r snapshot is 0,
13620 20 74 68 65 6e 0a 20 20 2a 2a 20 6e 6f 20 64 61   then.  ** no da
13630 74 61 20 77 69 6c 6c 20 62 65 20 72 65 61 64 20  ta will be read 
13640 66 72 6f 6d 20 74 68 65 20 77 61 6c 20 75 6e 64  from the wal und
13650 65 72 20 61 6e 79 20 63 69 72 63 75 6d 73 74 61  er any circumsta
13660 6e 63 65 73 2e 20 52 65 74 75 72 6e 20 65 61 72  nces. Return ear
13670 6c 79 0a 20 20 2a 2a 20 69 6e 20 74 68 69 73 20  ly.  ** in this 
13680 63 61 73 65 20 61 73 20 61 6e 20 6f 70 74 69 6d  case as an optim
13690 69 7a 61 74 69 6f 6e 2e 20 20 4c 69 6b 65 77 69  ization.  Likewi
136a0 73 65 2c 20 69 66 20 70 57 61 6c 2d 3e 72 65 61  se, if pWal->rea
136b0 64 4c 6f 63 6b 3d 3d 30 2c 20 0a 20 20 2a 2a 20  dLock==0, .  ** 
136c0 74 68 65 6e 20 74 68 65 20 57 41 4c 20 69 73 20  then the WAL is 
136d0 69 67 6e 6f 72 65 64 20 62 79 20 74 68 65 20 72  ignored by the r
136e0 65 61 64 65 72 20 73 6f 20 72 65 74 75 72 6e 20  eader so return 
136f0 65 61 72 6c 79 2c 20 61 73 20 69 66 20 74 68 65  early, as if the
13700 20 0a 20 20 2a 2a 20 57 41 4c 20 77 65 72 65 20   .  ** WAL were 
13710 65 6d 70 74 79 2e 0a 20 20 2a 2f 0a 20 20 69 66  empty..  */.  if
13720 28 20 69 4c 61 73 74 3d 3d 30 20 7c 7c 20 70 57  ( iLast==0 || pW
13730 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 20  al->readLock==0 
13740 29 7b 0a 20 20 20 20 2a 70 49 6e 57 61 6c 20 3d  ){.    *pInWal =
13750 20 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   0;.    return S
13760 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20  QLITE_OK;.  }.. 
13770 20 2f 2a 20 53 65 61 72 63 68 20 74 68 65 20 68   /* Search the h
13780 61 73 68 20 74 61 62 6c 65 20 6f 72 20 74 61 62  ash table or tab
13790 6c 65 73 20 66 6f 72 20 61 6e 20 65 6e 74 72 79  les for an entry
137a0 20 6d 61 74 63 68 69 6e 67 20 70 61 67 65 20 6e   matching page n
137b0 75 6d 62 65 72 0a 20 20 2a 2a 20 70 67 6e 6f 2e  umber.  ** pgno.
137c0 20 45 61 63 68 20 69 74 65 72 61 74 69 6f 6e 20   Each iteration 
137d0 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  of the following
137e0 20 66 6f 72 28 29 20 6c 6f 6f 70 20 73 65 61 72   for() loop sear
137f0 63 68 65 73 20 6f 6e 65 0a 20 20 2a 2a 20 68 61  ches one.  ** ha
13800 73 68 20 74 61 62 6c 65 20 28 65 61 63 68 20 68  sh table (each h
13810 61 73 68 20 74 61 62 6c 65 20 69 6e 64 65 78 65  ash table indexe
13820 73 20 75 70 20 74 6f 20 48 41 53 48 54 41 42 4c  s up to HASHTABL
13830 45 5f 4e 50 41 47 45 20 66 72 61 6d 65 73 29 2e  E_NPAGE frames).
13840 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 69 73 20  .  **.  ** This 
13850 63 6f 64 65 20 6d 69 67 68 74 20 72 75 6e 20 63  code might run c
13860 6f 6e 63 75 72 72 65 6e 74 6c 79 20 74 6f 20 74  oncurrently to t
13870 68 65 20 63 6f 64 65 20 69 6e 20 77 61 6c 49 6e  he code in walIn
13880 64 65 78 41 70 70 65 6e 64 28 29 0a 20 20 2a 2a  dexAppend().  **
13890 20 74 68 61 74 20 61 64 64 73 20 65 6e 74 72 69   that adds entri
138a0 65 73 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e  es to the wal-in
138b0 64 65 78 20 28 61 6e 64 20 70 6f 73 73 69 62 6c  dex (and possibl
138c0 79 20 74 6f 20 74 68 69 73 20 68 61 73 68 20 0a  y to this hash .
138d0 20 20 2a 2a 20 74 61 62 6c 65 29 2e 20 54 68 69    ** table). Thi
138e0 73 20 6d 65 61 6e 73 20 74 68 65 20 76 61 6c 75  s means the valu
138f0 65 20 6a 75 73 74 20 72 65 61 64 20 66 72 6f 6d  e just read from
13900 20 74 68 65 20 68 61 73 68 20 0a 20 20 2a 2a 20   the hash .  ** 
13910 73 6c 6f 74 20 28 61 48 61 73 68 5b 69 4b 65 79  slot (aHash[iKey
13920 5d 29 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e  ]) may have been
13930 20 61 64 64 65 64 20 62 65 66 6f 72 65 20 6f 72   added before or
13940 20 61 66 74 65 72 20 74 68 65 20 0a 20 20 2a 2a   after the .  **
13950 20 63 75 72 72 65 6e 74 20 72 65 61 64 20 74 72   current read tr
13960 61 6e 73 61 63 74 69 6f 6e 20 77 61 73 20 6f 70  ansaction was op
13970 65 6e 65 64 2e 20 56 61 6c 75 65 73 20 61 64 64  ened. Values add
13980 65 64 20 61 66 74 65 72 20 74 68 65 0a 20 20 2a  ed after the.  *
13990 2a 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  * read transacti
139a0 6f 6e 20 77 61 73 20 6f 70 65 6e 65 64 20 6d 61  on was opened ma
139b0 79 20 68 61 76 65 20 62 65 65 6e 20 77 72 69 74  y have been writ
139c0 74 65 6e 20 69 6e 63 6f 72 72 65 63 74 6c 79 20  ten incorrectly 
139d0 2d 0a 20 20 2a 2a 20 69 2e 65 2e 20 74 68 65 73  -.  ** i.e. thes
139e0 65 20 73 6c 6f 74 73 20 6d 61 79 20 63 6f 6e 74  e slots may cont
139f0 61 69 6e 20 67 61 72 62 61 67 65 20 64 61 74 61  ain garbage data
13a00 2e 20 48 6f 77 65 76 65 72 2c 20 77 65 20 61 73  . However, we as
13a10 73 75 6d 65 0a 20 20 2a 2a 20 74 68 61 74 20 61  sume.  ** that a
13a20 6e 79 20 73 6c 6f 74 73 20 77 72 69 74 74 65 6e  ny slots written
13a30 20 62 65 66 6f 72 65 20 74 68 65 20 63 75 72 72   before the curr
13a40 65 6e 74 20 72 65 61 64 20 74 72 61 6e 73 61 63  ent read transac
13a50 74 69 6f 6e 20 77 61 73 0a 20 20 2a 2a 20 6f 70  tion was.  ** op
13a60 65 6e 65 64 20 72 65 6d 61 69 6e 20 75 6e 6d 6f  ened remain unmo
13a70 64 69 66 69 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a  dified..  **.  *
13a80 2a 20 46 6f 72 20 74 68 65 20 72 65 61 73 6f 6e  * For the reason
13a90 73 20 61 62 6f 76 65 2c 20 74 68 65 20 69 66 28  s above, the if(
13aa0 2e 2e 2e 29 20 63 6f 6e 64 69 74 69 6f 6e 20 66  ...) condition f
13ab0 65 61 74 75 72 65 64 20 69 6e 20 74 68 65 20 69  eatured in the i
13ac0 6e 6e 65 72 0a 20 20 2a 2a 20 6c 6f 6f 70 20 6f  nner.  ** loop o
13ad0 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
13ae0 62 6c 6f 63 6b 20 69 73 20 6d 6f 72 65 20 73 74  block is more st
13af0 72 69 6e 67 65 6e 74 20 74 68 61 74 20 77 6f 75  ringent that wou
13b00 6c 64 20 62 65 20 72 65 71 75 69 72 65 64 20 0a  ld be required .
13b10 20 20 2a 2a 20 69 66 20 77 65 20 68 61 64 20 65    ** if we had e
13b20 78 63 6c 75 73 69 76 65 20 61 63 63 65 73 73 20  xclusive access 
13b30 74 6f 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c  to the hash-tabl
13b40 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 28  e:.  **.  **   (
13b50 61 50 67 6e 6f 5b 69 46 72 61 6d 65 5d 3d 3d 70  aPgno[iFrame]==p
13b60 67 6e 6f 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20  gno): .  **     
13b70 54 68 69 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66  This condition f
13b80 69 6c 74 65 72 73 20 6f 75 74 20 6e 6f 72 6d 61  ilters out norma
13b90 6c 20 68 61 73 68 2d 74 61 62 6c 65 20 63 6f 6c  l hash-table col
13ba0 6c 69 73 69 6f 6e 73 2e 0a 20 20 2a 2a 0a 20 20  lisions..  **.  
13bb0 2a 2a 20 20 20 28 69 46 72 61 6d 65 3c 3d 69 4c  **   (iFrame<=iL
13bc0 61 73 74 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20  ast): .  **     
13bd0 54 68 69 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66  This condition f
13be0 69 6c 74 65 72 73 20 6f 75 74 20 65 6e 74 72 69  ilters out entri
13bf0 65 73 20 74 68 61 74 20 77 65 72 65 20 61 64 64  es that were add
13c00 65 64 20 74 6f 20 74 68 65 20 68 61 73 68 0a 20  ed to the hash. 
13c10 20 2a 2a 20 20 20 20 20 74 61 62 6c 65 20 61 66   **     table af
13c20 74 65 72 20 74 68 65 20 63 75 72 72 65 6e 74 20  ter the current 
13c30 72 65 61 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e  read-transaction
13c40 20 68 61 64 20 73 74 61 72 74 65 64 2e 0a 20 20   had started..  
13c50 2a 2f 0a 20 20 66 6f 72 28 69 48 61 73 68 3d 77  */.  for(iHash=w
13c60 61 6c 46 72 61 6d 65 50 61 67 65 28 69 4c 61 73  alFramePage(iLas
13c70 74 29 3b 20 69 48 61 73 68 3e 3d 30 20 26 26 20  t); iHash>=0 && 
13c80 69 52 65 61 64 3d 3d 30 3b 20 69 48 61 73 68 2d  iRead==0; iHash-
13c90 2d 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65  -){.    volatile
13ca0 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b   ht_slot *aHash;
13cb0 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
13cc0 20 74 6f 20 68 61 73 68 20 74 61 62 6c 65 20 2a   to hash table *
13cd0 2f 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75  /.    volatile u
13ce0 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20  32 *aPgno;      
13cf0 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
13d00 6f 20 61 72 72 61 79 20 6f 66 20 70 61 67 65 20  o array of page 
13d10 6e 75 6d 62 65 72 73 20 2a 2f 0a 20 20 20 20 75  numbers */.    u
13d20 33 32 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20  32 iZero;       
13d30 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
13d40 46 72 61 6d 65 20 6e 75 6d 62 65 72 20 63 6f 72  Frame number cor
13d50 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 61 50  responding to aP
13d60 67 6e 6f 5b 30 5d 20 2a 2f 0a 20 20 20 20 69 6e  gno[0] */.    in
13d70 74 20 69 4b 65 79 3b 20 20 20 20 20 20 20 20 20  t iKey;         
13d80 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48              /* H
13d90 61 73 68 20 73 6c 6f 74 20 69 6e 64 65 78 20 2a  ash slot index *
13da0 2f 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a 0a 20  /.    int rc;.. 
13db0 20 20 20 72 63 20 3d 20 77 61 6c 48 61 73 68 47     rc = walHashG
13dc0 65 74 28 70 57 61 6c 2c 20 69 48 61 73 68 2c 20  et(pWal, iHash, 
13dd0 26 61 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20  &aHash, &aPgno, 
13de0 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20 69 66 28  &iZero);.    if(
13df0 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
13e00 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72  {.      return r
13e10 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72  c;.    }.    for
13e20 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 70 67  (iKey=walHash(pg
13e30 6e 6f 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  no); aHash[iKey]
13e40 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
13e50 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
13e60 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20 61 48   u32 iFrame = aH
13e70 61 73 68 5b 69 4b 65 79 5d 20 2b 20 69 5a 65 72  ash[iKey] + iZer
13e80 6f 3b 0a 20 20 20 20 20 20 69 66 28 20 69 46 72  o;.      if( iFr
13e90 61 6d 65 3c 3d 69 4c 61 73 74 20 26 26 20 61 50  ame<=iLast && aP
13ea0 67 6e 6f 5b 61 48 61 73 68 5b 69 4b 65 79 5d 5d  gno[aHash[iKey]]
13eb0 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20  ==pgno ){.      
13ec0 20 20 61 73 73 65 72 74 28 20 69 46 72 61 6d 65    assert( iFrame
13ed0 3e 69 52 65 61 64 20 29 3b 0a 20 20 20 20 20 20  >iRead );.      
13ee0 20 20 69 52 65 61 64 20 3d 20 69 46 72 61 6d 65    iRead = iFrame
13ef0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
13f00 20 20 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49    }..#ifdef SQLI
13f10 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53  TE_ENABLE_EXPENS
13f20 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20  IVE_ASSERT.  /* 
13f30 49 66 20 65 78 70 65 6e 73 69 76 65 20 61 73 73  If expensive ass
13f40 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74 73  ert() statements
13f50 20 61 72 65 20 61 76 61 69 6c 61 62 6c 65 2c 20   are available, 
13f60 64 6f 20 61 20 6c 69 6e 65 61 72 20 73 65 61 72  do a linear sear
13f70 63 68 0a 20 20 2a 2a 20 6f 66 20 74 68 65 20 77  ch.  ** of the w
13f80 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20 63 6f  al-index file co
13f90 6e 74 65 6e 74 2e 20 4d 61 6b 65 20 73 75 72 65  ntent. Make sure
13fa0 20 74 68 65 20 72 65 73 75 6c 74 73 20 61 67 72   the results agr
13fb0 65 65 20 77 69 74 68 20 74 68 65 0a 20 20 2a 2a  ee with the.  **
13fc0 20 72 65 73 75 6c 74 20 6f 62 74 61 69 6e 65 64   result obtained
13fd0 20 75 73 69 6e 67 20 74 68 65 20 68 61 73 68 20   using the hash 
13fe0 69 6e 64 65 78 65 73 20 61 62 6f 76 65 2e 20 20  indexes above.  
13ff0 2a 2f 0a 20 20 7b 0a 20 20 20 20 75 33 32 20 69  */.  {.    u32 i
14000 52 65 61 64 32 20 3d 20 30 3b 0a 20 20 20 20 75  Read2 = 0;.    u
14010 33 32 20 69 54 65 73 74 3b 0a 20 20 20 20 66 6f  32 iTest;.    fo
14020 72 28 69 54 65 73 74 3d 69 4c 61 73 74 3b 20 69  r(iTest=iLast; i
14030 54 65 73 74 3e 30 3b 20 69 54 65 73 74 2d 2d 29  Test>0; iTest--)
14040 7b 0a 20 20 20 20 20 20 69 66 28 20 77 61 6c 46  {.      if( walF
14050 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69  ramePgno(pWal, i
14060 54 65 73 74 29 3d 3d 70 67 6e 6f 20 29 7b 0a 20  Test)==pgno ){. 
14070 20 20 20 20 20 20 20 69 52 65 61 64 32 20 3d 20         iRead2 = 
14080 69 54 65 73 74 3b 0a 20 20 20 20 20 20 20 20 62  iTest;.        b
14090 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
140a0 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20    }.    assert( 
140b0 69 52 65 61 64 3d 3d 69 52 65 61 64 32 20 29 3b  iRead==iRead2 );
140c0 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2f  .  }.#endif..  /
140d0 2a 20 49 66 20 69 52 65 61 64 20 69 73 20 6e 6f  * If iRead is no
140e0 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 69 74 20  n-zero, then it 
140f0 69 73 20 74 68 65 20 6c 6f 67 20 66 72 61 6d 65  is the log frame
14100 20 6e 75 6d 62 65 72 20 74 68 61 74 20 63 6f 6e   number that con
14110 74 61 69 6e 73 20 74 68 65 0a 20 20 2a 2a 20 72  tains the.  ** r
14120 65 71 75 69 72 65 64 20 70 61 67 65 2e 20 52 65  equired page. Re
14130 61 64 20 61 6e 64 20 72 65 74 75 72 6e 20 64 61  ad and return da
14140 74 61 20 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20  ta from the log 
14150 66 69 6c 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  file..  */.  if(
14160 20 69 52 65 61 64 20 29 7b 0a 20 20 20 20 69 36   iRead ){.    i6
14170 34 20 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46  4 iOffset = walF
14180 72 61 6d 65 4f 66 66 73 65 74 28 69 52 65 61 64  rameOffset(iRead
14190 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61  , pWal->hdr.szPa
141a0 67 65 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  ge) + WAL_FRAME_
141b0 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 2a 70 49  HDRSIZE;.    *pI
141c0 6e 57 61 6c 20 3d 20 31 3b 0a 20 20 20 20 72 65  nWal = 1;.    re
141d0 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52 65  turn sqlite3OsRe
141e0 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  ad(pWal->pWalFd,
141f0 20 70 4f 75 74 2c 20 6e 4f 75 74 2c 20 69 4f 66   pOut, nOut, iOf
14200 66 73 65 74 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70  fset);.  }..  *p
14210 49 6e 57 61 6c 20 3d 20 30 3b 0a 20 20 72 65 74  InWal = 0;.  ret
14220 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
14230 0a 0a 0a 2f 2a 20 0a 2a 2a 20 53 65 74 20 2a 70  .../* .** Set *p
14240 50 67 6e 6f 20 74 6f 20 74 68 65 20 73 69 7a 65  Pgno to the size
14250 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65   of the database
14260 20 66 69 6c 65 20 28 6f 72 20 7a 65 72 6f 2c 20   file (or zero, 
14270 69 66 20 75 6e 6b 6e 6f 77 6e 29 2e 0a 2a 2f 0a  if unknown)..*/.
14280 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 44  void sqlite3WalD
14290 62 73 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c 2c  bsize(Wal *pWal,
142a0 20 50 67 6e 6f 20 2a 70 50 67 6e 6f 29 7b 0a 20   Pgno *pPgno){. 
142b0 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72   assert( pWal->r
142c0 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70 57  eadLock>=0 || pW
142d0 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 29 3b  al->lockError );
142e0 0a 20 20 2a 70 50 67 6e 6f 20 3d 20 70 57 61 6c  .  *pPgno = pWal
142f0 2d 3e 68 64 72 2e 6e 50 61 67 65 3b 0a 7d 0a 0a  ->hdr.nPage;.}..
14300 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ./* .** This fun
14310 63 74 69 6f 6e 20 73 74 61 72 74 73 20 61 20 77  ction starts a w
14320 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  rite transaction
14330 20 6f 6e 20 74 68 65 20 57 41 4c 2e 0a 2a 2a 0a   on the WAL..**.
14340 2a 2a 20 41 20 72 65 61 64 20 74 72 61 6e 73 61  ** A read transa
14350 63 74 69 6f 6e 20 6d 75 73 74 20 68 61 76 65 20  ction must have 
14360 61 6c 72 65 61 64 79 20 62 65 65 6e 20 73 74 61  already been sta
14370 72 74 65 64 20 62 79 20 61 20 70 72 69 6f 72 20  rted by a prior 
14380 63 61 6c 6c 0a 2a 2a 20 74 6f 20 73 71 6c 69 74  call.** to sqlit
14390 65 33 57 61 6c 42 65 67 69 6e 52 65 61 64 54 72  e3WalBeginReadTr
143a0 61 6e 73 61 63 74 69 6f 6e 28 29 2e 0a 2a 2a 0a  ansaction()..**.
143b0 2a 2a 20 49 66 20 61 6e 6f 74 68 65 72 20 74 68  ** If another th
143c0 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 20  read or process 
143d0 68 61 73 20 77 72 69 74 74 65 6e 20 69 6e 74 6f  has written into
143e0 20 74 68 65 20 64 61 74 61 62 61 73 65 20 73 69   the database si
143f0 6e 63 65 0a 2a 2a 20 74 68 65 20 72 65 61 64 20  nce.** the read 
14400 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61 73 20  transaction was 
14410 73 74 61 72 74 65 64 2c 20 74 68 65 6e 20 69 74  started, then it
14420 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65   is not possible
14430 20 66 6f 72 20 74 68 69 73 0a 2a 2a 20 74 68 72   for this.** thr
14440 65 61 64 20 74 6f 20 77 72 69 74 65 20 61 73 20  ead to write as 
14450 64 6f 69 6e 67 20 73 6f 20 77 6f 75 6c 64 20 63  doing so would c
14460 61 75 73 65 20 61 20 66 6f 72 6b 2e 20 20 53 6f  ause a fork.  So
14470 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a   this routine.**
14480 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f   returns SQLITE_
14490 42 55 53 59 20 69 6e 20 74 68 61 74 20 63 61 73  BUSY in that cas
144a0 65 20 61 6e 64 20 6e 6f 20 77 72 69 74 65 20 74  e and no write t
144b0 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20 73 74  ransaction is st
144c0 61 72 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  arted..**.** The
144d0 72 65 20 63 61 6e 20 6f 6e 6c 79 20 62 65 20 61  re can only be a
144e0 20 73 69 6e 67 6c 65 20 77 72 69 74 65 72 20 61   single writer a
144f0 63 74 69 76 65 20 61 74 20 61 20 74 69 6d 65 2e  ctive at a time.
14500 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
14510 61 6c 42 65 67 69 6e 57 72 69 74 65 54 72 61 6e  alBeginWriteTran
14520 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61  saction(Wal *pWa
14530 6c 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20  l){.  int rc;.. 
14540 20 2f 2a 20 43 61 6e 6e 6f 74 20 73 74 61 72 74   /* Cannot start
14550 20 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63   a write transac
14560 74 69 6f 6e 20 77 69 74 68 6f 75 74 20 66 69 72  tion without fir
14570 73 74 20 68 6f 6c 64 69 6e 67 20 61 20 72 65 61  st holding a rea
14580 64 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63 74 69  d.  ** transacti
14590 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  on. */.  assert(
145a0 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e   pWal->readLock>
145b0 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 4f 6e 6c 79  =0 );..  /* Only
145c0 20 6f 6e 65 20 77 72 69 74 65 72 20 61 6c 6c 6f   one writer allo
145d0 77 65 64 20 61 74 20 61 20 74 69 6d 65 2e 20 20  wed at a time.  
145e0 47 65 74 20 74 68 65 20 77 72 69 74 65 20 6c 6f  Get the write lo
145f0 63 6b 2e 20 20 52 65 74 75 72 6e 0a 20 20 2a 2a  ck.  Return.  **
14600 20 53 51 4c 49 54 45 5f 42 55 53 59 20 69 66 20   SQLITE_BUSY if 
14610 75 6e 61 62 6c 65 2e 0a 20 20 2a 2f 0a 20 20 72  unable..  */.  r
14620 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75  c = walLockExclu
14630 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57  sive(pWal, WAL_W
14640 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  RITE_LOCK, 1);. 
14650 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 72   if( rc ){.    r
14660 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20  eturn rc;.  }.  
14670 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
14680 3d 20 31 3b 0a 0a 20 20 2f 2a 20 49 66 20 61 6e  = 1;..  /* If an
14690 6f 74 68 65 72 20 63 6f 6e 6e 65 63 74 69 6f 6e  other connection
146a0 20 68 61 73 20 77 72 69 74 74 65 6e 20 74 6f 20   has written to 
146b0 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
146c0 65 20 73 69 6e 63 65 20 74 68 65 0a 20 20 2a 2a  e since the.  **
146d0 20 74 69 6d 65 20 74 68 65 20 72 65 61 64 20 74   time the read t
146e0 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68  ransaction on th
146f0 69 73 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 77 61  is connection wa
14700 73 20 73 74 61 72 74 65 64 2c 20 74 68 65 6e 0a  s started, then.
14710 20 20 2a 2a 20 74 68 65 20 77 72 69 74 65 20 69    ** the write i
14720 73 20 64 69 73 61 6c 6c 6f 77 65 64 2e 0a 20 20  s disallowed..  
14730 2a 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28  */.  if( memcmp(
14740 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69  &pWal->hdr, (voi
14750 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28  d *)walIndexHdr(
14760 70 57 61 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61  pWal), sizeof(Wa
14770 6c 49 6e 64 65 78 48 64 72 29 29 21 3d 30 20 29  lIndexHdr))!=0 )
14780 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45  {.    walUnlockE
14790 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
147a0 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31  AL_WRITE_LOCK, 1
147b0 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72 69  );.    pWal->wri
147c0 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20  teLock = 0;.    
147d0 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55 53 59  rc = SQLITE_BUSY
147e0 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
147f0 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 64  rc;.}../*.** End
14800 20 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63   a write transac
14810 74 69 6f 6e 2e 20 20 54 68 65 20 63 6f 6d 6d 69  tion.  The commi
14820 74 20 68 61 73 20 61 6c 72 65 61 64 79 20 62 65  t has already be
14830 65 6e 20 64 6f 6e 65 2e 20 20 54 68 69 73 0a 2a  en done.  This.*
14840 2a 20 72 6f 75 74 69 6e 65 20 6d 65 72 65 6c 79  * routine merely
14850 20 72 65 6c 65 61 73 65 73 20 74 68 65 20 6c 6f   releases the lo
14860 63 6b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ck..*/.int sqlit
14870 65 33 57 61 6c 45 6e 64 57 72 69 74 65 54 72 61  e3WalEndWriteTra
14880 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57  nsaction(Wal *pW
14890 61 6c 29 7b 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b  al){.  walUnlock
148a0 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
148b0 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20  WAL_WRITE_LOCK, 
148c0 31 29 3b 0a 20 20 70 57 61 6c 2d 3e 77 72 69 74  1);.  pWal->writ
148d0 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 72 65 74  eLock = 0;.  ret
148e0 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
148f0 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 61 6e 79 20 64  ../*.** If any d
14900 61 74 61 20 68 61 73 20 62 65 65 6e 20 77 72 69  ata has been wri
14910 74 74 65 6e 20 28 62 75 74 20 6e 6f 74 20 63 6f  tten (but not co
14920 6d 6d 69 74 74 65 64 29 20 74 6f 20 74 68 65 20  mmitted) to the 
14930 6c 6f 67 20 66 69 6c 65 2c 20 74 68 69 73 0a 2a  log file, this.*
14940 2a 20 66 75 6e 63 74 69 6f 6e 20 6d 6f 76 65 73  * function moves
14950 20 74 68 65 20 77 72 69 74 65 2d 70 6f 69 6e 74   the write-point
14960 65 72 20 62 61 63 6b 20 74 6f 20 74 68 65 20 73  er back to the s
14970 74 61 72 74 20 6f 66 20 74 68 65 20 74 72 61 6e  tart of the tran
14980 73 61 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41  saction..**.** A
14990 64 64 69 74 69 6f 6e 61 6c 6c 79 2c 20 74 68 65  dditionally, the
149a0 20 63 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69   callback functi
149b0 6f 6e 20 69 73 20 69 6e 76 6f 6b 65 64 20 66 6f  on is invoked fo
149c0 72 20 65 61 63 68 20 66 72 61 6d 65 20 77 72 69  r each frame wri
149d0 74 74 65 6e 0a 2a 2a 20 74 6f 20 74 68 65 20 57  tten.** to the W
149e0 41 4c 20 73 69 6e 63 65 20 74 68 65 20 73 74 61  AL since the sta
149f0 72 74 20 6f 66 20 74 68 65 20 74 72 61 6e 73 61  rt of the transa
14a00 63 74 69 6f 6e 2e 20 49 66 20 74 68 65 20 63 61  ction. If the ca
14a10 6c 6c 62 61 63 6b 20 72 65 74 75 72 6e 73 0a 2a  llback returns.*
14a20 2a 20 6f 74 68 65 72 20 74 68 61 6e 20 53 51 4c  * other than SQL
14a30 49 54 45 5f 4f 4b 2c 20 69 74 20 69 73 20 6e 6f  ITE_OK, it is no
14a40 74 20 69 6e 76 6f 6b 65 64 20 61 67 61 69 6e 20  t invoked again 
14a50 61 6e 64 20 74 68 65 20 65 72 72 6f 72 20 63 6f  and the error co
14a60 64 65 20 69 73 0a 2a 2a 20 72 65 74 75 72 6e 65  de is.** returne
14a70 64 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e  d to the caller.
14a80 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  .**.** Otherwise
14a90 2c 20 69 66 20 74 68 65 20 63 61 6c 6c 62 61 63  , if the callbac
14aa0 6b 20 66 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20  k function does 
14ab0 6e 6f 74 20 72 65 74 75 72 6e 20 61 6e 20 65 72  not return an er
14ac0 72 6f 72 2c 20 74 68 69 73 0a 2a 2a 20 66 75 6e  ror, this.** fun
14ad0 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 53 51  ction returns SQ
14ae0 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20  LITE_OK..*/.int 
14af0 73 71 6c 69 74 65 33 57 61 6c 55 6e 64 6f 28 57  sqlite3WalUndo(W
14b00 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 28 2a  al *pWal, int (*
14b10 78 55 6e 64 6f 29 28 76 6f 69 64 20 2a 2c 20 50  xUndo)(void *, P
14b20 67 6e 6f 29 2c 20 76 6f 69 64 20 2a 70 55 6e 64  gno), void *pUnd
14b30 6f 43 74 78 29 7b 0a 20 20 69 6e 74 20 72 63 20  oCtx){.  int rc 
14b40 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
14b50 66 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  f( pWal->writeLo
14b60 63 6b 20 29 7b 0a 20 20 20 20 50 67 6e 6f 20 69  ck ){.    Pgno i
14b70 4d 61 78 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  Max = pWal->hdr.
14b80 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 50 67 6e  mxFrame;.    Pgn
14b90 6f 20 69 46 72 61 6d 65 3b 0a 20 20 0a 20 20 20  o iFrame;.  .   
14ba0 20 2f 2a 20 52 65 73 74 6f 72 65 20 74 68 65 20   /* Restore the 
14bb0 63 6c 69 65 6e 74 73 20 63 61 63 68 65 20 6f 66  clients cache of
14bc0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
14bd0 65 61 64 65 72 20 74 6f 20 74 68 65 20 73 74 61  eader to the sta
14be0 74 65 20 69 74 0a 20 20 20 20 2a 2a 20 77 61 73  te it.    ** was
14bf0 20 69 6e 20 62 65 66 6f 72 65 20 74 68 65 20 63   in before the c
14c00 6c 69 65 6e 74 20 62 65 67 61 6e 20 77 72 69 74  lient began writ
14c10 69 6e 67 20 74 6f 20 74 68 65 20 64 61 74 61 62  ing to the datab
14c20 61 73 65 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20  ase. .    */.   
14c30 20 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68   memcpy(&pWal->h
14c40 64 72 2c 20 28 76 6f 69 64 20 2a 29 77 61 6c 49  dr, (void *)walI
14c50 6e 64 65 78 48 64 72 28 70 57 61 6c 29 2c 20 73  ndexHdr(pWal), s
14c60 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64  izeof(WalIndexHd
14c70 72 29 29 3b 0a 0a 20 20 20 20 66 6f 72 28 69 46  r));..    for(iF
14c80 72 61 6d 65 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d  rame=pWal->hdr.m
14c90 78 46 72 61 6d 65 2b 31 3b 20 0a 20 20 20 20 20  xFrame+1; .     
14ca0 20 20 20 41 4c 57 41 59 53 28 72 63 3d 3d 53 51     ALWAYS(rc==SQ
14cb0 4c 49 54 45 5f 4f 4b 29 20 26 26 20 69 46 72 61  LITE_OK) && iFra
14cc0 6d 65 3c 3d 69 4d 61 78 3b 20 0a 20 20 20 20 20  me<=iMax; .     
14cd0 20 20 20 69 46 72 61 6d 65 2b 2b 0a 20 20 20 20     iFrame++.    
14ce0 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73  ){.      /* This
14cf0 20 63 61 6c 6c 20 63 61 6e 6e 6f 74 20 66 61 69   call cannot fai
14d00 6c 2e 20 55 6e 6c 65 73 73 20 74 68 65 20 70 61  l. Unless the pa
14d10 67 65 20 66 6f 72 20 77 68 69 63 68 20 74 68 65  ge for which the
14d20 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 20 20 20   page number.   
14d30 20 20 20 2a 2a 20 69 73 20 70 61 73 73 65 64 20     ** is passed 
14d40 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72  as the second ar
14d50 67 75 6d 65 6e 74 20 69 73 20 28 61 29 20 69 6e  gument is (a) in
14d60 20 74 68 65 20 63 61 63 68 65 20 61 6e 64 20 0a   the cache and .
14d70 20 20 20 20 20 20 2a 2a 20 28 62 29 20 68 61 73        ** (b) has
14d80 20 61 6e 20 6f 75 74 73 74 61 6e 64 69 6e 67 20   an outstanding 
14d90 72 65 66 65 72 65 6e 63 65 2c 20 74 68 65 6e 20  reference, then 
14da0 78 55 6e 64 6f 20 69 73 20 65 69 74 68 65 72 20  xUndo is either 
14db0 61 20 6e 6f 2d 6f 70 0a 20 20 20 20 20 20 2a 2a  a no-op.      **
14dc0 20 28 69 66 20 28 61 29 20 69 73 20 66 61 6c 73   (if (a) is fals
14dd0 65 29 20 6f 72 20 73 69 6d 70 6c 79 20 65 78 70  e) or simply exp
14de0 65 6c 73 20 74 68 65 20 70 61 67 65 20 66 72 6f  els the page fro
14df0 6d 20 74 68 65 20 63 61 63 68 65 20 28 69 66 20  m the cache (if 
14e00 28 62 29 0a 20 20 20 20 20 20 2a 2a 20 69 73 20  (b).      ** is 
14e10 66 61 6c 73 65 29 2e 0a 20 20 20 20 20 20 2a 2a  false)..      **
14e20 0a 20 20 20 20 20 20 2a 2a 20 49 66 20 74 68 65  .      ** If the
14e30 20 75 70 70 65 72 20 6c 61 79 65 72 20 69 73 20   upper layer is 
14e40 64 6f 69 6e 67 20 61 20 72 6f 6c 6c 62 61 63 6b  doing a rollback
14e50 2c 20 69 74 20 69 73 20 67 75 61 72 61 6e 74 65  , it is guarante
14e60 65 64 20 74 68 61 74 20 74 68 65 72 65 0a 20 20  ed that there.  
14e70 20 20 20 20 2a 2a 20 61 72 65 20 6e 6f 20 6f 75      ** are no ou
14e80 74 73 74 61 6e 64 69 6e 67 20 72 65 66 65 72 65  tstanding refere
14e90 6e 63 65 73 20 74 6f 20 61 6e 79 20 70 61 67 65  nces to any page
14ea0 20 6f 74 68 65 72 20 74 68 61 6e 20 70 61 67 65   other than page
14eb0 20 31 2e 20 41 6e 64 0a 20 20 20 20 20 20 2a 2a   1. And.      **
14ec0 20 70 61 67 65 20 31 20 69 73 20 6e 65 76 65 72   page 1 is never
14ed0 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20   written to the 
14ee0 6c 6f 67 20 75 6e 74 69 6c 20 74 68 65 20 74 72  log until the tr
14ef0 61 6e 73 61 63 74 69 6f 6e 20 69 73 0a 20 20 20  ansaction is.   
14f00 20 20 20 2a 2a 20 63 6f 6d 6d 69 74 74 65 64 2e     ** committed.
14f10 20 41 73 20 61 20 72 65 73 75 6c 74 2c 20 74 68   As a result, th
14f20 65 20 63 61 6c 6c 20 74 6f 20 78 55 6e 64 6f 20  e call to xUndo 
14f30 6d 61 79 20 6e 6f 74 20 66 61 69 6c 2e 0a 20 20  may not fail..  
14f40 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 61 73 73      */.      ass
14f50 65 72 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e  ert( walFramePgn
14f60 6f 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 21  o(pWal, iFrame)!
14f70 3d 31 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  =1 );.      rc =
14f80 20 78 55 6e 64 6f 28 70 55 6e 64 6f 43 74 78 2c   xUndo(pUndoCtx,
14f90 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57   walFramePgno(pW
14fa0 61 6c 2c 20 69 46 72 61 6d 65 29 29 3b 0a 20 20  al, iFrame));.  
14fb0 20 20 7d 0a 20 20 20 20 77 61 6c 43 6c 65 61 6e    }.    walClean
14fc0 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20  upHash(pWal);.  
14fd0 7d 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d  }.  assert( rc==
14fe0 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72  SQLITE_OK );.  r
14ff0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
15000 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 61 57 61  .** Argument aWa
15010 6c 44 61 74 61 20 6d 75 73 74 20 70 6f 69 6e 74  lData must point
15020 20 74 6f 20 61 6e 20 61 72 72 61 79 20 6f 66 20   to an array of 
15030 57 41 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44  WAL_SAVEPOINT_ND
15040 41 54 41 20 75 33 32 20 0a 2a 2a 20 76 61 6c 75  ATA u32 .** valu
15050 65 73 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  es. This functio
15060 6e 20 70 6f 70 75 6c 61 74 65 73 20 74 68 65 20  n populates the 
15070 61 72 72 61 79 20 77 69 74 68 20 76 61 6c 75 65  array with value
15080 73 20 72 65 71 75 69 72 65 64 20 74 6f 20 0a 2a  s required to .*
15090 2a 20 22 72 6f 6c 6c 62 61 63 6b 22 20 74 68 65  * "rollback" the
150a0 20 77 72 69 74 65 20 70 6f 73 69 74 69 6f 6e 20   write position 
150b0 6f 66 20 74 68 65 20 57 41 4c 20 68 61 6e 64 6c  of the WAL handl
150c0 65 20 62 61 63 6b 20 74 6f 20 74 68 65 20 63 75  e back to the cu
150d0 72 72 65 6e 74 20 0a 2a 2a 20 70 6f 69 6e 74 20  rrent .** point 
150e0 69 6e 20 74 68 65 20 65 76 65 6e 74 20 6f 66 20  in the event of 
150f0 61 20 73 61 76 65 70 6f 69 6e 74 20 72 6f 6c 6c  a savepoint roll
15100 62 61 63 6b 20 28 76 69 61 20 57 61 6c 53 61 76  back (via WalSav
15110 65 70 6f 69 6e 74 55 6e 64 6f 28 29 29 2e 0a 2a  epointUndo())..*
15120 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61  /.void sqlite3Wa
15130 6c 53 61 76 65 70 6f 69 6e 74 28 57 61 6c 20 2a  lSavepoint(Wal *
15140 70 57 61 6c 2c 20 75 33 32 20 2a 61 57 61 6c 44  pWal, u32 *aWalD
15150 61 74 61 29 7b 0a 20 20 61 73 73 65 72 74 28 20  ata){.  assert( 
15160 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
15170 29 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 30 5d  );.  aWalData[0]
15180 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46   = pWal->hdr.mxF
15190 72 61 6d 65 3b 0a 20 20 61 57 61 6c 44 61 74 61  rame;.  aWalData
151a0 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  [1] = pWal->hdr.
151b0 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a  aFrameCksum[0];.
151c0 20 20 61 57 61 6c 44 61 74 61 5b 32 5d 20 3d 20    aWalData[2] = 
151d0 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
151e0 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 61 57 61 6c  Cksum[1];.  aWal
151f0 44 61 74 61 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e  Data[3] = pWal->
15200 6e 43 6b 70 74 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  nCkpt;.}../* .**
15210 20 4d 6f 76 65 20 74 68 65 20 77 72 69 74 65 20   Move the write 
15220 70 6f 73 69 74 69 6f 6e 20 6f 66 20 74 68 65 20  position of the 
15230 57 41 4c 20 62 61 63 6b 20 74 6f 20 74 68 65 20  WAL back to the 
15240 70 6f 69 6e 74 20 69 64 65 6e 74 69 66 69 65 64  point identified
15250 20 62 79 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65   by.** the value
15260 73 20 69 6e 20 74 68 65 20 61 57 61 6c 44 61 74  s in the aWalDat
15270 61 5b 5d 20 61 72 72 61 79 2e 20 61 57 61 6c 44  a[] array. aWalD
15280 61 74 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74  ata must point t
15290 6f 20 61 6e 20 61 72 72 61 79 0a 2a 2a 20 6f 66  o an array.** of
152a0 20 57 41 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e   WAL_SAVEPOINT_N
152b0 44 41 54 41 20 75 33 32 20 76 61 6c 75 65 73 20  DATA u32 values 
152c0 74 68 61 74 20 68 61 73 20 62 65 65 6e 20 70 72  that has been pr
152d0 65 76 69 6f 75 73 6c 79 20 70 6f 70 75 6c 61 74  eviously populat
152e0 65 64 0a 2a 2a 20 62 79 20 61 20 63 61 6c 6c 20  ed.** by a call 
152f0 74 6f 20 57 61 6c 53 61 76 65 70 6f 69 6e 74 28  to WalSavepoint(
15300 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  )..*/.int sqlite
15310 33 57 61 6c 53 61 76 65 70 6f 69 6e 74 55 6e 64  3WalSavepointUnd
15320 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32  o(Wal *pWal, u32
15330 20 2a 61 57 61 6c 44 61 74 61 29 7b 0a 20 20 69   *aWalData){.  i
15340 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
15350 4b 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57  K;..  assert( pW
15360 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
15370 0a 20 20 61 73 73 65 72 74 28 20 61 57 61 6c 44  .  assert( aWalD
15380 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43  ata[3]!=pWal->nC
15390 6b 70 74 20 7c 7c 20 61 57 61 6c 44 61 74 61 5b  kpt || aWalData[
153a0 30 5d 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  0]<=pWal->hdr.mx
153b0 46 72 61 6d 65 20 29 3b 0a 0a 20 20 69 66 28 20  Frame );..  if( 
153c0 61 57 61 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61  aWalData[3]!=pWa
153d0 6c 2d 3e 6e 43 6b 70 74 20 29 7b 0a 20 20 20 20  l->nCkpt ){.    
153e0 2f 2a 20 54 68 69 73 20 73 61 76 65 70 6f 69 6e  /* This savepoin
153f0 74 20 77 61 73 20 6f 70 65 6e 65 64 20 69 6d 6d  t was opened imm
15400 65 64 69 61 74 65 6c 79 20 61 66 74 65 72 20 74  ediately after t
15410 68 65 20 77 72 69 74 65 2d 74 72 61 6e 73 61 63  he write-transac
15420 74 69 6f 6e 0a 20 20 20 20 2a 2a 20 77 61 73 20  tion.    ** was 
15430 73 74 61 72 74 65 64 2e 20 52 69 67 68 74 20 61  started. Right a
15440 66 74 65 72 20 74 68 61 74 2c 20 74 68 65 20 77  fter that, the w
15450 72 69 74 65 72 20 64 65 63 69 64 65 64 20 74 6f  riter decided to
15460 20 77 72 61 70 20 61 72 6f 75 6e 64 0a 20 20 20   wrap around.   
15470 20 2a 2a 20 74 6f 20 74 68 65 20 73 74 61 72 74   ** to the start
15480 20 6f 66 20 74 68 65 20 6c 6f 67 2e 20 55 70 64   of the log. Upd
15490 61 74 65 20 74 68 65 20 73 61 76 65 70 6f 69 6e  ate the savepoin
154a0 74 20 76 61 6c 75 65 73 20 74 6f 20 6d 61 74 63  t values to matc
154b0 68 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 61 57  h..    */.    aW
154c0 61 6c 44 61 74 61 5b 30 5d 20 3d 20 30 3b 0a 20  alData[0] = 0;. 
154d0 20 20 20 61 57 61 6c 44 61 74 61 5b 33 5d 20 3d     aWalData[3] =
154e0 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 3b 0a 20 20   pWal->nCkpt;.  
154f0 7d 0a 0a 20 20 69 66 28 20 61 57 61 6c 44 61 74  }..  if( aWalDat
15500 61 5b 30 5d 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d  a[0]<pWal->hdr.m
15510 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 70 57  xFrame ){.    pW
15520 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
15530 3d 20 61 57 61 6c 44 61 74 61 5b 30 5d 3b 0a 20  = aWalData[0];. 
15540 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72     pWal->hdr.aFr
15550 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 57  ameCksum[0] = aW
15560 61 6c 44 61 74 61 5b 31 5d 3b 0a 20 20 20 20 70  alData[1];.    p
15570 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
15580 6b 73 75 6d 5b 31 5d 20 3d 20 61 57 61 6c 44 61  ksum[1] = aWalDa
15590 74 61 5b 32 5d 3b 0a 20 20 20 20 77 61 6c 43 6c  ta[2];.    walCl
155a0 65 61 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b  eanupHash(pWal);
155b0 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
155c0 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  c;.}../*.** This
155d0 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
155e0 6c 65 64 20 6a 75 73 74 20 62 65 66 6f 72 65 20  led just before 
155f0 77 72 69 74 69 6e 67 20 61 20 73 65 74 20 6f 66  writing a set of
15600 20 66 72 61 6d 65 73 20 74 6f 20 74 68 65 20 6c   frames to the l
15610 6f 67 0a 2a 2a 20 66 69 6c 65 20 28 73 65 65 20  og.** file (see 
15620 73 71 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73  sqlite3WalFrames
15630 28 29 29 2e 20 49 74 20 63 68 65 63 6b 73 20 74  ()). It checks t
15640 6f 20 73 65 65 20 69 66 2c 20 69 6e 73 74 65 61  o see if, instea
15650 64 20 6f 66 20 61 70 70 65 6e 64 69 6e 67 0a 2a  d of appending.*
15660 2a 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74  * to the current
15670 20 6c 6f 67 20 66 69 6c 65 2c 20 69 74 20 69 73   log file, it is
15680 20 70 6f 73 73 69 62 6c 65 20 74 6f 20 6f 76 65   possible to ove
15690 72 77 72 69 74 65 20 74 68 65 20 73 74 61 72 74  rwrite the start
156a0 20 6f 66 20 74 68 65 0a 2a 2a 20 65 78 69 73 74   of the.** exist
156b0 69 6e 67 20 6c 6f 67 20 66 69 6c 65 20 77 69 74  ing log file wit
156c0 68 20 74 68 65 20 6e 65 77 20 66 72 61 6d 65 73  h the new frames
156d0 20 28 69 2e 65 2e 20 22 72 65 73 65 74 22 20 74   (i.e. "reset" t
156e0 68 65 20 6c 6f 67 29 2e 20 49 66 20 73 6f 2c 0a  he log). If so,.
156f0 2a 2a 20 69 74 20 73 65 74 73 20 70 57 61 6c 2d  ** it sets pWal-
15700 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 74 6f 20  >hdr.mxFrame to 
15710 30 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 70 57  0. Otherwise, pW
15720 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
15730 69 73 20 6c 65 66 74 0a 2a 2a 20 75 6e 63 68 61  is left.** uncha
15740 6e 67 65 64 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49  nged..**.** SQLI
15750 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
15760 64 20 69 66 20 6e 6f 20 65 72 72 6f 72 20 69 73  d if no error is
15770 20 65 6e 63 6f 75 6e 74 65 72 65 64 20 28 72 65   encountered (re
15780 67 61 72 64 6c 65 73 73 20 6f 66 20 77 68 65 74  gardless of whet
15790 68 65 72 0a 2a 2a 20 6f 72 20 6e 6f 74 20 70 57  her.** or not pW
157a0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
157b0 69 73 20 6d 6f 64 69 66 69 65 64 29 2e 20 41 6e  is modified). An
157c0 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
157d0 64 65 20 69 73 20 72 65 74 75 72 6e 65 64 0a 2a  de is returned.*
157e0 2a 20 69 66 20 73 6f 6d 65 20 65 72 72 6f 72 20  * if some error 
157f0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
15800 61 6c 52 65 73 74 61 72 74 4c 6f 67 28 57 61 6c  alRestartLog(Wal
15810 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72   *pWal){.  int r
15820 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
15830 20 69 6e 74 20 63 6e 74 3b 0a 0a 20 20 69 66 28   int cnt;..  if(
15840 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d   pWal->readLock=
15850 3d 30 20 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69  =0 ){.    volati
15860 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a  le WalCkptInfo *
15870 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49  pInfo = walCkptI
15880 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20 20 61  nfo(pWal);.    a
15890 73 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e 6e 42  ssert( pInfo->nB
158a0 61 63 6b 66 69 6c 6c 3d 3d 70 57 61 6c 2d 3e 68  ackfill==pWal->h
158b0 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20  dr.mxFrame );.  
158c0 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61    if( pInfo->nBa
158d0 63 6b 66 69 6c 6c 3e 30 20 29 7b 0a 20 20 20 20  ckfill>0 ){.    
158e0 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78    rc = walLockEx
158f0 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
15900 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20  L_READ_LOCK(1), 
15910 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a  WAL_NREADER-1);.
15920 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
15930 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
15940 20 20 20 2f 2a 20 49 66 20 61 6c 6c 20 72 65 61     /* If all rea
15950 64 65 72 73 20 61 72 65 20 75 73 69 6e 67 20 57  ders are using W
15960 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20  AL_READ_LOCK(0) 
15970 28 69 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 20  (in other words 
15980 69 66 20 6e 6f 0a 20 20 20 20 20 20 20 20 2a 2a  if no.        **
15990 20 72 65 61 64 65 72 73 20 61 72 65 20 63 75 72   readers are cur
159a0 72 65 6e 74 6c 79 20 75 73 69 6e 67 20 74 68 65  rently using the
159b0 20 57 41 4c 29 2c 20 74 68 65 6e 20 74 68 65 20   WAL), then the 
159c0 74 72 61 6e 73 61 63 74 69 6f 6e 73 0a 20 20 20  transactions.   
159d0 20 20 20 20 20 2a 2a 20 66 72 61 6d 65 73 20 77       ** frames w
159e0 69 6c 6c 20 6f 76 65 72 77 72 69 74 65 20 74 68  ill overwrite th
159f0 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 65  e start of the e
15a00 78 69 73 74 69 6e 67 20 6c 6f 67 2e 20 55 70 64  xisting log. Upd
15a10 61 74 65 20 74 68 65 0a 20 20 20 20 20 20 20 20  ate the.        
15a20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  ** wal-index hea
15a30 64 65 72 20 74 6f 20 72 65 66 6c 65 63 74 20 74  der to reflect t
15a40 68 69 73 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a  his..        **.
15a50 20 20 20 20 20 20 20 20 2a 2a 20 49 6e 20 74 68          ** In th
15a60 65 6f 72 79 20 69 74 20 77 6f 75 6c 64 20 62 65  eory it would be
15a70 20 4f 6b 20 74 6f 20 75 70 64 61 74 65 20 74 68   Ok to update th
15a80 65 20 63 61 63 68 65 20 6f 66 20 74 68 65 20 68  e cache of the h
15a90 65 61 64 65 72 20 6f 6e 6c 79 0a 20 20 20 20 20  eader only.     
15aa0 20 20 20 2a 2a 20 61 74 20 74 68 69 73 20 70 6f     ** at this po
15ab0 69 6e 74 2e 20 42 75 74 20 75 70 64 61 74 69 6e  int. But updatin
15ac0 67 20 74 68 65 20 61 63 74 75 61 6c 20 77 61 6c  g the actual wal
15ad0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73  -index header is
15ae0 20 61 6c 73 6f 0a 20 20 20 20 20 20 20 20 2a 2a   also.        **
15af0 20 73 61 66 65 20 61 6e 64 20 6d 65 61 6e 73 20   safe and means 
15b00 74 68 65 72 65 20 69 73 20 6e 6f 20 73 70 65 63  there is no spec
15b10 69 61 6c 20 63 61 73 65 20 66 6f 72 20 73 71 6c  ial case for sql
15b20 69 74 65 33 57 61 6c 55 6e 64 6f 28 29 0a 20 20  ite3WalUndo().  
15b30 20 20 20 20 20 20 2a 2a 20 74 6f 20 68 61 6e 64        ** to hand
15b40 6c 65 20 69 66 20 74 68 69 73 20 74 72 61 6e 73  le if this trans
15b50 61 63 74 69 6f 6e 20 69 73 20 72 6f 6c 6c 65 64  action is rolled
15b60 20 62 61 63 6b 2e 0a 20 20 20 20 20 20 20 20 2a   back..        *
15b70 2f 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 3b  /.        int i;
15b80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15b90 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e      /* Loop coun
15ba0 74 65 72 20 2a 2f 0a 20 20 20 20 20 20 20 20 75  ter */.        u
15bb0 33 32 20 2a 61 53 61 6c 74 20 3d 20 70 57 61 6c  32 *aSalt = pWal
15bc0 2d 3e 68 64 72 2e 61 53 61 6c 74 3b 20 20 20 20  ->hdr.aSalt;    
15bd0 20 20 20 2f 2a 20 42 69 67 2d 65 6e 64 69 61 6e     /* Big-endian
15be0 20 73 61 6c 74 20 76 61 6c 75 65 73 20 2a 2f 0a   salt values */.
15bf0 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 6e 43          pWal->nC
15c00 6b 70 74 2b 2b 3b 0a 20 20 20 20 20 20 20 20 70  kpt++;.        p
15c10 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
15c20 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 73 71   = 0;.        sq
15c30 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 28 75  lite3Put4byte((u
15c40 38 2a 29 26 61 53 61 6c 74 5b 30 5d 2c 20 31 20  8*)&aSalt[0], 1 
15c50 2b 20 73 71 6c 69 74 65 33 47 65 74 34 62 79 74  + sqlite3Get4byt
15c60 65 28 28 75 38 2a 29 26 61 53 61 6c 74 5b 30 5d  e((u8*)&aSalt[0]
15c70 29 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69  ));.        sqli
15c80 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 34  te3_randomness(4
15c90 2c 20 26 61 53 61 6c 74 5b 31 5d 29 3b 0a 20 20  , &aSalt[1]);.  
15ca0 20 20 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72        walIndexWr
15cb0 69 74 65 48 64 72 28 70 57 61 6c 29 3b 0a 20 20  iteHdr(pWal);.  
15cc0 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61        pInfo->nBa
15cd0 63 6b 66 69 6c 6c 20 3d 20 30 3b 0a 20 20 20 20  ckfill = 0;.    
15ce0 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 57      for(i=1; i<W
15cf0 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29  AL_NREADER; i++)
15d00 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
15d10 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41 52 4b 5f  k[i] = READMARK_
15d20 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 20 20 20 20  NOT_USED;.      
15d30 20 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d    assert( pInfo-
15d40 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 3d 3d 30  >aReadMark[0]==0
15d50 20 29 3b 0a 20 20 20 20 20 20 20 20 77 61 6c 55   );.        walU
15d60 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  nlockExclusive(p
15d70 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
15d80 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44  CK(1), WAL_NREAD
15d90 45 52 2d 31 29 3b 0a 20 20 20 20 20 20 7d 0a 20  ER-1);.      }. 
15da0 20 20 20 7d 0a 20 20 20 20 77 61 6c 55 6e 6c 6f     }.    walUnlo
15db0 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
15dc0 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29  AL_READ_LOCK(0))
15dd0 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64  ;.    pWal->read
15de0 4c 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20 20 20 63  Lock = -1;.    c
15df0 6e 74 20 3d 20 30 3b 0a 20 20 20 20 64 6f 7b 0a  nt = 0;.    do{.
15e00 20 20 20 20 20 20 69 6e 74 20 6e 6f 74 55 73 65        int notUse
15e10 64 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61  d;.      rc = wa
15e20 6c 54 72 79 42 65 67 69 6e 52 65 61 64 28 70 57  lTryBeginRead(pW
15e30 61 6c 2c 20 26 6e 6f 74 55 73 65 64 2c 20 31 2c  al, &notUsed, 1,
15e40 20 2b 2b 63 6e 74 29 3b 0a 20 20 20 20 7d 77 68   ++cnt);.    }wh
15e50 69 6c 65 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54  ile( rc==WAL_RET
15e60 52 59 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  RY );.  }.  retu
15e70 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
15e80 20 57 72 69 74 65 20 61 20 73 65 74 20 6f 66 20   Write a set of 
15e90 66 72 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f  frames to the lo
15ea0 67 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75  g. The caller mu
15eb0 73 74 20 68 6f 6c 64 20 74 68 65 20 77 72 69 74  st hold the writ
15ec0 65 2d 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65  e-lock.** on the
15ed0 20 6c 6f 67 20 66 69 6c 65 20 28 6f 62 74 61 69   log file (obtai
15ee0 6e 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65  ned using sqlite
15ef0 33 57 61 6c 42 65 67 69 6e 57 72 69 74 65 54 72  3WalBeginWriteTr
15f00 61 6e 73 61 63 74 69 6f 6e 28 29 29 2e 0a 2a 2f  ansaction())..*/
15f10 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 46  .int sqlite3WalF
15f20 72 61 6d 65 73 28 0a 20 20 57 61 6c 20 2a 70 57  rames(.  Wal *pW
15f30 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
15f40 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20           /* Wal 
15f50 68 61 6e 64 6c 65 20 74 6f 20 77 72 69 74 65 20  handle to write 
15f60 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61  to */.  int szPa
15f70 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ge,             
15f80 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
15f90 61 73 65 20 70 61 67 65 2d 73 69 7a 65 20 69 6e  ase page-size in
15fa0 20 62 79 74 65 73 20 2a 2f 0a 20 20 50 67 48 64   bytes */.  PgHd
15fb0 72 20 2a 70 4c 69 73 74 2c 20 20 20 20 20 20 20  r *pList,       
15fc0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
15fd0 69 73 74 20 6f 66 20 64 69 72 74 79 20 70 61 67  ist of dirty pag
15fe0 65 73 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20  es to write */. 
15ff0 20 50 67 6e 6f 20 6e 54 72 75 6e 63 61 74 65 2c   Pgno nTruncate,
16000 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16010 20 2f 2a 20 44 61 74 61 62 61 73 65 20 73 69 7a   /* Database siz
16020 65 20 61 66 74 65 72 20 74 68 69 73 20 63 6f 6d  e after this com
16030 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43  mit */.  int isC
16040 6f 6d 6d 69 74 2c 20 20 20 20 20 20 20 20 20 20  ommit,          
16050 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
16060 20 69 66 20 74 68 69 73 20 69 73 20 61 20 63 6f   if this is a co
16070 6d 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20 73 79  mmit */.  int sy
16080 6e 63 5f 66 6c 61 67 73 20 20 20 20 20 20 20 20  nc_flags        
16090 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61            /* Fla
160a0 67 73 20 74 6f 20 70 61 73 73 20 74 6f 20 4f 73  gs to pass to Os
160b0 53 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f  Sync() (or 0) */
160c0 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  .){.  int rc;   
160d0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
160e0 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f        /* Used to
160f0 20 63 61 74 63 68 20 72 65 74 75 72 6e 20 63 6f   catch return co
16100 64 65 73 20 2a 2f 0a 20 20 75 33 32 20 69 46 72  des */.  u32 iFr
16110 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ame;            
16120 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
16130 20 66 72 61 6d 65 20 61 64 64 72 65 73 73 20 2a   frame address *
16140 2f 0a 20 20 75 38 20 61 46 72 61 6d 65 5b 57 41  /.  u8 aFrame[WA
16150 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 5d  L_FRAME_HDRSIZE]
16160 3b 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f  ;   /* Buffer to
16170 20 61 73 73 65 6d 62 6c 65 20 66 72 61 6d 65 2d   assemble frame-
16180 68 65 61 64 65 72 20 69 6e 20 2a 2f 0a 20 20 50  header in */.  P
16190 67 48 64 72 20 2a 70 3b 20 20 20 20 20 20 20 20  gHdr *p;        
161a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
161b0 2a 20 49 74 65 72 61 74 6f 72 20 74 6f 20 72 75  * Iterator to ru
161c0 6e 20 74 68 72 6f 75 67 68 20 70 4c 69 73 74 20  n through pList 
161d0 77 69 74 68 2e 20 2a 2f 0a 20 20 50 67 48 64 72  with. */.  PgHdr
161e0 20 2a 70 4c 61 73 74 20 3d 20 30 3b 20 20 20 20   *pLast = 0;    
161f0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
16200 73 74 20 66 72 61 6d 65 20 69 6e 20 6c 69 73 74  st frame in list
16210 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 61 73 74 20   */.  int nLast 
16220 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
16230 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
16240 6f 66 20 65 78 74 72 61 20 63 6f 70 69 65 73 20  of extra copies 
16250 6f 66 20 6c 61 73 74 20 70 61 67 65 20 2a 2f 0a  of last page */.
16260 0a 20 20 61 73 73 65 72 74 28 20 70 4c 69 73 74  .  assert( pList
16270 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57   );.  assert( pW
16280 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
16290 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51  ..#if defined(SQ
162a0 4c 49 54 45 5f 54 45 53 54 29 20 26 26 20 64 65  LITE_TEST) && de
162b0 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42  fined(SQLITE_DEB
162c0 55 47 29 0a 20 20 7b 20 69 6e 74 20 63 6e 74 3b  UG).  { int cnt;
162d0 20 66 6f 72 28 63 6e 74 3d 30 2c 20 70 3d 70 4c   for(cnt=0, p=pL
162e0 69 73 74 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69  ist; p; p=p->pDi
162f0 72 74 79 2c 20 63 6e 74 2b 2b 29 7b 7d 0a 20 20  rty, cnt++){}.  
16300 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c    WALTRACE(("WAL
16310 25 70 3a 20 66 72 61 6d 65 20 77 72 69 74 65 20  %p: frame write 
16320 62 65 67 69 6e 2e 20 25 64 20 66 72 61 6d 65 73  begin. %d frames
16330 2e 20 6d 78 46 72 61 6d 65 3d 25 64 2e 20 25 73  . mxFrame=%d. %s
16340 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20  \n",.           
16350 20 20 20 70 57 61 6c 2c 20 63 6e 74 2c 20 70 57     pWal, cnt, pW
16360 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2c  al->hdr.mxFrame,
16370 20 69 73 43 6f 6d 6d 69 74 20 3f 20 22 43 6f 6d   isCommit ? "Com
16380 6d 69 74 22 20 3a 20 22 53 70 69 6c 6c 22 29 29  mit" : "Spill"))
16390 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20  ;.  }.#endif..  
163a0 2f 2a 20 53 65 65 20 69 66 20 69 74 20 69 73 20  /* See if it is 
163b0 70 6f 73 73 69 62 6c 65 20 74 6f 20 77 72 69 74  possible to writ
163c0 65 20 74 68 65 73 65 20 66 72 61 6d 65 73 20 69  e these frames i
163d0 6e 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66  nto the start of
163e0 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 67 20 66 69   the.  ** log fi
163f0 6c 65 2c 20 69 6e 73 74 65 61 64 20 6f 66 20 61  le, instead of a
16400 70 70 65 6e 64 69 6e 67 20 74 6f 20 69 74 20 61  ppending to it a
16410 74 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  t pWal->hdr.mxFr
16420 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  ame..  */.  if( 
16430 53 51 4c 49 54 45 5f 4f 4b 21 3d 28 72 63 20 3d  SQLITE_OK!=(rc =
16440 20 77 61 6c 52 65 73 74 61 72 74 4c 6f 67 28 70   walRestartLog(p
16450 57 61 6c 29 29 20 29 7b 0a 20 20 20 20 72 65 74  Wal)) ){.    ret
16460 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f  urn rc;.  }..  /
16470 2a 20 49 66 20 74 68 69 73 20 69 73 20 74 68 65  * If this is the
16480 20 66 69 72 73 74 20 66 72 61 6d 65 20 77 72 69   first frame wri
16490 74 74 65 6e 20 69 6e 74 6f 20 74 68 65 20 6c 6f  tten into the lo
164a0 67 2c 20 77 72 69 74 65 20 74 68 65 20 57 41 4c  g, write the WAL
164b0 0a 20 20 2a 2a 20 68 65 61 64 65 72 20 74 6f 20  .  ** header to 
164c0 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
164d0 20 57 41 4c 20 66 69 6c 65 2e 20 53 65 65 20 63   WAL file. See c
164e0 6f 6d 6d 65 6e 74 73 20 61 74 20 74 68 65 20 74  omments at the t
164f0 6f 70 20 6f 66 0a 20 20 2a 2a 20 74 68 69 73 20  op of.  ** this 
16500 73 6f 75 72 63 65 20 66 69 6c 65 20 66 6f 72 20  source file for 
16510 61 20 64 65 73 63 72 69 70 74 69 6f 6e 20 6f 66  a description of
16520 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72 20   the WAL header 
16530 66 6f 72 6d 61 74 2e 0a 20 20 2a 2f 0a 20 20 69  format..  */.  i
16540 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64  Frame = pWal->hd
16550 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 69 66 28  r.mxFrame;.  if(
16560 20 69 46 72 61 6d 65 3d 3d 30 20 29 7b 0a 20 20   iFrame==0 ){.  
16570 20 20 75 38 20 61 57 61 6c 48 64 72 5b 57 41 4c    u8 aWalHdr[WAL
16580 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20 20 20 20  _HDRSIZE];      
16590 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 61 73 73  /* Buffer to ass
165a0 65 6d 62 6c 65 20 77 61 6c 2d 68 65 61 64 65 72  emble wal-header
165b0 20 69 6e 20 2a 2f 0a 20 20 20 20 75 33 32 20 61   in */.    u32 a
165c0 43 6b 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20  Cksum[2];       
165d0 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63           /* Chec
165e0 6b 73 75 6d 20 66 6f 72 20 77 61 6c 2d 68 65 61  ksum for wal-hea
165f0 64 65 72 20 2a 2f 0a 0a 20 20 20 20 73 71 6c 69  der */..    sqli
16600 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61  te3Put4byte(&aWa
16610 6c 48 64 72 5b 30 5d 2c 20 28 57 41 4c 5f 4d 41  lHdr[0], (WAL_MA
16620 47 49 43 20 7c 20 53 51 4c 49 54 45 5f 42 49 47  GIC | SQLITE_BIG
16630 45 4e 44 49 41 4e 29 29 3b 0a 20 20 20 20 73 71  ENDIAN));.    sq
16640 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61  lite3Put4byte(&a
16650 57 61 6c 48 64 72 5b 34 5d 2c 20 57 41 4c 5f 4d  WalHdr[4], WAL_M
16660 41 58 5f 56 45 52 53 49 4f 4e 29 3b 0a 20 20 20  AX_VERSION);.   
16670 20 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65   sqlite3Put4byte
16680 28 26 61 57 61 6c 48 64 72 5b 38 5d 2c 20 73 7a  (&aWalHdr[8], sz
16690 50 61 67 65 29 3b 0a 20 20 20 20 73 71 6c 69 74  Page);.    sqlit
166a0 65 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c  e3Put4byte(&aWal
166b0 48 64 72 5b 31 32 5d 2c 20 70 57 61 6c 2d 3e 6e  Hdr[12], pWal->n
166c0 43 6b 70 74 29 3b 0a 20 20 20 20 6d 65 6d 63 70  Ckpt);.    memcp
166d0 79 28 26 61 57 61 6c 48 64 72 5b 31 36 5d 2c 20  y(&aWalHdr[16], 
166e0 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c  pWal->hdr.aSalt,
166f0 20 38 29 3b 0a 20 20 20 20 77 61 6c 43 68 65 63   8);.    walChec
16700 6b 73 75 6d 42 79 74 65 73 28 31 2c 20 61 57 61  ksumBytes(1, aWa
16710 6c 48 64 72 2c 20 57 41 4c 5f 48 44 52 53 49 5a  lHdr, WAL_HDRSIZ
16720 45 2d 32 2a 34 2c 20 30 2c 20 61 43 6b 73 75 6d  E-2*4, 0, aCksum
16730 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75  );.    sqlite3Pu
16740 74 34 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b  t4byte(&aWalHdr[
16750 32 34 5d 2c 20 61 43 6b 73 75 6d 5b 30 5d 29 3b  24], aCksum[0]);
16760 0a 20 20 20 20 73 71 6c 69 74 65 33 50 75 74 34  .    sqlite3Put4
16770 62 79 74 65 28 26 61 57 61 6c 48 64 72 5b 32 38  byte(&aWalHdr[28
16780 5d 2c 20 61 43 6b 73 75 6d 5b 31 5d 29 3b 0a 20  ], aCksum[1]);. 
16790 20 20 20 0a 20 20 20 20 70 57 61 6c 2d 3e 73 7a     .    pWal->sz
167a0 50 61 67 65 20 3d 20 28 75 31 36 29 73 7a 50 61  Page = (u16)szPa
167b0 67 65 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64  ge;.    pWal->hd
167c0 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 20 3d 20  r.bigEndCksum = 
167d0 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e  SQLITE_BIGENDIAN
167e0 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  ;.    pWal->hdr.
167f0 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d  aFrameCksum[0] =
16800 20 61 43 6b 73 75 6d 5b 30 5d 3b 0a 20 20 20 20   aCksum[0];.    
16810 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
16820 43 6b 73 75 6d 5b 31 5d 20 3d 20 61 43 6b 73 75  Cksum[1] = aCksu
16830 6d 5b 31 5d 3b 0a 0a 20 20 20 20 72 63 20 3d 20  m[1];..    rc = 
16840 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70  sqlite3OsWrite(p
16850 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 57 61  Wal->pWalFd, aWa
16860 6c 48 64 72 2c 20 73 69 7a 65 6f 66 28 61 57 61  lHdr, sizeof(aWa
16870 6c 48 64 72 29 2c 20 30 29 3b 0a 20 20 20 20 57  lHdr), 0);.    W
16880 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
16890 20 77 61 6c 2d 68 65 61 64 65 72 20 77 72 69 74   wal-header writ
168a0 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  e %s\n", pWal, r
168b0 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
168c0 6f 6b 22 29 29 3b 0a 20 20 20 20 69 66 28 20 72  ok"));.    if( r
168d0 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
168e0 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
168f0 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 73 73  .    }.  }.  ass
16900 65 72 74 28 20 70 57 61 6c 2d 3e 73 7a 50 61 67  ert( pWal->szPag
16910 65 3d 3d 73 7a 50 61 67 65 20 29 3b 0a 0a 20 20  e==szPage );..  
16920 2f 2a 20 57 72 69 74 65 20 74 68 65 20 6c 6f 67  /* Write the log
16930 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 66 6f 72 28   file. */.  for(
16940 70 3d 70 4c 69 73 74 3b 20 70 3b 20 70 3d 70 2d  p=pList; p; p=p-
16950 3e 70 44 69 72 74 79 29 7b 0a 20 20 20 20 75 33  >pDirty){.    u3
16960 32 20 6e 44 62 73 69 7a 65 3b 20 20 20 20 20 20  2 nDbsize;      
16970 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
16980 62 2d 73 69 7a 65 20 66 69 65 6c 64 20 66 6f 72  b-size field for
16990 20 66 72 61 6d 65 20 68 65 61 64 65 72 20 2a 2f   frame header */
169a0 0a 20 20 20 20 69 36 34 20 69 4f 66 66 73 65 74  .    i64 iOffset
169b0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
169c0 20 20 20 2f 2a 20 57 72 69 74 65 20 6f 66 66 73     /* Write offs
169d0 65 74 20 69 6e 20 6c 6f 67 20 66 69 6c 65 20 2a  et in log file *
169e0 2f 0a 20 20 20 20 76 6f 69 64 20 2a 70 44 61 74  /.    void *pDat
169f0 61 3b 0a 20 20 20 0a 20 20 20 0a 20 20 20 20 69  a;.   .   .    i
16a00 4f 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61 6d  Offset = walFram
16a10 65 4f 66 66 73 65 74 28 2b 2b 69 46 72 61 6d 65  eOffset(++iFrame
16a20 2c 20 73 7a 50 61 67 65 29 3b 0a 20 20 20 20 0a  , szPage);.    .
16a30 20 20 20 20 2f 2a 20 50 6f 70 75 6c 61 74 65 20      /* Populate 
16a40 61 6e 64 20 77 72 69 74 65 20 74 68 65 20 66 72  and write the fr
16a50 61 6d 65 20 68 65 61 64 65 72 20 2a 2f 0a 20 20  ame header */.  
16a60 20 20 6e 44 62 73 69 7a 65 20 3d 20 28 69 73 43    nDbsize = (isC
16a70 6f 6d 6d 69 74 20 26 26 20 70 2d 3e 70 44 69 72  ommit && p->pDir
16a80 74 79 3d 3d 30 29 20 3f 20 6e 54 72 75 6e 63 61  ty==0) ? nTrunca
16a90 74 65 20 3a 20 30 3b 0a 23 69 66 20 64 65 66 69  te : 0;.#if defi
16aa0 6e 65 64 28 53 51 4c 49 54 45 5f 48 41 53 5f 43  ned(SQLITE_HAS_C
16ab0 4f 44 45 43 29 0a 20 20 20 20 69 66 28 20 28 70  ODEC).    if( (p
16ac0 44 61 74 61 20 3d 20 73 71 6c 69 74 65 33 50 61  Data = sqlite3Pa
16ad0 67 65 72 43 6f 64 65 63 28 70 29 29 3d 3d 30 20  gerCodec(p))==0 
16ae0 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
16af0 4e 4f 4d 45 4d 3b 0a 23 65 6c 73 65 0a 20 20 20  NOMEM;.#else.   
16b00 20 70 44 61 74 61 20 3d 20 70 2d 3e 70 44 61 74   pData = p->pDat
16b10 61 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 77 61  a;.#endif.    wa
16b20 6c 45 6e 63 6f 64 65 46 72 61 6d 65 28 70 57 61  lEncodeFrame(pWa
16b30 6c 2c 20 70 2d 3e 70 67 6e 6f 2c 20 6e 44 62 73  l, p->pgno, nDbs
16b40 69 7a 65 2c 20 70 44 61 74 61 2c 20 61 46 72 61  ize, pData, aFra
16b50 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71  me);.    rc = sq
16b60 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70 57 61  lite3OsWrite(pWa
16b70 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 46 72 61 6d  l->pWalFd, aFram
16b80 65 2c 20 73 69 7a 65 6f 66 28 61 46 72 61 6d 65  e, sizeof(aFrame
16b90 29 2c 20 69 4f 66 66 73 65 74 29 3b 0a 20 20 20  ), iOffset);.   
16ba0 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
16bb0 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75  OK ){.      retu
16bc0 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 0a 20 20  rn rc;.    }..  
16bd0 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 70    /* Write the p
16be0 61 67 65 20 64 61 74 61 20 2a 2f 0a 20 20 20 20  age data */.    
16bf0 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72  rc = sqlite3OsWr
16c00 69 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ite(pWal->pWalFd
16c10 2c 20 70 44 61 74 61 2c 20 73 7a 50 61 67 65 2c  , pData, szPage,
16c20 20 69 4f 66 66 73 65 74 2b 73 69 7a 65 6f 66 28   iOffset+sizeof(
16c30 61 46 72 61 6d 65 29 29 3b 0a 20 20 20 20 69 66  aFrame));.    if
16c40 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
16c50 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
16c60 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 4c  rc;.    }.    pL
16c70 61 73 74 20 3d 20 70 3b 0a 20 20 7d 0a 0a 20 20  ast = p;.  }..  
16c80 2f 2a 20 53 79 6e 63 20 74 68 65 20 6c 6f 67 20  /* Sync the log 
16c90 66 69 6c 65 20 69 66 20 74 68 65 20 27 69 73 53  file if the 'isS
16ca0 79 6e 63 27 20 66 6c 61 67 20 77 61 73 20 73 70  ync' flag was sp
16cb0 65 63 69 66 69 65 64 2e 20 2a 2f 0a 20 20 69 66  ecified. */.  if
16cc0 28 20 73 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a  ( sync_flags ){.
16cd0 20 20 20 20 69 36 34 20 69 53 65 67 6d 65 6e 74      i64 iSegment
16ce0 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 65 63 74   = sqlite3OsSect
16cf0 6f 72 53 69 7a 65 28 70 57 61 6c 2d 3e 70 57 61  orSize(pWal->pWa
16d00 6c 46 64 29 3b 0a 20 20 20 20 69 36 34 20 69 4f  lFd);.    i64 iO
16d10 66 66 73 65 74 20 3d 20 77 61 6c 46 72 61 6d 65  ffset = walFrame
16d20 4f 66 66 73 65 74 28 69 46 72 61 6d 65 2b 31 2c  Offset(iFrame+1,
16d30 20 73 7a 50 61 67 65 29 3b 0a 0a 20 20 20 20 61   szPage);..    a
16d40 73 73 65 72 74 28 20 69 73 43 6f 6d 6d 69 74 20  ssert( isCommit 
16d50 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 69  );.    assert( i
16d60 53 65 67 6d 65 6e 74 3e 30 20 29 3b 0a 0a 20 20  Segment>0 );..  
16d70 20 20 69 53 65 67 6d 65 6e 74 20 3d 20 28 28 28    iSegment = (((
16d80 69 4f 66 66 73 65 74 2b 69 53 65 67 6d 65 6e 74  iOffset+iSegment
16d90 2d 31 29 2f 69 53 65 67 6d 65 6e 74 29 20 2a 20  -1)/iSegment) * 
16da0 69 53 65 67 6d 65 6e 74 29 3b 0a 20 20 20 20 77  iSegment);.    w
16db0 68 69 6c 65 28 20 69 4f 66 66 73 65 74 3c 69 53  hile( iOffset<iS
16dc0 65 67 6d 65 6e 74 20 29 7b 0a 20 20 20 20 20 20  egment ){.      
16dd0 76 6f 69 64 20 2a 70 44 61 74 61 3b 0a 23 69 66  void *pData;.#if
16de0 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f   defined(SQLITE_
16df0 48 41 53 5f 43 4f 44 45 43 29 0a 20 20 20 20 20  HAS_CODEC).     
16e00 20 69 66 28 20 28 70 44 61 74 61 20 3d 20 73 71   if( (pData = sq
16e10 6c 69 74 65 33 50 61 67 65 72 43 6f 64 65 63 28  lite3PagerCodec(
16e20 70 4c 61 73 74 29 29 3d 3d 30 20 29 20 72 65 74  pLast))==0 ) ret
16e30 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
16e40 3b 0a 23 65 6c 73 65 0a 20 20 20 20 20 20 70 44  ;.#else.      pD
16e50 61 74 61 20 3d 20 70 4c 61 73 74 2d 3e 70 44 61  ata = pLast->pDa
16e60 74 61 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20  ta;.#endif.     
16e70 20 77 61 6c 45 6e 63 6f 64 65 46 72 61 6d 65 28   walEncodeFrame(
16e80 70 57 61 6c 2c 20 70 4c 61 73 74 2d 3e 70 67 6e  pWal, pLast->pgn
16e90 6f 2c 20 6e 54 72 75 6e 63 61 74 65 2c 20 70 44  o, nTruncate, pD
16ea0 61 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20  ata, aFrame);.  
16eb0 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
16ec0 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 57  OsWrite(pWal->pW
16ed0 61 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20 73 69  alFd, aFrame, si
16ee0 7a 65 6f 66 28 61 46 72 61 6d 65 29 2c 20 69 4f  zeof(aFrame), iO
16ef0 66 66 73 65 74 29 3b 0a 20 20 20 20 20 20 69 66  ffset);.      if
16f00 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
16f10 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
16f20 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 20 20  n rc;.      }.  
16f30 20 20 20 20 69 4f 66 66 73 65 74 20 2b 3d 20 57      iOffset += W
16f40 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
16f50 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  ;.      rc = sql
16f60 69 74 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c  ite3OsWrite(pWal
16f70 2d 3e 70 57 61 6c 46 64 2c 20 70 44 61 74 61 2c  ->pWalFd, pData,
16f80 20 73 7a 50 61 67 65 2c 20 69 4f 66 66 73 65 74   szPage, iOffset
16f90 29 3b 20 0a 20 20 20 20 20 20 69 66 28 20 72 63  ); .      if( rc
16fa0 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
16fb0 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63         return rc
16fc0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
16fd0 6e 4c 61 73 74 2b 2b 3b 0a 20 20 20 20 20 20 69  nLast++;.      i
16fe0 4f 66 66 73 65 74 20 2b 3d 20 73 7a 50 61 67 65  Offset += szPage
16ff0 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 63 20  ;.    }..    rc 
17000 3d 20 73 71 6c 69 74 65 33 4f 73 53 79 6e 63 28  = sqlite3OsSync(
17010 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 73 79  pWal->pWalFd, sy
17020 6e 63 5f 66 6c 61 67 73 29 3b 0a 20 20 7d 0a 0a  nc_flags);.  }..
17030 20 20 2f 2a 20 41 70 70 65 6e 64 20 64 61 74 61    /* Append data
17040 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   to the wal-inde
17050 78 2e 20 49 74 20 69 73 20 6e 6f 74 20 6e 65 63  x. It is not nec
17060 65 73 73 61 72 79 20 74 6f 20 6c 6f 63 6b 20 74  essary to lock t
17070 68 65 20 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64  he .  ** wal-ind
17080 65 78 20 74 6f 20 64 6f 20 74 68 69 73 20 61 73  ex to do this as
17090 20 74 68 65 20 53 51 4c 49 54 45 5f 53 48 4d 5f   the SQLITE_SHM_
170a0 57 52 49 54 45 20 6c 6f 63 6b 20 68 65 6c 64 20  WRITE lock held 
170b0 6f 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  on the wal-index
170c0 0a 20 20 2a 2a 20 67 75 61 72 61 6e 74 65 65 73  .  ** guarantees
170d0 20 74 68 61 74 20 74 68 65 72 65 20 61 72 65 20   that there are 
170e0 6e 6f 20 6f 74 68 65 72 20 77 72 69 74 65 72 73  no other writers
170f0 2c 20 61 6e 64 20 6e 6f 20 64 61 74 61 20 74 68  , and no data th
17100 61 74 20 6d 61 79 0a 20 20 2a 2a 20 62 65 20 69  at may.  ** be i
17110 6e 20 75 73 65 20 62 79 20 65 78 69 73 74 69 6e  n use by existin
17120 67 20 72 65 61 64 65 72 73 20 69 73 20 62 65 69  g readers is bei
17130 6e 67 20 6f 76 65 72 77 72 69 74 74 65 6e 2e 0a  ng overwritten..
17140 20 20 2a 2f 0a 20 20 69 46 72 61 6d 65 20 3d 20    */.  iFrame = 
17150 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
17160 65 3b 0a 20 20 66 6f 72 28 70 3d 70 4c 69 73 74  e;.  for(p=pList
17170 3b 20 70 20 26 26 20 72 63 3d 3d 53 51 4c 49 54  ; p && rc==SQLIT
17180 45 5f 4f 4b 3b 20 70 3d 70 2d 3e 70 44 69 72 74  E_OK; p=p->pDirt
17190 79 29 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b 2b  y){.    iFrame++
171a0 3b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e  ;.    rc = walIn
171b0 64 65 78 41 70 70 65 6e 64 28 70 57 61 6c 2c 20  dexAppend(pWal, 
171c0 69 46 72 61 6d 65 2c 20 70 2d 3e 70 67 6e 6f 29  iFrame, p->pgno)
171d0 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 6e  ;.  }.  while( n
171e0 4c 61 73 74 3e 30 20 26 26 20 72 63 3d 3d 53 51  Last>0 && rc==SQ
171f0 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69  LITE_OK ){.    i
17200 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 6e 4c 61  Frame++;.    nLa
17210 73 74 2d 2d 3b 0a 20 20 20 20 72 63 20 3d 20 77  st--;.    rc = w
17220 61 6c 49 6e 64 65 78 41 70 70 65 6e 64 28 70 57  alIndexAppend(pW
17230 61 6c 2c 20 69 46 72 61 6d 65 2c 20 70 4c 61 73  al, iFrame, pLas
17240 74 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 0a 20  t->pgno);.  }.. 
17250 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
17260 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 55 70 64  OK ){.    /* Upd
17270 61 74 65 20 74 68 65 20 70 72 69 76 61 74 65 20  ate the private 
17280 63 6f 70 79 20 6f 66 20 74 68 65 20 68 65 61 64  copy of the head
17290 65 72 2e 20 2a 2f 0a 20 20 20 20 70 57 61 6c 2d  er. */.    pWal-
172a0 3e 68 64 72 2e 73 7a 50 61 67 65 20 3d 20 28 75  >hdr.szPage = (u
172b0 31 36 29 73 7a 50 61 67 65 3b 0a 20 20 20 20 70  16)szPage;.    p
172c0 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
172d0 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20 20 69   = iFrame;.    i
172e0 66 28 20 69 73 43 6f 6d 6d 69 74 20 29 7b 0a 20  f( isCommit ){. 
172f0 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 69       pWal->hdr.i
17300 43 68 61 6e 67 65 2b 2b 3b 0a 20 20 20 20 20 20  Change++;.      
17310 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65 20  pWal->hdr.nPage 
17320 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a 20 20 20  = nTruncate;.   
17330 20 7d 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 69   }.    /* If thi
17340 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 2c 20 75  s is a commit, u
17350 70 64 61 74 65 20 74 68 65 20 77 61 6c 2d 69 6e  pdate the wal-in
17360 64 65 78 20 68 65 61 64 65 72 20 74 6f 6f 2e 20  dex header too. 
17370 2a 2f 0a 20 20 20 20 69 66 28 20 69 73 43 6f 6d  */.    if( isCom
17380 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 77 61 6c  mit ){.      wal
17390 49 6e 64 65 78 57 72 69 74 65 48 64 72 28 70 57  IndexWriteHdr(pW
173a0 61 6c 29 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d  al);.      pWal-
173b0 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20 69 46 72  >iCallback = iFr
173c0 61 6d 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ame;.    }.  }..
173d0 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c    WALTRACE(("WAL
173e0 25 70 3a 20 66 72 61 6d 65 20 77 72 69 74 65 20  %p: frame write 
173f0 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72 63 20  %s\n", pWal, rc 
17400 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b  ? "failed" : "ok
17410 22 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  "));.  return rc
17420 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73  ;.}../* .** This
17430 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c   routine is call
17440 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e 74 20  ed to implement 
17450 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68 65 63  sqlite3_wal_chec
17460 6b 70 6f 69 6e 74 28 29 20 61 6e 64 0a 2a 2a 20  kpoint() and.** 
17470 72 65 6c 61 74 65 64 20 69 6e 74 65 72 66 61 63  related interfac
17480 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74 61 69 6e  es..**.** Obtain
17490 20 61 20 43 48 45 43 4b 50 4f 49 4e 54 20 6c 6f   a CHECKPOINT lo
174a0 63 6b 20 61 6e 64 20 74 68 65 6e 20 62 61 63 6b  ck and then back
174b0 66 69 6c 6c 20 61 73 20 6d 75 63 68 20 69 6e 66  fill as much inf
174c0 6f 72 6d 61 74 69 6f 6e 20 61 73 0a 2a 2a 20 77  ormation as.** w
174d0 65 20 63 61 6e 20 66 72 6f 6d 20 57 41 4c 20 69  e can from WAL i
174e0 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65  nto the database
174f0 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
17500 57 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a 20  WalCheckpoint(. 
17510 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20 20   Wal *pWal,     
17520 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17530 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65 63 74 69   /* Wal connecti
17540 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63  on */.  int sync
17550 5f 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20 20  _flags,         
17560 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73          /* Flags
17570 20 74 6f 20 73 79 6e 63 20 64 62 20 66 69 6c 65   to sync db file
17580 20 77 69 74 68 20 28 6f 72 20 30 29 20 2a 2f 0a   with (or 0) */.
17590 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20 20 20    int nBuf,     
175a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
175b0 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74 65 6d    /* Size of tem
175c0 70 6f 72 61 72 79 20 62 75 66 66 65 72 20 2a 2f  porary buffer */
175d0 0a 20 20 75 38 20 2a 7a 42 75 66 20 20 20 20 20  .  u8 *zBuf     
175e0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
175f0 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20     /* Temporary 
17600 62 75 66 66 65 72 20 74 6f 20 75 73 65 20 2a 2f  buffer to use */
17610 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  .){.  int rc;   
17620 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17630 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
17640 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69 73  code */.  int is
17650 43 68 61 6e 67 65 64 20 3d 20 30 3b 20 20 20 20  Changed = 0;    
17660 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
17670 65 20 69 66 20 61 20 6e 65 77 20 77 61 6c 2d 69  e if a new wal-i
17680 6e 64 65 78 20 68 65 61 64 65 72 20 69 73 20 6c  ndex header is l
17690 6f 61 64 65 64 20 2a 2f 0a 0a 20 20 61 73 73 65  oaded */..  asse
176a0 72 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f  rt( pWal->ckptLo
176b0 63 6b 3d 3d 30 20 29 3b 0a 0a 20 20 57 41 4c 54  ck==0 );..  WALT
176c0 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20 63 68  RACE(("WAL%p: ch
176d0 65 63 6b 70 6f 69 6e 74 20 62 65 67 69 6e 73 5c  eckpoint begins\
176e0 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 20 20 72 63  n", pWal));.  rc
176f0 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73   = walLockExclus
17700 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 43 4b  ive(pWal, WAL_CK
17710 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20 20 69  PT_LOCK, 1);.  i
17720 66 28 20 72 63 20 29 7b 0a 20 20 20 20 2f 2a 20  f( rc ){.    /* 
17730 55 73 75 61 6c 6c 79 20 74 68 69 73 20 69 73 20  Usually this is 
17740 53 51 4c 49 54 45 5f 42 55 53 59 20 6d 65 61 6e  SQLITE_BUSY mean
17750 69 6e 67 20 74 68 61 74 20 61 6e 6f 74 68 65 72  ing that another
17760 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f 63 65   thread or proce
17770 73 73 0a 20 20 20 20 2a 2a 20 69 73 20 61 6c 72  ss.    ** is alr
17780 65 61 64 79 20 72 75 6e 6e 69 6e 67 20 61 20 63  eady running a c
17790 68 65 63 6b 70 6f 69 6e 74 2c 20 6f 72 20 6d 61  heckpoint, or ma
177a0 79 62 65 20 61 20 72 65 63 6f 76 65 72 79 2e 20  ybe a recovery. 
177b0 20 42 75 74 20 69 74 20 6d 69 67 68 74 0a 20 20   But it might.  
177c0 20 20 2a 2a 20 61 6c 73 6f 20 62 65 20 53 51 4c    ** also be SQL
177d0 49 54 45 5f 49 4f 45 52 52 2e 20 2a 2f 0a 20 20  ITE_IOERR. */.  
177e0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d    return rc;.  }
177f0 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63  .  pWal->ckptLoc
17800 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 43 6f 70  k = 1;..  /* Cop
17810 79 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65 20  y data from the 
17820 6c 6f 67 20 74 6f 20 74 68 65 20 64 61 74 61 62  log to the datab
17830 61 73 65 20 66 69 6c 65 2e 20 2a 2f 0a 20 20 72  ase file. */.  r
17840 63 20 3d 20 77 61 6c 49 6e 64 65 78 52 65 61 64  c = walIndexRead
17850 48 64 72 28 70 57 61 6c 2c 20 26 69 73 43 68 61  Hdr(pWal, &isCha
17860 6e 67 65 64 29 3b 0a 20 20 69 66 28 20 72 63 3d  nged);.  if( rc=
17870 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
17880 20 20 72 63 20 3d 20 77 61 6c 43 68 65 63 6b 70    rc = walCheckp
17890 6f 69 6e 74 28 70 57 61 6c 2c 20 73 79 6e 63 5f  oint(pWal, sync_
178a0 66 6c 61 67 73 2c 20 6e 42 75 66 2c 20 7a 42 75  flags, nBuf, zBu
178b0 66 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 73  f);.  }.  if( is
178c0 43 68 61 6e 67 65 64 20 29 7b 0a 20 20 20 20 2f  Changed ){.    /
178d0 2a 20 49 66 20 61 20 6e 65 77 20 77 61 6c 2d 69  * If a new wal-i
178e0 6e 64 65 78 20 68 65 61 64 65 72 20 77 61 73 20  ndex header was 
178f0 6c 6f 61 64 65 64 20 62 65 66 6f 72 65 20 74 68  loaded before th
17900 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 77 61 73  e checkpoint was
17910 20 0a 20 20 20 20 2a 2a 20 70 65 72 66 6f 72 6d   .    ** perform
17920 65 64 2c 20 74 68 65 6e 20 74 68 65 20 70 61 67  ed, then the pag
17930 65 72 2d 63 61 63 68 65 20 61 73 73 6f 63 69 61  er-cache associa
17940 74 65 64 20 77 69 74 68 20 70 57 61 6c 20 69 73  ted with pWal is
17950 20 6e 6f 77 0a 20 20 20 20 2a 2a 20 6f 75 74 20   now.    ** out 
17960 6f 66 20 64 61 74 65 2e 20 53 6f 20 7a 65 72 6f  of date. So zero
17970 20 74 68 65 20 63 61 63 68 65 64 20 77 61 6c 2d   the cached wal-
17980 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f 20  index header to 
17990 65 6e 73 75 72 65 20 74 68 61 74 0a 20 20 20 20  ensure that.    
179a0 2a 2a 20 6e 65 78 74 20 74 69 6d 65 20 74 68 65  ** next time the
179b0 20 70 61 67 65 72 20 6f 70 65 6e 73 20 61 20 73   pager opens a s
179c0 6e 61 70 73 68 6f 74 20 6f 6e 20 74 68 69 73 20  napshot on this 
179d0 64 61 74 61 62 61 73 65 20 69 74 20 6b 6e 6f 77  database it know
179e0 73 20 74 68 61 74 0a 20 20 20 20 2a 2a 20 74 68  s that.    ** th
179f0 65 20 63 61 63 68 65 20 6e 65 65 64 73 20 74 6f  e cache needs to
17a00 20 62 65 20 72 65 73 65 74 2e 0a 20 20 20 20 2a   be reset..    *
17a10 2f 0a 20 20 20 20 6d 65 6d 73 65 74 28 26 70 57  /.    memset(&pW
17a20 61 6c 2d 3e 68 64 72 2c 20 30 2c 20 73 69 7a 65  al->hdr, 0, size
17a30 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72 29 29  of(WalIndexHdr))
17a40 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 6c 65  ;.  }..  /* Rele
17a50 61 73 65 20 74 68 65 20 6c 6f 63 6b 73 2e 20 2a  ase the locks. *
17a60 2f 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63  /.  walUnlockExc
17a70 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c  lusive(pWal, WAL
17a80 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  _CKPT_LOCK, 1);.
17a90 20 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f 63 6b    pWal->ckptLock
17aa0 20 3d 20 30 3b 0a 20 20 57 41 4c 54 52 41 43 45   = 0;.  WALTRACE
17ab0 28 28 22 57 41 4c 25 70 3a 20 63 68 65 63 6b 70  (("WAL%p: checkp
17ac0 6f 69 6e 74 20 25 73 5c 6e 22 2c 20 70 57 61 6c  oint %s\n", pWal
17ad0 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20  , rc ? "failed" 
17ae0 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75  : "ok"));.  retu
17af0 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 52 65 74  rn rc;.}../* Ret
17b00 75 72 6e 20 74 68 65 20 76 61 6c 75 65 20 74 6f  urn the value to
17b10 20 70 61 73 73 20 74 6f 20 61 20 73 71 6c 69 74   pass to a sqlit
17b20 65 33 5f 77 61 6c 5f 68 6f 6f 6b 20 63 61 6c 6c  e3_wal_hook call
17b30 62 61 63 6b 2c 20 74 68 65 0a 2a 2a 20 6e 75 6d  back, the.** num
17b40 62 65 72 20 6f 66 20 66 72 61 6d 65 73 20 69 6e  ber of frames in
17b50 20 74 68 65 20 57 41 4c 20 61 74 20 74 68 65 20   the WAL at the 
17b60 70 6f 69 6e 74 20 6f 66 20 74 68 65 20 6c 61 73  point of the las
17b70 74 20 63 6f 6d 6d 69 74 20 73 69 6e 63 65 0a 2a  t commit since.*
17b80 2a 20 73 71 6c 69 74 65 33 57 61 6c 43 61 6c 6c  * sqlite3WalCall
17b90 62 61 63 6b 28 29 20 77 61 73 20 63 61 6c 6c 65  back() was calle
17ba0 64 2e 20 20 49 66 20 6e 6f 20 63 6f 6d 6d 69 74  d.  If no commit
17bb0 73 20 68 61 76 65 20 6f 63 63 75 72 72 65 64 20  s have occurred 
17bc0 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 6c 61 73  since.** the las
17bd0 74 20 63 61 6c 6c 2c 20 74 68 65 6e 20 72 65 74  t call, then ret
17be0 75 72 6e 20 30 2e 0a 2a 2f 0a 69 6e 74 20 73 71  urn 0..*/.int sq
17bf0 6c 69 74 65 33 57 61 6c 43 61 6c 6c 62 61 63 6b  lite3WalCallback
17c00 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20 20 75  (Wal *pWal){.  u
17c10 33 32 20 72 65 74 20 3d 20 30 3b 0a 20 20 69 66  32 ret = 0;.  if
17c20 28 20 70 57 61 6c 20 29 7b 0a 20 20 20 20 72 65  ( pWal ){.    re
17c30 74 20 3d 20 70 57 61 6c 2d 3e 69 43 61 6c 6c 62  t = pWal->iCallb
17c40 61 63 6b 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 69  ack;.    pWal->i
17c50 43 61 6c 6c 62 61 63 6b 20 3d 20 30 3b 0a 20 20  Callback = 0;.  
17c60 7d 0a 20 20 72 65 74 75 72 6e 20 28 69 6e 74 29  }.  return (int)
17c70 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  ret;.}../*.** Th
17c80 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
17c90 61 6c 6c 65 64 20 74 6f 20 63 68 61 6e 67 65 20  alled to change 
17ca0 74 68 65 20 57 41 4c 20 73 75 62 73 79 73 74 65  the WAL subsyste
17cb0 6d 20 69 6e 74 6f 20 6f 72 20 6f 75 74 0a 2a 2a  m into or out.**
17cc0 20 6f 66 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65   of locking_mode
17cd0 3d 45 58 43 4c 55 53 49 56 45 2e 0a 2a 2a 0a 2a  =EXCLUSIVE..**.*
17ce0 2a 20 49 66 20 6f 70 20 69 73 20 7a 65 72 6f 2c  * If op is zero,
17cf0 20 74 68 65 6e 20 61 74 74 65 6d 70 74 20 74 6f   then attempt to
17d00 20 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63   change from loc
17d10 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53  king_mode=EXCLUS
17d20 49 56 45 0a 2a 2a 20 69 6e 74 6f 20 6c 6f 63 6b  IVE.** into lock
17d30 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 2e  ing_mode=NORMAL.
17d40 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68 61    This means tha
17d50 74 20 77 65 20 6d 75 73 74 20 61 63 71 75 69 72  t we must acquir
17d60 65 20 61 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74  e a lock.** on t
17d70 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63  he pWal->readLoc
17d80 6b 20 62 79 74 65 2e 20 20 49 66 20 74 68 65 20  k byte.  If the 
17d90 57 41 4c 20 69 73 20 61 6c 72 65 61 64 79 20 69  WAL is already i
17da0 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e  n locking_mode=N
17db0 4f 52 4d 41 4c 0a 2a 2a 20 6f 72 20 69 66 20 74  ORMAL.** or if t
17dc0 68 65 20 61 63 71 75 69 73 69 74 69 6f 6e 20 6f  he acquisition o
17dd0 66 20 74 68 65 20 6c 6f 63 6b 20 66 61 69 6c 73  f the lock fails
17de0 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20 30 2e  , then return 0.
17df0 20 20 49 66 20 74 68 65 0a 2a 2a 20 74 72 61 6e    If the.** tran
17e00 73 69 74 69 6f 6e 20 6f 75 74 20 6f 66 20 65 78  sition out of ex
17e10 63 6c 75 73 69 76 65 2d 6d 6f 64 65 20 69 73 20  clusive-mode is 
17e20 73 75 63 63 65 73 73 66 75 6c 2c 20 72 65 74 75  successful, retu
17e30 72 6e 20 31 2e 20 20 54 68 69 73 0a 2a 2a 20 6f  rn 1.  This.** o
17e40 70 65 72 61 74 69 6f 6e 20 6d 75 73 74 20 6f 63  peration must oc
17e50 63 75 72 20 77 68 69 6c 65 20 74 68 65 20 70 61  cur while the pa
17e60 67 65 72 20 69 73 20 73 74 69 6c 6c 20 68 6f 6c  ger is still hol
17e70 64 69 6e 67 20 74 68 65 20 65 78 63 6c 75 73 69  ding the exclusi
17e80 76 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20 74 68  ve.** lock on th
17e90 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20  e main database 
17ea0 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6f  file..**.** If o
17eb0 70 20 69 73 20 6f 6e 65 2c 20 74 68 65 6e 20 63  p is one, then c
17ec0 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63 6b 69  hange from locki
17ed0 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 69  ng_mode=NORMAL i
17ee0 6e 74 6f 20 0a 2a 2a 20 6c 6f 63 6b 69 6e 67 5f  nto .** locking_
17ef0 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45 2e 20  mode=EXCLUSIVE. 
17f00 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68 61 74   This means that
17f10 20 74 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c   the pWal->readL
17f20 6f 63 6b 20 6d 75 73 74 0a 2a 2a 20 62 65 20 72  ock must.** be r
17f30 65 6c 65 61 73 65 64 2e 20 20 52 65 74 75 72 6e  eleased.  Return
17f40 20 31 20 69 66 20 74 68 65 20 74 72 61 6e 73 69   1 if the transi
17f50 74 69 6f 6e 20 69 73 20 6d 61 64 65 20 61 6e 64  tion is made and
17f60 20 30 20 69 66 20 74 68 65 0a 2a 2a 20 57 41 4c   0 if the.** WAL
17f70 20 69 73 20 61 6c 72 65 61 64 79 20 69 6e 20 65   is already in e
17f80 78 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69 6e 67  xclusive-locking
17f90 20 6d 6f 64 65 20 2d 20 6d 65 61 6e 69 6e 67 20   mode - meaning 
17fa0 74 68 61 74 20 74 68 69 73 0a 2a 2a 20 72 6f 75  that this.** rou
17fb0 74 69 6e 65 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  tine is a no-op.
17fc0 20 20 54 68 65 20 70 61 67 65 72 20 6d 75 73 74    The pager must
17fd0 20 61 6c 72 65 61 64 79 20 68 6f 6c 64 20 74 68   already hold th
17fe0 65 20 65 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b  e exclusive lock
17ff0 0a 2a 2a 20 6f 6e 20 74 68 65 20 6d 61 69 6e 20  .** on the main 
18000 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 62 65  database file be
18010 66 6f 72 65 20 69 6e 76 6f 6b 69 6e 67 20 74 68  fore invoking th
18020 69 73 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 2a 2a  is operation..**
18030 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20 6e 65 67  .** If op is neg
18040 61 74 69 76 65 2c 20 74 68 65 6e 20 64 6f 20 61  ative, then do a
18050 20 64 72 79 2d 72 75 6e 20 6f 66 20 74 68 65 20   dry-run of the 
18060 6f 70 3d 3d 31 20 63 61 73 65 20 62 75 74 20 64  op==1 case but d
18070 6f 0a 2a 2a 20 6e 6f 74 20 61 63 74 75 61 6c 6c  o.** not actuall
18080 79 20 63 68 61 6e 67 65 20 61 6e 79 74 68 69 6e  y change anythin
18090 67 2e 20 20 54 68 65 20 70 61 67 65 72 20 75 73  g.  The pager us
180a0 65 73 20 74 68 69 73 20 74 6f 20 73 65 65 20 69  es this to see i
180b0 66 20 69 74 0a 2a 2a 20 73 68 6f 75 6c 64 20 61  f it.** should a
180c0 63 71 75 69 72 65 20 74 68 65 20 64 61 74 61 62  cquire the datab
180d0 61 73 65 20 65 78 63 6c 75 73 69 76 65 20 6c 6f  ase exclusive lo
180e0 63 6b 20 70 72 69 6f 72 20 74 6f 20 69 6e 76 6f  ck prior to invo
180f0 6b 69 6e 67 0a 2a 2a 20 74 68 65 20 6f 70 3d 3d  king.** the op==
18100 31 20 63 61 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73  1 case..*/.int s
18110 71 6c 69 74 65 33 57 61 6c 45 78 63 6c 75 73 69  qlite3WalExclusi
18120 76 65 4d 6f 64 65 28 57 61 6c 20 2a 70 57 61 6c  veMode(Wal *pWal
18130 2c 20 69 6e 74 20 6f 70 29 7b 0a 20 20 69 6e 74  , int op){.  int
18140 20 72 63 3b 0a 20 20 61 73 73 65 72 74 28 20 70   rc;.  assert( p
18150 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 3d 3d  Wal->writeLock==
18160 30 20 29 3b 0a 0a 20 20 2f 2a 20 70 57 61 6c 2d  0 );..  /* pWal-
18170 3e 72 65 61 64 4c 6f 63 6b 20 69 73 20 75 73 75  >readLock is usu
18180 61 6c 6c 79 20 73 65 74 2c 20 62 75 74 20 6d 69  ally set, but mi
18190 67 68 74 20 62 65 20 2d 31 20 69 66 20 74 68 65  ght be -1 if the
181a0 72 65 20 77 61 73 20 61 20 0a 20 20 2a 2a 20 70  re was a .  ** p
181b0 72 69 6f 72 20 65 72 72 6f 72 20 77 68 69 6c 65  rior error while
181c0 20 61 74 74 65 6d 70 74 69 6e 67 20 74 6f 20 61   attempting to a
181d0 63 71 75 69 72 65 20 61 72 65 20 72 65 61 64 2d  cquire are read-
181e0 6c 6f 63 6b 2e 20 54 68 69 73 20 63 61 6e 6e 6f  lock. This canno
181f0 74 20 0a 20 20 2a 2a 20 68 61 70 70 65 6e 20 69  t .  ** happen i
18200 66 20 74 68 65 20 63 6f 6e 6e 65 63 74 69 6f 6e  f the connection
18210 20 69 73 20 61 63 74 75 61 6c 6c 79 20 69 6e 20   is actually in 
18220 65 78 63 6c 75 73 69 76 65 20 6d 6f 64 65 20 28  exclusive mode (
18230 61 73 20 6e 6f 20 78 53 68 6d 4c 6f 63 6b 0a 20  as no xShmLock. 
18240 20 2a 2a 20 6c 6f 63 6b 73 20 61 72 65 20 74 61   ** locks are ta
18250 6b 65 6e 20 69 6e 20 74 68 69 73 20 63 61 73 65  ken in this case
18260 29 2e 20 4e 6f 72 20 73 68 6f 75 6c 64 20 74 68  ). Nor should th
18270 65 20 70 61 67 65 72 20 61 74 74 65 6d 70 74 20  e pager attempt 
18280 74 6f 0a 20 20 2a 2a 20 75 70 67 72 61 64 65 20  to.  ** upgrade 
18290 74 6f 20 65 78 63 6c 75 73 69 76 65 2d 6d 6f 64  to exclusive-mod
182a0 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 75 63 68  e following such
182b0 20 61 6e 20 65 72 72 6f 72 2e 0a 20 20 2a 2f 0a   an error..  */.
182c0 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e    assert( pWal->
182d0 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70  readLock>=0 || p
182e0 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 29  Wal->lockError )
182f0 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  ;.  assert( pWal
18300 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c  ->readLock>=0 ||
18310 20 28 6f 70 3c 3d 30 20 26 26 20 70 57 61 6c 2d   (op<=0 && pWal-
18320 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 3d 3d  >exclusiveMode==
18330 30 29 20 29 3b 0a 0a 20 20 69 66 28 20 6f 70 3d  0) );..  if( op=
18340 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70 57  =0 ){.    if( pW
18350 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  al->exclusiveMod
18360 65 20 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d  e ){.      pWal-
18370 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d  >exclusiveMode =
18380 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20 77 61   0;.      if( wa
18390 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57 61 6c  lLockShared(pWal
183a0 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  , WAL_READ_LOCK(
183b0 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 29 29  pWal->readLock))
183c0 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
183d0 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 65 78 63         pWal->exc
183e0 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 31 3b 0a  lusiveMode = 1;.
183f0 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 63        }.      rc
18400 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69   = pWal->exclusi
18410 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 20 20 7d  veMode==0;.    }
18420 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a 20 41  else{.      /* A
18430 6c 72 65 61 64 79 20 69 6e 20 6c 6f 63 6b 69 6e  lready in lockin
18440 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20 2a 2f  g_mode=NORMAL */
18450 0a 20 20 20 20 20 20 72 63 20 3d 20 30 3b 0a 20  .      rc = 0;. 
18460 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69 66 28     }.  }else if(
18470 20 6f 70 3e 30 20 29 7b 0a 20 20 20 20 61 73 73   op>0 ){.    ass
18480 65 72 74 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75  ert( pWal->exclu
18490 73 69 76 65 4d 6f 64 65 3d 3d 30 20 29 3b 0a 20  siveMode==0 );. 
184a0 20 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d     assert( pWal-
184b0 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 3b 0a  >readLock>=0 );.
184c0 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68 61      walUnlockSha
184d0 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45  red(pWal, WAL_RE
184e0 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65  AD_LOCK(pWal->re
184f0 61 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70 57  adLock));.    pW
18500 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  al->exclusiveMod
18510 65 20 3d 20 31 3b 0a 20 20 20 20 72 63 20 3d 20  e = 1;.    rc = 
18520 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  1;.  }else{.    
18530 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75  rc = pWal->exclu
18540 73 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 7d  siveMode==0;.  }
18550 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
18560 0a 23 65 6e 64 69 66 20 2f 2a 20 23 69 66 6e 64  .#endif /* #ifnd
18570 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 57  ef SQLITE_OMIT_W
18580 41 4c 20 2a 2f 0a                                AL */.