/ Hex Artifact Content
Login

Artifact c261aeb28c9b40f4713bace3c1c0cee9dcba87ab:


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 32 34 20 62 79 74  header is 24 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 73 69 78 0a 2a 2a 20  ollowing six.** 
05e0: 62 69 67 2d 65 6e 64 69 61 6e 20 33 32 2d 62 69  big-endian 32-bi
05f0: 74 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 65 67  t unsigned integ
0600: 65 72 20 76 61 6c 75 65 73 3a 0a 2a 2a 0a 2a 2a  er values:.**.**
0610: 20 20 20 20 20 30 3a 20 4d 61 67 69 63 20 6e 75       0: Magic nu
0620: 6d 62 65 72 2e 20 20 30 78 33 37 37 66 30 36 38  mber.  0x377f068
0630: 32 20 6f 72 20 30 78 33 37 37 66 30 36 38 33 0a  2 or 0x377f0683.
0640: 2a 2a 20 20 20 20 20 34 3a 20 46 69 6c 65 20 66  **     4: File f
0650: 6f 72 6d 61 74 20 76 65 72 73 69 6f 6e 2e 20 20  ormat version.  
0660: 43 75 72 72 65 6e 74 6c 79 20 33 30 30 37 30 30  Currently 300700
0670: 30 0a 2a 2a 20 20 20 20 20 38 3a 20 44 61 74 61  0.**     8: Data
0680: 62 61 73 65 20 70 61 67 65 20 73 69 7a 65 2e 20  base page size. 
0690: 20 45 78 61 6d 70 6c 65 3a 20 31 30 32 34 0a 2a   Example: 1024.*
06a0: 2a 20 20 20 20 31 32 3a 20 43 68 65 63 6b 70 6f  *    12: Checkpo
06b0: 69 6e 74 20 73 65 71 75 65 6e 63 65 20 6e 75 6d  int sequence num
06c0: 62 65 72 0a 2a 2a 20 20 20 20 31 36 3a 20 53 61  ber.**    16: Sa
06d0: 6c 74 2d 31 2c 20 72 61 6e 64 6f 6d 20 69 6e 74  lt-1, random int
06e0: 65 67 65 72 20 69 6e 63 72 65 6d 65 6e 74 65 64  eger incremented
06f0: 20 77 69 74 68 20 65 61 63 68 20 63 68 65 63 6b   with each check
0700: 70 6f 69 6e 74 0a 2a 2a 20 20 20 20 32 30 3a 20  point.**    20: 
0710: 53 61 6c 74 2d 32 2c 20 61 20 64 69 66 66 65 72  Salt-2, a differ
0720: 65 6e 74 20 72 61 6e 64 6f 6d 20 69 6e 74 65 67  ent random integ
0730: 65 72 20 63 68 61 6e 67 69 6e 67 20 77 69 74 68  er changing with
0740: 20 65 61 63 68 20 63 6b 70 74 0a 2a 2a 0a 2a 2a   each ckpt.**.**
0750: 20 49 6d 6d 65 64 69 61 74 65 6c 79 20 66 6f 6c   Immediately fol
0760: 6c 6f 77 69 6e 67 20 74 68 65 20 77 61 6c 2d 68  lowing the wal-h
0770: 65 61 64 65 72 20 61 72 65 20 7a 65 72 6f 20 6f  eader are zero o
0780: 72 20 6d 6f 72 65 20 66 72 61 6d 65 73 2e 20 45  r more frames. E
0790: 61 63 68 0a 2a 2a 20 66 72 61 6d 65 20 63 6f 6e  ach.** frame con
07a0: 73 69 73 74 73 20 6f 66 20 61 20 32 34 2d 62 79  sists of a 24-by
07b0: 74 65 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20  te frame-header 
07c0: 66 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20 3c 70  followed by a <p
07d0: 61 67 65 2d 73 69 7a 65 3e 20 62 79 74 65 73 0a  age-size> bytes.
07e0: 2a 2a 20 6f 66 20 70 61 67 65 20 64 61 74 61 2e  ** of page data.
07f0: 20 54 68 65 20 66 72 61 6d 65 2d 68 65 61 64 65   The frame-heade
0800: 72 20 69 73 20 62 72 6f 6b 65 6e 20 69 6e 74 6f  r is broken into
0810: 20 36 20 62 69 67 2d 65 6e 64 69 61 6e 20 33 32   6 big-endian 32
0820: 2d 62 69 74 20 75 6e 73 69 67 6e 65 64 20 0a 2a  -bit unsigned .*
0830: 2a 20 69 6e 74 65 67 65 72 20 76 61 6c 75 65 73  * integer values
0840: 2c 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a  , as follows:.**
0850: 0a 2a 2a 20 20 20 20 20 30 3a 20 50 61 67 65 20  .**     0: Page 
0860: 6e 75 6d 62 65 72 2e 0a 2a 2a 20 20 20 20 20 34  number..**     4
0870: 3a 20 46 6f 72 20 63 6f 6d 6d 69 74 20 72 65 63  : For commit rec
0880: 6f 72 64 73 2c 20 74 68 65 20 73 69 7a 65 20 6f  ords, the size o
0890: 66 20 74 68 65 20 64 61 74 61 62 61 73 65 20 69  f the database i
08a0: 6d 61 67 65 20 69 6e 20 70 61 67 65 73 20 0a 2a  mage in pages .*
08b0: 2a 20 20 20 20 20 20 20 20 61 66 74 65 72 20 74  *        after t
08c0: 68 65 20 63 6f 6d 6d 69 74 2e 20 46 6f 72 20 61  he commit. For a
08d0: 6c 6c 20 6f 74 68 65 72 20 72 65 63 6f 72 64 73  ll other records
08e0: 2c 20 7a 65 72 6f 2e 0a 2a 2a 20 20 20 20 20 38  , zero..**     8
08f0: 3a 20 53 61 6c 74 2d 31 20 28 63 6f 70 69 65 64  : Salt-1 (copied
0900: 20 66 72 6f 6d 20 74 68 65 20 68 65 61 64 65 72   from the header
0910: 29 0a 2a 2a 20 20 20 20 31 32 3a 20 53 61 6c 74  ).**    12: Salt
0920: 2d 32 20 28 63 6f 70 69 65 64 20 66 72 6f 6d 20  -2 (copied from 
0930: 74 68 65 20 68 65 61 64 65 72 29 0a 2a 2a 20 20  the header).**  
0940: 20 20 31 36 3a 20 43 68 65 63 6b 73 75 6d 2d 31    16: Checksum-1
0950: 2e 0a 2a 2a 20 20 20 20 32 30 3a 20 43 68 65 63  ..**    20: Chec
0960: 6b 73 75 6d 2d 32 2e 0a 2a 2a 0a 2a 2a 20 41 20  ksum-2..**.** A 
0970: 66 72 61 6d 65 20 69 73 20 63 6f 6e 73 69 64 65  frame is conside
0980: 72 65 64 20 76 61 6c 69 64 20 69 66 20 61 6e 64  red valid if and
0990: 20 6f 6e 6c 79 20 69 66 20 74 68 65 20 66 6f 6c   only if the fol
09a0: 6c 6f 77 69 6e 67 20 63 6f 6e 64 69 74 69 6f 6e  lowing condition
09b0: 73 20 61 72 65 0a 2a 2a 20 74 72 75 65 3a 0a 2a  s are.** true:.*
09c0: 2a 0a 2a 2a 20 20 20 20 28 31 29 20 54 68 65 20  *.**    (1) The 
09d0: 73 61 6c 74 2d 31 20 61 6e 64 20 73 61 6c 74 2d  salt-1 and salt-
09e0: 32 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20  2 values in the 
09f0: 66 72 61 6d 65 2d 68 65 61 64 65 72 20 6d 61 74  frame-header mat
0a00: 63 68 0a 2a 2a 20 20 20 20 20 20 20 20 73 61 6c  ch.**        sal
0a10: 74 20 76 61 6c 75 65 73 20 69 6e 20 74 68 65 20  t values in the 
0a20: 77 61 6c 2d 68 65 61 64 65 72 0a 2a 2a 0a 2a 2a  wal-header.**.**
0a30: 20 20 20 20 28 32 29 20 54 68 65 20 63 68 65 63      (2) The chec
0a40: 6b 73 75 6d 20 76 61 6c 75 65 73 20 69 6e 20 74  ksum values in t
0a50: 68 65 20 66 69 6e 61 6c 20 38 20 62 79 74 65 73  he final 8 bytes
0a60: 20 6f 66 20 74 68 65 20 66 72 61 6d 65 2d 68 65   of the frame-he
0a70: 61 64 65 72 0a 2a 2a 20 20 20 20 20 20 20 20 65  ader.**        e
0a80: 78 61 63 74 6c 79 20 6d 61 74 63 68 20 74 68 65  xactly match the
0a90: 20 63 68 65 63 6b 73 75 6d 20 63 6f 6d 70 75 74   checksum comput
0aa0: 65 64 20 63 6f 6e 73 65 63 75 74 69 76 65 6c 79  ed consecutively
0ab0: 20 6f 6e 20 74 68 65 0a 2a 2a 20 20 20 20 20 20   on the.**      
0ac0: 20 20 57 41 4c 20 68 65 61 64 65 72 20 61 6e 64    WAL header and
0ad0: 20 74 68 65 20 66 69 72 73 74 20 38 20 62 79 74   the first 8 byt
0ae0: 65 73 20 61 6e 64 20 74 68 65 20 63 6f 6e 74 65  es and the conte
0af0: 6e 74 20 6f 66 20 61 6c 6c 20 66 72 61 6d 65 73  nt of all frames
0b00: 0a 2a 2a 20 20 20 20 20 20 20 20 75 70 20 74 6f  .**        up to
0b10: 20 61 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20 74   and including t
0b20: 68 65 20 63 75 72 72 65 6e 74 20 66 72 61 6d 65  he current frame
0b30: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65 63  ..**.** The chec
0b40: 6b 73 75 6d 20 69 73 20 63 6f 6d 70 75 74 65 64  ksum is computed
0b50: 20 75 73 69 6e 67 20 33 32 2d 62 69 74 20 62 69   using 32-bit bi
0b60: 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65 72  g-endian integer
0b70: 73 20 69 66 20 74 68 65 0a 2a 2a 20 6d 61 67 69  s if the.** magi
0b80: 63 20 6e 75 6d 62 65 72 20 69 6e 20 74 68 65 20  c number in the 
0b90: 66 69 72 73 74 20 34 20 62 79 74 65 73 20 6f 66  first 4 bytes of
0ba0: 20 74 68 65 20 57 41 4c 20 69 73 20 30 78 33 37   the WAL is 0x37
0bb0: 37 66 30 36 38 33 20 61 6e 64 20 69 74 0a 2a 2a  7f0683 and it.**
0bc0: 20 69 73 20 63 6f 6d 70 75 74 65 64 20 75 73 69   is computed usi
0bd0: 6e 67 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61 6e  ng little-endian
0be0: 20 69 66 20 74 68 65 20 6d 61 67 69 63 20 6e 75   if the magic nu
0bf0: 6d 62 65 72 20 69 73 20 30 78 33 37 37 66 30 36  mber is 0x377f06
0c00: 38 32 2e 0a 2a 2a 20 54 68 65 20 63 68 65 63 6b  82..** The check
0c10: 73 75 6d 20 76 61 6c 75 65 73 20 61 72 65 20 61  sum values are a
0c20: 6c 77 61 79 73 20 73 74 6f 72 65 64 20 69 6e 20  lways stored in 
0c30: 74 68 65 20 66 72 61 6d 65 20 68 65 61 64 65 72  the frame header
0c40: 20 69 6e 20 61 0a 2a 2a 20 62 69 67 2d 65 6e 64   in a.** big-end
0c50: 69 61 6e 20 66 6f 72 6d 61 74 20 72 65 67 61 72  ian format regar
0c60: 64 6c 65 73 73 20 6f 66 20 77 68 69 63 68 20 62  dless of which b
0c70: 79 74 65 20 6f 72 64 65 72 20 69 73 20 75 73 65  yte order is use
0c80: 64 20 74 6f 20 63 6f 6d 70 75 74 65 0a 2a 2a 20  d to compute.** 
0c90: 74 68 65 20 63 68 65 63 6b 73 75 6d 2e 20 20 54  the checksum.  T
0ca0: 68 65 20 63 68 65 63 6b 73 75 6d 20 69 73 20 63  he checksum is c
0cb0: 6f 6d 70 75 74 65 64 20 62 79 20 69 6e 74 65 72  omputed by inter
0cc0: 70 72 65 74 69 6e 67 20 74 68 65 20 69 6e 70 75  preting the inpu
0cd0: 74 20 61 73 0a 2a 2a 20 61 6e 20 65 76 65 6e 20  t as.** an even 
0ce0: 6e 75 6d 62 65 72 20 6f 66 20 75 6e 73 69 67 6e  number of unsign
0cf0: 65 64 20 33 32 2d 62 69 74 20 69 6e 74 65 67 65  ed 32-bit intege
0d00: 72 73 3a 20 78 5b 30 5d 20 74 68 72 6f 75 67 68  rs: x[0] through
0d10: 20 78 5b 4e 5d 2e 20 20 54 68 65 0a 2a 2a 20 0a   x[N].  The.** .
0d20: 2a 2a 20 20 20 66 6f 72 20 69 20 66 72 6f 6d 20  **   for i from 
0d30: 30 20 74 6f 20 6e 2d 31 20 73 74 65 70 20 32 3a  0 to n-1 step 2:
0d40: 0a 2a 2a 20 20 20 20 20 73 30 20 2b 3d 20 78 5b  .**     s0 += x[
0d50: 69 5d 20 2b 20 73 31 3b 0a 2a 2a 20 20 20 20 20  i] + s1;.**     
0d60: 73 31 20 2b 3d 20 78 5b 69 2b 31 5d 20 2b 20 73  s1 += x[i+1] + s
0d70: 30 3b 0a 2a 2a 20 20 20 65 6e 64 66 6f 72 0a 2a  0;.**   endfor.*
0d80: 2a 0a 2a 2a 20 4f 6e 20 61 20 63 68 65 63 6b 70  *.** On a checkp
0d90: 6f 69 6e 74 2c 20 74 68 65 20 57 41 4c 20 69 73  oint, the WAL is
0da0: 20 66 69 72 73 74 20 56 46 53 2e 78 53 79 6e 63   first VFS.xSync
0db0: 2d 65 64 2c 20 74 68 65 6e 20 76 61 6c 69 64 20  -ed, then valid 
0dc0: 63 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65 0a 2a  content of the.*
0dd0: 2a 20 57 41 4c 20 69 73 20 74 72 61 6e 73 66 65  * WAL is transfe
0de0: 72 72 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61  rred into the da
0df0: 74 61 62 61 73 65 2c 20 74 68 65 6e 20 74 68 65  tabase, then the
0e00: 20 64 61 74 61 62 61 73 65 20 69 73 20 56 46 53   database is VFS
0e10: 2e 78 53 79 6e 63 2d 65 64 2e 0a 2a 2a 20 54 68  .xSync-ed..** Th
0e20: 65 20 56 46 53 2e 78 53 79 6e 63 20 6f 70 65 72  e VFS.xSync oper
0e30: 61 74 69 6f 6e 73 20 73 65 72 76 65 72 20 61 73  ations server as
0e40: 20 77 72 69 74 65 20 62 61 72 72 69 65 72 73 20   write barriers 
0e50: 2d 20 61 6c 6c 20 77 72 69 74 65 73 20 6c 61 75  - all writes lau
0e60: 6e 63 68 65 64 0a 2a 2a 20 62 65 66 6f 72 65 20  nched.** before 
0e70: 74 68 65 20 78 53 79 6e 63 20 6d 75 73 74 20 63  the xSync must c
0e80: 6f 6d 70 6c 65 74 65 20 62 65 66 6f 72 65 20 61  omplete before a
0e90: 6e 79 20 77 72 69 74 65 20 74 68 61 74 20 6c 61  ny write that la
0ea0: 75 6e 63 68 65 73 20 61 66 74 65 72 20 74 68 65  unches after the
0eb0: 0a 2a 2a 20 78 53 79 6e 63 20 62 65 67 69 6e 73  .** xSync begins
0ec0: 2e 0a 2a 2a 0a 2a 2a 20 41 66 74 65 72 20 65 61  ..**.** After ea
0ed0: 63 68 20 63 68 65 63 6b 70 6f 69 6e 74 2c 20 74  ch checkpoint, t
0ee0: 68 65 20 73 61 6c 74 2d 31 20 76 61 6c 75 65 20  he salt-1 value 
0ef0: 69 73 20 69 6e 63 72 65 6d 65 6e 74 65 64 20 61  is incremented a
0f00: 6e 64 20 74 68 65 20 73 61 6c 74 2d 32 0a 2a 2a  nd the salt-2.**
0f10: 20 76 61 6c 75 65 20 69 73 20 72 61 6e 64 6f 6d   value is random
0f20: 69 7a 65 64 2e 20 20 54 68 69 73 20 70 72 65 76  ized.  This prev
0f30: 65 6e 74 73 20 6f 6c 64 20 61 6e 64 20 6e 65 77  ents old and new
0f40: 20 66 72 61 6d 65 73 20 69 6e 20 74 68 65 20 57   frames in the W
0f50: 41 4c 20 66 72 6f 6d 0a 2a 2a 20 62 65 69 6e 67  AL from.** being
0f60: 20 63 6f 6e 73 69 64 65 72 65 64 20 76 61 6c 69   considered vali
0f70: 64 20 61 74 20 74 68 65 20 73 61 6d 65 20 74 69  d at the same ti
0f80: 6d 65 20 61 6e 64 20 62 65 69 6e 67 20 63 68 65  me and being che
0f90: 63 6b 70 6f 69 6e 74 69 6e 67 20 74 6f 67 65 74  ckpointing toget
0fa0: 68 65 72 0a 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67  her.** following
0fb0: 20 61 20 63 72 61 73 68 2e 0a 2a 2a 0a 2a 2a 20   a crash..**.** 
0fc0: 52 45 41 44 45 52 20 41 4c 47 4f 52 49 54 48 4d  READER ALGORITHM
0fd0: 0a 2a 2a 0a 2a 2a 20 54 6f 20 72 65 61 64 20 61  .**.** To read a
0fe0: 20 70 61 67 65 20 66 72 6f 6d 20 74 68 65 20 64   page from the d
0ff0: 61 74 61 62 61 73 65 20 28 63 61 6c 6c 20 69 74  atabase (call it
1000: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 50 29 2c   page number P),
1010: 20 61 20 72 65 61 64 65 72 0a 2a 2a 20 66 69 72   a reader.** fir
1020: 73 74 20 63 68 65 63 6b 73 20 74 68 65 20 57 41  st checks the WA
1030: 4c 20 74 6f 20 73 65 65 20 69 66 20 69 74 20 63  L to see if it c
1040: 6f 6e 74 61 69 6e 73 20 70 61 67 65 20 50 2e 20  ontains page P. 
1050: 20 49 66 20 73 6f 2c 20 74 68 65 6e 20 74 68 65   If so, then the
1060: 0a 2a 2a 20 6c 61 73 74 20 76 61 6c 69 64 20 69  .** last valid i
1070: 6e 73 74 61 6e 63 65 20 6f 66 20 70 61 67 65 20  nstance of page 
1080: 50 20 74 68 61 74 20 69 73 20 61 20 66 6f 6c 6c  P that is a foll
1090: 6f 77 65 64 20 62 79 20 61 20 63 6f 6d 6d 69 74  owed by a commit
10a0: 20 66 72 61 6d 65 0a 2a 2a 20 6f 72 20 69 73 20   frame.** or is 
10b0: 61 20 63 6f 6d 6d 69 74 20 66 72 61 6d 65 20 69  a commit frame i
10c0: 74 73 65 6c 66 20 62 65 63 6f 6d 65 73 20 74 68  tself becomes th
10d0: 65 20 76 61 6c 75 65 20 72 65 61 64 2e 20 20 49  e value read.  I
10e0: 66 20 74 68 65 20 57 41 4c 0a 2a 2a 20 63 6f 6e  f the WAL.** con
10f0: 74 61 69 6e 73 20 6e 6f 20 63 6f 70 69 65 73 20  tains no copies 
1100: 6f 66 20 70 61 67 65 20 50 20 74 68 61 74 20 61  of page P that a
1110: 72 65 20 76 61 6c 69 64 20 61 6e 64 20 77 68 69  re valid and whi
1120: 63 68 20 61 72 65 20 61 20 63 6f 6d 6d 69 74 0a  ch are a commit.
1130: 2a 2a 20 66 72 61 6d 65 20 6f 72 20 61 72 65 20  ** frame or are 
1140: 66 6f 6c 6c 6f 77 65 64 20 62 79 20 61 20 63 6f  followed by a co
1150: 6d 6d 69 74 20 66 72 61 6d 65 2c 20 74 68 65 6e  mmit frame, then
1160: 20 70 61 67 65 20 50 20 69 73 20 72 65 61 64 20   page P is read 
1170: 66 72 6f 6d 0a 2a 2a 20 74 68 65 20 64 61 74 61  from.** the data
1180: 62 61 73 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a  base file..**.**
1190: 20 54 6f 20 73 74 61 72 74 20 61 20 72 65 61 64   To start a read
11a0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 2c 20 74 68   transaction, th
11b0: 65 20 72 65 61 64 65 72 20 72 65 63 6f 72 64 73  e reader records
11c0: 20 74 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68   the index of th
11d0: 65 20 6c 61 73 74 0a 2a 2a 20 76 61 6c 69 64 20  e last.** valid 
11e0: 66 72 61 6d 65 20 69 6e 20 74 68 65 20 57 41 4c  frame in the WAL
11f0: 2e 20 20 54 68 65 20 72 65 61 64 65 72 20 75 73  .  The reader us
1200: 65 73 20 74 68 69 73 20 72 65 63 6f 72 64 65 64  es this recorded
1210: 20 22 6d 78 46 72 61 6d 65 22 20 76 61 6c 75 65   "mxFrame" value
1220: 0a 2a 2a 20 66 6f 72 20 61 6c 6c 20 73 75 62 73  .** for all subs
1230: 65 71 75 65 6e 74 20 72 65 61 64 20 6f 70 65 72  equent read oper
1240: 61 74 69 6f 6e 73 2e 20 20 4e 65 77 20 74 72 61  ations.  New tra
1250: 6e 73 61 63 74 69 6f 6e 73 20 63 61 6e 20 62 65  nsactions can be
1260: 20 61 70 70 65 6e 64 65 64 0a 2a 2a 20 74 6f 20   appended.** to 
1270: 74 68 65 20 57 41 4c 2c 20 62 75 74 20 61 73 20  the WAL, but as 
1280: 6c 6f 6e 67 20 61 73 20 74 68 65 20 72 65 61 64  long as the read
1290: 65 72 20 75 73 65 73 20 69 74 73 20 6f 72 69 67  er uses its orig
12a0: 69 6e 61 6c 20 6d 78 46 72 61 6d 65 20 76 61 6c  inal mxFrame val
12b0: 75 65 0a 2a 2a 20 61 6e 64 20 69 67 6e 6f 72 65  ue.** and ignore
12c0: 73 20 74 68 65 20 6e 65 77 6c 79 20 61 70 70 65  s the newly appe
12d0: 6e 64 65 64 20 63 6f 6e 74 65 6e 74 2c 20 69 74  nded content, it
12e0: 20 77 69 6c 6c 20 73 65 65 20 61 20 63 6f 6e 73   will see a cons
12f0: 69 73 74 65 6e 74 20 73 6e 61 70 73 68 6f 74 0a  istent snapshot.
1300: 2a 2a 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  ** of the databa
1310: 73 65 20 66 72 6f 6d 20 61 20 73 69 6e 67 6c 65  se from a single
1320: 20 70 6f 69 6e 74 20 69 6e 20 74 69 6d 65 2e 20   point in time. 
1330: 20 54 68 69 73 20 74 65 63 68 6e 69 71 75 65 20   This technique 
1340: 61 6c 6c 6f 77 73 0a 2a 2a 20 6d 75 6c 74 69 70  allows.** multip
1350: 6c 65 20 63 6f 6e 63 75 72 72 65 6e 74 20 72 65  le concurrent re
1360: 61 64 65 72 73 20 74 6f 20 76 69 65 77 20 64 69  aders to view di
1370: 66 66 65 72 65 6e 74 20 76 65 72 73 69 6f 6e 73  fferent versions
1380: 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65   of the database
1390: 0a 2a 2a 20 63 6f 6e 74 65 6e 74 20 73 69 6d 75  .** content simu
13a0: 6c 74 61 6e 65 6f 75 73 6c 79 2e 0a 2a 2a 0a 2a  ltaneously..**.*
13b0: 2a 20 54 68 65 20 72 65 61 64 65 72 20 61 6c 67  * The reader alg
13c0: 6f 72 69 74 68 6d 20 69 6e 20 74 68 65 20 70 72  orithm in the pr
13d0: 65 76 69 6f 75 73 20 70 61 72 61 67 72 61 70 68  evious paragraph
13e0: 73 20 77 6f 72 6b 73 20 63 6f 72 72 65 63 74 6c  s works correctl
13f0: 79 2c 20 62 75 74 20 0a 2a 2a 20 62 65 63 61 75  y, but .** becau
1400: 73 65 20 66 72 61 6d 65 73 20 66 6f 72 20 70 61  se frames for pa
1410: 67 65 20 50 20 63 61 6e 20 61 70 70 65 61 72 20  ge P can appear 
1420: 61 6e 79 77 68 65 72 65 20 77 69 74 68 69 6e 20  anywhere within 
1430: 74 68 65 20 57 41 4c 2c 20 74 68 65 0a 2a 2a 20  the WAL, the.** 
1440: 72 65 61 64 65 72 20 68 61 73 20 74 6f 20 73 63  reader has to sc
1450: 61 6e 20 74 68 65 20 65 6e 74 69 72 65 20 57 41  an the entire WA
1460: 4c 20 6c 6f 6f 6b 69 6e 67 20 66 6f 72 20 70 61  L looking for pa
1470: 67 65 20 50 20 66 72 61 6d 65 73 2e 20 20 49 66  ge P frames.  If
1480: 20 74 68 65 0a 2a 2a 20 57 41 4c 20 69 73 20 6c   the.** WAL is l
1490: 61 72 67 65 20 28 6d 75 6c 74 69 70 6c 65 20 6d  arge (multiple m
14a0: 65 67 61 62 79 74 65 73 20 69 73 20 74 79 70 69  egabytes is typi
14b0: 63 61 6c 29 20 74 68 61 74 20 73 63 61 6e 20 63  cal) that scan c
14c0: 61 6e 20 62 65 20 73 6c 6f 77 2c 0a 2a 2a 20 61  an be slow,.** a
14d0: 6e 64 20 72 65 61 64 20 70 65 72 66 6f 72 6d 61  nd read performa
14e0: 6e 63 65 20 73 75 66 66 65 72 73 2e 20 20 54 6f  nce suffers.  To
14f0: 20 6f 76 65 72 63 6f 6d 65 20 74 68 69 73 20 70   overcome this p
1500: 72 6f 62 6c 65 6d 2c 20 61 20 73 65 70 61 72 61  roblem, a separa
1510: 74 65 0a 2a 2a 20 64 61 74 61 20 73 74 72 75 63  te.** data struc
1520: 74 75 72 65 20 63 61 6c 6c 65 64 20 74 68 65 20  ture called the 
1530: 77 61 6c 2d 69 6e 64 65 78 20 69 73 20 6d 61 69  wal-index is mai
1540: 6e 74 61 69 6e 65 64 20 74 6f 20 65 78 70 65 64  ntained to exped
1550: 69 74 65 20 74 68 65 0a 2a 2a 20 73 65 61 72 63  ite the.** searc
1560: 68 20 66 6f 72 20 66 72 61 6d 65 73 20 6f 66 20  h for frames of 
1570: 61 20 70 61 72 74 69 63 75 6c 61 72 20 70 61 67  a particular pag
1580: 65 2e 0a 2a 2a 20 0a 2a 2a 20 57 41 4c 2d 49 4e  e..** .** WAL-IN
1590: 44 45 58 20 46 4f 52 4d 41 54 0a 2a 2a 0a 2a 2a  DEX FORMAT.**.**
15a0: 20 43 6f 6e 63 65 70 74 75 61 6c 6c 79 2c 20 74   Conceptually, t
15b0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
15c0: 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 2c 20 74  shared memory, t
15d0: 68 6f 75 67 68 20 56 46 53 20 69 6d 70 6c 65 6d  hough VFS implem
15e0: 65 6e 74 61 74 69 6f 6e 73 0a 2a 2a 20 6d 69 67  entations.** mig
15f0: 68 74 20 63 68 6f 6f 73 65 20 74 6f 20 69 6d 70  ht choose to imp
1600: 6c 65 6d 65 6e 74 20 74 68 65 20 77 61 6c 2d 69  lement the wal-i
1610: 6e 64 65 78 20 75 73 69 6e 67 20 61 20 6d 6d 61  ndex using a mma
1620: 70 70 65 64 20 66 69 6c 65 2e 20 20 42 65 63 61  pped file.  Beca
1630: 75 73 65 0a 2a 2a 20 74 68 65 20 77 61 6c 2d 69  use.** the wal-i
1640: 6e 64 65 78 20 69 73 20 73 68 61 72 65 64 20 6d  ndex is shared m
1650: 65 6d 6f 72 79 2c 20 53 51 4c 69 74 65 20 64 6f  emory, SQLite do
1660: 65 73 20 6e 6f 74 20 73 75 70 70 6f 72 74 20 6a  es not support j
1670: 6f 75 72 6e 61 6c 5f 6d 6f 64 65 3d 57 41 4c 20  ournal_mode=WAL 
1680: 0a 2a 2a 20 6f 6e 20 61 20 6e 65 74 77 6f 72 6b  .** on a network
1690: 20 66 69 6c 65 73 79 73 74 65 6d 2e 20 20 41 6c   filesystem.  Al
16a0: 6c 20 75 73 65 72 73 20 6f 66 20 74 68 65 20 64  l users of the d
16b0: 61 74 61 62 61 73 65 20 6d 75 73 74 20 62 65 20  atabase must be 
16c0: 61 62 6c 65 20 74 6f 0a 2a 2a 20 73 68 61 72 65  able to.** share
16d0: 20 6d 65 6d 6f 72 79 2e 0a 2a 2a 0a 2a 2a 20 54   memory..**.** T
16e0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
16f0: 74 72 61 6e 73 69 65 6e 74 2e 20 20 41 66 74 65  transient.  Afte
1700: 72 20 61 20 63 72 61 73 68 2c 20 74 68 65 20 77  r a crash, the w
1710: 61 6c 2d 69 6e 64 65 78 20 63 61 6e 20 28 61 6e  al-index can (an
1720: 64 20 73 68 6f 75 6c 64 0a 2a 2a 20 62 65 29 20  d should.** be) 
1730: 72 65 63 6f 6e 73 74 72 75 63 74 65 64 20 66 72  reconstructed fr
1740: 6f 6d 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20  om the original 
1750: 57 41 4c 20 66 69 6c 65 2e 20 20 49 6e 20 66 61  WAL file.  In fa
1760: 63 74 2c 20 74 68 65 20 56 46 53 20 69 73 20 72  ct, the VFS is r
1770: 65 71 75 69 72 65 64 0a 2a 2a 20 74 6f 20 65 69  equired.** to ei
1780: 74 68 65 72 20 74 72 75 6e 63 61 74 65 20 6f 72  ther truncate or
1790: 20 7a 65 72 6f 20 74 68 65 20 68 65 61 64 65 72   zero the header
17a0: 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
17b0: 78 20 77 68 65 6e 20 74 68 65 20 6c 61 73 74 0a  x when the last.
17c0: 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f  ** connection to
17d0: 20 69 74 20 63 6c 6f 73 65 73 2e 20 20 42 65 63   it closes.  Bec
17e0: 61 75 73 65 20 74 68 65 20 77 61 6c 2d 69 6e 64  ause the wal-ind
17f0: 65 78 20 69 73 20 74 72 61 6e 73 69 65 6e 74 2c  ex is transient,
1800: 20 69 74 20 63 61 6e 0a 2a 2a 20 75 73 65 20 61   it can.** use a
1810: 6e 20 61 72 63 68 69 74 65 63 74 75 72 65 2d 73  n architecture-s
1820: 70 65 63 69 66 69 63 20 66 6f 72 6d 61 74 3b 20  pecific format; 
1830: 69 74 20 64 6f 65 73 20 6e 6f 74 20 68 61 76 65  it does not have
1840: 20 74 6f 20 62 65 20 63 72 6f 73 73 2d 70 6c 61   to be cross-pla
1850: 74 66 6f 72 6d 2e 0a 2a 2a 20 48 65 6e 63 65 2c  tform..** Hence,
1860: 20 75 6e 6c 69 6b 65 20 74 68 65 20 64 61 74 61   unlike the data
1870: 62 61 73 65 20 61 6e 64 20 57 41 4c 20 66 69 6c  base and WAL fil
1880: 65 20 66 6f 72 6d 61 74 73 20 77 68 69 63 68 20  e formats which 
1890: 73 74 6f 72 65 20 61 6c 6c 20 76 61 6c 75 65 73  store all values
18a0: 0a 2a 2a 20 61 73 20 62 69 67 20 65 6e 64 69 61  .** as big endia
18b0: 6e 2c 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  n, the wal-index
18c0: 20 63 61 6e 20 73 74 6f 72 65 20 6d 75 6c 74 69   can store multi
18d0: 2d 62 79 74 65 20 76 61 6c 75 65 73 20 69 6e 20  -byte values in 
18e0: 74 68 65 20 6e 61 74 69 76 65 0a 2a 2a 20 62 79  the native.** by
18f0: 74 65 20 6f 72 64 65 72 20 6f 66 20 74 68 65 20  te order of the 
1900: 68 6f 73 74 20 63 6f 6d 70 75 74 65 72 2e 0a 2a  host computer..*
1910: 2a 0a 2a 2a 20 54 68 65 20 70 75 72 70 6f 73 65  *.** The purpose
1920: 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   of the wal-inde
1930: 78 20 69 73 20 74 6f 20 61 6e 73 77 65 72 20 74  x is to answer t
1940: 68 69 73 20 71 75 65 73 74 69 6f 6e 20 71 75 69  his question qui
1950: 63 6b 6c 79 3a 20 20 47 69 76 65 6e 0a 2a 2a 20  ckly:  Given.** 
1960: 61 20 70 61 67 65 20 6e 75 6d 62 65 72 20 50 2c  a page number P,
1970: 20 72 65 74 75 72 6e 20 74 68 65 20 69 6e 64 65   return the inde
1980: 78 20 6f 66 20 74 68 65 20 6c 61 73 74 20 66 72  x of the last fr
1990: 61 6d 65 20 66 6f 72 20 70 61 67 65 20 50 20 69  ame for page P i
19a0: 6e 20 74 68 65 20 57 41 4c 2c 0a 2a 2a 20 6f 72  n the WAL,.** or
19b0: 20 72 65 74 75 72 6e 20 4e 55 4c 4c 20 69 66 20   return NULL if 
19c0: 74 68 65 72 65 20 61 72 65 20 6e 6f 20 66 72 61  there are no fra
19d0: 6d 65 73 20 66 6f 72 20 70 61 67 65 20 50 20 69  mes for page P i
19e0: 6e 20 74 68 65 20 57 41 4c 2e 0a 2a 2a 0a 2a 2a  n the WAL..**.**
19f0: 20 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 63   The wal-index c
1a00: 6f 6e 73 69 73 74 73 20 6f 66 20 61 20 68 65 61  onsists of a hea
1a10: 64 65 72 20 72 65 67 69 6f 6e 2c 20 66 6f 6c 6c  der region, foll
1a20: 6f 77 65 64 20 62 79 20 61 6e 20 6f 6e 65 20 6f  owed by an one o
1a30: 72 0a 2a 2a 20 6d 6f 72 65 20 69 6e 64 65 78 20  r.** more index 
1a40: 62 6c 6f 63 6b 73 2e 20 20 0a 2a 2a 0a 2a 2a 20  blocks.  .**.** 
1a50: 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  The wal-index he
1a60: 61 64 65 72 20 63 6f 6e 74 61 69 6e 73 20 74 68  ader contains th
1a70: 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f  e total number o
1a80: 66 20 66 72 61 6d 65 73 20 77 69 74 68 69 6e 20  f frames within 
1a90: 74 68 65 20 57 41 4c 0a 2a 2a 20 69 6e 20 74 68  the WAL.** in th
1aa0: 65 20 74 68 65 20 6d 78 46 72 61 6d 65 20 66 69  e the mxFrame fi
1ab0: 65 6c 64 2e 20 20 0a 2a 2a 0a 2a 2a 20 45 61 63  eld.  .**.** Eac
1ac0: 68 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 65 78  h index block ex
1ad0: 63 65 70 74 20 66 6f 72 20 74 68 65 20 66 69 72  cept for the fir
1ae0: 73 74 20 63 6f 6e 74 61 69 6e 73 20 69 6e 66 6f  st contains info
1af0: 72 6d 61 74 69 6f 6e 20 6f 6e 20 0a 2a 2a 20 48  rmation on .** H
1b00: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 66  ASHTABLE_NPAGE f
1b10: 72 61 6d 65 73 2e 20 54 68 65 20 66 69 72 73 74  rames. The first
1b20: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 63 6f 6e   index block con
1b30: 74 61 69 6e 73 20 69 6e 66 6f 72 6d 61 74 69 6f  tains informatio
1b40: 6e 20 6f 6e 0a 2a 2a 20 48 41 53 48 54 41 42 4c  n on.** HASHTABL
1b50: 45 5f 4e 50 41 47 45 5f 4f 4e 45 20 66 72 61 6d  E_NPAGE_ONE fram
1b60: 65 73 2e 20 54 68 65 20 76 61 6c 75 65 73 20 6f  es. The values o
1b70: 66 20 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  f HASHTABLE_NPAG
1b80: 45 5f 4f 4e 45 20 61 6e 64 20 0a 2a 2a 20 48 41  E_ONE and .** HA
1b90: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 61 72  SHTABLE_NPAGE ar
1ba0: 65 20 73 65 6c 65 63 74 65 64 20 73 6f 20 74 68  e selected so th
1bb0: 61 74 20 74 6f 67 65 74 68 65 72 20 74 68 65 20  at together the 
1bc0: 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
1bd0: 20 61 6e 64 0a 2a 2a 20 66 69 72 73 74 20 69 6e   and.** first in
1be0: 64 65 78 20 62 6c 6f 63 6b 20 61 72 65 20 74 68  dex block are th
1bf0: 65 20 73 61 6d 65 20 73 69 7a 65 20 61 73 20 61  e same size as a
1c00: 6c 6c 20 6f 74 68 65 72 20 69 6e 64 65 78 20 62  ll other index b
1c10: 6c 6f 63 6b 73 20 69 6e 20 74 68 65 0a 2a 2a 20  locks in the.** 
1c20: 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a  wal-index..**.**
1c30: 20 45 61 63 68 20 69 6e 64 65 78 20 62 6c 6f 63   Each index bloc
1c40: 6b 20 63 6f 6e 74 61 69 6e 73 20 74 77 6f 20 73  k contains two s
1c50: 65 63 74 69 6f 6e 73 2c 20 61 20 70 61 67 65 2d  ections, a page-
1c60: 6d 61 70 70 69 6e 67 20 74 68 61 74 20 63 6f 6e  mapping that con
1c70: 74 61 69 6e 73 20 74 68 65 0a 2a 2a 20 64 61 74  tains the.** dat
1c80: 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65  abase page numbe
1c90: 72 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74  r associated wit
1ca0: 68 20 65 61 63 68 20 77 61 6c 20 66 72 61 6d 65  h each wal frame
1cb0: 2c 20 61 6e 64 20 61 20 68 61 73 68 2d 74 61 62  , and a hash-tab
1cc0: 6c 65 20 0a 2a 2a 20 74 68 61 74 20 61 6c 6c 6f  le .** that allo
1cd0: 77 73 20 75 73 65 72 73 20 74 6f 20 71 75 65 72  ws users to quer
1ce0: 79 20 61 6e 20 69 6e 64 65 78 20 62 6c 6f 63 6b  y an index block
1cf0: 20 66 6f 72 20 61 20 73 70 65 63 69 66 69 63 20   for a specific 
1d00: 70 61 67 65 20 6e 75 6d 62 65 72 2e 0a 2a 2a 20  page number..** 
1d10: 54 68 65 20 70 61 67 65 2d 6d 61 70 70 69 6e 67  The page-mapping
1d20: 20 69 73 20 61 6e 20 61 72 72 61 79 20 6f 66 20   is an array of 
1d30: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20  HASHTABLE_NPAGE 
1d40: 28 6f 72 20 48 41 53 48 54 41 42 4c 45 5f 4e 50  (or HASHTABLE_NP
1d50: 41 47 45 5f 4f 4e 45 0a 2a 2a 20 66 6f 72 20 74  AGE_ONE.** for t
1d60: 68 65 20 66 69 72 73 74 20 69 6e 64 65 78 20 62  he first index b
1d70: 6c 6f 63 6b 29 20 33 32 2d 62 69 74 20 70 61 67  lock) 32-bit pag
1d80: 65 20 6e 75 6d 62 65 72 73 2e 20 54 68 65 20 66  e numbers. The f
1d90: 69 72 73 74 20 65 6e 74 72 79 20 69 6e 20 74 68  irst entry in th
1da0: 65 20 0a 2a 2a 20 66 69 72 73 74 20 69 6e 64 65  e .** first inde
1db0: 78 2d 62 6c 6f 63 6b 20 63 6f 6e 74 61 69 6e 73  x-block contains
1dc0: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 70 61   the database pa
1dd0: 67 65 20 6e 75 6d 62 65 72 20 63 6f 72 72 65 73  ge number corres
1de0: 70 6f 6e 64 69 6e 67 20 74 6f 20 74 68 65 0a 2a  ponding to the.*
1df0: 2a 20 66 69 72 73 74 20 66 72 61 6d 65 20 69 6e  * first frame in
1e00: 20 74 68 65 20 57 41 4c 20 66 69 6c 65 2e 20 54   the WAL file. T
1e10: 68 65 20 66 69 72 73 74 20 65 6e 74 72 79 20 69  he first entry i
1e20: 6e 20 74 68 65 20 73 65 63 6f 6e 64 20 69 6e 64  n the second ind
1e30: 65 78 20 62 6c 6f 63 6b 0a 2a 2a 20 69 6e 20 74  ex block.** in t
1e40: 68 65 20 57 41 4c 20 66 69 6c 65 20 63 6f 72 72  he WAL file corr
1e50: 65 73 70 6f 6e 64 73 20 74 6f 20 74 68 65 20 28  esponds to the (
1e60: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f  HASHTABLE_NPAGE_
1e70: 4f 4e 45 2b 31 29 74 68 20 66 72 61 6d 65 20 69  ONE+1)th frame i
1e80: 6e 0a 2a 2a 20 74 68 65 20 6c 6f 67 2c 20 61 6e  n.** the log, an
1e90: 64 20 73 6f 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54  d so on..**.** T
1ea0: 68 65 20 6c 61 73 74 20 69 6e 64 65 78 20 62 6c  he last index bl
1eb0: 6f 63 6b 20 69 6e 20 61 20 77 61 6c 2d 69 6e 64  ock in a wal-ind
1ec0: 65 78 20 75 73 75 61 6c 6c 79 20 63 6f 6e 74 61  ex usually conta
1ed0: 69 6e 73 20 6c 65 73 73 20 74 68 61 6e 20 74 68  ins less than th
1ee0: 65 20 66 75 6c 6c 0a 2a 2a 20 63 6f 6d 70 6c 65  e full.** comple
1ef0: 6d 65 6e 74 20 6f 66 20 48 41 53 48 54 41 42 4c  ment of HASHTABL
1f00: 45 5f 4e 50 41 47 45 20 28 6f 72 20 48 41 53 48  E_NPAGE (or HASH
1f10: 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 29  TABLE_NPAGE_ONE)
1f20: 20 70 61 67 65 2d 6e 75 6d 62 65 72 73 2c 0a 2a   page-numbers,.*
1f30: 2a 20 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74  * depending on t
1f40: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
1f50: 68 65 20 57 41 4c 20 66 69 6c 65 2e 20 54 68 69  he WAL file. Thi
1f60: 73 20 64 6f 65 73 20 6e 6f 74 20 63 68 61 6e 67  s does not chang
1f70: 65 20 74 68 65 0a 2a 2a 20 61 6c 6c 6f 63 61 74  e the.** allocat
1f80: 65 64 20 73 69 7a 65 20 6f 66 20 74 68 65 20 70  ed size of the p
1f90: 61 67 65 2d 6d 61 70 70 69 6e 67 20 61 72 72 61  age-mapping arra
1fa0: 79 20 2d 20 74 68 65 20 70 61 67 65 2d 6d 61 70  y - the page-map
1fb0: 70 69 6e 67 20 61 72 72 61 79 20 6d 65 72 65 6c  ping array merel
1fc0: 79 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 75 6e  y.** contains un
1fd0: 75 73 65 64 20 65 6e 74 72 69 65 73 2e 0a 2a 2a  used entries..**
1fe0: 0a 2a 2a 20 45 76 65 6e 20 77 69 74 68 6f 75 74  .** Even without
1ff0: 20 75 73 69 6e 67 20 74 68 65 20 68 61 73 68 20   using the hash 
2000: 74 61 62 6c 65 2c 20 74 68 65 20 6c 61 73 74 20  table, the last 
2010: 66 72 61 6d 65 20 66 6f 72 20 70 61 67 65 20 50  frame for page P
2020: 0a 2a 2a 20 63 61 6e 20 62 65 20 66 6f 75 6e 64  .** can be found
2030: 20 62 79 20 73 63 61 6e 6e 69 6e 67 20 74 68 65   by scanning the
2040: 20 70 61 67 65 2d 6d 61 70 70 69 6e 67 20 73 65   page-mapping se
2050: 63 74 69 6f 6e 73 20 6f 66 20 65 61 63 68 20 69  ctions of each i
2060: 6e 64 65 78 20 62 6c 6f 63 6b 0a 2a 2a 20 73 74  ndex block.** st
2070: 61 72 74 69 6e 67 20 77 69 74 68 20 74 68 65 20  arting with the 
2080: 6c 61 73 74 20 69 6e 64 65 78 20 62 6c 6f 63 6b  last index block
2090: 20 61 6e 64 20 6d 6f 76 69 6e 67 20 74 6f 77 61   and moving towa
20a0: 72 64 20 74 68 65 20 66 69 72 73 74 2c 20 61 6e  rd the first, an
20b0: 64 0a 2a 2a 20 77 69 74 68 69 6e 20 65 61 63 68  d.** within each
20c0: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 2c 20 73 74   index block, st
20d0: 61 72 74 69 6e 67 20 61 74 20 74 68 65 20 65 6e  arting at the en
20e0: 64 20 61 6e 64 20 6d 6f 76 69 6e 67 20 74 6f 77  d and moving tow
20f0: 61 72 64 20 74 68 65 0a 2a 2a 20 62 65 67 69 6e  ard the.** begin
2100: 6e 69 6e 67 2e 20 20 54 68 65 20 66 69 72 73 74  ning.  The first
2110: 20 65 6e 74 72 79 20 74 68 61 74 20 65 71 75 61   entry that equa
2120: 6c 73 20 50 20 63 6f 72 72 65 73 70 6f 6e 64 73  ls P corresponds
2130: 20 74 6f 20 74 68 65 20 66 72 61 6d 65 0a 2a 2a   to the frame.**
2140: 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 63 6f 6e   holding the con
2150: 74 65 6e 74 20 66 6f 72 20 74 68 61 74 20 70 61  tent for that pa
2160: 67 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 68 61  ge..**.** The ha
2170: 73 68 20 74 61 62 6c 65 20 63 6f 6e 73 69 73 74  sh table consist
2180: 73 20 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e  s of HASHTABLE_N
2190: 53 4c 4f 54 20 31 36 2d 62 69 74 20 75 6e 73 69  SLOT 16-bit unsi
21a0: 67 6e 65 64 20 69 6e 74 65 67 65 72 73 2e 0a 2a  gned integers..*
21b0: 2a 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f  * HASHTABLE_NSLO
21c0: 54 20 3d 20 32 2a 48 41 53 48 54 41 42 4c 45 5f  T = 2*HASHTABLE_
21d0: 4e 50 41 47 45 2c 20 61 6e 64 20 74 68 65 72 65  NPAGE, and there
21e0: 20 69 73 20 6f 6e 65 20 65 6e 74 72 79 20 69 6e   is one entry in
21f0: 20 74 68 65 0a 2a 2a 20 68 61 73 68 20 74 61 62   the.** hash tab
2200: 6c 65 20 66 6f 72 20 65 61 63 68 20 70 61 67 65  le for each page
2210: 20 6e 75 6d 62 65 72 20 69 6e 20 74 68 65 20 6d   number in the m
2220: 61 70 70 69 6e 67 20 73 65 63 74 69 6f 6e 2c 20  apping section, 
2230: 73 6f 20 74 68 65 20 68 61 73 68 20 0a 2a 2a 20  so the hash .** 
2240: 74 61 62 6c 65 20 69 73 20 6e 65 76 65 72 20 6d  table is never m
2250: 6f 72 65 20 74 68 61 6e 20 68 61 6c 66 20 66 75  ore than half fu
2260: 6c 6c 2e 20 20 54 68 65 20 65 78 70 65 63 74 65  ll.  The expecte
2270: 64 20 6e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 6c  d number of coll
2280: 69 73 69 6f 6e 73 20 0a 2a 2a 20 70 72 69 6f 72  isions .** prior
2290: 20 74 6f 20 66 69 6e 64 69 6e 67 20 61 20 6d 61   to finding a ma
22a0: 74 63 68 20 69 73 20 31 2e 20 20 45 61 63 68 20  tch is 1.  Each 
22b0: 65 6e 74 72 79 20 6f 66 20 74 68 65 20 68 61 73  entry of the has
22c0: 68 20 74 61 62 6c 65 20 69 73 20 61 6e 0a 2a 2a  h table is an.**
22d0: 20 31 2d 62 61 73 65 64 20 69 6e 64 65 78 20 6f   1-based index o
22e0: 66 20 61 6e 20 65 6e 74 72 79 20 69 6e 20 74 68  f an entry in th
22f0: 65 20 6d 61 70 70 69 6e 67 20 73 65 63 74 69 6f  e mapping sectio
2300: 6e 20 6f 66 20 74 68 65 20 73 61 6d 65 0a 2a 2a  n of the same.**
2310: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 2e 20 20 20   index block.   
2320: 4c 65 74 20 4b 20 62 65 20 74 68 65 20 31 2d 62  Let K be the 1-b
2330: 61 73 65 64 20 69 6e 64 65 78 20 6f 66 20 74 68  ased index of th
2340: 65 20 6c 61 72 67 65 73 74 20 65 6e 74 72 79 20  e largest entry 
2350: 69 6e 0a 2a 2a 20 74 68 65 20 6d 61 70 70 69 6e  in.** the mappin
2360: 67 20 73 65 63 74 69 6f 6e 2e 20 20 28 46 6f 72  g section.  (For
2370: 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73 20 6f 74   index blocks ot
2380: 68 65 72 20 74 68 61 6e 20 74 68 65 20 6c 61 73  her than the las
2390: 74 2c 20 4b 20 77 69 6c 6c 0a 2a 2a 20 61 6c 77  t, K will.** alw
23a0: 61 79 73 20 62 65 20 65 78 61 63 74 6c 79 20 48  ays be exactly H
23b0: 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 28  ASHTABLE_NPAGE (
23c0: 34 30 39 36 29 20 61 6e 64 20 66 6f 72 20 74 68  4096) and for th
23d0: 65 20 6c 61 73 74 20 69 6e 64 65 78 20 62 6c 6f  e last index blo
23e0: 63 6b 0a 2a 2a 20 4b 20 77 69 6c 6c 20 62 65 20  ck.** K will be 
23f0: 28 6d 78 46 72 61 6d 65 25 48 41 53 48 54 41 42  (mxFrame%HASHTAB
2400: 4c 45 5f 4e 50 41 47 45 29 2e 29 20 20 55 6e 75  LE_NPAGE).)  Unu
2410: 73 65 64 20 73 6c 6f 74 73 20 6f 66 20 74 68 65  sed slots of the
2420: 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a 20 63   hash table.** c
2430: 6f 6e 74 61 69 6e 20 61 20 76 61 6c 75 65 20 6f  ontain a value o
2440: 66 20 30 2e 0a 2a 2a 0a 2a 2a 20 54 6f 20 6c 6f  f 0..**.** To lo
2450: 6f 6b 20 66 6f 72 20 70 61 67 65 20 50 20 69 6e  ok for page P in
2460: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 2c   the hash table,
2470: 20 66 69 72 73 74 20 63 6f 6d 70 75 74 65 20 61   first compute a
2480: 20 68 61 73 68 20 69 4b 65 79 20 6f 6e 0a 2a 2a   hash iKey on.**
2490: 20 50 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a   P as follows:.*
24a0: 2a 0a 2a 2a 20 20 20 20 20 20 69 4b 65 79 20 3d  *.**      iKey =
24b0: 20 28 50 20 2a 20 33 38 33 29 20 25 20 48 41 53   (P * 383) % HAS
24c0: 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 0a 2a 2a 0a  HTABLE_NSLOT.**.
24d0: 2a 2a 20 54 68 65 6e 20 73 74 61 72 74 20 73 63  ** Then start sc
24e0: 61 6e 6e 69 6e 67 20 65 6e 74 72 69 65 73 20 6f  anning entries o
24f0: 66 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  f the hash table
2500: 2c 20 73 74 61 72 74 69 6e 67 20 77 69 74 68 20  , starting with 
2510: 69 4b 65 79 0a 2a 2a 20 28 77 72 61 70 70 69 6e  iKey.** (wrappin
2520: 67 20 61 72 6f 75 6e 64 20 74 6f 20 74 68 65 20  g around to the 
2530: 62 65 67 69 6e 6e 69 6e 67 20 77 68 65 6e 20 74  beginning when t
2540: 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 68 61  he end of the ha
2550: 73 68 20 74 61 62 6c 65 20 69 73 0a 2a 2a 20 72  sh table is.** r
2560: 65 61 63 68 65 64 29 20 75 6e 74 69 6c 20 61 6e  eached) until an
2570: 20 75 6e 75 73 65 64 20 68 61 73 68 20 73 6c 6f   unused hash slo
2580: 74 20 69 73 20 66 6f 75 6e 64 2e 20 4c 65 74 20  t is found. Let 
2590: 74 68 65 20 66 69 72 73 74 20 75 6e 75 73 65 64  the first unused
25a0: 20 73 6c 6f 74 0a 2a 2a 20 62 65 20 61 74 20 69   slot.** be at i
25b0: 6e 64 65 78 20 69 55 6e 75 73 65 64 2e 20 20 28  ndex iUnused.  (
25c0: 69 55 6e 75 73 65 64 20 6d 69 67 68 74 20 62 65  iUnused might be
25d0: 20 6c 65 73 73 20 74 68 61 6e 20 69 4b 65 79 20   less than iKey 
25e0: 69 66 20 74 68 65 72 65 20 77 61 73 0a 2a 2a 20  if there was.** 
25f0: 77 72 61 70 2d 61 72 6f 75 6e 64 2e 29 20 42 65  wrap-around.) Be
2600: 63 61 75 73 65 20 74 68 65 20 68 61 73 68 20 74  cause the hash t
2610: 61 62 6c 65 20 69 73 20 6e 65 76 65 72 20 6d 6f  able is never mo
2620: 72 65 20 74 68 61 6e 20 68 61 6c 66 20 66 75 6c  re than half ful
2630: 6c 2c 0a 2a 2a 20 74 68 65 20 73 65 61 72 63 68  l,.** the search
2640: 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74   is guaranteed t
2650: 6f 20 65 76 65 6e 74 75 61 6c 6c 79 20 68 69 74  o eventually hit
2660: 20 61 6e 20 75 6e 75 73 65 64 20 65 6e 74 72 79   an unused entry
2670: 2e 20 20 4c 65 74 20 0a 2a 2a 20 69 4d 61 78 20  .  Let .** iMax 
2680: 62 65 20 74 68 65 20 76 61 6c 75 65 20 62 65 74  be the value bet
2690: 77 65 65 6e 20 69 4b 65 79 20 61 6e 64 20 69 55  ween iKey and iU
26a0: 6e 75 73 65 64 2c 20 63 6c 6f 73 65 73 74 20 74  nused, closest t
26b0: 6f 20 69 55 6e 75 73 65 64 2c 0a 2a 2a 20 77 68  o iUnused,.** wh
26c0: 65 72 65 20 61 48 61 73 68 5b 69 4d 61 78 5d 3d  ere aHash[iMax]=
26d0: 3d 50 2e 20 20 49 66 20 74 68 65 72 65 20 69 73  =P.  If there is
26e0: 20 6e 6f 20 69 4d 61 78 20 65 6e 74 72 79 20 28   no iMax entry (
26f0: 69 66 20 74 68 65 72 65 20 65 78 69 73 74 73 0a  if there exists.
2700: 2a 2a 20 6e 6f 20 68 61 73 68 20 73 6c 6f 74 20  ** no hash slot 
2710: 73 75 63 68 20 74 68 61 74 20 61 48 61 73 68 5b  such that aHash[
2720: 69 5d 3d 3d 70 29 20 74 68 65 6e 20 70 61 67 65  i]==p) then page
2730: 20 50 20 69 73 20 6e 6f 74 20 69 6e 20 74 68 65   P is not in the
2740: 0a 2a 2a 20 63 75 72 72 65 6e 74 20 69 6e 64 65  .** current inde
2750: 78 20 62 6c 6f 63 6b 2e 20 20 4f 74 68 65 72 77  x block.  Otherw
2760: 69 73 65 20 74 68 65 20 69 4d 61 78 2d 74 68 20  ise the iMax-th 
2770: 6d 61 70 70 69 6e 67 20 65 6e 74 72 79 20 6f 66  mapping entry of
2780: 20 74 68 65 0a 2a 2a 20 63 75 72 72 65 6e 74 20   the.** current 
2790: 69 6e 64 65 78 20 62 6c 6f 63 6b 20 63 6f 72 72  index block corr
27a0: 65 73 70 6f 6e 64 73 20 74 6f 20 74 68 65 20 6c  esponds to the l
27b0: 61 73 74 20 65 6e 74 72 79 20 74 68 61 74 20 72  ast entry that r
27c0: 65 66 65 72 65 6e 63 65 73 20 0a 2a 2a 20 70 61  eferences .** pa
27d0: 67 65 20 50 2e 0a 2a 2a 0a 2a 2a 20 41 20 68 61  ge P..**.** A ha
27e0: 73 68 20 73 65 61 72 63 68 20 62 65 67 69 6e 73  sh search begins
27f0: 20 77 69 74 68 20 74 68 65 20 6c 61 73 74 20 69   with the last i
2800: 6e 64 65 78 20 62 6c 6f 63 6b 20 61 6e 64 20 6d  ndex block and m
2810: 6f 76 65 73 20 74 6f 77 61 72 64 20 74 68 65 0a  oves toward the.
2820: 2a 2a 20 66 69 72 73 74 20 69 6e 64 65 78 20 62  ** first index b
2830: 6c 6f 63 6b 2c 20 6c 6f 6f 6b 69 6e 67 20 66 6f  lock, looking fo
2840: 72 20 65 6e 74 72 69 65 73 20 63 6f 72 72 65 73  r entries corres
2850: 70 6f 6e 64 69 6e 67 20 74 6f 20 70 61 67 65 20  ponding to page 
2860: 50 2e 20 20 4f 6e 0a 2a 2a 20 61 76 65 72 61 67  P.  On.** averag
2870: 65 2c 20 6f 6e 6c 79 20 74 77 6f 20 6f 72 20 74  e, only two or t
2880: 68 72 65 65 20 73 6c 6f 74 73 20 69 6e 20 65 61  hree slots in ea
2890: 63 68 20 69 6e 64 65 78 20 62 6c 6f 63 6b 20 6e  ch index block n
28a0: 65 65 64 20 74 6f 20 62 65 0a 2a 2a 20 65 78 61  eed to be.** exa
28b0: 6d 69 6e 65 64 20 69 6e 20 6f 72 64 65 72 20 74  mined in order t
28c0: 6f 20 65 69 74 68 65 72 20 66 69 6e 64 20 74 68  o either find th
28d0: 65 20 6c 61 73 74 20 65 6e 74 72 79 20 66 6f 72  e last entry for
28e0: 20 70 61 67 65 20 50 2c 20 6f 72 20 74 6f 0a 2a   page P, or to.*
28f0: 2a 20 65 73 74 61 62 6c 69 73 68 20 74 68 61 74  * establish that
2900: 20 6e 6f 20 73 75 63 68 20 65 6e 74 72 79 20 65   no such entry e
2910: 78 69 73 74 73 20 69 6e 20 74 68 65 20 62 6c 6f  xists in the blo
2920: 63 6b 2e 20 20 45 61 63 68 20 69 6e 64 65 78 20  ck.  Each index 
2930: 62 6c 6f 63 6b 0a 2a 2a 20 68 6f 6c 64 73 20 6f  block.** holds o
2940: 76 65 72 20 34 30 30 30 20 65 6e 74 72 69 65 73  ver 4000 entries
2950: 2e 20 20 53 6f 20 74 77 6f 20 6f 72 20 74 68 72  .  So two or thr
2960: 65 65 20 69 6e 64 65 78 20 62 6c 6f 63 6b 73 20  ee index blocks 
2970: 61 72 65 20 73 75 66 66 69 63 69 65 6e 74 0a 2a  are sufficient.*
2980: 2a 20 74 6f 20 63 6f 76 65 72 20 61 20 74 79 70  * to cover a typ
2990: 69 63 61 6c 20 31 30 20 6d 65 67 61 62 79 74 65  ical 10 megabyte
29a0: 20 57 41 4c 20 66 69 6c 65 2c 20 61 73 73 75 6d   WAL file, assum
29b0: 69 6e 67 20 31 4b 20 70 61 67 65 73 2e 20 20 38  ing 1K pages.  8
29c0: 20 6f 72 20 31 30 0a 2a 2a 20 63 6f 6d 70 61 72   or 10.** compar
29d0: 69 73 6f 6e 73 20 28 6f 6e 20 61 76 65 72 61 67  isons (on averag
29e0: 65 29 20 73 75 66 66 69 63 65 20 74 6f 20 65 69  e) suffice to ei
29f0: 74 68 65 72 20 6c 6f 63 61 74 65 20 61 20 66 72  ther locate a fr
2a00: 61 6d 65 20 69 6e 20 74 68 65 0a 2a 2a 20 57 41  ame in the.** WA
2a10: 4c 20 6f 72 20 74 6f 20 65 73 74 61 62 6c 69 73  L or to establis
2a20: 68 20 74 68 61 74 20 74 68 65 20 66 72 61 6d 65  h that the frame
2a30: 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20   does not exist 
2a40: 69 6e 20 74 68 65 20 57 41 4c 2e 20 20 54 68 69  in the WAL.  Thi
2a50: 73 0a 2a 2a 20 69 73 20 6d 75 63 68 20 66 61 73  s.** is much fas
2a60: 74 65 72 20 74 68 61 6e 20 73 63 61 6e 6e 69 6e  ter than scannin
2a70: 67 20 74 68 65 20 65 6e 74 69 72 65 20 31 30 4d  g the entire 10M
2a80: 42 20 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74  B WAL..**.** Not
2a90: 65 20 74 68 61 74 20 65 6e 74 72 69 65 73 20 61  e that entries a
2aa0: 72 65 20 61 64 64 65 64 20 69 6e 20 6f 72 64 65  re added in orde
2ab0: 72 20 6f 66 20 69 6e 63 72 65 61 73 69 6e 67 20  r of increasing 
2ac0: 4b 2e 20 20 48 65 6e 63 65 2c 20 6f 6e 65 0a 2a  K.  Hence, one.*
2ad0: 2a 20 72 65 61 64 65 72 20 6d 69 67 68 74 20 62  * reader might b
2ae0: 65 20 75 73 69 6e 67 20 73 6f 6d 65 20 76 61 6c  e using some val
2af0: 75 65 20 4b 30 20 61 6e 64 20 61 20 73 65 63 6f  ue K0 and a seco
2b00: 6e 64 20 72 65 61 64 65 72 20 74 68 61 74 20 73  nd reader that s
2b10: 74 61 72 74 65 64 0a 2a 2a 20 61 74 20 61 20 6c  tarted.** at a l
2b20: 61 74 65 72 20 74 69 6d 65 20 28 61 66 74 65 72  ater time (after
2b30: 20 61 64 64 69 74 69 6f 6e 61 6c 20 74 72 61 6e   additional tran
2b40: 73 61 63 74 69 6f 6e 73 20 77 65 72 65 20 61 64  sactions were ad
2b50: 64 65 64 20 74 6f 20 74 68 65 20 57 41 4c 0a 2a  ded to the WAL.*
2b60: 2a 20 61 6e 64 20 74 6f 20 74 68 65 20 77 61 6c  * and to the wal
2b70: 2d 69 6e 64 65 78 29 20 6d 69 67 68 74 20 62 65  -index) might be
2b80: 20 75 73 69 6e 67 20 61 20 64 69 66 66 65 72 65   using a differe
2b90: 6e 74 20 76 61 6c 75 65 20 4b 31 2c 20 77 68 65  nt value K1, whe
2ba0: 72 65 20 4b 31 3e 4b 30 2e 0a 2a 2a 20 42 6f 74  re K1>K0..** Bot
2bb0: 68 20 72 65 61 64 65 72 73 20 63 61 6e 20 75 73  h readers can us
2bc0: 65 20 74 68 65 20 73 61 6d 65 20 68 61 73 68 20  e the same hash 
2bd0: 74 61 62 6c 65 20 61 6e 64 20 6d 61 70 70 69 6e  table and mappin
2be0: 67 20 73 65 63 74 69 6f 6e 20 74 6f 20 67 65 74  g section to get
2bf0: 0a 2a 2a 20 74 68 65 20 63 6f 72 72 65 63 74 20  .** the correct 
2c00: 72 65 73 75 6c 74 2e 20 20 54 68 65 72 65 20 6d  result.  There m
2c10: 61 79 20 62 65 20 65 6e 74 72 69 65 73 20 69 6e  ay be entries in
2c20: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
2c30: 77 69 74 68 0a 2a 2a 20 4b 3e 4b 30 20 62 75 74  with.** K>K0 but
2c40: 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 72 65   to the first re
2c50: 61 64 65 72 2c 20 74 68 6f 73 65 20 65 6e 74 72  ader, those entr
2c60: 69 65 73 20 77 69 6c 6c 20 61 70 70 65 61 72 20  ies will appear 
2c70: 74 6f 20 62 65 20 75 6e 75 73 65 64 0a 2a 2a 20  to be unused.** 
2c80: 73 6c 6f 74 73 20 69 6e 20 74 68 65 20 68 61 73  slots in the has
2c90: 68 20 74 61 62 6c 65 20 61 6e 64 20 73 6f 20 74  h table and so t
2ca0: 68 65 20 66 69 72 73 74 20 72 65 61 64 65 72 20  he first reader 
2cb0: 77 69 6c 6c 20 67 65 74 20 61 6e 20 61 6e 73 77  will get an answ
2cc0: 65 72 20 61 73 0a 2a 2a 20 69 66 20 6e 6f 20 76  er as.** if no v
2cd0: 61 6c 75 65 73 20 67 72 65 61 74 65 72 20 74 68  alues greater th
2ce0: 61 6e 20 4b 30 20 68 61 64 20 65 76 65 72 20 62  an K0 had ever b
2cf0: 65 65 6e 20 69 6e 73 65 72 74 65 64 20 69 6e 74  een inserted int
2d00: 6f 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65  o the hash table
2d10: 0a 2a 2a 20 69 6e 20 74 68 65 20 66 69 72 73 74  .** in the first
2d20: 20 70 6c 61 63 65 20 2d 20 77 68 69 63 68 20 69   place - which i
2d30: 73 20 77 68 61 74 20 72 65 61 64 65 72 20 6f 6e  s what reader on
2d40: 65 20 77 61 6e 74 73 2e 20 20 4d 65 61 6e 77 68  e wants.  Meanwh
2d50: 69 6c 65 2c 20 74 68 65 0a 2a 2a 20 73 65 63 6f  ile, the.** seco
2d60: 6e 64 20 72 65 61 64 65 72 20 75 73 69 6e 67 20  nd reader using 
2d70: 4b 31 20 77 69 6c 6c 20 73 65 65 20 61 64 64 69  K1 will see addi
2d80: 74 69 6f 6e 61 6c 20 76 61 6c 75 65 73 20 74 68  tional values th
2d90: 61 74 20 77 65 72 65 20 69 6e 73 65 72 74 65 64  at were inserted
2da0: 0a 2a 2a 20 6c 61 74 65 72 2c 20 77 68 69 63 68  .** later, which
2db0: 20 69 73 20 65 78 61 63 74 6c 79 20 77 68 61 74   is exactly what
2dc0: 20 72 65 61 64 65 72 20 74 77 6f 20 77 61 6e 74   reader two want
2dd0: 73 2e 20 20 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20  s.  .**.** When 
2de0: 61 20 72 6f 6c 6c 62 61 63 6b 20 6f 63 63 75 72  a rollback occur
2df0: 73 2c 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20  s, the value of 
2e00: 4b 20 69 73 20 64 65 63 72 65 61 73 65 64 2e 20  K is decreased. 
2e10: 48 61 73 68 20 74 61 62 6c 65 20 65 6e 74 72 69  Hash table entri
2e20: 65 73 0a 2a 2a 20 74 68 61 74 20 63 6f 72 72 65  es.** that corre
2e30: 73 70 6f 6e 64 20 74 6f 20 66 72 61 6d 65 73 20  spond to frames 
2e40: 67 72 65 61 74 65 72 20 74 68 61 6e 20 74 68 65  greater than the
2e50: 20 6e 65 77 20 4b 20 76 61 6c 75 65 20 61 72 65   new K value are
2e60: 20 72 65 6d 6f 76 65 64 0a 2a 2a 20 66 72 6f 6d   removed.** from
2e70: 20 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20   the hash table 
2e80: 61 74 20 74 68 69 73 20 70 6f 69 6e 74 2e 0a 2a  at this point..*
2e90: 2f 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45  /.#ifndef SQLITE
2ea0: 5f 4f 4d 49 54 5f 57 41 4c 0a 0a 23 69 6e 63 6c  _OMIT_WAL..#incl
2eb0: 75 64 65 20 22 77 61 6c 2e 68 22 0a 0a 2f 2a 0a  ude "wal.h"../*.
2ec0: 2a 2a 20 54 72 61 63 65 20 6f 75 74 70 75 74 20  ** Trace output 
2ed0: 6d 61 63 72 6f 73 0a 2a 2f 0a 23 69 66 20 64 65  macros.*/.#if de
2ee0: 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54 45 53  fined(SQLITE_TES
2ef0: 54 29 20 26 26 20 64 65 66 69 6e 65 64 28 53 51  T) && defined(SQ
2f00: 4c 49 54 45 5f 44 45 42 55 47 29 0a 69 6e 74 20  LITE_DEBUG).int 
2f10: 73 71 6c 69 74 65 33 57 61 6c 54 72 61 63 65 20  sqlite3WalTrace 
2f20: 3d 20 30 3b 0a 23 20 64 65 66 69 6e 65 20 57 41  = 0;.# define WA
2f30: 4c 54 52 41 43 45 28 58 29 20 20 69 66 28 73 71  LTRACE(X)  if(sq
2f40: 6c 69 74 65 33 57 61 6c 54 72 61 63 65 29 20 73  lite3WalTrace) s
2f50: 71 6c 69 74 65 33 44 65 62 75 67 50 72 69 6e 74  qlite3DebugPrint
2f60: 66 20 58 0a 23 65 6c 73 65 0a 23 20 64 65 66 69  f X.#else.# defi
2f70: 6e 65 20 57 41 4c 54 52 41 43 45 28 58 29 0a 23  ne WALTRACE(X).#
2f80: 65 6e 64 69 66 0a 0a 0a 2f 2a 0a 2a 2a 20 49 6e  endif.../*.** In
2f90: 64 69 63 65 73 20 6f 66 20 76 61 72 69 6f 75 73  dices of various
2fa0: 20 6c 6f 63 6b 69 6e 67 20 62 79 74 65 73 2e 20   locking bytes. 
2fb0: 20 20 57 41 4c 5f 4e 52 45 41 44 45 52 20 69 73    WAL_NREADER is
2fc0: 20 74 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f   the number.** o
2fd0: 66 20 61 76 61 69 6c 61 62 6c 65 20 72 65 61 64  f available read
2fe0: 65 72 20 6c 6f 63 6b 73 20 61 6e 64 20 73 68 6f  er locks and sho
2ff0: 75 6c 64 20 62 65 20 61 74 20 6c 65 61 73 74 20  uld be at least 
3000: 33 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41  3..*/.#define WA
3010: 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 20 20 20  L_WRITE_LOCK    
3020: 20 20 20 20 20 30 0a 23 64 65 66 69 6e 65 20 57       0.#define W
3030: 41 4c 5f 41 4c 4c 5f 42 55 54 5f 57 52 49 54 45  AL_ALL_BUT_WRITE
3040: 20 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65 20        1.#define 
3050: 57 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 20 20 20  WAL_CKPT_LOCK   
3060: 20 20 20 20 20 20 20 31 0a 23 64 65 66 69 6e 65         1.#define
3070: 20 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c 4f 43   WAL_RECOVER_LOC
3080: 4b 20 20 20 20 20 20 20 32 0a 23 64 65 66 69 6e  K       2.#defin
3090: 65 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  e WAL_READ_LOCK(
30a0: 49 29 20 20 20 20 20 20 20 28 33 2b 28 49 29 29  I)       (3+(I))
30b0: 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 4e 52 45  .#define WAL_NRE
30c0: 41 44 45 52 20 20 20 20 20 20 20 20 20 20 20 20  ADER            
30d0: 28 53 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f 43  (SQLITE_SHM_NLOC
30e0: 4b 2d 33 29 0a 0a 0a 2f 2a 20 4f 62 6a 65 63 74  K-3).../* Object
30f0: 20 64 65 63 6c 61 72 61 74 69 6f 6e 73 20 2a 2f   declarations */
3100: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
3110: 57 61 6c 49 6e 64 65 78 48 64 72 20 57 61 6c 49  WalIndexHdr WalI
3120: 6e 64 65 78 48 64 72 3b 0a 74 79 70 65 64 65 66  ndexHdr;.typedef
3130: 20 73 74 72 75 63 74 20 57 61 6c 49 74 65 72 61   struct WalItera
3140: 74 6f 72 20 57 61 6c 49 74 65 72 61 74 6f 72 3b  tor WalIterator;
3150: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
3160: 57 61 6c 43 6b 70 74 49 6e 66 6f 20 57 61 6c 43  WalCkptInfo WalC
3170: 6b 70 74 49 6e 66 6f 3b 0a 0a 0a 2f 2a 0a 2a 2a  kptInfo;.../*.**
3180: 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f   The following o
3190: 62 6a 65 63 74 20 68 6f 6c 64 73 20 61 20 63 6f  bject holds a co
31a0: 70 79 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e  py of the wal-in
31b0: 64 65 78 20 68 65 61 64 65 72 20 63 6f 6e 74 65  dex header conte
31c0: 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 63  nt..**.** The ac
31d0: 74 75 61 6c 20 68 65 61 64 65 72 20 69 6e 20 74  tual header in t
31e0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e  he wal-index con
31f0: 73 69 73 74 73 20 6f 66 20 74 77 6f 20 63 6f 70  sists of two cop
3200: 69 65 73 20 6f 66 20 74 68 69 73 0a 2a 2a 20 6f  ies of this.** o
3210: 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 72 75 63 74  bject..*/.struct
3220: 20 57 61 6c 49 6e 64 65 78 48 64 72 20 7b 0a 20   WalIndexHdr {. 
3230: 20 75 33 32 20 69 43 68 61 6e 67 65 3b 20 20 20   u32 iChange;   
3240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3250: 20 2f 2a 20 43 6f 75 6e 74 65 72 20 69 6e 63 72   /* Counter incr
3260: 65 6d 65 6e 74 65 64 20 65 61 63 68 20 74 72 61  emented each tra
3270: 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 75 38  nsaction */.  u8
3280: 20 69 73 49 6e 69 74 3b 20 20 20 20 20 20 20 20   isInit;        
3290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
32a0: 20 31 20 77 68 65 6e 20 69 6e 69 74 69 61 6c 69   1 when initiali
32b0: 7a 65 64 20 2a 2f 0a 20 20 75 38 20 62 69 67 45  zed */.  u8 bigE
32c0: 6e 64 43 6b 73 75 6d 3b 20 20 20 20 20 20 20 20  ndCksum;        
32d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
32e0: 20 69 66 20 63 68 65 63 6b 73 75 6d 73 20 69 6e   if checksums in
32f0: 20 57 41 4c 20 61 72 65 20 62 69 67 2d 65 6e 64   WAL are big-end
3300: 69 61 6e 20 2a 2f 0a 20 20 75 31 36 20 73 7a 50  ian */.  u16 szP
3310: 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
3320: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
3330: 62 61 73 65 20 70 61 67 65 20 73 69 7a 65 20 69  base page size i
3340: 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 75 33 32  n bytes */.  u32
3350: 20 6d 78 46 72 61 6d 65 3b 20 20 20 20 20 20 20   mxFrame;       
3360: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3370: 49 6e 64 65 78 20 6f 66 20 6c 61 73 74 20 76 61  Index of last va
3380: 6c 69 64 20 66 72 61 6d 65 20 69 6e 20 74 68 65  lid frame in the
3390: 20 57 41 4c 20 2a 2f 0a 20 20 75 33 32 20 6e 50   WAL */.  u32 nP
33a0: 61 67 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  age;            
33b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
33c0: 65 20 6f 66 20 64 61 74 61 62 61 73 65 20 69 6e  e of database in
33d0: 20 70 61 67 65 73 20 2a 2f 0a 20 20 75 33 32 20   pages */.  u32 
33e0: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 32 5d 3b 20  aFrameCksum[2]; 
33f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
3400: 68 65 63 6b 73 75 6d 20 6f 66 20 6c 61 73 74 20  hecksum of last 
3410: 66 72 61 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a  frame in log */.
3420: 20 20 75 33 32 20 61 53 61 6c 74 5b 32 5d 3b 20    u32 aSalt[2]; 
3430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3440: 20 20 2f 2a 20 54 77 6f 20 73 61 6c 74 20 76 61    /* Two salt va
3450: 6c 75 65 73 20 63 6f 70 69 65 64 20 66 72 6f 6d  lues copied from
3460: 20 57 41 4c 20 68 65 61 64 65 72 20 2a 2f 0a 20   WAL header */. 
3470: 20 75 33 32 20 61 43 6b 73 75 6d 5b 32 5d 3b 20   u32 aCksum[2]; 
3480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3490: 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 6f 76 65   /* Checksum ove
34a0: 72 20 61 6c 6c 20 70 72 69 6f 72 20 66 69 65 6c  r all prior fiel
34b0: 64 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  ds */.};../*.** 
34c0: 41 20 63 6f 70 79 20 6f 66 20 74 68 65 20 66 6f  A copy of the fo
34d0: 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 6f  llowing object o
34e0: 63 63 75 72 73 20 69 6e 20 74 68 65 20 77 61 6c  ccurs in the wal
34f0: 2d 69 6e 64 65 78 20 69 6d 6d 65 64 69 61 74 65  -index immediate
3500: 6c 79 0a 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20  ly.** following 
3510: 74 68 65 20 73 65 63 6f 6e 64 20 63 6f 70 79 20  the second copy 
3520: 6f 66 20 74 68 65 20 57 61 6c 49 6e 64 65 78 48  of the WalIndexH
3530: 64 72 2e 20 20 54 68 69 73 20 6f 62 6a 65 63 74  dr.  This object
3540: 20 73 74 6f 72 65 73 0a 2a 2a 20 69 6e 66 6f 72   stores.** infor
3550: 6d 61 74 69 6f 6e 20 75 73 65 64 20 62 79 20 63  mation used by c
3560: 68 65 63 6b 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a 2a  heckpoint..**.**
3570: 20 6e 42 61 63 6b 66 69 6c 6c 20 69 73 20 74 68   nBackfill is th
3580: 65 20 6e 75 6d 62 65 72 20 6f 66 20 66 72 61 6d  e number of fram
3590: 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68  es in the WAL th
35a0: 61 74 20 68 61 76 65 20 62 65 65 6e 20 77 72 69  at have been wri
35b0: 74 74 65 6e 0a 2a 2a 20 62 61 63 6b 20 69 6e 74  tten.** back int
35c0: 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 2e 20  o the database. 
35d0: 28 57 65 20 63 61 6c 6c 20 74 68 65 20 61 63 74  (We call the act
35e0: 20 6f 66 20 6d 6f 76 69 6e 67 20 63 6f 6e 74 65   of moving conte
35f0: 6e 74 20 66 72 6f 6d 20 57 41 4c 20 74 6f 0a 2a  nt from WAL to.*
3600: 2a 20 64 61 74 61 62 61 73 65 20 22 62 61 63 6b  * database "back
3610: 66 69 6c 6c 69 6e 67 22 2e 29 20 20 54 68 65 20  filling".)  The 
3620: 6e 42 61 63 6b 66 69 6c 6c 20 6e 75 6d 62 65 72  nBackfill number
3630: 20 69 73 20 6e 65 76 65 72 20 67 72 65 61 74 65   is never greate
3640: 72 20 74 68 61 6e 0a 2a 2a 20 57 61 6c 49 6e 64  r than.** WalInd
3650: 65 78 48 64 72 2e 6d 78 46 72 61 6d 65 2e 20 20  exHdr.mxFrame.  
3660: 6e 42 61 63 6b 66 69 6c 6c 20 63 61 6e 20 6f 6e  nBackfill can on
3670: 6c 79 20 62 65 20 69 6e 63 72 65 61 73 65 64 20  ly be increased 
3680: 62 79 20 74 68 72 65 61 64 73 0a 2a 2a 20 68 6f  by threads.** ho
3690: 6c 64 69 6e 67 20 74 68 65 20 57 41 4c 5f 43 4b  lding the WAL_CK
36a0: 50 54 5f 4c 4f 43 4b 20 6c 6f 63 6b 20 28 77 68  PT_LOCK lock (wh
36b0: 69 63 68 20 69 6e 63 6c 75 64 65 73 20 61 20 72  ich includes a r
36c0: 65 63 6f 76 65 72 79 20 74 68 72 65 61 64 29 2e  ecovery thread).
36d0: 0a 2a 2a 20 48 6f 77 65 76 65 72 2c 20 61 20 57  .** However, a W
36e0: 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 20 74 68  AL_WRITE_LOCK th
36f0: 72 65 61 64 20 63 61 6e 20 6d 6f 76 65 20 74 68  read can move th
3700: 65 20 76 61 6c 75 65 20 6f 66 20 6e 42 61 63 6b  e value of nBack
3710: 66 69 6c 6c 20 66 72 6f 6d 0a 2a 2a 20 6d 78 46  fill from.** mxF
3720: 72 61 6d 65 20 62 61 63 6b 20 74 6f 20 7a 65 72  rame back to zer
3730: 6f 20 77 68 65 6e 20 74 68 65 20 57 41 4c 20 69  o when the WAL i
3740: 73 20 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 54  s reset..**.** T
3750: 68 65 72 65 20 69 73 20 6f 6e 65 20 65 6e 74 72  here is one entr
3760: 79 20 69 6e 20 61 52 65 61 64 4d 61 72 6b 5b 5d  y in aReadMark[]
3770: 20 66 6f 72 20 65 61 63 68 20 72 65 61 64 65 72   for each reader
3780: 20 6c 6f 63 6b 2e 20 20 49 66 20 61 20 72 65 61   lock.  If a rea
3790: 64 65 72 0a 2a 2a 20 68 6f 6c 64 73 20 72 65 61  der.** holds rea
37a0: 64 2d 6c 6f 63 6b 20 4b 2c 20 74 68 65 6e 20 74  d-lock K, then t
37b0: 68 65 20 76 61 6c 75 65 20 69 6e 20 61 52 65 61  he value in aRea
37c0: 64 4d 61 72 6b 5b 4b 5d 20 69 73 20 6e 6f 20 67  dMark[K] is no g
37d0: 72 65 61 74 65 72 20 74 68 61 6e 0a 2a 2a 20 74  reater than.** t
37e0: 68 65 20 6d 78 46 72 61 6d 65 20 66 6f 72 20 74  he mxFrame for t
37f0: 68 61 74 20 72 65 61 64 65 72 2e 20 20 54 68 65  hat reader.  The
3800: 20 76 61 6c 75 65 20 52 45 41 44 4d 41 52 4b 5f   value READMARK_
3810: 4e 4f 54 5f 55 53 45 44 20 28 30 78 66 66 66 66  NOT_USED (0xffff
3820: 66 66 66 66 29 0a 2a 2a 20 66 6f 72 20 61 6e 79  ffff).** for any
3830: 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 6d 65 61   aReadMark[] mea
3840: 6e 73 20 74 68 61 74 20 65 6e 74 72 79 20 69 73  ns that entry is
3850: 20 75 6e 75 73 65 64 2e 20 20 61 52 65 61 64 4d   unused.  aReadM
3860: 61 72 6b 5b 30 5d 20 69 73 20 0a 2a 2a 20 61 20  ark[0] is .** a 
3870: 73 70 65 63 69 61 6c 20 63 61 73 65 3b 20 69 74  special case; it
3880: 73 20 76 61 6c 75 65 20 69 73 20 6e 65 76 65 72  s value is never
3890: 20 75 73 65 64 20 61 6e 64 20 69 74 20 65 78 69   used and it exi
38a0: 73 74 73 20 61 73 20 61 20 70 6c 61 63 65 2d 68  sts as a place-h
38b0: 6f 6c 64 65 72 0a 2a 2a 20 74 6f 20 61 76 6f 69  older.** to avoi
38c0: 64 20 68 61 76 69 6e 67 20 74 6f 20 6f 66 66 73  d having to offs
38d0: 65 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 69  et aReadMark[] i
38e0: 6e 64 65 78 73 20 62 79 20 6f 6e 65 2e 20 20 52  ndexs by one.  R
38f0: 65 61 64 65 72 73 20 68 6f 6c 64 69 6e 67 0a 2a  eaders holding.*
3900: 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28  * WAL_READ_LOCK(
3910: 30 29 20 61 6c 77 61 79 73 20 69 67 6e 6f 72 65  0) always ignore
3920: 20 74 68 65 20 65 6e 74 69 72 65 20 57 41 4c 20   the entire WAL 
3930: 61 6e 64 20 72 65 61 64 20 61 6c 6c 20 63 6f 6e  and read all con
3940: 74 65 6e 74 0a 2a 2a 20 64 69 72 65 63 74 6c 79  tent.** directly
3950: 20 66 72 6f 6d 20 74 68 65 20 64 61 74 61 62 61   from the databa
3960: 73 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61  se..**.** The va
3970: 6c 75 65 20 6f 66 20 61 52 65 61 64 4d 61 72 6b  lue of aReadMark
3980: 5b 4b 5d 20 6d 61 79 20 6f 6e 6c 79 20 62 65 20  [K] may only be 
3990: 63 68 61 6e 67 65 64 20 62 79 20 61 20 74 68 72  changed by a thr
39a0: 65 61 64 20 74 68 61 74 0a 2a 2a 20 69 73 20 68  ead that.** is h
39b0: 6f 6c 64 69 6e 67 20 61 6e 20 65 78 63 6c 75 73  olding an exclus
39c0: 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f  ive lock on WAL_
39d0: 52 45 41 44 5f 4c 4f 43 4b 28 4b 29 2e 20 20 54  READ_LOCK(K).  T
39e0: 68 75 73 2c 20 74 68 65 20 76 61 6c 75 65 20 6f  hus, the value o
39f0: 66 0a 2a 2a 20 61 52 65 61 64 4d 61 72 6b 5b 4b  f.** aReadMark[K
3a00: 5d 20 63 61 6e 6e 6f 74 20 63 68 61 6e 67 65 64  ] cannot changed
3a10: 20 77 68 69 6c 65 20 74 68 65 72 65 20 69 73 20   while there is 
3a20: 61 20 72 65 61 64 65 72 20 69 73 20 75 73 69 6e  a reader is usin
3a30: 67 20 74 68 61 74 20 6d 61 72 6b 0a 2a 2a 20 73  g that mark.** s
3a40: 69 6e 63 65 20 74 68 65 20 72 65 61 64 65 72 20  ince the reader 
3a50: 77 69 6c 6c 20 62 65 20 68 6f 6c 64 69 6e 67 20  will be holding 
3a60: 61 20 73 68 61 72 65 64 20 6c 6f 63 6b 20 6f 6e  a shared lock on
3a70: 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 4b   WAL_READ_LOCK(K
3a80: 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 68 65  )..**.** The che
3a90: 63 6b 70 6f 69 6e 74 65 72 20 6d 61 79 20 6f 6e  ckpointer may on
3aa0: 6c 79 20 74 72 61 6e 73 66 65 72 20 66 72 61 6d  ly transfer fram
3ab0: 65 73 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64  es from WAL to d
3ac0: 61 74 61 62 61 73 65 20 77 68 65 72 65 0a 2a 2a  atabase where.**
3ad0: 20 74 68 65 20 66 72 61 6d 65 20 6e 75 6d 62 65   the frame numbe
3ae0: 72 73 20 61 72 65 20 6c 65 73 73 20 74 68 61 6e  rs are less than
3af0: 20 6f 72 20 65 71 75 61 6c 20 74 6f 20 65 76 65   or equal to eve
3b00: 72 79 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 74  ry aReadMark[] t
3b10: 68 61 74 20 69 73 0a 2a 2a 20 69 6e 20 75 73 65  hat is.** in use
3b20: 20 28 74 68 61 74 20 69 73 2c 20 65 76 65 72 79   (that is, every
3b30: 20 61 52 65 61 64 4d 61 72 6b 5b 6a 5d 20 66 6f   aReadMark[j] fo
3b40: 72 20 77 68 69 63 68 20 74 68 65 72 65 20 69 73  r which there is
3b50: 20 61 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67   a corresponding
3b60: 0a 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  .** WAL_READ_LOC
3b70: 4b 28 6a 29 29 2e 20 20 4e 65 77 20 72 65 61 64  K(j)).  New read
3b80: 65 72 73 20 28 75 73 75 61 6c 6c 79 29 20 70 69  ers (usually) pi
3b90: 63 6b 20 74 68 65 20 61 52 65 61 64 4d 61 72 6b  ck the aReadMark
3ba0: 5b 5d 20 77 69 74 68 20 74 68 65 0a 2a 2a 20 6c  [] with the.** l
3bb0: 61 72 67 65 73 74 20 76 61 6c 75 65 20 61 6e 64  argest value and
3bc0: 20 77 69 6c 6c 20 69 6e 63 72 65 61 73 65 20 61   will increase a
3bd0: 6e 20 75 6e 75 73 65 64 20 61 52 65 61 64 4d 61  n unused aReadMa
3be0: 72 6b 5b 5d 20 74 6f 20 6d 78 46 72 61 6d 65 20  rk[] to mxFrame 
3bf0: 69 66 20 74 68 65 72 65 0a 2a 2a 20 69 73 20 6e  if there.** is n
3c00: 6f 74 20 61 6c 72 65 61 64 79 20 61 6e 20 61 52  ot already an aR
3c10: 65 61 64 4d 61 72 6b 5b 5d 20 65 71 75 61 6c 20  eadMark[] equal 
3c20: 74 6f 20 6d 78 46 72 61 6d 65 2e 20 20 54 68 65  to mxFrame.  The
3c30: 20 65 78 63 65 70 74 69 6f 6e 20 74 6f 20 74 68   exception to th
3c40: 65 0a 2a 2a 20 70 72 65 76 69 6f 75 73 20 73 65  e.** previous se
3c50: 6e 74 65 6e 63 65 20 69 73 20 77 68 65 6e 20 6e  ntence is when n
3c60: 42 61 63 6b 66 69 6c 6c 20 65 71 75 61 6c 73 20  Backfill equals 
3c70: 6d 78 46 72 61 6d 65 20 28 6d 65 61 6e 69 6e 67  mxFrame (meaning
3c80: 20 74 68 61 74 20 65 76 65 72 79 74 68 69 6e 67   that everything
3c90: 0a 2a 2a 20 69 6e 20 74 68 65 20 57 41 4c 20 68  .** in the WAL h
3ca0: 61 73 20 62 65 65 6e 20 62 61 63 6b 66 69 6c 6c  as been backfill
3cb0: 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ed into the data
3cc0: 62 61 73 65 29 20 74 68 65 6e 20 6e 65 77 20 72  base) then new r
3cd0: 65 61 64 65 72 73 0a 2a 2a 20 77 69 6c 6c 20 63  eaders.** will c
3ce0: 68 6f 6f 73 65 20 61 52 65 61 64 4d 61 72 6b 5b  hoose aReadMark[
3cf0: 30 5d 20 77 68 69 63 68 20 68 61 73 20 76 61 6c  0] which has val
3d00: 75 65 20 30 20 61 6e 64 20 68 65 6e 63 65 20 73  ue 0 and hence s
3d10: 75 63 68 20 72 65 61 64 65 72 20 77 69 6c 6c 0a  uch reader will.
3d20: 2a 2a 20 67 65 74 20 61 6c 6c 20 74 68 65 69 72  ** get all their
3d30: 20 61 6c 6c 20 63 6f 6e 74 65 6e 74 20 64 69 72   all content dir
3d40: 65 63 74 6c 79 20 66 72 6f 6d 20 74 68 65 20 64  ectly from the d
3d50: 61 74 61 62 61 73 65 20 66 69 6c 65 20 61 6e 64  atabase file and
3d60: 20 69 67 6e 6f 72 65 20 0a 2a 2a 20 74 68 65 20   ignore .** the 
3d70: 57 41 4c 2e 0a 2a 2a 0a 2a 2a 20 57 72 69 74 65  WAL..**.** Write
3d80: 72 73 20 6e 6f 72 6d 61 6c 6c 79 20 61 70 70 65  rs normally appe
3d90: 6e 64 20 6e 65 77 20 66 72 61 6d 65 73 20 74 6f  nd new frames to
3da0: 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
3db0: 57 41 4c 2e 20 20 48 6f 77 65 76 65 72 2c 0a 2a  WAL.  However,.*
3dc0: 2a 20 69 66 20 6e 42 61 63 6b 66 69 6c 6c 20 65  * if nBackfill e
3dd0: 71 75 61 6c 73 20 6d 78 46 72 61 6d 65 20 28 6d  quals mxFrame (m
3de0: 65 61 6e 69 6e 67 20 74 68 61 74 20 61 6c 6c 20  eaning that all 
3df0: 57 41 4c 20 63 6f 6e 74 65 6e 74 20 68 61 73 20  WAL content has 
3e00: 62 65 65 6e 0a 2a 2a 20 77 72 69 74 74 65 6e 20  been.** written 
3e10: 62 61 63 6b 20 69 6e 74 6f 20 74 68 65 20 64 61  back into the da
3e20: 74 61 62 61 73 65 29 20 61 6e 64 20 69 66 20 6e  tabase) and if n
3e30: 6f 20 72 65 61 64 65 72 73 20 61 72 65 20 75 73  o readers are us
3e40: 69 6e 67 20 74 68 65 20 57 41 4c 0a 2a 2a 20 28  ing the WAL.** (
3e50: 69 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c 20  in other words, 
3e60: 69 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20  if there are no 
3e70: 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29  WAL_READ_LOCK(i)
3e80: 20 77 68 65 72 65 20 69 3e 30 29 20 74 68 65 6e   where i>0) then
3e90: 0a 2a 2a 20 74 68 65 20 77 72 69 74 65 72 20 77  .** the writer w
3ea0: 69 6c 6c 20 66 69 72 73 74 20 22 72 65 73 65 74  ill first "reset
3eb0: 22 20 74 68 65 20 57 41 4c 20 62 61 63 6b 20 74  " the WAL back t
3ec0: 6f 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20  o the beginning 
3ed0: 61 6e 64 20 73 74 61 72 74 0a 2a 2a 20 77 72 69  and start.** wri
3ee0: 74 69 6e 67 20 6e 65 77 20 63 6f 6e 74 65 6e 74  ting new content
3ef0: 20 62 65 67 69 6e 6e 69 6e 67 20 61 74 20 66 72   beginning at fr
3f00: 61 6d 65 20 31 2e 0a 2a 2a 0a 2a 2a 20 57 65 20  ame 1..**.** We 
3f10: 61 73 73 75 6d 65 20 74 68 61 74 20 33 32 2d 62  assume that 32-b
3f20: 69 74 20 6c 6f 61 64 73 20 61 72 65 20 61 74 6f  it loads are ato
3f30: 6d 69 63 20 61 6e 64 20 73 6f 20 6e 6f 20 6c 6f  mic and so no lo
3f40: 63 6b 73 20 61 72 65 20 6e 65 65 64 65 64 20 69  cks are needed i
3f50: 6e 0a 2a 2a 20 6f 72 64 65 72 20 74 6f 20 72 65  n.** order to re
3f60: 61 64 20 66 72 6f 6d 20 61 6e 79 20 61 52 65 61  ad from any aRea
3f70: 64 4d 61 72 6b 5b 5d 20 65 6e 74 72 69 65 73 2e  dMark[] entries.
3f80: 0a 2a 2f 0a 73 74 72 75 63 74 20 57 61 6c 43 6b  .*/.struct WalCk
3f90: 70 74 49 6e 66 6f 20 7b 0a 20 20 75 33 32 20 6e  ptInfo {.  u32 n
3fa0: 42 61 63 6b 66 69 6c 6c 3b 20 20 20 20 20 20 20  Backfill;       
3fb0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
3fc0: 6d 62 65 72 20 6f 66 20 57 41 4c 20 66 72 61 6d  mber of WAL fram
3fd0: 65 73 20 62 61 63 6b 66 69 6c 6c 65 64 20 69 6e  es backfilled in
3fe0: 74 6f 20 44 42 20 2a 2f 0a 20 20 75 33 32 20 61  to DB */.  u32 a
3ff0: 52 65 61 64 4d 61 72 6b 5b 57 41 4c 5f 4e 52 45  ReadMark[WAL_NRE
4000: 41 44 45 52 5d 3b 20 20 20 20 20 2f 2a 20 52 65  ADER];     /* Re
4010: 61 64 65 72 20 6d 61 72 6b 73 20 2a 2f 0a 7d 3b  ader marks */.};
4020: 0a 23 64 65 66 69 6e 65 20 52 45 41 44 4d 41 52  .#define READMAR
4030: 4b 5f 4e 4f 54 5f 55 53 45 44 20 20 30 78 66 66  K_NOT_USED  0xff
4040: 66 66 66 66 66 66 0a 0a 0a 2f 2a 20 41 20 62 6c  ffffff.../* A bl
4050: 6f 63 6b 20 6f 66 20 57 41 4c 49 4e 44 45 58 5f  ock of WALINDEX_
4060: 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 20 62 79  LOCK_RESERVED by
4070: 74 65 73 20 62 65 67 69 6e 6e 69 6e 67 20 61 74  tes beginning at
4080: 0a 2a 2a 20 57 41 4c 49 4e 44 45 58 5f 4c 4f 43  .** WALINDEX_LOC
4090: 4b 5f 4f 46 46 53 45 54 20 69 73 20 72 65 73 65  K_OFFSET is rese
40a0: 72 76 65 64 20 66 6f 72 20 6c 6f 63 6b 73 2e 20  rved for locks. 
40b0: 53 69 6e 63 65 20 73 6f 6d 65 20 73 79 73 74 65  Since some syste
40c0: 6d 73 0a 2a 2a 20 6f 6e 6c 79 20 73 75 70 70 6f  ms.** only suppo
40d0: 72 74 20 6d 61 6e 64 61 74 6f 72 79 20 66 69 6c  rt mandatory fil
40e0: 65 2d 6c 6f 63 6b 73 2c 20 77 65 20 64 6f 20 6e  e-locks, we do n
40f0: 6f 74 20 72 65 61 64 20 6f 72 20 77 72 69 74 65  ot read or write
4100: 20 64 61 74 61 0a 2a 2a 20 66 72 6f 6d 20 74 68   data.** from th
4110: 65 20 72 65 67 69 6f 6e 20 6f 66 20 74 68 65 20  e region of the 
4120: 66 69 6c 65 20 6f 6e 20 77 68 69 63 68 20 6c 6f  file on which lo
4130: 63 6b 73 20 61 72 65 20 61 70 70 6c 69 65 64 2e  cks are applied.
4140: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 49  .*/.#define WALI
4150: 4e 44 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54  NDEX_LOCK_OFFSET
4160: 20 20 20 28 73 69 7a 65 6f 66 28 57 61 6c 49 6e     (sizeof(WalIn
4170: 64 65 78 48 64 72 29 2a 32 20 2b 20 73 69 7a 65  dexHdr)*2 + size
4180: 6f 66 28 57 61 6c 43 6b 70 74 49 6e 66 6f 29 29  of(WalCkptInfo))
4190: 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e 44 45  .#define WALINDE
41a0: 58 5f 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 20  X_LOCK_RESERVED 
41b0: 31 36 0a 23 64 65 66 69 6e 65 20 57 41 4c 49 4e  16.#define WALIN
41c0: 44 45 58 5f 48 44 52 5f 53 49 5a 45 20 20 20 20  DEX_HDR_SIZE    
41d0: 20 20 28 57 41 4c 49 4e 44 45 58 5f 4c 4f 43 4b    (WALINDEX_LOCK
41e0: 5f 4f 46 46 53 45 54 2b 57 41 4c 49 4e 44 45 58  _OFFSET+WALINDEX
41f0: 5f 4c 4f 43 4b 5f 52 45 53 45 52 56 45 44 29 0a  _LOCK_RESERVED).
4200: 0a 2f 2a 20 53 69 7a 65 20 6f 66 20 68 65 61 64  ./* Size of head
4210: 65 72 20 62 65 66 6f 72 65 20 65 61 63 68 20 66  er before each f
4220: 72 61 6d 65 20 69 6e 20 77 61 6c 20 2a 2f 0a 23  rame in wal */.#
4230: 64 65 66 69 6e 65 20 57 41 4c 5f 46 52 41 4d 45  define WAL_FRAME
4240: 5f 48 44 52 53 49 5a 45 20 32 34 0a 0a 2f 2a 20  _HDRSIZE 24../* 
4250: 53 69 7a 65 20 6f 66 20 77 72 69 74 65 20 61 68  Size of write ah
4260: 65 61 64 20 6c 6f 67 20 68 65 61 64 65 72 20 2a  ead log header *
4270: 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f 48 44  /.#define WAL_HD
4280: 52 53 49 5a 45 20 32 34 0a 0a 2f 2a 20 57 41 4c  RSIZE 24../* WAL
4290: 20 6d 61 67 69 63 20 76 61 6c 75 65 2e 20 45 69   magic value. Ei
42a0: 74 68 65 72 20 74 68 69 73 20 76 61 6c 75 65 2c  ther this value,
42b0: 20 6f 72 20 74 68 65 20 73 61 6d 65 20 76 61 6c   or the same val
42c0: 75 65 20 77 69 74 68 20 74 68 65 20 6c 65 61 73  ue with the leas
42d0: 74 0a 2a 2a 20 73 69 67 6e 69 66 69 63 61 6e 74  t.** significant
42e0: 20 62 69 74 20 61 6c 73 6f 20 73 65 74 20 28 57   bit also set (W
42f0: 41 4c 5f 4d 41 47 49 43 20 7c 20 30 78 30 30 30  AL_MAGIC | 0x000
4300: 30 30 30 30 31 29 20 69 73 20 73 74 6f 72 65 64  00001) is stored
4310: 20 69 6e 20 33 32 2d 62 69 74 0a 2a 2a 20 62 69   in 32-bit.** bi
4320: 67 2d 65 6e 64 69 61 6e 20 66 6f 72 6d 61 74 20  g-endian format 
4330: 69 6e 20 74 68 65 20 66 69 72 73 74 20 34 20 62  in the first 4 b
4340: 79 74 65 73 20 6f 66 20 61 20 57 41 4c 20 66 69  ytes of a WAL fi
4350: 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65  le..**.** If the
4360: 20 4c 53 42 20 69 73 20 73 65 74 2c 20 74 68 65   LSB is set, the
4370: 6e 20 74 68 65 20 63 68 65 63 6b 73 75 6d 73 20  n the checksums 
4380: 66 6f 72 20 65 61 63 68 20 66 72 61 6d 65 20 77  for each frame w
4390: 69 74 68 69 6e 20 74 68 65 20 57 41 4c 0a 2a 2a  ithin the WAL.**
43a0: 20 66 69 6c 65 20 61 72 65 20 63 61 6c 63 75 6c   file are calcul
43b0: 61 74 65 64 20 62 79 20 74 72 65 61 74 69 6e 67  ated by treating
43c0: 20 61 6c 6c 20 64 61 74 61 20 61 73 20 61 6e 20   all data as an 
43d0: 61 72 72 61 79 20 6f 66 20 33 32 2d 62 69 74 20  array of 32-bit 
43e0: 0a 2a 2a 20 62 69 67 2d 65 6e 64 69 61 6e 20 77  .** big-endian w
43f0: 6f 72 64 73 2e 20 4f 74 68 65 72 77 69 73 65 2c  ords. Otherwise,
4400: 20 74 68 65 79 20 61 72 65 20 63 61 6c 63 75 6c   they are calcul
4410: 61 74 65 64 20 62 79 20 69 6e 74 65 72 70 72 65  ated by interpre
4420: 74 69 6e 67 20 0a 2a 2a 20 61 6c 6c 20 64 61 74  ting .** all dat
4430: 61 20 61 73 20 33 32 2d 62 69 74 20 6c 69 74 74  a as 32-bit litt
4440: 6c 65 2d 65 6e 64 69 61 6e 20 77 6f 72 64 73 2e  le-endian words.
4450: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 57 41 4c 5f  .*/.#define WAL_
4460: 4d 41 47 49 43 20 30 78 33 37 37 66 30 36 38 32  MAGIC 0x377f0682
4470: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
4480: 68 65 20 6f 66 66 73 65 74 20 6f 66 20 66 72 61  he offset of fra
4490: 6d 65 20 69 46 72 61 6d 65 20 69 6e 20 74 68 65  me iFrame in the
44a0: 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67   write-ahead log
44b0: 20 66 69 6c 65 2c 20 0a 2a 2a 20 61 73 73 75 6d   file, .** assum
44c0: 69 6e 67 20 61 20 64 61 74 61 62 61 73 65 20 70  ing a database p
44d0: 61 67 65 20 73 69 7a 65 20 6f 66 20 73 7a 50 61  age size of szPa
44e0: 67 65 20 62 79 74 65 73 2e 20 54 68 65 20 6f 66  ge bytes. The of
44f0: 66 73 65 74 20 72 65 74 75 72 6e 65 64 0a 2a 2a  fset returned.**
4500: 20 69 73 20 74 6f 20 74 68 65 20 73 74 61 72 74   is to the start
4510: 20 6f 66 20 74 68 65 20 77 72 69 74 65 2d 61 68   of the write-ah
4520: 65 61 64 20 6c 6f 67 20 66 72 61 6d 65 2d 68 65  ead log frame-he
4530: 61 64 65 72 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  ader..*/.#define
4540: 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28   walFrameOffset(
4550: 69 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29 20  iFrame, szPage) 
4560: 28 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  (               
4570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4580: 5c 0a 20 20 57 41 4c 5f 48 44 52 53 49 5a 45 20  \.  WAL_HDRSIZE 
4590: 2b 20 28 28 69 46 72 61 6d 65 29 2d 31 29 2a 28  + ((iFrame)-1)*(
45a0: 28 73 7a 50 61 67 65 29 2b 57 41 4c 5f 46 52 41  (szPage)+WAL_FRA
45b0: 4d 45 5f 48 44 52 53 49 5a 45 29 20 20 20 20 20  ME_HDRSIZE)     
45c0: 20 20 20 5c 0a 29 0a 0a 2f 2a 0a 2a 2a 20 41 6e     \.)../*.** An
45d0: 20 6f 70 65 6e 20 77 72 69 74 65 2d 61 68 65 61   open write-ahea
45e0: 64 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 72 65  d log file is re
45f0: 70 72 65 73 65 6e 74 65 64 20 62 79 20 61 6e 20  presented by an 
4600: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 0a  instance of the.
4610: 2a 2a 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a  ** following obj
4620: 65 63 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 57  ect..*/.struct W
4630: 61 6c 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76  al {.  sqlite3_v
4640: 66 73 20 2a 70 56 66 73 3b 20 20 20 20 20 20 20  fs *pVfs;       
4650: 20 20 2f 2a 20 54 68 65 20 56 46 53 20 75 73 65    /* The VFS use
4660: 64 20 74 6f 20 63 72 65 61 74 65 20 70 44 62 46  d to create pDbF
4670: 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66  d */.  sqlite3_f
4680: 69 6c 65 20 2a 70 44 62 46 64 3b 20 20 20 20 20  ile *pDbFd;     
4690: 20 20 2f 2a 20 46 69 6c 65 20 68 61 6e 64 6c 65    /* File handle
46a0: 20 66 6f 72 20 74 68 65 20 64 61 74 61 62 61 73   for the databas
46b0: 65 20 66 69 6c 65 20 2a 2f 0a 20 20 73 71 6c 69  e file */.  sqli
46c0: 74 65 33 5f 66 69 6c 65 20 2a 70 57 61 6c 46 64  te3_file *pWalFd
46d0: 3b 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 68  ;      /* File h
46e0: 61 6e 64 6c 65 20 66 6f 72 20 57 41 4c 20 66 69  andle for WAL fi
46f0: 6c 65 20 2a 2f 0a 20 20 75 33 32 20 69 43 61 6c  le */.  u32 iCal
4700: 6c 62 61 63 6b 3b 20 20 20 20 20 20 20 20 20 20  lback;          
4710: 20 20 20 2f 2a 20 56 61 6c 75 65 20 74 6f 20 70     /* Value to p
4720: 61 73 73 20 74 6f 20 6c 6f 67 20 63 61 6c 6c 62  ass to log callb
4730: 61 63 6b 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20  ack (or 0) */.  
4740: 69 6e 74 20 6e 57 69 44 61 74 61 3b 20 20 20 20  int nWiData;    
4750: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
4760: 7a 65 20 6f 66 20 61 72 72 61 79 20 61 70 57 69  ze of array apWi
4770: 44 61 74 61 20 2a 2f 0a 20 20 76 6f 6c 61 74 69  Data */.  volati
4780: 6c 65 20 75 33 32 20 2a 2a 61 70 57 69 44 61 74  le u32 **apWiDat
4790: 61 3b 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20  a;   /* Pointer 
47a0: 74 6f 20 77 61 6c 2d 69 6e 64 65 78 20 63 6f 6e  to wal-index con
47b0: 74 65 6e 74 20 69 6e 20 6d 65 6d 6f 72 79 20 2a  tent in memory *
47c0: 2f 0a 20 20 75 31 36 20 73 7a 50 61 67 65 3b 20  /.  u16 szPage; 
47d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
47e0: 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65 20  * Database page 
47f0: 73 69 7a 65 20 2a 2f 0a 20 20 69 31 36 20 72 65  size */.  i16 re
4800: 61 64 4c 6f 63 6b 3b 20 20 20 20 20 20 20 20 20  adLock;         
4810: 20 20 20 20 20 2f 2a 20 57 68 69 63 68 20 72 65       /* Which re
4820: 61 64 20 6c 6f 63 6b 20 69 73 20 62 65 69 6e 67  ad lock is being
4830: 20 68 65 6c 64 2e 20 20 2d 31 20 66 6f 72 20 6e   held.  -1 for n
4840: 6f 6e 65 20 2a 2f 0a 20 20 75 38 20 65 78 63 6c  one */.  u8 excl
4850: 75 73 69 76 65 4d 6f 64 65 3b 20 20 20 20 20 20  usiveMode;      
4860: 20 20 20 20 2f 2a 20 4e 6f 6e 2d 7a 65 72 6f 20      /* Non-zero 
4870: 69 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 69 73  if connection is
4880: 20 69 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f   in exclusive mo
4890: 64 65 20 2a 2f 0a 20 20 75 38 20 69 73 57 49 6e  de */.  u8 isWIn
48a0: 64 65 78 4f 70 65 6e 3b 20 20 20 20 20 20 20 20  dexOpen;        
48b0: 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 53 68     /* True if Sh
48c0: 6d 4f 70 65 6e 28 29 20 63 61 6c 6c 65 64 20 6f  mOpen() called o
48d0: 6e 20 70 44 62 46 64 20 2a 2f 0a 20 20 75 38 20  n pDbFd */.  u8 
48e0: 77 72 69 74 65 4c 6f 63 6b 3b 20 20 20 20 20 20  writeLock;      
48f0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
4900: 69 66 20 69 6e 20 61 20 77 72 69 74 65 20 74 72  if in a write tr
4910: 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 75  ansaction */.  u
4920: 38 20 63 6b 70 74 4c 6f 63 6b 3b 20 20 20 20 20  8 ckptLock;     
4930: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
4940: 65 20 69 66 20 68 6f 6c 64 69 6e 67 20 61 20 63  e if holding a c
4950: 68 65 63 6b 70 6f 69 6e 74 20 6c 6f 63 6b 20 2a  heckpoint lock *
4960: 2f 0a 20 20 57 61 6c 49 6e 64 65 78 48 64 72 20  /.  WalIndexHdr 
4970: 68 64 72 3b 20 20 20 20 20 20 20 20 20 20 20 2f  hdr;           /
4980: 2a 20 57 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  * Wal-index head
4990: 65 72 20 66 6f 72 20 63 75 72 72 65 6e 74 20 74  er for current t
49a0: 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20  ransaction */.  
49b0: 63 68 61 72 20 2a 7a 57 61 6c 4e 61 6d 65 3b 20  char *zWalName; 
49c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61             /* Na
49d0: 6d 65 20 6f 66 20 57 41 4c 20 66 69 6c 65 20 2a  me of WAL file *
49e0: 2f 0a 20 20 75 33 32 20 6e 43 6b 70 74 3b 20 20  /.  u32 nCkpt;  
49f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4a00: 2a 20 43 68 65 63 6b 70 6f 69 6e 74 20 73 65 71  * Checkpoint seq
4a10: 75 65 6e 63 65 20 63 6f 75 6e 74 65 72 20 69 6e  uence counter in
4a20: 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72 20   the wal-header 
4a30: 2a 2f 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45  */.#ifdef SQLITE
4a40: 5f 44 45 42 55 47 0a 20 20 75 38 20 6c 6f 63 6b  _DEBUG.  u8 lock
4a50: 45 72 72 6f 72 3b 20 20 20 20 20 20 20 20 20 20  Error;          
4a60: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61      /* True if a
4a70: 20 6c 6f 63 6b 69 6e 67 20 65 72 72 6f 72 20 68   locking error h
4a80: 61 73 20 6f 63 63 75 72 72 65 64 20 2a 2f 0a 23  as occurred */.#
4a90: 65 6e 64 69 66 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  endif.};../*.** 
4aa0: 45 61 63 68 20 70 61 67 65 20 6f 66 20 74 68 65  Each page of the
4ab0: 20 77 61 6c 2d 69 6e 64 65 78 20 6d 61 70 70 69   wal-index mappi
4ac0: 6e 67 20 63 6f 6e 74 61 69 6e 73 20 61 20 68 61  ng contains a ha
4ad0: 73 68 2d 74 61 62 6c 65 20 6d 61 64 65 20 75 70  sh-table made up
4ae0: 20 6f 66 0a 2a 2a 20 61 6e 20 61 72 72 61 79 20   of.** an array 
4af0: 6f 66 20 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c  of HASHTABLE_NSL
4b00: 4f 54 20 65 6c 65 6d 65 6e 74 73 20 6f 66 20 74  OT elements of t
4b10: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 79 70  he following typ
4b20: 65 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 75 31  e..*/.typedef u1
4b30: 36 20 68 74 5f 73 6c 6f 74 3b 0a 0a 2f 2a 0a 2a  6 ht_slot;../*.*
4b40: 2a 20 54 68 69 73 20 73 74 72 75 63 74 75 72 65  * This structure
4b50: 20 69 73 20 75 73 65 64 20 74 6f 20 69 6d 70 6c   is used to impl
4b60: 65 6d 65 6e 74 20 61 6e 20 69 74 65 72 61 74 6f  ement an iterato
4b70: 72 20 74 68 61 74 20 6c 6f 6f 70 73 20 74 68 72  r that loops thr
4b80: 6f 75 67 68 0a 2a 2a 20 61 6c 6c 20 66 72 61 6d  ough.** all fram
4b90: 65 73 20 69 6e 20 74 68 65 20 57 41 4c 20 69 6e  es in the WAL in
4ba0: 20 64 61 74 61 62 61 73 65 20 70 61 67 65 20 6f   database page o
4bb0: 72 64 65 72 2e 20 57 68 65 72 65 20 74 77 6f 20  rder. Where two 
4bc0: 6f 72 20 6d 6f 72 65 20 66 72 61 6d 65 73 0a 2a  or more frames.*
4bd0: 2a 20 63 6f 72 72 65 73 70 6f 6e 64 20 74 6f 20  * correspond to 
4be0: 74 68 65 20 73 61 6d 65 20 64 61 74 61 62 61 73  the same databas
4bf0: 65 20 70 61 67 65 2c 20 74 68 65 20 69 74 65 72  e page, the iter
4c00: 61 74 6f 72 20 76 69 73 69 74 73 20 6f 6e 6c 79  ator visits only
4c10: 20 74 68 65 20 0a 2a 2a 20 66 72 61 6d 65 20 6d   the .** frame m
4c20: 6f 73 74 20 72 65 63 65 6e 74 6c 79 20 77 72 69  ost recently wri
4c30: 74 74 65 6e 20 74 6f 20 74 68 65 20 57 41 4c 20  tten to the WAL 
4c40: 28 69 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c  (in other words,
4c50: 20 74 68 65 20 66 72 61 6d 65 20 77 69 74 68 0a   the frame with.
4c60: 2a 2a 20 74 68 65 20 6c 61 72 67 65 73 74 20 69  ** the largest i
4c70: 6e 64 65 78 29 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  ndex)..**.** The
4c80: 20 69 6e 74 65 72 6e 61 6c 73 20 6f 66 20 74 68   internals of th
4c90: 69 73 20 73 74 72 75 63 74 75 72 65 20 61 72 65  is structure are
4ca0: 20 6f 6e 6c 79 20 61 63 63 65 73 73 65 64 20 62   only accessed b
4cb0: 79 3a 0a 2a 2a 0a 2a 2a 20 20 20 77 61 6c 49 74  y:.**.**   walIt
4cc0: 65 72 61 74 6f 72 49 6e 69 74 28 29 20 2d 20 43  eratorInit() - C
4cd0: 72 65 61 74 65 20 61 20 6e 65 77 20 69 74 65 72  reate a new iter
4ce0: 61 74 6f 72 2c 0a 2a 2a 20 20 20 77 61 6c 49 74  ator,.**   walIt
4cf0: 65 72 61 74 6f 72 4e 65 78 74 28 29 20 2d 20 53  eratorNext() - S
4d00: 74 65 70 20 61 6e 20 69 74 65 72 61 74 6f 72 2c  tep an iterator,
4d10: 0a 2a 2a 20 20 20 77 61 6c 49 74 65 72 61 74 6f  .**   walIterato
4d20: 72 46 72 65 65 28 29 20 2d 20 46 72 65 65 20 61  rFree() - Free a
4d30: 6e 20 69 74 65 72 61 74 6f 72 2e 0a 2a 2a 0a 2a  n iterator..**.*
4d40: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 61  * This functiona
4d50: 6c 69 74 79 20 69 73 20 75 73 65 64 20 62 79 20  lity is used by 
4d60: 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 63  the checkpoint c
4d70: 6f 64 65 20 28 73 65 65 20 77 61 6c 43 68 65 63  ode (see walChec
4d80: 6b 70 6f 69 6e 74 28 29 29 2e 0a 2a 2f 0a 73 74  kpoint())..*/.st
4d90: 72 75 63 74 20 57 61 6c 49 74 65 72 61 74 6f 72  ruct WalIterator
4da0: 20 7b 0a 20 20 69 6e 74 20 69 50 72 69 6f 72 3b   {.  int iPrior;
4db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4dc0: 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 72 65 73       /* Last res
4dd0: 75 6c 74 20 72 65 74 75 72 6e 65 64 20 66 72 6f  ult returned fro
4de0: 6d 20 74 68 65 20 69 74 65 72 61 74 6f 72 20 2a  m the iterator *
4df0: 2f 0a 20 20 69 6e 74 20 6e 53 65 67 6d 65 6e 74  /.  int nSegment
4e00: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
4e10: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74      /* Size of t
4e20: 68 65 20 61 53 65 67 6d 65 6e 74 5b 5d 20 61 72  he aSegment[] ar
4e30: 72 61 79 20 2a 2f 0a 20 20 73 74 72 75 63 74 20  ray */.  struct 
4e40: 57 61 6c 53 65 67 6d 65 6e 74 20 7b 0a 20 20 20  WalSegment {.   
4e50: 20 69 6e 74 20 69 4e 65 78 74 3b 20 20 20 20 20   int iNext;     
4e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4e70: 2a 20 4e 65 78 74 20 73 6c 6f 74 20 69 6e 20 61  * Next slot in a
4e80: 49 6e 64 65 78 5b 5d 20 6e 6f 74 20 79 65 74 20  Index[] not yet 
4e90: 72 65 74 75 72 6e 65 64 20 2a 2f 0a 20 20 20 20  returned */.    
4ea0: 68 74 5f 73 6c 6f 74 20 2a 61 49 6e 64 65 78 3b  ht_slot *aIndex;
4eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4ec0: 20 69 30 2c 20 69 31 2c 20 69 32 2e 2e 2e 20 73   i0, i1, i2... s
4ed0: 75 63 68 20 74 68 61 74 20 61 50 67 6e 6f 5b 69  uch that aPgno[i
4ee0: 4e 5d 20 61 73 63 65 6e 64 20 2a 2f 0a 20 20 20  N] ascend */.   
4ef0: 20 75 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20   u32 *aPgno;    
4f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4f10: 2a 20 41 72 72 61 79 20 6f 66 20 70 61 67 65 20  * Array of page 
4f20: 6e 75 6d 62 65 72 73 2e 20 2a 2f 0a 20 20 20 20  numbers. */.    
4f30: 69 6e 74 20 6e 45 6e 74 72 79 3b 20 20 20 20 20  int nEntry;     
4f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4f50: 20 4d 61 78 20 73 69 7a 65 20 6f 66 20 61 50 67   Max size of aPg
4f60: 6e 6f 5b 5d 20 61 6e 64 20 61 49 6e 64 65 78 5b  no[] and aIndex[
4f70: 5d 20 61 72 72 61 79 73 20 2a 2f 0a 20 20 20 20  ] arrays */.    
4f80: 69 6e 74 20 69 5a 65 72 6f 3b 20 20 20 20 20 20  int iZero;      
4f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4fa0: 20 46 72 61 6d 65 20 6e 75 6d 62 65 72 20 61 73   Frame number as
4fb0: 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 61 50  sociated with aP
4fc0: 67 6e 6f 5b 30 5d 20 2a 2f 0a 20 20 7d 20 61 53  gno[0] */.  } aS
4fd0: 65 67 6d 65 6e 74 5b 31 5d 3b 20 20 20 20 20 20  egment[1];      
4fe0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
4ff0: 6e 65 20 66 6f 72 20 65 76 65 72 79 20 33 32 4b  ne for every 32K
5000: 42 20 70 61 67 65 20 69 6e 20 74 68 65 20 57 41  B page in the WA
5010: 4c 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44  L */.};../*.** D
5020: 65 66 69 6e 65 20 74 68 65 20 70 61 72 61 6d 65  efine the parame
5030: 74 65 72 73 20 6f 66 20 74 68 65 20 68 61 73 68  ters of the hash
5040: 20 74 61 62 6c 65 73 20 69 6e 20 74 68 65 20 77   tables in the w
5050: 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 2e 20 54  al-index file. T
5060: 68 65 72 65 0a 2a 2a 20 69 73 20 61 20 68 61 73  here.** is a has
5070: 68 2d 74 61 62 6c 65 20 66 6f 6c 6c 6f 77 69 6e  h-table followin
5080: 67 20 65 76 65 72 79 20 48 41 53 48 54 41 42 4c  g every HASHTABL
5090: 45 5f 4e 50 41 47 45 20 70 61 67 65 20 6e 75 6d  E_NPAGE page num
50a0: 62 65 72 73 20 69 6e 20 74 68 65 0a 2a 2a 20 77  bers in the.** w
50b0: 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a 20  al-index..**.** 
50c0: 43 68 61 6e 67 69 6e 67 20 61 6e 79 20 6f 66 20  Changing any of 
50d0: 74 68 65 73 65 20 63 6f 6e 73 74 61 6e 74 73 20  these constants 
50e0: 77 69 6c 6c 20 61 6c 74 65 72 20 74 68 65 20 77  will alter the w
50f0: 61 6c 2d 69 6e 64 65 78 20 66 6f 72 6d 61 74 20  al-index format 
5100: 61 6e 64 0a 2a 2a 20 63 72 65 61 74 65 20 69 6e  and.** create in
5110: 63 6f 6d 70 61 74 69 62 69 6c 69 74 69 65 73 2e  compatibilities.
5120: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 48 41 53 48  .*/.#define HASH
5130: 54 41 42 4c 45 5f 4e 50 41 47 45 20 20 20 20 20  TABLE_NPAGE     
5140: 20 34 30 39 36 20 20 20 20 20 20 20 20 20 20 20   4096           
5150: 20 20 20 20 20 20 2f 2a 20 4d 75 73 74 20 62 65        /* Must be
5160: 20 70 6f 77 65 72 20 6f 66 20 32 20 2a 2f 0a 23   power of 2 */.#
5170: 64 65 66 69 6e 65 20 48 41 53 48 54 41 42 4c 45  define HASHTABLE
5180: 5f 48 41 53 48 5f 31 20 20 20 20 20 33 38 33 20  _HASH_1     383 
5190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
51a0: 20 2f 2a 20 53 68 6f 75 6c 64 20 62 65 20 70 72   /* Should be pr
51b0: 69 6d 65 20 2a 2f 0a 23 64 65 66 69 6e 65 20 48  ime */.#define H
51c0: 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 20 20  ASHTABLE_NSLOT  
51d0: 20 20 20 20 28 48 41 53 48 54 41 42 4c 45 5f 4e      (HASHTABLE_N
51e0: 50 41 47 45 2a 32 29 20 20 2f 2a 20 4d 75 73 74  PAGE*2)  /* Must
51f0: 20 62 65 20 61 20 70 6f 77 65 72 20 6f 66 20 32   be a power of 2
5200: 20 2a 2f 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 65 20   */../* .** The 
5210: 62 6c 6f 63 6b 20 6f 66 20 70 61 67 65 20 6e 75  block of page nu
5220: 6d 62 65 72 73 20 61 73 73 6f 63 69 61 74 65 64  mbers associated
5230: 20 77 69 74 68 20 74 68 65 20 66 69 72 73 74 20   with the first 
5240: 68 61 73 68 2d 74 61 62 6c 65 20 69 6e 20 61 0a  hash-table in a.
5250: 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  ** wal-index is 
5260: 73 6d 61 6c 6c 65 72 20 74 68 61 6e 20 75 73 75  smaller than usu
5270: 61 6c 2e 20 54 68 69 73 20 69 73 20 73 6f 20 74  al. This is so t
5280: 68 61 74 20 74 68 65 72 65 20 69 73 20 61 20 63  hat there is a c
5290: 6f 6d 70 6c 65 74 65 0a 2a 2a 20 68 61 73 68 2d  omplete.** hash-
52a0: 74 61 62 6c 65 20 6f 6e 20 65 61 63 68 20 61 6c  table on each al
52b0: 69 67 6e 65 64 20 33 32 4b 42 20 70 61 67 65 20  igned 32KB page 
52c0: 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78  of the wal-index
52d0: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 48 41 53  ..*/.#define HAS
52e0: 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45  HTABLE_NPAGE_ONE
52f0: 20 20 28 48 41 53 48 54 41 42 4c 45 5f 4e 50 41    (HASHTABLE_NPA
5300: 47 45 20 2d 20 28 57 41 4c 49 4e 44 45 58 5f 48  GE - (WALINDEX_H
5310: 44 52 5f 53 49 5a 45 2f 73 69 7a 65 6f 66 28 75  DR_SIZE/sizeof(u
5320: 33 32 29 29 29 0a 0a 2f 2a 20 54 68 65 20 77 61  32)))../* The wa
5330: 6c 2d 69 6e 64 65 78 20 69 73 20 64 69 76 69 64  l-index is divid
5340: 65 64 20 69 6e 74 6f 20 70 61 67 65 73 20 6f 66  ed into pages of
5350: 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a 20 62   WALINDEX_PGSZ b
5360: 79 74 65 73 20 65 61 63 68 2e 20 2a 2f 0a 23 64  ytes each. */.#d
5370: 65 66 69 6e 65 20 57 41 4c 49 4e 44 45 58 5f 50  efine WALINDEX_P
5380: 47 53 5a 20 20 20 28 20 20 20 20 20 20 20 20 20  GSZ   (         
5390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
53a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
53b0: 5c 0a 20 20 20 20 73 69 7a 65 6f 66 28 68 74 5f  \.    sizeof(ht_
53c0: 73 6c 6f 74 29 2a 48 41 53 48 54 41 42 4c 45 5f  slot)*HASHTABLE_
53d0: 4e 53 4c 4f 54 20 2b 20 48 41 53 48 54 41 42 4c  NSLOT + HASHTABL
53e0: 45 5f 4e 50 41 47 45 2a 73 69 7a 65 6f 66 28 75  E_NPAGE*sizeof(u
53f0: 33 32 29 20 5c 0a 29 0a 0a 2f 2a 0a 2a 2a 20 4f  32) \.)../*.** O
5400: 62 74 61 69 6e 20 61 20 70 6f 69 6e 74 65 72 20  btain a pointer 
5410: 74 6f 20 74 68 65 20 69 50 61 67 65 27 74 68 20  to the iPage'th 
5420: 70 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c 2d  page of the wal-
5430: 69 6e 64 65 78 2e 20 54 68 65 20 77 61 6c 2d 69  index. The wal-i
5440: 6e 64 65 78 0a 2a 2a 20 69 73 20 62 72 6f 6b 65  ndex.** is broke
5450: 6e 20 69 6e 74 6f 20 70 61 67 65 73 20 6f 66 20  n into pages of 
5460: 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a 20 62 79  WALINDEX_PGSZ by
5470: 74 65 73 2e 20 57 61 6c 2d 69 6e 64 65 78 20 70  tes. Wal-index p
5480: 61 67 65 73 20 61 72 65 0a 2a 2a 20 6e 75 6d 62  ages are.** numb
5490: 65 72 65 64 20 66 72 6f 6d 20 7a 65 72 6f 2e 0a  ered from zero..
54a0: 2a 2a 0a 2a 2a 20 49 66 20 74 68 69 73 20 63 61  **.** If this ca
54b0: 6c 6c 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  ll is successful
54c0: 2c 20 2a 70 70 50 61 67 65 20 69 73 20 73 65 74  , *ppPage is set
54d0: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   to point to the
54e0: 20 77 61 6c 2d 69 6e 64 65 78 0a 2a 2a 20 70 61   wal-index.** pa
54f0: 67 65 20 61 6e 64 20 53 51 4c 49 54 45 5f 4f 4b  ge and SQLITE_OK
5500: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 49 66   is returned. If
5510: 20 61 6e 20 65 72 72 6f 72 20 28 61 6e 20 4f 4f   an error (an OO
5520: 4d 20 6f 72 20 56 46 53 20 65 72 72 6f 72 29 20  M or VFS error) 
5530: 6f 63 63 75 72 73 2c 0a 2a 2a 20 74 68 65 6e 20  occurs,.** then 
5540: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
5550: 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65 64  code is returned
5560: 20 61 6e 64 20 2a 70 70 50 61 67 65 20 69 73 20   and *ppPage is 
5570: 73 65 74 20 74 6f 20 30 2e 0a 2a 2f 0a 73 74 61  set to 0..*/.sta
5580: 74 69 63 20 69 6e 74 20 77 61 6c 49 6e 64 65 78  tic int walIndex
5590: 50 61 67 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20  Page(Wal *pWal, 
55a0: 69 6e 74 20 69 50 61 67 65 2c 20 76 6f 6c 61 74  int iPage, volat
55b0: 69 6c 65 20 75 33 32 20 2a 2a 70 70 50 61 67 65  ile u32 **ppPage
55c0: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
55d0: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 2f 2a 20 45  LITE_OK;..  /* E
55e0: 6e 6c 61 72 67 65 20 74 68 65 20 70 57 61 6c 2d  nlarge the pWal-
55f0: 3e 61 70 57 69 44 61 74 61 5b 5d 20 61 72 72 61  >apWiData[] arra
5600: 79 20 69 66 20 72 65 71 75 69 72 65 64 20 2a 2f  y if required */
5610: 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 6e 57 69  .  if( pWal->nWi
5620: 44 61 74 61 3c 3d 69 50 61 67 65 20 29 7b 0a 20  Data<=iPage ){. 
5630: 20 20 20 69 6e 74 20 6e 42 79 74 65 20 3d 20 73     int nByte = s
5640: 69 7a 65 6f 66 28 75 33 32 20 2a 29 2a 28 69 50  izeof(u32 *)*(iP
5650: 61 67 65 2b 31 29 3b 0a 20 20 20 20 76 6f 6c 61  age+1);.    vola
5660: 74 69 6c 65 20 75 33 32 20 2a 2a 61 70 4e 65 77  tile u32 **apNew
5670: 3b 0a 20 20 20 20 61 70 4e 65 77 20 3d 20 28 76  ;.    apNew = (v
5680: 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 2a 29 73  olatile u32 **)s
5690: 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f 63 28 70  qlite3_realloc(p
56a0: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 2c 20 6e  Wal->apWiData, n
56b0: 42 79 74 65 29 3b 0a 20 20 20 20 69 66 28 20 21  Byte);.    if( !
56c0: 61 70 4e 65 77 20 29 7b 0a 20 20 20 20 20 20 2a  apNew ){.      *
56d0: 70 70 50 61 67 65 20 3d 20 30 3b 0a 20 20 20 20  ppPage = 0;.    
56e0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
56f0: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20  NOMEM;.    }.   
5700: 20 6d 65 6d 73 65 74 28 26 61 70 4e 65 77 5b 70   memset(&apNew[p
5710: 57 61 6c 2d 3e 6e 57 69 44 61 74 61 5d 2c 20 30  Wal->nWiData], 0
5720: 2c 20 73 69 7a 65 6f 66 28 75 33 32 20 2a 29 2a  , sizeof(u32 *)*
5730: 28 69 50 61 67 65 2b 31 2d 70 57 61 6c 2d 3e 6e  (iPage+1-pWal->n
5740: 57 69 44 61 74 61 29 29 3b 0a 20 20 20 20 70 57  WiData));.    pW
5750: 61 6c 2d 3e 61 70 57 69 44 61 74 61 20 3d 20 61  al->apWiData = a
5760: 70 4e 65 77 3b 0a 20 20 20 20 70 57 61 6c 2d 3e  pNew;.    pWal->
5770: 6e 57 69 44 61 74 61 20 3d 20 69 50 61 67 65 2b  nWiData = iPage+
5780: 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65 71  1;.  }..  /* Req
5790: 75 65 73 74 20 61 20 70 6f 69 6e 74 65 72 20 74  uest a pointer t
57a0: 6f 20 74 68 65 20 72 65 71 75 69 72 65 64 20 70  o the required p
57b0: 61 67 65 20 66 72 6f 6d 20 74 68 65 20 56 46 53  age from the VFS
57c0: 20 2a 2f 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e   */.  if( pWal->
57d0: 61 70 57 69 44 61 74 61 5b 69 50 61 67 65 5d 3d  apWiData[iPage]=
57e0: 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  =0 ){.    rc = s
57f0: 71 6c 69 74 65 33 4f 73 53 68 6d 4d 61 70 28 70  qlite3OsShmMap(p
5800: 57 61 6c 2d 3e 70 44 62 46 64 2c 20 69 50 61 67  Wal->pDbFd, iPag
5810: 65 2c 20 57 41 4c 49 4e 44 45 58 5f 50 47 53 5a  e, WALINDEX_PGSZ
5820: 2c 20 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d  , .        pWal-
5830: 3e 77 72 69 74 65 4c 6f 63 6b 2c 20 28 76 6f 69  >writeLock, (voi
5840: 64 20 76 6f 6c 61 74 69 6c 65 20 2a 2a 29 26 70  d volatile **)&p
5850: 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50  Wal->apWiData[iP
5860: 61 67 65 5d 0a 20 20 20 20 29 3b 0a 20 20 7d 0a  age].    );.  }.
5870: 0a 20 20 2a 70 70 50 61 67 65 20 3d 20 70 57 61  .  *ppPage = pWa
5880: 6c 2d 3e 61 70 57 69 44 61 74 61 5b 69 50 61 67  l->apWiData[iPag
5890: 65 5d 3b 0a 20 20 61 73 73 65 72 74 28 20 69 50  e];.  assert( iP
58a0: 61 67 65 3d 3d 30 20 7c 7c 20 2a 70 70 50 61 67  age==0 || *ppPag
58b0: 65 20 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45 5f  e || rc!=SQLITE_
58c0: 4f 4b 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  OK );.  return r
58d0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  c;.}../*.** Retu
58e0: 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  rn a pointer to 
58f0: 74 68 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20  the WalCkptInfo 
5900: 73 74 72 75 63 74 75 72 65 20 69 6e 20 74 68 65  structure in the
5910: 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 73   wal-index..*/.s
5920: 74 61 74 69 63 20 76 6f 6c 61 74 69 6c 65 20 57  tatic volatile W
5930: 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 77 61 6c 43  alCkptInfo *walC
5940: 6b 70 74 49 6e 66 6f 28 57 61 6c 20 2a 70 57 61  kptInfo(Wal *pWa
5950: 6c 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57  l){.  assert( pW
5960: 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20 26 26  al->nWiData>0 &&
5970: 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
5980: 30 5d 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 28  0] );.  return (
5990: 76 6f 6c 61 74 69 6c 65 20 57 61 6c 43 6b 70 74  volatile WalCkpt
59a0: 49 6e 66 6f 2a 29 26 28 70 57 61 6c 2d 3e 61 70  Info*)&(pWal->ap
59b0: 57 69 44 61 74 61 5b 30 5d 5b 73 69 7a 65 6f 66  WiData[0][sizeof
59c0: 28 57 61 6c 49 6e 64 65 78 48 64 72 29 2f 32 5d  (WalIndexHdr)/2]
59d0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  );.}../*.** Retu
59e0: 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  rn a pointer to 
59f0: 74 68 65 20 57 61 6c 49 6e 64 65 78 48 64 72 20  the WalIndexHdr 
5a00: 73 74 72 75 63 74 75 72 65 20 69 6e 20 74 68 65  structure in the
5a10: 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f 0a 73   wal-index..*/.s
5a20: 74 61 74 69 63 20 76 6f 6c 61 74 69 6c 65 20 57  tatic volatile W
5a30: 61 6c 49 6e 64 65 78 48 64 72 20 2a 77 61 6c 49  alIndexHdr *walI
5a40: 6e 64 65 78 48 64 72 28 57 61 6c 20 2a 70 57 61  ndexHdr(Wal *pWa
5a50: 6c 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 57  l){.  assert( pW
5a60: 61 6c 2d 3e 6e 57 69 44 61 74 61 3e 30 20 26 26  al->nWiData>0 &&
5a70: 20 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 5b   pWal->apWiData[
5a80: 30 5d 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 28  0] );.  return (
5a90: 76 6f 6c 61 74 69 6c 65 20 57 61 6c 49 6e 64 65  volatile WalInde
5aa0: 78 48 64 72 2a 29 70 57 61 6c 2d 3e 61 70 57 69  xHdr*)pWal->apWi
5ab0: 44 61 74 61 5b 30 5d 3b 0a 7d 0a 0a 2f 2a 0a 2a  Data[0];.}../*.*
5ac0: 2a 20 54 68 65 20 61 72 67 75 6d 65 6e 74 20 74  * The argument t
5ad0: 6f 20 74 68 69 73 20 6d 61 63 72 6f 20 6d 75 73  o this macro mus
5ae0: 74 20 62 65 20 6f 66 20 74 79 70 65 20 75 33 32  t be of type u32
5af0: 2e 20 4f 6e 20 61 20 6c 69 74 74 6c 65 2d 65 6e  . On a little-en
5b00: 64 69 61 6e 0a 2a 2a 20 61 72 63 68 69 74 65 63  dian.** architec
5b10: 74 75 72 65 2c 20 69 74 20 72 65 74 75 72 6e 73  ture, it returns
5b20: 20 74 68 65 20 75 33 32 20 76 61 6c 75 65 20 74   the u32 value t
5b30: 68 61 74 20 72 65 73 75 6c 74 73 20 66 72 6f 6d  hat results from
5b40: 20 69 6e 74 65 72 70 72 65 74 69 6e 67 0a 2a 2a   interpreting.**
5b50: 20 74 68 65 20 34 20 62 79 74 65 73 20 61 73 20   the 4 bytes as 
5b60: 61 20 62 69 67 2d 65 6e 64 69 61 6e 20 76 61 6c  a big-endian val
5b70: 75 65 2e 20 4f 6e 20 61 20 62 69 67 2d 65 6e 64  ue. On a big-end
5b80: 69 61 6e 20 61 72 63 68 69 74 65 63 74 75 72 65  ian architecture
5b90: 2c 20 69 74 0a 2a 2a 20 72 65 74 75 72 6e 73 20  , it.** returns 
5ba0: 74 68 65 20 76 61 6c 75 65 20 74 68 61 74 20 77  the value that w
5bb0: 6f 75 6c 64 20 62 65 20 70 72 6f 64 75 63 65 64  ould be produced
5bc0: 20 62 79 20 69 6e 74 65 70 72 65 74 69 6e 67 20   by intepreting 
5bd0: 74 68 65 20 34 20 62 79 74 65 73 0a 2a 2a 20 6f  the 4 bytes.** o
5be0: 66 20 74 68 65 20 69 6e 70 75 74 20 76 61 6c 75  f the input valu
5bf0: 65 20 61 73 20 61 20 6c 69 74 74 6c 65 2d 65 6e  e as a little-en
5c00: 64 69 61 6e 20 69 6e 74 65 67 65 72 2e 0a 2a 2f  dian integer..*/
5c10: 0a 23 64 65 66 69 6e 65 20 42 59 54 45 53 57 41  .#define BYTESWA
5c20: 50 33 32 28 78 29 20 28 20 5c 0a 20 20 20 20 28  P32(x) ( \.    (
5c30: 28 28 78 29 26 30 78 30 30 30 30 30 30 46 46 29  ((x)&0x000000FF)
5c40: 3c 3c 32 34 29 20 2b 20 28 28 28 78 29 26 30 78  <<24) + (((x)&0x
5c50: 30 30 30 30 46 46 30 30 29 3c 3c 38 29 20 20 5c  0000FF00)<<8)  \
5c60: 0a 20 20 2b 20 28 28 28 78 29 26 30 78 30 30 46  .  + (((x)&0x00F
5c70: 46 30 30 30 30 29 3e 3e 38 29 20 20 2b 20 28 28  F0000)>>8)  + ((
5c80: 28 78 29 26 30 78 46 46 30 30 30 30 30 30 29 3e  (x)&0xFF000000)>
5c90: 3e 32 34 29 20 5c 0a 29 0a 0a 2f 2a 0a 2a 2a 20  >24) \.)../*.** 
5ca0: 47 65 6e 65 72 61 74 65 20 6f 72 20 65 78 74 65  Generate or exte
5cb0: 6e 64 20 61 6e 20 38 20 62 79 74 65 20 63 68 65  nd an 8 byte che
5cc0: 63 6b 73 75 6d 20 62 61 73 65 64 20 6f 6e 20 74  cksum based on t
5cd0: 68 65 20 64 61 74 61 20 69 6e 20 0a 2a 2a 20 61  he data in .** a
5ce0: 72 72 61 79 20 61 42 79 74 65 5b 5d 20 61 6e 64  rray aByte[] and
5cf0: 20 74 68 65 20 69 6e 69 74 69 61 6c 20 76 61 6c   the initial val
5d00: 75 65 73 20 6f 66 20 61 49 6e 5b 30 5d 20 61 6e  ues of aIn[0] an
5d10: 64 20 61 49 6e 5b 31 5d 20 28 6f 72 0a 2a 2a 20  d aIn[1] (or.** 
5d20: 69 6e 69 74 69 61 6c 20 76 61 6c 75 65 73 20 6f  initial values o
5d30: 66 20 30 20 61 6e 64 20 30 20 69 66 20 61 49 6e  f 0 and 0 if aIn
5d40: 3d 3d 4e 55 4c 4c 29 2e 0a 2a 2a 0a 2a 2a 20 54  ==NULL)..**.** T
5d50: 68 65 20 63 68 65 63 6b 73 75 6d 20 69 73 20 77  he checksum is w
5d60: 72 69 74 74 65 6e 20 62 61 63 6b 20 69 6e 74 6f  ritten back into
5d70: 20 61 4f 75 74 5b 5d 20 62 65 66 6f 72 65 20 72   aOut[] before r
5d80: 65 74 75 72 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20  eturning..**.** 
5d90: 6e 42 79 74 65 20 6d 75 73 74 20 62 65 20 61 20  nByte must be a 
5da0: 70 6f 73 69 74 69 76 65 20 6d 75 6c 74 69 70 6c  positive multipl
5db0: 65 20 6f 66 20 38 2e 0a 2a 2f 0a 73 74 61 74 69  e of 8..*/.stati
5dc0: 63 20 76 6f 69 64 20 77 61 6c 43 68 65 63 6b 73  c void walChecks
5dd0: 75 6d 42 79 74 65 73 28 0a 20 20 69 6e 74 20 6e  umBytes(.  int n
5de0: 61 74 69 76 65 43 6b 73 75 6d 2c 20 2f 2a 20 54  ativeCksum, /* T
5df0: 72 75 65 20 66 6f 72 20 6e 61 74 69 76 65 20 62  rue for native b
5e00: 79 74 65 2d 6f 72 64 65 72 2c 20 66 61 6c 73 65  yte-order, false
5e10: 20 66 6f 72 20 6e 6f 6e 2d 6e 61 74 69 76 65 20   for non-native 
5e20: 2a 2f 0a 20 20 75 38 20 2a 61 2c 20 20 20 20 20  */.  u8 *a,     
5e30: 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 6e 74        /* Content
5e40: 20 74 6f 20 62 65 20 63 68 65 63 6b 73 75 6d 6d   to be checksumm
5e50: 65 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74  ed */.  int nByt
5e60: 65 2c 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65  e,       /* Byte
5e70: 73 20 6f 66 20 63 6f 6e 74 65 6e 74 20 69 6e 20  s of content in 
5e80: 61 5b 5d 2e 20 20 4d 75 73 74 20 62 65 20 61 20  a[].  Must be a 
5e90: 6d 75 6c 74 69 70 6c 65 20 6f 66 20 38 2e 20 2a  multiple of 8. *
5ea0: 2f 0a 20 20 63 6f 6e 73 74 20 75 33 32 20 2a 61  /.  const u32 *a
5eb0: 49 6e 2c 20 20 2f 2a 20 49 6e 69 74 69 61 6c 20  In,  /* Initial 
5ec0: 63 68 65 63 6b 73 75 6d 20 76 61 6c 75 65 20 69  checksum value i
5ed0: 6e 70 75 74 20 2a 2f 0a 20 20 75 33 32 20 2a 61  nput */.  u32 *a
5ee0: 4f 75 74 20 20 20 20 20 20 20 20 2f 2a 20 4f 55  Out        /* OU
5ef0: 54 3a 20 46 69 6e 61 6c 20 63 68 65 63 6b 73 75  T: Final checksu
5f00: 6d 20 76 61 6c 75 65 20 6f 75 74 70 75 74 20 2a  m value output *
5f10: 2f 0a 29 7b 0a 20 20 75 33 32 20 73 31 2c 20 73  /.){.  u32 s1, s
5f20: 32 3b 0a 20 20 75 33 32 20 2a 61 44 61 74 61 20  2;.  u32 *aData 
5f30: 3d 20 28 75 33 32 20 2a 29 61 3b 0a 20 20 75 33  = (u32 *)a;.  u3
5f40: 32 20 2a 61 45 6e 64 20 3d 20 28 75 33 32 20 2a  2 *aEnd = (u32 *
5f50: 29 26 61 5b 6e 42 79 74 65 5d 3b 0a 0a 20 20 69  )&a[nByte];..  i
5f60: 66 28 20 61 49 6e 20 29 7b 0a 20 20 20 20 73 31  f( aIn ){.    s1
5f70: 20 3d 20 61 49 6e 5b 30 5d 3b 0a 20 20 20 20 73   = aIn[0];.    s
5f80: 32 20 3d 20 61 49 6e 5b 31 5d 3b 0a 20 20 7d 65  2 = aIn[1];.  }e
5f90: 6c 73 65 7b 0a 20 20 20 20 73 31 20 3d 20 73 32  lse{.    s1 = s2
5fa0: 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 61 73 73   = 0;.  }..  ass
5fb0: 65 72 74 28 20 6e 42 79 74 65 3e 3d 38 20 29 3b  ert( nByte>=8 );
5fc0: 0a 20 20 61 73 73 65 72 74 28 20 28 6e 42 79 74  .  assert( (nByt
5fd0: 65 26 30 78 30 30 30 30 30 30 30 37 29 3d 3d 30  e&0x00000007)==0
5fe0: 20 29 3b 0a 0a 20 20 69 66 28 20 6e 61 74 69 76   );..  if( nativ
5ff0: 65 43 6b 73 75 6d 20 29 7b 0a 20 20 20 20 64 6f  eCksum ){.    do
6000: 20 7b 0a 20 20 20 20 20 20 73 31 20 2b 3d 20 2a   {.      s1 += *
6010: 61 44 61 74 61 2b 2b 20 2b 20 73 32 3b 0a 20 20  aData++ + s2;.  
6020: 20 20 20 20 73 32 20 2b 3d 20 2a 61 44 61 74 61      s2 += *aData
6030: 2b 2b 20 2b 20 73 31 3b 0a 20 20 20 20 7d 77 68  ++ + s1;.    }wh
6040: 69 6c 65 28 20 61 44 61 74 61 3c 61 45 6e 64 20  ile( aData<aEnd 
6050: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
6060: 64 6f 20 7b 0a 20 20 20 20 20 20 73 31 20 2b 3d  do {.      s1 +=
6070: 20 42 59 54 45 53 57 41 50 33 32 28 61 44 61 74   BYTESWAP32(aDat
6080: 61 5b 30 5d 29 20 2b 20 73 32 3b 0a 20 20 20 20  a[0]) + s2;.    
6090: 20 20 73 32 20 2b 3d 20 42 59 54 45 53 57 41 50    s2 += BYTESWAP
60a0: 33 32 28 61 44 61 74 61 5b 31 5d 29 20 2b 20 73  32(aData[1]) + s
60b0: 31 3b 0a 20 20 20 20 20 20 61 44 61 74 61 20 2b  1;.      aData +
60c0: 3d 20 32 3b 0a 20 20 20 20 7d 77 68 69 6c 65 28  = 2;.    }while(
60d0: 20 61 44 61 74 61 3c 61 45 6e 64 20 29 3b 0a 20   aData<aEnd );. 
60e0: 20 7d 0a 0a 20 20 61 4f 75 74 5b 30 5d 20 3d 20   }..  aOut[0] = 
60f0: 73 31 3b 0a 20 20 61 4f 75 74 5b 31 5d 20 3d 20  s1;.  aOut[1] = 
6100: 73 32 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69  s2;.}../*.** Wri
6110: 74 65 20 74 68 65 20 68 65 61 64 65 72 20 69 6e  te the header in
6120: 66 6f 72 6d 61 74 69 6f 6e 20 69 6e 20 70 57 61  formation in pWa
6130: 6c 2d 3e 68 64 72 20 69 6e 74 6f 20 74 68 65 20  l->hdr into the 
6140: 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2a 0a 2a 2a  wal-index..**.**
6150: 20 54 68 65 20 63 68 65 63 6b 73 75 6d 20 6f 6e   The checksum on
6160: 20 70 57 61 6c 2d 3e 68 64 72 20 69 73 20 75 70   pWal->hdr is up
6170: 64 61 74 65 64 20 62 65 66 6f 72 65 20 69 74 20  dated before it 
6180: 69 73 20 77 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73  is written..*/.s
6190: 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c 49 6e  tatic void walIn
61a0: 64 65 78 57 72 69 74 65 48 64 72 28 57 61 6c 20  dexWriteHdr(Wal 
61b0: 2a 70 57 61 6c 29 7b 0a 20 20 76 6f 6c 61 74 69  *pWal){.  volati
61c0: 6c 65 20 57 61 6c 49 6e 64 65 78 48 64 72 20 2a  le WalIndexHdr *
61d0: 61 48 64 72 20 3d 20 77 61 6c 49 6e 64 65 78 48  aHdr = walIndexH
61e0: 64 72 28 70 57 61 6c 29 3b 0a 20 20 63 6f 6e 73  dr(pWal);.  cons
61f0: 74 20 69 6e 74 20 6e 43 6b 73 75 6d 20 3d 20 6f  t int nCksum = o
6200: 66 66 73 65 74 6f 66 28 57 61 6c 49 6e 64 65 78  ffsetof(WalIndex
6210: 48 64 72 2c 20 61 43 6b 73 75 6d 29 3b 0a 0a 20  Hdr, aCksum);.. 
6220: 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77   assert( pWal->w
6230: 72 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 70 57  riteLock );.  pW
6240: 61 6c 2d 3e 68 64 72 2e 69 73 49 6e 69 74 20 3d  al->hdr.isInit =
6250: 20 31 3b 0a 20 20 77 61 6c 43 68 65 63 6b 73 75   1;.  walChecksu
6260: 6d 42 79 74 65 73 28 31 2c 20 28 75 38 2a 29 26  mBytes(1, (u8*)&
6270: 70 57 61 6c 2d 3e 68 64 72 2c 20 6e 43 6b 73 75  pWal->hdr, nCksu
6280: 6d 2c 20 30 2c 20 70 57 61 6c 2d 3e 68 64 72 2e  m, 0, pWal->hdr.
6290: 61 43 6b 73 75 6d 29 3b 0a 20 20 6d 65 6d 63 70  aCksum);.  memcp
62a0: 79 28 28 76 6f 69 64 20 2a 29 26 61 48 64 72 5b  y((void *)&aHdr[
62b0: 31 5d 2c 20 28 76 6f 69 64 20 2a 29 26 70 57 61  1], (void *)&pWa
62c0: 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57  l->hdr, sizeof(W
62d0: 61 6c 49 6e 64 65 78 48 64 72 29 29 3b 0a 20 20  alIndexHdr));.  
62e0: 73 71 6c 69 74 65 33 4f 73 53 68 6d 42 61 72 72  sqlite3OsShmBarr
62f0: 69 65 72 28 70 57 61 6c 2d 3e 70 44 62 46 64 29  ier(pWal->pDbFd)
6300: 3b 0a 20 20 6d 65 6d 63 70 79 28 28 76 6f 69 64  ;.  memcpy((void
6310: 20 2a 29 26 61 48 64 72 5b 30 5d 2c 20 28 76 6f   *)&aHdr[0], (vo
6320: 69 64 20 2a 29 26 70 57 61 6c 2d 3e 68 64 72 2c  id *)&pWal->hdr,
6330: 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78   sizeof(WalIndex
6340: 48 64 72 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Hdr));.}../*.** 
6350: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 65 6e  This function en
6360: 63 6f 64 65 73 20 61 20 73 69 6e 67 6c 65 20 66  codes a single f
6370: 72 61 6d 65 20 68 65 61 64 65 72 20 61 6e 64 20  rame header and 
6380: 77 72 69 74 65 73 20 69 74 20 74 6f 20 61 20 62  writes it to a b
6390: 75 66 66 65 72 0a 2a 2a 20 73 75 70 70 6c 69 65  uffer.** supplie
63a0: 64 20 62 79 20 74 68 65 20 63 61 6c 6c 65 72 2e  d by the caller.
63b0: 20 41 20 66 72 61 6d 65 2d 68 65 61 64 65 72 20   A frame-header 
63c0: 69 73 20 6d 61 64 65 20 75 70 20 6f 66 20 61 20  is made up of a 
63d0: 73 65 72 69 65 73 20 6f 66 20 0a 2a 2a 20 34 2d  series of .** 4-
63e0: 62 79 74 65 20 62 69 67 2d 65 6e 64 69 61 6e 20  byte big-endian 
63f0: 69 6e 74 65 67 65 72 73 2c 20 61 73 20 66 6f 6c  integers, as fol
6400: 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  lows:.**.**     
6410: 30 3a 20 50 61 67 65 20 6e 75 6d 62 65 72 2e 0a  0: Page number..
6420: 2a 2a 20 20 20 20 20 34 3a 20 46 6f 72 20 63 6f  **     4: For co
6430: 6d 6d 69 74 20 72 65 63 6f 72 64 73 2c 20 74 68  mmit records, th
6440: 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 64 61  e size of the da
6450: 74 61 62 61 73 65 20 69 6d 61 67 65 20 69 6e 20  tabase image in 
6460: 70 61 67 65 73 20 0a 2a 2a 20 20 20 20 20 20 20  pages .**       
6470: 20 61 66 74 65 72 20 74 68 65 20 63 6f 6d 6d 69   after the commi
6480: 74 2e 20 46 6f 72 20 61 6c 6c 20 6f 74 68 65 72  t. For all other
6490: 20 72 65 63 6f 72 64 73 2c 20 7a 65 72 6f 2e 0a   records, zero..
64a0: 2a 2a 20 20 20 20 20 38 3a 20 53 61 6c 74 2d 31  **     8: Salt-1
64b0: 20 28 63 6f 70 69 65 64 20 66 72 6f 6d 20 74 68   (copied from th
64c0: 65 20 77 61 6c 2d 68 65 61 64 65 72 29 0a 2a 2a  e wal-header).**
64d0: 20 20 20 20 31 32 3a 20 53 61 6c 74 2d 32 20 28      12: Salt-2 (
64e0: 63 6f 70 69 65 64 20 66 72 6f 6d 20 74 68 65 20  copied from the 
64f0: 77 61 6c 2d 68 65 61 64 65 72 29 0a 2a 2a 20 20  wal-header).**  
6500: 20 20 31 36 3a 20 43 68 65 63 6b 73 75 6d 2d 31    16: Checksum-1
6510: 2e 0a 2a 2a 20 20 20 20 32 30 3a 20 43 68 65 63  ..**    20: Chec
6520: 6b 73 75 6d 2d 32 2e 0a 2a 2f 0a 73 74 61 74 69  ksum-2..*/.stati
6530: 63 20 76 6f 69 64 20 77 61 6c 45 6e 63 6f 64 65  c void walEncode
6540: 46 72 61 6d 65 28 0a 20 20 57 61 6c 20 2a 70 57  Frame(.  Wal *pW
6550: 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
6560: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
6570: 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20  write-ahead log 
6580: 2a 2f 0a 20 20 75 33 32 20 69 50 61 67 65 2c 20  */.  u32 iPage, 
6590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
65a0: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
65b0: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 66 6f 72   page number for
65c0: 20 66 72 61 6d 65 20 2a 2f 0a 20 20 75 33 32 20   frame */.  u32 
65d0: 6e 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20 20  nTruncate,      
65e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
65f0: 65 77 20 64 62 20 73 69 7a 65 20 28 6f 72 20 30  ew db size (or 0
6600: 20 66 6f 72 20 6e 6f 6e 2d 63 6f 6d 6d 69 74 20   for non-commit 
6610: 66 72 61 6d 65 73 29 20 2a 2f 0a 20 20 75 38 20  frames) */.  u8 
6620: 2a 61 44 61 74 61 2c 20 20 20 20 20 20 20 20 20  *aData,         
6630: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6640: 50 6f 69 6e 74 65 72 20 74 6f 20 70 61 67 65 20  Pointer to page 
6650: 64 61 74 61 20 2a 2f 0a 20 20 75 38 20 2a 61 46  data */.  u8 *aF
6660: 72 61 6d 65 20 20 20 20 20 20 20 20 20 20 20 20  rame            
6670: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54            /* OUT
6680: 3a 20 57 72 69 74 65 20 65 6e 63 6f 64 65 64 20  : Write encoded 
6690: 66 72 61 6d 65 20 68 65 72 65 20 2a 2f 0a 29 7b  frame here */.){
66a0: 0a 20 20 69 6e 74 20 6e 61 74 69 76 65 43 6b 73  .  int nativeCks
66b0: 75 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  um;             
66c0: 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 6e     /* True for n
66d0: 61 74 69 76 65 20 62 79 74 65 2d 6f 72 64 65 72  ative byte-order
66e0: 20 63 68 65 63 6b 73 75 6d 73 20 2a 2f 0a 20 20   checksums */.  
66f0: 75 33 32 20 2a 61 43 6b 73 75 6d 20 3d 20 70 57  u32 *aCksum = pW
6700: 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b  al->hdr.aFrameCk
6710: 73 75 6d 3b 0a 20 20 61 73 73 65 72 74 28 20 57  sum;.  assert( W
6720: 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
6730: 3d 3d 32 34 20 29 3b 0a 20 20 73 71 6c 69 74 65  ==24 );.  sqlite
6740: 33 50 75 74 34 62 79 74 65 28 26 61 46 72 61 6d  3Put4byte(&aFram
6750: 65 5b 30 5d 2c 20 69 50 61 67 65 29 3b 0a 20 20  e[0], iPage);.  
6760: 73 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28  sqlite3Put4byte(
6770: 26 61 46 72 61 6d 65 5b 34 5d 2c 20 6e 54 72 75  &aFrame[4], nTru
6780: 6e 63 61 74 65 29 3b 0a 20 20 6d 65 6d 63 70 79  ncate);.  memcpy
6790: 28 26 61 46 72 61 6d 65 5b 38 5d 2c 20 70 57 61  (&aFrame[8], pWa
67a0: 6c 2d 3e 68 64 72 2e 61 53 61 6c 74 2c 20 38 29  l->hdr.aSalt, 8)
67b0: 3b 0a 0a 20 20 6e 61 74 69 76 65 43 6b 73 75 6d  ;..  nativeCksum
67c0: 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72 2e 62 69   = (pWal->hdr.bi
67d0: 67 45 6e 64 43 6b 73 75 6d 3d 3d 53 51 4c 49 54  gEndCksum==SQLIT
67e0: 45 5f 42 49 47 45 4e 44 49 41 4e 29 3b 0a 20 20  E_BIGENDIAN);.  
67f0: 77 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73  walChecksumBytes
6800: 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 61 46  (nativeCksum, aF
6810: 72 61 6d 65 2c 20 38 2c 20 61 43 6b 73 75 6d 2c  rame, 8, aCksum,
6820: 20 61 43 6b 73 75 6d 29 3b 0a 20 20 77 61 6c 43   aCksum);.  walC
6830: 68 65 63 6b 73 75 6d 42 79 74 65 73 28 6e 61 74  hecksumBytes(nat
6840: 69 76 65 43 6b 73 75 6d 2c 20 61 44 61 74 61 2c  iveCksum, aData,
6850: 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 2c 20 61   pWal->szPage, a
6860: 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a  Cksum, aCksum);.
6870: 0a 20 20 73 71 6c 69 74 65 33 50 75 74 34 62 79  .  sqlite3Put4by
6880: 74 65 28 26 61 46 72 61 6d 65 5b 31 36 5d 2c 20  te(&aFrame[16], 
6890: 61 43 6b 73 75 6d 5b 30 5d 29 3b 0a 20 20 73 71  aCksum[0]);.  sq
68a0: 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61  lite3Put4byte(&a
68b0: 46 72 61 6d 65 5b 32 30 5d 2c 20 61 43 6b 73 75  Frame[20], aCksu
68c0: 6d 5b 31 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  m[1]);.}../*.** 
68d0: 43 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20  Check to see if 
68e0: 74 68 65 20 66 72 61 6d 65 20 77 69 74 68 20 68  the frame with h
68f0: 65 61 64 65 72 20 69 6e 20 61 46 72 61 6d 65 5b  eader in aFrame[
6900: 5d 20 61 6e 64 20 63 6f 6e 74 65 6e 74 0a 2a 2a  ] and content.**
6910: 20 69 6e 20 61 44 61 74 61 5b 5d 20 69 73 20 76   in aData[] is v
6920: 61 6c 69 64 2e 20 20 49 66 20 69 74 20 69 73 20  alid.  If it is 
6930: 61 20 76 61 6c 69 64 20 66 72 61 6d 65 2c 20 66  a valid frame, f
6940: 69 6c 6c 20 2a 70 69 50 61 67 65 20 61 6e 64 0a  ill *piPage and.
6950: 2a 2a 20 2a 70 6e 54 72 75 6e 63 61 74 65 20 61  ** *pnTruncate a
6960: 6e 64 20 72 65 74 75 72 6e 20 74 72 75 65 2e 20  nd return true. 
6970: 20 52 65 74 75 72 6e 20 69 66 20 74 68 65 20 66   Return if the f
6980: 72 61 6d 65 20 69 73 20 6e 6f 74 20 76 61 6c 69  rame is not vali
6990: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
69a0: 20 77 61 6c 44 65 63 6f 64 65 46 72 61 6d 65 28   walDecodeFrame(
69b0: 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20  .  Wal *pWal,   
69c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69d0: 20 20 20 2f 2a 20 54 68 65 20 77 72 69 74 65 2d     /* The write-
69e0: 61 68 65 61 64 20 6c 6f 67 20 2a 2f 0a 20 20 75  ahead log */.  u
69f0: 33 32 20 2a 70 69 50 61 67 65 2c 20 20 20 20 20  32 *piPage,     
6a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6a10: 2a 20 4f 55 54 3a 20 44 61 74 61 62 61 73 65 20  * OUT: Database 
6a20: 70 61 67 65 20 6e 75 6d 62 65 72 20 66 6f 72 20  page number for 
6a30: 66 72 61 6d 65 20 2a 2f 0a 20 20 75 33 32 20 2a  frame */.  u32 *
6a40: 70 6e 54 72 75 6e 63 61 74 65 2c 20 20 20 20 20  pnTruncate,     
6a50: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
6a60: 54 3a 20 4e 65 77 20 64 62 20 73 69 7a 65 20 28  T: New db size (
6a70: 6f 72 20 30 20 69 66 20 6e 6f 74 20 63 6f 6d 6d  or 0 if not comm
6a80: 69 74 29 20 2a 2f 0a 20 20 75 38 20 2a 61 44 61  it) */.  u8 *aDa
6a90: 74 61 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ta,             
6aa0: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e           /* Poin
6ab0: 74 65 72 20 74 6f 20 70 61 67 65 20 64 61 74 61  ter to page data
6ac0: 20 28 66 6f 72 20 63 68 65 63 6b 73 75 6d 29 20   (for checksum) 
6ad0: 2a 2f 0a 20 20 75 38 20 2a 61 46 72 61 6d 65 20  */.  u8 *aFrame 
6ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6af0: 20 20 20 20 20 2f 2a 20 46 72 61 6d 65 20 64 61       /* Frame da
6b00: 74 61 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e  ta */.){.  int n
6b10: 61 74 69 76 65 43 6b 73 75 6d 3b 20 20 20 20 20  ativeCksum;     
6b20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
6b30: 75 65 20 66 6f 72 20 6e 61 74 69 76 65 20 62 79  ue for native by
6b40: 74 65 2d 6f 72 64 65 72 20 63 68 65 63 6b 73 75  te-order checksu
6b50: 6d 73 20 2a 2f 0a 20 20 75 33 32 20 2a 61 43 6b  ms */.  u32 *aCk
6b60: 73 75 6d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  sum = pWal->hdr.
6b70: 61 46 72 61 6d 65 43 6b 73 75 6d 3b 0a 20 20 75  aFrameCksum;.  u
6b80: 33 32 20 70 67 6e 6f 3b 20 20 20 20 20 20 20 20  32 pgno;        
6b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6ba0: 2a 20 50 61 67 65 20 6e 75 6d 62 65 72 20 6f 66  * Page number of
6bb0: 20 74 68 65 20 66 72 61 6d 65 20 2a 2f 0a 20 20   the frame */.  
6bc0: 61 73 73 65 72 74 28 20 57 41 4c 5f 46 52 41 4d  assert( WAL_FRAM
6bd0: 45 5f 48 44 52 53 49 5a 45 3d 3d 32 34 20 29 3b  E_HDRSIZE==24 );
6be0: 0a 0a 20 20 2f 2a 20 41 20 66 72 61 6d 65 20 69  ..  /* A frame i
6bf0: 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20 69 66 20  s only valid if 
6c00: 74 68 65 20 73 61 6c 74 20 76 61 6c 75 65 73 20  the salt values 
6c10: 69 6e 20 74 68 65 20 66 72 61 6d 65 2d 68 65 61  in the frame-hea
6c20: 64 65 72 0a 20 20 2a 2a 20 6d 61 74 63 68 20 74  der.  ** match t
6c30: 68 65 20 73 61 6c 74 20 76 61 6c 75 65 73 20 69  he salt values i
6c40: 6e 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  n the wal-header
6c50: 2e 20 0a 20 20 2a 2f 0a 20 20 69 66 28 20 6d 65  . .  */.  if( me
6c60: 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64 72 2e  mcmp(&pWal->hdr.
6c70: 61 53 61 6c 74 2c 20 26 61 46 72 61 6d 65 5b 38  aSalt, &aFrame[8
6c80: 5d 2c 20 38 29 21 3d 30 20 29 7b 0a 20 20 20 20  ], 8)!=0 ){.    
6c90: 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 0a 20  return 0;.  }.. 
6ca0: 20 2f 2a 20 41 20 66 72 61 6d 65 20 69 73 20 6f   /* A frame is o
6cb0: 6e 6c 79 20 76 61 6c 69 64 20 69 66 20 74 68 65  nly valid if the
6cc0: 20 70 61 67 65 20 6e 75 6d 62 65 72 20 69 73 20   page number is 
6cd0: 63 72 65 61 74 65 72 20 74 68 61 6e 20 7a 65 72  creater than zer
6ce0: 6f 2e 0a 20 20 2a 2f 0a 20 20 70 67 6e 6f 20 3d  o..  */.  pgno =
6cf0: 20 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65   sqlite3Get4byte
6d00: 28 26 61 46 72 61 6d 65 5b 30 5d 29 3b 0a 20 20  (&aFrame[0]);.  
6d10: 69 66 28 20 70 67 6e 6f 3d 3d 30 20 29 7b 0a 20  if( pgno==0 ){. 
6d20: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d     return 0;.  }
6d30: 0a 0a 20 20 2f 2a 20 41 20 66 72 61 6d 65 20 69  ..  /* A frame i
6d40: 73 20 6f 6e 6c 79 20 76 61 6c 69 64 20 69 66 20  s only valid if 
6d50: 61 20 63 68 65 63 6b 73 75 6d 20 6f 66 20 74 68  a checksum of th
6d60: 65 20 66 69 72 73 74 20 31 36 20 62 79 74 65 73  e first 16 bytes
6d70: 0a 20 20 2a 2a 20 6f 66 20 74 68 65 20 66 72 61  .  ** of the fra
6d80: 6d 65 2d 68 65 61 64 65 72 2c 20 61 6e 64 20 74  me-header, and t
6d90: 68 65 20 66 72 61 6d 65 2d 64 61 74 61 20 6d 61  he frame-data ma
6da0: 74 63 68 65 73 0a 20 20 2a 2a 20 74 68 65 20 63  tches.  ** the c
6db0: 68 65 63 6b 73 75 6d 20 69 6e 20 74 68 65 20 6c  hecksum in the l
6dc0: 61 73 74 20 38 20 62 79 74 65 73 20 6f 66 20 74  ast 8 bytes of t
6dd0: 68 65 20 66 72 61 6d 65 2d 68 65 61 64 65 72 2e  he frame-header.
6de0: 0a 20 20 2a 2f 0a 20 20 6e 61 74 69 76 65 43 6b  .  */.  nativeCk
6df0: 73 75 6d 20 3d 20 28 70 57 61 6c 2d 3e 68 64 72  sum = (pWal->hdr
6e00: 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d 3d 53 51  .bigEndCksum==SQ
6e10: 4c 49 54 45 5f 42 49 47 45 4e 44 49 41 4e 29 3b  LITE_BIGENDIAN);
6e20: 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79  .  walChecksumBy
6e30: 74 65 73 28 6e 61 74 69 76 65 43 6b 73 75 6d 2c  tes(nativeCksum,
6e40: 20 61 46 72 61 6d 65 2c 20 38 2c 20 61 43 6b 73   aFrame, 8, aCks
6e50: 75 6d 2c 20 61 43 6b 73 75 6d 29 3b 0a 20 20 77  um, aCksum);.  w
6e60: 61 6c 43 68 65 63 6b 73 75 6d 42 79 74 65 73 28  alChecksumBytes(
6e70: 6e 61 74 69 76 65 43 6b 73 75 6d 2c 20 61 44 61  nativeCksum, aDa
6e80: 74 61 2c 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65  ta, pWal->szPage
6e90: 2c 20 61 43 6b 73 75 6d 2c 20 61 43 6b 73 75 6d  , aCksum, aCksum
6ea0: 29 3b 0a 20 20 69 66 28 20 61 43 6b 73 75 6d 5b  );.  if( aCksum[
6eb0: 30 5d 21 3d 73 71 6c 69 74 65 33 47 65 74 34 62  0]!=sqlite3Get4b
6ec0: 79 74 65 28 26 61 46 72 61 6d 65 5b 31 36 5d 29  yte(&aFrame[16])
6ed0: 20 0a 20 20 20 7c 7c 20 61 43 6b 73 75 6d 5b 31   .   || aCksum[1
6ee0: 5d 21 3d 73 71 6c 69 74 65 33 47 65 74 34 62 79  ]!=sqlite3Get4by
6ef0: 74 65 28 26 61 46 72 61 6d 65 5b 32 30 5d 29 20  te(&aFrame[20]) 
6f00: 0a 20 20 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65  .  ){.    /* Che
6f10: 63 6b 73 75 6d 20 66 61 69 6c 65 64 2e 20 2a 2f  cksum failed. */
6f20: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
6f30: 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 77 65 20 72   }..  /* If we r
6f40: 65 61 63 68 20 74 68 69 73 20 70 6f 69 6e 74 2c  each this point,
6f50: 20 74 68 65 20 66 72 61 6d 65 20 69 73 20 76 61   the frame is va
6f60: 6c 69 64 2e 20 20 52 65 74 75 72 6e 20 74 68 65  lid.  Return the
6f70: 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 20 20 2a   page number.  *
6f80: 2a 20 61 6e 64 20 74 68 65 20 6e 65 77 20 64 61  * and the new da
6f90: 74 61 62 61 73 65 20 73 69 7a 65 2e 0a 20 20 2a  tabase size..  *
6fa0: 2f 0a 20 20 2a 70 69 50 61 67 65 20 3d 20 70 67  /.  *piPage = pg
6fb0: 6e 6f 3b 0a 20 20 2a 70 6e 54 72 75 6e 63 61 74  no;.  *pnTruncat
6fc0: 65 20 3d 20 73 71 6c 69 74 65 33 47 65 74 34 62  e = sqlite3Get4b
6fd0: 79 74 65 28 26 61 46 72 61 6d 65 5b 34 5d 29 3b  yte(&aFrame[4]);
6fe0: 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a  .  return 1;.}..
6ff0: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51 4c  .#if defined(SQL
7000: 49 54 45 5f 54 45 53 54 29 20 26 26 20 64 65 66  ITE_TEST) && def
7010: 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42 55  ined(SQLITE_DEBU
7020: 47 29 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 73 20 6f  G)./*.** Names o
7030: 66 20 6c 6f 63 6b 73 2e 20 20 54 68 69 73 20 72  f locks.  This r
7040: 6f 75 74 69 6e 65 20 69 73 20 75 73 65 64 20 74  outine is used t
7050: 6f 20 70 72 6f 76 69 64 65 20 64 65 62 75 67 67  o provide debugg
7060: 69 6e 67 20 6f 75 74 70 75 74 20 61 6e 64 20 69  ing output and i
7070: 73 20 6e 6f 74 0a 2a 2a 20 61 20 70 61 72 74 20  s not.** a part 
7080: 6f 66 20 61 6e 20 6f 72 64 69 6e 61 72 79 20 62  of an ordinary b
7090: 75 69 6c 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  uild..*/.static 
70a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 77 61 6c 4c  const char *walL
70b0: 6f 63 6b 4e 61 6d 65 28 69 6e 74 20 6c 6f 63 6b  ockName(int lock
70c0: 49 64 78 29 7b 0a 20 20 69 66 28 20 6c 6f 63 6b  Idx){.  if( lock
70d0: 49 64 78 3d 3d 57 41 4c 5f 57 52 49 54 45 5f 4c  Idx==WAL_WRITE_L
70e0: 4f 43 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72  OCK ){.    retur
70f0: 6e 20 22 57 52 49 54 45 2d 4c 4f 43 4b 22 3b 0a  n "WRITE-LOCK";.
7100: 20 20 7d 65 6c 73 65 20 69 66 28 20 6c 6f 63 6b    }else if( lock
7110: 49 64 78 3d 3d 57 41 4c 5f 43 4b 50 54 5f 4c 4f  Idx==WAL_CKPT_LO
7120: 43 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  CK ){.    return
7130: 20 22 43 4b 50 54 2d 4c 4f 43 4b 22 3b 0a 20 20   "CKPT-LOCK";.  
7140: 7d 65 6c 73 65 20 69 66 28 20 6c 6f 63 6b 49 64  }else if( lockId
7150: 78 3d 3d 57 41 4c 5f 52 45 43 4f 56 45 52 5f 4c  x==WAL_RECOVER_L
7160: 4f 43 4b 20 29 7b 0a 20 20 20 20 72 65 74 75 72  OCK ){.    retur
7170: 6e 20 22 52 45 43 4f 56 45 52 2d 4c 4f 43 4b 22  n "RECOVER-LOCK"
7180: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73  ;.  }else{.    s
7190: 74 61 74 69 63 20 63 68 61 72 20 7a 4e 61 6d 65  tatic char zName
71a0: 5b 31 35 5d 3b 0a 20 20 20 20 73 71 6c 69 74 65  [15];.    sqlite
71b0: 33 5f 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f  3_snprintf(sizeo
71c0: 66 28 7a 4e 61 6d 65 29 2c 20 7a 4e 61 6d 65 2c  f(zName), zName,
71d0: 20 22 52 45 41 44 2d 4c 4f 43 4b 5b 25 64 5d 22   "READ-LOCK[%d]"
71e0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
71f0: 20 20 20 20 20 20 20 6c 6f 63 6b 49 64 78 2d 57         lockIdx-W
7200: 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29  AL_READ_LOCK(0))
7210: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 7a 4e 61  ;.    return zNa
7220: 6d 65 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66  me;.  }.}.#endif
7230: 20 2f 2a 64 65 66 69 6e 65 64 28 53 51 4c 49 54   /*defined(SQLIT
7240: 45 5f 54 45 53 54 29 20 7c 7c 20 64 65 66 69 6e  E_TEST) || defin
7250: 65 64 28 53 51 4c 49 54 45 5f 44 45 42 55 47 29  ed(SQLITE_DEBUG)
7260: 20 2a 2f 0a 20 20 20 20 0a 0a 2f 2a 0a 2a 2a 20   */.    ../*.** 
7270: 53 65 74 20 6f 72 20 72 65 6c 65 61 73 65 20 6c  Set or release l
7280: 6f 63 6b 73 20 6f 6e 20 74 68 65 20 57 41 4c 2e  ocks on the WAL.
7290: 20 20 4c 6f 63 6b 73 20 61 72 65 20 65 69 74 68    Locks are eith
72a0: 65 72 20 73 68 61 72 65 64 20 6f 72 20 65 78 63  er shared or exc
72b0: 6c 75 73 69 76 65 2e 0a 2a 2a 20 41 20 6c 6f 63  lusive..** A loc
72c0: 6b 20 63 61 6e 6e 6f 74 20 62 65 20 6d 6f 76 65  k cannot be move
72d0: 64 20 64 69 72 65 63 74 6c 79 20 62 65 74 77 65  d directly betwe
72e0: 65 6e 20 73 68 61 72 65 64 20 61 6e 64 20 65 78  en shared and ex
72f0: 63 6c 75 73 69 76 65 20 2d 20 69 74 20 6d 75 73  clusive - it mus
7300: 74 20 67 6f 0a 2a 2a 20 74 68 72 6f 75 67 68 20  t go.** through 
7310: 74 68 65 20 75 6e 6c 6f 63 6b 65 64 20 73 74 61  the unlocked sta
7320: 74 65 20 66 69 72 73 74 2e 0a 2a 2a 0a 2a 2a 20  te first..**.** 
7330: 49 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d  In locking_mode=
7340: 45 58 43 4c 55 53 49 56 45 2c 20 61 6c 6c 20 6f  EXCLUSIVE, all o
7350: 66 20 74 68 65 73 65 20 72 6f 75 74 69 6e 65 73  f these routines
7360: 20 62 65 63 6f 6d 65 20 6e 6f 2d 6f 70 73 2e 0a   become no-ops..
7370: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  */.static int wa
7380: 6c 4c 6f 63 6b 53 68 61 72 65 64 28 57 61 6c 20  lLockShared(Wal 
7390: 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49  *pWal, int lockI
73a0: 64 78 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  dx){.  int rc;. 
73b0: 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63 6c 75   if( pWal->exclu
73c0: 73 69 76 65 4d 6f 64 65 20 29 20 72 65 74 75 72  siveMode ) retur
73d0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72  n SQLITE_OK;.  r
73e0: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53 68 6d  c = sqlite3OsShm
73f0: 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64  Lock(pWal->pDbFd
7400: 2c 20 6c 6f 63 6b 49 64 78 2c 20 31 2c 0a 20 20  , lockIdx, 1,.  
7410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7420: 20 20 20 20 20 20 53 51 4c 49 54 45 5f 53 48 4d        SQLITE_SHM
7430: 5f 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53  _LOCK | SQLITE_S
7440: 48 4d 5f 53 48 41 52 45 44 29 3b 0a 20 20 57 41  HM_SHARED);.  WA
7450: 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20  LTRACE(("WAL%p: 
7460: 61 63 71 75 69 72 65 20 53 48 41 52 45 44 2d 25  acquire SHARED-%
7470: 73 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 0a 20  s %s\n", pWal,. 
7480: 20 20 20 20 20 20 20 20 20 20 20 77 61 6c 4c 6f             walLo
7490: 63 6b 4e 61 6d 65 28 6c 6f 63 6b 49 64 78 29 2c  ckName(lockIdx),
74a0: 20 72 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a   rc ? "failed" :
74b0: 20 22 6f 6b 22 29 29 3b 0a 20 20 56 56 41 5f 4f   "ok"));.  VVA_O
74c0: 4e 4c 59 28 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45  NLY( pWal->lockE
74d0: 72 72 6f 72 20 3d 20 28 72 63 21 3d 53 51 4c 49  rror = (rc!=SQLI
74e0: 54 45 5f 4f 4b 20 26 26 20 72 63 21 3d 53 51 4c  TE_OK && rc!=SQL
74f0: 49 54 45 5f 42 55 53 59 29 3b 20 29 0a 20 20 72  ITE_BUSY); ).  r
7500: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74  eturn rc;.}.stat
7510: 69 63 20 76 6f 69 64 20 77 61 6c 55 6e 6c 6f 63  ic void walUnloc
7520: 6b 53 68 61 72 65 64 28 57 61 6c 20 2a 70 57 61  kShared(Wal *pWa
7530: 6c 2c 20 69 6e 74 20 6c 6f 63 6b 49 64 78 29 7b  l, int lockIdx){
7540: 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e 65 78 63  .  if( pWal->exc
7550: 6c 75 73 69 76 65 4d 6f 64 65 20 29 20 72 65 74  lusiveMode ) ret
7560: 75 72 6e 3b 0a 20 20 28 76 6f 69 64 29 73 71 6c  urn;.  (void)sql
7570: 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57  ite3OsShmLock(pW
7580: 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49  al->pDbFd, lockI
7590: 64 78 2c 20 31 2c 0a 20 20 20 20 20 20 20 20 20  dx, 1,.         
75a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
75b0: 53 51 4c 49 54 45 5f 53 48 4d 5f 55 4e 4c 4f 43  SQLITE_SHM_UNLOC
75c0: 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48 4d 5f 53  K | SQLITE_SHM_S
75d0: 48 41 52 45 44 29 3b 0a 20 20 57 41 4c 54 52 41  HARED);.  WALTRA
75e0: 43 45 28 28 22 57 41 4c 25 70 3a 20 72 65 6c 65  CE(("WAL%p: rele
75f0: 61 73 65 20 53 48 41 52 45 44 2d 25 73 5c 6e 22  ase SHARED-%s\n"
7600: 2c 20 70 57 61 6c 2c 20 77 61 6c 4c 6f 63 6b 4e  , pWal, walLockN
7610: 61 6d 65 28 6c 6f 63 6b 49 64 78 29 29 29 3b 0a  ame(lockIdx)));.
7620: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c  }.static int wal
7630: 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 57 61  LockExclusive(Wa
7640: 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 6c 6f 63  l *pWal, int loc
7650: 6b 49 64 78 2c 20 69 6e 74 20 6e 29 7b 0a 20 20  kIdx, int n){.  
7660: 69 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 70 57  int rc;.  if( pW
7670: 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64  al->exclusiveMod
7680: 65 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  e ) return SQLIT
7690: 45 5f 4f 4b 3b 0a 20 20 72 63 20 3d 20 73 71 6c  E_OK;.  rc = sql
76a0: 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b 28 70 57  ite3OsShmLock(pW
76b0: 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f 63 6b 49  al->pDbFd, lockI
76c0: 64 78 2c 20 6e 2c 0a 20 20 20 20 20 20 20 20 20  dx, n,.         
76d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53                 S
76e0: 51 4c 49 54 45 5f 53 48 4d 5f 4c 4f 43 4b 20 7c  QLITE_SHM_LOCK |
76f0: 20 53 51 4c 49 54 45 5f 53 48 4d 5f 45 58 43 4c   SQLITE_SHM_EXCL
7700: 55 53 49 56 45 29 3b 0a 20 20 57 41 4c 54 52 41  USIVE);.  WALTRA
7710: 43 45 28 28 22 57 41 4c 25 70 3a 20 61 63 71 75  CE(("WAL%p: acqu
7720: 69 72 65 20 45 58 43 4c 55 53 49 56 45 2d 25 73  ire EXCLUSIVE-%s
7730: 20 63 6e 74 3d 25 64 20 25 73 5c 6e 22 2c 20 70   cnt=%d %s\n", p
7740: 57 61 6c 2c 0a 20 20 20 20 20 20 20 20 20 20 20  Wal,.           
7750: 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65 28 6c 6f 63   walLockName(loc
7760: 6b 49 64 78 29 2c 20 6e 2c 20 72 63 20 3f 20 22  kIdx), n, rc ? "
7770: 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b 22 29 29  failed" : "ok"))
7780: 3b 0a 20 20 56 56 41 5f 4f 4e 4c 59 28 20 70 57  ;.  VVA_ONLY( pW
7790: 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 3d 20  al->lockError = 
77a0: 28 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26  (rc!=SQLITE_OK &
77b0: 26 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53  & rc!=SQLITE_BUS
77c0: 59 29 3b 20 29 0a 20 20 72 65 74 75 72 6e 20 72  Y); ).  return r
77d0: 63 3b 0a 7d 0a 73 74 61 74 69 63 20 76 6f 69 64  c;.}.static void
77e0: 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73   walUnlockExclus
77f0: 69 76 65 28 57 61 6c 20 2a 70 57 61 6c 2c 20 69  ive(Wal *pWal, i
7800: 6e 74 20 6c 6f 63 6b 49 64 78 2c 20 69 6e 74 20  nt lockIdx, int 
7810: 6e 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  n){.  if( pWal->
7820: 65 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 29 20  exclusiveMode ) 
7830: 72 65 74 75 72 6e 3b 0a 20 20 28 76 6f 69 64 29  return;.  (void)
7840: 73 71 6c 69 74 65 33 4f 73 53 68 6d 4c 6f 63 6b  sqlite3OsShmLock
7850: 28 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 6c 6f  (pWal->pDbFd, lo
7860: 63 6b 49 64 78 2c 20 6e 2c 0a 20 20 20 20 20 20  ckIdx, n,.      
7870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7880: 20 20 20 53 51 4c 49 54 45 5f 53 48 4d 5f 55 4e     SQLITE_SHM_UN
7890: 4c 4f 43 4b 20 7c 20 53 51 4c 49 54 45 5f 53 48  LOCK | SQLITE_SH
78a0: 4d 5f 45 58 43 4c 55 53 49 56 45 29 3b 0a 20 20  M_EXCLUSIVE);.  
78b0: 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70  WALTRACE(("WAL%p
78c0: 3a 20 72 65 6c 65 61 73 65 20 45 58 43 4c 55 53  : release EXCLUS
78d0: 49 56 45 2d 25 73 20 63 6e 74 3d 25 64 5c 6e 22  IVE-%s cnt=%d\n"
78e0: 2c 20 70 57 61 6c 2c 0a 20 20 20 20 20 20 20 20  , pWal,.        
78f0: 20 20 20 20 20 77 61 6c 4c 6f 63 6b 4e 61 6d 65       walLockName
7900: 28 6c 6f 63 6b 49 64 78 29 2c 20 6e 29 29 3b 0a  (lockIdx), n));.
7910: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65  }../*.** Compute
7920: 20 61 20 68 61 73 68 20 6f 6e 20 61 20 70 61 67   a hash on a pag
7930: 65 20 6e 75 6d 62 65 72 2e 20 20 54 68 65 20 72  e number.  The r
7940: 65 73 75 6c 74 69 6e 67 20 68 61 73 68 20 76 61  esulting hash va
7950: 6c 75 65 20 6d 75 73 74 20 6c 61 6e 64 0a 2a 2a  lue must land.**
7960: 20 62 65 74 77 65 65 6e 20 30 20 61 6e 64 20 28   between 0 and (
7970: 48 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d  HASHTABLE_NSLOT-
7980: 31 29 2e 20 20 54 68 65 20 77 61 6c 48 61 73 68  1).  The walHash
7990: 4e 65 78 74 28 29 20 66 75 6e 63 74 69 6f 6e 20  Next() function 
79a0: 61 64 76 61 6e 63 65 73 0a 2a 2a 20 74 68 65 20  advances.** the 
79b0: 68 61 73 68 20 74 6f 20 74 68 65 20 6e 65 78 74  hash to the next
79c0: 20 76 61 6c 75 65 20 69 6e 20 74 68 65 20 65 76   value in the ev
79d0: 65 6e 74 20 6f 66 20 61 20 63 6f 6c 6c 69 73 69  ent of a collisi
79e0: 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  on..*/.static in
79f0: 74 20 77 61 6c 48 61 73 68 28 75 33 32 20 69 50  t walHash(u32 iP
7a00: 61 67 65 29 7b 0a 20 20 61 73 73 65 72 74 28 20  age){.  assert( 
7a10: 69 50 61 67 65 3e 30 20 29 3b 0a 20 20 61 73 73  iPage>0 );.  ass
7a20: 65 72 74 28 20 28 48 41 53 48 54 41 42 4c 45 5f  ert( (HASHTABLE_
7a30: 4e 53 4c 4f 54 20 26 20 28 48 41 53 48 54 41 42  NSLOT & (HASHTAB
7a40: 4c 45 5f 4e 53 4c 4f 54 2d 31 29 29 3d 3d 30 20  LE_NSLOT-1))==0 
7a50: 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 69 50 61  );.  return (iPa
7a60: 67 65 2a 48 41 53 48 54 41 42 4c 45 5f 48 41 53  ge*HASHTABLE_HAS
7a70: 48 5f 31 29 20 26 20 28 48 41 53 48 54 41 42 4c  H_1) & (HASHTABL
7a80: 45 5f 4e 53 4c 4f 54 2d 31 29 3b 0a 7d 0a 73 74  E_NSLOT-1);.}.st
7a90: 61 74 69 63 20 69 6e 74 20 77 61 6c 4e 65 78 74  atic int walNext
7aa0: 48 61 73 68 28 69 6e 74 20 69 50 72 69 6f 72 48  Hash(int iPriorH
7ab0: 61 73 68 29 7b 0a 20 20 72 65 74 75 72 6e 20 28  ash){.  return (
7ac0: 69 50 72 69 6f 72 48 61 73 68 2b 31 29 26 28 48  iPriorHash+1)&(H
7ad0: 41 53 48 54 41 42 4c 45 5f 4e 53 4c 4f 54 2d 31  ASHTABLE_NSLOT-1
7ae0: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74  );.}../* .** Ret
7af0: 75 72 6e 20 70 6f 69 6e 74 65 72 73 20 74 6f 20  urn pointers to 
7b00: 74 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 61  the hash table a
7b10: 6e 64 20 70 61 67 65 20 6e 75 6d 62 65 72 20 61  nd page number a
7b20: 72 72 61 79 20 73 74 6f 72 65 64 20 6f 6e 0a 2a  rray stored on.*
7b30: 2a 20 70 61 67 65 20 69 48 61 73 68 20 6f 66 20  * page iHash of 
7b40: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 2e 20 54  the wal-index. T
7b50: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73 20  he wal-index is 
7b60: 62 72 6f 6b 65 6e 20 69 6e 74 6f 20 33 32 4b 42  broken into 32KB
7b70: 20 70 61 67 65 73 0a 2a 2a 20 6e 75 6d 62 65 72   pages.** number
7b80: 65 64 20 73 74 61 72 74 69 6e 67 20 66 72 6f 6d  ed starting from
7b90: 20 30 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20 6f 75   0..**.** Set ou
7ba0: 74 70 75 74 20 76 61 72 69 61 62 6c 65 20 2a 70  tput variable *p
7bb0: 61 48 61 73 68 20 74 6f 20 70 6f 69 6e 74 20 74  aHash to point t
7bc0: 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74  o the start of t
7bd0: 68 65 20 68 61 73 68 20 74 61 62 6c 65 0a 2a 2a  he hash table.**
7be0: 20 69 6e 20 74 68 65 20 77 61 6c 2d 69 6e 64 65   in the wal-inde
7bf0: 78 20 66 69 6c 65 2e 20 53 65 74 20 2a 70 69 5a  x file. Set *piZ
7c00: 65 72 6f 20 74 6f 20 6f 6e 65 20 6c 65 73 73 20  ero to one less 
7c10: 74 68 61 6e 20 74 68 65 20 66 72 61 6d 65 20 0a  than the frame .
7c20: 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 74 68 65  ** number of the
7c30: 20 66 69 72 73 74 20 66 72 61 6d 65 20 69 6e 64   first frame ind
7c40: 65 78 65 64 20 62 79 20 74 68 69 73 20 68 61 73  exed by this has
7c50: 68 20 74 61 62 6c 65 2e 20 49 66 20 61 0a 2a 2a  h table. If a.**
7c60: 20 73 6c 6f 74 20 69 6e 20 74 68 65 20 68 61 73   slot in the has
7c70: 68 20 74 61 62 6c 65 20 69 73 20 73 65 74 20 74  h table is set t
7c80: 6f 20 4e 2c 20 69 74 20 72 65 66 65 72 73 20 74  o N, it refers t
7c90: 6f 20 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 0a  o frame number .
7ca0: 2a 2a 20 28 2a 70 69 5a 65 72 6f 2b 4e 29 20 69  ** (*piZero+N) i
7cb0: 6e 20 74 68 65 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a  n the log..**.**
7cc0: 20 46 69 6e 61 6c 6c 79 2c 20 73 65 74 20 2a 70   Finally, set *p
7cd0: 61 50 67 6e 6f 20 73 6f 20 74 68 61 74 20 2a 70  aPgno so that *p
7ce0: 61 50 67 6e 6f 5b 31 5d 20 69 73 20 74 68 65 20  aPgno[1] is the 
7cf0: 70 61 67 65 20 6e 75 6d 62 65 72 20 6f 66 20 74  page number of t
7d00: 68 65 0a 2a 2a 20 66 69 72 73 74 20 66 72 61 6d  he.** first fram
7d10: 65 20 69 6e 64 65 78 65 64 20 62 79 20 74 68 65  e indexed by the
7d20: 20 68 61 73 68 20 74 61 62 6c 65 2c 20 66 72 61   hash table, fra
7d30: 6d 65 20 28 2a 70 69 5a 65 72 6f 2b 31 29 2e 0a  me (*piZero+1)..
7d40: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  */.static int wa
7d50: 6c 48 61 73 68 47 65 74 28 0a 20 20 57 61 6c 20  lHashGet(.  Wal 
7d60: 2a 70 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20  *pWal,          
7d70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
7d80: 41 4c 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69  AL handle */.  i
7d90: 6e 74 20 69 48 61 73 68 2c 20 20 20 20 20 20 20  nt iHash,       
7da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7db0: 2a 20 46 69 6e 64 20 74 68 65 20 69 48 61 73 68  * Find the iHash
7dc0: 27 74 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 76  'th table */.  v
7dd0: 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20  olatile ht_slot 
7de0: 2a 2a 70 61 48 61 73 68 2c 20 20 20 20 20 20 2f  **paHash,      /
7df0: 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74  * OUT: Pointer t
7e00: 6f 20 68 61 73 68 20 69 6e 64 65 78 20 2a 2f 0a  o hash index */.
7e10: 20 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a    volatile u32 *
7e20: 2a 70 61 50 67 6e 6f 2c 20 20 20 20 20 20 20 20  *paPgno,        
7e30: 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65    /* OUT: Pointe
7e40: 72 20 74 6f 20 70 61 67 65 20 6e 75 6d 62 65 72  r to page number
7e50: 20 61 72 72 61 79 20 2a 2f 0a 20 20 75 33 32 20   array */.  u32 
7e60: 2a 70 69 5a 65 72 6f 20 20 20 20 20 20 20 20 20  *piZero         
7e70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
7e80: 55 54 3a 20 46 72 61 6d 65 20 61 73 73 6f 63 69  UT: Frame associ
7e90: 61 74 65 64 20 77 69 74 68 20 2a 70 61 50 67 6e  ated with *paPgn
7ea0: 6f 5b 30 5d 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  o[0] */.){.  int
7eb0: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
7ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7ed0: 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  Return code */. 
7ee0: 20 76 6f 6c 61 74 69 6c 65 20 75 33 32 20 2a 61   volatile u32 *a
7ef0: 50 67 6e 6f 3b 0a 0a 20 20 72 63 20 3d 20 77 61  Pgno;..  rc = wa
7f00: 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c  lIndexPage(pWal,
7f10: 20 69 48 61 73 68 2c 20 26 61 50 67 6e 6f 29 3b   iHash, &aPgno);
7f20: 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d 53  .  assert( rc==S
7f30: 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 69 48 61 73  QLITE_OK || iHas
7f40: 68 3e 30 20 29 3b 0a 0a 20 20 69 66 28 20 72 63  h>0 );..  if( rc
7f50: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
7f60: 20 20 20 75 33 32 20 69 5a 65 72 6f 3b 0a 20 20     u32 iZero;.  
7f70: 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f 73 6c    volatile ht_sl
7f80: 6f 74 20 2a 61 48 61 73 68 3b 0a 0a 20 20 20 20  ot *aHash;..    
7f90: 61 48 61 73 68 20 3d 20 28 76 6f 6c 61 74 69 6c  aHash = (volatil
7fa0: 65 20 68 74 5f 73 6c 6f 74 20 2a 29 26 61 50 67  e ht_slot *)&aPg
7fb0: 6e 6f 5b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41  no[HASHTABLE_NPA
7fc0: 47 45 5d 3b 0a 20 20 20 20 69 66 28 20 69 48 61  GE];.    if( iHa
7fd0: 73 68 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 61  sh==0 ){.      a
7fe0: 50 67 6e 6f 20 3d 20 26 61 50 67 6e 6f 5b 57 41  Pgno = &aPgno[WA
7ff0: 4c 49 4e 44 45 58 5f 48 44 52 5f 53 49 5a 45 2f  LINDEX_HDR_SIZE/
8000: 73 69 7a 65 6f 66 28 75 33 32 29 5d 3b 0a 20 20  sizeof(u32)];.  
8010: 20 20 20 20 69 5a 65 72 6f 20 3d 20 30 3b 0a 20      iZero = 0;. 
8020: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
8030: 69 5a 65 72 6f 20 3d 20 48 41 53 48 54 41 42 4c  iZero = HASHTABL
8040: 45 5f 4e 50 41 47 45 5f 4f 4e 45 20 2b 20 28 69  E_NPAGE_ONE + (i
8050: 48 61 73 68 2d 31 29 2a 48 41 53 48 54 41 42 4c  Hash-1)*HASHTABL
8060: 45 5f 4e 50 41 47 45 3b 0a 20 20 20 20 7d 0a 20  E_NPAGE;.    }. 
8070: 20 0a 20 20 20 20 2a 70 61 50 67 6e 6f 20 3d 20   .    *paPgno = 
8080: 26 61 50 67 6e 6f 5b 2d 31 5d 3b 0a 20 20 20 20  &aPgno[-1];.    
8090: 2a 70 61 48 61 73 68 20 3d 20 61 48 61 73 68 3b  *paHash = aHash;
80a0: 0a 20 20 20 20 2a 70 69 5a 65 72 6f 20 3d 20 69  .    *piZero = i
80b0: 5a 65 72 6f 3b 0a 20 20 7d 0a 20 20 72 65 74 75  Zero;.  }.  retu
80c0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
80d0: 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65  Return the numbe
80e0: 72 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  r of the wal-ind
80f0: 65 78 20 70 61 67 65 20 74 68 61 74 20 63 6f 6e  ex page that con
8100: 74 61 69 6e 73 20 74 68 65 20 68 61 73 68 2d 74  tains the hash-t
8110: 61 62 6c 65 0a 2a 2a 20 61 6e 64 20 70 61 67 65  able.** and page
8120: 2d 6e 75 6d 62 65 72 20 61 72 72 61 79 20 74 68  -number array th
8130: 61 74 20 63 6f 6e 74 61 69 6e 20 65 6e 74 72 69  at contain entri
8140: 65 73 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67  es corresponding
8150: 20 74 6f 20 57 41 4c 20 66 72 61 6d 65 0a 2a 2a   to WAL frame.**
8160: 20 69 46 72 61 6d 65 2e 20 54 68 65 20 77 61 6c   iFrame. The wal
8170: 2d 69 6e 64 65 78 20 69 73 20 62 72 6f 6b 65 6e  -index is broken
8180: 20 75 70 20 69 6e 74 6f 20 33 32 4b 42 20 70 61   up into 32KB pa
8190: 67 65 73 2e 20 57 61 6c 2d 69 6e 64 65 78 20 70  ges. Wal-index p
81a0: 61 67 65 73 20 0a 2a 2a 20 61 72 65 20 6e 75 6d  ages .** are num
81b0: 62 65 72 65 64 20 73 74 61 72 74 69 6e 67 20 66  bered starting f
81c0: 72 6f 6d 20 30 2e 0a 2a 2f 0a 73 74 61 74 69 63  rom 0..*/.static
81d0: 20 69 6e 74 20 77 61 6c 46 72 61 6d 65 50 61 67   int walFramePag
81e0: 65 28 75 33 32 20 69 46 72 61 6d 65 29 7b 0a 20  e(u32 iFrame){. 
81f0: 20 69 6e 74 20 69 48 61 73 68 20 3d 20 28 69 46   int iHash = (iF
8200: 72 61 6d 65 2b 48 41 53 48 54 41 42 4c 45 5f 4e  rame+HASHTABLE_N
8210: 50 41 47 45 2d 48 41 53 48 54 41 42 4c 45 5f 4e  PAGE-HASHTABLE_N
8220: 50 41 47 45 5f 4f 4e 45 2d 31 29 20 2f 20 48 41  PAGE_ONE-1) / HA
8230: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 3b 0a 20  SHTABLE_NPAGE;. 
8240: 20 61 73 73 65 72 74 28 20 28 69 48 61 73 68 3d   assert( (iHash=
8250: 3d 30 20 7c 7c 20 69 46 72 61 6d 65 3e 48 41 53  =0 || iFrame>HAS
8260: 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45  HTABLE_NPAGE_ONE
8270: 29 0a 20 20 20 20 20 20 20 26 26 20 28 69 48 61  ).       && (iHa
8280: 73 68 3e 3d 31 20 7c 7c 20 69 46 72 61 6d 65 3c  sh>=1 || iFrame<
8290: 3d 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45  =HASHTABLE_NPAGE
82a0: 5f 4f 4e 45 29 0a 20 20 20 20 20 20 20 26 26 20  _ONE).       && 
82b0: 28 69 48 61 73 68 3c 3d 31 20 7c 7c 20 69 46 72  (iHash<=1 || iFr
82c0: 61 6d 65 3e 28 48 41 53 48 54 41 42 4c 45 5f 4e  ame>(HASHTABLE_N
82d0: 50 41 47 45 5f 4f 4e 45 2b 48 41 53 48 54 41 42  PAGE_ONE+HASHTAB
82e0: 4c 45 5f 4e 50 41 47 45 29 29 0a 20 20 20 20 20  LE_NPAGE)).     
82f0: 20 20 26 26 20 28 69 48 61 73 68 3e 3d 32 20 7c    && (iHash>=2 |
8300: 7c 20 69 46 72 61 6d 65 3c 3d 48 41 53 48 54 41  | iFrame<=HASHTA
8310: 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e 45 2b 48 41  BLE_NPAGE_ONE+HA
8320: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 29 0a 20  SHTABLE_NPAGE). 
8330: 20 20 20 20 20 20 26 26 20 28 69 48 61 73 68 3c        && (iHash<
8340: 3d 32 20 7c 7c 20 69 46 72 61 6d 65 3e 28 48 41  =2 || iFrame>(HA
8350: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 5f 4f 4e  SHTABLE_NPAGE_ON
8360: 45 2b 32 2a 48 41 53 48 54 41 42 4c 45 5f 4e 50  E+2*HASHTABLE_NP
8370: 41 47 45 29 29 0a 20 20 29 3b 0a 20 20 72 65 74  AGE)).  );.  ret
8380: 75 72 6e 20 69 48 61 73 68 3b 0a 7d 0a 0a 2f 2a  urn iHash;.}../*
8390: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 70  .** Return the p
83a0: 61 67 65 20 6e 75 6d 62 65 72 20 61 73 73 6f 63  age number assoc
83b0: 69 61 74 65 64 20 77 69 74 68 20 66 72 61 6d 65  iated with frame
83c0: 20 69 46 72 61 6d 65 20 69 6e 20 74 68 69 73 20   iFrame in this 
83d0: 57 41 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75  WAL..*/.static u
83e0: 33 32 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28  32 walFramePgno(
83f0: 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32 20 69  Wal *pWal, u32 i
8400: 46 72 61 6d 65 29 7b 0a 20 20 69 6e 74 20 69 48  Frame){.  int iH
8410: 61 73 68 20 3d 20 77 61 6c 46 72 61 6d 65 50 61  ash = walFramePa
8420: 67 65 28 69 46 72 61 6d 65 29 3b 0a 20 20 69 66  ge(iFrame);.  if
8430: 28 20 69 48 61 73 68 3d 3d 30 20 29 7b 0a 20 20  ( iHash==0 ){.  
8440: 20 20 72 65 74 75 72 6e 20 70 57 61 6c 2d 3e 61    return pWal->a
8450: 70 57 69 44 61 74 61 5b 30 5d 5b 57 41 4c 49 4e  pWiData[0][WALIN
8460: 44 45 58 5f 48 44 52 5f 53 49 5a 45 2f 73 69 7a  DEX_HDR_SIZE/siz
8470: 65 6f 66 28 75 33 32 29 20 2b 20 69 46 72 61 6d  eof(u32) + iFram
8480: 65 20 2d 20 31 5d 3b 0a 20 20 7d 0a 20 20 72 65  e - 1];.  }.  re
8490: 74 75 72 6e 20 70 57 61 6c 2d 3e 61 70 57 69 44  turn pWal->apWiD
84a0: 61 74 61 5b 69 48 61 73 68 5d 5b 28 69 46 72 61  ata[iHash][(iFra
84b0: 6d 65 2d 31 2d 48 41 53 48 54 41 42 4c 45 5f 4e  me-1-HASHTABLE_N
84c0: 50 41 47 45 5f 4f 4e 45 29 25 48 41 53 48 54 41  PAGE_ONE)%HASHTA
84d0: 42 4c 45 5f 4e 50 41 47 45 5d 3b 0a 7d 0a 0a 2f  BLE_NPAGE];.}../
84e0: 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 65 6e 74 72  *.** Remove entr
84f0: 69 65 73 20 66 72 6f 6d 20 74 68 65 20 68 61 73  ies from the has
8500: 68 20 74 61 62 6c 65 20 74 68 61 74 20 70 6f 69  h table that poi
8510: 6e 74 20 74 6f 20 57 41 4c 20 73 6c 6f 74 73 20  nt to WAL slots 
8520: 67 72 65 61 74 65 72 0a 2a 2a 20 74 68 61 6e 20  greater.** than 
8530: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
8540: 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75  e..**.** This fu
8550: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
8560: 20 77 68 65 6e 65 76 65 72 20 70 57 61 6c 2d 3e   whenever pWal->
8570: 68 64 72 2e 6d 78 46 72 61 6d 65 20 69 73 20 64  hdr.mxFrame is d
8580: 65 63 72 65 61 73 65 64 20 64 75 65 0a 2a 2a 20  ecreased due.** 
8590: 74 6f 20 61 20 72 6f 6c 6c 62 61 63 6b 20 6f 72  to a rollback or
85a0: 20 73 61 76 65 70 6f 69 6e 74 2e 0a 2a 2a 0a 2a   savepoint..**.*
85b0: 2a 20 41 74 20 6d 6f 73 74 20 6f 6e 6c 79 20 74  * At most only t
85c0: 68 65 20 68 61 73 68 20 74 61 62 6c 65 20 63 6f  he hash table co
85d0: 6e 74 61 69 6e 69 6e 67 20 70 57 61 6c 2d 3e 68  ntaining pWal->h
85e0: 64 72 2e 6d 78 46 72 61 6d 65 20 6e 65 65 64 73  dr.mxFrame needs
85f0: 20 74 6f 20 62 65 0a 2a 2a 20 75 70 64 61 74 65   to be.** update
8600: 64 2e 20 20 41 6e 79 20 6c 61 74 65 72 20 68 61  d.  Any later ha
8610: 73 68 20 74 61 62 6c 65 73 20 77 69 6c 6c 20 62  sh tables will b
8620: 65 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20  e automatically 
8630: 63 6c 65 61 72 65 64 20 77 68 65 6e 0a 2a 2a 20  cleared when.** 
8640: 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d  pWal->hdr.mxFram
8650: 65 20 61 64 76 61 6e 63 65 73 20 74 6f 20 74 68  e advances to th
8660: 65 20 70 6f 69 6e 74 20 77 68 65 72 65 20 74 68  e point where th
8670: 6f 73 65 20 68 61 73 68 20 74 61 62 6c 65 73 20  ose hash tables 
8680: 61 72 65 0a 2a 2a 20 61 63 74 75 61 6c 6c 79 20  are.** actually 
8690: 6e 65 65 64 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  needed..*/.stati
86a0: 63 20 76 6f 69 64 20 77 61 6c 43 6c 65 61 6e 75  c void walCleanu
86b0: 70 48 61 73 68 28 57 61 6c 20 2a 70 57 61 6c 29  pHash(Wal *pWal)
86c0: 7b 0a 20 20 76 6f 6c 61 74 69 6c 65 20 68 74 5f  {.  volatile ht_
86d0: 73 6c 6f 74 20 2a 61 48 61 73 68 3b 20 20 20 20  slot *aHash;    
86e0: 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
86f0: 6f 20 68 61 73 68 20 74 61 62 6c 65 20 74 6f 20  o hash table to 
8700: 63 6c 65 61 72 20 2a 2f 0a 20 20 76 6f 6c 61 74  clear */.  volat
8710: 69 6c 65 20 75 33 32 20 2a 61 50 67 6e 6f 3b 20  ile u32 *aPgno; 
8720: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
8730: 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20  ge number array 
8740: 66 6f 72 20 68 61 73 68 20 74 61 62 6c 65 20 2a  for hash table *
8750: 2f 0a 20 20 75 33 32 20 69 5a 65 72 6f 3b 20 20  /.  u32 iZero;  
8760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8770: 20 20 20 20 2f 2a 20 66 72 61 6d 65 20 3d 3d 20      /* frame == 
8780: 28 61 48 61 73 68 5b 78 5d 2b 69 5a 65 72 6f 29  (aHash[x]+iZero)
8790: 20 2a 2f 0a 20 20 69 6e 74 20 69 4c 69 6d 69 74   */.  int iLimit
87a0: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
87b0: 20 20 20 20 20 20 2f 2a 20 5a 65 72 6f 20 76 61        /* Zero va
87c0: 6c 75 65 73 20 67 72 65 61 74 65 72 20 74 68 61  lues greater tha
87d0: 6e 20 74 68 69 73 20 2a 2f 0a 20 20 69 6e 74 20  n this */.  int 
87e0: 6e 42 79 74 65 3b 20 20 20 20 20 20 20 20 20 20  nByte;          
87f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
8800: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 74  umber of bytes t
8810: 6f 20 7a 65 72 6f 20 69 6e 20 61 50 67 6e 6f 5b  o zero in aPgno[
8820: 5d 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  ] */.  int i;   
8830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8840: 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
8850: 6f 20 69 74 65 72 61 74 65 20 74 68 72 6f 75 67  o iterate throug
8860: 68 20 61 48 61 73 68 5b 5d 20 2a 2f 0a 0a 20 20  h aHash[] */..  
8870: 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72  assert( pWal->wr
8880: 69 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 74 65 73  iteLock );.  tes
8890: 74 63 61 73 65 28 20 70 57 61 6c 2d 3e 68 64 72  tcase( pWal->hdr
88a0: 2e 6d 78 46 72 61 6d 65 3d 3d 48 41 53 48 54 41  .mxFrame==HASHTA
88b0: 42 4c 45 5f 4e 50 41 47 45 2d 31 20 29 3b 0a 20  BLE_NPAGE-1 );. 
88c0: 20 74 65 73 74 63 61 73 65 28 20 70 57 61 6c 2d   testcase( pWal-
88d0: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 48 41  >hdr.mxFrame==HA
88e0: 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 20 29 3b  SHTABLE_NPAGE );
88f0: 0a 20 20 74 65 73 74 63 61 73 65 28 20 70 57 61  .  testcase( pWa
8900: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d  l->hdr.mxFrame==
8910: 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47 45 2b  HASHTABLE_NPAGE+
8920: 31 20 29 3b 0a 0a 20 20 69 66 28 20 70 57 61 6c  1 );..  if( pWal
8930: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 30  ->hdr.mxFrame==0
8940: 20 29 20 72 65 74 75 72 6e 3b 0a 0a 20 20 2f 2a   ) return;..  /*
8950: 20 4f 62 74 61 69 6e 20 70 6f 69 6e 74 65 72 73   Obtain pointers
8960: 20 74 6f 20 74 68 65 20 68 61 73 68 2d 74 61 62   to the hash-tab
8970: 6c 65 20 61 6e 64 20 70 61 67 65 2d 6e 75 6d 62  le and page-numb
8980: 65 72 20 61 72 72 61 79 20 63 6f 6e 74 61 69 6e  er array contain
8990: 69 6e 67 20 0a 20 20 2a 2a 20 74 68 65 20 65 6e  ing .  ** the en
89a0: 74 72 79 20 74 68 61 74 20 63 6f 72 72 65 73 70  try that corresp
89b0: 6f 6e 64 73 20 74 6f 20 66 72 61 6d 65 20 70 57  onds to frame pW
89c0: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e  al->hdr.mxFrame.
89d0: 20 49 74 20 69 73 20 67 75 61 72 61 6e 74 65 65   It is guarantee
89e0: 64 0a 20 20 2a 2a 20 74 68 61 74 20 74 68 65 20  d.  ** that the 
89f0: 70 61 67 65 20 73 61 69 64 20 68 61 73 68 2d 74  page said hash-t
8a00: 61 62 6c 65 20 61 6e 64 20 61 72 72 61 79 20 72  able and array r
8a10: 65 73 69 64 65 20 6f 6e 20 69 73 20 61 6c 72 65  eside on is alre
8a20: 61 64 79 20 6d 61 70 70 65 64 2e 0a 20 20 2a 2f  ady mapped..  */
8a30: 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d  .  assert( pWal-
8a40: 3e 6e 57 69 44 61 74 61 3e 77 61 6c 46 72 61 6d  >nWiData>walFram
8a50: 65 50 61 67 65 28 70 57 61 6c 2d 3e 68 64 72 2e  ePage(pWal->hdr.
8a60: 6d 78 46 72 61 6d 65 29 20 29 3b 0a 20 20 61 73  mxFrame) );.  as
8a70: 73 65 72 74 28 20 70 57 61 6c 2d 3e 61 70 57 69  sert( pWal->apWi
8a80: 44 61 74 61 5b 77 61 6c 46 72 61 6d 65 50 61 67  Data[walFramePag
8a90: 65 28 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  e(pWal->hdr.mxFr
8aa0: 61 6d 65 29 5d 20 29 3b 0a 20 20 77 61 6c 48 61  ame)] );.  walHa
8ab0: 73 68 47 65 74 28 70 57 61 6c 2c 20 77 61 6c 46  shGet(pWal, walF
8ac0: 72 61 6d 65 50 61 67 65 28 70 57 61 6c 2d 3e 68  ramePage(pWal->h
8ad0: 64 72 2e 6d 78 46 72 61 6d 65 29 2c 20 26 61 48  dr.mxFrame), &aH
8ae0: 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20 26 69 5a  ash, &aPgno, &iZ
8af0: 65 72 6f 29 3b 0a 0a 20 20 2f 2a 20 5a 65 72 6f  ero);..  /* Zero
8b00: 20 61 6c 6c 20 68 61 73 68 2d 74 61 62 6c 65 20   all hash-table 
8b10: 65 6e 74 72 69 65 73 20 74 68 61 74 20 63 6f 72  entries that cor
8b20: 72 65 73 70 6f 6e 64 20 74 6f 20 66 72 61 6d 65  respond to frame
8b30: 20 6e 75 6d 62 65 72 73 20 67 72 65 61 74 65 72   numbers greater
8b40: 0a 20 20 2a 2a 20 74 68 61 6e 20 70 57 61 6c 2d  .  ** than pWal-
8b50: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2e 0a 20 20  >hdr.mxFrame..  
8b60: 2a 2f 0a 20 20 69 4c 69 6d 69 74 20 3d 20 70 57  */.  iLimit = pW
8b70: 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
8b80: 2d 20 69 5a 65 72 6f 3b 0a 20 20 61 73 73 65 72  - iZero;.  asser
8b90: 74 28 20 69 4c 69 6d 69 74 3e 30 20 29 3b 0a 20  t( iLimit>0 );. 
8ba0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 48 41 53 48   for(i=0; i<HASH
8bb0: 54 41 42 4c 45 5f 4e 53 4c 4f 54 3b 20 69 2b 2b  TABLE_NSLOT; i++
8bc0: 29 7b 0a 20 20 20 20 69 66 28 20 61 48 61 73 68  ){.    if( aHash
8bd0: 5b 69 5d 3e 69 4c 69 6d 69 74 20 29 7b 0a 20 20  [i]>iLimit ){.  
8be0: 20 20 20 20 61 48 61 73 68 5b 69 5d 20 3d 20 30      aHash[i] = 0
8bf0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20  ;.    }.  }.  . 
8c00: 20 2f 2a 20 5a 65 72 6f 20 74 68 65 20 65 6e 74   /* Zero the ent
8c10: 72 69 65 73 20 69 6e 20 74 68 65 20 61 50 67 6e  ries in the aPgn
8c20: 6f 20 61 72 72 61 79 20 74 68 61 74 20 63 6f 72  o array that cor
8c30: 72 65 73 70 6f 6e 64 20 74 6f 20 66 72 61 6d 65  respond to frame
8c40: 73 20 77 69 74 68 0a 20 20 2a 2a 20 66 72 61 6d  s with.  ** fram
8c50: 65 20 6e 75 6d 62 65 72 73 20 67 72 65 61 74 65  e numbers greate
8c60: 72 20 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72  r than pWal->hdr
8c70: 2e 6d 78 46 72 61 6d 65 2e 20 0a 20 20 2a 2f 0a  .mxFrame. .  */.
8c80: 20 20 6e 42 79 74 65 20 3d 20 28 28 63 68 61 72    nByte = ((char
8c90: 20 2a 29 61 48 61 73 68 20 2d 20 28 63 68 61 72   *)aHash - (char
8ca0: 20 2a 29 26 61 50 67 6e 6f 5b 69 4c 69 6d 69 74   *)&aPgno[iLimit
8cb0: 2b 31 5d 29 3b 0a 20 20 6d 65 6d 73 65 74 28 28  +1]);.  memset((
8cc0: 76 6f 69 64 20 2a 29 26 61 50 67 6e 6f 5b 69 4c  void *)&aPgno[iL
8cd0: 69 6d 69 74 2b 31 5d 2c 20 30 2c 20 6e 42 79 74  imit+1], 0, nByt
8ce0: 65 29 3b 0a 0a 23 69 66 64 65 66 20 53 51 4c 49  e);..#ifdef SQLI
8cf0: 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53  TE_ENABLE_EXPENS
8d00: 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20  IVE_ASSERT.  /* 
8d10: 56 65 72 69 66 79 20 74 68 61 74 20 74 68 65 20  Verify that the 
8d20: 65 76 65 72 79 20 65 6e 74 72 79 20 69 6e 20 74  every entry in t
8d30: 68 65 20 6d 61 70 70 69 6e 67 20 72 65 67 69 6f  he mapping regio
8d40: 6e 20 69 73 20 73 74 69 6c 6c 20 72 65 61 63 68  n is still reach
8d50: 61 62 6c 65 0a 20 20 2a 2a 20 76 69 61 20 74 68  able.  ** via th
8d60: 65 20 68 61 73 68 20 74 61 62 6c 65 20 65 76 65  e hash table eve
8d70: 6e 20 61 66 74 65 72 20 74 68 65 20 63 6c 65 61  n after the clea
8d80: 6e 75 70 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  nup..  */.  if( 
8d90: 69 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20 69 6e  iLimit ){.    in
8da0: 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 2f  t i;           /
8db0: 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a  * Loop counter *
8dc0: 2f 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20  /.    int iKey; 
8dd0: 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20 6b         /* Hash k
8de0: 65 79 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d  ey */.    for(i=
8df0: 31 3b 20 69 3c 3d 69 4c 69 6d 69 74 3b 20 69 2b  1; i<=iLimit; i+
8e00: 2b 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 4b  +){.      for(iK
8e10: 65 79 3d 77 61 6c 48 61 73 68 28 61 50 67 6e 6f  ey=walHash(aPgno
8e20: 5b 69 5d 29 3b 20 61 48 61 73 68 5b 69 4b 65 79  [i]); aHash[iKey
8e30: 5d 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48  ]; iKey=walNextH
8e40: 61 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20  ash(iKey)){.    
8e50: 20 20 20 20 69 66 28 20 61 48 61 73 68 5b 69 4b      if( aHash[iK
8e60: 65 79 5d 3d 3d 69 20 29 20 62 72 65 61 6b 3b 0a  ey]==i ) break;.
8e70: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73        }.      as
8e80: 73 65 72 74 28 20 61 48 61 73 68 5b 69 4b 65 79  sert( aHash[iKey
8e90: 5d 3d 3d 69 20 29 3b 0a 20 20 20 20 7d 0a 20 20  ]==i );.    }.  
8ea0: 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  }.#endif /* SQLI
8eb0: 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53  TE_ENABLE_EXPENS
8ec0: 49 56 45 5f 41 53 53 45 52 54 20 2a 2f 0a 7d 0a  IVE_ASSERT */.}.
8ed0: 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 6e 20 65  ../*.** Set an e
8ee0: 6e 74 72 79 20 69 6e 20 74 68 65 20 77 61 6c 2d  ntry in the wal-
8ef0: 69 6e 64 65 78 20 74 68 61 74 20 77 69 6c 6c 20  index that will 
8f00: 6d 61 70 20 64 61 74 61 62 61 73 65 20 70 61 67  map database pag
8f10: 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 70 50 61 67  e number.** pPag
8f20: 65 20 69 6e 74 6f 20 57 41 4c 20 66 72 61 6d 65  e into WAL frame
8f30: 20 69 46 72 61 6d 65 2e 0a 2a 2f 0a 73 74 61 74   iFrame..*/.stat
8f40: 69 63 20 69 6e 74 20 77 61 6c 49 6e 64 65 78 41  ic int walIndexA
8f50: 70 70 65 6e 64 28 57 61 6c 20 2a 70 57 61 6c 2c  ppend(Wal *pWal,
8f60: 20 75 33 32 20 69 46 72 61 6d 65 2c 20 75 33 32   u32 iFrame, u32
8f70: 20 69 50 61 67 65 29 7b 0a 20 20 69 6e 74 20 72   iPage){.  int r
8f80: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
8f90: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
8fa0: 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 75  turn code */.  u
8fb0: 33 32 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20  32 iZero;       
8fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8fd0: 2a 20 4f 6e 65 20 6c 65 73 73 20 74 68 61 6e 20  * One less than 
8fe0: 66 72 61 6d 65 20 6e 75 6d 62 65 72 20 6f 66 20  frame number of 
8ff0: 61 50 67 6e 6f 5b 31 5d 20 2a 2f 0a 20 20 76 6f  aPgno[1] */.  vo
9000: 6c 61 74 69 6c 65 20 75 33 32 20 2a 61 50 67 6e  latile u32 *aPgn
9010: 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  o;            /*
9020: 20 50 61 67 65 20 6e 75 6d 62 65 72 20 61 72 72   Page number arr
9030: 61 79 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65  ay */.  volatile
9040: 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b   ht_slot *aHash;
9050: 20 20 20 20 20 20 20 20 2f 2a 20 48 61 73 68 20          /* Hash 
9060: 74 61 62 6c 65 20 2a 2f 0a 0a 20 20 72 63 20 3d  table */..  rc =
9070: 20 77 61 6c 48 61 73 68 47 65 74 28 70 57 61 6c   walHashGet(pWal
9080: 2c 20 77 61 6c 46 72 61 6d 65 50 61 67 65 28 69  , walFramePage(i
9090: 46 72 61 6d 65 29 2c 20 26 61 48 61 73 68 2c 20  Frame), &aHash, 
90a0: 26 61 50 67 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b  &aPgno, &iZero);
90b0: 0a 0a 20 20 2f 2a 20 41 73 73 75 6d 69 6e 67 20  ..  /* Assuming 
90c0: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 66 69  the wal-index fi
90d0: 6c 65 20 77 61 73 20 73 75 63 63 65 73 73 66 75  le was successfu
90e0: 6c 6c 79 20 6d 61 70 70 65 64 2c 20 70 6f 70 75  lly mapped, popu
90f0: 6c 61 74 65 20 74 68 65 0a 20 20 2a 2a 20 70 61  late the.  ** pa
9100: 67 65 20 6e 75 6d 62 65 72 20 61 72 72 61 79 20  ge number array 
9110: 61 6e 64 20 68 61 73 68 20 74 61 62 6c 65 20 65  and hash table e
9120: 6e 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  ntry..  */.  if(
9130: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
9140: 7b 0a 20 20 20 20 69 6e 74 20 69 4b 65 79 3b 20  {.    int iKey; 
9150: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9160: 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c      /* Hash tabl
9170: 65 20 6b 65 79 20 2a 2f 0a 20 20 20 20 69 6e 74  e key */.    int
9180: 20 69 64 78 3b 20 20 20 20 20 20 20 20 20 20 20   idx;           
9190: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61             /* Va
91a0: 6c 75 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20  lue to write to 
91b0: 68 61 73 68 2d 74 61 62 6c 65 20 73 6c 6f 74 20  hash-table slot 
91c0: 2a 2f 0a 20 20 20 20 54 45 53 54 4f 4e 4c 59 28  */.    TESTONLY(
91d0: 20 69 6e 74 20 6e 43 6f 6c 6c 69 64 65 20 3d 20   int nCollide = 
91e0: 30 3b 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f  0;   /* Number o
91f0: 66 20 68 61 73 68 20 63 6f 6c 6c 69 73 69 6f 6e  f hash collision
9200: 73 20 2a 2f 20 29 0a 0a 20 20 20 20 69 64 78 20  s */ )..    idx 
9210: 3d 20 69 46 72 61 6d 65 20 2d 20 69 5a 65 72 6f  = iFrame - iZero
9220: 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 69 64  ;.    assert( id
9230: 78 20 3c 3d 20 48 41 53 48 54 41 42 4c 45 5f 4e  x <= HASHTABLE_N
9240: 53 4c 4f 54 2f 32 20 2b 20 31 20 29 3b 0a 20 20  SLOT/2 + 1 );.  
9250: 20 20 0a 20 20 20 20 2f 2a 20 49 66 20 74 68 69    .    /* If thi
9260: 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 65  s is the first e
9270: 6e 74 72 79 20 74 6f 20 62 65 20 61 64 64 65 64  ntry to be added
9280: 20 74 6f 20 74 68 69 73 20 68 61 73 68 2d 74 61   to this hash-ta
9290: 62 6c 65 2c 20 7a 65 72 6f 20 74 68 65 0a 20 20  ble, zero the.  
92a0: 20 20 2a 2a 20 65 6e 74 69 72 65 20 68 61 73 68    ** entire hash
92b0: 20 74 61 62 6c 65 20 61 6e 64 20 61 50 67 6e 6f   table and aPgno
92c0: 5b 5d 20 61 72 72 61 79 20 62 65 66 6f 72 65 20  [] array before 
92d0: 70 72 6f 63 65 64 69 6e 67 2e 20 0a 20 20 20 20  proceding. .    
92e0: 2a 2f 0a 20 20 20 20 69 66 28 20 69 64 78 3d 3d  */.    if( idx==
92f0: 31 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e  1 ){.      int n
9300: 42 79 74 65 20 3d 20 28 75 38 20 2a 29 26 61 48  Byte = (u8 *)&aH
9310: 61 73 68 5b 48 41 53 48 54 41 42 4c 45 5f 4e 53  ash[HASHTABLE_NS
9320: 4c 4f 54 5d 20 2d 20 28 75 38 20 2a 29 26 61 50  LOT] - (u8 *)&aP
9330: 67 6e 6f 5b 31 5d 3b 0a 20 20 20 20 20 20 6d 65  gno[1];.      me
9340: 6d 73 65 74 28 28 76 6f 69 64 2a 29 26 61 50 67  mset((void*)&aPg
9350: 6e 6f 5b 31 5d 2c 20 30 2c 20 6e 42 79 74 65 29  no[1], 0, nByte)
9360: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20  ;.    }..    /* 
9370: 49 66 20 74 68 65 20 65 6e 74 72 79 20 69 6e 20  If the entry in 
9380: 61 50 67 6e 6f 5b 5d 20 69 73 20 61 6c 72 65 61  aPgno[] is alrea
9390: 64 79 20 73 65 74 2c 20 74 68 65 6e 20 74 68 65  dy set, then the
93a0: 20 70 72 65 76 69 6f 75 73 20 77 72 69 74 65 72   previous writer
93b0: 0a 20 20 20 20 2a 2a 20 6d 75 73 74 20 68 61 76  .    ** must hav
93c0: 65 20 65 78 69 74 65 64 20 75 6e 65 78 70 65 63  e exited unexpec
93d0: 74 65 64 6c 79 20 69 6e 20 74 68 65 20 6d 69 64  tedly in the mid
93e0: 64 6c 65 20 6f 66 20 61 20 74 72 61 6e 73 61 63  dle of a transac
93f0: 74 69 6f 6e 20 28 61 66 74 65 72 0a 20 20 20 20  tion (after.    
9400: 2a 2a 20 77 72 69 74 69 6e 67 20 6f 6e 65 20 6f  ** writing one o
9410: 72 20 6d 6f 72 65 20 64 69 72 74 79 20 70 61 67  r more dirty pag
9420: 65 73 20 74 6f 20 74 68 65 20 57 41 4c 20 74 6f  es to the WAL to
9430: 20 66 72 65 65 20 75 70 20 6d 65 6d 6f 72 79 29   free up memory)
9440: 2e 20 0a 20 20 20 20 2a 2a 20 52 65 6d 6f 76 65  . .    ** Remove
9450: 20 74 68 65 20 72 65 6d 6e 61 6e 74 73 20 6f 66   the remnants of
9460: 20 74 68 61 74 20 77 72 69 74 65 72 73 20 75 6e   that writers un
9470: 63 6f 6d 6d 69 74 74 65 64 20 74 72 61 6e 73 61  committed transa
9480: 63 74 69 6f 6e 20 66 72 6f 6d 20 0a 20 20 20 20  ction from .    
9490: 2a 2a 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c  ** the hash-tabl
94a0: 65 20 62 65 66 6f 72 65 20 77 72 69 74 69 6e 67  e before writing
94b0: 20 61 6e 79 20 6e 65 77 20 65 6e 74 72 69 65 73   any new entries
94c0: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28  ..    */.    if(
94d0: 20 61 50 67 6e 6f 5b 69 64 78 5d 20 29 7b 0a 20   aPgno[idx] ){. 
94e0: 20 20 20 20 20 77 61 6c 43 6c 65 61 6e 75 70 48       walCleanupH
94f0: 61 73 68 28 70 57 61 6c 29 3b 0a 20 20 20 20 20  ash(pWal);.     
9500: 20 61 73 73 65 72 74 28 20 21 61 50 67 6e 6f 5b   assert( !aPgno[
9510: 69 64 78 5d 20 29 3b 0a 20 20 20 20 7d 0a 0a 20  idx] );.    }.. 
9520: 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20     /* Write the 
9530: 61 50 67 6e 6f 5b 5d 20 61 72 72 61 79 20 65 6e  aPgno[] array en
9540: 74 72 79 20 61 6e 64 20 74 68 65 20 68 61 73 68  try and the hash
9550: 2d 74 61 62 6c 65 20 73 6c 6f 74 2e 20 2a 2f 0a  -table slot. */.
9560: 20 20 20 20 66 6f 72 28 69 4b 65 79 3d 77 61 6c      for(iKey=wal
9570: 48 61 73 68 28 69 50 61 67 65 29 3b 20 61 48 61  Hash(iPage); aHa
9580: 73 68 5b 69 4b 65 79 5d 3b 20 69 4b 65 79 3d 77  sh[iKey]; iKey=w
9590: 61 6c 4e 65 78 74 48 61 73 68 28 69 4b 65 79 29  alNextHash(iKey)
95a0: 29 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28  ){.      assert(
95b0: 20 6e 43 6f 6c 6c 69 64 65 2b 2b 20 3c 20 69 64   nCollide++ < id
95c0: 78 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  x );.    }.    a
95d0: 50 67 6e 6f 5b 69 64 78 5d 20 3d 20 69 50 61 67  Pgno[idx] = iPag
95e0: 65 3b 0a 20 20 20 20 61 48 61 73 68 5b 69 4b 65  e;.    aHash[iKe
95f0: 79 5d 20 3d 20 69 64 78 3b 0a 0a 23 69 66 64 65  y] = idx;..#ifde
9600: 66 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f  f SQLITE_ENABLE_
9610: 45 58 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54  EXPENSIVE_ASSERT
9620: 0a 20 20 20 20 2f 2a 20 56 65 72 69 66 79 20 74  .    /* Verify t
9630: 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  hat the number o
9640: 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65  f entries in the
9650: 20 68 61 73 68 20 74 61 62 6c 65 20 65 78 61 63   hash table exac
9660: 74 6c 79 20 65 71 75 61 6c 73 0a 20 20 20 20 2a  tly equals.    *
9670: 2a 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  * the number of 
9680: 65 6e 74 72 69 65 73 20 69 6e 20 74 68 65 20 6d  entries in the m
9690: 61 70 70 69 6e 67 20 72 65 67 69 6f 6e 2e 0a 20  apping region.. 
96a0: 20 20 20 2a 2f 0a 20 20 20 20 7b 0a 20 20 20 20     */.    {.    
96b0: 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20    int i;        
96c0: 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74     /* Loop count
96d0: 65 72 20 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20  er */.      int 
96e0: 6e 45 6e 74 72 79 20 3d 20 30 3b 20 20 2f 2a 20  nEntry = 0;  /* 
96f0: 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  Number of entrie
9700: 73 20 69 6e 20 74 68 65 20 68 61 73 68 20 74 61  s in the hash ta
9710: 62 6c 65 20 2a 2f 0a 20 20 20 20 20 20 66 6f 72  ble */.      for
9720: 28 69 3d 30 3b 20 69 3c 48 41 53 48 54 41 42 4c  (i=0; i<HASHTABL
9730: 45 5f 4e 53 4c 4f 54 3b 20 69 2b 2b 29 7b 20 69  E_NSLOT; i++){ i
9740: 66 28 20 61 48 61 73 68 5b 69 5d 20 29 20 6e 45  f( aHash[i] ) nE
9750: 6e 74 72 79 2b 2b 3b 20 7d 0a 20 20 20 20 20 20  ntry++; }.      
9760: 61 73 73 65 72 74 28 20 6e 45 6e 74 72 79 3d 3d  assert( nEntry==
9770: 69 64 78 20 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  idx );.    }..  
9780: 20 20 2f 2a 20 56 65 72 69 66 79 20 74 68 61 74    /* Verify that
9790: 20 74 68 65 20 65 76 65 72 79 20 65 6e 74 72 79   the every entry
97a0: 20 69 6e 20 74 68 65 20 6d 61 70 70 69 6e 67 20   in the mapping 
97b0: 72 65 67 69 6f 6e 20 69 73 20 72 65 61 63 68 61  region is reacha
97c0: 62 6c 65 0a 20 20 20 20 2a 2a 20 76 69 61 20 74  ble.    ** via t
97d0: 68 65 20 68 61 73 68 20 74 61 62 6c 65 2e 20 20  he hash table.  
97e0: 54 68 69 73 20 74 75 72 6e 73 20 6f 75 74 20 74  This turns out t
97f0: 6f 20 62 65 20 61 20 72 65 61 6c 6c 79 2c 20 72  o be a really, r
9800: 65 61 6c 6c 79 20 65 78 70 65 6e 73 69 76 65 0a  eally expensive.
9810: 20 20 20 20 2a 2a 20 74 68 69 6e 67 20 74 6f 20      ** thing to 
9820: 63 68 65 63 6b 2c 20 73 6f 20 6f 6e 6c 79 20 64  check, so only d
9830: 6f 20 74 68 69 73 20 6f 63 63 61 73 69 6f 6e 61  o this occasiona
9840: 6c 6c 79 20 2d 20 6e 6f 74 20 6f 6e 20 65 76 65  lly - not on eve
9850: 72 79 0a 20 20 20 20 2a 2a 20 69 74 65 72 61 74  ry.    ** iterat
9860: 69 6f 6e 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ion..    */.    
9870: 69 66 28 20 28 69 64 78 26 30 78 33 66 66 29 3d  if( (idx&0x3ff)=
9880: 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  =0 ){.      int 
9890: 69 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  i;           /* 
98a0: 4c 6f 6f 70 20 63 6f 75 6e 74 65 72 20 2a 2f 0a  Loop counter */.
98b0: 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69        for(i=1; i
98c0: 3c 3d 69 64 78 3b 20 69 2b 2b 29 7b 0a 20 20 20  <=idx; i++){.   
98d0: 20 20 20 20 20 66 6f 72 28 69 4b 65 79 3d 77 61       for(iKey=wa
98e0: 6c 48 61 73 68 28 61 50 67 6e 6f 5b 69 5d 29 3b  lHash(aPgno[i]);
98f0: 20 61 48 61 73 68 5b 69 4b 65 79 5d 3b 20 69 4b   aHash[iKey]; iK
9900: 65 79 3d 77 61 6c 4e 65 78 74 48 61 73 68 28 69  ey=walNextHash(i
9910: 4b 65 79 29 29 7b 0a 20 20 20 20 20 20 20 20 20  Key)){.         
9920: 20 69 66 28 20 61 48 61 73 68 5b 69 4b 65 79 5d   if( aHash[iKey]
9930: 3d 3d 69 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  ==i ) break;.   
9940: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 61       }.        a
9950: 73 73 65 72 74 28 20 61 48 61 73 68 5b 69 4b 65  ssert( aHash[iKe
9960: 79 5d 3d 3d 69 20 29 3b 0a 20 20 20 20 20 20 7d  y]==i );.      }
9970: 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66 20 2f 2a  .    }.#endif /*
9980: 20 53 51 4c 49 54 45 5f 45 4e 41 42 4c 45 5f 45   SQLITE_ENABLE_E
9990: 58 50 45 4e 53 49 56 45 5f 41 53 53 45 52 54 20  XPENSIVE_ASSERT 
99a0: 2a 2f 0a 20 20 7d 0a 0a 0a 20 20 72 65 74 75 72  */.  }...  retur
99b0: 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  n rc;.}.../*.** 
99c0: 52 65 63 6f 76 65 72 20 74 68 65 20 77 61 6c 2d  Recover the wal-
99d0: 69 6e 64 65 78 20 62 79 20 72 65 61 64 69 6e 67  index by reading
99e0: 20 74 68 65 20 77 72 69 74 65 2d 61 68 65 61 64   the write-ahead
99f0: 20 6c 6f 67 20 66 69 6c 65 2e 20 0a 2a 2a 0a 2a   log file. .**.*
9a00: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 66  * This routine f
9a10: 69 72 73 74 20 74 72 69 65 73 20 74 6f 20 65 73  irst tries to es
9a20: 74 61 62 6c 69 73 68 20 61 6e 20 65 78 63 6c 75  tablish an exclu
9a30: 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 20 74 68 65  sive lock on the
9a40: 0a 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 74 6f  .** wal-index to
9a50: 20 70 72 65 76 65 6e 74 20 6f 74 68 65 72 20 74   prevent other t
9a60: 68 72 65 61 64 73 2f 70 72 6f 63 65 73 73 65 73  hreads/processes
9a70: 20 66 72 6f 6d 20 64 6f 69 6e 67 20 61 6e 79 74   from doing anyt
9a80: 68 69 6e 67 0a 2a 2a 20 77 69 74 68 20 74 68 65  hing.** with the
9a90: 20 57 41 4c 20 6f 72 20 77 61 6c 2d 69 6e 64 65   WAL or wal-inde
9aa0: 78 20 77 68 69 6c 65 20 72 65 63 6f 76 65 72 79  x while recovery
9ab0: 20 69 73 20 72 75 6e 6e 69 6e 67 2e 20 20 54 68   is running.  Th
9ac0: 65 0a 2a 2a 20 57 41 4c 5f 52 45 43 4f 56 45 52  e.** WAL_RECOVER
9ad0: 5f 4c 4f 43 4b 20 69 73 20 61 6c 73 6f 20 68 65  _LOCK is also he
9ae0: 6c 64 20 73 6f 20 74 68 61 74 20 6f 74 68 65 72  ld so that other
9af0: 20 74 68 72 65 61 64 73 20 77 69 6c 6c 20 6b 6e   threads will kn
9b00: 6f 77 0a 2a 2a 20 74 68 61 74 20 74 68 69 73 20  ow.** that this 
9b10: 74 68 72 65 61 64 20 69 73 20 72 75 6e 6e 69 6e  thread is runnin
9b20: 67 20 72 65 63 6f 76 65 72 79 2e 20 20 49 66 20  g recovery.  If 
9b30: 75 6e 61 62 6c 65 20 74 6f 20 65 73 74 61 62 6c  unable to establ
9b40: 69 73 68 0a 2a 2a 20 74 68 65 20 6e 65 63 65 73  ish.** the neces
9b50: 73 61 72 79 20 6c 6f 63 6b 73 2c 20 74 68 69 73  sary locks, this
9b60: 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73   routine returns
9b70: 20 53 51 4c 49 54 45 5f 42 55 53 59 2e 0a 2a 2f   SQLITE_BUSY..*/
9b80: 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 49  .static int walI
9b90: 6e 64 65 78 52 65 63 6f 76 65 72 28 57 61 6c 20  ndexRecover(Wal 
9ba0: 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72 63  *pWal){.  int rc
9bb0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
9bc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
9bd0: 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 69 36  urn Code */.  i6
9be0: 34 20 6e 53 69 7a 65 3b 20 20 20 20 20 20 20 20  4 nSize;        
9bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9c00: 20 53 69 7a 65 20 6f 66 20 6c 6f 67 20 66 69 6c   Size of log fil
9c10: 65 20 2a 2f 0a 20 20 75 33 32 20 61 46 72 61 6d  e */.  u32 aFram
9c20: 65 43 6b 73 75 6d 5b 32 5d 20 3d 20 7b 30 2c 20  eCksum[2] = {0, 
9c30: 30 7d 3b 0a 20 20 69 6e 74 20 69 4c 6f 63 6b 3b  0};.  int iLock;
9c40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9c50: 20 20 20 20 20 20 2f 2a 20 4c 6f 63 6b 20 6f 66        /* Lock of
9c60: 66 73 65 74 20 74 6f 20 6c 6f 63 6b 20 66 6f 72  fset to lock for
9c70: 20 63 68 65 63 6b 70 6f 69 6e 74 20 2a 2f 0a 20   checkpoint */. 
9c80: 20 69 6e 74 20 6e 4c 6f 63 6b 3b 20 20 20 20 20   int nLock;     
9c90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9ca0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6c 6f   /* Number of lo
9cb0: 63 6b 73 20 74 6f 20 68 6f 6c 64 20 2a 2f 0a 0a  cks to hold */..
9cc0: 20 20 2f 2a 20 4f 62 74 61 69 6e 20 61 6e 20 65    /* Obtain an e
9cd0: 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e  xclusive lock on
9ce0: 20 61 6c 6c 20 62 79 74 65 20 69 6e 20 74 68 65   all byte in the
9cf0: 20 6c 6f 63 6b 69 6e 67 20 72 61 6e 67 65 20 6e   locking range n
9d00: 6f 74 20 61 6c 72 65 61 64 79 0a 20 20 2a 2a 20  ot already.  ** 
9d10: 6c 6f 63 6b 65 64 20 62 79 20 74 68 65 20 63 61  locked by the ca
9d20: 6c 6c 65 72 2e 20 54 68 65 20 63 61 6c 6c 65 72  ller. The caller
9d30: 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74   is guaranteed t
9d40: 6f 20 68 61 76 65 20 6c 6f 63 6b 65 64 20 74 68  o have locked th
9d50: 65 0a 20 20 2a 2a 20 57 41 4c 5f 57 52 49 54 45  e.  ** WAL_WRITE
9d60: 5f 4c 4f 43 4b 20 62 79 74 65 2c 20 61 6e 64 20  _LOCK byte, and 
9d70: 6d 61 79 20 68 61 76 65 20 61 6c 73 6f 20 6c 6f  may have also lo
9d80: 63 6b 65 64 20 74 68 65 20 57 41 4c 5f 43 4b 50  cked the WAL_CKP
9d90: 54 5f 4c 4f 43 4b 20 62 79 74 65 2e 0a 20 20 2a  T_LOCK byte..  *
9da0: 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c  * If successful,
9db0: 20 74 68 65 20 73 61 6d 65 20 62 79 74 65 73 20   the same bytes 
9dc0: 74 68 61 74 20 61 72 65 20 6c 6f 63 6b 65 64 20  that are locked 
9dd0: 68 65 72 65 20 61 72 65 20 75 6e 6c 6f 63 6b 65  here are unlocke
9de0: 64 20 62 65 66 6f 72 65 0a 20 20 2a 2a 20 74 68  d before.  ** th
9df0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75  is function retu
9e00: 72 6e 73 2e 0a 20 20 2a 2f 0a 20 20 61 73 73 65  rns..  */.  asse
9e10: 72 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f  rt( pWal->ckptLo
9e20: 63 6b 3d 3d 31 20 7c 7c 20 70 57 61 6c 2d 3e 63  ck==1 || pWal->c
9e30: 6b 70 74 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20  kptLock==0 );.  
9e40: 61 73 73 65 72 74 28 20 57 41 4c 5f 41 4c 4c 5f  assert( WAL_ALL_
9e50: 42 55 54 5f 57 52 49 54 45 3d 3d 57 41 4c 5f 57  BUT_WRITE==WAL_W
9e60: 52 49 54 45 5f 4c 4f 43 4b 2b 31 20 29 3b 0a 20  RITE_LOCK+1 );. 
9e70: 20 61 73 73 65 72 74 28 20 57 41 4c 5f 43 4b 50   assert( WAL_CKP
9e80: 54 5f 4c 4f 43 4b 3d 3d 57 41 4c 5f 41 4c 4c 5f  T_LOCK==WAL_ALL_
9e90: 42 55 54 5f 57 52 49 54 45 20 29 3b 0a 20 20 61  BUT_WRITE );.  a
9ea0: 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 77 72 69  ssert( pWal->wri
9eb0: 74 65 4c 6f 63 6b 20 29 3b 0a 20 20 69 4c 6f 63  teLock );.  iLoc
9ec0: 6b 20 3d 20 57 41 4c 5f 41 4c 4c 5f 42 55 54 5f  k = WAL_ALL_BUT_
9ed0: 57 52 49 54 45 20 2b 20 70 57 61 6c 2d 3e 63 6b  WRITE + pWal->ck
9ee0: 70 74 4c 6f 63 6b 3b 0a 20 20 6e 4c 6f 63 6b 20  ptLock;.  nLock 
9ef0: 3d 20 53 51 4c 49 54 45 5f 53 48 4d 5f 4e 4c 4f  = SQLITE_SHM_NLO
9f00: 43 4b 20 2d 20 69 4c 6f 63 6b 3b 0a 20 20 72 63  CK - iLock;.  rc
9f10: 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73   = walLockExclus
9f20: 69 76 65 28 70 57 61 6c 2c 20 69 4c 6f 63 6b 2c  ive(pWal, iLock,
9f30: 20 6e 4c 6f 63 6b 29 3b 0a 20 20 69 66 28 20 72   nLock);.  if( r
9f40: 63 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  c ){.    return 
9f50: 72 63 3b 0a 20 20 7d 0a 20 20 57 41 4c 54 52 41  rc;.  }.  WALTRA
9f60: 43 45 28 28 22 57 41 4c 25 70 3a 20 72 65 63 6f  CE(("WAL%p: reco
9f70: 76 65 72 79 20 62 65 67 69 6e 2e 2e 2e 5c 6e 22  very begin...\n"
9f80: 2c 20 70 57 61 6c 29 29 3b 0a 0a 20 20 6d 65 6d  , pWal));..  mem
9f90: 73 65 74 28 26 70 57 61 6c 2d 3e 68 64 72 2c 20  set(&pWal->hdr, 
9fa0: 30 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e 64  0, sizeof(WalInd
9fb0: 65 78 48 64 72 29 29 3b 0a 0a 20 20 72 63 20 3d  exHdr));..  rc =
9fc0: 20 73 71 6c 69 74 65 33 4f 73 46 69 6c 65 53 69   sqlite3OsFileSi
9fd0: 7a 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  ze(pWal->pWalFd,
9fe0: 20 26 6e 53 69 7a 65 29 3b 0a 20 20 69 66 28 20   &nSize);.  if( 
9ff0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
a000: 0a 20 20 20 20 67 6f 74 6f 20 72 65 63 6f 76 65  .    goto recove
a010: 72 79 5f 65 72 72 6f 72 3b 0a 20 20 7d 0a 0a 20  ry_error;.  }.. 
a020: 20 69 66 28 20 6e 53 69 7a 65 3e 57 41 4c 5f 48   if( nSize>WAL_H
a030: 44 52 53 49 5a 45 20 29 7b 0a 20 20 20 20 75 38  DRSIZE ){.    u8
a040: 20 61 42 75 66 5b 57 41 4c 5f 48 44 52 53 49 5a   aBuf[WAL_HDRSIZ
a050: 45 5d 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 42  E];         /* B
a060: 75 66 66 65 72 20 74 6f 20 6c 6f 61 64 20 57 41  uffer to load WA
a070: 4c 20 68 65 61 64 65 72 20 69 6e 74 6f 20 2a 2f  L header into */
a080: 0a 20 20 20 20 75 38 20 2a 61 46 72 61 6d 65 20  .    u8 *aFrame 
a090: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
a0a0: 20 20 20 2f 2a 20 4d 61 6c 6c 6f 63 27 64 20 62     /* Malloc'd b
a0b0: 75 66 66 65 72 20 74 6f 20 6c 6f 61 64 20 65 6e  uffer to load en
a0c0: 74 69 72 65 20 66 72 61 6d 65 20 2a 2f 0a 20 20  tire frame */.  
a0d0: 20 20 69 6e 74 20 73 7a 46 72 61 6d 65 3b 20 20    int szFrame;  
a0e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a0f0: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74  /* Number of byt
a100: 65 73 20 69 6e 20 62 75 66 66 65 72 20 61 46 72  es in buffer aFr
a110: 61 6d 65 5b 5d 20 2a 2f 0a 20 20 20 20 75 38 20  ame[] */.    u8 
a120: 2a 61 44 61 74 61 3b 20 20 20 20 20 20 20 20 20  *aData;         
a130: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 6f             /* Po
a140: 69 6e 74 65 72 20 74 6f 20 64 61 74 61 20 70 61  inter to data pa
a150: 72 74 20 6f 66 20 61 46 72 61 6d 65 20 62 75 66  rt of aFrame buf
a160: 66 65 72 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69  fer */.    int i
a170: 46 72 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  Frame;          
a180: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65           /* Inde
a190: 78 20 6f 66 20 6c 61 73 74 20 66 72 61 6d 65 20  x of last frame 
a1a0: 72 65 61 64 20 2a 2f 0a 20 20 20 20 69 36 34 20  read */.    i64 
a1b0: 69 4f 66 66 73 65 74 3b 20 20 20 20 20 20 20 20  iOffset;        
a1c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78            /* Nex
a1d0: 74 20 6f 66 66 73 65 74 20 74 6f 20 72 65 61 64  t offset to read
a1e0: 20 66 72 6f 6d 20 6c 6f 67 20 66 69 6c 65 20 2a   from log file *
a1f0: 2f 0a 20 20 20 20 69 6e 74 20 73 7a 50 61 67 65  /.    int szPage
a200: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
a210: 20 20 20 20 2f 2a 20 50 61 67 65 20 73 69 7a 65      /* Page size
a220: 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 74 68   according to th
a230: 65 20 6c 6f 67 20 2a 2f 0a 20 20 20 20 75 33 32  e log */.    u32
a240: 20 6d 61 67 69 63 3b 20 20 20 20 20 20 20 20 20   magic;         
a250: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61             /* Ma
a260: 67 69 63 20 76 61 6c 75 65 20 72 65 61 64 20 66  gic value read f
a270: 72 6f 6d 20 57 41 4c 20 68 65 61 64 65 72 20 2a  rom WAL header *
a280: 2f 0a 0a 20 20 20 20 2f 2a 20 52 65 61 64 20 69  /..    /* Read i
a290: 6e 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72  n the WAL header
a2a0: 2e 20 2a 2f 0a 20 20 20 20 72 63 20 3d 20 73 71  . */.    rc = sq
a2b0: 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57 61 6c  lite3OsRead(pWal
a2c0: 2d 3e 70 57 61 6c 46 64 2c 20 61 42 75 66 2c 20  ->pWalFd, aBuf, 
a2d0: 57 41 4c 5f 48 44 52 53 49 5a 45 2c 20 30 29 3b  WAL_HDRSIZE, 0);
a2e0: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
a2f0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
a300: 67 6f 74 6f 20 72 65 63 6f 76 65 72 79 5f 65 72  goto recovery_er
a310: 72 6f 72 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  ror;.    }..    
a320: 2f 2a 20 49 66 20 74 68 65 20 64 61 74 61 62 61  /* If the databa
a330: 73 65 20 70 61 67 65 20 73 69 7a 65 20 69 73 20  se page size is 
a340: 6e 6f 74 20 61 20 70 6f 77 65 72 20 6f 66 20 74  not a power of t
a350: 77 6f 2c 20 6f 72 20 69 73 20 67 72 65 61 74 65  wo, or is greate
a360: 72 20 74 68 61 6e 0a 20 20 20 20 2a 2a 20 53 51  r than.    ** SQ
a370: 4c 49 54 45 5f 4d 41 58 5f 50 41 47 45 5f 53 49  LITE_MAX_PAGE_SI
a380: 5a 45 2c 20 63 6f 6e 63 6c 75 64 65 20 74 68 61  ZE, conclude tha
a390: 74 20 74 68 65 20 57 41 4c 20 66 69 6c 65 20 63  t the WAL file c
a3a0: 6f 6e 74 61 69 6e 73 20 6e 6f 20 76 61 6c 69 64  ontains no valid
a3b0: 20 0a 20 20 20 20 2a 2a 20 64 61 74 61 2e 20 53   .    ** data. S
a3c0: 69 6d 69 6c 61 72 6c 79 2c 20 69 66 20 74 68 65  imilarly, if the
a3d0: 20 27 6d 61 67 69 63 27 20 76 61 6c 75 65 20 69   'magic' value i
a3e0: 73 20 69 6e 76 61 6c 69 64 2c 20 69 67 6e 6f 72  s invalid, ignor
a3f0: 65 20 74 68 65 20 77 68 6f 6c 65 0a 20 20 20 20  e the whole.    
a400: 2a 2a 20 57 41 4c 20 66 69 6c 65 2e 0a 20 20 20  ** WAL file..   
a410: 20 2a 2f 0a 20 20 20 20 6d 61 67 69 63 20 3d 20   */.    magic = 
a420: 73 71 6c 69 74 65 33 47 65 74 34 62 79 74 65 28  sqlite3Get4byte(
a430: 26 61 42 75 66 5b 30 5d 29 3b 0a 20 20 20 20 73  &aBuf[0]);.    s
a440: 7a 50 61 67 65 20 3d 20 73 71 6c 69 74 65 33 47  zPage = sqlite3G
a450: 65 74 34 62 79 74 65 28 26 61 42 75 66 5b 38 5d  et4byte(&aBuf[8]
a460: 29 3b 0a 20 20 20 20 69 66 28 20 28 6d 61 67 69  );.    if( (magi
a470: 63 26 30 78 46 46 46 46 46 46 46 45 29 21 3d 57  c&0xFFFFFFFE)!=W
a480: 41 4c 5f 4d 41 47 49 43 20 0a 20 20 20 20 20 7c  AL_MAGIC .     |
a490: 7c 20 73 7a 50 61 67 65 26 28 73 7a 50 61 67 65  | szPage&(szPage
a4a0: 2d 31 29 20 0a 20 20 20 20 20 7c 7c 20 73 7a 50  -1) .     || szP
a4b0: 61 67 65 3e 53 51 4c 49 54 45 5f 4d 41 58 5f 50  age>SQLITE_MAX_P
a4c0: 41 47 45 5f 53 49 5a 45 20 0a 20 20 20 20 20 7c  AGE_SIZE .     |
a4d0: 7c 20 73 7a 50 61 67 65 3c 35 31 32 20 0a 20 20  | szPage<512 .  
a4e0: 20 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20    ){.      goto 
a4f0: 66 69 6e 69 73 68 65 64 3b 0a 20 20 20 20 7d 0a  finished;.    }.
a500: 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 62 69      pWal->hdr.bi
a510: 67 45 6e 64 43 6b 73 75 6d 20 3d 20 28 6d 61 67  gEndCksum = (mag
a520: 69 63 26 30 78 30 30 30 30 30 30 30 31 29 3b 0a  ic&0x00000001);.
a530: 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65      pWal->szPage
a540: 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 70   = szPage;.    p
a550: 57 61 6c 2d 3e 6e 43 6b 70 74 20 3d 20 73 71 6c  Wal->nCkpt = sql
a560: 69 74 65 33 47 65 74 34 62 79 74 65 28 26 61 42  ite3Get4byte(&aB
a570: 75 66 5b 31 32 5d 29 3b 0a 20 20 20 20 6d 65 6d  uf[12]);.    mem
a580: 63 70 79 28 26 70 57 61 6c 2d 3e 68 64 72 2e 61  cpy(&pWal->hdr.a
a590: 53 61 6c 74 2c 20 26 61 42 75 66 5b 31 36 5d 2c  Salt, &aBuf[16],
a5a0: 20 38 29 3b 0a 20 20 20 20 77 61 6c 43 68 65 63   8);.    walChec
a5b0: 6b 73 75 6d 42 79 74 65 73 28 70 57 61 6c 2d 3e  ksumBytes(pWal->
a5c0: 68 64 72 2e 62 69 67 45 6e 64 43 6b 73 75 6d 3d  hdr.bigEndCksum=
a5d0: 3d 53 51 4c 49 54 45 5f 42 49 47 45 4e 44 49 41  =SQLITE_BIGENDIA
a5e0: 4e 2c 20 0a 20 20 20 20 20 20 20 20 61 42 75 66  N, .        aBuf
a5f0: 2c 20 57 41 4c 5f 48 44 52 53 49 5a 45 2c 20 30  , WAL_HDRSIZE, 0
a600: 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61  , pWal->hdr.aFra
a610: 6d 65 43 6b 73 75 6d 0a 20 20 20 20 29 3b 0a 0a  meCksum.    );..
a620: 20 20 20 20 2f 2a 20 4d 61 6c 6c 6f 63 20 61 20      /* Malloc a 
a630: 62 75 66 66 65 72 20 74 6f 20 72 65 61 64 20 66  buffer to read f
a640: 72 61 6d 65 73 20 69 6e 74 6f 2e 20 2a 2f 0a 20  rames into. */. 
a650: 20 20 20 73 7a 46 72 61 6d 65 20 3d 20 73 7a 50     szFrame = szP
a660: 61 67 65 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  age + WAL_FRAME_
a670: 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 61 46 72  HDRSIZE;.    aFr
a680: 61 6d 65 20 3d 20 28 75 38 20 2a 29 73 71 6c 69  ame = (u8 *)sqli
a690: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 7a 46 72 61  te3_malloc(szFra
a6a0: 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21 61 46  me);.    if( !aF
a6b0: 72 61 6d 65 20 29 7b 0a 20 20 20 20 20 20 72 63  rame ){.      rc
a6c0: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
a6d0: 0a 20 20 20 20 20 20 67 6f 74 6f 20 72 65 63 6f  .      goto reco
a6e0: 76 65 72 79 5f 65 72 72 6f 72 3b 0a 20 20 20 20  very_error;.    
a6f0: 7d 0a 20 20 20 20 61 44 61 74 61 20 3d 20 26 61  }.    aData = &a
a700: 46 72 61 6d 65 5b 57 41 4c 5f 46 52 41 4d 45 5f  Frame[WAL_FRAME_
a710: 48 44 52 53 49 5a 45 5d 3b 0a 0a 20 20 20 20 2f  HDRSIZE];..    /
a720: 2a 20 52 65 61 64 20 61 6c 6c 20 66 72 61 6d 65  * Read all frame
a730: 73 20 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20 66  s from the log f
a740: 69 6c 65 2e 20 2a 2f 0a 20 20 20 20 69 46 72 61  ile. */.    iFra
a750: 6d 65 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28  me = 0;.    for(
a760: 69 4f 66 66 73 65 74 3d 57 41 4c 5f 48 44 52 53  iOffset=WAL_HDRS
a770: 49 5a 45 3b 20 28 69 4f 66 66 73 65 74 2b 73 7a  IZE; (iOffset+sz
a780: 46 72 61 6d 65 29 3c 3d 6e 53 69 7a 65 3b 20 69  Frame)<=nSize; i
a790: 4f 66 66 73 65 74 2b 3d 73 7a 46 72 61 6d 65 29  Offset+=szFrame)
a7a0: 7b 0a 20 20 20 20 20 20 75 33 32 20 70 67 6e 6f  {.      u32 pgno
a7b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
a7c0: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
a7d0: 70 61 67 65 20 6e 75 6d 62 65 72 20 66 6f 72 20  page number for 
a7e0: 66 72 61 6d 65 20 2a 2f 0a 20 20 20 20 20 20 75  frame */.      u
a7f0: 33 32 20 6e 54 72 75 6e 63 61 74 65 3b 20 20 20  32 nTruncate;   
a800: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 64 62             /* db
a810: 73 69 7a 65 20 66 69 65 6c 64 20 66 72 6f 6d 20  size field from 
a820: 66 72 61 6d 65 20 68 65 61 64 65 72 20 2a 2f 0a  frame header */.
a830: 20 20 20 20 20 20 69 6e 74 20 69 73 56 61 6c 69        int isVali
a840: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
a850: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 74 68 69    /* True if thi
a860: 73 20 66 72 61 6d 65 20 69 73 20 76 61 6c 69 64  s frame is valid
a870: 20 2a 2f 0a 0a 20 20 20 20 20 20 2f 2a 20 52 65   */..      /* Re
a880: 61 64 20 61 6e 64 20 64 65 63 6f 64 65 20 74 68  ad and decode th
a890: 65 20 6e 65 78 74 20 6c 6f 67 20 66 72 61 6d 65  e next log frame
a8a0: 2e 20 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20  . */.      rc = 
a8b0: 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57  sqlite3OsRead(pW
a8c0: 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 46 72 61  al->pWalFd, aFra
a8d0: 6d 65 2c 20 73 7a 46 72 61 6d 65 2c 20 69 4f 66  me, szFrame, iOf
a8e0: 66 73 65 74 29 3b 0a 20 20 20 20 20 20 69 66 28  fset);.      if(
a8f0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
a900: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 69 73   break;.      is
a910: 56 61 6c 69 64 20 3d 20 77 61 6c 44 65 63 6f 64  Valid = walDecod
a920: 65 46 72 61 6d 65 28 70 57 61 6c 2c 20 26 70 67  eFrame(pWal, &pg
a930: 6e 6f 2c 20 26 6e 54 72 75 6e 63 61 74 65 2c 20  no, &nTruncate, 
a940: 61 44 61 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a  aData, aFrame);.
a950: 20 20 20 20 20 20 69 66 28 20 21 69 73 56 61 6c        if( !isVal
a960: 69 64 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  id ) break;.    
a970: 20 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 41    rc = walIndexA
a980: 70 70 65 6e 64 28 70 57 61 6c 2c 20 2b 2b 69 46  ppend(pWal, ++iF
a990: 72 61 6d 65 2c 20 70 67 6e 6f 29 3b 0a 20 20 20  rame, pgno);.   
a9a0: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
a9b0: 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 0a 20  E_OK ) break;.. 
a9c0: 20 20 20 20 20 2f 2a 20 49 66 20 6e 54 72 75 6e       /* If nTrun
a9d0: 63 61 74 65 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f  cate is non-zero
a9e0: 2c 20 74 68 69 73 20 69 73 20 61 20 63 6f 6d 6d  , this is a comm
a9f0: 69 74 20 72 65 63 6f 72 64 2e 20 2a 2f 0a 20 20  it record. */.  
aa00: 20 20 20 20 69 66 28 20 6e 54 72 75 6e 63 61 74      if( nTruncat
aa10: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 70 57 61  e ){.        pWa
aa20: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 3d  l->hdr.mxFrame =
aa30: 20 69 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 20   iFrame;.       
aa40: 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67 65   pWal->hdr.nPage
aa50: 20 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a 20 20   = nTruncate;.  
aa60: 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e        pWal->hdr.
aa70: 73 7a 50 61 67 65 20 3d 20 73 7a 50 61 67 65 3b  szPage = szPage;
aa80: 0a 20 20 20 20 20 20 20 20 61 46 72 61 6d 65 43  .        aFrameC
aa90: 6b 73 75 6d 5b 30 5d 20 3d 20 70 57 61 6c 2d 3e  ksum[0] = pWal->
aaa0: 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75 6d 5b  hdr.aFrameCksum[
aab0: 30 5d 3b 0a 20 20 20 20 20 20 20 20 61 46 72 61  0];.        aFra
aac0: 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20 70 57 61  meCksum[1] = pWa
aad0: 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73  l->hdr.aFrameCks
aae0: 75 6d 5b 31 5d 3b 0a 20 20 20 20 20 20 7d 0a 20  um[1];.      }. 
aaf0: 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65     }..    sqlite
ab00: 33 5f 66 72 65 65 28 61 46 72 61 6d 65 29 3b 0a  3_free(aFrame);.
ab10: 20 20 7d 0a 0a 66 69 6e 69 73 68 65 64 3a 0a 20    }..finished:. 
ab20: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
ab30: 4f 4b 20 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69  OK ){.    volati
ab40: 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a  le WalCkptInfo *
ab50: 70 49 6e 66 6f 3b 0a 20 20 20 20 69 6e 74 20 69  pInfo;.    int i
ab60: 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e  ;.    pWal->hdr.
ab70: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d  aFrameCksum[0] =
ab80: 20 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b   aFrameCksum[0];
ab90: 0a 20 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61  .    pWal->hdr.a
aba0: 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 20 3d 20  FrameCksum[1] = 
abb0: 61 46 72 61 6d 65 43 6b 73 75 6d 5b 31 5d 3b 0a  aFrameCksum[1];.
abc0: 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72 69 74      walIndexWrit
abd0: 65 48 64 72 28 70 57 61 6c 29 3b 0a 0a 20 20 20  eHdr(pWal);..   
abe0: 20 2f 2a 20 52 65 73 65 74 20 74 68 65 20 63 68   /* Reset the ch
abf0: 65 63 6b 70 6f 69 6e 74 2d 68 65 61 64 65 72 2e  eckpoint-header.
ac00: 20 54 68 69 73 20 69 73 20 73 61 66 65 20 62 65   This is safe be
ac10: 63 61 75 73 65 20 74 68 69 73 20 74 68 72 65 61  cause this threa
ac20: 64 20 69 73 20 0a 20 20 20 20 2a 2a 20 63 75 72  d is .    ** cur
ac30: 72 65 6e 74 6c 79 20 68 6f 6c 64 69 6e 67 20 6c  rently holding l
ac40: 6f 63 6b 73 20 74 68 61 74 20 65 78 63 6c 75 64  ocks that exclud
ac50: 65 20 61 6c 6c 20 6f 74 68 65 72 20 72 65 61 64  e all other read
ac60: 65 72 73 2c 20 77 72 69 74 65 72 73 20 61 6e 64  ers, writers and
ac70: 0a 20 20 20 20 2a 2a 20 63 68 65 63 6b 70 6f 69  .    ** checkpoi
ac80: 6e 74 65 72 73 2e 0a 20 20 20 20 2a 2f 0a 20 20  nters..    */.  
ac90: 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70    pInfo = walCkp
aca0: 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20  tInfo(pWal);.   
acb0: 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
acc0: 6c 20 3d 20 30 3b 0a 20 20 20 20 70 49 6e 66 6f  l = 0;.    pInfo
acd0: 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 20 3d  ->aReadMark[0] =
ace0: 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b   0;.    for(i=1;
acf0: 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52 3b 20   i<WAL_NREADER; 
ad00: 69 2b 2b 29 20 70 49 6e 66 6f 2d 3e 61 52 65 61  i++) pInfo->aRea
ad10: 64 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41 44 4d  dMark[i] = READM
ad20: 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a 20 20  ARK_NOT_USED;.  
ad30: 7d 0a 0a 72 65 63 6f 76 65 72 79 5f 65 72 72 6f  }..recovery_erro
ad40: 72 3a 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22  r:.  WALTRACE(("
ad50: 57 41 4c 25 70 3a 20 72 65 63 6f 76 65 72 79 20  WAL%p: recovery 
ad60: 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72 63 20  %s\n", pWal, rc 
ad70: 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22 6f 6b  ? "failed" : "ok
ad80: 22 29 29 3b 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b  "));.  walUnlock
ad90: 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
ada0: 69 4c 6f 63 6b 2c 20 6e 4c 6f 63 6b 29 3b 0a 20  iLock, nLock);. 
adb0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
adc0: 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 6e 20 6f 70  *.** Close an op
add0: 65 6e 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 2a 2f  en wal-index..*/
ade0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 77 61 6c  .static void wal
adf0: 49 6e 64 65 78 43 6c 6f 73 65 28 57 61 6c 20 2a  IndexClose(Wal *
ae00: 70 57 61 6c 2c 20 69 6e 74 20 69 73 44 65 6c 65  pWal, int isDele
ae10: 74 65 29 7b 0a 20 20 69 66 28 20 70 57 61 6c 2d  te){.  if( pWal-
ae20: 3e 69 73 57 49 6e 64 65 78 4f 70 65 6e 20 29 7b  >isWIndexOpen ){
ae30: 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53 68  .    sqlite3OsSh
ae40: 6d 43 6c 6f 73 65 28 70 57 61 6c 2d 3e 70 44 62  mClose(pWal->pDb
ae50: 46 64 2c 20 69 73 44 65 6c 65 74 65 29 3b 0a 20  Fd, isDelete);. 
ae60: 20 20 20 70 57 61 6c 2d 3e 69 73 57 49 6e 64 65     pWal->isWInde
ae70: 78 4f 70 65 6e 20 3d 20 30 3b 0a 20 20 7d 0a 7d  xOpen = 0;.  }.}
ae80: 0a 0a 2f 2a 20 0a 2a 2a 20 4f 70 65 6e 20 61 20  ../* .** Open a 
ae90: 63 6f 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 74 68  connection to th
aea0: 65 20 57 41 4c 20 66 69 6c 65 20 61 73 73 6f 63  e WAL file assoc
aeb0: 69 61 74 65 64 20 77 69 74 68 20 64 61 74 61 62  iated with datab
aec0: 61 73 65 20 7a 44 62 4e 61 6d 65 2e 0a 2a 2a 20  ase zDbName..** 
aed0: 54 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  The database fil
aee0: 65 20 6d 75 73 74 20 61 6c 72 65 61 64 79 20 62  e must already b
aef0: 65 20 6f 70 65 6e 65 64 20 6f 6e 20 63 6f 6e 6e  e opened on conn
af00: 65 63 74 69 6f 6e 20 70 44 62 46 64 2e 0a 2a 2a  ection pDbFd..**
af10: 0a 2a 2a 20 41 20 53 48 41 52 45 44 20 6c 6f 63  .** A SHARED loc
af20: 6b 20 73 68 6f 75 6c 64 20 62 65 20 68 65 6c 64  k should be held
af30: 20 6f 6e 20 74 68 65 20 64 61 74 61 62 61 73 65   on the database
af40: 20 66 69 6c 65 20 77 68 65 6e 20 74 68 69 73 20   file when this 
af50: 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 69 73 20 63  function.** is c
af60: 61 6c 6c 65 64 2e 20 54 68 65 20 70 75 72 70 6f  alled. The purpo
af70: 73 65 20 6f 66 20 74 68 69 73 20 53 48 41 52 45  se of this SHARE
af80: 44 20 6c 6f 63 6b 20 69 73 20 74 6f 20 70 72 65  D lock is to pre
af90: 76 65 6e 74 20 61 6e 79 20 6f 74 68 65 72 0a 2a  vent any other.*
afa0: 2a 20 63 6c 69 65 6e 74 20 66 72 6f 6d 20 75 6e  * client from un
afb0: 6c 69 6e 6b 69 6e 67 20 74 68 65 20 57 41 4c 20  linking the WAL 
afc0: 6f 72 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  or wal-index fil
afd0: 65 2e 20 49 66 20 61 6e 6f 74 68 65 72 20 70 72  e. If another pr
afe0: 6f 63 65 73 73 0a 2a 2a 20 77 65 72 65 20 74 6f  ocess.** were to
aff0: 20 64 6f 20 74 68 69 73 20 6a 75 73 74 20 61 66   do this just af
b000: 74 65 72 20 74 68 69 73 20 63 6c 69 65 6e 74 20  ter this client 
b010: 6f 70 65 6e 65 64 20 6f 6e 65 20 6f 66 20 74 68  opened one of th
b020: 65 73 65 20 66 69 6c 65 73 2c 20 74 68 65 0a 2a  ese files, the.*
b030: 2a 20 73 79 73 74 65 6d 20 77 6f 75 6c 64 20 62  * system would b
b040: 65 20 62 61 64 6c 79 20 62 72 6f 6b 65 6e 2e 0a  e badly broken..
b050: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 6c 6f 67  **.** If the log
b060: 20 66 69 6c 65 20 69 73 20 73 75 63 63 65 73 73   file is success
b070: 66 75 6c 6c 79 20 6f 70 65 6e 65 64 2c 20 53 51  fully opened, SQ
b080: 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72  LITE_OK is retur
b090: 6e 65 64 20 61 6e 64 20 0a 2a 2a 20 2a 70 70 57  ned and .** *ppW
b0a0: 61 6c 20 69 73 20 73 65 74 20 74 6f 20 70 6f 69  al is set to poi
b0b0: 6e 74 20 74 6f 20 61 20 6e 65 77 20 57 41 4c 20  nt to a new WAL 
b0c0: 68 61 6e 64 6c 65 2e 20 49 66 20 61 6e 20 65 72  handle. If an er
b0d0: 72 6f 72 20 6f 63 63 75 72 73 2c 0a 2a 2a 20 61  ror occurs,.** a
b0e0: 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63  n SQLite error c
b0f0: 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65 64 20  ode is returned 
b100: 61 6e 64 20 2a 70 70 57 61 6c 20 69 73 20 6c 65  and *ppWal is le
b110: 66 74 20 75 6e 6d 6f 64 69 66 69 65 64 2e 0a 2a  ft unmodified..*
b120: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c  /.int sqlite3Wal
b130: 4f 70 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f  Open(.  sqlite3_
b140: 76 66 73 20 2a 70 56 66 73 2c 20 20 20 20 20 20  vfs *pVfs,      
b150: 20 20 20 20 20 20 20 20 2f 2a 20 76 66 73 20 6d          /* vfs m
b160: 6f 64 75 6c 65 20 74 6f 20 6f 70 65 6e 20 77 61  odule to open wa
b170: 6c 20 61 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20  l and wal-index 
b180: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  */.  sqlite3_fil
b190: 65 20 2a 70 44 62 46 64 2c 20 20 20 20 20 20 20  e *pDbFd,       
b1a0: 20 20 20 20 20 2f 2a 20 54 68 65 20 6f 70 65 6e       /* The open
b1b0: 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20 2a   database file *
b1c0: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
b1d0: 7a 44 62 4e 61 6d 65 2c 20 20 20 20 20 20 20 20  zDbName,        
b1e0: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74      /* Name of t
b1f0: 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
b200: 20 2a 2f 0a 20 20 57 61 6c 20 2a 2a 70 70 57 61   */.  Wal **ppWa
b210: 6c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l               
b220: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 41 6c        /* OUT: Al
b230: 6c 6f 63 61 74 65 64 20 57 61 6c 20 68 61 6e 64  located Wal hand
b240: 6c 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72  le */.){.  int r
b250: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
b260: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
b270: 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20 20 57  turn Code */.  W
b280: 61 6c 20 2a 70 52 65 74 3b 20 20 20 20 20 20 20  al *pRet;       
b290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
b2a0: 2a 20 4f 62 6a 65 63 74 20 74 6f 20 61 6c 6c 6f  * Object to allo
b2b0: 63 61 74 65 20 61 6e 64 20 72 65 74 75 72 6e 20  cate and return 
b2c0: 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73 3b 20  */.  int flags; 
b2d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b2e0: 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 70 61       /* Flags pa
b2f0: 73 73 65 64 20 74 6f 20 4f 73 4f 70 65 6e 28 29  ssed to OsOpen()
b300: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 57 61 6c   */.  char *zWal
b310: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
b320: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
b330: 20 77 72 69 74 65 2d 61 68 65 61 64 20 6c 6f 67   write-ahead log
b340: 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e   file */.  int n
b350: 57 61 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  Wal;            
b360: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 65             /* Le
b370: 6e 67 74 68 20 6f 66 20 7a 57 61 6c 20 69 6e 20  ngth of zWal in 
b380: 62 79 74 65 73 20 2a 2f 0a 0a 20 20 61 73 73 65  bytes */..  asse
b390: 72 74 28 20 7a 44 62 4e 61 6d 65 20 26 26 20 7a  rt( zDbName && z
b3a0: 44 62 4e 61 6d 65 5b 30 5d 20 29 3b 0a 20 20 61  DbName[0] );.  a
b3b0: 73 73 65 72 74 28 20 70 44 62 46 64 20 29 3b 0a  ssert( pDbFd );.
b3c0: 0a 20 20 2f 2a 20 49 6e 20 74 68 65 20 61 6d 61  .  /* In the ama
b3d0: 6c 67 61 6d 61 74 69 6f 6e 2c 20 74 68 65 20 6f  lgamation, the o
b3e0: 73 5f 75 6e 69 78 2e 63 20 61 6e 64 20 6f 73 5f  s_unix.c and os_
b3f0: 77 69 6e 2e 63 20 73 6f 75 72 63 65 20 66 69 6c  win.c source fil
b400: 65 73 20 63 6f 6d 65 20 62 65 66 6f 72 65 0a 20  es come before. 
b410: 20 2a 2a 20 74 68 69 73 20 73 6f 75 72 63 65 20   ** this source 
b420: 66 69 6c 65 2e 20 20 56 65 72 69 66 79 20 74 68  file.  Verify th
b430: 61 74 20 74 68 65 20 23 64 65 66 69 6e 65 73 20  at the #defines 
b440: 6f 66 20 74 68 65 20 6c 6f 63 6b 69 6e 67 20 62  of the locking b
b450: 79 74 65 20 6f 66 66 73 65 74 73 0a 20 20 2a 2a  yte offsets.  **
b460: 20 69 6e 20 6f 73 5f 75 6e 69 78 2e 63 20 61 6e   in os_unix.c an
b470: 64 20 6f 73 5f 77 69 6e 2e 63 20 61 67 72 65 65  d os_win.c agree
b480: 20 77 69 74 68 20 74 68 65 20 57 41 4c 49 4e 44   with the WALIND
b490: 45 58 5f 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 76  EX_LOCK_OFFSET v
b4a0: 61 6c 75 65 2e 0a 20 20 2a 2f 0a 23 69 66 64 65  alue..  */.#ifde
b4b0: 66 20 57 49 4e 5f 53 48 4d 5f 42 41 53 45 0a 20  f WIN_SHM_BASE. 
b4c0: 20 61 73 73 65 72 74 28 20 57 49 4e 5f 53 48 4d   assert( WIN_SHM
b4d0: 5f 42 41 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f  _BASE==WALINDEX_
b4e0: 4c 4f 43 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23  LOCK_OFFSET );.#
b4f0: 65 6e 64 69 66 0a 23 69 66 64 65 66 20 55 4e 49  endif.#ifdef UNI
b500: 58 5f 53 48 4d 5f 42 41 53 45 0a 20 20 61 73 73  X_SHM_BASE.  ass
b510: 65 72 74 28 20 55 4e 49 58 5f 53 48 4d 5f 42 41  ert( UNIX_SHM_BA
b520: 53 45 3d 3d 57 41 4c 49 4e 44 45 58 5f 4c 4f 43  SE==WALINDEX_LOC
b530: 4b 5f 4f 46 46 53 45 54 20 29 3b 0a 23 65 6e 64  K_OFFSET );.#end
b540: 69 66 0a 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61  if...  /* Alloca
b550: 74 65 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f  te an instance o
b560: 66 20 73 74 72 75 63 74 20 57 61 6c 20 74 6f 20  f struct Wal to 
b570: 72 65 74 75 72 6e 2e 20 2a 2f 0a 20 20 2a 70 70  return. */.  *pp
b580: 57 61 6c 20 3d 20 30 3b 0a 20 20 6e 57 61 6c 20  Wal = 0;.  nWal 
b590: 3d 20 73 71 6c 69 74 65 33 53 74 72 6c 65 6e 33  = sqlite3Strlen3
b5a0: 30 28 7a 44 62 4e 61 6d 65 29 20 2b 20 35 3b 0a  0(zDbName) + 5;.
b5b0: 20 20 70 52 65 74 20 3d 20 28 57 61 6c 2a 29 73    pRet = (Wal*)s
b5c0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f  qlite3MallocZero
b5d0: 28 73 69 7a 65 6f 66 28 57 61 6c 29 20 2b 20 70  (sizeof(Wal) + p
b5e0: 56 66 73 2d 3e 73 7a 4f 73 46 69 6c 65 20 2b 20  Vfs->szOsFile + 
b5f0: 6e 57 61 6c 29 3b 0a 20 20 69 66 28 20 21 70 52  nWal);.  if( !pR
b600: 65 74 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  et ){.    return
b610: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
b620: 20 7d 0a 0a 20 20 70 52 65 74 2d 3e 70 56 66 73   }..  pRet->pVfs
b630: 20 3d 20 70 56 66 73 3b 0a 20 20 70 52 65 74 2d   = pVfs;.  pRet-
b640: 3e 70 57 61 6c 46 64 20 3d 20 28 73 71 6c 69 74  >pWalFd = (sqlit
b650: 65 33 5f 66 69 6c 65 20 2a 29 26 70 52 65 74 5b  e3_file *)&pRet[
b660: 31 5d 3b 0a 20 20 70 52 65 74 2d 3e 70 44 62 46  1];.  pRet->pDbF
b670: 64 20 3d 20 70 44 62 46 64 3b 0a 20 20 70 52 65  d = pDbFd;.  pRe
b680: 74 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20 2d 31  t->readLock = -1
b690: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 72 61 6e 64  ;.  sqlite3_rand
b6a0: 6f 6d 6e 65 73 73 28 38 2c 20 26 70 52 65 74 2d  omness(8, &pRet-
b6b0: 3e 68 64 72 2e 61 53 61 6c 74 29 3b 0a 20 20 70  >hdr.aSalt);.  p
b6c0: 52 65 74 2d 3e 7a 57 61 6c 4e 61 6d 65 20 3d 20  Ret->zWalName = 
b6d0: 7a 57 61 6c 20 3d 20 70 56 66 73 2d 3e 73 7a 4f  zWal = pVfs->szO
b6e0: 73 46 69 6c 65 20 2b 20 28 63 68 61 72 2a 29 70  sFile + (char*)p
b6f0: 52 65 74 2d 3e 70 57 61 6c 46 64 3b 0a 20 20 73  Ret->pWalFd;.  s
b700: 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 28  qlite3_snprintf(
b710: 6e 57 61 6c 2c 20 7a 57 61 6c 2c 20 22 25 73 2d  nWal, zWal, "%s-
b720: 77 61 6c 22 2c 20 7a 44 62 4e 61 6d 65 29 3b 0a  wal", zDbName);.
b730: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
b740: 53 68 6d 4f 70 65 6e 28 70 44 62 46 64 29 3b 0a  ShmOpen(pDbFd);.
b750: 0a 20 20 2f 2a 20 4f 70 65 6e 20 66 69 6c 65 20  .  /* Open file 
b760: 68 61 6e 64 6c 65 20 6f 6e 20 74 68 65 20 77 72  handle on the wr
b770: 69 74 65 2d 61 68 65 61 64 20 6c 6f 67 20 66 69  ite-ahead log fi
b780: 6c 65 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  le. */.  if( rc=
b790: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
b7a0: 20 20 70 52 65 74 2d 3e 69 73 57 49 6e 64 65 78    pRet->isWIndex
b7b0: 4f 70 65 6e 20 3d 20 31 3b 0a 20 20 20 20 66 6c  Open = 1;.    fl
b7c0: 61 67 73 20 3d 20 28 53 51 4c 49 54 45 5f 4f 50  ags = (SQLITE_OP
b7d0: 45 4e 5f 52 45 41 44 57 52 49 54 45 7c 53 51 4c  EN_READWRITE|SQL
b7e0: 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54 45 7c  ITE_OPEN_CREATE|
b7f0: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e  SQLITE_OPEN_MAIN
b800: 5f 4a 4f 55 52 4e 41 4c 29 3b 0a 20 20 20 20 72  _JOURNAL);.    r
b810: 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 4f 70 65  c = sqlite3OsOpe
b820: 6e 28 70 56 66 73 2c 20 7a 57 61 6c 2c 20 70 52  n(pVfs, zWal, pR
b830: 65 74 2d 3e 70 57 61 6c 46 64 2c 20 66 6c 61 67  et->pWalFd, flag
b840: 73 2c 20 26 66 6c 61 67 73 29 3b 0a 20 20 7d 0a  s, &flags);.  }.
b850: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
b860: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 77 61 6c 49  E_OK ){.    walI
b870: 6e 64 65 78 43 6c 6f 73 65 28 70 52 65 74 2c 20  ndexClose(pRet, 
b880: 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f  0);.    sqlite3O
b890: 73 43 6c 6f 73 65 28 70 52 65 74 2d 3e 70 57 61  sClose(pRet->pWa
b8a0: 6c 46 64 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  lFd);.    sqlite
b8b0: 33 5f 66 72 65 65 28 70 52 65 74 29 3b 0a 20 20  3_free(pRet);.  
b8c0: 7d 65 6c 73 65 7b 0a 20 20 20 20 2a 70 70 57 61  }else{.    *ppWa
b8d0: 6c 20 3d 20 70 52 65 74 3b 0a 20 20 20 20 57 41  l = pRet;.    WA
b8e0: 4c 54 52 41 43 45 28 28 22 57 41 4c 25 64 3a 20  LTRACE(("WAL%d: 
b8f0: 6f 70 65 6e 65 64 5c 6e 22 2c 20 70 52 65 74 29  opened\n", pRet)
b900: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
b910: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e  rc;.}../*.** Fin
b920: 64 20 74 68 65 20 73 6d 61 6c 6c 65 73 74 20 70  d the smallest p
b930: 61 67 65 20 6e 75 6d 62 65 72 20 6f 75 74 20 6f  age number out o
b940: 66 20 61 6c 6c 20 70 61 67 65 73 20 68 65 6c 64  f all pages held
b950: 20 69 6e 20 74 68 65 20 57 41 4c 20 74 68 61 74   in the WAL that
b960: 0a 2a 2a 20 68 61 73 20 6e 6f 74 20 62 65 65 6e  .** has not been
b970: 20 72 65 74 75 72 6e 65 64 20 62 79 20 61 6e 79   returned by any
b980: 20 70 72 69 6f 72 20 69 6e 76 6f 63 61 74 69 6f   prior invocatio
b990: 6e 20 6f 66 20 74 68 69 73 20 6d 65 74 68 6f 64  n of this method
b9a0: 20 6f 6e 20 74 68 65 0a 2a 2a 20 73 61 6d 65 20   on the.** same 
b9b0: 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62 6a 65  WalIterator obje
b9c0: 63 74 2e 20 20 20 57 72 69 74 65 20 69 6e 74 6f  ct.   Write into
b9d0: 20 2a 70 69 46 72 61 6d 65 20 74 68 65 20 66 72   *piFrame the fr
b9e0: 61 6d 65 20 69 6e 64 65 78 20 77 68 65 72 65 0a  ame index where.
b9f0: 2a 2a 20 74 68 61 74 20 70 61 67 65 20 77 61 73  ** that page was
ba00: 20 6c 61 73 74 20 77 72 69 74 74 65 6e 20 69 6e   last written in
ba10: 74 6f 20 74 68 65 20 57 41 4c 2e 20 20 57 72 69  to the WAL.  Wri
ba20: 74 65 20 69 6e 74 6f 20 2a 70 69 50 61 67 65 20  te into *piPage 
ba30: 74 68 65 20 70 61 67 65 0a 2a 2a 20 6e 75 6d 62  the page.** numb
ba40: 65 72 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e  er..**.** Return
ba50: 20 30 20 6f 6e 20 73 75 63 63 65 73 73 2e 20 20   0 on success.  
ba60: 49 66 20 74 68 65 72 65 20 61 72 65 20 6e 6f 20  If there are no 
ba70: 70 61 67 65 73 20 69 6e 20 74 68 65 20 57 41 4c  pages in the WAL
ba80: 20 77 69 74 68 20 61 20 70 61 67 65 0a 2a 2a 20   with a page.** 
ba90: 6e 75 6d 62 65 72 20 6c 61 72 67 65 72 20 74 68  number larger th
baa0: 61 6e 20 2a 70 69 50 61 67 65 2c 20 74 68 65 6e  an *piPage, then
bab0: 20 72 65 74 75 72 6e 20 31 2e 0a 2a 2f 0a 73 74   return 1..*/.st
bac0: 61 74 69 63 20 69 6e 74 20 77 61 6c 49 74 65 72  atic int walIter
bad0: 61 74 6f 72 4e 65 78 74 28 0a 20 20 57 61 6c 49  atorNext(.  WalI
bae0: 74 65 72 61 74 6f 72 20 2a 70 2c 20 20 20 20 20  terator *p,     
baf0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 74 65            /* Ite
bb00: 72 61 74 6f 72 20 2a 2f 0a 20 20 75 33 32 20 2a  rator */.  u32 *
bb10: 70 69 50 61 67 65 2c 20 20 20 20 20 20 20 20 20  piPage,         
bb20: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
bb30: 20 54 68 65 20 70 61 67 65 20 6e 75 6d 62 65 72   The page number
bb40: 20 6f 66 20 74 68 65 20 6e 65 78 74 20 70 61 67   of the next pag
bb50: 65 20 2a 2f 0a 20 20 75 33 32 20 2a 70 69 46 72  e */.  u32 *piFr
bb60: 61 6d 65 20 20 20 20 20 20 20 20 20 20 20 20 20  ame             
bb70: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 57 61 6c       /* OUT: Wal
bb80: 20 66 72 61 6d 65 20 69 6e 64 65 78 20 6f 66 20   frame index of 
bb90: 6e 65 78 74 20 70 61 67 65 20 2a 2f 0a 29 7b 0a  next page */.){.
bba0: 20 20 75 33 32 20 69 4d 69 6e 3b 20 20 20 20 20    u32 iMin;     
bbb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bbc0: 2f 2a 20 52 65 73 75 6c 74 20 70 67 6e 6f 20 6d  /* Result pgno m
bbd0: 75 73 74 20 62 65 20 67 72 65 61 74 65 72 20 74  ust be greater t
bbe0: 68 61 6e 20 69 4d 69 6e 20 2a 2f 0a 20 20 75 33  han iMin */.  u3
bbf0: 32 20 69 52 65 74 20 3d 20 30 78 46 46 46 46 46  2 iRet = 0xFFFFF
bc00: 46 46 46 3b 20 20 20 20 20 20 20 20 2f 2a 20 30  FFF;        /* 0
bc10: 78 66 66 66 66 66 66 66 66 20 69 73 20 6e 65 76  xffffffff is nev
bc20: 65 72 20 61 20 76 61 6c 69 64 20 70 61 67 65 20  er a valid page 
bc30: 6e 75 6d 62 65 72 20 2a 2f 0a 20 20 69 6e 74 20  number */.  int 
bc40: 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i;              
bc50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72            /* For
bc60: 20 6c 6f 6f 70 69 6e 67 20 74 68 72 6f 75 67 68   looping through
bc70: 20 73 65 67 6d 65 6e 74 73 20 2a 2f 0a 0a 20 20   segments */..  
bc80: 69 4d 69 6e 20 3d 20 70 2d 3e 69 50 72 69 6f 72  iMin = p->iPrior
bc90: 3b 0a 20 20 61 73 73 65 72 74 28 20 69 4d 69 6e  ;.  assert( iMin
bca0: 3c 30 78 66 66 66 66 66 66 66 66 20 29 3b 0a 20  <0xffffffff );. 
bcb0: 20 66 6f 72 28 69 3d 70 2d 3e 6e 53 65 67 6d 65   for(i=p->nSegme
bcc0: 6e 74 2d 31 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29  nt-1; i>=0; i--)
bcd0: 7b 0a 20 20 20 20 73 74 72 75 63 74 20 57 61 6c  {.    struct Wal
bce0: 53 65 67 6d 65 6e 74 20 2a 70 53 65 67 6d 65 6e  Segment *pSegmen
bcf0: 74 20 3d 20 26 70 2d 3e 61 53 65 67 6d 65 6e 74  t = &p->aSegment
bd00: 5b 69 5d 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  [i];.    while( 
bd10: 70 53 65 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 3c  pSegment->iNext<
bd20: 70 53 65 67 6d 65 6e 74 2d 3e 6e 45 6e 74 72 79  pSegment->nEntry
bd30: 20 29 7b 0a 20 20 20 20 20 20 75 33 32 20 69 50   ){.      u32 iP
bd40: 67 20 3d 20 70 53 65 67 6d 65 6e 74 2d 3e 61 50  g = pSegment->aP
bd50: 67 6e 6f 5b 70 53 65 67 6d 65 6e 74 2d 3e 61 49  gno[pSegment->aI
bd60: 6e 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69  ndex[pSegment->i
bd70: 4e 65 78 74 5d 5d 3b 0a 20 20 20 20 20 20 69 66  Next]];.      if
bd80: 28 20 69 50 67 3e 69 4d 69 6e 20 29 7b 0a 20 20  ( iPg>iMin ){.  
bd90: 20 20 20 20 20 20 69 66 28 20 69 50 67 3c 69 52        if( iPg<iR
bda0: 65 74 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  et ){.          
bdb0: 69 52 65 74 20 3d 20 69 50 67 3b 0a 20 20 20 20  iRet = iPg;.    
bdc0: 20 20 20 20 20 20 2a 70 69 46 72 61 6d 65 20 3d        *piFrame =
bdd0: 20 70 53 65 67 6d 65 6e 74 2d 3e 69 5a 65 72 6f   pSegment->iZero
bde0: 20 2b 20 70 53 65 67 6d 65 6e 74 2d 3e 61 49 6e   + pSegment->aIn
bdf0: 64 65 78 5b 70 53 65 67 6d 65 6e 74 2d 3e 69 4e  dex[pSegment->iN
be00: 65 78 74 5d 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ext];.        }.
be10: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
be20: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 53 65       }.      pSe
be30: 67 6d 65 6e 74 2d 3e 69 4e 65 78 74 2b 2b 3b 0a  gment->iNext++;.
be40: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 69      }.  }..  *pi
be50: 50 61 67 65 20 3d 20 70 2d 3e 69 50 72 69 6f 72  Page = p->iPrior
be60: 20 3d 20 69 52 65 74 3b 0a 20 20 72 65 74 75 72   = iRet;.  retur
be70: 6e 20 28 69 52 65 74 3d 3d 30 78 46 46 46 46 46  n (iRet==0xFFFFF
be80: 46 46 46 29 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63  FFF);.}...static
be90: 20 76 6f 69 64 20 77 61 6c 4d 65 72 67 65 73 6f   void walMergeso
bea0: 72 74 28 0a 20 20 75 33 32 20 2a 61 43 6f 6e 74  rt(.  u32 *aCont
beb0: 65 6e 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  ent,            
bec0: 20 20 20 20 20 20 2f 2a 20 50 61 67 65 73 20 69        /* Pages i
bed0: 6e 20 77 61 6c 20 2a 2f 0a 20 20 68 74 5f 73 6c  n wal */.  ht_sl
bee0: 6f 74 20 2a 61 42 75 66 66 65 72 2c 20 20 20 20  ot *aBuffer,    
bef0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75             /* Bu
bf00: 66 66 65 72 20 6f 66 20 61 74 20 6c 65 61 73 74  ffer of at least
bf10: 20 2a 70 6e 4c 69 73 74 20 69 74 65 6d 73 20 74   *pnList items t
bf20: 6f 20 75 73 65 20 2a 2f 0a 20 20 68 74 5f 73 6c  o use */.  ht_sl
bf30: 6f 74 20 2a 61 4c 69 73 74 2c 20 20 20 20 20 20  ot *aList,      
bf40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 4e             /* IN
bf50: 2f 4f 55 54 3a 20 4c 69 73 74 20 74 6f 20 73 6f  /OUT: List to so
bf60: 72 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 4c  rt */.  int *pnL
bf70: 69 73 74 20 20 20 20 20 20 20 20 20 20 20 20 20  ist             
bf80: 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55          /* IN/OU
bf90: 54 3a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65  T: Number of ele
bfa0: 6d 65 6e 74 73 20 69 6e 20 61 4c 69 73 74 5b 5d  ments in aList[]
bfb0: 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 6e 4c 69   */.){.  int nLi
bfc0: 73 74 20 3d 20 2a 70 6e 4c 69 73 74 3b 0a 20 20  st = *pnList;.  
bfd0: 69 66 28 20 6e 4c 69 73 74 3e 31 20 29 7b 0a 20  if( nList>1 ){. 
bfe0: 20 20 20 69 6e 74 20 6e 4c 65 66 74 20 3d 20 6e     int nLeft = n
bff0: 4c 69 73 74 20 2f 20 32 3b 20 20 20 20 20 20 20  List / 2;       
c000: 20 2f 2a 20 45 6c 65 6d 65 6e 74 73 20 69 6e 20   /* Elements in 
c010: 6c 65 66 74 20 6c 69 73 74 20 2a 2f 0a 20 20 20  left list */.   
c020: 20 69 6e 74 20 6e 52 69 67 68 74 20 3d 20 6e 4c   int nRight = nL
c030: 69 73 74 20 2d 20 6e 4c 65 66 74 3b 20 20 20 2f  ist - nLeft;   /
c040: 2a 20 45 6c 65 6d 65 6e 74 73 20 69 6e 20 72 69  * Elements in ri
c050: 67 68 74 20 6c 69 73 74 20 2a 2f 0a 20 20 20 20  ght list */.    
c060: 69 6e 74 20 69 4c 65 66 74 20 3d 20 30 3b 20 20  int iLeft = 0;  
c070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c080: 20 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69   Current index i
c090: 6e 20 61 4c 65 66 74 20 2a 2f 0a 20 20 20 20 69  n aLeft */.    i
c0a0: 6e 74 20 69 52 69 67 68 74 20 3d 20 30 3b 20 20  nt iRight = 0;  
c0b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c0c0: 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e  Current index in
c0d0: 20 61 72 69 67 68 74 20 2a 2f 0a 20 20 20 20 69   aright */.    i
c0e0: 6e 74 20 69 4f 75 74 20 3d 20 30 3b 20 20 20 20  nt iOut = 0;    
c0f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c100: 43 75 72 72 65 6e 74 20 69 6e 64 65 78 20 69 6e  Current index in
c110: 20 6f 75 74 70 75 74 20 62 75 66 66 65 72 20 2a   output buffer *
c120: 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20 2a 61  /.    ht_slot *a
c130: 4c 65 66 74 20 3d 20 61 4c 69 73 74 3b 20 20 20  Left = aList;   
c140: 20 20 20 20 2f 2a 20 4c 65 66 74 20 6c 69 73 74      /* Left list
c150: 20 2a 2f 0a 20 20 20 20 68 74 5f 73 6c 6f 74 20   */.    ht_slot 
c160: 2a 61 52 69 67 68 74 20 3d 20 61 4c 69 73 74 2b  *aRight = aList+
c170: 6e 4c 65 66 74 3b 2f 2a 20 52 69 67 68 74 20 6c  nLeft;/* Right l
c180: 69 73 74 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 54  ist */..    /* T
c190: 4f 44 4f 3a 20 43 68 61 6e 67 65 20 74 6f 20 6e  ODO: Change to n
c1a0: 6f 6e 2d 72 65 63 75 72 73 69 76 65 20 76 65 72  on-recursive ver
c1b0: 73 69 6f 6e 2e 20 2a 2f 0a 20 20 20 20 77 61 6c  sion. */.    wal
c1c0: 4d 65 72 67 65 73 6f 72 74 28 61 43 6f 6e 74 65  Mergesort(aConte
c1d0: 6e 74 2c 20 61 42 75 66 66 65 72 2c 20 61 4c 65  nt, aBuffer, aLe
c1e0: 66 74 2c 20 26 6e 4c 65 66 74 29 3b 0a 20 20 20  ft, &nLeft);.   
c1f0: 20 77 61 6c 4d 65 72 67 65 73 6f 72 74 28 61 43   walMergesort(aC
c200: 6f 6e 74 65 6e 74 2c 20 61 42 75 66 66 65 72 2c  ontent, aBuffer,
c210: 20 61 52 69 67 68 74 2c 20 26 6e 52 69 67 68 74   aRight, &nRight
c220: 29 3b 0a 0a 20 20 20 20 77 68 69 6c 65 28 20 69  );..    while( i
c230: 52 69 67 68 74 3c 6e 52 69 67 68 74 20 7c 7c 20  Right<nRight || 
c240: 69 4c 65 66 74 3c 6e 4c 65 66 74 20 29 7b 0a 20  iLeft<nLeft ){. 
c250: 20 20 20 20 20 68 74 5f 73 6c 6f 74 20 6c 6f 67       ht_slot log
c260: 70 61 67 65 3b 0a 20 20 20 20 20 20 50 67 6e 6f  page;.      Pgno
c270: 20 64 62 70 61 67 65 3b 0a 0a 20 20 20 20 20 20   dbpage;..      
c280: 69 66 28 20 28 69 4c 65 66 74 3c 6e 4c 65 66 74  if( (iLeft<nLeft
c290: 29 20 0a 20 20 20 20 20 20 20 26 26 20 28 69 52  ) .       && (iR
c2a0: 69 67 68 74 3e 3d 6e 52 69 67 68 74 20 7c 7c 20  ight>=nRight || 
c2b0: 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74 5b 69  aContent[aLeft[i
c2c0: 4c 65 66 74 5d 5d 3c 61 43 6f 6e 74 65 6e 74 5b  Left]]<aContent[
c2d0: 61 52 69 67 68 74 5b 69 52 69 67 68 74 5d 5d 29  aRight[iRight]])
c2e0: 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20  .      ){.      
c2f0: 20 20 6c 6f 67 70 61 67 65 20 3d 20 61 4c 65 66    logpage = aLef
c300: 74 5b 69 4c 65 66 74 2b 2b 5d 3b 0a 20 20 20 20  t[iLeft++];.    
c310: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
c320: 20 6c 6f 67 70 61 67 65 20 3d 20 61 52 69 67 68   logpage = aRigh
c330: 74 5b 69 52 69 67 68 74 2b 2b 5d 3b 0a 20 20 20  t[iRight++];.   
c340: 20 20 20 7d 0a 20 20 20 20 20 20 64 62 70 61 67     }.      dbpag
c350: 65 20 3d 20 61 43 6f 6e 74 65 6e 74 5b 6c 6f 67  e = aContent[log
c360: 70 61 67 65 5d 3b 0a 0a 20 20 20 20 20 20 61 42  page];..      aB
c370: 75 66 66 65 72 5b 69 4f 75 74 2b 2b 5d 20 3d 20  uffer[iOut++] = 
c380: 6c 6f 67 70 61 67 65 3b 0a 20 20 20 20 20 20 69  logpage;.      i
c390: 66 28 20 69 4c 65 66 74 3c 6e 4c 65 66 74 20 26  f( iLeft<nLeft &
c3a0: 26 20 61 43 6f 6e 74 65 6e 74 5b 61 4c 65 66 74  & aContent[aLeft
c3b0: 5b 69 4c 65 66 74 5d 5d 3d 3d 64 62 70 61 67 65  [iLeft]]==dbpage
c3c0: 20 29 20 69 4c 65 66 74 2b 2b 3b 0a 0a 20 20 20   ) iLeft++;..   
c3d0: 20 20 20 61 73 73 65 72 74 28 20 69 4c 65 66 74     assert( iLeft
c3e0: 3e 3d 6e 4c 65 66 74 20 7c 7c 20 61 43 6f 6e 74  >=nLeft || aCont
c3f0: 65 6e 74 5b 61 4c 65 66 74 5b 69 4c 65 66 74 5d  ent[aLeft[iLeft]
c400: 5d 3e 64 62 70 61 67 65 20 29 3b 0a 20 20 20 20  ]>dbpage );.    
c410: 20 20 61 73 73 65 72 74 28 20 69 52 69 67 68 74    assert( iRight
c420: 3e 3d 6e 52 69 67 68 74 20 7c 7c 20 61 43 6f 6e  >=nRight || aCon
c430: 74 65 6e 74 5b 61 52 69 67 68 74 5b 69 52 69 67  tent[aRight[iRig
c440: 68 74 5d 5d 3e 64 62 70 61 67 65 20 29 3b 0a 20  ht]]>dbpage );. 
c450: 20 20 20 7d 0a 20 20 20 20 6d 65 6d 63 70 79 28     }.    memcpy(
c460: 61 4c 69 73 74 2c 20 61 42 75 66 66 65 72 2c 20  aList, aBuffer, 
c470: 73 69 7a 65 6f 66 28 61 4c 69 73 74 5b 30 5d 29  sizeof(aList[0])
c480: 2a 69 4f 75 74 29 3b 0a 20 20 20 20 2a 70 6e 4c  *iOut);.    *pnL
c490: 69 73 74 20 3d 20 69 4f 75 74 3b 0a 20 20 7d 0a  ist = iOut;.  }.
c4a0: 0a 23 69 66 64 65 66 20 53 51 4c 49 54 45 5f 44  .#ifdef SQLITE_D
c4b0: 45 42 55 47 0a 20 20 7b 0a 20 20 20 20 69 6e 74  EBUG.  {.    int
c4c0: 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b   i;.    for(i=1;
c4d0: 20 69 3c 2a 70 6e 4c 69 73 74 3b 20 69 2b 2b 29   i<*pnList; i++)
c4e0: 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  {.      assert( 
c4f0: 61 43 6f 6e 74 65 6e 74 5b 61 4c 69 73 74 5b 69  aContent[aList[i
c500: 5d 5d 20 3e 20 61 43 6f 6e 74 65 6e 74 5b 61 4c  ]] > aContent[aL
c510: 69 73 74 5b 69 2d 31 5d 5d 20 29 3b 0a 20 20 20  ist[i-1]] );.   
c520: 20 7d 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 7d 0a   }.  }.#endif.}.
c530: 0a 2f 2a 20 0a 2a 2a 20 46 72 65 65 20 61 6e 20  ./* .** Free an 
c540: 69 74 65 72 61 74 6f 72 20 61 6c 6c 6f 63 61 74  iterator allocat
c550: 65 64 20 62 79 20 77 61 6c 49 74 65 72 61 74 6f  ed by walIterato
c560: 72 49 6e 69 74 28 29 2e 0a 2a 2f 0a 73 74 61 74  rInit()..*/.stat
c570: 69 63 20 76 6f 69 64 20 77 61 6c 49 74 65 72 61  ic void walItera
c580: 74 6f 72 46 72 65 65 28 57 61 6c 49 74 65 72 61  torFree(WalItera
c590: 74 6f 72 20 2a 70 29 7b 0a 20 20 73 71 6c 69 74  tor *p){.  sqlit
c5a0: 65 33 5f 66 72 65 65 28 70 29 3b 0a 7d 0a 0a 2f  e3_free(p);.}../
c5b0: 2a 0a 2a 2a 20 4d 61 70 20 74 68 65 20 77 61 6c  *.** Map the wal
c5c0: 2d 69 6e 64 65 78 20 69 6e 74 6f 20 6d 65 6d 6f  -index into memo
c5d0: 72 79 20 6f 77 6e 65 64 20 62 79 20 74 68 69 73  ry owned by this
c5e0: 20 74 68 72 65 61 64 2c 20 69 66 20 69 74 20 69   thread, if it i
c5f0: 73 20 6e 6f 74 0a 2a 2a 20 6d 61 70 70 65 64 20  s not.** mapped 
c600: 61 6c 72 65 61 64 79 2e 20 20 54 68 65 6e 20 63  already.  Then c
c610: 6f 6e 73 74 72 75 63 74 20 61 20 57 61 6c 49 6e  onstruct a WalIn
c620: 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 20 74  terator object t
c630: 68 61 74 20 63 61 6e 20 62 65 0a 2a 2a 20 75 73  hat can be.** us
c640: 65 64 20 74 6f 20 6c 6f 6f 70 20 6f 76 65 72 20  ed to loop over 
c650: 61 6c 6c 20 70 61 67 65 73 20 69 6e 20 74 68 65  all pages in the
c660: 20 57 41 4c 20 69 6e 20 61 73 63 65 6e 64 69 6e   WAL in ascendin
c670: 67 20 6f 72 64 65 72 2e 20 20 0a 2a 2a 0a 2a 2a  g order.  .**.**
c680: 20 4f 6e 20 73 75 63 63 65 73 73 2c 20 6d 61 6b   On success, mak
c690: 65 20 2a 70 70 20 70 6f 69 6e 74 20 74 6f 20 74  e *pp point to t
c6a0: 68 65 20 6e 65 77 6c 79 20 61 6c 6c 6f 63 61 74  he newly allocat
c6b0: 65 64 20 57 61 6c 49 6e 74 65 72 61 74 6f 72 20  ed WalInterator 
c6c0: 6f 62 6a 65 63 74 0a 2a 2a 20 72 65 74 75 72 6e  object.** return
c6d0: 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 20 4f 74 68   SQLITE_OK.  Oth
c6e0: 65 72 77 69 73 65 2c 20 6c 65 61 76 65 20 2a 70  erwise, leave *p
c6f0: 70 20 75 6e 63 68 61 6e 67 65 64 20 61 6e 64 20  p unchanged and 
c700: 72 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72 0a  return an error.
c710: 2a 2a 20 63 6f 64 65 2e 0a 2a 2a 0a 2a 2a 20 54  ** code..**.** T
c720: 68 65 20 63 61 6c 6c 69 6e 67 20 72 6f 75 74 69  he calling routi
c730: 6e 65 20 73 68 6f 75 6c 64 20 69 6e 76 6f 6b 65  ne should invoke
c740: 20 77 61 6c 49 74 65 72 61 74 6f 72 46 72 65 65   walIteratorFree
c750: 28 29 20 74 6f 20 64 65 73 74 72 6f 79 20 74 68  () to destroy th
c760: 65 0a 2a 2a 20 57 61 6c 49 74 65 72 61 74 6f 72  e.** WalIterator
c770: 20 6f 62 6a 65 63 74 20 77 68 65 6e 20 69 74 20   object when it 
c780: 68 61 73 20 66 69 6e 69 73 68 65 64 20 77 69 74  has finished wit
c790: 68 20 69 74 2e 20 20 54 68 65 20 63 61 6c 6c 65  h it.  The calle
c7a0: 72 20 6d 75 73 74 0a 2a 2a 20 61 6c 73 6f 20 75  r must.** also u
c7b0: 6e 6d 61 70 20 74 68 65 20 77 61 6c 2d 69 6e 64  nmap the wal-ind
c7c0: 65 78 2e 20 20 42 75 74 20 74 68 65 20 77 61 6c  ex.  But the wal
c7d0: 2d 69 6e 64 65 78 20 6d 75 73 74 20 6e 6f 74 20  -index must not 
c7e0: 62 65 20 75 6e 6d 61 70 70 65 64 0a 2a 2a 20 70  be unmapped.** p
c7f0: 72 69 6f 72 20 74 6f 20 74 68 65 20 57 61 6c 49  rior to the WalI
c800: 74 65 72 61 74 6f 72 20 6f 62 6a 65 63 74 20 62  terator object b
c810: 65 69 6e 67 20 64 65 73 74 72 6f 79 65 64 2e 0a  eing destroyed..
c820: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77 61  */.static int wa
c830: 6c 49 74 65 72 61 74 6f 72 49 6e 69 74 28 57 61  lIteratorInit(Wa
c840: 6c 20 2a 70 57 61 6c 2c 20 57 61 6c 49 74 65 72  l *pWal, WalIter
c850: 61 74 6f 72 20 2a 2a 70 70 29 7b 0a 20 20 57 61  ator **pp){.  Wa
c860: 6c 49 74 65 72 61 74 6f 72 20 2a 70 3b 20 20 20  lIterator *p;   
c870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
c880: 20 52 65 74 75 72 6e 20 76 61 6c 75 65 20 2a 2f   Return value */
c890: 0a 20 20 69 6e 74 20 6e 53 65 67 6d 65 6e 74 3b  .  int nSegment;
c8a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c8b0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
c8c0: 73 65 67 6d 65 6e 74 73 20 74 6f 20 6d 65 72 67  segments to merg
c8d0: 65 20 2a 2f 0a 20 20 75 33 32 20 69 4c 61 73 74  e */.  u32 iLast
c8e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
c8f0: 20 20 20 20 20 20 20 2f 2a 20 4c 61 73 74 20 66         /* Last f
c900: 72 61 6d 65 20 69 6e 20 6c 6f 67 20 2a 2f 0a 20  rame in log */. 
c910: 20 69 6e 74 20 6e 42 79 74 65 3b 20 20 20 20 20   int nByte;     
c920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c930: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
c940: 74 65 73 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  tes to allocate 
c950: 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20  */.  int i;     
c960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c970: 20 20 20 20 20 2f 2a 20 49 74 65 72 61 74 6f 72       /* Iterator
c980: 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 68   variable */.  h
c990: 74 5f 73 6c 6f 74 20 2a 61 54 6d 70 3b 20 20 20  t_slot *aTmp;   
c9a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c9b0: 2a 20 54 65 6d 70 20 73 70 61 63 65 20 75 73 65  * Temp space use
c9c0: 64 20 62 79 20 6d 65 72 67 65 2d 73 6f 72 74 20  d by merge-sort 
c9d0: 2a 2f 0a 20 20 68 74 5f 73 6c 6f 74 20 2a 61 53  */.  ht_slot *aS
c9e0: 70 61 63 65 3b 20 20 20 20 20 20 20 20 20 20 20  pace;           
c9f0: 20 20 20 20 20 2f 2a 20 53 70 61 63 65 20 61 74       /* Space at
ca00: 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
ca10: 61 6c 6c 6f 63 61 74 69 6f 6e 20 2a 2f 0a 0a 20  allocation */.. 
ca20: 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65   /* This routine
ca30: 20 6f 6e 6c 79 20 72 75 6e 73 20 77 68 69 6c 65   only runs while
ca40: 20 68 6f 6c 64 69 6e 67 20 53 51 4c 49 54 45 5f   holding SQLITE_
ca50: 53 48 4d 5f 43 48 45 43 4b 50 4f 49 4e 54 2e 20  SHM_CHECKPOINT. 
ca60: 20 4e 6f 20 6f 74 68 65 72 0a 20 20 2a 2a 20 74   No other.  ** t
ca70: 68 72 65 61 64 20 69 73 20 61 62 6c 65 20 74 6f  hread is able to
ca80: 20 77 72 69 74 65 20 74 6f 20 73 68 61 72 65 64   write to shared
ca90: 20 6d 65 6d 6f 72 79 20 77 68 69 6c 65 20 74 68   memory while th
caa0: 69 73 20 72 6f 75 74 69 6e 65 20 69 73 0a 20 20  is routine is.  
cab0: 2a 2a 20 72 75 6e 6e 69 6e 67 20 28 6f 72 2c 20  ** running (or, 
cac0: 69 6e 64 65 65 64 2c 20 77 68 69 6c 65 20 74 68  indeed, while th
cad0: 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f 62  e WalIterator ob
cae0: 6a 65 63 74 20 65 78 69 73 74 73 29 2e 20 20 48  ject exists).  H
caf0: 65 6e 63 65 2c 0a 20 20 2a 2a 20 77 65 20 63 61  ence,.  ** we ca
cb00: 6e 20 63 61 73 74 20 6f 66 66 20 74 68 65 20 76  n cast off the v
cb10: 6f 6c 61 74 69 6c 65 20 71 75 61 6c 69 66 69 63  olatile qualific
cb20: 61 74 69 6f 6e 20 66 72 6f 6d 20 73 68 61 72 65  ation from share
cb30: 64 20 6d 65 6d 6f 72 79 0a 20 20 2a 2f 0a 20 20  d memory.  */.  
cb40: 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 63 6b  assert( pWal->ck
cb50: 70 74 4c 6f 63 6b 20 29 3b 0a 20 20 69 4c 61 73  ptLock );.  iLas
cb60: 74 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  t = pWal->hdr.mx
cb70: 46 72 61 6d 65 3b 0a 0a 20 20 2f 2a 20 41 6c 6c  Frame;..  /* All
cb80: 6f 63 61 74 65 20 73 70 61 63 65 20 66 6f 72 20  ocate space for 
cb90: 74 68 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20  the WalIterator 
cba0: 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 6e 53 65 67  object */.  nSeg
cbb0: 6d 65 6e 74 20 3d 20 77 61 6c 46 72 61 6d 65 50  ment = walFrameP
cbc0: 61 67 65 28 69 4c 61 73 74 29 20 2b 20 31 3b 0a  age(iLast) + 1;.
cbd0: 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66    nByte = sizeof
cbe0: 28 57 61 6c 49 74 65 72 61 74 6f 72 29 20 0a 20  (WalIterator) . 
cbf0: 20 20 20 20 20 20 20 2b 20 6e 53 65 67 6d 65 6e         + nSegmen
cc00: 74 2a 28 73 69 7a 65 6f 66 28 73 74 72 75 63 74  t*(sizeof(struct
cc10: 20 57 61 6c 53 65 67 6d 65 6e 74 29 29 0a 20 20   WalSegment)).  
cc20: 20 20 20 20 20 20 2b 20 28 6e 53 65 67 6d 65 6e        + (nSegmen
cc30: 74 2b 31 29 2a 28 48 41 53 48 54 41 42 4c 45 5f  t+1)*(HASHTABLE_
cc40: 4e 50 41 47 45 20 2a 20 73 69 7a 65 6f 66 28 68  NPAGE * sizeof(h
cc50: 74 5f 73 6c 6f 74 29 29 3b 0a 20 20 70 20 3d 20  t_slot));.  p = 
cc60: 28 57 61 6c 49 74 65 72 61 74 6f 72 20 2a 29 73  (WalIterator *)s
cc70: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 42  qlite3_malloc(nB
cc80: 79 74 65 29 3b 0a 20 20 69 66 28 20 21 70 20 29  yte);.  if( !p )
cc90: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
cca0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20  ITE_NOMEM;.  }. 
ccb0: 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 6e 42   memset(p, 0, nB
ccc0: 79 74 65 29 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f  yte);..  /* Allo
ccd0: 63 61 74 65 20 73 70 61 63 65 20 66 6f 72 20 74  cate space for t
cce0: 68 65 20 57 61 6c 49 74 65 72 61 74 6f 72 20 6f  he WalIterator o
ccf0: 62 6a 65 63 74 20 2a 2f 0a 20 20 70 2d 3e 6e 53  bject */.  p->nS
cd00: 65 67 6d 65 6e 74 20 3d 20 6e 53 65 67 6d 65 6e  egment = nSegmen
cd10: 74 3b 0a 20 20 61 53 70 61 63 65 20 3d 20 28 68  t;.  aSpace = (h
cd20: 74 5f 73 6c 6f 74 20 2a 29 26 70 2d 3e 61 53 65  t_slot *)&p->aSe
cd30: 67 6d 65 6e 74 5b 6e 53 65 67 6d 65 6e 74 5d 3b  gment[nSegment];
cd40: 0a 20 20 61 54 6d 70 20 3d 20 26 61 53 70 61 63  .  aTmp = &aSpac
cd50: 65 5b 48 41 53 48 54 41 42 4c 45 5f 4e 50 41 47  e[HASHTABLE_NPAG
cd60: 45 2a 6e 53 65 67 6d 65 6e 74 5d 3b 0a 20 20 66  E*nSegment];.  f
cd70: 6f 72 28 69 3d 30 3b 20 69 3c 6e 53 65 67 6d 65  or(i=0; i<nSegme
cd80: 6e 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 76 6f  nt; i++){.    vo
cd90: 6c 61 74 69 6c 65 20 68 74 5f 73 6c 6f 74 20 2a  latile ht_slot *
cda0: 61 48 61 73 68 3b 0a 20 20 20 20 69 6e 74 20 6a  aHash;.    int j
cdb0: 3b 0a 20 20 20 20 75 33 32 20 69 5a 65 72 6f 3b  ;.    u32 iZero;
cdc0: 0a 20 20 20 20 69 6e 74 20 6e 45 6e 74 72 79 3b  .    int nEntry;
cdd0: 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75 33  .    volatile u3
cde0: 32 20 2a 61 50 67 6e 6f 3b 0a 20 20 20 20 69 6e  2 *aPgno;.    in
cdf0: 74 20 72 63 3b 0a 0a 20 20 20 20 72 63 20 3d 20  t rc;..    rc = 
ce00: 77 61 6c 48 61 73 68 47 65 74 28 70 57 61 6c 2c  walHashGet(pWal,
ce10: 20 69 2c 20 26 61 48 61 73 68 2c 20 26 61 50 67   i, &aHash, &aPg
ce20: 6e 6f 2c 20 26 69 5a 65 72 6f 29 3b 0a 20 20 20  no, &iZero);.   
ce30: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
ce40: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 77 61 6c 49  OK ){.      walI
ce50: 74 65 72 61 74 6f 72 46 72 65 65 28 70 29 3b 0a  teratorFree(p);.
ce60: 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
ce70: 0a 20 20 20 20 7d 0a 20 20 20 20 61 50 67 6e 6f  .    }.    aPgno
ce80: 2b 2b 3b 0a 20 20 20 20 6e 45 6e 74 72 79 20 3d  ++;.    nEntry =
ce90: 20 28 28 69 2b 31 29 3d 3d 6e 53 65 67 6d 65 6e   ((i+1)==nSegmen
cea0: 74 29 3f 69 4c 61 73 74 2d 69 5a 65 72 6f 3a 28  t)?iLast-iZero:(
ceb0: 75 33 32 20 2a 29 61 48 61 73 68 2d 28 75 33 32  u32 *)aHash-(u32
cec0: 20 2a 29 61 50 67 6e 6f 3b 0a 20 20 20 20 69 5a   *)aPgno;.    iZ
ced0: 65 72 6f 2b 2b 3b 0a 0a 20 20 20 20 66 6f 72 28  ero++;..    for(
cee0: 6a 3d 30 3b 20 6a 3c 6e 45 6e 74 72 79 3b 20 6a  j=0; j<nEntry; j
cef0: 2b 2b 29 7b 0a 20 20 20 20 20 20 61 53 70 61 63  ++){.      aSpac
cf00: 65 5b 6a 5d 20 3d 20 6a 3b 0a 20 20 20 20 7d 0a  e[j] = j;.    }.
cf10: 20 20 20 20 77 61 6c 4d 65 72 67 65 73 6f 72 74      walMergesort
cf20: 28 28 75 33 32 20 2a 29 61 50 67 6e 6f 2c 20 61  ((u32 *)aPgno, a
cf30: 54 6d 70 2c 20 61 53 70 61 63 65 2c 20 26 6e 45  Tmp, aSpace, &nE
cf40: 6e 74 72 79 29 3b 0a 20 20 20 20 70 2d 3e 61 53  ntry);.    p->aS
cf50: 65 67 6d 65 6e 74 5b 69 5d 2e 69 5a 65 72 6f 20  egment[i].iZero 
cf60: 3d 20 69 5a 65 72 6f 3b 0a 20 20 20 20 70 2d 3e  = iZero;.    p->
cf70: 61 53 65 67 6d 65 6e 74 5b 69 5d 2e 6e 45 6e 74  aSegment[i].nEnt
cf80: 72 79 20 3d 20 6e 45 6e 74 72 79 3b 0a 20 20 20  ry = nEntry;.   
cf90: 20 70 2d 3e 61 53 65 67 6d 65 6e 74 5b 69 5d 2e   p->aSegment[i].
cfa0: 61 49 6e 64 65 78 20 3d 20 61 53 70 61 63 65 3b  aIndex = aSpace;
cfb0: 0a 20 20 20 20 70 2d 3e 61 53 65 67 6d 65 6e 74  .    p->aSegment
cfc0: 5b 69 5d 2e 61 50 67 6e 6f 20 3d 20 28 75 33 32  [i].aPgno = (u32
cfd0: 20 2a 29 61 50 67 6e 6f 3b 0a 20 20 20 20 61 53   *)aPgno;.    aS
cfe0: 70 61 63 65 20 2b 3d 20 48 41 53 48 54 41 42 4c  pace += HASHTABL
cff0: 45 5f 4e 50 41 47 45 3b 0a 20 20 7d 0a 20 20 61  E_NPAGE;.  }.  a
d000: 73 73 65 72 74 28 20 61 53 70 61 63 65 3d 3d 61  ssert( aSpace==a
d010: 54 6d 70 20 29 3b 0a 0a 20 20 2f 2a 20 52 65 74  Tmp );..  /* Ret
d020: 75 72 6e 20 74 68 65 20 66 75 6c 6c 79 20 69 6e  urn the fully in
d030: 69 74 69 61 6c 69 7a 65 64 20 57 61 6c 49 74 65  itialized WalIte
d040: 72 61 74 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a  rator object */.
d050: 20 20 2a 70 70 20 3d 20 70 3b 0a 20 20 72 65 74    *pp = p;.  ret
d060: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 3b 0a  urn SQLITE_OK ;.
d070: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 61 73  }../*.** Copy as
d080: 20 6d 75 63 68 20 63 6f 6e 74 65 6e 74 20 61 73   much content as
d090: 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 74 68 65   we can from the
d0a0: 20 57 41 4c 20 62 61 63 6b 20 69 6e 74 6f 20 74   WAL back into t
d0b0: 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c 65  he database file
d0c0: 0a 2a 2a 20 69 6e 20 72 65 73 70 6f 6e 73 65 20  .** in response 
d0d0: 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f 77 61  to an sqlite3_wa
d0e0: 6c 5f 63 68 65 63 6b 70 6f 69 6e 74 28 29 20 72  l_checkpoint() r
d0f0: 65 71 75 65 73 74 20 6f 72 20 74 68 65 20 65 71  equest or the eq
d100: 75 69 76 61 6c 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20  uivalent..**.** 
d110: 54 68 65 20 61 6d 6f 75 6e 74 20 6f 66 20 69 6e  The amount of in
d120: 66 6f 72 6d 61 74 69 6f 6e 20 63 6f 70 69 65 73  formation copies
d130: 20 66 72 6f 6d 20 57 41 4c 20 74 6f 20 64 61 74   from WAL to dat
d140: 61 62 61 73 65 20 6d 69 67 68 74 20 62 65 20 6c  abase might be l
d150: 69 6d 69 74 65 64 0a 2a 2a 20 62 79 20 61 63 74  imited.** by act
d160: 69 76 65 20 72 65 61 64 65 72 73 2e 20 20 54 68  ive readers.  Th
d170: 69 73 20 72 6f 75 74 69 6e 65 20 77 69 6c 6c 20  is routine will 
d180: 6e 65 76 65 72 20 6f 76 65 72 77 72 69 74 65 20  never overwrite 
d190: 61 20 64 61 74 61 62 61 73 65 20 70 61 67 65 0a  a database page.
d1a0: 2a 2a 20 74 68 61 74 20 61 20 63 6f 6e 63 75 72  ** that a concur
d1b0: 72 65 6e 74 20 72 65 61 64 65 72 20 6d 69 67 68  rent reader migh
d1c0: 74 20 62 65 20 75 73 69 6e 67 2e 0a 2a 2a 0a 2a  t be using..**.*
d1d0: 2a 20 41 6c 6c 20 49 2f 4f 20 62 61 72 72 69 65  * All I/O barrie
d1e0: 72 20 6f 70 65 72 61 74 69 6f 6e 73 20 28 61 2e  r operations (a.
d1f0: 6b 2e 61 20 66 73 79 6e 63 73 29 20 6f 63 63 75  k.a fsyncs) occu
d200: 72 20 69 6e 20 74 68 69 73 20 72 6f 75 74 69 6e  r in this routin
d210: 65 20 77 68 65 6e 0a 2a 2a 20 53 51 4c 69 74 65  e when.** SQLite
d220: 20 69 73 20 69 6e 20 57 41 4c 2d 6d 6f 64 65 20   is in WAL-mode 
d230: 69 6e 20 73 79 6e 63 68 72 6f 6e 6f 75 73 3d 4e  in synchronous=N
d240: 4f 52 4d 41 4c 2e 20 20 54 68 61 74 20 6d 65 61  ORMAL.  That mea
d250: 6e 73 20 74 68 61 74 20 69 66 20 0a 2a 2a 20 63  ns that if .** c
d260: 68 65 63 6b 70 6f 69 6e 74 73 20 61 72 65 20 61  heckpoints are a
d270: 6c 77 61 79 73 20 72 75 6e 20 62 79 20 61 20 62  lways run by a b
d280: 61 63 6b 67 72 6f 75 6e 64 20 74 68 72 65 61 64  ackground thread
d290: 20 6f 72 20 62 61 63 6b 67 72 6f 75 6e 64 20 0a   or background .
d2a0: 2a 2a 20 70 72 6f 63 65 73 73 2c 20 66 6f 72 65  ** process, fore
d2b0: 67 72 6f 75 6e 64 20 74 68 72 65 61 64 73 20 77  ground threads w
d2c0: 69 6c 6c 20 6e 65 76 65 72 20 62 6c 6f 63 6b 20  ill never block 
d2d0: 6f 6e 20 61 20 6c 65 6e 67 74 68 79 20 66 73 79  on a lengthy fsy
d2e0: 6e 63 20 63 61 6c 6c 2e 0a 2a 2a 0a 2a 2a 20 46  nc call..**.** F
d2f0: 73 79 6e 63 20 69 73 20 63 61 6c 6c 65 64 20 6f  sync is called o
d300: 6e 20 74 68 65 20 57 41 4c 20 62 65 66 6f 72 65  n the WAL before
d310: 20 77 72 69 74 69 6e 67 20 63 6f 6e 74 65 6e 74   writing content
d320: 20 6f 75 74 20 6f 66 20 74 68 65 20 57 41 4c 20   out of the WAL 
d330: 61 6e 64 0a 2a 2a 20 69 6e 74 6f 20 74 68 65 20  and.** into the 
d340: 64 61 74 61 62 61 73 65 2e 20 20 54 68 69 73 20  database.  This 
d350: 65 6e 73 75 72 65 73 20 74 68 61 74 20 69 66 20  ensures that if 
d360: 74 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20  the new content 
d370: 69 73 20 70 65 72 73 69 73 74 65 6e 74 0a 2a 2a  is persistent.**
d380: 20 69 6e 20 74 68 65 20 57 41 4c 20 61 6e 64 20   in the WAL and 
d390: 63 61 6e 20 62 65 20 72 65 63 6f 76 65 72 65 64  can be recovered
d3a0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 70 6f 77   following a pow
d3b0: 65 72 2d 6c 6f 73 73 20 6f 72 20 68 61 72 64 20  er-loss or hard 
d3c0: 72 65 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 46 73 79  reset..**.** Fsy
d3d0: 6e 63 20 69 73 20 61 6c 73 6f 20 63 61 6c 6c 65  nc is also calle
d3e0: 64 20 6f 6e 20 74 68 65 20 64 61 74 61 62 61 73  d on the databas
d3f0: 65 20 66 69 6c 65 20 69 66 20 28 61 6e 64 20 6f  e file if (and o
d400: 6e 6c 79 20 69 66 29 20 74 68 65 20 65 6e 74 69  nly if) the enti
d410: 72 65 0a 2a 2a 20 57 41 4c 20 63 6f 6e 74 65 6e  re.** WAL conten
d420: 74 20 69 73 20 63 6f 70 69 65 64 20 69 6e 74 6f  t is copied into
d430: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
d440: 6c 65 2e 20 20 54 68 69 73 20 73 65 63 6f 6e 64  le.  This second
d450: 20 66 73 79 6e 63 20 6d 61 6b 65 73 0a 2a 2a 20   fsync makes.** 
d460: 69 74 20 73 61 66 65 20 74 6f 20 64 65 6c 65 74  it safe to delet
d470: 65 20 74 68 65 20 57 41 4c 20 73 69 6e 63 65 20  e the WAL since 
d480: 74 68 65 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20  the new content 
d490: 77 69 6c 6c 20 70 65 72 73 69 73 74 20 69 6e 20  will persist in 
d4a0: 74 68 65 0a 2a 2a 20 64 61 74 61 62 61 73 65 20  the.** database 
d4b0: 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73  file..**.** This
d4c0: 20 72 6f 75 74 69 6e 65 20 75 73 65 73 20 61 6e   routine uses an
d4d0: 64 20 75 70 64 61 74 65 73 20 74 68 65 20 6e 42  d updates the nB
d4e0: 61 63 6b 66 69 6c 6c 20 66 69 65 6c 64 20 6f 66  ackfill field of
d4f0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
d500: 65 61 64 65 72 2e 0a 2a 2a 20 54 68 69 73 20 69  eader..** This i
d510: 73 20 74 68 65 20 6f 6e 6c 79 20 72 6f 75 74 69  s the only routi
d520: 6e 65 20 74 68 61 20 77 69 6c 6c 20 69 6e 63 72  ne tha will incr
d530: 65 61 73 65 20 74 68 65 20 76 61 6c 75 65 20 6f  ease the value o
d540: 66 20 6e 42 61 63 6b 66 69 6c 6c 2e 20 20 0a 2a  f nBackfill.  .*
d550: 2a 20 28 41 20 57 41 4c 20 72 65 73 65 74 20 6f  * (A WAL reset o
d560: 72 20 72 65 63 6f 76 65 72 79 20 77 69 6c 6c 20  r recovery will 
d570: 72 65 76 65 72 74 20 6e 42 61 63 6b 66 69 6c 6c  revert nBackfill
d580: 20 74 6f 20 7a 65 72 6f 2c 20 62 75 74 20 6e 6f   to zero, but no
d590: 74 20 69 6e 63 72 65 61 73 65 0a 2a 2a 20 69 74  t increase.** it
d5a0: 73 20 76 61 6c 75 65 2e 29 0a 2a 2a 0a 2a 2a 20  s value.).**.** 
d5b0: 54 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74 20  The caller must 
d5c0: 62 65 20 68 6f 6c 64 69 6e 67 20 73 75 66 66 69  be holding suffi
d5d0: 63 69 65 6e 74 20 6c 6f 63 6b 73 20 74 6f 20 65  cient locks to e
d5e0: 6e 73 75 72 65 20 74 68 61 74 20 6e 6f 20 6f 74  nsure that no ot
d5f0: 68 65 72 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e  her.** checkpoin
d600: 74 20 69 73 20 72 75 6e 6e 69 6e 67 20 28 69 6e  t is running (in
d610: 20 61 6e 79 20 6f 74 68 65 72 20 74 68 72 65 61   any other threa
d620: 64 20 6f 72 20 70 72 6f 63 65 73 73 29 20 61 74  d or process) at
d630: 20 74 68 65 20 73 61 6d 65 0a 2a 2a 20 74 69 6d   the same.** tim
d640: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
d650: 20 77 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28 0a   walCheckpoint(.
d660: 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
d670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d680: 20 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65 63 74    /* Wal connect
d690: 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e  ion */.  int syn
d6a0: 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20  c_flags,        
d6b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67           /* Flag
d6c0: 73 20 66 6f 72 20 4f 73 53 79 6e 63 28 29 20 28  s for OsSync() (
d6d0: 6f 72 20 30 29 20 2a 2f 0a 20 20 69 6e 74 20 6e  or 0) */.  int n
d6e0: 42 75 66 2c 20 20 20 20 20 20 20 20 20 20 20 20  Buf,            
d6f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
d700: 7a 65 20 6f 66 20 7a 42 75 66 20 69 6e 20 62 79  ze of zBuf in by
d710: 74 65 73 20 2a 2f 0a 20 20 75 38 20 2a 7a 42 75  tes */.  u8 *zBu
d720: 66 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f               
d730: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70           /* Temp
d740: 6f 72 61 72 79 20 62 75 66 66 65 72 20 74 6f 20  orary buffer to 
d750: 75 73 65 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  use */.){.  int 
d760: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
d770: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
d780: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
d790: 69 6e 74 20 73 7a 50 61 67 65 20 3d 20 70 57 61  int szPage = pWa
d7a0: 6c 2d 3e 68 64 72 2e 73 7a 50 61 67 65 3b 20 20  l->hdr.szPage;  
d7b0: 2f 2a 20 44 61 74 61 62 61 73 65 20 70 61 67 65  /* Database page
d7c0: 2d 73 69 7a 65 20 2a 2f 0a 20 20 57 61 6c 49 74  -size */.  WalIt
d7d0: 65 72 61 74 6f 72 20 2a 70 49 74 65 72 20 3d 20  erator *pIter = 
d7e0: 30 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61  0;         /* Wa
d7f0: 6c 20 69 74 65 72 61 74 6f 72 20 63 6f 6e 74 65  l iterator conte
d800: 78 74 20 2a 2f 0a 20 20 75 33 32 20 69 44 62 70  xt */.  u32 iDbp
d810: 61 67 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20  age = 0;        
d820: 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20          /* Next 
d830: 64 61 74 61 62 61 73 65 20 70 61 67 65 20 74 6f  database page to
d840: 20 77 72 69 74 65 20 2a 2f 0a 20 20 75 33 32 20   write */.  u32 
d850: 69 46 72 61 6d 65 20 3d 20 30 3b 20 20 20 20 20  iFrame = 0;     
d860: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
d870: 61 6c 20 66 72 61 6d 65 20 63 6f 6e 74 61 69 6e  al frame contain
d880: 69 6e 67 20 64 61 74 61 20 66 6f 72 20 69 44 62  ing data for iDb
d890: 70 61 67 65 20 2a 2f 0a 20 20 75 33 32 20 6d 78  page */.  u32 mx
d8a0: 53 61 66 65 46 72 61 6d 65 3b 20 20 20 20 20 20  SafeFrame;      
d8b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 61 78            /* Max
d8c0: 20 66 72 61 6d 65 20 74 68 61 74 20 63 61 6e 20   frame that can 
d8d0: 62 65 20 62 61 63 6b 66 69 6c 6c 65 64 20 2a 2f  be backfilled */
d8e0: 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20  .  int i;       
d8f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
d900: 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e 74     /* Loop count
d910: 65 72 20 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65  er */.  volatile
d920: 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a 70 49   WalCkptInfo *pI
d930: 6e 66 6f 3b 20 20 20 20 2f 2a 20 54 68 65 20 63  nfo;    /* The c
d940: 68 65 63 6b 70 6f 69 6e 74 20 73 74 61 74 75 73  heckpoint status
d950: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 2a 2f 0a   information */.
d960: 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74  .  /* Allocate t
d970: 68 65 20 69 74 65 72 61 74 6f 72 20 2a 2f 0a 20  he iterator */. 
d980: 20 72 63 20 3d 20 77 61 6c 49 74 65 72 61 74 6f   rc = walIterato
d990: 72 49 6e 69 74 28 70 57 61 6c 2c 20 26 70 49 74  rInit(pWal, &pIt
d9a0: 65 72 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  er);.  if( rc!=S
d9b0: 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 57 61 6c  QLITE_OK || pWal
d9c0: 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3d 3d 30  ->hdr.mxFrame==0
d9d0: 20 29 7b 0a 20 20 20 20 67 6f 74 6f 20 77 61 6c   ){.    goto wal
d9e0: 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74 3b 0a  checkpoint_out;.
d9f0: 20 20 7d 0a 0a 20 20 2f 2a 2a 2a 20 54 4f 44 4f    }..  /*** TODO
da00: 3a 20 20 4d 6f 76 65 20 74 68 69 73 20 74 65 73  :  Move this tes
da10: 74 20 6f 75 74 20 74 6f 20 74 68 65 20 63 61 6c  t out to the cal
da20: 6c 65 72 2e 20 20 4d 61 6b 65 20 69 74 20 61 6e  ler.  Make it an
da30: 20 61 73 73 65 72 74 28 29 20 68 65 72 65 20 2a   assert() here *
da40: 2a 2a 2f 0a 20 20 69 66 28 20 70 57 61 6c 2d 3e  **/.  if( pWal->
da50: 68 64 72 2e 73 7a 50 61 67 65 21 3d 6e 42 75 66  hdr.szPage!=nBuf
da60: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
da70: 49 54 45 5f 43 4f 52 52 55 50 54 5f 42 4b 50 54  ITE_CORRUPT_BKPT
da80: 3b 0a 20 20 20 20 67 6f 74 6f 20 77 61 6c 63 68  ;.    goto walch
da90: 65 63 6b 70 6f 69 6e 74 5f 6f 75 74 3b 0a 20 20  eckpoint_out;.  
daa0: 7d 0a 0a 20 20 2f 2a 20 43 6f 6d 70 75 74 65 20  }..  /* Compute 
dab0: 69 6e 20 6d 78 53 61 66 65 46 72 61 6d 65 20 74  in mxSafeFrame t
dac0: 68 65 20 69 6e 64 65 78 20 6f 66 20 74 68 65 20  he index of the 
dad0: 6c 61 73 74 20 66 72 61 6d 65 20 6f 66 20 74 68  last frame of th
dae0: 65 20 57 41 4c 20 74 68 61 74 20 69 73 0a 20 20  e WAL that is.  
daf0: 2a 2a 20 73 61 66 65 20 74 6f 20 77 72 69 74 65  ** safe to write
db00: 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
db10: 73 65 2e 20 20 46 72 61 6d 65 73 20 62 65 79 6f  se.  Frames beyo
db20: 6e 64 20 6d 78 53 61 66 65 46 72 61 6d 65 20 6d  nd mxSafeFrame m
db30: 69 67 68 74 0a 20 20 2a 2a 20 6f 76 65 72 77 72  ight.  ** overwr
db40: 69 74 65 20 64 61 74 61 62 61 73 65 20 70 61 67  ite database pag
db50: 65 73 20 74 68 61 74 20 61 72 65 20 69 6e 20 75  es that are in u
db60: 73 65 20 62 79 20 61 63 74 69 76 65 20 72 65 61  se by active rea
db70: 64 65 72 73 20 61 6e 64 20 74 68 75 73 0a 20 20  ders and thus.  
db80: 2a 2a 20 63 61 6e 6e 6f 74 20 62 65 20 62 61 63  ** cannot be bac
db90: 6b 66 69 6c 6c 65 64 20 66 72 6f 6d 20 74 68 65  kfilled from the
dba0: 20 57 41 4c 2e 0a 20 20 2a 2f 0a 20 20 6d 78 53   WAL..  */.  mxS
dbb0: 61 66 65 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d  afeFrame = pWal-
dbc0: 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20  >hdr.mxFrame;.  
dbd0: 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49  pInfo = walCkptI
dbe0: 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 66 6f 72  nfo(pWal);.  for
dbf0: 28 69 3d 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41  (i=1; i<WAL_NREA
dc00: 44 45 52 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 75  DER; i++){.    u
dc10: 33 32 20 79 20 3d 20 70 49 6e 66 6f 2d 3e 61 52  32 y = pInfo->aR
dc20: 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a 20 20 20 20  eadMark[i];.    
dc30: 69 66 28 20 6d 78 53 61 66 65 46 72 61 6d 65 3e  if( mxSafeFrame>
dc40: 3d 79 20 29 7b 0a 20 20 20 20 20 20 61 73 73 65  =y ){.      asse
dc50: 72 74 28 20 79 3c 3d 70 57 61 6c 2d 3e 68 64 72  rt( y<=pWal->hdr
dc60: 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20 20 20  .mxFrame );.    
dc70: 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78    rc = walLockEx
dc80: 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
dc90: 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20  L_READ_LOCK(i), 
dca0: 31 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  1);.      if( rc
dcb0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
dcc0: 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 61 52         pInfo->aR
dcd0: 65 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 52 45 41  eadMark[i] = REA
dce0: 44 4d 41 52 4b 5f 4e 4f 54 5f 55 53 45 44 3b 0a  DMARK_NOT_USED;.
dcf0: 20 20 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63          walUnloc
dd00: 6b 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c  kExclusive(pWal,
dd10: 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 69   WAL_READ_LOCK(i
dd20: 29 2c 20 31 29 3b 0a 20 20 20 20 20 20 7d 65 6c  ), 1);.      }el
dd30: 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  se if( rc==SQLIT
dd40: 45 5f 42 55 53 59 20 29 7b 0a 20 20 20 20 20 20  E_BUSY ){.      
dd50: 20 20 6d 78 53 61 66 65 46 72 61 6d 65 20 3d 20    mxSafeFrame = 
dd60: 79 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  y;.      }else{.
dd70: 20 20 20 20 20 20 20 20 67 6f 74 6f 20 77 61 6c          goto wal
dd80: 63 68 65 63 6b 70 6f 69 6e 74 5f 6f 75 74 3b 0a  checkpoint_out;.
dd90: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
dda0: 7d 0a 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e  }..  if( pInfo->
ddb0: 6e 42 61 63 6b 66 69 6c 6c 3c 6d 78 53 61 66 65  nBackfill<mxSafe
ddc0: 46 72 61 6d 65 0a 20 20 20 26 26 20 28 72 63 20  Frame.   && (rc 
ddd0: 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75 73 69  = walLockExclusi
dde0: 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ve(pWal, WAL_REA
ddf0: 44 5f 4c 4f 43 4b 28 30 29 2c 20 31 29 29 3d 3d  D_LOCK(0), 1))==
de00: 53 51 4c 49 54 45 5f 4f 4b 0a 20 20 29 7b 0a 20  SQLITE_OK.  ){. 
de10: 20 20 20 75 33 32 20 6e 42 61 63 6b 66 69 6c 6c     u32 nBackfill
de20: 20 3d 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66   = pInfo->nBackf
de30: 69 6c 6c 3b 0a 0a 20 20 20 20 2f 2a 20 53 79 6e  ill;..    /* Syn
de40: 63 20 74 68 65 20 57 41 4c 20 74 6f 20 64 69 73  c the WAL to dis
de50: 6b 20 2a 2f 0a 20 20 20 20 69 66 28 20 73 79 6e  k */.    if( syn
de60: 63 5f 66 6c 61 67 73 20 29 7b 0a 20 20 20 20 20  c_flags ){.     
de70: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 53   rc = sqlite3OsS
de80: 79 6e 63 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64  ync(pWal->pWalFd
de90: 2c 20 73 79 6e 63 5f 66 6c 61 67 73 29 3b 0a 20  , sync_flags);. 
dea0: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 74 65     }..    /* Ite
deb0: 72 61 74 65 20 74 68 72 6f 75 67 68 20 74 68 65  rate through the
dec0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
ded0: 20 57 41 4c 2c 20 63 6f 70 79 69 6e 67 20 64 61   WAL, copying da
dee0: 74 61 20 74 6f 20 74 68 65 20 64 62 20 66 69 6c  ta to the db fil
def0: 65 2e 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28  e. */.    while(
df00: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
df10: 26 20 30 3d 3d 77 61 6c 49 74 65 72 61 74 6f 72  & 0==walIterator
df20: 4e 65 78 74 28 70 49 74 65 72 2c 20 26 69 44 62  Next(pIter, &iDb
df30: 70 61 67 65 2c 20 26 69 46 72 61 6d 65 29 20 29  page, &iFrame) )
df40: 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  {.      assert( 
df50: 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57 61  walFramePgno(pWa
df60: 6c 2c 20 69 46 72 61 6d 65 29 3d 3d 69 44 62 70  l, iFrame)==iDbp
df70: 61 67 65 20 29 3b 0a 20 20 20 20 20 20 69 66 28  age );.      if(
df80: 20 69 46 72 61 6d 65 3c 3d 6e 42 61 63 6b 66 69   iFrame<=nBackfi
df90: 6c 6c 20 7c 7c 20 69 46 72 61 6d 65 3e 6d 78 53  ll || iFrame>mxS
dfa0: 61 66 65 46 72 61 6d 65 20 29 20 63 6f 6e 74 69  afeFrame ) conti
dfb0: 6e 75 65 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  nue;.      rc = 
dfc0: 73 71 6c 69 74 65 33 4f 73 52 65 61 64 28 70 57  sqlite3OsRead(pW
dfd0: 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 7a 42 75 66  al->pWalFd, zBuf
dfe0: 2c 20 73 7a 50 61 67 65 2c 20 0a 20 20 20 20 20  , szPage, .     
dff0: 20 20 20 20 20 77 61 6c 46 72 61 6d 65 4f 66 66       walFrameOff
e000: 73 65 74 28 69 46 72 61 6d 65 2c 20 73 7a 50 61  set(iFrame, szPa
e010: 67 65 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  ge) + WAL_FRAME_
e020: 48 44 52 53 49 5a 45 0a 20 20 20 20 20 20 29 3b  HDRSIZE.      );
e030: 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53  .      if( rc!=S
e040: 51 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b  QLITE_OK ) break
e050: 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  ;.      rc = sql
e060: 69 74 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c  ite3OsWrite(pWal
e070: 2d 3e 70 44 62 46 64 2c 20 7a 42 75 66 2c 20 73  ->pDbFd, zBuf, s
e080: 7a 50 61 67 65 2c 20 28 69 44 62 70 61 67 65 2d  zPage, (iDbpage-
e090: 31 29 2a 73 7a 50 61 67 65 29 3b 0a 20 20 20 20  1)*szPage);.    
e0a0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
e0b0: 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  _OK ) break;.   
e0c0: 20 7d 0a 0a 20 20 20 20 2f 2a 20 49 66 20 77 6f   }..    /* If wo
e0d0: 72 6b 20 77 61 73 20 61 63 74 75 61 6c 6c 79 20  rk was actually 
e0e0: 61 63 63 6f 6d 70 6c 69 73 68 65 64 2e 2e 2e 20  accomplished... 
e0f0: 2a 2f 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  */.    if( rc==S
e100: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
e110: 20 20 69 66 28 20 6d 78 53 61 66 65 46 72 61 6d    if( mxSafeFram
e120: 65 3d 3d 77 61 6c 49 6e 64 65 78 48 64 72 28 70  e==walIndexHdr(p
e130: 57 61 6c 29 2d 3e 6d 78 46 72 61 6d 65 20 29 7b  Wal)->mxFrame ){
e140: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71  .        rc = sq
e150: 6c 69 74 65 33 4f 73 54 72 75 6e 63 61 74 65 28  lite3OsTruncate(
e160: 70 57 61 6c 2d 3e 70 44 62 46 64 2c 20 28 28 69  pWal->pDbFd, ((i
e170: 36 34 29 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61  64)pWal->hdr.nPa
e180: 67 65 2a 28 69 36 34 29 73 7a 50 61 67 65 29 29  ge*(i64)szPage))
e190: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
e1a0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 73  ==SQLITE_OK && s
e1b0: 79 6e 63 5f 66 6c 61 67 73 20 29 7b 0a 20 20 20  ync_flags ){.   
e1c0: 20 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69         rc = sqli
e1d0: 74 65 33 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e  te3OsSync(pWal->
e1e0: 70 44 62 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67  pDbFd, sync_flag
e1f0: 73 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  s);.        }.  
e200: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
e210: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
e220: 0a 20 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e  .        pInfo->
e230: 6e 42 61 63 6b 66 69 6c 6c 20 3d 20 6d 78 53 61  nBackfill = mxSa
e240: 66 65 46 72 61 6d 65 3b 0a 20 20 20 20 20 20 7d  feFrame;.      }
e250: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 52  .    }..    /* R
e260: 65 6c 65 61 73 65 20 74 68 65 20 72 65 61 64 65  elease the reade
e270: 72 20 6c 6f 63 6b 20 68 65 6c 64 20 77 68 69 6c  r lock held whil
e280: 65 20 62 61 63 6b 66 69 6c 6c 69 6e 67 20 2a 2f  e backfilling */
e290: 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78  .    walUnlockEx
e2a0: 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
e2b0: 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20  L_READ_LOCK(0), 
e2c0: 31 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20  1);.  }else if( 
e2d0: 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc==SQLITE_BUSY 
e2e0: 29 7b 0a 20 20 20 20 2f 2a 20 52 65 73 65 74 20  ){.    /* Reset 
e2f0: 74 68 65 20 72 65 74 75 72 6e 20 63 6f 64 65 20  the return code 
e300: 73 6f 20 61 73 20 6e 6f 74 20 74 6f 20 72 65 70  so as not to rep
e310: 6f 72 74 20 61 20 63 68 65 63 6b 70 6f 69 6e 74  ort a checkpoint
e320: 20 66 61 69 6c 75 72 65 0a 20 20 20 20 2a 2a 20   failure.    ** 
e330: 6a 75 73 74 20 62 65 63 61 75 73 65 20 61 63 74  just because act
e340: 69 76 65 20 72 65 61 64 65 72 73 20 70 72 65 76  ive readers prev
e350: 65 6e 74 20 61 6e 79 20 62 61 63 6b 66 69 6c 6c  ent any backfill
e360: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 72 63 20  ..    */.    rc 
e370: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d  = SQLITE_OK;.  }
e380: 0a 0a 20 77 61 6c 63 68 65 63 6b 70 6f 69 6e 74  .. walcheckpoint
e390: 5f 6f 75 74 3a 0a 20 20 77 61 6c 49 74 65 72 61  _out:.  walItera
e3a0: 74 6f 72 46 72 65 65 28 70 49 74 65 72 29 3b 0a  torFree(pIter);.
e3b0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
e3c0: 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 63 6f  /*.** Close a co
e3d0: 6e 6e 65 63 74 69 6f 6e 20 74 6f 20 61 20 6c 6f  nnection to a lo
e3e0: 67 20 66 69 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 73  g file..*/.int s
e3f0: 71 6c 69 74 65 33 57 61 6c 43 6c 6f 73 65 28 0a  qlite3WalClose(.
e400: 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20 20    Wal *pWal,    
e410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e420: 20 20 2f 2a 20 57 61 6c 20 74 6f 20 63 6c 6f 73    /* Wal to clos
e430: 65 20 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 5f  e */.  int sync_
e440: 66 6c 61 67 73 2c 20 20 20 20 20 20 20 20 20 20  flags,          
e450: 20 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20         /* Flags 
e460: 74 6f 20 70 61 73 73 20 74 6f 20 4f 73 53 79 6e  to pass to OsSyn
e470: 63 28 29 20 28 6f 72 20 30 29 20 2a 2f 0a 20 20  c() (or 0) */.  
e480: 69 6e 74 20 6e 42 75 66 2c 0a 20 20 75 38 20 2a  int nBuf,.  u8 *
e490: 7a 42 75 66 20 20 20 20 20 20 20 20 20 20 20 20  zBuf            
e4a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42              /* B
e4b0: 75 66 66 65 72 20 6f 66 20 61 74 20 6c 65 61 73  uffer of at leas
e4c0: 74 20 6e 42 75 66 20 62 79 74 65 73 20 2a 2f 0a  t nBuf bytes */.
e4d0: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
e4e0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70  LITE_OK;.  if( p
e4f0: 57 61 6c 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  Wal ){.    int i
e500: 73 44 65 6c 65 74 65 20 3d 20 30 3b 20 20 20 20  sDelete = 0;    
e510: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
e520: 20 74 6f 20 75 6e 6c 69 6e 6b 20 77 61 6c 20 61   to unlink wal a
e530: 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  nd wal-index fil
e540: 65 73 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 49 66  es */..    /* If
e550: 20 61 6e 20 45 58 43 4c 55 53 49 56 45 20 6c 6f   an EXCLUSIVE lo
e560: 63 6b 20 63 61 6e 20 62 65 20 6f 62 74 61 69 6e  ck can be obtain
e570: 65 64 20 6f 6e 20 74 68 65 20 64 61 74 61 62 61  ed on the databa
e580: 73 65 20 66 69 6c 65 20 28 75 73 69 6e 67 20 74  se file (using t
e590: 68 65 0a 20 20 20 20 2a 2a 20 6f 72 64 69 6e 61  he.    ** ordina
e5a0: 72 79 2c 20 72 6f 6c 6c 62 61 63 6b 2d 6d 6f 64  ry, rollback-mod
e5b0: 65 20 6c 6f 63 6b 69 6e 67 20 6d 65 74 68 6f 64  e locking method
e5c0: 73 2c 20 74 68 69 73 20 67 75 61 72 61 6e 74 65  s, this guarante
e5d0: 65 73 20 74 68 61 74 20 74 68 65 0a 20 20 20 20  es that the.    
e5e0: 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 61 73  ** connection as
e5f0: 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68  sociated with th
e600: 69 73 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 74  is log file is t
e610: 68 65 20 6f 6e 6c 79 20 63 6f 6e 6e 65 63 74 69  he only connecti
e620: 6f 6e 20 74 6f 0a 20 20 20 20 2a 2a 20 74 68 65  on to.    ** the
e630: 20 64 61 74 61 62 61 73 65 2e 20 49 6e 20 74 68   database. In th
e640: 69 73 20 63 61 73 65 20 63 68 65 63 6b 70 6f 69  is case checkpoi
e650: 6e 74 20 74 68 65 20 64 61 74 61 62 61 73 65 20  nt the database 
e660: 61 6e 64 20 75 6e 6c 69 6e 6b 20 62 6f 74 68 0a  and unlink both.
e670: 20 20 20 20 2a 2a 20 74 68 65 20 77 61 6c 20 61      ** the wal a
e680: 6e 64 20 77 61 6c 2d 69 6e 64 65 78 20 66 69 6c  nd wal-index fil
e690: 65 73 2e 0a 20 20 20 20 2a 2a 0a 20 20 20 20 2a  es..    **.    *
e6a0: 2a 20 54 68 65 20 45 58 43 4c 55 53 49 56 45 20  * The EXCLUSIVE 
e6b0: 6c 6f 63 6b 20 69 73 20 6e 6f 74 20 72 65 6c 65  lock is not rele
e6c0: 61 73 65 64 20 62 65 66 6f 72 65 20 72 65 74 75  ased before retu
e6d0: 72 6e 69 6e 67 2e 0a 20 20 20 20 2a 2f 0a 20 20  rning..    */.  
e6e0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f 73    rc = sqlite3Os
e6f0: 4c 6f 63 6b 28 70 57 61 6c 2d 3e 70 44 62 46 64  Lock(pWal->pDbFd
e700: 2c 20 53 51 4c 49 54 45 5f 4c 4f 43 4b 5f 45 58  , SQLITE_LOCK_EX
e710: 43 4c 55 53 49 56 45 29 3b 0a 20 20 20 20 69 66  CLUSIVE);.    if
e720: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
e730: 29 7b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 65  ){.      pWal->e
e740: 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 31  xclusiveMode = 1
e750: 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  ;.      rc = sql
e760: 69 74 65 33 57 61 6c 43 68 65 63 6b 70 6f 69 6e  ite3WalCheckpoin
e770: 74 28 70 57 61 6c 2c 20 73 79 6e 63 5f 66 6c 61  t(pWal, sync_fla
e780: 67 73 2c 20 6e 42 75 66 2c 20 7a 42 75 66 29 3b  gs, nBuf, zBuf);
e790: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
e7a0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
e7b0: 20 20 20 20 69 73 44 65 6c 65 74 65 20 3d 20 31      isDelete = 1
e7c0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
e7d0: 0a 20 20 20 20 77 61 6c 49 6e 64 65 78 43 6c 6f  .    walIndexClo
e7e0: 73 65 28 70 57 61 6c 2c 20 69 73 44 65 6c 65 74  se(pWal, isDelet
e7f0: 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 4f  e);.    sqlite3O
e800: 73 43 6c 6f 73 65 28 70 57 61 6c 2d 3e 70 57 61  sClose(pWal->pWa
e810: 6c 46 64 29 3b 0a 20 20 20 20 69 66 28 20 69 73  lFd);.    if( is
e820: 44 65 6c 65 74 65 20 29 7b 0a 20 20 20 20 20 20  Delete ){.      
e830: 73 71 6c 69 74 65 33 4f 73 44 65 6c 65 74 65 28  sqlite3OsDelete(
e840: 70 57 61 6c 2d 3e 70 56 66 73 2c 20 70 57 61 6c  pWal->pVfs, pWal
e850: 2d 3e 7a 57 61 6c 4e 61 6d 65 2c 20 30 29 3b 0a  ->zWalName, 0);.
e860: 20 20 20 20 7d 0a 20 20 20 20 57 41 4c 54 52 41      }.    WALTRA
e870: 43 45 28 28 22 57 41 4c 25 70 3a 20 63 6c 6f 73  CE(("WAL%p: clos
e880: 65 64 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 20  ed\n", pWal));. 
e890: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
e8a0: 70 57 61 6c 2d 3e 61 70 57 69 44 61 74 61 29 3b  pWal->apWiData);
e8b0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
e8c0: 65 28 70 57 61 6c 29 3b 0a 20 20 7d 0a 20 20 72  e(pWal);.  }.  r
e8d0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
e8e0: 2a 2a 20 54 72 79 20 74 6f 20 72 65 61 64 20 74  ** Try to read t
e8f0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  he wal-index hea
e900: 64 65 72 2e 20 20 52 65 74 75 72 6e 20 30 20 6f  der.  Return 0 o
e910: 6e 20 73 75 63 63 65 73 73 20 61 6e 64 20 31 20  n success and 1 
e920: 69 66 0a 2a 2a 20 74 68 65 72 65 20 69 73 20 61  if.** there is a
e930: 20 70 72 6f 62 6c 65 6d 2e 0a 2a 2a 0a 2a 2a 20   problem..**.** 
e940: 54 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 69 73  The wal-index is
e950: 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d 6f 72   in shared memor
e960: 79 2e 20 20 41 6e 6f 74 68 65 72 20 74 68 72 65  y.  Another thre
e970: 61 64 20 6f 72 20 70 72 6f 63 65 73 73 20 6d 69  ad or process mi
e980: 67 68 74 0a 2a 2a 20 62 65 20 77 72 69 74 69 6e  ght.** be writin
e990: 67 20 74 68 65 20 68 65 61 64 65 72 20 61 74 20  g the header at 
e9a0: 74 68 65 20 73 61 6d 65 20 74 69 6d 65 20 74 68  the same time th
e9b0: 69 73 20 70 72 6f 63 65 64 75 72 65 20 69 73 20  is procedure is 
e9c0: 74 72 79 69 6e 67 20 74 6f 0a 2a 2a 20 72 65 61  trying to.** rea
e9d0: 64 20 69 74 2c 20 77 68 69 63 68 20 6d 69 67 68  d it, which migh
e9e0: 74 20 72 65 73 75 6c 74 20 69 6e 20 69 6e 63 6f  t result in inco
e9f0: 6e 73 69 73 74 65 6e 63 79 2e 20 20 41 20 64 69  nsistency.  A di
ea00: 72 74 79 20 72 65 61 64 20 69 73 20 64 65 74 65  rty read is dete
ea10: 63 74 65 64 0a 2a 2a 20 62 79 20 76 65 72 69 66  cted.** by verif
ea20: 79 69 6e 67 20 74 68 61 74 20 62 6f 74 68 20 63  ying that both c
ea30: 6f 70 69 65 73 20 6f 66 20 74 68 65 20 68 65 61  opies of the hea
ea40: 64 65 72 20 61 72 65 20 74 68 65 20 73 61 6d 65  der are the same
ea50: 20 61 6e 64 20 61 6c 73 6f 20 62 79 0a 2a 2a 20   and also by.** 
ea60: 61 20 63 68 65 63 6b 73 75 6d 20 6f 6e 20 74 68  a checksum on th
ea70: 65 20 68 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20  e header..**.** 
ea80: 49 66 20 61 6e 64 20 6f 6e 6c 79 20 69 66 20 74  If and only if t
ea90: 68 65 20 72 65 61 64 20 69 73 20 63 6f 6e 73 69  he read is consi
eaa0: 73 74 65 6e 74 20 61 6e 64 20 74 68 65 20 68 65  stent and the he
eab0: 61 64 65 72 20 69 73 20 64 69 66 66 65 72 65 6e  ader is differen
eac0: 74 20 66 72 6f 6d 0a 2a 2a 20 70 57 61 6c 2d 3e  t from.** pWal->
ead0: 68 64 72 2c 20 74 68 65 6e 20 70 57 61 6c 2d 3e  hdr, then pWal->
eae0: 68 64 72 20 69 73 20 75 70 64 61 74 65 64 20 74  hdr is updated t
eaf0: 6f 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66  o the content of
eb00: 20 74 68 65 20 6e 65 77 20 68 65 61 64 65 72 0a   the new header.
eb10: 2a 2a 20 61 6e 64 20 2a 70 43 68 61 6e 67 65 64  ** and *pChanged
eb20: 20 69 73 20 73 65 74 20 74 6f 20 31 2e 0a 2a 2a   is set to 1..**
eb30: 0a 2a 2a 20 49 66 20 74 68 65 20 63 68 65 63 6b  .** If the check
eb40: 73 75 6d 20 63 61 6e 6e 6f 74 20 62 65 20 76 65  sum cannot be ve
eb50: 72 69 66 69 65 64 20 72 65 74 75 72 6e 20 6e 6f  rified return no
eb60: 6e 2d 7a 65 72 6f 2e 20 49 66 20 74 68 65 20 68  n-zero. If the h
eb70: 65 61 64 65 72 0a 2a 2a 20 69 73 20 72 65 61 64  eader.** is read
eb80: 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20 61 6e   successfully an
eb90: 64 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20 76  d the checksum v
eba0: 65 72 69 66 69 65 64 2c 20 72 65 74 75 72 6e 20  erified, return 
ebb0: 7a 65 72 6f 2e 0a 2a 2f 0a 69 6e 74 20 77 61 6c  zero..*/.int wal
ebc0: 49 6e 64 65 78 54 72 79 48 64 72 28 57 61 6c 20  IndexTryHdr(Wal 
ebd0: 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61  *pWal, int *pCha
ebe0: 6e 67 65 64 29 7b 0a 20 20 75 33 32 20 61 43 6b  nged){.  u32 aCk
ebf0: 73 75 6d 5b 32 5d 3b 20 20 20 20 20 20 20 20 20  sum[2];         
ec00: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 68 65 63           /* Chec
ec10: 6b 73 75 6d 20 6f 6e 20 74 68 65 20 68 65 61 64  ksum on the head
ec20: 65 72 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20  er content */.  
ec30: 57 61 6c 49 6e 64 65 78 48 64 72 20 68 31 2c 20  WalIndexHdr h1, 
ec40: 68 32 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  h2;             
ec50: 2f 2a 20 54 77 6f 20 63 6f 70 69 65 73 20 6f 66  /* Two copies of
ec60: 20 74 68 65 20 68 65 61 64 65 72 20 63 6f 6e 74   the header cont
ec70: 65 6e 74 20 2a 2f 0a 20 20 57 61 6c 49 6e 64 65  ent */.  WalInde
ec80: 78 48 64 72 20 76 6f 6c 61 74 69 6c 65 20 2a 61  xHdr volatile *a
ec90: 48 64 72 3b 20 20 20 20 20 2f 2a 20 48 65 61 64  Hdr;     /* Head
eca0: 65 72 20 69 6e 20 73 68 61 72 65 64 20 6d 65 6d  er in shared mem
ecb0: 6f 72 79 20 2a 2f 0a 0a 20 20 2f 2a 20 54 68 65  ory */..  /* The
ecc0: 20 66 69 72 73 74 20 70 61 67 65 20 6f 66 20 74   first page of t
ecd0: 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 6d 75 73  he wal-index mus
ece0: 74 20 62 65 20 6d 61 70 70 65 64 20 61 74 20 74  t be mapped at t
ecf0: 68 69 73 20 70 6f 69 6e 74 2e 20 2a 2f 0a 20 20  his point. */.  
ed00: 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 6e 57  assert( pWal->nW
ed10: 69 44 61 74 61 3e 30 20 26 26 20 70 57 61 6c 2d  iData>0 && pWal-
ed20: 3e 61 70 57 69 44 61 74 61 5b 30 5d 20 29 3b 0a  >apWiData[0] );.
ed30: 0a 20 20 2f 2a 20 52 65 61 64 20 74 68 65 20 68  .  /* Read the h
ed40: 65 61 64 65 72 2e 20 54 68 69 73 20 6d 69 67 68  eader. This migh
ed50: 74 20 68 61 70 70 65 6e 20 63 75 72 72 65 6e 74  t happen current
ed60: 6c 79 20 77 69 74 68 20 61 20 77 72 69 74 65 20  ly with a write 
ed70: 74 6f 20 74 68 65 0a 20 20 2a 2a 20 73 61 6d 65  to the.  ** same
ed80: 20 61 72 65 61 20 6f 66 20 73 68 61 72 65 64 20   area of shared 
ed90: 6d 65 6d 6f 72 79 20 6f 6e 20 61 20 64 69 66 66  memory on a diff
eda0: 65 72 65 6e 74 20 43 50 55 20 69 6e 20 61 20 53  erent CPU in a S
edb0: 4d 50 2c 0a 20 20 2a 2a 20 6d 65 61 6e 69 6e 67  MP,.  ** meaning
edc0: 20 69 74 20 69 73 20 70 6f 73 73 69 62 6c 65 20   it is possible 
edd0: 74 68 61 74 20 61 6e 20 69 6e 63 6f 6e 73 69 73  that an inconsis
ede0: 74 65 6e 74 20 73 6e 61 70 73 68 6f 74 20 69 73  tent snapshot is
edf0: 20 72 65 61 64 0a 20 20 2a 2a 20 66 72 6f 6d 20   read.  ** from 
ee00: 74 68 65 20 66 69 6c 65 2e 20 49 66 20 74 68 69  the file. If thi
ee10: 73 20 68 61 70 70 65 6e 73 2c 20 72 65 74 75 72  s happens, retur
ee20: 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 20 20 2a 2a  n non-zero..  **
ee30: 0a 20 20 2a 2a 20 54 68 65 72 65 20 61 72 65 20  .  ** There are 
ee40: 74 77 6f 20 63 6f 70 69 65 73 20 6f 66 20 74 68  two copies of th
ee50: 65 20 68 65 61 64 65 72 20 61 74 20 74 68 65 20  e header at the 
ee60: 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68 65  beginning of the
ee70: 20 77 61 6c 2d 69 6e 64 65 78 2e 0a 20 20 2a 2a   wal-index..  **
ee80: 20 57 68 65 6e 20 72 65 61 64 69 6e 67 2c 20 72   When reading, r
ee90: 65 61 64 20 5b 30 5d 20 66 69 72 73 74 20 74 68  ead [0] first th
eea0: 65 6e 20 5b 31 5d 2e 20 20 57 72 69 74 65 73 20  en [1].  Writes 
eeb0: 61 72 65 20 69 6e 20 74 68 65 20 72 65 76 65 72  are in the rever
eec0: 73 65 20 6f 72 64 65 72 2e 0a 20 20 2a 2a 20 4d  se order..  ** M
eed0: 65 6d 6f 72 79 20 62 61 72 72 69 65 72 73 20 61  emory barriers a
eee0: 72 65 20 75 73 65 64 20 74 6f 20 70 72 65 76 65  re used to preve
eef0: 6e 74 20 74 68 65 20 63 6f 6d 70 69 6c 65 72 20  nt the compiler 
ef00: 6f 72 20 74 68 65 20 68 61 72 64 77 61 72 65 20  or the hardware 
ef10: 66 72 6f 6d 0a 20 20 2a 2a 20 72 65 6f 72 64 65  from.  ** reorde
ef20: 72 69 6e 67 20 74 68 65 20 72 65 61 64 73 20 61  ring the reads a
ef30: 6e 64 20 77 72 69 74 65 73 2e 0a 20 20 2a 2f 0a  nd writes..  */.
ef40: 20 20 61 48 64 72 20 3d 20 77 61 6c 49 6e 64 65    aHdr = walInde
ef50: 78 48 64 72 28 70 57 61 6c 29 3b 0a 20 20 6d 65  xHdr(pWal);.  me
ef60: 6d 63 70 79 28 26 68 31 2c 20 28 76 6f 69 64 20  mcpy(&h1, (void 
ef70: 2a 29 26 61 48 64 72 5b 30 5d 2c 20 73 69 7a 65  *)&aHdr[0], size
ef80: 6f 66 28 68 31 29 29 3b 0a 20 20 73 71 6c 69 74  of(h1));.  sqlit
ef90: 65 33 4f 73 53 68 6d 42 61 72 72 69 65 72 28 70  e3OsShmBarrier(p
efa0: 57 61 6c 2d 3e 70 44 62 46 64 29 3b 0a 20 20 6d  Wal->pDbFd);.  m
efb0: 65 6d 63 70 79 28 26 68 32 2c 20 28 76 6f 69 64  emcpy(&h2, (void
efc0: 20 2a 29 26 61 48 64 72 5b 31 5d 2c 20 73 69 7a   *)&aHdr[1], siz
efd0: 65 6f 66 28 68 32 29 29 3b 0a 0a 20 20 69 66 28  eof(h2));..  if(
efe0: 20 6d 65 6d 63 6d 70 28 26 68 31 2c 20 26 68 32   memcmp(&h1, &h2
eff0: 2c 20 73 69 7a 65 6f 66 28 68 31 29 29 21 3d 30  , sizeof(h1))!=0
f000: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31   ){.    return 1
f010: 3b 20 20 20 2f 2a 20 44 69 72 74 79 20 72 65 61  ;   /* Dirty rea
f020: 64 20 2a 2f 0a 20 20 7d 20 20 0a 20 20 69 66 28  d */.  }  .  if(
f030: 20 68 31 2e 69 73 49 6e 69 74 3d 3d 30 20 29 7b   h1.isInit==0 ){
f040: 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b 20 20  .    return 1;  
f050: 20 2f 2a 20 4d 61 6c 66 6f 72 6d 65 64 20 68 65   /* Malformed he
f060: 61 64 65 72 20 2d 20 70 72 6f 62 61 62 6c 79 20  ader - probably 
f070: 61 6c 6c 20 7a 65 72 6f 73 20 2a 2f 0a 20 20 7d  all zeros */.  }
f080: 0a 20 20 77 61 6c 43 68 65 63 6b 73 75 6d 42 79  .  walChecksumBy
f090: 74 65 73 28 31 2c 20 28 75 38 2a 29 26 68 31 2c  tes(1, (u8*)&h1,
f0a0: 20 73 69 7a 65 6f 66 28 68 31 29 2d 73 69 7a 65   sizeof(h1)-size
f0b0: 6f 66 28 68 31 2e 61 43 6b 73 75 6d 29 2c 20 30  of(h1.aCksum), 0
f0c0: 2c 20 61 43 6b 73 75 6d 29 3b 0a 20 20 69 66 28  , aCksum);.  if(
f0d0: 20 61 43 6b 73 75 6d 5b 30 5d 21 3d 68 31 2e 61   aCksum[0]!=h1.a
f0e0: 43 6b 73 75 6d 5b 30 5d 20 7c 7c 20 61 43 6b 73  Cksum[0] || aCks
f0f0: 75 6d 5b 31 5d 21 3d 68 31 2e 61 43 6b 73 75 6d  um[1]!=h1.aCksum
f100: 5b 31 5d 20 29 7b 0a 20 20 20 20 72 65 74 75 72  [1] ){.    retur
f110: 6e 20 31 3b 20 20 20 2f 2a 20 43 68 65 63 6b 73  n 1;   /* Checks
f120: 75 6d 20 64 6f 65 73 20 6e 6f 74 20 6d 61 74 63  um does not matc
f130: 68 20 2a 2f 0a 20 20 7d 0a 0a 20 20 69 66 28 20  h */.  }..  if( 
f140: 6d 65 6d 63 6d 70 28 26 70 57 61 6c 2d 3e 68 64  memcmp(&pWal->hd
f150: 72 2c 20 26 68 31 2c 20 73 69 7a 65 6f 66 28 57  r, &h1, sizeof(W
f160: 61 6c 49 6e 64 65 78 48 64 72 29 29 20 29 7b 0a  alIndexHdr)) ){.
f170: 20 20 20 20 2a 70 43 68 61 6e 67 65 64 20 3d 20      *pChanged = 
f180: 31 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 26 70  1;.    memcpy(&p
f190: 57 61 6c 2d 3e 68 64 72 2c 20 26 68 31 2c 20 73  Wal->hdr, &h1, s
f1a0: 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64  izeof(WalIndexHd
f1b0: 72 29 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 73  r));.    pWal->s
f1c0: 7a 50 61 67 65 20 3d 20 70 57 61 6c 2d 3e 68 64  zPage = pWal->hd
f1d0: 72 2e 73 7a 50 61 67 65 3b 0a 20 20 7d 0a 0a 20  r.szPage;.  }.. 
f1e0: 20 2f 2a 20 54 68 65 20 68 65 61 64 65 72 20 77   /* The header w
f1f0: 61 73 20 73 75 63 63 65 73 73 66 75 6c 6c 79 20  as successfully 
f200: 72 65 61 64 2e 20 52 65 74 75 72 6e 20 7a 65 72  read. Return zer
f210: 6f 2e 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20 30  o. */.  return 0
f220: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20  ;.}../*.** Read 
f230: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
f240: 61 64 65 72 20 66 72 6f 6d 20 74 68 65 20 77 61  ader from the wa
f250: 6c 2d 69 6e 64 65 78 20 61 6e 64 20 69 6e 74 6f  l-index and into
f260: 20 70 57 61 6c 2d 3e 68 64 72 2e 0a 2a 2a 20 49   pWal->hdr..** I
f270: 66 20 74 68 65 20 77 61 6c 2d 68 65 61 64 65 72  f the wal-header
f280: 20 61 70 70 65 61 72 73 20 74 6f 20 62 65 20 63   appears to be c
f290: 6f 72 72 75 70 74 2c 20 74 72 79 20 74 6f 20 72  orrupt, try to r
f2a0: 65 63 6f 76 65 72 20 74 68 65 20 6c 6f 67 0a 2a  ecover the log.*
f2b0: 2a 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69  * before returni
f2c0: 6e 67 2e 0a 2a 2a 0a 2a 2a 20 53 65 74 20 2a 70  ng..**.** Set *p
f2d0: 43 68 61 6e 67 65 64 20 74 6f 20 31 20 69 66 20  Changed to 1 if 
f2e0: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
f2f0: 61 64 65 72 20 76 61 6c 75 65 20 69 6e 20 70 57  ader value in pW
f300: 61 6c 2d 3e 68 64 72 20 69 73 0a 2a 2a 20 63 68  al->hdr is.** ch
f310: 61 6e 67 65 64 20 62 79 20 74 68 69 73 20 6f 70  anged by this op
f320: 65 72 74 69 6f 6e 2e 20 20 49 66 20 70 57 61 6c  ertion.  If pWal
f330: 2d 3e 68 64 72 20 69 73 20 75 6e 63 68 61 6e 67  ->hdr is unchang
f340: 65 64 2c 20 73 65 74 20 2a 70 43 68 61 6e 67 65  ed, set *pChange
f350: 64 0a 2a 2a 20 74 6f 20 30 2e 0a 2a 2a 0a 2a 2a  d.** to 0..**.**
f360: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 61 6c   This routine al
f370: 73 6f 20 6d 61 70 73 20 74 68 65 20 77 61 6c 2d  so maps the wal-
f380: 69 6e 64 65 78 20 63 6f 6e 74 65 6e 74 20 69 6e  index content in
f390: 74 6f 20 6d 65 6d 6f 72 79 20 61 6e 64 20 61 73  to memory and as
f3a0: 73 69 67 6e 73 0a 2a 2a 20 6f 77 6e 65 72 73 68  signs.** ownersh
f3b0: 69 70 20 6f 66 20 74 68 61 74 20 6d 61 70 70 69  ip of that mappi
f3c0: 6e 67 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e  ng to the curren
f3d0: 74 20 74 68 72 65 61 64 2e 20 20 49 6e 20 73 6f  t thread.  In so
f3e0: 6d 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  me implementatio
f3f0: 6e 73 2c 0a 2a 2a 20 6f 6e 6c 79 20 6f 6e 65 20  ns,.** only one 
f400: 74 68 72 65 61 64 20 61 74 20 61 20 74 69 6d 65  thread at a time
f410: 20 63 61 6e 20 68 6f 6c 64 20 61 20 6d 61 70 70   can hold a mapp
f420: 69 6e 67 20 6f 66 20 74 68 65 20 77 61 6c 2d 69  ing of the wal-i
f430: 6e 64 65 78 2e 20 20 48 65 6e 63 65 2c 0a 2a 2a  ndex.  Hence,.**
f440: 20 74 68 65 20 63 61 6c 6c 65 72 20 73 68 6f 75   the caller shou
f450: 6c 64 20 73 74 72 69 76 65 20 74 6f 20 69 6e 76  ld strive to inv
f460: 6f 6b 65 20 77 61 6c 49 6e 64 65 78 55 6e 6d 61  oke walIndexUnma
f470: 70 28 29 20 61 73 20 73 6f 6f 6e 20 61 73 20 70  p() as soon as p
f480: 6f 73 73 69 62 6c 65 0a 2a 2a 20 61 66 74 65 72  ossible.** after
f490: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65   this routine re
f4a0: 74 75 72 6e 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  turns..**.** If 
f4b0: 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65  the wal-index he
f4c0: 61 64 65 72 20 69 73 20 73 75 63 63 65 73 73 66  ader is successf
f4d0: 75 6c 6c 79 20 72 65 61 64 2c 20 72 65 74 75 72  ully read, retur
f4e0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20 0a 2a 2a  n SQLITE_OK. .**
f4f0: 20 4f 74 68 65 72 77 69 73 65 20 61 6e 20 53 51   Otherwise an SQ
f500: 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 2e  Lite error code.
f510: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
f520: 61 6c 49 6e 64 65 78 52 65 61 64 48 64 72 28 57  alIndexReadHdr(W
f530: 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 2a 70  al *pWal, int *p
f540: 43 68 61 6e 67 65 64 29 7b 0a 20 20 69 6e 74 20  Changed){.  int 
f550: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
f560: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
f570: 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20  eturn code */.  
f580: 69 6e 74 20 62 61 64 48 64 72 3b 20 20 20 20 20  int badHdr;     
f590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
f5a0: 2f 2a 20 54 72 75 65 20 69 66 20 61 20 68 65 61  /* True if a hea
f5b0: 64 65 72 20 72 65 61 64 20 66 61 69 6c 65 64 20  der read failed 
f5c0: 2a 2f 0a 20 20 76 6f 6c 61 74 69 6c 65 20 75 33  */.  volatile u3
f5d0: 32 20 2a 70 61 67 65 30 3b 0a 0a 20 20 2f 2a 20  2 *page0;..  /* 
f5e0: 45 6e 73 75 72 65 20 74 68 61 74 20 70 61 67 65  Ensure that page
f5f0: 20 30 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e   0 of the wal-in
f600: 64 65 78 20 28 74 68 65 20 70 61 67 65 20 74 68  dex (the page th
f610: 61 74 20 63 6f 6e 74 61 69 6e 73 20 74 68 65 20  at contains the 
f620: 0a 20 20 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20  .  ** wal-index 
f630: 68 65 61 64 65 72 29 20 69 73 20 6d 61 70 70 65  header) is mappe
f640: 64 2e 20 52 65 74 75 72 6e 20 65 61 72 6c 79 20  d. Return early 
f650: 69 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75  if an error occu
f660: 72 73 20 68 65 72 65 2e 0a 20 20 2a 2f 0a 20 20  rs here..  */.  
f670: 61 73 73 65 72 74 28 20 70 43 68 61 6e 67 65 64  assert( pChanged
f680: 20 29 3b 0a 20 20 72 63 20 3d 20 77 61 6c 49 6e   );.  rc = walIn
f690: 64 65 78 50 61 67 65 28 70 57 61 6c 2c 20 30 2c  dexPage(pWal, 0,
f6a0: 20 26 70 61 67 65 30 29 3b 0a 20 20 69 66 28 20   &page0);.  if( 
f6b0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
f6c0: 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
f6d0: 20 20 7d 3b 0a 20 20 61 73 73 65 72 74 28 20 70    };.  assert( p
f6e0: 61 67 65 30 20 7c 7c 20 70 57 61 6c 2d 3e 77 72  age0 || pWal->wr
f6f0: 69 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 0a 20  iteLock==0 );.. 
f700: 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72 73 74   /* If the first
f710: 20 70 61 67 65 20 6f 66 20 74 68 65 20 77 61 6c   page of the wal
f720: 2d 69 6e 64 65 78 20 68 61 73 20 62 65 65 6e 20  -index has been 
f730: 6d 61 70 70 65 64 2c 20 74 72 79 20 74 6f 20 72  mapped, try to r
f740: 65 61 64 20 74 68 65 0a 20 20 2a 2a 20 77 61 6c  ead the.  ** wal
f750: 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 6d  -index header im
f760: 6d 65 64 69 61 74 65 6c 79 2c 20 77 69 74 68 6f  mediately, witho
f770: 75 74 20 68 6f 6c 64 69 6e 67 20 61 6e 79 20 6c  ut holding any l
f780: 6f 63 6b 2e 20 54 68 69 73 20 75 73 75 61 6c 6c  ock. This usuall
f790: 79 0a 20 20 2a 2a 20 77 6f 72 6b 73 2c 20 62 75  y.  ** works, bu
f7a0: 74 20 6d 61 79 20 66 61 69 6c 20 69 66 20 74 68  t may fail if th
f7b0: 65 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64  e wal-index head
f7c0: 65 72 20 69 73 20 63 6f 72 72 75 70 74 20 6f 72  er is corrupt or
f7d0: 20 63 75 72 72 65 6e 74 6c 79 20 0a 20 20 2a 2a   currently .  **
f7e0: 20 62 65 69 6e 67 20 6d 6f 64 69 66 69 65 64 20   being modified 
f7f0: 62 79 20 61 6e 6f 74 68 65 72 20 75 73 65 72 2e  by another user.
f800: 0a 20 20 2a 2f 0a 20 20 62 61 64 48 64 72 20 3d  .  */.  badHdr =
f810: 20 28 70 61 67 65 30 20 3f 20 77 61 6c 49 6e 64   (page0 ? walInd
f820: 65 78 54 72 79 48 64 72 28 70 57 61 6c 2c 20 70  exTryHdr(pWal, p
f830: 43 68 61 6e 67 65 64 29 20 3a 20 31 29 3b 0a 0a  Changed) : 1);..
f840: 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72 73    /* If the firs
f850: 74 20 61 74 74 65 6d 70 74 20 66 61 69 6c 65 64  t attempt failed
f860: 2c 20 69 74 20 6d 69 67 68 74 20 68 61 76 65 20  , it might have 
f870: 62 65 65 6e 20 64 75 65 20 74 6f 20 61 20 72 61  been due to a ra
f880: 63 65 0a 20 20 2a 2a 20 77 69 74 68 20 61 20 77  ce.  ** with a w
f890: 72 69 74 65 72 2e 20 20 53 6f 20 67 65 74 20 61  riter.  So get a
f8a0: 20 57 52 49 54 45 20 6c 6f 63 6b 20 61 6e 64 20   WRITE lock and 
f8b0: 74 72 79 20 61 67 61 69 6e 2e 0a 20 20 2a 2f 0a  try again..  */.
f8c0: 20 20 61 73 73 65 72 74 28 20 62 61 64 48 64 72    assert( badHdr
f8d0: 3d 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 77 72 69  ==0 || pWal->wri
f8e0: 74 65 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 20 20 69  teLock==0 );.  i
f8f0: 66 28 20 62 61 64 48 64 72 20 26 26 20 53 51 4c  f( badHdr && SQL
f900: 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61  ITE_OK==(rc = wa
f910: 6c 4c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  lLockExclusive(p
f920: 57 61 6c 2c 20 57 41 4c 5f 57 52 49 54 45 5f 4c  Wal, WAL_WRITE_L
f930: 4f 43 4b 2c 20 31 29 29 20 29 7b 0a 20 20 20 20  OCK, 1)) ){.    
f940: 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
f950: 3d 20 31 3b 0a 20 20 20 20 69 66 28 20 53 51 4c  = 1;.    if( SQL
f960: 49 54 45 5f 4f 4b 3d 3d 28 72 63 20 3d 20 77 61  ITE_OK==(rc = wa
f970: 6c 49 6e 64 65 78 50 61 67 65 28 70 57 61 6c 2c  lIndexPage(pWal,
f980: 20 30 2c 20 26 70 61 67 65 30 29 29 20 29 7b 0a   0, &page0)) ){.
f990: 20 20 20 20 20 20 62 61 64 48 64 72 20 3d 20 77        badHdr = w
f9a0: 61 6c 49 6e 64 65 78 54 72 79 48 64 72 28 70 57  alIndexTryHdr(pW
f9b0: 61 6c 2c 20 70 43 68 61 6e 67 65 64 29 3b 0a 20  al, pChanged);. 
f9c0: 20 20 20 20 20 69 66 28 20 62 61 64 48 64 72 20       if( badHdr 
f9d0: 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 49 66  ){.        /* If
f9e0: 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
f9f0: 65 61 64 65 72 20 69 73 20 73 74 69 6c 6c 20 6d  eader is still m
fa00: 61 6c 66 6f 72 6d 65 64 20 65 76 65 6e 20 77 68  alformed even wh
fa10: 69 6c 65 20 68 6f 6c 64 69 6e 67 0a 20 20 20 20  ile holding.    
fa20: 20 20 20 20 2a 2a 20 61 20 57 52 49 54 45 20 6c      ** a WRITE l
fa30: 6f 63 6b 2c 20 69 74 20 63 61 6e 20 6f 6e 6c 79  ock, it can only
fa40: 20 6d 65 61 6e 20 74 68 61 74 20 74 68 65 20 68   mean that the h
fa50: 65 61 64 65 72 20 69 73 20 63 6f 72 72 75 70 74  eader is corrupt
fa60: 65 64 20 61 6e 64 0a 20 20 20 20 20 20 20 20 2a  ed and.        *
fa70: 2a 20 6e 65 65 64 73 20 74 6f 20 62 65 20 72 65  * needs to be re
fa80: 63 6f 6e 73 74 72 75 63 74 65 64 2e 20 20 53 6f  constructed.  So
fa90: 20 72 75 6e 20 72 65 63 6f 76 65 72 79 20 74 6f   run recovery to
faa0: 20 64 6f 20 65 78 61 63 74 6c 79 20 74 68 61 74   do exactly that
fab0: 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20  ..        */.   
fac0: 20 20 20 20 20 72 63 20 3d 20 77 61 6c 49 6e 64       rc = walInd
fad0: 65 78 52 65 63 6f 76 65 72 28 70 57 61 6c 29 3b  exRecover(pWal);
fae0: 0a 20 20 20 20 20 20 20 20 2a 70 43 68 61 6e 67  .        *pChang
faf0: 65 64 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a  ed = 1;.      }.
fb00: 20 20 20 20 7d 0a 20 20 20 20 70 57 61 6c 2d 3e      }.    pWal->
fb10: 77 72 69 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20  writeLock = 0;. 
fb20: 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c     walUnlockExcl
fb30: 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
fb40: 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a  WRITE_LOCK, 1);.
fb50: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
fb60: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
fb70: 69 73 20 74 68 65 20 76 61 6c 75 65 20 74 68 61  is the value tha
fb80: 74 20 77 61 6c 54 72 79 42 65 67 69 6e 52 65 61  t walTryBeginRea
fb90: 64 20 72 65 74 75 72 6e 73 20 77 68 65 6e 20 69  d returns when i
fba0: 74 20 6e 65 65 64 73 20 74 6f 0a 2a 2a 20 62 65  t needs to.** be
fbb0: 20 72 65 74 72 69 65 64 2e 0a 2a 2f 0a 23 64 65   retried..*/.#de
fbc0: 66 69 6e 65 20 57 41 4c 5f 52 45 54 52 59 20 20  fine WAL_RETRY  
fbd0: 28 2d 31 29 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65  (-1)../*.** Atte
fbe0: 6d 70 74 20 74 6f 20 73 74 61 72 74 20 61 20 72  mpt to start a r
fbf0: 65 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 2e  ead transaction.
fc00: 20 20 54 68 69 73 20 6d 69 67 68 74 20 66 61 69    This might fai
fc10: 6c 20 64 75 65 20 74 6f 20 61 20 72 61 63 65 20  l due to a race 
fc20: 6f 72 0a 2a 2a 20 6f 74 68 65 72 20 74 72 61 6e  or.** other tran
fc30: 73 69 65 6e 74 20 63 6f 6e 64 69 74 69 6f 6e 2e  sient condition.
fc40: 20 20 57 68 65 6e 20 74 68 61 74 20 68 61 70 70    When that happ
fc50: 65 6e 73 2c 20 69 74 20 72 65 74 75 72 6e 73 20  ens, it returns 
fc60: 57 41 4c 5f 52 45 54 52 59 20 74 6f 0a 2a 2a 20  WAL_RETRY to.** 
fc70: 69 6e 64 69 63 61 74 65 20 74 6f 20 74 68 65 20  indicate to the 
fc80: 63 61 6c 6c 65 72 20 74 68 61 74 20 69 74 20 69  caller that it i
fc90: 73 20 73 61 66 65 20 74 6f 20 72 65 74 72 79 20  s safe to retry 
fca0: 69 6d 6d 65 64 69 61 74 65 6c 79 2e 0a 2a 2a 0a  immediately..**.
fcb0: 2a 2a 20 4f 6e 20 73 75 63 63 65 73 73 20 72 65  ** On success re
fcc0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 2e 20  turn SQLITE_OK. 
fcd0: 20 4f 6e 20 61 20 70 65 72 6d 61 6e 74 65 6e 74   On a permantent
fce0: 20 66 61 69 6c 75 72 65 20 28 73 75 63 68 20 61   failure (such a
fcf0: 6e 0a 2a 2a 20 49 2f 4f 20 65 72 72 6f 72 20 6f  n.** I/O error o
fd00: 72 20 61 6e 20 53 51 4c 49 54 45 5f 42 55 53 59  r an SQLITE_BUSY
fd10: 20 62 65 63 61 75 73 65 20 61 6e 6f 74 68 65 72   because another
fd20: 20 70 72 6f 63 65 73 73 20 69 73 20 72 75 6e 6e   process is runn
fd30: 69 6e 67 0a 2a 2a 20 72 65 63 6f 76 65 72 79 29  ing.** recovery)
fd40: 20 72 65 74 75 72 6e 20 61 20 70 6f 73 69 74 69   return a positi
fd50: 76 65 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a 2a  ve error code..*
fd60: 2a 0a 2a 2a 20 4f 6e 20 73 75 63 63 65 73 73 2c  *.** On success,
fd70: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 6f 62   this routine ob
fd80: 74 61 69 6e 73 20 61 20 72 65 61 64 20 6c 6f 63  tains a read loc
fd90: 6b 20 6f 6e 20 0a 2a 2a 20 57 41 4c 5f 52 45 41  k on .** WAL_REA
fda0: 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61  D_LOCK(pWal->rea
fdb0: 64 4c 6f 63 6b 29 2e 20 20 54 68 65 20 70 57 61  dLock).  The pWa
fdc0: 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69 6e 74 65  l->readLock inte
fdd0: 67 65 72 20 69 73 0a 2a 2a 20 69 6e 20 74 68 65  ger is.** in the
fde0: 20 72 61 6e 67 65 20 30 20 3c 3d 20 70 57 61 6c   range 0 <= pWal
fdf0: 2d 3e 72 65 61 64 4c 6f 63 6b 20 3c 20 57 41 4c  ->readLock < WAL
fe00: 5f 4e 52 45 41 44 45 52 2e 20 20 49 66 20 70 57  _NREADER.  If pW
fe10: 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 28 2d  al->readLock==(-
fe20: 31 29 0a 2a 2a 20 74 68 61 74 20 6d 65 61 6e 73  1).** that means
fe30: 20 74 68 65 20 57 61 6c 20 64 6f 65 73 20 6e 6f   the Wal does no
fe40: 74 20 68 6f 6c 64 20 61 6e 79 20 72 65 61 64 20  t hold any read 
fe50: 6c 6f 63 6b 2e 20 20 54 68 65 20 72 65 61 64 65  lock.  The reade
fe60: 72 20 6d 75 73 74 20 6e 6f 74 0a 2a 2a 20 61 63  r must not.** ac
fe70: 63 65 73 73 20 61 6e 79 20 64 61 74 61 62 61 73  cess any databas
fe80: 65 20 70 61 67 65 20 74 68 61 74 20 69 73 20 6d  e page that is m
fe90: 6f 64 69 66 69 65 64 20 62 79 20 61 20 57 41 4c  odified by a WAL
fea0: 20 66 72 61 6d 65 20 75 70 20 74 6f 20 61 6e 64   frame up to and
feb0: 0a 2a 2a 20 69 6e 63 6c 75 64 69 6e 67 20 66 72  .** including fr
fec0: 61 6d 65 20 6e 75 6d 62 65 72 20 61 52 65 61 64  ame number aRead
fed0: 4d 61 72 6b 5b 70 57 61 6c 2d 3e 72 65 61 64 4c  Mark[pWal->readL
fee0: 6f 63 6b 5d 2e 20 20 54 68 65 20 72 65 61 64 65  ock].  The reade
fef0: 72 20 77 69 6c 6c 0a 2a 2a 20 75 73 65 20 57 41  r will.** use WA
ff00: 4c 20 66 72 61 6d 65 73 20 75 70 20 74 6f 20 61  L frames up to a
ff10: 6e 64 20 69 6e 63 6c 75 64 69 6e 67 20 70 57 61  nd including pWa
ff20: 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 69  l->hdr.mxFrame i
ff30: 66 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  f pWal->readLock
ff40: 3e 30 0a 2a 2a 20 4f 72 20 69 66 20 70 57 61 6c  >0.** Or if pWal
ff50: 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d 30 2c 20 74  ->readLock==0, t
ff60: 68 65 6e 20 74 68 65 20 72 65 61 64 65 72 20 77  hen the reader w
ff70: 69 6c 6c 20 69 67 6e 6f 72 65 20 74 68 65 20 57  ill ignore the W
ff80: 41 4c 0a 2a 2a 20 63 6f 6d 70 6c 65 74 65 6c 79  AL.** completely
ff90: 20 61 6e 64 20 67 65 74 20 61 6c 6c 20 63 6f 6e   and get all con
ffa0: 74 65 6e 74 20 64 69 72 65 63 74 6c 79 20 66 72  tent directly fr
ffb0: 6f 6d 20 74 68 65 20 64 61 74 61 62 61 73 65 20  om the database 
ffc0: 66 69 6c 65 2e 0a 2a 2a 20 57 68 65 6e 20 74 68  file..** When th
ffd0: 65 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  e read transacti
ffe0: 6f 6e 20 69 73 20 63 6f 6d 70 6c 65 74 65 64 2c  on is completed,
fff0: 20 74 68 65 20 63 61 6c 6c 65 72 20 6d 75 73 74   the caller must
10000 20 72 65 6c 65 61 73 65 20 74 68 65 0a 2a 2a 20   release the.** 
10010 6c 6f 63 6b 20 6f 6e 20 57 41 4c 5f 52 45 41 44  lock on WAL_READ
10020 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72 65 61 64  _LOCK(pWal->read
10030 4c 6f 63 6b 29 20 61 6e 64 20 73 65 74 20 70 57  Lock) and set pW
10040 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 74 6f 20  al->readLock to 
10050 2d 31 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72  -1..**.** This r
10060 6f 75 74 69 6e 65 20 75 73 65 73 20 74 68 65 20  outine uses the 
10070 6e 42 61 63 6b 66 69 6c 6c 20 61 6e 64 20 61 52  nBackfill and aR
10080 65 61 64 4d 61 72 6b 5b 5d 20 66 69 65 6c 64 73  eadMark[] fields
10090 20 6f 66 20 74 68 65 20 68 65 61 64 65 72 0a 2a   of the header.*
100a0 2a 20 74 6f 20 73 65 6c 65 63 74 20 61 20 70 61  * to select a pa
100b0 72 74 69 63 75 6c 61 72 20 57 41 4c 5f 52 45 41  rticular WAL_REA
100c0 44 5f 4c 4f 43 4b 28 29 20 74 68 61 74 20 73 74  D_LOCK() that st
100d0 72 69 76 65 73 20 74 6f 20 6c 65 74 20 74 68 65  rives to let the
100e0 0a 2a 2a 20 63 68 65 63 6b 70 6f 69 6e 74 20 70  .** checkpoint p
100f0 72 6f 63 65 73 73 20 64 6f 20 61 73 20 6d 75 63  rocess do as muc
10100 68 20 77 6f 72 6b 20 61 73 20 70 6f 73 73 69 62  h work as possib
10110 6c 65 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e  le.  This routin
10120 65 20 6d 69 67 68 74 0a 2a 2a 20 75 70 64 61 74  e might.** updat
10130 65 20 76 61 6c 75 65 73 20 6f 66 20 74 68 65 20  e values of the 
10140 61 52 65 61 64 4d 61 72 6b 5b 5d 20 61 72 72 61  aReadMark[] arra
10150 79 20 69 6e 20 74 68 65 20 68 65 61 64 65 72 2c  y in the header,
10160 20 62 75 74 20 69 66 20 69 74 20 64 6f 65 73 0a   but if it does.
10170 2a 2a 20 73 6f 20 69 74 20 74 61 6b 65 73 20 63  ** so it takes c
10180 61 72 65 20 74 6f 20 68 6f 6c 64 20 61 6e 20 65  are to hold an e
10190 78 63 6c 75 73 69 76 65 20 6c 6f 63 6b 20 6f 6e  xclusive lock on
101a0 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69   the correspondi
101b0 6e 67 0a 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c  ng.** WAL_READ_L
101c0 4f 43 4b 28 29 20 77 68 69 6c 65 20 63 68 61 6e  OCK() while chan
101d0 67 69 6e 67 20 76 61 6c 75 65 73 2e 0a 2a 2f 0a  ging values..*/.
101e0 73 74 61 74 69 63 20 69 6e 74 20 77 61 6c 54 72  static int walTr
101f0 79 42 65 67 69 6e 52 65 61 64 28 57 61 6c 20 2a  yBeginRead(Wal *
10200 70 57 61 6c 2c 20 69 6e 74 20 2a 70 43 68 61 6e  pWal, int *pChan
10210 67 65 64 2c 20 69 6e 74 20 75 73 65 57 61 6c 2c  ged, int useWal,
10220 20 69 6e 74 20 63 6e 74 29 7b 0a 20 20 76 6f 6c   int cnt){.  vol
10230 61 74 69 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66  atile WalCkptInf
10240 6f 20 2a 70 49 6e 66 6f 3b 20 20 20 20 2f 2a 20  o *pInfo;    /* 
10250 43 68 65 63 6b 70 6f 69 6e 74 20 69 6e 66 6f 72  Checkpoint infor
10260 6d 61 74 69 6f 6e 20 69 6e 20 77 61 6c 2d 69 6e  mation in wal-in
10270 64 65 78 20 2a 2f 0a 20 20 75 33 32 20 6d 78 52  dex */.  u32 mxR
10280 65 61 64 4d 61 72 6b 3b 20 20 20 20 20 20 20 20  eadMark;        
10290 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61 72 67           /* Larg
102a0 65 73 74 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20  est aReadMark[] 
102b0 76 61 6c 75 65 20 2a 2f 0a 20 20 69 6e 74 20 6d  value */.  int m
102c0 78 49 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  xI;             
102d0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
102e0 64 65 78 20 6f 66 20 6c 61 72 67 65 73 74 20 61  dex of largest a
102f0 52 65 61 64 4d 61 72 6b 5b 5d 20 76 61 6c 75 65  ReadMark[] value
10300 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20   */.  int i;    
10310 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
10320 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f        /* Loop co
10330 75 6e 74 65 72 20 2a 2f 0a 20 20 69 6e 74 20 72  unter */.  int r
10340 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  c = SQLITE_OK;  
10350 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
10360 74 75 72 6e 20 63 6f 64 65 20 20 2a 2f 0a 0a 20  turn code  */.. 
10370 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72   assert( pWal->r
10380 65 61 64 4c 6f 63 6b 3c 30 20 29 3b 20 20 20 20  eadLock<0 );    
10390 20 2f 2a 20 4e 6f 74 20 63 75 72 72 65 6e 74 6c   /* Not currentl
103a0 79 20 6c 6f 63 6b 65 64 20 2a 2f 0a 0a 20 20 2f  y locked */..  /
103b0 2a 20 54 61 6b 65 20 73 74 65 70 73 20 74 6f 20  * Take steps to 
103c0 61 76 6f 69 64 20 73 70 69 6e 6e 69 6e 67 20 66  avoid spinning f
103d0 6f 72 65 76 65 72 20 69 66 20 74 68 65 72 65 20  orever if there 
103e0 69 73 20 61 20 70 72 6f 74 6f 63 6f 6c 20 65 72  is a protocol er
103f0 72 6f 72 2e 20 2a 2f 0a 20 20 69 66 28 20 63 6e  ror. */.  if( cn
10400 74 3e 35 20 29 7b 0a 20 20 20 20 69 66 28 20 63  t>5 ){.    if( c
10410 6e 74 3e 31 30 30 20 29 20 72 65 74 75 72 6e 20  nt>100 ) return 
10420 53 51 4c 49 54 45 5f 50 52 4f 54 4f 43 4f 4c 3b  SQLITE_PROTOCOL;
10430 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53 6c  .    sqlite3OsSl
10440 65 65 70 28 70 57 61 6c 2d 3e 70 56 66 73 2c 20  eep(pWal->pVfs, 
10450 31 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21  1);.  }..  if( !
10460 75 73 65 57 61 6c 20 29 7b 0a 20 20 20 20 72 63  useWal ){.    rc
10470 20 3d 20 77 61 6c 49 6e 64 65 78 52 65 61 64 48   = walIndexReadH
10480 64 72 28 70 57 61 6c 2c 20 70 43 68 61 6e 67 65  dr(pWal, pChange
10490 64 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  d);.    if( rc==
104a0 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b 0a 20  SQLITE_BUSY ){. 
104b0 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 72 65       /* If there
104c0 20 69 73 20 6e 6f 74 20 61 20 72 65 63 6f 76 65   is not a recove
104d0 72 79 20 72 75 6e 6e 69 6e 67 20 69 6e 20 61 6e  ry running in an
104e0 6f 74 68 65 72 20 74 68 72 65 61 64 20 6f 72 20  other thread or 
104f0 70 72 6f 63 65 73 73 0a 20 20 20 20 20 20 2a 2a  process.      **
10500 20 74 68 65 6e 20 63 6f 6e 76 65 72 74 20 42 55   then convert BU
10510 53 59 20 65 72 72 6f 72 73 20 74 6f 20 57 41 4c  SY errors to WAL
10520 5f 52 45 54 52 59 2e 20 20 49 66 20 72 65 63 6f  _RETRY.  If reco
10530 76 65 72 79 20 69 73 20 6b 6e 6f 77 6e 20 74 6f  very is known to
10540 0a 20 20 20 20 20 20 2a 2a 20 62 65 20 72 75 6e  .      ** be run
10550 6e 69 6e 67 2c 20 63 6f 6e 76 65 72 74 20 42 55  ning, convert BU
10560 53 59 20 74 6f 20 42 55 53 59 5f 52 45 43 4f 56  SY to BUSY_RECOV
10570 45 52 59 2e 20 20 54 68 65 72 65 20 69 73 20 61  ERY.  There is a
10580 20 72 61 63 65 20 68 65 72 65 0a 20 20 20 20 20   race here.     
10590 20 2a 2a 20 77 68 69 63 68 20 6d 69 67 68 74 20   ** which might 
105a0 63 61 75 73 65 20 57 41 4c 5f 52 45 54 52 59 20  cause WAL_RETRY 
105b0 74 6f 20 62 65 20 72 65 74 75 72 6e 65 64 20 65  to be returned e
105c0 76 65 6e 20 69 66 20 42 55 53 59 5f 52 45 43 4f  ven if BUSY_RECO
105d0 56 45 52 59 0a 20 20 20 20 20 20 2a 2a 20 77 6f  VERY.      ** wo
105e0 75 6c 64 20 62 65 20 74 65 63 68 6e 69 63 61 6c  uld be technical
105f0 6c 79 20 63 6f 72 72 65 63 74 2e 20 20 42 75 74  ly correct.  But
10600 20 74 68 65 20 72 61 63 65 20 69 73 20 62 65 6e   the race is ben
10610 69 67 6e 20 73 69 6e 63 65 20 77 69 74 68 0a 20  ign since with. 
10620 20 20 20 20 20 2a 2a 20 57 41 4c 5f 52 45 54 52       ** WAL_RETR
10630 59 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 77  Y this routine w
10640 69 6c 6c 20 62 65 20 63 61 6c 6c 65 64 20 61 67  ill be called ag
10650 61 69 6e 20 61 6e 64 20 77 69 6c 6c 20 70 72 6f  ain and will pro
10660 62 61 62 6c 79 20 62 65 0a 20 20 20 20 20 20 2a  bably be.      *
10670 2a 20 72 69 67 68 74 20 6f 6e 20 74 68 65 20 73  * right on the s
10680 65 63 6f 6e 64 20 69 74 65 72 61 74 69 6f 6e 2e  econd iteration.
10690 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20  .      */.      
106a0 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53 68 61 72  rc = walLockShar
106b0 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 43  ed(pWal, WAL_REC
106c0 4f 56 45 52 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20  OVER_LOCK);.    
106d0 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
106e0 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 77  _OK ){.        w
106f0 61 6c 55 6e 6c 6f 63 6b 53 68 61 72 65 64 28 70  alUnlockShared(p
10700 57 61 6c 2c 20 57 41 4c 5f 52 45 43 4f 56 45 52  Wal, WAL_RECOVER
10710 5f 4c 4f 43 4b 29 3b 0a 20 20 20 20 20 20 20 20  _LOCK);.        
10720 72 63 20 3d 20 57 41 4c 5f 52 45 54 52 59 3b 0a  rc = WAL_RETRY;.
10730 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
10740 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55 53 59 20  rc==SQLITE_BUSY 
10750 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  ){.        rc = 
10760 53 51 4c 49 54 45 5f 42 55 53 59 5f 52 45 43 4f  SQLITE_BUSY_RECO
10770 56 45 52 59 3b 0a 20 20 20 20 20 20 7d 0a 20 20  VERY;.      }.  
10780 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72 63    }.  }.  if( rc
10790 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
107a0 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
107b0 7d 0a 0a 20 20 70 49 6e 66 6f 20 3d 20 77 61 6c  }..  pInfo = wal
107c0 43 6b 70 74 49 6e 66 6f 28 70 57 61 6c 29 3b 0a  CkptInfo(pWal);.
107d0 20 20 69 66 28 20 21 75 73 65 57 61 6c 20 26 26    if( !useWal &&
107e0 20 70 49 6e 66 6f 2d 3e 6e 42 61 63 6b 66 69 6c   pInfo->nBackfil
107f0 6c 3d 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46  l==pWal->hdr.mxF
10800 72 61 6d 65 20 29 7b 0a 20 20 20 20 2f 2a 20 54  rame ){.    /* T
10810 68 65 20 57 41 4c 20 68 61 73 20 62 65 65 6e 20  he WAL has been 
10820 63 6f 6d 70 6c 65 74 65 6c 79 20 62 61 63 6b 66  completely backf
10830 69 6c 6c 65 64 20 28 6f 72 20 69 74 20 69 73 20  illed (or it is 
10840 65 6d 70 74 79 29 2e 0a 20 20 20 20 2a 2a 20 61  empty)..    ** a
10850 6e 64 20 63 61 6e 20 62 65 20 73 61 66 65 6c 79  nd can be safely
10860 20 69 67 6e 6f 72 65 64 2e 0a 20 20 20 20 2a 2f   ignored..    */
10870 0a 20 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63  .    rc = walLoc
10880 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41  kShared(pWal, WA
10890 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b  L_READ_LOCK(0));
108a0 0a 20 20 20 20 73 71 6c 69 74 65 33 4f 73 53 68  .    sqlite3OsSh
108b0 6d 42 61 72 72 69 65 72 28 70 57 61 6c 2d 3e 70  mBarrier(pWal->p
108c0 44 62 46 64 29 3b 0a 20 20 20 20 69 66 28 20 72  DbFd);.    if( r
108d0 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
108e0 20 20 20 20 20 20 69 66 28 20 6d 65 6d 63 6d 70        if( memcmp
108f0 28 28 76 6f 69 64 20 2a 29 77 61 6c 49 6e 64 65  ((void *)walInde
10900 78 48 64 72 28 70 57 61 6c 29 2c 20 26 70 57 61  xHdr(pWal), &pWa
10910 6c 2d 3e 68 64 72 2c 20 73 69 7a 65 6f 66 28 57  l->hdr, sizeof(W
10920 61 6c 49 6e 64 65 78 48 64 72 29 29 20 29 7b 0a  alIndexHdr)) ){.
10930 20 20 20 20 20 20 20 20 2f 2a 20 49 74 20 69 73          /* It is
10940 20 6e 6f 74 20 73 61 66 65 20 74 6f 20 61 6c 6c   not safe to all
10950 6f 77 20 74 68 65 20 72 65 61 64 65 72 20 74 6f  ow the reader to
10960 20 63 6f 6e 74 69 6e 75 65 20 68 65 72 65 20 69   continue here i
10970 66 20 66 72 61 6d 65 73 0a 20 20 20 20 20 20 20  f frames.       
10980 20 2a 2a 20 6d 61 79 20 68 61 76 65 20 62 65 65   ** may have bee
10990 6e 20 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68  n appended to th
109a0 65 20 6c 6f 67 20 62 65 66 6f 72 65 20 52 45 41  e log before REA
109b0 44 5f 4c 4f 43 4b 28 30 29 20 77 61 73 20 6f 62  D_LOCK(0) was ob
109c0 74 61 69 6e 65 64 2e 0a 20 20 20 20 20 20 20 20  tained..        
109d0 2a 2a 20 57 68 65 6e 20 68 6f 6c 64 69 6e 67 20  ** When holding 
109e0 52 45 41 44 5f 4c 4f 43 4b 28 30 29 2c 20 74 68  READ_LOCK(0), th
109f0 65 20 72 65 61 64 65 72 20 69 67 6e 6f 72 65 73  e reader ignores
10a00 20 74 68 65 20 65 6e 74 69 72 65 20 6c 6f 67 20   the entire log 
10a10 66 69 6c 65 2c 0a 20 20 20 20 20 20 20 20 2a 2a  file,.        **
10a20 20 77 68 69 63 68 20 69 6d 70 6c 69 65 73 20 74   which implies t
10a30 68 61 74 20 74 68 65 20 64 61 74 61 62 61 73 65  hat the database
10a40 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20 61   file contains a
10a50 20 74 72 75 73 74 77 6f 72 74 68 79 0a 20 20 20   trustworthy.   
10a60 20 20 20 20 20 2a 2a 20 73 6e 61 70 73 68 6f 54       ** snapshoT
10a70 2e 20 53 69 6e 63 65 20 68 6f 6c 64 69 6e 67 20  . Since holding 
10a80 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20 70 72 65  READ_LOCK(0) pre
10a90 76 65 6e 74 73 20 61 20 63 68 65 63 6b 70 6f 69  vents a checkpoi
10aa0 6e 74 20 66 72 6f 6d 0a 20 20 20 20 20 20 20 20  nt from.        
10ab0 2a 2a 20 68 61 70 70 65 6e 69 6e 67 2c 20 74 68  ** happening, th
10ac0 69 73 20 69 73 20 75 73 75 61 6c 6c 79 20 63 6f  is is usually co
10ad0 72 72 65 63 74 2e 0a 20 20 20 20 20 20 20 20 2a  rrect..        *
10ae0 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 48 6f 77  *.        ** How
10af0 65 76 65 72 2c 20 69 66 20 66 72 61 6d 65 73 20  ever, if frames 
10b00 68 61 76 65 20 62 65 65 6e 20 61 70 70 65 6e 64  have been append
10b10 65 64 20 74 6f 20 74 68 65 20 6c 6f 67 20 28 6f  ed to the log (o
10b20 72 20 69 66 20 74 68 65 20 6c 6f 67 20 0a 20 20  r if the log .  
10b30 20 20 20 20 20 20 2a 2a 20 69 73 20 77 72 61 70        ** is wrap
10b40 70 65 64 20 61 6e 64 20 77 72 69 74 74 65 6e 20  ped and written 
10b50 66 6f 72 20 74 68 61 74 20 6d 61 74 74 65 72 29  for that matter)
10b60 20 62 65 66 6f 72 65 20 74 68 65 20 52 45 41 44   before the READ
10b70 5f 4c 4f 43 4b 28 30 29 0a 20 20 20 20 20 20 20  _LOCK(0).       
10b80 20 2a 2a 20 69 73 20 6f 62 74 61 69 6e 65 64 2c   ** is obtained,
10b90 20 74 68 61 74 20 69 73 20 6e 6f 74 20 6e 65 63   that is not nec
10ba0 65 73 73 61 72 69 6c 79 20 74 72 75 65 2e 20 41  essarily true. A
10bb0 20 63 68 65 63 6b 70 6f 69 6e 74 65 72 20 6d 61   checkpointer ma
10bc0 79 0a 20 20 20 20 20 20 20 20 2a 2a 20 68 61 76  y.        ** hav
10bd0 65 20 73 74 61 72 74 65 64 20 74 6f 20 62 61 63  e started to bac
10be0 6b 66 69 6c 6c 20 74 68 65 20 61 70 70 65 6e 64  kfill the append
10bf0 65 64 20 66 72 61 6d 65 73 20 62 75 74 20 63 72  ed frames but cr
10c00 61 73 68 65 64 20 62 65 66 6f 72 65 0a 20 20 20  ashed before.   
10c10 20 20 20 20 20 2a 2a 20 69 74 20 66 69 6e 69 73       ** it finis
10c20 68 65 64 2e 20 4c 65 61 76 69 6e 67 20 61 20 63  hed. Leaving a c
10c30 6f 72 72 75 70 74 20 69 6d 61 67 65 20 69 6e 20  orrupt image in 
10c40 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
10c50 65 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a 20 20  e..        */.  
10c60 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53        walUnlockS
10c70 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
10c80 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29 3b 0a 20  READ_LOCK(0));. 
10c90 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 57 41         return WA
10ca0 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 20 20 7d  L_RETRY;.      }
10cb0 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 72 65 61  .      pWal->rea
10cc0 64 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20 20  dLock = 0;.     
10cd0 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
10ce0 4b 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  K;.    }else if(
10cf0 20 72 63 21 3d 53 51 4c 49 54 45 5f 42 55 53 59   rc!=SQLITE_BUSY
10d00 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
10d10 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a   rc;.    }.  }..
10d20 20 20 2f 2a 20 49 66 20 77 65 20 67 65 74 20 74    /* If we get t
10d30 68 69 73 20 66 61 72 2c 20 69 74 20 6d 65 61 6e  his far, it mean
10d40 73 20 74 68 61 74 20 74 68 65 20 72 65 61 64 65  s that the reade
10d50 72 20 77 69 6c 6c 20 77 61 6e 74 20 74 6f 20 75  r will want to u
10d60 73 65 0a 20 20 2a 2a 20 74 68 65 20 57 41 4c 20  se.  ** the WAL 
10d70 74 6f 20 67 65 74 20 61 74 20 63 6f 6e 74 65 6e  to get at conten
10d80 74 20 66 72 6f 6d 20 72 65 63 65 6e 74 20 63 6f  t from recent co
10d90 6d 6d 69 74 73 2e 20 20 54 68 65 20 6a 6f 62 20  mmits.  The job 
10da0 6e 6f 77 20 69 73 0a 20 20 2a 2a 20 74 6f 20 73  now is.  ** to s
10db0 65 6c 65 63 74 20 6f 6e 65 20 6f 66 20 74 68 65  elect one of the
10dc0 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e 74   aReadMark[] ent
10dd0 72 69 65 73 20 74 68 61 74 20 69 73 20 63 6c 6f  ries that is clo
10de0 73 65 73 74 20 74 6f 0a 20 20 2a 2a 20 62 75 74  sest to.  ** but
10df0 20 6e 6f 74 20 65 78 63 65 65 64 69 6e 67 20 70   not exceeding p
10e00 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
10e10 20 61 6e 64 20 6c 6f 63 6b 20 74 68 61 74 20 65   and lock that e
10e20 6e 74 72 79 2e 0a 20 20 2a 2f 0a 20 20 6d 78 52  ntry..  */.  mxR
10e30 65 61 64 4d 61 72 6b 20 3d 20 30 3b 0a 20 20 6d  eadMark = 0;.  m
10e40 78 49 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d  xI = 0;.  for(i=
10e50 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52  1; i<WAL_NREADER
10e60 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 75 33 32 20  ; i++){.    u32 
10e70 74 68 69 73 4d 61 72 6b 20 3d 20 70 49 6e 66 6f  thisMark = pInfo
10e80 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 69 5d 3b 0a  ->aReadMark[i];.
10e90 20 20 20 20 69 66 28 20 6d 78 52 65 61 64 4d 61      if( mxReadMa
10ea0 72 6b 3c 3d 74 68 69 73 4d 61 72 6b 20 26 26 20  rk<=thisMark && 
10eb0 74 68 69 73 4d 61 72 6b 3c 3d 70 57 61 6c 2d 3e  thisMark<=pWal->
10ec0 68 64 72 2e 6d 78 46 72 61 6d 65 20 29 7b 0a 20  hdr.mxFrame ){. 
10ed0 20 20 20 20 20 61 73 73 65 72 74 28 20 74 68 69       assert( thi
10ee0 73 4d 61 72 6b 21 3d 52 45 41 44 4d 41 52 4b 5f  sMark!=READMARK_
10ef0 4e 4f 54 5f 55 53 45 44 20 29 3b 0a 20 20 20 20  NOT_USED );.    
10f00 20 20 6d 78 52 65 61 64 4d 61 72 6b 20 3d 20 74    mxReadMark = t
10f10 68 69 73 4d 61 72 6b 3b 0a 20 20 20 20 20 20 6d  hisMark;.      m
10f20 78 49 20 3d 20 69 3b 0a 20 20 20 20 7d 0a 20 20  xI = i;.    }.  
10f30 7d 0a 20 20 69 66 28 20 6d 78 49 3d 3d 30 20 29  }.  if( mxI==0 )
10f40 7b 0a 20 20 20 20 2f 2a 20 49 66 20 77 65 20 67  {.    /* If we g
10f50 65 74 20 68 65 72 65 2c 20 69 74 20 6d 65 61 6e  et here, it mean
10f60 73 20 74 68 61 74 20 61 6c 6c 20 6f 66 20 74 68  s that all of th
10f70 65 20 61 52 65 61 64 4d 61 72 6b 5b 5d 20 65 6e  e aReadMark[] en
10f80 74 72 69 65 73 20 62 65 74 77 65 65 6e 0a 20 20  tries between.  
10f90 20 20 2a 2a 20 31 20 61 6e 64 20 57 41 4c 5f 4e    ** 1 and WAL_N
10fa0 52 45 41 44 45 52 2d 31 20 61 72 65 20 7a 65 72  READER-1 are zer
10fb0 6f 2e 20 20 54 72 79 20 74 6f 20 69 6e 69 74 69  o.  Try to initi
10fc0 61 6c 69 7a 65 20 61 52 65 61 64 4d 61 72 6b 5b  alize aReadMark[
10fd0 31 5d 20 74 6f 0a 20 20 20 20 2a 2a 20 62 65 20  1] to.    ** be 
10fe0 6d 78 46 72 61 6d 65 2c 20 74 68 65 6e 20 72 65  mxFrame, then re
10ff0 74 72 79 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  try..    */.    
11000 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
11010 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
11020 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20 31 29  READ_LOCK(1), 1)
11030 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
11040 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
11050 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
11060 6b 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72  k[1] = pWal->hdr
11070 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 20 20  .mxFrame;.      
11080 77 61 6c 55 6e 6c 6f 63 6b 45 78 63 6c 75 73 69  walUnlockExclusi
11090 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 52 45 41  ve(pWal, WAL_REA
110a0 44 5f 4c 4f 43 4b 28 31 29 2c 20 31 29 3b 0a 20  D_LOCK(1), 1);. 
110b0 20 20 20 20 20 72 63 20 3d 20 57 41 4c 5f 52 45       rc = WAL_RE
110c0 54 52 59 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  TRY;.    }else i
110d0 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 42 55  f( rc==SQLITE_BU
110e0 53 59 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  SY ){.      rc =
110f0 20 57 41 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20   WAL_RETRY;.    
11100 7d 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  }.    return rc;
11110 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66  .  }else{.    if
11120 28 20 6d 78 52 65 61 64 4d 61 72 6b 20 3c 20 70  ( mxReadMark < p
11130 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
11140 20 29 7b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d   ){.      for(i=
11150 31 3b 20 69 3c 57 41 4c 5f 4e 52 45 41 44 45 52  1; i<WAL_NREADER
11160 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; i++){.        
11170 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
11180 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
11190 52 45 41 44 5f 4c 4f 43 4b 28 69 29 2c 20 31 29  READ_LOCK(i), 1)
111a0 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 72 63  ;.        if( rc
111b0 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
111c0 20 20 20 20 20 20 20 20 20 6d 78 52 65 61 64 4d           mxReadM
111d0 61 72 6b 20 3d 20 70 49 6e 66 6f 2d 3e 61 52 65  ark = pInfo->aRe
111e0 61 64 4d 61 72 6b 5b 69 5d 20 3d 20 70 57 61 6c  adMark[i] = pWal
111f0 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 3b 0a 20  ->hdr.mxFrame;. 
11200 20 20 20 20 20 20 20 20 20 6d 78 49 20 3d 20 69           mxI = i
11210 3b 0a 20 20 20 20 20 20 20 20 20 20 77 61 6c 55  ;.          walU
11220 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  nlockExclusive(p
11230 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
11240 43 4b 28 69 29 2c 20 31 29 3b 0a 20 20 20 20 20  CK(i), 1);.     
11250 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
11260 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 72 63      }else if( rc
11270 21 3d 53 51 4c 49 54 45 5f 42 55 53 59 20 29 7b  !=SQLITE_BUSY ){
11280 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72  .          retur
11290 6e 20 72 63 3b 0a 20 20 20 20 20 20 20 20 7d 0a  n rc;.        }.
112a0 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20        }.    }.. 
112b0 20 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 53     rc = walLockS
112c0 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
112d0 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b  READ_LOCK(mxI));
112e0 0a 20 20 20 20 69 66 28 20 72 63 20 29 7b 0a 20  .    if( rc ){. 
112f0 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3d 3d       return rc==
11300 53 51 4c 49 54 45 5f 42 55 53 59 20 3f 20 57 41  SQLITE_BUSY ? WA
11310 4c 5f 52 45 54 52 59 20 3a 20 72 63 3b 0a 20 20  L_RETRY : rc;.  
11320 20 20 7d 0a 20 20 20 20 2f 2a 20 4e 6f 77 20 74    }.    /* Now t
11330 68 61 74 20 74 68 65 20 72 65 61 64 2d 6c 6f 63  hat the read-loc
11340 6b 20 68 61 73 20 62 65 65 6e 20 6f 62 74 61 69  k has been obtai
11350 6e 65 64 2c 20 63 68 65 63 6b 20 74 68 61 74 20  ned, check that 
11360 6e 65 69 74 68 65 72 20 74 68 65 0a 20 20 20 20  neither the.    
11370 2a 2a 20 76 61 6c 75 65 20 69 6e 20 74 68 65 20  ** value in the 
11380 61 52 65 61 64 4d 61 72 6b 5b 5d 20 61 72 72 61  aReadMark[] arra
11390 79 20 6f 72 20 74 68 65 20 63 6f 6e 74 65 6e 74  y or the content
113a0 73 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  s of the wal-ind
113b0 65 78 0a 20 20 20 20 2a 2a 20 68 65 61 64 65 72  ex.    ** header
113c0 20 68 61 76 65 20 63 68 61 6e 67 65 64 2e 0a 20   have changed.. 
113d0 20 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 49 74 20     **.    ** It 
113e0 69 73 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20  is necessary to 
113f0 63 68 65 63 6b 20 74 68 61 74 20 74 68 65 20 77  check that the w
11400 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20  al-index header 
11410 64 69 64 20 6e 6f 74 20 63 68 61 6e 67 65 0a 20  did not change. 
11420 20 20 20 2a 2a 20 62 65 74 77 65 65 6e 20 74 68     ** between th
11430 65 20 74 69 6d 65 20 69 74 20 77 61 73 20 72 65  e time it was re
11440 61 64 20 61 6e 64 20 77 68 65 6e 20 74 68 65 20  ad and when the 
11450 73 68 61 72 65 64 2d 6c 6f 63 6b 20 77 61 73 20  shared-lock was 
11460 6f 62 74 61 69 6e 65 64 0a 20 20 20 20 2a 2a 20  obtained.    ** 
11470 6f 6e 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b  on WAL_READ_LOCK
11480 28 6d 78 49 29 20 77 61 73 20 6f 62 74 61 69 6e  (mxI) was obtain
11490 65 64 20 74 6f 20 61 63 63 6f 75 6e 74 20 66 6f  ed to account fo
114a0 72 20 74 68 65 20 70 6f 73 73 69 62 69 6c 69 74  r the possibilit
114b0 79 0a 20 20 20 20 2a 2a 20 74 68 61 74 20 74 68  y.    ** that th
114c0 65 20 6c 6f 67 20 66 69 6c 65 20 6d 61 79 20 68  e log file may h
114d0 61 76 65 20 62 65 65 6e 20 77 72 61 70 70 65 64  ave been wrapped
114e0 20 62 79 20 61 20 77 72 69 74 65 72 2c 20 6f 72   by a writer, or
114f0 20 74 68 61 74 20 66 72 61 6d 65 73 0a 20 20 20   that frames.   
11500 20 2a 2a 20 74 68 61 74 20 6f 63 63 75 72 20 6c   ** that occur l
11510 61 74 65 72 20 69 6e 20 74 68 65 20 6c 6f 67 20  ater in the log 
11520 74 68 61 6e 20 70 57 61 6c 2d 3e 68 64 72 2e 6d  than pWal->hdr.m
11530 78 46 72 61 6d 65 20 6d 61 79 20 68 61 76 65 20  xFrame may have 
11540 62 65 65 6e 0a 20 20 20 20 2a 2a 20 63 6f 70 69  been.    ** copi
11550 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61  ed into the data
11560 62 61 73 65 20 62 79 20 61 20 63 68 65 63 6b 70  base by a checkp
11570 6f 69 6e 74 65 72 2e 20 49 66 20 65 69 74 68 65  ointer. If eithe
11580 72 20 6f 66 20 74 68 65 73 65 20 74 68 69 6e 67  r of these thing
11590 73 0a 20 20 20 20 2a 2a 20 68 61 70 70 65 6e 65  s.    ** happene
115a0 64 2c 20 74 68 65 6e 20 72 65 61 64 69 6e 67 20  d, then reading 
115b0 74 68 65 20 64 61 74 61 62 61 73 65 20 77 69 74  the database wit
115c0 68 20 74 68 65 20 63 75 72 72 65 6e 74 20 76 61  h the current va
115d0 6c 75 65 20 6f 66 0a 20 20 20 20 2a 2a 20 70 57  lue of.    ** pW
115e0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
115f0 72 69 73 6b 73 20 72 65 61 64 69 6e 67 20 61 20  risks reading a 
11600 63 6f 72 72 75 70 74 65 64 20 73 6e 61 70 73 68  corrupted snapsh
11610 6f 74 2e 20 53 6f 2c 20 72 65 74 72 79 0a 20 20  ot. So, retry.  
11620 20 20 2a 2a 20 69 6e 73 74 65 61 64 2e 0a 20 20    ** instead..  
11630 20 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 68 69 73    **.    ** This
11640 20 64 6f 65 73 20 6e 6f 74 20 67 75 61 72 61 6e   does not guaran
11650 74 65 65 20 74 68 61 74 20 74 68 65 20 63 6f 70  tee that the cop
11660 79 20 6f 66 20 74 68 65 20 77 61 6c 2d 69 6e 64  y of the wal-ind
11670 65 78 20 68 65 61 64 65 72 20 69 73 20 75 70 20  ex header is up 
11680 74 6f 0a 20 20 20 20 2a 2a 20 64 61 74 65 20 62  to.    ** date b
11690 65 66 6f 72 65 20 70 72 6f 63 65 65 64 69 6e 67  efore proceeding
116a0 2e 20 54 68 61 74 20 77 6f 75 6c 64 20 6e 6f 74  . That would not
116b0 20 62 65 20 70 6f 73 73 69 62 6c 65 20 77 69 74   be possible wit
116c0 68 6f 75 74 20 73 6f 6d 65 68 6f 77 0a 20 20 20  hout somehow.   
116d0 20 2a 2a 20 62 6c 6f 63 6b 69 6e 67 20 77 72 69   ** blocking wri
116e0 74 65 72 73 2e 20 49 74 20 6f 6e 6c 79 20 67 75  ters. It only gu
116f0 61 72 61 6e 74 65 65 73 20 74 68 61 74 20 61 20  arantees that a 
11700 64 61 6e 67 65 72 6f 75 73 20 63 68 65 63 6b 70  dangerous checkp
11710 6f 69 6e 74 20 6f 72 20 0a 20 20 20 20 2a 2a 20  oint or .    ** 
11720 6c 6f 67 2d 77 72 61 70 20 28 65 69 74 68 65 72  log-wrap (either
11730 20 6f 66 20 77 68 69 63 68 20 77 6f 75 6c 64 20   of which would 
11740 72 65 71 75 69 72 65 20 61 6e 20 65 78 63 6c 75  require an exclu
11750 73 69 76 65 20 6c 6f 63 6b 20 6f 6e 0a 20 20 20  sive lock on.   
11760 20 2a 2a 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43   ** WAL_READ_LOC
11770 4b 28 6d 78 49 29 29 20 68 61 73 20 6e 6f 74 20  K(mxI)) has not 
11780 6f 63 63 75 72 72 65 64 20 73 69 6e 63 65 20 74  occurred since t
11790 68 65 20 73 6e 61 70 73 68 6f 74 20 77 61 73 20  he snapshot was 
117a0 76 61 6c 69 64 2e 0a 20 20 20 20 2a 2f 0a 20 20  valid..    */.  
117b0 20 20 73 71 6c 69 74 65 33 4f 73 53 68 6d 42 61    sqlite3OsShmBa
117c0 72 72 69 65 72 28 70 57 61 6c 2d 3e 70 44 62 46  rrier(pWal->pDbF
117d0 64 29 3b 0a 20 20 20 20 69 66 28 20 70 49 6e 66  d);.    if( pInf
117e0 6f 2d 3e 61 52 65 61 64 4d 61 72 6b 5b 6d 78 49  o->aReadMark[mxI
117f0 5d 21 3d 6d 78 52 65 61 64 4d 61 72 6b 0a 20 20  ]!=mxReadMark.  
11800 20 20 20 7c 7c 20 6d 65 6d 63 6d 70 28 28 76 6f     || memcmp((vo
11810 69 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72  id *)walIndexHdr
11820 28 70 57 61 6c 29 2c 20 26 70 57 61 6c 2d 3e 68  (pWal), &pWal->h
11830 64 72 2c 20 73 69 7a 65 6f 66 28 57 61 6c 49 6e  dr, sizeof(WalIn
11840 64 65 78 48 64 72 29 29 0a 20 20 20 20 29 7b 0a  dexHdr)).    ){.
11850 20 20 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53        walUnlockS
11860 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
11870 52 45 41 44 5f 4c 4f 43 4b 28 6d 78 49 29 29 3b  READ_LOCK(mxI));
11880 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 57 41  .      return WA
11890 4c 5f 52 45 54 52 59 3b 0a 20 20 20 20 7d 65 6c  L_RETRY;.    }el
118a0 73 65 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74  se{.      assert
118b0 28 20 6d 78 52 65 61 64 4d 61 72 6b 3c 3d 70 57  ( mxReadMark<=pW
118c0 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
118d0 29 3b 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 72  );.      pWal->r
118e0 65 61 64 4c 6f 63 6b 20 3d 20 6d 78 49 3b 0a 20  eadLock = mxI;. 
118f0 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
11900 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42  n rc;.}../*.** B
11910 65 67 69 6e 20 61 20 72 65 61 64 20 74 72 61 6e  egin a read tran
11920 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20 64  saction on the d
11930 61 74 61 62 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 54  atabase..**.** T
11940 68 69 73 20 72 6f 75 74 69 6e 65 20 75 73 65 64  his routine used
11950 20 74 6f 20 62 65 20 63 61 6c 6c 65 64 20 73 71   to be called sq
11960 6c 69 74 65 33 4f 70 65 6e 53 6e 61 70 73 68 6f  lite3OpenSnapsho
11970 74 28 29 20 61 6e 64 20 77 69 74 68 20 67 6f 6f  t() and with goo
11980 64 20 72 65 61 73 6f 6e 3a 0a 2a 2a 20 69 74 20  d reason:.** it 
11990 74 61 6b 65 73 20 61 20 73 6e 61 70 73 68 6f 74  takes a snapshot
119a0 20 6f 66 20 74 68 65 20 73 74 61 74 65 20 6f 66   of the state of
119b0 20 74 68 65 20 57 41 4c 20 61 6e 64 20 77 61 6c   the WAL and wal
119c0 2d 69 6e 64 65 78 20 66 6f 72 20 74 68 65 20 63  -index for the c
119d0 75 72 72 65 6e 74 0a 2a 2a 20 69 6e 73 74 61 6e  urrent.** instan
119e0 74 20 69 6e 20 74 69 6d 65 2e 20 20 54 68 65 20  t in time.  The 
119f0 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 20 77  current thread w
11a00 69 6c 6c 20 63 6f 6e 74 69 6e 75 65 20 74 6f 20  ill continue to 
11a10 75 73 65 20 74 68 69 73 20 73 6e 61 70 73 68 6f  use this snapsho
11a20 74 2e 0a 2a 2a 20 4f 74 68 65 72 20 74 68 72 65  t..** Other thre
11a30 61 64 73 20 6d 69 67 68 74 20 61 70 70 65 6e 64  ads might append
11a40 20 6e 65 77 20 63 6f 6e 74 65 6e 74 20 74 6f 20   new content to 
11a50 74 68 65 20 57 41 4c 20 61 6e 64 20 77 61 6c 2d  the WAL and wal-
11a60 69 6e 64 65 78 20 62 75 74 0a 2a 2a 20 74 68 61  index but.** tha
11a70 74 20 65 78 74 72 61 20 63 6f 6e 74 65 6e 74 20  t extra content 
11a80 69 73 20 69 67 6e 6f 72 65 64 20 62 79 20 74 68  is ignored by th
11a90 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64  e current thread
11aa0 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 64  ..**.** If the d
11ab0 61 74 61 62 61 73 65 20 63 6f 6e 74 65 6e 74 73  atabase contents
11ac0 20 68 61 76 65 20 63 68 61 6e 67 65 73 20 73 69   have changes si
11ad0 6e 63 65 20 74 68 65 20 70 72 65 76 69 6f 75 73  nce the previous
11ae0 20 72 65 61 64 0a 2a 2a 20 74 72 61 6e 73 61 63   read.** transac
11af0 74 69 6f 6e 2c 20 74 68 65 6e 20 2a 70 43 68 61  tion, then *pCha
11b00 6e 67 65 64 20 69 73 20 73 65 74 20 74 6f 20 31  nged is set to 1
11b10 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e   before returnin
11b20 67 2e 20 20 54 68 65 0a 2a 2a 20 50 61 67 65 72  g.  The.** Pager
11b30 20 6c 61 79 65 72 20 77 69 6c 6c 20 75 73 65 20   layer will use 
11b40 74 68 69 73 20 74 6f 20 6b 6e 6f 77 20 74 68 61  this to know tha
11b50 74 20 69 73 20 63 61 63 68 65 20 69 73 20 73 74  t is cache is st
11b60 61 6c 65 20 61 6e 64 0a 2a 2a 20 6e 65 65 64 73  ale and.** needs
11b70 20 74 6f 20 62 65 20 66 6c 75 73 68 65 64 2e 0a   to be flushed..
11b80 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61  */.int sqlite3Wa
11b90 6c 42 65 67 69 6e 52 65 61 64 54 72 61 6e 73 61  lBeginReadTransa
11ba0 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61 6c 2c  ction(Wal *pWal,
11bb0 20 69 6e 74 20 2a 70 43 68 61 6e 67 65 64 29 7b   int *pChanged){
11bc0 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
11bd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11be0 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64     /* Return cod
11bf0 65 20 2a 2f 0a 20 20 69 6e 74 20 63 6e 74 20 3d  e */.  int cnt =
11c00 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
11c10 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
11c20 20 6f 66 20 54 72 79 42 65 67 69 6e 52 65 61 64   of TryBeginRead
11c30 20 61 74 74 65 6d 70 74 73 20 2a 2f 0a 0a 20 20   attempts */..  
11c40 64 6f 7b 0a 20 20 20 20 72 63 20 3d 20 77 61 6c  do{.    rc = wal
11c50 54 72 79 42 65 67 69 6e 52 65 61 64 28 70 57 61  TryBeginRead(pWa
11c60 6c 2c 20 70 43 68 61 6e 67 65 64 2c 20 30 2c 20  l, pChanged, 0, 
11c70 2b 2b 63 6e 74 29 3b 0a 20 20 7d 77 68 69 6c 65  ++cnt);.  }while
11c80 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54 52 59 20  ( rc==WAL_RETRY 
11c90 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
11ca0 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6e 69 73 68 20  }../*.** Finish 
11cb0 77 69 74 68 20 61 20 72 65 61 64 20 74 72 61 6e  with a read tran
11cc0 73 61 63 74 69 6f 6e 2e 20 20 41 6c 6c 20 74 68  saction.  All th
11cd0 69 73 20 64 6f 65 73 20 69 73 20 72 65 6c 65 61  is does is relea
11ce0 73 65 20 74 68 65 0a 2a 2a 20 72 65 61 64 2d 6c  se the.** read-l
11cf0 6f 63 6b 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  ock..*/.void sql
11d00 69 74 65 33 57 61 6c 45 6e 64 52 65 61 64 54 72  ite3WalEndReadTr
11d10 61 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70  ansaction(Wal *p
11d20 57 61 6c 29 7b 0a 20 20 69 66 28 20 70 57 61 6c  Wal){.  if( pWal
11d30 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29 7b  ->readLock>=0 ){
11d40 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53 68  .    walUnlockSh
11d50 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f 52  ared(pWal, WAL_R
11d60 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e 72  EAD_LOCK(pWal->r
11d70 65 61 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20 70  eadLock));.    p
11d80 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 3d 20  Wal->readLock = 
11d90 2d 31 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  -1;.  }.}../*.**
11da0 20 52 65 61 64 20 61 20 70 61 67 65 20 66 72 6f   Read a page fro
11db0 6d 20 74 68 65 20 57 41 4c 2c 20 69 66 20 69 74  m the WAL, if it
11dc0 20 69 73 20 70 72 65 73 65 6e 74 20 69 6e 20 74   is present in t
11dd0 68 65 20 57 41 4c 20 61 6e 64 20 69 66 20 74 68  he WAL and if th
11de0 65 20 0a 2a 2a 20 63 75 72 72 65 6e 74 20 72 65  e .** current re
11df0 61 64 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69  ad transaction i
11e00 73 20 63 6f 6e 66 69 67 75 72 65 64 20 74 6f 20  s configured to 
11e10 75 73 65 20 74 68 65 20 57 41 4c 2e 20 20 0a 2a  use the WAL.  .*
11e20 2a 0a 2a 2a 20 54 68 65 20 2a 70 49 6e 57 61 6c  *.** The *pInWal
11e30 20 69 73 20 73 65 74 20 74 6f 20 31 20 69 66 20   is set to 1 if 
11e40 74 68 65 20 72 65 71 75 65 73 74 65 64 20 70 61  the requested pa
11e50 67 65 20 69 73 20 69 6e 20 74 68 65 20 57 41 4c  ge is in the WAL
11e60 20 61 6e 64 0a 2a 2a 20 68 61 73 20 62 65 65 6e   and.** has been
11e70 20 6c 6f 61 64 65 64 2e 20 20 4f 72 20 2a 70 49   loaded.  Or *pI
11e80 6e 57 61 6c 20 69 73 20 73 65 74 20 74 6f 20 30  nWal is set to 0
11e90 20 69 66 20 74 68 65 20 70 61 67 65 20 77 61 73   if the page was
11ea0 20 6e 6f 74 20 69 6e 20 0a 2a 2a 20 74 68 65 20   not in .** the 
11eb0 57 41 4c 20 61 6e 64 20 6e 65 65 64 73 20 74 6f  WAL and needs to
11ec0 20 62 65 20 72 65 61 64 20 6f 75 74 20 6f 66 20   be read out of 
11ed0 74 68 65 20 64 61 74 61 62 61 73 65 2e 0a 2a 2f  the database..*/
11ee0 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 52  .int sqlite3WalR
11ef0 65 61 64 28 0a 20 20 57 61 6c 20 2a 70 57 61 6c  ead(.  Wal *pWal
11f00 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
11f10 20 20 20 20 20 20 20 2f 2a 20 57 41 4c 20 68 61         /* WAL ha
11f20 6e 64 6c 65 20 2a 2f 0a 20 20 50 67 6e 6f 20 70  ndle */.  Pgno p
11f30 67 6e 6f 2c 20 20 20 20 20 20 20 20 20 20 20 20  gno,            
11f40 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74            /* Dat
11f50 61 62 61 73 65 20 70 61 67 65 20 6e 75 6d 62 65  abase page numbe
11f60 72 20 74 6f 20 72 65 61 64 20 64 61 74 61 20 66  r to read data f
11f70 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 49 6e  or */.  int *pIn
11f80 57 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20  Wal,            
11f90 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20          /* OUT: 
11fa0 54 72 75 65 20 69 66 20 64 61 74 61 20 69 73 20  True if data is 
11fb0 72 65 61 64 20 66 72 6f 6d 20 57 41 4c 20 2a 2f  read from WAL */
11fc0 0a 20 20 69 6e 74 20 6e 4f 75 74 2c 20 20 20 20  .  int nOut,    
11fd0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
11fe0 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62 75     /* Size of bu
11ff0 66 66 65 72 20 70 4f 75 74 20 69 6e 20 62 79 74  ffer pOut in byt
12000 65 73 20 2a 2f 0a 20 20 75 38 20 2a 70 4f 75 74  es */.  u8 *pOut
12010 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12020 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65          /* Buffe
12030 72 20 74 6f 20 77 72 69 74 65 20 70 61 67 65 20  r to write page 
12040 64 61 74 61 20 74 6f 20 2a 2f 0a 29 7b 0a 20 20  data to */.){.  
12050 75 33 32 20 69 52 65 61 64 20 3d 20 30 3b 20 20  u32 iRead = 0;  
12060 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12070 2f 2a 20 49 66 20 21 3d 30 2c 20 57 41 4c 20 66  /* If !=0, WAL f
12080 72 61 6d 65 20 74 6f 20 72 65 74 75 72 6e 20 64  rame to return d
12090 61 74 61 20 66 72 6f 6d 20 2a 2f 0a 20 20 75 33  ata from */.  u3
120a0 32 20 69 4c 61 73 74 20 3d 20 70 57 61 6c 2d 3e  2 iLast = pWal->
120b0 68 64 72 2e 6d 78 46 72 61 6d 65 3b 20 20 2f 2a  hdr.mxFrame;  /*
120c0 20 4c 61 73 74 20 70 61 67 65 20 69 6e 20 57 41   Last page in WA
120d0 4c 20 66 6f 72 20 74 68 69 73 20 72 65 61 64 65  L for this reade
120e0 72 20 2a 2f 0a 20 20 69 6e 74 20 69 48 61 73 68  r */.  int iHash
120f0 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
12100 20 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74         /* Used t
12110 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20 4e  o loop through N
12120 20 68 61 73 68 20 74 61 62 6c 65 73 20 2a 2f 0a   hash tables */.
12130 0a 20 20 2f 2a 20 54 68 69 73 20 72 6f 75 74 69  .  /* This routi
12140 6e 65 20 69 73 20 6f 6e 6c 79 20 62 65 20 63 61  ne is only be ca
12150 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e  lled from within
12160 20 61 20 72 65 61 64 20 74 72 61 6e 73 61 63 74   a read transact
12170 69 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74  ion. */.  assert
12180 28 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  ( pWal->readLock
12190 3e 3d 30 20 7c 7c 20 70 57 61 6c 2d 3e 6c 6f 63  >=0 || pWal->loc
121a0 6b 45 72 72 6f 72 20 29 3b 0a 0a 20 20 2f 2a 20  kError );..  /* 
121b0 49 66 20 74 68 65 20 22 6c 61 73 74 20 70 61 67  If the "last pag
121c0 65 22 20 66 69 65 6c 64 20 6f 66 20 74 68 65 20  e" field of the 
121d0 77 61 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72  wal-index header
121e0 20 73 6e 61 70 73 68 6f 74 20 69 73 20 30 2c 20   snapshot is 0, 
121f0 74 68 65 6e 0a 20 20 2a 2a 20 6e 6f 20 64 61 74  then.  ** no dat
12200 61 20 77 69 6c 6c 20 62 65 20 72 65 61 64 20 66  a will be read f
12210 72 6f 6d 20 74 68 65 20 77 61 6c 20 75 6e 64 65  rom the wal unde
12220 72 20 61 6e 79 20 63 69 72 63 75 6d 73 74 61 6e  r any circumstan
12230 63 65 73 2e 20 52 65 74 75 72 6e 20 65 61 72 6c  ces. Return earl
12240 79 0a 20 20 2a 2a 20 69 6e 20 74 68 69 73 20 63  y.  ** in this c
12250 61 73 65 20 74 6f 20 61 76 6f 69 64 20 74 68 65  ase to avoid the
12260 20 77 61 6c 49 6e 64 65 78 4d 61 70 2f 55 6e 6d   walIndexMap/Unm
12270 61 70 20 6f 76 65 72 68 65 61 64 2e 20 20 4c 69  ap overhead.  Li
12280 6b 65 77 69 73 65 2c 20 69 66 0a 20 20 2a 2a 20  kewise, if.  ** 
12290 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d  pWal->readLock==
122a0 30 2c 20 74 68 65 6e 20 74 68 65 20 57 41 4c 20  0, then the WAL 
122b0 69 73 20 69 67 6e 6f 72 65 64 20 62 79 20 74 68  is ignored by th
122c0 65 20 72 65 61 64 65 72 20 73 6f 0a 20 20 2a 2a  e reader so.  **
122d0 20 72 65 74 75 72 6e 20 65 61 72 6c 79 2c 20 61   return early, a
122e0 73 20 69 66 20 74 68 65 20 57 41 4c 20 77 65 72  s if the WAL wer
122f0 65 20 65 6d 70 74 79 2e 0a 20 20 2a 2f 0a 20 20  e empty..  */.  
12300 69 66 28 20 69 4c 61 73 74 3d 3d 30 20 7c 7c 20  if( iLast==0 || 
12310 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d 3d  pWal->readLock==
12320 30 20 29 7b 0a 20 20 20 20 2a 70 49 6e 57 61 6c  0 ){.    *pInWal
12330 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75 72 6e   = 0;.    return
12340 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a   SQLITE_OK;.  }.
12350 0a 20 20 2f 2a 20 53 65 61 72 63 68 20 74 68 65  .  /* Search the
12360 20 68 61 73 68 20 74 61 62 6c 65 20 6f 72 20 74   hash table or t
12370 61 62 6c 65 73 20 66 6f 72 20 61 6e 20 65 6e 74  ables for an ent
12380 72 79 20 6d 61 74 63 68 69 6e 67 20 70 61 67 65  ry matching page
12390 20 6e 75 6d 62 65 72 0a 20 20 2a 2a 20 70 67 6e   number.  ** pgn
123a0 6f 2e 20 45 61 63 68 20 69 74 65 72 61 74 69 6f  o. Each iteratio
123b0 6e 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  n of the followi
123c0 6e 67 20 66 6f 72 28 29 20 6c 6f 6f 70 20 73 65  ng for() loop se
123d0 61 72 63 68 65 73 20 6f 6e 65 0a 20 20 2a 2a 20  arches one.  ** 
123e0 68 61 73 68 20 74 61 62 6c 65 20 28 65 61 63 68  hash table (each
123f0 20 68 61 73 68 20 74 61 62 6c 65 20 69 6e 64 65   hash table inde
12400 78 65 73 20 75 70 20 74 6f 20 48 41 53 48 54 41  xes up to HASHTA
12410 42 4c 45 5f 4e 50 41 47 45 20 66 72 61 6d 65 73  BLE_NPAGE frames
12420 29 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 54 68 69  )..  **.  ** Thi
12430 73 20 63 6f 64 65 20 6d 61 79 20 72 75 6e 20 63  s code may run c
12440 6f 6e 63 75 72 72 65 6e 74 6c 79 20 74 6f 20 74  oncurrently to t
12450 68 65 20 63 6f 64 65 20 69 6e 20 77 61 6c 49 6e  he code in walIn
12460 64 65 78 41 70 70 65 6e 64 28 29 0a 20 20 2a 2a  dexAppend().  **
12470 20 74 68 61 74 20 61 64 64 73 20 65 6e 74 72 69   that adds entri
12480 65 73 20 74 6f 20 74 68 65 20 77 61 6c 2d 69 6e  es to the wal-in
12490 64 65 78 20 28 61 6e 64 20 70 6f 73 73 69 62 6c  dex (and possibl
124a0 79 20 74 6f 20 74 68 69 73 20 68 61 73 68 20 0a  y to this hash .
124b0 20 20 2a 2a 20 74 61 62 6c 65 29 2e 20 54 68 69    ** table). Thi
124c0 73 20 6d 65 61 6e 73 20 74 68 65 20 76 61 6c 75  s means the valu
124d0 65 20 6a 75 73 74 20 72 65 61 64 20 66 72 6f 6d  e just read from
124e0 20 74 68 65 20 68 61 73 68 20 0a 20 20 2a 2a 20   the hash .  ** 
124f0 73 6c 6f 74 20 28 61 48 61 73 68 5b 69 4b 65 79  slot (aHash[iKey
12500 5d 29 20 6d 61 79 20 68 61 76 65 20 62 65 65 6e  ]) may have been
12510 20 61 64 64 65 64 20 62 65 66 6f 72 65 20 6f 72   added before or
12520 20 61 66 74 65 72 20 74 68 65 20 0a 20 20 2a 2a   after the .  **
12530 20 63 75 72 72 65 6e 74 20 72 65 61 64 20 74 72   current read tr
12540 61 6e 73 61 63 74 69 6f 6e 20 77 61 73 20 6f 70  ansaction was op
12550 65 6e 65 64 2e 20 56 61 6c 75 65 73 20 61 64 64  ened. Values add
12560 65 64 20 61 66 74 65 72 20 74 68 65 0a 20 20 2a  ed after the.  *
12570 2a 20 72 65 61 64 20 74 72 61 6e 73 61 63 74 69  * read transacti
12580 6f 6e 20 77 61 73 20 6f 70 65 6e 65 64 20 6d 61  on was opened ma
12590 79 20 68 61 76 65 20 62 65 65 6e 20 77 72 69 74  y have been writ
125a0 74 65 6e 20 69 6e 63 6f 72 72 65 63 74 6c 79 20  ten incorrectly 
125b0 2d 0a 20 20 2a 2a 20 69 2e 65 2e 20 74 68 65 73  -.  ** i.e. thes
125c0 65 20 73 6c 6f 74 73 20 6d 61 79 20 63 6f 6e 74  e slots may cont
125d0 61 69 6e 20 67 61 72 62 61 67 65 20 64 61 74 61  ain garbage data
125e0 2e 20 48 6f 77 65 76 65 72 2c 20 77 65 20 61 73  . However, we as
125f0 73 75 6d 65 0a 20 20 2a 2a 20 74 68 61 74 20 61  sume.  ** that a
12600 6e 79 20 73 6c 6f 74 73 20 77 72 69 74 74 65 6e  ny slots written
12610 20 62 65 66 6f 72 65 20 74 68 65 20 63 75 72 72   before the curr
12620 65 6e 74 20 72 65 61 64 20 74 72 61 6e 73 61 63  ent read transac
12630 74 69 6f 6e 20 77 61 73 0a 20 20 2a 2a 20 6f 70  tion was.  ** op
12640 65 6e 65 64 20 72 65 6d 61 69 6e 20 75 6e 6d 6f  ened remain unmo
12650 64 69 66 69 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a  dified..  **.  *
12660 2a 20 46 6f 72 20 74 68 65 20 72 65 61 73 6f 6e  * For the reason
12670 73 20 61 62 6f 76 65 2c 20 74 68 65 20 69 66 28  s above, the if(
12680 2e 2e 2e 29 20 63 6f 6e 64 69 74 69 6f 6e 20 66  ...) condition f
12690 65 61 74 75 72 65 64 20 69 6e 20 74 68 65 20 69  eatured in the i
126a0 6e 6e 65 72 0a 20 20 2a 2a 20 6c 6f 6f 70 20 6f  nner.  ** loop o
126b0 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
126c0 62 6c 6f 63 6b 20 69 73 20 6d 6f 72 65 20 73 74  block is more st
126d0 72 69 6e 67 65 6e 74 20 74 68 61 74 20 77 6f 75  ringent that wou
126e0 6c 64 20 62 65 20 72 65 71 75 69 72 65 64 20 0a  ld be required .
126f0 20 20 2a 2a 20 69 66 20 77 65 20 68 61 64 20 65    ** if we had e
12700 78 63 6c 75 73 69 76 65 20 61 63 63 65 73 73 20  xclusive access 
12710 74 6f 20 74 68 65 20 68 61 73 68 2d 74 61 62 6c  to the hash-tabl
12720 65 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 28  e:.  **.  **   (
12730 61 50 67 6e 6f 5b 69 46 72 61 6d 65 5d 3d 3d 70  aPgno[iFrame]==p
12740 67 6e 6f 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20  gno): .  **     
12750 54 68 69 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66  This condition f
12760 69 6c 74 65 72 73 20 6f 75 74 20 6e 6f 72 6d 61  ilters out norma
12770 6c 20 68 61 73 68 2d 74 61 62 6c 65 20 63 6f 6c  l hash-table col
12780 6c 69 73 69 6f 6e 73 2e 0a 20 20 2a 2a 0a 20 20  lisions..  **.  
12790 2a 2a 20 20 20 28 69 46 72 61 6d 65 3c 3d 69 4c  **   (iFrame<=iL
127a0 61 73 74 29 3a 20 0a 20 20 2a 2a 20 20 20 20 20  ast): .  **     
127b0 54 68 69 73 20 63 6f 6e 64 69 74 69 6f 6e 20 66  This condition f
127c0 69 6c 74 65 72 73 20 6f 75 74 20 65 6e 74 72 69  ilters out entri
127d0 65 73 20 74 68 61 74 20 77 65 72 65 20 61 64 64  es that were add
127e0 65 64 20 74 6f 20 74 68 65 20 68 61 73 68 0a 20  ed to the hash. 
127f0 20 2a 2a 20 20 20 20 20 74 61 62 6c 65 20 61 66   **     table af
12800 74 65 72 20 74 68 65 20 63 75 72 72 65 6e 74 20  ter the current 
12810 72 65 61 64 2d 74 72 61 6e 73 61 63 74 69 6f 6e  read-transaction
12820 20 68 61 64 20 73 74 61 72 74 65 64 2e 0a 20 20   had started..  
12830 2a 2f 0a 20 20 66 6f 72 28 69 48 61 73 68 3d 77  */.  for(iHash=w
12840 61 6c 46 72 61 6d 65 50 61 67 65 28 69 4c 61 73  alFramePage(iLas
12850 74 29 3b 20 69 48 61 73 68 3e 3d 30 20 26 26 20  t); iHash>=0 && 
12860 69 52 65 61 64 3d 3d 30 3b 20 69 48 61 73 68 2d  iRead==0; iHash-
12870 2d 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65  -){.    volatile
12880 20 68 74 5f 73 6c 6f 74 20 2a 61 48 61 73 68 3b   ht_slot *aHash;
12890 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
128a0 20 74 6f 20 68 61 73 68 20 74 61 62 6c 65 20 2a   to hash table *
128b0 2f 0a 20 20 20 20 76 6f 6c 61 74 69 6c 65 20 75  /.    volatile u
128c0 33 32 20 2a 61 50 67 6e 6f 3b 20 20 20 20 20 20  32 *aPgno;      
128d0 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
128e0 6f 20 61 72 72 61 79 20 6f 66 20 70 61 67 65 20  o array of page 
128f0 6e 75 6d 62 65 72 73 20 2a 2f 0a 20 20 20 20 75  numbers */.    u
12900 33 32 20 69 5a 65 72 6f 3b 20 20 20 20 20 20 20  32 iZero;       
12910 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12920 46 72 61 6d 65 20 6e 75 6d 62 65 72 20 63 6f 72  Frame number cor
12930 72 65 73 70 6f 6e 64 69 6e 67 20 74 6f 20 61 50  responding to aP
12940 67 6e 6f 5b 30 5d 20 2a 2f 0a 20 20 20 20 69 6e  gno[0] */.    in
12950 74 20 69 4b 65 79 3b 20 20 20 20 20 20 20 20 20  t iKey;         
12960 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48              /* H
12970 61 73 68 20 73 6c 6f 74 20 69 6e 64 65 78 20 2a  ash slot index *
12980 2f 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a 0a 20  /.    int rc;.. 
12990 20 20 20 72 63 20 3d 20 77 61 6c 48 61 73 68 47     rc = walHashG
129a0 65 74 28 70 57 61 6c 2c 20 69 48 61 73 68 2c 20  et(pWal, iHash, 
129b0 26 61 48 61 73 68 2c 20 26 61 50 67 6e 6f 2c 20  &aHash, &aPgno, 
129c0 26 69 5a 65 72 6f 29 3b 0a 20 20 20 20 69 66 28  &iZero);.    if(
129d0 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
129e0 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72  {.      return r
129f0 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72  c;.    }.    for
12a00 28 69 4b 65 79 3d 77 61 6c 48 61 73 68 28 70 67  (iKey=walHash(pg
12a10 6e 6f 29 3b 20 61 48 61 73 68 5b 69 4b 65 79 5d  no); aHash[iKey]
12a20 3b 20 69 4b 65 79 3d 77 61 6c 4e 65 78 74 48 61  ; iKey=walNextHa
12a30 73 68 28 69 4b 65 79 29 29 7b 0a 20 20 20 20 20  sh(iKey)){.     
12a40 20 75 33 32 20 69 46 72 61 6d 65 20 3d 20 61 48   u32 iFrame = aH
12a50 61 73 68 5b 69 4b 65 79 5d 20 2b 20 69 5a 65 72  ash[iKey] + iZer
12a60 6f 3b 0a 20 20 20 20 20 20 69 66 28 20 69 46 72  o;.      if( iFr
12a70 61 6d 65 3c 3d 69 4c 61 73 74 20 26 26 20 61 50  ame<=iLast && aP
12a80 67 6e 6f 5b 61 48 61 73 68 5b 69 4b 65 79 5d 5d  gno[aHash[iKey]]
12a90 3d 3d 70 67 6e 6f 20 29 7b 0a 20 20 20 20 20 20  ==pgno ){.      
12aa0 20 20 61 73 73 65 72 74 28 20 69 46 72 61 6d 65    assert( iFrame
12ab0 3e 69 52 65 61 64 20 29 3b 0a 20 20 20 20 20 20  >iRead );.      
12ac0 20 20 69 52 65 61 64 20 3d 20 69 46 72 61 6d 65    iRead = iFrame
12ad0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
12ae0 20 20 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49    }..#ifdef SQLI
12af0 54 45 5f 45 4e 41 42 4c 45 5f 45 58 50 45 4e 53  TE_ENABLE_EXPENS
12b00 49 56 45 5f 41 53 53 45 52 54 0a 20 20 2f 2a 20  IVE_ASSERT.  /* 
12b10 49 66 20 65 78 70 65 6e 73 69 76 65 20 61 73 73  If expensive ass
12b20 65 72 74 28 29 20 73 74 61 74 65 6d 65 6e 74 73  ert() statements
12b30 20 61 72 65 20 61 76 61 69 6c 61 62 6c 65 2c 20   are available, 
12b40 64 6f 20 61 20 6c 69 6e 65 61 72 20 73 65 61 72  do a linear sear
12b50 63 68 0a 20 20 2a 2a 20 6f 66 20 74 68 65 20 77  ch.  ** of the w
12b60 61 6c 2d 69 6e 64 65 78 20 66 69 6c 65 20 63 6f  al-index file co
12b70 6e 74 65 6e 74 2e 20 4d 61 6b 65 20 73 75 72 65  ntent. Make sure
12b80 20 74 68 65 20 72 65 73 75 6c 74 73 20 61 67 72   the results agr
12b90 65 65 20 77 69 74 68 20 74 68 65 0a 20 20 2a 2a  ee with the.  **
12ba0 20 72 65 73 75 6c 74 20 6f 62 74 61 69 6e 65 64   result obtained
12bb0 20 75 73 69 6e 67 20 74 68 65 20 68 61 73 68 20   using the hash 
12bc0 69 6e 64 65 78 65 73 20 61 62 6f 76 65 2e 20 20  indexes above.  
12bd0 2a 2f 0a 20 20 7b 0a 20 20 20 20 75 33 32 20 69  */.  {.    u32 i
12be0 52 65 61 64 32 20 3d 20 30 3b 0a 20 20 20 20 75  Read2 = 0;.    u
12bf0 33 32 20 69 54 65 73 74 3b 0a 20 20 20 20 66 6f  32 iTest;.    fo
12c00 72 28 69 54 65 73 74 3d 69 4c 61 73 74 3b 20 69  r(iTest=iLast; i
12c10 54 65 73 74 3e 30 3b 20 69 54 65 73 74 2d 2d 29  Test>0; iTest--)
12c20 7b 0a 20 20 20 20 20 20 69 66 28 20 77 61 6c 46  {.      if( walF
12c30 72 61 6d 65 50 67 6e 6f 28 70 57 61 6c 2c 20 69  ramePgno(pWal, i
12c40 54 65 73 74 29 3d 3d 70 67 6e 6f 20 29 7b 0a 20  Test)==pgno ){. 
12c50 20 20 20 20 20 20 20 69 52 65 61 64 32 20 3d 20         iRead2 = 
12c60 69 54 65 73 74 3b 0a 20 20 20 20 20 20 20 20 62  iTest;.        b
12c70 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
12c80 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20    }.    assert( 
12c90 69 52 65 61 64 3d 3d 69 52 65 61 64 32 20 29 3b  iRead==iRead2 );
12ca0 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 2f  .  }.#endif..  /
12cb0 2a 20 49 66 20 69 52 65 61 64 20 69 73 20 6e 6f  * If iRead is no
12cc0 6e 2d 7a 65 72 6f 2c 20 74 68 65 6e 20 69 74 20  n-zero, then it 
12cd0 69 73 20 74 68 65 20 6c 6f 67 20 66 72 61 6d 65  is the log frame
12ce0 20 6e 75 6d 62 65 72 20 74 68 61 74 20 63 6f 6e   number that con
12cf0 74 61 69 6e 73 20 74 68 65 0a 20 20 2a 2a 20 72  tains the.  ** r
12d00 65 71 75 69 72 65 64 20 70 61 67 65 2e 20 52 65  equired page. Re
12d10 61 64 20 61 6e 64 20 72 65 74 75 72 6e 20 64 61  ad and return da
12d20 74 61 20 66 72 6f 6d 20 74 68 65 20 6c 6f 67 20  ta from the log 
12d30 66 69 6c 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  file..  */.  if(
12d40 20 69 52 65 61 64 20 29 7b 0a 20 20 20 20 69 36   iRead ){.    i6
12d50 34 20 69 4f 66 66 73 65 74 20 3d 20 77 61 6c 46  4 iOffset = walF
12d60 72 61 6d 65 4f 66 66 73 65 74 28 69 52 65 61 64  rameOffset(iRead
12d70 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61  , pWal->hdr.szPa
12d80 67 65 29 20 2b 20 57 41 4c 5f 46 52 41 4d 45 5f  ge) + WAL_FRAME_
12d90 48 44 52 53 49 5a 45 3b 0a 20 20 20 20 2a 70 49  HDRSIZE;.    *pI
12da0 6e 57 61 6c 20 3d 20 31 3b 0a 20 20 20 20 72 65  nWal = 1;.    re
12db0 74 75 72 6e 20 73 71 6c 69 74 65 33 4f 73 52 65  turn sqlite3OsRe
12dc0 61 64 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  ad(pWal->pWalFd,
12dd0 20 70 4f 75 74 2c 20 6e 4f 75 74 2c 20 69 4f 66   pOut, nOut, iOf
12de0 66 73 65 74 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70  fset);.  }..  *p
12df0 49 6e 57 61 6c 20 3d 20 30 3b 0a 20 20 72 65 74  InWal = 0;.  ret
12e00 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
12e10 0a 0a 0a 2f 2a 20 0a 2a 2a 20 53 65 74 20 2a 70  .../* .** Set *p
12e20 50 67 6e 6f 20 74 6f 20 74 68 65 20 73 69 7a 65  Pgno to the size
12e30 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73 65   of the database
12e40 20 66 69 6c 65 20 28 6f 72 20 7a 65 72 6f 2c 20   file (or zero, 
12e50 69 66 20 75 6e 6b 6e 6f 77 6e 29 2e 0a 2a 2f 0a  if unknown)..*/.
12e60 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61 6c 44  void sqlite3WalD
12e70 62 73 69 7a 65 28 57 61 6c 20 2a 70 57 61 6c 2c  bsize(Wal *pWal,
12e80 20 50 67 6e 6f 20 2a 70 50 67 6e 6f 29 7b 0a 20   Pgno *pPgno){. 
12e90 20 61 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 72   assert( pWal->r
12ea0 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c 20 70 57  eadLock>=0 || pW
12eb0 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72 20 29 3b  al->lockError );
12ec0 0a 20 20 2a 70 50 67 6e 6f 20 3d 20 70 57 61 6c  .  *pPgno = pWal
12ed0 2d 3e 68 64 72 2e 6e 50 61 67 65 3b 0a 7d 0a 0a  ->hdr.nPage;.}..
12ee0 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ./* .** This fun
12ef0 63 74 69 6f 6e 20 73 74 61 72 74 73 20 61 20 77  ction starts a w
12f00 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  rite transaction
12f10 20 6f 6e 20 74 68 65 20 57 41 4c 2e 0a 2a 2a 0a   on the WAL..**.
12f20 2a 2a 20 41 20 72 65 61 64 20 74 72 61 6e 73 61  ** A read transa
12f30 63 74 69 6f 6e 20 6d 75 73 74 20 68 61 76 65 20  ction must have 
12f40 61 6c 72 65 61 64 79 20 62 65 65 6e 20 73 74 61  already been sta
12f50 72 74 65 64 20 62 79 20 61 20 70 72 69 6f 72 20  rted by a prior 
12f60 63 61 6c 6c 0a 2a 2a 20 74 6f 20 73 71 6c 69 74  call.** to sqlit
12f70 65 33 57 61 6c 42 65 67 69 6e 52 65 61 64 54 72  e3WalBeginReadTr
12f80 61 6e 73 61 63 74 69 6f 6e 28 29 2e 0a 2a 2a 0a  ansaction()..**.
12f90 2a 2a 20 49 66 20 61 6e 6f 74 68 65 72 20 74 68  ** If another th
12fa0 72 65 61 64 20 6f 72 20 70 72 6f 63 65 73 73 20  read or process 
12fb0 68 61 73 20 77 72 69 74 74 65 6e 20 69 6e 74 6f  has written into
12fc0 20 74 68 65 20 64 61 74 61 62 61 73 65 20 73 69   the database si
12fd0 6e 63 65 0a 2a 2a 20 74 68 65 20 72 65 61 64 20  nce.** the read 
12fe0 74 72 61 6e 73 61 63 74 69 6f 6e 20 77 61 73 20  transaction was 
12ff0 73 74 61 72 74 65 64 2c 20 74 68 65 6e 20 69 74  started, then it
13000 20 69 73 20 6e 6f 74 20 70 6f 73 73 69 62 6c 65   is not possible
13010 20 66 6f 72 20 74 68 69 73 0a 2a 2a 20 74 68 72   for this.** thr
13020 65 61 64 20 74 6f 20 77 72 69 74 65 20 61 73 20  ead to write as 
13030 64 6f 69 6e 67 20 73 6f 20 77 6f 75 6c 64 20 63  doing so would c
13040 61 75 73 65 20 61 20 66 6f 72 6b 2e 20 20 53 6f  ause a fork.  So
13050 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a   this routine.**
13060 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45 5f   returns SQLITE_
13070 42 55 53 59 20 69 6e 20 74 68 61 74 20 63 61 73  BUSY in that cas
13080 65 20 61 6e 64 20 6e 6f 20 77 72 69 74 65 20 74  e and no write t
13090 72 61 6e 73 61 63 74 69 6f 6e 20 69 73 20 73 74  ransaction is st
130a0 61 72 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  arted..**.** The
130b0 72 65 20 63 61 6e 20 6f 6e 6c 79 20 62 65 20 61  re can only be a
130c0 20 73 69 6e 67 6c 65 20 77 72 69 74 65 72 20 61   single writer a
130d0 63 74 69 76 65 20 61 74 20 61 20 74 69 6d 65 2e  ctive at a time.
130e0 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 57  .*/.int sqlite3W
130f0 61 6c 42 65 67 69 6e 57 72 69 74 65 54 72 61 6e  alBeginWriteTran
13100 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57 61  saction(Wal *pWa
13110 6c 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20  l){.  int rc;.. 
13120 20 2f 2a 20 43 61 6e 6e 6f 74 20 73 74 61 72 74   /* Cannot start
13130 20 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63   a write transac
13140 74 69 6f 6e 20 77 69 74 68 6f 75 74 20 66 69 72  tion without fir
13150 73 74 20 68 6f 6c 64 69 6e 67 20 61 20 72 65 61  st holding a rea
13160 64 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63 74 69  d.  ** transacti
13170 6f 6e 2e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  on. */.  assert(
13180 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e   pWal->readLock>
13190 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 4f 6e 6c 79  =0 );..  /* Only
131a0 20 6f 6e 65 20 77 72 69 74 65 72 20 61 6c 6c 6f   one writer allo
131b0 77 65 64 20 61 74 20 61 20 74 69 6d 65 2e 20 20  wed at a time.  
131c0 47 65 74 20 74 68 65 20 77 72 69 74 65 20 6c 6f  Get the write lo
131d0 63 6b 2e 20 20 52 65 74 75 72 6e 0a 20 20 2a 2a  ck.  Return.  **
131e0 20 53 51 4c 49 54 45 5f 42 55 53 59 20 69 66 20   SQLITE_BUSY if 
131f0 75 6e 61 62 6c 65 2e 0a 20 20 2a 2f 0a 20 20 72  unable..  */.  r
13200 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c 75  c = walLockExclu
13210 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f 57  sive(pWal, WAL_W
13220 52 49 54 45 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  RITE_LOCK, 1);. 
13230 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 72   if( rc ){.    r
13240 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20  eturn rc;.  }.  
13250 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
13260 3d 20 31 3b 0a 0a 20 20 2f 2a 20 49 66 20 61 6e  = 1;..  /* If an
13270 6f 74 68 65 72 20 63 6f 6e 6e 65 63 74 69 6f 6e  other connection
13280 20 68 61 73 20 77 72 69 74 74 65 6e 20 74 6f 20   has written to 
13290 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
132a0 65 20 73 69 6e 63 65 20 74 68 65 0a 20 20 2a 2a  e since the.  **
132b0 20 74 69 6d 65 20 74 68 65 20 72 65 61 64 20 74   time the read t
132c0 72 61 6e 73 61 63 74 69 6f 6e 20 6f 6e 20 74 68  ransaction on th
132d0 69 73 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 77 61  is connection wa
132e0 73 20 73 74 61 72 74 65 64 2c 20 74 68 65 6e 0a  s started, then.
132f0 20 20 2a 2a 20 74 68 65 20 77 72 69 74 65 20 69    ** the write i
13300 73 20 64 69 73 61 6c 6c 6f 77 65 64 2e 0a 20 20  s disallowed..  
13310 2a 2f 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28  */.  if( memcmp(
13320 26 70 57 61 6c 2d 3e 68 64 72 2c 20 28 76 6f 69  &pWal->hdr, (voi
13330 64 20 2a 29 77 61 6c 49 6e 64 65 78 48 64 72 28  d *)walIndexHdr(
13340 70 57 61 6c 29 2c 20 73 69 7a 65 6f 66 28 57 61  pWal), sizeof(Wa
13350 6c 49 6e 64 65 78 48 64 72 29 29 21 3d 30 20 29  lIndexHdr))!=0 )
13360 7b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 45  {.    walUnlockE
13370 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
13380 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20 31  AL_WRITE_LOCK, 1
13390 29 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 77 72 69  );.    pWal->wri
133a0 74 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 20 20  teLock = 0;.    
133b0 72 63 20 3d 20 53 51 4c 49 54 45 5f 42 55 53 59  rc = SQLITE_BUSY
133c0 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
133d0 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 6e 64  rc;.}../*.** End
133e0 20 61 20 77 72 69 74 65 20 74 72 61 6e 73 61 63   a write transac
133f0 74 69 6f 6e 2e 20 20 54 68 65 20 63 6f 6d 6d 69  tion.  The commi
13400 74 20 68 61 73 20 61 6c 72 65 61 64 79 20 62 65  t has already be
13410 65 6e 20 64 6f 6e 65 2e 20 20 54 68 69 73 0a 2a  en done.  This.*
13420 2a 20 72 6f 75 74 69 6e 65 20 6d 65 72 65 6c 79  * routine merely
13430 20 72 65 6c 65 61 73 65 73 20 74 68 65 20 6c 6f   releases the lo
13440 63 6b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  ck..*/.int sqlit
13450 65 33 57 61 6c 45 6e 64 57 72 69 74 65 54 72 61  e3WalEndWriteTra
13460 6e 73 61 63 74 69 6f 6e 28 57 61 6c 20 2a 70 57  nsaction(Wal *pW
13470 61 6c 29 7b 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b  al){.  walUnlock
13480 45 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20  Exclusive(pWal, 
13490 57 41 4c 5f 57 52 49 54 45 5f 4c 4f 43 4b 2c 20  WAL_WRITE_LOCK, 
134a0 31 29 3b 0a 20 20 70 57 61 6c 2d 3e 77 72 69 74  1);.  pWal->writ
134b0 65 4c 6f 63 6b 20 3d 20 30 3b 0a 20 20 72 65 74  eLock = 0;.  ret
134c0 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
134d0 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 61 6e 79 20 64  ../*.** If any d
134e0 61 74 61 20 68 61 73 20 62 65 65 6e 20 77 72 69  ata has been wri
134f0 74 74 65 6e 20 28 62 75 74 20 6e 6f 74 20 63 6f  tten (but not co
13500 6d 6d 69 74 74 65 64 29 20 74 6f 20 74 68 65 20  mmitted) to the 
13510 6c 6f 67 20 66 69 6c 65 2c 20 74 68 69 73 0a 2a  log file, this.*
13520 2a 20 66 75 6e 63 74 69 6f 6e 20 6d 6f 76 65 73  * function moves
13530 20 74 68 65 20 77 72 69 74 65 2d 70 6f 69 6e 74   the write-point
13540 65 72 20 62 61 63 6b 20 74 6f 20 74 68 65 20 73  er back to the s
13550 74 61 72 74 20 6f 66 20 74 68 65 20 74 72 61 6e  tart of the tran
13560 73 61 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41  saction..**.** A
13570 64 64 69 74 69 6f 6e 61 6c 6c 79 2c 20 74 68 65  dditionally, the
13580 20 63 61 6c 6c 62 61 63 6b 20 66 75 6e 63 74 69   callback functi
13590 6f 6e 20 69 73 20 69 6e 76 6f 6b 65 64 20 66 6f  on is invoked fo
135a0 72 20 65 61 63 68 20 66 72 61 6d 65 20 77 72 69  r each frame wri
135b0 74 74 65 6e 0a 2a 2a 20 74 6f 20 74 68 65 20 57  tten.** to the W
135c0 41 4c 20 73 69 6e 63 65 20 74 68 65 20 73 74 61  AL since the sta
135d0 72 74 20 6f 66 20 74 68 65 20 74 72 61 6e 73 61  rt of the transa
135e0 63 74 69 6f 6e 2e 20 49 66 20 74 68 65 20 63 61  ction. If the ca
135f0 6c 6c 62 61 63 6b 20 72 65 74 75 72 6e 73 0a 2a  llback returns.*
13600 2a 20 6f 74 68 65 72 20 74 68 61 6e 20 53 51 4c  * other than SQL
13610 49 54 45 5f 4f 4b 2c 20 69 74 20 69 73 20 6e 6f  ITE_OK, it is no
13620 74 20 69 6e 76 6f 6b 65 64 20 61 67 61 69 6e 20  t invoked again 
13630 61 6e 64 20 74 68 65 20 65 72 72 6f 72 20 63 6f  and the error co
13640 64 65 20 69 73 0a 2a 2a 20 72 65 74 75 72 6e 65  de is.** returne
13650 64 20 74 6f 20 74 68 65 20 63 61 6c 6c 65 72 2e  d to the caller.
13660 0a 2a 2a 0a 2a 2a 20 4f 74 68 65 72 77 69 73 65  .**.** Otherwise
13670 2c 20 69 66 20 74 68 65 20 63 61 6c 6c 62 61 63  , if the callbac
13680 6b 20 66 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20  k function does 
13690 6e 6f 74 20 72 65 74 75 72 6e 20 61 6e 20 65 72  not return an er
136a0 72 6f 72 2c 20 74 68 69 73 0a 2a 2a 20 66 75 6e  ror, this.** fun
136b0 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 53 51  ction returns SQ
136c0 4c 49 54 45 5f 4f 4b 2e 0a 2a 2f 0a 69 6e 74 20  LITE_OK..*/.int 
136d0 73 71 6c 69 74 65 33 57 61 6c 55 6e 64 6f 28 57  sqlite3WalUndo(W
136e0 61 6c 20 2a 70 57 61 6c 2c 20 69 6e 74 20 28 2a  al *pWal, int (*
136f0 78 55 6e 64 6f 29 28 76 6f 69 64 20 2a 2c 20 50  xUndo)(void *, P
13700 67 6e 6f 29 2c 20 76 6f 69 64 20 2a 70 55 6e 64  gno), void *pUnd
13710 6f 43 74 78 29 7b 0a 20 20 69 6e 74 20 72 63 20  oCtx){.  int rc 
13720 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
13730 66 28 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f  f( pWal->writeLo
13740 63 6b 20 29 7b 0a 20 20 20 20 50 67 6e 6f 20 69  ck ){.    Pgno i
13750 4d 61 78 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  Max = pWal->hdr.
13760 6d 78 46 72 61 6d 65 3b 0a 20 20 20 20 50 67 6e  mxFrame;.    Pgn
13770 6f 20 69 46 72 61 6d 65 3b 0a 20 20 0a 20 20 20  o iFrame;.  .   
13780 20 2f 2a 20 52 65 73 74 6f 72 65 20 74 68 65 20   /* Restore the 
13790 63 6c 69 65 6e 74 73 20 63 61 63 68 65 20 6f 66  clients cache of
137a0 20 74 68 65 20 77 61 6c 2d 69 6e 64 65 78 20 68   the wal-index h
137b0 65 61 64 65 72 20 74 6f 20 74 68 65 20 73 74 61  eader to the sta
137c0 74 65 20 69 74 0a 20 20 20 20 2a 2a 20 77 61 73  te it.    ** was
137d0 20 69 6e 20 62 65 66 6f 72 65 20 74 68 65 20 63   in before the c
137e0 6c 69 65 6e 74 20 62 65 67 61 6e 20 77 72 69 74  lient began writ
137f0 69 6e 67 20 74 6f 20 74 68 65 20 64 61 74 61 62  ing to the datab
13800 61 73 65 2e 20 0a 20 20 20 20 2a 2f 0a 20 20 20  ase. .    */.   
13810 20 6d 65 6d 63 70 79 28 26 70 57 61 6c 2d 3e 68   memcpy(&pWal->h
13820 64 72 2c 20 28 76 6f 69 64 20 2a 29 77 61 6c 49  dr, (void *)walI
13830 6e 64 65 78 48 64 72 28 70 57 61 6c 29 2c 20 73  ndexHdr(pWal), s
13840 69 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64  izeof(WalIndexHd
13850 72 29 29 3b 0a 0a 20 20 20 20 66 6f 72 28 69 46  r));..    for(iF
13860 72 61 6d 65 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d  rame=pWal->hdr.m
13870 78 46 72 61 6d 65 2b 31 3b 20 0a 20 20 20 20 20  xFrame+1; .     
13880 20 20 20 41 4c 57 41 59 53 28 72 63 3d 3d 53 51     ALWAYS(rc==SQ
13890 4c 49 54 45 5f 4f 4b 29 20 26 26 20 69 46 72 61  LITE_OK) && iFra
138a0 6d 65 3c 3d 69 4d 61 78 3b 20 0a 20 20 20 20 20  me<=iMax; .     
138b0 20 20 20 69 46 72 61 6d 65 2b 2b 0a 20 20 20 20     iFrame++.    
138c0 29 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73  ){.      /* This
138d0 20 63 61 6c 6c 20 63 61 6e 6e 6f 74 20 66 61 69   call cannot fai
138e0 6c 2e 20 55 6e 6c 65 73 73 20 74 68 65 20 70 61  l. Unless the pa
138f0 67 65 20 66 6f 72 20 77 68 69 63 68 20 74 68 65  ge for which the
13900 20 70 61 67 65 20 6e 75 6d 62 65 72 0a 20 20 20   page number.   
13910 20 20 20 2a 2a 20 69 73 20 70 61 73 73 65 64 20     ** is passed 
13920 61 73 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72  as the second ar
13930 67 75 6d 65 6e 74 20 69 73 20 28 61 29 20 69 6e  gument is (a) in
13940 20 74 68 65 20 63 61 63 68 65 20 61 6e 64 20 0a   the cache and .
13950 20 20 20 20 20 20 2a 2a 20 28 62 29 20 68 61 73        ** (b) has
13960 20 61 6e 20 6f 75 74 73 74 61 6e 64 69 6e 67 20   an outstanding 
13970 72 65 66 65 72 65 6e 63 65 2c 20 74 68 65 6e 20  reference, then 
13980 78 55 6e 64 6f 20 69 73 20 65 69 74 68 65 72 20  xUndo is either 
13990 61 20 6e 6f 2d 6f 70 0a 20 20 20 20 20 20 2a 2a  a no-op.      **
139a0 20 28 69 66 20 28 61 29 20 69 73 20 66 61 6c 73   (if (a) is fals
139b0 65 29 20 6f 72 20 73 69 6d 70 6c 79 20 65 78 70  e) or simply exp
139c0 65 6c 73 20 74 68 65 20 70 61 67 65 20 66 72 6f  els the page fro
139d0 6d 20 74 68 65 20 63 61 63 68 65 20 28 69 66 20  m the cache (if 
139e0 28 62 29 0a 20 20 20 20 20 20 2a 2a 20 69 73 20  (b).      ** is 
139f0 66 61 6c 73 65 29 2e 0a 20 20 20 20 20 20 2a 2a  false)..      **
13a00 0a 20 20 20 20 20 20 2a 2a 20 49 66 20 74 68 65  .      ** If the
13a10 20 75 70 70 65 72 20 6c 61 79 65 72 20 69 73 20   upper layer is 
13a20 64 6f 69 6e 67 20 61 20 72 6f 6c 6c 62 61 63 6b  doing a rollback
13a30 2c 20 69 74 20 69 73 20 67 75 61 72 61 6e 74 65  , it is guarante
13a40 65 64 20 74 68 61 74 20 74 68 65 72 65 0a 20 20  ed that there.  
13a50 20 20 20 20 2a 2a 20 61 72 65 20 6e 6f 20 6f 75      ** are no ou
13a60 74 73 74 61 6e 64 69 6e 67 20 72 65 66 65 72 65  tstanding refere
13a70 6e 63 65 73 20 74 6f 20 61 6e 79 20 70 61 67 65  nces to any page
13a80 20 6f 74 68 65 72 20 74 68 61 6e 20 70 61 67 65   other than page
13a90 20 31 2e 20 41 6e 64 0a 20 20 20 20 20 20 2a 2a   1. And.      **
13aa0 20 70 61 67 65 20 31 20 69 73 20 6e 65 76 65 72   page 1 is never
13ab0 20 77 72 69 74 74 65 6e 20 74 6f 20 74 68 65 20   written to the 
13ac0 6c 6f 67 20 75 6e 74 69 6c 20 74 68 65 20 74 72  log until the tr
13ad0 61 6e 73 61 63 74 69 6f 6e 20 69 73 0a 20 20 20  ansaction is.   
13ae0 20 20 20 2a 2a 20 63 6f 6d 6d 69 74 74 65 64 2e     ** committed.
13af0 20 41 73 20 61 20 72 65 73 75 6c 74 2c 20 74 68   As a result, th
13b00 65 20 63 61 6c 6c 20 74 6f 20 78 55 6e 64 6f 20  e call to xUndo 
13b10 6d 61 79 20 6e 6f 74 20 66 61 69 6c 2e 0a 20 20  may not fail..  
13b20 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 61 73 73      */.      ass
13b30 65 72 74 28 20 77 61 6c 46 72 61 6d 65 50 67 6e  ert( walFramePgn
13b40 6f 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 29 21  o(pWal, iFrame)!
13b50 3d 31 20 29 3b 0a 20 20 20 20 20 20 72 63 20 3d  =1 );.      rc =
13b60 20 78 55 6e 64 6f 28 70 55 6e 64 6f 43 74 78 2c   xUndo(pUndoCtx,
13b70 20 77 61 6c 46 72 61 6d 65 50 67 6e 6f 28 70 57   walFramePgno(pW
13b80 61 6c 2c 20 69 46 72 61 6d 65 29 29 3b 0a 20 20  al, iFrame));.  
13b90 20 20 7d 0a 20 20 20 20 77 61 6c 43 6c 65 61 6e    }.    walClean
13ba0 75 70 48 61 73 68 28 70 57 61 6c 29 3b 0a 20 20  upHash(pWal);.  
13bb0 7d 0a 20 20 61 73 73 65 72 74 28 20 72 63 3d 3d  }.  assert( rc==
13bc0 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 72  SQLITE_OK );.  r
13bd0 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
13be0 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 61 57 61  .** Argument aWa
13bf0 6c 44 61 74 61 20 6d 75 73 74 20 70 6f 69 6e 74  lData must point
13c00 20 74 6f 20 61 6e 20 61 72 72 61 79 20 6f 66 20   to an array of 
13c10 57 41 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e 44  WAL_SAVEPOINT_ND
13c20 41 54 41 20 75 33 32 20 0a 2a 2a 20 76 61 6c 75  ATA u32 .** valu
13c30 65 73 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  es. This functio
13c40 6e 20 70 6f 70 75 6c 61 74 65 73 20 74 68 65 20  n populates the 
13c50 61 72 72 61 79 20 77 69 74 68 20 76 61 6c 75 65  array with value
13c60 73 20 72 65 71 75 69 72 65 64 20 74 6f 20 0a 2a  s required to .*
13c70 2a 20 22 72 6f 6c 6c 62 61 63 6b 22 20 74 68 65  * "rollback" the
13c80 20 77 72 69 74 65 20 70 6f 73 69 74 69 6f 6e 20   write position 
13c90 6f 66 20 74 68 65 20 57 41 4c 20 68 61 6e 64 6c  of the WAL handl
13ca0 65 20 62 61 63 6b 20 74 6f 20 74 68 65 20 63 75  e back to the cu
13cb0 72 72 65 6e 74 20 0a 2a 2a 20 70 6f 69 6e 74 20  rrent .** point 
13cc0 69 6e 20 74 68 65 20 65 76 65 6e 74 20 6f 66 20  in the event of 
13cd0 61 20 73 61 76 65 70 6f 69 6e 74 20 72 6f 6c 6c  a savepoint roll
13ce0 62 61 63 6b 20 28 76 69 61 20 57 61 6c 53 61 76  back (via WalSav
13cf0 65 70 6f 69 6e 74 55 6e 64 6f 28 29 29 2e 0a 2a  epointUndo())..*
13d00 2f 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 57 61  /.void sqlite3Wa
13d10 6c 53 61 76 65 70 6f 69 6e 74 28 57 61 6c 20 2a  lSavepoint(Wal *
13d20 70 57 61 6c 2c 20 75 33 32 20 2a 61 57 61 6c 44  pWal, u32 *aWalD
13d30 61 74 61 29 7b 0a 20 20 61 73 73 65 72 74 28 20  ata){.  assert( 
13d40 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20  pWal->writeLock 
13d50 29 3b 0a 20 20 61 57 61 6c 44 61 74 61 5b 30 5d  );.  aWalData[0]
13d60 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46   = pWal->hdr.mxF
13d70 72 61 6d 65 3b 0a 20 20 61 57 61 6c 44 61 74 61  rame;.  aWalData
13d80 5b 31 5d 20 3d 20 70 57 61 6c 2d 3e 68 64 72 2e  [1] = pWal->hdr.
13d90 61 46 72 61 6d 65 43 6b 73 75 6d 5b 30 5d 3b 0a  aFrameCksum[0];.
13da0 20 20 61 57 61 6c 44 61 74 61 5b 32 5d 20 3d 20    aWalData[2] = 
13db0 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65  pWal->hdr.aFrame
13dc0 43 6b 73 75 6d 5b 31 5d 3b 0a 20 20 61 57 61 6c  Cksum[1];.  aWal
13dd0 44 61 74 61 5b 33 5d 20 3d 20 70 57 61 6c 2d 3e  Data[3] = pWal->
13de0 6e 43 6b 70 74 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  nCkpt;.}../* .**
13df0 20 4d 6f 76 65 20 74 68 65 20 77 72 69 74 65 20   Move the write 
13e00 70 6f 73 69 74 69 6f 6e 20 6f 66 20 74 68 65 20  position of the 
13e10 57 41 4c 20 62 61 63 6b 20 74 6f 20 74 68 65 20  WAL back to the 
13e20 70 6f 69 6e 74 20 69 64 65 6e 74 69 66 69 65 64  point identified
13e30 20 62 79 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65   by.** the value
13e40 73 20 69 6e 20 74 68 65 20 61 57 61 6c 44 61 74  s in the aWalDat
13e50 61 5b 5d 20 61 72 72 61 79 2e 20 61 57 61 6c 44  a[] array. aWalD
13e60 61 74 61 20 6d 75 73 74 20 70 6f 69 6e 74 20 74  ata must point t
13e70 6f 20 61 6e 20 61 72 72 61 79 0a 2a 2a 20 6f 66  o an array.** of
13e80 20 57 41 4c 5f 53 41 56 45 50 4f 49 4e 54 5f 4e   WAL_SAVEPOINT_N
13e90 44 41 54 41 20 75 33 32 20 76 61 6c 75 65 73 20  DATA u32 values 
13ea0 74 68 61 74 20 68 61 73 20 62 65 65 6e 20 70 72  that has been pr
13eb0 65 76 69 6f 75 73 6c 79 20 70 6f 70 75 6c 61 74  eviously populat
13ec0 65 64 0a 2a 2a 20 62 79 20 61 20 63 61 6c 6c 20  ed.** by a call 
13ed0 74 6f 20 57 61 6c 53 61 76 65 70 6f 69 6e 74 28  to WalSavepoint(
13ee0 29 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  )..*/.int sqlite
13ef0 33 57 61 6c 53 61 76 65 70 6f 69 6e 74 55 6e 64  3WalSavepointUnd
13f00 6f 28 57 61 6c 20 2a 70 57 61 6c 2c 20 75 33 32  o(Wal *pWal, u32
13f10 20 2a 61 57 61 6c 44 61 74 61 29 7b 0a 20 20 69   *aWalData){.  i
13f20 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
13f30 4b 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 70 57  K;..  assert( pW
13f40 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
13f50 0a 20 20 61 73 73 65 72 74 28 20 61 57 61 6c 44  .  assert( aWalD
13f60 61 74 61 5b 33 5d 21 3d 70 57 61 6c 2d 3e 6e 43  ata[3]!=pWal->nC
13f70 6b 70 74 20 7c 7c 20 61 57 61 6c 44 61 74 61 5b  kpt || aWalData[
13f80 30 5d 3c 3d 70 57 61 6c 2d 3e 68 64 72 2e 6d 78  0]<=pWal->hdr.mx
13f90 46 72 61 6d 65 20 29 3b 0a 0a 20 20 69 66 28 20  Frame );..  if( 
13fa0 61 57 61 6c 44 61 74 61 5b 33 5d 21 3d 70 57 61  aWalData[3]!=pWa
13fb0 6c 2d 3e 6e 43 6b 70 74 20 29 7b 0a 20 20 20 20  l->nCkpt ){.    
13fc0 2f 2a 20 54 68 69 73 20 73 61 76 65 70 6f 69 6e  /* This savepoin
13fd0 74 20 77 61 73 20 6f 70 65 6e 65 64 20 69 6d 6d  t was opened imm
13fe0 65 64 69 61 74 65 6c 79 20 61 66 74 65 72 20 74  ediately after t
13ff0 68 65 20 77 72 69 74 65 2d 74 72 61 6e 73 61 63  he write-transac
14000 74 69 6f 6e 0a 20 20 20 20 2a 2a 20 77 61 73 20  tion.    ** was 
14010 73 74 61 72 74 65 64 2e 20 52 69 67 68 74 20 61  started. Right a
14020 66 74 65 72 20 74 68 61 74 2c 20 74 68 65 20 77  fter that, the w
14030 72 69 74 65 72 20 64 65 63 69 64 65 64 20 74 6f  riter decided to
14040 20 77 72 61 70 20 61 72 6f 75 6e 64 0a 20 20 20   wrap around.   
14050 20 2a 2a 20 74 6f 20 74 68 65 20 73 74 61 72 74   ** to the start
14060 20 6f 66 20 74 68 65 20 6c 6f 67 2e 20 55 70 64   of the log. Upd
14070 61 74 65 20 74 68 65 20 73 61 76 65 70 6f 69 6e  ate the savepoin
14080 74 20 76 61 6c 75 65 73 20 74 6f 20 6d 61 74 63  t values to matc
14090 68 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 61 57  h..    */.    aW
140a0 61 6c 44 61 74 61 5b 30 5d 20 3d 20 30 3b 0a 20  alData[0] = 0;. 
140b0 20 20 20 61 57 61 6c 44 61 74 61 5b 33 5d 20 3d     aWalData[3] =
140c0 20 70 57 61 6c 2d 3e 6e 43 6b 70 74 3b 0a 20 20   pWal->nCkpt;.  
140d0 7d 0a 0a 20 20 69 66 28 20 61 57 61 6c 44 61 74  }..  if( aWalDat
140e0 61 5b 30 5d 3c 70 57 61 6c 2d 3e 68 64 72 2e 6d  a[0]<pWal->hdr.m
140f0 78 46 72 61 6d 65 20 29 7b 0a 20 20 20 20 70 57  xFrame ){.    pW
14100 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
14110 3d 20 61 57 61 6c 44 61 74 61 5b 30 5d 3b 0a 20  = aWalData[0];. 
14120 20 20 20 70 57 61 6c 2d 3e 68 64 72 2e 61 46 72     pWal->hdr.aFr
14130 61 6d 65 43 6b 73 75 6d 5b 30 5d 20 3d 20 61 57  ameCksum[0] = aW
14140 61 6c 44 61 74 61 5b 31 5d 3b 0a 20 20 20 20 70  alData[1];.    p
14150 57 61 6c 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43  Wal->hdr.aFrameC
14160 6b 73 75 6d 5b 31 5d 20 3d 20 61 57 61 6c 44 61  ksum[1] = aWalDa
14170 74 61 5b 32 5d 3b 0a 20 20 20 20 77 61 6c 43 6c  ta[2];.    walCl
14180 65 61 6e 75 70 48 61 73 68 28 70 57 61 6c 29 3b  eanupHash(pWal);
14190 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
141a0 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  c;.}../*.** This
141b0 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
141c0 6c 65 64 20 6a 75 73 74 20 62 65 66 6f 72 65 20  led just before 
141d0 77 72 69 74 69 6e 67 20 61 20 73 65 74 20 6f 66  writing a set of
141e0 20 66 72 61 6d 65 73 20 74 6f 20 74 68 65 20 6c   frames to the l
141f0 6f 67 0a 2a 2a 20 66 69 6c 65 20 28 73 65 65 20  og.** file (see 
14200 73 71 6c 69 74 65 33 57 61 6c 46 72 61 6d 65 73  sqlite3WalFrames
14210 28 29 29 2e 20 49 74 20 63 68 65 63 6b 73 20 74  ()). It checks t
14220 6f 20 73 65 65 20 69 66 2c 20 69 6e 73 74 65 61  o see if, instea
14230 64 20 6f 66 20 61 70 70 65 6e 64 69 6e 67 0a 2a  d of appending.*
14240 2a 20 74 6f 20 74 68 65 20 63 75 72 72 65 6e 74  * to the current
14250 20 6c 6f 67 20 66 69 6c 65 2c 20 69 74 20 69 73   log file, it is
14260 20 70 6f 73 73 69 62 6c 65 20 74 6f 20 6f 76 65   possible to ove
14270 72 77 72 69 74 65 20 74 68 65 20 73 74 61 72 74  rwrite the start
14280 20 6f 66 20 74 68 65 0a 2a 2a 20 65 78 69 73 74   of the.** exist
14290 69 6e 67 20 6c 6f 67 20 66 69 6c 65 20 77 69 74  ing log file wit
142a0 68 20 74 68 65 20 6e 65 77 20 66 72 61 6d 65 73  h the new frames
142b0 20 28 69 2e 65 2e 20 22 72 65 73 65 74 22 20 74   (i.e. "reset" t
142c0 68 65 20 6c 6f 67 29 2e 20 49 66 20 73 6f 2c 0a  he log). If so,.
142d0 2a 2a 20 69 74 20 73 65 74 73 20 70 57 61 6c 2d  ** it sets pWal-
142e0 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20 74 6f 20  >hdr.mxFrame to 
142f0 30 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 70 57  0. Otherwise, pW
14300 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
14310 69 73 20 6c 65 66 74 0a 2a 2a 20 75 6e 63 68 61  is left.** uncha
14320 6e 67 65 64 2e 0a 2a 2a 0a 2a 2a 20 53 51 4c 49  nged..**.** SQLI
14330 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
14340 64 20 69 66 20 6e 6f 20 65 72 72 6f 72 20 69 73  d if no error is
14350 20 65 6e 63 6f 75 6e 74 65 72 65 64 20 28 72 65   encountered (re
14360 67 61 72 64 6c 65 73 73 20 6f 66 20 77 68 65 74  gardless of whet
14370 68 65 72 0a 2a 2a 20 6f 72 20 6e 6f 74 20 70 57  her.** or not pW
14380 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 20  al->hdr.mxFrame 
14390 69 73 20 6d 6f 64 69 66 69 65 64 29 2e 20 41 6e  is modified). An
143a0 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
143b0 64 65 20 69 73 20 72 65 74 75 72 6e 65 64 0a 2a  de is returned.*
143c0 2a 20 69 66 20 73 6f 6d 65 20 65 72 72 6f 72 20  * if some error 
143d0 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 77  .*/.static int w
143e0 61 6c 52 65 73 74 61 72 74 4c 6f 67 28 57 61 6c  alRestartLog(Wal
143f0 20 2a 70 57 61 6c 29 7b 0a 20 20 69 6e 74 20 72   *pWal){.  int r
14400 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
14410 20 69 6e 74 20 63 6e 74 3b 0a 0a 20 20 69 66 28   int cnt;..  if(
14420 20 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3d   pWal->readLock=
14430 3d 30 20 29 7b 0a 20 20 20 20 76 6f 6c 61 74 69  =0 ){.    volati
14440 6c 65 20 57 61 6c 43 6b 70 74 49 6e 66 6f 20 2a  le WalCkptInfo *
14450 70 49 6e 66 6f 20 3d 20 77 61 6c 43 6b 70 74 49  pInfo = walCkptI
14460 6e 66 6f 28 70 57 61 6c 29 3b 0a 20 20 20 20 61  nfo(pWal);.    a
14470 73 73 65 72 74 28 20 70 49 6e 66 6f 2d 3e 6e 42  ssert( pInfo->nB
14480 61 63 6b 66 69 6c 6c 3d 3d 70 57 61 6c 2d 3e 68  ackfill==pWal->h
14490 64 72 2e 6d 78 46 72 61 6d 65 20 29 3b 0a 20 20  dr.mxFrame );.  
144a0 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 6e 42 61    if( pInfo->nBa
144b0 63 6b 66 69 6c 6c 3e 30 20 29 7b 0a 20 20 20 20  ckfill>0 ){.    
144c0 20 20 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78    rc = walLockEx
144d0 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41  clusive(pWal, WA
144e0 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 31 29 2c 20  L_READ_LOCK(1), 
144f0 57 41 4c 5f 4e 52 45 41 44 45 52 2d 31 29 3b 0a  WAL_NREADER-1);.
14500 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
14510 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
14520 20 20 20 2f 2a 20 49 66 20 61 6c 6c 20 72 65 61     /* If all rea
14530 64 65 72 73 20 61 72 65 20 75 73 69 6e 67 20 57  ders are using W
14540 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 20  AL_READ_LOCK(0) 
14550 28 69 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 20  (in other words 
14560 69 66 20 6e 6f 0a 20 20 20 20 20 20 20 20 2a 2a  if no.        **
14570 20 72 65 61 64 65 72 73 20 61 72 65 20 63 75 72   readers are cur
14580 72 65 6e 74 6c 79 20 75 73 69 6e 67 20 74 68 65  rently using the
14590 20 57 41 4c 29 2c 20 74 68 65 6e 20 74 68 65 20   WAL), then the 
145a0 74 72 61 6e 73 61 63 74 69 6f 6e 73 0a 20 20 20  transactions.   
145b0 20 20 20 20 20 2a 2a 20 66 72 61 6d 65 73 20 77       ** frames w
145c0 69 6c 6c 20 6f 76 65 72 77 72 69 74 65 20 74 68  ill overwrite th
145d0 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 65  e start of the e
145e0 78 69 73 74 69 6e 67 20 6c 6f 67 2e 20 55 70 64  xisting log. Upd
145f0 61 74 65 20 74 68 65 0a 20 20 20 20 20 20 20 20  ate the.        
14600 2a 2a 20 77 61 6c 2d 69 6e 64 65 78 20 68 65 61  ** wal-index hea
14610 64 65 72 20 74 6f 20 72 65 66 6c 65 63 74 20 74  der to reflect t
14620 68 69 73 2e 0a 20 20 20 20 20 20 20 20 2a 2a 0a  his..        **.
14630 20 20 20 20 20 20 20 20 2a 2a 20 49 6e 20 74 68          ** In th
14640 65 6f 72 79 20 69 74 20 77 6f 75 6c 64 20 62 65  eory it would be
14650 20 4f 6b 20 74 6f 20 75 70 64 61 74 65 20 74 68   Ok to update th
14660 65 20 63 61 63 68 65 20 6f 66 20 74 68 65 20 68  e cache of the h
14670 65 61 64 65 72 20 6f 6e 6c 79 0a 20 20 20 20 20  eader only.     
14680 20 20 20 2a 2a 20 61 74 20 74 68 69 73 20 70 6f     ** at this po
14690 69 6e 74 2e 20 42 75 74 20 75 70 64 61 74 69 6e  int. But updatin
146a0 67 20 74 68 65 20 61 63 74 75 61 6c 20 77 61 6c  g the actual wal
146b0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73  -index header is
146c0 20 61 6c 73 6f 0a 20 20 20 20 20 20 20 20 2a 2a   also.        **
146d0 20 73 61 66 65 20 61 6e 64 20 6d 65 61 6e 73 20   safe and means 
146e0 74 68 65 72 65 20 69 73 20 6e 6f 20 73 70 65 63  there is no spec
146f0 69 61 6c 20 63 61 73 65 20 66 6f 72 20 73 71 6c  ial case for sql
14700 69 74 65 33 57 61 6c 55 6e 64 6f 28 29 0a 20 20  ite3WalUndo().  
14710 20 20 20 20 20 20 2a 2a 20 74 6f 20 68 61 6e 64        ** to hand
14720 6c 65 20 69 66 20 74 68 69 73 20 74 72 61 6e 73  le if this trans
14730 61 63 74 69 6f 6e 20 69 73 20 72 6f 6c 6c 65 64  action is rolled
14740 20 62 61 63 6b 2e 0a 20 20 20 20 20 20 20 20 2a   back..        *
14750 2f 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 3b  /.        int i;
14760 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14770 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 63 6f 75 6e      /* Loop coun
14780 74 65 72 20 2a 2f 0a 20 20 20 20 20 20 20 20 75  ter */.        u
14790 33 32 20 2a 61 53 61 6c 74 20 3d 20 70 57 61 6c  32 *aSalt = pWal
147a0 2d 3e 68 64 72 2e 61 53 61 6c 74 3b 20 20 20 20  ->hdr.aSalt;    
147b0 20 20 20 2f 2a 20 42 69 67 2d 65 6e 64 69 61 6e     /* Big-endian
147c0 20 73 61 6c 74 20 76 61 6c 75 65 73 20 2a 2f 0a   salt values */.
147d0 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 6e 43          pWal->nC
147e0 6b 70 74 2b 2b 3b 0a 20 20 20 20 20 20 20 20 70  kpt++;.        p
147f0 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65  Wal->hdr.mxFrame
14800 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 73 71   = 0;.        sq
14810 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 28 75  lite3Put4byte((u
14820 38 2a 29 26 61 53 61 6c 74 5b 30 5d 2c 20 31 20  8*)&aSalt[0], 1 
14830 2b 20 73 71 6c 69 74 65 33 47 65 74 34 62 79 74  + sqlite3Get4byt
14840 65 28 28 75 38 2a 29 26 61 53 61 6c 74 5b 30 5d  e((u8*)&aSalt[0]
14850 29 29 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69  ));.        sqli
14860 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 34  te3_randomness(4
14870 2c 20 26 61 53 61 6c 74 5b 31 5d 29 3b 0a 20 20  , &aSalt[1]);.  
14880 20 20 20 20 20 20 77 61 6c 49 6e 64 65 78 57 72        walIndexWr
14890 69 74 65 48 64 72 28 70 57 61 6c 29 3b 0a 20 20  iteHdr(pWal);.  
148a0 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 61        pInfo->nBa
148b0 63 6b 66 69 6c 6c 20 3d 20 30 3b 0a 20 20 20 20  ckfill = 0;.    
148c0 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 57      for(i=1; i<W
148d0 41 4c 5f 4e 52 45 41 44 45 52 3b 20 69 2b 2b 29  AL_NREADER; i++)
148e0 20 70 49 6e 66 6f 2d 3e 61 52 65 61 64 4d 61 72   pInfo->aReadMar
148f0 6b 5b 69 5d 20 3d 20 52 45 41 44 4d 41 52 4b 5f  k[i] = READMARK_
14900 4e 4f 54 5f 55 53 45 44 3b 0a 20 20 20 20 20 20  NOT_USED;.      
14910 20 20 61 73 73 65 72 74 28 20 70 49 6e 66 6f 2d    assert( pInfo-
14920 3e 61 52 65 61 64 4d 61 72 6b 5b 30 5d 3d 3d 30  >aReadMark[0]==0
14930 20 29 3b 0a 20 20 20 20 20 20 20 20 77 61 6c 55   );.        walU
14940 6e 6c 6f 63 6b 45 78 63 6c 75 73 69 76 65 28 70  nlockExclusive(p
14950 57 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f  Wal, WAL_READ_LO
14960 43 4b 28 31 29 2c 20 57 41 4c 5f 4e 52 45 41 44  CK(1), WAL_NREAD
14970 45 52 2d 31 29 3b 0a 20 20 20 20 20 20 7d 0a 20  ER-1);.      }. 
14980 20 20 20 7d 0a 20 20 20 20 77 61 6c 55 6e 6c 6f     }.    walUnlo
14990 63 6b 53 68 61 72 65 64 28 70 57 61 6c 2c 20 57  ckShared(pWal, W
149a0 41 4c 5f 52 45 41 44 5f 4c 4f 43 4b 28 30 29 29  AL_READ_LOCK(0))
149b0 3b 0a 20 20 20 20 70 57 61 6c 2d 3e 72 65 61 64  ;.    pWal->read
149c0 4c 6f 63 6b 20 3d 20 2d 31 3b 0a 20 20 20 20 63  Lock = -1;.    c
149d0 6e 74 20 3d 20 30 3b 0a 20 20 20 20 64 6f 7b 0a  nt = 0;.    do{.
149e0 20 20 20 20 20 20 69 6e 74 20 6e 6f 74 55 73 65        int notUse
149f0 64 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 77 61  d;.      rc = wa
14a00 6c 54 72 79 42 65 67 69 6e 52 65 61 64 28 70 57  lTryBeginRead(pW
14a10 61 6c 2c 20 26 6e 6f 74 55 73 65 64 2c 20 31 2c  al, &notUsed, 1,
14a20 20 2b 2b 63 6e 74 29 3b 0a 20 20 20 20 7d 77 68   ++cnt);.    }wh
14a30 69 6c 65 28 20 72 63 3d 3d 57 41 4c 5f 52 45 54  ile( rc==WAL_RET
14a40 52 59 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  RY );.  }.  retu
14a50 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
14a60 20 57 72 69 74 65 20 61 20 73 65 74 20 6f 66 20   Write a set of 
14a70 66 72 61 6d 65 73 20 74 6f 20 74 68 65 20 6c 6f  frames to the lo
14a80 67 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 6d 75  g. The caller mu
14a90 73 74 20 68 6f 6c 64 20 74 68 65 20 77 72 69 74  st hold the writ
14aa0 65 2d 6c 6f 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65  e-lock.** on the
14ab0 20 6c 6f 67 20 66 69 6c 65 20 28 6f 62 74 61 69   log file (obtai
14ac0 6e 65 64 20 75 73 69 6e 67 20 73 71 6c 69 74 65  ned using sqlite
14ad0 33 57 61 6c 42 65 67 69 6e 57 72 69 74 65 54 72  3WalBeginWriteTr
14ae0 61 6e 73 61 63 74 69 6f 6e 28 29 29 2e 0a 2a 2f  ansaction())..*/
14af0 0a 69 6e 74 20 73 71 6c 69 74 65 33 57 61 6c 46  .int sqlite3WalF
14b00 72 61 6d 65 73 28 0a 20 20 57 61 6c 20 2a 70 57  rames(.  Wal *pW
14b10 61 6c 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  al,             
14b20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 61 6c 20           /* Wal 
14b30 68 61 6e 64 6c 65 20 74 6f 20 77 72 69 74 65 20  handle to write 
14b40 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 50 61  to */.  int szPa
14b50 67 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ge,             
14b60 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62          /* Datab
14b70 61 73 65 20 70 61 67 65 2d 73 69 7a 65 20 69 6e  ase page-size in
14b80 20 62 79 74 65 73 20 2a 2f 0a 20 20 50 67 48 64   bytes */.  PgHd
14b90 72 20 2a 70 4c 69 73 74 2c 20 20 20 20 20 20 20  r *pList,       
14ba0 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
14bb0 69 73 74 20 6f 66 20 64 69 72 74 79 20 70 61 67  ist of dirty pag
14bc0 65 73 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20  es to write */. 
14bd0 20 50 67 6e 6f 20 6e 54 72 75 6e 63 61 74 65 2c   Pgno nTruncate,
14be0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14bf0 20 2f 2a 20 44 61 74 61 62 61 73 65 20 73 69 7a   /* Database siz
14c00 65 20 61 66 74 65 72 20 74 68 69 73 20 63 6f 6d  e after this com
14c10 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20 69 73 43  mit */.  int isC
14c20 6f 6d 6d 69 74 2c 20 20 20 20 20 20 20 20 20 20  ommit,          
14c30 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
14c40 20 69 66 20 74 68 69 73 20 69 73 20 61 20 63 6f   if this is a co
14c50 6d 6d 69 74 20 2a 2f 0a 20 20 69 6e 74 20 73 79  mmit */.  int sy
14c60 6e 63 5f 66 6c 61 67 73 20 20 20 20 20 20 20 20  nc_flags        
14c70 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61            /* Fla
14c80 67 73 20 74 6f 20 70 61 73 73 20 74 6f 20 4f 73  gs to pass to Os
14c90 53 79 6e 63 28 29 20 28 6f 72 20 30 29 20 2a 2f  Sync() (or 0) */
14ca0 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20  .){.  int rc;   
14cb0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
14cc0 20 20 20 20 20 20 2f 2a 20 55 73 65 64 20 74 6f        /* Used to
14cd0 20 63 61 74 63 68 20 72 65 74 75 72 6e 20 63 6f   catch return co
14ce0 64 65 73 20 2a 2f 0a 20 20 75 33 32 20 69 46 72  des */.  u32 iFr
14cf0 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ame;            
14d00 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65 78 74           /* Next
14d10 20 66 72 61 6d 65 20 61 64 64 72 65 73 73 20 2a   frame address *
14d20 2f 0a 20 20 75 38 20 61 46 72 61 6d 65 5b 57 41  /.  u8 aFrame[WA
14d30 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45 5d  L_FRAME_HDRSIZE]
14d40 3b 20 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f  ;   /* Buffer to
14d50 20 61 73 73 65 6d 62 6c 65 20 66 72 61 6d 65 2d   assemble frame-
14d60 68 65 61 64 65 72 20 69 6e 20 2a 2f 0a 20 20 50  header in */.  P
14d70 67 48 64 72 20 2a 70 3b 20 20 20 20 20 20 20 20  gHdr *p;        
14d80 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
14d90 2a 20 49 74 65 72 61 74 6f 72 20 74 6f 20 72 75  * Iterator to ru
14da0 6e 20 74 68 72 6f 75 67 68 20 70 4c 69 73 74 20  n through pList 
14db0 77 69 74 68 2e 20 2a 2f 0a 20 20 50 67 48 64 72  with. */.  PgHdr
14dc0 20 2a 70 4c 61 73 74 20 3d 20 30 3b 20 20 20 20   *pLast = 0;    
14dd0 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 61             /* La
14de0 73 74 20 66 72 61 6d 65 20 69 6e 20 6c 69 73 74  st frame in list
14df0 20 2a 2f 0a 20 20 69 6e 74 20 6e 4c 61 73 74 20   */.  int nLast 
14e00 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
14e10 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
14e20 6f 66 20 65 78 74 72 61 20 63 6f 70 69 65 73 20  of extra copies 
14e30 6f 66 20 6c 61 73 74 20 70 61 67 65 20 2a 2f 0a  of last page */.
14e40 0a 20 20 61 73 73 65 72 74 28 20 70 4c 69 73 74  .  assert( pList
14e50 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57   );.  assert( pW
14e60 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b 20 29 3b  al->writeLock );
14e70 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28 53 51  ..#if defined(SQ
14e80 4c 49 54 45 5f 54 45 53 54 29 20 26 26 20 64 65  LITE_TEST) && de
14e90 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 44 45 42  fined(SQLITE_DEB
14ea0 55 47 29 0a 20 20 7b 20 69 6e 74 20 63 6e 74 3b  UG).  { int cnt;
14eb0 20 66 6f 72 28 63 6e 74 3d 30 2c 20 70 3d 70 4c   for(cnt=0, p=pL
14ec0 69 73 74 3b 20 70 3b 20 70 3d 70 2d 3e 70 44 69  ist; p; p=p->pDi
14ed0 72 74 79 2c 20 63 6e 74 2b 2b 29 7b 7d 0a 20 20  rty, cnt++){}.  
14ee0 20 20 57 41 4c 54 52 41 43 45 28 28 22 57 41 4c    WALTRACE(("WAL
14ef0 25 70 3a 20 66 72 61 6d 65 20 77 72 69 74 65 20  %p: frame write 
14f00 62 65 67 69 6e 2e 20 25 64 20 66 72 61 6d 65 73  begin. %d frames
14f10 2e 20 6d 78 46 72 61 6d 65 3d 25 64 2e 20 25 73  . mxFrame=%d. %s
14f20 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20  \n",.           
14f30 20 20 20 70 57 61 6c 2c 20 63 6e 74 2c 20 70 57     pWal, cnt, pW
14f40 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61 6d 65 2c  al->hdr.mxFrame,
14f50 20 69 73 43 6f 6d 6d 69 74 20 3f 20 22 43 6f 6d   isCommit ? "Com
14f60 6d 69 74 22 20 3a 20 22 53 70 69 6c 6c 22 29 29  mit" : "Spill"))
14f70 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20  ;.  }.#endif..  
14f80 2f 2a 20 53 65 65 20 69 66 20 69 74 20 69 73 20  /* See if it is 
14f90 70 6f 73 73 69 62 6c 65 20 74 6f 20 77 72 69 74  possible to writ
14fa0 65 20 74 68 65 73 65 20 66 72 61 6d 65 73 20 69  e these frames i
14fb0 6e 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66  nto the start of
14fc0 20 74 68 65 0a 20 20 2a 2a 20 6c 6f 67 20 66 69   the.  ** log fi
14fd0 6c 65 2c 20 69 6e 73 74 65 61 64 20 6f 66 20 61  le, instead of a
14fe0 70 70 65 6e 64 69 6e 67 20 74 6f 20 69 74 20 61  ppending to it a
14ff0 74 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72  t pWal->hdr.mxFr
15000 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  ame..  */.  if( 
15010 53 51 4c 49 54 45 5f 4f 4b 21 3d 28 72 63 20 3d  SQLITE_OK!=(rc =
15020 20 77 61 6c 52 65 73 74 61 72 74 4c 6f 67 28 70   walRestartLog(p
15030 57 61 6c 29 29 20 29 7b 0a 20 20 20 20 72 65 74  Wal)) ){.    ret
15040 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f  urn rc;.  }..  /
15050 2a 20 49 66 20 74 68 69 73 20 69 73 20 74 68 65  * If this is the
15060 20 66 69 72 73 74 20 66 72 61 6d 65 20 77 72 69   first frame wri
15070 74 74 65 6e 20 69 6e 74 6f 20 74 68 65 20 6c 6f  tten into the lo
15080 67 2c 20 77 72 69 74 65 20 74 68 65 20 57 41 4c  g, write the WAL
15090 0a 20 20 2a 2a 20 68 65 61 64 65 72 20 74 6f 20  .  ** header to 
150a0 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65  the start of the
150b0 20 57 41 4c 20 66 69 6c 65 2e 20 53 65 65 20 63   WAL file. See c
150c0 6f 6d 6d 65 6e 74 73 20 61 74 20 74 68 65 20 74  omments at the t
150d0 6f 70 20 6f 66 0a 20 20 2a 2a 20 74 68 69 73 20  op of.  ** this 
150e0 73 6f 75 72 63 65 20 66 69 6c 65 20 66 6f 72 20  source file for 
150f0 61 20 64 65 73 63 72 69 70 74 69 6f 6e 20 6f 66  a description of
15100 20 74 68 65 20 57 41 4c 20 68 65 61 64 65 72 20   the WAL header 
15110 66 6f 72 6d 61 74 2e 0a 20 20 2a 2f 0a 20 20 69  format..  */.  i
15120 46 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64  Frame = pWal->hd
15130 72 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 69 66 28  r.mxFrame;.  if(
15140 20 69 46 72 61 6d 65 3d 3d 30 20 29 7b 0a 20 20   iFrame==0 ){.  
15150 20 20 75 38 20 61 57 61 6c 48 64 72 5b 57 41 4c    u8 aWalHdr[WAL
15160 5f 48 44 52 53 49 5a 45 5d 3b 20 20 20 20 20 20  _HDRSIZE];      
15170 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 61    /* Buffer to a
15180 73 73 65 6d 62 6c 79 20 77 61 6c 2d 68 65 61 64  ssembly wal-head
15190 65 72 20 69 6e 20 2a 2f 0a 20 20 20 20 73 71 6c  er in */.    sql
151a0 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57  ite3Put4byte(&aW
151b0 61 6c 48 64 72 5b 30 5d 2c 20 28 57 41 4c 5f 4d  alHdr[0], (WAL_M
151c0 41 47 49 43 20 7c 20 53 51 4c 49 54 45 5f 42 49  AGIC | SQLITE_BI
151d0 47 45 4e 44 49 41 4e 29 29 3b 0a 20 20 20 20 73  GENDIAN));.    s
151e0 71 6c 69 74 65 33 50 75 74 34 62 79 74 65 28 26  qlite3Put4byte(&
151f0 61 57 61 6c 48 64 72 5b 34 5d 2c 20 33 30 30 37  aWalHdr[4], 3007
15200 30 30 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  000);.    sqlite
15210 33 50 75 74 34 62 79 74 65 28 26 61 57 61 6c 48  3Put4byte(&aWalH
15220 64 72 5b 38 5d 2c 20 73 7a 50 61 67 65 29 3b 0a  dr[8], szPage);.
15230 20 20 20 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65      pWal->szPage
15240 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 70   = szPage;.    p
15250 57 61 6c 2d 3e 68 64 72 2e 62 69 67 45 6e 64 43  Wal->hdr.bigEndC
15260 6b 73 75 6d 20 3d 20 53 51 4c 49 54 45 5f 42 49  ksum = SQLITE_BI
15270 47 45 4e 44 49 41 4e 3b 0a 20 20 20 20 73 71 6c  GENDIAN;.    sql
15280 69 74 65 33 50 75 74 34 62 79 74 65 28 26 61 57  ite3Put4byte(&aW
15290 61 6c 48 64 72 5b 31 32 5d 2c 20 70 57 61 6c 2d  alHdr[12], pWal-
152a0 3e 6e 43 6b 70 74 29 3b 0a 20 20 20 20 6d 65 6d  >nCkpt);.    mem
152b0 63 70 79 28 26 61 57 61 6c 48 64 72 5b 31 36 5d  cpy(&aWalHdr[16]
152c0 2c 20 70 57 61 6c 2d 3e 68 64 72 2e 61 53 61 6c  , pWal->hdr.aSal
152d0 74 2c 20 38 29 3b 0a 20 20 20 20 72 63 20 3d 20  t, 8);.    rc = 
152e0 73 71 6c 69 74 65 33 4f 73 57 72 69 74 65 28 70  sqlite3OsWrite(p
152f0 57 61 6c 2d 3e 70 57 61 6c 46 64 2c 20 61 57 61  Wal->pWalFd, aWa
15300 6c 48 64 72 2c 20 73 69 7a 65 6f 66 28 61 57 61  lHdr, sizeof(aWa
15310 6c 48 64 72 29 2c 20 30 29 3b 0a 20 20 20 20 57  lHdr), 0);.    W
15320 41 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a  ALTRACE(("WAL%p:
15330 20 77 61 6c 2d 68 65 61 64 65 72 20 77 72 69 74   wal-header writ
15340 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  e %s\n", pWal, r
15350 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
15360 6f 6b 22 29 29 3b 0a 20 20 20 20 69 66 28 20 72  ok"));.    if( r
15370 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
15380 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
15390 0a 20 20 20 20 7d 0a 20 20 20 20 77 61 6c 43 68  .    }.    walCh
153a0 65 63 6b 73 75 6d 42 79 74 65 73 28 31 2c 20 61  ecksumBytes(1, a
153b0 57 61 6c 48 64 72 2c 20 73 69 7a 65 6f 66 28 61  WalHdr, sizeof(a
153c0 57 61 6c 48 64 72 29 2c 20 30 2c 20 70 57 61 6c  WalHdr), 0, pWal
153d0 2d 3e 68 64 72 2e 61 46 72 61 6d 65 43 6b 73 75  ->hdr.aFrameCksu
153e0 6d 29 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74  m);.  }.  assert
153f0 28 20 70 57 61 6c 2d 3e 73 7a 50 61 67 65 3d 3d  ( pWal->szPage==
15400 73 7a 50 61 67 65 20 29 3b 0a 0a 20 20 2f 2a 20  szPage );..  /* 
15410 57 72 69 74 65 20 74 68 65 20 6c 6f 67 20 66 69  Write the log fi
15420 6c 65 2e 20 2a 2f 0a 20 20 66 6f 72 28 70 3d 70  le. */.  for(p=p
15430 4c 69 73 74 3b 20 70 3b 20 70 3d 70 2d 3e 70 44  List; p; p=p->pD
15440 69 72 74 79 29 7b 0a 20 20 20 20 75 33 32 20 6e  irty){.    u32 n
15450 44 62 73 69 7a 65 3b 20 20 20 20 20 20 20 20 20  Dbsize;         
15460 20 20 20 20 20 20 20 20 20 2f 2a 20 44 62 2d 73           /* Db-s
15470 69 7a 65 20 66 69 65 6c 64 20 66 6f 72 20 66 72  ize field for fr
15480 61 6d 65 20 68 65 61 64 65 72 20 2a 2f 0a 20 20  ame header */.  
15490 20 20 69 36 34 20 69 4f 66 66 73 65 74 3b 20 20    i64 iOffset;  
154a0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
154b0 2f 2a 20 57 72 69 74 65 20 6f 66 66 73 65 74 20  /* Write offset 
154c0 69 6e 20 6c 6f 67 20 66 69 6c 65 20 2a 2f 0a 0a  in log file */..
154d0 20 20 20 20 69 4f 66 66 73 65 74 20 3d 20 77 61      iOffset = wa
154e0 6c 46 72 61 6d 65 4f 66 66 73 65 74 28 2b 2b 69  lFrameOffset(++i
154f0 46 72 61 6d 65 2c 20 73 7a 50 61 67 65 29 3b 0a  Frame, szPage);.
15500 20 20 20 20 0a 20 20 20 20 2f 2a 20 50 6f 70 75      .    /* Popu
15510 6c 61 74 65 20 61 6e 64 20 77 72 69 74 65 20 74  late and write t
15520 68 65 20 66 72 61 6d 65 20 68 65 61 64 65 72 20  he frame header 
15530 2a 2f 0a 20 20 20 20 6e 44 62 73 69 7a 65 20 3d  */.    nDbsize =
15540 20 28 69 73 43 6f 6d 6d 69 74 20 26 26 20 70 2d   (isCommit && p-
15550 3e 70 44 69 72 74 79 3d 3d 30 29 20 3f 20 6e 54  >pDirty==0) ? nT
15560 72 75 6e 63 61 74 65 20 3a 20 30 3b 0a 20 20 20  runcate : 0;.   
15570 20 77 61 6c 45 6e 63 6f 64 65 46 72 61 6d 65 28   walEncodeFrame(
15580 70 57 61 6c 2c 20 70 2d 3e 70 67 6e 6f 2c 20 6e  pWal, p->pgno, n
15590 44 62 73 69 7a 65 2c 20 70 2d 3e 70 44 61 74 61  Dbsize, p->pData
155a0 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20 20 20 72  , aFrame);.    r
155b0 63 20 3d 20 73 71 6c 69 74 65 33 4f 73 57 72 69  c = sqlite3OsWri
155c0 74 65 28 70 57 61 6c 2d 3e 70 57 61 6c 46 64 2c  te(pWal->pWalFd,
155d0 20 61 46 72 61 6d 65 2c 20 73 69 7a 65 6f 66 28   aFrame, sizeof(
155e0 61 46 72 61 6d 65 29 2c 20 69 4f 66 66 73 65 74  aFrame), iOffset
155f0 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
15600 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
15610 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20    return rc;.   
15620 20 7d 0a 0a 20 20 20 20 2f 2a 20 57 72 69 74 65   }..    /* Write
15630 20 74 68 65 20 70 61 67 65 20 64 61 74 61 20 2a   the page data *
15640 2f 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  /.    rc = sqlit
15650 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c 2d 3e  e3OsWrite(pWal->
15660 70 57 61 6c 46 64 2c 20 70 2d 3e 70 44 61 74 61  pWalFd, p->pData
15670 2c 20 73 7a 50 61 67 65 2c 20 69 4f 66 66 73 65  , szPage, iOffse
15680 74 2b 73 69 7a 65 6f 66 28 61 46 72 61 6d 65 29  t+sizeof(aFrame)
15690 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
156a0 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
156b0 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20    return rc;.   
156c0 20 7d 0a 20 20 20 20 70 4c 61 73 74 20 3d 20 70   }.    pLast = p
156d0 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 79 6e 63  ;.  }..  /* Sync
156e0 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 69 66   the log file if
156f0 20 74 68 65 20 27 69 73 53 79 6e 63 27 20 66 6c   the 'isSync' fl
15700 61 67 20 77 61 73 20 73 70 65 63 69 66 69 65 64  ag was specified
15710 2e 20 2a 2f 0a 20 20 69 66 28 20 73 79 6e 63 5f  . */.  if( sync_
15720 66 6c 61 67 73 20 29 7b 0a 20 20 20 20 69 36 34  flags ){.    i64
15730 20 69 53 65 67 6d 65 6e 74 20 3d 20 73 71 6c 69   iSegment = sqli
15740 74 65 33 4f 73 53 65 63 74 6f 72 53 69 7a 65 28  te3OsSectorSize(
15750 70 57 61 6c 2d 3e 70 57 61 6c 46 64 29 3b 0a 20  pWal->pWalFd);. 
15760 20 20 20 69 36 34 20 69 4f 66 66 73 65 74 20 3d     i64 iOffset =
15770 20 77 61 6c 46 72 61 6d 65 4f 66 66 73 65 74 28   walFrameOffset(
15780 69 46 72 61 6d 65 2b 31 2c 20 73 7a 50 61 67 65  iFrame+1, szPage
15790 29 3b 0a 0a 20 20 20 20 61 73 73 65 72 74 28 20  );..    assert( 
157a0 69 73 43 6f 6d 6d 69 74 20 29 3b 0a 20 20 20 20  isCommit );.    
157b0 61 73 73 65 72 74 28 20 69 53 65 67 6d 65 6e 74  assert( iSegment
157c0 3e 30 20 29 3b 0a 0a 20 20 20 20 69 53 65 67 6d  >0 );..    iSegm
157d0 65 6e 74 20 3d 20 28 28 28 69 4f 66 66 73 65 74  ent = (((iOffset
157e0 2b 69 53 65 67 6d 65 6e 74 2d 31 29 2f 69 53 65  +iSegment-1)/iSe
157f0 67 6d 65 6e 74 29 20 2a 20 69 53 65 67 6d 65 6e  gment) * iSegmen
15800 74 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69  t);.    while( i
15810 4f 66 66 73 65 74 3c 69 53 65 67 6d 65 6e 74 20  Offset<iSegment 
15820 29 7b 0a 20 20 20 20 20 20 77 61 6c 45 6e 63 6f  ){.      walEnco
15830 64 65 46 72 61 6d 65 28 70 57 61 6c 2c 20 70 4c  deFrame(pWal, pL
15840 61 73 74 2d 3e 70 67 6e 6f 2c 20 6e 54 72 75 6e  ast->pgno, nTrun
15850 63 61 74 65 2c 20 70 4c 61 73 74 2d 3e 70 44 61  cate, pLast->pDa
15860 74 61 2c 20 61 46 72 61 6d 65 29 3b 0a 20 20 20  ta, aFrame);.   
15870 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 4f     rc = sqlite3O
15880 73 57 72 69 74 65 28 70 57 61 6c 2d 3e 70 57 61  sWrite(pWal->pWa
15890 6c 46 64 2c 20 61 46 72 61 6d 65 2c 20 73 69 7a  lFd, aFrame, siz
158a0 65 6f 66 28 61 46 72 61 6d 65 29 2c 20 69 4f 66  eof(aFrame), iOf
158b0 66 73 65 74 29 3b 0a 20 20 20 20 20 20 69 66 28  fset);.      if(
158c0 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
158d0 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  {.        return
158e0 20 72 63 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20   rc;.      }..  
158f0 20 20 20 20 69 4f 66 66 73 65 74 20 2b 3d 20 57      iOffset += W
15900 41 4c 5f 46 52 41 4d 45 5f 48 44 52 53 49 5a 45  AL_FRAME_HDRSIZE
15910 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  ;.      rc = sql
15920 69 74 65 33 4f 73 57 72 69 74 65 28 70 57 61 6c  ite3OsWrite(pWal
15930 2d 3e 70 57 61 6c 46 64 2c 20 70 4c 61 73 74 2d  ->pWalFd, pLast-
15940 3e 70 44 61 74 61 2c 20 73 7a 50 61 67 65 2c 20  >pData, szPage, 
15950 69 4f 66 66 73 65 74 29 3b 20 0a 20 20 20 20 20  iOffset); .     
15960 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
15970 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72 65  OK ){.        re
15980 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 20 20 7d  turn rc;.      }
15990 0a 20 20 20 20 20 20 6e 4c 61 73 74 2b 2b 3b 0a  .      nLast++;.
159a0 20 20 20 20 20 20 69 4f 66 66 73 65 74 20 2b 3d        iOffset +=
159b0 20 73 7a 50 61 67 65 3b 0a 20 20 20 20 7d 0a 0a   szPage;.    }..
159c0 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
159d0 4f 73 53 79 6e 63 28 70 57 61 6c 2d 3e 70 57 61  OsSync(pWal->pWa
159e0 6c 46 64 2c 20 73 79 6e 63 5f 66 6c 61 67 73 29  lFd, sync_flags)
159f0 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 70 70 65  ;.  }..  /* Appe
15a00 6e 64 20 64 61 74 61 20 74 6f 20 74 68 65 20 77  nd data to the w
15a10 61 6c 2d 69 6e 64 65 78 2e 20 49 74 20 69 73 20  al-index. It is 
15a20 6e 6f 74 20 6e 65 63 65 73 73 61 72 79 20 74 6f  not necessary to
15a30 20 6c 6f 63 6b 20 74 68 65 20 0a 20 20 2a 2a 20   lock the .  ** 
15a40 77 61 6c 2d 69 6e 64 65 78 20 74 6f 20 64 6f 20  wal-index to do 
15a50 74 68 69 73 20 61 73 20 74 68 65 20 53 51 4c 49  this as the SQLI
15a60 54 45 5f 53 48 4d 5f 57 52 49 54 45 20 6c 6f 63  TE_SHM_WRITE loc
15a70 6b 20 68 65 6c 64 20 6f 6e 20 74 68 65 20 77 61  k held on the wa
15a80 6c 2d 69 6e 64 65 78 0a 20 20 2a 2a 20 67 75 61  l-index.  ** gua
15a90 72 61 6e 74 65 65 73 20 74 68 61 74 20 74 68 65  rantees that the
15aa0 72 65 20 61 72 65 20 6e 6f 20 6f 74 68 65 72 20  re are no other 
15ab0 77 72 69 74 65 72 73 2c 20 61 6e 64 20 6e 6f 20  writers, and no 
15ac0 64 61 74 61 20 74 68 61 74 20 6d 61 79 0a 20 20  data that may.  
15ad0 2a 2a 20 62 65 20 69 6e 20 75 73 65 20 62 79 20  ** be in use by 
15ae0 65 78 69 73 74 69 6e 67 20 72 65 61 64 65 72 73  existing readers
15af0 20 69 73 20 62 65 69 6e 67 20 6f 76 65 72 77 72   is being overwr
15b00 69 74 74 65 6e 2e 0a 20 20 2a 2f 0a 20 20 69 46  itten..  */.  iF
15b10 72 61 6d 65 20 3d 20 70 57 61 6c 2d 3e 68 64 72  rame = pWal->hdr
15b20 2e 6d 78 46 72 61 6d 65 3b 0a 20 20 66 6f 72 28  .mxFrame;.  for(
15b30 70 3d 70 4c 69 73 74 3b 20 70 20 26 26 20 72 63  p=pList; p && rc
15b40 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 70 3d 70  ==SQLITE_OK; p=p
15b50 2d 3e 70 44 69 72 74 79 29 7b 0a 20 20 20 20 69  ->pDirty){.    i
15b60 46 72 61 6d 65 2b 2b 3b 0a 20 20 20 20 72 63 20  Frame++;.    rc 
15b70 3d 20 77 61 6c 49 6e 64 65 78 41 70 70 65 6e 64  = walIndexAppend
15b80 28 70 57 61 6c 2c 20 69 46 72 61 6d 65 2c 20 70  (pWal, iFrame, p
15b90 2d 3e 70 67 6e 6f 29 3b 0a 20 20 7d 0a 20 20 77  ->pgno);.  }.  w
15ba0 68 69 6c 65 28 20 6e 4c 61 73 74 3e 30 20 26 26  hile( nLast>0 &&
15bb0 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
15bc0 7b 0a 20 20 20 20 69 46 72 61 6d 65 2b 2b 3b 0a  {.    iFrame++;.
15bd0 20 20 20 20 6e 4c 61 73 74 2d 2d 3b 0a 20 20 20      nLast--;.   
15be0 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 41 70   rc = walIndexAp
15bf0 70 65 6e 64 28 70 57 61 6c 2c 20 69 46 72 61 6d  pend(pWal, iFram
15c00 65 2c 20 70 4c 61 73 74 2d 3e 70 67 6e 6f 29 3b  e, pLast->pgno);
15c10 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
15c20 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
15c30 20 2f 2a 20 55 70 64 61 74 65 20 74 68 65 20 70   /* Update the p
15c40 72 69 76 61 74 65 20 63 6f 70 79 20 6f 66 20 74  rivate copy of t
15c50 68 65 20 68 65 61 64 65 72 2e 20 2a 2f 0a 20 20  he header. */.  
15c60 20 20 70 57 61 6c 2d 3e 68 64 72 2e 73 7a 50 61    pWal->hdr.szPa
15c70 67 65 20 3d 20 73 7a 50 61 67 65 3b 0a 20 20 20  ge = szPage;.   
15c80 20 70 57 61 6c 2d 3e 68 64 72 2e 6d 78 46 72 61   pWal->hdr.mxFra
15c90 6d 65 20 3d 20 69 46 72 61 6d 65 3b 0a 20 20 20  me = iFrame;.   
15ca0 20 69 66 28 20 69 73 43 6f 6d 6d 69 74 20 29 7b   if( isCommit ){
15cb0 0a 20 20 20 20 20 20 70 57 61 6c 2d 3e 68 64 72  .      pWal->hdr
15cc0 2e 69 43 68 61 6e 67 65 2b 2b 3b 0a 20 20 20 20  .iChange++;.    
15cd0 20 20 70 57 61 6c 2d 3e 68 64 72 2e 6e 50 61 67    pWal->hdr.nPag
15ce0 65 20 3d 20 6e 54 72 75 6e 63 61 74 65 3b 0a 20  e = nTruncate;. 
15cf0 20 20 20 7d 0a 20 20 20 20 2f 2a 20 49 66 20 74     }.    /* If t
15d00 68 69 73 20 69 73 20 61 20 63 6f 6d 6d 69 74 2c  his is a commit,
15d10 20 75 70 64 61 74 65 20 74 68 65 20 77 61 6c 2d   update the wal-
15d20 69 6e 64 65 78 20 68 65 61 64 65 72 20 74 6f 6f  index header too
15d30 2e 20 2a 2f 0a 20 20 20 20 69 66 28 20 69 73 43  . */.    if( isC
15d40 6f 6d 6d 69 74 20 29 7b 0a 20 20 20 20 20 20 77  ommit ){.      w
15d50 61 6c 49 6e 64 65 78 57 72 69 74 65 48 64 72 28  alIndexWriteHdr(
15d60 70 57 61 6c 29 3b 0a 20 20 20 20 20 20 70 57 61  pWal);.      pWa
15d70 6c 2d 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20 69  l->iCallback = i
15d80 46 72 61 6d 65 3b 0a 20 20 20 20 7d 0a 20 20 7d  Frame;.    }.  }
15d90 0a 0a 20 20 57 41 4c 54 52 41 43 45 28 28 22 57  ..  WALTRACE(("W
15da0 41 4c 25 70 3a 20 66 72 61 6d 65 20 77 72 69 74  AL%p: frame writ
15db0 65 20 25 73 5c 6e 22 2c 20 70 57 61 6c 2c 20 72  e %s\n", pWal, r
15dc0 63 20 3f 20 22 66 61 69 6c 65 64 22 20 3a 20 22  c ? "failed" : "
15dd0 6f 6b 22 29 29 3b 0a 20 20 72 65 74 75 72 6e 20  ok"));.  return 
15de0 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68  rc;.}../* .** Th
15df0 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61  is routine is ca
15e00 6c 6c 65 64 20 74 6f 20 69 6d 70 6c 65 6d 65 6e  lled to implemen
15e10 74 20 73 71 6c 69 74 65 33 5f 77 61 6c 5f 63 68  t sqlite3_wal_ch
15e20 65 63 6b 70 6f 69 6e 74 28 29 20 61 6e 64 0a 2a  eckpoint() and.*
15e30 2a 20 72 65 6c 61 74 65 64 20 69 6e 74 65 72 66  * related interf
15e40 61 63 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 62 74 61  aces..**.** Obta
15e50 69 6e 20 61 20 43 48 45 43 4b 50 4f 49 4e 54 20  in a CHECKPOINT 
15e60 6c 6f 63 6b 20 61 6e 64 20 74 68 65 6e 20 62 61  lock and then ba
15e70 63 6b 66 69 6c 6c 20 61 73 20 6d 75 63 68 20 69  ckfill as much i
15e80 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 73 0a 2a 2a  nformation as.**
15e90 20 77 65 20 63 61 6e 20 66 72 6f 6d 20 57 41 4c   we can from WAL
15ea0 20 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61   into the databa
15eb0 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  se..*/.int sqlit
15ec0 65 33 57 61 6c 43 68 65 63 6b 70 6f 69 6e 74 28  e3WalCheckpoint(
15ed0 0a 20 20 57 61 6c 20 2a 70 57 61 6c 2c 20 20 20  .  Wal *pWal,   
15ee0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15ef0 20 20 20 2f 2a 20 57 61 6c 20 63 6f 6e 6e 65 63     /* Wal connec
15f00 74 69 6f 6e 20 2a 2f 0a 20 20 69 6e 74 20 73 79  tion */.  int sy
15f10 6e 63 5f 66 6c 61 67 73 2c 20 20 20 20 20 20 20  nc_flags,       
15f20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6c 61            /* Fla
15f30 67 73 20 74 6f 20 73 79 6e 63 20 64 62 20 66 69  gs to sync db fi
15f40 6c 65 20 77 69 74 68 20 28 6f 72 20 30 29 20 2a  le with (or 0) *
15f50 2f 0a 20 20 69 6e 74 20 6e 42 75 66 2c 20 20 20  /.  int nBuf,   
15f60 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15f70 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 74      /* Size of t
15f80 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72 20  emporary buffer 
15f90 2a 2f 0a 20 20 75 38 20 2a 7a 42 75 66 20 20 20  */.  u8 *zBuf   
15fa0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15fb0 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72       /* Temporar
15fc0 79 20 62 75 66 66 65 72 20 74 6f 20 75 73 65 20  y buffer to use 
15fd0 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 20  */.){.  int rc; 
15fe0 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15ff0 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
16000 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20  n code */.  int 
16010 69 73 43 68 61 6e 67 65 64 20 3d 20 30 3b 20 20  isChanged = 0;  
16020 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
16030 72 75 65 20 69 66 20 61 20 6e 65 77 20 77 61 6c  rue if a new wal
16040 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 69 73  -index header is
16050 20 6c 6f 61 64 65 64 20 2a 2f 0a 0a 20 20 61 73   loaded */..  as
16060 73 65 72 74 28 20 70 57 61 6c 2d 3e 63 6b 70 74  sert( pWal->ckpt
16070 4c 6f 63 6b 3d 3d 30 20 29 3b 0a 0a 20 20 57 41  Lock==0 );..  WA
16080 4c 54 52 41 43 45 28 28 22 57 41 4c 25 70 3a 20  LTRACE(("WAL%p: 
16090 63 68 65 63 6b 70 6f 69 6e 74 20 62 65 67 69 6e  checkpoint begin
160a0 73 5c 6e 22 2c 20 70 57 61 6c 29 29 3b 0a 20 20  s\n", pWal));.  
160b0 72 63 20 3d 20 77 61 6c 4c 6f 63 6b 45 78 63 6c  rc = walLockExcl
160c0 75 73 69 76 65 28 70 57 61 6c 2c 20 57 41 4c 5f  usive(pWal, WAL_
160d0 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29 3b 0a 20  CKPT_LOCK, 1);. 
160e0 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 2f   if( rc ){.    /
160f0 2a 20 55 73 75 61 6c 6c 79 20 74 68 69 73 20 69  * Usually this i
16100 73 20 53 51 4c 49 54 45 5f 42 55 53 59 20 6d 65  s SQLITE_BUSY me
16110 61 6e 69 6e 67 20 74 68 61 74 20 61 6e 6f 74 68  aning that anoth
16120 65 72 20 74 68 72 65 61 64 20 6f 72 20 70 72 6f  er thread or pro
16130 63 65 73 73 0a 20 20 20 20 2a 2a 20 69 73 20 61  cess.    ** is a
16140 6c 72 65 61 64 79 20 72 75 6e 6e 69 6e 67 20 61  lready running a
16150 20 63 68 65 63 6b 70 6f 69 6e 74 2c 20 6f 72 20   checkpoint, or 
16160 6d 61 79 62 65 20 61 20 72 65 63 6f 76 65 72 79  maybe a recovery
16170 2e 20 20 42 75 74 20 69 74 20 6d 69 67 68 74 0a  .  But it might.
16180 20 20 20 20 2a 2a 20 61 6c 73 6f 20 62 65 20 53      ** also be S
16190 51 4c 49 54 45 5f 49 4f 45 52 52 2e 20 2a 2f 0a  QLITE_IOERR. */.
161a0 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
161b0 20 7d 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74 4c   }.  pWal->ckptL
161c0 6f 63 6b 20 3d 20 31 3b 0a 0a 20 20 2f 2a 20 43  ock = 1;..  /* C
161d0 6f 70 79 20 64 61 74 61 20 66 72 6f 6d 20 74 68  opy data from th
161e0 65 20 6c 6f 67 20 74 6f 20 74 68 65 20 64 61 74  e log to the dat
161f0 61 62 61 73 65 20 66 69 6c 65 2e 20 2a 2f 0a 20  abase file. */. 
16200 20 72 63 20 3d 20 77 61 6c 49 6e 64 65 78 52 65   rc = walIndexRe
16210 61 64 48 64 72 28 70 57 61 6c 2c 20 26 69 73 43  adHdr(pWal, &isC
16220 68 61 6e 67 65 64 29 3b 0a 20 20 69 66 28 20 72  hanged);.  if( r
16230 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
16240 20 20 20 20 72 63 20 3d 20 77 61 6c 43 68 65 63      rc = walChec
16250 6b 70 6f 69 6e 74 28 70 57 61 6c 2c 20 73 79 6e  kpoint(pWal, syn
16260 63 5f 66 6c 61 67 73 2c 20 6e 42 75 66 2c 20 7a  c_flags, nBuf, z
16270 42 75 66 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  Buf);.  }.  if( 
16280 69 73 43 68 61 6e 67 65 64 20 29 7b 0a 20 20 20  isChanged ){.   
16290 20 2f 2a 20 49 66 20 61 20 6e 65 77 20 77 61 6c   /* If a new wal
162a0 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 77 61  -index header wa
162b0 73 20 6c 6f 61 64 65 64 20 62 65 66 6f 72 65 20  s loaded before 
162c0 74 68 65 20 63 68 65 63 6b 70 6f 69 6e 74 20 77  the checkpoint w
162d0 61 73 20 0a 20 20 20 20 2a 2a 20 70 65 72 66 6f  as .    ** perfo
162e0 72 6d 65 64 2c 20 74 68 65 6e 20 74 68 65 20 70  rmed, then the p
162f0 61 67 65 72 2d 63 61 63 68 65 20 61 73 73 6f 63  ager-cache assoc
16300 69 61 74 65 64 20 77 69 74 68 20 70 57 61 6c 20  iated with pWal 
16310 69 73 20 6e 6f 77 0a 20 20 20 20 2a 2a 20 6f 75  is now.    ** ou
16320 74 20 6f 66 20 64 61 74 65 2e 20 53 6f 20 7a 65  t of date. So ze
16330 72 6f 20 74 68 65 20 63 61 63 68 65 64 20 77 61  ro the cached wa
16340 6c 2d 69 6e 64 65 78 20 68 65 61 64 65 72 20 74  l-index header t
16350 6f 20 65 6e 73 75 72 65 20 74 68 61 74 0a 20 20  o ensure that.  
16360 20 20 2a 2a 20 6e 65 78 74 20 74 69 6d 65 20 74    ** next time t
16370 68 65 20 70 61 67 65 72 20 6f 70 65 6e 73 20 61  he pager opens a
16380 20 73 6e 61 70 73 68 6f 74 20 6f 6e 20 74 68 69   snapshot on thi
16390 73 20 64 61 74 61 62 61 73 65 20 69 74 20 6b 6e  s database it kn
163a0 6f 77 73 20 74 68 61 74 0a 20 20 20 20 2a 2a 20  ows that.    ** 
163b0 74 68 65 20 63 61 63 68 65 20 6e 65 65 64 73 20  the cache needs 
163c0 74 6f 20 62 65 20 72 65 73 65 74 2e 0a 20 20 20  to be reset..   
163d0 20 2a 2f 0a 20 20 20 20 6d 65 6d 73 65 74 28 26   */.    memset(&
163e0 70 57 61 6c 2d 3e 68 64 72 2c 20 30 2c 20 73 69  pWal->hdr, 0, si
163f0 7a 65 6f 66 28 57 61 6c 49 6e 64 65 78 48 64 72  zeof(WalIndexHdr
16400 29 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65  ));.  }..  /* Re
16410 6c 65 61 73 65 20 74 68 65 20 6c 6f 63 6b 73 2e  lease the locks.
16420 20 2a 2f 0a 20 20 77 61 6c 55 6e 6c 6f 63 6b 45   */.  walUnlockE
16430 78 63 6c 75 73 69 76 65 28 70 57 61 6c 2c 20 57  xclusive(pWal, W
16440 41 4c 5f 43 4b 50 54 5f 4c 4f 43 4b 2c 20 31 29  AL_CKPT_LOCK, 1)
16450 3b 0a 20 20 70 57 61 6c 2d 3e 63 6b 70 74 4c 6f  ;.  pWal->ckptLo
16460 63 6b 20 3d 20 30 3b 0a 20 20 57 41 4c 54 52 41  ck = 0;.  WALTRA
16470 43 45 28 28 22 57 41 4c 25 70 3a 20 63 68 65 63  CE(("WAL%p: chec
16480 6b 70 6f 69 6e 74 20 25 73 5c 6e 22 2c 20 70 57  kpoint %s\n", pW
16490 61 6c 2c 20 72 63 20 3f 20 22 66 61 69 6c 65 64  al, rc ? "failed
164a0 22 20 3a 20 22 6f 6b 22 29 29 3b 0a 20 20 72 65  " : "ok"));.  re
164b0 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 52  turn rc;.}../* R
164c0 65 74 75 72 6e 20 74 68 65 20 76 61 6c 75 65 20  eturn the value 
164d0 74 6f 20 70 61 73 73 20 74 6f 20 61 20 73 71 6c  to pass to a sql
164e0 69 74 65 33 5f 77 61 6c 5f 68 6f 6f 6b 20 63 61  ite3_wal_hook ca
164f0 6c 6c 62 61 63 6b 2c 20 74 68 65 0a 2a 2a 20 6e  llback, the.** n
16500 75 6d 62 65 72 20 6f 66 20 66 72 61 6d 65 73 20  umber of frames 
16510 69 6e 20 74 68 65 20 57 41 4c 20 61 74 20 74 68  in the WAL at th
16520 65 20 70 6f 69 6e 74 20 6f 66 20 74 68 65 20 6c  e point of the l
16530 61 73 74 20 63 6f 6d 6d 69 74 20 73 69 6e 63 65  ast commit since
16540 0a 2a 2a 20 73 71 6c 69 74 65 33 57 61 6c 43 61  .** sqlite3WalCa
16550 6c 6c 62 61 63 6b 28 29 20 77 61 73 20 63 61 6c  llback() was cal
16560 6c 65 64 2e 20 20 49 66 20 6e 6f 20 63 6f 6d 6d  led.  If no comm
16570 69 74 73 20 68 61 76 65 20 6f 63 63 75 72 72 65  its have occurre
16580 64 20 73 69 6e 63 65 0a 2a 2a 20 74 68 65 20 6c  d since.** the l
16590 61 73 74 20 63 61 6c 6c 2c 20 74 68 65 6e 20 72  ast call, then r
165a0 65 74 75 72 6e 20 30 2e 0a 2a 2f 0a 69 6e 74 20  eturn 0..*/.int 
165b0 73 71 6c 69 74 65 33 57 61 6c 43 61 6c 6c 62 61  sqlite3WalCallba
165c0 63 6b 28 57 61 6c 20 2a 70 57 61 6c 29 7b 0a 20  ck(Wal *pWal){. 
165d0 20 75 33 32 20 72 65 74 20 3d 20 30 3b 0a 20 20   u32 ret = 0;.  
165e0 69 66 28 20 70 57 61 6c 20 29 7b 0a 20 20 20 20  if( pWal ){.    
165f0 72 65 74 20 3d 20 70 57 61 6c 2d 3e 69 43 61 6c  ret = pWal->iCal
16600 6c 62 61 63 6b 3b 0a 20 20 20 20 70 57 61 6c 2d  lback;.    pWal-
16610 3e 69 43 61 6c 6c 62 61 63 6b 20 3d 20 30 3b 0a  >iCallback = 0;.
16620 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 28 69 6e    }.  return (in
16630 74 29 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  t)ret;.}../*.** 
16640 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
16650 20 63 61 6c 6c 65 64 20 74 6f 20 63 68 61 6e 67   called to chang
16660 65 20 74 68 65 20 57 41 4c 20 73 75 62 73 79 73  e the WAL subsys
16670 74 65 6d 20 69 6e 74 6f 20 6f 72 20 6f 75 74 0a  tem into or out.
16680 2a 2a 20 6f 66 20 6c 6f 63 6b 69 6e 67 5f 6d 6f  ** of locking_mo
16690 64 65 3d 45 58 43 4c 55 53 49 56 45 2e 0a 2a 2a  de=EXCLUSIVE..**
166a0 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20 7a 65 72  .** If op is zer
166b0 6f 2c 20 74 68 65 6e 20 61 74 74 65 6d 70 74 20  o, then attempt 
166c0 74 6f 20 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c  to change from l
166d0 6f 63 6b 69 6e 67 5f 6d 6f 64 65 3d 45 58 43 4c  ocking_mode=EXCL
166e0 55 53 49 56 45 0a 2a 2a 20 69 6e 74 6f 20 6c 6f  USIVE.** into lo
166f0 63 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41  cking_mode=NORMA
16700 4c 2e 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74  L.  This means t
16710 68 61 74 20 77 65 20 6d 75 73 74 20 61 63 71 75  hat we must acqu
16720 69 72 65 20 61 20 6c 6f 63 6b 0a 2a 2a 20 6f 6e  ire a lock.** on
16730 20 74 68 65 20 70 57 61 6c 2d 3e 72 65 61 64 4c   the pWal->readL
16740 6f 63 6b 20 62 79 74 65 2e 20 20 49 66 20 74 68  ock byte.  If th
16750 65 20 57 41 4c 20 69 73 20 61 6c 72 65 61 64 79  e WAL is already
16760 20 69 6e 20 6c 6f 63 6b 69 6e 67 5f 6d 6f 64 65   in locking_mode
16770 3d 4e 4f 52 4d 41 4c 0a 2a 2a 20 6f 72 20 69 66  =NORMAL.** or if
16780 20 74 68 65 20 61 63 71 75 69 73 69 74 69 6f 6e   the acquisition
16790 20 6f 66 20 74 68 65 20 6c 6f 63 6b 20 66 61 69   of the lock fai
167a0 6c 73 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20  ls, then return 
167b0 30 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 74 72  0.  If the.** tr
167c0 61 6e 73 69 74 69 6f 6e 20 6f 75 74 20 6f 66 20  ansition out of 
167d0 65 78 63 6c 75 73 69 76 65 2d 6d 6f 64 65 20 69  exclusive-mode i
167e0 73 20 73 75 63 63 65 73 73 66 75 6c 2c 20 72 65  s successful, re
167f0 74 75 72 6e 20 31 2e 20 20 54 68 69 73 0a 2a 2a  turn 1.  This.**
16800 20 6f 70 65 72 61 74 69 6f 6e 20 6d 75 73 74 20   operation must 
16810 6f 63 63 75 72 20 77 68 69 6c 65 20 74 68 65 20  occur while the 
16820 70 61 67 65 72 20 69 73 20 73 74 69 6c 6c 20 68  pager is still h
16830 6f 6c 64 69 6e 67 20 74 68 65 20 65 78 63 6c 75  olding the exclu
16840 73 69 76 65 0a 2a 2a 20 6c 6f 63 6b 20 6f 6e 20  sive.** lock on 
16850 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73  the main databas
16860 65 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66  e file..**.** If
16870 20 6f 70 20 69 73 20 6f 6e 65 2c 20 74 68 65 6e   op is one, then
16880 20 63 68 61 6e 67 65 20 66 72 6f 6d 20 6c 6f 63   change from loc
16890 6b 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c  king_mode=NORMAL
168a0 20 69 6e 74 6f 20 0a 2a 2a 20 6c 6f 63 6b 69 6e   into .** lockin
168b0 67 5f 6d 6f 64 65 3d 45 58 43 4c 55 53 49 56 45  g_mode=EXCLUSIVE
168c0 2e 20 20 54 68 69 73 20 6d 65 61 6e 73 20 74 68  .  This means th
168d0 61 74 20 74 68 65 20 70 57 61 6c 2d 3e 72 65 61  at the pWal->rea
168e0 64 4c 6f 63 6b 20 6d 75 73 74 0a 2a 2a 20 62 65  dLock must.** be
168f0 20 72 65 6c 65 61 73 65 64 2e 20 20 52 65 74 75   released.  Retu
16900 72 6e 20 31 20 69 66 20 74 68 65 20 74 72 61 6e  rn 1 if the tran
16910 73 69 74 69 6f 6e 20 69 73 20 6d 61 64 65 20 61  sition is made a
16920 6e 64 20 30 20 69 66 20 74 68 65 0a 2a 2a 20 57  nd 0 if the.** W
16930 41 4c 20 69 73 20 61 6c 72 65 61 64 79 20 69 6e  AL is already in
16940 20 65 78 63 6c 75 73 69 76 65 2d 6c 6f 63 6b 69   exclusive-locki
16950 6e 67 20 6d 6f 64 65 20 2d 20 6d 65 61 6e 69 6e  ng mode - meanin
16960 67 20 74 68 61 74 20 74 68 69 73 0a 2a 2a 20 72  g that this.** r
16970 6f 75 74 69 6e 65 20 69 73 20 61 20 6e 6f 2d 6f  outine is a no-o
16980 70 2e 20 20 54 68 65 20 70 61 67 65 72 20 6d 75  p.  The pager mu
16990 73 74 20 61 6c 72 65 61 64 79 20 68 6f 6c 64 20  st already hold 
169a0 74 68 65 20 65 78 63 6c 75 73 69 76 65 20 6c 6f  the exclusive lo
169b0 63 6b 0a 2a 2a 20 6f 6e 20 74 68 65 20 6d 61 69  ck.** on the mai
169c0 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  n database file 
169d0 62 65 66 6f 72 65 20 69 6e 76 6f 6b 69 6e 67 20  before invoking 
169e0 74 68 69 73 20 6f 70 65 72 61 74 69 6f 6e 2e 0a  this operation..
169f0 2a 2a 0a 2a 2a 20 49 66 20 6f 70 20 69 73 20 6e  **.** If op is n
16a00 65 67 61 74 69 76 65 2c 20 74 68 65 6e 20 64 6f  egative, then do
16a10 20 61 20 64 72 79 2d 72 75 6e 20 6f 66 20 74 68   a dry-run of th
16a20 65 20 6f 70 3d 3d 31 20 63 61 73 65 20 62 75 74  e op==1 case but
16a30 20 64 6f 0a 2a 2a 20 6e 6f 74 20 61 63 74 75 61   do.** not actua
16a40 6c 6c 79 20 63 68 61 6e 67 65 20 61 6e 79 74 68  lly change anyth
16a50 69 6e 67 2e 20 20 54 68 65 20 70 61 67 65 72 20  ing.  The pager 
16a60 75 73 65 73 20 74 68 69 73 20 74 6f 20 73 65 65  uses this to see
16a70 20 69 66 20 69 74 0a 2a 2a 20 73 68 6f 75 6c 64   if it.** should
16a80 20 61 63 71 75 69 72 65 20 74 68 65 20 64 61 74   acquire the dat
16a90 61 62 61 73 65 20 65 78 63 6c 75 73 69 76 65 20  abase exclusive 
16aa0 6c 6f 63 6b 20 70 72 69 6f 72 20 74 6f 20 69 6e  lock prior to in
16ab0 76 6f 6b 69 6e 67 0a 2a 2a 20 74 68 65 20 6f 70  voking.** the op
16ac0 3d 3d 31 20 63 61 73 65 2e 0a 2a 2f 0a 69 6e 74  ==1 case..*/.int
16ad0 20 73 71 6c 69 74 65 33 57 61 6c 45 78 63 6c 75   sqlite3WalExclu
16ae0 73 69 76 65 4d 6f 64 65 28 57 61 6c 20 2a 70 57  siveMode(Wal *pW
16af0 61 6c 2c 20 69 6e 74 20 6f 70 29 7b 0a 20 20 69  al, int op){.  i
16b00 6e 74 20 72 63 3b 0a 20 20 61 73 73 65 72 74 28  nt rc;.  assert(
16b10 20 70 57 61 6c 2d 3e 77 72 69 74 65 4c 6f 63 6b   pWal->writeLock
16b20 3d 3d 30 20 29 3b 0a 0a 20 20 2f 2a 20 70 57 61  ==0 );..  /* pWa
16b30 6c 2d 3e 72 65 61 64 4c 6f 63 6b 20 69 73 20 75  l->readLock is u
16b40 73 75 61 6c 6c 79 20 73 65 74 2c 20 62 75 74 20  sually set, but 
16b50 6d 69 67 68 74 20 62 65 20 2d 31 20 69 66 20 74  might be -1 if t
16b60 68 65 72 65 20 77 61 73 20 61 20 0a 20 20 2a 2a  here was a .  **
16b70 20 70 72 69 6f 72 20 65 72 72 6f 72 20 77 68 69   prior error whi
16b80 6c 65 20 61 74 74 65 6d 70 74 69 6e 67 20 74 6f  le attempting to
16b90 20 61 63 71 75 69 72 65 20 61 72 65 20 72 65 61   acquire are rea
16ba0 64 2d 6c 6f 63 6b 2e 20 54 68 69 73 20 63 61 6e  d-lock. This can
16bb0 6e 6f 74 20 0a 20 20 2a 2a 20 68 61 70 70 65 6e  not .  ** happen
16bc0 20 69 66 20 74 68 65 20 63 6f 6e 6e 65 63 74 69   if the connecti
16bd0 6f 6e 20 69 73 20 61 63 74 75 61 6c 6c 79 20 69  on is actually i
16be0 6e 20 65 78 63 6c 75 73 69 76 65 20 6d 6f 64 65  n exclusive mode
16bf0 20 28 61 73 20 6e 6f 20 78 53 68 6d 4c 6f 63 6b   (as no xShmLock
16c00 0a 20 20 2a 2a 20 6c 6f 63 6b 73 20 61 72 65 20  .  ** locks are 
16c10 74 61 6b 65 6e 20 69 6e 20 74 68 69 73 20 63 61  taken in this ca
16c20 73 65 29 2e 20 4e 6f 72 20 73 68 6f 75 6c 64 20  se). Nor should 
16c30 74 68 65 20 70 61 67 65 72 20 61 74 74 65 6d 70  the pager attemp
16c40 74 20 74 6f 0a 20 20 2a 2a 20 75 70 67 72 61 64  t to.  ** upgrad
16c50 65 20 74 6f 20 65 78 63 6c 75 73 69 76 65 2d 6d  e to exclusive-m
16c60 6f 64 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 75  ode following su
16c70 63 68 20 61 6e 20 65 72 72 6f 72 2e 0a 20 20 2a  ch an error..  *
16c80 2f 0a 20 20 61 73 73 65 72 74 28 20 70 57 61 6c  /.  assert( pWal
16c90 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 7c 7c  ->readLock>=0 ||
16ca0 20 70 57 61 6c 2d 3e 6c 6f 63 6b 45 72 72 6f 72   pWal->lockError
16cb0 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 57   );.  assert( pW
16cc0 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20  al->readLock>=0 
16cd0 7c 7c 20 28 6f 70 3c 3d 30 20 26 26 20 70 57 61  || (op<=0 && pWa
16ce0 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
16cf0 3d 3d 30 29 20 29 3b 0a 0a 20 20 69 66 28 20 6f  ==0) );..  if( o
16d00 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20  p==0 ){.    if( 
16d10 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
16d20 6f 64 65 20 29 7b 0a 20 20 20 20 20 20 70 57 61  ode ){.      pWa
16d30 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d 6f 64 65  l->exclusiveMode
16d40 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20   = 0;.      if( 
16d50 77 61 6c 4c 6f 63 6b 53 68 61 72 65 64 28 70 57  walLockShared(pW
16d60 61 6c 2c 20 57 41 4c 5f 52 45 41 44 5f 4c 4f 43  al, WAL_READ_LOC
16d70 4b 28 70 57 61 6c 2d 3e 72 65 61 64 4c 6f 63 6b  K(pWal->readLock
16d80 29 29 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  ))!=SQLITE_OK ){
16d90 0a 20 20 20 20 20 20 20 20 70 57 61 6c 2d 3e 65  .        pWal->e
16da0 78 63 6c 75 73 69 76 65 4d 6f 64 65 20 3d 20 31  xclusiveMode = 1
16db0 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
16dc0 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63 6c 75  rc = pWal->exclu
16dd0 73 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20 20 20  siveMode==0;.   
16de0 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 2f 2a   }else{.      /*
16df0 20 41 6c 72 65 61 64 79 20 69 6e 20 6c 6f 63 6b   Already in lock
16e00 69 6e 67 5f 6d 6f 64 65 3d 4e 4f 52 4d 41 4c 20  ing_mode=NORMAL 
16e10 2a 2f 0a 20 20 20 20 20 20 72 63 20 3d 20 30 3b  */.      rc = 0;
16e20 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65 20 69  .    }.  }else i
16e30 66 28 20 6f 70 3e 30 20 29 7b 0a 20 20 20 20 61  f( op>0 ){.    a
16e40 73 73 65 72 74 28 20 70 57 61 6c 2d 3e 65 78 63  ssert( pWal->exc
16e50 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 20 29 3b  lusiveMode==0 );
16e60 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 57 61  .    assert( pWa
16e70 6c 2d 3e 72 65 61 64 4c 6f 63 6b 3e 3d 30 20 29  l->readLock>=0 )
16e80 3b 0a 20 20 20 20 77 61 6c 55 6e 6c 6f 63 6b 53  ;.    walUnlockS
16e90 68 61 72 65 64 28 70 57 61 6c 2c 20 57 41 4c 5f  hared(pWal, WAL_
16ea0 52 45 41 44 5f 4c 4f 43 4b 28 70 57 61 6c 2d 3e  READ_LOCK(pWal->
16eb0 72 65 61 64 4c 6f 63 6b 29 29 3b 0a 20 20 20 20  readLock));.    
16ec0 70 57 61 6c 2d 3e 65 78 63 6c 75 73 69 76 65 4d  pWal->exclusiveM
16ed0 6f 64 65 20 3d 20 31 3b 0a 20 20 20 20 72 63 20  ode = 1;.    rc 
16ee0 3d 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  = 1;.  }else{.  
16ef0 20 20 72 63 20 3d 20 70 57 61 6c 2d 3e 65 78 63    rc = pWal->exc
16f00 6c 75 73 69 76 65 4d 6f 64 65 3d 3d 30 3b 0a 20  lusiveMode==0;. 
16f10 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
16f20 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 23 69 66  }..#endif /* #if
16f30 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
16f40 5f 57 41 4c 20 2a 2f 0a                          _WAL */.