/ Hex Artifact Content
Login

Artifact a8bf334532109bba05b09a504ee45fc393828b0d034ca61ab45e3940709d9a7c:


0000: 2f 2a 0a 2a 2a 20 32 30 31 31 2d 30 38 2d 31 33  /*.** 2011-08-13
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
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 0a  ***************.
0170: 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 20  **.** This file 
0180: 63 6f 6e 74 61 69 6e 73 20 74 68 65 20 69 6d 70  contains the imp
0190: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 4c  lementation of L
01a0: 53 4d 20 64 61 74 61 62 61 73 65 20 6c 6f 67 67  SM database logg
01b0: 69 6e 67 2e 20 4c 6f 67 67 69 6e 67 0a 2a 2a 20  ing. Logging.** 
01c0: 68 61 73 20 6f 6e 65 20 70 75 72 70 6f 73 65 20  has one purpose 
01d0: 69 6e 20 4c 53 4d 20 2d 20 74 6f 20 6d 61 6b 65  in LSM - to make
01e0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 20 64 75   transactions du
01f0: 72 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 57 68 65  rable..**.** Whe
0200: 6e 20 64 61 74 61 20 69 73 20 77 72 69 74 74 65  n data is writte
0210: 6e 20 74 6f 20 61 6e 20 4c 53 4d 20 64 61 74 61  n to an LSM data
0220: 62 61 73 65 2c 20 69 74 20 69 73 20 69 6e 69 74  base, it is init
0230: 69 61 6c 6c 79 20 73 74 6f 72 65 64 20 69 6e 20  ially stored in 
0240: 61 6e 0a 2a 2a 20 69 6e 2d 6d 65 6d 6f 72 79 20  an.** in-memory 
0250: 74 72 65 65 20 73 74 72 75 63 74 75 72 65 2e 20  tree structure. 
0260: 53 69 6e 63 65 20 74 68 69 73 20 73 74 72 75 63  Since this struc
0270: 74 75 72 65 20 69 73 20 69 6e 20 76 6f 6c 61 74  ture is in volat
0280: 69 6c 65 20 6d 65 6d 6f 72 79 2c 0a 2a 2a 20 69  ile memory,.** i
0290: 66 20 61 20 70 6f 77 65 72 20 66 61 69 6c 75 72  f a power failur
02a0: 65 20 6f 72 20 61 70 70 6c 69 63 61 74 69 6f 6e  e or application
02b0: 20 63 72 61 73 68 20 6f 63 63 75 72 73 20 69 74   crash occurs it
02c0: 20 6d 61 79 20 62 65 20 6c 6f 73 74 2e 20 54 6f   may be lost. To
02d0: 0a 2a 2a 20 70 72 65 76 65 6e 74 20 6c 6f 73 73  .** prevent loss
02e0: 20 6f 66 20 64 61 74 61 20 69 6e 20 74 68 69 73   of data in this
02f0: 20 63 61 73 65 2c 20 65 61 63 68 20 74 69 6d 65   case, each time
0300: 20 61 20 72 65 63 6f 72 64 20 69 73 20 77 72 69   a record is wri
0310: 74 74 65 6e 20 74 6f 20 74 68 65 0a 2a 2a 20 69  tten to the.** i
0320: 6e 2d 6d 65 6d 6f 72 79 20 74 72 65 65 20 61 6e  n-memory tree an
0330: 20 65 71 75 69 76 61 6c 65 6e 74 20 72 65 63 6f   equivalent reco
0340: 72 64 20 69 73 20 61 70 70 65 6e 64 65 64 20 74  rd is appended t
0350: 6f 20 74 68 65 20 6c 6f 67 20 6f 6e 20 64 69 73  o the log on dis
0360: 6b 2e 0a 2a 2a 20 49 66 20 61 20 70 6f 77 65 72  k..** If a power
0370: 20 66 61 69 6c 75 72 65 20 6f 72 20 61 70 70 6c   failure or appl
0380: 69 63 61 74 69 6f 6e 20 63 72 61 73 68 20 64 6f  ication crash do
0390: 65 73 20 6f 63 63 75 72 2c 20 64 61 74 61 20 63  es occur, data c
03a0: 61 6e 20 62 65 20 72 65 63 6f 76 65 72 65 64 0a  an be recovered.
03b0: 2a 2a 20 62 79 20 72 65 61 64 69 6e 67 20 74 68  ** by reading th
03c0: 65 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a 20 41 20 6c  e log..**.** A l
03d0: 6f 67 20 66 69 6c 65 20 63 6f 6e 73 69 73 74 73  og file consists
03e0: 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e   of the followin
03f0: 67 20 74 79 70 65 73 20 6f 66 20 72 65 63 6f 72  g types of recor
0400: 64 73 20 72 65 70 72 65 73 65 6e 74 69 6e 67 20  ds representing 
0410: 64 61 74 61 0a 2a 2a 20 77 72 69 74 74 65 6e 20  data.** written 
0420: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
0430: 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 4c 4f 47 5f 57  e:.**.**   LOG_W
0440: 52 49 54 45 3a 20 20 41 20 6b 65 79 2d 76 61 6c  RITE:  A key-val
0450: 75 65 20 70 61 69 72 20 77 72 69 74 74 65 6e 20  ue pair written 
0460: 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 2e  to the database.
0470: 0a 2a 2a 20 20 20 4c 4f 47 5f 44 45 4c 45 54 45  .**   LOG_DELETE
0480: 3a 20 41 20 64 65 6c 65 74 65 20 6b 65 79 20 69  : A delete key i
0490: 73 73 75 65 64 20 74 6f 20 74 68 65 20 64 61 74  ssued to the dat
04a0: 61 62 61 73 65 2e 0a 2a 2a 20 20 20 4c 4f 47 5f  abase..**   LOG_
04b0: 43 4f 4d 4d 49 54 3a 20 41 20 74 72 61 6e 73 61  COMMIT: A transa
04c0: 63 74 69 6f 6e 20 63 6f 6d 6d 69 74 2e 0a 2a 2a  ction commit..**
04d0: 0a 2a 2a 20 41 6e 64 20 74 68 65 20 66 6f 6c 6c  .** And the foll
04e0: 6f 77 69 6e 67 20 74 79 70 65 73 20 6f 66 20 72  owing types of r
04f0: 65 63 6f 72 64 73 20 66 6f 72 20 61 6e 63 69 6c  ecords for ancil
0500: 6c 61 72 79 20 70 75 72 70 6f 73 65 73 2e 2e 0a  lary purposes...
0510: 2a 2a 0a 2a 2a 20 20 20 4c 4f 47 5f 45 4f 46 3a  **.**   LOG_EOF:
0520: 20 20 20 20 41 20 72 65 63 6f 72 64 20 69 6e 64      A record ind
0530: 69 63 61 74 69 6e 67 20 74 68 65 20 65 6e 64 20  icating the end 
0540: 6f 66 20 61 20 6c 6f 67 20 66 69 6c 65 2e 0a 2a  of a log file..*
0550: 2a 20 20 20 4c 4f 47 5f 50 41 44 31 3a 20 20 20  *   LOG_PAD1:   
0560: 41 20 73 69 6e 67 6c 65 20 62 79 74 65 20 70 61  A single byte pa
0570: 64 64 69 6e 67 20 72 65 63 6f 72 64 2e 0a 2a 2a  dding record..**
0580: 20 20 20 4c 4f 47 5f 50 41 44 32 3a 20 20 20 41     LOG_PAD2:   A
0590: 6e 20 4e 20 62 79 74 65 20 70 61 64 64 69 6e 67  n N byte padding
05a0: 20 72 65 63 6f 72 64 20 28 4e 3e 31 29 2e 0a 2a   record (N>1)..*
05b0: 2a 20 20 20 4c 4f 47 5f 4a 55 4d 50 3a 20 20 20  *   LOG_JUMP:   
05c0: 41 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 6e 6f  A pointer to ano
05d0: 74 68 65 72 20 6f 66 66 73 65 74 20 77 69 74 68  ther offset with
05e0: 69 6e 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2e  in the log file.
05f0: 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 74 72 61 6e  .**.** Each tran
0600: 73 61 63 74 69 6f 6e 20 77 72 69 74 74 65 6e 20  saction written 
0610: 74 6f 20 74 68 65 20 6c 6f 67 20 63 6f 6e 74 61  to the log conta
0620: 69 6e 73 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20  ins one or more 
0630: 4c 4f 47 5f 57 52 49 54 45 20 61 6e 64 2f 6f 72  LOG_WRITE and/or
0640: 0a 2a 2a 20 4c 4f 47 5f 44 45 4c 45 54 45 20 72  .** LOG_DELETE r
0650: 65 63 6f 72 64 73 2c 20 66 6f 6c 6c 6f 77 65 64  ecords, followed
0660: 20 62 79 20 61 20 4c 4f 47 5f 43 4f 4d 4d 49 54   by a LOG_COMMIT
0670: 20 72 65 63 6f 72 64 2e 20 54 68 65 20 4c 4f 47   record. The LOG
0680: 5f 43 4f 4d 4d 49 54 20 72 65 63 6f 72 64 0a 2a  _COMMIT record.*
0690: 2a 20 63 6f 6e 74 61 69 6e 73 20 61 6e 20 38 2d  * contains an 8-
06a0: 62 79 74 65 20 63 68 65 63 6b 73 75 6d 20 62 61  byte checksum ba
06b0: 73 65 64 20 6f 6e 20 61 6c 6c 20 70 72 65 76 69  sed on all previ
06c0: 6f 75 73 20 64 61 74 61 20 77 72 69 74 74 65 6e  ous data written
06d0: 20 74 6f 20 74 68 65 0a 2a 2a 20 6c 6f 67 20 66   to the.** log f
06e0: 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 4c 4f 47 20 43  ile..**.** LOG C
06f0: 48 45 43 4b 53 55 4d 53 20 26 20 52 45 43 4f 56  HECKSUMS & RECOV
0700: 45 52 59 0a 2a 2a 0a 2a 2a 20 20 20 43 68 65 63  ERY.**.**   Chec
0710: 6b 73 75 6d 73 20 61 72 65 20 66 6f 75 6e 64 20  ksums are found 
0720: 69 6e 20 74 77 6f 20 74 79 70 65 73 20 6f 66 20  in two types of 
0730: 6c 6f 67 20 72 65 63 6f 72 64 73 3a 20 4c 4f 47  log records: LOG
0740: 5f 43 4f 4d 4d 49 54 20 61 6e 64 0a 2a 2a 20 20  _COMMIT and.**  
0750: 20 4c 4f 47 5f 43 4b 53 55 4d 20 72 65 63 6f 72   LOG_CKSUM recor
0760: 64 73 2e 20 49 6e 20 6f 72 64 65 72 20 74 6f 20  ds. In order to 
0770: 72 65 63 6f 76 65 72 20 63 6f 6e 74 65 6e 74 20  recover content 
0780: 66 72 6f 6d 20 61 20 6c 6f 67 2c 20 61 20 63 6c  from a log, a cl
0790: 69 65 6e 74 0a 2a 2a 20 20 20 72 65 61 64 73 20  ient.**   reads 
07a0: 65 61 63 68 20 72 65 63 6f 72 64 20 66 72 6f 6d  each record from
07b0: 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68   the start of th
07c0: 65 20 6c 6f 67 2c 20 63 61 6c 63 75 6c 61 74 69  e log, calculati
07d0: 6e 67 20 61 20 63 68 65 63 6b 73 75 6d 20 61 73  ng a checksum as
07e0: 0a 2a 2a 20 20 20 69 74 20 64 6f 65 73 2e 20 45  .**   it does. E
07f0: 61 63 68 20 74 69 6d 65 20 61 20 4c 4f 47 5f 43  ach time a LOG_C
0800: 4f 4d 4d 49 54 20 6f 72 20 4c 4f 47 5f 43 4b 53  OMMIT or LOG_CKS
0810: 55 4d 20 69 73 20 65 6e 63 6f 75 6e 74 65 72 65  UM is encountere
0820: 64 2c 20 74 68 65 20 0a 2a 2a 20 20 20 72 65 63  d, the .**   rec
0830: 6f 76 65 72 79 20 70 72 6f 63 65 73 73 20 76 65  overy process ve
0840: 72 69 66 69 65 73 20 74 68 61 74 20 74 68 65 20  rifies that the 
0850: 63 68 65 63 6b 73 75 6d 20 73 74 6f 72 65 64 20  checksum stored 
0860: 69 6e 20 74 68 65 20 6c 6f 67 20 0a 2a 2a 20 20  in the log .**  
0870: 20 6d 61 74 63 68 65 73 20 74 68 65 20 63 61 6c   matches the cal
0880: 63 75 6c 61 74 65 64 20 63 68 65 63 6b 73 75 6d  culated checksum
0890: 2e 20 49 66 20 69 74 20 64 6f 65 73 20 6e 6f 74  . If it does not
08a0: 2c 20 74 68 65 20 72 65 63 6f 76 65 72 79 20 70  , the recovery p
08b0: 72 6f 63 65 73 73 0a 2a 2a 20 20 20 63 61 6e 20  rocess.**   can 
08c0: 73 74 6f 70 20 72 65 61 64 69 6e 67 20 74 68 65  stop reading the
08d0: 20 6c 6f 67 2e 0a 2a 2a 0a 2a 2a 20 20 20 49 66   log..**.**   If
08e0: 20 61 20 72 65 63 6f 76 65 72 79 20 70 72 6f 63   a recovery proc
08f0: 65 73 73 20 72 65 61 64 73 20 72 65 63 6f 72 64  ess reads record
0900: 73 20 28 6f 74 68 65 72 20 74 68 61 6e 20 43 4f  s (other than CO
0910: 4d 4d 49 54 20 6f 72 20 43 4b 53 55 4d 29 20 0a  MMIT or CKSUM) .
0920: 2a 2a 20 20 20 63 6f 6e 73 69 73 74 69 6e 67 20  **   consisting 
0930: 6f 66 20 61 74 20 6c 65 61 73 74 20 4c 53 4d 5f  of at least LSM_
0940: 43 4b 53 55 4d 5f 4d 41 58 44 41 54 41 20 62 79  CKSUM_MAXDATA by
0950: 74 65 73 2c 20 74 68 65 6e 20 74 68 65 20 6e 65  tes, then the ne
0960: 78 74 20 72 65 63 6f 72 64 20 69 6e 0a 2a 2a 20  xt record in.** 
0970: 20 20 74 68 65 20 6c 6f 67 20 6d 75 73 74 20 62    the log must b
0980: 65 20 65 69 74 68 65 72 20 61 20 4c 4f 47 5f 43  e either a LOG_C
0990: 4b 53 55 4d 20 6f 72 20 4c 4f 47 5f 43 4f 4d 4d  KSUM or LOG_COMM
09a0: 49 54 20 72 65 63 6f 72 64 2e 20 49 66 20 69 74  IT record. If it
09b0: 20 69 73 0a 2a 2a 20 20 20 6e 6f 74 2c 20 74 68   is.**   not, th
09c0: 65 20 72 65 63 6f 76 65 72 79 20 70 72 6f 63 65  e recovery proce
09d0: 73 73 20 61 6c 73 6f 20 73 74 6f 70 73 20 72 65  ss also stops re
09e0: 61 64 69 6e 67 20 74 68 65 20 6c 6f 67 2e 0a 2a  ading the log..*
09f0: 2a 0a 2a 2a 20 20 20 54 6f 20 72 65 63 6f 76 65  *.**   To recove
0a00: 72 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 2c 20  r the log file, 
0a10: 69 74 20 6d 75 73 74 20 62 65 20 72 65 61 64 20  it must be read 
0a20: 74 77 69 63 65 2e 20 54 68 65 20 66 69 72 73 74  twice. The first
0a30: 20 74 69 6d 65 20 74 6f 20 0a 2a 2a 20 20 20 64   time to .**   d
0a40: 65 74 65 72 6d 69 6e 65 20 74 68 65 20 6c 6f 63  etermine the loc
0a50: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 6c 61 73  ation of the las
0a60: 74 20 76 61 6c 69 64 20 63 6f 6d 6d 69 74 20 72  t valid commit r
0a70: 65 63 6f 72 64 2e 20 41 6e 64 20 74 68 65 20 73  ecord. And the s
0a80: 65 63 6f 6e 64 0a 2a 2a 20 20 20 74 69 6d 65 20  econd.**   time 
0a90: 74 6f 20 6c 6f 61 64 20 64 61 74 61 20 69 6e 74  to load data int
0aa0: 6f 20 74 68 65 20 69 6e 2d 6d 65 6d 6f 72 79 20  o the in-memory 
0ab0: 74 72 65 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 54 6f  tree..**.**   To
0ac0: 64 6f 3a 20 53 75 72 65 6c 79 20 74 68 65 72 65  do: Surely there
0ad0: 20 69 73 20 61 20 62 65 74 74 65 72 20 77 61 79   is a better way
0ae0: 2e 2e 2e 0a 2a 2a 0a 2a 2a 20 4c 4f 47 20 57 52  ....**.** LOG WR
0af0: 41 50 50 49 4e 47 0a 2a 2a 0a 2a 2a 20 20 20 49  APPING.**.**   I
0b00: 66 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 77  f the log file w
0b10: 65 72 65 20 6e 65 76 65 72 20 64 65 6c 65 74 65  ere never delete
0b20: 64 20 6f 72 20 77 72 61 70 70 65 64 2c 20 69 74  d or wrapped, it
0b30: 20 77 6f 75 6c 64 20 62 65 20 70 6f 73 73 69 62   would be possib
0b40: 6c 65 20 74 6f 0a 2a 2a 20 20 20 72 65 61 64 20  le to.**   read 
0b50: 69 74 20 66 72 6f 6d 20 73 74 61 72 74 20 74 6f  it from start to
0b60: 20 65 6e 64 20 65 61 63 68 20 74 69 6d 65 20 69   end each time i
0b70: 73 20 72 65 71 75 69 72 65 64 20 72 65 63 6f 76  s required recov
0b80: 65 72 79 20 28 69 2e 65 20 65 61 63 68 20 74 69  ery (i.e each ti
0b90: 6d 65 0a 2a 2a 20 20 20 74 68 65 20 6e 75 6d 62  me.**   the numb
0ba0: 65 72 20 6f 66 20 64 61 74 61 62 61 73 65 20 63  er of database c
0bb0: 6c 69 65 6e 74 73 20 63 68 61 6e 67 65 73 20 66  lients changes f
0bc0: 72 6f 6d 20 30 20 74 6f 20 31 29 2e 20 45 66 66  rom 0 to 1). Eff
0bd0: 65 63 74 69 76 65 6c 79 20 72 65 61 64 69 6e 67  ectively reading
0be0: 0a 2a 2a 20 20 20 74 68 65 20 65 6e 74 69 72 65  .**   the entire
0bf0: 20 68 69 73 74 6f 72 79 20 6f 66 20 74 68 65 20   history of the 
0c00: 64 61 74 61 62 61 73 65 20 65 61 63 68 20 74 69  database each ti
0c10: 6d 65 2e 20 54 68 69 73 20 77 6f 75 6c 64 20 71  me. This would q
0c20: 75 69 63 6b 6c 79 20 62 65 63 6f 6d 65 20 0a 2a  uickly become .*
0c30: 2a 20 20 20 69 6e 65 66 66 69 63 69 65 6e 74 2e  *   inefficient.
0c40: 20 41 64 64 69 74 69 6f 6e 61 6c 6c 79 2c 20 73   Additionally, s
0c50: 69 6e 63 65 20 74 68 65 20 6c 6f 67 20 66 69 6c  ince the log fil
0c60: 65 20 77 6f 75 6c 64 20 67 72 6f 77 20 77 69 74  e would grow wit
0c70: 68 6f 75 74 20 62 6f 75 6e 64 2c 0a 2a 2a 20 20  hout bound,.**  
0c80: 20 69 74 20 77 61 73 74 65 73 20 73 74 6f 72 61   it wastes stora
0c90: 67 65 20 73 70 61 63 65 2e 0a 2a 2a 0a 2a 2a 20  ge space..**.** 
0ca0: 20 20 49 6e 73 74 65 61 64 2c 20 70 61 72 74 20    Instead, part 
0cb0: 6f 66 20 65 61 63 68 20 63 68 65 63 6b 70 6f 69  of each checkpoi
0cc0: 6e 74 20 77 72 69 74 74 65 6e 20 69 6e 74 6f 20  nt written into 
0cd0: 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  the database fil
0ce0: 65 20 63 6f 6e 74 61 69 6e 73 20 0a 2a 2a 20 20  e contains .**  
0cf0: 20 61 20 6c 6f 67 20 6f 66 66 73 65 74 20 28 61   a log offset (a
0d00: 6e 64 20 6f 74 68 65 72 20 69 6e 66 6f 72 6d 61  nd other informa
0d10: 74 69 6f 6e 20 72 65 71 75 69 72 65 64 20 74 6f  tion required to
0d20: 20 72 65 61 64 20 74 68 65 20 6c 6f 67 20 73 74   read the log st
0d30: 61 72 74 69 6e 67 20 61 74 0a 2a 2a 20 20 20 61  arting at.**   a
0d40: 74 20 74 68 69 73 20 6f 66 66 73 65 74 29 20 61  t this offset) a
0d50: 74 20 77 68 69 63 68 20 74 6f 20 62 65 67 69 6e  t which to begin
0d60: 20 72 65 63 6f 76 65 72 79 2e 20 4f 66 66 73 65   recovery. Offse
0d70: 74 20 24 4f 2e 0a 2a 2a 0a 2a 2a 20 20 20 4f 6e  t $O..**.**   On
0d80: 63 65 20 61 20 63 68 65 63 6b 70 6f 69 6e 74 20  ce a checkpoint 
0d90: 68 61 73 20 62 65 65 6e 20 77 72 69 74 74 65 6e  has been written
0da0: 20 61 6e 64 20 73 79 6e 63 65 64 20 69 6e 74 6f   and synced into
0db0: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
0dc0: 6c 65 2c 20 69 74 0a 2a 2a 20 20 20 69 73 20 67  le, it.**   is g
0dd0: 75 61 72 61 6e 74 65 65 64 20 74 68 61 74 20 6e  uaranteed that n
0de0: 6f 20 72 65 63 6f 76 65 72 79 20 70 72 6f 63 65  o recovery proce
0df0: 73 73 20 77 69 6c 6c 20 6e 65 65 64 20 74 6f 20  ss will need to 
0e00: 72 65 61 64 20 61 6e 79 20 64 61 74 61 20 62 65  read any data be
0e10: 66 6f 72 65 0a 2a 2a 20 20 20 6f 66 66 73 65 74  fore.**   offset
0e20: 20 24 4f 20 6f 66 20 74 68 65 20 6c 6f 67 20 66   $O of the log f
0e30: 69 6c 65 2e 20 49 74 20 69 73 20 74 68 65 72 65  ile. It is there
0e40: 66 6f 72 65 20 73 61 66 65 20 74 6f 20 62 65 67  fore safe to beg
0e50: 69 6e 20 6f 76 65 72 77 72 69 74 69 6e 67 0a 2a  in overwriting.*
0e60: 2a 20 20 20 61 6e 79 20 64 61 74 61 20 74 68 61  *   any data tha
0e70: 74 20 6f 63 63 75 72 73 20 62 65 66 6f 72 65 20  t occurs before 
0e80: 6f 66 66 73 65 74 20 24 4f 2e 0a 2a 2a 0a 2a 2a  offset $O..**.**
0e90: 20 20 20 54 68 69 73 20 69 6d 70 6c 65 6d 65 6e     This implemen
0ea0: 74 61 74 69 6f 6e 20 73 65 70 61 72 61 74 65 73  tation separates
0eb0: 20 74 68 65 20 6c 6f 67 20 69 6e 74 6f 20 74 68   the log into th
0ec0: 72 65 65 20 72 65 67 69 6f 6e 73 20 6d 61 70 70  ree regions mapp
0ed0: 65 64 20 69 6e 74 6f 0a 2a 2a 20 20 20 74 68 65  ed into.**   the
0ee0: 20 6c 6f 67 20 66 69 6c 65 20 2d 20 72 65 67 69   log file - regi
0ef0: 6f 6e 73 20 30 2c 20 31 20 61 6e 64 20 32 2e 20  ons 0, 1 and 2. 
0f00: 44 75 72 69 6e 67 20 72 65 63 6f 76 65 72 79 2c  During recovery,
0f10: 20 72 65 67 69 6f 6e 73 20 61 72 65 20 72 65 61   regions are rea
0f20: 64 0a 2a 2a 20 20 20 69 6e 20 61 73 63 65 6e 64  d.**   in ascend
0f30: 69 6e 67 20 6f 72 64 65 72 20 28 69 2e 65 2e 20  ing order (i.e. 
0f40: 30 2c 20 74 68 65 6e 20 31 2c 20 74 68 65 6e 20  0, then 1, then 
0f50: 32 29 2e 20 45 61 63 68 20 72 65 67 69 6f 6e 20  2). Each region 
0f60: 69 73 20 7a 65 72 6f 20 6f 72 0a 2a 2a 20 20 20  is zero or.**   
0f70: 6d 6f 72 65 20 62 79 74 65 73 20 69 6e 20 73 69  more bytes in si
0f80: 7a 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 7c 2d  ze..**.**     |-
0f90: 2d 2d 31 2d 2d 2d 7c 2e 2e 7c 2d 2d 30 2d 2d 7c  --1---|..|--0--|
0fa0: 2e 7c 2d 2d 32 2d 2d 7c 2e 2e 2e 2e 0a 2a 2a 0a  .|--2--|.....**.
0fb0: 2a 2a 20 20 20 4e 65 77 20 72 65 63 6f 72 64 73  **   New records
0fc0: 20 61 72 65 20 61 6c 77 61 79 73 20 61 70 70 65   are always appe
0fd0: 6e 64 65 64 20 74 6f 20 74 68 65 20 65 6e 64 20  nded to the end 
0fe0: 6f 66 20 72 65 67 69 6f 6e 20 32 2e 0a 2a 2a 0a  of region 2..**.
0ff0: 2a 2a 20 20 20 49 6e 69 74 69 61 6c 6c 79 20 28  **   Initially (
1000: 77 68 65 6e 20 69 74 20 69 73 20 65 6d 70 74 79  when it is empty
1010: 29 2c 20 61 6c 6c 20 74 68 72 65 65 20 72 65 67  ), all three reg
1020: 69 6f 6e 73 20 61 72 65 20 7a 65 72 6f 20 62 79  ions are zero by
1030: 74 65 73 20 69 6e 20 73 69 7a 65 2e 0a 2a 2a 20  tes in size..** 
1040: 20 20 45 61 63 68 20 6f 66 20 74 68 65 6d 20 61    Each of them a
1050: 72 65 20 6c 6f 63 61 74 65 64 20 61 74 20 74 68  re located at th
1060: 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74  e beginning of t
1070: 68 65 20 66 69 6c 65 2e 20 41 73 20 72 65 63 6f  he file. As reco
1080: 72 64 73 20 61 72 65 0a 2a 2a 20 20 20 61 64 64  rds are.**   add
1090: 65 64 20 74 6f 20 74 68 65 20 6c 6f 67 2c 20 72  ed to the log, r
10a0: 65 67 69 6f 6e 20 32 20 67 72 6f 77 73 2c 20 73  egion 2 grows, s
10b0: 6f 20 74 68 61 74 20 74 68 65 20 6c 6f 67 20 63  o that the log c
10c0: 6f 6e 73 69 73 74 73 20 6f 66 20 61 20 7a 65 72  onsists of a zer
10d0: 6f 0a 2a 2a 20 20 20 62 79 74 65 20 72 65 67 69  o.**   byte regi
10e0: 6f 6e 20 31 2c 20 66 6f 6c 6c 6f 77 65 64 20 62  on 1, followed b
10f0: 79 20 61 20 7a 65 72 6f 20 62 79 74 65 20 72 65  y a zero byte re
1100: 67 69 6f 6e 20 30 2c 20 66 6f 6c 6c 6f 77 65 64  gion 0, followed
1110: 20 62 79 20 61 6e 20 4e 20 62 79 74 65 0a 2a 2a   by an N byte.**
1120: 20 20 20 72 65 67 69 6f 6e 20 32 2e 20 41 66 74     region 2. Aft
1130: 65 72 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 63  er one or more c
1140: 68 65 63 6b 70 6f 69 6e 74 73 20 68 61 76 65 20  heckpoints have 
1150: 62 65 65 6e 20 77 72 69 74 74 65 6e 20 74 6f 20  been written to 
1160: 64 69 73 6b 2c 20 0a 2a 2a 20 20 20 74 68 65 20  disk, .**   the 
1170: 73 74 61 72 74 20 70 6f 69 6e 74 20 6f 66 20 72  start point of r
1180: 65 67 69 6f 6e 20 32 20 69 73 20 6d 6f 76 65 64  egion 2 is moved
1190: 20 74 6f 20 24 4f 2e 20 46 6f 72 20 65 78 61 6d   to $O. For exam
11a0: 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 41  ple:.**.**     A
11b0: 29 20 7c 7c 2e 2e 2e 2e 2e 2e 2e 2e 2e 7c 2d 2d  ) ||.........|--
11c0: 32 2d 2d 7c 2e 2e 2e 2e 0a 2a 2a 20 20 20 0a 2a  2--|.....**   .*
11d0: 2a 20 20 20 28 62 6f 74 68 20 72 65 67 69 6f 6e  *   (both region
11e0: 73 20 30 20 61 6e 64 20 31 20 61 72 65 20 30 20  s 0 and 1 are 0 
11f0: 62 79 74 65 73 20 69 6e 20 73 69 7a 65 20 61 74  bytes in size at
1200: 20 6f 66 66 73 65 74 20 30 29 2e 0a 2a 2a 0a 2a   offset 0)..**.*
1210: 2a 20 20 20 45 76 65 6e 74 75 61 6c 6c 79 2c 20  *   Eventually, 
1220: 74 68 65 20 6c 6f 67 20 77 72 61 70 73 20 61 72  the log wraps ar
1230: 6f 75 6e 64 20 74 6f 20 77 72 69 74 65 20 6e 65  ound to write ne
1240: 77 20 72 65 63 6f 72 64 73 20 69 6e 74 6f 20 74  w records into t
1250: 68 65 20 73 74 61 72 74 2e 0a 2a 2a 20 20 20 41  he start..**   A
1260: 74 20 74 68 69 73 20 70 6f 69 6e 74 2c 20 72 65  t this point, re
1270: 67 69 6f 6e 20 32 20 69 73 20 72 65 6e 61 6d 65  gion 2 is rename
1280: 64 20 74 6f 20 72 65 67 69 6f 6e 20 30 2e 20 52  d to region 0. R
1290: 65 67 69 6f 6e 20 30 20 69 73 20 72 65 6e 61 6d  egion 0 is renam
12a0: 65 64 0a 2a 2a 20 20 20 74 6f 20 72 65 67 69 6f  ed.**   to regio
12b0: 6e 20 32 2e 20 41 66 74 65 72 20 61 70 70 65 6e  n 2. After appen
12c0: 64 69 6e 67 20 61 20 66 65 77 20 72 65 63 6f 72  ding a few recor
12d0: 64 73 20 74 6f 20 74 68 65 20 6e 65 77 20 72 65  ds to the new re
12e0: 67 69 6f 6e 20 32 2c 20 74 68 65 0a 2a 2a 20 20  gion 2, the.**  
12f0: 20 6c 6f 67 20 66 69 6c 65 20 6c 6f 6f 6b 73 20   log file looks 
1300: 6c 69 6b 65 20 74 68 69 73 3a 0a 2a 2a 0a 2a 2a  like this:.**.**
1310: 20 20 20 20 20 42 29 20 7c 7c 2d 2d 32 2d 2d 7c       B) ||--2--|
1320: 2e 2e 2e 7c 2d 2d 30 2d 2d 7c 2e 2e 2e 2e 0a 2a  ...|--0--|.....*
1330: 2a 0a 2a 2a 20 20 20 28 72 65 67 69 6f 6e 20 31  *.**   (region 1
1340: 20 69 73 20 73 74 69 6c 6c 20 30 20 62 79 74 65   is still 0 byte
1350: 73 20 69 6e 20 73 69 7a 65 2c 20 6c 6f 63 61 74  s in size, locat
1360: 65 64 20 61 74 20 6f 66 66 73 65 74 20 30 29 2e  ed at offset 0).
1370: 0a 2a 2a 0a 2a 2a 20 20 20 41 6e 79 20 63 68 65  .**.**   Any che
1380: 63 6b 70 6f 69 6e 74 73 20 6d 61 64 65 20 61 74  ckpoints made at
1390: 20 74 68 69 73 20 70 6f 69 6e 74 20 6d 61 79 20   this point may 
13a0: 72 65 64 75 63 65 20 74 68 65 20 73 69 7a 65 20  reduce the size 
13b0: 6f 66 20 72 65 67 69 6f 6e 20 30 2e 0a 2a 2a 20  of region 0..** 
13c0: 20 20 48 6f 77 65 76 65 72 2c 20 69 66 20 74 68    However, if th
13d0: 65 79 20 64 6f 20 6e 6f 74 2c 20 61 6e 64 20 72  ey do not, and r
13e0: 65 67 69 6f 6e 20 32 20 65 78 70 61 6e 64 73 20  egion 2 expands 
13f0: 73 6f 20 74 68 61 74 20 69 74 20 69 73 20 61 62  so that it is ab
1400: 6f 75 74 20 74 6f 0a 2a 2a 20 20 20 6f 76 65 72  out to.**   over
1410: 77 72 69 74 65 20 74 68 65 20 73 74 61 72 74 20  write the start 
1420: 6f 66 20 72 65 67 69 6f 6e 20 30 2c 20 74 68 65  of region 0, the
1430: 6e 20 72 65 67 69 6f 6e 20 32 20 69 73 20 72 65  n region 2 is re
1440: 6e 61 6d 65 64 20 74 6f 20 72 65 67 69 6f 6e 20  named to region 
1450: 31 2c 0a 2a 2a 20 20 20 61 6e 64 20 61 20 6e 65  1,.**   and a ne
1460: 77 20 72 65 67 69 6f 6e 20 32 20 63 72 65 61 74  w region 2 creat
1470: 65 64 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66  ed at the end of
1480: 20 74 68 65 20 66 69 6c 65 20 66 6f 6c 6c 6f 77   the file follow
1490: 69 6e 67 20 74 68 65 20 65 78 69 73 74 69 6e 67  ing the existing
14a0: 0a 2a 2a 20 20 20 72 65 67 69 6f 6e 20 30 2e 0a  .**   region 0..
14b0: 2a 2a 0a 2a 2a 20 20 20 20 20 43 29 20 7c 2d 2d  **.**     C) |--
14c0: 2d 31 2d 2d 2d 7c 2e 2e 7c 2d 2d 30 2d 2d 7c 2e  -1---|..|--0--|.
14d0: 7c 2d 32 2d 7c 0a 2a 2a 0a 2a 2a 20 20 20 49 6e  |-2-|.**.**   In
14e0: 20 74 68 69 73 20 73 74 61 74 65 20 72 65 63 6f   this state reco
14f0: 72 64 73 20 61 72 65 20 61 70 70 65 6e 64 65 64  rds are appended
1500: 20 74 6f 20 72 65 67 69 6f 6e 20 32 20 75 6e 74   to region 2 unt
1510: 69 6c 20 63 68 65 63 6b 70 6f 69 6e 74 73 20 68  il checkpoints h
1520: 61 76 65 0a 2a 2a 20 20 20 63 6f 6e 74 72 61 63  ave.**   contrac
1530: 74 65 64 20 72 65 67 69 6f 6e 73 20 30 20 41 4e  ted regions 0 AN
1540: 44 20 31 20 55 4e 54 69 6c 20 74 68 65 79 20 61  D 1 UNTil they a
1550: 72 65 20 62 6f 74 68 20 7a 65 72 6f 20 62 79 74  re both zero byt
1560: 65 73 20 69 6e 20 73 69 7a 65 2e 20 54 68 65 79  es in size. They
1570: 20 0a 2a 2a 20 20 20 61 72 65 20 74 68 65 6e 20   .**   are then 
1580: 73 68 69 66 74 65 64 20 74 6f 20 74 68 65 20 73  shifted to the s
1590: 74 61 72 74 20 6f 66 20 74 68 65 20 6c 6f 67 20  tart of the log 
15a0: 66 69 6c 65 2c 20 6c 65 61 76 69 6e 67 20 74 68  file, leaving th
15b0: 65 20 73 79 73 74 65 6d 20 69 6e 20 0a 2a 2a 20  e system in .** 
15c0: 20 20 74 68 65 20 65 71 75 69 76 61 6c 65 6e 74    the equivalent
15d0: 20 6f 66 20 73 74 61 74 65 20 41 20 61 62 6f 76   of state A abov
15e0: 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 41 6c 74 65 72  e..**.**   Alter
15f0: 6e 61 74 69 76 65 6c 79 2c 20 73 74 61 74 65 20  natively, state 
1600: 42 20 6d 61 79 20 74 72 61 6e 73 69 74 69 6f 6e  B may transition
1610: 20 64 69 72 65 63 74 6c 79 20 74 6f 20 73 74 61   directly to sta
1620: 74 65 20 41 20 69 66 20 74 68 65 20 73 69 7a 65  te A if the size
1630: 0a 2a 2a 20 20 20 6f 66 20 72 65 67 69 6f 6e 20  .**   of region 
1640: 30 20 69 73 20 72 65 64 75 63 65 64 20 74 6f 20  0 is reduced to 
1650: 7a 65 72 6f 20 62 79 74 65 73 20 62 65 66 6f 72  zero bytes befor
1660: 65 20 72 65 67 69 6f 6e 20 32 20 74 68 72 65 61  e region 2 threa
1670: 74 65 6e 73 20 74 6f 20 0a 2a 2a 20 20 20 65 6e  tens to .**   en
1680: 63 72 6f 61 63 68 20 75 70 6f 6e 20 69 74 2e 0a  croach upon it..
1690: 2a 2a 0a 2a 2a 20 4c 4f 47 5f 50 41 44 31 20 26  **.** LOG_PAD1 &
16a0: 20 4c 4f 47 5f 50 41 44 32 20 52 45 43 4f 52 44   LOG_PAD2 RECORD
16b0: 53 0a 2a 2a 0a 2a 2a 20 20 20 50 41 44 31 20 61  S.**.**   PAD1 a
16c0: 6e 64 20 50 41 44 32 20 72 65 63 6f 72 64 73 20  nd PAD2 records 
16d0: 6d 61 79 20 61 70 70 65 61 72 20 69 6e 20 61 20  may appear in a 
16e0: 6c 6f 67 20 66 69 6c 65 20 61 74 20 61 6e 79 20  log file at any 
16f0: 70 6f 69 6e 74 2e 20 54 68 65 79 20 61 6c 6c 6f  point. They allo
1700: 77 0a 2a 2a 20 20 20 61 20 70 72 6f 63 65 73 73  w.**   a process
1710: 20 77 72 69 74 69 6e 67 20 74 68 65 20 6c 6f 67   writing the log
1720: 20 66 69 6c 65 20 61 6c 69 67 6e 20 74 68 65 20   file align the 
1730: 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 72 61  beginning of tra
1740: 6e 73 61 63 74 69 6f 6e 73 20 77 69 74 68 20 0a  nsactions with .
1750: 2a 2a 20 20 20 74 68 65 20 62 65 67 69 6e 6e 69  **   the beginni
1760: 6e 67 20 6f 66 20 64 69 73 6b 20 73 65 63 74 6f  ng of disk secto
1770: 72 73 2c 20 77 68 69 63 68 20 69 6e 63 72 65 61  rs, which increa
1780: 73 65 73 20 72 6f 62 75 73 74 6e 65 73 73 2e 0a  ses robustness..
1790: 2a 2a 0a 2a 2a 20 52 45 43 4f 52 44 20 46 4f 52  **.** RECORD FOR
17a0: 4d 41 54 53 3a 0a 2a 2a 0a 2a 2a 20 20 20 4c 4f  MATS:.**.**   LO
17b0: 47 5f 45 4f 46 3a 20 20 20 20 2a 20 41 20 73 69  G_EOF:    * A si
17c0: 6e 67 6c 65 20 30 78 30 30 20 62 79 74 65 2e 0a  ngle 0x00 byte..
17d0: 2a 2a 0a 2a 2a 20 20 20 4c 4f 47 5f 50 41 44 31  **.**   LOG_PAD1
17e0: 3a 20 20 20 2a 20 41 20 73 69 6e 67 6c 65 20 30  :   * A single 0
17f0: 78 30 31 20 62 79 74 65 2e 0a 2a 2a 0a 2a 2a 20  x01 byte..**.** 
1800: 20 20 4c 4f 47 5f 50 41 44 32 3a 20 20 20 2a 20    LOG_PAD2:   * 
1810: 41 20 73 69 6e 67 6c 65 20 30 78 30 32 20 62 79  A single 0x02 by
1820: 74 65 2c 20 66 6f 6c 6c 6f 77 65 64 20 62 79 0a  te, followed by.
1830: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  **              
1840: 20 2a 20 54 68 65 20 6e 75 6d 62 65 72 20 6f 66   * The number of
1850: 20 75 6e 75 73 65 64 20 62 79 74 65 73 20 28 4e   unused bytes (N
1860: 29 20 61 73 20 61 20 76 61 72 69 6e 74 2c 0a 2a  ) as a varint,.*
1870: 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  *               
1880: 2a 20 41 6e 20 4e 20 62 79 74 65 20 62 6c 6f 63  * An N byte bloc
1890: 6b 20 6f 66 20 75 6e 75 73 65 64 20 73 70 61 63  k of unused spac
18a0: 65 2e 0a 2a 2a 0a 2a 2a 20 20 20 4c 4f 47 5f 43  e..**.**   LOG_C
18b0: 4f 4d 4d 49 54 3a 20 2a 20 41 20 73 69 6e 67 6c  OMMIT: * A singl
18c0: 65 20 30 78 30 33 20 62 79 74 65 2e 0a 2a 2a 20  e 0x03 byte..** 
18d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20                * 
18e0: 41 6e 20 38 2d 62 79 74 65 20 63 68 65 63 6b 73  An 8-byte checks
18f0: 75 6d 2e 0a 2a 2a 0a 2a 2a 20 20 20 4c 4f 47 5f  um..**.**   LOG_
1900: 4a 55 4d 50 3a 20 20 20 2a 20 41 20 73 69 6e 67  JUMP:   * A sing
1910: 6c 65 20 30 78 30 34 20 62 79 74 65 2e 0a 2a 2a  le 0x04 byte..**
1920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
1930: 20 41 62 73 6f 6c 75 74 65 20 66 69 6c 65 20 6f   Absolute file o
1940: 66 66 73 65 74 20 74 6f 20 6a 75 6d 70 20 74 6f  ffset to jump to
1950: 2c 20 65 6e 63 6f 64 65 64 20 61 73 20 61 20 76  , encoded as a v
1960: 61 72 69 6e 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 4c  arint..**.**   L
1970: 4f 47 5f 57 52 49 54 45 3a 20 20 2a 20 41 20 73  OG_WRITE:  * A s
1980: 69 6e 67 6c 65 20 30 78 30 36 20 6f 72 20 30 78  ingle 0x06 or 0x
1990: 30 37 20 62 79 74 65 2c 20 0a 2a 2a 20 20 20 20  07 byte, .**    
19a0: 20 20 20 20 20 20 20 20 20 20 20 2a 20 54 68 65             * The
19b0: 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   number of bytes
19c0: 20 69 6e 20 74 68 65 20 6b 65 79 2c 20 65 6e 63   in the key, enc
19d0: 6f 64 65 64 20 61 73 20 61 20 76 61 72 69 6e 74  oded as a varint
19e0: 2c 20 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  , .**           
19f0: 20 20 20 20 2a 20 54 68 65 20 6e 75 6d 62 65 72      * The number
1a00: 20 6f 66 20 62 79 74 65 73 20 69 6e 20 74 68 65   of bytes in the
1a10: 20 76 61 6c 75 65 2c 20 65 6e 63 6f 64 65 64 20   value, encoded 
1a20: 61 73 20 61 20 76 61 72 69 6e 74 2c 20 0a 2a 2a  as a varint, .**
1a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
1a40: 20 49 66 20 74 68 65 20 66 69 72 73 74 20 62 79   If the first by
1a50: 74 65 20 77 61 73 20 30 78 30 37 2c 20 61 6e 20  te was 0x07, an 
1a60: 38 20 62 79 74 65 20 63 68 65 63 6b 73 75 6d 2e  8 byte checksum.
1a70: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  .**             
1a80: 20 20 2a 20 54 68 65 20 6b 65 79 20 64 61 74 61    * The key data
1a90: 2c 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20  ,.**            
1aa0: 20 20 20 2a 20 54 68 65 20 76 61 6c 75 65 20 64     * The value d
1ab0: 61 74 61 2e 0a 2a 2a 0a 2a 2a 20 20 20 4c 4f 47  ata..**.**   LOG
1ac0: 5f 44 45 4c 45 54 45 3a 20 2a 20 41 20 73 69 6e  _DELETE: * A sin
1ad0: 67 6c 65 20 30 78 30 38 20 6f 72 20 30 78 30 39  gle 0x08 or 0x09
1ae0: 20 62 79 74 65 2c 20 0a 2a 2a 20 20 20 20 20 20   byte, .**      
1af0: 20 20 20 20 20 20 20 20 20 2a 20 54 68 65 20 6e           * The n
1b00: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
1b10: 6e 20 74 68 65 20 6b 65 79 2c 20 65 6e 63 6f 64  n the key, encod
1b20: 65 64 20 61 73 20 61 20 76 61 72 69 6e 74 2c 20  ed as a varint, 
1b30: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20  .**             
1b40: 20 20 2a 20 49 66 20 74 68 65 20 66 69 72 73 74    * If the first
1b50: 20 62 79 74 65 20 77 61 73 20 30 78 30 39 2c 20   byte was 0x09, 
1b60: 61 6e 20 38 20 62 79 74 65 20 63 68 65 63 6b 73  an 8 byte checks
1b70: 75 6d 2e 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  um..**          
1b80: 20 20 20 20 20 2a 20 54 68 65 20 6b 65 79 20 64       * The key d
1b90: 61 74 61 2e 0a 2a 2a 0a 2a 2a 20 20 20 56 61 72  ata..**.**   Var
1ba0: 69 6e 74 73 20 61 72 65 20 61 73 20 64 65 73 63  ints are as desc
1bb0: 72 69 62 65 64 20 69 6e 20 6c 73 6d 5f 76 61 72  ribed in lsm_var
1bc0: 69 6e 74 2e 63 20 28 53 51 4c 69 74 65 20 34 20  int.c (SQLite 4 
1bd0: 66 6f 72 6d 61 74 29 2e 0a 2a 2a 0a 2a 2a 20 43  format)..**.** C
1be0: 48 45 43 4b 53 55 4d 53 3a 0a 2a 2a 0a 2a 2a 20  HECKSUMS:.**.** 
1bf0: 20 20 54 68 65 20 63 68 65 63 6b 73 75 6d 20 69    The checksum i
1c00: 73 20 63 61 6c 63 75 6c 61 74 65 64 20 75 73 69  s calculated usi
1c10: 6e 67 20 74 77 6f 20 33 32 2d 62 69 74 20 75 6e  ng two 32-bit un
1c20: 73 69 67 6e 65 64 20 69 6e 74 65 67 65 72 73 2c  signed integers,
1c30: 20 73 30 20 61 6e 64 0a 2a 2a 20 20 20 73 31 2e   s0 and.**   s1.
1c40: 20 54 68 65 20 69 6e 69 74 69 61 6c 20 76 61 6c   The initial val
1c50: 75 65 20 66 6f 72 20 62 6f 74 68 20 69 73 20 34  ue for both is 4
1c60: 32 2e 20 49 74 20 69 73 20 75 70 64 61 74 65 64  2. It is updated
1c70: 20 65 61 63 68 20 74 69 6d 65 20 61 20 72 65 63   each time a rec
1c80: 6f 72 64 0a 2a 2a 20 20 20 69 73 20 77 72 69 74  ord.**   is writ
1c90: 74 65 6e 20 69 6e 74 6f 20 74 68 65 20 6c 6f 67  ten into the log
1ca0: 20 66 69 6c 65 20 62 79 20 74 72 65 61 74 69 6e   file by treatin
1cb0: 67 20 74 68 65 20 65 6e 63 6f 64 65 64 20 28 62  g the encoded (b
1cc0: 69 6e 61 72 79 29 20 72 65 63 6f 72 64 20 61 73  inary) record as
1cd0: 20 0a 2a 2a 20 20 20 61 6e 20 61 72 72 61 79 20   .**   an array 
1ce0: 6f 66 20 33 32 2d 62 69 74 20 6c 69 74 74 6c 65  of 32-bit little
1cf0: 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65 72 73  -endian integers
1d00: 2e 20 54 68 65 6e 2c 20 69 66 20 78 5b 5d 20 69  . Then, if x[] i
1d10: 73 20 74 68 65 20 69 6e 74 65 67 65 72 0a 2a 2a  s the integer.**
1d20: 20 20 20 61 72 72 61 79 2c 20 75 70 64 61 74 69     array, updati
1d30: 6e 67 20 74 68 65 20 63 68 65 63 6b 73 75 6d 20  ng the checksum 
1d40: 61 63 63 75 6d 75 6c 61 74 6f 72 73 20 61 73 20  accumulators as 
1d50: 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20  follows:.**.**  
1d60: 20 20 20 66 6f 72 20 69 20 66 72 6f 6d 20 30 20     for i from 0 
1d70: 74 6f 20 6e 2d 31 20 73 74 65 70 20 32 3a 0a 2a  to n-1 step 2:.*
1d80: 2a 20 20 20 20 20 20 20 73 30 20 2b 3d 20 78 5b  *       s0 += x[
1d90: 69 5d 20 2b 20 73 31 3b 0a 2a 2a 20 20 20 20 20  i] + s1;.**     
1da0: 20 20 73 31 20 2b 3d 20 78 5b 69 2b 31 5d 20 2b    s1 += x[i+1] +
1db0: 20 73 30 3b 0a 2a 2a 20 20 20 20 20 65 6e 64 66   s0;.**     endf
1dc0: 6f 72 0a 2a 2a 0a 2a 2a 20 20 20 49 66 20 74 68  or.**.**   If th
1dd0: 65 20 72 65 63 6f 72 64 20 69 73 20 6e 6f 74 20  e record is not 
1de0: 61 6e 20 65 76 65 6e 20 6d 75 6c 74 69 70 6c 65  an even multiple
1df0: 20 6f 66 20 38 2d 62 79 74 65 73 20 69 6e 20 73   of 8-bytes in s
1e00: 69 7a 65 20 69 74 20 69 73 20 70 61 64 64 65 64  ize it is padded
1e10: 0a 2a 2a 20 20 20 77 69 74 68 20 7a 65 72 6f 65  .**   with zeroe
1e20: 73 20 74 6f 20 6d 61 6b 65 20 69 74 20 73 6f 20  s to make it so 
1e30: 62 65 66 6f 72 65 20 74 68 65 20 63 68 65 63 6b  before the check
1e40: 73 75 6d 20 69 73 20 75 70 64 61 74 65 64 2e 0a  sum is updated..
1e50: 2a 2a 0a 2a 2a 20 20 20 54 68 65 20 63 68 65 63  **.**   The chec
1e60: 6b 73 75 6d 20 73 74 6f 72 65 64 20 69 6e 20 61  ksum stored in a
1e70: 20 43 4f 4d 4d 49 54 2c 20 57 52 49 54 45 20 6f   COMMIT, WRITE o
1e80: 72 20 44 45 4c 45 54 45 20 69 73 20 62 61 73 65  r DELETE is base
1e90: 64 20 6f 6e 20 61 6c 6c 20 62 79 74 65 73 0a 2a  d on all bytes.*
1ea0: 2a 20 20 20 75 70 20 74 6f 20 74 68 65 20 73 74  *   up to the st
1eb0: 61 72 74 20 6f 66 20 74 68 65 20 38 2d 62 79 74  art of the 8-byt
1ec0: 65 20 63 68 65 63 6b 73 75 6d 20 69 74 73 65 6c  e checksum itsel
1ed0: 66 2c 20 69 6e 63 6c 75 64 69 6e 67 20 74 68 65  f, including the
1ee0: 20 43 4f 4d 4d 49 54 2c 0a 2a 2a 20 20 20 57 52   COMMIT,.**   WR
1ef0: 49 54 45 20 6f 72 20 44 45 4c 45 54 45 20 66 69  ITE or DELETE fi
1f00: 65 6c 64 73 20 74 68 61 74 20 61 70 70 65 61 72  elds that appear
1f10: 20 62 65 66 6f 72 65 20 74 68 65 20 63 68 65 63   before the chec
1f20: 6b 73 75 6d 20 69 6e 20 74 68 65 20 72 65 63 6f  ksum in the reco
1f30: 72 64 2e 0a 2a 2a 0a 2a 2a 20 56 41 52 49 4e 54  rd..**.** VARINT
1f40: 20 46 4f 52 4d 41 54 0a 2a 2a 0a 2a 2a 20 53 65   FORMAT.**.** Se
1f50: 65 20 6c 73 6d 5f 76 61 72 69 6e 74 2e 63 2e 0a  e lsm_varint.c..
1f60: 2a 2f 0a 0a 23 69 66 6e 64 65 66 20 5f 4c 53 4d  */..#ifndef _LSM
1f70: 5f 49 4e 54 5f 48 0a 23 20 69 6e 63 6c 75 64 65  _INT_H.# include
1f80: 20 22 6c 73 6d 49 6e 74 2e 68 22 0a 23 65 6e 64   "lsmInt.h".#end
1f90: 69 66 0a 0a 2f 2a 20 4c 6f 67 20 72 65 63 6f 72  if../* Log recor
1fa0: 64 20 74 79 70 65 73 20 2a 2f 0a 23 64 65 66 69  d types */.#defi
1fb0: 6e 65 20 4c 53 4d 5f 4c 4f 47 5f 45 4f 46 20 20  ne LSM_LOG_EOF  
1fc0: 20 20 20 20 20 20 20 20 30 78 30 30 0a 23 64 65          0x00.#de
1fd0: 66 69 6e 65 20 4c 53 4d 5f 4c 4f 47 5f 50 41 44  fine LSM_LOG_PAD
1fe0: 31 20 20 20 20 20 20 20 20 20 30 78 30 31 0a 23  1         0x01.#
1ff0: 64 65 66 69 6e 65 20 4c 53 4d 5f 4c 4f 47 5f 50  define LSM_LOG_P
2000: 41 44 32 20 20 20 20 20 20 20 20 20 30 78 30 32  AD2         0x02
2010: 0a 23 64 65 66 69 6e 65 20 4c 53 4d 5f 4c 4f 47  .#define LSM_LOG
2020: 5f 43 4f 4d 4d 49 54 20 20 20 20 20 20 20 30 78  _COMMIT       0x
2030: 30 33 0a 23 64 65 66 69 6e 65 20 4c 53 4d 5f 4c  03.#define LSM_L
2040: 4f 47 5f 4a 55 4d 50 20 20 20 20 20 20 20 20 20  OG_JUMP         
2050: 30 78 30 34 0a 0a 23 64 65 66 69 6e 65 20 4c 53  0x04..#define LS
2060: 4d 5f 4c 4f 47 5f 57 52 49 54 45 20 20 20 20 20  M_LOG_WRITE     
2070: 20 20 20 30 78 30 36 0a 23 64 65 66 69 6e 65 20     0x06.#define 
2080: 4c 53 4d 5f 4c 4f 47 5f 57 52 49 54 45 5f 43 4b  LSM_LOG_WRITE_CK
2090: 53 55 4d 20 20 30 78 30 37 0a 0a 23 64 65 66 69  SUM  0x07..#defi
20a0: 6e 65 20 4c 53 4d 5f 4c 4f 47 5f 44 45 4c 45 54  ne LSM_LOG_DELET
20b0: 45 20 20 20 20 20 20 20 30 78 30 38 0a 23 64 65  E       0x08.#de
20c0: 66 69 6e 65 20 4c 53 4d 5f 4c 4f 47 5f 44 45 4c  fine LSM_LOG_DEL
20d0: 45 54 45 5f 43 4b 53 55 4d 20 30 78 30 39 0a 0a  ETE_CKSUM 0x09..
20e0: 23 64 65 66 69 6e 65 20 4c 53 4d 5f 4c 4f 47 5f  #define LSM_LOG_
20f0: 44 52 41 4e 47 45 20 20 20 20 20 20 20 30 78 30  DRANGE       0x0
2100: 41 0a 23 64 65 66 69 6e 65 20 4c 53 4d 5f 4c 4f  A.#define LSM_LO
2110: 47 5f 44 52 41 4e 47 45 5f 43 4b 53 55 4d 20 30  G_DRANGE_CKSUM 0
2120: 78 30 42 0a 0a 2f 2a 20 52 65 71 75 69 72 65 20  x0B../* Require 
2130: 61 20 63 68 65 63 6b 73 75 6d 20 65 76 65 72 79  a checksum every
2140: 20 33 32 4b 42 2e 20 2a 2f 0a 23 64 65 66 69 6e   32KB. */.#defin
2150: 65 20 4c 53 4d 5f 43 4b 53 55 4d 5f 4d 41 58 44  e LSM_CKSUM_MAXD
2160: 41 54 41 20 28 33 32 2a 31 30 32 34 29 0a 0a 2f  ATA (32*1024)../
2170: 2a 20 44 6f 20 6e 6f 74 20 77 72 61 70 20 61 20  * Do not wrap a 
2180: 6c 6f 67 20 66 69 6c 65 20 73 6d 61 6c 6c 65 72  log file smaller
2190: 20 74 68 61 6e 20 74 68 69 73 20 69 6e 20 62 79   than this in by
21a0: 74 65 73 2e 20 2a 2f 0a 23 64 65 66 69 6e 65 20  tes. */.#define 
21b0: 4c 53 4d 5f 4d 49 4e 5f 4c 4f 47 57 52 41 50 20  LSM_MIN_LOGWRAP 
21c0: 20 20 20 20 20 28 31 32 38 2a 31 30 32 34 29 0a       (128*1024).
21d0: 0a 2f 2a 0a 2a 2a 20 73 7a 53 65 63 74 6f 72 3a  ./*.** szSector:
21e0: 0a 2a 2a 20 20 20 43 6f 6d 6d 69 74 20 72 65 63  .**   Commit rec
21f0: 6f 72 64 73 20 6d 75 73 74 20 62 65 20 61 6c 69  ords must be ali
2200: 67 6e 65 64 20 74 6f 20 65 6e 64 20 6f 6e 20 73  gned to end on s
2210: 7a 53 65 63 74 6f 72 20 62 6f 75 6e 64 61 72 69  zSector boundari
2220: 65 73 2e 20 49 66 0a 2a 2a 20 20 20 74 68 65 20  es. If.**   the 
2230: 73 61 66 65 74 79 2d 6d 6f 64 65 20 69 73 20 73  safety-mode is s
2240: 65 74 20 74 6f 20 4e 4f 52 4d 41 4c 20 6f 72 20  et to NORMAL or 
2250: 4f 46 46 2c 20 74 68 69 73 20 76 61 6c 75 65 20  OFF, this value 
2260: 69 73 20 31 2e 20 4f 74 68 65 72 77 69 73 65 2c  is 1. Otherwise,
2270: 0a 2a 2a 20 20 20 69 66 20 74 68 65 20 73 61 66  .**   if the saf
2280: 65 74 79 2d 6d 6f 64 65 20 69 73 20 73 65 74 20  ety-mode is set 
2290: 74 6f 20 46 55 4c 4c 2c 20 69 74 20 69 73 20 74  to FULL, it is t
22a0: 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 66  he size of the f
22b0: 69 6c 65 2d 73 79 73 74 65 6d 0a 2a 2a 20 20 20  ile-system.**   
22c0: 73 65 63 74 6f 72 73 20 61 73 20 72 65 70 6f 72  sectors as repor
22d0: 74 65 64 20 62 79 20 6c 73 6d 46 73 53 65 63 74  ted by lsmFsSect
22e0: 6f 72 53 69 7a 65 28 29 2e 0a 2a 2f 0a 73 74 72  orSize()..*/.str
22f0: 75 63 74 20 4c 6f 67 57 72 69 74 65 72 20 7b 0a  uct LogWriter {.
2300: 20 20 75 33 32 20 63 6b 73 75 6d 30 3b 20 20 20    u32 cksum0;   
2310: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2320: 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20 30 20    /* Checksum 0 
2330: 61 74 20 6f 66 66 73 65 74 20 69 4f 66 66 20 2a  at offset iOff *
2340: 2f 0a 20 20 75 33 32 20 63 6b 73 75 6d 31 3b 20  /.  u32 cksum1; 
2350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2360: 20 20 20 20 2f 2a 20 43 68 65 63 6b 73 75 6d 20      /* Checksum 
2370: 31 20 61 74 20 6f 66 66 73 65 74 20 69 4f 66 66  1 at offset iOff
2380: 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6b 73 75 6d   */.  int iCksum
2390: 42 75 66 3b 20 20 20 20 20 20 20 20 20 20 20 20  Buf;            
23a0: 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f        /* Bytes o
23b0: 66 20 62 75 66 20 74 68 61 74 20 68 61 76 65 20  f buf that have 
23c0: 62 65 65 6e 20 63 68 65 63 6b 73 75 6d 6d 65 64  been checksummed
23d0: 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66 3b 20   */.  i64 iOff; 
23e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
23f0: 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20        /* Offset 
2400: 61 74 20 73 74 61 72 74 20 6f 66 20 62 75 66 66  at start of buff
2410: 65 72 20 62 75 66 20 2a 2f 0a 20 20 69 6e 74 20  er buf */.  int 
2420: 73 7a 53 65 63 74 6f 72 3b 20 20 20 20 20 20 20  szSector;       
2430: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
2440: 65 63 74 6f 72 20 73 69 7a 65 20 66 6f 72 20 74  ector size for t
2450: 68 69 73 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  his transaction 
2460: 2a 2f 0a 20 20 4c 6f 67 52 65 67 69 6f 6e 20 6a  */.  LogRegion j
2470: 75 6d 70 3b 20 20 20 20 20 20 20 20 20 20 20 20  ump;            
2480: 20 20 20 20 20 2f 2a 20 41 76 6f 69 64 20 77 72       /* Avoid wr
2490: 69 74 69 6e 67 20 74 6f 20 74 68 69 73 20 72 65  iting to this re
24a0: 67 69 6f 6e 20 2a 2f 0a 20 20 69 36 34 20 69 52  gion */.  i64 iR
24b0: 65 67 69 6f 6e 31 45 6e 64 3b 20 20 20 20 20 20  egion1End;      
24c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45 6e 64            /* End
24d0: 20 6f 66 20 66 69 72 73 74 20 72 65 67 69 6f 6e   of first region
24e0: 20 77 72 69 74 74 65 6e 20 62 79 20 74 72 61 6e   written by tran
24f0: 73 20 2a 2f 0a 20 20 69 36 34 20 69 52 65 67 69  s */.  i64 iRegi
2500: 6f 6e 32 53 74 61 72 74 3b 20 20 20 20 20 20 20  on2Start;       
2510: 20 20 20 20 20 20 20 2f 2a 20 53 74 61 72 74 20         /* Start 
2520: 6f 66 20 73 65 63 6f 6e 64 20 72 65 67 69 6f 6e  of second region
2530: 73 20 77 72 69 74 74 65 6e 20 62 79 20 74 72 61  s written by tra
2540: 6e 73 20 2a 2f 0a 20 20 4c 73 6d 53 74 72 69 6e  ns */.  LsmStrin
2550: 67 20 62 75 66 3b 20 20 20 20 20 20 20 20 20 20  g buf;          
2560: 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65          /* Buffe
2570: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64 61 74  r containing dat
2580: 61 20 6e 6f 74 20 79 65 74 20 77 72 69 74 74 65  a not yet writte
2590: 6e 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 52  n */.};../*.** R
25a0: 65 74 75 72 6e 20 74 68 65 20 72 65 73 75 6c 74  eturn the result
25b0: 20 6f 66 20 69 6e 74 65 72 70 72 65 74 69 6e 67   of interpreting
25c0: 20 74 68 65 20 66 69 72 73 74 20 34 20 62 79 74   the first 4 byt
25d0: 65 73 20 69 6e 20 62 75 66 66 65 72 20 61 49 6e  es in buffer aIn
25e0: 20 61 73 20 0a 2a 2a 20 61 20 33 32 2d 62 69 74   as .** a 32-bit
25f0: 20 75 6e 73 69 67 6e 65 64 20 6c 69 74 74 6c 65   unsigned little
2600: 2d 65 6e 64 69 61 6e 20 69 6e 74 65 67 65 72 2e  -endian integer.
2610: 0a 2a 2f 0a 73 74 61 74 69 63 20 75 33 32 20 67  .*/.static u32 g
2620: 65 74 55 33 32 6c 65 28 75 38 20 2a 61 49 6e 29  etU32le(u8 *aIn)
2630: 7b 0a 20 20 72 65 74 75 72 6e 20 28 28 75 33 32  {.  return ((u32
2640: 29 61 49 6e 5b 33 5d 20 3c 3c 20 32 34 29 20 0a  )aIn[3] << 24) .
2650: 20 20 20 20 20 20 20 2b 20 28 28 75 33 32 29 61         + ((u32)a
2660: 49 6e 5b 32 5d 20 3c 3c 20 31 36 29 20 0a 20 20  In[2] << 16) .  
2670: 20 20 20 20 20 2b 20 28 28 75 33 32 29 61 49 6e       + ((u32)aIn
2680: 5b 31 5d 20 3c 3c 20 38 29 20 0a 20 20 20 20 20  [1] << 8) .     
2690: 20 20 2b 20 28 28 75 33 32 29 61 49 6e 5b 30 5d    + ((u32)aIn[0]
26a0: 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  );.}.../*.** Thi
26b0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 74 68  s function is th
26c0: 65 20 73 61 6d 65 20 61 73 20 6c 6f 67 43 6b 73  e same as logCks
26d0: 75 6d 28 29 2c 20 65 78 63 65 70 74 20 74 68 61  um(), except tha
26e0: 74 20 70 6f 69 6e 74 65 72 20 22 61 22 20 6e 65  t pointer "a" ne
26f0: 65 64 0a 2a 2a 20 6e 6f 74 20 62 65 20 61 6c 69  ed.** not be ali
2700: 67 6e 65 64 20 74 6f 20 61 6e 20 38 2d 62 79 74  gned to an 8-byt
2710: 65 20 62 6f 75 6e 64 61 72 79 20 6f 72 20 70 61  e boundary or pa
2720: 64 64 65 64 20 77 69 74 68 20 7a 65 72 6f 20 62  dded with zero b
2730: 79 74 65 73 2e 20 54 68 69 73 0a 2a 2a 20 76 65  ytes. This.** ve
2740: 72 73 69 6f 6e 20 69 73 20 73 6c 6f 77 65 72 2c  rsion is slower,
2750: 20 62 75 74 20 73 6f 6d 65 74 69 6d 65 73 20 6d   but sometimes m
2760: 6f 72 65 20 63 6f 6e 76 65 6e 69 65 6e 74 20 74  ore convenient t
2770: 6f 20 75 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  o use..*/.static
2780: 20 76 6f 69 64 20 6c 6f 67 43 6b 73 75 6d 55 6e   void logCksumUn
2790: 61 6c 69 67 6e 65 64 28 0a 20 20 63 68 61 72 20  aligned(.  char 
27a0: 2a 7a 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  *z,             
27b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
27c0: 70 75 74 20 62 75 66 66 65 72 20 2a 2f 0a 20 20  put buffer */.  
27d0: 69 6e 74 20 6e 2c 20 20 20 20 20 20 20 20 20 20  int n,          
27e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27f0: 2f 2a 20 53 69 7a 65 20 6f 66 20 69 6e 70 75 74  /* Size of input
2800: 20 62 75 66 66 65 72 20 69 6e 20 62 79 74 65 73   buffer in bytes
2810: 20 2a 2f 0a 20 20 75 33 32 20 2a 70 43 6b 73 75   */.  u32 *pCksu
2820: 6d 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  m0,             
2830: 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a        /* IN/OUT:
2840: 20 43 68 65 63 6b 73 75 6d 20 76 61 6c 75 65 20   Checksum value 
2850: 31 20 2a 2f 0a 20 20 75 33 32 20 2a 70 43 6b 73  1 */.  u32 *pCks
2860: 75 6d 31 20 20 20 20 20 20 20 20 20 20 20 20 20  um1             
2870: 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54         /* IN/OUT
2880: 3a 20 43 68 65 63 6b 73 75 6d 20 76 61 6c 75 65  : Checksum value
2890: 20 32 20 2a 2f 0a 29 7b 0a 20 20 75 38 20 2a 61   2 */.){.  u8 *a
28a0: 20 3d 20 28 75 38 20 2a 29 7a 3b 0a 20 20 75 33   = (u8 *)z;.  u3
28b0: 32 20 63 6b 73 75 6d 30 20 3d 20 2a 70 43 6b 73  2 cksum0 = *pCks
28c0: 75 6d 30 3b 0a 20 20 75 33 32 20 63 6b 73 75 6d  um0;.  u32 cksum
28d0: 31 20 3d 20 2a 70 43 6b 73 75 6d 31 3b 0a 20 20  1 = *pCksum1;.  
28e0: 69 6e 74 20 6e 49 6e 20 3d 20 28 6e 2f 38 29 20  int nIn = (n/8) 
28f0: 2a 20 38 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20  * 8;.  int i;.. 
2900: 20 61 73 73 65 72 74 28 20 6e 3e 30 20 29 3b 0a   assert( n>0 );.
2910: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 49 6e    for(i=0; i<nIn
2920: 3b 20 69 2b 3d 38 29 7b 0a 20 20 20 20 63 6b 73  ; i+=8){.    cks
2930: 75 6d 30 20 2b 3d 20 67 65 74 55 33 32 6c 65 28  um0 += getU32le(
2940: 26 61 5b 69 5d 29 20 2b 20 63 6b 73 75 6d 31 3b  &a[i]) + cksum1;
2950: 0a 20 20 20 20 63 6b 73 75 6d 31 20 2b 3d 20 67  .    cksum1 += g
2960: 65 74 55 33 32 6c 65 28 26 61 5b 69 2b 34 5d 29  etU32le(&a[i+4])
2970: 20 2b 20 63 6b 73 75 6d 30 3b 0a 20 20 7d 0a 0a   + cksum0;.  }..
2980: 20 20 69 66 28 20 6e 49 6e 21 3d 6e 20 29 7b 0a    if( nIn!=n ){.
2990: 20 20 20 20 75 38 20 61 42 75 66 5b 38 5d 20 3d      u8 aBuf[8] =
29a0: 20 7b 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c   {0, 0, 0, 0, 0,
29b0: 20 30 2c 20 30 2c 20 30 7d 3b 0a 20 20 20 20 61   0, 0, 0};.    a
29c0: 73 73 65 72 74 28 20 28 6e 2d 6e 49 6e 29 3c 38  ssert( (n-nIn)<8
29d0: 20 26 26 20 6e 3e 6e 49 6e 20 29 3b 0a 20 20 20   && n>nIn );.   
29e0: 20 6d 65 6d 63 70 79 28 61 42 75 66 2c 20 26 61   memcpy(aBuf, &a
29f0: 5b 6e 49 6e 5d 2c 20 6e 2d 6e 49 6e 29 3b 0a 20  [nIn], n-nIn);. 
2a00: 20 20 20 63 6b 73 75 6d 30 20 2b 3d 20 67 65 74     cksum0 += get
2a10: 55 33 32 6c 65 28 61 42 75 66 29 20 2b 20 63 6b  U32le(aBuf) + ck
2a20: 73 75 6d 31 3b 0a 20 20 20 20 63 6b 73 75 6d 31  sum1;.    cksum1
2a30: 20 2b 3d 20 67 65 74 55 33 32 6c 65 28 26 61 42   += getU32le(&aB
2a40: 75 66 5b 34 5d 29 20 2b 20 63 6b 73 75 6d 30 3b  uf[4]) + cksum0;
2a50: 0a 20 20 7d 0a 0a 20 20 2a 70 43 6b 73 75 6d 30  .  }..  *pCksum0
2a60: 20 3d 20 63 6b 73 75 6d 30 3b 0a 20 20 2a 70 43   = cksum0;.  *pC
2a70: 6b 73 75 6d 31 20 3d 20 63 6b 73 75 6d 31 3b 0a  ksum1 = cksum1;.
2a80: 7d 0a 0a 2f 2a 0a 2a 2a 20 55 70 64 61 74 65 20  }../*.** Update 
2a90: 70 4c 6f 67 2d 3e 63 6b 73 75 6d 30 20 61 6e 64  pLog->cksum0 and
2aa0: 20 70 4c 6f 67 2d 3e 63 6b 73 75 6d 31 20 73 6f   pLog->cksum1 so
2ab0: 20 74 68 61 74 20 74 68 65 20 66 69 72 73 74 20   that the first 
2ac0: 6e 42 75 66 20 62 79 74 65 73 20 69 6e 20 74 68  nBuf bytes in th
2ad0: 65 20 0a 2a 2a 20 77 72 69 74 65 20 62 75 66 66  e .** write buff
2ae0: 65 72 20 28 70 4c 6f 67 2d 3e 62 75 66 29 20 61  er (pLog->buf) a
2af0: 72 65 20 69 6e 63 6c 75 64 65 64 20 69 6e 20 74  re included in t
2b00: 68 65 20 63 68 65 63 6b 73 75 6d 2e 0a 2a 2f 0a  he checksum..*/.
2b10: 73 74 61 74 69 63 20 76 6f 69 64 20 6c 6f 67 55  static void logU
2b20: 70 64 61 74 65 43 6b 73 75 6d 28 4c 6f 67 57 72  pdateCksum(LogWr
2b30: 69 74 65 72 20 2a 70 4c 6f 67 2c 20 69 6e 74 20  iter *pLog, int 
2b40: 6e 42 75 66 29 7b 0a 20 20 61 73 73 65 72 74 28  nBuf){.  assert(
2b50: 20 28 70 4c 6f 67 2d 3e 69 43 6b 73 75 6d 42 75   (pLog->iCksumBu
2b60: 66 20 25 20 38 29 3d 3d 30 20 29 3b 0a 20 20 61  f % 8)==0 );.  a
2b70: 73 73 65 72 74 28 20 70 4c 6f 67 2d 3e 69 43 6b  ssert( pLog->iCk
2b80: 73 75 6d 42 75 66 3c 3d 6e 42 75 66 20 29 3b 0a  sumBuf<=nBuf );.
2b90: 20 20 61 73 73 65 72 74 28 20 28 6e 42 75 66 20    assert( (nBuf 
2ba0: 25 20 38 29 3d 3d 30 20 7c 7c 20 6e 42 75 66 3d  % 8)==0 || nBuf=
2bb0: 3d 70 4c 6f 67 2d 3e 62 75 66 2e 6e 20 29 3b 0a  =pLog->buf.n );.
2bc0: 20 20 69 66 28 20 6e 42 75 66 3e 70 4c 6f 67 2d    if( nBuf>pLog-
2bd0: 3e 69 43 6b 73 75 6d 42 75 66 20 29 7b 0a 20 20  >iCksumBuf ){.  
2be0: 20 20 6c 6f 67 43 6b 73 75 6d 55 6e 61 6c 69 67    logCksumUnalig
2bf0: 6e 65 64 28 0a 20 20 20 20 20 20 20 20 26 70 4c  ned(.        &pL
2c00: 6f 67 2d 3e 62 75 66 2e 7a 5b 70 4c 6f 67 2d 3e  og->buf.z[pLog->
2c10: 69 43 6b 73 75 6d 42 75 66 5d 2c 20 6e 42 75 66  iCksumBuf], nBuf
2c20: 2d 70 4c 6f 67 2d 3e 69 43 6b 73 75 6d 42 75 66  -pLog->iCksumBuf
2c30: 2c 20 0a 20 20 20 20 20 20 20 20 26 70 4c 6f 67  , .        &pLog
2c40: 2d 3e 63 6b 73 75 6d 30 2c 20 26 70 4c 6f 67 2d  ->cksum0, &pLog-
2c50: 3e 63 6b 73 75 6d 31 0a 20 20 20 20 29 3b 0a 20  >cksum1.    );. 
2c60: 20 7d 0a 20 20 70 4c 6f 67 2d 3e 69 43 6b 73 75   }.  pLog->iCksu
2c70: 6d 42 75 66 20 3d 20 6e 42 75 66 3b 0a 7d 0a 0a  mBuf = nBuf;.}..
2c80: 73 74 61 74 69 63 20 69 36 34 20 66 69 72 73 74  static i64 first
2c90: 42 79 74 65 4f 6e 53 65 63 74 6f 72 28 4c 6f 67  ByteOnSector(Log
2ca0: 57 72 69 74 65 72 20 2a 70 4c 6f 67 2c 20 69 36  Writer *pLog, i6
2cb0: 34 20 69 4f 66 66 29 7b 0a 20 20 72 65 74 75 72  4 iOff){.  retur
2cc0: 6e 20 28 69 4f 66 66 20 2f 20 70 4c 6f 67 2d 3e  n (iOff / pLog->
2cd0: 73 7a 53 65 63 74 6f 72 29 20 2a 20 70 4c 6f 67  szSector) * pLog
2ce0: 2d 3e 73 7a 53 65 63 74 6f 72 3b 0a 7d 0a 73 74  ->szSector;.}.st
2cf0: 61 74 69 63 20 69 36 34 20 6c 61 73 74 42 79 74  atic i64 lastByt
2d00: 65 4f 6e 53 65 63 74 6f 72 28 4c 6f 67 57 72 69  eOnSector(LogWri
2d10: 74 65 72 20 2a 70 4c 6f 67 2c 20 69 36 34 20 69  ter *pLog, i64 i
2d20: 4f 66 66 29 7b 0a 20 20 72 65 74 75 72 6e 20 66  Off){.  return f
2d30: 69 72 73 74 42 79 74 65 4f 6e 53 65 63 74 6f 72  irstByteOnSector
2d40: 28 70 4c 6f 67 2c 20 69 4f 66 66 29 20 2b 20 70  (pLog, iOff) + p
2d50: 4c 6f 67 2d 3e 73 7a 53 65 63 74 6f 72 20 2d 20  Log->szSector - 
2d60: 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 70  1;.}../*.** If p
2d70: 6f 73 73 69 62 6c 65 2c 20 72 65 63 6c 61 69 6d  ossible, reclaim
2d80: 20 6c 6f 67 20 66 69 6c 65 20 73 70 61 63 65 2e   log file space.
2d90: 20 4c 6f 67 20 66 69 6c 65 20 73 70 61 63 65 20   Log file space 
2da0: 69 73 20 72 65 63 6c 61 69 6d 65 64 20 61 66 74  is reclaimed aft
2db0: 65 72 0a 2a 2a 20 61 20 73 6e 61 70 73 68 6f 74  er.** a snapshot
2dc0: 20 74 68 61 74 20 70 6f 69 6e 74 73 20 74 6f 20   that points to 
2dd0: 74 68 65 20 73 61 6d 65 20 64 61 74 61 20 69 6e  the same data in
2de0: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
2df0: 6c 65 20 69 73 20 73 79 6e 63 65 64 0a 2a 2a 20  le is synced.** 
2e00: 69 6e 74 6f 20 74 68 65 20 64 62 20 68 65 61 64  into the db head
2e10: 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  er..*/.static in
2e20: 74 20 6c 6f 67 52 65 63 6c 61 69 6d 53 70 61 63  t logReclaimSpac
2e30: 65 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29 7b 0a  e(lsm_db *pDb){.
2e40: 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20    int rc;.  int 
2e50: 69 4d 65 74 61 3b 0a 20 20 69 6e 74 20 62 52 6f  iMeta;.  int bRo
2e60: 74 72 61 6e 73 3b 20 20 20 20 20 20 20 20 20 20  trans;          
2e70: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
2e80: 20 69 66 20 74 68 65 72 65 20 65 78 69 73 74 73   if there exists
2e90: 20 73 6f 6d 65 20 72 6f 2d 74 72 61 6e 73 20 2a   some ro-trans *
2ea0: 2f 0a 0a 20 20 2f 2a 20 54 65 73 74 20 69 66 20  /..  /* Test if 
2eb0: 74 68 65 72 65 20 65 78 69 73 74 73 20 73 6f 6d  there exists som
2ec0: 65 20 6f 74 68 65 72 20 63 6f 6e 6e 65 63 74 69  e other connecti
2ed0: 6f 6e 20 77 69 74 68 20 61 20 72 65 61 64 2d 6f  on with a read-o
2ee0: 6e 6c 79 20 74 72 61 6e 73 61 63 74 69 6f 6e 0a  nly transaction.
2ef0: 20 20 2a 2a 20 6f 70 65 6e 2e 20 49 66 20 74 68    ** open. If th
2f00: 65 72 65 20 64 6f 65 73 2c 20 74 68 65 6e 20 6c  ere does, then l
2f10: 6f 67 20 66 69 6c 65 20 73 70 61 63 65 20 6d 61  og file space ma
2f20: 79 20 6e 6f 74 20 62 65 20 72 65 63 6c 61 69 6d  y not be reclaim
2f30: 65 64 2e 20 20 2a 2f 0a 20 20 72 63 20 3d 20 6c  ed.  */.  rc = l
2f40: 73 6d 44 65 74 65 63 74 52 6f 54 72 61 6e 73 28  smDetectRoTrans(
2f50: 70 44 62 2c 20 26 62 52 6f 74 72 61 6e 73 29 3b  pDb, &bRotrans);
2f60: 0a 20 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f  .  if( rc!=LSM_O
2f70: 4b 20 7c 7c 20 62 52 6f 74 72 61 6e 73 20 29 20  K || bRotrans ) 
2f80: 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20 20 69 4d  return rc;..  iM
2f90: 65 74 61 20 3d 20 28 69 6e 74 29 70 44 62 2d 3e  eta = (int)pDb->
2fa0: 70 53 68 6d 68 64 72 2d 3e 69 4d 65 74 61 50 61  pShmhdr->iMetaPa
2fb0: 67 65 3b 0a 20 20 69 66 28 20 69 4d 65 74 61 3d  ge;.  if( iMeta=
2fc0: 3d 31 20 7c 7c 20 69 4d 65 74 61 3d 3d 32 20 29  =1 || iMeta==2 )
2fd0: 7b 0a 20 20 20 20 44 62 4c 6f 67 20 2a 70 4c 6f  {.    DbLog *pLo
2fe0: 67 20 3d 20 26 70 44 62 2d 3e 74 72 65 65 68 64  g = &pDb->treehd
2ff0: 72 2e 6c 6f 67 3b 0a 20 20 20 20 69 36 34 20 69  r.log;.    i64 i
3000: 53 79 6e 63 65 64 49 64 3b 0a 0a 20 20 20 20 2f  SyncedId;..    /
3010: 2a 20 52 65 61 64 20 74 68 65 20 73 6e 61 70 73  * Read the snaps
3020: 68 6f 74 2d 69 64 20 6f 66 20 74 68 65 20 73 6e  hot-id of the sn
3030: 61 70 73 68 6f 74 20 73 74 6f 72 65 64 20 6f 6e  apshot stored on
3040: 20 6d 65 74 61 2d 70 61 67 65 20 69 4d 65 74 61   meta-page iMeta
3050: 2e 20 4e 6f 74 65 0a 20 20 20 20 2a 2a 20 74 68  . Note.    ** th
3060: 61 74 20 69 6e 20 74 68 65 6f 72 79 2c 20 74 68  at in theory, th
3070: 65 20 76 61 6c 75 65 20 72 65 61 64 20 69 73 20  e value read is 
3080: 75 6e 74 72 75 73 74 77 6f 72 74 68 79 20 28 64  untrustworthy (d
3090: 75 65 20 74 6f 20 61 20 72 61 63 65 20 0a 20 20  ue to a race .  
30a0: 20 20 2a 2a 20 63 6f 6e 64 69 74 69 6f 6e 20 2d    ** condition -
30b0: 20 73 65 65 20 63 6f 6d 6d 65 6e 74 73 20 61 62   see comments ab
30c0: 6f 76 65 20 6c 73 6d 46 73 52 65 61 64 53 79 6e  ove lsmFsReadSyn
30d0: 63 65 64 49 64 28 29 29 2e 20 53 6f 20 69 74 20  cedId()). So it 
30e0: 69 73 20 6f 6e 6c 79 20 0a 20 20 20 20 2a 2a 20  is only .    ** 
30f0: 65 76 65 72 20 75 73 65 64 20 74 6f 20 63 6f 6e  ever used to con
3100: 63 6c 75 64 65 20 74 68 61 74 20 6e 6f 20 6c 6f  clude that no lo
3110: 67 20 73 70 61 63 65 20 63 61 6e 20 62 65 20 72  g space can be r
3120: 65 63 6c 61 69 6d 65 64 2e 20 49 66 20 69 74 20  eclaimed. If it 
3130: 73 65 65 6d 73 0a 20 20 20 20 2a 2a 20 74 6f 20  seems.    ** to 
3140: 69 6e 64 69 63 61 74 65 20 74 68 61 74 20 69 74  indicate that it
3150: 20 6d 61 79 20 62 65 20 70 6f 73 73 69 62 6c 65   may be possible
3160: 20 74 6f 20 72 65 63 6c 61 69 6d 20 6c 6f 67 20   to reclaim log 
3170: 73 70 61 63 65 2c 20 61 0a 20 20 20 20 2a 2a 20  space, a.    ** 
3180: 73 65 63 6f 6e 64 20 63 61 6c 6c 20 74 6f 20 6c  second call to l
3190: 73 6d 43 68 65 63 6b 70 6f 69 6e 74 53 79 6e 63  smCheckpointSync
31a0: 65 64 28 29 20 28 77 68 69 63 68 20 64 6f 65 73  ed() (which does
31b0: 20 72 65 74 75 72 6e 20 74 72 75 73 74 77 6f 72   return trustwor
31c0: 74 68 79 0a 20 20 20 20 2a 2a 20 76 61 6c 75 65  thy.    ** value
31d0: 73 29 20 69 73 20 6d 61 64 65 20 62 65 6c 6f 77  s) is made below
31e0: 20 74 6f 20 63 6f 6e 66 69 72 6d 2e 20 20 2a 2f   to confirm.  */
31f0: 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73 52  .    rc = lsmFsR
3200: 65 61 64 53 79 6e 63 65 64 49 64 28 70 44 62 2c  eadSyncedId(pDb,
3210: 20 69 4d 65 74 61 2c 20 26 69 53 79 6e 63 65 64   iMeta, &iSynced
3220: 49 64 29 3b 0a 0a 20 20 20 20 69 66 28 20 72 63  Id);..    if( rc
3230: 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 70 4c 6f 67  ==LSM_OK && pLog
3240: 2d 3e 69 53 6e 61 70 73 68 6f 74 49 64 21 3d 69  ->iSnapshotId!=i
3250: 53 79 6e 63 65 64 49 64 20 29 7b 0a 20 20 20 20  SyncedId ){.    
3260: 20 20 69 36 34 20 69 53 6e 61 70 73 68 6f 74 49    i64 iSnapshotI
3270: 64 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 36 34  d = 0;.      i64
3280: 20 69 4f 66 66 20 3d 20 30 3b 0a 20 20 20 20 20   iOff = 0;.     
3290: 20 72 63 20 3d 20 6c 73 6d 43 68 65 63 6b 70 6f   rc = lsmCheckpo
32a0: 69 6e 74 53 79 6e 63 65 64 28 70 44 62 2c 20 26  intSynced(pDb, &
32b0: 69 53 6e 61 70 73 68 6f 74 49 64 2c 20 26 69 4f  iSnapshotId, &iO
32c0: 66 66 2c 20 30 29 3b 0a 20 20 20 20 20 20 69 66  ff, 0);.      if
32d0: 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20  ( rc==LSM_OK && 
32e0: 70 4c 6f 67 2d 3e 69 53 6e 61 70 73 68 6f 74 49  pLog->iSnapshotI
32f0: 64 3c 69 53 6e 61 70 73 68 6f 74 49 64 20 29 7b  d<iSnapshotId ){
3300: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 52 65  .        int iRe
3310: 67 69 6f 6e 3b 0a 20 20 20 20 20 20 20 20 66 6f  gion;.        fo
3320: 72 28 69 52 65 67 69 6f 6e 3d 30 3b 20 69 52 65  r(iRegion=0; iRe
3330: 67 69 6f 6e 3c 33 3b 20 69 52 65 67 69 6f 6e 2b  gion<3; iRegion+
3340: 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 4c 6f  +){.          Lo
3350: 67 52 65 67 69 6f 6e 20 2a 70 20 3d 20 26 70 4c  gRegion *p = &pL
3360: 6f 67 2d 3e 61 52 65 67 69 6f 6e 5b 69 52 65 67  og->aRegion[iReg
3370: 69 6f 6e 5d 3b 0a 20 20 20 20 20 20 20 20 20 20  ion];.          
3380: 69 66 28 20 69 4f 66 66 3e 3d 70 2d 3e 69 53 74  if( iOff>=p->iSt
3390: 61 72 74 20 26 26 20 69 4f 66 66 3c 3d 70 2d 3e  art && iOff<=p->
33a0: 69 45 6e 64 20 29 20 62 72 65 61 6b 3b 0a 20 20  iEnd ) break;.  
33b0: 20 20 20 20 20 20 20 20 70 2d 3e 69 53 74 61 72          p->iStar
33c0: 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 20  t = 0;.         
33d0: 20 70 2d 3e 69 45 6e 64 20 3d 20 30 3b 0a 20 20   p->iEnd = 0;.  
33e0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
33f0: 61 73 73 65 72 74 28 20 69 52 65 67 69 6f 6e 3c  assert( iRegion<
3400: 33 20 29 3b 0a 20 20 20 20 20 20 20 20 70 4c 6f  3 );.        pLo
3410: 67 2d 3e 61 52 65 67 69 6f 6e 5b 69 52 65 67 69  g->aRegion[iRegi
3420: 6f 6e 5d 2e 69 53 74 61 72 74 20 3d 20 69 4f 66  on].iStart = iOf
3430: 66 3b 0a 20 20 20 20 20 20 20 20 70 4c 6f 67 2d  f;.        pLog-
3440: 3e 69 53 6e 61 70 73 68 6f 74 49 64 20 3d 20 69  >iSnapshotId = i
3450: 53 6e 61 70 73 68 6f 74 49 64 3b 0a 20 20 20 20  SnapshotId;.    
3460: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20    }.    }.  }.  
3470: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
3480: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
3490: 6e 20 69 73 20 63 61 6c 6c 65 64 20 77 68 65 6e  n is called when
34a0: 20 61 20 77 72 69 74 65 2d 74 72 61 6e 73 61 63   a write-transac
34b0: 74 69 6f 6e 20 69 73 20 66 69 72 73 74 20 6f 70  tion is first op
34c0: 65 6e 65 64 2e 20 49 74 0a 2a 2a 20 69 73 20 61  ened. It.** is a
34d0: 73 73 75 6d 65 64 20 74 68 61 74 20 74 68 65 20  ssumed that the 
34e0: 63 61 6c 6c 65 72 20 69 73 20 68 6f 6c 64 69 6e  caller is holdin
34f0: 67 20 74 68 65 20 63 6c 69 65 6e 74 2d 6d 75 74  g the client-mut
3500: 65 78 20 77 68 65 6e 20 69 74 20 69 73 20 0a 2a  ex when it is .*
3510: 2a 20 63 61 6c 6c 65 64 2e 0a 2a 2a 0a 2a 2a 20  * called..**.** 
3520: 42 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67  Before returning
3530: 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  , this function 
3540: 61 6c 6c 6f 63 61 74 65 73 20 74 68 65 20 4c 6f  allocates the Lo
3550: 67 57 72 69 74 65 72 20 6f 62 6a 65 63 74 20 74  gWriter object t
3560: 68 61 74 0a 2a 2a 20 77 69 6c 6c 20 62 65 20 75  hat.** will be u
3570: 73 65 64 20 74 6f 20 77 72 69 74 65 20 74 6f 20  sed to write to 
3580: 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 64 75 72  the log file dur
3590: 69 6e 67 20 74 68 65 20 77 72 69 74 65 20 74 72  ing the write tr
35a0: 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a 2a 20 4c 53  ansaction..** LS
35b0: 4d 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64  M_OK is returned
35c0: 20 69 66 20 6e 6f 20 65 72 72 6f 72 20 6f 63 63   if no error occ
35d0: 75 72 73 2c 20 6f 74 68 65 72 77 69 73 65 20 61  urs, otherwise a
35e0: 6e 20 4c 53 4d 20 65 72 72 6f 72 20 63 6f 64 65  n LSM error code
35f0: 2e 0a 2a 2f 0a 69 6e 74 20 6c 73 6d 4c 6f 67 42  ..*/.int lsmLogB
3600: 65 67 69 6e 28 6c 73 6d 5f 64 62 20 2a 70 44 62  egin(lsm_db *pDb
3610: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53  ){.  int rc = LS
3620: 4d 5f 4f 4b 3b 0a 20 20 4c 6f 67 57 72 69 74 65  M_OK;.  LogWrite
3630: 72 20 2a 70 4e 65 77 3b 0a 20 20 4c 6f 67 52 65  r *pNew;.  LogRe
3640: 67 69 6f 6e 20 2a 61 52 65 67 3b 0a 0a 20 20 69  gion *aReg;..  i
3650: 66 28 20 70 44 62 2d 3e 62 55 73 65 4c 6f 67 3d  f( pDb->bUseLog=
3660: 3d 30 20 29 20 72 65 74 75 72 6e 20 4c 53 4d 5f  =0 ) return LSM_
3670: 4f 4b 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65  OK;..  /* If the
3680: 20 6c 6f 67 20 66 69 6c 65 20 68 61 73 20 6e 6f   log file has no
3690: 74 20 79 65 74 20 62 65 65 6e 20 6f 70 65 6e 65  t yet been opene
36a0: 64 2c 20 6f 70 65 6e 20 69 74 20 6e 6f 77 2e 20  d, open it now. 
36b0: 41 6c 73 6f 20 61 6c 6c 6f 63 61 74 65 0a 20 20  Also allocate.  
36c0: 2a 2a 20 74 68 65 20 4c 6f 67 57 72 69 74 65 72  ** the LogWriter
36d0: 20 73 74 72 75 63 74 75 72 65 2c 20 69 66 20 69   structure, if i
36e0: 74 20 68 61 73 20 6e 6f 74 20 61 6c 72 65 61 64  t has not alread
36f0: 79 20 62 65 65 6e 20 61 6c 6c 6f 63 61 74 65 64  y been allocated
3700: 2e 20 20 2a 2f 0a 20 20 72 63 20 3d 20 6c 73 6d  .  */.  rc = lsm
3710: 46 73 4f 70 65 6e 4c 6f 67 28 70 44 62 2c 20 30  FsOpenLog(pDb, 0
3720: 29 3b 0a 20 20 69 66 28 20 70 44 62 2d 3e 70 4c  );.  if( pDb->pL
3730: 6f 67 57 72 69 74 65 72 3d 3d 30 20 29 7b 0a 20  ogWriter==0 ){. 
3740: 20 20 20 70 4e 65 77 20 3d 20 6c 73 6d 4d 61 6c     pNew = lsmMal
3750: 6c 6f 63 5a 65 72 6f 52 63 28 70 44 62 2d 3e 70  locZeroRc(pDb->p
3760: 45 6e 76 2c 20 73 69 7a 65 6f 66 28 4c 6f 67 57  Env, sizeof(LogW
3770: 72 69 74 65 72 29 2c 20 26 72 63 29 3b 0a 20 20  riter), &rc);.  
3780: 20 20 69 66 28 20 70 4e 65 77 20 29 7b 0a 20 20    if( pNew ){.  
3790: 20 20 20 20 6c 73 6d 53 74 72 69 6e 67 49 6e 69      lsmStringIni
37a0: 74 28 26 70 4e 65 77 2d 3e 62 75 66 2c 20 70 44  t(&pNew->buf, pD
37b0: 62 2d 3e 70 45 6e 76 29 3b 0a 20 20 20 20 20 20  b->pEnv);.      
37c0: 72 63 20 3d 20 6c 73 6d 53 74 72 69 6e 67 45 78  rc = lsmStringEx
37d0: 74 65 6e 64 28 26 70 4e 65 77 2d 3e 62 75 66 2c  tend(&pNew->buf,
37e0: 20 32 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70   2);.    }.    p
37f0: 44 62 2d 3e 70 4c 6f 67 57 72 69 74 65 72 20 3d  Db->pLogWriter =
3800: 20 70 4e 65 77 3b 0a 20 20 7d 65 6c 73 65 7b 0a   pNew;.  }else{.
3810: 20 20 20 20 70 4e 65 77 20 3d 20 70 44 62 2d 3e      pNew = pDb->
3820: 70 4c 6f 67 57 72 69 74 65 72 3b 0a 20 20 20 20  pLogWriter;.    
3830: 61 73 73 65 72 74 28 20 28 75 38 20 2a 29 28 26  assert( (u8 *)(&
3840: 70 4e 65 77 5b 31 5d 29 3d 3d 28 75 38 20 2a 29  pNew[1])==(u8 *)
3850: 28 26 28 28 26 70 4e 65 77 2d 3e 62 75 66 29 5b  (&((&pNew->buf)[
3860: 31 5d 29 29 20 29 3b 0a 20 20 20 20 6d 65 6d 73  1])) );.    mems
3870: 65 74 28 70 4e 65 77 2c 20 30 2c 20 28 28 75 38  et(pNew, 0, ((u8
3880: 20 2a 29 26 70 4e 65 77 2d 3e 62 75 66 29 20 2d   *)&pNew->buf) -
3890: 20 28 75 38 20 2a 29 70 4e 65 77 29 3b 0a 20 20   (u8 *)pNew);.  
38a0: 20 20 70 4e 65 77 2d 3e 62 75 66 2e 6e 20 3d 20    pNew->buf.n = 
38b0: 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63  0;.  }..  if( rc
38c0: 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20  ==LSM_OK ){.    
38d0: 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  /* The following
38e0: 20 63 61 6c 6c 20 64 65 74 65 63 74 73 20 77 68   call detects wh
38f0: 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 61 20 6e  ether or not a n
3900: 65 77 20 73 6e 61 70 73 68 6f 74 20 68 61 73 20  ew snapshot has 
3910: 62 65 65 6e 20 0a 20 20 20 20 2a 2a 20 73 79 6e  been .    ** syn
3920: 63 65 64 20 69 6e 74 6f 20 74 68 65 20 64 61 74  ced into the dat
3930: 61 62 61 73 65 20 66 69 6c 65 2e 20 49 66 20 73  abase file. If s
3940: 6f 2c 20 69 74 20 75 70 64 61 74 65 73 20 74 68  o, it updates th
3950: 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 0a 20 20  e contents of.  
3960: 20 20 2a 2a 20 74 68 65 20 70 44 62 2d 3e 74 72    ** the pDb->tr
3970: 65 65 68 64 72 2e 6c 6f 67 20 73 74 72 75 63 74  eehdr.log struct
3980: 75 72 65 20 74 6f 20 72 65 63 6c 61 69 6d 20 61  ure to reclaim a
3990: 6e 79 20 73 70 61 63 65 20 69 6e 20 74 68 65 20  ny space in the 
39a0: 6c 6f 67 0a 20 20 20 20 2a 2a 20 66 69 6c 65 20  log.    ** file 
39b0: 74 68 61 74 20 69 73 20 6e 6f 20 6c 6f 6e 67 65  that is no longe
39c0: 72 20 72 65 71 75 69 72 65 64 2e 20 0a 20 20 20  r required. .   
39d0: 20 2a 2a 0a 20 20 20 20 2a 2a 20 54 4f 44 4f 3a   **.    ** TODO:
39e0: 20 43 61 6c 6c 69 6e 67 20 74 68 69 73 20 65 76   Calling this ev
39f0: 65 72 79 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ery transaction 
3a00: 69 73 20 6f 76 65 72 6b 69 6c 6c 2e 20 41 6e 64  is overkill. And
3a10: 20 73 69 6e 63 65 20 74 68 65 20 0a 20 20 20 20   since the .    
3a20: 2a 2a 20 63 61 6c 6c 20 68 61 73 20 74 6f 20 72  ** call has to r
3a30: 65 61 64 20 61 6e 64 20 63 68 65 63 6b 73 75 6d  ead and checksum
3a40: 20 61 20 73 6e 61 70 73 68 6f 74 20 66 72 6f 6d   a snapshot from
3a50: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 66 69   the database fi
3a60: 6c 65 2c 0a 20 20 20 20 2a 2a 20 69 74 20 69 73  le,.    ** it is
3a70: 20 65 78 70 65 6e 73 69 76 65 2e 20 49 74 20 77   expensive. It w
3a80: 6f 75 6c 64 20 62 65 20 62 65 74 74 65 72 20 74  ould be better t
3a90: 6f 20 66 69 67 75 72 65 20 6f 75 74 20 61 20 77  o figure out a w
3aa0: 61 79 20 73 6f 20 74 68 61 74 0a 20 20 20 20 2a  ay so that.    *
3ab0: 2a 20 74 68 69 73 20 69 73 20 6f 6e 6c 79 20 63  * this is only c
3ac0: 61 6c 6c 65 64 20 6f 63 63 61 73 69 6f 6e 61 6c  alled occasional
3ad0: 6c 79 20 2d 20 73 61 79 20 66 6f 72 20 65 76 65  ly - say for eve
3ae0: 72 79 20 33 32 4b 42 20 77 72 69 74 74 65 6e 20  ry 32KB written 
3af0: 74 6f 20 0a 20 20 20 20 2a 2a 20 74 68 65 20 6c  to .    ** the l
3b00: 6f 67 20 66 69 6c 65 2e 0a 20 20 20 20 2a 2f 0a  og file..    */.
3b10: 20 20 20 20 72 63 20 3d 20 6c 6f 67 52 65 63 6c      rc = logRecl
3b20: 61 69 6d 53 70 61 63 65 28 70 44 62 29 3b 0a 20  aimSpace(pDb);. 
3b30: 20 7d 0a 20 20 69 66 28 20 72 63 21 3d 4c 53 4d   }.  if( rc!=LSM
3b40: 5f 4f 4b 20 29 7b 0a 20 20 20 20 6c 73 6d 4c 6f  _OK ){.    lsmLo
3b50: 67 43 6c 6f 73 65 28 70 44 62 29 3b 0a 20 20 20  gClose(pDb);.   
3b60: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
3b70: 0a 20 20 2f 2a 20 53 65 74 20 74 68 65 20 65 66  .  /* Set the ef
3b80: 66 65 63 74 69 76 65 20 73 65 63 74 6f 72 2d 73  fective sector-s
3b90: 69 7a 65 20 66 6f 72 20 74 68 69 73 20 74 72 61  ize for this tra
3ba0: 6e 73 61 63 74 69 6f 6e 2e 20 53 65 63 74 6f 72  nsaction. Sector
3bb0: 73 20 61 72 65 20 61 73 73 75 6d 65 64 0a 20 20  s are assumed.  
3bc0: 2a 2a 20 74 6f 20 62 65 20 6f 6e 65 20 62 79 74  ** to be one byt
3bd0: 65 20 69 6e 20 73 69 7a 65 20 69 66 20 74 68 65  e in size if the
3be0: 20 73 61 66 65 74 79 2d 6d 6f 64 65 20 69 73 20   safety-mode is 
3bf0: 4f 46 46 20 6f 72 20 4e 4f 52 4d 41 4c 2c 20 6f  OFF or NORMAL, o
3c00: 72 20 61 73 0a 20 20 2a 2a 20 72 65 70 6f 72 74  r as.  ** report
3c10: 65 64 20 62 79 20 6c 73 6d 46 73 53 65 63 74 6f  ed by lsmFsSecto
3c20: 72 53 69 7a 65 20 69 66 20 69 74 20 69 73 20 46  rSize if it is F
3c30: 55 4c 4c 2e 20 20 2a 2f 0a 20 20 69 66 28 20 70  ULL.  */.  if( p
3c40: 44 62 2d 3e 65 53 61 66 65 74 79 3d 3d 4c 53 4d  Db->eSafety==LSM
3c50: 5f 53 41 46 45 54 59 5f 46 55 4c 4c 20 29 7b 0a  _SAFETY_FULL ){.
3c60: 20 20 20 20 70 4e 65 77 2d 3e 73 7a 53 65 63 74      pNew->szSect
3c70: 6f 72 20 3d 20 6c 73 6d 46 73 53 65 63 74 6f 72  or = lsmFsSector
3c80: 53 69 7a 65 28 70 44 62 2d 3e 70 46 53 29 3b 0a  Size(pDb->pFS);.
3c90: 20 20 20 20 61 73 73 65 72 74 28 20 70 4e 65 77      assert( pNew
3ca0: 2d 3e 73 7a 53 65 63 74 6f 72 3e 30 20 29 3b 0a  ->szSector>0 );.
3cb0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 4e 65    }else{.    pNe
3cc0: 77 2d 3e 73 7a 53 65 63 74 6f 72 20 3d 20 31 3b  w->szSector = 1;
3cd0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 54 68 65 72 65  .  }..  /* There
3ce0: 20 61 72 65 20 6e 6f 77 20 74 68 72 65 65 20 73   are now three s
3cf0: 63 65 6e 61 72 69 6f 73 3a 0a 20 20 2a 2a 0a 20  cenarios:.  **. 
3d00: 20 2a 2a 20 20 20 31 29 20 52 65 67 69 6f 6e 73   **   1) Regions
3d10: 20 30 20 61 6e 64 20 31 20 61 72 65 20 62 6f 74   0 and 1 are bot
3d20: 68 20 7a 65 72 6f 20 62 79 74 65 73 20 69 6e 20  h zero bytes in 
3d30: 73 69 7a 65 20 61 6e 64 20 72 65 67 69 6f 6e 20  size and region 
3d40: 32 20 62 65 67 69 6e 73 0a 20 20 2a 2a 20 20 20  2 begins.  **   
3d50: 20 20 20 61 74 20 61 20 66 69 6c 65 20 6f 66 66     at a file off
3d60: 73 65 74 20 67 72 65 61 74 65 72 20 74 68 61 6e  set greater than
3d70: 20 4c 53 4d 5f 4d 49 4e 5f 4c 4f 47 57 52 41 50   LSM_MIN_LOGWRAP
3d80: 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 2c 20  . In this case, 
3d90: 77 72 61 70 0a 20 20 2a 2a 20 20 20 20 20 20 61  wrap.  **      a
3da0: 72 6f 75 6e 64 20 74 6f 20 74 68 65 20 73 74 61  round to the sta
3db0: 72 74 20 61 6e 64 20 77 72 69 74 65 20 64 61 74  rt and write dat
3dc0: 61 20 69 6e 74 6f 20 74 68 65 20 73 74 61 72 74  a into the start
3dd0: 20 6f 66 20 74 68 65 20 6c 6f 67 20 66 69 6c 65   of the log file
3de0: 2e 20 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20 32  . .  **.  **   2
3df0: 29 20 52 65 67 69 6f 6e 20 31 20 69 73 20 7a 65  ) Region 1 is ze
3e00: 72 6f 20 62 79 74 65 73 20 69 6e 20 73 69 7a 65  ro bytes in size
3e10: 20 61 6e 64 20 72 65 67 69 6f 6e 20 32 20 6f 63   and region 2 oc
3e20: 63 75 72 73 20 65 61 72 6c 69 65 72 20 69 6e 20  curs earlier in 
3e30: 74 68 65 20 0a 20 20 2a 2a 20 20 20 20 20 20 66  the .  **      f
3e40: 69 6c 65 20 74 68 61 6e 20 72 65 67 69 6f 6e 20  ile than region 
3e50: 30 2e 20 49 6e 20 74 68 69 73 20 63 61 73 65 2c  0. In this case,
3e60: 20 61 70 70 65 6e 64 20 64 61 74 61 20 74 6f 20   append data to 
3e70: 72 65 67 69 6f 6e 20 32 2c 20 62 75 74 0a 20 20  region 2, but.  
3e80: 2a 2a 20 20 20 20 20 20 72 65 6d 65 6d 62 65 72  **      remember
3e90: 20 74 6f 20 6a 75 6d 70 20 6f 76 65 72 20 72 65   to jump over re
3ea0: 67 69 6f 6e 20 31 20 69 66 20 72 65 71 75 69 72  gion 1 if requir
3eb0: 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  ed..  **.  **   
3ec0: 33 29 20 52 65 67 69 6f 6e 20 32 20 69 73 20 74  3) Region 2 is t
3ed0: 68 65 20 6c 61 73 74 20 69 6e 20 74 68 65 20 66  he last in the f
3ee0: 69 6c 65 2e 20 41 70 70 65 6e 64 20 74 6f 20 69  ile. Append to i
3ef0: 74 2e 0a 20 20 2a 2f 0a 20 20 61 52 65 67 20 3d  t..  */.  aReg =
3f00: 20 26 70 44 62 2d 3e 74 72 65 65 68 64 72 2e 6c   &pDb->treehdr.l
3f10: 6f 67 2e 61 52 65 67 69 6f 6e 5b 30 5d 3b 0a 0a  og.aRegion[0];..
3f20: 20 20 61 73 73 65 72 74 28 20 61 52 65 67 5b 30    assert( aReg[0
3f30: 5d 2e 69 45 6e 64 3d 3d 30 20 7c 7c 20 61 52 65  ].iEnd==0 || aRe
3f40: 67 5b 30 5d 2e 69 45 6e 64 3e 61 52 65 67 5b 30  g[0].iEnd>aReg[0
3f50: 5d 2e 69 53 74 61 72 74 20 29 3b 0a 20 20 61 73  ].iStart );.  as
3f60: 73 65 72 74 28 20 61 52 65 67 5b 31 5d 2e 69 45  sert( aReg[1].iE
3f70: 6e 64 3d 3d 30 20 7c 7c 20 61 52 65 67 5b 31 5d  nd==0 || aReg[1]
3f80: 2e 69 45 6e 64 3e 61 52 65 67 5b 31 5d 2e 69 53  .iEnd>aReg[1].iS
3f90: 74 61 72 74 20 29 3b 0a 0a 20 20 70 4e 65 77 2d  tart );..  pNew-
3fa0: 3e 63 6b 73 75 6d 30 20 3d 20 70 44 62 2d 3e 74  >cksum0 = pDb->t
3fb0: 72 65 65 68 64 72 2e 6c 6f 67 2e 63 6b 73 75 6d  reehdr.log.cksum
3fc0: 30 3b 0a 20 20 70 4e 65 77 2d 3e 63 6b 73 75 6d  0;.  pNew->cksum
3fd0: 31 20 3d 20 70 44 62 2d 3e 74 72 65 65 68 64 72  1 = pDb->treehdr
3fe0: 2e 6c 6f 67 2e 63 6b 73 75 6d 31 3b 0a 0a 20 20  .log.cksum1;..  
3ff0: 69 66 28 20 61 52 65 67 5b 30 5d 2e 69 45 6e 64  if( aReg[0].iEnd
4000: 3d 3d 30 20 26 26 20 61 52 65 67 5b 31 5d 2e 69  ==0 && aReg[1].i
4010: 45 6e 64 3d 3d 30 20 26 26 20 61 52 65 67 5b 32  End==0 && aReg[2
4020: 5d 2e 69 53 74 61 72 74 3e 3d 4c 53 4d 5f 4d 49  ].iStart>=LSM_MI
4030: 4e 5f 4c 4f 47 57 52 41 50 20 29 7b 0a 20 20 20  N_LOGWRAP ){.   
4040: 20 2f 2a 20 43 61 73 65 20 31 2e 20 57 72 61 70   /* Case 1. Wrap
4050: 20 61 72 6f 75 6e 64 20 74 6f 20 74 68 65 20 73   around to the s
4060: 74 61 72 74 20 6f 66 20 74 68 65 20 66 69 6c 65  tart of the file
4070: 2e 20 57 72 69 74 65 20 61 6e 20 4c 53 4d 5f 4c  . Write an LSM_L
4080: 4f 47 5f 4a 55 4d 50 20 0a 20 20 20 20 2a 2a 20  OG_JUMP .    ** 
4090: 69 6e 74 6f 20 74 68 65 20 6c 6f 67 20 66 69 6c  into the log fil
40a0: 65 20 69 6e 20 74 68 69 73 20 63 61 73 65 2e 20  e in this case. 
40b0: 50 61 64 20 69 74 20 6f 75 74 20 74 6f 20 38 20  Pad it out to 8 
40c0: 62 79 74 65 73 20 75 73 69 6e 67 20 61 20 50 41  bytes using a PA
40d0: 44 32 0a 20 20 20 20 2a 2a 20 72 65 63 6f 72 64  D2.    ** record
40e0: 20 73 6f 20 74 68 61 74 20 74 68 65 20 63 68 65   so that the che
40f0: 63 6b 73 75 6d 73 20 63 61 6e 20 62 65 20 75 70  cksums can be up
4100: 64 61 74 65 64 20 69 6d 6d 65 64 69 61 74 65 6c  dated immediatel
4110: 79 2e 20 20 2a 2f 0a 20 20 20 20 75 38 20 61 4a  y.  */.    u8 aJ
4120: 75 6d 70 5b 5d 20 3d 20 7b 20 0a 20 20 20 20 20  ump[] = { .     
4130: 20 4c 53 4d 5f 4c 4f 47 5f 50 41 44 32 2c 20 30   LSM_LOG_PAD2, 0
4140: 78 30 34 2c 20 30 78 30 30 2c 20 30 78 30 30 2c  x04, 0x00, 0x00,
4150: 20 30 78 30 30 2c 20 30 78 30 30 2c 20 4c 53 4d   0x00, 0x00, LSM
4160: 5f 4c 4f 47 5f 4a 55 4d 50 2c 20 30 78 30 30 20  _LOG_JUMP, 0x00 
4170: 0a 20 20 20 20 7d 3b 0a 0a 20 20 20 20 6c 73 6d  .    };..    lsm
4180: 53 74 72 69 6e 67 42 69 6e 41 70 70 65 6e 64 28  StringBinAppend(
4190: 26 70 4e 65 77 2d 3e 62 75 66 2c 20 61 4a 75 6d  &pNew->buf, aJum
41a0: 70 2c 20 73 69 7a 65 6f 66 28 61 4a 75 6d 70 29  p, sizeof(aJump)
41b0: 29 3b 0a 20 20 20 20 6c 6f 67 55 70 64 61 74 65  );.    logUpdate
41c0: 43 6b 73 75 6d 28 70 4e 65 77 2c 20 70 4e 65 77  Cksum(pNew, pNew
41d0: 2d 3e 62 75 66 2e 6e 29 3b 0a 20 20 20 20 72 63  ->buf.n);.    rc
41e0: 20 3d 20 6c 73 6d 46 73 57 72 69 74 65 4c 6f 67   = lsmFsWriteLog
41f0: 28 70 44 62 2d 3e 70 46 53 2c 20 61 52 65 67 5b  (pDb->pFS, aReg[
4200: 32 5d 2e 69 45 6e 64 2c 20 26 70 4e 65 77 2d 3e  2].iEnd, &pNew->
4210: 62 75 66 29 3b 0a 20 20 20 20 70 4e 65 77 2d 3e  buf);.    pNew->
4220: 69 43 6b 73 75 6d 42 75 66 20 3d 20 70 4e 65 77  iCksumBuf = pNew
4230: 2d 3e 62 75 66 2e 6e 20 3d 20 30 3b 0a 0a 20 20  ->buf.n = 0;..  
4240: 20 20 61 52 65 67 5b 32 5d 2e 69 45 6e 64 20 2b    aReg[2].iEnd +
4250: 3d 20 38 3b 0a 20 20 20 20 70 4e 65 77 2d 3e 6a  = 8;.    pNew->j
4260: 75 6d 70 20 3d 20 61 52 65 67 5b 30 5d 20 3d 20  ump = aReg[0] = 
4270: 61 52 65 67 5b 32 5d 3b 0a 20 20 20 20 61 52 65  aReg[2];.    aRe
4280: 67 5b 32 5d 2e 69 53 74 61 72 74 20 3d 20 61 52  g[2].iStart = aR
4290: 65 67 5b 32 5d 2e 69 45 6e 64 20 3d 20 30 3b 0a  eg[2].iEnd = 0;.
42a0: 20 20 7d 65 6c 73 65 20 69 66 28 20 61 52 65 67    }else if( aReg
42b0: 5b 31 5d 2e 69 45 6e 64 3d 3d 30 20 26 26 20 61  [1].iEnd==0 && a
42c0: 52 65 67 5b 32 5d 2e 69 45 6e 64 3c 61 52 65 67  Reg[2].iEnd<aReg
42d0: 5b 30 5d 2e 69 45 6e 64 20 29 7b 0a 20 20 20 20  [0].iEnd ){.    
42e0: 2f 2a 20 43 61 73 65 20 32 2e 20 2a 2f 0a 20 20  /* Case 2. */.  
42f0: 20 20 70 4e 65 77 2d 3e 69 4f 66 66 20 3d 20 61    pNew->iOff = a
4300: 52 65 67 5b 32 5d 2e 69 45 6e 64 3b 0a 20 20 20  Reg[2].iEnd;.   
4310: 20 70 4e 65 77 2d 3e 6a 75 6d 70 20 3d 20 61 52   pNew->jump = aR
4320: 65 67 5b 30 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a  eg[0];.  }else{.
4330: 20 20 20 20 2f 2a 20 43 61 73 65 20 33 2e 20 2a      /* Case 3. *
4340: 2f 0a 20 20 20 20 61 73 73 65 72 74 28 20 61 52  /.    assert( aR
4350: 65 67 5b 32 5d 2e 69 53 74 61 72 74 3e 3d 61 52  eg[2].iStart>=aR
4360: 65 67 5b 30 5d 2e 69 45 6e 64 20 26 26 20 61 52  eg[0].iEnd && aR
4370: 65 67 5b 32 5d 2e 69 53 74 61 72 74 3e 3d 61 52  eg[2].iStart>=aR
4380: 65 67 5b 31 5d 2e 69 45 6e 64 20 29 3b 0a 20 20  eg[1].iEnd );.  
4390: 20 20 70 4e 65 77 2d 3e 69 4f 66 66 20 3d 20 61    pNew->iOff = a
43a0: 52 65 67 5b 32 5d 2e 69 45 6e 64 3b 0a 20 20 7d  Reg[2].iEnd;.  }
43b0: 0a 0a 20 20 69 66 28 20 70 4e 65 77 2d 3e 6a 75  ..  if( pNew->ju
43c0: 6d 70 2e 69 53 74 61 72 74 20 29 7b 0a 20 20 20  mp.iStart ){.   
43d0: 20 69 36 34 20 69 52 6f 75 6e 64 3b 0a 20 20 20   i64 iRound;.   
43e0: 20 61 73 73 65 72 74 28 20 70 4e 65 77 2d 3e 6a   assert( pNew->j
43f0: 75 6d 70 2e 69 53 74 61 72 74 3e 70 4e 65 77 2d  ump.iStart>pNew-
4400: 3e 69 4f 66 66 20 29 3b 0a 0a 20 20 20 20 69 52  >iOff );..    iR
4410: 6f 75 6e 64 20 3d 20 66 69 72 73 74 42 79 74 65  ound = firstByte
4420: 4f 6e 53 65 63 74 6f 72 28 70 4e 65 77 2c 20 70  OnSector(pNew, p
4430: 4e 65 77 2d 3e 6a 75 6d 70 2e 69 53 74 61 72 74  New->jump.iStart
4440: 29 3b 0a 20 20 20 20 69 66 28 20 69 52 6f 75 6e  );.    if( iRoun
4450: 64 3e 70 4e 65 77 2d 3e 69 4f 66 66 20 29 20 70  d>pNew->iOff ) p
4460: 4e 65 77 2d 3e 6a 75 6d 70 2e 69 53 74 61 72 74  New->jump.iStart
4470: 20 3d 20 69 52 6f 75 6e 64 3b 0a 20 20 20 20 70   = iRound;.    p
4480: 4e 65 77 2d 3e 6a 75 6d 70 2e 69 45 6e 64 20 3d  New->jump.iEnd =
4490: 20 6c 61 73 74 42 79 74 65 4f 6e 53 65 63 74 6f   lastByteOnSecto
44a0: 72 28 70 4e 65 77 2c 20 70 4e 65 77 2d 3e 6a 75  r(pNew, pNew->ju
44b0: 6d 70 2e 69 45 6e 64 29 3b 0a 20 20 7d 0a 0a 20  mp.iEnd);.  }.. 
44c0: 20 61 73 73 65 72 74 28 20 70 44 62 2d 3e 70 4c   assert( pDb->pL
44d0: 6f 67 57 72 69 74 65 72 3d 3d 70 4e 65 77 20 29  ogWriter==pNew )
44e0: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
44f0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
4500: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
4510: 77 68 65 6e 20 61 20 77 72 69 74 65 2d 74 72 61  when a write-tra
4520: 6e 73 61 63 74 69 6f 6e 20 69 73 20 62 65 69 6e  nsaction is bein
4530: 67 20 63 6c 6f 73 65 64 2e 0a 2a 2a 20 50 61 72  g closed..** Par
4540: 61 6d 65 74 65 72 20 62 43 6f 6d 6d 69 74 20 69  ameter bCommit i
4550: 73 20 74 72 75 65 20 69 66 20 74 68 65 20 74 72  s true if the tr
4560: 61 6e 73 61 63 74 69 6f 6e 20 69 73 20 62 65 69  ansaction is bei
4570: 6e 67 20 63 6f 6d 6d 69 74 74 65 64 2c 0a 2a 2a  ng committed,.**
4580: 20 6f 72 20 66 61 6c 73 65 20 6f 74 68 65 72 77   or false otherw
4590: 69 73 65 2e 20 54 68 65 20 63 61 6c 6c 65 72 20  ise. The caller 
45a0: 6d 75 73 74 20 68 6f 6c 64 20 74 68 65 20 63 6c  must hold the cl
45b0: 69 65 6e 74 2d 6d 75 74 65 78 20 74 6f 20 63 61  ient-mutex to ca
45c0: 6c 6c 0a 2a 2a 20 74 68 69 73 20 66 75 6e 63 74  ll.** this funct
45d0: 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 41 20 63 61 6c  ion..**.** A cal
45e0: 6c 20 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69  l to this functi
45f0: 6f 6e 20 64 65 6c 65 74 65 73 20 74 68 65 20 4c  on deletes the L
4600: 6f 67 57 72 69 74 65 72 20 6f 62 6a 65 63 74 20  ogWriter object 
4610: 61 6c 6c 6f 63 61 74 65 64 20 62 79 0a 2a 2a 20  allocated by.** 
4620: 6c 73 6d 4c 6f 67 42 65 67 69 6e 28 29 2e 20 49  lsmLogBegin(). I
4630: 66 20 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f  f the transactio
4640: 6e 20 69 73 20 62 65 69 6e 67 20 63 6f 6d 6d 69  n is being commi
4650: 74 74 65 64 2c 20 74 68 65 20 73 68 61 72 65 64  tted, the shared
4660: 20 73 74 61 74 65 0a 2a 2a 20 69 6e 20 2a 70 4c   state.** in *pL
4670: 6f 67 20 69 73 20 75 70 64 61 74 65 64 20 62 65  og is updated be
4680: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
4690: 2a 2f 0a 76 6f 69 64 20 6c 73 6d 4c 6f 67 45 6e  */.void lsmLogEn
46a0: 64 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 69  d(lsm_db *pDb, i
46b0: 6e 74 20 62 43 6f 6d 6d 69 74 29 7b 0a 20 20 44  nt bCommit){.  D
46c0: 62 4c 6f 67 20 2a 70 4c 6f 67 3b 0a 20 20 4c 6f  bLog *pLog;.  Lo
46d0: 67 57 72 69 74 65 72 20 2a 70 3b 0a 20 20 70 20  gWriter *p;.  p 
46e0: 3d 20 70 44 62 2d 3e 70 4c 6f 67 57 72 69 74 65  = pDb->pLogWrite
46f0: 72 3b 0a 0a 20 20 69 66 28 20 70 3d 3d 30 20 29  r;..  if( p==0 )
4700: 20 72 65 74 75 72 6e 3b 0a 20 20 70 4c 6f 67 20   return;.  pLog 
4710: 3d 20 26 70 44 62 2d 3e 74 72 65 65 68 64 72 2e  = &pDb->treehdr.
4720: 6c 6f 67 3b 0a 0a 20 20 69 66 28 20 62 43 6f 6d  log;..  if( bCom
4730: 6d 69 74 20 29 7b 0a 20 20 20 20 70 4c 6f 67 2d  mit ){.    pLog-
4740: 3e 61 52 65 67 69 6f 6e 5b 32 5d 2e 69 45 6e 64  >aRegion[2].iEnd
4750: 20 3d 20 70 2d 3e 69 4f 66 66 3b 0a 20 20 20 20   = p->iOff;.    
4760: 70 4c 6f 67 2d 3e 63 6b 73 75 6d 30 20 3d 20 70  pLog->cksum0 = p
4770: 2d 3e 63 6b 73 75 6d 30 3b 0a 20 20 20 20 70 4c  ->cksum0;.    pL
4780: 6f 67 2d 3e 63 6b 73 75 6d 31 20 3d 20 70 2d 3e  og->cksum1 = p->
4790: 63 6b 73 75 6d 31 3b 0a 20 20 20 20 69 66 28 20  cksum1;.    if( 
47a0: 70 2d 3e 69 52 65 67 69 6f 6e 31 45 6e 64 20 29  p->iRegion1End )
47b0: 7b 0a 20 20 20 20 20 20 2f 2a 20 54 68 69 73 20  {.      /* This 
47c0: 68 61 70 70 65 6e 73 20 77 68 65 6e 20 74 68 65  happens when the
47d0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 68 61 64   transaction had
47e0: 20 74 6f 20 6a 75 6d 70 20 6f 76 65 72 20 73 6f   to jump over so
47f0: 6d 65 20 6f 74 68 65 72 0a 20 20 20 20 20 20 2a  me other.      *
4800: 2a 20 70 61 72 74 20 6f 66 20 74 68 65 20 6c 6f  * part of the lo
4810: 67 2e 20 20 2a 2f 0a 20 20 20 20 20 20 61 73 73  g.  */.      ass
4820: 65 72 74 28 20 70 4c 6f 67 2d 3e 61 52 65 67 69  ert( pLog->aRegi
4830: 6f 6e 5b 31 5d 2e 69 45 6e 64 3d 3d 30 20 29 3b  on[1].iEnd==0 );
4840: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 70  .      assert( p
4850: 4c 6f 67 2d 3e 61 52 65 67 69 6f 6e 5b 32 5d 2e  Log->aRegion[2].
4860: 69 53 74 61 72 74 3c 70 2d 3e 69 52 65 67 69 6f  iStart<p->iRegio
4870: 6e 31 45 6e 64 20 29 3b 0a 20 20 20 20 20 20 70  n1End );.      p
4880: 4c 6f 67 2d 3e 61 52 65 67 69 6f 6e 5b 31 5d 2e  Log->aRegion[1].
4890: 69 53 74 61 72 74 20 3d 20 70 4c 6f 67 2d 3e 61  iStart = pLog->a
48a0: 52 65 67 69 6f 6e 5b 32 5d 2e 69 53 74 61 72 74  Region[2].iStart
48b0: 3b 0a 20 20 20 20 20 20 70 4c 6f 67 2d 3e 61 52  ;.      pLog->aR
48c0: 65 67 69 6f 6e 5b 31 5d 2e 69 45 6e 64 20 3d 20  egion[1].iEnd = 
48d0: 70 2d 3e 69 52 65 67 69 6f 6e 31 45 6e 64 3b 0a  p->iRegion1End;.
48e0: 20 20 20 20 20 20 70 4c 6f 67 2d 3e 61 52 65 67        pLog->aReg
48f0: 69 6f 6e 5b 32 5d 2e 69 53 74 61 72 74 20 3d 20  ion[2].iStart = 
4900: 70 2d 3e 69 52 65 67 69 6f 6e 32 53 74 61 72 74  p->iRegion2Start
4910: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 73  ;.    }.  }.}..s
4920: 74 61 74 69 63 20 69 6e 74 20 6a 75 6d 70 49 66  tatic int jumpIf
4930: 52 65 71 75 69 72 65 64 28 0a 20 20 6c 73 6d 5f  Required(.  lsm_
4940: 64 62 20 2a 70 44 62 2c 0a 20 20 4c 6f 67 57 72  db *pDb,.  LogWr
4950: 69 74 65 72 20 2a 70 4c 6f 67 2c 0a 20 20 69 6e  iter *pLog,.  in
4960: 74 20 6e 52 65 71 2c 0a 20 20 69 6e 74 20 2a 70  t nReq,.  int *p
4970: 62 4a 75 6d 70 0a 29 7b 0a 20 20 2f 2a 20 44 65  bJump.){.  /* De
4980: 74 65 72 6d 69 6e 65 20 69 66 20 69 74 20 69 73  termine if it is
4990: 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20 61 64   necessary to ad
49a0: 64 20 61 6e 20 4c 53 4d 5f 4c 4f 47 5f 4a 55 4d  d an LSM_LOG_JUM
49b0: 50 20 74 6f 20 6a 75 6d 70 20 6f 76 65 72 20 74  P to jump over t
49c0: 68 65 0a 20 20 2a 2a 20 6a 75 6d 70 20 72 65 67  he.  ** jump reg
49d0: 69 6f 6e 20 62 65 66 6f 72 65 20 77 72 69 74 69  ion before writi
49e0: 6e 67 20 74 68 65 20 4c 53 4d 5f 4c 4f 47 5f 57  ng the LSM_LOG_W
49f0: 52 49 54 45 20 6f 72 20 44 45 4c 45 54 45 20 72  RITE or DELETE r
4a00: 65 63 6f 72 64 2e 20 54 68 69 73 0a 20 20 2a 2a  ecord. This.  **
4a10: 20 69 73 20 6e 65 63 65 73 73 61 72 79 20 69 66   is necessary if
4a20: 20 74 68 65 72 65 20 69 73 20 69 6e 73 75 66 66   there is insuff
4a30: 69 63 69 65 6e 74 20 72 6f 6f 6d 20 62 65 74 77  icient room betw
4a40: 65 65 6e 20 74 68 65 20 63 75 72 72 65 6e 74 20  een the current 
4a50: 6f 66 66 73 65 74 0a 20 20 2a 2a 20 61 6e 64 20  offset.  ** and 
4a60: 74 68 65 20 6a 75 6d 70 20 72 65 67 69 6f 6e 20  the jump region 
4a70: 74 6f 20 66 69 74 20 74 68 65 20 6e 65 77 20 57  to fit the new W
4a80: 52 49 54 45 2f 44 45 4c 45 54 45 20 72 65 63 6f  RITE/DELETE reco
4a90: 72 64 20 61 6e 64 20 74 68 65 20 6c 61 72 67 65  rd and the large
4aa0: 73 74 0a 20 20 2a 2a 20 70 6f 73 73 69 62 6c 65  st.  ** possible
4ab0: 20 4a 55 4d 50 20 72 65 63 6f 72 64 20 77 69 74   JUMP record wit
4ac0: 68 20 75 70 20 74 6f 20 37 20 62 79 74 65 73 20  h up to 7 bytes 
4ad0: 6f 66 20 70 61 64 64 69 6e 67 20 28 61 20 74 6f  of padding (a to
4ae0: 74 61 6c 20 6f 66 20 31 37 20 0a 20 20 2a 2a 20  tal of 17 .  ** 
4af0: 62 79 74 65 73 29 2e 20 20 2a 2f 0a 20 20 69 66  bytes).  */.  if
4b00: 28 20 28 70 4c 6f 67 2d 3e 6a 75 6d 70 2e 69 53  ( (pLog->jump.iS
4b10: 74 61 72 74 20 3e 20 28 70 4c 6f 67 2d 3e 69 4f  tart > (pLog->iO
4b20: 66 66 20 2b 20 70 4c 6f 67 2d 3e 62 75 66 2e 6e  ff + pLog->buf.n
4b30: 29 29 0a 20 20 20 26 26 20 28 70 4c 6f 67 2d 3e  )).   && (pLog->
4b40: 6a 75 6d 70 2e 69 53 74 61 72 74 20 3c 20 28 70  jump.iStart < (p
4b50: 4c 6f 67 2d 3e 69 4f 66 66 20 2b 20 70 4c 6f 67  Log->iOff + pLog
4b60: 2d 3e 62 75 66 2e 6e 20 2b 20 28 6e 52 65 71 20  ->buf.n + (nReq 
4b70: 2b 20 31 37 29 29 29 20 0a 20 20 29 7b 0a 20 20  + 17))) .  ){.  
4b80: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
4b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4ba0: 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
4bb0: 2f 0a 20 20 20 20 69 36 34 20 69 4a 75 6d 70 3b  /.    i64 iJump;
4bc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4bd0: 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 74 6f      /* Offset to
4be0: 20 6a 75 6d 70 20 74 6f 20 2a 2f 0a 20 20 20 20   jump to */.    
4bf0: 75 38 20 61 4a 75 6d 70 5b 31 30 5d 3b 20 20 20  u8 aJump[10];   
4c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4c10: 20 45 6e 63 6f 64 65 64 20 6a 75 6d 70 20 72 65   Encoded jump re
4c20: 63 6f 72 64 20 2a 2f 0a 20 20 20 20 69 6e 74 20  cord */.    int 
4c30: 6e 4a 75 6d 70 3b 20 20 20 20 20 20 20 20 20 20  nJump;          
4c40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c            /* Val
4c50: 69 64 20 62 79 74 65 73 20 69 6e 20 61 4a 75 6d  id bytes in aJum
4c60: 70 5b 5d 20 2a 2f 0a 20 20 20 20 69 6e 74 20 6e  p[] */.    int n
4c70: 50 61 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  Pad;            
4c80: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65           /* Byte
4c90: 73 20 6f 66 20 70 61 64 64 69 6e 67 20 72 65 71  s of padding req
4ca0: 75 69 72 65 64 20 2a 2f 0a 0a 20 20 20 20 2f 2a  uired */..    /*
4cb0: 20 53 65 72 69 61 6c 69 7a 65 20 74 68 65 20 4a   Serialize the J
4cc0: 55 4d 50 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20  UMP record */.  
4cd0: 20 20 69 4a 75 6d 70 20 3d 20 70 4c 6f 67 2d 3e    iJump = pLog->
4ce0: 6a 75 6d 70 2e 69 45 6e 64 2b 31 3b 0a 20 20 20  jump.iEnd+1;.   
4cf0: 20 61 4a 75 6d 70 5b 30 5d 20 3d 20 4c 53 4d 5f   aJump[0] = LSM_
4d00: 4c 4f 47 5f 4a 55 4d 50 3b 0a 20 20 20 20 6e 4a  LOG_JUMP;.    nJ
4d10: 75 6d 70 20 3d 20 31 20 2b 20 6c 73 6d 56 61 72  ump = 1 + lsmVar
4d20: 69 6e 74 50 75 74 36 34 28 26 61 4a 75 6d 70 5b  intPut64(&aJump[
4d30: 31 5d 2c 20 69 4a 75 6d 70 29 3b 0a 0a 20 20 20  1], iJump);..   
4d40: 20 2f 2a 20 41 64 64 69 6e 67 20 70 61 64 64 69   /* Adding paddi
4d50: 6e 67 20 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e  ng to the conten
4d60: 74 73 20 6f 66 20 74 68 65 20 62 75 66 66 65 72  ts of the buffer
4d70: 20 73 6f 20 74 68 61 74 20 69 74 20 77 69 6c 6c   so that it will
4d80: 20 62 65 20 61 20 0a 20 20 20 20 2a 2a 20 6d 75   be a .    ** mu
4d90: 6c 74 69 70 6c 65 20 6f 66 20 38 20 62 79 74 65  ltiple of 8 byte
4da0: 73 20 69 6e 20 73 69 7a 65 20 61 66 74 65 72 20  s in size after 
4db0: 74 68 65 20 4a 55 4d 50 20 72 65 63 6f 72 64 20  the JUMP record 
4dc0: 69 73 20 61 70 70 65 6e 64 65 64 2e 20 54 68 69  is appended. Thi
4dd0: 73 0a 20 20 20 20 2a 2a 20 69 73 20 6e 6f 74 20  s.    ** is not 
4de0: 73 74 72 69 63 74 6c 79 20 72 65 71 75 69 72 65  strictly require
4df0: 64 2c 20 69 74 20 6a 75 73 74 20 6d 61 6b 65 73  d, it just makes
4e00: 20 74 68 65 20 6b 65 65 70 69 6e 67 20 74 68 65   the keeping the
4e10: 20 72 75 6e 6e 69 6e 67 20 0a 20 20 20 20 2a 2a   running .    **
4e20: 20 63 68 65 63 6b 73 75 6d 20 75 70 20 74 6f 20   checksum up to 
4e30: 64 61 74 65 20 69 6e 20 74 68 69 73 20 66 69 6c  date in this fil
4e40: 65 20 61 20 6c 69 74 74 6c 65 20 73 69 6d 70 6c  e a little simpl
4e50: 65 72 2e 20 20 2a 2f 0a 20 20 20 20 6e 50 61 64  er.  */.    nPad
4e60: 20 3d 20 28 70 4c 6f 67 2d 3e 62 75 66 2e 6e 20   = (pLog->buf.n 
4e70: 2b 20 6e 4a 75 6d 70 29 20 25 20 38 3b 0a 20 20  + nJump) % 8;.  
4e80: 20 20 69 66 28 20 6e 50 61 64 20 29 7b 0a 20 20    if( nPad ){.  
4e90: 20 20 20 20 75 38 20 61 50 61 64 5b 37 5d 20 3d      u8 aPad[7] =
4ea0: 20 7b 30 2c 30 2c 30 2c 30 2c 30 2c 30 2c 30 7d   {0,0,0,0,0,0,0}
4eb0: 3b 0a 20 20 20 20 20 20 6e 50 61 64 20 3d 20 38  ;.      nPad = 8
4ec0: 2d 6e 50 61 64 3b 0a 20 20 20 20 20 20 69 66 28  -nPad;.      if(
4ed0: 20 6e 50 61 64 3d 3d 31 20 29 7b 0a 20 20 20 20   nPad==1 ){.    
4ee0: 20 20 20 20 61 50 61 64 5b 30 5d 20 3d 20 4c 53      aPad[0] = LS
4ef0: 4d 5f 4c 4f 47 5f 50 41 44 31 3b 0a 20 20 20 20  M_LOG_PAD1;.    
4f00: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
4f10: 20 61 50 61 64 5b 30 5d 20 3d 20 4c 53 4d 5f 4c   aPad[0] = LSM_L
4f20: 4f 47 5f 50 41 44 32 3b 0a 20 20 20 20 20 20 20  OG_PAD2;.       
4f30: 20 61 50 61 64 5b 31 5d 20 3d 20 28 75 38 29 28   aPad[1] = (u8)(
4f40: 6e 50 61 64 2d 32 29 3b 0a 20 20 20 20 20 20 7d  nPad-2);.      }
4f50: 0a 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 53  .      rc = lsmS
4f60: 74 72 69 6e 67 42 69 6e 41 70 70 65 6e 64 28 26  tringBinAppend(&
4f70: 70 4c 6f 67 2d 3e 62 75 66 2c 20 61 50 61 64 2c  pLog->buf, aPad,
4f80: 20 6e 50 61 64 29 3b 0a 20 20 20 20 20 20 69 66   nPad);.      if
4f90: 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72  ( rc!=LSM_OK ) r
4fa0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
4fb0: 0a 20 20 20 20 2f 2a 20 41 70 70 65 6e 64 20 74  .    /* Append t
4fc0: 68 65 20 4a 55 4d 50 20 72 65 63 6f 72 64 20 74  he JUMP record t
4fd0: 6f 20 74 68 65 20 62 75 66 66 65 72 2e 20 54 68  o the buffer. Th
4fe0: 65 6e 20 66 6c 75 73 68 20 74 68 65 20 62 75 66  en flush the buf
4ff0: 66 65 72 20 74 6f 20 64 69 73 6b 0a 20 20 20 20  fer to disk.    
5000: 2a 2a 20 61 6e 64 20 75 70 64 61 74 65 20 74 68  ** and update th
5010: 65 20 63 68 65 63 6b 73 75 6d 73 2e 20 54 68 65  e checksums. The
5020: 20 6e 65 78 74 20 77 72 69 74 65 20 74 6f 20 74   next write to t
5030: 68 65 20 6c 6f 67 20 66 69 6c 65 20 28 61 73 73  he log file (ass
5040: 75 6d 69 6e 67 0a 20 20 20 20 2a 2a 20 74 68 65  uming.    ** the
5050: 72 65 20 69 73 20 6e 6f 20 74 72 61 6e 73 61 63  re is no transac
5060: 74 69 6f 6e 20 72 6f 6c 6c 62 61 63 6b 29 20 77  tion rollback) w
5070: 69 6c 6c 20 62 65 20 74 6f 20 6f 66 66 73 65 74  ill be to offset
5080: 20 69 4a 75 6d 70 20 28 6a 75 73 74 20 70 61 73   iJump (just pas
5090: 74 0a 20 20 20 20 2a 2a 20 74 68 65 20 6a 75 6d  t.    ** the jum
50a0: 70 20 72 65 67 69 6f 6e 29 2e 20 20 2a 2f 0a 20  p region).  */. 
50b0: 20 20 20 72 63 20 3d 20 6c 73 6d 53 74 72 69 6e     rc = lsmStrin
50c0: 67 42 69 6e 41 70 70 65 6e 64 28 26 70 4c 6f 67  gBinAppend(&pLog
50d0: 2d 3e 62 75 66 2c 20 61 4a 75 6d 70 2c 20 6e 4a  ->buf, aJump, nJ
50e0: 75 6d 70 29 3b 0a 20 20 20 20 69 66 28 20 72 63  ump);.    if( rc
50f0: 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74 75 72  !=LSM_OK ) retur
5100: 6e 20 72 63 3b 0a 20 20 20 20 61 73 73 65 72 74  n rc;.    assert
5110: 28 20 28 70 4c 6f 67 2d 3e 62 75 66 2e 6e 20 25  ( (pLog->buf.n %
5120: 20 38 29 3d 3d 30 20 29 3b 0a 20 20 20 20 72 63   8)==0 );.    rc
5130: 20 3d 20 6c 73 6d 46 73 57 72 69 74 65 4c 6f 67   = lsmFsWriteLog
5140: 28 70 44 62 2d 3e 70 46 53 2c 20 70 4c 6f 67 2d  (pDb->pFS, pLog-
5150: 3e 69 4f 66 66 2c 20 26 70 4c 6f 67 2d 3e 62 75  >iOff, &pLog->bu
5160: 66 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  f);.    if( rc!=
5170: 4c 53 4d 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20  LSM_OK ) return 
5180: 72 63 3b 0a 20 20 20 20 6c 6f 67 55 70 64 61 74  rc;.    logUpdat
5190: 65 43 6b 73 75 6d 28 70 4c 6f 67 2c 20 70 4c 6f  eCksum(pLog, pLo
51a0: 67 2d 3e 62 75 66 2e 6e 29 3b 0a 20 20 20 20 70  g->buf.n);.    p
51b0: 4c 6f 67 2d 3e 69 52 65 67 69 6f 6e 31 45 6e 64  Log->iRegion1End
51c0: 20 3d 20 28 70 4c 6f 67 2d 3e 69 4f 66 66 20 2b   = (pLog->iOff +
51d0: 20 70 4c 6f 67 2d 3e 62 75 66 2e 6e 29 3b 0a 20   pLog->buf.n);. 
51e0: 20 20 20 70 4c 6f 67 2d 3e 69 52 65 67 69 6f 6e     pLog->iRegion
51f0: 32 53 74 61 72 74 20 3d 20 69 4a 75 6d 70 3b 0a  2Start = iJump;.
5200: 20 20 20 20 70 4c 6f 67 2d 3e 69 4f 66 66 20 3d      pLog->iOff =
5210: 20 69 4a 75 6d 70 3b 0a 20 20 20 20 70 4c 6f 67   iJump;.    pLog
5220: 2d 3e 69 43 6b 73 75 6d 42 75 66 20 3d 20 70 4c  ->iCksumBuf = pL
5230: 6f 67 2d 3e 62 75 66 2e 6e 20 3d 20 30 3b 0a 20  og->buf.n = 0;. 
5240: 20 20 20 69 66 28 20 70 62 4a 75 6d 70 20 29 20     if( pbJump ) 
5250: 2a 70 62 4a 75 6d 70 20 3d 20 31 3b 0a 20 20 7d  *pbJump = 1;.  }
5260: 0a 0a 20 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f  ..  return LSM_O
5270: 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  K;.}..static int
5280: 20 6c 6f 67 43 6b 73 75 6d 41 6e 64 46 6c 75 73   logCksumAndFlus
5290: 68 28 6c 73 6d 5f 64 62 20 2a 70 44 62 29 7b 0a  h(lsm_db *pDb){.
52a0: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
52b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
52c0: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
52d0: 20 2a 2f 0a 20 20 4c 6f 67 57 72 69 74 65 72 20   */.  LogWriter 
52e0: 2a 70 4c 6f 67 20 3d 20 70 44 62 2d 3e 70 4c 6f  *pLog = pDb->pLo
52f0: 67 57 72 69 74 65 72 3b 0a 0a 20 20 2f 2a 20 43  gWriter;..  /* C
5300: 61 6c 63 75 6c 61 74 65 20 74 68 65 20 63 68 65  alculate the che
5310: 63 6b 73 75 6d 20 76 61 6c 75 65 2e 20 41 70 70  cksum value. App
5320: 65 6e 64 20 69 74 20 74 6f 20 74 68 65 20 62 75  end it to the bu
5330: 66 66 65 72 2e 20 2a 2f 0a 20 20 6c 6f 67 55 70  ffer. */.  logUp
5340: 64 61 74 65 43 6b 73 75 6d 28 70 4c 6f 67 2c 20  dateCksum(pLog, 
5350: 70 4c 6f 67 2d 3e 62 75 66 2e 6e 29 3b 0a 20 20  pLog->buf.n);.  
5360: 6c 73 6d 50 75 74 55 33 32 28 28 75 38 20 2a 29  lsmPutU32((u8 *)
5370: 26 70 4c 6f 67 2d 3e 62 75 66 2e 7a 5b 70 4c 6f  &pLog->buf.z[pLo
5380: 67 2d 3e 62 75 66 2e 6e 5d 2c 20 70 4c 6f 67 2d  g->buf.n], pLog-
5390: 3e 63 6b 73 75 6d 30 29 3b 0a 20 20 70 4c 6f 67  >cksum0);.  pLog
53a0: 2d 3e 62 75 66 2e 6e 20 2b 3d 20 34 3b 0a 20 20  ->buf.n += 4;.  
53b0: 6c 73 6d 50 75 74 55 33 32 28 28 75 38 20 2a 29  lsmPutU32((u8 *)
53c0: 26 70 4c 6f 67 2d 3e 62 75 66 2e 7a 5b 70 4c 6f  &pLog->buf.z[pLo
53d0: 67 2d 3e 62 75 66 2e 6e 5d 2c 20 70 4c 6f 67 2d  g->buf.n], pLog-
53e0: 3e 63 6b 73 75 6d 31 29 3b 0a 20 20 70 4c 6f 67  >cksum1);.  pLog
53f0: 2d 3e 62 75 66 2e 6e 20 2b 3d 20 34 3b 0a 0a 20  ->buf.n += 4;.. 
5400: 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 63 6f   /* Write the co
5410: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 62 75  ntents of the bu
5420: 66 66 65 72 20 74 6f 20 64 69 73 6b 2e 20 2a 2f  ffer to disk. */
5430: 0a 20 20 72 63 20 3d 20 6c 73 6d 46 73 57 72 69  .  rc = lsmFsWri
5440: 74 65 4c 6f 67 28 70 44 62 2d 3e 70 46 53 2c 20  teLog(pDb->pFS, 
5450: 70 4c 6f 67 2d 3e 69 4f 66 66 2c 20 26 70 4c 6f  pLog->iOff, &pLo
5460: 67 2d 3e 62 75 66 29 3b 0a 20 20 70 4c 6f 67 2d  g->buf);.  pLog-
5470: 3e 69 4f 66 66 20 2b 3d 20 70 4c 6f 67 2d 3e 62  >iOff += pLog->b
5480: 75 66 2e 6e 3b 0a 20 20 70 4c 6f 67 2d 3e 69 43  uf.n;.  pLog->iC
5490: 6b 73 75 6d 42 75 66 20 3d 20 70 4c 6f 67 2d 3e  ksumBuf = pLog->
54a0: 62 75 66 2e 6e 20 3d 20 30 3b 0a 0a 20 20 72 65  buf.n = 0;..  re
54b0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
54c0: 2a 20 57 72 69 74 65 20 74 68 65 20 63 6f 6e 74  * Write the cont
54d0: 65 6e 74 73 20 6f 66 20 74 68 65 20 6c 6f 67 2d  ents of the log-
54e0: 62 75 66 66 65 72 20 74 6f 20 64 69 73 6b 2e 20  buffer to disk. 
54f0: 54 68 65 6e 20 77 72 69 74 65 20 65 69 74 68 65  Then write eithe
5500: 72 20 61 20 43 4b 53 55 4d 0a 2a 2a 20 6f 72 20  r a CKSUM.** or 
5510: 43 4f 4d 4d 49 54 20 72 65 63 6f 72 64 2c 20 64  COMMIT record, d
5520: 65 70 65 6e 64 69 6e 67 20 6f 6e 20 74 68 65 20  epending on the 
5530: 76 61 6c 75 65 20 6f 66 20 70 61 72 61 6d 65 74  value of paramet
5540: 65 72 20 65 54 79 70 65 2e 0a 2a 2f 0a 73 74 61  er eType..*/.sta
5550: 74 69 63 20 69 6e 74 20 6c 6f 67 46 6c 75 73 68  tic int logFlush
5560: 28 6c 73 6d 5f 64 62 20 2a 70 44 62 2c 20 69 6e  (lsm_db *pDb, in
5570: 74 20 65 54 79 70 65 29 7b 0a 20 20 69 6e 74 20  t eType){.  int 
5580: 72 63 3b 0a 20 20 69 6e 74 20 6e 52 65 71 3b 0a  rc;.  int nReq;.
5590: 20 20 4c 6f 67 57 72 69 74 65 72 20 2a 70 4c 6f    LogWriter *pLo
55a0: 67 20 3d 20 70 44 62 2d 3e 70 4c 6f 67 57 72 69  g = pDb->pLogWri
55b0: 74 65 72 3b 0a 20 20 0a 20 20 61 73 73 65 72 74  ter;.  .  assert
55c0: 28 20 65 54 79 70 65 3d 3d 4c 53 4d 5f 4c 4f 47  ( eType==LSM_LOG
55d0: 5f 43 4f 4d 4d 49 54 20 29 3b 0a 20 20 61 73 73  _COMMIT );.  ass
55e0: 65 72 74 28 20 70 4c 6f 67 20 29 3b 0a 0a 20 20  ert( pLog );..  
55f0: 2f 2a 20 43 6f 6d 6d 69 74 20 72 65 63 6f 72 64  /* Commit record
5600: 20 69 73 20 61 6c 77 61 79 73 20 39 20 62 79 74   is always 9 byt
5610: 65 73 20 69 6e 20 73 69 7a 65 2e 20 2a 2f 0a 20  es in size. */. 
5620: 20 6e 52 65 71 20 3d 20 39 3b 0a 20 20 69 66 28   nReq = 9;.  if(
5630: 20 65 54 79 70 65 3d 3d 4c 53 4d 5f 4c 4f 47 5f   eType==LSM_LOG_
5640: 43 4f 4d 4d 49 54 20 26 26 20 70 4c 6f 67 2d 3e  COMMIT && pLog->
5650: 73 7a 53 65 63 74 6f 72 3e 31 20 29 20 6e 52 65  szSector>1 ) nRe
5660: 71 20 2b 3d 20 70 4c 6f 67 2d 3e 73 7a 53 65 63  q += pLog->szSec
5670: 74 6f 72 20 2b 20 31 37 3b 0a 20 20 72 63 20 3d  tor + 17;.  rc =
5680: 20 6a 75 6d 70 49 66 52 65 71 75 69 72 65 64 28   jumpIfRequired(
5690: 70 44 62 2c 20 70 4c 6f 67 2c 20 6e 52 65 71 2c  pDb, pLog, nReq,
56a0: 20 30 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68   0);..  /* If th
56b0: 69 73 20 69 73 20 61 20 43 4f 4d 4d 49 54 2c 20  is is a COMMIT, 
56c0: 61 64 64 20 70 61 64 64 69 6e 67 20 74 6f 20 74  add padding to t
56d0: 68 65 20 6c 6f 67 20 73 6f 20 74 68 61 74 20 74  he log so that t
56e0: 68 65 20 43 4f 4d 4d 49 54 20 72 65 63 6f 72 64  he COMMIT record
56f0: 0a 20 20 2a 2a 20 69 73 20 61 6c 69 67 6e 65 64  .  ** is aligned
5700: 20 61 67 61 69 6e 73 74 20 74 68 65 20 65 6e 64   against the end
5710: 20 6f 66 20 61 20 64 69 73 6b 20 73 65 63 74 6f   of a disk secto
5720: 72 2e 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64  r. In other word
5730: 73 2c 20 61 64 64 20 70 61 64 64 69 6e 67 0a 20  s, add padding. 
5740: 20 2a 2a 20 73 6f 20 74 68 61 74 20 74 68 65 20   ** so that the 
5750: 66 69 72 73 74 20 62 79 74 65 20 66 6f 6c 6c 6f  first byte follo
5760: 77 69 6e 67 20 74 68 65 20 43 4f 4d 4d 49 54 20  wing the COMMIT 
5770: 72 65 63 6f 72 64 20 6c 69 65 73 20 6f 6e 20 61  record lies on a
5780: 20 64 69 66 66 65 72 65 6e 74 0a 20 20 2a 2a 20   different.  ** 
5790: 73 65 63 74 6f 72 2e 20 20 2a 2f 0a 20 20 69 66  sector.  */.  if
57a0: 28 20 65 54 79 70 65 3d 3d 4c 53 4d 5f 4c 4f 47  ( eType==LSM_LOG
57b0: 5f 43 4f 4d 4d 49 54 20 26 26 20 70 4c 6f 67 2d  _COMMIT && pLog-
57c0: 3e 73 7a 53 65 63 74 6f 72 3e 31 20 29 7b 0a 20  >szSector>1 ){. 
57d0: 20 20 20 69 6e 74 20 6e 50 61 64 3b 20 20 20 20     int nPad;    
57e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57f0: 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 70 61 64   /* Bytes of pad
5800: 64 69 6e 67 20 74 6f 20 61 64 64 20 2a 2f 0a 0a  ding to add */..
5810: 20 20 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65      /* Determine
5820: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 6e 50   the value of nP
5830: 61 64 2e 20 2a 2f 0a 20 20 20 20 6e 50 61 64 20  ad. */.    nPad 
5840: 3d 20 28 28 70 4c 6f 67 2d 3e 69 4f 66 66 20 2b  = ((pLog->iOff +
5850: 20 70 4c 6f 67 2d 3e 62 75 66 2e 6e 20 2b 20 39   pLog->buf.n + 9
5860: 29 20 25 20 70 4c 6f 67 2d 3e 73 7a 53 65 63 74  ) % pLog->szSect
5870: 6f 72 29 3b 0a 20 20 20 20 69 66 28 20 6e 50 61  or);.    if( nPa
5880: 64 20 29 20 6e 50 61 64 20 3d 20 70 4c 6f 67 2d  d ) nPad = pLog-
5890: 3e 73 7a 53 65 63 74 6f 72 20 2d 20 6e 50 61 64  >szSector - nPad
58a0: 3b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 53 74  ;.    rc = lsmSt
58b0: 72 69 6e 67 45 78 74 65 6e 64 28 26 70 4c 6f 67  ringExtend(&pLog
58c0: 2d 3e 62 75 66 2c 20 6e 50 61 64 29 3b 0a 20 20  ->buf, nPad);.  
58d0: 20 20 69 66 28 20 72 63 21 3d 4c 53 4d 5f 4f 4b    if( rc!=LSM_OK
58e0: 20 29 20 72 65 74 75 72 6e 20 72 63 3b 0a 0a 20   ) return rc;.. 
58f0: 20 20 20 77 68 69 6c 65 28 20 6e 50 61 64 20 29     while( nPad )
5900: 7b 0a 20 20 20 20 20 20 69 66 28 20 6e 50 61 64  {.      if( nPad
5910: 3d 3d 31 20 29 7b 0a 20 20 20 20 20 20 20 20 70  ==1 ){.        p
5920: 4c 6f 67 2d 3e 62 75 66 2e 7a 5b 70 4c 6f 67 2d  Log->buf.z[pLog-
5930: 3e 62 75 66 2e 6e 2b 2b 5d 20 3d 20 4c 53 4d 5f  >buf.n++] = LSM_
5940: 4c 4f 47 5f 50 41 44 31 3b 0a 20 20 20 20 20 20  LOG_PAD1;.      
5950: 20 20 6e 50 61 64 20 3d 20 30 3b 0a 20 20 20 20    nPad = 0;.    
5960: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
5970: 20 69 6e 74 20 6e 20 3d 20 4c 53 4d 5f 4d 49 4e   int n = LSM_MIN
5980: 28 32 30 30 2c 20 6e 50 61 64 2d 32 29 3b 0a 20  (200, nPad-2);. 
5990: 20 20 20 20 20 20 20 70 4c 6f 67 2d 3e 62 75 66         pLog->buf
59a0: 2e 7a 5b 70 4c 6f 67 2d 3e 62 75 66 2e 6e 2b 2b  .z[pLog->buf.n++
59b0: 5d 20 3d 20 4c 53 4d 5f 4c 4f 47 5f 50 41 44 32  ] = LSM_LOG_PAD2
59c0: 3b 0a 20 20 20 20 20 20 20 20 70 4c 6f 67 2d 3e  ;.        pLog->
59d0: 62 75 66 2e 7a 5b 70 4c 6f 67 2d 3e 62 75 66 2e  buf.z[pLog->buf.
59e0: 6e 2b 2b 5d 20 3d 20 28 63 68 61 72 29 6e 3b 0a  n++] = (char)n;.
59f0: 20 20 20 20 20 20 20 20 6e 50 61 64 20 2d 3d 20          nPad -= 
5a00: 32 3b 0a 20 20 20 20 20 20 20 20 6d 65 6d 73 65  2;.        memse
5a10: 74 28 26 70 4c 6f 67 2d 3e 62 75 66 2e 7a 5b 70  t(&pLog->buf.z[p
5a20: 4c 6f 67 2d 3e 62 75 66 2e 6e 5d 2c 20 30 78 32  Log->buf.n], 0x2
5a30: 42 2c 20 6e 29 3b 0a 20 20 20 20 20 20 20 20 70  B, n);.        p
5a40: 4c 6f 67 2d 3e 62 75 66 2e 6e 20 2b 3d 20 6e 3b  Log->buf.n += n;
5a50: 0a 20 20 20 20 20 20 20 20 6e 50 61 64 20 2d 3d  .        nPad -=
5a60: 20 6e 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   n;.      }.    
5a70: 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4d 61 6b 65  }.  }..  /* Make
5a80: 20 73 75 72 65 20 74 68 65 72 65 20 69 73 20 72   sure there is r
5a90: 6f 6f 6d 20 69 6e 20 74 68 65 20 6c 6f 67 2d 62  oom in the log-b
5aa0: 75 66 66 65 72 20 74 6f 20 61 64 64 20 74 68 65  uffer to add the
5ab0: 20 43 4b 53 55 4d 20 6f 72 20 43 4f 4d 4d 49 54   CKSUM or COMMIT
5ac0: 0a 20 20 2a 2a 20 72 65 63 6f 72 64 2e 20 54 68  .  ** record. Th
5ad0: 65 6e 20 61 64 64 20 74 68 65 20 66 69 72 73 74  en add the first
5ae0: 20 62 79 74 65 20 6f 66 20 69 74 2e 20 20 2a 2f   byte of it.  */
5af0: 0a 20 20 72 63 20 3d 20 6c 73 6d 53 74 72 69 6e  .  rc = lsmStrin
5b00: 67 45 78 74 65 6e 64 28 26 70 4c 6f 67 2d 3e 62  gExtend(&pLog->b
5b10: 75 66 2c 20 39 29 3b 0a 20 20 69 66 28 20 72 63  uf, 9);.  if( rc
5b20: 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65 74 75 72  !=LSM_OK ) retur
5b30: 6e 20 72 63 3b 0a 20 20 70 4c 6f 67 2d 3e 62 75  n rc;.  pLog->bu
5b40: 66 2e 7a 5b 70 4c 6f 67 2d 3e 62 75 66 2e 6e 2b  f.z[pLog->buf.n+
5b50: 2b 5d 20 3d 20 28 63 68 61 72 29 65 54 79 70 65  +] = (char)eType
5b60: 3b 0a 20 20 6d 65 6d 73 65 74 28 26 70 4c 6f 67  ;.  memset(&pLog
5b70: 2d 3e 62 75 66 2e 7a 5b 70 4c 6f 67 2d 3e 62 75  ->buf.z[pLog->bu
5b80: 66 2e 6e 5d 2c 20 30 2c 20 38 29 3b 0a 0a 20 20  f.n], 0, 8);..  
5b90: 72 63 20 3d 20 6c 6f 67 43 6b 73 75 6d 41 6e 64  rc = logCksumAnd
5ba0: 46 6c 75 73 68 28 70 44 62 29 3b 0a 0a 20 20 2f  Flush(pDb);..  /
5bb0: 2a 20 49 66 20 74 68 69 73 20 69 73 20 61 20 63  * If this is a c
5bc0: 6f 6d 6d 69 74 20 61 6e 64 20 73 79 6e 63 68 72  ommit and synchr
5bd0: 6f 6e 6f 75 73 3d 66 75 6c 6c 2c 20 73 79 6e 63  onous=full, sync
5be0: 20 74 68 65 20 6c 6f 67 20 74 6f 20 64 69 73 6b   the log to disk
5bf0: 2e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 4c  . */.  if( rc==L
5c00: 53 4d 5f 4f 4b 20 26 26 20 65 54 79 70 65 3d 3d  SM_OK && eType==
5c10: 4c 53 4d 5f 4c 4f 47 5f 43 4f 4d 4d 49 54 20 26  LSM_LOG_COMMIT &
5c20: 26 20 70 44 62 2d 3e 65 53 61 66 65 74 79 3d 3d  & pDb->eSafety==
5c30: 4c 53 4d 5f 53 41 46 45 54 59 5f 46 55 4c 4c 20  LSM_SAFETY_FULL 
5c40: 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 46  ){.    rc = lsmF
5c50: 73 53 79 6e 63 4c 6f 67 28 70 44 62 2d 3e 70 46  sSyncLog(pDb->pF
5c60: 53 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  S);.  }.  return
5c70: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70   rc;.}../*.** Ap
5c80: 70 65 6e 64 20 61 6e 20 4c 53 4d 5f 4c 4f 47 5f  pend an LSM_LOG_
5c90: 57 52 49 54 45 20 28 69 66 20 6e 56 61 6c 3e 3d  WRITE (if nVal>=
5ca0: 30 29 20 6f 72 20 4c 53 4d 5f 4c 4f 47 5f 44 45  0) or LSM_LOG_DE
5cb0: 4c 45 54 45 20 28 69 66 20 6e 56 61 6c 3c 30 29  LETE (if nVal<0)
5cc0: 20 0a 2a 2a 20 72 65 63 6f 72 64 20 74 6f 20 74   .** record to t
5cd0: 68 65 20 64 61 74 61 62 61 73 65 20 6c 6f 67 2e  he database log.
5ce0: 0a 2a 2f 0a 69 6e 74 20 6c 73 6d 4c 6f 67 57 72  .*/.int lsmLogWr
5cf0: 69 74 65 28 0a 20 20 6c 73 6d 5f 64 62 20 2a 70  ite(.  lsm_db *p
5d00: 44 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  Db,             
5d10: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61         /* Databa
5d20: 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69  se handle */.  i
5d30: 6e 74 20 65 54 79 70 65 2c 0a 20 20 76 6f 69 64  nt eType,.  void
5d40: 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79   *pKey, int nKey
5d50: 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44  ,           /* D
5d60: 61 74 61 62 61 73 65 20 6b 65 79 20 74 6f 20 77  atabase key to w
5d70: 72 69 74 65 20 74 6f 20 6c 6f 67 20 2a 2f 0a 20  rite to log */. 
5d80: 20 76 6f 69 64 20 2a 70 56 61 6c 2c 20 69 6e 74   void *pVal, int
5d90: 20 6e 56 61 6c 20 20 20 20 20 20 20 20 20 20 20   nVal           
5da0: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 76 61 6c   /* Database val
5db0: 75 65 20 28 6f 72 20 6e 56 61 6c 3c 30 29 20 74  ue (or nVal<0) t
5dc0: 6f 20 77 72 69 74 65 20 2a 2f 0a 29 7b 0a 20 20  o write */.){.  
5dd0: 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f 4b 3b  int rc = LSM_OK;
5de0: 0a 20 20 4c 6f 67 57 72 69 74 65 72 20 2a 70 4c  .  LogWriter *pL
5df0: 6f 67 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  og;             
5e00: 20 20 20 2f 2a 20 4c 6f 67 20 6f 62 6a 65 63 74     /* Log object
5e10: 20 74 6f 20 77 72 69 74 65 20 74 6f 20 2a 2f 0a   to write to */.
5e20: 20 20 69 6e 74 20 6e 52 65 71 3b 20 20 20 20 20    int nReq;     
5e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e40: 20 20 2f 2a 20 42 79 74 65 73 20 6f 66 20 73 70    /* Bytes of sp
5e50: 61 63 65 20 72 65 71 75 69 72 65 64 20 69 6e 20  ace required in 
5e60: 6c 6f 67 20 2a 2f 0a 20 20 69 6e 74 20 62 43 6b  log */.  int bCk
5e70: 73 75 6d 20 3d 20 30 3b 20 20 20 20 20 20 20 20  sum = 0;        
5e80: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
5e90: 20 74 6f 20 65 6d 62 65 64 20 61 20 63 68 65 63   to embed a chec
5ea0: 6b 73 75 6d 20 69 6e 20 74 68 69 73 20 72 65 63  ksum in this rec
5eb0: 6f 72 64 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74  ord */..  assert
5ec0: 28 20 65 54 79 70 65 3d 3d 4c 53 4d 5f 57 52 49  ( eType==LSM_WRI
5ed0: 54 45 20 7c 7c 20 65 54 79 70 65 3d 3d 4c 53 4d  TE || eType==LSM
5ee0: 5f 44 45 4c 45 54 45 20 7c 7c 20 65 54 79 70 65  _DELETE || eType
5ef0: 3d 3d 4c 53 4d 5f 44 52 41 4e 47 45 20 29 3b 0a  ==LSM_DRANGE );.
5f00: 20 20 61 73 73 65 72 74 28 20 4c 53 4d 5f 4c 4f    assert( LSM_LO
5f10: 47 5f 57 52 49 54 45 3d 3d 4c 53 4d 5f 57 52 49  G_WRITE==LSM_WRI
5f20: 54 45 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  TE );.  assert( 
5f30: 4c 53 4d 5f 4c 4f 47 5f 44 45 4c 45 54 45 3d 3d  LSM_LOG_DELETE==
5f40: 4c 53 4d 5f 44 45 4c 45 54 45 20 29 3b 0a 20 20  LSM_DELETE );.  
5f50: 61 73 73 65 72 74 28 20 4c 53 4d 5f 4c 4f 47 5f  assert( LSM_LOG_
5f60: 44 52 41 4e 47 45 3d 3d 4c 53 4d 5f 44 52 41 4e  DRANGE==LSM_DRAN
5f70: 47 45 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  GE );.  assert( 
5f80: 28 65 54 79 70 65 3d 3d 4c 53 4d 5f 4c 4f 47 5f  (eType==LSM_LOG_
5f90: 44 45 4c 45 54 45 29 3d 3d 28 6e 56 61 6c 3c 30  DELETE)==(nVal<0
5fa0: 29 20 29 3b 0a 0a 20 20 69 66 28 20 70 44 62 2d  ) );..  if( pDb-
5fb0: 3e 62 55 73 65 4c 6f 67 3d 3d 30 20 29 20 72 65  >bUseLog==0 ) re
5fc0: 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b 0a 20 20 70  turn LSM_OK;.  p
5fd0: 4c 6f 67 20 3d 20 70 44 62 2d 3e 70 4c 6f 67 57  Log = pDb->pLogW
5fe0: 72 69 74 65 72 3b 0a 0a 20 20 2f 2a 20 44 65 74  riter;..  /* Det
5ff0: 65 72 6d 69 6e 65 20 68 6f 77 20 6d 61 6e 79 20  ermine how many 
6000: 62 79 74 65 73 20 6f 66 20 73 70 61 63 65 20 61  bytes of space a
6010: 72 65 20 72 65 71 75 69 72 65 64 2c 20 61 73 73  re required, ass
6020: 75 6d 69 6e 67 20 74 68 61 74 20 61 20 63 68 65  uming that a che
6030: 63 6b 73 75 6d 0a 20 20 2a 2a 20 77 69 6c 6c 20  cksum.  ** will 
6040: 62 65 20 65 6d 62 65 64 64 65 64 20 69 6e 20 74  be embedded in t
6050: 68 69 73 20 72 65 63 6f 72 64 20 28 65 76 65 6e  his record (even
6060: 20 74 68 6f 75 67 68 20 69 74 20 6d 61 79 20 6e   though it may n
6070: 6f 74 20 62 65 29 2e 20 20 2a 2f 0a 20 20 6e 52  ot be).  */.  nR
6080: 65 71 20 3d 20 31 20 2b 20 6c 73 6d 56 61 72 69  eq = 1 + lsmVari
6090: 6e 74 4c 65 6e 33 32 28 6e 4b 65 79 29 20 2b 20  ntLen32(nKey) + 
60a0: 38 20 2b 20 6e 4b 65 79 3b 0a 20 20 69 66 28 20  8 + nKey;.  if( 
60b0: 65 54 79 70 65 21 3d 4c 53 4d 5f 4c 4f 47 5f 44  eType!=LSM_LOG_D
60c0: 45 4c 45 54 45 20 29 20 6e 52 65 71 20 2b 3d 20  ELETE ) nReq += 
60d0: 6c 73 6d 56 61 72 69 6e 74 4c 65 6e 33 32 28 6e  lsmVarintLen32(n
60e0: 56 61 6c 29 20 2b 20 6e 56 61 6c 3b 0a 0a 20 20  Val) + nVal;..  
60f0: 2f 2a 20 4a 75 6d 70 20 6f 76 65 72 20 74 68 65  /* Jump over the
6100: 20 6a 75 6d 70 20 72 65 67 69 6f 6e 20 69 66 20   jump region if 
6110: 72 65 71 75 69 72 65 64 2e 20 53 65 74 20 62 43  required. Set bC
6120: 6b 73 75 6d 20 74 6f 20 74 72 75 65 20 74 6f 20  ksum to true to 
6130: 74 65 6c 6c 20 74 68 65 0a 20 20 2a 2a 20 63 6f  tell the.  ** co
6140: 64 65 20 62 65 6c 6f 77 20 74 6f 20 69 6e 63 6c  de below to incl
6150: 75 64 65 20 61 20 63 68 65 63 6b 73 75 6d 20 69  ude a checksum i
6160: 6e 20 74 68 65 20 72 65 63 6f 72 64 20 69 66 20  n the record if 
6170: 65 69 74 68 65 72 20 28 61 29 20 77 72 69 74 69  either (a) writi
6180: 6e 67 0a 20 20 2a 2a 20 74 68 69 73 20 72 65 63  ng.  ** this rec
6190: 6f 72 64 20 77 6f 75 6c 64 20 6d 65 61 6e 20 74  ord would mean t
61a0: 68 61 74 20 6d 6f 72 65 20 74 68 61 6e 20 4c 53  hat more than LS
61b0: 4d 5f 43 4b 53 55 4d 5f 4d 41 58 44 41 54 41 20  M_CKSUM_MAXDATA 
61c0: 62 79 74 65 73 20 6f 66 20 64 61 74 61 0a 20 20  bytes of data.  
61d0: 2a 2a 20 68 61 76 65 20 62 65 65 6e 20 77 72 69  ** have been wri
61e0: 74 74 65 6e 20 74 6f 20 74 68 65 20 6c 6f 67 20  tten to the log 
61f0: 73 69 6e 63 65 20 74 68 65 20 6c 61 73 74 20 63  since the last c
6200: 68 65 63 6b 73 75 6d 2c 20 6f 72 20 28 62 29 20  hecksum, or (b) 
6210: 74 68 65 20 6a 75 6d 70 0a 20 20 2a 2a 20 69 73  the jump.  ** is
6220: 20 74 61 6b 65 6e 2e 20 20 2a 2f 0a 20 20 72 63   taken.  */.  rc
6230: 20 3d 20 6a 75 6d 70 49 66 52 65 71 75 69 72 65   = jumpIfRequire
6240: 64 28 70 44 62 2c 20 70 4c 6f 67 2c 20 6e 52 65  d(pDb, pLog, nRe
6250: 71 2c 20 26 62 43 6b 73 75 6d 29 3b 0a 20 20 69  q, &bCksum);.  i
6260: 66 28 20 28 70 4c 6f 67 2d 3e 62 75 66 2e 6e 2b  f( (pLog->buf.n+
6270: 6e 52 65 71 29 20 3e 20 4c 53 4d 5f 43 4b 53 55  nReq) > LSM_CKSU
6280: 4d 5f 4d 41 58 44 41 54 41 20 29 20 62 43 6b 73  M_MAXDATA ) bCks
6290: 75 6d 20 3d 20 31 3b 0a 0a 20 20 69 66 28 20 72  um = 1;..  if( r
62a0: 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20  c==LSM_OK ){.   
62b0: 20 72 63 20 3d 20 6c 73 6d 53 74 72 69 6e 67 45   rc = lsmStringE
62c0: 78 74 65 6e 64 28 26 70 4c 6f 67 2d 3e 62 75 66  xtend(&pLog->buf
62d0: 2c 20 6e 52 65 71 29 3b 0a 20 20 7d 0a 20 20 69  , nReq);.  }.  i
62e0: 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b  f( rc==LSM_OK ){
62f0: 0a 20 20 20 20 75 38 20 2a 61 20 3d 20 28 75 38  .    u8 *a = (u8
6300: 20 2a 29 26 70 4c 6f 67 2d 3e 62 75 66 2e 7a 5b   *)&pLog->buf.z[
6310: 70 4c 6f 67 2d 3e 62 75 66 2e 6e 5d 3b 0a 20 20  pLog->buf.n];.  
6320: 20 20 0a 20 20 20 20 2f 2a 20 57 72 69 74 65 20    .    /* Write 
6330: 74 68 65 20 72 65 63 6f 72 64 20 68 65 61 64 65  the record heade
6340: 72 20 2d 20 74 68 65 20 74 79 70 65 20 62 79 74  r - the type byt
6350: 65 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 65 69  e followed by ei
6360: 74 68 65 72 20 31 20 28 66 6f 72 0a 20 20 20 20  ther 1 (for.    
6370: 2a 2a 20 44 45 4c 45 54 45 29 20 6f 72 20 32 20  ** DELETE) or 2 
6380: 28 66 6f 72 20 57 52 49 54 45 29 20 76 61 72 69  (for WRITE) vari
6390: 6e 74 73 2e 20 20 2a 2f 0a 20 20 20 20 61 73 73  nts.  */.    ass
63a0: 65 72 74 28 20 4c 53 4d 5f 4c 4f 47 5f 57 52 49  ert( LSM_LOG_WRI
63b0: 54 45 5f 43 4b 53 55 4d 20 3d 3d 20 28 4c 53 4d  TE_CKSUM == (LSM
63c0: 5f 4c 4f 47 5f 57 52 49 54 45 20 7c 20 30 78 30  _LOG_WRITE | 0x0
63d0: 30 30 31 29 20 29 3b 0a 20 20 20 20 61 73 73 65  001) );.    asse
63e0: 72 74 28 20 4c 53 4d 5f 4c 4f 47 5f 44 45 4c 45  rt( LSM_LOG_DELE
63f0: 54 45 5f 43 4b 53 55 4d 20 3d 3d 20 28 4c 53 4d  TE_CKSUM == (LSM
6400: 5f 4c 4f 47 5f 44 45 4c 45 54 45 20 7c 20 30 78  _LOG_DELETE | 0x
6410: 30 30 30 31 29 20 29 3b 0a 20 20 20 20 61 73 73  0001) );.    ass
6420: 65 72 74 28 20 4c 53 4d 5f 4c 4f 47 5f 44 52 41  ert( LSM_LOG_DRA
6430: 4e 47 45 5f 43 4b 53 55 4d 20 3d 3d 20 28 4c 53  NGE_CKSUM == (LS
6440: 4d 5f 4c 4f 47 5f 44 52 41 4e 47 45 20 7c 20 30  M_LOG_DRANGE | 0
6450: 78 30 30 30 31 29 20 29 3b 0a 20 20 20 20 2a 28  x0001) );.    *(
6460: 61 2b 2b 29 20 3d 20 28 75 38 29 65 54 79 70 65  a++) = (u8)eType
6470: 20 7c 20 28 75 38 29 62 43 6b 73 75 6d 3b 0a 20   | (u8)bCksum;. 
6480: 20 20 20 61 20 2b 3d 20 6c 73 6d 56 61 72 69 6e     a += lsmVarin
6490: 74 50 75 74 33 32 28 61 2c 20 6e 4b 65 79 29 3b  tPut32(a, nKey);
64a0: 0a 20 20 20 20 69 66 28 20 65 54 79 70 65 21 3d  .    if( eType!=
64b0: 4c 53 4d 5f 4c 4f 47 5f 44 45 4c 45 54 45 20 29  LSM_LOG_DELETE )
64c0: 20 61 20 2b 3d 20 6c 73 6d 56 61 72 69 6e 74 50   a += lsmVarintP
64d0: 75 74 33 32 28 61 2c 20 6e 56 61 6c 29 3b 0a 0a  ut32(a, nVal);..
64e0: 20 20 20 20 69 66 28 20 62 43 6b 73 75 6d 20 29      if( bCksum )
64f0: 7b 0a 20 20 20 20 20 20 70 4c 6f 67 2d 3e 62 75  {.      pLog->bu
6500: 66 2e 6e 20 3d 20 28 61 20 2d 20 28 75 38 20 2a  f.n = (a - (u8 *
6510: 29 70 4c 6f 67 2d 3e 62 75 66 2e 7a 29 3b 0a 20  )pLog->buf.z);. 
6520: 20 20 20 20 20 72 63 20 3d 20 6c 6f 67 43 6b 73       rc = logCks
6530: 75 6d 41 6e 64 46 6c 75 73 68 28 70 44 62 29 3b  umAndFlush(pDb);
6540: 0a 20 20 20 20 20 20 61 20 3d 20 28 75 38 20 2a  .      a = (u8 *
6550: 29 26 70 4c 6f 67 2d 3e 62 75 66 2e 7a 5b 70 4c  )&pLog->buf.z[pL
6560: 6f 67 2d 3e 62 75 66 2e 6e 5d 3b 0a 20 20 20 20  og->buf.n];.    
6570: 7d 0a 0a 20 20 20 20 6d 65 6d 63 70 79 28 61 2c  }..    memcpy(a,
6580: 20 70 4b 65 79 2c 20 6e 4b 65 79 29 3b 0a 20 20   pKey, nKey);.  
6590: 20 20 61 20 2b 3d 20 6e 4b 65 79 3b 0a 20 20 20    a += nKey;.   
65a0: 20 69 66 28 20 65 54 79 70 65 21 3d 4c 53 4d 5f   if( eType!=LSM_
65b0: 4c 4f 47 5f 44 45 4c 45 54 45 20 29 7b 0a 20 20  LOG_DELETE ){.  
65c0: 20 20 20 20 6d 65 6d 63 70 79 28 61 2c 20 70 56      memcpy(a, pV
65d0: 61 6c 2c 20 6e 56 61 6c 29 3b 0a 20 20 20 20 20  al, nVal);.     
65e0: 20 61 20 2b 3d 20 6e 56 61 6c 3b 0a 20 20 20 20   a += nVal;.    
65f0: 7d 0a 20 20 20 20 70 4c 6f 67 2d 3e 62 75 66 2e  }.    pLog->buf.
6600: 6e 20 3d 20 61 20 2d 20 28 75 38 20 2a 29 70 4c  n = a - (u8 *)pL
6610: 6f 67 2d 3e 62 75 66 2e 7a 3b 0a 20 20 20 20 61  og->buf.z;.    a
6620: 73 73 65 72 74 28 20 70 4c 6f 67 2d 3e 62 75 66  ssert( pLog->buf
6630: 2e 6e 3c 3d 70 4c 6f 67 2d 3e 62 75 66 2e 6e 41  .n<=pLog->buf.nA
6640: 6c 6c 6f 63 20 29 3b 0a 20 20 7d 0a 0a 20 20 72  lloc );.  }..  r
6650: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
6660: 2a 2a 20 41 70 70 65 6e 64 20 61 6e 20 4c 53 4d  ** Append an LSM
6670: 5f 4c 4f 47 5f 43 4f 4d 4d 49 54 20 72 65 63 6f  _LOG_COMMIT reco
6680: 72 64 20 74 6f 20 74 68 65 20 64 61 74 61 62 61  rd to the databa
6690: 73 65 20 6c 6f 67 2e 0a 2a 2f 0a 69 6e 74 20 6c  se log..*/.int l
66a0: 73 6d 4c 6f 67 43 6f 6d 6d 69 74 28 6c 73 6d 5f  smLogCommit(lsm_
66b0: 64 62 20 2a 70 44 62 29 7b 0a 20 20 69 66 28 20  db *pDb){.  if( 
66c0: 70 44 62 2d 3e 62 55 73 65 4c 6f 67 3d 3d 30 20  pDb->bUseLog==0 
66d0: 29 20 72 65 74 75 72 6e 20 4c 53 4d 5f 4f 4b 3b  ) return LSM_OK;
66e0: 0a 20 20 72 65 74 75 72 6e 20 6c 6f 67 46 6c 75  .  return logFlu
66f0: 73 68 28 70 44 62 2c 20 4c 53 4d 5f 4c 4f 47 5f  sh(pDb, LSM_LOG_
6700: 43 4f 4d 4d 49 54 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  COMMIT);.}../*.*
6710: 2a 20 53 74 6f 72 65 20 74 68 65 20 63 75 72 72  * Store the curr
6720: 65 6e 74 20 6f 66 66 73 65 74 20 61 6e 64 20 6f  ent offset and o
6730: 74 68 65 72 20 63 68 65 63 6b 73 75 6d 20 72 65  ther checksum re
6740: 6c 61 74 65 64 20 69 6e 66 6f 72 6d 61 74 69 6f  lated informatio
6750: 6e 20 69 6e 20 74 68 65 0a 2a 2a 20 73 74 72 75  n in the.** stru
6760: 63 74 75 72 65 20 2a 70 4d 61 72 6b 2e 20 4c 61  cture *pMark. La
6770: 74 65 72 2c 20 2a 70 4d 61 72 6b 20 63 61 6e 20  ter, *pMark can 
6780: 62 65 20 70 61 73 73 65 64 20 74 6f 20 6c 73 6d  be passed to lsm
6790: 4c 6f 67 53 65 65 6b 28 29 20 74 6f 20 22 72 65  LogSeek() to "re
67a0: 77 69 6e 64 22 0a 2a 2a 20 74 68 65 20 4c 6f 67  wind".** the Log
67b0: 57 72 69 74 65 72 20 6f 62 6a 65 63 74 20 74 6f  Writer object to
67c0: 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c 6f 67   the current log
67d0: 20 66 69 6c 65 20 6f 66 66 73 65 74 2e 20 54 68   file offset. Th
67e0: 69 73 20 69 73 20 75 73 65 64 20 77 68 65 6e 0a  is is used when.
67f0: 2a 2a 20 72 6f 6c 6c 69 6e 67 20 62 61 63 6b 20  ** rolling back 
6800: 73 61 76 65 70 6f 69 6e 74 20 74 72 61 6e 73 61  savepoint transa
6810: 63 74 69 6f 6e 73 2e 0a 2a 2f 0a 76 6f 69 64 20  ctions..*/.void 
6820: 6c 73 6d 4c 6f 67 54 65 6c 6c 28 0a 20 20 6c 73  lsmLogTell(.  ls
6830: 6d 5f 64 62 20 2a 70 44 62 2c 20 20 20 20 20 20  m_db *pDb,      
6840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6850: 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c 65   Database handle
6860: 20 2a 2f 0a 20 20 4c 6f 67 4d 61 72 6b 20 2a 70   */.  LogMark *p
6870: 4d 61 72 6b 20 20 20 20 20 20 20 20 20 20 20 20  Mark            
6880: 20 20 20 20 20 20 2f 2a 20 50 6f 70 75 6c 61 74        /* Populat
6890: 65 20 74 68 69 73 20 6f 62 6a 65 63 74 20 77 69  e this object wi
68a0: 74 68 20 63 75 72 72 65 6e 74 20 6f 66 66 73 65  th current offse
68b0: 74 20 2a 2f 0a 29 7b 0a 20 20 4c 6f 67 57 72 69  t */.){.  LogWri
68c0: 74 65 72 20 2a 70 4c 6f 67 3b 0a 20 20 69 6e 74  ter *pLog;.  int
68d0: 20 6e 43 6b 73 75 6d 3b 0a 0a 20 20 69 66 28 20   nCksum;..  if( 
68e0: 70 44 62 2d 3e 62 55 73 65 4c 6f 67 3d 3d 30 20  pDb->bUseLog==0 
68f0: 29 20 72 65 74 75 72 6e 3b 0a 20 20 70 4c 6f 67  ) return;.  pLog
6900: 20 3d 20 70 44 62 2d 3e 70 4c 6f 67 57 72 69 74   = pDb->pLogWrit
6910: 65 72 3b 0a 20 20 6e 43 6b 73 75 6d 20 3d 20 70  er;.  nCksum = p
6920: 4c 6f 67 2d 3e 62 75 66 2e 6e 20 26 20 30 78 46  Log->buf.n & 0xF
6930: 46 46 46 46 46 46 38 3b 0a 20 20 6c 6f 67 55 70  FFFFFF8;.  logUp
6940: 64 61 74 65 43 6b 73 75 6d 28 70 4c 6f 67 2c 20  dateCksum(pLog, 
6950: 6e 43 6b 73 75 6d 29 3b 0a 20 20 61 73 73 65 72  nCksum);.  asser
6960: 74 28 20 70 4c 6f 67 2d 3e 69 43 6b 73 75 6d 42  t( pLog->iCksumB
6970: 75 66 3d 3d 6e 43 6b 73 75 6d 20 29 3b 0a 20 20  uf==nCksum );.  
6980: 70 4d 61 72 6b 2d 3e 6e 42 75 66 20 3d 20 70 4c  pMark->nBuf = pL
6990: 6f 67 2d 3e 62 75 66 2e 6e 20 2d 20 6e 43 6b 73  og->buf.n - nCks
69a0: 75 6d 3b 0a 20 20 6d 65 6d 63 70 79 28 70 4d 61  um;.  memcpy(pMa
69b0: 72 6b 2d 3e 61 42 75 66 2c 20 26 70 4c 6f 67 2d  rk->aBuf, &pLog-
69c0: 3e 62 75 66 2e 7a 5b 6e 43 6b 73 75 6d 5d 2c 20  >buf.z[nCksum], 
69d0: 70 4d 61 72 6b 2d 3e 6e 42 75 66 29 3b 0a 0a 20  pMark->nBuf);.. 
69e0: 20 70 4d 61 72 6b 2d 3e 69 4f 66 66 20 3d 20 70   pMark->iOff = p
69f0: 4c 6f 67 2d 3e 69 4f 66 66 20 2b 20 70 4c 6f 67  Log->iOff + pLog
6a00: 2d 3e 62 75 66 2e 6e 3b 0a 20 20 70 4d 61 72 6b  ->buf.n;.  pMark
6a10: 2d 3e 63 6b 73 75 6d 30 20 3d 20 70 4c 6f 67 2d  ->cksum0 = pLog-
6a20: 3e 63 6b 73 75 6d 30 3b 0a 20 20 70 4d 61 72 6b  >cksum0;.  pMark
6a30: 2d 3e 63 6b 73 75 6d 31 20 3d 20 70 4c 6f 67 2d  ->cksum1 = pLog-
6a40: 3e 63 6b 73 75 6d 31 3b 0a 7d 0a 0a 2f 2a 0a 2a  >cksum1;.}../*.*
6a50: 2a 20 53 65 65 6b 20 28 72 65 77 69 6e 64 29 20  * Seek (rewind) 
6a60: 62 61 63 6b 20 74 6f 20 74 68 65 20 6c 6f 67 20  back to the log 
6a70: 66 69 6c 65 20 6f 66 66 73 65 74 20 73 74 6f 72  file offset stor
6a80: 65 64 20 62 79 20 61 6e 20 65 61 6c 69 65 72 20  ed by an ealier 
6a90: 63 61 6c 6c 20 74 6f 0a 2a 2a 20 6c 73 6d 4c 6f  call to.** lsmLo
6aa0: 67 54 65 6c 6c 28 29 20 69 6e 20 2a 70 4d 61 72  gTell() in *pMar
6ab0: 6b 2e 0a 2a 2f 0a 76 6f 69 64 20 6c 73 6d 4c 6f  k..*/.void lsmLo
6ac0: 67 53 65 65 6b 28 0a 20 20 6c 73 6d 5f 64 62 20  gSeek(.  lsm_db 
6ad0: 2a 70 44 62 2c 20 20 20 20 20 20 20 20 20 20 20  *pDb,           
6ae0: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
6af0: 62 61 73 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20  base handle */. 
6b00: 20 4c 6f 67 4d 61 72 6b 20 2a 70 4d 61 72 6b 20   LogMark *pMark 
6b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b20: 20 2f 2a 20 4f 62 6a 65 63 74 20 63 6f 6e 74 61   /* Object conta
6b30: 69 6e 69 6e 67 20 6c 6f 67 20 6f 66 66 73 65 74  ining log offset
6b40: 20 74 6f 20 73 65 65 6b 20 74 6f 20 2a 2f 0a 29   to seek to */.)
6b50: 7b 0a 20 20 4c 6f 67 57 72 69 74 65 72 20 2a 70  {.  LogWriter *p
6b60: 4c 6f 67 3b 0a 0a 20 20 69 66 28 20 70 44 62 2d  Log;..  if( pDb-
6b70: 3e 62 55 73 65 4c 6f 67 3d 3d 30 20 29 20 72 65  >bUseLog==0 ) re
6b80: 74 75 72 6e 3b 0a 20 20 70 4c 6f 67 20 3d 20 70  turn;.  pLog = p
6b90: 44 62 2d 3e 70 4c 6f 67 57 72 69 74 65 72 3b 0a  Db->pLogWriter;.
6ba0: 0a 20 20 61 73 73 65 72 74 28 20 70 4d 61 72 6b  .  assert( pMark
6bb0: 2d 3e 69 4f 66 66 3c 3d 70 4c 6f 67 2d 3e 69 4f  ->iOff<=pLog->iO
6bc0: 66 66 2b 70 4c 6f 67 2d 3e 62 75 66 2e 6e 20 29  ff+pLog->buf.n )
6bd0: 3b 0a 20 20 69 66 28 20 28 70 4d 61 72 6b 2d 3e  ;.  if( (pMark->
6be0: 69 4f 66 66 20 26 20 30 78 46 46 46 46 46 46 46  iOff & 0xFFFFFFF
6bf0: 38 29 3e 3d 70 4c 6f 67 2d 3e 69 4f 66 66 20 29  8)>=pLog->iOff )
6c00: 7b 0a 20 20 20 20 70 4c 6f 67 2d 3e 62 75 66 2e  {.    pLog->buf.
6c10: 6e 20 3d 20 28 69 6e 74 29 28 70 4d 61 72 6b 2d  n = (int)(pMark-
6c20: 3e 69 4f 66 66 20 2d 20 70 4c 6f 67 2d 3e 69 4f  >iOff - pLog->iO
6c30: 66 66 29 3b 0a 20 20 20 20 70 4c 6f 67 2d 3e 69  ff);.    pLog->i
6c40: 43 6b 73 75 6d 42 75 66 20 3d 20 28 70 4c 6f 67  CksumBuf = (pLog
6c50: 2d 3e 62 75 66 2e 6e 20 26 20 30 78 46 46 46 46  ->buf.n & 0xFFFF
6c60: 46 46 46 38 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  FFF8);.  }else{.
6c70: 20 20 20 20 70 4c 6f 67 2d 3e 62 75 66 2e 6e 20      pLog->buf.n 
6c80: 3d 20 70 4d 61 72 6b 2d 3e 6e 42 75 66 3b 0a 20  = pMark->nBuf;. 
6c90: 20 20 20 6d 65 6d 63 70 79 28 70 4c 6f 67 2d 3e     memcpy(pLog->
6ca0: 62 75 66 2e 7a 2c 20 70 4d 61 72 6b 2d 3e 61 42  buf.z, pMark->aB
6cb0: 75 66 2c 20 70 4d 61 72 6b 2d 3e 6e 42 75 66 29  uf, pMark->nBuf)
6cc0: 3b 0a 20 20 20 20 70 4c 6f 67 2d 3e 69 43 6b 73  ;.    pLog->iCks
6cd0: 75 6d 42 75 66 20 3d 20 30 3b 0a 20 20 20 20 70  umBuf = 0;.    p
6ce0: 4c 6f 67 2d 3e 69 4f 66 66 20 3d 20 70 4d 61 72  Log->iOff = pMar
6cf0: 6b 2d 3e 69 4f 66 66 20 2d 20 70 4d 61 72 6b 2d  k->iOff - pMark-
6d00: 3e 6e 42 75 66 3b 0a 20 20 7d 0a 20 20 70 4c 6f  >nBuf;.  }.  pLo
6d10: 67 2d 3e 63 6b 73 75 6d 30 20 3d 20 70 4d 61 72  g->cksum0 = pMar
6d20: 6b 2d 3e 63 6b 73 75 6d 30 3b 0a 20 20 70 4c 6f  k->cksum0;.  pLo
6d30: 67 2d 3e 63 6b 73 75 6d 31 20 3d 20 70 4d 61 72  g->cksum1 = pMar
6d40: 6b 2d 3e 63 6b 73 75 6d 31 3b 0a 0a 20 20 69 66  k->cksum1;..  if
6d50: 28 20 70 4d 61 72 6b 2d 3e 69 4f 66 66 20 3e 20  ( pMark->iOff > 
6d60: 70 4c 6f 67 2d 3e 69 52 65 67 69 6f 6e 31 45 6e  pLog->iRegion1En
6d70: 64 20 29 20 70 4c 6f 67 2d 3e 69 52 65 67 69 6f  d ) pLog->iRegio
6d80: 6e 31 45 6e 64 20 3d 20 30 3b 0a 20 20 69 66 28  n1End = 0;.  if(
6d90: 20 70 4d 61 72 6b 2d 3e 69 4f 66 66 20 3e 20 70   pMark->iOff > p
6da0: 4c 6f 67 2d 3e 69 52 65 67 69 6f 6e 32 53 74 61  Log->iRegion2Sta
6db0: 72 74 20 29 20 70 4c 6f 67 2d 3e 69 52 65 67 69  rt ) pLog->iRegi
6dc0: 6f 6e 32 53 74 61 72 74 20 3d 20 30 3b 0a 7d 0a  on2Start = 0;.}.
6dd0: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
6de0: 74 69 6f 6e 20 64 6f 65 73 20 74 68 65 20 77 6f  tion does the wo
6df0: 72 6b 20 66 6f 72 20 61 6e 20 6c 73 6d 5f 69 6e  rk for an lsm_in
6e00: 66 6f 28 4c 4f 47 5f 53 54 52 55 43 54 55 52 45  fo(LOG_STRUCTURE
6e10: 29 20 72 65 71 75 65 73 74 2e 0a 2a 2f 0a 69 6e  ) request..*/.in
6e20: 74 20 6c 73 6d 49 6e 66 6f 4c 6f 67 53 74 72 75  t lsmInfoLogStru
6e30: 63 74 75 72 65 28 6c 73 6d 5f 64 62 20 2a 70 44  cture(lsm_db *pD
6e40: 62 2c 20 63 68 61 72 20 2a 2a 70 7a 56 61 6c 29  b, char **pzVal)
6e50: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d  {.  int rc = LSM
6e60: 5f 4f 4b 3b 0a 20 20 63 68 61 72 20 2a 7a 56 61  _OK;.  char *zVa
6e70: 6c 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 49 66 20  l = 0;..  /* If 
6e80: 74 68 65 72 65 20 69 73 20 6e 6f 20 72 65 61 64  there is no read
6e90: 20 6f 72 20 77 72 69 74 65 20 74 72 61 6e 73 61   or write transa
6ea0: 63 74 69 6f 6e 20 6f 70 65 6e 2c 20 72 65 61 64  ction open, read
6eb0: 20 74 68 65 20 6c 61 74 65 73 74 20 0a 20 20 2a   the latest .  *
6ec0: 2a 20 74 72 65 65 2d 68 65 61 64 65 72 20 66 72  * tree-header fr
6ed0: 6f 6d 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79  om shared-memory
6ee0: 20 74 6f 20 72 65 70 6f 72 74 20 6f 6e 2e 20 49   to report on. I
6ef0: 66 20 6e 65 63 65 73 73 61 72 79 2c 20 75 70 64  f necessary, upd
6f00: 61 74 65 0a 20 20 2a 2a 20 69 74 20 62 61 73 65  ate.  ** it base
6f10: 64 20 6f 6e 20 74 68 65 20 63 6f 6e 74 65 6e 74  d on the content
6f20: 73 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  s of the databas
6f30: 65 20 68 65 61 64 65 72 2e 20 20 0a 20 20 2a 2a  e header.  .  **
6f40: 0a 20 20 2a 2a 20 4e 6f 20 6c 6f 63 6b 73 20 61  .  ** No locks a
6f50: 72 65 20 74 61 6b 65 6e 20 68 65 72 65 20 2d 20  re taken here - 
6f60: 74 68 65 73 65 20 61 72 65 20 70 61 73 73 69 76  these are passiv
6f70: 65 20 72 65 61 64 20 6f 70 65 72 61 74 69 6f 6e  e read operation
6f80: 73 20 6f 6e 6c 79 2e 0a 20 20 2a 2f 0a 20 20 69  s only..  */.  i
6f90: 66 28 20 70 44 62 2d 3e 70 43 73 72 3d 3d 30 20  f( pDb->pCsr==0 
6fa0: 26 26 20 70 44 62 2d 3e 6e 54 72 61 6e 73 4f 70  && pDb->nTransOp
6fb0: 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20  en==0 ){.    rc 
6fc0: 3d 20 6c 73 6d 54 72 65 65 4c 6f 61 64 48 65 61  = lsmTreeLoadHea
6fd0: 64 65 72 28 70 44 62 2c 20 30 29 3b 0a 20 20 20  der(pDb, 0);.   
6fe0: 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
6ff0: 29 20 72 63 20 3d 20 6c 6f 67 52 65 63 6c 61 69  ) rc = logReclai
7000: 6d 53 70 61 63 65 28 70 44 62 29 3b 0a 20 20 7d  mSpace(pDb);.  }
7010: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f  ..  if( rc==LSM_
7020: 4f 4b 20 29 7b 0a 20 20 20 20 44 62 4c 6f 67 20  OK ){.    DbLog 
7030: 2a 70 4c 6f 67 20 3d 20 26 70 44 62 2d 3e 74 72  *pLog = &pDb->tr
7040: 65 65 68 64 72 2e 6c 6f 67 3b 0a 20 20 20 20 7a  eehdr.log;.    z
7050: 56 61 6c 20 3d 20 6c 73 6d 4d 61 6c 6c 6f 63 50  Val = lsmMallocP
7060: 72 69 6e 74 66 28 70 44 62 2d 3e 70 45 6e 76 2c  rintf(pDb->pEnv,
7070: 20 0a 20 20 20 20 20 20 20 20 22 25 64 20 25 64   .        "%d %d
7080: 20 25 64 20 25 64 20 25 64 20 25 64 22 2c 20 0a   %d %d %d %d", .
7090: 20 20 20 20 20 20 20 20 28 69 6e 74 29 70 4c 6f          (int)pLo
70a0: 67 2d 3e 61 52 65 67 69 6f 6e 5b 30 5d 2e 69 53  g->aRegion[0].iS
70b0: 74 61 72 74 2c 20 28 69 6e 74 29 70 4c 6f 67 2d  tart, (int)pLog-
70c0: 3e 61 52 65 67 69 6f 6e 5b 30 5d 2e 69 45 6e 64  >aRegion[0].iEnd
70d0: 2c 0a 20 20 20 20 20 20 20 20 28 69 6e 74 29 70  ,.        (int)p
70e0: 4c 6f 67 2d 3e 61 52 65 67 69 6f 6e 5b 31 5d 2e  Log->aRegion[1].
70f0: 69 53 74 61 72 74 2c 20 28 69 6e 74 29 70 4c 6f  iStart, (int)pLo
7100: 67 2d 3e 61 52 65 67 69 6f 6e 5b 31 5d 2e 69 45  g->aRegion[1].iE
7110: 6e 64 2c 0a 20 20 20 20 20 20 20 20 28 69 6e 74  nd,.        (int
7120: 29 70 4c 6f 67 2d 3e 61 52 65 67 69 6f 6e 5b 32  )pLog->aRegion[2
7130: 5d 2e 69 53 74 61 72 74 2c 20 28 69 6e 74 29 70  ].iStart, (int)p
7140: 4c 6f 67 2d 3e 61 52 65 67 69 6f 6e 5b 32 5d 2e  Log->aRegion[2].
7150: 69 45 6e 64 0a 20 20 20 20 29 3b 0a 20 20 20 20  iEnd.    );.    
7160: 69 66 28 20 21 7a 56 61 6c 20 29 20 72 63 20 3d  if( !zVal ) rc =
7170: 20 4c 53 4d 5f 4e 4f 4d 45 4d 5f 42 4b 50 54 3b   LSM_NOMEM_BKPT;
7180: 0a 20 20 7d 0a 0a 20 20 2a 70 7a 56 61 6c 20 3d  .  }..  *pzVal =
7190: 20 7a 56 61 6c 3b 0a 20 20 72 65 74 75 72 6e 20   zVal;.  return 
71a0: 72 63 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a  rc;.}../********
71b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
71c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
71d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
71e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
71f0: 2a 0a 2a 2a 20 42 65 67 69 6e 20 63 6f 64 65 20  *.** Begin code 
7200: 66 6f 72 20 6c 6f 67 20 72 65 63 6f 76 65 72 79  for log recovery
7210: 2e 0a 2a 2f 0a 0a 74 79 70 65 64 65 66 20 73 74  ..*/..typedef st
7220: 72 75 63 74 20 4c 6f 67 52 65 61 64 65 72 20 4c  ruct LogReader L
7230: 6f 67 52 65 61 64 65 72 3b 0a 73 74 72 75 63 74  ogReader;.struct
7240: 20 4c 6f 67 52 65 61 64 65 72 20 7b 0a 20 20 46   LogReader {.  F
7250: 69 6c 65 53 79 73 74 65 6d 20 2a 70 46 53 3b 20  ileSystem *pFS; 
7260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7270: 2a 20 46 69 6c 65 20 73 79 73 74 65 6d 20 74 6f  * File system to
7280: 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20   read from */.  
7290: 69 36 34 20 69 4f 66 66 3b 20 20 20 20 20 20 20  i64 iOff;       
72a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
72b0: 2f 2a 20 46 69 6c 65 20 6f 66 66 73 65 74 20 61  /* File offset a
72c0: 74 20 65 6e 64 20 6f 66 20 62 75 66 20 63 6f 6e  t end of buf con
72d0: 74 65 6e 74 20 2a 2f 0a 20 20 69 6e 74 20 69 42  tent */.  int iB
72e0: 75 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  uf;             
72f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72            /* Cur
7300: 72 65 6e 74 20 72 65 61 64 20 6f 66 66 73 65 74  rent read offset
7310: 20 69 6e 20 62 75 66 20 2a 2f 0a 20 20 4c 73 6d   in buf */.  Lsm
7320: 53 74 72 69 6e 67 20 62 75 66 3b 20 20 20 20 20  String buf;     
7330: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7340: 42 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e  Buffer containin
7350: 67 20 66 69 6c 65 20 63 6f 6e 74 65 6e 74 20 2a  g file content *
7360: 2f 0a 0a 20 20 69 6e 74 20 69 43 6b 73 75 6d 42  /..  int iCksumB
7370: 75 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  uf;             
7380: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 69       /* Offset i
7390: 6e 20 62 75 66 20 63 6f 72 72 65 73 70 6f 6e 64  n buf correspond
73a0: 69 6e 67 20 74 6f 20 63 6b 73 75 6d 5b 30 31 5d  ing to cksum[01]
73b0: 20 2a 2f 0a 20 20 75 33 32 20 63 6b 73 75 6d 30   */.  u32 cksum0
73c0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
73d0: 20 20 20 20 20 20 2f 2a 20 43 68 65 63 6b 73 75        /* Checksu
73e0: 6d 20 30 20 61 74 20 6f 66 66 73 65 74 20 69 43  m 0 at offset iC
73f0: 6b 73 75 6d 42 75 66 20 2a 2f 0a 20 20 75 33 32  ksumBuf */.  u32
7400: 20 63 6b 73 75 6d 31 3b 20 20 20 20 20 20 20 20   cksum1;        
7410: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7420: 43 68 65 63 6b 73 75 6d 20 31 20 61 74 20 6f 66  Checksum 1 at of
7430: 66 73 65 74 20 69 43 6b 73 75 6d 42 75 66 20 2a  fset iCksumBuf *
7440: 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 76 6f 69  /.};..static voi
7450: 64 20 6c 6f 67 52 65 61 64 65 72 42 6c 6f 62 28  d logReaderBlob(
7460: 0a 20 20 4c 6f 67 52 65 61 64 65 72 20 2a 70 2c  .  LogReader *p,
7470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7480: 20 20 20 2f 2a 20 4c 6f 67 20 72 65 61 64 65 72     /* Log reader
7490: 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 4c 73 6d   object */.  Lsm
74a0: 53 74 72 69 6e 67 20 2a 70 42 75 66 2c 20 20 20  String *pBuf,   
74b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
74c0: 44 79 6e 61 6d 69 63 20 73 74 6f 72 61 67 65 2c  Dynamic storage,
74d0: 20 69 66 20 72 65 71 75 69 72 65 64 20 2a 2f 0a   if required */.
74e0: 20 20 69 6e 74 20 6e 42 6c 6f 62 2c 20 20 20 20    int nBlob,    
74f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7500: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62    /* Number of b
7510: 79 74 65 73 20 74 6f 20 72 65 61 64 20 2a 2f 0a  ytes to read */.
7520: 20 20 75 38 20 2a 2a 70 70 42 6c 6f 62 2c 20 20    u8 **ppBlob,  
7530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7540: 20 20 2f 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65    /* OUT: Pointe
7550: 72 20 74 6f 20 62 6c 6f 62 20 72 65 61 64 20 2a  r to blob read *
7560: 2f 0a 20 20 69 6e 74 20 2a 70 52 63 20 20 20 20  /.  int *pRc    
7570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7580: 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45      /* IN/OUT: E
7590: 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 29 7b 0a  rror code */.){.
75a0: 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20 69    static const i
75b0: 6e 74 20 4c 4f 47 5f 52 45 41 44 5f 53 49 5a 45  nt LOG_READ_SIZE
75c0: 20 3d 20 35 31 32 3b 0a 20 20 69 6e 74 20 72 63   = 512;.  int rc
75d0: 20 3d 20 2a 70 52 63 3b 20 20 20 20 20 20 20 20   = *pRc;        
75e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74            /* Ret
75f0: 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e  urn code */.  in
7600: 74 20 6e 52 65 71 20 3d 20 6e 42 6c 6f 62 3b 20  t nReq = nBlob; 
7610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7620: 20 42 79 74 65 73 20 72 65 71 75 69 72 65 64 20   Bytes required 
7630: 2a 2f 0a 0a 20 20 77 68 69 6c 65 28 20 72 63 3d  */..  while( rc=
7640: 3d 4c 53 4d 5f 4f 4b 20 26 26 20 6e 52 65 71 3e  =LSM_OK && nReq>
7650: 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 41 76  0 ){.    int nAv
7660: 61 69 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  ail;            
7670: 20 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20         /* Bytes 
7680: 6f 66 20 64 61 74 61 20 61 76 61 69 6c 61 62 6c  of data availabl
7690: 65 20 69 6e 20 70 2d 3e 62 75 66 20 2a 2f 0a 20  e in p->buf */. 
76a0: 20 20 20 69 66 28 20 70 2d 3e 62 75 66 2e 6e 3d     if( p->buf.n=
76b0: 3d 70 2d 3e 69 42 75 66 20 29 7b 0a 20 20 20 20  =p->iBuf ){.    
76c0: 20 20 69 6e 74 20 6e 43 6b 73 75 6d 3b 20 20 20    int nCksum;   
76d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
76e0: 20 54 6f 74 61 6c 20 62 79 74 65 73 20 72 65 71   Total bytes req
76f0: 75 69 72 69 6e 67 20 63 68 65 63 6b 73 75 6d 20  uiring checksum 
7700: 2a 2f 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 61  */.      int nCa
7710: 72 72 79 20 3d 20 30 3b 20 20 20 20 20 20 20 20  rry = 0;        
7720: 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 62 79       /* Total by
7730: 74 65 73 20 72 65 71 75 69 72 69 6e 67 20 63 68  tes requiring ch
7740: 65 63 6b 73 75 6d 20 2a 2f 0a 0a 20 20 20 20 20  ecksum */..     
7750: 20 6e 43 6b 73 75 6d 20 3d 20 70 2d 3e 69 42 75   nCksum = p->iBu
7760: 66 20 2d 20 70 2d 3e 69 43 6b 73 75 6d 42 75 66  f - p->iCksumBuf
7770: 3b 0a 20 20 20 20 20 20 69 66 28 20 6e 43 6b 73  ;.      if( nCks
7780: 75 6d 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20  um>0 ){.        
7790: 6e 43 61 72 72 79 20 3d 20 6e 43 6b 73 75 6d 20  nCarry = nCksum 
77a0: 25 20 38 3b 0a 20 20 20 20 20 20 20 20 6e 43 6b  % 8;.        nCk
77b0: 73 75 6d 20 3d 20 28 28 6e 43 6b 73 75 6d 20 2f  sum = ((nCksum /
77c0: 20 38 29 20 2a 20 38 29 3b 0a 20 20 20 20 20 20   8) * 8);.      
77d0: 20 20 69 66 28 20 6e 43 6b 73 75 6d 3e 30 20 29    if( nCksum>0 )
77e0: 7b 0a 20 20 20 20 20 20 20 20 20 20 6c 6f 67 43  {.          logC
77f0: 6b 73 75 6d 55 6e 61 6c 69 67 6e 65 64 28 0a 20  ksumUnaligned(. 
7800: 20 20 20 20 20 20 20 20 20 20 20 20 20 26 70 2d               &p-
7810: 3e 62 75 66 2e 7a 5b 70 2d 3e 69 43 6b 73 75 6d  >buf.z[p->iCksum
7820: 42 75 66 5d 2c 20 6e 43 6b 73 75 6d 2c 20 26 70  Buf], nCksum, &p
7830: 2d 3e 63 6b 73 75 6d 30 2c 20 26 70 2d 3e 63 6b  ->cksum0, &p->ck
7840: 73 75 6d 31 0a 20 20 20 20 20 20 20 20 20 20 29  sum1.          )
7850: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
7860: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 6e 43    }.      if( nC
7870: 61 72 72 79 3e 30 20 29 20 6d 65 6d 63 70 79 28  arry>0 ) memcpy(
7880: 70 2d 3e 62 75 66 2e 7a 2c 20 26 70 2d 3e 62 75  p->buf.z, &p->bu
7890: 66 2e 7a 5b 70 2d 3e 69 42 75 66 2d 6e 43 61 72  f.z[p->iBuf-nCar
78a0: 72 79 5d 2c 20 6e 43 61 72 72 79 29 3b 0a 20 20  ry], nCarry);.  
78b0: 20 20 20 20 70 2d 3e 62 75 66 2e 6e 20 3d 20 6e      p->buf.n = n
78c0: 43 61 72 72 79 3b 0a 20 20 20 20 20 20 70 2d 3e  Carry;.      p->
78d0: 69 42 75 66 20 3d 20 6e 43 61 72 72 79 3b 0a 0a  iBuf = nCarry;..
78e0: 20 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 46 73        rc = lsmFs
78f0: 52 65 61 64 4c 6f 67 28 70 2d 3e 70 46 53 2c 20  ReadLog(p->pFS, 
7900: 70 2d 3e 69 4f 66 66 2c 20 4c 4f 47 5f 52 45 41  p->iOff, LOG_REA
7910: 44 5f 53 49 5a 45 2c 20 26 70 2d 3e 62 75 66 29  D_SIZE, &p->buf)
7920: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 21 3d  ;.      if( rc!=
7930: 4c 53 4d 5f 4f 4b 20 29 20 62 72 65 61 6b 3b 0a  LSM_OK ) break;.
7940: 20 20 20 20 20 20 70 2d 3e 69 43 6b 73 75 6d 42        p->iCksumB
7950: 75 66 20 3d 20 30 3b 0a 20 20 20 20 20 20 70 2d  uf = 0;.      p-
7960: 3e 69 4f 66 66 20 2b 3d 20 4c 4f 47 5f 52 45 41  >iOff += LOG_REA
7970: 44 5f 53 49 5a 45 3b 0a 20 20 20 20 7d 0a 0a 20  D_SIZE;.    }.. 
7980: 20 20 20 6e 41 76 61 69 6c 20 3d 20 70 2d 3e 62     nAvail = p->b
7990: 75 66 2e 6e 20 2d 20 70 2d 3e 69 42 75 66 3b 0a  uf.n - p->iBuf;.
79a0: 20 20 20 20 69 66 28 20 70 70 42 6c 6f 62 20 26      if( ppBlob &
79b0: 26 20 6e 52 65 71 3d 3d 6e 42 6c 6f 62 20 26 26  & nReq==nBlob &&
79c0: 20 6e 42 6c 6f 62 3c 3d 6e 41 76 61 69 6c 20 29   nBlob<=nAvail )
79d0: 7b 0a 20 20 20 20 20 20 2a 70 70 42 6c 6f 62 20  {.      *ppBlob 
79e0: 3d 20 28 75 38 20 2a 29 26 70 2d 3e 62 75 66 2e  = (u8 *)&p->buf.
79f0: 7a 5b 70 2d 3e 69 42 75 66 5d 3b 0a 20 20 20 20  z[p->iBuf];.    
7a00: 20 20 70 2d 3e 69 42 75 66 20 2b 3d 20 6e 42 6c    p->iBuf += nBl
7a10: 6f 62 3b 0a 20 20 20 20 20 20 6e 52 65 71 20 3d  ob;.      nReq =
7a20: 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   0;.    }else{. 
7a30: 20 20 20 20 20 69 6e 74 20 6e 43 6f 70 79 20 3d       int nCopy =
7a40: 20 4c 53 4d 5f 4d 49 4e 28 6e 41 76 61 69 6c 2c   LSM_MIN(nAvail,
7a50: 20 6e 52 65 71 29 3b 0a 20 20 20 20 20 20 69 66   nReq);.      if
7a60: 28 20 6e 42 6c 6f 62 3d 3d 6e 52 65 71 20 29 7b  ( nBlob==nReq ){
7a70: 0a 20 20 20 20 20 20 20 20 70 42 75 66 2d 3e 6e  .        pBuf->n
7a80: 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = 0;.      }.  
7a90: 20 20 20 20 72 63 20 3d 20 6c 73 6d 53 74 72 69      rc = lsmStri
7aa0: 6e 67 42 69 6e 41 70 70 65 6e 64 28 70 42 75 66  ngBinAppend(pBuf
7ab0: 2c 20 28 75 38 20 2a 29 26 70 2d 3e 62 75 66 2e  , (u8 *)&p->buf.
7ac0: 7a 5b 70 2d 3e 69 42 75 66 5d 2c 20 6e 43 6f 70  z[p->iBuf], nCop
7ad0: 79 29 3b 0a 20 20 20 20 20 20 6e 52 65 71 20 2d  y);.      nReq -
7ae0: 3d 20 6e 43 6f 70 79 3b 0a 20 20 20 20 20 20 70  = nCopy;.      p
7af0: 2d 3e 69 42 75 66 20 2b 3d 20 6e 43 6f 70 79 3b  ->iBuf += nCopy;
7b00: 0a 20 20 20 20 20 20 69 66 28 20 6e 52 65 71 3d  .      if( nReq=
7b10: 3d 30 20 26 26 20 70 70 42 6c 6f 62 20 29 7b 0a  =0 && ppBlob ){.
7b20: 20 20 20 20 20 20 20 20 2a 70 70 42 6c 6f 62 20          *ppBlob 
7b30: 3d 20 28 75 38 2a 29 70 42 75 66 2d 3e 7a 3b 0a  = (u8*)pBuf->z;.
7b40: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
7b50: 7d 0a 0a 20 20 2a 70 52 63 20 3d 20 72 63 3b 0a  }..  *pRc = rc;.
7b60: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6c  }..static void l
7b70: 6f 67 52 65 61 64 65 72 56 61 72 69 6e 74 28 0a  ogReaderVarint(.
7b80: 20 20 4c 6f 67 52 65 61 64 65 72 20 2a 70 2c 20    LogReader *p, 
7b90: 0a 20 20 4c 73 6d 53 74 72 69 6e 67 20 2a 70 42  .  LsmString *pB
7ba0: 75 66 2c 0a 20 20 69 6e 74 20 2a 70 69 56 61 6c  uf,.  int *piVal
7bb0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
7bc0: 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 56 61        /* OUT: Va
7bd0: 6c 75 65 20 72 65 61 64 20 66 72 6f 6d 20 6c 6f  lue read from lo
7be0: 67 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 52 63 20  g */.  int *pRc 
7bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7c00: 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54         /* IN/OUT
7c10: 3a 20 45 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a  : Error code */.
7c20: 29 7b 0a 20 20 69 66 28 20 2a 70 52 63 3d 3d 4c  ){.  if( *pRc==L
7c30: 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 75 38 20  SM_OK ){.    u8 
7c40: 2a 61 56 61 72 69 6e 74 3b 0a 20 20 20 20 69 66  *aVarint;.    if
7c50: 28 20 70 2d 3e 62 75 66 2e 6e 3d 3d 70 2d 3e 69  ( p->buf.n==p->i
7c60: 42 75 66 20 29 7b 0a 20 20 20 20 20 20 6c 6f 67  Buf ){.      log
7c70: 52 65 61 64 65 72 42 6c 6f 62 28 70 2c 20 30 2c  ReaderBlob(p, 0,
7c80: 20 31 30 2c 20 26 61 56 61 72 69 6e 74 2c 20 70   10, &aVarint, p
7c90: 52 63 29 3b 0a 20 20 20 20 20 20 69 66 28 20 4c  Rc);.      if( L
7ca0: 53 4d 5f 4f 4b 3d 3d 2a 70 52 63 20 29 20 70 2d  SM_OK==*pRc ) p-
7cb0: 3e 69 42 75 66 20 2d 3d 20 28 31 30 20 2d 20 6c  >iBuf -= (10 - l
7cc0: 73 6d 56 61 72 69 6e 74 47 65 74 33 32 28 61 56  smVarintGet32(aV
7cd0: 61 72 69 6e 74 2c 20 70 69 56 61 6c 29 29 3b 0a  arint, piVal));.
7ce0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
7cf0: 20 6c 6f 67 52 65 61 64 65 72 42 6c 6f 62 28 70   logReaderBlob(p
7d00: 2c 20 70 42 75 66 2c 20 6c 73 6d 56 61 72 69 6e  , pBuf, lsmVarin
7d10: 74 53 69 7a 65 28 70 2d 3e 62 75 66 2e 7a 5b 70  tSize(p->buf.z[p
7d20: 2d 3e 69 42 75 66 5d 29 2c 20 26 61 56 61 72 69  ->iBuf]), &aVari
7d30: 6e 74 2c 20 70 52 63 29 3b 0a 20 20 20 20 20 20  nt, pRc);.      
7d40: 69 66 28 20 4c 53 4d 5f 4f 4b 3d 3d 2a 70 52 63  if( LSM_OK==*pRc
7d50: 20 29 20 6c 73 6d 56 61 72 69 6e 74 47 65 74 33   ) lsmVarintGet3
7d60: 32 28 61 56 61 72 69 6e 74 2c 20 70 69 56 61 6c  2(aVarint, piVal
7d70: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a  );.    }.  }.}..
7d80: 73 74 61 74 69 63 20 76 6f 69 64 20 6c 6f 67 52  static void logR
7d90: 65 61 64 65 72 42 79 74 65 28 4c 6f 67 52 65 61  eaderByte(LogRea
7da0: 64 65 72 20 2a 70 2c 20 75 38 20 2a 70 42 79 74  der *p, u8 *pByt
7db0: 65 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20  e, int *pRc){.  
7dc0: 75 38 20 2a 70 50 74 72 20 3d 20 30 3b 0a 20 20  u8 *pPtr = 0;.  
7dd0: 6c 6f 67 52 65 61 64 65 72 42 6c 6f 62 28 70 2c  logReaderBlob(p,
7de0: 20 30 2c 20 31 2c 20 26 70 50 74 72 2c 20 70 52   0, 1, &pPtr, pR
7df0: 63 29 3b 0a 20 20 69 66 28 20 70 50 74 72 20 29  c);.  if( pPtr )
7e00: 20 2a 70 42 79 74 65 20 3d 20 2a 70 50 74 72 3b   *pByte = *pPtr;
7e10: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
7e20: 6c 6f 67 52 65 61 64 65 72 43 6b 73 75 6d 28 4c  logReaderCksum(L
7e30: 6f 67 52 65 61 64 65 72 20 2a 70 2c 20 4c 73 6d  ogReader *p, Lsm
7e40: 53 74 72 69 6e 67 20 2a 70 42 75 66 2c 20 69 6e  String *pBuf, in
7e50: 74 20 2a 70 62 45 6f 66 2c 20 69 6e 74 20 2a 70  t *pbEof, int *p
7e60: 52 63 29 7b 0a 20 20 69 66 28 20 2a 70 52 63 3d  Rc){.  if( *pRc=
7e70: 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a 20 20 20 20 75  =LSM_OK ){.    u
7e80: 38 20 2a 70 50 74 72 20 3d 20 30 3b 0a 20 20 20  8 *pPtr = 0;.   
7e90: 20 75 33 32 20 63 6b 73 75 6d 30 2c 20 63 6b 73   u32 cksum0, cks
7ea0: 75 6d 31 3b 0a 20 20 20 20 69 6e 74 20 6e 43 6b  um1;.    int nCk
7eb0: 73 75 6d 20 3d 20 70 2d 3e 69 42 75 66 20 2d 20  sum = p->iBuf - 
7ec0: 70 2d 3e 69 43 6b 73 75 6d 42 75 66 3b 0a 0a 20  p->iCksumBuf;.. 
7ed0: 20 20 20 2f 2a 20 55 70 64 61 74 65 20 69 6e 2d     /* Update in-
7ee0: 6d 65 6d 6f 72 79 20 28 65 78 70 65 63 74 65 64  memory (expected
7ef0: 29 20 63 68 65 63 6b 73 75 6d 73 20 2a 2f 0a 20  ) checksums */. 
7f00: 20 20 20 61 73 73 65 72 74 28 20 6e 43 6b 73 75     assert( nCksu
7f10: 6d 3e 3d 30 20 29 3b 0a 20 20 20 20 6c 6f 67 43  m>=0 );.    logC
7f20: 6b 73 75 6d 55 6e 61 6c 69 67 6e 65 64 28 26 70  ksumUnaligned(&p
7f30: 2d 3e 62 75 66 2e 7a 5b 70 2d 3e 69 43 6b 73 75  ->buf.z[p->iCksu
7f40: 6d 42 75 66 5d 2c 20 6e 43 6b 73 75 6d 2c 20 26  mBuf], nCksum, &
7f50: 70 2d 3e 63 6b 73 75 6d 30 2c 20 26 70 2d 3e 63  p->cksum0, &p->c
7f60: 6b 73 75 6d 31 29 3b 0a 20 20 20 20 70 2d 3e 69  ksum1);.    p->i
7f70: 43 6b 73 75 6d 42 75 66 20 3d 20 70 2d 3e 69 42  CksumBuf = p->iB
7f80: 75 66 20 2b 20 38 3b 0a 20 20 20 20 6c 6f 67 52  uf + 8;.    logR
7f90: 65 61 64 65 72 42 6c 6f 62 28 70 2c 20 70 42 75  eaderBlob(p, pBu
7fa0: 66 2c 20 38 2c 20 26 70 50 74 72 2c 20 70 52 63  f, 8, &pPtr, pRc
7fb0: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
7fc0: 50 74 72 20 7c 7c 20 2a 70 52 63 20 29 3b 0a 0a  Ptr || *pRc );..
7fd0: 20 20 20 20 2f 2a 20 52 65 61 64 20 74 68 65 20      /* Read the 
7fe0: 63 68 65 63 6b 73 75 6d 73 20 66 72 6f 6d 20 74  checksums from t
7ff0: 68 65 20 6c 6f 67 20 66 69 6c 65 2e 20 53 65 74  he log file. Set
8000: 20 2a 70 62 45 6f 66 20 69 66 20 74 68 65 79 20   *pbEof if they 
8010: 64 6f 20 6e 6f 74 20 6d 61 74 63 68 2e 20 2a 2f  do not match. */
8020: 0a 20 20 20 20 69 66 28 20 70 50 74 72 20 29 7b  .    if( pPtr ){
8030: 0a 20 20 20 20 20 20 63 6b 73 75 6d 30 20 3d 20  .      cksum0 = 
8040: 6c 73 6d 47 65 74 55 33 32 28 70 50 74 72 29 3b  lsmGetU32(pPtr);
8050: 0a 20 20 20 20 20 20 63 6b 73 75 6d 31 20 3d 20  .      cksum1 = 
8060: 6c 73 6d 47 65 74 55 33 32 28 26 70 50 74 72 5b  lsmGetU32(&pPtr[
8070: 34 5d 29 3b 0a 20 20 20 20 20 20 2a 70 62 45 6f  4]);.      *pbEo
8080: 66 20 3d 20 28 63 6b 73 75 6d 30 21 3d 70 2d 3e  f = (cksum0!=p->
8090: 63 6b 73 75 6d 30 20 7c 7c 20 63 6b 73 75 6d 31  cksum0 || cksum1
80a0: 21 3d 70 2d 3e 63 6b 73 75 6d 31 29 3b 0a 20 20  !=p->cksum1);.  
80b0: 20 20 20 20 70 2d 3e 69 43 6b 73 75 6d 42 75 66      p->iCksumBuf
80c0: 20 3d 20 70 2d 3e 69 42 75 66 3b 0a 20 20 20 20   = p->iBuf;.    
80d0: 7d 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20  }.  }.}..static 
80e0: 76 6f 69 64 20 6c 6f 67 52 65 61 64 65 72 49 6e  void logReaderIn
80f0: 69 74 28 0a 20 20 6c 73 6d 5f 64 62 20 2a 70 44  it(.  lsm_db *pD
8100: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
8110: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
8120: 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 44 62  e handle */.  Db
8130: 4c 6f 67 20 2a 70 4c 6f 67 2c 20 20 20 20 20 20  Log *pLog,      
8140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8150: 20 4c 6f 67 20 6f 62 6a 65 63 74 20 61 73 73 6f   Log object asso
8160: 63 69 61 74 65 64 20 77 69 74 68 20 70 44 62 20  ciated with pDb 
8170: 2a 2f 0a 20 20 69 6e 74 20 62 49 6e 69 74 42 75  */.  int bInitBu
8180: 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f,              
8190: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
81a0: 70 2d 3e 62 75 66 20 69 73 20 75 6e 69 6e 69 74  p->buf is uninit
81b0: 69 61 6c 69 7a 65 64 20 2a 2f 0a 20 20 4c 6f 67  ialized */.  Log
81c0: 52 65 61 64 65 72 20 2a 70 20 20 20 20 20 20 20  Reader *p       
81d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
81e0: 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 69 73 20  Initialize this 
81f0: 4c 6f 67 52 65 61 64 65 72 20 6f 62 6a 65 63 74  LogReader object
8200: 20 2a 2f 0a 29 7b 0a 20 20 70 2d 3e 70 46 53 20   */.){.  p->pFS 
8210: 3d 20 70 44 62 2d 3e 70 46 53 3b 0a 20 20 70 2d  = pDb->pFS;.  p-
8220: 3e 69 4f 66 66 20 3d 20 70 4c 6f 67 2d 3e 61 52  >iOff = pLog->aR
8230: 65 67 69 6f 6e 5b 32 5d 2e 69 53 74 61 72 74 3b  egion[2].iStart;
8240: 0a 20 20 70 2d 3e 63 6b 73 75 6d 30 20 3d 20 70  .  p->cksum0 = p
8250: 4c 6f 67 2d 3e 63 6b 73 75 6d 30 3b 0a 20 20 70  Log->cksum0;.  p
8260: 2d 3e 63 6b 73 75 6d 31 20 3d 20 70 4c 6f 67 2d  ->cksum1 = pLog-
8270: 3e 63 6b 73 75 6d 31 3b 0a 20 20 69 66 28 20 62  >cksum1;.  if( b
8280: 49 6e 69 74 42 75 66 20 29 7b 20 6c 73 6d 53 74  InitBuf ){ lsmSt
8290: 72 69 6e 67 49 6e 69 74 28 26 70 2d 3e 62 75 66  ringInit(&p->buf
82a0: 2c 20 70 44 62 2d 3e 70 45 6e 76 29 3b 20 7d 0a  , pDb->pEnv); }.
82b0: 20 20 70 2d 3e 62 75 66 2e 6e 20 3d 20 30 3b 0a    p->buf.n = 0;.
82c0: 20 20 70 2d 3e 69 43 6b 73 75 6d 42 75 66 20 3d    p->iCksumBuf =
82d0: 20 30 3b 0a 20 20 70 2d 3e 69 42 75 66 20 3d 20   0;.  p->iBuf = 
82e0: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  0;.}../*.** This
82f0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
8300: 6c 65 64 20 61 66 74 65 72 20 72 65 61 64 69 6e  led after readin
8310: 67 20 74 68 65 20 68 65 61 64 65 72 20 6f 66 20  g the header of 
8320: 61 20 4c 4f 47 5f 44 45 4c 45 54 45 20 6f 72 0a  a LOG_DELETE or.
8330: 2a 2a 20 4c 4f 47 5f 57 52 49 54 45 20 72 65 63  ** LOG_WRITE rec
8340: 6f 72 64 2e 20 50 61 72 61 6d 65 74 65 72 20 6e  ord. Parameter n
8350: 42 79 74 65 20 69 73 20 74 68 65 20 74 6f 74 61  Byte is the tota
8360: 6c 20 73 69 7a 65 20 6f 66 20 74 68 65 20 6b 65  l size of the ke
8370: 79 20 61 6e 64 0a 2a 2a 20 76 61 6c 75 65 20 74  y and.** value t
8380: 68 61 74 20 66 6f 6c 6c 6f 77 20 74 68 65 20 68  hat follow the h
8390: 65 61 64 65 72 20 6a 75 73 74 20 72 65 61 64 2e  eader just read.
83a0: 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20   Return true if 
83b0: 74 68 65 20 73 69 7a 65 20 61 6e 64 0a 2a 2a 20  the size and.** 
83c0: 70 6f 73 69 74 69 6f 6e 20 6f 66 20 74 68 65 20  position of the 
83d0: 72 65 63 6f 72 64 20 69 6e 64 69 63 61 74 65 20  record indicate 
83e0: 74 68 61 74 20 69 74 20 73 68 6f 75 6c 64 20 63  that it should c
83f0: 6f 6e 74 61 69 6e 20 61 20 63 68 65 63 6b 73 75  ontain a checksu
8400: 6d 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  m..*/.static int
8410: 20 6c 6f 67 52 65 71 75 69 72 65 43 6b 73 75 6d   logRequireCksum
8420: 28 4c 6f 67 52 65 61 64 65 72 20 2a 70 2c 20 69  (LogReader *p, i
8430: 6e 74 20 6e 42 79 74 65 29 7b 0a 20 20 72 65 74  nt nByte){.  ret
8440: 75 72 6e 20 28 28 70 2d 3e 69 42 75 66 20 2b 20  urn ((p->iBuf + 
8450: 6e 42 79 74 65 20 2d 20 70 2d 3e 69 43 6b 73 75  nByte - p->iCksu
8460: 6d 42 75 66 29 20 3e 20 4c 53 4d 5f 43 4b 53 55  mBuf) > LSM_CKSU
8470: 4d 5f 4d 41 58 44 41 54 41 29 3b 0a 7d 0a 0a 2f  M_MAXDATA);.}../
8480: 2a 0a 2a 2a 20 52 65 63 6f 76 65 72 20 74 68 65  *.** Recover the
8490: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
84a0: 20 6c 6f 67 20 66 69 6c 65 2e 0a 2a 2f 0a 69 6e   log file..*/.in
84b0: 74 20 6c 73 6d 4c 6f 67 52 65 63 6f 76 65 72 28  t lsmLogRecover(
84c0: 6c 73 6d 5f 64 62 20 2a 70 44 62 29 7b 0a 20 20  lsm_db *pDb){.  
84d0: 4c 73 6d 53 74 72 69 6e 67 20 62 75 66 31 3b 20  LsmString buf1; 
84e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
84f0: 2f 2a 20 4b 65 79 20 62 75 66 66 65 72 20 2a 2f  /* Key buffer */
8500: 0a 20 20 4c 73 6d 53 74 72 69 6e 67 20 62 75 66  .  LsmString buf
8510: 32 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  2;              
8520: 20 20 20 2f 2a 20 56 61 6c 75 65 20 62 75 66 66     /* Value buff
8530: 65 72 20 2a 2f 0a 20 20 4c 6f 67 52 65 61 64 65  er */.  LogReade
8540: 72 20 72 65 61 64 65 72 3b 20 20 20 20 20 20 20  r reader;       
8550: 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 67 20 72          /* Log r
8560: 65 61 64 65 72 20 6f 62 6a 65 63 74 20 2a 2f 0a  eader object */.
8570: 20 20 69 6e 74 20 72 63 20 3d 20 4c 53 4d 5f 4f    int rc = LSM_O
8580: 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  K;              
8590: 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65    /* Return code
85a0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6d 6d 69   */.  int nCommi
85b0: 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  t = 0;          
85c0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
85d0: 6f 66 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 20  of transactions 
85e0: 74 6f 20 72 65 63 6f 76 65 72 20 2a 2f 0a 20 20  to recover */.  
85f0: 69 6e 74 20 69 50 61 73 73 3b 0a 20 20 69 6e 74  int iPass;.  int
8600: 20 6e 4a 75 6d 70 20 3d 20 30 3b 20 20 20 20 20   nJump = 0;     
8610: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8620: 4e 75 6d 62 65 72 20 6f 66 20 4c 53 4d 5f 4c 4f  Number of LSM_LO
8630: 47 5f 4a 55 4d 50 20 72 65 63 6f 72 64 73 20 69  G_JUMP records i
8640: 6e 20 70 61 73 73 20 30 20 2a 2f 0a 20 20 44 62  n pass 0 */.  Db
8650: 4c 6f 67 20 2a 70 4c 6f 67 3b 0a 20 20 69 6e 74  Log *pLog;.  int
8660: 20 62 4f 70 65 6e 3b 0a 0a 20 20 72 63 20 3d 20   bOpen;..  rc = 
8670: 6c 73 6d 46 73 4f 70 65 6e 4c 6f 67 28 70 44 62  lsmFsOpenLog(pDb
8680: 2c 20 26 62 4f 70 65 6e 29 3b 0a 20 20 69 66 28  , &bOpen);.  if(
8690: 20 72 63 21 3d 4c 53 4d 5f 4f 4b 20 29 20 72 65   rc!=LSM_OK ) re
86a0: 74 75 72 6e 20 72 63 3b 0a 0a 20 20 72 63 20 3d  turn rc;..  rc =
86b0: 20 6c 73 6d 54 72 65 65 49 6e 69 74 28 70 44 62   lsmTreeInit(pDb
86c0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 4c 53 4d  );.  if( rc!=LSM
86d0: 5f 4f 4b 20 29 20 72 65 74 75 72 6e 20 72 63 3b  _OK ) return rc;
86e0: 0a 0a 20 20 70 4c 6f 67 20 3d 20 26 70 44 62 2d  ..  pLog = &pDb-
86f0: 3e 74 72 65 65 68 64 72 2e 6c 6f 67 3b 0a 20 20  >treehdr.log;.  
8700: 6c 73 6d 43 68 65 63 6b 70 6f 69 6e 74 4c 6f 67  lsmCheckpointLog
8710: 6f 66 66 73 65 74 28 70 44 62 2d 3e 70 53 68 6d  offset(pDb->pShm
8720: 68 64 72 2d 3e 61 53 6e 61 70 32 2c 20 70 4c 6f  hdr->aSnap2, pLo
8730: 67 29 3b 0a 0a 20 20 6c 6f 67 52 65 61 64 65 72  g);..  logReader
8740: 49 6e 69 74 28 70 44 62 2c 20 70 4c 6f 67 2c 20  Init(pDb, pLog, 
8750: 31 2c 20 26 72 65 61 64 65 72 29 3b 0a 20 20 6c  1, &reader);.  l
8760: 73 6d 53 74 72 69 6e 67 49 6e 69 74 28 26 62 75  smStringInit(&bu
8770: 66 31 2c 20 70 44 62 2d 3e 70 45 6e 76 29 3b 0a  f1, pDb->pEnv);.
8780: 20 20 6c 73 6d 53 74 72 69 6e 67 49 6e 69 74 28    lsmStringInit(
8790: 26 62 75 66 32 2c 20 70 44 62 2d 3e 70 45 6e 76  &buf2, pDb->pEnv
87a0: 29 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 6f 75 74  );..  /* The out
87b0: 65 72 20 66 6f 72 28 29 20 6c 6f 6f 70 20 72 75  er for() loop ru
87c0: 6e 73 20 61 74 20 6d 6f 73 74 20 74 77 69 63 65  ns at most twice
87d0: 2e 20 54 68 65 20 66 69 72 73 74 20 69 74 65 72  . The first iter
87e0: 61 74 69 6f 6e 20 69 73 20 74 6f 20 0a 20 20 2a  ation is to .  *
87f0: 2a 20 63 6f 75 6e 74 20 74 68 65 20 6e 75 6d 62  * count the numb
8800: 65 72 20 6f 66 20 63 6f 6d 6d 69 74 74 65 64 20  er of committed 
8810: 74 72 61 6e 73 61 63 74 69 6f 6e 73 20 69 6e 20  transactions in 
8820: 74 68 65 20 6c 6f 67 2e 20 54 68 65 20 73 65 63  the log. The sec
8830: 6f 6e 64 20 0a 20 20 2a 2a 20 69 74 65 72 61 74  ond .  ** iterat
8840: 65 73 20 74 68 72 6f 75 67 68 20 74 68 6f 73 65  es through those
8850: 20 74 72 61 6e 73 61 63 74 69 6f 6e 73 20 61 6e   transactions an
8860: 64 20 75 70 64 61 74 65 73 20 74 68 65 20 69 6e  d updates the in
8870: 2d 6d 65 6d 6f 72 79 20 74 72 65 65 20 0a 20 20  -memory tree .  
8880: 2a 2a 20 73 74 72 75 63 74 75 72 65 20 77 69 74  ** structure wit
8890: 68 20 74 68 65 69 72 20 63 6f 6e 74 65 6e 74 73  h their contents
88a0: 2e 20 20 2a 2f 0a 20 20 69 66 28 20 62 4f 70 65  .  */.  if( bOpe
88b0: 6e 20 29 7b 0a 20 20 20 20 66 6f 72 28 69 50 61  n ){.    for(iPa
88c0: 73 73 3d 30 3b 20 69 50 61 73 73 3c 32 20 26 26  ss=0; iPass<2 &&
88d0: 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 3b 20 69 50 61   rc==LSM_OK; iPa
88e0: 73 73 2b 2b 29 7b 0a 20 20 20 20 20 20 69 6e 74  ss++){.      int
88f0: 20 62 45 6f 66 20 3d 20 30 3b 0a 0a 20 20 20 20   bEof = 0;..    
8900: 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 4c 53 4d    while( rc==LSM
8910: 5f 4f 4b 20 26 26 20 21 62 45 6f 66 20 29 7b 0a  _OK && !bEof ){.
8920: 20 20 20 20 20 20 20 20 75 38 20 65 54 79 70 65          u8 eType
8930: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 6c 6f   = 0;.        lo
8940: 67 52 65 61 64 65 72 42 79 74 65 28 26 72 65 61  gReaderByte(&rea
8950: 64 65 72 2c 20 26 65 54 79 70 65 2c 20 26 72 63  der, &eType, &rc
8960: 29 3b 0a 0a 20 20 20 20 20 20 20 20 73 77 69 74  );..        swit
8970: 63 68 28 20 65 54 79 70 65 20 29 7b 0a 20 20 20  ch( eType ){.   
8980: 20 20 20 20 20 20 20 63 61 73 65 20 4c 53 4d 5f         case LSM_
8990: 4c 4f 47 5f 50 41 44 31 3a 0a 20 20 20 20 20 20  LOG_PAD1:.      
89a0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20        break;..  
89b0: 20 20 20 20 20 20 20 20 63 61 73 65 20 4c 53 4d          case LSM
89c0: 5f 4c 4f 47 5f 50 41 44 32 3a 20 7b 0a 20 20 20  _LOG_PAD2: {.   
89d0: 20 20 20 20 20 20 20 20 20 69 6e 74 20 6e 50 61           int nPa
89e0: 64 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c  d;.            l
89f0: 6f 67 52 65 61 64 65 72 56 61 72 69 6e 74 28 26  ogReaderVarint(&
8a00: 72 65 61 64 65 72 2c 20 26 62 75 66 31 2c 20 26  reader, &buf1, &
8a10: 6e 50 61 64 2c 20 26 72 63 29 3b 0a 20 20 20 20  nPad, &rc);.    
8a20: 20 20 20 20 20 20 20 20 6c 6f 67 52 65 61 64 65          logReade
8a30: 72 42 6c 6f 62 28 26 72 65 61 64 65 72 2c 20 26  rBlob(&reader, &
8a40: 62 75 66 31 2c 20 6e 50 61 64 2c 20 30 2c 20 26  buf1, nPad, 0, &
8a50: 72 63 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  rc);.           
8a60: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
8a70: 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 63    }..          c
8a80: 61 73 65 20 4c 53 4d 5f 4c 4f 47 5f 44 52 41 4e  ase LSM_LOG_DRAN
8a90: 47 45 3a 0a 20 20 20 20 20 20 20 20 20 20 63 61  GE:.          ca
8aa0: 73 65 20 4c 53 4d 5f 4c 4f 47 5f 44 52 41 4e 47  se LSM_LOG_DRANG
8ab0: 45 5f 43 4b 53 55 4d 3a 0a 20 20 20 20 20 20 20  E_CKSUM:.       
8ac0: 20 20 20 63 61 73 65 20 4c 53 4d 5f 4c 4f 47 5f     case LSM_LOG_
8ad0: 57 52 49 54 45 3a 0a 20 20 20 20 20 20 20 20 20  WRITE:.         
8ae0: 20 63 61 73 65 20 4c 53 4d 5f 4c 4f 47 5f 57 52   case LSM_LOG_WR
8af0: 49 54 45 5f 43 4b 53 55 4d 3a 20 7b 0a 20 20 20  ITE_CKSUM: {.   
8b00: 20 20 20 20 20 20 20 20 20 69 6e 74 20 6e 4b 65           int nKe
8b10: 79 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  y;.            i
8b20: 6e 74 20 6e 56 61 6c 3b 0a 20 20 20 20 20 20 20  nt nVal;.       
8b30: 20 20 20 20 20 75 38 20 2a 61 56 61 6c 3b 0a 20       u8 *aVal;. 
8b40: 20 20 20 20 20 20 20 20 20 20 20 6c 6f 67 52 65             logRe
8b50: 61 64 65 72 56 61 72 69 6e 74 28 26 72 65 61 64  aderVarint(&read
8b60: 65 72 2c 20 26 62 75 66 31 2c 20 26 6e 4b 65 79  er, &buf1, &nKey
8b70: 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20  , &rc);.        
8b80: 20 20 20 20 6c 6f 67 52 65 61 64 65 72 56 61 72      logReaderVar
8b90: 69 6e 74 28 26 72 65 61 64 65 72 2c 20 26 62 75  int(&reader, &bu
8ba0: 66 32 2c 20 26 6e 56 61 6c 2c 20 26 72 63 29 3b  f2, &nVal, &rc);
8bb0: 0a 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66  ..            if
8bc0: 28 20 65 54 79 70 65 3d 3d 4c 53 4d 5f 4c 4f 47  ( eType==LSM_LOG
8bd0: 5f 57 52 49 54 45 5f 43 4b 53 55 4d 20 7c 7c 20  _WRITE_CKSUM || 
8be0: 65 54 79 70 65 3d 3d 4c 53 4d 5f 4c 4f 47 5f 44  eType==LSM_LOG_D
8bf0: 52 41 4e 47 45 5f 43 4b 53 55 4d 20 29 7b 0a 20  RANGE_CKSUM ){. 
8c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 67               log
8c10: 52 65 61 64 65 72 43 6b 73 75 6d 28 26 72 65 61  ReaderCksum(&rea
8c20: 64 65 72 2c 20 26 62 75 66 31 2c 20 26 62 45 6f  der, &buf1, &bEo
8c30: 66 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20  f, &rc);.       
8c40: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
8c50: 20 20 20 20 20 20 20 20 20 20 62 45 6f 66 20 3d            bEof =
8c60: 20 6c 6f 67 52 65 71 75 69 72 65 43 6b 73 75 6d   logRequireCksum
8c70: 28 26 72 65 61 64 65 72 2c 20 6e 4b 65 79 2b 6e  (&reader, nKey+n
8c80: 56 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Val);.          
8c90: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20    }.            
8ca0: 69 66 28 20 62 45 6f 66 20 29 20 62 72 65 61 6b  if( bEof ) break
8cb0: 3b 0a 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c  ;..            l
8cc0: 6f 67 52 65 61 64 65 72 42 6c 6f 62 28 26 72 65  ogReaderBlob(&re
8cd0: 61 64 65 72 2c 20 26 62 75 66 31 2c 20 6e 4b 65  ader, &buf1, nKe
8ce0: 79 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20 20 20  y, 0, &rc);.    
8cf0: 20 20 20 20 20 20 20 20 6c 6f 67 52 65 61 64 65          logReade
8d00: 72 42 6c 6f 62 28 26 72 65 61 64 65 72 2c 20 26  rBlob(&reader, &
8d10: 62 75 66 32 2c 20 6e 56 61 6c 2c 20 26 61 56 61  buf2, nVal, &aVa
8d20: 6c 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20  l, &rc);.       
8d30: 20 20 20 20 20 69 66 28 20 69 50 61 73 73 3d 3d       if( iPass==
8d40: 31 20 26 26 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20  1 && rc==LSM_OK 
8d50: 29 7b 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  ){ .            
8d60: 20 20 69 66 28 20 65 54 79 70 65 3d 3d 4c 53 4d    if( eType==LSM
8d70: 5f 4c 4f 47 5f 57 52 49 54 45 20 7c 7c 20 65 54  _LOG_WRITE || eT
8d80: 79 70 65 3d 3d 4c 53 4d 5f 4c 4f 47 5f 57 52 49  ype==LSM_LOG_WRI
8d90: 54 45 5f 43 4b 53 55 4d 20 29 7b 0a 20 20 20 20  TE_CKSUM ){.    
8da0: 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20 3d              rc =
8db0: 20 6c 73 6d 54 72 65 65 49 6e 73 65 72 74 28 70   lsmTreeInsert(p
8dc0: 44 62 2c 20 28 75 38 20 2a 29 62 75 66 31 2e 7a  Db, (u8 *)buf1.z
8dd0: 2c 20 6e 4b 65 79 2c 20 61 56 61 6c 2c 20 6e 56  , nKey, aVal, nV
8de0: 61 6c 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  al);.           
8df0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
8e00: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 6c            rc = l
8e10: 73 6d 54 72 65 65 44 65 6c 65 74 65 28 70 44 62  smTreeDelete(pDb
8e20: 2c 20 28 75 38 20 2a 29 62 75 66 31 2e 7a 2c 20  , (u8 *)buf1.z, 
8e30: 6e 4b 65 79 2c 20 61 56 61 6c 2c 20 6e 56 61 6c  nKey, aVal, nVal
8e40: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  );.             
8e50: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d   }.            }
8e60: 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65  .            bre
8e70: 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  ak;.          }.
8e80: 0a 20 20 20 20 20 20 20 20 20 20 63 61 73 65 20  .          case 
8e90: 4c 53 4d 5f 4c 4f 47 5f 44 45 4c 45 54 45 3a 0a  LSM_LOG_DELETE:.
8ea0: 20 20 20 20 20 20 20 20 20 20 63 61 73 65 20 4c            case L
8eb0: 53 4d 5f 4c 4f 47 5f 44 45 4c 45 54 45 5f 43 4b  SM_LOG_DELETE_CK
8ec0: 53 55 4d 3a 20 7b 0a 20 20 20 20 20 20 20 20 20  SUM: {.         
8ed0: 20 20 20 69 6e 74 20 6e 4b 65 79 3b 20 75 38 20     int nKey; u8 
8ee0: 2a 61 4b 65 79 3b 0a 20 20 20 20 20 20 20 20 20  *aKey;.         
8ef0: 20 20 20 6c 6f 67 52 65 61 64 65 72 56 61 72 69     logReaderVari
8f00: 6e 74 28 26 72 65 61 64 65 72 2c 20 26 62 75 66  nt(&reader, &buf
8f10: 31 2c 20 26 6e 4b 65 79 2c 20 26 72 63 29 3b 0a  1, &nKey, &rc);.
8f20: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28  .            if(
8f30: 20 65 54 79 70 65 3d 3d 4c 53 4d 5f 4c 4f 47 5f   eType==LSM_LOG_
8f40: 44 45 4c 45 54 45 5f 43 4b 53 55 4d 20 29 7b 0a  DELETE_CKSUM ){.
8f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f                lo
8f60: 67 52 65 61 64 65 72 43 6b 73 75 6d 28 26 72 65  gReaderCksum(&re
8f70: 61 64 65 72 2c 20 26 62 75 66 31 2c 20 26 62 45  ader, &buf1, &bE
8f80: 6f 66 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20  of, &rc);.      
8f90: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
8fa0: 20 20 20 20 20 20 20 20 20 20 20 62 45 6f 66 20             bEof 
8fb0: 3d 20 6c 6f 67 52 65 71 75 69 72 65 43 6b 73 75  = logRequireCksu
8fc0: 6d 28 26 72 65 61 64 65 72 2c 20 6e 4b 65 79 29  m(&reader, nKey)
8fd0: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a  ;.            }.
8fe0: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20              if( 
8ff0: 62 45 6f 66 20 29 20 62 72 65 61 6b 3b 0a 0a 20  bEof ) break;.. 
9000: 20 20 20 20 20 20 20 20 20 20 20 6c 6f 67 52 65             logRe
9010: 61 64 65 72 42 6c 6f 62 28 26 72 65 61 64 65 72  aderBlob(&reader
9020: 2c 20 26 62 75 66 31 2c 20 6e 4b 65 79 2c 20 26  , &buf1, nKey, &
9030: 61 4b 65 79 2c 20 26 72 63 29 3b 0a 20 20 20 20  aKey, &rc);.    
9040: 20 20 20 20 20 20 20 20 69 66 28 20 69 50 61 73          if( iPas
9050: 73 3d 3d 31 20 26 26 20 72 63 3d 3d 4c 53 4d 5f  s==1 && rc==LSM_
9060: 4f 4b 20 29 7b 20 0a 20 20 20 20 20 20 20 20 20  OK ){ .         
9070: 20 20 20 20 20 72 63 20 3d 20 6c 73 6d 54 72 65       rc = lsmTre
9080: 65 49 6e 73 65 72 74 28 70 44 62 2c 20 61 4b 65  eInsert(pDb, aKe
9090: 79 2c 20 6e 4b 65 79 2c 20 4e 55 4c 4c 2c 20 2d  y, nKey, NULL, -
90a0: 31 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  1);.            
90b0: 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 72  }.            br
90c0: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  eak;.          }
90d0: 0a 0a 20 20 20 20 20 20 20 20 20 20 63 61 73 65  ..          case
90e0: 20 4c 53 4d 5f 4c 4f 47 5f 43 4f 4d 4d 49 54 3a   LSM_LOG_COMMIT:
90f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 67  .            log
9100: 52 65 61 64 65 72 43 6b 73 75 6d 28 26 72 65 61  ReaderCksum(&rea
9110: 64 65 72 2c 20 26 62 75 66 31 2c 20 26 62 45 6f  der, &buf1, &bEo
9120: 66 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20  f, &rc);.       
9130: 20 20 20 20 20 69 66 28 20 62 45 6f 66 3d 3d 30       if( bEof==0
9140: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
9150: 20 20 6e 43 6f 6d 6d 69 74 2b 2b 3b 0a 20 20 20    nCommit++;.   
9160: 20 20 20 20 20 20 20 20 20 20 20 61 73 73 65 72             asser
9170: 74 28 20 6e 43 6f 6d 6d 69 74 3e 30 20 7c 7c 20  t( nCommit>0 || 
9180: 69 50 61 73 73 3d 3d 31 20 29 3b 0a 20 20 20 20  iPass==1 );.    
9190: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 6e 43            if( nC
91a0: 6f 6d 6d 69 74 3d 3d 30 20 29 20 62 45 6f 66 20  ommit==0 ) bEof 
91b0: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20 20  = 1;.           
91c0: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 62   }.            b
91d0: 72 65 61 6b 3b 0a 0a 20 20 20 20 20 20 20 20 20  reak;..         
91e0: 20 63 61 73 65 20 4c 53 4d 5f 4c 4f 47 5f 4a 55   case LSM_LOG_JU
91f0: 4d 50 3a 20 7b 0a 20 20 20 20 20 20 20 20 20 20  MP: {.          
9200: 20 20 69 6e 74 20 69 4f 66 66 20 3d 20 30 3b 0a    int iOff = 0;.
9210: 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 67 52              logR
9220: 65 61 64 65 72 56 61 72 69 6e 74 28 26 72 65 61  eaderVarint(&rea
9230: 64 65 72 2c 20 26 62 75 66 31 2c 20 26 69 4f 66  der, &buf1, &iOf
9240: 66 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20  f, &rc);.       
9250: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 4c 53 4d       if( rc==LSM
9260: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20  _OK ){.         
9270: 20 20 20 20 20 69 66 28 20 69 50 61 73 73 3d 3d       if( iPass==
9280: 31 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  1 ){.           
9290: 20 20 20 20 20 69 66 28 20 70 4c 6f 67 2d 3e 61       if( pLog->a
92a0: 52 65 67 69 6f 6e 5b 32 5d 2e 69 53 74 61 72 74  Region[2].iStart
92b0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
92c0: 20 20 20 20 20 20 20 20 20 61 73 73 65 72 74 28           assert(
92d0: 20 70 4c 6f 67 2d 3e 61 52 65 67 69 6f 6e 5b 31   pLog->aRegion[1
92e0: 5d 2e 69 53 74 61 72 74 3d 3d 30 20 29 3b 0a 20  ].iStart==0 );. 
92f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9300: 20 70 4c 6f 67 2d 3e 61 52 65 67 69 6f 6e 5b 31   pLog->aRegion[1
9310: 5d 2e 69 45 6e 64 20 3d 20 72 65 61 64 65 72 2e  ].iEnd = reader.
9320: 69 4f 66 66 3b 0a 20 20 20 20 20 20 20 20 20 20  iOff;.          
9330: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
9340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61                 a
9350: 73 73 65 72 74 28 20 70 4c 6f 67 2d 3e 61 52 65  ssert( pLog->aRe
9360: 67 69 6f 6e 5b 30 5d 2e 69 53 74 61 72 74 3d 3d  gion[0].iStart==
9370: 30 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  0 );.           
9380: 20 20 20 20 20 20 20 70 4c 6f 67 2d 3e 61 52 65         pLog->aRe
9390: 67 69 6f 6e 5b 30 5d 2e 69 53 74 61 72 74 20 3d  gion[0].iStart =
93a0: 20 70 4c 6f 67 2d 3e 61 52 65 67 69 6f 6e 5b 32   pLog->aRegion[2
93b0: 5d 2e 69 53 74 61 72 74 3b 0a 20 20 20 20 20 20  ].iStart;.      
93c0: 20 20 20 20 20 20 20 20 20 20 20 20 70 4c 6f 67              pLog
93d0: 2d 3e 61 52 65 67 69 6f 6e 5b 30 5d 2e 69 45 6e  ->aRegion[0].iEn
93e0: 64 20 3d 20 72 65 61 64 65 72 2e 69 4f 66 66 2d  d = reader.iOff-
93f0: 72 65 61 64 65 72 2e 62 75 66 2e 6e 2b 72 65 61  reader.buf.n+rea
9400: 64 65 72 2e 69 42 75 66 3b 0a 20 20 20 20 20 20  der.iBuf;.      
9410: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
9420: 20 20 20 20 20 20 20 20 20 20 20 20 70 4c 6f 67              pLog
9430: 2d 3e 61 52 65 67 69 6f 6e 5b 32 5d 2e 69 53 74  ->aRegion[2].iSt
9440: 61 72 74 20 3d 20 69 4f 66 66 3b 0a 20 20 20 20  art = iOff;.    
9450: 20 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b            }else{
9460: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
9470: 20 69 66 28 20 28 6e 4a 75 6d 70 2b 2b 29 3d 3d   if( (nJump++)==
9480: 32 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  2 ){.           
9490: 20 20 20 20 20 20 20 62 45 6f 66 20 3d 20 31 3b         bEof = 1;
94a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
94b0: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   }.             
94c0: 20 7d 0a 0a 20 20 20 20 20 20 20 20 20 20 20 20   }..            
94d0: 20 20 72 65 61 64 65 72 2e 69 4f 66 66 20 3d 20    reader.iOff = 
94e0: 69 4f 66 66 3b 0a 20 20 20 20 20 20 20 20 20 20  iOff;.          
94f0: 20 20 20 20 72 65 61 64 65 72 2e 62 75 66 2e 6e      reader.buf.n
9500: 20 3d 20 72 65 61 64 65 72 2e 69 42 75 66 3b 0a   = reader.iBuf;.
9510: 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20              }.  
9520: 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
9530: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 0a 20 20  .          }..  
9540: 20 20 20 20 20 20 20 20 64 65 66 61 75 6c 74 3a          default:
9550: 0a 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  .            /* 
9560: 49 6e 63 6c 75 64 69 6e 67 20 4c 53 4d 5f 4c 4f  Including LSM_LO
9570: 47 5f 45 4f 46 20 2a 2f 0a 20 20 20 20 20 20 20  G_EOF */.       
9580: 20 20 20 20 20 62 45 6f 66 20 3d 20 31 3b 0a 20       bEof = 1;. 
9590: 20 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b             break
95a0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
95b0: 20 20 7d 0a 0a 20 20 20 20 20 20 69 66 28 20 72    }..      if( r
95c0: 63 3d 3d 4c 53 4d 5f 4f 4b 20 26 26 20 69 50 61  c==LSM_OK && iPa
95d0: 73 73 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  ss==0 ){.       
95e0: 20 69 66 28 20 6e 43 6f 6d 6d 69 74 3d 3d 30 20   if( nCommit==0 
95f0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  ){.          if(
9600: 20 70 4c 6f 67 2d 3e 61 52 65 67 69 6f 6e 5b 32   pLog->aRegion[2
9610: 5d 2e 69 53 74 61 72 74 3d 3d 30 20 29 7b 0a 20  ].iStart==0 ){. 
9620: 20 20 20 20 20 20 20 20 20 20 20 69 50 61 73 73             iPass
9630: 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20   = 1;.          
9640: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20  }else{.         
9650: 20 20 20 70 4c 6f 67 2d 3e 61 52 65 67 69 6f 6e     pLog->aRegion
9660: 5b 32 5d 2e 69 53 74 61 72 74 20 3d 20 30 3b 0a  [2].iStart = 0;.
9670: 20 20 20 20 20 20 20 20 20 20 20 20 69 50 61 73              iPas
9680: 73 20 3d 20 2d 31 3b 0a 20 20 20 20 20 20 20 20  s = -1;.        
9690: 20 20 20 20 6c 73 6d 43 68 65 63 6b 70 6f 69 6e      lsmCheckpoin
96a0: 74 5a 65 72 6f 4c 6f 67 6f 66 66 73 65 74 28 70  tZeroLogoffset(p
96b0: 44 62 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d  Db);.          }
96c0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
96d0: 20 20 20 6c 6f 67 52 65 61 64 65 72 49 6e 69 74     logReaderInit
96e0: 28 70 44 62 2c 20 70 4c 6f 67 2c 20 30 2c 20 26  (pDb, pLog, 0, &
96f0: 72 65 61 64 65 72 29 3b 0a 20 20 20 20 20 20 20  reader);.       
9700: 20 6e 43 6f 6d 6d 69 74 20 3d 20 6e 43 6f 6d 6d   nCommit = nComm
9710: 69 74 20 2a 20 2d 31 3b 0a 20 20 20 20 20 20 7d  it * -1;.      }
9720: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
9730: 20 49 6e 69 74 69 61 6c 69 7a 65 20 44 62 4c 6f   Initialize DbLo
9740: 67 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69 66  g object */.  if
9750: 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20 29 7b 0a  ( rc==LSM_OK ){.
9760: 20 20 20 20 70 4c 6f 67 2d 3e 61 52 65 67 69 6f      pLog->aRegio
9770: 6e 5b 32 5d 2e 69 45 6e 64 20 3d 20 72 65 61 64  n[2].iEnd = read
9780: 65 72 2e 69 4f 66 66 20 2d 20 72 65 61 64 65 72  er.iOff - reader
9790: 2e 62 75 66 2e 6e 20 2b 20 72 65 61 64 65 72 2e  .buf.n + reader.
97a0: 69 42 75 66 3b 0a 20 20 20 20 70 4c 6f 67 2d 3e  iBuf;.    pLog->
97b0: 63 6b 73 75 6d 30 20 3d 20 72 65 61 64 65 72 2e  cksum0 = reader.
97c0: 63 6b 73 75 6d 30 3b 0a 20 20 20 20 70 4c 6f 67  cksum0;.    pLog
97d0: 2d 3e 63 6b 73 75 6d 31 20 3d 20 72 65 61 64 65  ->cksum1 = reade
97e0: 72 2e 63 6b 73 75 6d 31 3b 0a 20 20 7d 0a 0a 20  r.cksum1;.  }.. 
97f0: 20 69 66 28 20 72 63 3d 3d 4c 53 4d 5f 4f 4b 20   if( rc==LSM_OK 
9800: 29 7b 0a 20 20 20 20 72 63 20 3d 20 6c 73 6d 46  ){.    rc = lsmF
9810: 69 6e 69 73 68 52 65 63 6f 76 65 72 79 28 70 44  inishRecovery(pD
9820: 62 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  b);.  }else{.   
9830: 20 6c 73 6d 46 69 6e 69 73 68 52 65 63 6f 76 65   lsmFinishRecove
9840: 72 79 28 70 44 62 29 3b 0a 20 20 7d 0a 0a 20 20  ry(pDb);.  }..  
9850: 69 66 28 20 70 44 62 2d 3e 62 52 6f 54 72 61 6e  if( pDb->bRoTran
9860: 73 20 29 7b 0a 20 20 20 20 6c 73 6d 46 73 43 6c  s ){.    lsmFsCl
9870: 6f 73 65 4c 6f 67 28 70 44 62 29 3b 0a 20 20 7d  oseLog(pDb);.  }
9880: 0a 0a 20 20 6c 73 6d 53 74 72 69 6e 67 43 6c 65  ..  lsmStringCle
9890: 61 72 28 26 62 75 66 31 29 3b 0a 20 20 6c 73 6d  ar(&buf1);.  lsm
98a0: 53 74 72 69 6e 67 43 6c 65 61 72 28 26 62 75 66  StringClear(&buf
98b0: 32 29 3b 0a 20 20 6c 73 6d 53 74 72 69 6e 67 43  2);.  lsmStringC
98c0: 6c 65 61 72 28 26 72 65 61 64 65 72 2e 62 75 66  lear(&reader.buf
98d0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
98e0: 7d 0a 0a 76 6f 69 64 20 6c 73 6d 4c 6f 67 43 6c  }..void lsmLogCl
98f0: 6f 73 65 28 6c 73 6d 5f 64 62 20 2a 64 62 29 7b  ose(lsm_db *db){
9900: 0a 20 20 69 66 28 20 64 62 2d 3e 70 4c 6f 67 57  .  if( db->pLogW
9910: 72 69 74 65 72 20 29 7b 0a 20 20 20 20 6c 73 6d  riter ){.    lsm
9920: 46 72 65 65 28 64 62 2d 3e 70 45 6e 76 2c 20 64  Free(db->pEnv, d
9930: 62 2d 3e 70 4c 6f 67 57 72 69 74 65 72 2d 3e 62  b->pLogWriter->b
9940: 75 66 2e 7a 29 3b 0a 20 20 20 20 6c 73 6d 46 72  uf.z);.    lsmFr
9950: 65 65 28 64 62 2d 3e 70 45 6e 76 2c 20 64 62 2d  ee(db->pEnv, db-
9960: 3e 70 4c 6f 67 57 72 69 74 65 72 29 3b 0a 20 20  >pLogWriter);.  
9970: 20 20 64 62 2d 3e 70 4c 6f 67 57 72 69 74 65 72    db->pLogWriter
9980: 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a               = 0;.  }.}.